1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2021, 2023 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_inputmux.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.inputmux"
18 #endif
19
20 #if defined(INPUTMUX_RSTS)
21 #define INPUTMUX_RESETS_ARRAY INPUTMUX_RSTS
22 #endif
23
24 /*******************************************************************************
25 * Prototypes
26 ******************************************************************************/
27 #if defined(INPUTMUX_RESETS_ARRAY)
28 /*!
29 * @brief Get instance number for INPUTMUX module.
30 *
31 * @param base INPUTMUX peripheral base address
32 */
33 static uint32_t INPUTMUX_GetInstance(INPUTMUX_Type *base);
34 #endif
35 /*******************************************************************************
36 * Variables
37 ******************************************************************************/
38 #if defined(INPUTMUX_RESETS_ARRAY)
39 /*! @brief Pointers to INPUTMUX bases for each instance. */
40 static INPUTMUX_Type *const s_inputmuxBases[] = INPUTMUX_BASE_PTRS;
41
42 /* Reset array */
43 static const reset_ip_name_t s_inputmuxResets[] = INPUTMUX_RESETS_ARRAY;
44 #endif
45
46 /*******************************************************************************
47 * Code
48 ******************************************************************************/
49 #if defined(INPUTMUX_RESETS_ARRAY)
INPUTMUX_GetInstance(INPUTMUX_Type * base)50 static uint32_t INPUTMUX_GetInstance(INPUTMUX_Type *base)
51 {
52 uint32_t instance;
53
54 /* Find the instance index from base address mappings. */
55 for (instance = 0; instance < ARRAY_SIZE(s_inputmuxBases); instance++)
56 {
57 if (s_inputmuxBases[instance] == base)
58 {
59 break;
60 }
61 }
62
63 assert(instance < ARRAY_SIZE(s_inputmuxBases));
64
65 return instance;
66 }
67 #endif
68
69 /*!
70 * brief Initialize INPUTMUX peripheral.
71
72 * This function enables the INPUTMUX clock.
73 *
74 * param base Base address of the INPUTMUX peripheral.
75 *
76 * retval None.
77 */
INPUTMUX_Init(INPUTMUX_Type * base)78 void INPUTMUX_Init(INPUTMUX_Type *base)
79 {
80 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
81 #if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE
82 #if (defined(FSL_FEATURE_SOC_SCT_COUNT) && (FSL_FEATURE_SOC_SCT_COUNT > 0))
83 CLOCK_EnableClock(kCLOCK_Sct);
84 #endif /* FSL_FEATURE_SOC_SCT_COUNT */
85 CLOCK_EnableClock(kCLOCK_Dma);
86 #else
87 CLOCK_EnableClock(kCLOCK_InputMux);
88 #endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */
89 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
90
91 #if defined(INPUTMUX_RESETS_ARRAY)
92 RESET_ReleasePeripheralReset(s_inputmuxResets[INPUTMUX_GetInstance(base)]);
93 #endif
94 }
95
96 /*!
97 * brief Attaches a signal
98 *
99 * This function attaches multiplexed signals from INPUTMUX to target signals.
100 * For example, to attach GPIO PORT0 Pin 5 to PINT peripheral, do the following:
101 * code
102 * INPUTMUX_AttachSignal(INPUTMUX, 2, kINPUTMUX_GpioPort0Pin5ToPintsel);
103 * endcode
104 * In this example, INTMUX has 8 registers for PINT, PINT_SEL0~PINT_SEL7.
105 * With parameter p index specified as 2, this function configures register PINT_SEL2.
106 *
107 * param base Base address of the INPUTMUX peripheral.
108 * param index The serial number of destination register in the group of INPUTMUX registers with same name.
109 * param connection Applies signal from source signals collection to target signal.
110 *
111 * retval None.
112 */
INPUTMUX_AttachSignal(INPUTMUX_Type * base,uint32_t index,inputmux_connection_t connection)113 void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection)
114 {
115 uint32_t pmux_id;
116 uint32_t output_id;
117
118 /* extract pmux to be used */
119 pmux_id = ((uint32_t)(connection)) >> PMUX_SHIFT;
120 /* extract function number */
121 output_id = ((uint32_t)(connection)) & ((1UL << PMUX_SHIFT) - 1U);
122 /* programm signal */
123 *(volatile uint32_t *)(((uint32_t)base) + pmux_id + (index * 4U)) = output_id;
124 }
125
126 #if defined(FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA)
127 /*!
128 * brief Enable/disable a signal
129 *
130 * This function gates the INPUTPMUX clock.
131 *
132 * param base Base address of the INPUTMUX peripheral.
133 * param signal Enable signal register id and bit offset.
134 * param enable Selects enable or disable.
135 *
136 * retval None.
137 */
INPUTMUX_EnableSignal(INPUTMUX_Type * base,inputmux_signal_t signal,bool enable)138 void INPUTMUX_EnableSignal(INPUTMUX_Type *base, inputmux_signal_t signal, bool enable)
139 {
140 uint32_t ena_id;
141 uint32_t ena_id_mask = (1UL << (32U - ENA_SHIFT)) - 1U;
142 uint32_t bit_offset;
143
144 #if defined(FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX) && FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX
145 uint32_t chmux_offset;
146 uint32_t chmux_value;
147
148 /* Only enable need to update channel mux */
149 if (enable && ((((uint32_t)signal) & (1UL << CHMUX_AVL_SHIFT)) != 0U))
150 {
151 chmux_offset = (((uint32_t)signal) >> CHMUX_OFF_SHIFT) & ((1UL << (CHMUX_AVL_SHIFT - CHMUX_OFF_SHIFT)) - 1UL);
152 chmux_value = (((uint32_t)signal) >> CHMUX_VAL_SHIFT) & ((1UL << (CHMUX_OFF_SHIFT - CHMUX_VAL_SHIFT)) - 1UL);
153 *(volatile uint32_t *)(((uint32_t)base) + chmux_offset) = chmux_value;
154 }
155 ena_id_mask = (1UL << (CHMUX_VAL_SHIFT - ENA_SHIFT)) - 1U;
156 #endif
157 /* extract enable register to be used */
158 ena_id = (((uint32_t)signal) >> ENA_SHIFT) & ena_id_mask;
159 /* extract enable bit offset */
160 bit_offset = ((uint32_t)signal) & ((1UL << ENA_SHIFT) - 1U);
161 /* set signal */
162 if (enable)
163 {
164 *(volatile uint32_t *)(((uint32_t)base) + ena_id) |= (1UL << bit_offset);
165 }
166 else
167 {
168 *(volatile uint32_t *)(((uint32_t)base) + ena_id) &= ~(1UL << bit_offset);
169 }
170 }
171 #endif
172
173 /*!
174 * brief Deinitialize INPUTMUX peripheral.
175
176 * This function disables the INPUTMUX clock.
177 *
178 * param base Base address of the INPUTMUX peripheral.
179 *
180 * retval None.
181 */
INPUTMUX_Deinit(INPUTMUX_Type * base)182 void INPUTMUX_Deinit(INPUTMUX_Type *base)
183 {
184 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
185 #if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE
186 #if (defined(FSL_FEATURE_SOC_SCT_COUNT) && (FSL_FEATURE_SOC_SCT_COUNT > 0))
187 CLOCK_DisableClock(kCLOCK_Sct);
188 #endif /* FSL_FEATURE_SOC_SCT_COUNT */
189 CLOCK_DisableClock(kCLOCK_Dma);
190 #else
191 CLOCK_DisableClock(kCLOCK_InputMux);
192 #endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */
193 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
194 }
195