@@ -951,6 +951,20 @@ static int lsm6dsv16x_init_chip(const struct device *dev)
951
951
uint8_t chip_id ;
952
952
uint8_t odr , fs ;
953
953
954
+ #if DT_ANY_INST_ON_BUS_STATUS_OKAY (i3c )
955
+ if (cfg -> i3c .bus != NULL ) {
956
+ /*
957
+ * Need to grab the pointer to the I3C device descriptor
958
+ * before we can talk to the sensor.
959
+ */
960
+ lsm6dsv16x -> i3c_dev = i3c_device_find (cfg -> i3c .bus , & cfg -> i3c .dev_id );
961
+ if (lsm6dsv16x -> i3c_dev == NULL ) {
962
+ LOG_ERR ("Cannot find I3C device descriptor" );
963
+ return - ENODEV ;
964
+ }
965
+ }
966
+ #endif
967
+
954
968
/* All registers except 0x01 are different between banks, including the WHO_AM_I
955
969
* register and the register used for a SW reset. If the lsm6dsv16x wasn't on the user
956
970
* bank when it reset, then both the chip id check and the sw reset will fail unless we
@@ -973,13 +987,26 @@ static int lsm6dsv16x_init_chip(const struct device *dev)
973
987
return - EIO ;
974
988
}
975
989
976
- /* reset device (sw_por) */
977
- if (lsm6dsv16x_reset_set (ctx , LSM6DSV16X_GLOBAL_RST ) < 0 ) {
978
- return - EIO ;
979
- }
990
+ /* Resetting the whole device while using I3C will also reset the DA, therefore perform
991
+ * only a software reset if the bus is I3C. It should be assumed that the device was
992
+ * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus
993
+ * initialization.
994
+ */
995
+ if (ON_I3C_BUS (cfg )) {
996
+ /* Restore default configuration */
997
+ lsm6dsv16x_reset_set (ctx , LSM6DSV16X_RESTORE_CAL_PARAM );
998
+
999
+ /* wait 150us as reported in AN5763 */
1000
+ k_sleep (K_USEC (150 ));
1001
+ } else {
1002
+ /* reset device (sw_por) */
1003
+ if (lsm6dsv16x_reset_set (ctx , LSM6DSV16X_GLOBAL_RST ) < 0 ) {
1004
+ return - EIO ;
1005
+ }
980
1006
981
- /* wait 30ms as reported in AN5763 */
982
- k_sleep (K_MSEC (30 ));
1007
+ /* wait 30ms as reported in AN5763 */
1008
+ k_sleep (K_MSEC (30 ));
1009
+ }
983
1010
984
1011
fs = cfg -> accel_range ;
985
1012
LOG_DBG ("accel range is %d" , fs );
@@ -1012,6 +1039,23 @@ static int lsm6dsv16x_init_chip(const struct device *dev)
1012
1039
return - EIO ;
1013
1040
}
1014
1041
1042
+ #if DT_ANY_INST_ON_BUS_STATUS_OKAY (i3c )
1043
+ if (IS_ENABLED (CONFIG_LSM6DSV16X_STREAM ) && (ON_I3C_BUS (cfg ))) {
1044
+ /*
1045
+ * Set MRL to the Max Size of the FIFO so the entire FIFO can be read
1046
+ * out at once
1047
+ */
1048
+ struct i3c_ccc_mrl setmrl = {
1049
+ .len = 0x0700 ,
1050
+ .ibi_len = lsm6dsv16x -> i3c_dev -> data_length .max_ibi ,
1051
+ };
1052
+ if (i3c_ccc_do_setmrl (lsm6dsv16x -> i3c_dev , & setmrl ) < 0 ) {
1053
+ LOG_ERR ("failed to set mrl" );
1054
+ return - EIO ;
1055
+ }
1056
+ }
1057
+ #endif
1058
+
1015
1059
if (lsm6dsv16x_block_data_update_set (ctx , 1 ) < 0 ) {
1016
1060
LOG_DBG ("failed to set BDU mode" );
1017
1061
return - EIO ;
@@ -1164,15 +1208,55 @@ static int lsm6dsv16x_init(const struct device *dev)
1164
1208
static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \
1165
1209
LSM6DSV16X_CONFIG_I2C(inst); \
1166
1210
1211
+ /*
1212
+ * Instantiation macros used when a device is on an I3C bus.
1213
+ */
1214
+
1215
+ #define LSM6DSV16X_I3C_RTIO_DEFINE (inst ) \
1216
+ I3C_DT_IODEV_DEFINE(lsm6dsv16x_i3c_iodev_##inst, DT_DRV_INST(inst)); \
1217
+ RTIO_DEFINE(lsm6dsv16x_rtio_ctx_##inst, 4, 4);
1218
+
1219
+ #define LSM6DSV16X_CONFIG_I3C (inst ) \
1220
+ { \
1221
+ STMEMSC_CTX_I3C(&lsm6dsv16x_config_##inst.stmemsc_cfg), \
1222
+ .stmemsc_cfg = { \
1223
+ .i3c = &lsm6dsv16x_data_##inst.i3c_dev, \
1224
+ }, \
1225
+ .i3c.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
1226
+ .i3c.dev_id = I3C_DEVICE_ID_DT_INST(inst), \
1227
+ IF_ENABLED(CONFIG_LSM6DSV16X_TRIGGER, \
1228
+ (.int_en_i3c = DT_INST_PROP(inst, int_en_i3c), \
1229
+ .bus_act_sel = DT_INST_ENUM_IDX(inst, bus_act_sel_us),)) \
1230
+ LSM6DSV16X_CONFIG_COMMON(inst) \
1231
+ }
1232
+
1233
+ #define LSM6DSV16X_DEFINE_I3C (inst ) \
1234
+ IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, (LSM6DSV16X_I3C_RTIO_DEFINE(inst))); \
1235
+ static struct lsm6dsv16x_data lsm6dsv16x_data_##inst = { \
1236
+ IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \
1237
+ (.rtio_ctx = &lsm6dsv16x_rtio_ctx_##inst, \
1238
+ .iodev = &lsm6dsv16x_i3c_iodev_##inst, \
1239
+ .bus_type = BUS_I3C,)) \
1240
+ }; \
1241
+ static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \
1242
+ LSM6DSV16X_CONFIG_I3C(inst); \
1243
+
1244
+ #define LSM6DSV16X_DEFINE_I3C_OR_I2C (inst ) \
1245
+ COND_CODE_0(DT_INST_PROP_BY_IDX(inst, reg, 1), \
1246
+ (LSM6DSV16X_DEFINE_I2C(inst)), \
1247
+ (LSM6DSV16X_DEFINE_I3C(inst)))
1248
+
1167
1249
/*
1168
1250
* Main instantiation macro. Use of COND_CODE_1() selects the right
1169
1251
* bus-specific macro at preprocessor time.
1170
1252
*/
1171
1253
1172
- #define LSM6DSV16X_DEFINE (inst ) \
1173
- COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
1174
- (LSM6DSV16X_DEFINE_SPI(inst)), \
1175
- (LSM6DSV16X_DEFINE_I2C(inst))); \
1176
- LSM6DSV16X_DEVICE_INIT(inst)
1254
+ #define LSM6DSV16X_DEFINE (inst ) \
1255
+ COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
1256
+ (LSM6DSV16X_DEFINE_SPI(inst)), \
1257
+ (COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \
1258
+ (LSM6DSV16X_DEFINE_I3C_OR_I2C(inst)), \
1259
+ (LSM6DSV16X_DEFINE_I2C(inst))))); \
1260
+ LSM6DSV16X_DEVICE_INIT(inst)
1177
1261
1178
1262
DT_INST_FOREACH_STATUS_OKAY (LSM6DSV16X_DEFINE )
0 commit comments