1 /*
2  * Copyright  2019 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_sysctl.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.sysctl"
18 #endif
19 
20 /*******************************************************************************
21  * Prototypes
22  ******************************************************************************/
23 /*!
24  * @brief Get the instance.
25  *
26  * @param base SYSCTL peripheral base address.
27  * @return Instance number.
28  */
29 static uint32_t SYSCTL_GetInstance(SYSCTL_Type *base);
30 
31 /*!
32  * @brief Enable SYSCTL write protect
33  *
34  * @param base SYSCTL peripheral base address.
35  * @param regAddr register address
36  * @param value value to write.
37  */
38 static void SYSCTL_UpdateRegister(SYSCTL_Type *base, volatile uint32_t *regAddr, uint32_t value);
39 
40 /*******************************************************************************
41  * Variables
42  ******************************************************************************/
43 /*! @brief SYSCTL base address array name */
44 static SYSCTL_Type *const s_sysctlBase[] = SYSCTL_BASE_PTRS;
45 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
46 /*! @brief SYSCTL clock array name */
47 static const clock_ip_name_t s_sysctlClock[] = SYSCTL_CLOCKS;
48 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
49 
50 /*******************************************************************************
51  * Code
52  ******************************************************************************/
SYSCTL_UpdateRegister(SYSCTL_Type * base,volatile uint32_t * regAddr,uint32_t value)53 static void SYSCTL_UpdateRegister(SYSCTL_Type *base, volatile uint32_t *regAddr, uint32_t value)
54 {
55     base->UPDATELCKOUT &= ~SYSCTL_UPDATELCKOUT_UPDATELCKOUT_MASK;
56     *regAddr = value;
57     base->UPDATELCKOUT |= SYSCTL_UPDATELCKOUT_UPDATELCKOUT_MASK;
58 }
59 
SYSCTL_GetInstance(SYSCTL_Type * base)60 static uint32_t SYSCTL_GetInstance(SYSCTL_Type *base)
61 {
62     uint8_t instance = 0;
63 
64     while ((instance < ARRAY_SIZE(s_sysctlBase)) && (s_sysctlBase[instance] != base))
65     {
66         instance++;
67     }
68 
69     assert(instance < ARRAY_SIZE(s_sysctlBase));
70 
71     return instance;
72 }
73 
74 /*!
75  * @brief SYSCTL initial
76  *
77  * @param base Base address of the SYSCTL peripheral.
78  */
SYSCTL_Init(SYSCTL_Type * base)79 void SYSCTL_Init(SYSCTL_Type *base)
80 {
81 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
82     /* Enable SYSCTL clock. */
83     CLOCK_EnableClock(s_sysctlClock[SYSCTL_GetInstance(base)]);
84 #endif
85 }
86 
87 /*!
88  * @brief SYSCTL deinit
89  *
90  * @param base Base address of the SYSCTL peripheral.
91  */
SYSCTL_Deinit(SYSCTL_Type * base)92 void SYSCTL_Deinit(SYSCTL_Type *base)
93 {
94 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
95     /* Disable SYSCTL clock. */
96     CLOCK_DisableClock(s_sysctlClock[SYSCTL_GetInstance(base)]);
97 #endif
98 }
99 
100 /*!
101  * @brief SYSCTL share set configure for separate signal
102  *
103  * @param base Base address of the SYSCTL peripheral
104  * @param flexCommIndex index of flexcomm,reference _sysctl_share_src
105  * @param setIndex share set for sck, reference _sysctl_share_set_index
106  *
107  */
SYSCTL_SetShareSet(SYSCTL_Type * base,uint32_t flexCommIndex,sysctl_fcctrlsel_signal_t signal,uint32_t set)108 void SYSCTL_SetShareSet(SYSCTL_Type *base, uint32_t flexCommIndex, sysctl_fcctrlsel_signal_t signal, uint32_t set)
109 {
110     uint32_t tempReg = base->FCCTRLSEL[flexCommIndex];
111 
112     tempReg &= ~((uint32_t)SYSCTL_FCCTRLSEL_SCKINSEL_MASK << (uint32_t)signal);
113     tempReg |= (set + 1U) << (uint32_t)signal;
114 
115     SYSCTL_UpdateRegister(base, &base->FCCTRLSEL[flexCommIndex], tempReg);
116 }
117 
118 /*!
119  * @brief SYSCTL share set configure for flexcomm
120  *
121  * @param base Base address of the SYSCTL peripheral.
122  * @param flexCommIndex index of flexcomm, reference _sysctl_share_src
123  * @param sckSet share set for sck,reference _sysctl_share_set_index
124  * @param wsSet share set for ws, reference _sysctl_share_set_index
125  * @param dataInSet share set for data in, reference _sysctl_share_set_index
126  * @param dataOutSet share set for data out, reference _sysctl_share_set_index
127  *
128  */
SYSCTL_SetFlexcommShareSet(SYSCTL_Type * base,uint32_t flexCommIndex,uint32_t sckSet,uint32_t wsSet,uint32_t dataInSet,uint32_t dataOutSet)129 void SYSCTL_SetFlexcommShareSet(
130     SYSCTL_Type *base, uint32_t flexCommIndex, uint32_t sckSet, uint32_t wsSet, uint32_t dataInSet, uint32_t dataOutSet)
131 {
132     uint32_t tempReg = base->FCCTRLSEL[flexCommIndex];
133 
134     tempReg &= ~(SYSCTL_FCCTRLSEL_SCKINSEL_MASK | SYSCTL_FCCTRLSEL_WSINSEL_MASK | SYSCTL_FCCTRLSEL_DATAINSEL_MASK |
135                  SYSCTL_FCCTRLSEL_DATAOUTSEL_MASK);
136     tempReg |= SYSCTL_FCCTRLSEL_SCKINSEL(sckSet + 1U) | SYSCTL_FCCTRLSEL_WSINSEL(wsSet + 1U) |
137                SYSCTL_FCCTRLSEL_DATAINSEL(dataInSet + 1U) | SYSCTL_FCCTRLSEL_DATAOUTSEL(dataOutSet + 1U);
138 
139     SYSCTL_UpdateRegister(base, &base->FCCTRLSEL[flexCommIndex], tempReg);
140 }
141 
142 /*!
143  * @brief SYSCTL share set source configure
144  *
145  * @param base Base address of the SYSCTL peripheral
146  * @param setIndex index of share set, reference _sysctl_share_set_index
147  * @param sckShareSrc sck source for this share set,reference _sysctl_share_src
148  * @param wsShareSrc ws source for this share set,reference _sysctl_share_src
149  * @param dataInShareSrc data in source for this share set,reference _sysctl_share_src
150  * @param dataOutShareSrc data out source for this share set,reference _sysctl_dataout_mask
151  *
152  */
SYSCTL_SetShareSetSrc(SYSCTL_Type * base,uint32_t setIndex,uint32_t sckShareSrc,uint32_t wsShareSrc,uint32_t dataInShareSrc,uint32_t dataOutShareSrc)153 void SYSCTL_SetShareSetSrc(SYSCTL_Type *base,
154                            uint32_t setIndex,
155                            uint32_t sckShareSrc,
156                            uint32_t wsShareSrc,
157                            uint32_t dataInShareSrc,
158                            uint32_t dataOutShareSrc)
159 {
160     uint32_t tempReg = base->SHAREDCTRLSET[setIndex];
161 
162     /* WS,SCK,DATA IN */
163     tempReg &= ~(SYSCTL_SHAREDCTRLSET_SHAREDSCKSEL_MASK | SYSCTL_SHAREDCTRLSET_SHAREDWSSEL_MASK |
164                  SYSCTL_SHAREDCTRLSET_SHAREDDATASEL_MASK);
165     tempReg |= SYSCTL_SHAREDCTRLSET_SHAREDSCKSEL(sckShareSrc) | SYSCTL_SHAREDCTRLSET_SHAREDWSSEL(wsShareSrc) |
166                SYSCTL_SHAREDCTRLSET_SHAREDDATASEL(dataInShareSrc);
167 
168     /* data out */
169     tempReg &= ~(SYSCTL_SHAREDCTRLSET_FC0DATAOUTEN_MASK | SYSCTL_SHAREDCTRLSET_FC1DATAOUTEN_MASK |
170                  SYSCTL_SHAREDCTRLSET_FC2DATAOUTEN_MASK | SYSCTL_SHAREDCTRLSET_FC6DATAOUTEN_MASK |
171                  SYSCTL_SHAREDCTRLSET_FC7DATAOUTEN_MASK);
172     tempReg |= dataOutShareSrc;
173 
174     SYSCTL_UpdateRegister(base, &base->SHAREDCTRLSET[setIndex], tempReg);
175 }
176 
177 /*!
178  * @brief SYSCTL sck source configure
179  *
180  * @param base Base address of the SYSCTL peripheral
181  * @param setIndex index of share set, reference _sysctl_share_set_index
182  * @param sckShareSrc sck source fro this share set,reference _sysctl_share_src
183  *
184  */
SYSCTL_SetShareSignalSrc(SYSCTL_Type * base,uint32_t setIndex,sysctl_sharedctrlset_signal_t signal,uint32_t shareSrc)185 void SYSCTL_SetShareSignalSrc(SYSCTL_Type *base,
186                               uint32_t setIndex,
187                               sysctl_sharedctrlset_signal_t signal,
188                               uint32_t shareSrc)
189 {
190     uint32_t tempReg = base->SHAREDCTRLSET[setIndex];
191 
192     if (signal == kSYSCTL_SharedCtrlSignalDataOut)
193     {
194         tempReg |= 1UL << ((uint32_t)signal + shareSrc);
195     }
196     else
197     {
198         tempReg &= ~((uint32_t)SYSCTL_SHAREDCTRLSET_SHAREDSCKSEL_MASK << (uint32_t)signal);
199         tempReg |= shareSrc << (uint32_t)signal;
200     }
201 
202     SYSCTL_UpdateRegister(base, &base->SHAREDCTRLSET[setIndex], tempReg);
203 }
204