1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     Cadence I2C module.
9  */
10 
11 #ifndef MOD_CDNS_I2C_H
12 #define MOD_CDNS_I2C_H
13 
14 #include <internal/cdns_i2c.h>
15 
16 #include <fwk_id.h>
17 #include <fwk_macros.h>
18 #include <fwk_module_idx.h>
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 
23 /*!
24  * \addtogroup GroupCDNSModule CDNS Product Modules
25  * \{
26  */
27 
28 /*!
29  * \defgroup Cadence I2C Driver
30  *
31  * \brief Driver support for Cadence I2C.
32  *
33  * \details This module provides driver support for Cadence I2C controller.
34  *
35  * \{
36  */
37 
38 /*!
39  * \brief I2C API ID.
40  */
41 enum mod_cdns_i2c_api {
42     MOD_CDNS_I2C_API_CONTROLLER_POLLED,
43     MOD_CDNS_I2C_API_TARGET_IRQ,
44     MOD_CDNS_I2C_API_COUNT,
45 };
46 
47 /*!
48  * \brief I2C Speed.
49  */
50 enum mod_cdns_i2c_speed {
51     MOD_CDNS_I2C_SPEED_NORMAL = (100 * FWK_KHZ),
52     MOD_CDNS_I2C_SPEED_FAST = (400 * FWK_KHZ),
53     MOD_CDNS_I2C_SPEED_FAST_PLUS = (1 * FWK_MHZ),
54 };
55 
56 /*!
57  * \brief Operating mode.
58  */
59 enum mod_cdns_i2c_mode {
60     MOD_CDNS_I2C_TARGET_MODE,
61     MOD_CDNS_I2C_CONTROLLER_MODE,
62 };
63 
64 /*!
65  * \brief Address size.
66  */
67 enum mod_cdns_i2c_address_size {
68     MOD_CDNS_I2C_ADDRESS_10_BIT,
69     MOD_CDNS_I2C_ADDRESS_7_BIT,
70 };
71 
72 /*!
73  * \brief Hold mode.
74  */
75 enum mod_cdns_i2c_hold {
76     MOD_CDNS_I2C_HOLD_OFF,
77     MOD_CDNS_I2C_HOLD_ON,
78 };
79 
80 /*!
81  * \brief I2C acknowledge.
82  */
83 enum mod_cdns_i2c_ack {
84     MOD_CDNS_I2C_ACK_DISABLE,
85     MOD_CDNS_I2C_ACK_ENABLE,
86 };
87 
88 /*!
89  * \brief I2C transmission state.
90  */
91 enum mod_cdns_i2c_trx_state {
92     MOD_CDNS_I2C_STATE_TX,
93     MOD_CDNS_I2C_STATE_RX,
94 };
95 
96 /*!
97  * \brief I2C interrupt mode data context.
98  */
99 struct mod_cdns_i2c_irq_data_ctx {
100     /*! Transmission state */
101     enum mod_cdns_i2c_trx_state state;
102     /*! Pointer to buffer */
103     uint8_t *data;
104     /*! Buffer size */
105     uint8_t size;
106     /*! Index to the buffer */
107     uint8_t index;
108     /*! Flag to indicate ongoing transaction */
109     bool busy;
110 };
111 
112 /*!
113  * \brief I2C device configuration.
114  */
115 struct mod_cdns_i2c_device_config {
116     /*! Base address of the device registers */
117     uintptr_t reg_base;
118 
119     /*! Reference clock (Hertz) */
120     uint64_t clock_rate_hz;
121 
122     /*! I2C bus speed (Hertz) */
123     enum mod_cdns_i2c_speed bus_speed_hz;
124 
125     /*! Acknowledge enable */
126     enum mod_cdns_i2c_ack ack_en;
127 
128     /*! Operating mode (Controller/Target) */
129     enum mod_cdns_i2c_mode mode;
130 
131     /*! Address size (7Bit/10Bit) */
132     enum mod_cdns_i2c_address_size addr_size;
133 
134     /*! Hold mode (ON/OFF) */
135     enum mod_cdns_i2c_hold hold_mode;
136 
137     /*! Target address */
138     uint16_t target_addr;
139 
140     /*! I2C IRQ */
141     uint8_t irq;
142 
143     /*! Identifier where callback notifications are sent */
144     fwk_id_t callback_mod_id;
145 
146     /*! I2C Transfer Register Size (TSR) */
147     uint16_t max_xfr_size;
148 
149     /*! I2C FIFO depth */
150     uint8_t fifo_depth;
151 };
152 
153 /*!
154  * \brief API to access the I2C controller functions in polled mode.
155  */
156 struct mod_cdns_i2c_controller_api_polled {
157     /*!
158      * \brief I2C read function.
159      *
160      * \param device_id Element identifier.
161      * \param address Address of the target.
162      * \param data Pointer to data buffer.
163      * \param length Data size to be read in bytes.
164      *
165      * \retval ::FWK_SUCCESS Operation succeeded.
166      * \return One of the other specific error codes described by the framework.
167      */
168     int (*read)(
169         fwk_id_t device_id,
170         uint16_t address,
171         char *data,
172         uint16_t length);
173 
174     /*!
175      * \brief I2C write function.
176      *
177      * \param device_id Element identifier.
178      * \param address Address of target.
179      * \param data Pointer to data buffer.
180      * \param length Data size to be written in bytes.
181      * \param stop When set to true indicates end of data transfer and interface
182      *      releases the sclk line.
183      *
184      * \retval ::FWK_SUCCESS Operation succeeded.
185      * \return One of the other specific error codes described by the framework.
186      */
187     int (*write)(
188         fwk_id_t device_id,
189         uint16_t address,
190         const char *data,
191         uint16_t length,
192         bool stop);
193 };
194 
195 /*!
196  * \brief API to access the I2C target functions in interrupt mode.
197  */
198 struct mod_cdns_i2c_target_api_irq {
199     /*!
200      * \brief I2C read function.
201      *
202      * \param device_id Element identifier.
203      * \param data Pointer to data buffer.
204      * \param length Data size to be read in bytes.
205      *
206      * \retval ::FWK_SUCCESS Operation succeeded.
207      * \return One of the other specific error codes described by the framework.
208      */
209     int (*read)(fwk_id_t device_id, uint8_t *data, uint8_t length);
210 
211     /*!
212      * \brief I2C write function.
213      *
214      * \param device_id Element identifier.
215      * \param data Pointer to data buffer.
216      * \param length Data size to be written in bytes.
217      * \param stop When set to true indicates end of data transfer and interface
218      *      releases the sclk line.
219      *
220      * \retval ::FWK_SUCCESS Operation succeeded.
221      * \return One of the other specific error codes described by the framework.
222      */
223     int (*write)(fwk_id_t device_id, uint8_t *data, uint8_t length);
224 };
225 
226 /*!
227  * \brief I2C module notifications.
228  */
229 enum mod_cdns_i2c_notifications {
230     MOD_CDNS_I2C_NOTIFICATION_IDX_RX,
231     MOD_CDNS_I2C_NOTIFICATION_IDX_TX,
232     MOD_CDNS_I2C_NOTIFICATION_IDX_ERROR,
233     MOD_CDNS_I2C_NOTIFICATION_COUNT,
234 };
235 
236 /*!
237  * \brief Identifier for I2C target receive callback notification.
238  */
239 static const fwk_id_t mod_cdns_i2c_notification_id_target_rx =
240     FWK_ID_NOTIFICATION_INIT(
241         FWK_MODULE_IDX_CDNS_I2C,
242         MOD_CDNS_I2C_NOTIFICATION_IDX_RX);
243 
244 /*!
245  * \brief Identifier for I2C target transmit callback notification.
246  */
247 static const fwk_id_t mod_cdns_i2c_notification_id_target_tx =
248     FWK_ID_NOTIFICATION_INIT(
249         FWK_MODULE_IDX_CDNS_I2C,
250         MOD_CDNS_I2C_NOTIFICATION_IDX_TX);
251 
252 /*!
253  * \brief Identifier for I2C target error callback notification.
254  */
255 static const fwk_id_t mod_cdns_i2c_notification_id_target_error =
256     FWK_ID_NOTIFICATION_INIT(
257         FWK_MODULE_IDX_CDNS_I2C,
258         MOD_CDNS_I2C_NOTIFICATION_IDX_ERROR);
259 
260 /*!
261  * \}
262  */
263 
264 /*!
265  * \}
266  */
267 
268 #endif /* MOD_CDNS_I2C_H */
269