1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_display.h"
9 #include "fsl_hx8394.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 #define HX8394_DelayMs VIDEO_DelayMs
15
16 typedef struct
17 {
18 const uint8_t *cmd;
19 uint8_t cmdLen;
20 } hx8394_cmd_t;
21
22 /*******************************************************************************
23 * Variables
24 ******************************************************************************/
25 const display_operations_t hx8394_ops = {
26 .init = HX8394_Init,
27 .deinit = HX8394_Deinit,
28 .start = HX8394_Start,
29 .stop = HX8394_Stop,
30 };
31
32 static const hx8394_cmd_t s_hx8394Cmds[] = {
33 {(const uint8_t[]){0x36U, 0x02U}, 2U},
34
35 {(const uint8_t[]){0xB1U, 0x48U, 0x12U, 0x72U, 0x09U, 0x32U, 0x54U, 0x71U, 0x71U, 0x57U, 0x47U}, 11U},
36
37 {(const uint8_t[]){0xB2U, 0x00U, 0x80U, 0x64U, 0x0CU, 0x0DU, 0x2FU}, 7U},
38
39 {(const uint8_t[]){0xB4U, 0x73U, 0x74U, 0x73U, 0x74U, 0x73U, 0x74U, 0x01U, 0x0CU, 0x86U, /* 10 */
40 0x75U, 0x00U, 0x3FU, 0x73U, 0x74U, 0x73U, 0x74U, 0x73U, 0x74U, 0x01U, /* 20 */
41 0x0CU, 0x86U},
42 22U},
43
44 {(const uint8_t[]){0xD3U, 0x00U, 0x00U, 0x07U, 0x07U, 0x40U, 0x07U, 0x0CU, 0x00U, 0x08U, /* 10 */
45 0x10U, 0x08U, 0x00U, 0x08U, 0x54U, 0x15U, 0x0AU, 0x05U, 0x0AU, 0x02U, /* 20 */
46 0x15U, 0x06U, 0x05U, 0x06U, 0x47U, 0x44U, 0x0AU, 0x0AU, 0x4BU, 0x10U, /* 30 */
47 0x07U, 0x07U, 0x0CU, 0x40U},
48 34U},
49
50 {(const uint8_t[]){0xD5U, 0x1CU, 0x1CU, 0x1DU, 0x1DU, 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, /* 10 */
51 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0AU, 0x0BU, 0x24U, 0x25U, 0x18U, /* 20 */
52 0x18U, 0x26U, 0x27U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, /* 30 */
53 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x20U, /* 40 */
54 0x21U, 0x18U, 0x18U, 0x18U, 0x18U},
55 45U},
56
57 {(const uint8_t[]){0xD6U, 0x1CU, 0x1CU, 0x1DU, 0x1DU, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, /* 10 */
58 0x02U, 0x01U, 0x00U, 0x0BU, 0x0AU, 0x09U, 0x08U, 0x21U, 0x20U, 0x18U, /* 20 */
59 0x18U, 0x27U, 0x26U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, /* 30 */
60 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x25U, /* 40 */
61 0x24U, 0x18U, 0x18U, 0x18U, 0x18U},
62 45U},
63
64 {(const uint8_t[]){0xB6U, 0x92U, 0x92U}, 3U},
65
66 {(const uint8_t[]){0xE0U, 0x00U, 0x0AU, 0x15U, 0x1BU, 0x1EU, 0x21U, 0x24U, 0x22U, 0x47U, /* 10 */
67 0x56U, 0x65U, 0x66U, 0x6EU, 0x82U, 0x88U, 0x8BU, 0x9AU, 0x9DU, 0x98U, /* 20 */
68 0xA8U, 0xB9U, 0x5DU, 0x5CU, 0x61U, 0x66U, 0x6AU, 0x6FU, 0x7FU, 0x7FU, /* 30 */
69 0x00U, 0x0AU, 0x15U, 0x1BU, 0x1EU, 0x21U, 0x24U, 0x22U, 0x47U, 0x56U, /* 40 */
70 0x65U, 0x65U, 0x6EU, 0x81U, 0x87U, 0x8BU, 0x98U, 0x9DU, 0x99U, 0xA8U, /* 50 */
71 0xBAU, 0x5DU, 0x5DU, 0x62U, 0x67U, 0x6BU, 0x72U, 0x7FU, 0x7FU},
72 59U},
73
74 {(const uint8_t[]){0xC0U, 0x1FU, 0x31U}, 3U},
75 {(const uint8_t[]){0xCCU, 0x03U}, 2U},
76 {(const uint8_t[]){0xD4U, 0x02U}, 2U},
77 {(const uint8_t[]){0xBDU, 0x02U}, 2U},
78
79 {(const uint8_t[]){0xD8U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, /* 10 */
80 0xFFU, 0xFFU, 0xFFU},
81 13U},
82
83 {(const uint8_t[]){0xBDU, 0x00U}, 2U},
84 {(const uint8_t[]){0xBDU, 0x01U}, 2U},
85 {(const uint8_t[]){0xB1U, 0x00U}, 2U},
86 {(const uint8_t[]){0xBDU, 0x00U}, 2U},
87
88 {(const uint8_t[]){0xBFU, 0x40U, 0x81U, 0x50U, 0x00U, 0x1AU, 0xFCU, 0x01}, 8U},
89
90 {(const uint8_t[]){0xC6U, 0xEDU}, 2U},
91
92 {(const uint8_t[]){0x35U, 0x00U}, 2U},
93 };
94
95 /*******************************************************************************
96 * Code
97 ******************************************************************************/
98
HX8394_Init(display_handle_t * handle,const display_config_t * config)99 status_t HX8394_Init(display_handle_t *handle, const display_config_t *config)
100 {
101 uint8_t i;
102 status_t status = kStatus_Success;
103 const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
104 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
105 uint8_t setmipi[7] = {0xBAU, 0x60U, 0x03U, 0x68U, 0x6BU, 0xB2U, 0xC0U};
106
107 /* Only support 720 * 1280 */
108 if (config->resolution != FSL_VIDEO_RESOLUTION(720, 1280))
109 {
110 return kStatus_InvalidArgument;
111 }
112
113 /* Power on. */
114 resource->pullPowerPin(true);
115 HX8394_DelayMs(1);
116
117 /* Perform reset. */
118 resource->pullResetPin(false);
119 HX8394_DelayMs(1);
120 resource->pullResetPin(true);
121 HX8394_DelayMs(50U);
122
123 status = MIPI_DSI_GenericWrite(dsiDevice, (const uint8_t[]){0xB9U, 0xFFU, 0x83U, 0x94U}, 4);
124
125 setmipi[1] |= (config->dsiLanes - 1U);
126
127 if (kStatus_Success == status)
128 {
129 status = MIPI_DSI_GenericWrite(dsiDevice, setmipi, 7);
130 }
131
132 if (kStatus_Success == status)
133 {
134 for (i = 0; i < ARRAY_SIZE(s_hx8394Cmds); i++)
135 {
136 status = MIPI_DSI_GenericWrite(dsiDevice, s_hx8394Cmds[i].cmd, (int32_t)s_hx8394Cmds[i].cmdLen);
137
138 if (kStatus_Success != status)
139 {
140 break;
141 }
142 }
143 }
144
145 if (kStatus_Success == status)
146 {
147 status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, false);
148 }
149
150 if (kStatus_Success == status)
151 {
152 HX8394_DelayMs(120U);
153
154 status = MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
155 }
156
157 return status;
158 }
159
HX8394_Deinit(display_handle_t * handle)160 status_t HX8394_Deinit(display_handle_t *handle)
161 {
162 const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
163 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
164
165 (void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
166
167 resource->pullResetPin(false);
168 resource->pullPowerPin(false);
169
170 return kStatus_Success;
171 }
172
HX8394_Start(display_handle_t * handle)173 status_t HX8394_Start(display_handle_t *handle)
174 {
175 const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
176 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
177
178 return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
179 }
180
HX8394_Stop(display_handle_t * handle)181 status_t HX8394_Stop(display_handle_t *handle)
182 {
183 const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
184 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
185
186 return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
187 }
188