1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_common.h"
10 #include "fsl_flexcomm.h"
11
12 /*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16 /* Component ID definition, used by tools. */
17 #ifndef FSL_COMPONENT_ID
18 #define FSL_COMPONENT_ID "platform.drivers.flexcomm"
19 #endif
20
21 /*******************************************************************************
22 * Prototypes
23 ******************************************************************************/
24 /*! @brief Set the FLEXCOMM mode . */
25 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
26
27 /*! @brief check whether flexcomm supports peripheral type */
28 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
29
30 /*******************************************************************************
31 * Variables
32 ******************************************************************************/
33
34 /*! @brief Array to map FLEXCOMM instance number to base address. */
35 static const uint32_t s_flexcommBaseAddrs[] = FLEXCOMM_BASE_ADDRS;
36
37 /*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
38 static flexcomm_irq_handler_t s_flexcommIrqHandler[ARRAY_SIZE(s_flexcommBaseAddrs)];
39
40 /*! @brief Pointers to handles for each instance to provide context to interrupt routines */
41 static void *s_flexcommHandle[ARRAY_SIZE(s_flexcommBaseAddrs)];
42
43 /*! @brief Array to map FLEXCOMM instance number to IRQ number. */
44 IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
45
46 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
47 /*! @brief IDs of clock for each FLEXCOMM module */
48 static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
49 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
50
51 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
52 /*! @brief Pointers to FLEXCOMM resets for each instance. */
53 static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
54 #endif
55
56 /*******************************************************************************
57 * Code
58 ******************************************************************************/
59
60 /* check whether flexcomm supports peripheral type */
FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type * base,FLEXCOMM_PERIPH_T periph)61 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
62 {
63 if (periph == FLEXCOMM_PERIPH_NONE)
64 {
65 return true;
66 }
67 else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
68 {
69 return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;
70 }
71 else if (periph == FLEXCOMM_PERIPH_I2S_RX)
72 {
73 return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;
74 }
75 else
76 {
77 return false;
78 }
79 }
80
81 /* Get the index corresponding to the FLEXCOMM */
82 /*! brief Returns instance number for FLEXCOMM module with given base address. */
FLEXCOMM_GetInstance(void * base)83 uint32_t FLEXCOMM_GetInstance(void *base)
84 {
85 uint32_t i;
86
87 for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
88 {
89 if ((uintptr_t)(uint8_t*)base == s_flexcommBaseAddrs[i])
90 {
91 break;
92 }
93 }
94
95 assert(i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT);
96 return i;
97 }
98
99 /* Changes FLEXCOMM mode */
FLEXCOMM_SetPeriph(FLEXCOMM_Type * base,FLEXCOMM_PERIPH_T periph,int lock)100 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
101 {
102 /* Check whether peripheral type is present */
103 if (!FLEXCOMM_PeripheralIsPresent(base, periph))
104 {
105 return kStatus_OutOfRange;
106 }
107
108 /* Flexcomm is locked to different peripheral type than expected */
109 if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&
110 ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))
111 {
112 return kStatus_Fail;
113 }
114
115 /* Check if we are asked to lock */
116 if (lock != 0)
117 {
118 base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
119 }
120 else
121 {
122 base->PSELID = (uint32_t)periph;
123 }
124
125 return kStatus_Success;
126 }
127
128 /*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
FLEXCOMM_Init(void * base,FLEXCOMM_PERIPH_T periph)129 status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
130 {
131 uint32_t idx = FLEXCOMM_GetInstance(base);
132
133 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
134 /* Enable the peripheral clock */
135 CLOCK_EnableClock(s_flexcommClocks[idx]);
136 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
137
138 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
139 /* Reset the FLEXCOMM module */
140 RESET_PeripheralReset(s_flexcommResets[idx]);
141 #endif
142
143 /* Set the FLEXCOMM to given peripheral */
144 return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
145 }
146
147 /*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
148 * mode */
FLEXCOMM_SetIRQHandler(void * base,flexcomm_irq_handler_t handler,void * flexcommHandle)149 void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle)
150 {
151 uint32_t instance;
152
153 /* Look up instance number */
154 instance = FLEXCOMM_GetInstance(base);
155
156 /* Clear handler first to avoid execution of the handler with wrong handle */
157 s_flexcommIrqHandler[instance] = NULL;
158 s_flexcommHandle[instance] = flexcommHandle;
159 s_flexcommIrqHandler[instance] = handler;
160 SDK_ISR_EXIT_BARRIER;
161 }
162
163 /* IRQ handler functions overloading weak symbols in the startup */
164 #if defined(FLEXCOMM0)
165 void FLEXCOMM0_DriverIRQHandler(void);
FLEXCOMM0_DriverIRQHandler(void)166 void FLEXCOMM0_DriverIRQHandler(void)
167 {
168 uint32_t instance;
169
170 /* Look up instance number */
171 instance = FLEXCOMM_GetInstance(FLEXCOMM0);
172 assert(s_flexcommIrqHandler[instance] != NULL);
173 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
174 SDK_ISR_EXIT_BARRIER;
175 }
176 #endif
177
178 #if defined(FLEXCOMM1)
179 void FLEXCOMM1_DriverIRQHandler(void);
FLEXCOMM1_DriverIRQHandler(void)180 void FLEXCOMM1_DriverIRQHandler(void)
181 {
182 uint32_t instance;
183
184 /* Look up instance number */
185 instance = FLEXCOMM_GetInstance(FLEXCOMM1);
186 assert(s_flexcommIrqHandler[instance] != NULL);
187 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
188 SDK_ISR_EXIT_BARRIER;
189 }
190 #endif
191
192 #if defined(FLEXCOMM2)
193 void FLEXCOMM2_DriverIRQHandler(void);
FLEXCOMM2_DriverIRQHandler(void)194 void FLEXCOMM2_DriverIRQHandler(void)
195 {
196 uint32_t instance;
197
198 /* Look up instance number */
199 instance = FLEXCOMM_GetInstance(FLEXCOMM2);
200 assert(s_flexcommIrqHandler[instance] != NULL);
201 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
202 SDK_ISR_EXIT_BARRIER;
203 }
204 #endif
205
206 #if defined(FLEXCOMM3)
207 void FLEXCOMM3_DriverIRQHandler(void);
FLEXCOMM3_DriverIRQHandler(void)208 void FLEXCOMM3_DriverIRQHandler(void)
209 {
210 uint32_t instance;
211
212 /* Look up instance number */
213 instance = FLEXCOMM_GetInstance(FLEXCOMM3);
214 assert(s_flexcommIrqHandler[instance] != NULL);
215 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
216 SDK_ISR_EXIT_BARRIER;
217 }
218 #endif
219
220 #if defined(FLEXCOMM4)
221 void FLEXCOMM4_DriverIRQHandler(void);
FLEXCOMM4_DriverIRQHandler(void)222 void FLEXCOMM4_DriverIRQHandler(void)
223 {
224 uint32_t instance;
225
226 /* Look up instance number */
227 instance = FLEXCOMM_GetInstance(FLEXCOMM4);
228 assert(s_flexcommIrqHandler[instance] != NULL);
229 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
230 SDK_ISR_EXIT_BARRIER;
231 }
232
233 #endif
234
235 #if defined(FLEXCOMM5)
236 void FLEXCOMM5_DriverIRQHandler(void);
FLEXCOMM5_DriverIRQHandler(void)237 void FLEXCOMM5_DriverIRQHandler(void)
238 {
239 uint32_t instance;
240
241 /* Look up instance number */
242 instance = FLEXCOMM_GetInstance(FLEXCOMM5);
243 assert(s_flexcommIrqHandler[instance] != NULL);
244 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
245 SDK_ISR_EXIT_BARRIER;
246 }
247 #endif
248
249 #if defined(FLEXCOMM6)
250 void FLEXCOMM6_DriverIRQHandler(void);
FLEXCOMM6_DriverIRQHandler(void)251 void FLEXCOMM6_DriverIRQHandler(void)
252 {
253 uint32_t instance;
254
255 /* Look up instance number */
256 instance = FLEXCOMM_GetInstance(FLEXCOMM6);
257 assert(s_flexcommIrqHandler[instance] != NULL);
258 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
259 SDK_ISR_EXIT_BARRIER;
260 }
261 #endif
262
263 #if defined(FLEXCOMM7)
264 void FLEXCOMM7_DriverIRQHandler(void);
FLEXCOMM7_DriverIRQHandler(void)265 void FLEXCOMM7_DriverIRQHandler(void)
266 {
267 uint32_t instance;
268
269 /* Look up instance number */
270 instance = FLEXCOMM_GetInstance(FLEXCOMM7);
271 assert(s_flexcommIrqHandler[instance] != NULL);
272 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
273 SDK_ISR_EXIT_BARRIER;
274 }
275 #endif
276
277 #if defined(FLEXCOMM8)
278 void FLEXCOMM8_DriverIRQHandler(void);
FLEXCOMM8_DriverIRQHandler(void)279 void FLEXCOMM8_DriverIRQHandler(void)
280 {
281 uint32_t instance;
282
283 /* Look up instance number */
284 instance = FLEXCOMM_GetInstance(FLEXCOMM8);
285 assert(s_flexcommIrqHandler[instance] != NULL);
286 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
287 SDK_ISR_EXIT_BARRIER;
288 }
289 #endif
290
291 #if defined(FLEXCOMM9)
292 void FLEXCOMM9_DriverIRQHandler(void);
FLEXCOMM9_DriverIRQHandler(void)293 void FLEXCOMM9_DriverIRQHandler(void)
294 {
295 uint32_t instance;
296
297 /* Look up instance number */
298 instance = FLEXCOMM_GetInstance(FLEXCOMM9);
299 assert(s_flexcommIrqHandler[instance] != NULL);
300 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
301 SDK_ISR_EXIT_BARRIER;
302 }
303 #endif
304
305 #if defined(FLEXCOMM10)
306 void FLEXCOMM10_DriverIRQHandler(void);
FLEXCOMM10_DriverIRQHandler(void)307 void FLEXCOMM10_DriverIRQHandler(void)
308 {
309 uint32_t instance;
310
311 /* Look up instance number */
312 instance = FLEXCOMM_GetInstance(FLEXCOMM10);
313 assert(s_flexcommIrqHandler[instance] != NULL);
314 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
315 SDK_ISR_EXIT_BARRIER;
316 }
317 #endif
318
319 #if defined(FLEXCOMM11)
320 void FLEXCOMM11_DriverIRQHandler(void);
FLEXCOMM11_DriverIRQHandler(void)321 void FLEXCOMM11_DriverIRQHandler(void)
322 {
323 uint32_t instance;
324
325 /* Look up instance number */
326 instance = FLEXCOMM_GetInstance(FLEXCOMM11);
327 assert(s_flexcommIrqHandler[instance] != NULL);
328 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
329 SDK_ISR_EXIT_BARRIER;
330 }
331 #endif
332
333 #if defined(FLEXCOMM12)
334 void FLEXCOMM12_DriverIRQHandler(void);
FLEXCOMM12_DriverIRQHandler(void)335 void FLEXCOMM12_DriverIRQHandler(void)
336 {
337 uint32_t instance;
338
339 /* Look up instance number */
340 instance = FLEXCOMM_GetInstance(FLEXCOMM12);
341 assert(s_flexcommIrqHandler[instance] != NULL);
342 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
343 SDK_ISR_EXIT_BARRIER;
344 }
345 #endif
346
347 #if defined(FLEXCOMM13)
348 void FLEXCOMM13_DriverIRQHandler(void);
FLEXCOMM13_DriverIRQHandler(void)349 void FLEXCOMM13_DriverIRQHandler(void)
350 {
351 uint32_t instance;
352
353 /* Look up instance number */
354 instance = FLEXCOMM_GetInstance(FLEXCOMM13);
355 assert(s_flexcommIrqHandler[instance] != NULL);
356 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
357 SDK_ISR_EXIT_BARRIER;
358 }
359 #endif
360
361 #if defined(FLEXCOMM14)
362 void FLEXCOMM14_DriverIRQHandler(void);
FLEXCOMM14_DriverIRQHandler(void)363 void FLEXCOMM14_DriverIRQHandler(void)
364 {
365 uint32_t instance;
366
367 /* Look up instance number */
368 instance = FLEXCOMM_GetInstance(FLEXCOMM14);
369 assert(s_flexcommIrqHandler[instance] != NULL);
370 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
371 SDK_ISR_EXIT_BARRIER;
372 }
373 #endif
374
375 #if defined(FLEXCOMM15)
376 void FLEXCOMM15_DriverIRQHandler(void);
FLEXCOMM15_DriverIRQHandler(void)377 void FLEXCOMM15_DriverIRQHandler(void)
378 {
379 uint32_t instance;
380
381 /* Look up instance number */
382 instance = FLEXCOMM_GetInstance(FLEXCOMM15);
383 assert(s_flexcommIrqHandler[instance] != NULL);
384 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
385 SDK_ISR_EXIT_BARRIER;
386 }
387 #endif
388
389 #if defined(FLEXCOMM16)
390 void FLEXCOMM16_DriverIRQHandler(void);
FLEXCOMM16_DriverIRQHandler(void)391 void FLEXCOMM16_DriverIRQHandler(void)
392 {
393 uint32_t instance;
394
395 /* Look up instance number */
396 instance = FLEXCOMM_GetInstance(FLEXCOMM16);
397 assert(s_flexcommIrqHandler[instance] != NULL);
398 s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
399 SDK_ISR_EXIT_BARRIER;
400 }
401 #endif
402