1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef _MEC_KSCAN_API_H
7 #define _MEC_KSCAN_API_H
8 
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <device_mec5.h>
14 #include "mec_defs.h"
15 #include "mec_retval.h"
16 
17 /* Interfaces to any C modules */
18 #ifdef __cplusplus
19 extern "C"
20 {
21 #endif
22 
23 /* Key scan matrix controller */
24 
25 #define MEC_KSCAN_NUM_IRQS 1 /* number of IRQ sources per instance */
26 
27 struct mec_kscan_regs;
28 
29 enum mec_kscan_cfg_flags {
30     MEC_KSCAN_CFG_ENABLE = MEC_BIT(0),
31     MEC_KSCAN_CFG_RESET = MEC_BIT(1),
32     MEC_KSCAN_KSO_PREDRIVE_EN = MEC_BIT(2),
33     MEC_KSCAN_KSO_SELECT_DRV_HI = MEC_BIT(3),
34     MEC_KSCAN_INTR_EN = MEC_BIT(4),
35 };
36 
37 enum mec_kscan_out_sel {
38     MEC_KSCAN_KSO_SEL00 = 0,
39     MEC_KSCAN_KSO_SEL01,
40     MEC_KSCAN_KSO_SEL02,
41     MEC_KSCAN_KSO_SEL03,
42     MEC_KSCAN_KSO_SEL04,
43     MEC_KSCAN_KSO_SEL05,
44     MEC_KSCAN_KSO_SEL06,
45     MEC_KSCAN_KSO_SEL07,
46     MEC_KSCAN_KSO_SEL08,
47     MEC_KSCAN_KSO_SEL09,
48     MEC_KSCAN_KSO_SEL10,
49     MEC_KSCAN_KSO_SEL11,
50     MEC_KSCAN_KSO_SEL12,
51     MEC_KSCAN_KSO_SEL13,
52     MEC_KSCAN_KSO_SEL14,
53     MEC_KSCAN_KSO_SEL15,
54     MEC_KSCAN_KSO_SEL16,
55     MEC_KSCAN_KSO_SEL17,
56     MEC_KSCAN_KSO_MAX,
57 };
58 
59 enum mec_kscan_in {
60     MEC_KSCAN_IN0 = MEC_BIT(0),
61     MEC_KSCAN_IN1 = MEC_BIT(1),
62     MEC_KSCAN_IN2 = MEC_BIT(2),
63     MEC_KSCAN_IN3 = MEC_BIT(3),
64     MEC_KSCAN_IN4 = MEC_BIT(4),
65     MEC_KSCAN_IN5 = MEC_BIT(5),
66     MEC_KSCAN_IN6 = MEC_BIT(6),
67     MEC_KSCAN_IN7 = MEC_BIT(7),
68 };
69 
70 #define MEC_KSCAN_KSI_INTR_ALL 0xffu
71 
72 int mec_hal_kscan_init(struct mec_kscan_regs *regs, uint32_t flags, uint8_t ksi_in_intr_mask);
73 
74 int mec_hal_kscan_enable(struct mec_kscan_regs *regs, uint8_t enable);
75 bool mec_hal_kscan_is_enabled(struct mec_kscan_regs *regs);
76 
77 int mec_hal_kscan_kso_pre_drive_enable(struct mec_kscan_regs *regs, uint8_t enable);
78 
79 int mec_hal_kscan_girq_en(struct mec_kscan_regs *regs);
80 int mec_hal_kscan_girq_dis(struct mec_kscan_regs *regs);
81 int mec_hal_kscan_girq_clr(struct mec_kscan_regs *regs);
82 uint32_t mec_hal_kscan_girq_result(struct mec_kscan_regs *regs);
83 
84 void mec_hal_kscan_wake_enable(uint8_t enable);
85 
86 /* Enable key scan and enable driving all KSO pins high
87  * Preserve KSO_INVERT bit
88  * Preserve KSO_SELECT field
89  */
mec_hal_kscan_kso_drive_all(struct mec_kscan_regs * regs)90 static inline void mec_hal_kscan_kso_drive_all(struct mec_kscan_regs *regs)
91 {
92     regs->KSO_SEL = (regs->KSO_SEL & (uint8_t)~MEC_BIT(MEC_KSCAN_KSO_SEL_KSCAN_DIS_Pos))
93                     | MEC_BIT(MEC_KSCAN_KSO_SEL_KSO_ALL_Pos);
94 }
95 
mec_hal_kscan_kso_disable_keyscan(struct mec_kscan_regs * regs)96 static inline void mec_hal_kscan_kso_disable_keyscan(struct mec_kscan_regs *regs)
97 {
98     regs->KSO_SEL = (regs->KSO_SEL & (uint8_t)~MEC_BIT(MEC_KSCAN_KSO_SEL_KSO_ALL_Pos))
99                     | MEC_BIT(MEC_KSCAN_KSO_SEL_KSCAN_DIS_Pos);
100 }
101 
mec_hal_kscan_kso_invert(struct mec_kscan_regs * regs,uint8_t invert)102 static inline void mec_hal_kscan_kso_invert(struct mec_kscan_regs *regs, uint8_t invert)
103 {
104     if (invert) {
105         regs->KSO_SEL |= MEC_BIT(MEC_KSCAN_KSO_SEL_KSO_INVERT_Pos);
106     } else {
107         regs->KSO_SEL &= (uint8_t)~MEC_BIT(MEC_KSCAN_KSO_SEL_KSO_INVERT_Pos);
108     }
109 }
110 
111 /* Select KSO line and drive to value with key scan enabled */
112 static inline
mec_hal_kscan_kso_select(struct mec_kscan_regs * regs,uint8_t kso_sel,uint8_t val)113 void mec_hal_kscan_kso_select(struct mec_kscan_regs *regs, uint8_t kso_sel, uint8_t val)
114 {
115     uint8_t ksoinv = (val) ? MEC_BIT(MEC_KSCAN_KSO_SEL_KSO_INVERT_Pos) : 0;
116 
117     regs->KSO_SEL = (((kso_sel << MEC_KSCAN_KSO_SEL_OSEL_Pos) & MEC_KSCAN_KSO_SEL_OSEL_Msk)
118                      | ksoinv);
119 }
120 
mec_hal_kscan_ksi_state(struct mec_kscan_regs * regs)121 static inline uint8_t mec_hal_kscan_ksi_state(struct mec_kscan_regs *regs)
122 {
123     return regs->KSI_IN;
124 }
125 
mec_hal_kscan_ksi_status(struct mec_kscan_regs * regs)126 static inline uint8_t mec_hal_kscan_ksi_status(struct mec_kscan_regs *regs)
127 {
128     return regs->KSI_STS;
129 }
130 
mec_hal_kscan_ksi_status_clr(struct mec_kscan_regs * regs,uint8_t clrmsk)131 static inline void mec_hal_kscan_ksi_status_clr(struct mec_kscan_regs *regs, uint8_t clrmsk)
132 {
133     regs->KSI_STS = clrmsk;
134 }
135 
mec_hal_kscan_ksi_intr_en_set(struct mec_kscan_regs * regs,uint8_t enmsk)136 static inline void mec_hal_kscan_ksi_intr_en_set(struct mec_kscan_regs *regs, uint8_t enmsk)
137 {
138     regs->KSI_INT_EN = enmsk;
139 }
140 
mec_hal_kscan_ksi_intr_en_get(struct mec_kscan_regs * regs)141 static inline uint8_t mec_hal_kscan_ksi_intr_en_get(struct mec_kscan_regs *regs)
142 {
143     return regs->KSI_INT_EN;
144 }
145 
146 #ifdef __cplusplus
147 }
148 #endif
149 
150 #endif /* #ifndef _MEC_KSCAN_API_H */
151