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