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