1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * MIPI DSI Bus
4 *
5 * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
6 * Andrzej Hajda <a.hajda@samsung.com>
7 */
8
9 #include <drm/drm_mipi_dsi.h>
10
11 #include <config.h>
12 #include <common.h>
13 #include <errno.h>
14 #include <malloc.h>
15
16 /**
17 * mipi_dsi_attach - attach a DSI device to its DSI host
18 * @dsi: DSI peripheral
19 */
mipi_dsi_attach(struct mipi_dsi_device * dsi)20 int mipi_dsi_attach(struct mipi_dsi_device *dsi)
21 {
22 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
23
24 if (!ops || !ops->attach)
25 return -ENOSYS;
26
27 return ops->attach(dsi->host, dsi);
28 }
29
30 /**
31 * mipi_dsi_detach - detach a DSI device from its DSI host
32 * @dsi: DSI peripheral
33 */
mipi_dsi_detach(struct mipi_dsi_device * dsi)34 int mipi_dsi_detach(struct mipi_dsi_device *dsi)
35 {
36 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
37
38 if (!ops || !ops->detach)
39 return -ENOSYS;
40
41 return ops->detach(dsi->host, dsi);
42 }
43
mipi_dsi_device_transfer(struct mipi_dsi_device * dsi,struct mipi_dsi_msg * msg)44 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
45 struct mipi_dsi_msg *msg)
46 {
47 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
48
49 if (!ops || !ops->transfer)
50 return -ENOSYS;
51
52 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
53 msg->flags |= MIPI_DSI_MSG_USE_LPM;
54
55 return ops->transfer(dsi->host, msg);
56 }
57
58 /**
59 * mipi_dsi_packet_format_is_short - check if a packet is of the short format
60 * @type: MIPI DSI data type of the packet
61 *
62 * Return: true if the packet for the given data type is a short packet, false
63 * otherwise.
64 */
mipi_dsi_packet_format_is_short(u8 type)65 bool mipi_dsi_packet_format_is_short(u8 type)
66 {
67 switch (type) {
68 case MIPI_DSI_V_SYNC_START:
69 case MIPI_DSI_V_SYNC_END:
70 case MIPI_DSI_H_SYNC_START:
71 case MIPI_DSI_H_SYNC_END:
72 case MIPI_DSI_COMPRESSION_MODE:
73 case MIPI_DSI_END_OF_TRANSMISSION:
74 case MIPI_DSI_COLOR_MODE_OFF:
75 case MIPI_DSI_COLOR_MODE_ON:
76 case MIPI_DSI_SHUTDOWN_PERIPHERAL:
77 case MIPI_DSI_TURN_ON_PERIPHERAL:
78 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
79 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
80 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
81 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
82 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
83 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
84 case MIPI_DSI_DCS_SHORT_WRITE:
85 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
86 case MIPI_DSI_DCS_READ:
87 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
88 return true;
89 }
90
91 return false;
92 }
93
94 /**
95 * mipi_dsi_packet_format_is_long - check if a packet is of the long format
96 * @type: MIPI DSI data type of the packet
97 *
98 * Return: true if the packet for the given data type is a long packet, false
99 * otherwise.
100 */
mipi_dsi_packet_format_is_long(u8 type)101 bool mipi_dsi_packet_format_is_long(u8 type)
102 {
103 switch (type) {
104 case MIPI_DSI_NULL_PACKET:
105 case MIPI_DSI_BLANKING_PACKET:
106 case MIPI_DSI_GENERIC_LONG_WRITE:
107 case MIPI_DSI_DCS_LONG_WRITE:
108 case MIPI_DSI_PICTURE_PARAMETER_SET:
109 case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
110 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
111 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
112 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
113 case MIPI_DSI_PACKED_PIXEL_STREAM_30:
114 case MIPI_DSI_PACKED_PIXEL_STREAM_36:
115 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
116 case MIPI_DSI_PACKED_PIXEL_STREAM_16:
117 case MIPI_DSI_PACKED_PIXEL_STREAM_18:
118 case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
119 case MIPI_DSI_PACKED_PIXEL_STREAM_24:
120 return true;
121 }
122
123 return false;
124 }
125
126 /**
127 * mipi_dsi_create_packet - create a packet from a message according to the
128 * DSI protocol
129 * @packet: pointer to a DSI packet structure
130 * @msg: message to translate into a packet
131 *
132 * Return: 0 on success or a negative error code on failure.
133 */
mipi_dsi_create_packet(struct mipi_dsi_packet * packet,const struct mipi_dsi_msg * msg)134 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
135 const struct mipi_dsi_msg *msg)
136 {
137 if (!packet || !msg)
138 return -EINVAL;
139
140 /* do some minimum sanity checking */
141 if (!mipi_dsi_packet_format_is_short(msg->type) &&
142 !mipi_dsi_packet_format_is_long(msg->type))
143 return -EINVAL;
144
145 if (msg->channel > 3)
146 return -EINVAL;
147
148 memset(packet, 0, sizeof(*packet));
149 packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
150 if (mipi_dsi_packet_format_is_long(msg->type)) {
151 packet->header[1] = (msg->tx_len >> 0) & 0xff;
152 packet->header[2] = (msg->tx_len >> 8) & 0xff;
153
154 packet->payload_length = msg->tx_len;
155 packet->payload = msg->tx_buf;
156 } else {
157 const u8 *tx = msg->tx_buf;
158
159 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
160 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
161 }
162
163 packet->size = sizeof(packet->header) + packet->payload_length;
164
165 return 0;
166 }
167
168 /**
169 * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
170 * @dsi: DSI peripheral device
171 *
172 * Return: 0 on success or a negative error code on failure.
173 */
mipi_dsi_shutdown_peripheral(struct mipi_dsi_device * dsi)174 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
175 {
176 struct mipi_dsi_msg msg = {
177 .channel = dsi->channel,
178 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
179 .tx_buf = (u8 [2]) { 0, 0 },
180 .tx_len = 2,
181 };
182 int ret = mipi_dsi_device_transfer(dsi, &msg);
183
184 return (ret < 0) ? ret : 0;
185 }
186
187 /**
188 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
189 * @dsi: DSI peripheral device
190 *
191 * Return: 0 on success or a negative error code on failure.
192 */
mipi_dsi_turn_on_peripheral(struct mipi_dsi_device * dsi)193 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
194 {
195 struct mipi_dsi_msg msg = {
196 .channel = dsi->channel,
197 .type = MIPI_DSI_TURN_ON_PERIPHERAL,
198 .tx_buf = (u8 [2]) { 0, 0 },
199 .tx_len = 2,
200 };
201 int ret = mipi_dsi_device_transfer(dsi, &msg);
202
203 return (ret < 0) ? ret : 0;
204 }
205
206 /*
207 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
208 * the payload in a long packet transmitted from the peripheral back to the
209 * host processor
210 * @dsi: DSI peripheral device
211 * @value: the maximum size of the payload
212 *
213 * Return: 0 on success or a negative error code on failure.
214 */
mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device * dsi,u16 value)215 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
216 u16 value)
217 {
218 u8 tx[2] = { value & 0xff, value >> 8 };
219 struct mipi_dsi_msg msg = {
220 .channel = dsi->channel,
221 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
222 .tx_len = sizeof(tx),
223 .tx_buf = tx,
224 };
225 int ret = mipi_dsi_device_transfer(dsi, &msg);
226
227 return (ret < 0) ? ret : 0;
228 }
229
230 /**
231 * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
232 * @dsi: DSI peripheral device
233 * @enable: Whether to enable or disable the DSC
234 *
235 * Enable or disable Display Stream Compression on the peripheral using the
236 * default Picture Parameter Set and VESA DSC 1.1 algorithm.
237 *
238 * Return: 0 on success or a negative error code on failure.
239 */
mipi_dsi_compression_mode(struct mipi_dsi_device * dsi,bool enable)240 ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
241 {
242 /* Note: Needs updating for non-default PPS or algorithm */
243 u8 tx[2] = { enable << 0, 0 };
244 struct mipi_dsi_msg msg = {
245 .channel = dsi->channel,
246 .type = MIPI_DSI_COMPRESSION_MODE,
247 .tx_len = sizeof(tx),
248 .tx_buf = tx,
249 };
250 int ret = mipi_dsi_device_transfer(dsi, &msg);
251
252 return (ret < 0) ? ret : 0;
253 }
254
255 /**
256 * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
257 * @dsi: DSI peripheral device
258 * @pps: VESA DSC 1.1 Picture Parameter Set
259 *
260 * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
261 *
262 * Return: 0 on success or a negative error code on failure.
263 */
mipi_dsi_picture_parameter_set(struct mipi_dsi_device * dsi,const struct drm_dsc_picture_parameter_set * pps)264 ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
265 const struct drm_dsc_picture_parameter_set *pps)
266 {
267 struct mipi_dsi_msg msg = {
268 .channel = dsi->channel,
269 .type = MIPI_DSI_PICTURE_PARAMETER_SET,
270 .tx_len = sizeof(*pps),
271 .tx_buf = pps,
272 };
273 int ret = mipi_dsi_device_transfer(dsi, &msg);
274
275 return (ret < 0) ? ret : 0;
276 }
277
278 /**
279 * mipi_dsi_generic_write() - transmit data using a generic write packet
280 * @dsi: DSI peripheral device
281 * @payload: buffer containing the payload
282 * @size: size of payload buffer
283 *
284 * This function will automatically choose the right data type depending on
285 * the payload length.
286 *
287 * Return: The number of bytes transmitted on success or a negative error code
288 * on failure.
289 */
mipi_dsi_generic_write(struct mipi_dsi_device * dsi,const void * payload,size_t size)290 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
291 size_t size)
292 {
293 struct mipi_dsi_msg msg = {
294 .channel = dsi->channel,
295 .tx_buf = payload,
296 .tx_len = size
297 };
298
299 switch (size) {
300 case 0:
301 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
302 break;
303 case 1:
304 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
305 break;
306 case 2:
307 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
308 break;
309 default:
310 msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
311 break;
312 }
313
314 return mipi_dsi_device_transfer(dsi, &msg);
315 }
316
317 /**
318 * mipi_dsi_generic_read() - receive data using a generic read packet
319 * @dsi: DSI peripheral device
320 * @params: buffer containing the request parameters
321 * @num_params: number of request parameters
322 * @data: buffer in which to return the received data
323 * @size: size of receive buffer
324 *
325 * This function will automatically choose the right data type depending on
326 * the number of parameters passed in.
327 *
328 * Return: The number of bytes successfully read or a negative error code on
329 * failure.
330 */
mipi_dsi_generic_read(struct mipi_dsi_device * dsi,const void * params,size_t num_params,void * data,size_t size)331 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
332 size_t num_params, void *data, size_t size)
333 {
334 struct mipi_dsi_msg msg = {
335 .channel = dsi->channel,
336 .tx_len = num_params,
337 .tx_buf = params,
338 .rx_len = size,
339 .rx_buf = data
340 };
341
342 switch (num_params) {
343 case 0:
344 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
345 break;
346
347 case 1:
348 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
349 break;
350
351 case 2:
352 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
353 break;
354
355 default:
356 return -EINVAL;
357 }
358
359 return mipi_dsi_device_transfer(dsi, &msg);
360 }
361
362 /**
363 * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
364 * @dsi: DSI peripheral device
365 * @data: buffer containing data to be transmitted
366 * @len: size of transmission buffer
367 *
368 * This function will automatically choose the right data type depending on
369 * the command payload length.
370 *
371 * Return: The number of bytes successfully transmitted or a negative error
372 * code on failure.
373 */
mipi_dsi_dcs_write_buffer(struct mipi_dsi_device * dsi,const void * data,size_t len)374 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
375 const void *data, size_t len)
376 {
377 struct mipi_dsi_msg msg = {
378 .channel = dsi->channel,
379 .tx_buf = data,
380 .tx_len = len
381 };
382
383 switch (len) {
384 case 0:
385 return -EINVAL;
386
387 case 1:
388 msg.type = MIPI_DSI_DCS_SHORT_WRITE;
389 break;
390
391 case 2:
392 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
393 break;
394
395 default:
396 msg.type = MIPI_DSI_DCS_LONG_WRITE;
397 break;
398 }
399
400 return mipi_dsi_device_transfer(dsi, &msg);
401 }
402
403 /**
404 * mipi_dsi_dcs_write() - send DCS write command
405 * @dsi: DSI peripheral device
406 * @cmd: DCS command
407 * @data: buffer containing the command payload
408 * @len: command payload length
409 *
410 * This function will automatically choose the right data type depending on
411 * the command payload length.
412 *
413 * Return: The number of bytes successfully transmitted or a negative error
414 * code on failure.
415 */
mipi_dsi_dcs_write(struct mipi_dsi_device * dsi,u8 cmd,const void * data,size_t len)416 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
417 const void *data, size_t len)
418 {
419 ssize_t err;
420 size_t size;
421 u8 *tx;
422
423 if (len > 0) {
424 size = 1 + len;
425
426 tx = malloc(size);
427 if (!tx)
428 return -ENOMEM;
429
430 /* concatenate the DCS command byte and the payload */
431 tx[0] = cmd;
432 memcpy(&tx[1], data, len);
433 } else {
434 tx = &cmd;
435 size = 1;
436 }
437
438 err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
439
440 if (len > 0)
441 free(tx);
442
443 return err;
444 }
445
446 /**
447 * mipi_dsi_dcs_read() - send DCS read request command
448 * @dsi: DSI peripheral device
449 * @cmd: DCS command
450 * @data: buffer in which to receive data
451 * @len: size of receive buffer
452 * Return: The number of bytes read or a negative error code on failure.
453 */
mipi_dsi_dcs_read(struct mipi_dsi_device * dsi,u8 cmd,void * data,size_t len)454 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
455 size_t len)
456 {
457 struct mipi_dsi_msg msg = {
458 .channel = dsi->channel,
459 .type = MIPI_DSI_DCS_READ,
460 .tx_buf = &cmd,
461 .tx_len = 1,
462 .rx_buf = data,
463 .rx_len = len
464 };
465
466 return mipi_dsi_device_transfer(dsi, &msg);
467 }
468
469 /**
470 * mipi_dsi_dcs_nop() - send DCS nop packet
471 * @dsi: DSI peripheral device
472 *
473 * Return: 0 on success or a negative error code on failure.
474 */
mipi_dsi_dcs_nop(struct mipi_dsi_device * dsi)475 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
476 {
477 ssize_t err;
478
479 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
480 if (err < 0)
481 return err;
482
483 return 0;
484 }
485
486 /**
487 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
488 * @dsi: DSI peripheral device
489 *
490 * Return: 0 on success or a negative error code on failure.
491 */
mipi_dsi_dcs_soft_reset(struct mipi_dsi_device * dsi)492 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
493 {
494 ssize_t err;
495
496 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
497 if (err < 0)
498 return err;
499
500 return 0;
501 }
502
503 /**
504 * mipi_dsi_dcs_get_power_mode() - query the display module's current power
505 * mode
506 * @dsi: DSI peripheral device
507 * @mode: return location for the current power mode
508 *
509 * Return: 0 on success or a negative error code on failure.
510 */
mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device * dsi,u8 * mode)511 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
512 {
513 ssize_t err;
514
515 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
516 sizeof(*mode));
517 if (err <= 0) {
518 if (err == 0)
519 err = -ENODATA;
520
521 return err;
522 }
523
524 return 0;
525 }
526
527 /**
528 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
529 * data used by the interface
530 * @dsi: DSI peripheral device
531 * @format: return location for the pixel format
532 *
533 * Return: 0 on success or a negative error code on failure.
534 */
mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device * dsi,u8 * format)535 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
536 {
537 ssize_t err;
538
539 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
540 sizeof(*format));
541 if (err <= 0) {
542 if (err == 0)
543 err = -ENODATA;
544
545 return err;
546 }
547
548 return 0;
549 }
550
551 /**
552 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
553 * display module except interface communication
554 * @dsi: DSI peripheral device
555 *
556 * Return: 0 on success or a negative error code on failure.
557 */
mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device * dsi)558 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
559 {
560 ssize_t err;
561
562 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
563 if (err < 0)
564 return err;
565
566 return 0;
567 }
568
569 /**
570 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
571 * module
572 * @dsi: DSI peripheral device
573 *
574 * Return: 0 on success or a negative error code on failure.
575 */
mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device * dsi)576 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
577 {
578 ssize_t err;
579
580 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
581 if (err < 0)
582 return err;
583
584 return 0;
585 }
586
587 /**
588 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
589 * display device
590 * @dsi: DSI peripheral device
591 *
592 * Return: 0 on success or a negative error code on failure.
593 */
mipi_dsi_dcs_set_display_off(struct mipi_dsi_device * dsi)594 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
595 {
596 ssize_t err;
597
598 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
599 if (err < 0)
600 return err;
601
602 return 0;
603 }
604
605 /**
606 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
607 * display device
608 * @dsi: DSI peripheral device
609 *
610 * Return: 0 on success or a negative error code on failure
611 */
mipi_dsi_dcs_set_display_on(struct mipi_dsi_device * dsi)612 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
613 {
614 ssize_t err;
615
616 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
617 if (err < 0)
618 return err;
619
620 return 0;
621 }
622
623 /**
624 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
625 * memory accessed by the host processor
626 * @dsi: DSI peripheral device
627 * @start: first column of frame memory
628 * @end: last column of frame memory
629 *
630 * Return: 0 on success or a negative error code on failure.
631 */
mipi_dsi_dcs_set_column_address(struct mipi_dsi_device * dsi,u16 start,u16 end)632 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
633 u16 end)
634 {
635 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
636 ssize_t err;
637
638 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
639 sizeof(payload));
640 if (err < 0)
641 return err;
642
643 return 0;
644 }
645
646 /**
647 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
648 * memory accessed by the host processor
649 * @dsi: DSI peripheral device
650 * @start: first page of frame memory
651 * @end: last page of frame memory
652 *
653 * Return: 0 on success or a negative error code on failure.
654 */
mipi_dsi_dcs_set_page_address(struct mipi_dsi_device * dsi,u16 start,u16 end)655 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
656 u16 end)
657 {
658 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
659 ssize_t err;
660
661 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
662 sizeof(payload));
663 if (err < 0)
664 return err;
665
666 return 0;
667 }
668
669 /**
670 * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
671 * output signal on the TE signal line
672 * @dsi: DSI peripheral device
673 *
674 * Return: 0 on success or a negative error code on failure
675 */
mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device * dsi)676 int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
677 {
678 ssize_t err;
679
680 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
681 if (err < 0)
682 return err;
683
684 return 0;
685 }
686
687 /**
688 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
689 * output signal on the TE signal line.
690 * @dsi: DSI peripheral device
691 * @mode: the Tearing Effect Output Line mode
692 *
693 * Return: 0 on success or a negative error code on failure
694 */
mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device * dsi,enum mipi_dsi_dcs_tear_mode mode)695 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
696 enum mipi_dsi_dcs_tear_mode mode)
697 {
698 u8 value = mode;
699 ssize_t err;
700
701 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
702 sizeof(value));
703 if (err < 0)
704 return err;
705
706 return 0;
707 }
708
709 /**
710 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
711 * data used by the interface
712 * @dsi: DSI peripheral device
713 * @format: pixel format
714 *
715 * Return: 0 on success or a negative error code on failure.
716 */
mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device * dsi,u8 format)717 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
718 {
719 ssize_t err;
720
721 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
722 sizeof(format));
723 if (err < 0)
724 return err;
725
726 return 0;
727 }
728
729 /**
730 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
731 * the Tearing Effect output signal of the display module
732 * @dsi: DSI peripheral device
733 * @scanline: scanline to use as trigger
734 *
735 * Return: 0 on success or a negative error code on failure
736 */
mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device * dsi,u16 scanline)737 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
738 {
739 u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8,
740 scanline & 0xff };
741 ssize_t err;
742
743 err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
744 if (err < 0)
745 return err;
746
747 return 0;
748 }
749
750 /**
751 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
752 * display
753 * @dsi: DSI peripheral device
754 * @brightness: brightness value
755 *
756 * Return: 0 on success or a negative error code on failure.
757 */
mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device * dsi,u16 brightness)758 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
759 u16 brightness)
760 {
761 u8 payload[2] = { brightness & 0xff, brightness >> 8 };
762 ssize_t err;
763
764 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
765 payload, sizeof(payload));
766 if (err < 0)
767 return err;
768
769 return 0;
770 }
771
772 /**
773 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
774 * of the display
775 * @dsi: DSI peripheral device
776 * @brightness: brightness value
777 *
778 * Return: 0 on success or a negative error code on failure.
779 */
mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device * dsi,u16 * brightness)780 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
781 u16 *brightness)
782 {
783 ssize_t err;
784
785 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
786 brightness, sizeof(*brightness));
787 if (err <= 0) {
788 if (err == 0)
789 err = -ENODATA;
790
791 return err;
792 }
793
794 return 0;
795 }
796