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 <device_mec5.h>
10 #include "mec_pcfg.h"
11 #include "mec_gpio_api.h"
12 #include "mec_vci_api.h"
13 #include "mec_retval.h"
14 
15 /** @brief
16  * Port 0: GPIO_0000 - 0036  GIRQ11
17  * Port 1: GPIO_0040 - 0076  GIRQ10
18  * Port 2: GPIO_0100 - 0136  GIRQ09
19  * Port 3: GPIO_0140 - 0176  GIRQ08
20  * Port 4: GPIO_0200 - 0236  GIRQ12
21  * Port 5: GPIO_0240 - 0276  GIRQ26
22  */
23 
24 /* Work-around for GPIO hardware anonmaly when interrupt detection
25  * field is changed.
26  */
27 #define MEC_GPIO_EDGE_DLY_COUNT 4
28 
29 /*
30  * Pin numbers in data sheet are octal.
31  * Use octal or decimal/hex equivalent.
32  */
33 struct mec_gpio_cfg_field {
34     uint8_t mask;
35     uint8_t bitpos;
36     uint8_t ctrl_reg;
37     uint8_t rsvd3;
38 };
39 
40 const struct mec_gpio_cfg_field mec_cfg_tbl[MEC_GPIO_MAX_PROP_ID] = {
41     { 0x03u, 0, 0, 0 },  /* Pull Up/Down/Repeater-Mode */
42     { 0x03u, 2, 0, 0 },  /* Power Gate */
43     { 0x0Fu, 4, 0, 0 },  /* Interrupt detect & edge enable */
44     { 0x01u, 8, 0, 0 },  /* Output buffer type */
45     { 0x01u, 9, 0, 0 },  /* Direction */
46     { 0x01u, 10, 0, 0 }, /* Output control select */
47     { 0x01u, 11, 0, 0 }, /* Polarity */
48     { 0x07u, 12, 0, 0 }, /* Mux control */
49     { 0x01u, 15, 0, 0 }, /* Input disable */
50     { 0x01u, 16, 0, 0 }, /* output value */
51     { 0x01u, 0, 1, 0 },  /* slew rate in b[0] of control2 */
52     { 0x03u, 4, 1, 0 },  /* drive strength in b[5:4] of control 2 */
53 };
54 
55 /* All MEC5 GPIO interrupts are aggregated into GIRQ 8 - 12, and 26.
56  * Lowest numbered pin starts at bit[0].
57  * GIRQ does not implement bit[31] therefore each bank can only have
58  * 31 pins.            GPIO Port number     GIRQ     ECIA->GIRQ[index]
59  * GPIO 0000 - 0036    0                    GIRQ11   3
60  * GPIO 0040 - 0076    1                    GIRQ10   2
61  * GPIO 0100 - 0136    2                    GIRQ09   1
62  * GPIO 0140 - 0176    3                    GIRQ08   0
63  * GPIO 0200 - 0206    4                    GIRQ12   4
64  * GPIO 0240 - 0276    5                    GIRQ26   18
65  * Table is indexed by GPIO port number and contains the zero based
66  * index into the ECIA->GIRQ[] structure array.
67  */
68 const uint8_t mec_gpio_irq_routing[] = {
69     3u, 2u, 1u, 0, 4u, 18u
70 };
71 
72 const uint8_t mec_gpio_girq_blk_pos[] = {
73     11u, 10u, 9u, 8u, 12u, 26u
74 };
75 
76 /* GPIO's with VCI functions.
77  * When switched to a non-VCI function these pins require
78  * clearing the respective bits in VCI input enable and
79  * buffer enable registers.
80  */
81 #define GPIO_VCI_FUNC(f) ((f) & 0x7u)
82 #define GPIO_VCI_FUNC_GET(v) ((v) & 0x7u)
83 #define GPIO_VCI_PIN(n) (((n) & 0x7u) << 4)
84 #define GPIO_VCI_PIN_GET(v) (((v) >> 4) & 0x7u)
85 
86 struct mec_gpio_vci_pin {
87     uint8_t pin;
88     uint8_t vci_info;
89 };
90 
91 static const struct mec_gpio_vci_pin gpio_vci_table[] = {
92     { (uint8_t)MEC_PIN_0162, GPIO_VCI_FUNC(1) | GPIO_VCI_PIN(1) },
93     { (uint8_t)MEC_PIN_0161, GPIO_VCI_FUNC(1) | GPIO_VCI_PIN(2) },
94     { (uint8_t)MEC_PIN_0000, GPIO_VCI_FUNC(1) | GPIO_VCI_PIN(3) },
95 #ifdef MEC5_PKG176
96     { (uint8_t)MEC_PIN_0234, GPIO_VCI_FUNC(1) | GPIO_VCI_PIN(4) },
97 #endif
98 };
99 #define MEC_GPIO_NUM_VCI_PINS (sizeof(gpio_vci_table) / sizeof (struct mec_gpio_vci_pin))
100 
pin_is_vci(uint16_t pin)101 static bool pin_is_vci(uint16_t pin)
102 {
103     for (size_t i = 0; i < MEC_GPIO_NUM_VCI_PINS; i++) {
104         if (pin == gpio_vci_table[i].pin) {
105             return true;
106         }
107     }
108     return false;
109 }
110 
find_gpio_vci_info(uint16_t pin)111 static struct mec_gpio_vci_pin const *find_gpio_vci_info(uint16_t pin)
112 {
113     for (size_t i = 0; i < MEC_GPIO_NUM_VCI_PINS; i++) {
114         if (pin == gpio_vci_table[i].pin) {
115             return &gpio_vci_table[i];
116         }
117     }
118     return NULL;
119 }
120 
121 /* Pin is a zero based pin number. */
122 
pin_get_port(uint16_t pin)123 static inline uint8_t pin_get_port(uint16_t pin)
124 {
125     return (uint8_t)(((pin & 0x1FFu) >> 5) & 0xffu);
126 }
127 
pin_get_bitpos(uint16_t pin)128 static inline uint8_t pin_get_bitpos(uint16_t pin)
129 {
130     return (uint8_t)(pin & 0x1Fu);
131 }
132 
133 #ifdef MEC_GPIO_PIN_VALIDATION
134 
135 /*
136  * These values need more testing.
137  * They also change with the package!
138  * SRAM: L=352KB, M=384KB, N=416KB
139  * Version/Rev: B# L#(lenovo)
140  * I/ -40C to +85C temperature range
141  * Packages:
142  * SZ = 144 pin WFBGA
143  * LJ = 176 pin WFBGA
144  *
145  * MEC5200M-D0-I/LJ  176-pin
146  * MEC1725N-B0-I/LJ  176-pin
147  * MEC172X ?? is this SZ?
148  * MEC1723M-177 pin
149  * EG 144 pin
150  * CG60 pin
151  *
152  * Packages:
153  *  LJ = 176 pin
154  *  SZ = 144 pin
155  */
156 const uint32_t valid_ctrl_masks[] = {
157     MEC5_GPIO_PORT0_BITMAP, MEC5_GPIO_PORT1_BITMAP,
158     MEC5_GPIO_PORT2_BITMAP, MEC5_GPIO_PORT3_BITMAP,
159     MEC5_GPIO_PORT4_BITMAP, MEC5_GPIO_PORT5_BITMAP,
160 };
161 
162 const uint32_t valid_ctrl2_masks[] = {
163     MEC5_GPIO_PORT0_C2_BITMAP, MEC5_GPIO_PORT1_C2_BITMAP,
164     MEC5_GPIO_PORT2_C2_BITMAP, MEC5_GPIO_PORT3_C2_BITMAP,
165     MEC5_GPIO_PORT4_C2_BITMAP, MEC5_GPIO_PORT5_C2_BITMAP,
166 };
167 /*-----------------------------------------------------------*/
168 
pin_is_valid(uint32_t pin)169 static inline bool pin_is_valid(uint32_t pin)
170 {
171     uint32_t port = pin_get_port((uint16_t)(pin & 0xffffu));
172     uint8_t bitpos = pin_get_bitpos((uint16_t)(pin & 0xffffu));
173 
174     if ((port < MEC_GPIO_PORT_MAX) && (valid_ctrl_masks[port] & MEC_BIT(bitpos))) {
175         return true;
176     }
177 
178     return false;
179 }
180 
mec_hal_gpio_pin_valid(uint32_t pin)181 int mec_hal_gpio_pin_valid(uint32_t pin)
182 {
183     if (pin_is_valid(pin)) {
184         return 1;
185     }
186 
187     return 0;
188 }
189 
mec_hal_gpio_port_pin_valid(uint8_t port,uint8_t pin_port_pos)190 int mec_hal_gpio_port_pin_valid(uint8_t port, uint8_t pin_port_pos)
191 {
192     if ((port < MEC_GPIO_PORT_MAX) && (pin_port_pos < 32u)) {
193         if (valid_ctrl_masks[port] & MEC_BIT(pin_port_pos)) {
194             return MEC_RET_OK;
195         }
196     }
197 
198     return MEC_RET_ERR_INVAL;
199 }
200 
mec_hal_gpio_port_valid_mask(uint8_t port,uint32_t * valid_msk)201 int mec_hal_gpio_port_valid_mask(uint8_t port, uint32_t *valid_msk)
202 {
203     if ((port >= MEC_GPIO_PORT_MAX) || !valid_msk) {
204         return MEC_RET_ERR_INVAL;
205     }
206 
207     *valid_msk = valid_ctrl_masks[port];
208 
209     return 0;
210 }
211 #else
mec_hal_gpio_pin_valid(uint32_t pin)212 int mec_hal_gpio_pin_valid(uint32_t pin)
213 {
214     return 1u;
215 }
216 
mec_hal_gpio_port_pin_valid(uint8_t port,uint8_t pin_port_pos)217 int mec_hal_gpio_port_pin_valid(uint8_t port, uint8_t pin_port_pos)
218 {
219     if ((port >= MEC_GPIO_PORT_MAX) || (pin_port_pos >= 32u)) {
220         return MEC_RET_ERR_INVAL;
221     }
222 
223     return MEC_RET_OK;
224 }
225 
mec_hal_gpio_port_valid_mask(uint8_t port,uint32_t * valid_msk)226 int mec_hal_gpio_port_valid_mask(uint8_t port, uint32_t *valid_msk)
227 {
228     if ((port >= MEC_GPIO_PORT_MAX) || !valid_msk) {
229         return MEC_RET_ERR_INVAL;
230     }
231 
232     *valid_msk = 0xffffffffu;
233 
234     return MEC_RET_OK;
235 }
236 #endif /* #ifdef MEC_GPIO_PIN_VALIDATION */
237 
238 /*
239  * Parameter pin is a zero based number.
240  * Each GPIO control register is 32 bits located consecutively
241  * from the base address.
242  */
243 #define MEC_GPIO_CTRL_ADDR   (MEC_GPIO_BASE)
244 #define MEC_GPIO_CTRL2_ADDR  (MEC_GPIO_BASE + MEC_GPIO_CTRL2_OFS)
245 #define MEC_GPIO_PARIN_ADDR  (MEC_GPIO_BASE + MEC_GPIO_PARIN_OFS)
246 #define MEC_GPIO_PAROUT_ADDR (MEC_GPIO_BASE + MEC_GPIO_PAROUT_OFS)
247 /* NOTE: LOCK0 is at top of range */
248 #define MEC_GPIO_LOCK0_ADDR (MEC_GPIO_BASE + MEC_GPIO_LOCK_OFS_HI)
249 
250 #define MEC_GPIO_PIN_CTRL_ADDR(pin) \
251         ((MEC_GPIO_CTRL_ADDR) + ((uint32_t)(pin) * 4u));
252 
253 #define MEC_GPIO_PIN_CTRL2_ADDR(pin) \
254         ((MEC_GPIO_CTRL2_ADDR) + ((uint32_t)(pin) * 4u));
255 
256 #define MEC_GPIO_PARIN_PORT_ADDR(p) \
257         ((uintptr_t)(MEC_GPIO_PARIN_ADDR) + ((uintptr_t)(p) * 4U))
258 
259 #define MEC_GPIO_PAROUT_PORT_ADDR(p) \
260         ((uintptr_t)(MEC_GPIO_PAROUT_ADDR) + ((uintptr_t)(p) * 4U))
261 
262 /* offset from AHB peripheral region */
263 #define MEC_GPIO_PAROUT_AHB_OFS(p) \
264     ((uintptr_t)((MEC_GPIO_PAROUT_ADDR) & 0xFFFFFu) + ((uintptr_t)(p) * 4U))
265 
gpio_control_addr(uint32_t pin)266 static inline uintptr_t gpio_control_addr(uint32_t pin)
267 {
268     return (uintptr_t)(MEC_GPIO_CTRL_ADDR) + (uint32_t)(pin * 4U);
269 }
270 
gpio_control2_addr(uint16_t pin)271 static inline uintptr_t gpio_control2_addr(uint16_t pin)
272 {
273     return (uintptr_t)(MEC_GPIO_CTRL2_ADDR) + (uint32_t)(pin * 4U);
274 }
275 
276 /*--------------------- Public API -------------------------*/
mec_hal_gpio_pin_num(uint8_t port,uint8_t pin_port_pos,uint32_t * pin_num)277 int mec_hal_gpio_pin_num(uint8_t port, uint8_t pin_port_pos, uint32_t *pin_num)
278 {
279     if ((port > MEC_GPIO_PORT_MAX) || (pin_port_pos > 32u) || !pin_num) {
280         return MEC_RET_ERR_INVAL;
281     }
282 
283     *pin_num = ((uint32_t)port * 32U) + (uint32_t)pin_port_pos;
284 
285     return 0;
286 }
287 
mec_hal_gpio_ctrl_addr(uint32_t pin)288 uintptr_t mec_hal_gpio_ctrl_addr(uint32_t pin)
289 {
290 #ifdef MEC_GPIO_PIN_VALIDATION
291     if (!pin_is_valid(pin)) {
292         return 0;
293     }
294 #endif
295     return gpio_control_addr(pin);
296 }
297 
mec_hal_gpio_ctrl2_addr(uint32_t pin)298 uintptr_t mec_hal_gpio_ctrl2_addr(uint32_t pin)
299 {
300 #ifdef MEC_GPIO_PIN_VALIDATION
301     if (!pin_is_valid(pin)) {
302         return 0;
303     }
304 #endif
305     return gpio_control2_addr(pin & 0xffffu);
306 }
307 
mec_hal_gpio_is_output(uint32_t pin)308 int mec_hal_gpio_is_output(uint32_t pin)
309 {
310 #ifdef MEC_GPIO_PIN_VALIDATION
311     if (!pin_is_valid(pin)) {
312         return 0;
313     }
314 #endif
315     if (MEC_GPIO->CTRL[pin] & (MEC_GPIO_CTRL_DIR_OUTPUT << MEC_GPIO_CTRL_DIR_Pos)) {
316         return 1;
317     }
318 
319     return 0;
320 }
321 
mec_hal_gpio_disable_input_pad(uint32_t pin)322 int mec_hal_gpio_disable_input_pad(uint32_t pin)
323 {
324 #ifdef MEC_GPIO_PIN_VALIDATION
325     if (!pin_is_valid(pin)) {
326         return MEC_RET_ERR_INVAL;
327     }
328 #endif
329 
330     MEC_GPIO->CTRL[pin] |= MEC_BIT(MEC_GPIO_CTRL_INPD_Pos);
331 
332     return MEC_RET_OK;
333 }
334 
mec_hal_gpio_enable_input_pad(uint32_t pin)335 int mec_hal_gpio_enable_input_pad(uint32_t pin)
336 {
337 #ifdef MEC_GPIO_PIN_VALIDATION
338     if (!pin_is_valid(pin)) {
339         return MEC_RET_ERR_INVAL;
340     }
341 #endif
342 
343     MEC_GPIO->CTRL[pin] &= ~MEC_BIT(MEC_GPIO_CTRL_INPD_Pos);
344 
345     return MEC_RET_OK;
346 }
347 
348 /* Check if pin control registers are locked */
mec_hal_gpio_is_locked(uint32_t pin)349 int mec_hal_gpio_is_locked(uint32_t pin)
350 {
351 #ifdef MEC_GPIO_PIN_VALIDATION
352     if (!pin_is_valid(pin)) {
353         return 0;
354     }
355 #endif
356     uint32_t bitpos = pin_get_bitpos(pin & 0xffffu);
357     uint32_t port = pin_get_port(pin & 0xffffu);
358 
359     /* lock registers are from high address to low address */
360     if (MEC_GPIO->LOCK[MEC_GPIO_PORT_MAX - 1u - port] & MEC_BIT(bitpos)) {
361         return 1;
362     }
363 
364     return 0;
365 }
366 
mec_hal_gpio_get_config(uint32_t pin,uint32_t * config)367 int mec_hal_gpio_get_config(uint32_t pin, uint32_t *config)
368 {
369 #ifdef MEC_GPIO_PIN_VALIDATION
370     if (!pin_is_valid(pin)) {
371         return MEC_RET_ERR_INVAL;
372     }
373 #endif
374     if (!config) {
375         return MEC_RET_ERR_INVAL;
376     }
377 
378     *config = MEC_GPIO->CTRL[pin] & 0xffffu;
379 
380     return MEC_RET_OK;
381 }
382 
mec_hal_gpio_set_config(uint32_t pin,uint32_t cfg)383 int mec_hal_gpio_set_config(uint32_t pin, uint32_t cfg)
384 {
385 #ifdef MEC_GPIO_PIN_VALIDATION
386     if (!pin_is_valid(pin)) {
387         return MEC_RET_ERR_INVAL;
388     }
389 #endif
390 
391     MEC_MMCR16_WR(&MEC_GPIO->CTRL[pin], cfg & 0xffffu);
392 
393     return MEC_RET_OK;
394 }
395 
mec_hal_gpio_set_config_mask(uint32_t pin,uint32_t cfg,uint32_t mask)396 int mec_hal_gpio_set_config_mask(uint32_t pin, uint32_t cfg, uint32_t mask)
397 {
398 #ifdef MEC_GPIO_PIN_VALIDATION
399     if (!pin_is_valid(pin)) {
400         return MEC_RET_ERR_INVAL;
401     }
402 #endif
403 
404     uint16_t pin_cfg = MEC_MMCR16_RD(&MEC_GPIO->CTRL[pin]) & (uint16_t)~mask;
405 
406     pin_cfg |= (uint16_t)(cfg & mask);
407     MEC_MMCR16_WR(&MEC_GPIO->CTRL[pin], pin_cfg);
408 
409     return MEC_RET_OK;
410 }
411 
mec_hal_gpio_get_ctrl_property(uint32_t ctrl,uint8_t prop_id,uint8_t * prop)412 int mec_hal_gpio_get_ctrl_property(uint32_t ctrl, uint8_t prop_id, uint8_t *prop)
413 {
414     if (prop_id >= MEC_GPIO_MAX_PROP_ID) {
415         return MEC_RET_ERR_INVAL;
416     }
417 
418     uint32_t msk0 = mec_cfg_tbl[prop_id].mask;
419     uint32_t bpos = mec_cfg_tbl[prop_id].bitpos;
420 
421     *prop = (uint8_t)((ctrl >> bpos) & msk0);
422 
423     return MEC_RET_OK;
424 }
425 
mec_hal_gpio_set_ctrl_property(uint32_t ctrl,uint8_t prop_id,uint8_t val)426 uint32_t mec_hal_gpio_set_ctrl_property(uint32_t ctrl, uint8_t prop_id, uint8_t val)
427 {
428     if (prop_id >= MEC_GPIO_MAX_PROP_ID) {
429         return ctrl;
430     }
431 
432     uint32_t msk0 = mec_cfg_tbl[prop_id].mask;
433     uint32_t bpos = mec_cfg_tbl[prop_id].bitpos;
434 
435     ctrl = (ctrl & ~(msk0 << bpos)) | (((uint32_t)val & msk0) << bpos);
436 
437     return ctrl;
438 }
439 
mec_hal_gpio_get_property(uint32_t pin,uint8_t prop_id,uint8_t * prop)440 int mec_hal_gpio_get_property(uint32_t pin, uint8_t prop_id, uint8_t *prop)
441 {
442 #ifdef MEC_GPIO_PIN_VALIDATION
443     if (!pin_is_valid(pin)) {
444         return MEC_RET_ERR_INVAL;
445     }
446 #endif
447 
448     if ((prop_id >= MEC_GPIO_MAX_PROP_ID) || !prop) {
449         return MEC_RET_ERR_INVAL;
450     }
451 
452     uintptr_t regaddr = (uintptr_t)&MEC_GPIO->CTRL[pin];
453     uint32_t msk0 = mec_cfg_tbl[prop_id].mask;
454     uint32_t bpos = mec_cfg_tbl[prop_id].bitpos;
455 
456     if (mec_cfg_tbl[prop_id].ctrl_reg) {
457         regaddr += MEC_GPIO_CTRL2_OFS;
458     }
459 
460     *prop = (uint8_t)((MEC_MMCR32(regaddr) >> bpos) & msk0);
461 
462     return MEC_RET_OK;
463 }
464 
mec_hal_gpio_set_property(uint32_t pin,uint8_t prop_id,uint8_t val)465 int mec_hal_gpio_set_property(uint32_t pin, uint8_t prop_id, uint8_t val)
466 {
467 #ifdef MEC_GPIO_PIN_VALIDATION
468     if (!pin_is_valid(pin)) {
469         return MEC_RET_ERR_INVAL;
470     }
471 #endif
472 
473     if (prop_id >= MEC_GPIO_MAX_PROP_ID) {
474         return MEC_RET_ERR_INVAL;
475     }
476 
477     uint32_t msk0 = mec_cfg_tbl[prop_id].mask;
478     uint32_t bpos = mec_cfg_tbl[prop_id].bitpos;
479     uintptr_t regaddr = (uintptr_t)&MEC_GPIO->CTRL[pin];
480 
481     if (mec_cfg_tbl[prop_id].ctrl_reg) {
482         regaddr += MEC_GPIO_CTRL2_OFS;
483     }
484 
485     MEC_MMCR32(regaddr) = ((MEC_MMCR32(regaddr) & ~(msk0 << bpos))
486                            | (((uint32_t)val & msk0) << bpos));
487 
488 #ifdef MEC_GPIO_IDET_CHG_ANOMALY_FIX
489     if (prop_id == MEC_GPIO_IDET_PROP_ID) {
490         for (int i = 0; i < MEC_GPIO_EDGE_DLY_COUNT; i++) {
491             MEC_MMCR32(regaddr);
492         }
493     }
494 #endif
495 
496     return MEC_RET_OK;
497 }
498 
mec_hal_gpio_set_props(uint32_t pin,const struct mec_gpio_props * gprops,size_t nprops)499 int mec_hal_gpio_set_props(uint32_t pin, const struct mec_gpio_props *gprops, size_t nprops)
500 {
501 #ifdef MEC_GPIO_PIN_VALIDATION
502     if (!pin_is_valid(pin)) {
503         return MEC_RET_ERR_INVAL;
504     }
505 #endif
506 
507     if (!nprops) {
508         return MEC_RET_OK;
509     }
510 
511     if (!gprops) {
512         return MEC_RET_ERR_INVAL;
513     }
514 
515     uint32_t ctrl = MEC_GPIO->CTRL[pin];
516     uint32_t ctrl2 = MEC_GPIO->CTL2[pin];
517 
518     for (size_t n = 0; n < nprops; n++) {
519         uint32_t prop = gprops[n].prop;
520         uint32_t bitpos = mec_cfg_tbl[prop].bitpos;
521         uint32_t mask = mec_cfg_tbl[prop].mask;
522         uint32_t val = gprops[n].val & mask;
523 
524         if (mec_cfg_tbl[prop].ctrl_reg) {
525             ctrl2 = (ctrl2 & ~(mask << bitpos)) | (val << bitpos);
526         } else {
527             ctrl = (ctrl & ~(mask << bitpos)) | (val << bitpos);
528         }
529     }
530 
531     MEC_GPIO->CTL2[pin] = ctrl2;
532     MEC_GPIO->CTRL[pin] = ctrl;
533 
534     return MEC_RET_OK;
535 }
536 
pull_config(uint32_t config)537 static uint32_t pull_config(uint32_t config)
538 {
539     uint32_t val = MEC_GPIO_CTRL_PUD_NONE;
540 
541     switch (config & MEC5_GPIO_CFG_PULL_MSK) {
542     case MEC5_GPIO_CFG_PULL_UP:
543         val = MEC_GPIO_CTRL_PUD_PULLUP;
544         break;
545     case MEC5_GPIO_CFG_PULL_DN:
546         val = MEC_GPIO_CTRL_PUD_PULLDN;
547         break;
548     case MEC5_GPIO_CFG_PULL_KEEPER:
549         val = MEC_GPIO_CTRL_PUD_REPEATER;
550         break;
551     default:
552         break;
553     }
554 
555     return (val << MEC_GPIO_CTRL_PUD_Pos);
556 }
557 
pwrgate_config(uint32_t config)558 static uint32_t pwrgate_config(uint32_t config)
559 {
560     uint32_t val = MEC_GPIO_CTRL_PGS_VTR;
561 
562     switch (config & MEC5_GPIO_CFG_PWR_GATE_MSK) {
563     case MEC5_GPIO_CFG_PWRGT_VCC:
564         val = MEC_GPIO_CTRL_PGS_VCC;
565         break;
566     case MEC5_GPIO_CFG_PWRGT_OFF:
567         val = MEC_GPIO_CTRL_PGS_UNPWRD;
568         break;
569     default:
570         break;
571     }
572 
573     return (val << MEC_GPIO_CTRL_PGS_Pos);
574 }
575 
idet_config(uint32_t config)576 static uint32_t idet_config(uint32_t config)
577 {
578     uint32_t val = MEC_GPIO_CTRL_IDET_DIS;
579 
580     switch (config & MEC5_GPIO_CFG_IDET_POS) {
581     case MEC5_GPIO_CFG_IDET_LVL_LO:
582         val = MEC_GPIO_CTRL_IDET_LVL_LO;
583         break;
584     case MEC5_GPIO_CFG_IDET_LVL_HI:
585         val = MEC_GPIO_CTRL_IDET_LVL_HI;
586         break;
587     case MEC5_GPIO_CFG_IDET_RISING_EDG:
588         val = MEC_GPIO_CTRL_IDET_REDGE;
589         break;
590     case MEC5_GPIO_CFG_IDET_FALLING_EDG:
591         val = MEC_GPIO_CTRL_IDET_FEDGE;
592         break;
593     case MEC5_GPIO_CFG_IDET_BOTH_EDG:
594         val = MEC_GPIO_CTRL_IDET_BEDGE;
595         break;
596     default:
597         break;
598     }
599 
600     return (val << MEC_GPIO_CTRL_IDET_Pos);
601 }
602 
603 /* Program specified GPIO pin's configuration.
604  * NOTE 1: Parallel output bit cannot be written until parallel output
605  * is enabled. If parallel output is selected and we want to set the output
606  * value before enabling output then we must do:
607  *   Set output value in Control register output bit.
608  *   Program pin Control register as output. HW reflects the output value
609  *   from Control register bit to corresponding bit in parallel output register.
610  *   Enable parallel output mode.
611  * NOTE 2: Enabling interrupt detect for one of the edge modes will always
612  * trigger an edge was detected. We leave clearing this "enable" spurious status
613  * to the driver/application.
614  */
mec_hal_gpio_pin_config(uint32_t pin,uint32_t config)615 int mec_hal_gpio_pin_config(uint32_t pin, uint32_t config)
616 {
617     uint32_t ctrl;
618 
619 #ifdef MEC_GPIO_PIN_VALIDATION
620     if (!pin_is_valid(pin)) {
621         return MEC_RET_ERR_INVAL;
622     }
623 #endif
624 
625     ctrl = (config & MEC5_GPIO_CFG_DRV_STR_MSK) >> MEC5_GPIO_CFG_DRV_STR_POS;
626     ctrl <<= MEC_GPIO_CTL2_DRVSTR_Pos;
627     ctrl &= MEC_GPIO_CTL2_DRVSTR_Msk;
628 
629     if (config & MEC_BIT(MEC5_GPIO_CFG_SLEW_RATE_POS)) {
630         ctrl |= MEC_BIT(MEC_GPIO_CTL2_SLR_Pos);
631     }
632     MEC_GPIO->CTL2[pin] = ctrl;
633 
634     ctrl = (config & MEC5_GPIO_CFG_FUNC_MSK) >> MEC5_GPIO_CFG_FUNC_POS;
635     ctrl = (ctrl << MEC_GPIO_CTRL_MUX_Pos) & MEC_GPIO_CTRL_MUX_Msk;
636     if ((config & MEC5_GPIO_CFG_FUNC_MSK) && (config & MEC_BIT(MEC5_GPIO_CFG_FUNC_INV_POS))) {
637         ctrl |= MEC_BIT(MEC_GPIO_CTRL_ALTPOL_Pos);
638     }
639 
640     if (config & MEC_BIT(MEC5_GPIO_CFG_OUT_OPEN_DRAIN_POS)) { /* opendrain? */
641         ctrl |= MEC_BIT(MEC_GPIO_CTRL_OBT_Pos);
642     }
643 
644     if (config & MEC_BIT(MEC5_GPIO_CFG_DIR_OUT_POS)) { /* direction is output? */
645         ctrl |= MEC_BIT(MEC_GPIO_CTRL_DIR_Pos);
646         if (config & MEC_BIT(MEC5_GPIO_CFG_SET_OUT_VAL_POS)) {
647             if (config & MEC_BIT(MEC5_GPIO_CFG_OUT_VAL_POS)) {
648                 ctrl |= MEC_BIT(MEC_GPIO_CTRL_ALTVAL_Pos);
649             }
650         }
651     }
652 
653     ctrl |= pull_config(config);
654     ctrl |= pwrgate_config(config);
655     ctrl |= idet_config(config);
656 
657     MEC_GPIO->CTRL[pin] = ctrl;
658 
659     if (config & MEC_BIT(MEC5_GPIO_CFG_PAR_OUT_EN_POS)) {
660         MEC_GPIO->CTRL[pin] |= MEC_BIT(MEC_GPIO_CTRL_PAREN_Pos);
661     }
662 
663     return MEC_RET_OK;
664 }
665 
mec_hal_gpio_get_ctrl_nc(uint32_t pin)666 uint32_t mec_hal_gpio_get_ctrl_nc(uint32_t pin)
667 {
668     return MEC_GPIO->CTRL[pin];
669 }
670 
mec_hal_gpio_set_ctrl_nc(uint32_t pin,uint32_t ctrl_val)671 void mec_hal_gpio_set_ctrl_nc(uint32_t pin, uint32_t ctrl_val)
672 {
673     MEC_GPIO->CTRL[pin] = ctrl_val;
674 }
675 
mec_hal_gpio_port_get_ctrl_nc(uint8_t port,uint8_t port_pin_pos)676 uint32_t mec_hal_gpio_port_get_ctrl_nc(uint8_t port, uint8_t port_pin_pos)
677 {
678     uint32_t pin = mec_hal_gpio_pin_num_nc(port, port_pin_pos);
679 
680     return MEC_GPIO->CTRL[pin];
681 }
682 
mec_hal_gpio_port_set_ctrl_nc(uint8_t port,uint8_t port_pin_pos,uint32_t ctrl_val)683 void mec_hal_gpio_port_set_ctrl_nc(uint8_t port, uint8_t port_pin_pos,
684                                    uint32_t ctrl_val)
685 {
686     uint32_t pin = mec_hal_gpio_pin_num_nc(port, port_pin_pos);
687 
688     MEC_GPIO->CTRL[pin] = ctrl_val;
689 }
690 
mec_hal_gpio_get_ctrl(uint32_t pin,uint32_t * ctrl)691 int mec_hal_gpio_get_ctrl(uint32_t pin, uint32_t *ctrl)
692 {
693 #ifdef MEC_GPIO_PIN_VALIDATION
694     if (!pin_is_valid(pin)) {
695         return MEC_RET_ERR_INVAL;
696     }
697 #endif
698 
699     if (!ctrl) {
700         return MEC_RET_ERR_INVAL;
701     }
702 
703     *ctrl = MEC_GPIO->CTRL[pin];
704 
705     return MEC_RET_OK;
706 }
707 
mec_hal_gpio_set_ctrl(uint32_t pin,uint32_t new_ctrl)708 int mec_hal_gpio_set_ctrl(uint32_t pin, uint32_t new_ctrl)
709 {
710 #ifdef MEC_GPIO_PIN_VALIDATION
711     if (!pin_is_valid(pin)) {
712         return MEC_RET_ERR_INVAL;
713     }
714 #endif
715 
716     MEC_GPIO->CTRL[pin] = new_ctrl;
717 
718     return MEC_RET_OK;
719 }
720 
mec_hal_gpio_set_ctrl_mask(uint32_t pin,uint32_t val,uint32_t mask)721 int mec_hal_gpio_set_ctrl_mask(uint32_t pin, uint32_t val, uint32_t mask)
722 {
723 #ifdef MEC_GPIO_PIN_VALIDATION
724     if (!pin_is_valid(pin)) {
725         return MEC_RET_ERR_INVAL;
726     }
727 #endif
728     MEC_GPIO->CTRL[pin] = (MEC_GPIO->CTRL[pin] & ~mask) | (val & mask);
729 
730     return MEC_RET_OK;
731 }
732 
mec_hal_gpio_get_ctrl2(uint32_t pin,uint32_t * ctrl2)733 int mec_hal_gpio_get_ctrl2(uint32_t pin, uint32_t *ctrl2)
734 {
735 #ifdef MEC_GPIO_PIN_VALIDATION
736     if (!pin_is_valid(pin)) {
737         return MEC_RET_ERR_INVAL;
738     }
739 #endif
740 
741     if (!ctrl2) {
742         return MEC_RET_ERR_INVAL;
743     }
744 
745     *ctrl2 = MEC_GPIO->CTL2[pin];
746 
747     return MEC_RET_OK;
748 }
749 
mec_hal_gpio_set_ctrl2(uint32_t pin,uint32_t new_ctrl2)750 int mec_hal_gpio_set_ctrl2(uint32_t pin, uint32_t new_ctrl2)
751 {
752 #ifdef MEC_GPIO_PIN_VALIDATION
753     if (!pin_is_valid(pin)) {
754         return MEC_RET_ERR_INVAL;
755     }
756 #endif
757 
758     MEC_GPIO->CTL2[pin] = new_ctrl2;
759 
760     return MEC_RET_OK;
761 }
762 
mec_hal_gpio_ctrl2_mask(const uint32_t pin,uint32_t val,uint32_t mask)763 int mec_hal_gpio_ctrl2_mask(const uint32_t pin, uint32_t val, uint32_t mask)
764 {
765 #ifdef MEC_GPIO_PIN_VALIDATION
766     if (!pin_is_valid(pin)) {
767         return MEC_RET_ERR_INVAL;
768     }
769 #endif
770     MEC_GPIO->CTL2[pin] = (MEC_GPIO->CTL2[pin] & ~mask) | (val & mask);
771 
772     return MEC_RET_OK;
773 }
774 
mec_hal_gpio_get_slew_rate(uint32_t pin)775 int mec_hal_gpio_get_slew_rate(uint32_t pin)
776 {
777 #ifdef MEC_GPIO_PIN_VALIDATION
778     if (!pin_is_valid(pin)) {
779         return MEC_RET_ERR_INVAL;
780     }
781 #endif
782 
783     return (int)((MEC_GPIO->CTL2[pin] & MEC_GPIO_CTL2_SLR_Msk) >> MEC_GPIO_CTL2_SLR_Pos);
784 }
785 
mec_hal_gpio_set_slew_rate(uint32_t pin,enum mec_gpio_slew_rate slew_rate)786 int mec_hal_gpio_set_slew_rate(uint32_t pin, enum mec_gpio_slew_rate slew_rate)
787 {
788     uint32_t val = 0;
789 
790 #ifdef MEC_GPIO_PIN_VALIDATION
791     if (!pin_is_valid(pin)) {
792         return MEC_RET_ERR_INVAL;
793     }
794 #endif
795 
796     switch (slew_rate) {
797     case MEC_GPIO_SLEW_RATE_SLOW:
798         val = MEC_GPIO_CTL2_SLR_SLOW;
799         break;
800     case MEC_GPIO_SLEW_RATE_FAST:
801         val = MEC_GPIO_CTL2_SLR_FAST;
802         break;
803     default:
804         return MEC_RET_ERR_INVAL;
805     }
806 
807     MEC_GPIO->CTL2[pin] = ((MEC_GPIO->CTL2[pin] & ~(MEC_GPIO_CTL2_SLR_Msk))
808                            | (val << MEC_GPIO_CTL2_SLR_Pos));
809 
810     return MEC_RET_OK;
811 }
812 
mec_hal_gpio_get_drive_strength(uint32_t pin)813 int mec_hal_gpio_get_drive_strength(uint32_t pin)
814 {
815 #ifdef MEC_GPIO_PIN_VALIDATION
816     if (!pin_is_valid(pin)) {
817         return MEC_RET_ERR_INVAL;
818     }
819 #endif
820 
821     return (int)((MEC_GPIO->CTL2[pin] & MEC_GPIO_CTL2_DRVSTR_Msk) >> MEC_GPIO_CTL2_DRVSTR_Pos);
822 }
823 
mec_hal_gpio_set_drive_strength(uint32_t pin,enum mec_gpio_drive_str drive_str)824 int mec_hal_gpio_set_drive_strength(uint32_t pin, enum mec_gpio_drive_str drive_str)
825 {
826     uint32_t val = 0;
827 
828 #ifdef MEC_GPIO_PIN_VALIDATION
829     if (!pin_is_valid(pin)) {
830         return MEC_RET_ERR_INVAL;
831     }
832 #endif
833 
834     switch (drive_str) {
835     case MEC_GPIO_DRIVE_STR_1X:
836         val = MEC_GPIO_CTL2_DRVSTR_2MA;
837         break;
838     case MEC_GPIO_DRIVE_STR_2X:
839         val = MEC_GPIO_CTL2_DRVSTR_4MA;
840         break;
841     case MEC_GPIO_DRIVE_STR_4X:
842         val = MEC_GPIO_CTL2_DRVSTR_8MA;
843         break;
844     case MEC_GPIO_DRIVE_STR_6X:
845         val = MEC_GPIO_CTL2_DRVSTR_12MA;
846         break;
847     default:
848         return MEC_RET_ERR_INVAL;
849     }
850 
851     MEC_GPIO->CTL2[pin] = ((MEC_GPIO->CTL2[pin] & ~(MEC_GPIO_CTL2_DRVSTR_Msk))
852                            | (val << MEC_GPIO_CTL2_DRVSTR_Pos));
853 
854     return MEC_RET_OK;
855 }
856 
mec_hal_gpio_alt_out(const uint32_t pin,uint8_t val)857 int mec_hal_gpio_alt_out(const uint32_t pin, uint8_t val)
858 {
859 #ifdef MEC_GPIO_PIN_VALIDATION
860     if (!pin_is_valid(pin)) {
861         return MEC_RET_ERR_INVAL;
862     }
863 #endif
864 
865     if (val) {
866         MEC_GPIO->CTRL[pin] |= MEC_BIT(MEC_GPIO_CTRL_ALTVAL_Pos);
867     } else {
868         MEC_GPIO->CTRL[pin] &= (uint32_t)~MEC_BIT(MEC_GPIO_CTRL_ALTVAL_Pos);
869     }
870 
871     return MEC_RET_OK;
872 }
873 
mec_hal_gpio_alt_out_toggle(const uint32_t pin)874 int mec_hal_gpio_alt_out_toggle(const uint32_t pin)
875 {
876 #ifdef MEC_GPIO_PIN_VALIDATION
877     if (!pin_is_valid(pin)) {
878         return MEC_RET_ERR_INVAL;
879     }
880 #endif
881 
882     MEC_GPIO->CTRL[pin] ^= MEC_BIT(MEC_GPIO_CTRL_ALTVAL_Pos);
883 
884     return MEC_RET_OK;
885 }
886 
mec_hal_gpio_pad_in(const uint32_t pin,uint8_t * padin)887 int mec_hal_gpio_pad_in(const uint32_t pin, uint8_t *padin)
888 {
889 #ifdef MEC_GPIO_PIN_VALIDATION
890     if (!pin_is_valid(pin)) {
891         return MEC_RET_ERR_INVAL;
892     }
893 #endif
894     if (!padin) {
895         return MEC_RET_ERR_INVAL;
896     }
897 
898     *padin = (uint8_t)((MEC_GPIO->CTRL[pin] >> MEC_GPIO_CTRL_PADIN_Pos) & MEC_BIT(0));
899 
900     return MEC_RET_OK;
901 }
902 
mec_hal_gpio_par_in(const uint32_t pin,uint8_t * pinval)903 int mec_hal_gpio_par_in(const uint32_t pin, uint8_t *pinval)
904 {
905 #ifdef MEC_GPIO_PIN_VALIDATION
906     if (!pin_is_valid(pin)) {
907         return MEC_RET_ERR_INVAL;
908     }
909 #endif
910     if (!pinval) {
911         return MEC_RET_ERR_INVAL;
912     }
913 
914     uint32_t bitpos = pin_get_bitpos(pin & 0xffffu);
915     uint32_t port = pin_get_port(pin & 0xffffu);
916 
917     *pinval = (uint8_t)((MEC_GPIO->PARIN[port] >> bitpos) & MEC_BIT(0));
918 
919     return MEC_RET_OK;
920 }
921 
mec_hal_gpio_par_out(const uint32_t pin,const uint8_t pin_state)922 int mec_hal_gpio_par_out(const uint32_t pin, const uint8_t pin_state)
923 {
924 #ifdef MEC_GPIO_PIN_VALIDATION
925     if (!pin_is_valid(pin)) {
926         return MEC_RET_ERR_INVAL;
927     }
928 #endif
929     uint32_t port = pin_get_port(pin & 0xffffu);
930     uint32_t bitpos = pin_get_bitpos(pin & 0xffffu);
931 
932 #ifdef MEC_GPIO_PAROUT_BITBAND
933     uintptr_t bit_word_addr = (uintptr_t)(MEC_PERIPH_BITBAND_BASE)
934                               + (MEC_GPIO_PAROUT_AHB_OFS(port) * 32U)
935                               + (uintptr_t)(bitpos * 4U);
936     uint32_t bbval = (pin_state) ? 1: 0;
937 
938     MMCR32_WR(bit_word_addr, bbval);
939 #else
940     if (pin_state) {
941         MEC_GPIO->PAROUT[port] |= MEC_BIT(bitpos);
942     } else {
943         MEC_GPIO->PAROUT[port] &= (uint32_t)~MEC_BIT(bitpos);
944     }
945 #endif
946     return MEC_RET_OK;
947 }
948 
mec_hal_gpio_parin_port(const uint8_t port,uint32_t * val)949 int mec_hal_gpio_parin_port(const uint8_t port, uint32_t *val)
950 {
951     if ((port >= MEC_GPIO_PORT_MAX) || !val) {
952         return MEC_RET_ERR_INVAL;
953     }
954 
955     *val = MEC_GPIO->PARIN[port];
956 
957     return MEC_RET_OK;
958 }
959 
mec_hal_gpio_parin_by_pin(uint32_t pin,uint32_t * val)960 int mec_hal_gpio_parin_by_pin(uint32_t pin, uint32_t *val)
961 {
962 #ifdef MEC_GPIO_PIN_VALIDATION
963     if (!pin_is_valid(pin)) {
964         return MEC_RET_ERR_INVAL;
965     }
966 #endif
967     if (!val) {
968         return MEC_RET_ERR_INVAL;
969     }
970 
971     uint32_t port = pin_get_port(pin & 0xffffu);
972 
973     *val = MEC_GPIO->PARIN[port];
974 
975     return MEC_RET_OK;
976 }
977 
mec_hal_gpio_parout_port_get(const uint8_t port,uint32_t * val)978 int mec_hal_gpio_parout_port_get(const uint8_t port, uint32_t *val)
979 {
980     if ((port >= MEC_GPIO_PORT_MAX) || !val) {
981         return MEC_RET_ERR_INVAL;
982     }
983 
984     *val = MEC_GPIO->PAROUT[port];
985 
986     return MEC_RET_OK;
987 }
988 
mec_hal_gpio_parout_port_get_by_pin(uint32_t pin,uint32_t * val)989 int mec_hal_gpio_parout_port_get_by_pin(uint32_t pin, uint32_t *val)
990 {
991 #ifdef MEC_GPIO_PIN_VALIDATION
992     if (!pin_is_valid(pin)) {
993         return MEC_RET_ERR_INVAL;
994     }
995 #endif
996     if (!val) {
997         return MEC_RET_ERR_INVAL;
998     }
999 
1000     uint32_t port = pin_get_port(pin & 0xffffu);
1001 
1002     *val = MEC_GPIO->PAROUT[port];
1003 
1004     return MEC_RET_OK;
1005 }
1006 
mec_hal_gpio_parout_port(const uint8_t port,const uint32_t newval)1007 int mec_hal_gpio_parout_port(const uint8_t port, const uint32_t newval)
1008 {
1009     if (port >= MEC_GPIO_PORT_MAX) {
1010         return MEC_RET_ERR_INVAL;
1011     }
1012 
1013     MEC_GPIO->PAROUT[port] = newval;
1014 
1015     return MEC_RET_OK;
1016 }
1017 
mec_hal_gpio_parout_port_xor(const uint8_t port,const uint32_t xormask)1018 int mec_hal_gpio_parout_port_xor(const uint8_t port, const uint32_t xormask)
1019 {
1020     if (port >= MEC_GPIO_PORT_MAX) {
1021         return MEC_RET_ERR_INVAL;
1022     }
1023 
1024     MEC_GPIO->PAROUT[port] ^= xormask;
1025 
1026     return MEC_RET_OK;
1027 }
1028 
mec_hal_gpio_parout_port_set_bits(const uint8_t port,const uint32_t mask)1029 int mec_hal_gpio_parout_port_set_bits(const uint8_t port, const uint32_t mask)
1030 {
1031     if (port >= MEC_GPIO_PORT_MAX) {
1032         return MEC_RET_ERR_INVAL;
1033     }
1034 
1035     MEC_GPIO->PAROUT[port] |= mask;
1036 
1037     return MEC_RET_OK;
1038 }
1039 
mec_hal_gpio_parout_port_mask(const uint8_t port,const uint32_t newval,const uint32_t mask)1040 int mec_hal_gpio_parout_port_mask(const uint8_t port, const uint32_t newval, const uint32_t mask)
1041 {
1042     if (port >= MEC_GPIO_PORT_MAX) {
1043         return MEC_RET_ERR_INVAL;
1044     }
1045 
1046     MEC_GPIO->PAROUT[port] = (MEC_GPIO->PAROUT[port] & ~mask) | (newval & mask);
1047 
1048     return MEC_RET_OK;
1049 }
1050 
mec_hal_gpio_port_ia_ctrl(uint8_t port,uint8_t enable)1051 int mec_hal_gpio_port_ia_ctrl(uint8_t port, uint8_t enable)
1052 {
1053     if (port >= MEC_GPIO_PORT_MAX) {
1054         return MEC_RET_ERR_INVAL;
1055     }
1056 
1057     uint8_t bitpos = mec_gpio_girq_blk_pos[port];
1058 
1059     if (enable) {
1060         MEC_ECIA0->BLK_EN_SET = MEC_BIT(bitpos);
1061     } else {
1062         MEC_ECIA0->BLK_EN_CLR = MEC_BIT(bitpos);
1063     }
1064 
1065     return 0;
1066 }
1067 
mec_hal_gpio_port_pin_ia_enable(uint8_t port,uint8_t port_pin_pos,uint8_t enable)1068 int mec_hal_gpio_port_pin_ia_enable(uint8_t port, uint8_t port_pin_pos, uint8_t enable)
1069 {
1070     if (port >= MEC_GPIO_PORT_MAX) {
1071         return MEC_RET_ERR_INVAL;
1072     }
1073 
1074     uint8_t girq_idx = mec_gpio_irq_routing[port];
1075 
1076     port_pin_pos &= 0x1fu;
1077     if (enable) {
1078         MEC_ECIA0->GIRQ[girq_idx].EN_SET = MEC_BIT(port_pin_pos);
1079     } else {
1080         MEC_ECIA0->GIRQ[girq_idx].EN_CLR = MEC_BIT(port_pin_pos);
1081     }
1082 
1083     return 0;
1084 }
1085 
mec_hal_gpio_pin_ia_enable(uint8_t pin,uint8_t enable)1086 int mec_hal_gpio_pin_ia_enable(uint8_t pin, uint8_t enable)
1087 {
1088 #ifdef MEC_GPIO_PIN_VALIDATION
1089     if (!pin_is_valid(pin)) {
1090         return MEC_RET_ERR_INVAL;
1091     }
1092 #endif
1093     const uint8_t port = pin_get_port(pin);
1094     const uint8_t bitpos = pin_get_bitpos(pin);
1095 
1096     return mec_hal_gpio_port_pin_ia_enable(port, bitpos, enable);
1097 }
1098 
mec_hal_gpio_port_pin_ia_status_clear(uint8_t port,uint8_t port_pin_pos)1099 int mec_hal_gpio_port_pin_ia_status_clear(uint8_t port, uint8_t port_pin_pos)
1100 {
1101     if (port >= MEC_GPIO_PORT_MAX) {
1102         return MEC_RET_ERR_INVAL;
1103     }
1104 
1105     uint8_t girq_idx = mec_gpio_irq_routing[port];
1106 
1107     MEC_ECIA0->GIRQ[girq_idx].SOURCE = MEC_BIT(port_pin_pos & 0x1fu);
1108 
1109     return 0;
1110 }
1111 
mec_hal_gpio_pin_ia_status_clr(uint8_t pin)1112 int mec_hal_gpio_pin_ia_status_clr(uint8_t pin)
1113 {
1114 #ifdef MEC_GPIO_PIN_VALIDATION
1115     if (!pin_is_valid(pin)) {
1116         return MEC_RET_ERR_INVAL;
1117     }
1118 #endif
1119     const uint8_t port = pin_get_port(pin);
1120     const uint8_t bitpos = pin_get_bitpos(pin);
1121 
1122     return mec_hal_gpio_port_pin_ia_status_clear(port, bitpos);
1123 }
1124 
mec_hal_gpio_port_ia_status_clr_mask(uint8_t port,uint32_t mask)1125 int mec_hal_gpio_port_ia_status_clr_mask(uint8_t port, uint32_t mask)
1126 {
1127     if (port >= MEC_GPIO_PORT_MAX) {
1128         return MEC_RET_ERR_INVAL;
1129     }
1130 
1131     uint8_t girq_idx = mec_gpio_irq_routing[port];
1132 
1133     MEC_ECIA0->GIRQ[girq_idx].SOURCE = mask;
1134 
1135     return 0;
1136 }
1137 
mec_hal_gpio_port_ia_result(uint8_t port,uint32_t * result)1138 int mec_hal_gpio_port_ia_result(uint8_t port, uint32_t *result)
1139 {
1140     if ((port >= MEC_GPIO_PORT_MAX) || !result) {
1141         return MEC_RET_ERR_INVAL;
1142     }
1143 
1144     uint8_t girq_idx = mec_gpio_irq_routing[port];
1145 
1146     *result = MEC_ECIA0->GIRQ[girq_idx].RESULT;
1147 
1148     return 0;
1149 }
1150 
mec_hal_gpio_pin_is_vci_capable(uint16_t pin)1151 bool mec_hal_gpio_pin_is_vci_capable(uint16_t pin)
1152 {
1153     return pin_is_vci(pin);
1154 }
1155 
1156 /* Disable VCI functionality of a VCI pin in the VCI block.
1157  * The pin can be used as a GPIO or another non-VCI function.
1158  */
mec_hal_gpio_vci_disable(uint16_t pin)1159 int mec_hal_gpio_vci_disable(uint16_t pin)
1160 {
1161     const struct mec_gpio_vci_pin *v = find_gpio_vci_info(pin);
1162 
1163     if (!v) {
1164         return MEC_RET_ERR_INVAL;
1165     }
1166 
1167     mec_hal_vci_pin_disable(GPIO_VCI_PIN_GET(v->vci_info));
1168 
1169     return MEC_RET_OK;
1170 }
1171 
mec_hal_gpio_vci_get_func(uint16_t pin,uint8_t * func)1172 int mec_hal_gpio_vci_get_func(uint16_t pin, uint8_t *func)
1173 {
1174     const struct mec_gpio_vci_pin *v = find_gpio_vci_info(pin);
1175 
1176     if (!v || !func) {
1177         return MEC_RET_ERR_INVAL;
1178     }
1179 
1180     *func = (uint8_t)(GPIO_VCI_FUNC_GET(v->vci_info));
1181 
1182     return MEC_RET_OK;
1183 }
1184 
1185 /* end mec_gpio.c */
1186