--- /dev/null
+/*\r
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.\r
+ * Copyright 2016-2019 NXP\r
+ * All rights reserved.\r
+ *\r
+ * SPDX-License-Identifier: BSD-3-Clause\r
+ */\r
+\r
+#include "fsl_common.h"\r
+#include "fsl_flexcomm.h"\r
+\r
+/*******************************************************************************\r
+ * Definitions\r
+ ******************************************************************************/\r
+\r
+/* Component ID definition, used by tools. */\r
+#ifndef FSL_COMPONENT_ID\r
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm"\r
+#endif\r
+\r
+/*!\r
+ * @brief Used for conversion between `void*` and `uint32_t`.\r
+ */\r
+typedef union pvoid_to_u32\r
+{\r
+ void *pvoid;\r
+ uint32_t u32;\r
+} pvoid_to_u32_t;\r
+\r
+/*******************************************************************************\r
+ * Prototypes\r
+ ******************************************************************************/\r
+/*! @brief Set the FLEXCOMM mode . */\r
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);\r
+\r
+/*! @brief check whether flexcomm supports peripheral type */\r
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);\r
+\r
+/*******************************************************************************\r
+ * Variables\r
+ ******************************************************************************/\r
+\r
+/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */\r
+static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];\r
+\r
+/*! @brief Pointers to handles for each instance to provide context to interrupt routines */\r
+static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];\r
+\r
+/*! @brief Array to map FLEXCOMM instance number to IRQ number. */\r
+IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;\r
+\r
+/*! @brief Array to map FLEXCOMM instance number to base address. */\r
+static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;\r
+\r
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)\r
+/*! @brief IDs of clock for each FLEXCOMM module */\r
+static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;\r
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */\r
+\r
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)\r
+/*! @brief Pointers to FLEXCOMM resets for each instance. */\r
+static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;\r
+#endif\r
+\r
+/*******************************************************************************\r
+ * Code\r
+ ******************************************************************************/\r
+\r
+/* check whether flexcomm supports peripheral type */\r
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)\r
+{\r
+ if (periph == FLEXCOMM_PERIPH_NONE)\r
+ {\r
+ return true;\r
+ }\r
+ else if (periph <= FLEXCOMM_PERIPH_I2S_TX)\r
+ {\r
+ return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;\r
+ }\r
+ else if (periph == FLEXCOMM_PERIPH_I2S_RX)\r
+ {\r
+ return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
+\r
+/* Get the index corresponding to the FLEXCOMM */\r
+/*! brief Returns instance number for FLEXCOMM module with given base address. */\r
+uint32_t FLEXCOMM_GetInstance(void *base)\r
+{\r
+ uint32_t i;\r
+ pvoid_to_u32_t BaseAddr;\r
+ BaseAddr.pvoid = base;\r
+\r
+ for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)\r
+ {\r
+ if (BaseAddr.u32 == s_flexcommBaseAddrs[i])\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ assert(i < FSL_FEATURE_SOC_FLEXCOMM_COUNT);\r
+ return i;\r
+}\r
+\r
+/* Changes FLEXCOMM mode */\r
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)\r
+{\r
+ /* Check whether peripheral type is present */\r
+ if (!FLEXCOMM_PeripheralIsPresent(base, periph))\r
+ {\r
+ return kStatus_OutOfRange;\r
+ }\r
+\r
+ /* Flexcomm is locked to different peripheral type than expected */\r
+ if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&\r
+ ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))\r
+ {\r
+ return kStatus_Fail;\r
+ }\r
+\r
+ /* Check if we are asked to lock */\r
+ if (lock != 0)\r
+ {\r
+ base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;\r
+ }\r
+ else\r
+ {\r
+ base->PSELID = (uint32_t)periph;\r
+ }\r
+\r
+ return kStatus_Success;\r
+}\r
+\r
+/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */\r
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)\r
+{\r
+ uint32_t idx = FLEXCOMM_GetInstance(base);\r
+\r
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)\r
+ /* Enable the peripheral clock */\r
+ CLOCK_EnableClock(s_flexcommClocks[idx]);\r
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */\r
+\r
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)\r
+ /* Reset the FLEXCOMM module */\r
+ RESET_PeripheralReset(s_flexcommResets[idx]);\r
+#endif\r
+\r
+ /* Set the FLEXCOMM to given peripheral */\r
+ return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);\r
+}\r
+\r
+/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM\r
+ * mode */\r
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)\r
+{\r
+ uint32_t instance;\r
+\r
+ /* Look up instance number */\r
+ instance = FLEXCOMM_GetInstance(base);\r
+\r
+ /* Clear handler first to avoid execution of the handler with wrong handle */\r
+ s_flexcommIrqHandler[instance] = NULL;\r
+ s_flexcommHandle[instance] = handle;\r
+ s_flexcommIrqHandler[instance] = handler;\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+\r
+/* IRQ handler functions overloading weak symbols in the startup */\r
+#if defined(FLEXCOMM0)\r
+void FLEXCOMM0_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[0]);\r
+ s_flexcommIrqHandler[0]((uint32_t *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM1)\r
+void FLEXCOMM1_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[1]);\r
+ s_flexcommIrqHandler[1]((uint32_t *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM2)\r
+void FLEXCOMM2_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[2]);\r
+ s_flexcommIrqHandler[2]((uint32_t *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM3)\r
+void FLEXCOMM3_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[3]);\r
+ s_flexcommIrqHandler[3]((uint32_t *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM4)\r
+void FLEXCOMM4_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[4]);\r
+ s_flexcommIrqHandler[4]((uint32_t *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+\r
+#endif\r
+\r
+#if defined(FLEXCOMM5)\r
+void FLEXCOMM5_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[5]);\r
+ s_flexcommIrqHandler[5]((uint32_t *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM6)\r
+void FLEXCOMM6_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[6]);\r
+ s_flexcommIrqHandler[6]((uint32_t *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM7)\r
+void FLEXCOMM7_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[7]);\r
+ s_flexcommIrqHandler[7]((uint32_t *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM8)\r
+void FLEXCOMM8_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[8]);\r
+ s_flexcommIrqHandler[8]((uint32_t *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM9)\r
+void FLEXCOMM9_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[9]);\r
+ s_flexcommIrqHandler[9]((uint32_t *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM10)\r
+void FLEXCOMM10_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[10]);\r
+ s_flexcommIrqHandler[10]((uint32_t *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM11)\r
+void FLEXCOMM11_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[11]);\r
+ s_flexcommIrqHandler[11]((uint32_t *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM12)\r
+void FLEXCOMM12_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[12]);\r
+ s_flexcommIrqHandler[12]((uint32_t *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM13)\r
+void FLEXCOMM13_DriverIRQHandler(void)\r
+{\r
+ assert(s_flexcommIrqHandler[13]);\r
+ s_flexcommIrqHandler[13]((uint32_t *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM14)\r
+void FLEXCOMM14_DriverIRQHandler(void)\r
+{\r
+ uint32_t instance;\r
+\r
+ /* Look up instance number */\r
+ instance = FLEXCOMM_GetInstance(FLEXCOMM14);\r
+ assert(s_flexcommIrqHandler[instance]);\r
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM15)\r
+void FLEXCOMM15_DriverIRQHandler(void)\r
+{\r
+ uint32_t instance;\r
+\r
+ /* Look up instance number */\r
+ instance = FLEXCOMM_GetInstance(FLEXCOMM15);\r
+ assert(s_flexcommIrqHandler[instance]);\r
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r
+\r
+#if defined(FLEXCOMM16)\r
+void FLEXCOMM16_DriverIRQHandler(void)\r
+{\r
+ uint32_t instance;\r
+\r
+ /* Look up instance number */\r
+ instance = FLEXCOMM_GetInstance(FLEXCOMM16);\r
+ assert(s_flexcommIrqHandler[instance]);\r
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
+ exception return operation might vector to incorrect interrupt */\r
+#if defined __CORTEX_M && (__CORTEX_M == 4U)\r
+ __DSB();\r
+#endif\r
+}\r
+#endif\r