1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef _MEC_I2C_API_H
7 #define _MEC_I2C_API_H
8 
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include "mec_retval.h"
14 
15 /* Interfaces to any C modules */
16 #ifdef __cplusplus
17 extern "C"
18 {
19 #endif
20 
21 #define MEC_I2C_SMB_BAUD_CLK_FREQ_HZ 16000000u
22 
23 #define MEC_I2C_SMB_CFG_CUST_FREQ 0x01u
24 #define MEC_I2C_SMB_CFG_PRESERVE_TARGET_ADDRS 0x02u
25 
26 /* I2C Network layer HW limited to 16-bit byte counts for TX and RX */
27 #define MEC_I2C_SMB_NL_MAX_XFR_COUNT 0xffffu
28 
29 enum mec_i2c_status {
30     MEC_I2C_STS_LL_NBB_POS = 0,
31     MEC_I2C_STS_LL_LAB_POS,
32     MEC_I2C_STS_LL_AAT_POS, /* addressed as target: match one of OWN_ADDR */
33     MEC_I2C_STS_LL_LRB_AD0_POS,
34     MEC_I2C_STS_LL_BER_POS,
35     MEC_I2C_STS_LL_STO_POS,
36     MEC_I2C_STS_LL_SAD_POS, /* SMBus address decoded */
37     MEC_I2C_STS_LL_NIPEND_POS,
38     MEC_I2C_STS_DEV_TMOUT_POS = 8, /* device timeout */
39     MEC_I2C_STS_CM_CUM_TMOUT_POS, /* controller mode cumulative timeout */
40     MEC_I2C_STS_TM_CUM_TMOUT_POS, /* target mode cumulative timeout */
41     MEC_I2C_STS_CHDL_POS,
42     MEC_I2C_STS_CHDH_POS,
43     MEC_I2C_STS_BERR_POS,
44     MEC_I2C_STS_LAB_POS,
45     MEC_I2C_STS_TM_NACK_POS = 16,
46     MEC_I2C_STS_TM_RCV_DONE_RO_POS, /* Valid when TM_DONE=1. Receive phase finished else transmit phase finished */
47     MEC_I2C_STS_TM_PERR_POS = 19, /* Target mode protocol error */
48     MEC_I2C_STS_TM_RPTS_RD_POS, /* Target mode repeated start with read address detected */
49     MEC_I2C_STS_TM_RPTS_WR_POS, /* Target mode repeated start with write address detected */
50     MEC_I2C_STS_CM_TX_NACK_POS = 24, /* Controller mode transmit received NACK from target */
51     MEC_I2C_STS_CM_TX_DONE_RO_POS,
52     MEC_I2C_STS_IDLE_POS = 29,
53     MEC_I2C_STS_CM_DONE_POS,
54     MEC_I2C_STS_TM_DONE_POS,
55 };
56 
57 enum mec_i2c_ctrl {
58     MEC_I2C_CTRL_ACK_EN_POS = 0,
59     MEC_I2C_CTRL_STO_GEN_POS,
60     MEC_I2C_CTRL_STA_EN_POS,
61     MEC_I2C_CTRL_ENI_POS,
62     MEC_I2C_CTRL_ESO_POS = 6,
63     MEC_I2C_CTRL_STS_CLR_POS,
64 };
65 
66 enum mec_i2c_std_freq {
67     MEC_I2C_STD_FREQ_100K = 0,
68     MEC_I2C_STD_FREQ_400K,
69     MEC_I2C_STD_FREQ_1M,
70     MEC_I2C_STD_FREQ_MAX
71 };
72 
73 enum mec_i2c_target_mode_addr {
74     MEC_I2C_TARGET_ADDR_0 = 0,
75     MEC_I2C_TARGET_ADDR_1,
76     MEC_I2C_TARGET_ADDR_MAX,
77 };
78 
79 enum mec_i2c_start {
80     MEC_I2C_NO_START = 0,
81     MEC_I2C_NORM_START,
82     MEC_I2C_RPT_START,
83 };
84 
85 enum mec_i2c_ien {
86     MEC_I2C_IEN_BYTE_MODE_POS = 0,
87     MEC_I2C_IEN_IDLE_POS,
88     MEC_I2C_NL_IEN_CM_DONE_POS,
89     MEC_I2C_NL_IEN_TM_DONE_POS,
90     MEC_I2C_NL_IEN_AAT_POS,
91 };
92 
93 enum mec_i2c_nl_cm_event {
94     MEC_I2C_NL_CM_EVENT_NONE = 0,
95     MEC_I2C_NL_CM_EVENT_W2R,
96     MEC_I2C_NL_CM_EVENT_ALL_DONE,
97 };
98 
99 enum mec_i2c_nl_tm_event {
100     MEC_I2C_NL_TM_EVENT_NONE = 0,
101     MEC_I2C_NL_TM_EVENT_W2R,
102     MEC_I2C_NL_TM_EVENT_ALL_DONE,
103 };
104 
105 struct mec_i2c_freq_cfg {
106     uint32_t freqhz;
107     uint32_t idle_scaling;
108     uint32_t timeout_scaling;
109     uint32_t data_timing;
110     uint16_t bus_clk;
111     uint8_t rpt_start_hold_time;
112 };
113 
114 struct mec_i2c_smb_cfg {
115     uint8_t std_freq;
116     uint8_t cfg_flags;
117     uint8_t port;
118     uint8_t target_addr1;
119     uint8_t target_addr2;
120 };
121 
122 /* forward declaration */
123 struct mec_i2c_smb_regs;
124 
125 /* MEC I2C-SMB Control structure required by API */
126 struct mec_i2c_smb_ctx {
127     struct mec_i2c_smb_regs *base;
128     uint32_t devi;
129     uint16_t wrcnt;
130     uint16_t rdcnt;
131     uint16_t cmdctrl;
132     uint8_t i2c_ctrl_cached;
133     uint8_t rsvd[1];
134 };
135 
136 int mec_hal_i2c_smb_reset(struct mec_i2c_smb_ctx *ctx);
137 
138 int mec_hal_i2c_smb_init(struct mec_i2c_smb_ctx *ctx, struct mec_i2c_smb_cfg *config,
139                          struct mec_i2c_freq_cfg *custom_freq_cfg);
140 
141 int mec_hal_i2c_smb_bus_freq_get(struct mec_i2c_smb_ctx *ctx, uint32_t *bus_freq_hz);
142 
143 int mec_hal_i2c_smb_ctrl_set(struct mec_i2c_smb_ctx *ctx, uint8_t ctrl);
144 uint8_t mec_hal_i2c_smb_ctrl_get(struct mec_i2c_smb_ctx *ctx);
145 
146 int mec_hal_i2c_cmd_ack_ctrl(struct mec_i2c_smb_ctx *ctx, uint8_t ack_en);
147 
148 int mec_hal_i2c_smb_is_bus_owned(struct mec_i2c_smb_ctx *ctx);
149 
150 int mec_hal_i2c_smb_get_target_addr(struct mec_i2c_smb_ctx *ctx, uint8_t target_id,
151                                     uint16_t *target_addr);
152 int mec_hal_i2c_smb_set_target_addr(struct mec_i2c_smb_ctx *ctx, uint8_t target_id,
153                                     uint16_t target_addr);
154 int mec_hal_i2c_smb_clr_target_addr(struct mec_i2c_smb_ctx *ctx, uint16_t target_addr);
155 
156 int mec_hal_i2c_smb_auto_ack_enable(struct mec_i2c_smb_ctx *ctx, uint8_t ien);
157 int mec_hal_i2c_smb_auto_ack_disable(struct mec_i2c_smb_ctx *ctx, uint8_t ien);
158 
159 #define MEC_I2C_SMB_GIRQ_EN 0x1
160 #define MEC_I2C_SMB_GIRQ_DIS 0x2
161 #define MEC_I2C_SMB_GIRQ_CLR_STS 0x4
162 
163 int mec_hal_i2c_smb_girq_ctrl(struct mec_i2c_smb_ctx *ctx, int flags);
164 int mec_hal_i2c_smb_girq_status_clr(struct mec_i2c_smb_ctx *ctx);
165 int mec_hal_i2c_smb_girq_status(struct mec_i2c_smb_ctx *ctx);
166 int mec_hal_i2c_smb_girq_result(struct mec_i2c_smb_ctx *ctx);
167 
168 uint32_t mec_hal_i2c_smb_wake_status(struct mec_i2c_smb_ctx *ctx);
169 void mec_hal_i2c_smb_wake_status_clr(struct mec_i2c_smb_ctx *ctx);
170 
171 int mec_hal_i2c_smb_idle_intr_enable(struct mec_i2c_smb_ctx *ctx, uint8_t enable);
172 
173 /* mask are enum mec_i2c_ien values */
174 int mec_hal_i2c_smb_intr_ctrl(struct mec_i2c_smb_ctx *ctx, uint32_t mask, uint8_t en);
175 
176 uint32_t mec_hal_i2c_smb_status(struct mec_i2c_smb_ctx *ctx, uint8_t clear);
177 int mec_hal_i2c_smb_is_idle_intr(struct mec_i2c_smb_ctx *ctx);
178 int mec_hal_i2c_smb_is_idle_ien(struct mec_i2c_smb_ctx *ctx);
179 int mec_hal_i2c_smb_idle_status_clr(struct mec_i2c_smb_ctx *ctx);
180 
181 bool mec_hal_i2c_smb_is_aat_ien(struct mec_i2c_smb_ctx *ctx);
182 
183 /* enable per byte interrupt */
184 #define MEC_I2C_SMB_BYTE_ENI 0x01
185 
186 int mec_hal_i2c_smb_start_gen(struct mec_i2c_smb_ctx *ctx, uint8_t target_addr, int flags);
187 
188 /* Generate an I2C STOP only if the bus owned by this controller */
189 int mec_hal_i2c_smb_stop_gen(struct mec_i2c_smb_ctx *ctx);
190 
191 int mec_hal_i2c_smb_rearm_target_rx(struct mec_i2c_smb_ctx *ctx);
192 
193 int mec_hal_i2c_smb_xmit_byte(struct mec_i2c_smb_ctx *ctx, uint8_t msg_byte);
194 
195 int mec_hal_i2c_smb_read_byte(struct mec_i2c_smb_ctx *ctx, uint8_t *msg_byte);
196 
197 #define MEC_I2C_BB_SCL_POS 0
198 #define MEC_I2C_BB_SDA_POS 1
199 
200 int mec_hal_i2c_smb_bbctrl(struct mec_i2c_smb_ctx *ctx, uint8_t enable, uint8_t pin_drive);
201 uint8_t mec_hal_i2c_smb_bbctrl_pin_states(struct mec_i2c_smb_ctx *ctx);
202 
203 /* ---- I2C Network Layer ---- */
204 struct mec_i2c_smb_nl_state {
205     uint16_t wrcnt;
206     uint16_t rdcnt;
207     uint16_t ctrl;
208 };
209 
210 #define MEC_I2C_NL_FLAG_START       0x01
211 #define MEC_I2C_NL_FLAG_RPT_START   0x02
212 #define MEC_I2C_NL_FLAG_STOP        0x04
213 #define MEC_I2C_NL_FLAG_CM_DONE_IEN 0x100u
214 #define MEC_I2C_NL_FLAG_IDLE_IEN    0x200u
215 
216 int mec_hal_i2c_nl_cm_cfg_start(struct mec_i2c_smb_ctx *ctx, uint16_t ntx, uint16_t nrx,
217                                 uint32_t flags);
218 
219 #define MEC_I2C_NL_CM_SEL 0
220 #define MEC_I2C_NL_TM_SEL 1
221 
222 int mec_hal_i2c_nl_cmd_clear(struct mec_i2c_smb_ctx *ctx, uint8_t is_tm);
223 int mec_hal_i2c_nl_cm_proceed(struct mec_i2c_smb_ctx *ctx);
224 int mec_hal_i2c_nl_tm_proceed(struct mec_i2c_smb_ctx *ctx);
225 
226 uint32_t mec_hal_i2c_nl_cmd_get(struct mec_i2c_smb_ctx *ctx, uint8_t is_tm);
227 
228 int mec_hal_i2c_nl_state_get(struct mec_i2c_smb_regs *regs, struct mec_i2c_smb_nl_state *state,
229                              uint8_t is_tm);
230 
231 uint32_t mec_hal_i2c_nl_cm_event(struct mec_i2c_smb_ctx *ctx);
232 
233 #define MEC_I2C_NL_CM_DIR_WR 0
234 #define MEC_I2C_NL_CM_DIR_RD 1
235 
236 uint32_t mec_hal_i2c_nl_cm_xfr_count_get(struct mec_i2c_smb_regs *regs, uint8_t is_read);
237 int mec_hal_i2c_nl_cm_xfr_count_set(struct mec_i2c_smb_regs *regs, uint8_t is_read, uint32_t cnt);
238 
mec_hal_i2c_nl_flush_buffers(struct mec_i2c_smb_regs * regs)239 static inline void mec_hal_i2c_nl_flush_buffers(struct mec_i2c_smb_regs *regs)
240 {
241     regs->CONFIG |= (MEC_BIT(MEC_I2C_SMB_CONFIG_FLUSH_TM_TXB_Pos)
242                      | MEC_BIT(MEC_I2C_SMB_CONFIG_FLUSH_TM_RXB_Pos)
243                      | MEC_BIT(MEC_I2C_SMB_CONFIG_FLUSH_CTXB_Pos)
244                      | MEC_BIT(MEC_I2C_SMB_CONFIG_FLUSH_CRXB_Pos));
245 }
246 
247 /* Get copy of address transmitted by external controller.
248  * b[0]=nW/R, b[7:1]=7-bit I2C target address.
249  * Reading this register does not trigger HW FSM to change state.
250  */
mec_hal_i2c_nl_shad_addr_get(struct mec_i2c_smb_regs * regs)251 static inline uint8_t mec_hal_i2c_nl_shad_addr_get(struct mec_i2c_smb_regs *regs)
252 {
253     return (uint8_t)(regs->SHAD_ADDR & 0xffu);
254 }
255 
256 /* Get copy of last data byte transmitted or received.
257  * Reading this register does not trigger HW FSM to change state.
258  */
mec_hal_i2c_nl_shad_data_get(struct mec_i2c_smb_regs * regs)259 static inline uint8_t mec_hal_i2c_nl_shad_data_get(struct mec_i2c_smb_regs *regs)
260 {
261     return (uint8_t)(regs->SHAD_DATA & 0xffu);
262 }
263 
264 /* ---- I2C-NL Target Mode ---- */
265 #define MEC_I2C_NL_TM_FLAG_DONE_IEN 0x01
266 #define MEC_I2C_NL_TM_FLAG_AAT_IEN  0x02
267 #ifdef MEC5_I2C_SMB_HAS_STOP_DETECT_IRQ
268 #define MEC_I2C_NL_TM_FLAG_STOP_IEN  0x04
269 #endif
270 #define MEC_I2C_NL_TM_FLAG_RUN 0x08
271 
272 int mec_hal_i2c_nl_tm_config(struct mec_i2c_smb_ctx *ctx, uint16_t ntx, uint16_t nrx,
273                              uint32_t flags);
274 
275 uint32_t mec_hal_i2c_nl_tm_event(struct mec_i2c_smb_ctx *ctx);
276 
277 #define MEC_I2C_NL_TM_DIR_TX 0 /* We supply data to external Controller */
278 #define MEC_I2C_NL_TM_DIR_RX 1 /* We clock in data from external Controller */
279 
280 uint32_t mec_hal_i2c_nl_tm_xfr_count_get(struct mec_i2c_smb_ctx *ctx, uint8_t is_rx);
281 int mec_hal_i2c_nl_tm_xfr_count_set(struct mec_i2c_smb_regs *regs, uint8_t is_read, uint32_t cnt);
282 uint32_t mec_hal_i2c_nl_tm_transfered(struct mec_i2c_smb_ctx *ctx, uint8_t is_rx);
283 
284 /* ---- Power Management ---- */
285 void mec_hal_i2c_pm_save_disable(void);
286 void mec_hal_i2c_pm_restore(void);
287 
288 #ifdef __cplusplus
289 }
290 #endif
291 
292 #endif /* #ifndef _MEC_I2C_API_H */
293