aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/driver_display-adv7535.cmake23
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.c274
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.h63
3 files changed, 360 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/driver_display-adv7535.cmake b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/driver_display-adv7535.cmake
new file mode 100644
index 000000000..6c9425aba
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/driver_display-adv7535.cmake
@@ -0,0 +1,23 @@
1if(NOT DRIVER_DISPLAY-ADV7535_INCLUDED)
2
3 set(DRIVER_DISPLAY-ADV7535_INCLUDED true CACHE BOOL "driver_display-adv7535 component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 ${CMAKE_CURRENT_LIST_DIR}/fsl_adv7535.c
7 )
8
9 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
10 ${CMAKE_CURRENT_LIST_DIR}/.
11 )
12
13 #OR Logic component
14 if(${MCUX_DEVICE} STREQUAL "MIMX8QM6_cm4_core1")
15 include(driver_video-i2c)
16 endif()
17 if(${MCUX_DEVICE} STREQUAL "MIMX8QX6")
18 include(driver_video-i2c)
19 endif()
20
21 include(driver_common)
22
23endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.c b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.c
new file mode 100644
index 000000000..40b81c25d
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.c
@@ -0,0 +1,274 @@
1/*
2 * Copyright 2017-2018, 2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#include "fsl_video_common.h"
10#include "fsl_display.h"
11#include "fsl_adv7535.h"
12
13/*******************************************************************************
14 * Definitions
15 ******************************************************************************/
16#define ADV7535_CHIP_REVISION 0x14U
17
18#define ADV7535_DSI_CEC_ADDR (0x78U >> 1)
19
20#define ADV7535_I2C_WriteReg(handle, addr, reg, value) \
21 VIDEO_I2C_WriteReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, (value), \
22 ((const adv7535_resource_t *)((handle)->resource))->i2cSendFunc)
23
24#define ADV7535_I2C_ReadReg(handle, addr, reg, value) \
25 VIDEO_I2C_ReadReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, (value), \
26 ((const adv7535_resource_t *)((handle)->resource))->i2cReceiveFunc)
27
28#define ADV7535_I2C_ModifyReg(handle, addr, reg, mask, value) \
29 VIDEO_I2C_ModifyReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, mask, (value), \
30 ((const adv7535_resource_t *)((handle)->resource))->i2cReceiveFunc, \
31 ((const adv7535_resource_t *)((handle)->resource))->i2cSendFunc)
32
33#define ADV7535_CHECK_RET(x) \
34 do \
35 { \
36 status = (x); \
37 if (kStatus_Success != status) \
38 { \
39 return status; \
40 } \
41 } while (false)
42
43typedef struct _adv7533_reg_val
44{
45 uint8_t reg; /* Register index. */
46 uint8_t mask; /* Mask of the value. */
47 uint8_t value; /* Register value. */
48} adv7533_reg_val_t;
49
50/*******************************************************************************
51 * Variables
52 ******************************************************************************/
53static const adv7533_reg_val_t s_adv7533FixedRegs[] = {
54 /* Fixed registers that must be set on power up. */
55 /* 0x16[5:1] = 0b10000 */
56 {0x16U, (0x1FU << 1U), (0x10U << 1)},
57
58 /* 0x9A = 0xE0 */
59 {0x9AU, 0xFF, 0x0E},
60
61 /* 0xBA[7:3] = 0b01110 */
62 {0xBAU, (0x1FU << 3U), (0x0EU << 3U)},
63
64 /* 0xDE = 0x82 */
65 {0xDEU, 0xFF, 0x82},
66
67 /* 0xE4[6] = 1 */
68 {0xE4U, (1 << 6), (1 << 6)},
69
70 /* 0xE5 = 0x80 */
71 {0xE5U, 0xFF, 0x80},
72};
73
74static const adv7533_reg_val_t s_adv7533CecFixedRegs[] = {
75 /* CEC memory 0x15[5:4] = 1 */
76 {0x15U, (3U << 4U), (1 << 4)},
77
78 /* CEC memory 0x17[7:4] = 0b1101 */
79 {0x17U, (0xFU << 4U), (0x0D << 4U)},
80
81 /* CEC memory 0x24[4] = 0 */
82 {0x24U, (1 << 4U), (0x0 << 4U)},
83
84 /* CEC memory 0x57[0] = 1 */
85 {0x57U, (1 << 0U), (0x1 << 0U)},
86
87 /* CEC memory 0x57[4] = 1 */
88 {0x57U, (1 << 4U), (0x1 << 4U)},
89};
90
91const display_operations_t adv7535_ops = {
92 .init = ADV7535_Init,
93 .deinit = ADV7535_Deinit,
94 .start = ADV7535_Start,
95 .stop = ADV7535_Stop,
96};
97
98/*******************************************************************************
99 * Code
100 ******************************************************************************/
101
102static status_t ADV7535_I2C_ModifyRegs(display_handle_t *handle,
103 uint8_t i2cAddr,
104 const adv7533_reg_val_t values[],
105 uint32_t len)
106{
107 status_t status = kStatus_Success;
108
109 for (uint32_t i = 0; i < len; i++)
110 {
111 status = ADV7535_I2C_ModifyReg(handle, i2cAddr, values[i].reg, values[i].mask, values[i].value);
112
113 if (kStatus_Success != status)
114 {
115 return status;
116 }
117 }
118
119 return status;
120}
121
122status_t ADV7535_Init(display_handle_t *handle, const display_config_t *config)
123{
124 uint8_t chipRevision = 0U;
125 uint8_t mainI2cAddr = (((const adv7535_resource_t *)(handle->resource))->i2cAddr);
126 status_t status;
127
128 uint8_t lanes = config->dsiLanes;
129 uint16_t total_width, total_height;
130
131 if ((lanes <= 1U) || (lanes > 4U))
132 {
133 return kStatus_InvalidArgument;
134 }
135
136 /* Identify the device. */
137 status = ADV7535_I2C_ReadReg(handle, mainI2cAddr, 0x00, &chipRevision);
138
139 if (kStatus_Success != status)
140 {
141 return status;
142 }
143
144 if (ADV7535_CHIP_REVISION != chipRevision)
145 {
146 return kStatus_Fail;
147 }
148
149 /* -------- Power up sequence. -------- */
150 /* 0x41[6] - HDMI Power-down (Power Up = 0 HPD Must be High). */
151 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0x41, (0x01U << 6U), 0U << 6));
152
153 /* 0xD6[6] - HPD Override (Override = 1). */
154 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0xD6, (0x01U << 6U), 1U << 6));
155
156 /*
157 * DSI and CEC Map: 0x03[1] - Gate DSI LP Oscillator and DSI Bias Clock Powerdown, set to 0
158 * to enable normal operation
159 */
160 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x03, (0x01U << 1U), 0U << 1));
161
162 ADV7535_CHECK_RET(ADV7535_I2C_ModifyRegs(handle, mainI2cAddr, s_adv7533FixedRegs, ARRAY_SIZE(s_adv7533FixedRegs)));
163
164 status =
165 ADV7535_I2C_ModifyRegs(handle, ADV7535_DSI_CEC_ADDR, s_adv7533CecFixedRegs, ARRAY_SIZE(s_adv7533CecFixedRegs));
166 if (kStatus_Success != status)
167 {
168 return status;
169 }
170
171 /* -------- Configure the video timing. --------*/
172
173 /* Mute the HDMI. */
174 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0xd5, 1U << 0, 1U << 0));
175
176 /* Use automatic pixel clock divider: 0x16[2] = 0 */
177 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x16, (0x01U << 2U), 0U << 2));
178
179 /* MIPI DSI lanes: 0x1c[4:6]. */
180 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x1c, (0x07U << 4U), (uint32_t)lanes << 4));
181
182 /* Use internal timing generator, first disable it then configure: 0x27[7] = 1 */
183 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x27, (0x01U << 7U), 1U << 7));
184
185 /* Total width. */
186 total_width = FSL_VIDEO_EXTRACT_WIDTH(config->resolution) + config->hfp + config->hbp + config->hsw;
187 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x28, (uint8_t)(total_width >> 4U)));
188 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x29, (uint8_t)(total_width << 4U)));
189
190 /* HSW. */
191 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2A, (uint8_t)(config->hsw >> 4U)));
192 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2B, (uint8_t)(config->hsw << 4U)));
193
194 /* HFP. */
195 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2C, (uint8_t)(config->hfp >> 4U)));
196 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2D, (uint8_t)(config->hfp << 4U)));
197
198 /* HBP. */
199 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2E, (uint8_t)(config->hbp >> 4U)));
200 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x2F, (uint8_t)(config->hbp << 4U)));
201
202 /* Total height. */
203 total_height = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution) + config->vfp + config->vbp + config->vsw;
204 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x30, (uint8_t)(total_height >> 4U)));
205 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x31, (uint8_t)(total_height << 4U)));
206
207 /* VSW. */
208 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x32, (uint8_t)(config->vsw >> 4U)));
209 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x33, (uint8_t)(config->vsw << 4U)));
210
211 /* VFP. */
212 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x34, (uint8_t)(config->vfp >> 4U)));
213 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x35, (uint8_t)(config->vfp << 4U)));
214
215 /* VBP. */
216 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x36, (uint8_t)(config->vbp >> 4U)));
217 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x37, (uint8_t)(config->vbp << 4U)));
218
219 /* Toggle the 0x27[6] to use the new timing parameter. */
220 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x27, (0x01U << 6U), 1U << 6));
221 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x27, (0x01U << 6U), 0U << 6));
222 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x27, (0x01U << 6U), 1U << 6));
223
224 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0xd5, 1U << 0, 0U << 0));
225
226 /* ----------- HDMI output. ----------- */
227 /* 0xAF[1] - HDMI/DVI Mode Select (HDMI = 1) */
228 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0xAF, (0x01U << 1U), 1U << 1));
229
230 /* Disable the test pattern. */
231 ADV7535_CHECK_RET(ADV7535_I2C_WriteReg(handle, ADV7535_DSI_CEC_ADDR, 0x55, 0x00));
232
233 /* 0x40[7] - GC Packet Enable (Enable = 1) */
234 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0x40, (0x01U << 7U), 1U << 7));
235
236 /*
237 * 0x4C[3:0] Color depth of video to RX.
238 * 0000 = color depth not indicated
239 * 0100 = 24 bits per pixel
240 * 0101 = 30 bits per pixel
241 * 0110 = 36 bits per pixel
242 *
243 * Here use 24 bpp
244 */
245 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0x4C, (0x0FU << 0U), 4U << 0));
246
247 /* 0x49[1:0] - Down Dither Output Color Depth (12 bits = 0b10) */
248 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0x49, (0x03U << 0U), 2U << 0));
249
250 /* DSI and CEC Map: 0x03[7] - HDMI Output Enable (Enable = 1) */
251 ADV7535_CHECK_RET(ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x03, (0x01U << 7U), 1U << 7));
252
253 return kStatus_Success;
254}
255
256status_t ADV7535_Deinit(display_handle_t *handle)
257{
258 uint8_t mainI2cAddr = (((const adv7535_resource_t *)(handle->resource))->i2cAddr);
259
260 /* 0x41[6] - HDMI Power-down */
261 return ADV7535_I2C_ModifyReg(handle, mainI2cAddr, 0x41, (0x01U << 6U), 1U << 6);
262}
263
264status_t ADV7535_Start(display_handle_t *handle)
265{
266 /* DSI and CEC Map: 0x03[7] - HDMI Output Enable (Enable = 1) */
267 return ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x03, (0x01U << 7U), 1U << 7);
268}
269
270status_t ADV7535_Stop(display_handle_t *handle)
271{
272 /* DSI and CEC Map: 0x03[7] - HDMI Output Enable (Enable = 1) */
273 return ADV7535_I2C_ModifyReg(handle, ADV7535_DSI_CEC_ADDR, 0x03, (0x01U << 7U), 0U << 7);
274}
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.h b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.h
new file mode 100644
index 000000000..d84c762bf
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/adv7535/fsl_adv7535.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2017-2018, 2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#ifndef _FSL_ADV7535_H_
10#define _FSL_ADV7535_H_
11
12#include "fsl_common.h"
13#include "fsl_video_i2c.h"
14
15/*
16 * Change log:
17 *
18 * 1.0.1
19 * - Fix MISRA-C 2012 issues.
20 *
21 * 1.0.0
22 * - Initial version
23 */
24
25/*******************************************************************************
26 * Definitions
27 ******************************************************************************/
28
29/*!
30 * @brief ADV7535 resource.
31 *
32 * The I2C instance should be initialized before calling @ref ADV7535_Init.
33 */
34typedef struct _adv7535_resource
35{
36 video_i2c_send_func_t i2cSendFunc; /* I2C send function. */
37 video_i2c_receive_func_t i2cReceiveFunc; /* I2C receive function. */
38 uint8_t i2cAddr; /* I2C address for the main memory. */
39} adv7535_resource_t;
40
41extern const display_operations_t adv7535_ops;
42
43/*******************************************************************************
44 * API
45 ******************************************************************************/
46
47#if defined(__cplusplus)
48extern "C" {
49#endif
50
51status_t ADV7535_Init(display_handle_t *handle, const display_config_t *config);
52
53status_t ADV7535_Deinit(display_handle_t *handle);
54
55status_t ADV7535_Start(display_handle_t *handle);
56
57status_t ADV7535_Stop(display_handle_t *handle);
58
59#if defined(__cplusplus)
60}
61#endif
62
63#endif /* _FSL_ADV7535_H_ */