1 /* Copyright (C) 2024 BeagleBoard.org Foundation
2 * Copyright (C) 2024 Dhruv Menon <dhruvmenon1104@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT ti_omap_i2c
8 #include <errno.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/device.h>
11 #include <zephyr/devicetree.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/irq.h>
14 #include <zephyr/drivers/i2c.h>
15 #include <zephyr/drivers/pinctrl.h>
16
17 #ifdef CONFIG_I2C_OMAP_BUS_RECOVERY
18 #include "i2c_bitbang.h"
19 #endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */
20
21 LOG_MODULE_REGISTER(omap_i2c, CONFIG_I2C_LOG_LEVEL);
22
23 #define I2C_OMAP_TIMEOUT 100U
24 /* OCP_SYSSTATUS bit definitions */
25 #define SYSS_RESETDONE_MASK BIT(0)
26 #define RETRY -1
27 #define I2C_BITRATE_FAST 400000
28 #define I2C_BITRATE_STANDARD 100000
29
30 /* I2C Registers */
31 typedef struct {
32 uint8_t RESERVED_0[0x10]; /**< Reserved, offset: 0x0 */
33
34 __IO uint32_t SYSC; /**< System Configuration, offset: 0x10 */
35 uint8_t RESERVED_1[0x18]; /**< Reserved, offset: 0x14 - 0x2C */
36 __IO uint32_t IRQENABLE_SET; /**< Interrupt Enable Set, offset: 0x2C */
37 uint8_t RESERVED_2[0x4]; /**< Reserved, offset: 0x30 - 0x34 */
38 __IO uint32_t WE; /**< Wakeup Enable, offset: 0x34 */
39 uint8_t RESERVED_3[0x4C]; /**< Reserved, offset: 0x38 - 0x84 */
40 __IO uint32_t IE; /**< Interrupt Enable (Legacy), offset: 0x84 */
41 __IO uint32_t STAT; /**< Status, offset: 0x88 */
42 uint8_t RESERVED_4[0x4]; /**< Reserved, offset: 0x8C - 0x90 */
43 __IO uint32_t SYSS; /**< System Status, offset: 0x90 */
44 __IO uint32_t BUF; /**< Buffer, offset: 0x94 */
45 __IO uint32_t CNT; /**< Data Count, offset: 0x98 */
46 __IO uint32_t DATA; /**< Data Access, offset: 0x9C */
47 uint8_t RESERVED_5[0x4]; /**< Reserved, offset: 0xA0 - 0xA4 */
48 __IO uint32_t CON; /**< Configuration, offset: 0xA4 */
49 __IO uint32_t OA; /**< Own Address, offset: 0xA8 */
50 __IO uint32_t SA; /**< Target Address, offset: 0xAC */
51 __IO uint32_t PSC; /**< Clock Prescaler, offset: 0xB0 */
52 __IO uint32_t SCLL; /**< SCL Low Time, offset: 0xB4 */
53 __IO uint32_t SCLH; /**< SCL High Time, offset: 0xB8 */
54 __IO uint32_t SYSTEST; /**< System Test, offset: 0xBC */
55 __IO uint32_t BUFSTAT; /**< Buffer Status, offset: 0xC0 */
56 } i2c_omap_regs_t;
57
58 /* I2C Configuration Register (I2C_OMAP_CON) */
59 #define I2C_OMAP_CON_EN BIT(15) /* I2C module enable */
60 #define I2C_OMAP_CON_OPMODE_HS BIT(12) /* High Speed support */
61 #define I2C_OMAP_CON_MST BIT(10) /* Controller/target mode */
62 #define I2C_OMAP_CON_TRX BIT(9) /* TX/RX mode (controller only) */
63 #define I2C_OMAP_CON_STP BIT(1) /* Stop condition (controller only) */
64 #define I2C_OMAP_CON_STT BIT(0) /* Start condition (controller) */
65
66 /* I2C Buffer Configuration Register (I2C_OMAP_BUF): */
67 #define I2C_OMAP_BUF_RXFIF_CLR BIT(14) /* RX FIFO Clear */
68 #define I2C_OMAP_BUF_TXFIF_CLR BIT(6) /* TX FIFO Clear */
69
70 /* I2C Status Register (I2C_OMAP_STAT): */
71 #define I2C_OMAP_STAT_XDR BIT(14) /* TX Buffer draining */
72 #define I2C_OMAP_STAT_RDR BIT(13) /* RX Buffer draining */
73 #define I2C_OMAP_STAT_BB BIT(12) /* Bus busy */
74 #define I2C_OMAP_STAT_ROVR BIT(11) /* Receive overrun */
75 #define I2C_OMAP_STAT_XUDF BIT(10) /* Transmit underflow */
76 #define I2C_OMAP_STAT_AAS BIT(9) /* Address as target */
77 #define I2C_OMAP_STAT_XRDY BIT(4) /* Transmit data ready */
78 #define I2C_OMAP_STAT_RRDY BIT(3) /* Receive data ready */
79 #define I2C_OMAP_STAT_ARDY BIT(2) /* Register access ready */
80 #define I2C_OMAP_STAT_NACK BIT(1) /* No ack interrupt enable */
81 #define I2C_OMAP_STAT_AL BIT(0) /* Arbitration lost */
82
83 /* I2C System Test Register (I2C_OMAP_SYSTEST): */
84 #define I2C_OMAP_SYSTEST_ST_EN BIT(15) /* System test enable */
85 #define I2C_OMAP_SYSTEST_FREE BIT(14) /* Free running mode */
86 #define I2C_OMAP_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select mask */
87 #define I2C_OMAP_SYSTEST_TMODE_SHIFT (12) /* Test mode select shift */
88
89 /* Functional mode */
90 #define I2C_OMAP_SYSTEST_SCL_I_FUNC BIT(8) /* SCL line input value */
91 #define I2C_OMAP_SYSTEST_SDA_I_FUNC BIT(6) /* SDA line input value */
92
93 /* SDA/SCL IO mode */
94 #define I2C_OMAP_SYSTEST_SCL_I BIT(3) /* SCL line sense in */
95 #define I2C_OMAP_SYSTEST_SCL_O BIT(2) /* SCL line drive out */
96 #define I2C_OMAP_SYSTEST_SDA_I BIT(1) /* SDA line sense in */
97 #define I2C_OMAP_SYSTEST_SDA_O BIT(0) /* SDA line drive out */
98
99 typedef void (*init_func_t)(const struct device *dev);
100 #define DEV_CFG(dev) ((const struct i2c_omap_cfg *)(dev)->config)
101 #define DEV_DATA(dev) ((struct i2c_omap_data *)(dev)->data)
102 #define DEV_I2C_BASE(dev) ((i2c_omap_regs_t *)DEVICE_MMIO_NAMED_GET(dev, base))
103
104 struct i2c_omap_cfg {
105 DEVICE_MMIO_NAMED_ROM(base);
106 uint32_t irq;
107 uint32_t speed;
108 const struct pinctrl_dev_config *pcfg;
109 };
110
111 enum i2c_omap_speed {
112 I2C_OMAP_SPEED_STANDARD,
113 I2C_OMAP_SPEED_FAST,
114 I2C_OMAP_SPEED_FAST_PLUS,
115 };
116
117 struct i2c_omap_speed_config {
118 uint32_t pscstate;
119 uint32_t scllstate;
120 uint32_t sclhstate;
121 };
122
123 struct i2c_omap_data {
124 DEVICE_MMIO_NAMED_RAM(base);
125 enum i2c_omap_speed speed;
126 struct i2c_omap_speed_config speed_config;
127 struct i2c_msg current_msg;
128 struct k_sem lock;
129 bool receiver;
130 bool bb_valid;
131 };
132
133 /**
134 * @brief Initializes the OMAP I2C driver.
135 *
136 * This function is responsible for initializing the OMAP I2C driver.
137 *
138 * @param dev Pointer to the device structure for the I2C driver instance.
139 */
i2c_omap_init_ll(const struct device * dev)140 static void i2c_omap_init_ll(const struct device *dev)
141 {
142
143 struct i2c_omap_data *data = DEV_DATA(dev);
144 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
145
146 i2c_base_addr->CON = 0;
147 i2c_base_addr->PSC = data->speed_config.pscstate;
148 i2c_base_addr->SCLL = data->speed_config.scllstate;
149 i2c_base_addr->SCLH = data->speed_config.sclhstate;
150 i2c_base_addr->CON = I2C_OMAP_CON_EN;
151 }
152
153 /**
154 * @brief Reset the OMAP I2C controller.
155 *
156 * This function resets the OMAP I2C controller specified by the device pointer.
157 *
158 * @param dev Pointer to the device structure for the I2C controller.
159 * @return 0 on success, negative errno code on failure.
160 */
i2c_omap_reset(const struct device * dev)161 static int i2c_omap_reset(const struct device *dev)
162 {
163 struct i2c_omap_data *data = DEV_DATA(dev);
164 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
165 uint64_t timeout;
166 uint16_t sysc;
167
168 sysc = i2c_base_addr->SYSC;
169 i2c_base_addr->CON &= ~I2C_OMAP_CON_EN;
170 timeout = k_uptime_get() + I2C_OMAP_TIMEOUT;
171 i2c_base_addr->CON = I2C_OMAP_CON_EN;
172 while (!(i2c_base_addr->SYSS & SYSS_RESETDONE_MASK)) {
173 if (k_uptime_get() > timeout) {
174 LOG_WRN("timeout waiting for controller reset");
175 return -ETIMEDOUT;
176 }
177 k_busy_wait(100);
178 }
179 i2c_base_addr->SYSC = sysc;
180 data->bb_valid = 0;
181 return 0;
182 }
183
184 /**
185 * @brief Set the speed of the OMAP I2C controller.
186 *
187 * This function sets the speed of the OMAP I2C controller based on the
188 * specified speed parameter. The speed can be set to either Fast mode or
189 * Standard mode.
190 *
191 * @param dev The pointer to the device structure.
192 * @param speed The desired speed for the I2C controller.
193 *
194 * @return 0 on success, negative error code on failure.
195 */
i2c_omap_set_speed(const struct device * dev,uint32_t speed)196 static int i2c_omap_set_speed(const struct device *dev, uint32_t speed)
197 {
198 struct i2c_omap_data *data = DEV_DATA(dev);
199
200 /* If configured for High Speed */
201 switch (speed) {
202 case I2C_BITRATE_FAST:
203 /* Fast mode */
204 data->speed_config = (struct i2c_omap_speed_config){
205 .pscstate = 9,
206 .scllstate = 7,
207 .sclhstate = 5,
208 };
209 break;
210 case I2C_BITRATE_STANDARD:
211 /* Standard mode */
212 data->speed_config = (struct i2c_omap_speed_config){
213 .pscstate = 23,
214 .scllstate = 13,
215 .sclhstate = 15,
216 };
217 break;
218 default:
219 return -ERANGE;
220 }
221
222 return 0;
223 }
224
225 /**
226 * @brief Configure the OMAP I2C controller with the specified device configuration.
227 *
228 * This function configures the OMAP I2C controller with the specified device configuration.
229 *
230 * @param dev The pointer to the device structure.
231 * @param dev_config The device configuration to be applied.
232 *
233 * @return 0 on success, negative error code on failure.
234 */
i2c_omap_configure(const struct device * dev,uint32_t dev_config)235 static int i2c_omap_configure(const struct device *dev, uint32_t dev_config)
236 {
237 uint32_t speed_cfg = I2C_BITRATE_STANDARD;
238 struct i2c_omap_data *data = DEV_DATA(dev);
239
240 switch (I2C_SPEED_GET(dev_config)) {
241 case I2C_SPEED_STANDARD:
242 speed_cfg = I2C_BITRATE_STANDARD;
243 break;
244 case I2C_SPEED_FAST:
245 speed_cfg = I2C_BITRATE_FAST;
246 break;
247 default:
248 return -ENOTSUP;
249 }
250 if ((dev_config & I2C_MODE_CONTROLLER) != I2C_MODE_CONTROLLER) {
251 return -ENOTSUP;
252 }
253 k_sem_take(&data->lock, K_FOREVER);
254 i2c_omap_set_speed(dev, speed_cfg);
255 i2c_omap_init_ll(dev);
256 k_sem_give(&data->lock);
257 return 0;
258 }
259
260 /**
261 * @brief Transmit or receive data over I2C bus
262 *
263 * This function transmits or receives data over the I2C bus using the OMAP I2C controller.
264 *
265 * @param dev Pointer to the I2C device structure
266 * @param num_bytes Number of bytes to transmit or receive
267 */
i2c_omap_transmit_receive_data(const struct device * dev,uint8_t num_bytes)268 static void i2c_omap_transmit_receive_data(const struct device *dev, uint8_t num_bytes)
269 {
270 struct i2c_omap_data *data = DEV_DATA(dev);
271 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
272 uint8_t *buf_ptr = data->current_msg.buf;
273
274 while (num_bytes--) {
275 if (data->receiver) {
276 *buf_ptr++ = i2c_base_addr->DATA;
277 } else {
278 i2c_base_addr->DATA = *(buf_ptr++);
279 }
280 }
281 }
282
283 /**
284 * @brief Resize the FIFO buffer for the OMAP I2C controller.
285 *
286 * This function resizes the FIFO buffer for the OMAP I2C controller based on the specified size.
287 * It clears the RX threshold and sets the new size for the receiver, or clears the TX threshold
288 * and sets the new size for the transmitter.
289 *
290 * @param dev Pointer to the device structure.
291 * @param size The new size of the FIFO buffer.
292 */
i2c_omap_resize_fifo(const struct device * dev,uint8_t size)293 static void i2c_omap_resize_fifo(const struct device *dev, uint8_t size)
294 {
295 struct i2c_omap_data *data = DEV_DATA(dev);
296 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
297
298 if (data->receiver) {
299 i2c_base_addr->BUF &= I2C_OMAP_BUF_RXFIF_CLR;
300 i2c_base_addr->BUF |= ((size) << 8) | I2C_OMAP_BUF_RXFIF_CLR;
301 } else {
302 i2c_base_addr->BUF &= I2C_OMAP_BUF_TXFIF_CLR;
303 i2c_base_addr->BUF |= (size) | I2C_OMAP_BUF_TXFIF_CLR;
304 }
305 }
306
307 #ifdef CONFIG_I2C_OMAP_BUS_RECOVERY
308 /**
309 * @brief Get the state of the SDA line.
310 *
311 * This function retrieves the state of the SDA (data) line for the OMAP I2C controller.
312 *
313 * @param io_context The I2C context.
314 * @return The state of the SDA line.
315 */
i2c_omap_get_sda(void * io_context)316 static int i2c_omap_get_sda(void *io_context)
317 {
318 const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context;
319 i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr;
320
321 return (i2c_base_addr->SYSTEST & I2C_OMAP_SYSTEST_SDA_I_FUNC) ? 1 : 0;
322 }
323
324 /**
325 * @brief Set the state of the SDA line.
326 *
327 * This function sets the state of the SDA (data) line for the OMAP I2C controller.
328 *
329 * @param io_context The I2C context.
330 * @param state The state to set (0 for low, 1 for high).
331 */
i2c_omap_set_sda(void * io_context,int state)332 static void i2c_omap_set_sda(void *io_context, int state)
333 {
334 const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context;
335 i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr;
336
337 if (state) {
338 i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_SDA_O;
339 } else {
340 i2c_base_addr->SYSTEST &= ~I2C_OMAP_SYSTEST_SDA_O;
341 }
342 }
343
344 /**
345 * @brief Set the state of the SCL line.
346 *
347 * This function sets the state of the SCL (clock) line for the OMAP I2C controller.
348 *
349 * @param io_context The I2C context.
350 * @param state The state to set (0 for low, 1 for high).
351 */
i2c_omap_set_scl(void * io_context,int state)352 static void i2c_omap_set_scl(void *io_context, int state)
353 {
354 const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context;
355 i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr;
356
357 if (state) {
358 i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_SCL_O;
359 } else {
360 i2c_base_addr->SYSTEST &= ~I2C_OMAP_SYSTEST_SCL_O;
361 }
362 }
363 /**
364 * @brief Recovers the I2C bus using the OMAP I2C controller.
365 *
366 * This function attempts to recover the I2C bus by performing a bus recovery
367 * sequence using the OMAP I2C controller. It uses the provided device
368 * configuration and bit-banging operations to recover the bus.
369 *
370 * @param dev Pointer to the device structure.
371 * @return 0 on success, negative error code on failure.
372 */
373
i2c_omap_recover_bus(const struct device * dev)374 static int i2c_omap_recover_bus(const struct device *dev)
375 {
376 const struct i2c_omap_cfg *cfg = DEV_CFG(dev);
377 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
378 struct i2c_omap_data *data = DEV_DATA(dev);
379
380 struct i2c_bitbang bitbang_omap;
381 struct i2c_bitbang_io bitbang_omap_io = {
382 .get_sda = i2c_omap_get_sda,
383 .set_scl = i2c_omap_set_scl,
384 .set_sda = i2c_omap_set_sda,
385 };
386 int error = 0;
387
388 k_sem_take(&data->lock, K_FOREVER);
389 i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_ST_EN | (3 << I2C_OMAP_SYSTEST_TMODE_SHIFT) |
390 I2C_OMAP_SYSTEST_SCL_O | I2C_OMAP_SYSTEST_SDA_O;
391 i2c_bitbang_init(&bitbang_omap, &bitbang_omap_io, (void *)cfg);
392 error = i2c_bitbang_recover_bus(&bitbang_omap);
393 if (error != 0) {
394 LOG_ERR("failed to recover bus (err %d)", error);
395 goto restore;
396 }
397
398 restore:
399 i2c_base_addr->SYSTEST &= ~(I2C_OMAP_SYSTEST_ST_EN | I2C_OMAP_SYSTEST_TMODE_MASK |
400 I2C_OMAP_SYSTEST_SCL_O | I2C_OMAP_SYSTEST_SDA_O);
401 i2c_omap_reset(dev);
402 k_sem_give(&data->lock);
403 return error;
404 }
405 #endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */
406
407 /**
408 * @brief Wait for the bus to become free (no longer busy).
409 *
410 * This function waits for the bus to become free by continuously checking the
411 * status register of the OMAP I2C controller. If the bus remains busy for a
412 * certain timeout period, the function will return attempts to recover the bus by calling
413 * i2c_omap_recover_bus().
414 *
415 * @param dev The I2C device structure.
416 * @return 0 if the bus becomes free, or a negative error code if the bus cannot
417 * be recovered.
418 */
i2c_omap_wait_for_bb(const struct device * dev)419 static int i2c_omap_wait_for_bb(const struct device *dev)
420 {
421 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
422 uint32_t timeout = k_uptime_get_32() + I2C_OMAP_TIMEOUT;
423
424 while (i2c_base_addr->STAT & I2C_OMAP_STAT_BB) {
425 if (k_uptime_get_32() > timeout) {
426 LOG_ERR("Bus busy timeout");
427 #ifdef CONFIG_I2C_OMAP_BUS_RECOVERY
428 return i2c_omap_recover_bus(dev);
429 #else
430 return -ETIMEDOUT;
431 #endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */
432 }
433 k_busy_wait(100);
434 }
435 return 0;
436 }
437
438 /**
439 * @brief Performs data transfer for the OMAP I2C driver.
440 *
441 * This function is responsible for handling the data transfer logic for the OMAP I2C driver.
442 * It reads the status register and performs the necessary actions based on the status flags.
443 * It handles both receive and transmit logic, and also handles error conditions such as NACK,
444 * arbitration lost, receive overrun, and transmit underflow.
445 *
446 * @param dev Pointer to the device structure.
447 *
448 * @return Returns 0 on success, or a negative error code on failure.
449 */
i2c_omap_transfer_message_ll(const struct device * dev)450 static int i2c_omap_transfer_message_ll(const struct device *dev)
451 {
452 struct i2c_omap_data *data = DEV_DATA(dev);
453 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
454 uint16_t stat = i2c_base_addr->STAT, result = 0;
455
456 if (data->receiver) {
457 stat &= ~(I2C_OMAP_STAT_XDR | I2C_OMAP_STAT_XRDY);
458 } else {
459 stat &= ~(I2C_OMAP_STAT_RDR | I2C_OMAP_STAT_RRDY);
460 }
461 if (stat & I2C_OMAP_STAT_NACK) {
462 result |= I2C_OMAP_STAT_NACK;
463 i2c_base_addr->STAT |= I2C_OMAP_STAT_NACK;
464 }
465 if (stat & I2C_OMAP_STAT_AL) {
466 result |= I2C_OMAP_STAT_AL;
467 i2c_base_addr->STAT |= I2C_OMAP_STAT_AL;
468 }
469 if (stat & I2C_OMAP_STAT_ARDY) {
470 i2c_base_addr->STAT |= I2C_OMAP_STAT_ARDY;
471 }
472 if (stat & (I2C_OMAP_STAT_ARDY | I2C_OMAP_STAT_NACK | I2C_OMAP_STAT_AL)) {
473
474 i2c_base_addr->STAT |=
475 (I2C_OMAP_STAT_RRDY | I2C_OMAP_STAT_RDR | I2C_OMAP_STAT_XRDY |
476 I2C_OMAP_STAT_XDR | I2C_OMAP_STAT_ARDY);
477 return result;
478 }
479
480 /* Handle receive logic */
481 if (stat & (I2C_OMAP_STAT_RRDY | I2C_OMAP_STAT_RDR)) {
482 int buffer =
483 (stat & I2C_OMAP_STAT_RRDY) ? i2c_base_addr->BUF : i2c_base_addr->BUFSTAT;
484 i2c_omap_transmit_receive_data(dev, buffer);
485 i2c_base_addr->STAT |=
486 (stat & I2C_OMAP_STAT_RRDY) ? I2C_OMAP_STAT_RRDY : I2C_OMAP_STAT_RDR;
487 return RETRY;
488 }
489
490 /* Handle transmit logic */
491 if (stat & (I2C_OMAP_STAT_XRDY | I2C_OMAP_STAT_XDR)) {
492 int buffer =
493 (stat & I2C_OMAP_STAT_XRDY) ? i2c_base_addr->BUF : i2c_base_addr->BUFSTAT;
494 i2c_omap_transmit_receive_data(dev, buffer);
495 i2c_base_addr->STAT |=
496 (stat & I2C_OMAP_STAT_XRDY) ? I2C_OMAP_STAT_XRDY : I2C_OMAP_STAT_XDR;
497 return RETRY;
498 }
499
500 if (stat & I2C_OMAP_STAT_ROVR) {
501 i2c_base_addr->STAT |= I2C_OMAP_STAT_ROVR;
502 return I2C_OMAP_STAT_ROVR;
503 }
504 if (stat & I2C_OMAP_STAT_XUDF) {
505 i2c_base_addr->STAT |= I2C_OMAP_STAT_XUDF;
506 return I2C_OMAP_STAT_XUDF;
507 }
508 return RETRY;
509 }
510
511 /**
512 * @brief Performs an I2C transfer of a single message.
513 *
514 * This function is responsible for performing an I2C transfer of a single message.
515 * It sets up the necessary configurations, writes the target device address,
516 * sets the buffer and buffer length, and handles various error conditions.
517 *
518 * @param dev The I2C device structure.
519 * @param msg Pointer to the I2C message structure.
520 * @param polling Flag indicating whether to use polling mode or not.
521 * @param addr The target device address.
522 *
523 * @return 0 on success, negative error code on failure.
524 * Possible error codes include:
525 * - ETIMEDOUT: Timeout occurred during the transfer.
526 * - EIO: I/O error due to receiver overrun or transmit underflow.
527 * - EAGAIN: Arbitration lost error, try again.
528 * - ENOMSG: Message error due to NACK.
529 */
i2c_omap_transfer_message(const struct device * dev,struct i2c_msg * msg,bool polling,uint16_t addr)530 static int i2c_omap_transfer_message(const struct device *dev, struct i2c_msg *msg, bool polling,
531 uint16_t addr)
532 {
533 struct i2c_omap_data *data = DEV_DATA(dev);
534 i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev);
535 unsigned long time_left = 1000;
536 uint16_t control_reg;
537 int result = 0;
538 /* Determine message direction (read or write) and update the receiver flag */
539 data->receiver = msg->flags & I2C_MSG_READ;
540 /* Adjust the FIFO size according to the message length */
541 i2c_omap_resize_fifo(dev, msg->len);
542 /* Set the target I2C address for the transfer */
543 i2c_base_addr->SA = addr;
544 /* Store the message in the data structure */
545 data->current_msg = *msg;
546 /* Set the message length in the I2C controller */
547 i2c_base_addr->CNT = msg->len;
548 /* Clear FIFO buffers */
549 control_reg = i2c_base_addr->BUF;
550 control_reg |= I2C_OMAP_BUF_RXFIF_CLR | I2C_OMAP_BUF_TXFIF_CLR;
551 i2c_base_addr->BUF = control_reg;
552 /* If we're not polling, reset the command completion semaphore */
553 if (!polling) {
554 k_sem_reset(&data->lock);
555 }
556 /* Reset the command error status */
557 /* Prepare the control register for the I2C operation */
558 control_reg = I2C_OMAP_CON_EN | I2C_OMAP_CON_MST | I2C_OMAP_CON_STT;
559 /* Enable high-speed mode if required by the transfer speed */
560 if (data->speed > I2C_BITRATE_FAST) {
561 control_reg |= I2C_OMAP_CON_OPMODE_HS;
562 }
563 /* Set the STOP condition if it's specified in the message flags */
564 if (msg->flags & I2C_MSG_STOP) {
565 control_reg |= I2C_OMAP_CON_STP;
566 }
567 /* Set the transmission mode based on whether it's a read or write operation */
568 if (!(msg->flags & I2C_MSG_READ)) {
569 control_reg |= I2C_OMAP_CON_TRX;
570 }
571 /* Start the I2C transfer by writing the control register */
572 i2c_base_addr->CON = control_reg;
573 /* Poll for status until the transfer is complete */
574 /* Call a lower-level function to continue the transfer */
575 do {
576 result = i2c_omap_transfer_message_ll(dev);
577 time_left--;
578 } while (result == RETRY && time_left);
579
580 /* If no errors occurred, return success */
581 if (!result) {
582 return 0;
583 }
584
585 /* Handle timeout or specific error conditions */
586 if (result & (I2C_OMAP_STAT_ROVR | I2C_OMAP_STAT_XUDF)) {
587 i2c_omap_reset(dev);
588 i2c_omap_init_ll(dev);
589 /* Return an error code based on whether it was a timeout or buffer error */
590 return -EIO; /* Receiver overrun or transmitter underflow */
591 }
592 /* Handle arbitration loss and NACK errors */
593 if (result & (I2C_OMAP_STAT_AL | -EAGAIN)) {
594 return -EAGAIN;
595 }
596 if (result & I2C_OMAP_STAT_NACK) {
597 /* Issue a STOP condition after NACK */
598 i2c_base_addr->CON |= I2C_OMAP_CON_STP;
599 return -ENOMSG; /* Indicate a message error due to NACK */
600 }
601
602 /* Return a general I/O error if no specific error conditions matched */
603 return -EIO;
604 }
605
606 /**
607 * @brief Performs a common transfer operation for OMAP I2C devices.
608 *
609 * This function is responsible for transferring multiple I2C messages in a common way
610 * for OMAP I2C devices. It waits for the bus to be idle, then iterates through each
611 * message in the provided array and transfers them one by one using the i2c_omap_transfer_message()
612 * function. After all messages have been transferred, it waits for the bus to be idle again
613 * before returning.
614 *
615 * @param dev The pointer to the I2C device structure.
616 * @param msg An array of I2C messages to be transferred.
617 * @param num The number of messages in the array.
618 * @param polling Specifies whether to use polling or interrupt-based transfer.
619 * @param addr The I2C target address.
620 * @return 0 on success, or a negative error code on failure.
621 */
i2c_omap_transfer_main(const struct device * dev,struct i2c_msg msg[],int num,bool polling,uint16_t addr)622 static int i2c_omap_transfer_main(const struct device *dev, struct i2c_msg msg[], int num,
623 bool polling, uint16_t addr)
624 {
625 int ret;
626
627 ret = i2c_omap_wait_for_bb(dev);
628 struct i2c_omap_data *data = DEV_DATA(dev);
629
630 k_sem_take(&data->lock, K_FOREVER);
631 if (ret < 0) {
632 return ret;
633 }
634 for (int msg_idx = 0; msg_idx < num; msg_idx++) {
635 ret = i2c_omap_transfer_message(dev, &msg[msg_idx], polling, addr);
636 if (ret < 0) {
637 break;
638 }
639 }
640 k_sem_give(&data->lock);
641 i2c_omap_wait_for_bb(dev);
642 return ret;
643 }
644
645 /**
646 * @brief OMAP I2C transfer function using polling.
647 *
648 * This function performs the I2C transfer using the OMAP I2C controller
649 * in polling mode. It calls the common transfer function with the
650 * specified messages, number of messages, and target address.
651 *
652 * @param dev Pointer to the I2C device structure.
653 * @param msgs Array of I2C messages to be transferred.
654 * @param num_msgs Number of I2C messages in the array.
655 * @param addr Target address.
656 * @return 0 on success, negative error code on failure.
657 */
i2c_omap_transfer_polling(const struct device * dev,struct i2c_msg msgs[],uint8_t num_msgs,uint16_t addr)658 static int i2c_omap_transfer_polling(const struct device *dev, struct i2c_msg msgs[],
659 uint8_t num_msgs, uint16_t addr)
660 {
661 return i2c_omap_transfer_main(dev, msgs, num_msgs, true, addr);
662 }
663
664 static DEVICE_API(i2c, i2c_omap_api) = {
665 .transfer = i2c_omap_transfer_polling,
666 .configure = i2c_omap_configure,
667 #ifdef CONFIG_I2C_OMAP_BUS_RECOVERY
668 .recover_bus = i2c_omap_recover_bus,
669 #endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */
670 };
671
672 /**
673 * @brief Initialize the OMAP I2C controller.
674 *
675 * This function initializes the OMAP I2C controller by setting the speed and
676 * performing any necessary initialization steps.
677 *
678 * @param dev Pointer to the device structure for the I2C controller.
679 * @return 0 if successful, negative error code otherwise.
680 */
i2c_omap_init(const struct device * dev)681 static int i2c_omap_init(const struct device *dev)
682 {
683 struct i2c_omap_data *data = DEV_DATA(dev);
684 const struct i2c_omap_cfg *cfg = DEV_CFG(dev);
685 int ret;
686
687 ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
688 if (ret < 0) {
689 LOG_ERR("failed to apply pinctrl");
690 return ret;
691 }
692
693 k_sem_init(&data->lock, 1, 1);
694 /* Set the speed for I2C */
695 if (i2c_omap_set_speed(dev, cfg->speed)) {
696 LOG_ERR("Failed to set speed");
697 return -ENOTSUP;
698 }
699 i2c_omap_init_ll(dev);
700 return 0;
701 }
702
703 #define I2C_OMAP_INIT(inst) \
704 PINCTRL_DT_INST_DEFINE(inst); \
705 LOG_INSTANCE_REGISTER(omap_i2c, inst, CONFIG_I2C_LOG_LEVEL); \
706 static const struct i2c_omap_cfg i2c_omap_cfg_##inst = { \
707 DEVICE_MMIO_NAMED_ROM_INIT(base, DT_DRV_INST(inst)), \
708 .irq = DT_INST_IRQN(inst), \
709 .speed = DT_INST_PROP(inst, clock_frequency), \
710 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
711 }; \
712 \
713 static struct i2c_omap_data i2c_omap_data_##inst; \
714 \
715 I2C_DEVICE_DT_INST_DEFINE(inst, \
716 i2c_omap_init, \
717 NULL, \
718 &i2c_omap_data_##inst, \
719 &i2c_omap_cfg_##inst, \
720 POST_KERNEL, \
721 CONFIG_I2C_INIT_PRIORITY, \
722 &i2c_omap_api);
723
724 DT_INST_FOREACH_STATUS_OKAY(I2C_OMAP_INIT)
725