@@ -685,7 +685,10 @@ static inline void mcux_i3c_request_emit_stop(I3C_Type *base, bool wait_stop)
685
685
I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_DIR_MASK | I3C_MCTRL_RDTERM_MASK ,
686
686
I3C_MCTRL_REQUEST_EMIT_STOP );
687
687
688
- mcux_i3c_status_wait_clear (base , I3C_MSTATUS_MCTRLDONE_MASK );
688
+ /*
689
+ * EMIT_STOP request doesn't result in MCTRLDONE being cleared
690
+ * so don't wait for it.
691
+ */
689
692
690
693
if (wait_stop ) {
691
694
/*
@@ -816,27 +819,6 @@ struct i3c_device_desc *mcux_i3c_device_find(const struct device *dev,
816
819
return i3c_dev_list_find (& config -> common .dev_list , id );
817
820
}
818
821
819
- /**
820
- * Find a registered I2C target device.
821
- *
822
- * Controller only API.
823
- *
824
- * This returns the I2C device descriptor of the I2C device
825
- * matching the device address @p addr.
826
- *
827
- * @param dev Pointer to controller device driver instance.
828
- * @param id I2C target device address.
829
- *
830
- * @return @see i3c_i2c_device_find.
831
- */
832
- static struct i3c_i2c_device_desc *
833
- mcux_i3c_i2c_device_find (const struct device * dev , uint16_t addr )
834
- {
835
- struct mcux_i3c_data * data = dev -> data ;
836
-
837
- return i3c_dev_list_i2c_addr_find (& data -> common .attached_dev , addr );
838
- }
839
-
840
822
/**
841
823
* @brief Perform bus recovery.
842
824
*
@@ -1035,7 +1017,7 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data,
1035
1017
}
1036
1018
}
1037
1019
1038
- if (buf == NULL ) {
1020
+ if (( buf == NULL ) || ( buf_sz == 0 ) ) {
1039
1021
goto out_one_xfer ;
1040
1022
}
1041
1023
@@ -1050,6 +1032,8 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data,
1050
1032
ret = mcux_i3c_status_wait_clear_timeout (base , I3C_MSTATUS_COMPLETE_MASK ,
1051
1033
0 , 10 , 1000 );
1052
1034
if (ret != 0 ) {
1035
+ LOG_DBG ("%s: timed out addr 0x%02x, buf_sz %u" ,
1036
+ __func__ , addr , buf_sz );
1053
1037
emit_stop = true;
1054
1038
1055
1039
goto out_one_xfer ;
@@ -1165,97 +1149,6 @@ static int mcux_i3c_transfer(const struct device *dev,
1165
1149
return ret ;
1166
1150
}
1167
1151
1168
- /**
1169
- * @brief Transfer messages in I2C mode.
1170
- *
1171
- * @see i3c_i2c_transfer
1172
- *
1173
- * @param dev Pointer to device driver instance.
1174
- * @param target Pointer to target device descriptor.
1175
- * @param msgs Pointer to I2C messages.
1176
- * @param num_msgs Number of messages to transfers.
1177
- *
1178
- * @return @see i3c_i2c_transfer
1179
- */
1180
- static int mcux_i3c_i2c_transfer (const struct device * dev ,
1181
- struct i3c_i2c_device_desc * i2c_dev ,
1182
- struct i2c_msg * msgs ,
1183
- uint8_t num_msgs )
1184
- {
1185
- const struct mcux_i3c_config * config = dev -> config ;
1186
- struct mcux_i3c_data * dev_data = dev -> data ;
1187
- I3C_Type * base = config -> base ;
1188
- uint32_t intmask ;
1189
- int ret ;
1190
-
1191
- k_sem_take (& dev_data -> lock , K_FOREVER );
1192
-
1193
- intmask = mcux_i3c_interrupt_disable (base );
1194
-
1195
- ret = mcux_i3c_state_wait_timeout (base , I3C_MSTATUS_STATE_IDLE , 0 , 100 , 100000 );
1196
- if (ret == - ETIMEDOUT ) {
1197
- goto out_xfer_i2c_unlock ;
1198
- }
1199
-
1200
- mcux_i3c_xfer_reset (base );
1201
-
1202
- /* Iterate over all the messages */
1203
- for (int i = 0 ; i < num_msgs ; i ++ ) {
1204
- bool is_read = (msgs [i ].flags & I2C_MSG_RW_MASK ) == I2C_MSG_READ ;
1205
- bool no_ending = false;
1206
-
1207
- /*
1208
- * Emit start if this is the first message or that
1209
- * the RESTART flag is set in message.
1210
- */
1211
- bool emit_start = (i == 0 ) ||
1212
- ((msgs [i ].flags & I2C_MSG_RESTART ) == I2C_MSG_RESTART );
1213
-
1214
- bool emit_stop = (msgs [i ].flags & I2C_MSG_STOP ) == I2C_MSG_STOP ;
1215
-
1216
- /*
1217
- * The controller requires special treatment of last byte of
1218
- * a write message. Since the API permits having a bunch of
1219
- * write messages without RESTART in between, this is just some
1220
- * logic to determine whether to treat the last byte of this
1221
- * message to be the last byte of a series of write mssages.
1222
- * If not, tell the write function not to treat it that way.
1223
- */
1224
- if (!is_read && !emit_stop && ((i + 1 ) != num_msgs )) {
1225
- bool next_is_write =
1226
- (msgs [i + 1 ].flags & I2C_MSG_RW_MASK ) == I2C_MSG_WRITE ;
1227
- bool next_is_restart =
1228
- ((msgs [i + 1 ].flags & I2C_MSG_RESTART ) == I2C_MSG_RESTART );
1229
-
1230
- if (next_is_write && !next_is_restart ) {
1231
- no_ending = true;
1232
- }
1233
- }
1234
-
1235
- ret = mcux_i3c_do_one_xfer (base , dev_data , i2c_dev -> addr , true,
1236
- msgs [i ].buf , msgs [i ].len ,
1237
- is_read , emit_start , emit_stop , no_ending );
1238
- if (ret < 0 ) {
1239
- goto out_xfer_i2c_stop_unlock ;
1240
- }
1241
- }
1242
-
1243
- ret = 0 ;
1244
-
1245
- out_xfer_i2c_stop_unlock :
1246
- mcux_i3c_request_emit_stop (base , true);
1247
-
1248
- out_xfer_i2c_unlock :
1249
- mcux_i3c_errwarn_clear_all_nowait (base );
1250
- mcux_i3c_status_clear_all (base );
1251
-
1252
- mcux_i3c_interrupt_enable (base , intmask );
1253
-
1254
- k_sem_give (& dev_data -> lock );
1255
-
1256
- return ret ;
1257
- }
1258
-
1259
1152
/**
1260
1153
* @brief Perform Dynamic Address Assignment.
1261
1154
*
@@ -1417,6 +1310,15 @@ static int mcux_i3c_do_ccc(const struct device *dev,
1417
1310
return - EINVAL ;
1418
1311
}
1419
1312
1313
+ if (config -> common .dev_list .num_i3c == 0 ) {
1314
+ /*
1315
+ * No i3c devices in dev tree. Just return so
1316
+ * we don't get errors doing cmds when there
1317
+ * are no devices listening/responding.
1318
+ */
1319
+ return 0 ;
1320
+ }
1321
+
1420
1322
k_sem_take (& data -> lock , K_FOREVER );
1421
1323
1422
1324
intmask = mcux_i3c_interrupt_disable (base );
@@ -2078,16 +1980,77 @@ static int mcux_i3c_i2c_api_transfer(const struct device *dev,
2078
1980
uint8_t num_msgs ,
2079
1981
uint16_t addr )
2080
1982
{
2081
- struct i3c_i2c_device_desc * i2c_dev =
2082
- mcux_i3c_i2c_device_find (dev , addr );
1983
+ const struct mcux_i3c_config * config = dev -> config ;
1984
+ struct mcux_i3c_data * dev_data = dev -> data ;
1985
+ I3C_Type * base = config -> base ;
1986
+ uint32_t intmask ;
2083
1987
int ret ;
2084
1988
2085
- if (i2c_dev == NULL ) {
2086
- ret = - ENODEV ;
2087
- } else {
2088
- ret = mcux_i3c_i2c_transfer (dev , i2c_dev , msgs , num_msgs );
1989
+ k_sem_take (& dev_data -> lock , K_FOREVER );
1990
+
1991
+ intmask = mcux_i3c_interrupt_disable (base );
1992
+
1993
+ ret = mcux_i3c_state_wait_timeout (base , I3C_MSTATUS_STATE_IDLE , 0 , 100 , 100000 );
1994
+ if (ret == - ETIMEDOUT ) {
1995
+ goto out_xfer_i2c_unlock ;
1996
+ }
1997
+
1998
+ mcux_i3c_xfer_reset (base );
1999
+
2000
+ /* Iterate over all the messages */
2001
+ for (int i = 0 ; i < num_msgs ; i ++ ) {
2002
+ bool is_read = (msgs [i ].flags & I2C_MSG_RW_MASK ) == I2C_MSG_READ ;
2003
+ bool no_ending = false;
2004
+
2005
+ /*
2006
+ * Emit start if this is the first message or that
2007
+ * the RESTART flag is set in message.
2008
+ */
2009
+ bool emit_start = (i == 0 ) ||
2010
+ ((msgs [i ].flags & I2C_MSG_RESTART ) == I2C_MSG_RESTART );
2011
+
2012
+ bool emit_stop = (msgs [i ].flags & I2C_MSG_STOP ) == I2C_MSG_STOP ;
2013
+
2014
+ /*
2015
+ * The controller requires special treatment of last byte of
2016
+ * a write message. Since the API permits having a bunch of
2017
+ * write messages without RESTART in between, this is just some
2018
+ * logic to determine whether to treat the last byte of this
2019
+ * message to be the last byte of a series of write mssages.
2020
+ * If not, tell the write function not to treat it that way.
2021
+ */
2022
+ if (!is_read && !emit_stop && ((i + 1 ) != num_msgs )) {
2023
+ bool next_is_write =
2024
+ (msgs [i + 1 ].flags & I2C_MSG_RW_MASK ) == I2C_MSG_WRITE ;
2025
+ bool next_is_restart =
2026
+ ((msgs [i + 1 ].flags & I2C_MSG_RESTART ) == I2C_MSG_RESTART );
2027
+
2028
+ if (next_is_write && !next_is_restart ) {
2029
+ no_ending = true;
2030
+ }
2031
+ }
2032
+
2033
+ ret = mcux_i3c_do_one_xfer (base , dev_data , addr , true,
2034
+ msgs [i ].buf , msgs [i ].len ,
2035
+ is_read , emit_start , emit_stop , no_ending );
2036
+ if (ret < 0 ) {
2037
+ goto out_xfer_i2c_stop_unlock ;
2038
+ }
2089
2039
}
2090
2040
2041
+ ret = 0 ;
2042
+
2043
+ out_xfer_i2c_stop_unlock :
2044
+ mcux_i3c_request_emit_stop (base , true);
2045
+
2046
+ out_xfer_i2c_unlock :
2047
+ mcux_i3c_errwarn_clear_all_nowait (base );
2048
+ mcux_i3c_status_clear_all (base );
2049
+
2050
+ mcux_i3c_interrupt_enable (base , intmask );
2051
+
2052
+ k_sem_give (& dev_data -> lock );
2053
+
2091
2054
return ret ;
2092
2055
}
2093
2056
0 commit comments