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