summaryrefslogtreecommitdiff
path: root/src/drivers/mipi/panel.c
blob: 9646ecaa863558649d3b0598b3333fe2f8a5a3a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <delay.h>
#include <mipi/panel.h>

enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func)
{
	const struct panel_init_command *init = buf;
	enum mipi_dsi_transaction type;

	/*
	 * The given commands should be in a buffer containing a packed array of
	 * panel_init_command and each element may be in variable size so we have
	 * to parse and scan.
	 */

	for (; init->cmd != PANEL_CMD_END; init = (const void *)buf) {
		/*
		 * For some commands like DELAY, the init->len should not be
		 * counted for buf.
		 */
		buf += sizeof(*init);

		u32 cmd = init->cmd, len = init->len;

		if (cmd == PANEL_CMD_DELAY) {
			mdelay(len);
			continue;
		}

		switch (cmd) {
		case PANEL_CMD_DCS:
			switch (len) {
			case 0:
				printk(BIOS_ERR, "%s: DCS command length 0?\n", __func__);
				return CB_ERR;
			case 1:
				type = MIPI_DSI_DCS_SHORT_WRITE;
				break;
			case 2:
				type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
				break;
			default:
				type = MIPI_DSI_DCS_LONG_WRITE;
				break;
			}
			break;
		case PANEL_CMD_GENERIC:
			switch (len) {
			case 0:
				type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
				break;
			case 1:
				type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
				break;
			case 2:
				type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
				break;
			default:
				type = MIPI_DSI_GENERIC_LONG_WRITE;
				break;
			}
			break;
		default:
			printk(BIOS_ERR, "%s: Unknown command code: %d, "
			       "abort panel initialization.\n", __func__, cmd);
			return CB_ERR;
		}

		enum cb_err ret = cmd_func(type, init->data, len);
		if (ret != CB_SUCCESS)
			return ret;
		buf += len;
	}

	return CB_SUCCESS;
}