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_CFG_CUST_FREQ 0x01u
22
23 enum mec_i2c_status {
24 MEC_I2C_STS_LL_NBB_POS = 0,
25 MEC_I2C_STS_LL_LAB_POS,
26 MEC_I2C_STS_LL_AAS_POS,
27 MEC_I2C_STS_LL_LRB_AD0_POS,
28 MEC_I2C_STS_LL_BER_POS,
29 MEC_I2C_STS_LL_STO_POS,
30 MEC_I2C_STS_LL_SAD_POS,
31 MEC_I2C_STS_LL_NIPEND_POS,
32 MEC_I2C_STS_DEV_TMOUT_POS = 8, /* device timeout */
33 MEC_I2C_STS_CM_CUM_TMOUT_POS, /* controller mode cumulative timeout */
34 MEC_I2C_STS_TM_CUM_TMOUT_POS, /* target mode cumulative timeout */
35 MEC_I2C_STS_CHDL_POS,
36 MEC_I2C_STS_CHDH_POS,
37 MEC_I2C_STS_BERR_POS,
38 MEC_I2C_STS_LAB_POS,
39 MEC_I2C_STS_TM_NACK_POS = 16,
40 MEC_I2C_STS_TM_RX_DONE_RO_POS,
41 MEC_I2C_STS_TM_PERR_POS = 19, /* Target mode protocol error */
42 MEC_I2C_STS_TM_RPTS_RD_POS, /* Target mode repeated start with read address detected */
43 MEC_I2C_STS_TM_RPTS_WR_POS, /* Target mode repeated start with write address detected */
44 MEC_I2C_STS_CM_TX_NACK_POS = 24, /* Controller mode transmit received NACK from target */
45 MEC_I2C_STS_CM_TX_DONE_RO_POS,
46 MEC_I2C_STS_IDLE_POS = 29,
47 MEC_I2C_STS_CM_DONE_POS,
48 MEC_I2C_STS_TM_DONE_POS,
49 };
50
51 enum mec_i2c_ctrl {
52 MEC_I2C_CTRL_ACK_EN_POS = 0,
53 MEC_I2C_CTRL_STO_GEN_POS,
54 MEC_I2C_CTRL_STA_EN_POS,
55 MEC_I2C_CTRL_ENI_POS,
56 MEC_I2C_CTRL_ESO_POS = 6,
57 MEC_I2C_CTRL_STS_CLR_POS,
58 };
59
60 enum mec_i2c_std_freq {
61 MEC_I2C_STD_FREQ_100K = 0,
62 MEC_I2C_STD_FREQ_400K,
63 MEC_I2C_STD_FREQ_1M,
64 MEC_I2C_STD_FREQ_MAX
65 };
66
67 enum mec_i2c_start {
68 MEC_I2C_NO_START = 0,
69 MEC_I2C_NORM_START,
70 MEC_I2C_RPT_START,
71 };
72
73 enum mec_i2c_ien {
74 MEC_I2C_IEN_BYTE_MODE_POS = 0,
75 MEC_I2C_IEN_IDLE_POS,
76 MEC_I2C_NL_IEN_CM_DONE_POS,
77 MEC_I2C_NL_IEN_TM_DONE_POS,
78 MEC_I2C_NL_IEN_AAT_POS,
79 };
80
81 enum mec_i2c_nl_cm_event {
82 MEC_I2C_NL_CM_EVENT_NONE = 0,
83 MEC_I2C_NL_CM_EVENT_W2R,
84 MEC_I2C_NL_CM_EVENT_ALL_DONE,
85 };
86
87 struct mec_i2c_freq_cfg {
88 uint32_t freqhz;
89 uint32_t idle_scaling;
90 uint32_t timeout_scaling;
91 uint32_t data_timing;
92 uint16_t bus_clk;
93 uint8_t rpt_start_hold_time;
94 };
95
96 struct mec_i2c_smb_cfg {
97 uint8_t std_freq;
98 uint8_t cfg_flags;
99 uint8_t port;
100 uint8_t target_addr1;
101 uint8_t target_addr2;
102 };
103
104 /* forward declaration */
105 struct mec_i2c_smb_regs;
106
107 /* MEC I2C-SMB Control structure required by API */
108 struct mec_i2c_smb_ctx {
109 struct mec_i2c_smb_regs *base;
110 uint32_t devi;
111 uint8_t i2c_ctrl_cached;
112 uint8_t rsvd[3];
113 };
114
115 int mec_hal_i2c_smb_reset(struct mec_i2c_smb_ctx *ctx);
116
117 int mec_hal_i2c_smb_init(struct mec_i2c_smb_ctx *ctx, struct mec_i2c_smb_cfg *config,
118 struct mec_i2c_freq_cfg *custom_freq_cfg);
119
120 int mec_hal_i2c_smb_ctrl_set(struct mec_i2c_smb_ctx *ctx, uint8_t ctrl);
121 uint8_t mec_hal_i2c_smb_ctrl_get(struct mec_i2c_smb_ctx *ctx);
122
123 int mec_hal_i2c_smb_is_bus_owned(struct mec_i2c_smb_ctx *ctx);
124
125 int mec_hal_i2c_smb_auto_ack_enable(struct mec_i2c_smb_ctx *ctx, uint8_t ien);
126 int mec_hal_i2c_smb_auto_ack_disable(struct mec_i2c_smb_ctx *ctx, uint8_t ien);
127
128 #define MEC_I2C_SMB_GIRQ_EN 0x1
129 #define MEC_I2C_SMB_GIRQ_DIS 0x2
130 #define MEC_I2C_SMB_GIRQ_CLR_STS 0x4
131
132 int mec_hal_i2c_smb_girq_ctrl(struct mec_i2c_smb_ctx *ctx, int flags);
133 int mec_hal_i2c_smb_girq_status_clr(struct mec_i2c_smb_ctx *ctx);
134 int mec_hal_i2c_smb_girq_status(struct mec_i2c_smb_ctx *ctx);
135 int mec_hal_i2c_smb_girq_result(struct mec_i2c_smb_ctx *ctx);
136
137 uint32_t mec_hal_i2c_smb_wake_status(struct mec_i2c_smb_ctx *ctx);
138 void mec_hal_i2c_smb_wake_status_clr(struct mec_i2c_smb_ctx *ctx);
139
140 int mec_hal_i2c_smb_idle_intr_enable(struct mec_i2c_smb_ctx *ctx, uint8_t enable);
141
142 /* mask are enum mec_i2c_ien values */
143 int mec_hal_i2c_smb_intr_ctrl(struct mec_i2c_smb_ctx *ctx, uint32_t mask, uint8_t en);
144
145 uint32_t mec_hal_i2c_smb_status(struct mec_i2c_smb_ctx *ctx, uint8_t clear);
146 int mec_hal_i2c_smb_is_idle_intr(struct mec_i2c_smb_ctx *ctx);
147 int mec_hal_i2c_smb_idle_status_clr(struct mec_i2c_smb_ctx *ctx);
148
149 /* enable per byte interrupt */
150 #define MEC_I2C_SMB_BYTE_ENI 0x01
151
152 int mec_hal_i2c_smb_start_gen(struct mec_i2c_smb_ctx *ctx, uint8_t target_addr, int flags);
153
154 /* Generate an I2C STOP only if the bus owned by this controller */
155 int mec_hal_i2c_smb_stop_gen(struct mec_i2c_smb_ctx *ctx);
156
157 int mec_hal_i2c_smb_rearm_target_rx(struct mec_i2c_smb_ctx *ctx);
158
159 int mec_hal_i2c_smb_xmit_byte(struct mec_i2c_smb_ctx *ctx, uint8_t msg_byte);
160
161 int mec_hal_i2c_smb_read_byte(struct mec_i2c_smb_ctx *ctx, uint8_t *msg_byte);
162
163 #define MEC_I2C_BB_SCL_POS 0
164 #define MEC_I2C_BB_SDA_POS 1
165
166 int mec_hal_i2c_smb_bbctrl(struct mec_i2c_smb_ctx *ctx, uint8_t enable, uint8_t pin_drive);
167 uint8_t mec_hal_i2c_smb_bbctrl_pin_states(struct mec_i2c_smb_ctx *ctx);
168
169 /* I2C Network Layer */
170 #define MEC_I2C_NL_FLAG_START 0x01
171 #define MEC_I2C_NL_FLAG_RPT_START 0x02
172 #define MEC_I2C_NL_FLAG_STOP 0x04
173 #define MEC_I2C_NL_FLAG_CM_DONE_IEN 0x100u
174
175 int mec_hal_i2c_nl_cm_cfg_start(struct mec_i2c_smb_ctx *ctx, uint16_t ntx, uint16_t nrx,
176 uint32_t flags);
177
178 uint32_t mec_hal_i2c_nl_cm_event(struct mec_i2c_smb_regs *regs);
179
mec_hal_i2c_nl_cm_cmd(struct mec_i2c_smb_regs * regs)180 static inline uint32_t mec_hal_i2c_nl_cm_cmd(struct mec_i2c_smb_regs *regs)
181 {
182 return regs->CM_CMD;
183 }
184
mec_hal_i2c_nl_cm_proceed(struct mec_i2c_smb_regs * regs)185 static inline void mec_hal_i2c_nl_cm_proceed(struct mec_i2c_smb_regs *regs)
186 {
187 regs->CM_CMD |= MEC_BIT(MEC_I2C_SMB_CM_CMD_MPROCEED_Pos);
188 }
189
mec_hal_i2c_nl_cm_txb_write(struct mec_i2c_smb_regs * regs,uint8_t data_byte)190 static inline void mec_hal_i2c_nl_cm_txb_write(struct mec_i2c_smb_regs *regs, uint8_t data_byte)
191 {
192 regs->CM_TXB = data_byte;
193 }
194
mec_hal_i2c_nl_tm_cmd(struct mec_i2c_smb_regs * regs)195 static inline uint32_t mec_hal_i2c_nl_tm_cmd(struct mec_i2c_smb_regs *regs)
196 {
197 return regs->TM_CMD;
198 }
199
mec_hal_i2c_nl_tm_proceed(struct mec_i2c_smb_regs * regs)200 static inline void mec_hal_i2c_nl_tm_proceed(struct mec_i2c_smb_regs *regs)
201 {
202 regs->TM_CMD |= MEC_BIT(MEC_I2C_SMB_TM_CMD_SPROCEED_Pos);
203 }
204
205 void mec_hal_i2c_pm_save_disable(void);
206 void mec_hal_i2c_pm_restore(void);
207
208 #ifdef __cplusplus
209 }
210 #endif
211
212 #endif /* #ifndef _MEC_I2C_API_H */
213