1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 /**
10  * @addtogroup I3C
11  * @{
12  *
13  * @brief Provides Improved Inter-Integrated Circuit (I3C) interfaces.
14  *
15  * This module allows a driver to perform operations on an I3C controller for accessing devices on the I3C bus,
16  * including creating and destroying I3C controller handles as well as reading and writing data.
17  *
18  * @since 1.0
19  */
20 
21 /**
22  * @file i3c_if.h
23  *
24  * @brief Declares the standard I3C interface functions.
25  *
26  * @since 1.0
27  */
28 
29 #ifndef I3C_IF_H
30 #define I3C_IF_H
31 
32 #include "platform_if.h"
33 
34 #ifdef __cplusplus
35 #if __cplusplus
36 extern "C" {
37 #endif
38 #endif /* __cplusplus */
39 
40 /** CCC(Common Command Code) structure */
41 struct I3cCccCmd;
42 
43 /** Broatcast commands */
44 #define I3C_CCC_ENEC_B        0x00
45 #define I3C_CCC_DISEC_B       0x01
46 #define I3C_CCC_ENTAS0_B      0x02
47 #define I3C_CCC_ENTAS1_B      0x03
48 #define I3C_CCC_ENTAS2_B      0x04
49 #define I3C_CCC_ENTAS3_B      0x05
50 #define I3C_CCC_RSTDAA_B      0x06
51 #define I3C_CCC_ENTDAA        0x07
52 #define I3C_CCC_DEFSLVS       0x08
53 #define I3C_CCC_SETMWL_B      0x09
54 #define I3C_CCC_SETMRL_B      0x0a
55 #define I3C_CCC_ENTTM         0x0b
56 #define I3C_CCC_ENDXFER       0X12
57 #define I3C_CCC_ENTHDR0       0x20
58 #define I3C_CCC_ENTHDR1       0x21
59 #define I3C_CCC_ENTHDR2       0x22
60 #define I3C_CCC_ENTHDR3       0x23
61 #define I3C_CCC_ENTHDR4       0x24
62 #define I3C_CCC_ENTHDR5       0x25
63 #define I3C_CCC_ENTHDR6       0x26
64 #define I3C_CCC_ENTHDR7       0x27
65 #define I3C_CCC_SETXTIME_B    0x28
66 #define I3C_CCC_SETAASA       0X29
67 #define I3C_CCC_VENDOR_B      0x61
68 /** Driect commands */
69 #define I3C_CCC_ENEC_D        0x80
70 #define I3C_CCC_DISEC_D       0x81
71 #define I3C_CCC_ENTAS0_D      0x82
72 #define I3C_CCC_ENTAS1_D      0x83
73 #define I3C_CCC_ENTAS2_D      0x84
74 #define I3C_CCC_ENTAS3_D      0x85
75 #define I3C_CCC_RSTDAA_D      0x86
76 #define I3C_CCC_SETDASA       0x87
77 #define I3C_CCC_SETNEWDA      0x88
78 #define I3C_CCC_SETMWL_D      0x89
79 #define I3C_CCC_SETMRL_D      0x8a
80 #define I3C_CCC_GETMWL        0x8b
81 #define I3C_CCC_GETMRL        0x8c
82 #define I3C_CCC_GETPID        0x8d
83 #define I3C_CCC_GETBCR        0x8e
84 #define I3C_CCC_GETDCR        0x8f
85 #define I3C_CCC_GETSTATUS     0x90
86 #define I3C_CCC_GETACCMST     0x91
87 #define I3C_CCC_SETBRGTGT     0x93
88 #define I3C_CCC_GETMXDS       0x94
89 #define I3C_CCC_GETHDRCAP     0x95
90 #define I3C_CCC_SETXTIME_D    0x98
91 #define I3C_CCC_GETXTIME      0x99
92 #define I3C_CCC_VENDOR_D      0xe0
93 
94 struct I3cCccCmd {
95     /** CCC(Common Command Code) */
96     uint8_t cmd;
97     /** The destination address of the command, valid only if sending a direct CCC. */
98     uint16_t dest;
99     /** When sending a read command, <b>dataLength</b> represents the length of the read data */
100     uint32_t dataLength;
101     /** When sending a read command, <b>buf</b> is address of the buffer for storing transferred data */
102     uint8_t *buf;
103 };
104 
105 enum TransMode {
106     /** I2C transfer mode */
107     I2C_MODE = 0,
108     /** I3C transfer mode */
109     I3C_MODE,
110     /** CCC(Common Command Code) mode */
111     CCC_CMD_MODE,
112 };
113 
114 enum I3cBusMode {
115     /** Single Data Rate mode */
116     I3C_BUS_SDR_MODE = 0,
117     /** High Data Rate mode */
118     I3C_BUS_HDR_MODE,
119 };
120 
121 /**
122  * @brief Defines the configurations of I3C controller.
123  *
124  * @since 1.0
125  */
126 struct I3cConfig {
127     /** I3C bus mode */
128     enum I3cBusMode busMode;
129     /** Current host object, its <b>NULL</b> when the controller is the host */
130     struct I3cDevice *curHost;
131 };
132 
133 /**
134  * @brief Defines the I3C transfer message used during I3C transfer, I2C transfer or sending CCC(Common Command Code).
135  *
136  * @attention This structure does not limit the data transfer length specified by <b>len</b>.
137  * The specific I3C controller determines the maximum length allowed. \n
138  * The device address <b>addr</b> indicates the original device address and does not need to
139  * contain the read/write flag bit.
140  *
141  * @since 1.0
142  */
143 struct I3cMsg {
144     /** Address of the target device */
145     uint16_t addr;
146     /** Address of the buffer for storing transferred data */
147     uint8_t *buf;
148     /** Length of the transferred data */
149     uint16_t len;
150     /**
151      * Transfer Mode Flag | Description
152      * ------------| -----------------------
153      * I2C_FLAG_READ | Read flag
154      * I2C_FLAG_READ_NO_ACK | No-ACK read flag
155      * I2C_FLAG_IGNORE_NO_ACK | Ignoring no-ACK flag
156      * I2C_FLAG_NO_START | No START condition flag
157      * I2C_FLAG_STOP | STOP condition flag
158      */
159     uint16_t flags;
160     /** Transfer mode select, using I2C_MODE defalut */
161     enum TransMode mode;
162     /** CCC(Common Command Code) structure, which is used in CCC_CMD_MODE transfer mode */
163     struct I3cCccCmd *ccc;
164     /** I3C error code, update by driver */
165     uint16_t err;
166 };
167 
168 /**
169  * @brief Defines the data of I3C IBI(In-Band Interrupt).
170  *
171  * @attention The data of IBI can be obtained by payload and buf in the IBI function when generate an IBI.
172  *
173  * @since 1.0
174  */
175 struct I3cIbiData {
176     /** payload data length. Indicates the length of IBI payload data. It is automatically generated when an
177      *  IBI is generated, do not modify while reading.
178      */
179     uint32_t payload;
180     /** data buffer. The pointer of payload data. */
181     uint8_t *buf;
182 };
183 
184 enum I3cFlag {
185     /** Read flag. The value <b>1</b> indicates the read operation, and <b>0</b> indicates the write operation. */
186     I3C_FLAG_READ           = (0x1 << 0),
187     /** Non-ACK read flag. The value <b>1</b> indicates that no ACK signal is sent during the read process. */
188     I3C_FLAG_READ_NO_ACK    = (0x1 << 11),
189     /** Ignoring no-ACK flag. The value <b>1</b> indicates that the non-ACK signal is ignored. */
190     I3C_FLAG_IGNORE_NO_ACK  = (0x1 << 12),
191     /**
192      * No START condition flag. The value <b>1</b> indicates that there is no START condition for the message
193      * transfer.
194      */
195     I3C_FLAG_NO_START       = (0x1 << 14),
196     /** STOP condition flag. The value <b>1</b> indicates that the current transfer ends with a STOP condition. */
197     I3C_FLAG_STOP           = (0x1 << 15),
198 };
199 
200 /**
201  * @brief IBI(In-Band Interrupt) callback function.
202  *
203  * Use {@link I3cRequestIbi} to attach it to an I3C device.
204  *
205  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
206  * @param addr Indicates the address of device to requeset IBI(In-Band Interrupt).
207  * @param data Indicates the data structure of IBI.
208  *
209  * @return Returns <b>0</b> if the operation is successful; Returns a negative value otherwise.
210  * @since 1.0
211  */
212 typedef int32_t (*I3cIbiFunc)(DevHandle handle, uint16_t addr, struct I3cIbiData data);
213 
214 /**
215  * @brief Obtains the handle of an I3C controller.
216  *
217  * You must call this function before accessing the I3C bus.
218  *
219  * @param number Indicates the I3C controller ID.
220  *
221  * @return Returns the pointer to the {@link DevHandle} of the I3C controller if the operation is successful;
222  * returns <b>NULL</b> otherwise.
223  *
224  * @since 1.0
225  */
226 DevHandle I3cOpen(int16_t number);
227 
228  /**
229  * @brief Releases the handle of an I3C controller.
230  *
231  * If you no longer need to access the I3C controller, you should call this function to close its handle so as
232  * to release unused memory resources.
233  *
234  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
235  *
236  * @since 1.0
237  */
238 void I3cClose(DevHandle handle);
239 
240  /**
241  * @brief Launches an transfer to an I3C device or a compatible I2C device,
242  *         or send a CCC (Common Command Code) to an I3C device which is supported.
243  *
244  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
245  * @param msg Indicates the pointer to the I3C transfer message structure array.
246  * @param count Indicates the length of the message structure array.
247  * @param mode Indicates the transmission mode.
248  *
249  * @return Returns the number of transferred message structures if the operation is successful;
250  * returns a negative value otherwise.
251  * @see I3cMsg
252  * @attention This function does not limit the number of message structures specified by <b>count</b> or the data
253  * length of each message structure. The specific I3C controller determines the maximum number and data length allowed.
254  *
255  * @since 1.0
256  */
257 int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msg, int16_t count, enum TransMode mode);
258 
259  /**
260  * @brief Requeset an IBI(in-bind interrupt) for an I3C device which is supported.
261  *
262  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
263  * @param addr Indicates the address of device to requeset IBI(In-Band Interrupt).
264  * @param func Indicates the call back function of the IBI.
265  * @param payload Indicates the length of payload data, in bytes.
266  *
267  * @return Returns <b>0</b> if the operation is successful; Returns a negative value otherwise.
268  *
269  * @since 1.0
270  */
271 int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t payload);
272 
273  /**
274  * @brief Free the IBI(in-bind interrupt) which is Requeseted by {@link I3cRequestIbi}.
275  *
276  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
277  * @param addr Indicates the address of device to free IBI.
278  *
279  * @return Returns <b>0</b> if the operation is successful; Returns a negative value otherwise.
280  *
281  * @since 1.0
282  */
283 int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
284 
285  /**
286  * @brief Set the config of a I3C controller.
287  *
288  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
289  * @param config Indicates the pointer of a configuration structure to set.
290  *
291  * @return Returns <b>0</b> if the operation is successful; Returns a negative value otherwise.
292  *
293  * @since 1.0
294  */
295 int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
296 
297  /**
298  * @brief Get the config of a I3C controller.
299  *
300  * @param handle Indicates the pointer to the device handle of the I3C controller obtained via {@link I3cOpen}.
301  * @param config Indicates the structure used to store the configuration.
302  *
303  * @return Returns <b>0</b> if the operation is successful; Returns a negative value otherwise.
304  *
305  * @since 1.0
306  */
307 int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
308 
309 #ifdef __cplusplus
310 #if __cplusplus
311 }
312 #endif
313 #endif /* __cplusplus */
314 
315 #endif /* I3C_IF_H */
316 /** @} */
317