12
12
#include <zephyr/drivers/clock_control/adi_max32_clock_control.h>
13
13
#include <zephyr/irq.h>
14
14
15
+ #if defined(CONFIG_I2C_MAX32_DMA )
16
+ #include <zephyr/drivers/dma.h>
17
+ #endif /* CONFIG_I2C_MAX32_DMA */
18
+
15
19
#include <wrap_max32_i2c.h>
16
20
17
21
#define ADI_MAX32_I2C_INT_FL0_MASK 0x00FFFFFF
21
25
22
26
#define I2C_RECOVER_MAX_RETRIES 3
23
27
28
+ #ifdef CONFIG_I2C_MAX32_DMA
29
+ struct max32_i2c_dma_config {
30
+ const struct device * dev ;
31
+ const uint32_t channel ;
32
+ const uint32_t slot ;
33
+ };
34
+ #endif /* CONFIG_I2C_MAX32_DMA */
35
+
24
36
/* Driver config */
25
37
struct max32_i2c_config {
26
38
mxc_i2c_regs_t * regs ;
@@ -32,6 +44,10 @@ struct max32_i2c_config {
32
44
uint8_t irqn ;
33
45
void (* irq_config_func )(const struct device * dev );
34
46
#endif
47
+ #ifdef CONFIG_I2C_MAX32_DMA
48
+ struct max32_i2c_dma_config tx_dma ;
49
+ struct max32_i2c_dma_config rx_dma ;
50
+ #endif /* CONFIG_I2C_MAX32_DMA */
35
51
};
36
52
37
53
struct max32_i2c_data {
@@ -46,7 +62,7 @@ struct max32_i2c_data {
46
62
#endif /* CONFIG_I2C_TARGET */
47
63
uint32_t readb ;
48
64
uint32_t written ;
49
- #if defined(CONFIG_I2C_MAX32_INTERRUPT )
65
+ #if defined(CONFIG_I2C_MAX32_INTERRUPT ) || defined( CONFIG_I2C_MAX32_DMA )
50
66
struct k_sem xfer ;
51
67
int err ;
52
68
#endif
@@ -266,6 +282,149 @@ static int i2c_max32_transfer_sync(mxc_i2c_regs_t *i2c, struct max32_i2c_data *d
266
282
}
267
283
#endif /* CONFIG_I2C_MAX32_INTERRUPT */
268
284
285
+ #if defined(CONFIG_I2C_MAX32_DMA )
286
+ static void i2c_max32_dma_callback (const struct device * dev , void * arg , uint32_t channel ,
287
+ int status )
288
+ {
289
+ struct max32_i2c_data * data = arg ;
290
+ const struct device * i2c_dev = data -> dev ;
291
+ const struct max32_i2c_config * const cfg = i2c_dev -> config ;
292
+
293
+ if (status < 0 ) {
294
+ data -> err = - EIO ;
295
+ } else {
296
+ if (data -> req .restart ) {
297
+ Wrap_MXC_I2C_Restart (cfg -> regs );
298
+ } else {
299
+ Wrap_MXC_I2C_Stop (cfg -> regs );
300
+ }
301
+ }
302
+ }
303
+
304
+ static int i2c_max32_tx_dma_load (const struct device * dev , struct i2c_msg * msg )
305
+ {
306
+ int ret ;
307
+ const struct max32_i2c_config * config = dev -> config ;
308
+ struct max32_i2c_data * data = dev -> data ;
309
+ struct dma_config dma_cfg = {0 };
310
+ struct dma_block_config dma_blk = {0 };
311
+
312
+ dma_cfg .channel_direction = MEMORY_TO_PERIPHERAL ;
313
+ dma_cfg .dma_callback = i2c_max32_dma_callback ;
314
+ dma_cfg .user_data = (void * )data ;
315
+ dma_cfg .dma_slot = config -> tx_dma .slot ;
316
+ dma_cfg .block_count = 1 ;
317
+ dma_cfg .source_data_size = 1U ;
318
+ dma_cfg .source_burst_length = 1U ;
319
+ dma_cfg .dest_data_size = 1U ;
320
+ dma_cfg .head_block = & dma_blk ;
321
+ dma_blk .block_size = msg -> len ;
322
+ dma_blk .source_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
323
+ dma_blk .source_address = (uint32_t )msg -> buf ;
324
+
325
+ ret = dma_config (config -> tx_dma .dev , config -> tx_dma .channel , & dma_cfg );
326
+ if (ret < 0 ) {
327
+ return ret ;
328
+ }
329
+
330
+ return dma_start (config -> tx_dma .dev , config -> tx_dma .channel );
331
+ }
332
+
333
+ static int i2c_max32_rx_dma_load (const struct device * dev , struct i2c_msg * msg )
334
+ {
335
+ int ret ;
336
+ const struct max32_i2c_config * config = dev -> config ;
337
+ struct max32_i2c_data * data = dev -> data ;
338
+ struct dma_config dma_cfg = {0 };
339
+ struct dma_block_config dma_blk = {0 };
340
+
341
+ dma_cfg .channel_direction = PERIPHERAL_TO_MEMORY ;
342
+ dma_cfg .dma_callback = i2c_max32_dma_callback ;
343
+ dma_cfg .user_data = (void * )data ;
344
+ dma_cfg .dma_slot = config -> rx_dma .slot ;
345
+ dma_cfg .block_count = 1 ;
346
+ dma_cfg .source_data_size = 1U ;
347
+ dma_cfg .source_burst_length = 1U ;
348
+ dma_cfg .dest_data_size = 1U ;
349
+ dma_cfg .head_block = & dma_blk ;
350
+ dma_blk .block_size = msg -> len ;
351
+ dma_blk .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
352
+ dma_blk .dest_address = (uint32_t )msg -> buf ;
353
+
354
+ ret = dma_config (config -> rx_dma .dev , config -> rx_dma .channel , & dma_cfg );
355
+ if (ret < 0 ) {
356
+ return ret ;
357
+ }
358
+
359
+ return dma_start (config -> rx_dma .dev , config -> rx_dma .channel );
360
+ }
361
+
362
+ static int i2c_max32_transfer_dma (const struct device * dev , struct i2c_msg * msgs , uint8_t num_msgs ,
363
+ uint16_t target_address )
364
+ {
365
+ int ret = 0 ;
366
+ const struct max32_i2c_config * const cfg = dev -> config ;
367
+ struct max32_i2c_data * data = dev -> data ;
368
+ mxc_i2c_regs_t * i2c = cfg -> regs ;
369
+ uint8_t target_rw ;
370
+ unsigned int i = 0 ;
371
+
372
+ k_sem_take (& data -> lock , K_FOREVER );
373
+
374
+ MXC_I2C_SetRXThreshold (i2c , 1 );
375
+ MXC_I2C_SetTXThreshold (i2c , 2 );
376
+ MXC_I2C_ClearTXFIFO (i2c );
377
+ MXC_I2C_ClearRXFIFO (i2c );
378
+
379
+ for (i = 0 ; i < num_msgs ; i ++ ) {
380
+ data -> req .restart = !(msgs [i ].flags & I2C_MSG_STOP );
381
+ if (msgs [i ].flags & I2C_MSG_READ ) {
382
+ target_rw = (target_address << 1 ) | 0x1 ;
383
+ MXC_I2C_WriteTXFIFO (i2c , & target_rw , 1 );
384
+ Wrap_MXC_I2C_SetRxCount (i2c , msgs [i ].len );
385
+ ret = i2c_max32_rx_dma_load (dev , & msgs [i ]);
386
+ if (ret < 0 ) {
387
+ break ;
388
+ }
389
+
390
+ MXC_I2C_EnableInt (
391
+ i2c , ADI_MAX32_I2C_INT_EN0_DONE | ADI_MAX32_I2C_INT_EN0_ERR , 0 );
392
+ i2c -> dma |= ADI_MAX32_I2C_DMA_RX_EN ;
393
+ } else {
394
+ target_rw = (target_address << 1 ) & ~0x1 ;
395
+ MXC_I2C_WriteTXFIFO (i2c , & target_rw , 1 );
396
+ ret = i2c_max32_tx_dma_load (dev , & msgs [i ]);
397
+ if (ret < 0 ) {
398
+ break ;
399
+ }
400
+
401
+ MXC_I2C_EnableInt (
402
+ i2c , ADI_MAX32_I2C_INT_EN0_DONE | ADI_MAX32_I2C_INT_EN0_ERR , 0 );
403
+ i2c -> dma |= ADI_MAX32_I2C_DMA_TX_EN ;
404
+ }
405
+ data -> err = 0 ;
406
+
407
+ Wrap_MXC_I2C_Start (i2c );
408
+ ret = k_sem_take (& data -> xfer , K_FOREVER );
409
+ Wrap_MXC_I2C_SetIntEn (i2c , 0 , 0 );
410
+ i2c -> dma &= ~(ADI_MAX32_I2C_DMA_TX_EN | ADI_MAX32_I2C_DMA_RX_EN );
411
+
412
+ if (data -> err ) {
413
+ ret = data -> err ;
414
+ }
415
+ if (ret ) {
416
+ MXC_I2C_Stop (i2c );
417
+ dma_stop (cfg -> tx_dma .dev , cfg -> tx_dma .channel );
418
+ dma_stop (cfg -> rx_dma .dev , cfg -> rx_dma .channel );
419
+ }
420
+ }
421
+
422
+ k_sem_give (& data -> lock );
423
+
424
+ return ret ;
425
+ }
426
+ #endif /* CONFIG_I2C_MAX32_DMA */
427
+
269
428
#ifdef CONFIG_I2C_MAX32_INTERRUPT
270
429
static int i2c_max32_transfer (const struct device * dev , struct i2c_msg * msgs , uint8_t num_msgs ,
271
430
uint16_t target_address )
@@ -434,6 +593,13 @@ static int i2c_max32_transfer(const struct device *dev, struct i2c_msg *msgs, ui
434
593
static int api_transfer (const struct device * dev , struct i2c_msg * msgs , uint8_t num_msgs ,
435
594
uint16_t target_address )
436
595
{
596
+ #if CONFIG_I2C_MAX32_DMA
597
+ const struct max32_i2c_config * cfg = dev -> config ;
598
+
599
+ if ((cfg -> tx_dma .channel != 0xFF ) && (cfg -> rx_dma .channel != 0xFF )) {
600
+ return i2c_max32_transfer_dma (dev , msgs , num_msgs , target_address );
601
+ }
602
+ #endif
437
603
return i2c_max32_transfer (dev , msgs , num_msgs , target_address );
438
604
}
439
605
@@ -615,6 +781,29 @@ static void i2c_max32_isr_controller(const struct device *dev, mxc_i2c_regs_t *i
615
781
}
616
782
#endif /* CONFIG_I2C_MAX32_INTERRUPT */
617
783
784
+ #ifdef CONFIG_I2C_MAX32_DMA
785
+ static void i2c_max32_isr_controller_dma (const struct device * dev , mxc_i2c_regs_t * i2c )
786
+ {
787
+ struct max32_i2c_data * data = dev -> data ;
788
+ uint32_t int_fl0 , int_fl1 ;
789
+ uint32_t int_en0 , int_en1 ;
790
+
791
+ Wrap_MXC_I2C_GetIntEn (i2c , & int_en0 , & int_en1 );
792
+ MXC_I2C_GetFlags (i2c , & int_fl0 , & int_fl1 );
793
+ MXC_I2C_ClearFlags (i2c , ADI_MAX32_I2C_INT_FL0_MASK , ADI_MAX32_I2C_INT_FL1_MASK );
794
+
795
+ if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR ) {
796
+ data -> err = - EIO ;
797
+ Wrap_MXC_I2C_SetIntEn (i2c , 0 , 0 );
798
+ k_sem_give (& data -> xfer );
799
+ } else {
800
+ if (!data -> err && (int_en0 & ADI_MAX32_I2C_INT_EN0_DONE )) {
801
+ k_sem_give (& data -> xfer );
802
+ }
803
+ }
804
+ }
805
+ #endif /* CONFIG_I2C_MAX32_DMA */
806
+
618
807
#if defined(CONFIG_I2C_TARGET ) || defined(CONFIG_I2C_MAX32_INTERRUPT )
619
808
static void i2c_max32_isr (const struct device * dev )
620
809
{
@@ -624,6 +813,12 @@ static void i2c_max32_isr(const struct device *dev)
624
813
625
814
#ifdef CONFIG_I2C_MAX32_INTERRUPT
626
815
if (data -> target_mode == 0 ) {
816
+ #ifdef CONFIG_I2C_MAX32_DMA
817
+ if ((cfg -> tx_dma .channel != 0xFF ) && (cfg -> rx_dma .channel != 0xFF )) {
818
+ i2c_max32_isr_controller_dma (dev , i2c );
819
+ return ;
820
+ }
821
+ #endif
627
822
i2c_max32_isr_controller (dev , i2c );
628
823
return ;
629
824
}
@@ -713,6 +908,28 @@ static int i2c_max32_init(const struct device *dev)
713
908
#define I2C_MAX32_IRQ_CONFIG_FUNC (n )
714
909
#endif
715
910
911
+ #if CONFIG_I2C_MAX32_DMA
912
+ #define MAX32_DT_INST_DMA_CTLR (n , name ) \
913
+ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
914
+ (DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, name))), (NULL))
915
+
916
+ #define MAX32_DT_INST_DMA_CELL (n , name , cell ) \
917
+ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), (DT_INST_DMAS_CELL_BY_NAME(n, name, cell)), \
918
+ (0xff))
919
+
920
+ #define MAX32_I2C_TX_DMA_INIT (n ) \
921
+ .tx_dma.dev = MAX32_DT_INST_DMA_CTLR(n, tx), \
922
+ .tx_dma.channel = MAX32_DT_INST_DMA_CELL(n, tx, channel), \
923
+ .tx_dma.slot = MAX32_DT_INST_DMA_CELL(n, tx, slot),
924
+ #define MAX32_I2C_RX_DMA_INIT (n ) \
925
+ .rx_dma.dev = MAX32_DT_INST_DMA_CTLR(n, rx), \
926
+ .rx_dma.channel = MAX32_DT_INST_DMA_CELL(n, rx, channel), \
927
+ .rx_dma.slot = MAX32_DT_INST_DMA_CELL(n, rx, slot),
928
+ #else
929
+ #define MAX32_I2C_TX_DMA_INIT (n )
930
+ #define MAX32_I2C_RX_DMA_INIT (n )
931
+ #endif
932
+
716
933
#define DEFINE_I2C_MAX32 (_num ) \
717
934
PINCTRL_DT_INST_DEFINE(_num); \
718
935
I2C_MAX32_IRQ_CONFIG_FUNC(_num) \
@@ -723,7 +940,8 @@ static int i2c_max32_init(const struct device *dev)
723
940
.perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \
724
941
.perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \
725
942
.bitrate = DT_INST_PROP(_num, clock_frequency), \
726
- I2C_MAX32_CONFIG_IRQ_FUNC(_num)}; \
943
+ I2C_MAX32_CONFIG_IRQ_FUNC(_num) MAX32_I2C_TX_DMA_INIT(_num) \
944
+ MAX32_I2C_RX_DMA_INIT(_num)}; \
727
945
static struct max32_i2c_data max32_i2c_data_##_num; \
728
946
I2C_DEVICE_DT_INST_DEFINE(_num, i2c_max32_init, NULL, &max32_i2c_data_##_num, \
729
947
&max32_i2c_dev_cfg_##_num, PRE_KERNEL_2, \
0 commit comments