1 /*
2  * Copyright (c) 2025 Advanced Micro Devices, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/i2c.h>
8 #include <zephyr/dt-bindings/i2c/i2c.h>
9 #include <zephyr/sys/util.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/irq.h>
12 
13 LOG_MODULE_REGISTER(i2c_cadence, CONFIG_I2C_LOG_LEVEL);
14 
15 /* Register offsets for the I2C device. */
16 #define CDNS_I2C_CR_OFFSET		0x00 /* Control Register, RW */
17 #define CDNS_I2C_SR_OFFSET		0x04 /* Status Register, RO */
18 #define CDNS_I2C_ADDR_OFFSET		0x08 /* I2C Address Register, RW */
19 #define CDNS_I2C_DATA_OFFSET		0x0C /* I2C Data Register, RW */
20 #define CDNS_I2C_ISR_OFFSET		0x10 /* IRQ Status Register, RW */
21 #define CDNS_I2C_XFER_SIZE_OFFSET	0x14 /* Transfer Size Register, RW */
22 #define CDNS_I2C_TIME_OUT_OFFSET	0x1C /* Time Out Register, RW */
23 #define CDNS_I2C_IMR_OFFSET		0x20 /* IRQ Mask Register, RO */
24 #define CDNS_I2C_IER_OFFSET		0x24 /* IRQ Enable Register, WO */
25 #define CDNS_I2C_IDR_OFFSET		0x28 /* IRQ Disable Register, WO */
26 #define CDNS_I2C_GFR_OFFSET		0x2C /* Glitch Filter Register, RW */
27 
28 /* Control Register Bit mask definitions */
29 #define CDNS_I2C_CR_HOLD		BIT(4) /* Hold the I2C Bus */
30 #define CDNS_I2C_CR_ACK_EN		BIT(3) /* Enables or disables acknowledgment */
31 #define CDNS_I2C_CR_NEA			BIT(2) /* No Extended addressing */
32 #define CDNS_I2C_CR_MS			BIT(1) /* 0 = Slave Mode, 1 = Master Mode */
33 #define CDNS_I2C_CR_RW			BIT(0) /* Transfer Dir: 0 = Transmitter, 1 = Receiver */
34 #define CDNS_I2C_CR_CLR_FIFO		BIT(6) /* Clears the FIFO on initialization */
35 
36 /* Master Enable Mask */
37 #define CDNS_I2C_CR_MASTER_EN_MASK	(CDNS_I2C_CR_ACK_EN | \
38 					 CDNS_I2C_CR_NEA | \
39 					 CDNS_I2C_CR_MS)
40 
41 /* Dividers for clock generation */
42 #define CDNS_I2C_CR_DIVA_SHIFT		14U
43 #define CDNS_I2C_CR_DIVA_MASK		((uint32_t)3U << CDNS_I2C_CR_DIVA_SHIFT)
44 #define CDNS_I2C_CR_DIVB_SHIFT		8U
45 #define CDNS_I2C_CR_DIVB_MASK		((uint32_t)0x3f << CDNS_I2C_CR_DIVB_SHIFT)
46 
47 /* Status Register Bit mask definitions */
48 #define CDNS_I2C_SR_BA			BIT(8) /* Bus is available */
49 #define CDNS_I2C_SR_TXDV		BIT(6) /* Transmit data is valid */
50 #define CDNS_I2C_SR_RXDV		BIT(5) /* Received data is valid */
51 #define CDNS_I2C_SR_RXRW		BIT(3) /* Read or Write operation */
52 
53 /*
54  * I2C Address Register Bit mask definitions
55  * Normal addressing mode uses [6:0] bits.
56  * Extended addressing mode uses [9:0] bits.
57  * A write access to this register always initiates a transfer if the I2C is in master mode.
58  */
59 #define CDNS_I2C_ADDR_MASK		0x000003FFU /* I2C Address Mask */
60 
61 /*
62  * I2C Interrupt Registers Bit mask definitions
63  * All the four interrupt registers (Status/Mask/Enable/Disable) have the same bit definitions.
64  */
65 #define CDNS_I2C_IXR_ARB_LOST		BIT(9) /* Arbitration Lost Interrupt */
66 #define CDNS_I2C_IXR_RX_UNF		BIT(7) /* RX FIFO Underflow Interrupt */
67 #define CDNS_I2C_IXR_TX_OVF		BIT(6) /* TX FIFO Overflow Interrupt */
68 #define CDNS_I2C_IXR_RX_OVF		BIT(5) /* RX FIFO Overflow Interrupt */
69 #define CDNS_I2C_IXR_SLV_RDY		BIT(4) /* Slave Ready Interrupt */
70 #define CDNS_I2C_IXR_TO			BIT(3) /* Timeout Interrupt */
71 #define CDNS_I2C_IXR_NACK		BIT(2) /* NACK Interrupt */
72 #define CDNS_I2C_IXR_DATA		BIT(1) /* Data Interrupt */
73 #define CDNS_I2C_IXR_COMP		BIT(0) /* Transfer Complete Interrupt */
74 
75 /* All Interrupt Mask */
76 #define CDNS_I2C_IXR_ALL_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \
77 					 CDNS_I2C_IXR_RX_UNF | \
78 					 CDNS_I2C_IXR_TX_OVF | \
79 					 CDNS_I2C_IXR_RX_OVF | \
80 					 CDNS_I2C_IXR_SLV_RDY | \
81 					 CDNS_I2C_IXR_TO | \
82 					 CDNS_I2C_IXR_NACK | \
83 					 CDNS_I2C_IXR_DATA | \
84 					 CDNS_I2C_IXR_COMP)
85 
86 /* Error Interrupt Mask */
87 #define CDNS_I2C_IXR_ERR_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \
88 					 CDNS_I2C_IXR_RX_UNF | \
89 					 CDNS_I2C_IXR_TX_OVF | \
90 					 CDNS_I2C_IXR_RX_OVF | \
91 					 CDNS_I2C_IXR_NACK)
92 
93 /* Enabled Interrupt Mask */
94 #define CDNS_I2C_ENABLED_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \
95 					 CDNS_I2C_IXR_RX_UNF | \
96 					 CDNS_I2C_IXR_TX_OVF | \
97 					 CDNS_I2C_IXR_RX_OVF | \
98 					 CDNS_I2C_IXR_NACK | \
99 					 CDNS_I2C_IXR_DATA | \
100 					 CDNS_I2C_IXR_COMP)
101 
102 /* System clock frequency for I2C ticks */
103 #define CDNS_I2C_TICKS_PER_SEC		CONFIG_SYS_CLOCK_TICKS_PER_SEC
104 
105 /* Default timeout ticks for I2C operations */
106 #define CDNS_I2C_TIMEOUT_TICKS		CDNS_I2C_TICKS_PER_SEC
107 
108 #define CDNS_I2C_MAX_TRANSFER_SIZE	255U /* Maximum transfer size for I2C data */
109 
110 /* Default transfer size */
111 #define CDNS_I2C_TRANSFER_SIZE_DEFAULT	(CDNS_I2C_MAX_TRANSFER_SIZE - 3U)
112 
113 /* Maximum dividers for I2C clock */
114 #define CDNS_I2C_DIVA_MAX		4U
115 #define CDNS_I2C_DIVB_MAX		64U
116 #define CDNS_I2C_CLK_DIV_FACTOR		22U
117 
118 #define CDNS_I2C_TIMEOUT_MAX		  0xFFU /* Maximum value for Timeout Register */
119 #define CDNS_I2C_POLL_US		100000U /* Polling interval in microseconds */
120 #define CDNS_I2C_TIMEOUT_US		500000U /* Timeout value for I2C operations */
121 
122 /* Event flag for I2C transfer completion */
123 #define I2C_XFER_COMPLETION_EVENT	BIT(0)
124 
125 /**
126  * struct cdns_i2c_config - Cadence I2C device private constant structure
127  * @irq_config_func: function pointer to configure I2C IRQ
128  */
129 struct cdns_i2c_config {
130 	void (*irq_config_func)(void);
131 };
132 
133 /**
134  * struct cdns_i2c_data - Cadence I2C device private data structure
135  * @membase: Base address of the I2C device.
136  * @ctrl_reg: Cached value of the control register.
137  * @input_clk: Input clock to I2C controller.
138  * @i2c_clk: Actual I2C clock speed.
139  * @fifo_depth: The depth of the transfer FIFO.
140  * @transfer_size: The maximum number of bytes in one transfer.
141  * @bus_hold_flag: Flag used in repeated start for clearing HOLD bit.
142  * @xfer_done: Transfer complete event.
143  * @err_status: Error status in Interrupt Status Register.
144  * @p_msg: Message pointer for I2C communication.
145  * @p_send_buf:	Pointer to transmit buffer.
146  * @p_recv_buf:	Pointer to receive buffer.
147  * @send_count:	Number of bytes still expected to send.
148  * @recv_count:	Number of bytes still expected to receive.
149  * @curr_recv_count: Number of bytes to be received in current transfer.
150  * @bus_mutex: Mutex for bus access synchronization
151  */
152 struct cdns_i2c_data {
153 	mem_addr_t membase;
154 	uint32_t ctrl_reg;
155 	uint32_t input_clk;
156 	uint32_t i2c_clk;
157 	uint32_t fifo_depth;
158 	uint32_t transfer_size;
159 	uint32_t bus_hold_flag;
160 
161 	struct k_event xfer_done;
162 	uint32_t err_status;
163 	struct i2c_msg *p_msg;
164 	uint8_t *p_send_buf;
165 	uint8_t *p_recv_buf;
166 	uint32_t send_count;
167 	uint32_t recv_count;
168 	uint32_t curr_recv_count;
169 
170 	struct k_mutex bus_mutex;
171 };
172 
173 /**
174  * cdns_i2c_writereg - Write a 32-bit value to a specific offset in the I2C register space.
175  * @i2c_bus: Pointer to the I2C data structure.
176  * @value: The 32-bit value to write to the register.
177  * @offset: The offset in the I2C register space where the value will be written.
178  */
cdns_i2c_writereg(const struct cdns_i2c_data * i2c_bus,uint32_t value,uintptr_t offset)179 static inline void cdns_i2c_writereg(const struct cdns_i2c_data *i2c_bus,
180 				     uint32_t value, uintptr_t offset)
181 {
182 	uintptr_t reg_address = (uintptr_t)(i2c_bus->membase) + offset;
183 
184 	sys_write32(value, reg_address);
185 }
186 
187 /**
188  * cdns_i2c_readreg - Read a 32-bit value from a specific offset in the I2C register space.
189  * @i2c_bus: Pointer to the I2C data structure.
190  * @offset: The offset in the I2C register space from which the value will be read.
191  *
192  * Return: The 32-bit value read from the register.
193  */
cdns_i2c_readreg(const struct cdns_i2c_data * i2c_bus,uintptr_t offset)194 static inline uint32_t cdns_i2c_readreg(const struct cdns_i2c_data *i2c_bus, uintptr_t offset)
195 {
196 	uintptr_t reg_address = (uintptr_t)(i2c_bus->membase) + offset;
197 
198 	return sys_read32(reg_address);
199 }
200 
201 /**
202  * cdns_i2c_enable_peripheral - Enable the Cadence I2C controller
203  * @i2c_bus: Pointer to the device's private data structure for the I2C controller
204  */
cdns_i2c_enable_peripheral(struct cdns_i2c_data * i2c_bus)205 static void cdns_i2c_enable_peripheral(struct cdns_i2c_data *i2c_bus)
206 {
207 	cdns_i2c_writereg(i2c_bus, i2c_bus->ctrl_reg, CDNS_I2C_CR_OFFSET);
208 
209 	/*
210 	 * Cadence I2C controller has a bug causing invalid reads after a timeout
211 	 * in master receiver mode. While the timeout feature is disabled,
212 	 * writing the max value to the timeout register reduces the issue.
213 	 */
214 	cdns_i2c_writereg(i2c_bus, CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET);
215 }
216 
217 /**
218  * cdns_i2c_calc_divs - Calculate clock dividers for I2C frequency
219  * @f: Pointer to the I2C target frequency (input/output)
220  * @input_clk: Input clock frequency in Hz
221  * @a: Pointer to the first divider (output)
222  * @b: Pointer to the second divider (output)
223  *
224  * On entry, @f holds the target I2C frequency. On exit, @f will hold the
225  * actual I2C frequency generated by the calculated dividers.
226  *
227  * Return: 0 on success, negative errno otherwise.
228  */
cdns_i2c_calc_divs(uint32_t * f,uint32_t input_clk,uint32_t * a,uint32_t * b)229 static int32_t cdns_i2c_calc_divs(uint32_t *f, uint32_t input_clk,
230 				  uint32_t *a, uint32_t *b)
231 {
232 	uint32_t fscl = *f;
233 	uint32_t best_fscl = *f;
234 	uint32_t actual_fscl, temp;
235 	uint32_t div_a, div_b;
236 	uint32_t calc_div_a = 0, calc_div_b = 0;
237 	uint32_t last_error, current_error;
238 	int32_t ret = 0;
239 
240 	/* calculate initial estimate for divisor_a and divisor_b */
241 	temp = input_clk / (CDNS_I2C_CLK_DIV_FACTOR * fscl);
242 
243 	/* Check if the calculated value is out of range */
244 	if ((temp == 0U) || (temp > (CDNS_I2C_DIVA_MAX * CDNS_I2C_DIVB_MAX))) {
245 		ret = -EINVAL;
246 		goto out;
247 	}
248 
249 	/* Initialize the last error to a large value (no error yet) */
250 	last_error = UINT32_MAX;
251 
252 	/* Iterate over possible values for divisor_a */
253 	for (div_a = 0; div_a < CDNS_I2C_DIVA_MAX; div_a++) {
254 		/* Calculate the corresponding divisor_b for this div_a */
255 		div_b = DIV_ROUND_UP(input_clk, CDNS_I2C_CLK_DIV_FACTOR * fscl * (div_a + 1U));
256 
257 		/* Skip invalid values of div_b */
258 		if ((div_b < 1U) || (div_b > CDNS_I2C_DIVB_MAX)) {
259 			continue;
260 		}
261 
262 		/* Adjust div_b for zero-based indexing */
263 		div_b--;
264 
265 		/* Calculate the actual fscl based on the current divisors */
266 		actual_fscl = input_clk / (CDNS_I2C_CLK_DIV_FACTOR * (div_a + 1U) * (div_b + 1U));
267 
268 		/* Skip if the actual fscl exceeds the target fscl */
269 		if (actual_fscl > fscl) {
270 			continue;
271 		}
272 
273 		/* Calculate the error between the target fscl and the actual fscl */
274 		current_error = fscl - actual_fscl;
275 
276 		/* Update the best divisors if a smaller error is found */
277 		if (last_error > current_error) {
278 			calc_div_a = div_a;
279 			calc_div_b = div_b;
280 			best_fscl = actual_fscl;
281 			last_error = current_error;
282 		}
283 	}
284 
285 	/* Set the output values */
286 	*a = calc_div_a;
287 	*b = calc_div_b;
288 	*f = best_fscl;
289 
290 out:
291 	return ret;
292 }
293 
294 /**
295  * cdns_i2c_setclk - Set the serial clock rate for the I2C device
296  * @i2c_bus: Pointer to the I2C data structure
297  * @req_i2c_speed: requested I2C clock frequency in Hz
298  *
299  * This function sets the serial clock rate for the I2C device by configuring
300  * the clock divisors in the device's control register. The device must be idle
301  * (i.e., not actively transferring data) before calling this function.
302  *
303  * The clock rate is determined by the following formula:
304  *	Fscl = Fpclk / (22 * (divisor_a + 1) * (divisor_b + 1))
305  * Where:
306  *	- Fscl is the desired I2C clock rate
307  *	- Fpclk is the input clock frequency
308  *	- divisor_a and divisor_b are the calculated divisors to achieve the desired clock rate
309  *
310  * The serial clock rate cannot exceed the input clock divided by 22. Common I2C clock
311  * rates are 100 KHz and 400 KHz.
312  *
313  * Return: 0 on success, negative error code on failure
314  */
cdns_i2c_setclk(struct cdns_i2c_data * i2c_bus,uint32_t req_i2c_speed)315 static int32_t cdns_i2c_setclk(struct cdns_i2c_data *i2c_bus, uint32_t req_i2c_speed)
316 {
317 	uint32_t div_a, div_b;
318 	uint32_t ctrl_reg;
319 	int32_t ret = 0;
320 	uint32_t fscl = req_i2c_speed;
321 
322 	/* Calculate the divider values */
323 	ret = cdns_i2c_calc_divs(&fscl, i2c_bus->input_clk, &div_a, &div_b);
324 	if (ret != 0) {
325 		goto out;
326 	}
327 	i2c_bus->i2c_clk = fscl; /* Update true SCL value */
328 
329 	/* Set new divider values in the control register */
330 	ctrl_reg = i2c_bus->ctrl_reg;
331 	ctrl_reg &= ~(CDNS_I2C_CR_DIVA_MASK | CDNS_I2C_CR_DIVB_MASK);
332 	ctrl_reg |= ((div_a << CDNS_I2C_CR_DIVA_SHIFT) |
333 		     (div_b << CDNS_I2C_CR_DIVB_SHIFT));
334 	i2c_bus->ctrl_reg = ctrl_reg;
335 	cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET);
336 
337 out:
338 	return ret;
339 }
340 
341 /**
342  * cdns_i2c_configure - Configures the I2C bus speed and initializes the I2C peripheral
343  * @dev: Pointer to the device structure representing the I2C bus
344  * @dev_config: Configuration value containing the desired I2C bus speed
345  *
346  * This function configures the I2C bus speed based on the value provided in @dev_config
347  * It then sets the appropriate clock for the I2C bus, verifies the clock is valid, and
348  * initializes the I2C peripheral. The configuration is saved to the device's data structure.
349  *
350  * Return: 0 on success, negative error value on failure
351  */
cdns_i2c_configure(const struct device * dev,uint32_t dev_config)352 static int32_t cdns_i2c_configure(const struct device *dev, uint32_t dev_config)
353 {
354 	int32_t ret = 0;
355 	struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data;
356 	uint32_t i2c_speed = 0U;
357 
358 	(void)k_mutex_lock(&i2c_bus->bus_mutex, K_FOREVER);
359 
360 	/* Check requested I2C Speed */
361 	switch (I2C_SPEED_GET(dev_config)) {
362 	case I2C_SPEED_STANDARD:
363 		i2c_speed = I2C_BITRATE_STANDARD; /* 100 KHz */
364 		break;
365 	case I2C_SPEED_FAST:
366 		i2c_speed = I2C_BITRATE_FAST; /* 400 KHz */
367 		break;
368 	case I2C_SPEED_FAST_PLUS:
369 		i2c_speed = I2C_BITRATE_FAST_PLUS; /* 1 MHz */
370 		break;
371 	default:
372 		LOG_ERR("Unsupported I2C speed requested: %u", i2c_speed);
373 		ret = -ERANGE;
374 		goto out;
375 	}
376 
377 	/* Set I2C Speed (SCL frequency) */
378 	ret = cdns_i2c_setclk(i2c_bus, i2c_speed);
379 	if (ret != 0) {
380 		LOG_ERR("Invalid SCL clock: %u Hz", i2c_speed);
381 		ret = -EIO;
382 		goto out;
383 	}
384 
385 	/* Enable the I2C peripheral */
386 	i2c_bus->ctrl_reg |= CDNS_I2C_CR_MASTER_EN_MASK;
387 	cdns_i2c_enable_peripheral(i2c_bus);
388 
389 out:
390 	(void)k_mutex_unlock(&i2c_bus->bus_mutex);
391 
392 	return ret;
393 }
394 
395 /**
396  * cdns_i2c_get_config - Retrieve the current I2C configuration.
397  * @dev: Pointer to the device structure.
398  * @dev_config: Pointer to a variable where the configuration will be stored.
399  *
400  * Return: 0 on success, or a negative error code on failure.
401  */
cdns_i2c_get_config(const struct device * dev,uint32_t * dev_config)402 static int32_t cdns_i2c_get_config(const struct device *dev, uint32_t *dev_config)
403 {
404 	int32_t ret = 0;
405 	struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data;
406 	uint32_t bus_speed = i2c_bus->i2c_clk;
407 	uint32_t speed_cfg = 0U;
408 
409 	/* Retrieve Speed configuration from Actual Bus Speed */
410 	if ((bus_speed > 0U) && (bus_speed <= I2C_BITRATE_STANDARD)) {
411 		speed_cfg = I2C_SPEED_SET(I2C_SPEED_STANDARD);
412 	} else if ((bus_speed > I2C_BITRATE_STANDARD) &&
413 		   (bus_speed <= I2C_BITRATE_FAST)) {
414 		speed_cfg = I2C_SPEED_SET(I2C_SPEED_FAST);
415 	} else if ((bus_speed > I2C_BITRATE_FAST) &&
416 		   (bus_speed <= I2C_BITRATE_FAST_PLUS)) {
417 		speed_cfg = I2C_SPEED_SET(I2C_SPEED_FAST_PLUS);
418 	} else {
419 		ret = -ERANGE;
420 		goto out;
421 	}
422 
423 	/* Return current configuration */
424 	*dev_config = (speed_cfg | I2C_MODE_CONTROLLER);
425 
426 out:
427 	return ret;
428 }
429 
430 /**
431  * cdns_i2c_clear_bus_hold - Clear bus hold bit in the controller's register
432  * @i2c_bus: Pointer to the I2C controller driver data structure
433  */
cdns_i2c_clear_bus_hold(struct cdns_i2c_data * i2c_bus)434 static void cdns_i2c_clear_bus_hold(struct cdns_i2c_data *i2c_bus)
435 {
436 	uint32_t reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
437 
438 	if ((reg & CDNS_I2C_CR_HOLD) == CDNS_I2C_CR_HOLD) {
439 		cdns_i2c_writereg(i2c_bus, reg & ~CDNS_I2C_CR_HOLD, CDNS_I2C_CR_OFFSET);
440 	}
441 }
442 
443 /**
444  * cdns_is_fifo_hold_quirk - Check if the FIFO hold quirk is triggered for I2C
445  * @i2c_bus: Pointer to the I2C controller driver data structure
446  * @hold_wrkaround: Boolean indicating if hold workarounds should be applied
447  *
448  * Return: True if the quirk condition is met, false otherwise.
449  */
cdns_is_fifo_hold_quirk(const struct cdns_i2c_data * i2c_bus,bool hold_wrkaround)450 static inline bool cdns_is_fifo_hold_quirk(const struct cdns_i2c_data *i2c_bus,
451 					   bool hold_wrkaround)
452 {
453 	return (hold_wrkaround && (i2c_bus->curr_recv_count == (i2c_bus->fifo_depth + 1U)));
454 }
455 
456 /**
457  * cdns_i2c_master_handle_receive_interrupt - Handles I2C master receive interrupts
458  * @i2c_bus: Pointer to the I2C data structure
459  * @isr_status: Interrupt status, indicating the cause of the interrupt
460  */
cdns_i2c_master_handle_receive_interrupt(struct cdns_i2c_data * i2c_bus,uint32_t isr_status)461 static void cdns_i2c_master_handle_receive_interrupt(struct cdns_i2c_data *i2c_bus,
462 						     uint32_t isr_status)
463 {
464 	uint32_t transfer_size;
465 	uint32_t xfer_size;
466 
467 	/* Handle reception interrupt (data available or transfer complete) */
468 	if (((isr_status & CDNS_I2C_IXR_COMP) == 0U) && ((isr_status & CDNS_I2C_IXR_DATA) == 0U)) {
469 		return;
470 	}
471 
472 	/* Receiving Data: Keep reading as long as data is available */
473 	while ((cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_RXDV) != 0U) {
474 		/* Ensure there's space to store received data */
475 		if (i2c_bus->recv_count > 0U) {
476 			*(i2c_bus->p_recv_buf) = (uint8_t)cdns_i2c_readreg(i2c_bus,
477 									   CDNS_I2C_DATA_OFFSET);
478 			i2c_bus->p_recv_buf++;
479 			i2c_bus->recv_count--;
480 			i2c_bus->curr_recv_count--;
481 		} else {
482 			/* Handle receive buffer overflow or unexpected condition */
483 			LOG_ERR("I2C receive buffer overflow. Transfer aborted!");
484 			i2c_bus->err_status |= CDNS_I2C_IXR_TO;
485 			break;
486 		}
487 
488 		/* Handle issues with receiving more data than expected */
489 		if (cdns_is_fifo_hold_quirk(i2c_bus,
490 					i2c_bus->recv_count > i2c_bus->curr_recv_count)) {
491 			break;
492 		}
493 	}
494 
495 	/* Workaround for large data receive in case of FIFO space issues */
496 	if (cdns_is_fifo_hold_quirk(i2c_bus, i2c_bus->recv_count > i2c_bus->curr_recv_count)) {
497 		transfer_size = i2c_bus->recv_count - i2c_bus->fifo_depth;
498 
499 		if (transfer_size > i2c_bus->transfer_size) {
500 			xfer_size = i2c_bus->transfer_size;
501 		} else {
502 			xfer_size = transfer_size;
503 		}
504 
505 		/* Busy-wait until FIFO has space for more data */
506 		while (cdns_i2c_readreg(i2c_bus, CDNS_I2C_XFER_SIZE_OFFSET) !=
507 		       (i2c_bus->curr_recv_count - i2c_bus->fifo_depth)) {
508 		}
509 
510 		/* Update the transfer size for the next batch of data */
511 		cdns_i2c_writereg(i2c_bus, xfer_size, CDNS_I2C_XFER_SIZE_OFFSET);
512 		i2c_bus->curr_recv_count = xfer_size + i2c_bus->fifo_depth;
513 	}
514 
515 	/* Complete transfer if all data has been received and no more data is expected */
516 	if (((isr_status & CDNS_I2C_IXR_COMP) == CDNS_I2C_IXR_COMP) &&
517 	    (i2c_bus->recv_count == 0U)) {
518 		/* Release bus hold if no longer needed */
519 		if (i2c_bus->bus_hold_flag == 0U) {
520 			cdns_i2c_clear_bus_hold(i2c_bus);
521 		}
522 		/* Notify completion of the transfer */
523 		(void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT);
524 	}
525 }
526 
527 /**
528  * cdns_i2c_master_handle_transmit_interrupt - Handles I2C master transmit interrupts
529  * @i2c_bus: Pointer to the I2C data structure
530  * @isr_status: Interrupt status, indicating the cause of the interrupt
531  */
cdns_i2c_master_handle_transmit_interrupt(struct cdns_i2c_data * i2c_bus,uint32_t isr_status)532 static void cdns_i2c_master_handle_transmit_interrupt(struct cdns_i2c_data *i2c_bus,
533 						      uint32_t isr_status)
534 {
535 	uint32_t avail_bytes;
536 	uint32_t bytes_to_send;
537 
538 	/* Handle transmission interrupt (data sent or transfer complete) */
539 	if ((isr_status & CDNS_I2C_IXR_COMP) == 0U) {
540 		return;
541 	}
542 
543 	/* Sending data: Check if there is any data left to send */
544 	if (i2c_bus->send_count > 0U) {
545 		/* Calculate how many bytes can be sent based on FIFO availability */
546 		avail_bytes = i2c_bus->fifo_depth - cdns_i2c_readreg(i2c_bus,
547 								     CDNS_I2C_XFER_SIZE_OFFSET);
548 
549 		if (i2c_bus->send_count > avail_bytes) {
550 			bytes_to_send = avail_bytes;
551 		} else {
552 			bytes_to_send = i2c_bus->send_count;
553 		}
554 
555 		/* Write data to the I2C data register */
556 		while (bytes_to_send > 0U) {
557 			cdns_i2c_writereg(i2c_bus, *(i2c_bus->p_send_buf), CDNS_I2C_DATA_OFFSET);
558 			i2c_bus->p_send_buf++;
559 			i2c_bus->send_count--;
560 			bytes_to_send--;
561 		}
562 	} else {
563 		/* If there is no data to send, signal transfer completion */
564 		(void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT);
565 	}
566 
567 	/* Clear bus hold if no more data is pending */
568 	if ((i2c_bus->send_count == 0U) && (i2c_bus->bus_hold_flag == 0U)) {
569 		cdns_i2c_clear_bus_hold(i2c_bus);
570 	}
571 }
572 
573 /**
574  * cdns_i2c_master_isr - Interrupt handler for the I2C device in master role
575  * @i2c_bus: Pointer to I2C device private data structure
576  *
577  * This function handles various interrupt events including data received,
578  * transfer complete, and error interrupts for the I2C master role.
579  */
cdns_i2c_master_isr(struct cdns_i2c_data * i2c_bus)580 static void cdns_i2c_master_isr(struct cdns_i2c_data *i2c_bus)
581 {
582 	uint32_t isr_status;
583 
584 	/* Read the interrupt status register */
585 	isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET);
586 
587 	/* Clear interrupt status */
588 	cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET);
589 
590 	/* Update the error status based on interrupt flags */
591 	i2c_bus->err_status = isr_status & CDNS_I2C_IXR_ERR_INTR_MASK;
592 
593 	/* Handling NACK or arbitration lost interrupts */
594 	if ((isr_status & (CDNS_I2C_IXR_NACK | CDNS_I2C_IXR_ARB_LOST)) != 0U) {
595 		(void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT);
596 		return;
597 	}
598 
599 	/* Handle reception interrupt */
600 	if (i2c_bus->p_recv_buf != NULL) {
601 		cdns_i2c_master_handle_receive_interrupt(i2c_bus, isr_status);
602 	}
603 
604 	/* Handle transmission interrupt */
605 	if (i2c_bus->p_recv_buf == NULL) {
606 		cdns_i2c_master_handle_transmit_interrupt(i2c_bus, isr_status);
607 	}
608 }
609 
610 /**
611  * cdns_i2c_isr - Interrupt handler for the I2C controller
612  * @dev: Pointer to I2C device
613  */
cdns_i2c_isr(const struct device * dev)614 static void cdns_i2c_isr(const struct device *dev)
615 {
616 	struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data;
617 
618 	/* Handle the interrupt for master mode */
619 	cdns_i2c_master_isr(i2c_bus);
620 }
621 
622 /**
623  * cdns_i2c_mrecv - Prepare and start a master receive operation
624  * @i2c_bus: Pointer to the I2C data structure
625  * @msg_addr: The address of the slave device to receive data from
626  */
cdns_i2c_mrecv(struct cdns_i2c_data * i2c_bus,uint16_t msg_addr)627 static void cdns_i2c_mrecv(struct cdns_i2c_data *i2c_bus, uint16_t msg_addr)
628 {
629 	uint32_t ctrl_reg;
630 	uint32_t isr_status;
631 	bool hold_clear = false;
632 	uint32_t addr;
633 
634 	/* Initialize the receive buffer and count */
635 	i2c_bus->p_recv_buf = i2c_bus->p_msg->buf;
636 	i2c_bus->recv_count = i2c_bus->p_msg->len;
637 	i2c_bus->curr_recv_count = i2c_bus->recv_count;
638 
639 	/* Prepare controller for master receive mode and clear FIFO */
640 	ctrl_reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
641 	ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
642 
643 	/* Check if the message size exceeds FIFO depth, hold the bus if true */
644 	if (i2c_bus->recv_count > i2c_bus->fifo_depth) {
645 		ctrl_reg |= CDNS_I2C_CR_HOLD;
646 	}
647 
648 	cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET);
649 
650 	/* Clear the interrupts in interrupt status register */
651 	isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET);
652 	cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET);
653 
654 	/* Set transfer size register and enable interrupts */
655 	if ((i2c_bus->recv_count) > (i2c_bus->transfer_size)) {
656 		cdns_i2c_writereg(i2c_bus, i2c_bus->transfer_size,
657 				  CDNS_I2C_XFER_SIZE_OFFSET);
658 		i2c_bus->curr_recv_count = i2c_bus->transfer_size;
659 	} else {
660 		cdns_i2c_writereg(i2c_bus, i2c_bus->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);
661 	}
662 
663 	/* Determine whether to clear the hold bit based on conditions */
664 	if ((i2c_bus->bus_hold_flag == 0U) && (i2c_bus->recv_count <= i2c_bus->fifo_depth)) {
665 		if ((ctrl_reg & CDNS_I2C_CR_HOLD) != 0U) {
666 			hold_clear = true;
667 		}
668 	}
669 
670 	/* Mask address and prepare for I2C communication */
671 	addr = msg_addr;
672 	addr &= CDNS_I2C_ADDR_MASK;
673 
674 	/* Handle clearing of the hold bit */
675 	if (hold_clear) {
676 		ctrl_reg &= ~CDNS_I2C_CR_HOLD;
677 		ctrl_reg &= ~CDNS_I2C_CR_CLR_FIFO;
678 
679 		/* Write the address and control register values */
680 		cdns_i2c_writereg(i2c_bus, addr, CDNS_I2C_ADDR_OFFSET);
681 		cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET);
682 		/* Read back to ensure write completion */
683 		(void)cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
684 	} else {
685 		/* Directly write the address if no need to clear the hold bit */
686 		cdns_i2c_writereg(i2c_bus, addr, CDNS_I2C_ADDR_OFFSET);
687 	}
688 
689 	/* Enable interrupts */
690 	cdns_i2c_writereg(i2c_bus, CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET);
691 }
692 
693 /**
694  * cdns_i2c_msend - Prepare and start a master send operation
695  * @i2c_bus: Pointer to the I2C data structure
696  * @msg_addr: I2C address of the slave to communicate with
697  */
cdns_i2c_msend(struct cdns_i2c_data * i2c_bus,uint16_t msg_addr)698 static void cdns_i2c_msend(struct cdns_i2c_data *i2c_bus, uint16_t msg_addr)
699 {
700 	uint32_t avail_bytes;
701 	uint32_t bytes_to_send;
702 	uint32_t ctrl_reg;
703 	uint32_t isr_status;
704 
705 	/* Initialize send buffer and update send count */
706 	i2c_bus->p_recv_buf = NULL;
707 	i2c_bus->p_send_buf = i2c_bus->p_msg->buf;
708 	i2c_bus->send_count = i2c_bus->p_msg->len;
709 
710 	/* Configure the controller in Master transmit mode and clear FIFO. */
711 	ctrl_reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
712 	ctrl_reg &= ~CDNS_I2C_CR_RW;
713 	ctrl_reg |= CDNS_I2C_CR_CLR_FIFO;
714 
715 	/* Check if the message size exceeds FIFO depth, hold the bus if true */
716 	if (i2c_bus->send_count > i2c_bus->fifo_depth) {
717 		ctrl_reg |= CDNS_I2C_CR_HOLD;
718 	}
719 	cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET);
720 
721 	/* Clear any previous interrupt flags */
722 	isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET);
723 	cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET);
724 
725 	/* Calculate available FIFO space and determine how many bytes to send */
726 	avail_bytes = i2c_bus->fifo_depth - cdns_i2c_readreg(i2c_bus, CDNS_I2C_XFER_SIZE_OFFSET);
727 	bytes_to_send = (i2c_bus->send_count > avail_bytes) ? avail_bytes : i2c_bus->send_count;
728 
729 	/* Send data to FIFO until all bytes are transmitted */
730 	while (bytes_to_send > 0U) {
731 		cdns_i2c_writereg(i2c_bus, (*(i2c_bus->p_send_buf)), CDNS_I2C_DATA_OFFSET);
732 		(i2c_bus->p_send_buf)++;
733 		i2c_bus->send_count--;
734 		bytes_to_send--;
735 	}
736 
737 	/* Clear the 'hold bus' flag if there's no more data and it's the last message */
738 	if ((i2c_bus->bus_hold_flag == 0U) && (i2c_bus->send_count == 0U)) {
739 		cdns_i2c_clear_bus_hold(i2c_bus);
740 	}
741 
742 	/* Set the slave address to trigger operation. */
743 	cdns_i2c_writereg(i2c_bus, ((uint32_t)msg_addr & CDNS_I2C_ADDR_MASK),
744 				   CDNS_I2C_ADDR_OFFSET);
745 
746 	/* Enable interrupts after data transmission starts */
747 	cdns_i2c_writereg(i2c_bus, CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET);
748 }
749 
750 /**
751  * cdns_i2c_master_reset - Reset the I2C master interface
752  * @i2c_bus: Pointer to the i2c driver instance
753  *
754  * This function performs a full reset of the I2C master interface
755  * The reset ensures that the interface is returned to a known idle state.
756  */
cdns_i2c_master_reset(struct cdns_i2c_data * i2c_bus)757 static void cdns_i2c_master_reset(struct cdns_i2c_data *i2c_bus)
758 {
759 	uint32_t regval;
760 
761 	/* Disable the interrupts */
762 	cdns_i2c_writereg(i2c_bus, CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET);
763 
764 	/* Clear the hold bit and flush FIFOs */
765 	regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
766 	regval &= ~CDNS_I2C_CR_HOLD;
767 	regval |= CDNS_I2C_CR_CLR_FIFO;
768 	cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_CR_OFFSET);
769 
770 	/* Reset transfer count register to zero */
771 	cdns_i2c_writereg(i2c_bus, 0, CDNS_I2C_XFER_SIZE_OFFSET);
772 
773 	/* Clear the interrupt status register */
774 	regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET);
775 	cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_ISR_OFFSET);
776 
777 	/* Clear the status register */
778 	regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET);
779 	cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_SR_OFFSET);
780 }
781 
782 /**
783  * cdns_i2c_process_msg - Processes an I2C message on the specified I2C bus
784  * @i2c_bus: Pointer to the I2C data structure
785  * @msg: Pointer to the I2C message to be processed
786  * @addr: The 7-bit or 10-bit I2C address of the slave device
787  *
788  * Return: 0 on success, negative error code on failure.
789  */
cdns_i2c_process_msg(struct cdns_i2c_data * i2c_bus,struct i2c_msg * msg,uint16_t addr)790 static int32_t cdns_i2c_process_msg(struct cdns_i2c_data *i2c_bus, struct i2c_msg *msg,
791 				    uint16_t addr)
792 {
793 	int32_t ret = 0;
794 	uint32_t reg;
795 	k_timeout_t msg_timeout;
796 	uint32_t events;
797 
798 	/* Initialize message processing state */
799 	i2c_bus->p_msg = msg;
800 	i2c_bus->err_status = 0U;
801 	(void)k_event_clear(&i2c_bus->xfer_done, (uint32_t)I2C_XFER_COMPLETION_EVENT);
802 
803 	/* Handle 10-bit addressing mode */
804 	reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
805 	if ((msg->flags & I2C_MSG_ADDR_10_BITS) != 0U) {
806 		/* Enable 10-bit address mode if not already enabled */
807 		if ((reg & CDNS_I2C_CR_NEA) == CDNS_I2C_CR_NEA) {
808 			cdns_i2c_writereg(i2c_bus,
809 					reg & ~CDNS_I2C_CR_NEA,
810 					CDNS_I2C_CR_OFFSET);
811 		}
812 	} else {
813 		/* Disable 10-bit address mode if currently enabled */
814 		if ((reg & CDNS_I2C_CR_NEA) == 0U) {
815 			cdns_i2c_writereg(i2c_bus,
816 					reg | CDNS_I2C_CR_NEA,
817 					CDNS_I2C_CR_OFFSET);
818 		}
819 	}
820 
821 	/* Handle read/write flag and perform the appropriate action */
822 	if ((msg->flags & I2C_MSG_READ) != 0U) {
823 		cdns_i2c_mrecv(i2c_bus, addr); /* Receive data */
824 	} else {
825 		cdns_i2c_msend(i2c_bus, addr); /* Send data */
826 	}
827 
828 	/* Calculate the minimal timeout based on message length */
829 	msg_timeout.ticks = (((k_ticks_t)(msg->len) * 8)*(CDNS_I2C_TICKS_PER_SEC)) /
830 			     ((k_ticks_t)(i2c_bus->i2c_clk));
831 	msg_timeout.ticks += (CDNS_I2C_TICKS_PER_SEC / 2);
832 	if (msg_timeout.ticks < CDNS_I2C_TIMEOUT_TICKS) {
833 		msg_timeout.ticks = CDNS_I2C_TIMEOUT_TICKS;
834 	}
835 
836 	/* Wait for the completion signal or timeout */
837 	events = k_event_wait(&i2c_bus->xfer_done, (uint32_t)I2C_XFER_COMPLETION_EVENT,
838 			      false, msg_timeout);
839 	if ((events & I2C_XFER_COMPLETION_EVENT) == 0U) {
840 		/* Timeout occurred, reset the master */
841 		cdns_i2c_master_reset(i2c_bus);
842 		ret = -ETIMEDOUT;
843 		goto out;
844 	}
845 
846 	/* Disable interrupt masking for the current transfer */
847 	cdns_i2c_writereg(i2c_bus, CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET);
848 
849 	/* If it is bus arbitration error, try again */
850 	if ((i2c_bus->err_status & CDNS_I2C_IXR_ARB_LOST) == CDNS_I2C_IXR_ARB_LOST) {
851 		ret = -EAGAIN;
852 	}
853 
854 out:
855 	return ret;
856 }
857 
858 /**
859  * cdns_i2c_wait_for_bus_free - Wait for the I2C bus to become free.
860  * @i2c_bus: Pointer to the I2C data structure that holds bus state information.
861  * @timeout_us: Maximum time (in microseconds) to wait for the bus to become free.
862  *
863  * This function waits for the I2C bus to become idle. It checks the bus state
864  * register periodically until the bus is free or the timeout occurs.
865  *
866  * Return: true if the bus is free within the timeout, false otherwise.
867  */
cdns_i2c_wait_for_bus_free(struct cdns_i2c_data * i2c_bus,uint32_t timeout_us)868 static bool cdns_i2c_wait_for_bus_free(struct cdns_i2c_data *i2c_bus, uint32_t timeout_us)
869 {
870 	bool ret_flag = false;
871 	uint32_t reg;
872 
873 	/* Poll until the bus is free or the timeout is reached */
874 	while (timeout_us > 0U) {
875 		reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET);
876 		if ((reg & CDNS_I2C_SR_BA) == 0U) {
877 			/* Bus Available (BA) bit is cleared, the bus is free */
878 			ret_flag = true;
879 			break;
880 		}
881 
882 		/* Wait for a small period before checking again */
883 		(void)k_usleep((int32_t)CDNS_I2C_POLL_US);
884 		timeout_us -= CDNS_I2C_POLL_US;
885 	}
886 
887 	if (timeout_us == 0U) {
888 		/* Timeout reached, bus not available */
889 		ret_flag = false;
890 	}
891 
892 	return ret_flag;
893 }
894 
895 /**
896  * cdns_i2c_master_handle_repeated_start - Handle repeated start during I2C master transfer
897  * @i2c_bus: Pointer to the I2C data structure that holds bus state information
898  * @msgs: Array of I2C messages to be processed
899  * @num_msgs: Number of messages in the @msgs array
900  *
901  * Return: 0 on success
902  */
cdns_i2c_master_handle_repeated_start(struct cdns_i2c_data * i2c_bus,struct i2c_msg * msgs,uint8_t num_msgs)903 static int32_t cdns_i2c_master_handle_repeated_start(struct cdns_i2c_data *i2c_bus,
904 						     struct i2c_msg *msgs, uint8_t num_msgs)
905 {
906 	uint32_t reg;
907 	(void)msgs;
908 	(void)num_msgs;
909 
910 	/* Set the hold flag and register */
911 	i2c_bus->bus_hold_flag = 1;
912 	reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET);
913 	reg |= CDNS_I2C_CR_HOLD;
914 	cdns_i2c_writereg(i2c_bus, reg, CDNS_I2C_CR_OFFSET);
915 
916 	return 0;
917 }
918 
919 /**
920  * cdns_i2c_master_handle_transfer_error - Handle errors during I2C master transfer.
921  * @i2c_bus: Pointer to the I2C data structure
922  *
923  * Return: -EIO or -ENXIO.
924  */
cdns_i2c_master_handle_transfer_error(struct cdns_i2c_data * i2c_bus)925 static int32_t cdns_i2c_master_handle_transfer_error(struct cdns_i2c_data *i2c_bus)
926 {
927 	int32_t ret;
928 
929 	/* Perform a reset of the I2C master to clear the error condition */
930 	cdns_i2c_master_reset(i2c_bus);
931 
932 	if ((i2c_bus->err_status & CDNS_I2C_IXR_NACK) != 0U) {
933 		ret = -ENXIO; /* No device found (NACK) */
934 	} else {
935 		ret = -EIO; /* General I/O error */
936 	}
937 
938 	return ret;
939 }
940 
941 /**
942  * cdns_i2c_master_transfer - Performs an I2C master transfer using the Cadence I2C controller.
943  * @dev: Pointer to the device structure representing the I2C controller.
944  * @msgs: Array of I2C message structures representing the messages to be sent/received.
945  * @num_msgs: Number of messages in the msgs array.
946  * @addr: The 7-bit or 10-bit I2C address of the slave device.
947  *
948  * Return: 0 on success, negative error code on failure.
949  */
cdns_i2c_master_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)950 static int32_t cdns_i2c_master_transfer(const struct device *dev, struct i2c_msg *msgs,
951 					uint8_t num_msgs, uint16_t addr)
952 {
953 	struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data;
954 	int32_t ret = 0;
955 	uint32_t count;
956 	struct i2c_msg *msg_ptr = msgs;
957 
958 	(void)k_mutex_lock(&i2c_bus->bus_mutex, K_FOREVER);
959 
960 	/* Wait for the bus to be free */
961 	if (cdns_i2c_wait_for_bus_free(i2c_bus, CDNS_I2C_TIMEOUT_US) == false) {
962 		ret = -EAGAIN;
963 		goto out;
964 	}
965 
966 	/* Handle repeated start for multiple messages */
967 	if (num_msgs > 1U) {
968 		ret = cdns_i2c_master_handle_repeated_start(i2c_bus, msgs, num_msgs);
969 		if (ret != 0) {
970 			goto out;
971 		}
972 	}
973 
974 	/* Process each message individually */
975 	for (count = 0; count < num_msgs; count++) {
976 		/* Reset hold flag for the last message */
977 		if (count == ((uint32_t)num_msgs - 1U)) {
978 			i2c_bus->bus_hold_flag = 0;
979 		}
980 
981 		/* Process the current message */
982 		ret = cdns_i2c_process_msg(i2c_bus, msg_ptr, addr);
983 		if (ret != 0) {
984 			goto out;
985 		}
986 
987 		/* Handle any errors during the transfer */
988 		if ((i2c_bus->err_status) != 0U) {
989 			ret = cdns_i2c_master_handle_transfer_error(i2c_bus);
990 			if (ret != 0) {
991 				goto out;
992 			}
993 		}
994 
995 		msg_ptr++;
996 	}
997 
998 out:
999 	(void)k_mutex_unlock(&i2c_bus->bus_mutex);
1000 
1001 	return ret;
1002 }
1003 
1004 /**
1005  * cdns_i2c_init - Initialize the Cadence I2C controller
1006  * @dev: Pointer to the device
1007  *
1008  * Return: 0 on success, negative error code on failure.
1009  */
cdns_i2c_init(const struct device * dev)1010 static int32_t cdns_i2c_init(const struct device *dev)
1011 {
1012 	const struct cdns_i2c_config *config = (const struct cdns_i2c_config *)dev->config;
1013 	struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data;
1014 	int32_t ret;
1015 
1016 	(void)k_mutex_init(&i2c_bus->bus_mutex);
1017 	k_event_init(&i2c_bus->xfer_done);
1018 
1019 	/* Configure the control reg flags, transfer size */
1020 	i2c_bus->ctrl_reg = CDNS_I2C_CR_MASTER_EN_MASK;
1021 	i2c_bus->transfer_size = CDNS_I2C_TRANSFER_SIZE_DEFAULT;
1022 
1023 	/* Set the I2C clock frequency */
1024 	ret = cdns_i2c_setclk(i2c_bus, i2c_bus->i2c_clk);
1025 	if (ret != 0) {
1026 		LOG_ERR("Invalid SCL clock: %u Hz", i2c_bus->i2c_clk);
1027 		ret = -EINVAL;
1028 		goto out;
1029 	}
1030 
1031 	/* Configure IRQ */
1032 	config->irq_config_func();
1033 
1034 	/* Enable the I2C peripheral */
1035 	cdns_i2c_enable_peripheral(i2c_bus);
1036 
1037 	LOG_INF("%u KHz mmio %08lx", i2c_bus->i2c_clk/1000U, i2c_bus->membase);
1038 
1039 out:
1040 	return ret;
1041 }
1042 
1043 /* I2C driver API structure for the Cadence I2C controller */
1044 static DEVICE_API(i2c, cdns_i2c_driver_api) = {
1045 	.configure = cdns_i2c_configure,
1046 	.get_config = cdns_i2c_get_config,
1047 	.transfer = cdns_i2c_master_transfer,
1048 #ifdef CONFIG_I2C_RTIO
1049 	.iodev_submit = i2c_iodev_submit_fallback,
1050 #endif
1051 };
1052 
1053 #define CADENCE_I2C_INIT(n, compat)							\
1054 	static void cdns_i2c_config_func_##compat##_##n(void);				\
1055 											\
1056 	static const struct cdns_i2c_config cdns_i2c_config_##compat##_##n = {		\
1057 		.irq_config_func = cdns_i2c_config_func_##compat##_##n,			\
1058 	};										\
1059 											\
1060 	static struct cdns_i2c_data cdns_i2c_data_##compat##_##n = {			\
1061 		.membase = DT_INST_REG_ADDR(n),						\
1062 		.input_clk = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency),	\
1063 		.i2c_clk = DT_INST_PROP(n, clock_frequency),				\
1064 		.fifo_depth = DT_INST_PROP(n, fifo_depth),				\
1065 	};										\
1066 											\
1067 	I2C_DEVICE_DT_INST_DEFINE(n, cdns_i2c_init, NULL,				\
1068 				&cdns_i2c_data_##compat##_##n,				\
1069 				&cdns_i2c_config_##compat##_##n, POST_KERNEL,		\
1070 				CONFIG_I2C_INIT_PRIORITY, &cdns_i2c_driver_api);	\
1071 											\
1072 	static void cdns_i2c_config_func_##compat##_##n(void)				\
1073 	{										\
1074 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), cdns_i2c_isr,	\
1075 			    DEVICE_DT_INST_GET(n), 0);					\
1076 											\
1077 		irq_enable(DT_INST_IRQN(n));						\
1078 	}
1079 
1080 #define DT_DRV_COMPAT cdns_i2c
1081 DT_INST_FOREACH_STATUS_OKAY_VARGS(CADENCE_I2C_INIT, DT_DRV_COMPAT)
1082