blob: ed880522b0da23d74f62032b45165de0cbe3bf40 [file] [log] [blame]
Yann Gautiere4f559f2018-07-16 17:55:07 +02001/*
Yann Gautier435832a2019-01-17 09:34:18 +01002 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
Yann Gautiere4f559f2018-07-16 17:55:07 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautiere4f559f2018-07-16 17:55:07 +02007#include <errno.h>
Yann Gautiere4f559f2018-07-16 17:55:07 +02008#include <stdbool.h>
9#include <stdlib.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000010
Yann Gautierd82d4ff2019-02-14 11:15:03 +010011#include <libfdt.h>
12
13#include <platform_def.h>
14
15#include <common/debug.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000016#include <drivers/delay_timer.h>
Yann Gautierd82d4ff2019-02-14 11:15:03 +010017#include <drivers/st/stm32_gpio.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000018#include <drivers/st/stm32_i2c.h>
19#include <lib/mmio.h>
Yann Gautierd82d4ff2019-02-14 11:15:03 +010020#include <lib/utils.h>
Yann Gautiere4f559f2018-07-16 17:55:07 +020021
22/* STM32 I2C registers offsets */
23#define I2C_CR1 0x00U
24#define I2C_CR2 0x04U
25#define I2C_OAR1 0x08U
26#define I2C_OAR2 0x0CU
27#define I2C_TIMINGR 0x10U
28#define I2C_TIMEOUTR 0x14U
29#define I2C_ISR 0x18U
30#define I2C_ICR 0x1CU
31#define I2C_PECR 0x20U
32#define I2C_RXDR 0x24U
33#define I2C_TXDR 0x28U
34
Yann Gautierd82d4ff2019-02-14 11:15:03 +010035#define TIMINGR_CLEAR_MASK 0xF0FFFFFFU
Yann Gautiere4f559f2018-07-16 17:55:07 +020036
37#define MAX_NBYTE_SIZE 255U
38
Yann Gautierd82d4ff2019-02-14 11:15:03 +010039#define I2C_NSEC_PER_SEC 1000000000L
Yann Gautiere4f559f2018-07-16 17:55:07 +020040
Yann Gautierd82d4ff2019-02-14 11:15:03 +010041/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
42#define I2C_TIMING 0x10D07DB5
Yann Gautiere4f559f2018-07-16 17:55:07 +020043
Yann Gautierd82d4ff2019-02-14 11:15:03 +010044static void notif_i2c_timeout(struct i2c_handle_s *hi2c)
45{
46 hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
47 hi2c->i2c_mode = I2C_MODE_NONE;
48 hi2c->i2c_state = I2C_STATE_READY;
49}
Yann Gautiere4f559f2018-07-16 17:55:07 +020050
Yann Gautierd82d4ff2019-02-14 11:15:03 +010051/*
52 * @brief Configure I2C Analog noise filter.
53 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
54 * the configuration information for the specified I2C peripheral.
55 * @param analog_filter: New state of the Analog filter
56 * @retval 0 if OK, negative value else
57 */
58static int i2c_config_analog_filter(struct i2c_handle_s *hi2c,
59 uint32_t analog_filter)
60{
61 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
62 return -EBUSY;
63 }
64
65 hi2c->lock = 1;
66
67 hi2c->i2c_state = I2C_STATE_BUSY;
68
69 /* Disable the selected I2C peripheral */
70 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
71
72 /* Reset I2Cx ANOFF bit */
73 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
74
75 /* Set analog filter bit*/
76 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
77
78 /* Enable the selected I2C peripheral */
79 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
80
81 hi2c->i2c_state = I2C_STATE_READY;
82
83 hi2c->lock = 0;
84
85 return 0;
86}
87
88/*
89 * @brief Get I2C setup information from the device tree and set pinctrl
90 * configuration.
91 * @param fdt: Pointer to the device tree
92 * @param node: I2C node offset
93 * @param init: Ref to the initialization configuration structure
94 * @retval 0 if OK, negative value else
95 */
96int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
97 struct stm32_i2c_init_s *init)
98{
99 const fdt32_t *cuint;
100
101 cuint = fdt_getprop(fdt, node, "i2c-scl-rising-time-ns", NULL);
102 if (cuint == NULL) {
103 init->rise_time = STM32_I2C_RISE_TIME_DEFAULT;
104 } else {
105 init->rise_time = fdt32_to_cpu(*cuint);
106 }
107
108 cuint = fdt_getprop(fdt, node, "i2c-scl-falling-time-ns", NULL);
109 if (cuint == NULL) {
110 init->fall_time = STM32_I2C_FALL_TIME_DEFAULT;
111 } else {
112 init->fall_time = fdt32_to_cpu(*cuint);
113 }
114
115 cuint = fdt_getprop(fdt, node, "clock-frequency", NULL);
116 if (cuint == NULL) {
117 init->speed_mode = STM32_I2C_SPEED_DEFAULT;
118 } else {
119 switch (fdt32_to_cpu(*cuint)) {
120 case STANDARD_RATE:
121 init->speed_mode = I2C_SPEED_STANDARD;
122 break;
123 case FAST_RATE:
124 init->speed_mode = I2C_SPEED_FAST;
125 break;
126 case FAST_PLUS_RATE:
127 init->speed_mode = I2C_SPEED_FAST_PLUS;
128 break;
129 default:
130 init->speed_mode = STM32_I2C_SPEED_DEFAULT;
131 break;
132 }
133 }
134
135 return dt_set_pinctrl_config(node);
136}
Yann Gautiere4f559f2018-07-16 17:55:07 +0200137
138/*
139 * @brief Initialize the I2C device.
140 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
141 * the configuration information for the specified I2C.
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100142 * @param init_data: Initialization configuration structure
Yann Gautiere4f559f2018-07-16 17:55:07 +0200143 * @retval 0 if OK, negative value else
144 */
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100145int stm32_i2c_init(struct i2c_handle_s *hi2c,
146 struct stm32_i2c_init_s *init_data)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200147{
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100148 int rc = 0;
149 uint32_t timing = I2C_TIMING;
150
Yann Gautiere4f559f2018-07-16 17:55:07 +0200151 if (hi2c == NULL) {
152 return -ENOENT;
153 }
154
155 if (hi2c->i2c_state == I2C_STATE_RESET) {
156 hi2c->lock = 0;
157 }
158
159 hi2c->i2c_state = I2C_STATE_BUSY;
160
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100161 stm32mp_clk_enable(hi2c->clock);
162
Yann Gautiere4f559f2018-07-16 17:55:07 +0200163 /* Disable the selected I2C peripheral */
164 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
165
166 /* Configure I2Cx: Frequency range */
167 mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100168 timing & TIMINGR_CLEAR_MASK);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200169
170 /* Disable Own Address1 before set the Own Address1 configuration */
171 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
172
173 /* Configure I2Cx: Own Address1 and ack own address1 mode */
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100174 if (init_data->addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
Yann Gautiere4f559f2018-07-16 17:55:07 +0200175 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100176 I2C_OAR1_OA1EN | init_data->own_address1);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200177 } else { /* I2C_ADDRESSINGMODE_10BIT */
178 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
179 I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100180 init_data->own_address1);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200181 }
182
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100183 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, 0);
184
Yann Gautiere4f559f2018-07-16 17:55:07 +0200185 /* Configure I2Cx: Addressing Master mode */
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100186 if (init_data->addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
187 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200188 }
189
190 /*
191 * Enable the AUTOEND by default, and enable NACK
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100192 * (should be disabled only during Slave process).
Yann Gautiere4f559f2018-07-16 17:55:07 +0200193 */
194 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
195 I2C_CR2_AUTOEND | I2C_CR2_NACK);
196
197 /* Disable Own Address2 before set the Own Address2 configuration */
198 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
199
200 /* Configure I2Cx: Dual mode and Own Address2 */
201 mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100202 init_data->dual_address_mode |
203 init_data->own_address2 |
204 (init_data->own_address2_masks << 8));
Yann Gautiere4f559f2018-07-16 17:55:07 +0200205
206 /* Configure I2Cx: Generalcall and NoStretch mode */
207 mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100208 init_data->general_call_mode |
209 init_data->no_stretch_mode);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200210
211 /* Enable the selected I2C peripheral */
212 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
213
214 hi2c->i2c_err = I2C_ERROR_NONE;
215 hi2c->i2c_state = I2C_STATE_READY;
216 hi2c->i2c_mode = I2C_MODE_NONE;
217
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100218 rc = i2c_config_analog_filter(hi2c, init_data->analog_filter ?
219 I2C_ANALOGFILTER_ENABLE :
220 I2C_ANALOGFILTER_DISABLE);
221 if (rc != 0) {
222 ERROR("Cannot initialize I2C analog filter (%d)\n", rc);
223 stm32mp_clk_disable(hi2c->clock);
224 return rc;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200225 }
226
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100227 stm32mp_clk_disable(hi2c->clock);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200228
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100229 return rc;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200230}
231
232/*
233 * @brief I2C Tx data register flush process.
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100234 * @param hi2c: I2C handle
Yann Gautiere4f559f2018-07-16 17:55:07 +0200235 * @retval None
236 */
237static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
238{
239 /*
240 * If a pending TXIS flag is set,
241 * write a dummy data in TXDR to clear it.
242 */
243 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
244 0U) {
245 mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
246 }
247
248 /* Flush TX register if not empty */
249 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
250 0U) {
251 mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
252 I2C_FLAG_TXE);
253 }
254}
255
256/*
257 * @brief This function handles I2C Communication timeout.
258 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
259 * the configuration information for the specified I2C.
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100260 * @param flag: Specifies the I2C flag to check
261 * @param awaited_value: The awaited bit value for the flag (0 or 1)
262 * @param timeout_ref: Reference to target timeout
Yann Gautiere4f559f2018-07-16 17:55:07 +0200263 * @retval 0 if OK, negative value else
264 */
265static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100266 uint8_t awaited_value, uint64_t timeout_ref)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200267{
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100268 for ( ; ; ) {
269 uint32_t isr = mmio_read_32(hi2c->i2c_base_addr + I2C_ISR);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200270
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100271 if (!!(isr & flag) != !!awaited_value) {
272 return 0;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200273 }
274
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100275 if (timeout_elapsed(timeout_ref)) {
276 notif_i2c_timeout(hi2c);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200277 hi2c->lock = 0;
278
279 return -EIO;
280 }
281 }
Yann Gautiere4f559f2018-07-16 17:55:07 +0200282}
283
284/*
285 * @brief This function handles Acknowledge failed detection during
286 * an I2C Communication.
287 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
288 * the configuration information for the specified I2C.
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100289 * @param timeout_ref: Reference to target timeout
Yann Gautiere4f559f2018-07-16 17:55:07 +0200290 * @retval 0 if OK, negative value else
291 */
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100292static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200293{
294 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
295 return 0;
296 }
297
298 /*
299 * Wait until STOP Flag is reset.
300 * AutoEnd should be initiate after AF.
301 */
302 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
303 I2C_FLAG_STOPF) == 0U) {
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100304 if (timeout_elapsed(timeout_ref)) {
305 notif_i2c_timeout(hi2c);
306 hi2c->lock = 0;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200307
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100308 return -EIO;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200309 }
310 }
311
312 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
313
314 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
315
316 i2c_flush_txdr(hi2c);
317
318 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
319
320 hi2c->i2c_err |= I2C_ERROR_AF;
321 hi2c->i2c_state = I2C_STATE_READY;
322 hi2c->i2c_mode = I2C_MODE_NONE;
323
324 hi2c->lock = 0;
325
326 return -EIO;
327}
328
329/*
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100330 * @brief This function handles I2C Communication timeout for specific usage
331 * of TXIS flag.
332 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
333 * the configuration information for the specified I2C.
334 * @param timeout_ref: Reference to target timeout
335 * @retval 0 if OK, negative value else
336 */
337static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
338{
339 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
340 I2C_FLAG_TXIS) == 0U) {
341 if (i2c_ack_failed(hi2c, timeout_ref) != 0) {
342 return -EIO;
343 }
344
345 if (timeout_elapsed(timeout_ref)) {
346 notif_i2c_timeout(hi2c);
347 hi2c->lock = 0;
348
349 return -EIO;
350 }
351 }
352
353 return 0;
354}
355
356/*
357 * @brief This function handles I2C Communication timeout for specific
358 * usage of STOP flag.
359 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
360 * the configuration information for the specified I2C.
361 * @param timeout_ref: Reference to target timeout
362 * @retval 0 if OK, negative value else
363 */
364static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint64_t timeout_ref)
365{
366 while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
367 I2C_FLAG_STOPF) == 0U) {
368 if (i2c_ack_failed(hi2c, timeout_ref) != 0) {
369 return -EIO;
370 }
371
372 if (timeout_elapsed(timeout_ref)) {
373 notif_i2c_timeout(hi2c);
374 hi2c->lock = 0;
375
376 return -EIO;
377 }
378 }
379
380 return 0;
381}
382
383/*
Yann Gautiere4f559f2018-07-16 17:55:07 +0200384 * @brief Handles I2Cx communication when starting transfer or during transfer
385 * (TC or TCR flag are set).
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100386 * @param hi2c: I2C handle
387 * @param dev_addr: Specifies the slave address to be programmed
Yann Gautiere4f559f2018-07-16 17:55:07 +0200388 * @param size: Specifies the number of bytes to be programmed.
389 * This parameter must be a value between 0 and 255.
390 * @param i2c_mode: New state of the I2C START condition generation.
391 * This parameter can be one of the following values:
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100392 * @arg @ref I2C_RELOAD_MODE: Enable Reload mode.
Yann Gautiere4f559f2018-07-16 17:55:07 +0200393 * @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
394 * @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
395 * @param request: New state of the I2C START condition generation.
396 * This parameter can be one of the following values:
397 * @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
398 * @arg @ref I2C_GENERATE_STOP: Generate stop condition
399 * (size should be set to 0).
400 * @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
401 * @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
402 * @retval None
403 */
404static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
405 uint16_t size, uint32_t i2c_mode,
406 uint32_t request)
407{
408 uint32_t clr_value, set_value;
409
410 clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
411 I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
412 (I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
413
414 set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
415 (((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
416 i2c_mode | request;
417
418 mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
419}
420
421/*
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100422 * @brief Master sends target device address followed by internal memory
423 * address for write request.
Yann Gautiere4f559f2018-07-16 17:55:07 +0200424 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100425 * the configuration information for the specified I2C.
426 * @param dev_addr: Target device address
427 * @param mem_addr: Internal memory address
428 * @param mem_add_size: Size of internal memory address
429 * @param timeout_ref: Reference to target timeout
Yann Gautiere4f559f2018-07-16 17:55:07 +0200430 * @retval 0 if OK, negative value else
431 */
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100432static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
433 uint16_t dev_addr, uint16_t mem_addr,
434 uint16_t mem_add_size, uint64_t timeout_ref)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200435{
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100436 i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
437 I2C_GENERATE_START_WRITE);
438
439 if (i2c_wait_txis(hi2c, timeout_ref) != 0) {
440 return -EIO;
441 }
442
443 if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
444 /* Send Memory Address */
445 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
446 (uint8_t)(mem_addr & 0x00FFU));
447 } else {
448 /* Send MSB of Memory Address */
449 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
450 (uint8_t)((mem_addr & 0xFF00U) >> 8));
451
452 if (i2c_wait_txis(hi2c, timeout_ref) != 0) {
453 return -EIO;
454 }
455
456 /* Send LSB of Memory Address */
457 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
458 (uint8_t)(mem_addr & 0x00FFU));
459 }
460
461 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout_ref) != 0) {
462 return -EIO;
463 }
464
465 return 0;
466}
467
468/*
469 * @brief Master sends target device address followed by internal memory
470 * address for read request.
471 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
472 * the configuration information for the specified I2C.
473 * @param dev_addr: Target device address
474 * @param mem_addr: Internal memory address
475 * @param mem_add_size: Size of internal memory address
476 * @param timeout_ref: Reference to target timeout
477 * @retval 0 if OK, negative value else
478 */
479static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
480 uint16_t mem_addr, uint16_t mem_add_size,
481 uint64_t timeout_ref)
482{
483 i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
484 I2C_GENERATE_START_WRITE);
485
486 if (i2c_wait_txis(hi2c, timeout_ref) != 0) {
487 return -EIO;
488 }
489
490 if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
491 /* Send Memory Address */
492 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
493 (uint8_t)(mem_addr & 0x00FFU));
494 } else {
495 /* Send MSB of Memory Address */
496 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
497 (uint8_t)((mem_addr & 0xFF00U) >> 8));
498
499 if (i2c_wait_txis(hi2c, timeout_ref) != 0) {
500 return -EIO;
501 }
502
503 /* Send LSB of Memory Address */
504 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
505 (uint8_t)(mem_addr & 0x00FFU));
506 }
507
508 if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout_ref) != 0) {
509 return -EIO;
510 }
511
512 return 0;
513}
514/*
515 * @brief Generic function to write an amount of data in blocking mode
516 * (for Memory Mode and Master Mode)
517 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
518 * the configuration information for the specified I2C.
519 * @param dev_addr: Target device address
520 * @param mem_addr: Internal memory address (if Memory Mode)
521 * @param mem_add_size: Size of internal memory address (if Memory Mode)
522 * @param p_data: Pointer to data buffer
523 * @param size: Amount of data to be sent
524 * @param timeout_ms: Timeout duration in milliseconds
525 * @param mode: Communication mode
526 * @retval 0 if OK, negative value else
527 */
528static int i2c_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
529 uint16_t mem_addr, uint16_t mem_add_size,
530 uint8_t *p_data, uint16_t size, uint32_t timeout_ms,
531 enum i2c_mode_e mode)
532{
533 uint64_t timeout_ref;
534 int rc = -EIO;
535 uint8_t *p_buff = p_data;
536 uint32_t xfer_size;
537 uint32_t xfer_count = size;
538
539 if ((mode != I2C_MODE_MASTER) && (mode != I2C_MODE_MEM)) {
540 return -1;
541 }
542
Yann Gautiere4f559f2018-07-16 17:55:07 +0200543 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
544 return -EBUSY;
545 }
546
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100547 if ((p_data == NULL) || (size == 0U)) {
548 return -EINVAL;
549 }
550
551 stm32mp_clk_enable(hi2c->clock);
552
Yann Gautiere4f559f2018-07-16 17:55:07 +0200553 hi2c->lock = 1;
554
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100555 timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000);
556 if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, timeout_ref) != 0) {
557 goto bail;
558 }
Yann Gautiere4f559f2018-07-16 17:55:07 +0200559
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100560 hi2c->i2c_state = I2C_STATE_BUSY_TX;
561 hi2c->i2c_mode = mode;
562 hi2c->i2c_err = I2C_ERROR_NONE;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200563
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100564 timeout_ref = timeout_init_us(timeout_ms * 1000);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200565
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100566 if (mode == I2C_MODE_MEM) {
567 /* In Memory Mode, Send Slave Address and Memory Address */
568 if (i2c_request_memory_write(hi2c, dev_addr, mem_addr,
569 mem_add_size, timeout_ref) != 0) {
570 goto bail;
571 }
Yann Gautiere4f559f2018-07-16 17:55:07 +0200572
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100573 if (xfer_count > MAX_NBYTE_SIZE) {
574 xfer_size = MAX_NBYTE_SIZE;
575 i2c_transfer_config(hi2c, dev_addr, xfer_size,
576 I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
577 } else {
578 xfer_size = xfer_count;
579 i2c_transfer_config(hi2c, dev_addr, xfer_size,
580 I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
581 }
582 } else {
583 /* In Master Mode, Send Slave Address */
584 if (xfer_count > MAX_NBYTE_SIZE) {
585 xfer_size = MAX_NBYTE_SIZE;
586 i2c_transfer_config(hi2c, dev_addr, xfer_size,
587 I2C_RELOAD_MODE,
588 I2C_GENERATE_START_WRITE);
589 } else {
590 xfer_size = xfer_count;
591 i2c_transfer_config(hi2c, dev_addr, xfer_size,
592 I2C_AUTOEND_MODE,
593 I2C_GENERATE_START_WRITE);
594 }
595 }
596
597 do {
598 if (i2c_wait_txis(hi2c, timeout_ref) != 0) {
599 goto bail;
600 }
601
602 mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *p_buff);
603 p_buff++;
604 xfer_count--;
605 xfer_size--;
606
607 if ((xfer_count != 0U) && (xfer_size == 0U)) {
608 /* Wait until TCR flag is set */
609 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0,
610 timeout_ref) != 0) {
611 goto bail;
612 }
613
614 if (xfer_count > MAX_NBYTE_SIZE) {
615 xfer_size = MAX_NBYTE_SIZE;
616 i2c_transfer_config(hi2c, dev_addr,
617 xfer_size,
618 I2C_RELOAD_MODE,
619 I2C_NO_STARTSTOP);
620 } else {
621 xfer_size = xfer_count;
622 i2c_transfer_config(hi2c, dev_addr,
623 xfer_size,
624 I2C_AUTOEND_MODE,
625 I2C_NO_STARTSTOP);
626 }
627 }
628
629 } while (xfer_count > 0U);
630
631 /*
632 * No need to Check TC flag, with AUTOEND mode the stop
633 * is automatically generated.
634 * Wait until STOPF flag is reset.
635 */
636 if (i2c_wait_stop(hi2c, timeout_ref) != 0) {
637 goto bail;
638 }
639
640 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
641
642 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200643
644 hi2c->i2c_state = I2C_STATE_READY;
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100645 hi2c->i2c_mode = I2C_MODE_NONE;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200646
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100647 rc = 0;
648
649bail:
Yann Gautiere4f559f2018-07-16 17:55:07 +0200650 hi2c->lock = 0;
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100651 stm32mp_clk_disable(hi2c->clock);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200652
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100653 return rc;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200654}
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100655
656/*
657 * @brief Write an amount of data in blocking mode to a specific memory
658 * address.
659 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
660 * the configuration information for the specified I2C.
661 * @param dev_addr: Target device address
662 * @param mem_addr: Internal memory address
663 * @param mem_add_size: Size of internal memory address
664 * @param p_data: Pointer to data buffer
665 * @param size: Amount of data to be sent
666 * @param timeout_ms: Timeout duration in milliseconds
667 * @retval 0 if OK, negative value else
668 */
669int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
670 uint16_t mem_addr, uint16_t mem_add_size,
671 uint8_t *p_data, uint16_t size, uint32_t timeout_ms)
672{
673 return i2c_write(hi2c, dev_addr, mem_addr, mem_add_size,
674 p_data, size, timeout_ms, I2C_MODE_MEM);
675}
676
677/*
678 * @brief Transmits in master mode an amount of data in blocking mode.
679 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
680 * the configuration information for the specified I2C.
681 * @param dev_addr: Target device address
682 * @param p_data: Pointer to data buffer
683 * @param size: Amount of data to be sent
684 * @param timeout_ms: Timeout duration in milliseconds
685 * @retval 0 if OK, negative value else
686 */
687int stm32_i2c_master_transmit(struct i2c_handle_s *hi2c, uint16_t dev_addr,
688 uint8_t *p_data, uint16_t size,
689 uint32_t timeout_ms)
690{
691 return i2c_write(hi2c, dev_addr, 0, 0,
692 p_data, size, timeout_ms, I2C_MODE_MASTER);
693}
694
695/*
696 * @brief Generic function to read an amount of data in blocking mode
697 * (for Memory Mode and Master Mode)
698 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
699 * the configuration information for the specified I2C.
700 * @param dev_addr: Target device address
701 * @param mem_addr: Internal memory address (if Memory Mode)
702 * @param mem_add_size: Size of internal memory address (if Memory Mode)
703 * @param p_data: Pointer to data buffer
704 * @param size: Amount of data to be sent
705 * @param timeout_ms: Timeout duration in milliseconds
706 * @param mode: Communication mode
707 * @retval 0 if OK, negative value else
708 */
709static int i2c_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
710 uint16_t mem_addr, uint16_t mem_add_size,
711 uint8_t *p_data, uint16_t size, uint32_t timeout_ms,
712 enum i2c_mode_e mode)
713{
714 uint64_t timeout_ref;
715 int rc = -EIO;
716 uint8_t *p_buff = p_data;
717 uint32_t xfer_count = size;
718 uint32_t xfer_size;
719
720 if ((mode != I2C_MODE_MASTER) && (mode != I2C_MODE_MEM)) {
721 return -1;
722 }
723
724 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
725 return -EBUSY;
726 }
727
728 if ((p_data == NULL) || (size == 0U)) {
729 return -EINVAL;
730 }
731
732 stm32mp_clk_enable(hi2c->clock);
733
734 hi2c->lock = 1;
735
736 timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000);
737 if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, timeout_ref) != 0) {
738 goto bail;
739 }
740
741 hi2c->i2c_state = I2C_STATE_BUSY_RX;
742 hi2c->i2c_mode = mode;
743 hi2c->i2c_err = I2C_ERROR_NONE;
744
745 if (mode == I2C_MODE_MEM) {
746 /* Send Memory Address */
747 if (i2c_request_memory_read(hi2c, dev_addr, mem_addr,
748 mem_add_size, timeout_ref) != 0) {
749 goto bail;
750 }
751 }
752
753 /*
754 * Send Slave Address.
755 * Set NBYTES to write and reload if xfer_count > MAX_NBYTE_SIZE
756 * and generate RESTART.
757 */
758 if (xfer_count > MAX_NBYTE_SIZE) {
759 xfer_size = MAX_NBYTE_SIZE;
760 i2c_transfer_config(hi2c, dev_addr, xfer_size,
761 I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
762 } else {
763 xfer_size = xfer_count;
764 i2c_transfer_config(hi2c, dev_addr, xfer_size,
765 I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
766 }
767
768 do {
769 if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout_ref) != 0) {
770 goto bail;
771 }
772
773 *p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
774 p_buff++;
775 xfer_size--;
776 xfer_count--;
777
778 if ((xfer_count != 0U) && (xfer_size == 0U)) {
779 if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0,
780 timeout_ref) != 0) {
781 goto bail;
782 }
783
784 if (xfer_count > MAX_NBYTE_SIZE) {
785 xfer_size = MAX_NBYTE_SIZE;
786 i2c_transfer_config(hi2c, dev_addr,
787 xfer_size,
788 I2C_RELOAD_MODE,
789 I2C_NO_STARTSTOP);
790 } else {
791 xfer_size = xfer_count;
792 i2c_transfer_config(hi2c, dev_addr,
793 xfer_size,
794 I2C_AUTOEND_MODE,
795 I2C_NO_STARTSTOP);
796 }
797 }
798 } while (xfer_count > 0U);
799
800 /*
801 * No need to Check TC flag, with AUTOEND mode the stop
802 * is automatically generated.
803 * Wait until STOPF flag is reset.
804 */
805 if (i2c_wait_stop(hi2c, timeout_ref) != 0) {
806 goto bail;
807 }
808
809 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
810
811 mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
812
813 hi2c->i2c_state = I2C_STATE_READY;
814 hi2c->i2c_mode = I2C_MODE_NONE;
815
816 rc = 0;
817
818bail:
819 hi2c->lock = 0;
820 stm32mp_clk_disable(hi2c->clock);
821
822 return rc;
823}
824
825/*
826 * @brief Read an amount of data in blocking mode from a specific memory
827 * address.
828 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
829 * the configuration information for the specified I2C.
830 * @param dev_addr: Target device address
831 * @param mem_addr: Internal memory address
832 * @param mem_add_size: Size of internal memory address
833 * @param p_data: Pointer to data buffer
834 * @param size: Amount of data to be sent
835 * @param timeout_ms: Timeout duration in milliseconds
836 * @retval 0 if OK, negative value else
837 */
838int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
839 uint16_t mem_addr, uint16_t mem_add_size,
840 uint8_t *p_data, uint16_t size, uint32_t timeout_ms)
841{
842 return i2c_read(hi2c, dev_addr, mem_addr, mem_add_size,
843 p_data, size, timeout_ms, I2C_MODE_MEM);
844}
845
846/*
847 * @brief Receives in master mode an amount of data in blocking mode.
848 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
849 * the configuration information for the specified I2C.
850 * @param dev_addr: Target device address
851 * @param p_data: Pointer to data buffer
852 * @param size: Amount of data to be sent
853 * @param timeout_ms: Timeout duration in milliseconds
854 * @retval 0 if OK, negative value else
855 */
856int stm32_i2c_master_receive(struct i2c_handle_s *hi2c, uint16_t dev_addr,
857 uint8_t *p_data, uint16_t size,
858 uint32_t timeout_ms)
859{
860 return i2c_read(hi2c, dev_addr, 0, 0,
861 p_data, size, timeout_ms, I2C_MODE_MASTER);
862}
863
864/*
865 * @brief Checks if target device is ready for communication.
866 * @note This function is used with Memory devices
867 * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
868 * the configuration information for the specified I2C.
869 * @param dev_addr: Target device address
870 * @param trials: Number of trials
871 * @param timeout_ms: Timeout duration in milliseconds
872 * @retval True if device is ready, false else
873 */
874bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
875 uint16_t dev_addr, uint32_t trials,
876 uint32_t timeout_ms)
877{
878 uint32_t i2c_trials = 0U;
879 bool rc = false;
880
881 if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
882 return rc;
883 }
884
885 stm32mp_clk_enable(hi2c->clock);
886
887 hi2c->lock = 1;
888 hi2c->i2c_mode = I2C_MODE_NONE;
889
890 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
891 0U) {
892 goto bail;
893 }
894
895 hi2c->i2c_state = I2C_STATE_BUSY;
896 hi2c->i2c_err = I2C_ERROR_NONE;
897
898 do {
899 uint64_t timeout_ref;
900
901 /* Generate Start */
902 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_OAR1) &
903 I2C_OAR1_OA1MODE) == 0) {
904 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
905 (((uint32_t)dev_addr & I2C_CR2_SADD) |
906 I2C_CR2_START | I2C_CR2_AUTOEND) &
907 ~I2C_CR2_RD_WRN);
908 } else {
909 mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
910 (((uint32_t)dev_addr & I2C_CR2_SADD) |
911 I2C_CR2_START | I2C_CR2_ADD10) &
912 ~I2C_CR2_RD_WRN);
913 }
914
915 /*
916 * No need to Check TC flag, with AUTOEND mode the stop
917 * is automatically generated.
918 * Wait until STOPF flag is set or a NACK flag is set.
919 */
920 timeout_ref = timeout_init_us(timeout_ms * 1000);
921 do {
922 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
923 (I2C_FLAG_STOPF | I2C_FLAG_AF)) != 0U) {
924 break;
925 }
926
927 if (timeout_elapsed(timeout_ref)) {
928 notif_i2c_timeout(hi2c);
929 goto bail;
930 }
931 } while (true);
932
933 if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
934 I2C_FLAG_AF) == 0U) {
935 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0,
936 timeout_ref) != 0) {
937 goto bail;
938 }
939
940 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
941 I2C_FLAG_STOPF);
942
943 hi2c->i2c_state = I2C_STATE_READY;
944
945 rc = true;
946 goto bail;
947 }
948
949 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout_ref) != 0) {
950 goto bail;
951 }
952
953 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
954
955 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
956
957 if (i2c_trials == trials) {
958 mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
959 I2C_CR2_STOP);
960
961 if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0,
962 timeout_ref) != 0) {
963 goto bail;
964 }
965
966 mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
967 I2C_FLAG_STOPF);
968 }
969
970 i2c_trials++;
971 } while (i2c_trials < trials);
972
973 notif_i2c_timeout(hi2c);
974
975bail:
976 hi2c->lock = 0;
977 stm32mp_clk_disable(hi2c->clock);
978
979 return rc;
980}
981