@@ -16,6 +16,11 @@ LOG_MODULE_REGISTER(i2c_litex_litei2c, CONFIG_I2C_LOG_LEVEL);
16
16
17
17
#include <soc.h>
18
18
19
+ #define I2C_LITEX_ANY_HAS_IRQ DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts)
20
+ #define I2C_LITEX_ALL_HAS_IRQ DT_ALL_INST_HAS_PROP_STATUS_OKAY(interrupts)
21
+
22
+ #define I2C_LITEX_HAS_IRQ UTIL_OR(I2C_LITEX_ALL_HAS_IRQ, config->has_irq)
23
+
19
24
#define MASTER_STATUS_TX_READY_OFFSET 0x0
20
25
#define MASTER_STATUS_RX_READY_OFFSET 0x1
21
26
#define MASTER_STATUS_NACK_OFFSET 0x8
@@ -28,10 +33,21 @@ struct i2c_litex_litei2c_config {
28
33
uint32_t master_rxtx_addr ;
29
34
uint32_t master_status_addr ;
30
35
uint32_t bitrate ;
36
+ #if I2C_LITEX_ANY_HAS_IRQ
37
+ uint32_t master_ev_pending_addr ;
38
+ uint32_t master_ev_enable_addr ;
39
+ void (* irq_config_func )(const struct device * dev );
40
+ #if !I2C_LITEX_ALL_HAS_IRQ
41
+ bool has_irq ;
42
+ #endif /* !I2C_LITEX_ALL_HAS_IRQ */
43
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
31
44
};
32
45
33
46
struct i2c_litex_litei2c_data {
34
47
struct k_mutex mutex ;
48
+ #if I2C_LITEX_ANY_HAS_IRQ
49
+ struct k_sem sem_rx_ready ;
50
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
35
51
};
36
52
37
53
static int i2c_litex_configure (const struct device * dev , uint32_t dev_config )
@@ -105,6 +121,26 @@ static int i2c_litex_write_settings(const struct device *dev, uint8_t len_tx, ui
105
121
return 0 ;
106
122
}
107
123
124
+ static void i2c_litex_wait_for_rx_ready (const struct device * dev )
125
+ {
126
+ const struct i2c_litex_litei2c_config * config = dev -> config ;
127
+
128
+ #if I2C_LITEX_ANY_HAS_IRQ
129
+ struct i2c_litex_litei2c_data * data = dev -> data ;
130
+
131
+ if (I2C_LITEX_HAS_IRQ ) {
132
+ /* Wait for the RX ready event */
133
+ k_sem_take (& data -> sem_rx_ready , K_FOREVER );
134
+ return ;
135
+ }
136
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
137
+
138
+ while (!(litex_read8 (config -> master_status_addr ) &
139
+ BIT (MASTER_STATUS_RX_READY_OFFSET ))) {
140
+ /* Wait until RX is ready */
141
+ }
142
+ }
143
+
108
144
static int i2c_litex_transfer (const struct device * dev , struct i2c_msg * msgs , uint8_t num_msgs ,
109
145
uint16_t addr )
110
146
{
@@ -130,6 +166,26 @@ static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, ui
130
166
131
167
litex_write8 (1 , config -> master_active_addr );
132
168
169
+ /* Flush RX buffer */
170
+ while ((litex_read8 (config -> master_status_addr ) &
171
+ BIT (MASTER_STATUS_RX_READY_OFFSET ))) {
172
+ rx_buf = litex_read32 (config -> master_rxtx_addr );
173
+ LOG_DBG ("flushed rxd: 0x%x" , rx_buf );
174
+ }
175
+
176
+ while (!(litex_read8 (config -> master_status_addr ) &
177
+ BIT (MASTER_STATUS_TX_READY_OFFSET ))) {
178
+ (void )litex_read32 (config -> master_rxtx_addr );
179
+ }
180
+
181
+ #if I2C_LITEX_ANY_HAS_IRQ
182
+ if (I2C_LITEX_HAS_IRQ ) {
183
+ litex_write8 (BIT (0 ), config -> master_ev_enable_addr );
184
+ litex_write8 (BIT (0 ), config -> master_ev_pending_addr );
185
+ k_sem_reset (& data -> sem_rx_ready );
186
+ }
187
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
188
+
133
189
LOG_DBG ("addr: 0x%x" , addr );
134
190
litex_write8 ((uint8_t )addr , config -> master_addr_addr );
135
191
@@ -206,18 +262,10 @@ static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, ui
206
262
LOG_DBG ("len_tx: %d, len_rx: %d" , len_tx , len_rx );
207
263
i2c_litex_write_settings (dev , len_tx , len_rx , false);
208
264
209
- while (!(litex_read8 (config -> master_status_addr ) &
210
- BIT (MASTER_STATUS_TX_READY_OFFSET ))) {
211
- ;
212
- }
213
-
214
265
LOG_DBG ("tx_buf: 0x%x" , tx_buf );
215
266
litex_write32 (tx_buf , config -> master_rxtx_addr );
216
267
217
- while (!(litex_read8 (config -> master_status_addr ) &
218
- BIT (MASTER_STATUS_RX_READY_OFFSET ))) {
219
- ;
220
- }
268
+ i2c_litex_wait_for_rx_ready (dev );
221
269
222
270
if (litex_read16 (config -> master_status_addr ) &
223
271
BIT (MASTER_STATUS_NACK_OFFSET )) {
@@ -269,6 +317,12 @@ static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, ui
269
317
270
318
litex_write8 (0 , config -> master_active_addr );
271
319
320
+ #if I2C_LITEX_ANY_HAS_IRQ
321
+ if (I2C_LITEX_HAS_IRQ ) {
322
+ litex_write8 (0 , config -> master_ev_enable_addr );
323
+ }
324
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
325
+
272
326
k_mutex_unlock (& data -> mutex );
273
327
274
328
return ret ;
@@ -304,19 +358,40 @@ static int i2c_litex_recover_bus(const struct device *dev)
304
358
return 0 ;
305
359
}
306
360
307
- static int i2c_litex_init (const struct device * dev )
361
+ #if I2C_LITEX_ANY_HAS_IRQ
362
+ static void i2c_litex_irq_handler (const struct device * dev )
308
363
{
309
364
const struct i2c_litex_litei2c_config * config = dev -> config ;
310
365
struct i2c_litex_litei2c_data * data = dev -> data ;
311
- int ret ;
312
366
313
- k_mutex_init (& data -> mutex );
367
+ if (litex_read8 (config -> master_ev_pending_addr ) & BIT (0 )) {
368
+ k_sem_give (& data -> sem_rx_ready );
369
+
370
+ /* ack reader irq */
371
+ litex_write8 (BIT (0 ), config -> master_ev_pending_addr );
372
+ }
373
+ }
374
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
375
+
376
+ static int i2c_litex_init (const struct device * dev )
377
+ {
378
+ const struct i2c_litex_litei2c_config * config = dev -> config ;
379
+ int ret ;
314
380
315
381
ret = i2c_litex_configure (dev , I2C_MODE_CONTROLLER | i2c_map_dt_bitrate (config -> bitrate ));
316
382
if (ret != 0 ) {
317
383
LOG_ERR ("failed to configure I2C: %d" , ret );
318
384
}
319
385
386
+ #if I2C_LITEX_ANY_HAS_IRQ
387
+ if (I2C_LITEX_HAS_IRQ ) {
388
+ /* Disable interrupts initially */
389
+ litex_write8 (0 , config -> master_ev_enable_addr );
390
+
391
+ config -> irq_config_func (dev );
392
+ }
393
+ #endif /* I2C_LITEX_ANY_HAS_IRQ */
394
+
320
395
return ret ;
321
396
}
322
397
@@ -332,8 +407,35 @@ static DEVICE_API(i2c, i2c_litex_litei2c_driver_api) = {
332
407
333
408
/* Device Instantiation */
334
409
410
+ #define I2C_LITEX_IRQ (n ) \
411
+ BUILD_ASSERT(DT_INST_REG_HAS_NAME(n, master_ev_pending) && \
412
+ DT_INST_REG_HAS_NAME(n, master_ev_enable), "registers for interrupts missing"); \
413
+ \
414
+ static void i2c_litex_irq_config##n(const struct device *dev) \
415
+ { \
416
+ IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_litex_irq_handler, \
417
+ DEVICE_DT_INST_GET(n), 0); \
418
+ \
419
+ irq_enable(DT_INST_IRQN(n)); \
420
+ };
421
+
422
+ #define I2C_LITEC_IRQ_DATA (n ) \
423
+ .sem_rx_ready = Z_SEM_INITIALIZER(i2c_litex_litei2c_data_##n.sem_rx_ready, 0, 1),
424
+
425
+ #define I2C_LITEC_IRQ_CONFIG (n ) \
426
+ IF_DISABLED(I2C_LITEX_ALL_HAS_IRQ, (.has_irq = DT_INST_IRQ_HAS_IDX(n, 0),)) \
427
+ .master_ev_pending_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, master_ev_pending, 0), \
428
+ .master_ev_enable_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, master_ev_enable, 0), \
429
+ .irq_config_func = COND_CODE_1(DT_INST_IRQ_HAS_IDX(n, 0), \
430
+ (i2c_litex_irq_config##n), (NULL)),
431
+
335
432
#define I2C_LITEX_INIT (n ) \
336
- static struct i2c_litex_litei2c_data i2c_litex_litei2c_data_##n; \
433
+ IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), (I2C_LITEX_IRQ(n))) \
434
+ \
435
+ static struct i2c_litex_litei2c_data i2c_litex_litei2c_data_##n = { \
436
+ .mutex = Z_MUTEX_INITIALIZER(i2c_litex_litei2c_data_##n.mutex), \
437
+ IF_ENABLED(I2C_LITEX_ANY_HAS_IRQ, (I2C_LITEC_IRQ_DATA(n))) \
438
+ }; \
337
439
\
338
440
static const struct i2c_litex_litei2c_config i2c_litex_litei2c_config_##n = { \
339
441
.phy_speed_mode_addr = DT_INST_REG_ADDR_BY_NAME(n, phy_speed_mode), \
@@ -343,6 +445,7 @@ static DEVICE_API(i2c, i2c_litex_litei2c_driver_api) = {
343
445
.master_rxtx_addr = DT_INST_REG_ADDR_BY_NAME(n, master_rxtx), \
344
446
.master_status_addr = DT_INST_REG_ADDR_BY_NAME(n, master_status), \
345
447
.bitrate = DT_INST_PROP(n, clock_frequency), \
448
+ IF_ENABLED(I2C_LITEX_ANY_HAS_IRQ, (I2C_LITEC_IRQ_CONFIG(n))) \
346
449
}; \
347
450
\
348
451
I2C_DEVICE_DT_INST_DEFINE(n, i2c_litex_init, NULL, &i2c_litex_litei2c_data_##n, \
0 commit comments