1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _SEDI_DRIVER_I2C_H_
8 #define _SEDI_DRIVER_I2C_H_
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include "sedi_driver_common.h"
15 
16 /*!
17  * \defgroup sedi_driver_i2c I2C
18  * \ingroup sedi_driver
19  */
20 
21 #define SEDI_I2C_API_VERSION SEDI_DRIVER_VERSION_MAJOR_MINOR(0, 1)
22 
23 /****** I2C Control Codes *****/
24 
25 /*!
26  * \defgroup i2c_control_codes  I2C Control Codes
27  * \ingroup sedi_driver_i2c
28  * \{
29  */
30 
31 /*!
32  * \def SEDI_I2C_OWN_ADDRESS
33  * \brief Set Own Slave Address; arg = address
34  */
35 #define SEDI_I2C_OWN_ADDRESS (0x01)
36 
37 /*!
38  * \def SEDI_I2C_BUS_SPEED
39  * \brief Set Bus Speed; arg = speed
40  */
41 #define SEDI_I2C_BUS_SPEED (0x02)
42 
43 /*!
44  * \def SEDI_I2C_BUS_CLEAR
45  * \brief Execute Bus clear: send nine clock pulses
46  */
47 #define SEDI_I2C_BUS_CLEAR (0x03)
48 
49 /*!
50  * \def SEDI_I2C_ABORT_TRANSFER
51  * \brief Abort Master/Slave Transmit/Receive
52  */
53 #define SEDI_I2C_ABORT_TRANSFER (0x04)
54 
55 /*!
56  * \def SEDI_I2C_SET_TX_MEMORY_TYPE
57  * \brief Control function parameter, set DMA memory type, only used to tell
58  *        driver tx buffer located in DRAM.
59  */
60 #define SEDI_I2C_SET_TX_MEMORY_TYPE (0x05)
61 
62 /*!
63  * \def SEDI_I2C_SET_RX_MEMORY_TYPE
64  * \brief Control function parameter, set DMA memory type, only used to tell
65  *        driver rx buffer located in DRAM.
66  */
67 #define SEDI_I2C_SET_RX_MEMORY_TYPE (0x06)
68 
69 /*!
70  * \}
71  */
72 
73 /*----- I2C Bus Speed -----*/
74 
75 /*!
76  * \defgroup i2c_bus_speed  I2C Bus Speed
77  * \ingroup sedi_driver_i2c
78  * \{
79  */
80 
81 /*!
82  * \def SEDI_I2C_BUS_SPEED_STANDARD
83  * \brief Standard Speed (100kHz)
84  */
85 #define SEDI_I2C_BUS_SPEED_STANDARD (0x01)
86 
87 /*!
88  * \def SEDI_I2C_BUS_SPEED_FAST
89  * \brief Fast Speed (400kHz)
90  */
91 #define SEDI_I2C_BUS_SPEED_FAST (0x02)
92 
93 /*!
94  * \def SEDI_I2C_BUS_SPEED_FAST_PLUS
95  * \brief Fast+ Speed (1MHz)
96  */
97 #define SEDI_I2C_BUS_SPEED_FAST_PLUS (0x03)
98 
99 /*!
100  * \def SEDI_I2C_BUS_SPEED_HIGH
101  * \brief High Speed (3.4MHz)
102  */
103 #define SEDI_I2C_BUS_SPEED_HIGH (0x04)
104 
105 /*!
106  * \}
107  */
108 
109 /****** I2C Address Flags *****/
110 
111 /*!
112  * \defgroup i2c_address_flags  I2C Address Flags
113  * \ingroup sedi_driver_i2c
114  * \{
115  */
116 
117 /*!
118  * \def SEDI_I2C_ADDRESS_10BIT
119  * \brief 10-bit address flag
120  */
121 #define SEDI_I2C_ADDRESS_10BIT (0x0400)
122 
123 /*!
124  * \def SEDI_I2C_ADDRESS_GC
125  * \brief General Call flag
126  */
127 #define SEDI_I2C_ADDRESS_GC (0x8000)
128 
129 /*!
130  * \}
131  */
132 
133 /****** I2C Event *****/
134 
135 /*!
136  * \defgroup i2c_event I2C Event Types
137  * \ingroup sedi_driver_i2c
138  * \{
139  */
140 
141 #define SEDI_I2C_EVENT_TRANSFER_NONE (0)
142 
143 /*!
144  * \def SEDI_I2C_EVENT_TRANSFER_DONE
145  * \brief Master/Slave Transmit/Receive finished
146  */
147 #define SEDI_I2C_EVENT_TRANSFER_DONE (1UL << 0)
148 
149 /*!
150  * \def SEDI_I2C_EVENT_TRANSFER_INCOMPLETE
151  * \brief Master/Slave Transmit/Receive incomplete transfer
152  */
153 #define SEDI_I2C_EVENT_TRANSFER_INCOMPLETE (1UL << 1)
154 
155 /*!
156  * \def SEDI_I2C_EVENT_SLAVE_TRANSMIT
157  * \brief Slave Transmit operation requested
158  */
159 #define SEDI_I2C_EVENT_SLAVE_TRANSMIT (1UL << 2)
160 
161 /*!
162  * \def SEDI_I2C_EVENT_SLAVE_RECEIVE
163  * \brief Slave Receive operation requested
164  */
165 #define SEDI_I2C_EVENT_SLAVE_RECEIVE (1UL << 3)
166 
167 /*!
168  * \def SEDI_I2C_EVENT_ADDRESS_NACK
169  * \brief Address not acknowledged from Slave
170  */
171 #define SEDI_I2C_EVENT_ADDRESS_NACK (1UL << 4)
172 
173 /*!
174  * \def SEDI_I2C_EVENT_GENERAL_CALL
175  * \brief General Call indication
176  */
177 #define SEDI_I2C_EVENT_GENERAL_CALL (1UL << 5)
178 
179 /*!
180  * \def SEDI_I2C_EVENT_ARBITRATION_LOST
181  * \brief Master lost arbitration
182  */
183 #define SEDI_I2C_EVENT_ARBITRATION_LOST (1UL << 6)
184 
185 /*!
186  * \def SEDI_I2C_EVENT_BUS_ERROR
187  * \brief Bus error detected (START/STOP at illegal position)
188  */
189 #define SEDI_I2C_EVENT_BUS_ERROR (1UL << 7)
190 
191 /*!
192  * \def SEDI_I2C_EVENT_BUS_CLEAR
193  * \brief Bus clear finished
194  */
195 #define SEDI_I2C_EVENT_BUS_CLEAR (1UL << 8)
196 
197 /*!
198  * \}
199  */
200 
201 /****** I2C Usage Limits *****/
202 
203 /*!
204  * \defgroup i2c_usage_limits  I2C Usage Limits
205  * \ingroup sedi_driver_i2c
206  * \{
207  */
208 
209 /*!
210  * \def SEDI_I2C_DMA_LENGTH_LIMIT
211  * \brief define the minimal data length if use dma transfer
212  */
213 #define SEDI_I2C_DMA_LENGTH_LIMIT (2)
214 
215 /*!
216  * \}
217  */
218 
219 /*!
220  * \struct sedi_i2c_status_t
221  * \brief I2C Status
222  * \ingroup sedi_driver_i2c
223  */
224 typedef volatile struct {
225 	/**< Busy flag */
226 	uint32_t busy : 1;
227 	/**< Mode: 0=Slave, 1=Master */
228 	uint32_t mode : 1;
229 	/**< Direction: 0=Transmitter, 1=Receiver */
230 	uint32_t direction : 1;
231 	/**< General Call indication (cleared for next Slave operation) */
232 	uint32_t general_call : 1;
233 	/**< Master lost arbitration (cleared for next Master operation) */
234 	uint32_t arbitration_lost : 1;
235 	/**< Bus error detected (cleared for next operation) */
236 	uint32_t bus_error : 1;
237 	/* Event for I2C transfer */
238 	uint32_t event : 9;
239 	uint32_t reserved : 17;
240 } sedi_i2c_status_t;
241 
242 /*!
243  * \struct sedi_i2c_capabilities_t
244  * \brief I2C Driver Capabilities.
245  * \ingroup sedi_driver_i2c
246  */
247 typedef struct {
248 	uint32_t address_10_bit : 1; /**< supports 10-bit addressing */
249 	uint32_t dma : 1;	    /**< supports DMA */
250 	uint32_t is_available : 1;   /** 1:available 0:used by host  **/
251 	uint32_t rx_buffer_depth : 9;
252 	uint32_t tx_buffer_depth : 9;
253 	uint32_t reserved : 11;      /**< Reserved (must be zero) */
254 } sedi_i2c_capabilities_t;
255 
256 /*!
257  * \struct sedi_i2c_bus_clk_t
258  * \brief I2C bus clock frequency configuration.
259  * \ingroup sedi_driver_i2c
260  */
261 typedef struct{
262 	uint16_t		sda_hold;
263 	uint16_t		hcnt;
264 	uint16_t		lcnt;
265 } sedi_i2c_bus_clk_t;
266 
267 /*!
268  * \struct sedi_i2c_bus_info_t
269  * \brief I2C bus clock frequency configuration for each mode.
270  * \ingroup sedi_driver_i2c
271  */
272 typedef struct {
273 	sedi_i2c_bus_clk_t	std_clk;
274 	sedi_i2c_bus_clk_t	fst_clk;
275 	sedi_i2c_bus_clk_t	fsp_clk;
276 	sedi_i2c_bus_clk_t	high_clk;
277 } sedi_i2c_bus_info_t;
278 
279 /*!
280  * \defgroup i2c_event_handler I2C Event Handler Callback
281  * \ingroup sedi_driver_i2c
282  * \{
283  */
284 
285 /*!
286  * \typedef sedi_i2c_event_cb_t
287  * \brief Callback function type for signal i2c event.
288  * \param[in] event: event type. see \ref i2c_event
289  * \return    void
290  */
291 typedef void (*sedi_i2c_event_cb_t)(IN uint32_t event);
292 
293 /*!
294  * \}
295  */
296 
297 /*!
298  * \defgroup i2c_function_calls I2C Driver Function Calls
299  * \ingroup sedi_driver_i2c
300  * \{
301  */
302 
303 /*!
304  * \brief Get the i2c driver's API version.
305  * \return the version of current i2c driver's API
306  */
307 sedi_driver_version_t sedi_i2c_get_version(void);
308 
309 /*!
310  * \brief Get the device's capabilities.
311  * \param[in] i2c_device: i2c device id
312  * \param[out] cap: i2c device capabilities
313  * \return  \ref return_status
314  */
315 int sedi_i2c_get_capabilities(IN sedi_i2c_t i2c_device,
316 			      sedi_i2c_capabilities_t *cap);
317 
318 /*!
319  * \brief Initialize the device
320  * \param[in] i2c_device: i2c device id
321  * \param[in] cb: the callback function which can receive device's events.
322  * \param[in] base: register base address of the i2c device.
323  * \return  \ref return_status
324  */
325 int32_t sedi_i2c_init(IN sedi_i2c_t i2c_device, IN sedi_i2c_event_cb_t cb,
326 		IN uint32_t base);
327 
328 /*!
329  * \brief Uninitialize the device
330  * \param[in] i2c_device: i2c device id
331  * \return  \ref return_status
332  */
333 int32_t sedi_i2c_uninit(IN sedi_i2c_t i2c_device);
334 
335 /*!
336  * \brief Set the device's power
337  * \param[in] i2c_device: i2c device id
338  * \param[in] state: the power state to be set to the device
339  * \return  \ref return_status
340  */
341 int32_t sedi_i2c_set_power(IN sedi_i2c_t i2c_device,
342 			   IN sedi_power_state_t state);
343 
344 /*!
345  * \brief Start transmitting data to i2c slave device as master
346  * \param[in] i2c_device: i2c device id
347  * \param[in] addr: slave address (7-bit or 10-bit)
348  * \param[in] *data: pointer of the buffer with data
349  *                   which need write to the slave
350  * \param[in] num: number of data bytes to transfer
351  * \param[in] pending: i2c data transfer operation is pending
352  *                     ('Stop' signal will not be sent)
353  * \return  \ref return_status
354  */
355 int32_t sedi_i2c_master_write_async(IN sedi_i2c_t i2c_device, IN uint32_t addr,
356 				    IN uint8_t *data, IN uint32_t num,
357 				    IN bool pending);
358 
359 /*!
360  * \brief Start receiving data from i2c slave device as master
361  * \param[in] i2c_device: i2c device id
362  * \param[in] addr: slave address (7-bit or 10-bit)
363  * \param[in] *data: pointer of the buffer for data from the slave device
364  * \param[out] num: number of data bytes to receive
365  * \param[in] pending: i2c data transfer operation is pending
366  *                     ('Stop' signal will not be sent)
367  * \return  \ref return_status
368  */
369 int32_t sedi_i2c_master_read_async(IN sedi_i2c_t i2c_device, IN uint32_t addr,
370 				   OUT uint8_t *data, IN uint32_t num,
371 				   IN bool pending);
372 
373 /*!
374  * \brief Start transmitting data to i2c slave device as master
375  * \note DMA function do not support transfer length smaller than 3 bytes.
376  * \param[in] i2c_device: i2c device id
377  * \param[in] dma: dma device id
378  * \param[in] dma_chan: dma channel id
379  * \param[in] addr: slave address (7-bit or 10-bit)
380  * \param[in] *data: pointer of the buffer with data
381  *                   which need write to the slave
382  * \param[in] num: number of data bytes to transfer
383  * \param[in] pending: i2c data transfer operation is pending
384  *                     ('Stop' signal will not be sent)
385  * \return  \ref return_status
386  */
387 int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t dma,
388 				  IN uint32_t dma_chan, IN uint32_t addr,
389 				  IN uint8_t *data, IN uint32_t num,
390 				  IN bool pending);
391 
392 /*!
393  * \brief Start receiving data from i2c slave device as master
394  * \note As the DW I2C needs 2 channels to do RX DMA operation, need to add
395  * another parameter. \param[in] i2c_device: i2c device id \param[in] dma: dma
396  * device id \param[in] dma_chan: dma channel id \param[in] addr: slave address
397  * (7-bit or 10-bit) \param[in] *data: pointer of the buffer for data from the
398  * slave device \param[out] num: number of data bytes to receive \param[in]
399  * pending: i2c data transfer operation is pending
400  *                     ('Stop' signal will not be sent)
401  * DMA function do not support transfer length smaller than 3 bytes.
402  * \return  \ref return_status
403  */
404 int32_t sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device, IN uint32_t dma,
405 				 IN uint32_t dma_chan, IN uint32_t cmd_dma_chan,
406 				 IN uint32_t addr, OUT uint8_t *data,
407 				 IN uint32_t num, IN bool pending);
408 
409 /*!
410  * \brief Send data to i2c slave device as master through polling mode.
411  * \param[in] i2c_device: i2c device id
412  * \param[in] addr: slave address (7-bit or 10-bit)
413  * \param[in] *data: pointer of the buffer with data
414  *                   which need write to the slave
415  * \param[in] num: number of data bytes to transfer
416  * \param[in] pending: i2c data transfer operation is pending
417  *                     ('Stop' signal will not be sent)
418  * \return  \ref return_status
419  */
420 int32_t sedi_i2c_master_poll_write(IN sedi_i2c_t i2c_device, IN uint32_t addr,
421 				   IN uint8_t *data, IN uint32_t num,
422 				   IN bool pending);
423 
424 /*!
425  * \brief Receiving data from i2c slave device as master through polling mode
426  * \param[in] i2c_device: i2c device id
427  * \param[in] addr: slave address (7-bit or 10-bit)
428  * \param[in] *data: pointer of the buffer for data from the slave device
429  * \param[out] num: number of data bytes to receive
430  * \param[in] pending: i2c data transfer operation is pending
431  *                     ('Stop' signal will not be sent)
432  * \return  \ref return_status
433  */
434 int32_t sedi_i2c_master_poll_read(IN sedi_i2c_t i2c_device, IN uint32_t addr,
435 				  OUT uint8_t *data, IN uint32_t num,
436 				  IN bool pending);
437 
438 /*!
439  * \brief  Get transferred data count
440  * \param[in] i2c_device: i2c device id
441  * \return number of data bytes transferred;
442  *         -1 when slave is not addressed by master
443  */
444 int32_t sedi_i2c_get_data_count(IN sedi_i2c_t i2c_device);
445 
446 /*!
447  * \brief  Control the i2c device
448  * \param[in] i2c_device: i2c device id
449  * \param[in] control: control operation code. see \ref i2c_control_codes
450  * \param[in] arg: argument of operation (optional)
451  * \return  \ref return_status
452  */
453 int32_t sedi_i2c_control(IN sedi_i2c_t i2c_device, IN uint32_t control,
454 			 IN uint32_t arg);
455 
456 /*!
457  * \brief  Get device's status
458  * \param[in] i2c_device: i2c device id
459  * \param[out] status: i2c device status
460  * \return  \ref return_status
461  */
462 int sedi_i2c_get_status(IN sedi_i2c_t i2c_device, sedi_i2c_status_t *status);
463 
464 /*!
465  * \brief Handle devices's interrupt
466  * \param[in] i2c_device: i2c device id
467  * \return  void
468  */
469 void sedi_i2c_isr_handler(IN sedi_i2c_t i2c_device);
470 
471 /*!
472  * \}
473  */
474 
475 #ifdef __cplusplus
476 }
477 #endif
478 
479 #endif /* _SEDI_DRIVER_I2C_H_*/
480