@@ -545,30 +545,62 @@ static void target_i2c_isr_fifo(const struct device *dev)
545
545
#endif
546
546
}
547
547
548
+ static void clear_target_status (const struct device * dev , uint8_t status )
549
+ {
550
+ const struct i2c_it51xxx_config * config = dev -> config ;
551
+
552
+ /* Write to clear a specific status */
553
+ #ifdef CONFIG_SOC_IT51526AW
554
+ sys_write8 (status , config -> i2cbase_mapping + SMB_SLSTA (config -> port ));
555
+ #else
556
+ sys_write8 (status , config -> target_base + SMB_SLSTn );
557
+ #endif
558
+ }
559
+
548
560
static void target_i2c_isr_pio (const struct device * dev )
549
561
{
550
562
const struct i2c_it51xxx_config * config = dev -> config ;
551
563
struct i2c_it51xxx_data * data = dev -> data ;
552
564
struct i2c_target_config * target_cfg ;
553
565
const struct i2c_target_callbacks * target_cb ;
554
- int ret ;
555
566
uint8_t target_status , target_idx ;
556
567
uint8_t val ;
557
568
558
569
target_status = sys_read8 (config -> target_base + SMB_SLSTn );
570
+ /* Write to clear a target status */
571
+ clear_target_status (dev , target_status );
559
572
560
573
/* Any error */
561
574
if (target_status & SMB_STS ) {
562
575
data -> w_index = 0 ;
563
576
data -> r_index = 0 ;
564
- goto done ;
577
+
578
+ return ;
565
579
}
566
580
567
581
/* Which target address to match. */
568
582
target_idx = (target_status & SMB_MSLA2 ) ? SMB_SADR2 : SMB_SADR ;
569
583
target_cfg = data -> target_cfg [target_idx ];
570
584
target_cb = target_cfg -> callbacks ;
571
585
586
+ /* Stop condition, indicate stop condition detected. */
587
+ if (target_status & SMB_SPDS ) {
588
+ /* Transfer done callback function */
589
+ if (target_cb -> stop ) {
590
+ target_cb -> stop (target_cfg );
591
+ }
592
+ data -> w_index = 0 ;
593
+ data -> r_index = 0 ;
594
+
595
+ if (config -> target_shared_fifo_mode ) {
596
+ uint8_t sdfpctl ;
597
+
598
+ /* Disable FIFO mode to clear left count */
599
+ sdfpctl = sys_read8 (config -> target_base + SMB_SnDFPCTL );
600
+ sys_write8 (sdfpctl & ~SMB_SADFE , config -> target_base + SMB_SnDFPCTL );
601
+ }
602
+ }
603
+
572
604
if (target_status & SMB_SDS ) {
573
605
if (target_status & SMB_RCS ) {
574
606
/* Target shared FIFO mode */
@@ -593,6 +625,8 @@ static void target_i2c_isr_pio(const struct device *dev)
593
625
sndfpctl = sys_read8 (config -> target_base + SMB_SnDFPCTL );
594
626
sys_write8 (sndfpctl | SMB_SADFE ,
595
627
config -> target_base + SMB_SnDFPCTL );
628
+ /* Write to clear data status of target */
629
+ clear_target_status (dev , SMB_SDS );
596
630
} else {
597
631
/* Host receiving, target transmitting */
598
632
if (!data -> r_index ) {
@@ -620,44 +654,14 @@ static void target_i2c_isr_pio(const struct device *dev)
620
654
/* Read data */
621
655
val = sys_read8 (config -> target_base + SMB_SLDn );
622
656
if (target_cb -> write_received ) {
623
- ret = target_cb -> write_received (target_cfg , val );
624
- if (!ret ) {
625
- /* Release clock pin */
626
- val = sys_read8 (config -> target_base + SMB_SLDn );
627
- }
657
+ target_cb -> write_received (target_cfg , val );
628
658
}
629
-
659
+ /* Release target clock stretch */
660
+ sys_write8 (sys_read8 (config -> target_base + SMB_SLVCTLn ) | SMB_RSCS ,
661
+ config -> target_base + SMB_SLVCTLn );
630
662
data -> w_index ++ ;
631
663
}
632
664
}
633
- /* Stop condition, indicate stop condition detected. */
634
- if (target_status & SMB_SPDS ) {
635
- /* Transfer done callback function */
636
- if (target_cb -> stop ) {
637
- target_cb -> stop (target_cfg );
638
- }
639
- data -> w_index = 0 ;
640
- data -> r_index = 0 ;
641
-
642
- if (config -> target_shared_fifo_mode ) {
643
- uint8_t sdfpctl ;
644
-
645
- /* Disable FIFO mode to clear left count */
646
- sdfpctl = sys_read8 (config -> target_base + SMB_SnDFPCTL );
647
- sys_write8 (sdfpctl & ~SMB_SADFE , config -> target_base + SMB_SnDFPCTL );
648
- }
649
- }
650
-
651
- done :
652
- sys_write8 (sys_read8 (config -> target_base + SMB_SLVCTLn ) | SMB_RSCS ,
653
- config -> target_base + SMB_SLVCTLn );
654
-
655
- /* W/C */
656
- #ifdef CONFIG_SOC_IT51526AW
657
- sys_write8 (target_status , config -> i2cbase_mapping + SMB_SLSTA (config -> port ));
658
- #else
659
- sys_write8 (target_status , config -> target_base + SMB_SLSTn );
660
- #endif
661
665
}
662
666
663
667
static void target_i2c_isr (const struct device * dev )
0 commit comments