1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include "mec_pcfg.h"
10 #include "mec_defs.h"
11 #include "mec_vci_api.h"
12 #include "mec_retval.h"
13 #include "device_mec5.h"
14
15 /* VCI_IN[0:6] are always bits[0:5] in registers referencing them */
16 #define MEC5_VCI_IN_0_6_MASK 0x3fu
17
18 /* -------- VBAT Powered Control Interface (VCI) API -------- */
19
mec_hal_vci_pin_disable(uint8_t vci_id)20 int mec_hal_vci_pin_disable(uint8_t vci_id)
21 {
22 if (vci_id >= MEC5_VCI_PINS) {
23 return MEC_RET_ERR_INVAL;
24 }
25
26 MEC_VCI->VCI_INPUT_EN &= (uint32_t)~MEC_BIT(vci_id);
27 MEC_VCI->VCI_IN_VBAT_BUFEN &= (uint32_t)~MEC_BIT(vci_id);
28
29 return MEC_RET_OK;
30 }
31
32 /* Return current state of VCI pin inputs. If latching is enabled
33 * the current state is the latched state otherwise the state is
34 * live pin after filtering and polarity are applied.
35 * b[6:0] = VCI_IN[6:0]
36 * b[8] = current VCI_OVRD_IN state
37 * b[9] = current VCI_OUT state
38 * b[16] = Week Alarm state
39 * b[17] = RTC Alaram state
40 */
mec_hal_vci_in_pin_states(struct mec_vci_regs * regs)41 uint32_t mec_hal_vci_in_pin_states(struct mec_vci_regs *regs)
42 {
43 if (!regs) {
44 return 0;
45 }
46
47 return (regs->CONFIG & 0x3037fu);
48 }
49
mec_hal_vci_out_get(struct mec_vci_regs * regs)50 uint8_t mec_hal_vci_out_get(struct mec_vci_regs *regs)
51 {
52 if (!regs) {
53 return 0;
54 }
55
56 return (uint8_t)((regs->CONFIG >> MEC_VCI_CONFIG_VCI_OUT_Pos) & MEC_BIT(0));
57 }
58
mec_hal_vci_ovrd_in_get(struct mec_vci_regs * regs)59 uint8_t mec_hal_vci_ovrd_in_get(struct mec_vci_regs *regs)
60 {
61 if (!regs) {
62 return 0;
63 }
64
65 return (uint8_t)((regs->CONFIG >> MEC_VCI_CONFIG_VCI_OVRD_IN_Pos) & MEC_BIT(0));
66 }
67
68 /* VCI_IN[] pin filter enable/disable */
mec_hal_vci_in_filter_enable(struct mec_vci_regs * regs,uint8_t enable)69 int mec_hal_vci_in_filter_enable(struct mec_vci_regs *regs, uint8_t enable)
70 {
71 if (!regs) {
72 return MEC_RET_ERR_INVAL;
73 }
74
75 if (enable) {
76 regs->CONFIG &= (uint32_t)~MEC_BIT(MEC_VCI_CONFIG_VCI_FILT_Pos);
77 } else {
78 regs->CONFIG |= MEC_BIT(MEC_VCI_CONFIG_VCI_FILT_Pos);
79 }
80
81 return MEC_RET_OK;
82 }
83
84 /* set the state of software controlled VCI_OUT pin state
85 * This value has no effect on VCI_OUT pin unless the FW_EXT bit is 1.
86 */
mec_hal_vci_sw_vci_out_set(struct mec_vci_regs * regs,uint8_t pin_state)87 int mec_hal_vci_sw_vci_out_set(struct mec_vci_regs *regs, uint8_t pin_state)
88 {
89 if (!regs) {
90 return MEC_RET_ERR_INVAL;
91 }
92
93 if (pin_state) {
94 regs->CONFIG |= MEC_BIT(MEC_VCI_CONFIG_FW_VCI_OUT_Pos);
95 } else {
96 regs->CONFIG &= (uint32_t)~MEC_BIT(MEC_VCI_CONFIG_FW_VCI_OUT_Pos);
97 }
98
99 return MEC_RET_OK;
100 }
101
102 /* Enable software control of VCI_OUT pin state */
mec_hal_vci_sw_vci_out_enable(struct mec_vci_regs * regs,uint8_t enable)103 int mec_hal_vci_sw_vci_out_enable(struct mec_vci_regs *regs, uint8_t enable)
104 {
105 if (!regs) {
106 return MEC_RET_ERR_INVAL;
107 }
108
109 if (enable) { /* VCI_OUT pin state is set by bit[10] of this register */
110 regs->CONFIG |= MEC_BIT(MEC_VCI_CONFIG_VCI_OUT_SRC_Pos);
111 } else { /* VCI_OUT pin controlled by external pin inputs */
112 regs->CONFIG &= (uint32_t)~MEC_BIT(MEC_VCI_CONFIG_VCI_OUT_SRC_Pos);
113 }
114
115 return MEC_RET_OK;
116 }
117
mec_hal_vci_in_latched_get(struct mec_vci_regs * regs)118 uint32_t mec_hal_vci_in_latched_get(struct mec_vci_regs *regs)
119 {
120 if (!regs) {
121 return 0;
122 }
123
124 return (regs->CONFIG & MEC5_VCI_IN_0_6_MASK);
125 }
126
mec_hal_vci_in_latch_enable(struct mec_vci_regs * regs,uint32_t latch_bitmap)127 int mec_hal_vci_in_latch_enable(struct mec_vci_regs *regs, uint32_t latch_bitmap)
128 {
129 if (!regs) {
130 return MEC_RET_ERR_INVAL;
131 }
132
133 regs->LATCH_EN = latch_bitmap;
134
135 return MEC_RET_OK;
136 }
137
mec_hal_vci_in_latch_disable(struct mec_vci_regs * regs,uint32_t latch_bitmap)138 int mec_hal_vci_in_latch_disable(struct mec_vci_regs *regs, uint32_t latch_bitmap)
139 {
140 if (!regs) {
141 return MEC_RET_ERR_INVAL;
142 }
143
144 regs->LATCH_EN &= (uint32_t)~latch_bitmap;
145
146 return MEC_RET_OK;
147 }
148
mec_hal_vci_in_latch_enable_get(struct mec_vci_regs * regs)149 uint32_t mec_hal_vci_in_latch_enable_get(struct mec_vci_regs *regs)
150 {
151 if (!regs) {
152 return 0;
153 }
154
155 return regs->LATCH_EN;
156 }
157
mec_hal_vci_in_latch_reset(struct mec_vci_regs * regs,uint32_t latch_bitmap)158 int mec_hal_vci_in_latch_reset(struct mec_vci_regs *regs, uint32_t latch_bitmap)
159 {
160 if (!regs) {
161 return MEC_RET_ERR_INVAL;
162 }
163
164 regs->LATCH_RESET = latch_bitmap;
165
166 return MEC_RET_OK;
167 }
168
mec_hal_vci_in_input_enable(struct mec_vci_regs * regs,uint32_t latch_bitmap)169 int mec_hal_vci_in_input_enable(struct mec_vci_regs *regs, uint32_t latch_bitmap)
170 {
171 if (!regs) {
172 return MEC_RET_ERR_INVAL;
173 }
174
175 regs->VCI_INPUT_EN = latch_bitmap;
176 regs->LATCH_RESET = latch_bitmap; /* clear spurious status */
177
178 return MEC_RET_OK;
179 }
180
mec_hal_vci_in_input_enable_get(struct mec_vci_regs * regs)181 uint32_t mec_hal_vci_in_input_enable_get(struct mec_vci_regs *regs)
182 {
183 if (!regs) {
184 return 0;
185 }
186
187 return regs->VCI_INPUT_EN;
188 }
189
mec_hal_vci_out_power_on_delay(struct mec_vci_regs * regs,uint32_t delay_ms)190 int mec_hal_vci_out_power_on_delay(struct mec_vci_regs *regs, uint32_t delay_ms)
191 {
192 uint32_t delay_cnt = 0;
193
194 if (!regs) {
195 return MEC_RET_ERR_INVAL;
196 }
197
198 if (delay_ms == 0) { /* disable */
199 regs->HOLD_OFF_CNT = 0;
200 }
201
202 if ((delay_ms < 125u) || (delay_ms > (32u * 1000u))) {
203 return MEC_RET_ERR_INVAL;
204 }
205
206 delay_cnt = delay_ms / 125u;
207 if (((delay_cnt % 125u) > 62u) && (delay_cnt < 0xffu)) {
208 delay_cnt++;
209 }
210
211 regs->HOLD_OFF_CNT = delay_cnt;
212
213 return MEC_RET_OK;
214 }
215
216 /* Set the polarity of selected VCI_IN[n] pins.
217 * Polarity = 1 Active High
218 * = 0 Active Low
219 */
mec_hal_vci_in_polarity(struct mec_vci_regs * regs,uint32_t vci_in_bitmap,uint32_t polarity_bitmap)220 int mec_hal_vci_in_polarity(struct mec_vci_regs *regs, uint32_t vci_in_bitmap,
221 uint32_t polarity_bitmap)
222 {
223 uint32_t temp = 0;
224
225 if (!regs) {
226 return MEC_RET_ERR_INVAL;
227 }
228
229 temp = regs->VCI_POLARITY;
230 temp &= (uint32_t)~(vci_in_bitmap);
231 temp |= (polarity_bitmap & vci_in_bitmap);
232 regs->VCI_POLARITY = temp;
233
234 return MEC_RET_OK;
235 }
236
mec_hal_vci_pedge_detect(struct mec_vci_regs * regs)237 uint32_t mec_hal_vci_pedge_detect(struct mec_vci_regs *regs)
238 {
239 if (!regs) {
240 return 0;
241 }
242
243 return regs->VCI_IN_POSED_STS;
244 }
245
mec_hal_vci_nedge_detect(struct mec_vci_regs * regs)246 uint32_t mec_hal_vci_nedge_detect(struct mec_vci_regs *regs)
247 {
248 if (!regs) {
249 return 0;
250 }
251
252 return regs->VCI_IN_NEGED_STS;
253 }
254
mec_hal_vci_pedge_detect_clr(struct mec_vci_regs * regs,uint32_t bitmap)255 void mec_hal_vci_pedge_detect_clr(struct mec_vci_regs *regs, uint32_t bitmap)
256 {
257 if (!regs) {
258 return;
259 }
260
261 regs->VCI_IN_POSED_STS = bitmap;
262 }
263
mec_hal_vci_nedge_detect_clr(struct mec_vci_regs * regs,uint32_t bitmap)264 void mec_hal_vci_nedge_detect_clr(struct mec_vci_regs *regs, uint32_t bitmap)
265 {
266 if (!regs) {
267 return;
268 }
269
270 regs->VCI_IN_NEGED_STS = bitmap;
271 }
272
mec_hal_vci_edge_detect_clr_all(struct mec_vci_regs * regs)273 void mec_hal_vci_edge_detect_clr_all(struct mec_vci_regs *regs)
274 {
275 if (!regs) {
276 return;
277 }
278
279 regs->VCI_IN_POSED_STS = UINT32_MAX;
280 regs->VCI_IN_NEGED_STS = UINT32_MAX;
281 }
282
283 /* Select which VCI_IN[] pin edge detector are enabled when the chip
284 * is powered only by the VBAT power rail (VTR Core is off).
285 * When the chip is on (VTR Core ON) this register has no effect on
286 * the edge detector enables.
287 */
mec_hal_vci_vbat_edge_detect_get(struct mec_vci_regs * regs)288 uint32_t mec_hal_vci_vbat_edge_detect_get(struct mec_vci_regs *regs)
289 {
290 if (!regs) {
291 return 0;
292 }
293
294 return regs->VCI_IN_VBAT_BUFEN;
295 }
296
mec_hal_vci_vbat_edge_detect(struct mec_vci_regs * regs,uint32_t bitmap)297 int mec_hal_vci_vbat_edge_detect(struct mec_vci_regs *regs, uint32_t bitmap)
298 {
299 if (!regs) {
300 return MEC_RET_ERR_INVAL;
301 }
302
303 regs->VCI_IN_VBAT_BUFEN = bitmap;
304
305 return MEC_RET_OK;
306 }
307
308 #ifdef MEC5_VCI_HAS_LID_DETECT
309
mec_hal_vci_lid_detect_enable(struct mec_vci_regs * regs)310 int mec_hal_vci_lid_detect_enable(struct mec_vci_regs *regs)
311 {
312 if ((uintptr_t)regs != (uintptr_t)MEC_VCI_BASE) {
313 return MEC_RET_ERR_INVAL;
314 }
315
316 regs->VCI_LID_OPEN_DET_EN |= MEC_BIT(MEC_VCI_VCI_LID_OPEN_DET_EN_VCI_LID_EN_Pos);
317
318 return MEC_RET_OK;
319 }
320
321 #endif
322
323 /* end mec_vci.c */
324