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  * \def SEDI_I2C_EVENT_DMA_ERROR
199  * \brief DMA error detected
200  */
201 #define SEDI_I2C_EVENT_DMA_ERROR (1UL << 12)
202 
203 /*!
204  * \}
205  */
206 
207 /****** I2C Usage Limits *****/
208 
209 /*!
210  * \defgroup i2c_usage_limits  I2C Usage Limits
211  * \ingroup sedi_driver_i2c
212  * \{
213  */
214 
215 /*!
216  * \def SEDI_I2C_DMA_LENGTH_LIMIT
217  * \brief define the minimal data length if use dma transfer
218  */
219 #define SEDI_I2C_DMA_LENGTH_LIMIT (2)
220 
221 /*!
222  * \}
223  */
224 
225 /*!
226  * \struct sedi_i2c_status_t
227  * \brief I2C Status
228  * \ingroup sedi_driver_i2c
229  */
230 typedef volatile struct {
231 	/**< Busy flag */
232 	uint32_t busy : 1;
233 	/**< Mode: 0=Slave, 1=Master */
234 	uint32_t mode : 1;
235 	/**< Direction: 0=Transmitter, 1=Receiver */
236 	uint32_t direction : 1;
237 	/**< General Call indication (cleared for next Slave operation) */
238 	uint32_t general_call : 1;
239 	/**< Master lost arbitration (cleared for next Master operation) */
240 	uint32_t arbitration_lost : 1;
241 	/**< Bus error detected (cleared for next operation) */
242 	uint32_t bus_error : 1;
243 	/* Event for I2C transfer */
244 	uint32_t event : 13;
245 	uint32_t reserved : 13;
246 } sedi_i2c_status_t;
247 
248 /*!
249  * \struct sedi_i2c_capabilities_t
250  * \brief I2C Driver Capabilities.
251  * \ingroup sedi_driver_i2c
252  */
253 typedef struct {
254 	uint32_t address_10_bit : 1; /**< supports 10-bit addressing */
255 	uint32_t dma : 1;	    /**< supports DMA */
256 	uint32_t is_available : 1;   /** 1:available 0:used by host  **/
257 	uint32_t rx_buffer_depth : 9;
258 	uint32_t tx_buffer_depth : 9;
259 	uint32_t reserved : 11;      /**< Reserved (must be zero) */
260 } sedi_i2c_capabilities_t;
261 
262 /*!
263  * \struct sedi_i2c_bus_clk_t
264  * \brief I2C bus clock frequency configuration.
265  * \ingroup sedi_driver_i2c
266  */
267 typedef struct{
268 	uint16_t		sda_hold;
269 	uint16_t		hcnt;
270 	uint16_t		lcnt;
271 } sedi_i2c_bus_clk_t;
272 
273 /*!
274  * \struct sedi_i2c_bus_info_t
275  * \brief I2C bus clock frequency configuration for each mode.
276  * \ingroup sedi_driver_i2c
277  */
278 typedef struct {
279 	sedi_i2c_bus_clk_t	std_clk;
280 	sedi_i2c_bus_clk_t	fst_clk;
281 	sedi_i2c_bus_clk_t	fsp_clk;
282 	sedi_i2c_bus_clk_t	high_clk;
283 } sedi_i2c_bus_info_t;
284 
285 /*!
286  * \defgroup i2c_event_handler I2C Event Handler Callback
287  * \ingroup sedi_driver_i2c
288  * \{
289  */
290 
291 /*!
292  * \typedef sedi_i2c_event_cb_t
293  * \brief Callback function type for signal i2c event.
294  * \param[in] event: event type. see \ref i2c_event
295  * \return    void
296  */
297 typedef void (*sedi_i2c_event_cb_t)(IN uint32_t event);
298 
299 /*!
300  * \}
301  */
302 
303 /*!
304  * \defgroup i2c_function_calls I2C Driver Function Calls
305  * \ingroup sedi_driver_i2c
306  * \{
307  */
308 
309 /*!
310  * \brief Get the i2c driver's API version.
311  * \return the version of current i2c driver's API
312  */
313 sedi_driver_version_t sedi_i2c_get_version(void);
314 
315 /*!
316  * \brief Get the device's capabilities.
317  * \param[in] i2c_device: i2c device id
318  * \param[out] cap: i2c device capabilities
319  * \return  \ref return_status
320  */
321 int sedi_i2c_get_capabilities(IN sedi_i2c_t i2c_device,
322 			      sedi_i2c_capabilities_t *cap);
323 
324 /*!
325  * \brief Initialize the device
326  * \param[in] i2c_device: i2c device id
327  * \param[in] cb: the callback function which can receive device's events.
328  * \param[in] base: register base address of the i2c device.
329  * \return  \ref return_status
330  */
331 int32_t sedi_i2c_init(IN sedi_i2c_t i2c_device, IN sedi_i2c_event_cb_t cb,
332 		IN uint32_t base);
333 
334 /*!
335  * \brief Uninitialize the device
336  * \param[in] i2c_device: i2c device id
337  * \return  \ref return_status
338  */
339 int32_t sedi_i2c_uninit(IN sedi_i2c_t i2c_device);
340 
341 /*!
342  * \brief Set the device's power
343  * \param[in] i2c_device: i2c device id
344  * \param[in] state: the power state to be set to the device
345  * \return  \ref return_status
346  */
347 int32_t sedi_i2c_set_power(IN sedi_i2c_t i2c_device,
348 			   IN sedi_power_state_t state);
349 
350 /*!
351  * \brief Start transmitting data to i2c slave device as master
352  * \param[in] i2c_device: i2c device id
353  * \param[in] addr: slave address (7-bit or 10-bit)
354  * \param[in] *data: pointer of the buffer with data
355  *                   which need write to the slave
356  * \param[in] num: number of data bytes to transfer
357  * \param[in] pending: i2c data transfer operation is pending
358  *                     ('Stop' signal will not be sent)
359  * \return  \ref return_status
360  */
361 int32_t sedi_i2c_master_write_async(IN sedi_i2c_t i2c_device, IN uint32_t addr,
362 				    IN uint8_t *data, IN uint32_t num,
363 				    IN bool pending);
364 
365 /*!
366  * \brief Start receiving data from i2c slave device as master
367  * \param[in] i2c_device: i2c device id
368  * \param[in] addr: slave address (7-bit or 10-bit)
369  * \param[in] *data: pointer of the buffer for data from the slave device
370  * \param[out] num: number of data bytes to receive
371  * \param[in] pending: i2c data transfer operation is pending
372  *                     ('Stop' signal will not be sent)
373  * \return  \ref return_status
374  */
375 int32_t sedi_i2c_master_read_async(IN sedi_i2c_t i2c_device, IN uint32_t addr,
376 				   OUT uint8_t *data, IN uint32_t num,
377 				   IN bool pending);
378 
379 /*!
380  * \brief Start transmitting data to i2c slave device as master
381  * \note DMA function do not support transfer length smaller than 3 bytes.
382  * \param[in] i2c_device: i2c device id
383  * \param[in] addr: slave address (7-bit or 10-bit)
384  * \param[in] *data: pointer of the buffer with data
385  *                   which need write to the slave
386  * \param[in] num: number of data bytes to transfer
387  * \param[in] pending: i2c data transfer operation is pending
388  *                     ('Stop' signal will not be sent)
389  * \param[in] dma_dev: dma device id
390  * \param[in] dma_chan: dma channel id
391  * \return  \ref return_status
392  */
393 int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr,
394 	IN uint8_t *data, IN uint32_t num, IN bool pending,
395 	IN uint32_t dma_dev, IN uint32_t dma_chan);
396 
397 /*!
398  * \brief Start receiving data from i2c slave device as master
399  * \note DMA function do not support transfer length smaller than 3 bytes.
400  * \note As the DW I2C needs 2 channels to do RX DMA operation, need to add
401  *			another parameter.
402  * \param[in] i2c_device: i2c device id
403  * \param[in] addr: slave address(7-bit or 10-bit)
404  * \param[in] *data: pointer of the buffer for data from the slave device
405  * \param[out] num: number of data bytes to receive
406  * \param[in] pending: i2c data transfer operation is pending
407  *                     ('Stop' signal will not be sent)
408  * \param[in] rx_dma_dev: rx dma device id
409  * \param[in] rx_dma_chan: rx dma channel id
410  * \param[in] cmd_dma_dev: cmd dma device id
411  * \param[in] cmd_dma_chan: cmd dma channel id
412  * \return  \ref return_status
413  */
414 int32_t sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr,
415 	OUT uint8_t *data, IN uint32_t num, IN bool pending,
416 	IN uint32_t rx_dma_dev, IN uint32_t rx_dma_chan,
417 	IN uint32_t cmd_dma_dev, IN uint32_t cmd_dma_chan);
418 
419 /*!
420  * \brief Send data to i2c slave device as master through polling mode.
421  * \param[in] i2c_device: i2c device id
422  * \param[in] addr: slave address (7-bit or 10-bit)
423  * \param[in] *data: pointer of the buffer with data
424  *                   which need write to the slave
425  * \param[in] num: number of data bytes to transfer
426  * \param[in] pending: i2c data transfer operation is pending
427  *                     ('Stop' signal will not be sent)
428  * \return  \ref return_status
429  */
430 int32_t sedi_i2c_master_poll_write(IN sedi_i2c_t i2c_device, IN uint32_t addr,
431 				   IN uint8_t *data, IN uint32_t num,
432 				   IN bool pending);
433 
434 /*!
435  * \brief Receiving data from i2c slave device as master through polling mode
436  * \param[in] i2c_device: i2c device id
437  * \param[in] addr: slave address (7-bit or 10-bit)
438  * \param[in] *data: pointer of the buffer for data from the slave device
439  * \param[out] num: number of data bytes to receive
440  * \param[in] pending: i2c data transfer operation is pending
441  *                     ('Stop' signal will not be sent)
442  * \return  \ref return_status
443  */
444 int32_t sedi_i2c_master_poll_read(IN sedi_i2c_t i2c_device, IN uint32_t addr,
445 				  OUT uint8_t *data, IN uint32_t num,
446 				  IN bool pending);
447 
448 /*!
449  * \brief  Get transferred data count
450  * \param[in] i2c_device: i2c device id
451  * \return number of data bytes transferred;
452  *         -1 when slave is not addressed by master
453  */
454 int32_t sedi_i2c_get_data_count(IN sedi_i2c_t i2c_device);
455 
456 /*!
457  * \brief  Control the i2c device
458  * \param[in] i2c_device: i2c device id
459  * \param[in] control: control operation code. see \ref i2c_control_codes
460  * \param[in] arg: argument of operation (optional)
461  * \return  \ref return_status
462  */
463 int32_t sedi_i2c_control(IN sedi_i2c_t i2c_device, IN uint32_t control,
464 			 IN uint32_t arg);
465 
466 /*!
467  * \brief  Get device's status
468  * \param[in] i2c_device: i2c device id
469  * \param[out] status: i2c device status
470  * \return  \ref return_status
471  */
472 int sedi_i2c_get_status(IN sedi_i2c_t i2c_device, sedi_i2c_status_t *status);
473 
474 /*!
475  * \brief Handle devices's interrupt
476  * \param[in] i2c_device: i2c device id
477  * \return  void
478  */
479 void sedi_i2c_isr_handler(IN sedi_i2c_t i2c_device);
480 
481 /*!
482  * \}
483  */
484 
485 #ifdef __cplusplus
486 }
487 #endif
488 
489 #endif /* _SEDI_DRIVER_I2C_H_*/
490