@@ -672,33 +672,6 @@ static int get_i3c_addr_pos(const struct device *dev, uint8_t addr, bool sa)
672
672
return dw_i3c_device_data -> id ;
673
673
}
674
674
675
- /**
676
- * @brief Get the position of an I2C device with the specified address.
677
- *
678
- * This function retrieves the position (ID) of an I2C device with the specified
679
- * address on the I3C bus associated with the provided I3C device structure. This
680
- * utilizes the controller private data for where the id reg is stored.
681
- *
682
- * @param dev Pointer to the I3C device structure.
683
- * @param addr I2C address of the device whose position is to be retrieved.
684
- *
685
- * @return The position (ID) of the device on success, or a negative error code
686
- * if the device with the given address is not found.
687
- */
688
- static int get_i2c_addr_pos (const struct device * dev , uint16_t addr )
689
- {
690
- struct dw_i3c_i2c_dev_data * dw_i3c_device_data ;
691
- struct i3c_i2c_device_desc * desc = i3c_dev_list_i2c_addr_find (dev , addr );
692
-
693
- if (desc == NULL ) {
694
- return - ENODEV ;
695
- }
696
-
697
- dw_i3c_device_data = desc -> controller_priv ;
698
-
699
- return dw_i3c_device_data -> id ;
700
- }
701
-
702
675
/**
703
676
* @brief Transfer messages in I3C mode.
704
677
*
@@ -891,6 +864,41 @@ static int dw_i3c_xfers(const struct device *dev, struct i3c_device_desc *target
891
864
return ret ;
892
865
}
893
866
867
+ static int dw_i3c_i2c_attach_device (const struct device * dev , struct i3c_i2c_device_desc * desc )
868
+ {
869
+ const struct dw_i3c_config * config = dev -> config ;
870
+ struct dw_i3c_data * data = dev -> data ;
871
+ uint8_t pos ;
872
+
873
+ pos = get_free_pos (data -> free_pos );
874
+ if (pos < 0 ) {
875
+ return - ENOSPC ;
876
+ }
877
+
878
+ data -> dw_i3c_i2c_priv_data [pos ].id = pos ;
879
+ desc -> controller_priv = & (data -> dw_i3c_i2c_priv_data [pos ]);
880
+ data -> free_pos &= ~BIT (pos );
881
+
882
+ sys_write32 (DEV_ADDR_TABLE_LEGACY_I2C_DEV | DEV_ADDR_TABLE_STATIC_ADDR (desc -> addr ),
883
+ config -> regs + DEV_ADDR_TABLE_LOC (data -> datstartaddr , pos ));
884
+
885
+ return 0 ;
886
+ }
887
+
888
+ static void dw_i3c_i2c_detach_device (const struct device * dev , struct i3c_i2c_device_desc * desc )
889
+ {
890
+ const struct dw_i3c_config * config = dev -> config ;
891
+ struct dw_i3c_data * data = dev -> data ;
892
+ struct dw_i3c_i2c_dev_data * dw_i2c_device_data = desc -> controller_priv ;
893
+
894
+ __ASSERT_NO_MSG (dw_i2c_device_data != NULL );
895
+
896
+ sys_write32 (0 ,
897
+ config -> regs + DEV_ADDR_TABLE_LOC (data -> datstartaddr , dw_i2c_device_data -> id ));
898
+ data -> free_pos |= BIT (dw_i2c_device_data -> id );
899
+ desc -> controller_priv = NULL ;
900
+ }
901
+
894
902
/**
895
903
* @brief Transfer messages in I2C mode.
896
904
*
@@ -921,12 +929,6 @@ static int dw_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device_d
921
929
return - ENOTSUP ;
922
930
}
923
931
924
- pos = get_i2c_addr_pos (dev , target -> addr );
925
- if (pos < 0 ) {
926
- LOG_ERR ("%s: Invalid slave device" , dev -> name );
927
- return - EINVAL ;
928
- }
929
-
930
932
for (i = 0 ; i < num_msgs ; i ++ ) {
931
933
if (msgs [i ].flags & I2C_MSG_READ ) {
932
934
nrxwords += DIV_ROUND_UP (msgs [i ].len , 4 );
@@ -947,6 +949,17 @@ static int dw_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device_d
947
949
948
950
pm_device_busy_set (dev );
949
951
952
+ /* In order limit the number of retaining registers occupied by connected devices,
953
+ * I2C devices are only configured during transfers. This allows the number of devices
954
+ * to be larger than the number of retaining registers on mixed buses.
955
+ */
956
+ ret = dw_i3c_i2c_attach_device (dev , target );
957
+ if (ret != 0 ) {
958
+ LOG_ERR ("%s: Failed to attach I2C device (%d)" , dev -> name , ret );
959
+ goto error_attach ;
960
+ }
961
+ pos = ((struct dw_i3c_i2c_dev_data * )target -> controller_priv )-> id ;
962
+
950
963
memset (xfer , 0 , sizeof (struct dw_i3c_xfer ));
951
964
952
965
xfer -> ncmds = num_msgs ;
@@ -1002,6 +1015,8 @@ static int dw_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device_d
1002
1015
ret = xfer -> ret ;
1003
1016
1004
1017
error :
1018
+ dw_i3c_i2c_detach_device (dev , target );
1019
+ error_attach :
1005
1020
pm_device_busy_clear (dev );
1006
1021
k_mutex_unlock (& data -> mt );
1007
1022
@@ -1032,25 +1047,22 @@ static struct i3c_i2c_device_desc *dw_i3c_i2c_device_find(const struct device *d
1032
1047
* @see i2c_transfer
1033
1048
*
1034
1049
* @param dev Pointer to device driver instance.
1035
- * @param target Pointer to target device descriptor.
1036
1050
* @param msgs Pointer to I2C messages.
1037
1051
* @param num_msgs Number of messages to transfers.
1052
+ * @param addr Address of the I2C target device.
1038
1053
*
1039
1054
* @return @see i2c_transfer
1040
1055
*/
1041
1056
static int dw_i3c_i2c_api_transfer (const struct device * dev , struct i2c_msg * msgs , uint8_t num_msgs ,
1042
1057
uint16_t addr )
1043
1058
{
1044
1059
struct i3c_i2c_device_desc * i2c_dev = dw_i3c_i2c_device_find (dev , addr );
1045
- int ret ;
1046
1060
1047
1061
if (i2c_dev == NULL ) {
1048
- ret = - ENODEV ;
1049
- } else {
1050
- ret = dw_i3c_i2c_transfer (dev , i2c_dev , msgs , num_msgs );
1062
+ return - ENODEV ;
1051
1063
}
1052
1064
1053
- return ret ;
1065
+ return dw_i3c_i2c_transfer ( dev , i2c_dev , msgs , num_msgs ) ;
1054
1066
}
1055
1067
1056
1068
#ifdef CONFIG_I3C_USE_IBI
@@ -1571,50 +1583,6 @@ static int dw_i3c_detach_device(const struct device *dev, struct i3c_device_desc
1571
1583
return 0 ;
1572
1584
}
1573
1585
1574
- static int dw_i3c_i2c_attach_device (const struct device * dev , struct i3c_i2c_device_desc * desc )
1575
- {
1576
- const struct dw_i3c_config * config = dev -> config ;
1577
- struct dw_i3c_data * data = dev -> data ;
1578
- uint8_t pos ;
1579
-
1580
- pos = get_free_pos (data -> free_pos );
1581
- if (pos < 0 ) {
1582
- return - ENOSPC ;
1583
- }
1584
-
1585
- data -> dw_i3c_i2c_priv_data [pos ].id = pos ;
1586
- desc -> controller_priv = & (data -> dw_i3c_i2c_priv_data [pos ]);
1587
- data -> free_pos &= ~BIT (pos );
1588
-
1589
- sys_write32 (DEV_ADDR_TABLE_LEGACY_I2C_DEV | DEV_ADDR_TABLE_STATIC_ADDR (desc -> addr ),
1590
- config -> regs + DEV_ADDR_TABLE_LOC (data -> datstartaddr , pos ));
1591
-
1592
- return 0 ;
1593
- }
1594
-
1595
- static int dw_i3c_i2c_detach_device (const struct device * dev , struct i3c_i2c_device_desc * desc )
1596
- {
1597
- const struct dw_i3c_config * config = dev -> config ;
1598
- struct dw_i3c_data * data = dev -> data ;
1599
- struct dw_i3c_i2c_dev_data * dw_i2c_device_data = desc -> controller_priv ;
1600
-
1601
- if (dw_i2c_device_data == NULL ) {
1602
- LOG_ERR ("%s: device not attached" , dev -> name );
1603
- return - EINVAL ;
1604
- }
1605
-
1606
- k_mutex_lock (& data -> mt , K_FOREVER );
1607
-
1608
- sys_write32 (0 ,
1609
- config -> regs + DEV_ADDR_TABLE_LOC (data -> datstartaddr , dw_i2c_device_data -> id ));
1610
- data -> free_pos |= BIT (dw_i2c_device_data -> id );
1611
- desc -> controller_priv = NULL ;
1612
-
1613
- k_mutex_unlock (& data -> mt );
1614
-
1615
- return 0 ;
1616
- }
1617
-
1618
1586
static int set_controller_info (const struct device * dev )
1619
1587
{
1620
1588
const struct dw_i3c_config * config = dev -> config ;
@@ -2389,8 +2357,6 @@ static DEVICE_API(i3c, dw_i3c_api) = {
2389
2357
.attach_i3c_device = dw_i3c_attach_device ,
2390
2358
.reattach_i3c_device = dw_i3c_reattach_device ,
2391
2359
.detach_i3c_device = dw_i3c_detach_device ,
2392
- .attach_i2c_device = dw_i3c_i2c_attach_device ,
2393
- .detach_i2c_device = dw_i3c_i2c_detach_device ,
2394
2360
2395
2361
.do_daa = dw_i3c_do_daa ,
2396
2362
.do_ccc = dw_i3c_do_ccc ,
0 commit comments