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