@@ -185,6 +185,12 @@ LOG_MODULE_REGISTER(i2c_ite_it51xxx, CONFIG_I2C_LOG_LEVEL);
185
185
/* 0x02, 0x22, 0x42: Slave Status Register n */
186
186
#define SMB_SLSTn 0x02
187
187
#define SMB_SPDS BIT(5)
188
+ #define SMB_MSLA2 BIT(4)
189
+ enum it51xxx_msla2 {
190
+ SMB_SADR ,
191
+ SMB_SADR2 ,
192
+ MAX_I2C_TARGET_ADDRS ,
193
+ };
188
194
#define SMB_RCS BIT(3)
189
195
#define SMB_STS BIT(2)
190
196
#define SMB_SDS BIT(1)
@@ -205,6 +211,9 @@ LOG_MODULE_REGISTER(i2c_ite_it51xxx, CONFIG_I2C_LOG_LEVEL);
205
211
#define SMB_SSMCDTD BIT(0)
206
212
/* 0x07, 0x27, 0x47: 25 ms Slave Register */
207
213
#define SMB_25SLVREGn 0x07
214
+ /* 0x08, 0x28, 0x48: Receive Slave Address Register */
215
+ #define SMB_RESLADR2n 0x08
216
+ #define SMB_SADR2_EN BIT(7)
208
217
/* 0x0a, 0x2a, 0x4a: Slave n Dedicated FIFO Pre-defined Control */
209
218
#define SMB_SnDFPCTL 0x0a
210
219
#define SMB_SADFE BIT(0)
@@ -336,16 +345,17 @@ struct i2c_it51xxx_data {
336
345
uint8_t msg_index ;
337
346
#endif
338
347
#ifdef CONFIG_I2C_TARGET
339
- struct i2c_target_config * target_cfg ;
348
+ struct i2c_target_config * target_cfg [ MAX_I2C_TARGET_ADDRS ] ;
340
349
const struct target_shared_fifo_size_sel * fifo_size_list ;
350
+ atomic_t num_registered_addrs ;
341
351
uint32_t w_index ;
342
352
uint32_t r_index ;
343
353
/* Target mode FIFO buffer. */
344
354
uint8_t __aligned (4 ) target_in_buffer [CONFIG_I2C_TARGET_IT51XXX_MAX_BUF_SIZE ];
345
355
uint8_t __aligned (4 ) target_out_buffer [CONFIG_I2C_TARGET_IT51XXX_MAX_BUF_SIZE ];
346
356
/* Target shared FIFO mode. */
347
357
uint8_t __aligned (16 ) target_shared_fifo [CONFIG_I2C_IT51XXX_MAX_SHARE_FIFO_SIZE ];
348
- bool target_attached ;
358
+ uint8_t registered_addrs [ MAX_I2C_TARGET_ADDRS ] ;
349
359
#endif
350
360
#ifdef CONFIG_PM
351
361
ATOMIC_DEFINE (pm_policy_state_flag , I2C_ITE_PM_POLICY_FLAG_COUNT );
@@ -405,10 +415,10 @@ static void target_i2c_isr_fifo(const struct device *dev)
405
415
{
406
416
const struct i2c_it51xxx_config * config = dev -> config ;
407
417
struct i2c_it51xxx_data * data = dev -> data ;
408
- const struct i2c_target_callbacks * target_cb = data -> target_cfg -> callbacks ;
418
+ const struct i2c_target_callbacks * target_cb = NULL ;
409
419
uint32_t count , len ;
410
420
uint8_t sdfpctl ;
411
- uint8_t target_status , fifo_status ;
421
+ uint8_t target_status , fifo_status , target_idx ;
412
422
413
423
#ifdef CONFIG_SOC_IT51526AW
414
424
target_status = sys_read8 (config -> i2cbase_mapping + SMB_SLSTA (config -> port ));
@@ -425,6 +435,11 @@ static void target_i2c_isr_fifo(const struct device *dev)
425
435
data -> r_index = 0 ;
426
436
goto done ;
427
437
}
438
+
439
+ /* Which target address to match. */
440
+ target_idx = (target_status & SMB_MSLA2 ) ? SMB_SADR2 : SMB_SADR ;
441
+ target_cb = data -> target_cfg [target_idx ]-> callbacks ;
442
+
428
443
/* Target data status, the register is waiting for read or write. */
429
444
if (target_status & SMB_SDS ) {
430
445
if (target_status & SMB_RCS ) {
@@ -433,7 +448,8 @@ static void target_i2c_isr_fifo(const struct device *dev)
433
448
#ifdef CONFIG_I2C_TARGET_BUFFER_MODE
434
449
/* Read data callback function */
435
450
if (target_cb -> buf_read_requested ) {
436
- target_cb -> buf_read_requested (data -> target_cfg , & rdata , & len );
451
+ target_cb -> buf_read_requested (data -> target_cfg [target_idx ], & rdata ,
452
+ & len );
437
453
}
438
454
#endif
439
455
if (len > sizeof (data -> target_out_buffer )) {
@@ -469,7 +485,7 @@ static void target_i2c_isr_fifo(const struct device *dev)
469
485
#ifdef CONFIG_I2C_TARGET_BUFFER_MODE
470
486
/* Write data done callback function */
471
487
if (target_cb -> buf_write_received ) {
472
- target_cb -> buf_write_received (data -> target_cfg ,
488
+ target_cb -> buf_write_received (data -> target_cfg [ target_idx ] ,
473
489
data -> target_in_buffer , count );
474
490
}
475
491
#endif
@@ -505,15 +521,15 @@ static void target_i2c_isr_fifo(const struct device *dev)
505
521
#ifdef CONFIG_I2C_TARGET_BUFFER_MODE
506
522
/* Write data done callback function */
507
523
if (target_cb -> buf_write_received ) {
508
- target_cb -> buf_write_received (data -> target_cfg ,
524
+ target_cb -> buf_write_received (data -> target_cfg [ target_idx ] ,
509
525
data -> target_in_buffer , count );
510
526
}
511
527
#endif
512
528
}
513
529
514
530
/* Transfer done callback function */
515
531
if (target_cb -> stop ) {
516
- target_cb -> stop (data -> target_cfg );
532
+ target_cb -> stop (data -> target_cfg [ target_idx ] );
517
533
}
518
534
data -> w_index = 0 ;
519
535
data -> r_index = 0 ;
@@ -532,9 +548,9 @@ static void target_i2c_isr_pio(const struct device *dev)
532
548
{
533
549
const struct i2c_it51xxx_config * config = dev -> config ;
534
550
struct i2c_it51xxx_data * data = dev -> data ;
535
- const struct i2c_target_callbacks * target_cb = data -> target_cfg -> callbacks ;
551
+ const struct i2c_target_callbacks * target_cb = NULL ;
536
552
int ret ;
537
- uint8_t target_status ;
553
+ uint8_t target_status , target_idx ;
538
554
uint8_t val ;
539
555
540
556
target_status = sys_read8 (config -> target_base + SMB_SLSTn );
@@ -545,6 +561,11 @@ static void target_i2c_isr_pio(const struct device *dev)
545
561
data -> r_index = 0 ;
546
562
goto done ;
547
563
}
564
+
565
+ /* Which target address to match. */
566
+ target_idx = (target_status & SMB_MSLA2 ) ? SMB_SADR2 : SMB_SADR ;
567
+ target_cb = data -> target_cfg [target_idx ]-> callbacks ;
568
+
548
569
if (target_status & SMB_SDS ) {
549
570
if (target_status & SMB_RCS ) {
550
571
/* Target shared FIFO mode */
@@ -556,8 +577,8 @@ static void target_i2c_isr_pio(const struct device *dev)
556
577
#ifdef CONFIG_I2C_TARGET_BUFFER_MODE
557
578
/* Read data callback function */
558
579
if (target_cb -> buf_read_requested ) {
559
- target_cb -> buf_read_requested (data -> target_cfg , & rdata ,
560
- & len );
580
+ target_cb -> buf_read_requested (data -> target_cfg [ target_idx ] ,
581
+ & rdata , & len );
561
582
}
562
583
#endif
563
584
if (len > sizeof (data -> target_shared_fifo )) {
@@ -574,11 +595,13 @@ static void target_i2c_isr_pio(const struct device *dev)
574
595
/* Host receiving, target transmitting */
575
596
if (!data -> r_index ) {
576
597
if (target_cb -> read_requested ) {
577
- target_cb -> read_requested (data -> target_cfg , & val );
598
+ target_cb -> read_requested (
599
+ data -> target_cfg [target_idx ], & val );
578
600
}
579
601
} else {
580
602
if (target_cb -> read_processed ) {
581
- target_cb -> read_processed (data -> target_cfg , & val );
603
+ target_cb -> read_processed (
604
+ data -> target_cfg [target_idx ], & val );
582
605
}
583
606
}
584
607
/* Write data */
@@ -591,13 +614,13 @@ static void target_i2c_isr_pio(const struct device *dev)
591
614
/* Host transmitting, target receiving */
592
615
if (!data -> w_index ) {
593
616
if (target_cb -> write_requested ) {
594
- target_cb -> write_requested (data -> target_cfg );
617
+ target_cb -> write_requested (data -> target_cfg [ target_idx ] );
595
618
}
596
619
}
597
620
/* Read data */
598
621
val = sys_read8 (config -> target_base + SMB_SLDn );
599
622
if (target_cb -> write_received ) {
600
- ret = target_cb -> write_received (data -> target_cfg , val );
623
+ ret = target_cb -> write_received (data -> target_cfg [ target_idx ] , val );
601
624
if (!ret ) {
602
625
/* Release clock pin */
603
626
val = sys_read8 (config -> target_base + SMB_SLDn );
@@ -611,7 +634,7 @@ static void target_i2c_isr_pio(const struct device *dev)
611
634
if (target_status & SMB_SPDS ) {
612
635
/* Transfer done callback function */
613
636
if (target_cb -> stop ) {
614
- target_cb -> stop (data -> target_cfg );
637
+ target_cb -> stop (data -> target_cfg [ target_idx ] );
615
638
}
616
639
data -> w_index = 0 ;
617
640
data -> r_index = 0 ;
@@ -1233,7 +1256,7 @@ static void i2c_it51xxx_isr(const void *arg)
1233
1256
struct i2c_it51xxx_data * data = dev -> data ;
1234
1257
1235
1258
#ifdef CONFIG_I2C_TARGET
1236
- if (data -> target_attached ) {
1259
+ if (atomic_get ( & data -> num_registered_addrs ) != 0 ) {
1237
1260
target_i2c_isr (dev );
1238
1261
} else {
1239
1262
#endif
@@ -1425,7 +1448,7 @@ static int i2c_it51xxx_transfer(const struct device *dev, struct i2c_msg *msgs,
1425
1448
int ret ;
1426
1449
1427
1450
#ifdef CONFIG_I2C_TARGET
1428
- if (data -> target_attached ) {
1451
+ if (atomic_get ( & data -> num_registered_addrs ) != 0 ) {
1429
1452
LOG_ERR ("I2CS ch%d: Device is registered as target" , config -> port );
1430
1453
return - EBUSY ;
1431
1454
}
@@ -1644,71 +1667,136 @@ static int i2c_it51xxx_target_register(const struct device *dev,
1644
1667
return - ENOTSUP ;
1645
1668
}
1646
1669
1647
- if (data -> target_attached ) {
1648
- return - EBUSY ;
1670
+ if (atomic_get (& data -> num_registered_addrs ) >= MAX_I2C_TARGET_ADDRS ) {
1671
+ LOG_ERR ("%s: One device supports at most two target addresses" , __func__ );
1672
+ return - ENOMEM ;
1649
1673
}
1650
1674
1651
- data -> target_cfg = target_cfg ;
1652
- data -> target_attached = true;
1675
+ /* Compare with the saved I2C address */
1676
+ for (int i = 0 ; i < MAX_I2C_TARGET_ADDRS ; i ++ ) {
1677
+ if (data -> registered_addrs [i ] == target_cfg -> address ) {
1678
+ LOG_ERR ("%s: I2C target address=%x already registered" , __func__ ,
1679
+ target_cfg -> address );
1680
+ return - EALREADY ;
1681
+ }
1682
+ }
1653
1683
1654
- /* Target address[6:0] */
1655
- sys_write8 (target_cfg -> address , config -> target_base + SMB_RESLADR );
1684
+ /* To confirm which target_cfg is empty */
1685
+ for (int i = 0 ; i < MAX_I2C_TARGET_ADDRS ; i ++ ) {
1686
+ if (data -> target_cfg [i ] == NULL && data -> registered_addrs [i ] == 0 ) {
1687
+ if (i == SMB_SADR ) {
1688
+ LOG_INF ("I2C target register address=%x" , target_cfg -> address );
1689
+ /* Target address[6:0] */
1690
+ sys_write8 (target_cfg -> address , config -> target_base + SMB_RESLADR );
1691
+ } else if (i == SMB_SADR2 ) {
1692
+ LOG_INF ("I2C target register address2=%x" , target_cfg -> address );
1693
+ /* Target address 2[6:0] */
1694
+ sys_write8 (target_cfg -> address ,
1695
+ config -> target_base + SMB_RESLADR2n );
1696
+ /* Target address 2 enable */
1697
+ sys_write8 (sys_read8 (config -> target_base + SMB_RESLADR2n ) |
1698
+ SMB_SADR2_EN ,
1699
+ config -> target_base + SMB_RESLADR2n );
1700
+ }
1656
1701
1657
- /* Reset i2c port */
1658
- i2c_reset (dev );
1702
+ /* Save the registered I2C target_cfg */
1703
+ data -> target_cfg [i ] = target_cfg ;
1704
+ /* Save the registered I2C target address */
1705
+ data -> registered_addrs [i ] = target_cfg -> address ;
1659
1706
1660
- /* W/C all target status */
1661
- slsta = sys_read8 (config -> target_base + SMB_SLSTn );
1662
- sys_write8 (slsta | SMB_SPDS | SMB_STS | SMB_SDS , config -> target_base + SMB_SLSTn );
1663
-
1664
- if (config -> target_shared_fifo_mode ) {
1665
- uint32_t fifo_addr ;
1666
-
1667
- memset (data -> target_shared_fifo , 0 , sizeof (data -> target_shared_fifo ));
1668
- fifo_addr = (uint32_t )data -> target_shared_fifo & GENMASK (23 , 0 );
1669
- /* Define shared FIFO base address bit[11:4] */
1670
- sys_write8 ((fifo_addr >> 4 ) & GENMASK (7 , 0 ), config -> target_base + SMB_SFBASn );
1671
- /* Define shared FIFO base address bit[17:12] */
1672
- sys_write8 ((fifo_addr >> 12 ) & GENMASK (5 , 0 ), config -> target_base + SMB_SFBAMSn );
1673
- /* Block to enter idle mode. */
1674
- chip_block_idle ();
1707
+ break ;
1708
+ }
1675
1709
}
1710
+
1711
+ if (atomic_get (& data -> num_registered_addrs ) == 0 ) {
1712
+ if (config -> target_shared_fifo_mode ) {
1713
+ uint32_t fifo_addr ;
1714
+
1715
+ memset (data -> target_shared_fifo , 0 , sizeof (data -> target_shared_fifo ));
1716
+ fifo_addr = (uint32_t )data -> target_shared_fifo & GENMASK (23 , 0 );
1717
+ /* Define shared FIFO base address bit[11:4] */
1718
+ sys_write8 ((fifo_addr >> 4 ) & GENMASK (7 , 0 ),
1719
+ config -> target_base + SMB_SFBASn );
1720
+ /* Define shared FIFO base address bit[17:12] */
1721
+ sys_write8 ((fifo_addr >> 12 ) & GENMASK (5 , 0 ),
1722
+ config -> target_base + SMB_SFBAMSn );
1723
+ /* Block to enter idle mode. */
1724
+ chip_block_idle ();
1725
+ }
1676
1726
#ifdef CONFIG_PM
1677
- /* Block to enter power policy. */
1678
- i2c_ite_pm_policy_state_lock_get (data , I2CS_ITE_PM_POLICY_FLAG );
1727
+ /* Block to enter power policy. */
1728
+ i2c_ite_pm_policy_state_lock_get (data , I2CS_ITE_PM_POLICY_FLAG );
1679
1729
#endif
1680
- /* Enable the SMBus target device. */
1681
- sys_write8 (sys_read8 (config -> target_base + SMB_SLVCTLn ) | SMB_SLVEN ,
1682
- config -> target_base + SMB_SLVCTLn );
1730
+ /* Enable the SMBus target device. */
1731
+ sys_write8 (sys_read8 (config -> target_base + SMB_SLVCTLn ) | SMB_SLVEN ,
1732
+ config -> target_base + SMB_SLVCTLn );
1733
+
1734
+ /* Reset i2c port */
1735
+ i2c_reset (dev );
1683
1736
1684
- ite_intc_isr_clear (config -> i2cs_irq_base );
1685
- irq_enable (config -> i2cs_irq_base );
1737
+ /* W/C all target status */
1738
+ slsta = sys_read8 (config -> target_base + SMB_SLSTn );
1739
+ sys_write8 (slsta | SMB_SPDS | SMB_STS | SMB_SDS , config -> target_base + SMB_SLSTn );
1740
+
1741
+ ite_intc_isr_clear (config -> i2cs_irq_base );
1742
+ irq_enable (config -> i2cs_irq_base );
1743
+ }
1744
+ /* data->num_registered_addrs++ */
1745
+ atomic_inc (& data -> num_registered_addrs );
1686
1746
1687
1747
return 0 ;
1688
1748
}
1689
1749
1690
- static int i2c_it51xxx_target_unregister (const struct device * dev , struct i2c_target_config * cfg )
1750
+ static int i2c_it51xxx_target_unregister (const struct device * dev ,
1751
+ struct i2c_target_config * target_cfg )
1691
1752
{
1692
1753
const struct i2c_it51xxx_config * config = dev -> config ;
1693
1754
struct i2c_it51xxx_data * data = dev -> data ;
1755
+ bool match_reg = false;
1756
+
1757
+ /* Compare with the saved I2C address */
1758
+ for (int i = 0 ; i < MAX_I2C_TARGET_ADDRS ; i ++ ) {
1759
+ if (data -> target_cfg [i ] == target_cfg &&
1760
+ data -> registered_addrs [i ] == target_cfg -> address ) {
1761
+ if (i == SMB_SADR ) {
1762
+ LOG_INF ("I2C target unregister address=%x" , target_cfg -> address );
1763
+ sys_write8 (0 , config -> target_base + SMB_RESLADR );
1764
+ } else if (i == SMB_SADR2 ) {
1765
+ LOG_INF ("I2C target unregister address2=%x" , target_cfg -> address );
1766
+ sys_write8 (0 , config -> target_base + SMB_RESLADR2n );
1767
+ }
1768
+
1769
+ data -> target_cfg [i ] = NULL ;
1770
+ data -> registered_addrs [i ] = 0 ;
1771
+ match_reg = true;
1772
+
1773
+ break ;
1774
+ }
1775
+ }
1694
1776
1695
- if (!data -> target_attached ) {
1777
+ if (!match_reg ) {
1778
+ LOG_ERR ("%s: I2C cannot be unregistered due to address=%x mismatch" , __func__ ,
1779
+ target_cfg -> address );
1696
1780
return - EINVAL ;
1697
1781
}
1698
1782
1699
- irq_disable (config -> i2cs_irq_base );
1783
+ if (atomic_get (& data -> num_registered_addrs ) > 0 ) {
1784
+ /* data->num_registered_addrs-- */
1785
+ atomic_dec (& data -> num_registered_addrs );
1700
1786
1787
+ if (atomic_get (& data -> num_registered_addrs ) == 0 ) {
1701
1788
#ifdef CONFIG_PM
1702
- /* Permit to enter power policy. */
1703
- i2c_ite_pm_policy_state_lock_put (data , I2CS_ITE_PM_POLICY_FLAG );
1789
+ /* Permit to enter power policy. */
1790
+ i2c_ite_pm_policy_state_lock_put (data , I2CS_ITE_PM_POLICY_FLAG );
1704
1791
#endif
1705
- if (config -> target_shared_fifo_mode ) {
1706
- /* Permit to enter idle mode. */
1707
- chip_permit_idle ();
1708
- }
1792
+ if (config -> target_shared_fifo_mode ) {
1793
+ /* Permit to enter idle mode. */
1794
+ chip_permit_idle ();
1795
+ }
1709
1796
1710
- data -> target_cfg = NULL ;
1711
- data -> target_attached = false;
1797
+ irq_disable (config -> i2cs_irq_base );
1798
+ }
1799
+ }
1712
1800
1713
1801
return 0 ;
1714
1802
}
@@ -1857,7 +1945,8 @@ static int i2c_it51xxx_init(const struct device *dev)
1857
1945
(DT_INST_PROP(inst, clock_frequency) == I2C_BITRATE_FAST) || \
1858
1946
(DT_INST_PROP(inst, clock_frequency) == I2C_BITRATE_FAST_PLUS), \
1859
1947
"Not support I2C bit rate value"); \
1860
- \
1948
+ BUILD_ASSERT(!(DT_INST_PROP(inst, target_enable) && (inst > SMB_CHANNEL_C)), \
1949
+ "Only instances 0~2 can enable target-enable"); \
1861
1950
static const struct i2c_it51xxx_config i2c_it51xxx_cfg_##inst = { \
1862
1951
.i2cbase = DT_REG_ADDR_BY_IDX(DT_NODELABEL(i2cbase), 0), \
1863
1952
.i2cbase_mapping = DT_REG_ADDR_BY_IDX(DT_NODELABEL(i2cbase), 1), \
0 commit comments