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", ®);
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