@@ -545,30 +545,62 @@ static void target_i2c_isr_fifo(const struct device *dev)
545545#endif
546546}
547547
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+
548560static void target_i2c_isr_pio (const struct device * dev )
549561{
550562 const struct i2c_it51xxx_config * config = dev -> config ;
551563 struct i2c_it51xxx_data * data = dev -> data ;
552564 struct i2c_target_config * target_cfg ;
553565 const struct i2c_target_callbacks * target_cb ;
554- int ret ;
555566 uint8_t target_status , target_idx ;
556567 uint8_t val ;
557568
558569 target_status = sys_read8 (config -> target_base + SMB_SLSTn );
570+ /* Write to clear a target status */
571+ clear_target_status (dev , target_status );
559572
560573 /* Any error */
561574 if (target_status & SMB_STS ) {
562575 data -> w_index = 0 ;
563576 data -> r_index = 0 ;
564- goto done ;
577+
578+ return ;
565579 }
566580
567581 /* Which target address to match. */
568582 target_idx = (target_status & SMB_MSLA2 ) ? SMB_SADR2 : SMB_SADR ;
569583 target_cfg = data -> target_cfg [target_idx ];
570584 target_cb = target_cfg -> callbacks ;
571585
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+
572604 if (target_status & SMB_SDS ) {
573605 if (target_status & SMB_RCS ) {
574606 /* Target shared FIFO mode */
@@ -593,6 +625,8 @@ static void target_i2c_isr_pio(const struct device *dev)
593625 sndfpctl = sys_read8 (config -> target_base + SMB_SnDFPCTL );
594626 sys_write8 (sndfpctl | SMB_SADFE ,
595627 config -> target_base + SMB_SnDFPCTL );
628+ /* Write to clear data status of target */
629+ clear_target_status (dev , SMB_SDS );
596630 } else {
597631 /* Host receiving, target transmitting */
598632 if (!data -> r_index ) {
@@ -620,44 +654,14 @@ static void target_i2c_isr_pio(const struct device *dev)
620654 /* Read data */
621655 val = sys_read8 (config -> target_base + SMB_SLDn );
622656 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 );
628658 }
629-
659+ /* Release target clock stretch */
660+ sys_write8 (sys_read8 (config -> target_base + SMB_SLVCTLn ) | SMB_RSCS ,
661+ config -> target_base + SMB_SLVCTLn );
630662 data -> w_index ++ ;
631663 }
632664 }
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
661665}
662666
663667static void target_i2c_isr (const struct device * dev )
0 commit comments