xref: /openbsd/sys/dev/pci/drm/drm_mipi_dsi.c (revision 9ea232b5)
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 #ifdef notyet
52 
53 static int mipi_dsi_device_match(struct device *dev, 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 
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 static 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 
101 /**
102  * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
103  *    device tree node
104  * @np: device tree node
105  *
106  * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
107  *    such device exists (or has not been registered yet).
108  */
109 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
110 {
111 	struct device *dev;
112 
113 	dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
114 
115 	return dev ? to_mipi_dsi_device(dev) : NULL;
116 }
117 EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
118 
119 static void mipi_dsi_dev_release(struct device *dev)
120 {
121 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
122 
123 	of_node_put(dev->of_node);
124 	kfree(dsi);
125 }
126 
127 static const struct device_type mipi_dsi_device_type = {
128 	.release = mipi_dsi_dev_release,
129 };
130 
131 static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
132 {
133 	struct mipi_dsi_device *dsi;
134 
135 	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
136 	if (!dsi)
137 		return ERR_PTR(-ENOMEM);
138 
139 	dsi->host = host;
140 	dsi->dev.bus = &mipi_dsi_bus_type;
141 	dsi->dev.parent = host->dev;
142 	dsi->dev.type = &mipi_dsi_device_type;
143 
144 	device_initialize(&dsi->dev);
145 
146 	return dsi;
147 }
148 
149 static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
150 {
151 	struct mipi_dsi_host *host = dsi->host;
152 
153 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
154 
155 	return device_add(&dsi->dev);
156 }
157 
158 #if IS_ENABLED(CONFIG_OF)
159 static struct mipi_dsi_device *
160 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
161 {
162 	struct mipi_dsi_device_info info = { };
163 	int ret;
164 	u32 reg;
165 
166 	if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
167 		drm_err(host, "modalias failure on %pOF\n", node);
168 		return ERR_PTR(-EINVAL);
169 	}
170 
171 	ret = of_property_read_u32(node, "reg", &reg);
172 	if (ret) {
173 		drm_err(host, "device node %pOF has no valid reg property: %d\n",
174 			node, ret);
175 		return ERR_PTR(-EINVAL);
176 	}
177 
178 	info.channel = reg;
179 	info.node = of_node_get(node);
180 
181 	return mipi_dsi_device_register_full(host, &info);
182 }
183 #else
184 static struct mipi_dsi_device *
185 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
186 {
187 	return ERR_PTR(-ENODEV);
188 }
189 #endif
190 
191 /**
192  * mipi_dsi_device_register_full - create a MIPI DSI device
193  * @host: DSI host to which this device is connected
194  * @info: pointer to template containing DSI device information
195  *
196  * Create a MIPI DSI device by using the device information provided by
197  * mipi_dsi_device_info template
198  *
199  * Returns:
200  * A pointer to the newly created MIPI DSI device, or, a pointer encoded
201  * with an error
202  */
203 struct mipi_dsi_device *
204 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
205 			      const struct mipi_dsi_device_info *info)
206 {
207 	struct mipi_dsi_device *dsi;
208 	int ret;
209 
210 	if (!info) {
211 		drm_err(host, "invalid mipi_dsi_device_info pointer\n");
212 		return ERR_PTR(-EINVAL);
213 	}
214 
215 	if (info->channel > 3) {
216 		drm_err(host, "invalid virtual channel: %u\n", info->channel);
217 		return ERR_PTR(-EINVAL);
218 	}
219 
220 	dsi = mipi_dsi_device_alloc(host);
221 	if (IS_ERR(dsi)) {
222 		drm_err(host, "failed to allocate DSI device %ld\n",
223 			PTR_ERR(dsi));
224 		return dsi;
225 	}
226 
227 	device_set_node(&dsi->dev, of_fwnode_handle(info->node));
228 	dsi->channel = info->channel;
229 	strscpy(dsi->name, info->type, sizeof(dsi->name));
230 
231 	ret = mipi_dsi_device_add(dsi);
232 	if (ret) {
233 		drm_err(host, "failed to add DSI device %d\n", ret);
234 		kfree(dsi);
235 		return ERR_PTR(ret);
236 	}
237 
238 	return dsi;
239 }
240 EXPORT_SYMBOL(mipi_dsi_device_register_full);
241 
242 /**
243  * mipi_dsi_device_unregister - unregister MIPI DSI device
244  * @dsi: DSI peripheral device
245  */
246 void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
247 {
248 	device_unregister(&dsi->dev);
249 }
250 EXPORT_SYMBOL(mipi_dsi_device_unregister);
251 
252 static void devm_mipi_dsi_device_unregister(void *arg)
253 {
254 	struct mipi_dsi_device *dsi = arg;
255 
256 	mipi_dsi_device_unregister(dsi);
257 }
258 
259 /**
260  * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
261  * @dev: device to tie the MIPI-DSI device lifetime to
262  * @host: DSI host to which this device is connected
263  * @info: pointer to template containing DSI device information
264  *
265  * Create a MIPI DSI device by using the device information provided by
266  * mipi_dsi_device_info template
267  *
268  * This is the managed version of mipi_dsi_device_register_full() which
269  * automatically calls mipi_dsi_device_unregister() when @dev is
270  * unbound.
271  *
272  * Returns:
273  * A pointer to the newly created MIPI DSI device, or, a pointer encoded
274  * with an error
275  */
276 struct mipi_dsi_device *
277 devm_mipi_dsi_device_register_full(struct device *dev,
278 				   struct mipi_dsi_host *host,
279 				   const struct mipi_dsi_device_info *info)
280 {
281 	struct mipi_dsi_device *dsi;
282 	int ret;
283 
284 	dsi = mipi_dsi_device_register_full(host, info);
285 	if (IS_ERR(dsi))
286 		return dsi;
287 
288 	STUB();
289 	return ERR_PTR(-ENOSYS);
290 #ifdef notyet
291 	ret = devm_add_action_or_reset(dev,
292 				       devm_mipi_dsi_device_unregister,
293 				       dsi);
294 	if (ret)
295 		return ERR_PTR(ret);
296 
297 	return dsi;
298 #endif
299 }
300 EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
301 
302 static DEFINE_MUTEX(host_lock);
303 static DRM_LIST_HEAD(host_list);
304 
305 /**
306  * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
307  *				     device tree node
308  * @node: device tree node
309  *
310  * Returns:
311  * A pointer to the MIPI DSI host corresponding to @node or NULL if no
312  * such device exists (or has not been registered yet).
313  */
314 struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
315 {
316 	struct mipi_dsi_host *host;
317 
318 	mutex_lock(&host_lock);
319 
320 	list_for_each_entry(host, &host_list, list) {
321 		if (host->dev->of_node == node) {
322 			mutex_unlock(&host_lock);
323 			return host;
324 		}
325 	}
326 
327 	mutex_unlock(&host_lock);
328 
329 	return NULL;
330 }
331 EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
332 
333 int mipi_dsi_host_register(struct mipi_dsi_host *host)
334 {
335 	struct device_node *node;
336 
337 	for_each_available_child_of_node(host->dev->of_node, node) {
338 		/* skip nodes without reg property */
339 		if (!of_property_present(node, "reg"))
340 			continue;
341 		of_mipi_dsi_device_add(host, node);
342 	}
343 
344 	mutex_lock(&host_lock);
345 	list_add_tail(&host->list, &host_list);
346 	mutex_unlock(&host_lock);
347 
348 	return 0;
349 }
350 EXPORT_SYMBOL(mipi_dsi_host_register);
351 
352 static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
353 {
354 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
355 
356 	mipi_dsi_detach(dsi);
357 	mipi_dsi_device_unregister(dsi);
358 
359 	return 0;
360 }
361 
362 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
363 {
364 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
365 
366 	mutex_lock(&host_lock);
367 	list_del_init(&host->list);
368 	mutex_unlock(&host_lock);
369 }
370 EXPORT_SYMBOL(mipi_dsi_host_unregister);
371 
372 #endif
373 
374 /**
375  * mipi_dsi_attach - attach a DSI device to its DSI host
376  * @dsi: DSI peripheral
377  */
378 int mipi_dsi_attach(struct mipi_dsi_device *dsi)
379 {
380 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
381 
382 	if (!ops || !ops->attach)
383 		return -ENOSYS;
384 
385 	return ops->attach(dsi->host, dsi);
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 (!ops || !ops->detach)
398 		return -ENOSYS;
399 
400 	return ops->detach(dsi->host, dsi);
401 }
402 EXPORT_SYMBOL(mipi_dsi_detach);
403 
404 static void devm_mipi_dsi_detach(void *arg)
405 {
406 	struct mipi_dsi_device *dsi = arg;
407 
408 	mipi_dsi_detach(dsi);
409 }
410 
411 /**
412  * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
413  * @dev: device to tie the MIPI-DSI device attachment lifetime to
414  * @dsi: DSI peripheral
415  *
416  * This is the managed version of mipi_dsi_attach() which automatically
417  * calls mipi_dsi_detach() when @dev is unbound.
418  *
419  * Returns:
420  * 0 on success, a negative error code on failure.
421  */
422 int devm_mipi_dsi_attach(struct device *dev,
423 			 struct mipi_dsi_device *dsi)
424 {
425 	int ret;
426 
427 	ret = mipi_dsi_attach(dsi);
428 	if (ret)
429 		return ret;
430 
431 	STUB();
432 	return -ENOSYS;
433 #ifdef notyet
434 	ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
435 	if (ret)
436 		return ret;
437 
438 	return 0;
439 #endif
440 }
441 EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
442 
443 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
444 					struct mipi_dsi_msg *msg)
445 {
446 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
447 
448 	if (!ops || !ops->transfer)
449 		return -ENOSYS;
450 
451 	if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
452 		msg->flags |= MIPI_DSI_MSG_USE_LPM;
453 
454 	return ops->transfer(dsi->host, msg);
455 }
456 
457 /**
458  * mipi_dsi_packet_format_is_short - check if a packet is of the short format
459  * @type: MIPI DSI data type of the packet
460  *
461  * Return: true if the packet for the given data type is a short packet, false
462  * otherwise.
463  */
464 bool mipi_dsi_packet_format_is_short(u8 type)
465 {
466 	switch (type) {
467 	case MIPI_DSI_V_SYNC_START:
468 	case MIPI_DSI_V_SYNC_END:
469 	case MIPI_DSI_H_SYNC_START:
470 	case MIPI_DSI_H_SYNC_END:
471 	case MIPI_DSI_COMPRESSION_MODE:
472 	case MIPI_DSI_END_OF_TRANSMISSION:
473 	case MIPI_DSI_COLOR_MODE_OFF:
474 	case MIPI_DSI_COLOR_MODE_ON:
475 	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
476 	case MIPI_DSI_TURN_ON_PERIPHERAL:
477 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
478 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
479 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
480 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
481 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
482 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
483 	case MIPI_DSI_DCS_SHORT_WRITE:
484 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
485 	case MIPI_DSI_DCS_READ:
486 	case MIPI_DSI_EXECUTE_QUEUE:
487 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
488 		return true;
489 	}
490 
491 	return false;
492 }
493 EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
494 
495 /**
496  * mipi_dsi_packet_format_is_long - check if a packet is of the long format
497  * @type: MIPI DSI data type of the packet
498  *
499  * Return: true if the packet for the given data type is a long packet, false
500  * otherwise.
501  */
502 bool mipi_dsi_packet_format_is_long(u8 type)
503 {
504 	switch (type) {
505 	case MIPI_DSI_NULL_PACKET:
506 	case MIPI_DSI_BLANKING_PACKET:
507 	case MIPI_DSI_GENERIC_LONG_WRITE:
508 	case MIPI_DSI_DCS_LONG_WRITE:
509 	case MIPI_DSI_PICTURE_PARAMETER_SET:
510 	case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
511 	case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
512 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
513 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
514 	case MIPI_DSI_PACKED_PIXEL_STREAM_30:
515 	case MIPI_DSI_PACKED_PIXEL_STREAM_36:
516 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
517 	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
518 	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
519 	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
520 	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
521 		return true;
522 	}
523 
524 	return false;
525 }
526 EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
527 
528 /**
529  * mipi_dsi_create_packet - create a packet from a message according to the
530  *     DSI protocol
531  * @packet: pointer to a DSI packet structure
532  * @msg: message to translate into a packet
533  *
534  * Return: 0 on success or a negative error code on failure.
535  */
536 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
537 			   const struct mipi_dsi_msg *msg)
538 {
539 	if (!packet || !msg)
540 		return -EINVAL;
541 
542 	/* do some minimum sanity checking */
543 	if (!mipi_dsi_packet_format_is_short(msg->type) &&
544 	    !mipi_dsi_packet_format_is_long(msg->type))
545 		return -EINVAL;
546 
547 	if (msg->channel > 3)
548 		return -EINVAL;
549 
550 	memset(packet, 0, sizeof(*packet));
551 	packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
552 
553 	/* TODO: compute ECC if hardware support is not available */
554 
555 	/*
556 	 * Long write packets contain the word count in header bytes 1 and 2.
557 	 * The payload follows the header and is word count bytes long.
558 	 *
559 	 * Short write packets encode up to two parameters in header bytes 1
560 	 * and 2.
561 	 */
562 	if (mipi_dsi_packet_format_is_long(msg->type)) {
563 		packet->header[1] = (msg->tx_len >> 0) & 0xff;
564 		packet->header[2] = (msg->tx_len >> 8) & 0xff;
565 
566 		packet->payload_length = msg->tx_len;
567 		packet->payload = msg->tx_buf;
568 	} else {
569 		const u8 *tx = msg->tx_buf;
570 
571 		packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
572 		packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
573 	}
574 
575 	packet->size = sizeof(packet->header) + packet->payload_length;
576 
577 	return 0;
578 }
579 EXPORT_SYMBOL(mipi_dsi_create_packet);
580 
581 /**
582  * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
583  * @dsi: DSI peripheral device
584  *
585  * Return: 0 on success or a negative error code on failure.
586  */
587 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
588 {
589 	struct mipi_dsi_msg msg = {
590 		.channel = dsi->channel,
591 		.type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
592 		.tx_buf = (u8 [2]) { 0, 0 },
593 		.tx_len = 2,
594 	};
595 	int ret = mipi_dsi_device_transfer(dsi, &msg);
596 
597 	return (ret < 0) ? ret : 0;
598 }
599 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
600 
601 /**
602  * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
603  * @dsi: DSI peripheral device
604  *
605  * Return: 0 on success or a negative error code on failure.
606  */
607 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
608 {
609 	struct mipi_dsi_msg msg = {
610 		.channel = dsi->channel,
611 		.type = MIPI_DSI_TURN_ON_PERIPHERAL,
612 		.tx_buf = (u8 [2]) { 0, 0 },
613 		.tx_len = 2,
614 	};
615 	int ret = mipi_dsi_device_transfer(dsi, &msg);
616 
617 	return (ret < 0) ? ret : 0;
618 }
619 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
620 
621 /*
622  * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of
623  *    the payload in a long packet transmitted from the peripheral back to the
624  *    host processor
625  * @dsi: DSI peripheral device
626  * @value: the maximum size of the payload
627  *
628  * Return: 0 on success or a negative error code on failure.
629  */
630 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
631 					    u16 value)
632 {
633 	u8 tx[2] = { value & 0xff, value >> 8 };
634 	struct mipi_dsi_msg msg = {
635 		.channel = dsi->channel,
636 		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
637 		.tx_len = sizeof(tx),
638 		.tx_buf = tx,
639 	};
640 	int ret = mipi_dsi_device_transfer(dsi, &msg);
641 
642 	return (ret < 0) ? ret : 0;
643 }
644 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
645 
646 /**
647  * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
648  * @dsi: DSI peripheral device
649  * @enable: Whether to enable or disable the DSC
650  *
651  * Enable or disable Display Stream Compression on the peripheral using the
652  * default Picture Parameter Set and VESA DSC 1.1 algorithm.
653  *
654  * Return: 0 on success or a negative error code on failure.
655  */
656 ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
657 {
658 	/* Note: Needs updating for non-default PPS or algorithm */
659 	u8 tx[2] = { enable << 0, 0 };
660 	struct mipi_dsi_msg msg = {
661 		.channel = dsi->channel,
662 		.type = MIPI_DSI_COMPRESSION_MODE,
663 		.tx_len = sizeof(tx),
664 		.tx_buf = tx,
665 	};
666 	int ret = mipi_dsi_device_transfer(dsi, &msg);
667 
668 	return (ret < 0) ? ret : 0;
669 }
670 EXPORT_SYMBOL(mipi_dsi_compression_mode);
671 
672 /**
673  * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
674  * @dsi: DSI peripheral device
675  * @pps: VESA DSC 1.1 Picture Parameter Set
676  *
677  * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
678  *
679  * Return: 0 on success or a negative error code on failure.
680  */
681 ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
682 				       const struct drm_dsc_picture_parameter_set *pps)
683 {
684 	struct mipi_dsi_msg msg = {
685 		.channel = dsi->channel,
686 		.type = MIPI_DSI_PICTURE_PARAMETER_SET,
687 		.tx_len = sizeof(*pps),
688 		.tx_buf = pps,
689 	};
690 	int ret = mipi_dsi_device_transfer(dsi, &msg);
691 
692 	return (ret < 0) ? ret : 0;
693 }
694 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
695 
696 /**
697  * mipi_dsi_generic_write() - transmit data using a generic write packet
698  * @dsi: DSI peripheral device
699  * @payload: buffer containing the payload
700  * @size: size of payload buffer
701  *
702  * This function will automatically choose the right data type depending on
703  * the payload length.
704  *
705  * Return: The number of bytes transmitted on success or a negative error code
706  * on failure.
707  */
708 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
709 			       size_t size)
710 {
711 	struct mipi_dsi_msg msg = {
712 		.channel = dsi->channel,
713 		.tx_buf = payload,
714 		.tx_len = size
715 	};
716 
717 	switch (size) {
718 	case 0:
719 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
720 		break;
721 
722 	case 1:
723 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
724 		break;
725 
726 	case 2:
727 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
728 		break;
729 
730 	default:
731 		msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
732 		break;
733 	}
734 
735 	return mipi_dsi_device_transfer(dsi, &msg);
736 }
737 EXPORT_SYMBOL(mipi_dsi_generic_write);
738 
739 /**
740  * mipi_dsi_generic_read() - receive data using a generic read packet
741  * @dsi: DSI peripheral device
742  * @params: buffer containing the request parameters
743  * @num_params: number of request parameters
744  * @data: buffer in which to return the received data
745  * @size: size of receive buffer
746  *
747  * This function will automatically choose the right data type depending on
748  * the number of parameters passed in.
749  *
750  * Return: The number of bytes successfully read or a negative error code on
751  * failure.
752  */
753 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
754 			      size_t num_params, void *data, size_t size)
755 {
756 	struct mipi_dsi_msg msg = {
757 		.channel = dsi->channel,
758 		.tx_len = num_params,
759 		.tx_buf = params,
760 		.rx_len = size,
761 		.rx_buf = data
762 	};
763 
764 	switch (num_params) {
765 	case 0:
766 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
767 		break;
768 
769 	case 1:
770 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
771 		break;
772 
773 	case 2:
774 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
775 		break;
776 
777 	default:
778 		return -EINVAL;
779 	}
780 
781 	return mipi_dsi_device_transfer(dsi, &msg);
782 }
783 EXPORT_SYMBOL(mipi_dsi_generic_read);
784 
785 /**
786  * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
787  * @dsi: DSI peripheral device
788  * @data: buffer containing data to be transmitted
789  * @len: size of transmission buffer
790  *
791  * This function will automatically choose the right data type depending on
792  * the command payload length.
793  *
794  * Return: The number of bytes successfully transmitted or a negative error
795  * code on failure.
796  */
797 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
798 				  const void *data, size_t len)
799 {
800 	struct mipi_dsi_msg msg = {
801 		.channel = dsi->channel,
802 		.tx_buf = data,
803 		.tx_len = len
804 	};
805 
806 	switch (len) {
807 	case 0:
808 		return -EINVAL;
809 
810 	case 1:
811 		msg.type = MIPI_DSI_DCS_SHORT_WRITE;
812 		break;
813 
814 	case 2:
815 		msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
816 		break;
817 
818 	default:
819 		msg.type = MIPI_DSI_DCS_LONG_WRITE;
820 		break;
821 	}
822 
823 	return mipi_dsi_device_transfer(dsi, &msg);
824 }
825 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
826 
827 /**
828  * mipi_dsi_dcs_write() - send DCS write command
829  * @dsi: DSI peripheral device
830  * @cmd: DCS command
831  * @data: buffer containing the command payload
832  * @len: command payload length
833  *
834  * This function will automatically choose the right data type depending on
835  * the command payload length.
836  *
837  * Return: The number of bytes successfully transmitted or a negative error
838  * code on failure.
839  */
840 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
841 			   const void *data, size_t len)
842 {
843 	ssize_t err;
844 	size_t size;
845 	u8 stack_tx[8];
846 	u8 *tx;
847 
848 	size = 1 + len;
849 	if (len > ARRAY_SIZE(stack_tx) - 1) {
850 		tx = kmalloc(size, GFP_KERNEL);
851 		if (!tx)
852 			return -ENOMEM;
853 	} else {
854 		tx = stack_tx;
855 	}
856 
857 	/* concatenate the DCS command byte and the payload */
858 	tx[0] = cmd;
859 	if (data)
860 		memcpy(&tx[1], data, len);
861 
862 	err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
863 
864 	if (tx != stack_tx)
865 		kfree(tx);
866 
867 	return err;
868 }
869 EXPORT_SYMBOL(mipi_dsi_dcs_write);
870 
871 /**
872  * mipi_dsi_dcs_read() - send DCS read request command
873  * @dsi: DSI peripheral device
874  * @cmd: DCS command
875  * @data: buffer in which to receive data
876  * @len: size of receive buffer
877  *
878  * Return: The number of bytes read or a negative error code on failure.
879  */
880 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
881 			  size_t len)
882 {
883 	struct mipi_dsi_msg msg = {
884 		.channel = dsi->channel,
885 		.type = MIPI_DSI_DCS_READ,
886 		.tx_buf = &cmd,
887 		.tx_len = 1,
888 		.rx_buf = data,
889 		.rx_len = len
890 	};
891 
892 	return mipi_dsi_device_transfer(dsi, &msg);
893 }
894 EXPORT_SYMBOL(mipi_dsi_dcs_read);
895 
896 /**
897  * mipi_dsi_dcs_nop() - send DCS nop packet
898  * @dsi: DSI peripheral device
899  *
900  * Return: 0 on success or a negative error code on failure.
901  */
902 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
903 {
904 	ssize_t err;
905 
906 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
907 	if (err < 0)
908 		return err;
909 
910 	return 0;
911 }
912 EXPORT_SYMBOL(mipi_dsi_dcs_nop);
913 
914 /**
915  * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
916  * @dsi: DSI peripheral device
917  *
918  * Return: 0 on success or a negative error code on failure.
919  */
920 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
921 {
922 	ssize_t err;
923 
924 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
925 	if (err < 0)
926 		return err;
927 
928 	return 0;
929 }
930 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
931 
932 /**
933  * mipi_dsi_dcs_get_power_mode() - query the display module's current power
934  *    mode
935  * @dsi: DSI peripheral device
936  * @mode: return location for the current power mode
937  *
938  * Return: 0 on success or a negative error code on failure.
939  */
940 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
941 {
942 	ssize_t err;
943 
944 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
945 				sizeof(*mode));
946 	if (err <= 0) {
947 		if (err == 0)
948 			err = -ENODATA;
949 
950 		return err;
951 	}
952 
953 	return 0;
954 }
955 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
956 
957 /**
958  * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
959  *    data used by the interface
960  * @dsi: DSI peripheral device
961  * @format: return location for the pixel format
962  *
963  * Return: 0 on success or a negative error code on failure.
964  */
965 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
966 {
967 	ssize_t err;
968 
969 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
970 				sizeof(*format));
971 	if (err <= 0) {
972 		if (err == 0)
973 			err = -ENODATA;
974 
975 		return err;
976 	}
977 
978 	return 0;
979 }
980 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
981 
982 /**
983  * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
984  *    display module except interface communication
985  * @dsi: DSI peripheral device
986  *
987  * Return: 0 on success or a negative error code on failure.
988  */
989 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
990 {
991 	ssize_t err;
992 
993 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
994 	if (err < 0)
995 		return err;
996 
997 	return 0;
998 }
999 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
1000 
1001 /**
1002  * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
1003  *    module
1004  * @dsi: DSI peripheral device
1005  *
1006  * Return: 0 on success or a negative error code on failure.
1007  */
1008 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
1009 {
1010 	ssize_t err;
1011 
1012 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
1013 	if (err < 0)
1014 		return err;
1015 
1016 	return 0;
1017 }
1018 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
1019 
1020 /**
1021  * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
1022  *    display device
1023  * @dsi: DSI peripheral device
1024  *
1025  * Return: 0 on success or a negative error code on failure.
1026  */
1027 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
1028 {
1029 	ssize_t err;
1030 
1031 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
1032 	if (err < 0)
1033 		return err;
1034 
1035 	return 0;
1036 }
1037 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
1038 
1039 /**
1040  * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
1041  *    display device
1042  * @dsi: DSI peripheral device
1043  *
1044  * Return: 0 on success or a negative error code on failure
1045  */
1046 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
1047 {
1048 	ssize_t err;
1049 
1050 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
1051 	if (err < 0)
1052 		return err;
1053 
1054 	return 0;
1055 }
1056 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
1057 
1058 /**
1059  * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
1060  *    memory accessed by the host processor
1061  * @dsi: DSI peripheral device
1062  * @start: first column of frame memory
1063  * @end: last column of frame memory
1064  *
1065  * Return: 0 on success or a negative error code on failure.
1066  */
1067 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
1068 				    u16 end)
1069 {
1070 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1071 	ssize_t err;
1072 
1073 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
1074 				 sizeof(payload));
1075 	if (err < 0)
1076 		return err;
1077 
1078 	return 0;
1079 }
1080 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
1081 
1082 /**
1083  * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
1084  *    memory accessed by the host processor
1085  * @dsi: DSI peripheral device
1086  * @start: first page of frame memory
1087  * @end: last page of frame memory
1088  *
1089  * Return: 0 on success or a negative error code on failure.
1090  */
1091 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
1092 				  u16 end)
1093 {
1094 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1095 	ssize_t err;
1096 
1097 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
1098 				 sizeof(payload));
1099 	if (err < 0)
1100 		return err;
1101 
1102 	return 0;
1103 }
1104 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
1105 
1106 /**
1107  * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
1108  *    output signal on the TE signal line
1109  * @dsi: DSI peripheral device
1110  *
1111  * Return: 0 on success or a negative error code on failure
1112  */
1113 int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
1114 {
1115 	ssize_t err;
1116 
1117 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
1118 	if (err < 0)
1119 		return err;
1120 
1121 	return 0;
1122 }
1123 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
1124 
1125 /**
1126  * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
1127  *    output signal on the TE signal line.
1128  * @dsi: DSI peripheral device
1129  * @mode: the Tearing Effect Output Line mode
1130  *
1131  * Return: 0 on success or a negative error code on failure
1132  */
1133 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
1134 			     enum mipi_dsi_dcs_tear_mode mode)
1135 {
1136 	u8 value = mode;
1137 	ssize_t err;
1138 
1139 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
1140 				 sizeof(value));
1141 	if (err < 0)
1142 		return err;
1143 
1144 	return 0;
1145 }
1146 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
1147 
1148 /**
1149  * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
1150  *    data used by the interface
1151  * @dsi: DSI peripheral device
1152  * @format: pixel format
1153  *
1154  * Return: 0 on success or a negative error code on failure.
1155  */
1156 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
1157 {
1158 	ssize_t err;
1159 
1160 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
1161 				 sizeof(format));
1162 	if (err < 0)
1163 		return err;
1164 
1165 	return 0;
1166 }
1167 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
1168 
1169 #ifdef notyet
1170 
1171 /**
1172  * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
1173  *    the Tearing Effect output signal of the display module
1174  * @dsi: DSI peripheral device
1175  * @scanline: scanline to use as trigger
1176  *
1177  * Return: 0 on success or a negative error code on failure
1178  */
1179 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
1180 {
1181 	u8 payload[2] = { scanline >> 8, scanline & 0xff };
1182 	ssize_t err;
1183 
1184 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload,
1185 				 sizeof(payload));
1186 	if (err < 0)
1187 		return err;
1188 
1189 	return 0;
1190 }
1191 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
1192 
1193 /**
1194  * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
1195  *    display
1196  * @dsi: DSI peripheral device
1197  * @brightness: brightness value
1198  *
1199  * Return: 0 on success or a negative error code on failure.
1200  */
1201 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
1202 					u16 brightness)
1203 {
1204 	u8 payload[2] = { brightness & 0xff, brightness >> 8 };
1205 	ssize_t err;
1206 
1207 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1208 				 payload, sizeof(payload));
1209 	if (err < 0)
1210 		return err;
1211 
1212 	return 0;
1213 }
1214 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness);
1215 
1216 /**
1217  * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
1218  *    of the display
1219  * @dsi: DSI peripheral device
1220  * @brightness: brightness value
1221  *
1222  * Return: 0 on success or a negative error code on failure.
1223  */
1224 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
1225 					u16 *brightness)
1226 {
1227 	ssize_t err;
1228 
1229 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1230 				brightness, sizeof(*brightness));
1231 	if (err <= 0) {
1232 		if (err == 0)
1233 			err = -ENODATA;
1234 
1235 		return err;
1236 	}
1237 
1238 	return 0;
1239 }
1240 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
1241 
1242 /**
1243  * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
1244  *    of the display
1245  * @dsi: DSI peripheral device
1246  * @brightness: brightness value
1247  *
1248  * Return: 0 on success or a negative error code on failure.
1249  */
1250 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
1251 					     u16 brightness)
1252 {
1253 	u8 payload[2] = { brightness >> 8, brightness & 0xff };
1254 	ssize_t err;
1255 
1256 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1257 				 payload, sizeof(payload));
1258 	if (err < 0)
1259 		return err;
1260 
1261 	return 0;
1262 }
1263 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
1264 
1265 /**
1266  * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
1267  *    brightness value of the display
1268  * @dsi: DSI peripheral device
1269  * @brightness: brightness value
1270  *
1271  * Return: 0 on success or a negative error code on failure.
1272  */
1273 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
1274 					     u16 *brightness)
1275 {
1276 	u8 brightness_be[2];
1277 	ssize_t err;
1278 
1279 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1280 				brightness_be, sizeof(brightness_be));
1281 	if (err <= 0) {
1282 		if (err == 0)
1283 			err = -ENODATA;
1284 
1285 		return err;
1286 	}
1287 
1288 	*brightness = (brightness_be[0] << 8) | brightness_be[1];
1289 
1290 	return 0;
1291 }
1292 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
1293 
1294 static int mipi_dsi_drv_probe(struct device *dev)
1295 {
1296 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1297 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1298 
1299 	return drv->probe(dsi);
1300 }
1301 
1302 static int mipi_dsi_drv_remove(struct device *dev)
1303 {
1304 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1305 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1306 
1307 	drv->remove(dsi);
1308 
1309 	return 0;
1310 }
1311 
1312 static void mipi_dsi_drv_shutdown(struct device *dev)
1313 {
1314 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1315 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1316 
1317 	drv->shutdown(dsi);
1318 }
1319 
1320 /**
1321  * mipi_dsi_driver_register_full() - register a driver for DSI devices
1322  * @drv: DSI driver structure
1323  * @owner: owner module
1324  *
1325  * Return: 0 on success or a negative error code on failure.
1326  */
1327 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
1328 				  struct module *owner)
1329 {
1330 	drv->driver.bus = &mipi_dsi_bus_type;
1331 	drv->driver.owner = owner;
1332 
1333 	if (drv->probe)
1334 		drv->driver.probe = mipi_dsi_drv_probe;
1335 	if (drv->remove)
1336 		drv->driver.remove = mipi_dsi_drv_remove;
1337 	if (drv->shutdown)
1338 		drv->driver.shutdown = mipi_dsi_drv_shutdown;
1339 
1340 	return driver_register(&drv->driver);
1341 }
1342 EXPORT_SYMBOL(mipi_dsi_driver_register_full);
1343 
1344 /**
1345  * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
1346  * @drv: DSI driver structure
1347  *
1348  * Return: 0 on success or a negative error code on failure.
1349  */
1350 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
1351 {
1352 	driver_unregister(&drv->driver);
1353 }
1354 EXPORT_SYMBOL(mipi_dsi_driver_unregister);
1355 
1356 static int __init mipi_dsi_bus_init(void)
1357 {
1358 	return bus_register(&mipi_dsi_bus_type);
1359 }
1360 postcore_initcall(mipi_dsi_bus_init);
1361 
1362 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
1363 MODULE_DESCRIPTION("MIPI DSI Bus");
1364 MODULE_LICENSE("GPL and additional rights");
1365 
1366 #endif
1367