xref: /rk3399_ARM-atf/drivers/st/i2c/stm32_i2c.c (revision 435832abfd731e1f25b704117ece68dfaf052c46)
1*435832abSYann Gautier /*
2*435832abSYann Gautier  * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
3*435832abSYann Gautier  *
4*435832abSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
5*435832abSYann Gautier  */
6*435832abSYann Gautier 
7*435832abSYann Gautier #include <errno.h>
8*435832abSYann Gautier #include <stdbool.h>
9*435832abSYann Gautier #include <stdlib.h>
10*435832abSYann Gautier 
11*435832abSYann Gautier #include <arch_helpers.h>
12*435832abSYann Gautier #include <drivers/delay_timer.h>
13*435832abSYann Gautier #include <drivers/st/stm32_i2c.h>
14*435832abSYann Gautier #include <lib/mmio.h>
15*435832abSYann Gautier 
16*435832abSYann Gautier /* STM32 I2C registers offsets */
17*435832abSYann Gautier #define I2C_CR1			0x00U
18*435832abSYann Gautier #define I2C_CR2			0x04U
19*435832abSYann Gautier #define I2C_OAR1		0x08U
20*435832abSYann Gautier #define I2C_OAR2		0x0CU
21*435832abSYann Gautier #define I2C_TIMINGR		0x10U
22*435832abSYann Gautier #define I2C_TIMEOUTR		0x14U
23*435832abSYann Gautier #define I2C_ISR			0x18U
24*435832abSYann Gautier #define I2C_ICR			0x1CU
25*435832abSYann Gautier #define I2C_PECR		0x20U
26*435832abSYann Gautier #define I2C_RXDR		0x24U
27*435832abSYann Gautier #define I2C_TXDR		0x28U
28*435832abSYann Gautier 
29*435832abSYann Gautier #define MAX_DELAY		0xFFFFFFFFU
30*435832abSYann Gautier 
31*435832abSYann Gautier /* I2C TIMING clear register Mask */
32*435832abSYann Gautier #define TIMING_CLEAR_MASK	0xF0FFFFFFU
33*435832abSYann Gautier /* Timeout 25 ms */
34*435832abSYann Gautier #define I2C_TIMEOUT_BUSY	25U
35*435832abSYann Gautier 
36*435832abSYann Gautier #define MAX_NBYTE_SIZE		255U
37*435832abSYann Gautier 
38*435832abSYann Gautier static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
39*435832abSYann Gautier 				    uint16_t dev_addr, uint16_t mem_addr,
40*435832abSYann Gautier 				    uint16_t mem_add_size, uint32_t timeout,
41*435832abSYann Gautier 				    uint32_t tick_start);
42*435832abSYann Gautier static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
43*435832abSYann Gautier 				   uint16_t mem_addr, uint16_t mem_add_size,
44*435832abSYann Gautier 				   uint32_t timeout, uint32_t tick_start);
45*435832abSYann Gautier 
46*435832abSYann Gautier /* Private functions to handle flags during polling transfer */
47*435832abSYann Gautier static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
48*435832abSYann Gautier 			 uint8_t awaited_value, uint32_t timeout,
49*435832abSYann Gautier 			 uint32_t tick_start);
50*435832abSYann Gautier static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
51*435832abSYann Gautier 			 uint32_t tick_start);
52*435832abSYann Gautier static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
53*435832abSYann Gautier 			 uint32_t tick_start);
54*435832abSYann Gautier static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
55*435832abSYann Gautier 			  uint32_t tick_start);
56*435832abSYann Gautier 
57*435832abSYann Gautier /* Private function to flush TXDR register */
58*435832abSYann Gautier static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
59*435832abSYann Gautier 
60*435832abSYann Gautier /* Private function to start, restart or stop a transfer */
61*435832abSYann Gautier static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
62*435832abSYann Gautier 				uint16_t size, uint32_t i2c_mode,
63*435832abSYann Gautier 				uint32_t request);
64*435832abSYann Gautier 
65*435832abSYann Gautier /*
66*435832abSYann Gautier  * @brief  Initialize the I2C device.
67*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
68*435832abSYann Gautier  *               the configuration information for the specified I2C.
69*435832abSYann Gautier  * @retval 0 if OK, negative value else
70*435832abSYann Gautier  */
71*435832abSYann Gautier int stm32_i2c_init(struct i2c_handle_s *hi2c)
72*435832abSYann Gautier {
73*435832abSYann Gautier 	if (hi2c == NULL) {
74*435832abSYann Gautier 		return -ENOENT;
75*435832abSYann Gautier 	}
76*435832abSYann Gautier 
77*435832abSYann Gautier 	if (hi2c->i2c_state == I2C_STATE_RESET) {
78*435832abSYann Gautier 		hi2c->lock = 0;
79*435832abSYann Gautier 	}
80*435832abSYann Gautier 
81*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_BUSY;
82*435832abSYann Gautier 
83*435832abSYann Gautier 	/* Disable the selected I2C peripheral */
84*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
85*435832abSYann Gautier 
86*435832abSYann Gautier 	/* Configure I2Cx: Frequency range */
87*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
88*435832abSYann Gautier 		      hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
89*435832abSYann Gautier 
90*435832abSYann Gautier 	/* Disable Own Address1 before set the Own Address1 configuration */
91*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
92*435832abSYann Gautier 
93*435832abSYann Gautier 	/* Configure I2Cx: Own Address1 and ack own address1 mode */
94*435832abSYann Gautier 	if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
95*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
96*435832abSYann Gautier 			      I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
97*435832abSYann Gautier 	} else { /* I2C_ADDRESSINGMODE_10BIT */
98*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
99*435832abSYann Gautier 			      I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
100*435832abSYann Gautier 			      hi2c->i2c_init.own_address1);
101*435832abSYann Gautier 	}
102*435832abSYann Gautier 
103*435832abSYann Gautier 	/* Configure I2Cx: Addressing Master mode */
104*435832abSYann Gautier 	if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
105*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
106*435832abSYann Gautier 	}
107*435832abSYann Gautier 
108*435832abSYann Gautier 	/*
109*435832abSYann Gautier 	 * Enable the AUTOEND by default, and enable NACK
110*435832abSYann Gautier 	 * (should be disable only during Slave process)
111*435832abSYann Gautier 	 */
112*435832abSYann Gautier 	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
113*435832abSYann Gautier 			I2C_CR2_AUTOEND | I2C_CR2_NACK);
114*435832abSYann Gautier 
115*435832abSYann Gautier 	/* Disable Own Address2 before set the Own Address2 configuration */
116*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
117*435832abSYann Gautier 
118*435832abSYann Gautier 	/* Configure I2Cx: Dual mode and Own Address2 */
119*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
120*435832abSYann Gautier 		      hi2c->i2c_init.dual_address_mode |
121*435832abSYann Gautier 		      hi2c->i2c_init.own_address2 |
122*435832abSYann Gautier 		      (hi2c->i2c_init.own_address2_masks << 8));
123*435832abSYann Gautier 
124*435832abSYann Gautier 	/* Configure I2Cx: Generalcall and NoStretch mode */
125*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
126*435832abSYann Gautier 		      hi2c->i2c_init.general_call_mode |
127*435832abSYann Gautier 		      hi2c->i2c_init.no_stretch_mode);
128*435832abSYann Gautier 
129*435832abSYann Gautier 	/* Enable the selected I2C peripheral */
130*435832abSYann Gautier 	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
131*435832abSYann Gautier 
132*435832abSYann Gautier 	hi2c->i2c_err = I2C_ERROR_NONE;
133*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
134*435832abSYann Gautier 	hi2c->i2c_mode = I2C_MODE_NONE;
135*435832abSYann Gautier 
136*435832abSYann Gautier 	return 0;
137*435832abSYann Gautier }
138*435832abSYann Gautier 
139*435832abSYann Gautier /*
140*435832abSYann Gautier  * @brief  Write an amount of data in blocking mode to a specific memory address
141*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
142*435832abSYann Gautier  *               the configuration information for the specified I2C.
143*435832abSYann Gautier  * @param  dev_addr: Target device address
144*435832abSYann Gautier  * @param  mem_addr: Internal memory address
145*435832abSYann Gautier  * @param  mem_add_size: size of internal memory address
146*435832abSYann Gautier  * @param  p_data: Pointer to data buffer
147*435832abSYann Gautier  * @param  size: Amount of data to be sent
148*435832abSYann Gautier  * @param  timeout: timeout duration
149*435832abSYann Gautier  * @retval 0 if OK, negative value else
150*435832abSYann Gautier  */
151*435832abSYann Gautier int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
152*435832abSYann Gautier 			uint16_t mem_addr, uint16_t mem_add_size,
153*435832abSYann Gautier 			uint8_t *p_data, uint16_t size, uint32_t timeout)
154*435832abSYann Gautier {
155*435832abSYann Gautier 	uint32_t tickstart;
156*435832abSYann Gautier 
157*435832abSYann Gautier 	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
158*435832abSYann Gautier 		return -EBUSY;
159*435832abSYann Gautier 	}
160*435832abSYann Gautier 
161*435832abSYann Gautier 	if ((p_data == NULL) || (size == 0U)) {
162*435832abSYann Gautier 		return -EINVAL;
163*435832abSYann Gautier 	}
164*435832abSYann Gautier 
165*435832abSYann Gautier 	hi2c->lock = 1;
166*435832abSYann Gautier 
167*435832abSYann Gautier 	tickstart = (uint32_t)read_cntpct_el0();
168*435832abSYann Gautier 
169*435832abSYann Gautier 	if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
170*435832abSYann Gautier 			  tickstart) != 0) {
171*435832abSYann Gautier 		return -EIO;
172*435832abSYann Gautier 	}
173*435832abSYann Gautier 
174*435832abSYann Gautier 	hi2c->i2c_state     = I2C_STATE_BUSY_TX;
175*435832abSYann Gautier 	hi2c->i2c_mode      = I2C_MODE_MEM;
176*435832abSYann Gautier 	hi2c->i2c_err = I2C_ERROR_NONE;
177*435832abSYann Gautier 
178*435832abSYann Gautier 	hi2c->p_buff  = p_data;
179*435832abSYann Gautier 	hi2c->xfer_count = size;
180*435832abSYann Gautier 
181*435832abSYann Gautier 	/* Send Slave Address and Memory Address */
182*435832abSYann Gautier 	if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
183*435832abSYann Gautier 				     timeout, tickstart) != 0) {
184*435832abSYann Gautier 		hi2c->lock = 0;
185*435832abSYann Gautier 		return -EIO;
186*435832abSYann Gautier 	}
187*435832abSYann Gautier 
188*435832abSYann Gautier 	/*
189*435832abSYann Gautier 	 * Set NBYTES to write and reload
190*435832abSYann Gautier 	 * if hi2c->xfer_count > MAX_NBYTE_SIZE
191*435832abSYann Gautier 	 */
192*435832abSYann Gautier 	if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
193*435832abSYann Gautier 		hi2c->xfer_size = MAX_NBYTE_SIZE;
194*435832abSYann Gautier 		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
195*435832abSYann Gautier 				    I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
196*435832abSYann Gautier 	} else {
197*435832abSYann Gautier 		hi2c->xfer_size = hi2c->xfer_count;
198*435832abSYann Gautier 		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
199*435832abSYann Gautier 				    I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
200*435832abSYann Gautier 	}
201*435832abSYann Gautier 
202*435832abSYann Gautier 	do {
203*435832abSYann Gautier 		if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
204*435832abSYann Gautier 			return -EIO;
205*435832abSYann Gautier 		}
206*435832abSYann Gautier 
207*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
208*435832abSYann Gautier 		hi2c->p_buff++;
209*435832abSYann Gautier 		hi2c->xfer_count--;
210*435832abSYann Gautier 		hi2c->xfer_size--;
211*435832abSYann Gautier 
212*435832abSYann Gautier 		if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
213*435832abSYann Gautier 			/* Wait until TCR flag is set */
214*435832abSYann Gautier 			if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
215*435832abSYann Gautier 					  tickstart) != 0) {
216*435832abSYann Gautier 				return -EIO;
217*435832abSYann Gautier 		}
218*435832abSYann Gautier 
219*435832abSYann Gautier 			if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
220*435832abSYann Gautier 				hi2c->xfer_size = MAX_NBYTE_SIZE;
221*435832abSYann Gautier 				i2c_transfer_config(hi2c, dev_addr,
222*435832abSYann Gautier 						    hi2c->xfer_size,
223*435832abSYann Gautier 						    I2C_RELOAD_MODE,
224*435832abSYann Gautier 						    I2C_NO_STARTSTOP);
225*435832abSYann Gautier 			} else {
226*435832abSYann Gautier 				hi2c->xfer_size = hi2c->xfer_count;
227*435832abSYann Gautier 				i2c_transfer_config(hi2c, dev_addr,
228*435832abSYann Gautier 						    hi2c->xfer_size,
229*435832abSYann Gautier 						    I2C_AUTOEND_MODE,
230*435832abSYann Gautier 						    I2C_NO_STARTSTOP);
231*435832abSYann Gautier 			}
232*435832abSYann Gautier 		}
233*435832abSYann Gautier 
234*435832abSYann Gautier 	} while (hi2c->xfer_count > 0U);
235*435832abSYann Gautier 
236*435832abSYann Gautier 	/*
237*435832abSYann Gautier 	 * No need to Check TC flag, with AUTOEND mode the stop
238*435832abSYann Gautier 	 * is automatically generated.
239*435832abSYann Gautier 	 * Wait until STOPF flag is reset.
240*435832abSYann Gautier 	 */
241*435832abSYann Gautier 	if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
242*435832abSYann Gautier 		return -EIO;
243*435832abSYann Gautier 	}
244*435832abSYann Gautier 
245*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
246*435832abSYann Gautier 
247*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
248*435832abSYann Gautier 
249*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
250*435832abSYann Gautier 	hi2c->i2c_mode  = I2C_MODE_NONE;
251*435832abSYann Gautier 
252*435832abSYann Gautier 	hi2c->lock = 0;
253*435832abSYann Gautier 
254*435832abSYann Gautier 	return 0;
255*435832abSYann Gautier }
256*435832abSYann Gautier 
257*435832abSYann Gautier /*
258*435832abSYann Gautier  * @brief  Read an amount of data in blocking mode from a specific memory
259*435832abSYann Gautier  *	   address
260*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
261*435832abSYann Gautier  *               the configuration information for the specified I2C.
262*435832abSYann Gautier  * @param  dev_addr: Target device address
263*435832abSYann Gautier  * @param  mem_addr: Internal memory address
264*435832abSYann Gautier  * @param  mem_add_size: size of internal memory address
265*435832abSYann Gautier  * @param  p_data: Pointer to data buffer
266*435832abSYann Gautier  * @param  size: Amount of data to be sent
267*435832abSYann Gautier  * @param  timeout: timeout duration
268*435832abSYann Gautier  * @retval 0 if OK, negative value else
269*435832abSYann Gautier  */
270*435832abSYann Gautier int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
271*435832abSYann Gautier 		       uint16_t mem_addr, uint16_t mem_add_size,
272*435832abSYann Gautier 		       uint8_t *p_data, uint16_t size, uint32_t timeout)
273*435832abSYann Gautier {
274*435832abSYann Gautier 	uint32_t tickstart;
275*435832abSYann Gautier 
276*435832abSYann Gautier 	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
277*435832abSYann Gautier 		return -EBUSY;
278*435832abSYann Gautier 	}
279*435832abSYann Gautier 
280*435832abSYann Gautier 	if ((p_data == NULL) || (size == 0U)) {
281*435832abSYann Gautier 		return  -EINVAL;
282*435832abSYann Gautier 	}
283*435832abSYann Gautier 
284*435832abSYann Gautier 	hi2c->lock = 1;
285*435832abSYann Gautier 
286*435832abSYann Gautier 	tickstart = (uint32_t)read_cntpct_el0();
287*435832abSYann Gautier 
288*435832abSYann Gautier 	if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
289*435832abSYann Gautier 			  tickstart) != 0) {
290*435832abSYann Gautier 		return -EIO;
291*435832abSYann Gautier 	}
292*435832abSYann Gautier 
293*435832abSYann Gautier 	hi2c->i2c_state     = I2C_STATE_BUSY_RX;
294*435832abSYann Gautier 	hi2c->i2c_mode      = I2C_MODE_MEM;
295*435832abSYann Gautier 	hi2c->i2c_err = I2C_ERROR_NONE;
296*435832abSYann Gautier 
297*435832abSYann Gautier 	hi2c->p_buff  = p_data;
298*435832abSYann Gautier 	hi2c->xfer_count = size;
299*435832abSYann Gautier 
300*435832abSYann Gautier 	/* Send Slave Address and Memory Address */
301*435832abSYann Gautier 	if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
302*435832abSYann Gautier 				    timeout, tickstart) != 0) {
303*435832abSYann Gautier 		hi2c->lock = 0;
304*435832abSYann Gautier 		return -EIO;
305*435832abSYann Gautier 	}
306*435832abSYann Gautier 
307*435832abSYann Gautier 	/*
308*435832abSYann Gautier 	 * Send Slave Address.
309*435832abSYann Gautier 	 * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
310*435832abSYann Gautier 	 * and generate RESTART.
311*435832abSYann Gautier 	 */
312*435832abSYann Gautier 	if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
313*435832abSYann Gautier 		hi2c->xfer_size = MAX_NBYTE_SIZE;
314*435832abSYann Gautier 		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
315*435832abSYann Gautier 				    I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
316*435832abSYann Gautier 	} else {
317*435832abSYann Gautier 		hi2c->xfer_size = hi2c->xfer_count;
318*435832abSYann Gautier 		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
319*435832abSYann Gautier 				    I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
320*435832abSYann Gautier 	}
321*435832abSYann Gautier 
322*435832abSYann Gautier 	do {
323*435832abSYann Gautier 		if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
324*435832abSYann Gautier 				  tickstart) != 0) {
325*435832abSYann Gautier 			return -EIO;
326*435832abSYann Gautier 		}
327*435832abSYann Gautier 
328*435832abSYann Gautier 		*hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
329*435832abSYann Gautier 		hi2c->p_buff++;
330*435832abSYann Gautier 		hi2c->xfer_size--;
331*435832abSYann Gautier 		hi2c->xfer_count--;
332*435832abSYann Gautier 
333*435832abSYann Gautier 		if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
334*435832abSYann Gautier 			if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
335*435832abSYann Gautier 					  tickstart) != 0) {
336*435832abSYann Gautier 				return -EIO;
337*435832abSYann Gautier 			}
338*435832abSYann Gautier 
339*435832abSYann Gautier 			if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
340*435832abSYann Gautier 				hi2c->xfer_size = MAX_NBYTE_SIZE;
341*435832abSYann Gautier 				i2c_transfer_config(hi2c, dev_addr,
342*435832abSYann Gautier 						    hi2c->xfer_size,
343*435832abSYann Gautier 						    I2C_RELOAD_MODE,
344*435832abSYann Gautier 						    I2C_NO_STARTSTOP);
345*435832abSYann Gautier 			} else {
346*435832abSYann Gautier 				hi2c->xfer_size = hi2c->xfer_count;
347*435832abSYann Gautier 				i2c_transfer_config(hi2c, dev_addr,
348*435832abSYann Gautier 						    hi2c->xfer_size,
349*435832abSYann Gautier 						    I2C_AUTOEND_MODE,
350*435832abSYann Gautier 						    I2C_NO_STARTSTOP);
351*435832abSYann Gautier 			}
352*435832abSYann Gautier 		}
353*435832abSYann Gautier 	} while (hi2c->xfer_count > 0U);
354*435832abSYann Gautier 
355*435832abSYann Gautier 	/*
356*435832abSYann Gautier 	 * No need to Check TC flag, with AUTOEND mode the stop
357*435832abSYann Gautier 	 * is automatically generated
358*435832abSYann Gautier 	 * Wait until STOPF flag is reset
359*435832abSYann Gautier 	 */
360*435832abSYann Gautier 	if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
361*435832abSYann Gautier 		return -EIO;
362*435832abSYann Gautier 	}
363*435832abSYann Gautier 
364*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
365*435832abSYann Gautier 
366*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
367*435832abSYann Gautier 
368*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
369*435832abSYann Gautier 	hi2c->i2c_mode  = I2C_MODE_NONE;
370*435832abSYann Gautier 
371*435832abSYann Gautier 	hi2c->lock = 0;
372*435832abSYann Gautier 
373*435832abSYann Gautier 	return 0;
374*435832abSYann Gautier }
375*435832abSYann Gautier 
376*435832abSYann Gautier /*
377*435832abSYann Gautier  * @brief  Checks if target device is ready for communication.
378*435832abSYann Gautier  * @note   This function is used with Memory devices
379*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
380*435832abSYann Gautier  *               the configuration information for the specified I2C.
381*435832abSYann Gautier  * @param  dev_addr: Target device address
382*435832abSYann Gautier  * @param  trials: Number of trials
383*435832abSYann Gautier  * @param  timeout: timeout duration
384*435832abSYann Gautier  * @retval 0 if OK, negative value else
385*435832abSYann Gautier  */
386*435832abSYann Gautier int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
387*435832abSYann Gautier 			      uint16_t dev_addr, uint32_t trials,
388*435832abSYann Gautier 			      uint32_t timeout)
389*435832abSYann Gautier {
390*435832abSYann Gautier 	uint32_t i2c_trials = 0U;
391*435832abSYann Gautier 
392*435832abSYann Gautier 	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
393*435832abSYann Gautier 		return -EBUSY;
394*435832abSYann Gautier 	}
395*435832abSYann Gautier 
396*435832abSYann Gautier 	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
397*435832abSYann Gautier 	    0U) {
398*435832abSYann Gautier 		return -EBUSY;
399*435832abSYann Gautier 	}
400*435832abSYann Gautier 
401*435832abSYann Gautier 	hi2c->lock = 1;
402*435832abSYann Gautier 
403*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_BUSY;
404*435832abSYann Gautier 	hi2c->i2c_err = I2C_ERROR_NONE;
405*435832abSYann Gautier 
406*435832abSYann Gautier 	do {
407*435832abSYann Gautier 		uint32_t tickstart;
408*435832abSYann Gautier 
409*435832abSYann Gautier 		/* Generate Start */
410*435832abSYann Gautier 		if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
411*435832abSYann Gautier 			mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
412*435832abSYann Gautier 				      (((uint32_t)dev_addr & I2C_CR2_SADD) |
413*435832abSYann Gautier 				       I2C_CR2_START | I2C_CR2_AUTOEND) &
414*435832abSYann Gautier 				       ~I2C_CR2_RD_WRN);
415*435832abSYann Gautier 		} else {
416*435832abSYann Gautier 			mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
417*435832abSYann Gautier 				      (((uint32_t)dev_addr & I2C_CR2_SADD) |
418*435832abSYann Gautier 				       I2C_CR2_START | I2C_CR2_ADD10) &
419*435832abSYann Gautier 				      ~I2C_CR2_RD_WRN);
420*435832abSYann Gautier 		}
421*435832abSYann Gautier 
422*435832abSYann Gautier 		/*
423*435832abSYann Gautier 		 * No need to Check TC flag, with AUTOEND mode the stop
424*435832abSYann Gautier 		 * is automatically generated
425*435832abSYann Gautier 		 * Wait until STOPF flag is set or a NACK flag is set
426*435832abSYann Gautier 		 */
427*435832abSYann Gautier 		tickstart = (uint32_t)read_cntpct_el0();
428*435832abSYann Gautier 		while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
429*435832abSYann Gautier 			 (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
430*435832abSYann Gautier 		       (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
431*435832abSYann Gautier 			if (timeout != MAX_DELAY) {
432*435832abSYann Gautier 				if ((((uint32_t)read_cntpct_el0() - tickstart) >
433*435832abSYann Gautier 				     timeout) || (timeout == 0U)) {
434*435832abSYann Gautier 					hi2c->i2c_state = I2C_STATE_READY;
435*435832abSYann Gautier 
436*435832abSYann Gautier 					hi2c->i2c_err |=
437*435832abSYann Gautier 						I2C_ERROR_TIMEOUT;
438*435832abSYann Gautier 
439*435832abSYann Gautier 					hi2c->lock = 0;
440*435832abSYann Gautier 
441*435832abSYann Gautier 					return -EIO;
442*435832abSYann Gautier 				}
443*435832abSYann Gautier 			}
444*435832abSYann Gautier 		}
445*435832abSYann Gautier 
446*435832abSYann Gautier 		/* Check if the NACKF flag has not been set */
447*435832abSYann Gautier 		if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
448*435832abSYann Gautier 		     I2C_FLAG_AF) == 0U) {
449*435832abSYann Gautier 			if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
450*435832abSYann Gautier 					  tickstart) != 0) {
451*435832abSYann Gautier 				return -EIO;
452*435832abSYann Gautier 			}
453*435832abSYann Gautier 
454*435832abSYann Gautier 			mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
455*435832abSYann Gautier 				      I2C_FLAG_STOPF);
456*435832abSYann Gautier 
457*435832abSYann Gautier 			hi2c->i2c_state = I2C_STATE_READY;
458*435832abSYann Gautier 
459*435832abSYann Gautier 			hi2c->lock = 0;
460*435832abSYann Gautier 
461*435832abSYann Gautier 			return 0;
462*435832abSYann Gautier 		}
463*435832abSYann Gautier 
464*435832abSYann Gautier 		if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
465*435832abSYann Gautier 				  tickstart) != 0) {
466*435832abSYann Gautier 			return -EIO;
467*435832abSYann Gautier 		}
468*435832abSYann Gautier 
469*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
470*435832abSYann Gautier 
471*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
472*435832abSYann Gautier 
473*435832abSYann Gautier 		if (i2c_trials == trials) {
474*435832abSYann Gautier 			mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
475*435832abSYann Gautier 					I2C_CR2_STOP);
476*435832abSYann Gautier 
477*435832abSYann Gautier 			if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
478*435832abSYann Gautier 					  tickstart) != 0) {
479*435832abSYann Gautier 				return -EIO;
480*435832abSYann Gautier 			}
481*435832abSYann Gautier 
482*435832abSYann Gautier 			mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
483*435832abSYann Gautier 				      I2C_FLAG_STOPF);
484*435832abSYann Gautier 		}
485*435832abSYann Gautier 
486*435832abSYann Gautier 		i2c_trials++;
487*435832abSYann Gautier 	} while (i2c_trials < trials);
488*435832abSYann Gautier 
489*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
490*435832abSYann Gautier 
491*435832abSYann Gautier 	hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
492*435832abSYann Gautier 
493*435832abSYann Gautier 	hi2c->lock = 0;
494*435832abSYann Gautier 
495*435832abSYann Gautier 	return -EIO;
496*435832abSYann Gautier }
497*435832abSYann Gautier 
498*435832abSYann Gautier /*
499*435832abSYann Gautier  * @brief  Master sends target device address followed by internal memory
500*435832abSYann Gautier  *	   address for write request.
501*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
502*435832abSYann Gautier  *               the configuration information for the specified I2C.
503*435832abSYann Gautier  * @param  dev_addr: Target device address
504*435832abSYann Gautier  * @param  mem_addr: Internal memory address
505*435832abSYann Gautier  * @param  mem_add_size: size of internal memory address
506*435832abSYann Gautier  * @param  timeout: timeout duration
507*435832abSYann Gautier  * @param  tick_start Tick start value
508*435832abSYann Gautier  * @retval 0 if OK, negative value else
509*435832abSYann Gautier  */
510*435832abSYann Gautier static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
511*435832abSYann Gautier 				    uint16_t dev_addr, uint16_t mem_addr,
512*435832abSYann Gautier 				    uint16_t mem_add_size, uint32_t timeout,
513*435832abSYann Gautier 				    uint32_t tick_start)
514*435832abSYann Gautier {
515*435832abSYann Gautier 	i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
516*435832abSYann Gautier 			    I2C_GENERATE_START_WRITE);
517*435832abSYann Gautier 
518*435832abSYann Gautier 	if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
519*435832abSYann Gautier 		return -EIO;
520*435832abSYann Gautier 	}
521*435832abSYann Gautier 
522*435832abSYann Gautier 	if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
523*435832abSYann Gautier 		/* Send Memory Address */
524*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
525*435832abSYann Gautier 			     (uint8_t)(mem_addr & 0x00FFU));
526*435832abSYann Gautier 	} else {
527*435832abSYann Gautier 		/* Send MSB of Memory Address */
528*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
529*435832abSYann Gautier 			     (uint8_t)((mem_addr & 0xFF00U) >> 8));
530*435832abSYann Gautier 
531*435832abSYann Gautier 		/* Wait until TXIS flag is set */
532*435832abSYann Gautier 		if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
533*435832abSYann Gautier 			return -EIO;
534*435832abSYann Gautier 		}
535*435832abSYann Gautier 
536*435832abSYann Gautier 		/* Send LSB of Memory Address */
537*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
538*435832abSYann Gautier 			     (uint8_t)(mem_addr & 0x00FFU));
539*435832abSYann Gautier 	}
540*435832abSYann Gautier 
541*435832abSYann Gautier 	if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
542*435832abSYann Gautier 	    0) {
543*435832abSYann Gautier 		return -EIO;
544*435832abSYann Gautier 	}
545*435832abSYann Gautier 
546*435832abSYann Gautier 	return 0;
547*435832abSYann Gautier }
548*435832abSYann Gautier 
549*435832abSYann Gautier /*
550*435832abSYann Gautier  * @brief  Master sends target device address followed by internal memory
551*435832abSYann Gautier  *	   address for read request.
552*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
553*435832abSYann Gautier  *               the configuration information for the specified I2C.
554*435832abSYann Gautier  * @param  dev_addr: Target device address
555*435832abSYann Gautier  * @param  mem_addr: Internal memory address
556*435832abSYann Gautier  * @param  mem_add_size: size of internal memory address
557*435832abSYann Gautier  * @param  timeout: timeout duration
558*435832abSYann Gautier  * @param  tick_start Tick start value
559*435832abSYann Gautier  * @retval 0 if OK, negative value else
560*435832abSYann Gautier  */
561*435832abSYann Gautier static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
562*435832abSYann Gautier 				   uint16_t mem_addr, uint16_t mem_add_size,
563*435832abSYann Gautier 				   uint32_t timeout, uint32_t tick_start)
564*435832abSYann Gautier {
565*435832abSYann Gautier 	i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
566*435832abSYann Gautier 			    I2C_GENERATE_START_WRITE);
567*435832abSYann Gautier 
568*435832abSYann Gautier 	if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
569*435832abSYann Gautier 		return -EIO;
570*435832abSYann Gautier 	}
571*435832abSYann Gautier 
572*435832abSYann Gautier 	if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
573*435832abSYann Gautier 		/* Send Memory Address */
574*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
575*435832abSYann Gautier 			     (uint8_t)(mem_addr & 0x00FFU));
576*435832abSYann Gautier 	} else {
577*435832abSYann Gautier 		/* Send MSB of Memory Address */
578*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
579*435832abSYann Gautier 			     (uint8_t)((mem_addr & 0xFF00U) >> 8));
580*435832abSYann Gautier 
581*435832abSYann Gautier 		/* Wait until TXIS flag is set */
582*435832abSYann Gautier 		if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
583*435832abSYann Gautier 			return -EIO;
584*435832abSYann Gautier 		}
585*435832abSYann Gautier 
586*435832abSYann Gautier 		/* Send LSB of Memory Address */
587*435832abSYann Gautier 		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
588*435832abSYann Gautier 			     (uint8_t)(mem_addr & 0x00FFU));
589*435832abSYann Gautier 	}
590*435832abSYann Gautier 
591*435832abSYann Gautier 	if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
592*435832abSYann Gautier 		return -EIO;
593*435832abSYann Gautier 	}
594*435832abSYann Gautier 
595*435832abSYann Gautier 	return 0;
596*435832abSYann Gautier }
597*435832abSYann Gautier 
598*435832abSYann Gautier /*
599*435832abSYann Gautier  * @brief  I2C Tx data register flush process.
600*435832abSYann Gautier  * @param  hi2c: I2C handle.
601*435832abSYann Gautier  * @retval None
602*435832abSYann Gautier  */
603*435832abSYann Gautier static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
604*435832abSYann Gautier {
605*435832abSYann Gautier 	/*
606*435832abSYann Gautier 	 * If a pending TXIS flag is set,
607*435832abSYann Gautier 	 * write a dummy data in TXDR to clear it.
608*435832abSYann Gautier 	 */
609*435832abSYann Gautier 	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
610*435832abSYann Gautier 	    0U) {
611*435832abSYann Gautier 		mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
612*435832abSYann Gautier 	}
613*435832abSYann Gautier 
614*435832abSYann Gautier 	/* Flush TX register if not empty */
615*435832abSYann Gautier 	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
616*435832abSYann Gautier 	    0U) {
617*435832abSYann Gautier 		mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
618*435832abSYann Gautier 				I2C_FLAG_TXE);
619*435832abSYann Gautier 	}
620*435832abSYann Gautier }
621*435832abSYann Gautier 
622*435832abSYann Gautier /*
623*435832abSYann Gautier  * @brief  This function handles I2C Communication timeout.
624*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
625*435832abSYann Gautier  *               the configuration information for the specified I2C.
626*435832abSYann Gautier  * @param  flag: Specifies the I2C flag to check.
627*435832abSYann Gautier  * @param  awaited_value: The awaited bit value for the flag (0 or 1).
628*435832abSYann Gautier  * @param  timeout: timeout duration
629*435832abSYann Gautier  * @param  tick_start: Tick start value
630*435832abSYann Gautier  * @retval 0 if OK, negative value else
631*435832abSYann Gautier  */
632*435832abSYann Gautier static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
633*435832abSYann Gautier 			 uint8_t awaited_value, uint32_t timeout,
634*435832abSYann Gautier 			 uint32_t tick_start)
635*435832abSYann Gautier {
636*435832abSYann Gautier 	uint8_t flag_check;
637*435832abSYann Gautier 
638*435832abSYann Gautier 	do {
639*435832abSYann Gautier 		flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
640*435832abSYann Gautier 			       flag) == flag) ? 1U : 0U;
641*435832abSYann Gautier 
642*435832abSYann Gautier 		if (timeout != MAX_DELAY) {
643*435832abSYann Gautier 			if ((((uint32_t)read_cntpct_el0() - tick_start) >
644*435832abSYann Gautier 			     timeout) || (timeout == 0U)) {
645*435832abSYann Gautier 				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
646*435832abSYann Gautier 				hi2c->i2c_state = I2C_STATE_READY;
647*435832abSYann Gautier 				hi2c->i2c_mode = I2C_MODE_NONE;
648*435832abSYann Gautier 
649*435832abSYann Gautier 				hi2c->lock = 0;
650*435832abSYann Gautier 				return -EIO;
651*435832abSYann Gautier 			}
652*435832abSYann Gautier 		}
653*435832abSYann Gautier 	} while (flag_check == awaited_value);
654*435832abSYann Gautier 
655*435832abSYann Gautier 	return 0;
656*435832abSYann Gautier }
657*435832abSYann Gautier 
658*435832abSYann Gautier /*
659*435832abSYann Gautier  * @brief  This function handles I2C Communication timeout for specific usage
660*435832abSYann Gautier  *	   of TXIS flag.
661*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
662*435832abSYann Gautier  *               the configuration information for the specified I2C.
663*435832abSYann Gautier  * @param  timeout: timeout duration
664*435832abSYann Gautier  * @param  tick_start: Tick start value
665*435832abSYann Gautier  * @retval 0 if OK, negative value else
666*435832abSYann Gautier  */
667*435832abSYann Gautier static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
668*435832abSYann Gautier 			 uint32_t tick_start)
669*435832abSYann Gautier {
670*435832abSYann Gautier 	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
671*435832abSYann Gautier 		I2C_FLAG_TXIS) == 0U) {
672*435832abSYann Gautier 		if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
673*435832abSYann Gautier 			return -EIO;
674*435832abSYann Gautier 		}
675*435832abSYann Gautier 
676*435832abSYann Gautier 		if (timeout != MAX_DELAY) {
677*435832abSYann Gautier 			if ((((uint32_t)read_cntpct_el0() - tick_start) >
678*435832abSYann Gautier 			     timeout) || (timeout == 0U)) {
679*435832abSYann Gautier 				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
680*435832abSYann Gautier 				hi2c->i2c_state = I2C_STATE_READY;
681*435832abSYann Gautier 				hi2c->i2c_mode = I2C_MODE_NONE;
682*435832abSYann Gautier 
683*435832abSYann Gautier 				hi2c->lock = 0;
684*435832abSYann Gautier 
685*435832abSYann Gautier 				return -EIO;
686*435832abSYann Gautier 			}
687*435832abSYann Gautier 		}
688*435832abSYann Gautier 	}
689*435832abSYann Gautier 
690*435832abSYann Gautier 	return 0;
691*435832abSYann Gautier }
692*435832abSYann Gautier 
693*435832abSYann Gautier /*
694*435832abSYann Gautier  * @brief  This function handles I2C Communication timeout for specific
695*435832abSYann Gautier  *	   usage of STOP flag.
696*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
697*435832abSYann Gautier  *               the configuration information for the specified I2C.
698*435832abSYann Gautier  * @param  timeout: timeout duration
699*435832abSYann Gautier  * @param  tick_start: Tick start value
700*435832abSYann Gautier  * @retval 0 if OK, negative value else
701*435832abSYann Gautier  */
702*435832abSYann Gautier static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
703*435832abSYann Gautier 			 uint32_t tick_start)
704*435832abSYann Gautier {
705*435832abSYann Gautier 	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
706*435832abSYann Gautier 		 I2C_FLAG_STOPF) == 0U) {
707*435832abSYann Gautier 		if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
708*435832abSYann Gautier 			return -EIO;
709*435832abSYann Gautier 		}
710*435832abSYann Gautier 
711*435832abSYann Gautier 		if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
712*435832abSYann Gautier 		    (timeout == 0U)) {
713*435832abSYann Gautier 			hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
714*435832abSYann Gautier 			hi2c->i2c_state = I2C_STATE_READY;
715*435832abSYann Gautier 			hi2c->i2c_mode = I2C_MODE_NONE;
716*435832abSYann Gautier 
717*435832abSYann Gautier 			hi2c->lock = 0;
718*435832abSYann Gautier 
719*435832abSYann Gautier 			return -EIO;
720*435832abSYann Gautier 		}
721*435832abSYann Gautier 	}
722*435832abSYann Gautier 
723*435832abSYann Gautier 	return 0;
724*435832abSYann Gautier }
725*435832abSYann Gautier 
726*435832abSYann Gautier /*
727*435832abSYann Gautier  * @brief  This function handles Acknowledge failed detection during
728*435832abSYann Gautier  *	   an I2C Communication.
729*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
730*435832abSYann Gautier  *               the configuration information for the specified I2C.
731*435832abSYann Gautier  * @param  timeout: timeout duration
732*435832abSYann Gautier  * @param  tick_start: Tick start value
733*435832abSYann Gautier  * @retval 0 if OK, negative value else
734*435832abSYann Gautier  */
735*435832abSYann Gautier static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
736*435832abSYann Gautier 			  uint32_t tick_start)
737*435832abSYann Gautier {
738*435832abSYann Gautier 	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
739*435832abSYann Gautier 		return 0;
740*435832abSYann Gautier 	}
741*435832abSYann Gautier 
742*435832abSYann Gautier 	/*
743*435832abSYann Gautier 	 * Wait until STOP Flag is reset.
744*435832abSYann Gautier 	 * AutoEnd should be initiate after AF.
745*435832abSYann Gautier 	 */
746*435832abSYann Gautier 	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
747*435832abSYann Gautier 		I2C_FLAG_STOPF) == 0U) {
748*435832abSYann Gautier 		if (timeout != MAX_DELAY) {
749*435832abSYann Gautier 			if ((((uint32_t)read_cntpct_el0() - tick_start) >
750*435832abSYann Gautier 			     timeout) || (timeout == 0U)) {
751*435832abSYann Gautier 				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
752*435832abSYann Gautier 				hi2c->i2c_state = I2C_STATE_READY;
753*435832abSYann Gautier 				hi2c->i2c_mode = I2C_MODE_NONE;
754*435832abSYann Gautier 
755*435832abSYann Gautier 				hi2c->lock = 0;
756*435832abSYann Gautier 
757*435832abSYann Gautier 				return -EIO;
758*435832abSYann Gautier 			}
759*435832abSYann Gautier 		}
760*435832abSYann Gautier 	}
761*435832abSYann Gautier 
762*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
763*435832abSYann Gautier 
764*435832abSYann Gautier 	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
765*435832abSYann Gautier 
766*435832abSYann Gautier 	i2c_flush_txdr(hi2c);
767*435832abSYann Gautier 
768*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
769*435832abSYann Gautier 
770*435832abSYann Gautier 	hi2c->i2c_err |= I2C_ERROR_AF;
771*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
772*435832abSYann Gautier 	hi2c->i2c_mode = I2C_MODE_NONE;
773*435832abSYann Gautier 
774*435832abSYann Gautier 	hi2c->lock = 0;
775*435832abSYann Gautier 
776*435832abSYann Gautier 	return -EIO;
777*435832abSYann Gautier }
778*435832abSYann Gautier 
779*435832abSYann Gautier /*
780*435832abSYann Gautier  * @brief  Handles I2Cx communication when starting transfer or during transfer
781*435832abSYann Gautier  *	   (TC or TCR flag are set).
782*435832abSYann Gautier  * @param  hi2c: I2C handle.
783*435832abSYann Gautier  * @param  dev_addr: Specifies the slave address to be programmed.
784*435832abSYann Gautier  * @param  size: Specifies the number of bytes to be programmed.
785*435832abSYann Gautier  *   This parameter must be a value between 0 and 255.
786*435832abSYann Gautier  * @param  i2c_mode: New state of the I2C START condition generation.
787*435832abSYann Gautier  *   This parameter can be one of the following values:
788*435832abSYann Gautier  *     @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
789*435832abSYann Gautier  *     @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
790*435832abSYann Gautier  *     @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
791*435832abSYann Gautier  * @param  request: New state of the I2C START condition generation.
792*435832abSYann Gautier  *   This parameter can be one of the following values:
793*435832abSYann Gautier  *     @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
794*435832abSYann Gautier  *     @arg @ref I2C_GENERATE_STOP: Generate stop condition
795*435832abSYann Gautier  *                                  (size should be set to 0).
796*435832abSYann Gautier  *     @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
797*435832abSYann Gautier  *     @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
798*435832abSYann Gautier  * @retval None
799*435832abSYann Gautier  */
800*435832abSYann Gautier static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
801*435832abSYann Gautier 				uint16_t size, uint32_t i2c_mode,
802*435832abSYann Gautier 				uint32_t request)
803*435832abSYann Gautier {
804*435832abSYann Gautier 	uint32_t clr_value, set_value;
805*435832abSYann Gautier 
806*435832abSYann Gautier 	clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
807*435832abSYann Gautier 		     I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
808*435832abSYann Gautier 		(I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
809*435832abSYann Gautier 
810*435832abSYann Gautier 	set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
811*435832abSYann Gautier 		(((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
812*435832abSYann Gautier 		i2c_mode | request;
813*435832abSYann Gautier 
814*435832abSYann Gautier 	mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
815*435832abSYann Gautier }
816*435832abSYann Gautier 
817*435832abSYann Gautier /*
818*435832abSYann Gautier  * @brief  Configure I2C Analog noise filter.
819*435832abSYann Gautier  * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
820*435832abSYann Gautier  *               the configuration information for the specified I2Cx peripheral
821*435832abSYann Gautier  * @param  analog_filter: New state of the Analog filter.
822*435832abSYann Gautier  * @retval 0 if OK, negative value else
823*435832abSYann Gautier  */
824*435832abSYann Gautier int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
825*435832abSYann Gautier 				   uint32_t analog_filter)
826*435832abSYann Gautier {
827*435832abSYann Gautier 	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
828*435832abSYann Gautier 		return -EBUSY;
829*435832abSYann Gautier 	}
830*435832abSYann Gautier 
831*435832abSYann Gautier 	hi2c->lock = 1;
832*435832abSYann Gautier 
833*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_BUSY;
834*435832abSYann Gautier 
835*435832abSYann Gautier 	/* Disable the selected I2C peripheral */
836*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
837*435832abSYann Gautier 
838*435832abSYann Gautier 	/* Reset I2Cx ANOFF bit */
839*435832abSYann Gautier 	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
840*435832abSYann Gautier 
841*435832abSYann Gautier 	/* Set analog filter bit*/
842*435832abSYann Gautier 	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
843*435832abSYann Gautier 
844*435832abSYann Gautier 	/* Enable the selected I2C peripheral */
845*435832abSYann Gautier 	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
846*435832abSYann Gautier 
847*435832abSYann Gautier 	hi2c->i2c_state = I2C_STATE_READY;
848*435832abSYann Gautier 
849*435832abSYann Gautier 	hi2c->lock = 0;
850*435832abSYann Gautier 
851*435832abSYann Gautier 	return 0;
852*435832abSYann Gautier }
853