xref: /optee_os/core/drivers/stm32_i2c.c (revision b844655c9519aed1cdaa146873a02fcbf7585006)
1*b844655cSEtienne Carriere // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2*b844655cSEtienne Carriere /*
3*b844655cSEtienne Carriere  * Copyright (c) 2017-2019, STMicroelectronics
4*b844655cSEtienne Carriere  *
5*b844655cSEtienne Carriere  * The driver API is defined in header file stm32_i2c.h.
6*b844655cSEtienne Carriere  *
7*b844655cSEtienne Carriere  * I2C bus driver does not register to the PM framework. It is the
8*b844655cSEtienne Carriere  * responsibility of the bus owner to call the related STM32 I2C driver
9*b844655cSEtienne Carriere  * API functions when bus suspends or resumes.
10*b844655cSEtienne Carriere  */
11*b844655cSEtienne Carriere 
12*b844655cSEtienne Carriere #include <arm.h>
13*b844655cSEtienne Carriere #include <drivers/stm32_i2c.h>
14*b844655cSEtienne Carriere #include <io.h>
15*b844655cSEtienne Carriere #include <kernel/delay.h>
16*b844655cSEtienne Carriere #include <kernel/dt.h>
17*b844655cSEtienne Carriere #include <kernel/generic_boot.h>
18*b844655cSEtienne Carriere #include <kernel/panic.h>
19*b844655cSEtienne Carriere #include <libfdt.h>
20*b844655cSEtienne Carriere #include <stdbool.h>
21*b844655cSEtienne Carriere #include <stdlib.h>
22*b844655cSEtienne Carriere #include <stm32_util.h>
23*b844655cSEtienne Carriere #include <trace.h>
24*b844655cSEtienne Carriere 
25*b844655cSEtienne Carriere /* STM32 I2C registers offsets */
26*b844655cSEtienne Carriere #define I2C_CR1				0x00U
27*b844655cSEtienne Carriere #define I2C_CR2				0x04U
28*b844655cSEtienne Carriere #define I2C_OAR1			0x08U
29*b844655cSEtienne Carriere #define I2C_OAR2			0x0CU
30*b844655cSEtienne Carriere #define I2C_TIMINGR			0x10U
31*b844655cSEtienne Carriere #define I2C_TIMEOUTR			0x14U
32*b844655cSEtienne Carriere #define I2C_ISR				0x18U
33*b844655cSEtienne Carriere #define I2C_ICR				0x1CU
34*b844655cSEtienne Carriere #define I2C_PECR			0x20U
35*b844655cSEtienne Carriere #define I2C_RXDR			0x24U
36*b844655cSEtienne Carriere #define I2C_TXDR			0x28U
37*b844655cSEtienne Carriere 
38*b844655cSEtienne Carriere /* Bit definition for I2C_CR1 register */
39*b844655cSEtienne Carriere #define I2C_CR1_PE			BIT(0)
40*b844655cSEtienne Carriere #define I2C_CR1_TXIE			BIT(1)
41*b844655cSEtienne Carriere #define I2C_CR1_RXIE			BIT(2)
42*b844655cSEtienne Carriere #define I2C_CR1_ADDRIE			BIT(3)
43*b844655cSEtienne Carriere #define I2C_CR1_NACKIE			BIT(4)
44*b844655cSEtienne Carriere #define I2C_CR1_STOPIE			BIT(5)
45*b844655cSEtienne Carriere #define I2C_CR1_TCIE			BIT(6)
46*b844655cSEtienne Carriere #define I2C_CR1_ERRIE			BIT(7)
47*b844655cSEtienne Carriere #define I2C_CR1_DNF			GENMASK_32(11, 8)
48*b844655cSEtienne Carriere #define I2C_CR1_ANFOFF			BIT(12)
49*b844655cSEtienne Carriere #define I2C_CR1_SWRST			BIT(13)
50*b844655cSEtienne Carriere #define I2C_CR1_TXDMAEN			BIT(14)
51*b844655cSEtienne Carriere #define I2C_CR1_RXDMAEN			BIT(15)
52*b844655cSEtienne Carriere #define I2C_CR1_SBC			BIT(16)
53*b844655cSEtienne Carriere #define I2C_CR1_NOSTRETCH		BIT(17)
54*b844655cSEtienne Carriere #define I2C_CR1_WUPEN			BIT(18)
55*b844655cSEtienne Carriere #define I2C_CR1_GCEN			BIT(19)
56*b844655cSEtienne Carriere #define I2C_CR1_SMBHEN			BIT(22)
57*b844655cSEtienne Carriere #define I2C_CR1_SMBDEN			BIT(21)
58*b844655cSEtienne Carriere #define I2C_CR1_ALERTEN			BIT(22)
59*b844655cSEtienne Carriere #define I2C_CR1_PECEN			BIT(23)
60*b844655cSEtienne Carriere 
61*b844655cSEtienne Carriere /* Bit definition for I2C_CR2 register */
62*b844655cSEtienne Carriere #define I2C_CR2_SADD			GENMASK_32(9, 0)
63*b844655cSEtienne Carriere #define I2C_CR2_RD_WRN			BIT(10)
64*b844655cSEtienne Carriere #define I2C_CR2_RD_WRN_OFFSET		10U
65*b844655cSEtienne Carriere #define I2C_CR2_ADD10			BIT(11)
66*b844655cSEtienne Carriere #define I2C_CR2_HEAD10R			BIT(12)
67*b844655cSEtienne Carriere #define I2C_CR2_START			BIT(13)
68*b844655cSEtienne Carriere #define I2C_CR2_STOP			BIT(14)
69*b844655cSEtienne Carriere #define I2C_CR2_NACK			BIT(15)
70*b844655cSEtienne Carriere #define I2C_CR2_NBYTES			GENMASK_32(23, 16)
71*b844655cSEtienne Carriere #define I2C_CR2_NBYTES_OFFSET		16U
72*b844655cSEtienne Carriere #define I2C_CR2_RELOAD			BIT(24)
73*b844655cSEtienne Carriere #define I2C_CR2_AUTOEND			BIT(25)
74*b844655cSEtienne Carriere #define I2C_CR2_PECBYTE			BIT(26)
75*b844655cSEtienne Carriere 
76*b844655cSEtienne Carriere /* Bit definition for I2C_OAR1 register */
77*b844655cSEtienne Carriere #define I2C_OAR1_OA1			GENMASK_32(9, 0)
78*b844655cSEtienne Carriere #define I2C_OAR1_OA1MODE		BIT(10)
79*b844655cSEtienne Carriere #define I2C_OAR1_OA1EN			BIT(15)
80*b844655cSEtienne Carriere 
81*b844655cSEtienne Carriere /* Bit definition for I2C_OAR2 register */
82*b844655cSEtienne Carriere #define I2C_OAR2_OA2			GENMASK_32(7, 1)
83*b844655cSEtienne Carriere #define I2C_OAR2_OA2MSK			GENMASK_32(10, 8)
84*b844655cSEtienne Carriere #define I2C_OAR2_OA2NOMASK		0
85*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK01		BIT(8)
86*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK02		BIT(9)
87*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK03		GENMASK_32(9, 8)
88*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK04		BIT(10)
89*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK05		(BIT(8) | BIT(10))
90*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK06		(BIT(9) | BIT(10))
91*b844655cSEtienne Carriere #define I2C_OAR2_OA2MASK07		GENMASK_32(10, 8)
92*b844655cSEtienne Carriere #define I2C_OAR2_OA2EN			BIT(15)
93*b844655cSEtienne Carriere 
94*b844655cSEtienne Carriere /* Bit definition for I2C_TIMINGR register */
95*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLL		GENMASK_32(7, 0)
96*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLH		GENMASK_32(15, 8)
97*b844655cSEtienne Carriere #define I2C_TIMINGR_SDADEL		GENMASK_32(19, 16)
98*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLDEL		GENMASK_32(23, 20)
99*b844655cSEtienne Carriere #define I2C_TIMINGR_PRESC		GENMASK_32(31, 28)
100*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLL_MAX		(I2C_TIMINGR_SCLL + 1)
101*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLH_MAX		((I2C_TIMINGR_SCLH >> 8) + 1)
102*b844655cSEtienne Carriere #define I2C_TIMINGR_SDADEL_MAX		((I2C_TIMINGR_SDADEL >> 16) + 1)
103*b844655cSEtienne Carriere #define I2C_TIMINGR_SCLDEL_MAX		((I2C_TIMINGR_SCLDEL >> 20) + 1)
104*b844655cSEtienne Carriere #define I2C_TIMINGR_PRESC_MAX		((I2C_TIMINGR_PRESC >> 28) + 1)
105*b844655cSEtienne Carriere #define I2C_SET_TIMINGR_SCLL(n)		((n) & \
106*b844655cSEtienne Carriere 					 (I2C_TIMINGR_SCLL_MAX - 1))
107*b844655cSEtienne Carriere #define I2C_SET_TIMINGR_SCLH(n)		(((n) & \
108*b844655cSEtienne Carriere 					  (I2C_TIMINGR_SCLH_MAX - 1)) << 8)
109*b844655cSEtienne Carriere #define I2C_SET_TIMINGR_SDADEL(n)	(((n) & \
110*b844655cSEtienne Carriere 					  (I2C_TIMINGR_SDADEL_MAX - 1)) << 16)
111*b844655cSEtienne Carriere #define I2C_SET_TIMINGR_SCLDEL(n)	(((n) & \
112*b844655cSEtienne Carriere 					  (I2C_TIMINGR_SCLDEL_MAX - 1)) << 20)
113*b844655cSEtienne Carriere #define I2C_SET_TIMINGR_PRESC(n)	(((n) & \
114*b844655cSEtienne Carriere 					  (I2C_TIMINGR_PRESC_MAX - 1)) << 28)
115*b844655cSEtienne Carriere 
116*b844655cSEtienne Carriere /* Bit definition for I2C_TIMEOUTR register */
117*b844655cSEtienne Carriere #define I2C_TIMEOUTR_TIMEOUTA		GENMASK_32(11, 0)
118*b844655cSEtienne Carriere #define I2C_TIMEOUTR_TIDLE		BIT(12)
119*b844655cSEtienne Carriere #define I2C_TIMEOUTR_TIMOUTEN		BIT(15)
120*b844655cSEtienne Carriere #define I2C_TIMEOUTR_TIMEOUTB		GENMASK_32(27, 16)
121*b844655cSEtienne Carriere #define I2C_TIMEOUTR_TEXTEN		BIT(31)
122*b844655cSEtienne Carriere 
123*b844655cSEtienne Carriere /* Bit definition for I2C_ISR register */
124*b844655cSEtienne Carriere #define I2C_ISR_TXE			BIT(0)
125*b844655cSEtienne Carriere #define I2C_ISR_TXIS			BIT(1)
126*b844655cSEtienne Carriere #define I2C_ISR_RXNE			BIT(2)
127*b844655cSEtienne Carriere #define I2C_ISR_ADDR			BIT(3)
128*b844655cSEtienne Carriere #define I2C_ISR_NACKF			BIT(4)
129*b844655cSEtienne Carriere #define I2C_ISR_STOPF			BIT(5)
130*b844655cSEtienne Carriere #define I2C_ISR_TC			BIT(6)
131*b844655cSEtienne Carriere #define I2C_ISR_TCR			BIT(7)
132*b844655cSEtienne Carriere #define I2C_ISR_BERR			BIT(8)
133*b844655cSEtienne Carriere #define I2C_ISR_ARLO			BIT(9)
134*b844655cSEtienne Carriere #define I2C_ISR_OVR			BIT(10)
135*b844655cSEtienne Carriere #define I2C_ISR_PECERR			BIT(11)
136*b844655cSEtienne Carriere #define I2C_ISR_TIMEOUT			BIT(12)
137*b844655cSEtienne Carriere #define I2C_ISR_ALERT			BIT(13)
138*b844655cSEtienne Carriere #define I2C_ISR_BUSY			BIT(15)
139*b844655cSEtienne Carriere #define I2C_ISR_DIR			BIT(16)
140*b844655cSEtienne Carriere #define I2C_ISR_ADDCODE			GENMASK_32(23, 17)
141*b844655cSEtienne Carriere 
142*b844655cSEtienne Carriere /* Bit definition for I2C_ICR register */
143*b844655cSEtienne Carriere #define I2C_ICR_ADDRCF			BIT(3)
144*b844655cSEtienne Carriere #define I2C_ICR_NACKCF			BIT(4)
145*b844655cSEtienne Carriere #define I2C_ICR_STOPCF			BIT(5)
146*b844655cSEtienne Carriere #define I2C_ICR_BERRCF			BIT(8)
147*b844655cSEtienne Carriere #define I2C_ICR_ARLOCF			BIT(9)
148*b844655cSEtienne Carriere #define I2C_ICR_OVRCF			BIT(10)
149*b844655cSEtienne Carriere #define I2C_ICR_PECCF			BIT(11)
150*b844655cSEtienne Carriere #define I2C_ICR_TIMOUTCF		BIT(12)
151*b844655cSEtienne Carriere #define I2C_ICR_ALERTCF			BIT(13)
152*b844655cSEtienne Carriere 
153*b844655cSEtienne Carriere /* Max data size for a single I2C transfer */
154*b844655cSEtienne Carriere #define MAX_NBYTE_SIZE		255U
155*b844655cSEtienne Carriere 
156*b844655cSEtienne Carriere #define I2C_NSEC_PER_SEC	1000000000L
157*b844655cSEtienne Carriere #define I2C_TIMEOUT_BUSY_MS		25U
158*b844655cSEtienne Carriere 
159*b844655cSEtienne Carriere #define CR2_RESET_MASK			(I2C_CR2_SADD | I2C_CR2_HEAD10R | \
160*b844655cSEtienne Carriere 					 I2C_CR2_NBYTES | I2C_CR2_RELOAD | \
161*b844655cSEtienne Carriere 					 I2C_CR2_RD_WRN)
162*b844655cSEtienne Carriere 
163*b844655cSEtienne Carriere #define TIMINGR_CLEAR_MASK		(I2C_TIMINGR_SCLL | I2C_TIMINGR_SCLH | \
164*b844655cSEtienne Carriere 					 I2C_TIMINGR_SDADEL | \
165*b844655cSEtienne Carriere 					 I2C_TIMINGR_SCLDEL | I2C_TIMINGR_PRESC)
166*b844655cSEtienne Carriere 
167*b844655cSEtienne Carriere /*
168*b844655cSEtienne Carriere  * I2C transfer modes
169*b844655cSEtienne Carriere  * I2C_RELOAD: Enable Reload mode
170*b844655cSEtienne Carriere  * I2C_AUTOEND_MODE: Enable automatic end mode
171*b844655cSEtienne Carriere  * I2C_SOFTEND_MODE: Enable software end mode
172*b844655cSEtienne Carriere  */
173*b844655cSEtienne Carriere #define I2C_RELOAD_MODE				I2C_CR2_RELOAD
174*b844655cSEtienne Carriere #define I2C_AUTOEND_MODE			I2C_CR2_AUTOEND
175*b844655cSEtienne Carriere #define I2C_SOFTEND_MODE			0x0
176*b844655cSEtienne Carriere 
177*b844655cSEtienne Carriere /*
178*b844655cSEtienne Carriere  * Start/restart/stop I2C transfer requests.
179*b844655cSEtienne Carriere  *
180*b844655cSEtienne Carriere  * I2C_NO_STARTSTOP: Don't Generate stop and start condition
181*b844655cSEtienne Carriere  * I2C_GENERATE_STOP: Generate stop condition (size should be set to 0)
182*b844655cSEtienne Carriere  * I2C_GENERATE_START_READ: Generate Restart for read request.
183*b844655cSEtienne Carriere  * I2C_GENERATE_START_WRITE: Generate Restart for write request
184*b844655cSEtienne Carriere  */
185*b844655cSEtienne Carriere #define I2C_NO_STARTSTOP			0x0
186*b844655cSEtienne Carriere #define I2C_GENERATE_STOP			(BIT(31) | I2C_CR2_STOP)
187*b844655cSEtienne Carriere #define I2C_GENERATE_START_READ			(BIT(31) | I2C_CR2_START | \
188*b844655cSEtienne Carriere 						 I2C_CR2_RD_WRN)
189*b844655cSEtienne Carriere #define I2C_GENERATE_START_WRITE		(BIT(31) | I2C_CR2_START)
190*b844655cSEtienne Carriere 
191*b844655cSEtienne Carriere /* Memory address byte sizes */
192*b844655cSEtienne Carriere #define I2C_MEMADD_SIZE_8BIT		1
193*b844655cSEtienne Carriere #define I2C_MEMADD_SIZE_16BIT		2
194*b844655cSEtienne Carriere 
195*b844655cSEtienne Carriere /*
196*b844655cSEtienne Carriere  * struct i2c_spec_s - Private I2C timing specifications.
197*b844655cSEtienne Carriere  * @rate: I2C bus speed (Hz)
198*b844655cSEtienne Carriere  * @rate_min: 80% of I2C bus speed (Hz)
199*b844655cSEtienne Carriere  * @rate_max: 120% of I2C bus speed (Hz)
200*b844655cSEtienne Carriere  * @fall_max: Max fall time of both SDA and SCL signals (ns)
201*b844655cSEtienne Carriere  * @rise_max: Max rise time of both SDA and SCL signals (ns)
202*b844655cSEtienne Carriere  * @hddat_min: Min data hold time (ns)
203*b844655cSEtienne Carriere  * @vddat_max: Max data valid time (ns)
204*b844655cSEtienne Carriere  * @sudat_min: Min data setup time (ns)
205*b844655cSEtienne Carriere  * @l_min: Min low period of the SCL clock (ns)
206*b844655cSEtienne Carriere  * @h_min: Min high period of the SCL clock (ns)
207*b844655cSEtienne Carriere  */
208*b844655cSEtienne Carriere struct i2c_spec_s {
209*b844655cSEtienne Carriere 	uint32_t rate;
210*b844655cSEtienne Carriere 	uint32_t rate_min;
211*b844655cSEtienne Carriere 	uint32_t rate_max;
212*b844655cSEtienne Carriere 	uint32_t fall_max;
213*b844655cSEtienne Carriere 	uint32_t rise_max;
214*b844655cSEtienne Carriere 	uint32_t hddat_min;
215*b844655cSEtienne Carriere 	uint32_t vddat_max;
216*b844655cSEtienne Carriere 	uint32_t sudat_min;
217*b844655cSEtienne Carriere 	uint32_t l_min;
218*b844655cSEtienne Carriere 	uint32_t h_min;
219*b844655cSEtienne Carriere };
220*b844655cSEtienne Carriere 
221*b844655cSEtienne Carriere /*
222*b844655cSEtienne Carriere  * struct i2c_timing_s - Private I2C output parameters.
223*b844655cSEtienne Carriere  * @scldel: Data setup time
224*b844655cSEtienne Carriere  * @sdadel: Data hold time
225*b844655cSEtienne Carriere  * @sclh: SCL high period (master mode)
226*b844655cSEtienne Carriere  * @sclh: SCL low period (master mode)
227*b844655cSEtienne Carriere  * @is_saved: True if relating to a configuration candidate
228*b844655cSEtienne Carriere  */
229*b844655cSEtienne Carriere struct i2c_timing_s {
230*b844655cSEtienne Carriere 	uint8_t scldel;
231*b844655cSEtienne Carriere 	uint8_t sdadel;
232*b844655cSEtienne Carriere 	uint8_t sclh;
233*b844655cSEtienne Carriere 	uint8_t scll;
234*b844655cSEtienne Carriere 	bool is_saved;
235*b844655cSEtienne Carriere };
236*b844655cSEtienne Carriere 
237*b844655cSEtienne Carriere /*
238*b844655cSEtienne Carriere  * I2C specification values as per version 6.0, 4th of April 2014 [1],
239*b844655cSEtienne Carriere  * table 10 page 48: Characteristics of the SDA and SCL bus lines for
240*b844655cSEtienne Carriere  * Standard, Fast, and Fast-mode Plus I2C-bus devices.
241*b844655cSEtienne Carriere  *
242*b844655cSEtienne Carriere  * [1] https://www.nxp.com/docs/en/user-guide/UM10204.pdf
243*b844655cSEtienne Carriere  */
244*b844655cSEtienne Carriere enum i2c_speed_e {
245*b844655cSEtienne Carriere 	I2C_SPEED_STANDARD,	/* 100 kHz */
246*b844655cSEtienne Carriere 	I2C_SPEED_FAST,		/* 400 kHz */
247*b844655cSEtienne Carriere 	I2C_SPEED_FAST_PLUS,	/* 1 MHz   */
248*b844655cSEtienne Carriere };
249*b844655cSEtienne Carriere 
250*b844655cSEtienne Carriere #define STANDARD_RATE				100000
251*b844655cSEtienne Carriere #define FAST_RATE				400000
252*b844655cSEtienne Carriere #define FAST_PLUS_RATE				1000000
253*b844655cSEtienne Carriere 
254*b844655cSEtienne Carriere static const struct i2c_spec_s i2c_specs[] = {
255*b844655cSEtienne Carriere 	[I2C_SPEED_STANDARD] = {
256*b844655cSEtienne Carriere 		.rate = STANDARD_RATE,
257*b844655cSEtienne Carriere 		.rate_min = (STANDARD_RATE * 80) / 100,
258*b844655cSEtienne Carriere 		.rate_max = (STANDARD_RATE * 120) / 100,
259*b844655cSEtienne Carriere 		.fall_max = 300,
260*b844655cSEtienne Carriere 		.rise_max = 1000,
261*b844655cSEtienne Carriere 		.hddat_min = 0,
262*b844655cSEtienne Carriere 		.vddat_max = 3450,
263*b844655cSEtienne Carriere 		.sudat_min = 250,
264*b844655cSEtienne Carriere 		.l_min = 4700,
265*b844655cSEtienne Carriere 		.h_min = 4000,
266*b844655cSEtienne Carriere 	},
267*b844655cSEtienne Carriere 	[I2C_SPEED_FAST] = {
268*b844655cSEtienne Carriere 		.rate = FAST_RATE,
269*b844655cSEtienne Carriere 		.rate_min = (FAST_RATE * 80) / 100,
270*b844655cSEtienne Carriere 		.rate_max = (FAST_RATE * 120) / 100,
271*b844655cSEtienne Carriere 		.fall_max = 300,
272*b844655cSEtienne Carriere 		.rise_max = 300,
273*b844655cSEtienne Carriere 		.hddat_min = 0,
274*b844655cSEtienne Carriere 		.vddat_max = 900,
275*b844655cSEtienne Carriere 		.sudat_min = 100,
276*b844655cSEtienne Carriere 		.l_min = 1300,
277*b844655cSEtienne Carriere 		.h_min = 600,
278*b844655cSEtienne Carriere 	},
279*b844655cSEtienne Carriere 	[I2C_SPEED_FAST_PLUS] = {
280*b844655cSEtienne Carriere 		.rate = FAST_PLUS_RATE,
281*b844655cSEtienne Carriere 		.rate_min = (FAST_PLUS_RATE * 80) / 100,
282*b844655cSEtienne Carriere 		.rate_max = (FAST_PLUS_RATE * 120) / 100,
283*b844655cSEtienne Carriere 		.fall_max = 100,
284*b844655cSEtienne Carriere 		.rise_max = 120,
285*b844655cSEtienne Carriere 		.hddat_min = 0,
286*b844655cSEtienne Carriere 		.vddat_max = 450,
287*b844655cSEtienne Carriere 		.sudat_min = 50,
288*b844655cSEtienne Carriere 		.l_min = 500,
289*b844655cSEtienne Carriere 		.h_min = 260,
290*b844655cSEtienne Carriere 	},
291*b844655cSEtienne Carriere };
292*b844655cSEtienne Carriere 
293*b844655cSEtienne Carriere /*
294*b844655cSEtienne Carriere  * I2C request parameters
295*b844655cSEtienne Carriere  * @dev_addr: I2C address of the target device
296*b844655cSEtienne Carriere  * @mode: Communication mode, one of I2C_MODE_(MASTER|MEM)
297*b844655cSEtienne Carriere  * @mem_addr: Target memory cell accessed in device (memory mode)
298*b844655cSEtienne Carriere  * @mem_addr_size: Byte size of the memory cell address (memory mode)
299*b844655cSEtienne Carriere  * @timeout_ms: Timeout in millisenconds for the request
300*b844655cSEtienne Carriere  */
301*b844655cSEtienne Carriere struct i2c_request {
302*b844655cSEtienne Carriere 	uint32_t dev_addr;
303*b844655cSEtienne Carriere 	enum i2c_mode_e mode;
304*b844655cSEtienne Carriere 	uint32_t mem_addr;
305*b844655cSEtienne Carriere 	uint32_t mem_addr_size;
306*b844655cSEtienne Carriere 	unsigned int timeout_ms;
307*b844655cSEtienne Carriere };
308*b844655cSEtienne Carriere 
309*b844655cSEtienne Carriere static vaddr_t get_base(struct i2c_handle_s *hi2c)
310*b844655cSEtienne Carriere {
311*b844655cSEtienne Carriere 	return io_pa_or_va(&hi2c->base);
312*b844655cSEtienne Carriere }
313*b844655cSEtienne Carriere 
314*b844655cSEtienne Carriere static void notif_i2c_timeout(struct i2c_handle_s *hi2c)
315*b844655cSEtienne Carriere {
316*b844655cSEtienne Carriere 	hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
317*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
318*b844655cSEtienne Carriere }
319*b844655cSEtienne Carriere 
320*b844655cSEtienne Carriere static void save_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg)
321*b844655cSEtienne Carriere {
322*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
323*b844655cSEtienne Carriere 
324*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
325*b844655cSEtienne Carriere 
326*b844655cSEtienne Carriere 	cfg->cr1 = io_read32(base + I2C_CR1);
327*b844655cSEtienne Carriere 	cfg->cr2 = io_read32(base + I2C_CR2);
328*b844655cSEtienne Carriere 	cfg->oar1 = io_read32(base + I2C_OAR1);
329*b844655cSEtienne Carriere 	cfg->oar2 = io_read32(base + I2C_OAR2);
330*b844655cSEtienne Carriere 	cfg->timingr = io_read32(base + I2C_TIMINGR);
331*b844655cSEtienne Carriere 
332*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
333*b844655cSEtienne Carriere }
334*b844655cSEtienne Carriere 
335*b844655cSEtienne Carriere static void restore_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg)
336*b844655cSEtienne Carriere {
337*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
338*b844655cSEtienne Carriere 
339*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
340*b844655cSEtienne Carriere 
341*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR1, I2C_CR1_PE);
342*b844655cSEtienne Carriere 	io_write32(base + I2C_TIMINGR, cfg->timingr & TIMINGR_CLEAR_MASK);
343*b844655cSEtienne Carriere 	io_write32(base + I2C_OAR1, cfg->oar1);
344*b844655cSEtienne Carriere 	io_write32(base + I2C_CR2, cfg->cr2);
345*b844655cSEtienne Carriere 	io_write32(base + I2C_OAR2, cfg->oar2);
346*b844655cSEtienne Carriere 	io_write32(base + I2C_CR1, cfg->cr1 & ~I2C_CR1_PE);
347*b844655cSEtienne Carriere 	io_setbits32(base + I2C_CR1, cfg->cr1 & I2C_CR1_PE);
348*b844655cSEtienne Carriere 
349*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
350*b844655cSEtienne Carriere }
351*b844655cSEtienne Carriere 
352*b844655cSEtienne Carriere static void __maybe_unused dump_cfg(struct i2c_cfg *cfg __maybe_unused)
353*b844655cSEtienne Carriere {
354*b844655cSEtienne Carriere 	DMSG("CR1:  0x%" PRIx32, cfg->cr1);
355*b844655cSEtienne Carriere 	DMSG("CR2:  0x%" PRIx32, cfg->cr2);
356*b844655cSEtienne Carriere 	DMSG("OAR1: 0x%" PRIx32, cfg->oar1);
357*b844655cSEtienne Carriere 	DMSG("OAR2: 0x%" PRIx32, cfg->oar2);
358*b844655cSEtienne Carriere 	DMSG("TIM:  0x%" PRIx32, cfg->timingr);
359*b844655cSEtienne Carriere }
360*b844655cSEtienne Carriere 
361*b844655cSEtienne Carriere static void __maybe_unused dump_i2c(struct i2c_handle_s *hi2c)
362*b844655cSEtienne Carriere {
363*b844655cSEtienne Carriere 	vaddr_t __maybe_unused base = get_base(hi2c);
364*b844655cSEtienne Carriere 
365*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
366*b844655cSEtienne Carriere 
367*b844655cSEtienne Carriere 	DMSG("CR1:  0x%" PRIx32, io_read32(base + I2C_CR1));
368*b844655cSEtienne Carriere 	DMSG("CR2:  0x%" PRIx32, io_read32(base + I2C_CR2));
369*b844655cSEtienne Carriere 	DMSG("OAR1: 0x%" PRIx32, io_read32(base + I2C_OAR1));
370*b844655cSEtienne Carriere 	DMSG("OAR2: 0x%" PRIx32, io_read32(base + I2C_OAR2));
371*b844655cSEtienne Carriere 	DMSG("TIM:  0x%" PRIx32, io_read32(base + I2C_TIMINGR));
372*b844655cSEtienne Carriere 
373*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
374*b844655cSEtienne Carriere }
375*b844655cSEtienne Carriere 
376*b844655cSEtienne Carriere /*
377*b844655cSEtienne Carriere  * Compute the I2C device timings
378*b844655cSEtienne Carriere  *
379*b844655cSEtienne Carriere  * @init: Ref to the initialization configuration structure
380*b844655cSEtienne Carriere  * @clock_src: I2C clock source frequency (Hz)
381*b844655cSEtienne Carriere  * @timing: Pointer to the final computed timing result
382*b844655cSEtienne Carriere  * Return 0 on success or a negative value
383*b844655cSEtienne Carriere  */
384*b844655cSEtienne Carriere static int i2c_compute_timing(struct stm32_i2c_init_s *init,
385*b844655cSEtienne Carriere 			      uint32_t clock_src, uint32_t *timing)
386*b844655cSEtienne Carriere {
387*b844655cSEtienne Carriere 	enum i2c_speed_e mode = init->speed_mode;
388*b844655cSEtienne Carriere 	uint32_t speed_freq = i2c_specs[mode].rate;
389*b844655cSEtienne Carriere 	uint32_t i2cbus = UDIV_ROUND_NEAREST(I2C_NSEC_PER_SEC, speed_freq);
390*b844655cSEtienne Carriere 	uint32_t i2cclk = UDIV_ROUND_NEAREST(I2C_NSEC_PER_SEC, clock_src);
391*b844655cSEtienne Carriere 	uint32_t p_prev = I2C_TIMINGR_PRESC_MAX;
392*b844655cSEtienne Carriere 	uint32_t af_delay_min = 0;
393*b844655cSEtienne Carriere 	uint32_t af_delay_max = 0;
394*b844655cSEtienne Carriere 	uint32_t dnf_delay = 0;
395*b844655cSEtienne Carriere 	uint32_t tsync = 0;
396*b844655cSEtienne Carriere 	uint32_t clk_min = 0;
397*b844655cSEtienne Carriere 	uint32_t clk_max = 0;
398*b844655cSEtienne Carriere 	int clk_error_prev = 0;
399*b844655cSEtienne Carriere 	uint16_t p = 0;
400*b844655cSEtienne Carriere 	uint16_t l = 0;
401*b844655cSEtienne Carriere 	uint16_t a = 0;
402*b844655cSEtienne Carriere 	uint16_t h = 0;
403*b844655cSEtienne Carriere 	unsigned int sdadel_min = 0;
404*b844655cSEtienne Carriere 	unsigned int sdadel_max = 0;
405*b844655cSEtienne Carriere 	unsigned int scldel_min = 0;
406*b844655cSEtienne Carriere 	unsigned int delay = 0;
407*b844655cSEtienne Carriere 	int s = -1;
408*b844655cSEtienne Carriere 	struct i2c_timing_s solutions[I2C_TIMINGR_PRESC_MAX] = { 0 };
409*b844655cSEtienne Carriere 
410*b844655cSEtienne Carriere 	switch (mode) {
411*b844655cSEtienne Carriere 	case I2C_SPEED_STANDARD:
412*b844655cSEtienne Carriere 	case I2C_SPEED_FAST:
413*b844655cSEtienne Carriere 	case I2C_SPEED_FAST_PLUS:
414*b844655cSEtienne Carriere 		break;
415*b844655cSEtienne Carriere 	default:
416*b844655cSEtienne Carriere 		EMSG("I2C speed out of bound {%d/%d}",
417*b844655cSEtienne Carriere 		     mode, I2C_SPEED_FAST_PLUS);
418*b844655cSEtienne Carriere 		return -1;
419*b844655cSEtienne Carriere 	}
420*b844655cSEtienne Carriere 
421*b844655cSEtienne Carriere 	speed_freq = i2c_specs[mode].rate;
422*b844655cSEtienne Carriere 	i2cbus = UDIV_ROUND_NEAREST(I2C_NSEC_PER_SEC, speed_freq);
423*b844655cSEtienne Carriere 	clk_error_prev = INT_MAX;
424*b844655cSEtienne Carriere 
425*b844655cSEtienne Carriere 	if ((init->rise_time > i2c_specs[mode].rise_max) ||
426*b844655cSEtienne Carriere 	    (init->fall_time > i2c_specs[mode].fall_max)) {
427*b844655cSEtienne Carriere 		EMSG(" I2C timings out of bound: Rise{%d > %d}/Fall{%d > %d}",
428*b844655cSEtienne Carriere 		     init->rise_time, i2c_specs[mode].rise_max,
429*b844655cSEtienne Carriere 		     init->fall_time, i2c_specs[mode].fall_max);
430*b844655cSEtienne Carriere 		return -1;
431*b844655cSEtienne Carriere 	}
432*b844655cSEtienne Carriere 
433*b844655cSEtienne Carriere 	if (init->digital_filter_coef > STM32_I2C_DIGITAL_FILTER_MAX) {
434*b844655cSEtienne Carriere 		EMSG("DNF out of bound %d/%d",
435*b844655cSEtienne Carriere 		     init->digital_filter_coef, STM32_I2C_DIGITAL_FILTER_MAX);
436*b844655cSEtienne Carriere 		return -1;
437*b844655cSEtienne Carriere 	}
438*b844655cSEtienne Carriere 
439*b844655cSEtienne Carriere 	/* Analog and Digital Filters */
440*b844655cSEtienne Carriere 	if (init->analog_filter) {
441*b844655cSEtienne Carriere 		af_delay_min = STM32_I2C_ANALOG_FILTER_DELAY_MIN;
442*b844655cSEtienne Carriere 		af_delay_max = STM32_I2C_ANALOG_FILTER_DELAY_MAX;
443*b844655cSEtienne Carriere 	}
444*b844655cSEtienne Carriere 	dnf_delay = init->digital_filter_coef * i2cclk;
445*b844655cSEtienne Carriere 
446*b844655cSEtienne Carriere 	sdadel_min = i2c_specs[mode].hddat_min + init->fall_time;
447*b844655cSEtienne Carriere 	delay = af_delay_min - ((init->digital_filter_coef + 3) * i2cclk);
448*b844655cSEtienne Carriere 	if (SUB_OVERFLOW(sdadel_min, delay, &sdadel_min))
449*b844655cSEtienne Carriere 		sdadel_min = 0;
450*b844655cSEtienne Carriere 
451*b844655cSEtienne Carriere 	sdadel_max = i2c_specs[mode].vddat_max - init->rise_time;
452*b844655cSEtienne Carriere 	delay = af_delay_max - ((init->digital_filter_coef + 4) * i2cclk);
453*b844655cSEtienne Carriere 	if (SUB_OVERFLOW(sdadel_max, delay, &sdadel_max))
454*b844655cSEtienne Carriere 		sdadel_max = 0;
455*b844655cSEtienne Carriere 
456*b844655cSEtienne Carriere 	scldel_min = init->rise_time + i2c_specs[mode].sudat_min;
457*b844655cSEtienne Carriere 
458*b844655cSEtienne Carriere 	DMSG("I2C SDADEL(min/max): %u/%u, SCLDEL(Min): %u",
459*b844655cSEtienne Carriere 	     sdadel_min, sdadel_max, scldel_min);
460*b844655cSEtienne Carriere 
461*b844655cSEtienne Carriere 	/* Compute possible values for PRESC, SCLDEL and SDADEL */
462*b844655cSEtienne Carriere 	for (p = 0; p < I2C_TIMINGR_PRESC_MAX; p++) {
463*b844655cSEtienne Carriere 		for (l = 0; l < I2C_TIMINGR_SCLDEL_MAX; l++) {
464*b844655cSEtienne Carriere 			uint32_t scldel = (l + 1) * (p + 1) * i2cclk;
465*b844655cSEtienne Carriere 
466*b844655cSEtienne Carriere 			if (scldel < scldel_min)
467*b844655cSEtienne Carriere 				continue;
468*b844655cSEtienne Carriere 
469*b844655cSEtienne Carriere 			for (a = 0; a < I2C_TIMINGR_SDADEL_MAX; a++) {
470*b844655cSEtienne Carriere 				uint32_t sdadel = (a * (p + 1) + 1) * i2cclk;
471*b844655cSEtienne Carriere 
472*b844655cSEtienne Carriere 				if ((sdadel >= sdadel_min) &&
473*b844655cSEtienne Carriere 				    (sdadel <= sdadel_max) &&
474*b844655cSEtienne Carriere 				    (p != p_prev)) {
475*b844655cSEtienne Carriere 					solutions[p].scldel = l;
476*b844655cSEtienne Carriere 					solutions[p].sdadel = a;
477*b844655cSEtienne Carriere 					solutions[p].is_saved = true;
478*b844655cSEtienne Carriere 					p_prev = p;
479*b844655cSEtienne Carriere 					break;
480*b844655cSEtienne Carriere 				}
481*b844655cSEtienne Carriere 			}
482*b844655cSEtienne Carriere 
483*b844655cSEtienne Carriere 			if (p_prev == p)
484*b844655cSEtienne Carriere 				break;
485*b844655cSEtienne Carriere 		}
486*b844655cSEtienne Carriere 	}
487*b844655cSEtienne Carriere 
488*b844655cSEtienne Carriere 	if (p_prev == I2C_TIMINGR_PRESC_MAX) {
489*b844655cSEtienne Carriere 		EMSG(" I2C no Prescaler solution");
490*b844655cSEtienne Carriere 		return -1;
491*b844655cSEtienne Carriere 	}
492*b844655cSEtienne Carriere 
493*b844655cSEtienne Carriere 	tsync = af_delay_min + dnf_delay + (2 * i2cclk);
494*b844655cSEtienne Carriere 	clk_max = I2C_NSEC_PER_SEC / i2c_specs[mode].rate_min;
495*b844655cSEtienne Carriere 	clk_min = I2C_NSEC_PER_SEC / i2c_specs[mode].rate_max;
496*b844655cSEtienne Carriere 
497*b844655cSEtienne Carriere 	/*
498*b844655cSEtienne Carriere 	 * Among prescaler possibilities discovered above figures out SCL Low
499*b844655cSEtienne Carriere 	 * and High Period. Provided:
500*b844655cSEtienne Carriere 	 * - SCL Low Period has to be higher than Low Period of the SCL Clock
501*b844655cSEtienne Carriere 	 *   defined by I2C Specification. I2C Clock has to be lower than
502*b844655cSEtienne Carriere 	 *   (SCL Low Period - Analog/Digital filters) / 4.
503*b844655cSEtienne Carriere 	 * - SCL High Period has to be lower than High Period of the SCL Clock
504*b844655cSEtienne Carriere 	 *   defined by I2C Specification.
505*b844655cSEtienne Carriere 	 * - I2C Clock has to be lower than SCL High Period.
506*b844655cSEtienne Carriere 	 */
507*b844655cSEtienne Carriere 	for (p = 0; p < I2C_TIMINGR_PRESC_MAX; p++) {
508*b844655cSEtienne Carriere 		uint32_t prescaler = (p + 1) * i2cclk;
509*b844655cSEtienne Carriere 
510*b844655cSEtienne Carriere 		if (!solutions[p].is_saved)
511*b844655cSEtienne Carriere 			continue;
512*b844655cSEtienne Carriere 
513*b844655cSEtienne Carriere 		for (l = 0; l < I2C_TIMINGR_SCLL_MAX; l++) {
514*b844655cSEtienne Carriere 			uint32_t tscl_l = ((l + 1) * prescaler) + tsync;
515*b844655cSEtienne Carriere 
516*b844655cSEtienne Carriere 			if ((tscl_l < i2c_specs[mode].l_min) ||
517*b844655cSEtienne Carriere 			    (i2cclk >=
518*b844655cSEtienne Carriere 			     ((tscl_l - af_delay_min - dnf_delay) / 4)))
519*b844655cSEtienne Carriere 				continue;
520*b844655cSEtienne Carriere 
521*b844655cSEtienne Carriere 			for (h = 0; h < I2C_TIMINGR_SCLH_MAX; h++) {
522*b844655cSEtienne Carriere 				uint32_t tscl_h = ((h + 1) * prescaler) + tsync;
523*b844655cSEtienne Carriere 				uint32_t tscl = tscl_l + tscl_h +
524*b844655cSEtienne Carriere 						init->rise_time +
525*b844655cSEtienne Carriere 						init->fall_time;
526*b844655cSEtienne Carriere 
527*b844655cSEtienne Carriere 				if ((tscl >= clk_min) && (tscl <= clk_max) &&
528*b844655cSEtienne Carriere 				    (tscl_h >= i2c_specs[mode].h_min) &&
529*b844655cSEtienne Carriere 				    (i2cclk < tscl_h)) {
530*b844655cSEtienne Carriere 					int clk_error = tscl - i2cbus;
531*b844655cSEtienne Carriere 
532*b844655cSEtienne Carriere 					if (clk_error < 0)
533*b844655cSEtienne Carriere 						clk_error = -clk_error;
534*b844655cSEtienne Carriere 
535*b844655cSEtienne Carriere 					if (clk_error < clk_error_prev) {
536*b844655cSEtienne Carriere 						clk_error_prev = clk_error;
537*b844655cSEtienne Carriere 						solutions[p].scll = l;
538*b844655cSEtienne Carriere 						solutions[p].sclh = h;
539*b844655cSEtienne Carriere 						s = p;
540*b844655cSEtienne Carriere 					}
541*b844655cSEtienne Carriere 				}
542*b844655cSEtienne Carriere 			}
543*b844655cSEtienne Carriere 		}
544*b844655cSEtienne Carriere 	}
545*b844655cSEtienne Carriere 
546*b844655cSEtienne Carriere 	if (s < 0) {
547*b844655cSEtienne Carriere 		EMSG(" I2C no solution at all");
548*b844655cSEtienne Carriere 		return -1;
549*b844655cSEtienne Carriere 	}
550*b844655cSEtienne Carriere 
551*b844655cSEtienne Carriere 	/* Finalize timing settings */
552*b844655cSEtienne Carriere 	*timing = I2C_SET_TIMINGR_PRESC(s) |
553*b844655cSEtienne Carriere 		   I2C_SET_TIMINGR_SCLDEL(solutions[s].scldel) |
554*b844655cSEtienne Carriere 		   I2C_SET_TIMINGR_SDADEL(solutions[s].sdadel) |
555*b844655cSEtienne Carriere 		   I2C_SET_TIMINGR_SCLH(solutions[s].sclh) |
556*b844655cSEtienne Carriere 		   I2C_SET_TIMINGR_SCLL(solutions[s].scll);
557*b844655cSEtienne Carriere 
558*b844655cSEtienne Carriere 	DMSG("I2C TIMINGR (PRESC/SCLDEL/SDADEL): %i/%i/%i",
559*b844655cSEtienne Carriere 		s, solutions[s].scldel, solutions[s].sdadel);
560*b844655cSEtienne Carriere 	DMSG("I2C TIMINGR (SCLH/SCLL): %i/%i",
561*b844655cSEtienne Carriere 		solutions[s].sclh, solutions[s].scll);
562*b844655cSEtienne Carriere 	DMSG("I2C TIMINGR: 0x%x", *timing);
563*b844655cSEtienne Carriere 
564*b844655cSEtienne Carriere 	return 0;
565*b844655cSEtienne Carriere }
566*b844655cSEtienne Carriere 
567*b844655cSEtienne Carriere /*
568*b844655cSEtienne Carriere  * Setup the I2C device timings
569*b844655cSEtienne Carriere  *
570*b844655cSEtienne Carriere  * @hi2c: I2C handle structure
571*b844655cSEtienne Carriere  * @init: Ref to the initialization configuration structure
572*b844655cSEtienne Carriere  * @timing: Output TIMINGR register configuration value
573*b844655cSEtienne Carriere  * @retval 0 if OK, negative value else
574*b844655cSEtienne Carriere  */
575*b844655cSEtienne Carriere static int i2c_setup_timing(struct i2c_handle_s *hi2c,
576*b844655cSEtienne Carriere 			    struct stm32_i2c_init_s *init,
577*b844655cSEtienne Carriere 			    uint32_t *timing)
578*b844655cSEtienne Carriere {
579*b844655cSEtienne Carriere 	int rc = 0;
580*b844655cSEtienne Carriere 	uint32_t clock_src = stm32_clock_get_rate(hi2c->clock);
581*b844655cSEtienne Carriere 
582*b844655cSEtienne Carriere 	if (!clock_src) {
583*b844655cSEtienne Carriere 		EMSG("Null I2C clock rate");
584*b844655cSEtienne Carriere 		return -1;
585*b844655cSEtienne Carriere 	}
586*b844655cSEtienne Carriere 
587*b844655cSEtienne Carriere 	do {
588*b844655cSEtienne Carriere 		rc = i2c_compute_timing(init, clock_src, timing);
589*b844655cSEtienne Carriere 		if (rc) {
590*b844655cSEtienne Carriere 			EMSG("Failed to compute I2C timings");
591*b844655cSEtienne Carriere 			if (init->speed_mode > I2C_SPEED_STANDARD) {
592*b844655cSEtienne Carriere 				init->speed_mode--;
593*b844655cSEtienne Carriere 				IMSG("Downgrade I2C speed to %uHz)",
594*b844655cSEtienne Carriere 				     i2c_specs[init->speed_mode].rate);
595*b844655cSEtienne Carriere 			} else {
596*b844655cSEtienne Carriere 				break;
597*b844655cSEtienne Carriere 			}
598*b844655cSEtienne Carriere 		}
599*b844655cSEtienne Carriere 	} while (rc);
600*b844655cSEtienne Carriere 
601*b844655cSEtienne Carriere 	if (rc) {
602*b844655cSEtienne Carriere 		EMSG("Impossible to compute I2C timings");
603*b844655cSEtienne Carriere 		return rc;
604*b844655cSEtienne Carriere 	}
605*b844655cSEtienne Carriere 
606*b844655cSEtienne Carriere 	DMSG("I2C Speed Mode(%i), Freq(%i), Clk Source(%i)",
607*b844655cSEtienne Carriere 	     init->speed_mode, i2c_specs[init->speed_mode].rate, clock_src);
608*b844655cSEtienne Carriere 	DMSG("I2C Rise(%i) and Fall(%i) Time",
609*b844655cSEtienne Carriere 	     init->rise_time, init->fall_time);
610*b844655cSEtienne Carriere 	DMSG("I2C Analog Filter(%s), DNF(%i)",
611*b844655cSEtienne Carriere 	     init->analog_filter ? "On" : "Off", init->digital_filter_coef);
612*b844655cSEtienne Carriere 
613*b844655cSEtienne Carriere 	return 0;
614*b844655cSEtienne Carriere }
615*b844655cSEtienne Carriere 
616*b844655cSEtienne Carriere /*
617*b844655cSEtienne Carriere  * Configure I2C Analog noise filter.
618*b844655cSEtienne Carriere  * @hi2c: I2C handle structure
619*b844655cSEtienne Carriere  * @analog_filter_on: True if enabling analog filter, false otherwise
620*b844655cSEtienne Carriere  * Return 0 on success or a negative value
621*b844655cSEtienne Carriere  */
622*b844655cSEtienne Carriere static int i2c_config_analog_filter(struct i2c_handle_s *hi2c,
623*b844655cSEtienne Carriere 				    bool analog_filter_on)
624*b844655cSEtienne Carriere {
625*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
626*b844655cSEtienne Carriere 
627*b844655cSEtienne Carriere 	if (hi2c->i2c_state != I2C_STATE_READY)
628*b844655cSEtienne Carriere 		return -1;
629*b844655cSEtienne Carriere 
630*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_BUSY;
631*b844655cSEtienne Carriere 
632*b844655cSEtienne Carriere 	/* Disable the selected I2C peripheral */
633*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR1, I2C_CR1_PE);
634*b844655cSEtienne Carriere 
635*b844655cSEtienne Carriere 	/* Reset I2Cx ANOFF bit */
636*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR1, I2C_CR1_ANFOFF);
637*b844655cSEtienne Carriere 
638*b844655cSEtienne Carriere 	/* Set analog filter bit if filter is disabled */
639*b844655cSEtienne Carriere 	if (!analog_filter_on)
640*b844655cSEtienne Carriere 		io_setbits32(base + I2C_CR1, I2C_CR1_ANFOFF);
641*b844655cSEtienne Carriere 
642*b844655cSEtienne Carriere 	/* Enable the selected I2C peripheral */
643*b844655cSEtienne Carriere 	io_setbits32(base + I2C_CR1, I2C_CR1_PE);
644*b844655cSEtienne Carriere 
645*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
646*b844655cSEtienne Carriere 
647*b844655cSEtienne Carriere 	return 0;
648*b844655cSEtienne Carriere }
649*b844655cSEtienne Carriere 
650*b844655cSEtienne Carriere int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
651*b844655cSEtienne Carriere 				 struct stm32_i2c_init_s *init)
652*b844655cSEtienne Carriere {
653*b844655cSEtienne Carriere 	const fdt32_t *cuint = NULL;
654*b844655cSEtienne Carriere 	struct dt_node_info info = { .status = 0 };
655*b844655cSEtienne Carriere 
656*b844655cSEtienne Carriere 	/* Default STM32 specific configs caller may need to overwrite */
657*b844655cSEtienne Carriere 	memset(init, 0, sizeof(*init));
658*b844655cSEtienne Carriere 
659*b844655cSEtienne Carriere 	_fdt_fill_device_info(fdt, &info, node);
660*b844655cSEtienne Carriere 	init->pbase = info.reg;
661*b844655cSEtienne Carriere 	init->clock = info.clock;
662*b844655cSEtienne Carriere 	assert(info.reg != DT_INFO_INVALID_REG &&
663*b844655cSEtienne Carriere 	       info.clock != DT_INFO_INVALID_CLOCK);
664*b844655cSEtienne Carriere 
665*b844655cSEtienne Carriere 	cuint = fdt_getprop(fdt, node, "i2c-scl-rising-time-ns", NULL);
666*b844655cSEtienne Carriere 	if (cuint)
667*b844655cSEtienne Carriere 		init->rise_time = fdt32_to_cpu(*cuint);
668*b844655cSEtienne Carriere 	else
669*b844655cSEtienne Carriere 		init->rise_time = STM32_I2C_RISE_TIME_DEFAULT;
670*b844655cSEtienne Carriere 
671*b844655cSEtienne Carriere 	cuint = fdt_getprop(fdt, node, "i2c-scl-falling-time-ns", NULL);
672*b844655cSEtienne Carriere 	if (cuint)
673*b844655cSEtienne Carriere 		init->fall_time = fdt32_to_cpu(*cuint);
674*b844655cSEtienne Carriere 	else
675*b844655cSEtienne Carriere 		init->fall_time = STM32_I2C_FALL_TIME_DEFAULT;
676*b844655cSEtienne Carriere 
677*b844655cSEtienne Carriere 	cuint = fdt_getprop(fdt, node, "clock-frequency", NULL);
678*b844655cSEtienne Carriere 	if (cuint) {
679*b844655cSEtienne Carriere 		switch (fdt32_to_cpu(*cuint)) {
680*b844655cSEtienne Carriere 		case STANDARD_RATE:
681*b844655cSEtienne Carriere 			init->speed_mode = I2C_SPEED_STANDARD;
682*b844655cSEtienne Carriere 			break;
683*b844655cSEtienne Carriere 		case FAST_RATE:
684*b844655cSEtienne Carriere 			init->speed_mode = I2C_SPEED_FAST;
685*b844655cSEtienne Carriere 			break;
686*b844655cSEtienne Carriere 		case FAST_PLUS_RATE:
687*b844655cSEtienne Carriere 			init->speed_mode = I2C_SPEED_FAST_PLUS;
688*b844655cSEtienne Carriere 			break;
689*b844655cSEtienne Carriere 		default:
690*b844655cSEtienne Carriere 			init->speed_mode = STM32_I2C_SPEED_DEFAULT;
691*b844655cSEtienne Carriere 			break;
692*b844655cSEtienne Carriere 		}
693*b844655cSEtienne Carriere 	} else {
694*b844655cSEtienne Carriere 		init->speed_mode = STM32_I2C_SPEED_DEFAULT;
695*b844655cSEtienne Carriere 	}
696*b844655cSEtienne Carriere 
697*b844655cSEtienne Carriere 	return 0;
698*b844655cSEtienne Carriere }
699*b844655cSEtienne Carriere 
700*b844655cSEtienne Carriere int stm32_i2c_init(struct i2c_handle_s *hi2c,
701*b844655cSEtienne Carriere 		   struct stm32_i2c_init_s *init_data)
702*b844655cSEtienne Carriere {
703*b844655cSEtienne Carriere 	int rc = 0;
704*b844655cSEtienne Carriere 	uint32_t timing = 0;
705*b844655cSEtienne Carriere 	vaddr_t base = 0;
706*b844655cSEtienne Carriere 	uint32_t val = 0;
707*b844655cSEtienne Carriere 
708*b844655cSEtienne Carriere 	hi2c->base.pa = init_data->pbase;
709*b844655cSEtienne Carriere 	hi2c->clock = init_data->clock;
710*b844655cSEtienne Carriere 
711*b844655cSEtienne Carriere 	rc = i2c_setup_timing(hi2c, init_data, &timing);
712*b844655cSEtienne Carriere 	if (rc)
713*b844655cSEtienne Carriere 		return rc;
714*b844655cSEtienne Carriere 
715*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
716*b844655cSEtienne Carriere 	base = get_base(hi2c);
717*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_BUSY;
718*b844655cSEtienne Carriere 
719*b844655cSEtienne Carriere 	/* Disable the selected I2C peripheral */
720*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR1, I2C_CR1_PE);
721*b844655cSEtienne Carriere 
722*b844655cSEtienne Carriere 	/* Configure I2Cx: Frequency range */
723*b844655cSEtienne Carriere 	io_write32(base + I2C_TIMINGR, timing & TIMINGR_CLEAR_MASK);
724*b844655cSEtienne Carriere 
725*b844655cSEtienne Carriere 	/* Disable Own Address1 before set the Own Address1 configuration */
726*b844655cSEtienne Carriere 	io_write32(base + I2C_OAR1, 0);
727*b844655cSEtienne Carriere 
728*b844655cSEtienne Carriere 	/* Configure I2Cx: Own Address1 and ack own address1 mode */
729*b844655cSEtienne Carriere 	if (init_data->addr_mode_10b_not_7b)
730*b844655cSEtienne Carriere 		io_write32(base + I2C_OAR1,
731*b844655cSEtienne Carriere 			   I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
732*b844655cSEtienne Carriere 			   init_data->own_address1);
733*b844655cSEtienne Carriere 	else
734*b844655cSEtienne Carriere 		io_write32(base + I2C_OAR1,
735*b844655cSEtienne Carriere 			   I2C_OAR1_OA1EN | init_data->own_address1);
736*b844655cSEtienne Carriere 
737*b844655cSEtienne Carriere 	/* Configure I2Cx: Addressing Master mode */
738*b844655cSEtienne Carriere 	io_write32(base + I2C_CR2, 0);
739*b844655cSEtienne Carriere 	if (init_data->addr_mode_10b_not_7b)
740*b844655cSEtienne Carriere 		io_setbits32(base + I2C_CR2, I2C_CR2_ADD10);
741*b844655cSEtienne Carriere 
742*b844655cSEtienne Carriere 	/*
743*b844655cSEtienne Carriere 	 * Enable the AUTOEND by default, and enable NACK
744*b844655cSEtienne Carriere 	 * (should be disabled only during Slave process).
745*b844655cSEtienne Carriere 	 */
746*b844655cSEtienne Carriere 	io_setbits32(base + I2C_CR2, I2C_CR2_AUTOEND | I2C_CR2_NACK);
747*b844655cSEtienne Carriere 
748*b844655cSEtienne Carriere 	/* Disable Own Address2 before set the Own Address2 configuration */
749*b844655cSEtienne Carriere 	io_write32(base + I2C_OAR2, 0);
750*b844655cSEtienne Carriere 
751*b844655cSEtienne Carriere 	/* Configure I2Cx: Dual mode and Own Address2 */
752*b844655cSEtienne Carriere 	if (init_data->dual_address_mode)
753*b844655cSEtienne Carriere 		io_write32(base + I2C_OAR2,
754*b844655cSEtienne Carriere 			   I2C_OAR2_OA2EN | init_data->own_address2 |
755*b844655cSEtienne Carriere 			   (init_data->own_address2_masks << 8));
756*b844655cSEtienne Carriere 
757*b844655cSEtienne Carriere 	/* Configure I2Cx: Generalcall and NoStretch mode */
758*b844655cSEtienne Carriere 	val = 0;
759*b844655cSEtienne Carriere 	if (init_data->general_call_mode)
760*b844655cSEtienne Carriere 		val |= I2C_CR1_GCEN;
761*b844655cSEtienne Carriere 	if (init_data->no_stretch_mode)
762*b844655cSEtienne Carriere 		val |= I2C_CR1_NOSTRETCH;
763*b844655cSEtienne Carriere 	io_write32(base + I2C_CR1, val);
764*b844655cSEtienne Carriere 
765*b844655cSEtienne Carriere 	/* Enable the selected I2C peripheral */
766*b844655cSEtienne Carriere 	io_setbits32(base + I2C_CR1, I2C_CR1_PE);
767*b844655cSEtienne Carriere 
768*b844655cSEtienne Carriere 	hi2c->i2c_err = I2C_ERROR_NONE;
769*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
770*b844655cSEtienne Carriere 
771*b844655cSEtienne Carriere 	rc = i2c_config_analog_filter(hi2c, init_data->analog_filter);
772*b844655cSEtienne Carriere 	if (rc)
773*b844655cSEtienne Carriere 		EMSG("I2C analog filter error %d", rc);
774*b844655cSEtienne Carriere 
775*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
776*b844655cSEtienne Carriere 
777*b844655cSEtienne Carriere 	return rc;
778*b844655cSEtienne Carriere }
779*b844655cSEtienne Carriere 
780*b844655cSEtienne Carriere /* I2C transmit (TX) data register flush sequence */
781*b844655cSEtienne Carriere static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
782*b844655cSEtienne Carriere {
783*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
784*b844655cSEtienne Carriere 
785*b844655cSEtienne Carriere 	/*
786*b844655cSEtienne Carriere 	 * If a pending TXIS flag is set,
787*b844655cSEtienne Carriere 	 * write a dummy data in TXDR to clear it.
788*b844655cSEtienne Carriere 	 */
789*b844655cSEtienne Carriere 	if (io_read32(base + I2C_ISR) & I2C_ISR_TXIS)
790*b844655cSEtienne Carriere 		io_write32(base + I2C_TXDR, 0);
791*b844655cSEtienne Carriere 
792*b844655cSEtienne Carriere 	/* Flush TX register if not empty */
793*b844655cSEtienne Carriere 	if ((io_read32(base + I2C_ISR) & I2C_ISR_TXE) == 0)
794*b844655cSEtienne Carriere 		io_setbits32(base + I2C_ISR, I2C_ISR_TXE);
795*b844655cSEtienne Carriere }
796*b844655cSEtienne Carriere 
797*b844655cSEtienne Carriere /*
798*b844655cSEtienne Carriere  * Wait for a single target I2C_ISR bit to reach an awaited value (0 or 1)
799*b844655cSEtienne Carriere  *
800*b844655cSEtienne Carriere  * @hi2c: I2C handle structure
801*b844655cSEtienne Carriere  * @bit_mask: Bit mask for the target single bit position to consider
802*b844655cSEtienne Carriere  * @awaited_value: Awaited value of the target bit in I2C_ISR, 0 or 1
803*b844655cSEtienne Carriere  * @timeout_ref: Expriation timeout reference
804*b844655cSEtienne Carriere  * Return 0 on success and a non-zero value on timeout
805*b844655cSEtienne Carriere  */
806*b844655cSEtienne Carriere static int wait_isr_event(struct i2c_handle_s *hi2c, uint32_t bit_mask,
807*b844655cSEtienne Carriere 			  unsigned int awaited_value, uint64_t timeout_ref)
808*b844655cSEtienne Carriere {
809*b844655cSEtienne Carriere 	vaddr_t isr = get_base(hi2c) + I2C_ISR;
810*b844655cSEtienne Carriere 
811*b844655cSEtienne Carriere 	assert(IS_POWER_OF_TWO(bit_mask) && !(awaited_value & ~1U));
812*b844655cSEtienne Carriere 
813*b844655cSEtienne Carriere 	/* May timeout while TEE thread is suspended */
814*b844655cSEtienne Carriere 	while (!timeout_elapsed(timeout_ref))
815*b844655cSEtienne Carriere 		if (!!(io_read32(isr) & bit_mask) == awaited_value)
816*b844655cSEtienne Carriere 			break;
817*b844655cSEtienne Carriere 
818*b844655cSEtienne Carriere 	if (!!(io_read32(isr) & bit_mask) == awaited_value)
819*b844655cSEtienne Carriere 		return 0;
820*b844655cSEtienne Carriere 
821*b844655cSEtienne Carriere 	notif_i2c_timeout(hi2c);
822*b844655cSEtienne Carriere 	return -1;
823*b844655cSEtienne Carriere }
824*b844655cSEtienne Carriere 
825*b844655cSEtienne Carriere /* Handle Acknowledge-Failed sequence detection during an I2C Communication */
826*b844655cSEtienne Carriere static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
827*b844655cSEtienne Carriere {
828*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
829*b844655cSEtienne Carriere 
830*b844655cSEtienne Carriere 	if ((io_read32(base + I2C_ISR) & I2C_ISR_NACKF) == 0U)
831*b844655cSEtienne Carriere 		return 0;
832*b844655cSEtienne Carriere 
833*b844655cSEtienne Carriere 	/*
834*b844655cSEtienne Carriere 	 * Wait until STOP Flag is reset. Use polling method.
835*b844655cSEtienne Carriere 	 * AutoEnd should be initiate after AF.
836*b844655cSEtienne Carriere 	 * Timeout may elpased while TEE thread is suspended.
837*b844655cSEtienne Carriere 	 */
838*b844655cSEtienne Carriere 	while (!timeout_elapsed(timeout_ref))
839*b844655cSEtienne Carriere 		if (io_read32(base + I2C_ISR) & I2C_ISR_STOPF)
840*b844655cSEtienne Carriere 			break;
841*b844655cSEtienne Carriere 
842*b844655cSEtienne Carriere 	if ((io_read32(base + I2C_ISR) & I2C_ISR_STOPF) == 0) {
843*b844655cSEtienne Carriere 		notif_i2c_timeout(hi2c);
844*b844655cSEtienne Carriere 		return -1;
845*b844655cSEtienne Carriere 	}
846*b844655cSEtienne Carriere 
847*b844655cSEtienne Carriere 	io_write32(base + I2C_ICR, I2C_ISR_NACKF);
848*b844655cSEtienne Carriere 
849*b844655cSEtienne Carriere 	io_write32(base + I2C_ICR, I2C_ISR_STOPF);
850*b844655cSEtienne Carriere 
851*b844655cSEtienne Carriere 	i2c_flush_txdr(hi2c);
852*b844655cSEtienne Carriere 
853*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR2, CR2_RESET_MASK);
854*b844655cSEtienne Carriere 
855*b844655cSEtienne Carriere 	hi2c->i2c_err |= I2C_ERROR_ACKF;
856*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
857*b844655cSEtienne Carriere 
858*b844655cSEtienne Carriere 	return -1;
859*b844655cSEtienne Carriere }
860*b844655cSEtienne Carriere 
861*b844655cSEtienne Carriere /* Wait TXIS bit is 1 in I2C_ISR register */
862*b844655cSEtienne Carriere static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
863*b844655cSEtienne Carriere {
864*b844655cSEtienne Carriere 	while (!timeout_elapsed(timeout_ref)) {
865*b844655cSEtienne Carriere 		if (io_read32(get_base(hi2c) + I2C_ISR) & I2C_ISR_TXIS)
866*b844655cSEtienne Carriere 			break;
867*b844655cSEtienne Carriere 		if (i2c_ack_failed(hi2c, timeout_ref))
868*b844655cSEtienne Carriere 			return -1;
869*b844655cSEtienne Carriere 	}
870*b844655cSEtienne Carriere 
871*b844655cSEtienne Carriere 	if (io_read32(get_base(hi2c) + I2C_ISR) & I2C_ISR_TXIS)
872*b844655cSEtienne Carriere 		return 0;
873*b844655cSEtienne Carriere 
874*b844655cSEtienne Carriere 	if (i2c_ack_failed(hi2c, timeout_ref))
875*b844655cSEtienne Carriere 		return -1;
876*b844655cSEtienne Carriere 
877*b844655cSEtienne Carriere 	notif_i2c_timeout(hi2c);
878*b844655cSEtienne Carriere 	return -1;
879*b844655cSEtienne Carriere }
880*b844655cSEtienne Carriere 
881*b844655cSEtienne Carriere /* Wait STOPF bit is 1 in I2C_ISR register */
882*b844655cSEtienne Carriere static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
883*b844655cSEtienne Carriere {
884*b844655cSEtienne Carriere 	while (timeout_elapsed(timeout_ref)) {
885*b844655cSEtienne Carriere 		if (io_read32(get_base(hi2c) + I2C_ISR) & I2C_ISR_STOPF)
886*b844655cSEtienne Carriere 			break;
887*b844655cSEtienne Carriere 
888*b844655cSEtienne Carriere 		if (i2c_ack_failed(hi2c, timeout_ref))
889*b844655cSEtienne Carriere 			return -1;
890*b844655cSEtienne Carriere 	}
891*b844655cSEtienne Carriere 
892*b844655cSEtienne Carriere 	if (io_read32(get_base(hi2c) + I2C_ISR) & I2C_ISR_STOPF)
893*b844655cSEtienne Carriere 		return 0;
894*b844655cSEtienne Carriere 
895*b844655cSEtienne Carriere 	if (i2c_ack_failed(hi2c, timeout_ref))
896*b844655cSEtienne Carriere 		return -1;
897*b844655cSEtienne Carriere 
898*b844655cSEtienne Carriere 	notif_i2c_timeout(hi2c);
899*b844655cSEtienne Carriere 	return -1;
900*b844655cSEtienne Carriere }
901*b844655cSEtienne Carriere 
902*b844655cSEtienne Carriere /*
903*b844655cSEtienne Carriere  * Load I2C_CR2 register for a I2C transfer
904*b844655cSEtienne Carriere  *
905*b844655cSEtienne Carriere  * @hi2c: I2C handle structure
906*b844655cSEtienne Carriere  * @dev_addr: Slave address to be transferred
907*b844655cSEtienne Carriere  * @size: Number of bytes to be transferred
908*b844655cSEtienne Carriere  * @i2c_mode: One of I2C_{RELOAD|AUTOEND|SOFTEND}_MODE: Enable Reload mode.
909*b844655cSEtienne Carriere  * @startstop: One of I2C_NO_STARTSTOP, I2C_GENERATE_STOP,
910*b844655cSEtienne Carriere  *		I2C_GENERATE_START_{READ|WRITE}
911*b844655cSEtienne Carriere  */
912*b844655cSEtienne Carriere static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint32_t dev_addr,
913*b844655cSEtienne Carriere 				uint32_t size, uint32_t i2c_mode,
914*b844655cSEtienne Carriere 				uint32_t startstop)
915*b844655cSEtienne Carriere {
916*b844655cSEtienne Carriere 	uint32_t clr_value = I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
917*b844655cSEtienne Carriere 			     I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP |
918*b844655cSEtienne Carriere 			     (I2C_CR2_RD_WRN &
919*b844655cSEtienne Carriere 			      (startstop >> (31U - I2C_CR2_RD_WRN_OFFSET)));
920*b844655cSEtienne Carriere 	uint32_t set_value = (dev_addr & I2C_CR2_SADD) |
921*b844655cSEtienne Carriere 			     ((size << I2C_CR2_NBYTES_OFFSET) &
922*b844655cSEtienne Carriere 			      I2C_CR2_NBYTES) |
923*b844655cSEtienne Carriere 			     i2c_mode | startstop;
924*b844655cSEtienne Carriere 
925*b844655cSEtienne Carriere 	io_clrsetbits32(get_base(hi2c) + I2C_CR2, clr_value, set_value);
926*b844655cSEtienne Carriere }
927*b844655cSEtienne Carriere 
928*b844655cSEtienne Carriere /*
929*b844655cSEtienne Carriere  * Master sends target device address followed by internal memory
930*b844655cSEtienne Carriere  * address for a memory write request.
931*b844655cSEtienne Carriere  * Function returns 0 on success or a negative value.
932*b844655cSEtienne Carriere  */
933*b844655cSEtienne Carriere static int i2c_request_mem_write(struct i2c_handle_s *hi2c,
934*b844655cSEtienne Carriere 				 struct i2c_request *request,
935*b844655cSEtienne Carriere 				 uint64_t timeout_ref)
936*b844655cSEtienne Carriere {
937*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
938*b844655cSEtienne Carriere 
939*b844655cSEtienne Carriere 	i2c_transfer_config(hi2c, request->dev_addr, request->mem_addr_size,
940*b844655cSEtienne Carriere 			    I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
941*b844655cSEtienne Carriere 
942*b844655cSEtienne Carriere 	if (i2c_wait_txis(hi2c, timeout_ref))
943*b844655cSEtienne Carriere 		return -1;
944*b844655cSEtienne Carriere 
945*b844655cSEtienne Carriere 	if (request->mem_addr_size == I2C_MEMADD_SIZE_8BIT) {
946*b844655cSEtienne Carriere 		/* Send memory address */
947*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, request->mem_addr & 0x00FFU);
948*b844655cSEtienne Carriere 	} else {
949*b844655cSEtienne Carriere 		/* Send MSB of memory address */
950*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, (request->mem_addr & 0xFF00U) >> 8);
951*b844655cSEtienne Carriere 
952*b844655cSEtienne Carriere 		if (i2c_wait_txis(hi2c, timeout_ref))
953*b844655cSEtienne Carriere 			return -1;
954*b844655cSEtienne Carriere 
955*b844655cSEtienne Carriere 		/* Send LSB of memory address */
956*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, request->mem_addr & 0x00FFU);
957*b844655cSEtienne Carriere 	}
958*b844655cSEtienne Carriere 
959*b844655cSEtienne Carriere 	if (wait_isr_event(hi2c, I2C_ISR_TCR, 1, timeout_ref))
960*b844655cSEtienne Carriere 		return -1;
961*b844655cSEtienne Carriere 
962*b844655cSEtienne Carriere 	return 0;
963*b844655cSEtienne Carriere }
964*b844655cSEtienne Carriere 
965*b844655cSEtienne Carriere /*
966*b844655cSEtienne Carriere  * Master sends target device address followed by internal memory
967*b844655cSEtienne Carriere  * address to prepare a memory read request.
968*b844655cSEtienne Carriere  * Function returns 0 on success or a negative value.
969*b844655cSEtienne Carriere  */
970*b844655cSEtienne Carriere static int i2c_request_mem_read(struct i2c_handle_s *hi2c,
971*b844655cSEtienne Carriere 				struct i2c_request *request,
972*b844655cSEtienne Carriere 				uint64_t timeout_ref)
973*b844655cSEtienne Carriere {
974*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
975*b844655cSEtienne Carriere 
976*b844655cSEtienne Carriere 	i2c_transfer_config(hi2c, request->dev_addr, request->mem_addr_size,
977*b844655cSEtienne Carriere 			    I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
978*b844655cSEtienne Carriere 
979*b844655cSEtienne Carriere 	if (i2c_wait_txis(hi2c, timeout_ref))
980*b844655cSEtienne Carriere 		return -1;
981*b844655cSEtienne Carriere 
982*b844655cSEtienne Carriere 	if (request->mem_addr_size == I2C_MEMADD_SIZE_8BIT) {
983*b844655cSEtienne Carriere 		/* Send memory address */
984*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, request->mem_addr & 0x00FFU);
985*b844655cSEtienne Carriere 	} else {
986*b844655cSEtienne Carriere 		/* Send MSB of memory address */
987*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, (request->mem_addr & 0xFF00U) >> 8);
988*b844655cSEtienne Carriere 
989*b844655cSEtienne Carriere 		if (i2c_wait_txis(hi2c, timeout_ref))
990*b844655cSEtienne Carriere 			return -1;
991*b844655cSEtienne Carriere 
992*b844655cSEtienne Carriere 		/* Send LSB of memory address */
993*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, request->mem_addr & 0x00FFU);
994*b844655cSEtienne Carriere 	}
995*b844655cSEtienne Carriere 
996*b844655cSEtienne Carriere 	if (wait_isr_event(hi2c, I2C_ISR_TC, 1, timeout_ref))
997*b844655cSEtienne Carriere 		return -1;
998*b844655cSEtienne Carriere 
999*b844655cSEtienne Carriere 	return 0;
1000*b844655cSEtienne Carriere }
1001*b844655cSEtienne Carriere 
1002*b844655cSEtienne Carriere /*
1003*b844655cSEtienne Carriere  * Write an amount of data in blocking mode
1004*b844655cSEtienne Carriere  *
1005*b844655cSEtienne Carriere  * @hi2c: Reference to struct i2c_handle_s
1006*b844655cSEtienne Carriere  * @request: I2C request parameters
1007*b844655cSEtienne Carriere  * @p_data: Pointer to data buffer
1008*b844655cSEtienne Carriere  * @size: Amount of data to be sent
1009*b844655cSEtienne Carriere  * Return 0 on success or a negative value
1010*b844655cSEtienne Carriere  */
1011*b844655cSEtienne Carriere static int i2c_write(struct i2c_handle_s *hi2c, struct i2c_request *request,
1012*b844655cSEtienne Carriere 		     uint8_t *p_data, uint16_t size)
1013*b844655cSEtienne Carriere {
1014*b844655cSEtienne Carriere 	uint64_t timeout_ref = 0;
1015*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
1016*b844655cSEtienne Carriere 	int rc = -1;
1017*b844655cSEtienne Carriere 	uint8_t *p_buff = p_data;
1018*b844655cSEtienne Carriere 	size_t xfer_size = 0;
1019*b844655cSEtienne Carriere 	size_t xfer_count = size;
1020*b844655cSEtienne Carriere 
1021*b844655cSEtienne Carriere 	if (request->mode != I2C_MODE_MASTER && request->mode != I2C_MODE_MEM)
1022*b844655cSEtienne Carriere 		return -1;
1023*b844655cSEtienne Carriere 
1024*b844655cSEtienne Carriere 	if (hi2c->i2c_state != I2C_STATE_READY)
1025*b844655cSEtienne Carriere 		return -1;
1026*b844655cSEtienne Carriere 
1027*b844655cSEtienne Carriere 	if (!p_data || !size)
1028*b844655cSEtienne Carriere 		return -1;
1029*b844655cSEtienne Carriere 
1030*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
1031*b844655cSEtienne Carriere 
1032*b844655cSEtienne Carriere 	timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000);
1033*b844655cSEtienne Carriere 	if (wait_isr_event(hi2c, I2C_ISR_BUSY, 0, timeout_ref))
1034*b844655cSEtienne Carriere 		goto bail;
1035*b844655cSEtienne Carriere 
1036*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_BUSY_TX;
1037*b844655cSEtienne Carriere 	hi2c->i2c_err = I2C_ERROR_NONE;
1038*b844655cSEtienne Carriere 	timeout_ref = timeout_init_us(request->timeout_ms * 1000);
1039*b844655cSEtienne Carriere 
1040*b844655cSEtienne Carriere 	if (request->mode == I2C_MODE_MEM) {
1041*b844655cSEtienne Carriere 		/* In memory mode, send slave address and memory address */
1042*b844655cSEtienne Carriere 		if (i2c_request_mem_write(hi2c, request, timeout_ref))
1043*b844655cSEtienne Carriere 			goto bail;
1044*b844655cSEtienne Carriere 
1045*b844655cSEtienne Carriere 		if (xfer_count > MAX_NBYTE_SIZE) {
1046*b844655cSEtienne Carriere 			xfer_size = MAX_NBYTE_SIZE;
1047*b844655cSEtienne Carriere 			i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1048*b844655cSEtienne Carriere 					    I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
1049*b844655cSEtienne Carriere 		} else {
1050*b844655cSEtienne Carriere 			xfer_size = xfer_count;
1051*b844655cSEtienne Carriere 			i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1052*b844655cSEtienne Carriere 					    I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
1053*b844655cSEtienne Carriere 		}
1054*b844655cSEtienne Carriere 	} else {
1055*b844655cSEtienne Carriere 		/* In master mode, send slave address */
1056*b844655cSEtienne Carriere 		if (xfer_count > MAX_NBYTE_SIZE) {
1057*b844655cSEtienne Carriere 			xfer_size = MAX_NBYTE_SIZE;
1058*b844655cSEtienne Carriere 			i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1059*b844655cSEtienne Carriere 					    I2C_RELOAD_MODE,
1060*b844655cSEtienne Carriere 					    I2C_GENERATE_START_WRITE);
1061*b844655cSEtienne Carriere 		} else {
1062*b844655cSEtienne Carriere 			xfer_size = xfer_count;
1063*b844655cSEtienne Carriere 			i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1064*b844655cSEtienne Carriere 					    I2C_AUTOEND_MODE,
1065*b844655cSEtienne Carriere 					    I2C_GENERATE_START_WRITE);
1066*b844655cSEtienne Carriere 		}
1067*b844655cSEtienne Carriere 	}
1068*b844655cSEtienne Carriere 
1069*b844655cSEtienne Carriere 	do {
1070*b844655cSEtienne Carriere 		if (i2c_wait_txis(hi2c, timeout_ref))
1071*b844655cSEtienne Carriere 			goto bail;
1072*b844655cSEtienne Carriere 
1073*b844655cSEtienne Carriere 		io_write8(base + I2C_TXDR, *p_buff);
1074*b844655cSEtienne Carriere 		p_buff++;
1075*b844655cSEtienne Carriere 		xfer_count--;
1076*b844655cSEtienne Carriere 		xfer_size--;
1077*b844655cSEtienne Carriere 
1078*b844655cSEtienne Carriere 		if (xfer_count && !xfer_size) {
1079*b844655cSEtienne Carriere 			/* Wait until TCR flag is set */
1080*b844655cSEtienne Carriere 			if (wait_isr_event(hi2c, I2C_ISR_TCR, 1, timeout_ref))
1081*b844655cSEtienne Carriere 				goto bail;
1082*b844655cSEtienne Carriere 
1083*b844655cSEtienne Carriere 			if (xfer_count > MAX_NBYTE_SIZE) {
1084*b844655cSEtienne Carriere 				xfer_size = MAX_NBYTE_SIZE;
1085*b844655cSEtienne Carriere 				i2c_transfer_config(hi2c, request->dev_addr,
1086*b844655cSEtienne Carriere 						    xfer_size,
1087*b844655cSEtienne Carriere 						    I2C_RELOAD_MODE,
1088*b844655cSEtienne Carriere 						    I2C_NO_STARTSTOP);
1089*b844655cSEtienne Carriere 			} else {
1090*b844655cSEtienne Carriere 				xfer_size = xfer_count;
1091*b844655cSEtienne Carriere 				i2c_transfer_config(hi2c, request->dev_addr,
1092*b844655cSEtienne Carriere 						    xfer_size,
1093*b844655cSEtienne Carriere 						    I2C_AUTOEND_MODE,
1094*b844655cSEtienne Carriere 						    I2C_NO_STARTSTOP);
1095*b844655cSEtienne Carriere 			}
1096*b844655cSEtienne Carriere 		}
1097*b844655cSEtienne Carriere 
1098*b844655cSEtienne Carriere 	} while (xfer_count > 0U);
1099*b844655cSEtienne Carriere 
1100*b844655cSEtienne Carriere 	/*
1101*b844655cSEtienne Carriere 	 * No need to Check TC flag, with AUTOEND mode the stop
1102*b844655cSEtienne Carriere 	 * is automatically generated.
1103*b844655cSEtienne Carriere 	 * Wait until STOPF flag is reset.
1104*b844655cSEtienne Carriere 	 */
1105*b844655cSEtienne Carriere 	if (i2c_wait_stop(hi2c, timeout_ref))
1106*b844655cSEtienne Carriere 		goto bail;
1107*b844655cSEtienne Carriere 
1108*b844655cSEtienne Carriere 	io_write32(base + I2C_ICR, I2C_ISR_STOPF);
1109*b844655cSEtienne Carriere 
1110*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR2, CR2_RESET_MASK);
1111*b844655cSEtienne Carriere 
1112*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
1113*b844655cSEtienne Carriere 
1114*b844655cSEtienne Carriere 	rc = 0;
1115*b844655cSEtienne Carriere 
1116*b844655cSEtienne Carriere bail:
1117*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
1118*b844655cSEtienne Carriere 
1119*b844655cSEtienne Carriere 	return rc;
1120*b844655cSEtienne Carriere }
1121*b844655cSEtienne Carriere 
1122*b844655cSEtienne Carriere int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint32_t dev_addr,
1123*b844655cSEtienne Carriere 			uint32_t mem_addr, uint32_t mem_addr_size,
1124*b844655cSEtienne Carriere 			uint8_t *p_data, size_t size, unsigned int timeout_ms)
1125*b844655cSEtienne Carriere {
1126*b844655cSEtienne Carriere 	struct i2c_request request = {
1127*b844655cSEtienne Carriere 		.dev_addr = dev_addr,
1128*b844655cSEtienne Carriere 		.mode = I2C_MODE_MEM,
1129*b844655cSEtienne Carriere 		.mem_addr = mem_addr,
1130*b844655cSEtienne Carriere 		.mem_addr_size = mem_addr_size,
1131*b844655cSEtienne Carriere 		.timeout_ms = timeout_ms,
1132*b844655cSEtienne Carriere 	};
1133*b844655cSEtienne Carriere 
1134*b844655cSEtienne Carriere 	return i2c_write(hi2c, &request, p_data, size);
1135*b844655cSEtienne Carriere }
1136*b844655cSEtienne Carriere 
1137*b844655cSEtienne Carriere int stm32_i2c_master_transmit(struct i2c_handle_s *hi2c, uint32_t dev_addr,
1138*b844655cSEtienne Carriere 			      uint8_t *p_data, size_t size,
1139*b844655cSEtienne Carriere 			      unsigned int timeout_ms)
1140*b844655cSEtienne Carriere {
1141*b844655cSEtienne Carriere 	struct i2c_request request = {
1142*b844655cSEtienne Carriere 		.dev_addr = dev_addr,
1143*b844655cSEtienne Carriere 		.mode = I2C_MODE_MASTER,
1144*b844655cSEtienne Carriere 		.timeout_ms = timeout_ms,
1145*b844655cSEtienne Carriere 	};
1146*b844655cSEtienne Carriere 
1147*b844655cSEtienne Carriere 	return i2c_write(hi2c, &request, p_data, size);
1148*b844655cSEtienne Carriere }
1149*b844655cSEtienne Carriere 
1150*b844655cSEtienne Carriere /*
1151*b844655cSEtienne Carriere  * Read an amount of data in blocking mode
1152*b844655cSEtienne Carriere  *
1153*b844655cSEtienne Carriere  * @hi2c: Reference to struct i2c_handle_s
1154*b844655cSEtienne Carriere  * @request: I2C request parameters
1155*b844655cSEtienne Carriere  * @p_data: Pointer to data buffer
1156*b844655cSEtienne Carriere  * @size: Amount of data to be sent
1157*b844655cSEtienne Carriere  * Return 0 on success or a negative value
1158*b844655cSEtienne Carriere  */
1159*b844655cSEtienne Carriere static int i2c_read(struct i2c_handle_s *hi2c, struct i2c_request *request,
1160*b844655cSEtienne Carriere 		    uint8_t *p_data, uint32_t size)
1161*b844655cSEtienne Carriere {
1162*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
1163*b844655cSEtienne Carriere 	uint64_t timeout_ref = 0;
1164*b844655cSEtienne Carriere 	int rc = -1;
1165*b844655cSEtienne Carriere 	uint8_t *p_buff = p_data;
1166*b844655cSEtienne Carriere 	size_t xfer_count = size;
1167*b844655cSEtienne Carriere 	size_t xfer_size = 0;
1168*b844655cSEtienne Carriere 
1169*b844655cSEtienne Carriere 	if (request->mode != I2C_MODE_MASTER && request->mode != I2C_MODE_MEM)
1170*b844655cSEtienne Carriere 		return -1;
1171*b844655cSEtienne Carriere 
1172*b844655cSEtienne Carriere 	if (hi2c->i2c_state != I2C_STATE_READY)
1173*b844655cSEtienne Carriere 		return -1;
1174*b844655cSEtienne Carriere 
1175*b844655cSEtienne Carriere 	if (!p_data || !size)
1176*b844655cSEtienne Carriere 		return -1;
1177*b844655cSEtienne Carriere 
1178*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
1179*b844655cSEtienne Carriere 
1180*b844655cSEtienne Carriere 	timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000);
1181*b844655cSEtienne Carriere 	if (wait_isr_event(hi2c, I2C_ISR_BUSY, 0, timeout_ref))
1182*b844655cSEtienne Carriere 		goto bail;
1183*b844655cSEtienne Carriere 
1184*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_BUSY_RX;
1185*b844655cSEtienne Carriere 	hi2c->i2c_err = I2C_ERROR_NONE;
1186*b844655cSEtienne Carriere 	timeout_ref = timeout_init_us(request->timeout_ms * 1000);
1187*b844655cSEtienne Carriere 
1188*b844655cSEtienne Carriere 	if (request->mode == I2C_MODE_MEM) {
1189*b844655cSEtienne Carriere 		/* Send memory address */
1190*b844655cSEtienne Carriere 		if (i2c_request_mem_read(hi2c, request, timeout_ref))
1191*b844655cSEtienne Carriere 			goto bail;
1192*b844655cSEtienne Carriere 	}
1193*b844655cSEtienne Carriere 
1194*b844655cSEtienne Carriere 	/*
1195*b844655cSEtienne Carriere 	 * Send slave address.
1196*b844655cSEtienne Carriere 	 * Set NBYTES to write and reload if xfer_count > MAX_NBYTE_SIZE
1197*b844655cSEtienne Carriere 	 * and generate RESTART.
1198*b844655cSEtienne Carriere 	 */
1199*b844655cSEtienne Carriere 	if (xfer_count > MAX_NBYTE_SIZE) {
1200*b844655cSEtienne Carriere 		xfer_size = MAX_NBYTE_SIZE;
1201*b844655cSEtienne Carriere 		i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1202*b844655cSEtienne Carriere 				    I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
1203*b844655cSEtienne Carriere 	} else {
1204*b844655cSEtienne Carriere 		xfer_size = xfer_count;
1205*b844655cSEtienne Carriere 		i2c_transfer_config(hi2c, request->dev_addr, xfer_size,
1206*b844655cSEtienne Carriere 				    I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
1207*b844655cSEtienne Carriere 	}
1208*b844655cSEtienne Carriere 
1209*b844655cSEtienne Carriere 	do {
1210*b844655cSEtienne Carriere 		if (wait_isr_event(hi2c, I2C_ISR_RXNE, 1, timeout_ref))
1211*b844655cSEtienne Carriere 			goto bail;
1212*b844655cSEtienne Carriere 
1213*b844655cSEtienne Carriere 		*p_buff = io_read8(base + I2C_RXDR);
1214*b844655cSEtienne Carriere 		p_buff++;
1215*b844655cSEtienne Carriere 		xfer_size--;
1216*b844655cSEtienne Carriere 		xfer_count--;
1217*b844655cSEtienne Carriere 
1218*b844655cSEtienne Carriere 		if (xfer_count && !xfer_size) {
1219*b844655cSEtienne Carriere 			if (wait_isr_event(hi2c, I2C_ISR_TCR, 1, timeout_ref))
1220*b844655cSEtienne Carriere 				goto bail;
1221*b844655cSEtienne Carriere 
1222*b844655cSEtienne Carriere 			if (xfer_count > MAX_NBYTE_SIZE) {
1223*b844655cSEtienne Carriere 				xfer_size = MAX_NBYTE_SIZE;
1224*b844655cSEtienne Carriere 				i2c_transfer_config(hi2c, request->dev_addr,
1225*b844655cSEtienne Carriere 						    xfer_size,
1226*b844655cSEtienne Carriere 						    I2C_RELOAD_MODE,
1227*b844655cSEtienne Carriere 						    I2C_NO_STARTSTOP);
1228*b844655cSEtienne Carriere 			} else {
1229*b844655cSEtienne Carriere 				xfer_size = xfer_count;
1230*b844655cSEtienne Carriere 				i2c_transfer_config(hi2c, request->dev_addr,
1231*b844655cSEtienne Carriere 						    xfer_size,
1232*b844655cSEtienne Carriere 						    I2C_AUTOEND_MODE,
1233*b844655cSEtienne Carriere 						    I2C_NO_STARTSTOP);
1234*b844655cSEtienne Carriere 			}
1235*b844655cSEtienne Carriere 		}
1236*b844655cSEtienne Carriere 	} while (xfer_count > 0U);
1237*b844655cSEtienne Carriere 
1238*b844655cSEtienne Carriere 	/*
1239*b844655cSEtienne Carriere 	 * No need to Check TC flag, with AUTOEND mode the stop
1240*b844655cSEtienne Carriere 	 * is automatically generated.
1241*b844655cSEtienne Carriere 	 * Wait until STOPF flag is reset.
1242*b844655cSEtienne Carriere 	 */
1243*b844655cSEtienne Carriere 	if (i2c_wait_stop(hi2c, timeout_ref))
1244*b844655cSEtienne Carriere 		goto bail;
1245*b844655cSEtienne Carriere 
1246*b844655cSEtienne Carriere 	io_write32(base + I2C_ICR, I2C_ISR_STOPF);
1247*b844655cSEtienne Carriere 
1248*b844655cSEtienne Carriere 	io_clrbits32(base + I2C_CR2, CR2_RESET_MASK);
1249*b844655cSEtienne Carriere 
1250*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
1251*b844655cSEtienne Carriere 
1252*b844655cSEtienne Carriere 	rc = 0;
1253*b844655cSEtienne Carriere 
1254*b844655cSEtienne Carriere bail:
1255*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
1256*b844655cSEtienne Carriere 
1257*b844655cSEtienne Carriere 	return rc;
1258*b844655cSEtienne Carriere }
1259*b844655cSEtienne Carriere 
1260*b844655cSEtienne Carriere int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint32_t dev_addr,
1261*b844655cSEtienne Carriere 		       uint32_t mem_addr, uint32_t mem_addr_size,
1262*b844655cSEtienne Carriere 		       uint8_t *p_data, size_t size, unsigned int timeout_ms)
1263*b844655cSEtienne Carriere {
1264*b844655cSEtienne Carriere 	struct i2c_request request = {
1265*b844655cSEtienne Carriere 		.dev_addr = dev_addr,
1266*b844655cSEtienne Carriere 		.mode = I2C_MODE_MEM,
1267*b844655cSEtienne Carriere 		.mem_addr = mem_addr,
1268*b844655cSEtienne Carriere 		.mem_addr_size = mem_addr_size,
1269*b844655cSEtienne Carriere 		.timeout_ms = timeout_ms,
1270*b844655cSEtienne Carriere 	};
1271*b844655cSEtienne Carriere 
1272*b844655cSEtienne Carriere 	return i2c_read(hi2c, &request, p_data, size);
1273*b844655cSEtienne Carriere }
1274*b844655cSEtienne Carriere 
1275*b844655cSEtienne Carriere int stm32_i2c_master_receive(struct i2c_handle_s *hi2c, uint32_t dev_addr,
1276*b844655cSEtienne Carriere 			     uint8_t *p_data, size_t size,
1277*b844655cSEtienne Carriere 			     unsigned int timeout_ms)
1278*b844655cSEtienne Carriere {
1279*b844655cSEtienne Carriere 	struct i2c_request request = {
1280*b844655cSEtienne Carriere 		.dev_addr = dev_addr,
1281*b844655cSEtienne Carriere 		.mode = I2C_MODE_MASTER,
1282*b844655cSEtienne Carriere 		.timeout_ms = timeout_ms,
1283*b844655cSEtienne Carriere 	};
1284*b844655cSEtienne Carriere 
1285*b844655cSEtienne Carriere 	return i2c_read(hi2c, &request, p_data, size);
1286*b844655cSEtienne Carriere }
1287*b844655cSEtienne Carriere 
1288*b844655cSEtienne Carriere bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint32_t dev_addr,
1289*b844655cSEtienne Carriere 			       unsigned int trials, unsigned int timeout_ms)
1290*b844655cSEtienne Carriere {
1291*b844655cSEtienne Carriere 	vaddr_t base = get_base(hi2c);
1292*b844655cSEtienne Carriere 	unsigned int i2c_trials = 0U;
1293*b844655cSEtienne Carriere 	bool rc = false;
1294*b844655cSEtienne Carriere 
1295*b844655cSEtienne Carriere 	if (hi2c->i2c_state != I2C_STATE_READY)
1296*b844655cSEtienne Carriere 		return rc;
1297*b844655cSEtienne Carriere 
1298*b844655cSEtienne Carriere 	stm32_clock_enable(hi2c->clock);
1299*b844655cSEtienne Carriere 
1300*b844655cSEtienne Carriere 	if (io_read32(base + I2C_ISR) & I2C_ISR_BUSY)
1301*b844655cSEtienne Carriere 		goto bail;
1302*b844655cSEtienne Carriere 
1303*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_BUSY;
1304*b844655cSEtienne Carriere 	hi2c->i2c_err = I2C_ERROR_NONE;
1305*b844655cSEtienne Carriere 
1306*b844655cSEtienne Carriere 	do {
1307*b844655cSEtienne Carriere 		uint64_t timeout_ref = 0;
1308*b844655cSEtienne Carriere 		vaddr_t isr = base + I2C_ISR;
1309*b844655cSEtienne Carriere 
1310*b844655cSEtienne Carriere 		/* Generate Start */
1311*b844655cSEtienne Carriere 		if ((io_read32(base + I2C_OAR1) & I2C_OAR1_OA1MODE) == 0)
1312*b844655cSEtienne Carriere 			io_write32(base + I2C_CR2,
1313*b844655cSEtienne Carriere 				   ((dev_addr & I2C_CR2_SADD) |
1314*b844655cSEtienne Carriere 				    I2C_CR2_START | I2C_CR2_AUTOEND) &
1315*b844655cSEtienne Carriere 				   ~I2C_CR2_RD_WRN);
1316*b844655cSEtienne Carriere 		else
1317*b844655cSEtienne Carriere 			io_write32(base + I2C_CR2,
1318*b844655cSEtienne Carriere 				   ((dev_addr & I2C_CR2_SADD) |
1319*b844655cSEtienne Carriere 				    I2C_CR2_START | I2C_CR2_ADD10) &
1320*b844655cSEtienne Carriere 				   ~I2C_CR2_RD_WRN);
1321*b844655cSEtienne Carriere 
1322*b844655cSEtienne Carriere 		/*
1323*b844655cSEtienne Carriere 		 * No need to Check TC flag, with AUTOEND mode the stop
1324*b844655cSEtienne Carriere 		 * is automatically generated.
1325*b844655cSEtienne Carriere 		 * Wait until STOPF flag is set or a NACK flag is set.
1326*b844655cSEtienne Carriere 		 */
1327*b844655cSEtienne Carriere 		timeout_ref = timeout_init_us(timeout_ms * 1000);
1328*b844655cSEtienne Carriere 		while (!timeout_elapsed(timeout_ref))
1329*b844655cSEtienne Carriere 			if (io_read32(isr) & (I2C_ISR_STOPF | I2C_ISR_NACKF))
1330*b844655cSEtienne Carriere 				break;
1331*b844655cSEtienne Carriere 
1332*b844655cSEtienne Carriere 		if ((io_read32(isr) & (I2C_ISR_STOPF | I2C_ISR_NACKF)) == 0) {
1333*b844655cSEtienne Carriere 			notif_i2c_timeout(hi2c);
1334*b844655cSEtienne Carriere 			goto bail;
1335*b844655cSEtienne Carriere 		}
1336*b844655cSEtienne Carriere 
1337*b844655cSEtienne Carriere 		if ((io_read32(base + I2C_ISR) & I2C_ISR_NACKF) == 0U) {
1338*b844655cSEtienne Carriere 			if (wait_isr_event(hi2c, I2C_ISR_STOPF, 1, timeout_ref))
1339*b844655cSEtienne Carriere 				goto bail;
1340*b844655cSEtienne Carriere 
1341*b844655cSEtienne Carriere 			io_write32(base + I2C_ICR, I2C_ISR_STOPF);
1342*b844655cSEtienne Carriere 
1343*b844655cSEtienne Carriere 			hi2c->i2c_state = I2C_STATE_READY;
1344*b844655cSEtienne Carriere 
1345*b844655cSEtienne Carriere 			rc = true;
1346*b844655cSEtienne Carriere 			goto bail;
1347*b844655cSEtienne Carriere 		}
1348*b844655cSEtienne Carriere 
1349*b844655cSEtienne Carriere 		if (wait_isr_event(hi2c, I2C_ISR_STOPF, 1, timeout_ref))
1350*b844655cSEtienne Carriere 			goto bail;
1351*b844655cSEtienne Carriere 
1352*b844655cSEtienne Carriere 		io_write32(base + I2C_ICR, I2C_ISR_NACKF);
1353*b844655cSEtienne Carriere 		io_write32(base + I2C_ICR, I2C_ISR_STOPF);
1354*b844655cSEtienne Carriere 
1355*b844655cSEtienne Carriere 		if (i2c_trials == trials) {
1356*b844655cSEtienne Carriere 			io_setbits32(base + I2C_CR2, I2C_CR2_STOP);
1357*b844655cSEtienne Carriere 
1358*b844655cSEtienne Carriere 			if (wait_isr_event(hi2c, I2C_ISR_STOPF, 1, timeout_ref))
1359*b844655cSEtienne Carriere 				goto bail;
1360*b844655cSEtienne Carriere 
1361*b844655cSEtienne Carriere 			io_write32(base + I2C_ICR, I2C_ISR_STOPF);
1362*b844655cSEtienne Carriere 		}
1363*b844655cSEtienne Carriere 
1364*b844655cSEtienne Carriere 		i2c_trials++;
1365*b844655cSEtienne Carriere 	} while (i2c_trials < trials);
1366*b844655cSEtienne Carriere 
1367*b844655cSEtienne Carriere 	notif_i2c_timeout(hi2c);
1368*b844655cSEtienne Carriere 
1369*b844655cSEtienne Carriere bail:
1370*b844655cSEtienne Carriere 	stm32_clock_disable(hi2c->clock);
1371*b844655cSEtienne Carriere 
1372*b844655cSEtienne Carriere 	return rc;
1373*b844655cSEtienne Carriere }
1374*b844655cSEtienne Carriere 
1375*b844655cSEtienne Carriere void stm32_i2c_resume(struct i2c_handle_s *hi2c)
1376*b844655cSEtienne Carriere {
1377*b844655cSEtienne Carriere 	if (hi2c->i2c_state == I2C_STATE_READY)
1378*b844655cSEtienne Carriere 		return;
1379*b844655cSEtienne Carriere 
1380*b844655cSEtienne Carriere 	if ((hi2c->i2c_state != I2C_STATE_RESET) &&
1381*b844655cSEtienne Carriere 	    (hi2c->i2c_state != I2C_STATE_SUSPENDED))
1382*b844655cSEtienne Carriere 		panic();
1383*b844655cSEtienne Carriere 
1384*b844655cSEtienne Carriere 	if (hi2c->i2c_state == I2C_STATE_RESET) {
1385*b844655cSEtienne Carriere 		/* This is no valid I2C configuration loaded yet */
1386*b844655cSEtienne Carriere 		return;
1387*b844655cSEtienne Carriere 	}
1388*b844655cSEtienne Carriere 
1389*b844655cSEtienne Carriere 	restore_cfg(hi2c, &hi2c->sec_cfg);
1390*b844655cSEtienne Carriere 
1391*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_READY;
1392*b844655cSEtienne Carriere }
1393*b844655cSEtienne Carriere 
1394*b844655cSEtienne Carriere void stm32_i2c_suspend(struct i2c_handle_s *hi2c)
1395*b844655cSEtienne Carriere {
1396*b844655cSEtienne Carriere 	if (hi2c->i2c_state == I2C_STATE_SUSPENDED)
1397*b844655cSEtienne Carriere 		return;
1398*b844655cSEtienne Carriere 
1399*b844655cSEtienne Carriere 	if (hi2c->i2c_state != I2C_STATE_READY)
1400*b844655cSEtienne Carriere 		panic();
1401*b844655cSEtienne Carriere 
1402*b844655cSEtienne Carriere 	save_cfg(hi2c, &hi2c->sec_cfg);
1403*b844655cSEtienne Carriere 
1404*b844655cSEtienne Carriere 	hi2c->i2c_state = I2C_STATE_SUSPENDED;
1405*b844655cSEtienne Carriere }
1406