1 /*
2 * Copyright 2024 NXP
3 * Copyright (c) 2018 Phytec Messtechnik GmbH
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT nxp_fxls8974
9
10 #include "fxls8974.h"
11 #include <zephyr/sys/util.h>
12 #include <zephyr/sys/__assert.h>
13 #include <zephyr/logging/log.h>
14 #include <stdlib.h>
15
16 LOG_MODULE_REGISTER(FXLS8974, CONFIG_SENSOR_LOG_LEVEL);
17
18 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
19 #define DIR_READ(a) ((a) & 0x7f)
20 #define DIR_WRITE(a) ((a) | BIT(7))
21 #define ADDR_7(a) ((a) & BIT(7))
22
fxls8974_transceive(const struct device * dev,void * data,size_t length)23 int fxls8974_transceive(const struct device *dev,
24 void *data, size_t length)
25 {
26 const struct fxls8974_config *cfg = dev->config;
27 const struct spi_buf buf = { .buf = data, .len = length };
28 const struct spi_buf_set s = { .bufs = &buf, .count = 1 };
29
30 return spi_transceive_dt(&cfg->bus_cfg.spi, &s, &s);
31 }
32
fxls8974_read_spi(const struct device * dev,uint8_t reg,void * data,size_t length)33 int fxls8974_read_spi(const struct device *dev,
34 uint8_t reg,
35 void *data,
36 size_t length)
37 {
38 const struct fxls8974_config *cfg = dev->config;
39
40 /* Reads must clock out a dummy byte after sending the address. */
41 uint8_t reg_buf[3] = { DIR_READ(reg), ADDR_7(reg), 0 };
42 const struct spi_buf buf[2] = {
43 { .buf = reg_buf, .len = 3 },
44 { .buf = data, .len = length }
45 };
46 const struct spi_buf_set tx = { .bufs = buf, .count = 1 };
47 const struct spi_buf_set rx = { .bufs = buf, .count = 2 };
48
49 return spi_transceive_dt(&cfg->bus_cfg.spi, &tx, &rx);
50 }
51
fxls8974_byte_read_spi(const struct device * dev,uint8_t reg,uint8_t * byte)52 int fxls8974_byte_read_spi(const struct device *dev,
53 uint8_t reg,
54 uint8_t *byte)
55 {
56 /* Reads must clock out a dummy byte after sending the address. */
57 uint8_t data[] = { DIR_READ(reg), ADDR_7(reg), 0};
58 int ret;
59
60 ret = fxls8974_transceive(dev, data, sizeof(data));
61
62 *byte = data[2];
63
64 return ret;
65 }
66
fxls8974_byte_write_spi(const struct device * dev,uint8_t reg,uint8_t byte)67 int fxls8974_byte_write_spi(const struct device *dev,
68 uint8_t reg,
69 uint8_t byte)
70 {
71 uint8_t data[] = { DIR_WRITE(reg), ADDR_7(reg), byte };
72
73 return fxls8974_transceive(dev, data, sizeof(data));
74 }
75
fxls8974_reg_field_update_spi(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)76 int fxls8974_reg_field_update_spi(const struct device *dev,
77 uint8_t reg,
78 uint8_t mask,
79 uint8_t val)
80 {
81 uint8_t old_val;
82
83 if (fxls8974_byte_read_spi(dev, reg, &old_val) < 0) {
84 return -EIO;
85 }
86
87 return fxls8974_byte_write_spi(dev, reg, (old_val & ~mask) | (val & mask));
88 }
89
90 static const struct fxls8974_io_ops fxls8974_spi_ops = {
91 .read = fxls8974_read_spi,
92 .byte_read = fxls8974_byte_read_spi,
93 .byte_write = fxls8974_byte_write_spi,
94 .reg_field_update = fxls8974_reg_field_update_spi,
95 };
96 #endif
97
98 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
fxls8974_read_i2c(const struct device * dev,uint8_t reg,void * data,size_t length)99 int fxls8974_read_i2c(const struct device *dev,
100 uint8_t reg,
101 void *data,
102 size_t length)
103 {
104 const struct fxls8974_config *cfg = dev->config;
105
106 return i2c_burst_read_dt(&cfg->bus_cfg.i2c, reg, data, length);
107 }
108
fxls8974_byte_read_i2c(const struct device * dev,uint8_t reg,uint8_t * byte)109 int fxls8974_byte_read_i2c(const struct device *dev,
110 uint8_t reg,
111 uint8_t *byte)
112 {
113 const struct fxls8974_config *cfg = dev->config;
114
115 return i2c_reg_read_byte_dt(&cfg->bus_cfg.i2c, reg, byte);
116 }
117
fxls8974_byte_write_i2c(const struct device * dev,uint8_t reg,uint8_t byte)118 int fxls8974_byte_write_i2c(const struct device *dev,
119 uint8_t reg,
120 uint8_t byte)
121 {
122 const struct fxls8974_config *cfg = dev->config;
123
124 return i2c_reg_write_byte_dt(&cfg->bus_cfg.i2c, reg, byte);
125 }
126
fxls8974_reg_field_update_i2c(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)127 int fxls8974_reg_field_update_i2c(const struct device *dev,
128 uint8_t reg,
129 uint8_t mask,
130 uint8_t val)
131 {
132 const struct fxls8974_config *cfg = dev->config;
133
134 return i2c_reg_update_byte_dt(&cfg->bus_cfg.i2c, reg, mask, val);
135 }
136 static const struct fxls8974_io_ops fxls8974_i2c_ops = {
137 .read = fxls8974_read_i2c,
138 .byte_read = fxls8974_byte_read_i2c,
139 .byte_write = fxls8974_byte_write_i2c,
140 .reg_field_update = fxls8974_reg_field_update_i2c,
141 };
142 #endif
143
fxls8974_set_odr(const struct device * dev,const struct sensor_value * val,enum fxls8974_wake mode)144 static int fxls8974_set_odr(const struct device *dev,
145 const struct sensor_value *val, enum fxls8974_wake mode)
146 {
147 const struct fxls8974_config *cfg = dev->config;
148 uint8_t odr;
149 /* val int32 */
150 switch (val->val1) {
151 case 3200:
152 odr = FXLS8974_CTRLREG3_ODR_RATE_3200;
153 break;
154 case 800:
155 odr = FXLS8974_CTRLREG3_ODR_RATE_800;
156 break;
157 case 400:
158 odr = FXLS8974_CTRLREG3_ODR_RATE_400;
159 break;
160 case 200:
161 odr = FXLS8974_CTRLREG3_ODR_RATE_200;
162 break;
163 case 100:
164 odr = FXLS8974_CTRLREG3_ODR_RATE_100;
165 break;
166 case 50:
167 odr = FXLS8974_CTRLREG3_ODR_RATE_50;
168 break;
169 case 25:
170 odr = FXLS8974_CTRLREG3_ODR_RATE_25;
171 break;
172 case 12:
173 if (val->val2 == 500000) {
174 odr = FXLS8974_CTRLREG3_ODR_RATE_12_5;
175 break;
176 }
177 return -EINVAL;
178 case 6:
179 if (val->val2 == 250000) {
180 odr = FXLS8974_CTRLREG3_ODR_RATE_6_25;
181 break;
182 }
183 return -EINVAL;
184 case 3:
185 if (val->val2 == 125000) {
186 odr = FXLS8974_CTRLREG3_ODR_RATE_3_125;
187 break;
188 }
189 return -EINVAL;
190 case 1:
191 if (val->val2 == 563000) {
192 odr = FXLS8974_CTRLREG3_ODR_RATE_1_563;
193 break;
194 }
195 return -EINVAL;
196 case 0:
197 if (val->val2 == 781000) {
198 odr = FXLS8974_CTRLREG3_ODR_RATE_0_781;
199 break;
200 }
201 return -EINVAL;
202 default:
203 return -EINVAL;
204 }
205
206 LOG_DBG("Set %s ODR to 0x%02x", (mode == FXLS8974_WAKE) ? "wake" : "sleep", odr);
207
208 /* Change the attribute and restore active mode. */
209 if (mode == FXLS8974_WAKE) {
210 return cfg->ops->reg_field_update(dev, FXLS8974_REG_CTRLREG3,
211 FXLS8974_CTRLREG3_WAKE_ODR_MASK,
212 odr<<4);
213 } else {
214 return cfg->ops->reg_field_update(dev, FXLS8974_REG_CTRLREG3,
215 FXLS8974_CTRLREG3_SLEEP_ODR_MASK,
216 odr);
217 }
218 }
219
fxls8974_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)220 static int fxls8974_attr_set(const struct device *dev,
221 enum sensor_channel chan,
222 enum sensor_attribute attr,
223 const struct sensor_value *val)
224 {
225 if (chan != SENSOR_CHAN_ALL) {
226 return -ENOTSUP;
227 }
228
229 switch (attr) {
230 case SENSOR_ATTR_SAMPLING_FREQUENCY:
231 return fxls8974_set_odr(dev, val, FXLS8974_WAKE);
232 default:
233 return -ENOTSUP;
234 }
235 return 0;
236 }
237
fxls8974_sample_fetch(const struct device * dev,enum sensor_channel ch)238 static int fxls8974_sample_fetch(const struct device *dev, enum sensor_channel ch)
239 {
240 const struct fxls8974_config *cfg = dev->config;
241 struct fxls8974_data *data = dev->data;
242 uint8_t buf[FXLS8974_MAX_NUM_BYTES];
243 int16_t *raw;
244 int ret = 0;
245 int i;
246
247 k_sem_take(&data->sem, K_FOREVER);
248
249 /* Read all the accel channels in one I2C/SPI transaction. */
250 if (cfg->ops->read(dev, FXLS8974_REG_OUTXLSB, buf, FXLS8974_MAX_ACCEL_BYTES)) {
251 LOG_ERR("Could not fetch accelerometer data");
252 ret = -EIO;
253 goto exit;
254 }
255
256 if (cfg->ops->byte_read(dev, FXLS8974_REG_OUTTEMP, buf+FXLS8974_DATA_TEMP_OFFSET)) {
257 LOG_ERR("Could not fetch temperature");
258 ret = -EIO;
259 goto exit;
260 }
261
262 /* Parse the buf into raw channel data (16-bit integers). To save
263 * RAM, store the data in raw format and wait to convert to the
264 * normalized sensor_value type until later.
265 */
266 __ASSERT(FXLS8974_MAX_NUM_CHANNELS <= ARRAY_SIZE(data->raw),
267 "Too many channels");
268
269 raw = &data->raw[FXLS8974_CHANNEL_ACCEL_X];
270
271 for (i = 0; i < FXLS8974_MAX_ACCEL_BYTES; i += 2) {
272 *raw++ = (buf[i+1] << 8) | (buf[i]);
273 }
274
275 *raw = *(buf+FXLS8974_MAX_ACCEL_BYTES);
276
277 exit:
278 k_sem_give(&data->sem);
279
280 return ret;
281 }
282
fxls8974_accel_convert(struct sensor_value * val,int16_t raw,uint8_t fsr)283 static void fxls8974_accel_convert(struct sensor_value *val, int16_t raw,
284 uint8_t fsr)
285 {
286 int64_t micro_ms2;
287
288 /* Convert units to micro m/s^2. */
289 micro_ms2 = (raw * SENSOR_G) >> fsr;
290
291 /* The maximum possible value is 16g, which in units of micro m/s^2
292 * always fits into 32-bits. Cast down to int32_t so we can use a
293 * faster divide.
294 */
295 val->val1 = (int32_t) micro_ms2 / 1000000;
296 val->val2 = (int32_t) micro_ms2 % 1000000;
297 }
298
fxls8974_get_accel_data(const struct device * dev,struct sensor_value * val,enum sensor_channel ch)299 static int fxls8974_get_accel_data(const struct device *dev,
300 struct sensor_value *val, enum sensor_channel ch)
301 {
302 const struct fxls8974_config *cfg = dev->config;
303 struct fxls8974_data *data = dev->data;
304 int16_t *raw;
305 uint8_t fsr;
306
307 k_sem_take(&data->sem, K_FOREVER);
308
309 if (cfg->ops->byte_read(dev, FXLS8974_REG_CTRLREG1, &fsr)) {
310 LOG_ERR("Could not read scale settings");
311 return -EIO;
312 }
313
314 fsr = (fsr & FXLS8974_CTRLREG1_FSR_MASK) >> 1;
315 switch (fsr) {
316 case 0b00:
317 fsr = 10U;
318 break;
319 case 0b01:
320 fsr = 9U;
321 break;
322 case 0b10:
323 fsr = 8U;
324 break;
325 case 0b11:
326 fsr = 7U;
327 break;
328 }
329
330 if (ch == SENSOR_CHAN_ACCEL_XYZ) {
331 raw = &data->raw[FXLS8974_CHANNEL_ACCEL_X];
332 for (int i = 0; i < FXLS8974_MAX_ACCEL_CHANNELS; i++) {
333 fxls8974_accel_convert(val++, *raw++, fsr);
334 }
335 } else {
336 switch (ch) {
337 case SENSOR_CHAN_ACCEL_X:
338 raw = &data->raw[FXLS8974_CHANNEL_ACCEL_X];
339 break;
340 case SENSOR_CHAN_ACCEL_Y:
341 raw = &data->raw[FXLS8974_CHANNEL_ACCEL_Y];
342 break;
343 case SENSOR_CHAN_ACCEL_Z:
344 raw = &data->raw[FXLS8974_CHANNEL_ACCEL_Z];
345 break;
346 default:
347 return -ENOTSUP;
348 }
349 fxls8974_accel_convert(val, *raw, fsr);
350 }
351 k_sem_give(&data->sem);
352
353 return 0;
354 }
355
fxls8974_get_temp_data(const struct device * dev,struct sensor_value * val)356 static int fxls8974_get_temp_data(const struct device *dev, struct sensor_value *val)
357 {
358 struct fxls8974_data *data = dev->data;
359 int16_t *raw;
360
361 k_sem_take(&data->sem, K_FOREVER);
362 raw = &data->raw[FXLS8974_CHANNEL_TEMP];
363 val->val1 = *raw+FXLS8974_ZERO_TEMP;
364 k_sem_give(&data->sem);
365
366 return 0;
367 }
368
fxls8974_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)369 static int fxls8974_channel_get(const struct device *dev,
370 enum sensor_channel chan,
371 struct sensor_value *val)
372 {
373
374 switch (chan) {
375 case SENSOR_CHAN_ALL:
376 if (fxls8974_get_accel_data(dev, val, SENSOR_CHAN_ACCEL_XYZ)) {
377 return -EIO;
378 }
379
380 val += FXLS8974_MAX_ACCEL_CHANNELS;
381
382 if (fxls8974_get_temp_data(dev, val)) {
383 return -EIO;
384 }
385 break;
386 case SENSOR_CHAN_ACCEL_XYZ:
387 return fxls8974_get_accel_data(dev, val, SENSOR_CHAN_ACCEL_XYZ);
388 case SENSOR_CHAN_ACCEL_X:
389 __fallthrough;
390 case SENSOR_CHAN_ACCEL_Y:
391 __fallthrough;
392 case SENSOR_CHAN_ACCEL_Z:
393 return fxls8974_get_accel_data(dev, val, chan);
394 case SENSOR_CHAN_AMBIENT_TEMP:
395 return fxls8974_get_temp_data(dev, val);
396 default:
397 LOG_ERR("Unsupported channel");
398 return -ENOTSUP;
399 }
400
401 return 0;
402 }
403
fxls8974_get_active(const struct device * dev,enum fxls8974_active * active)404 int fxls8974_get_active(const struct device *dev, enum fxls8974_active *active)
405 {
406 const struct fxls8974_config *cfg = dev->config;
407 uint8_t val;
408
409 if (cfg->ops->byte_read(dev, FXLS8974_REG_CTRLREG1, &val)) {
410 LOG_ERR("Could not get active setting");
411 return -EIO;
412 }
413 val &= FXLS8974_CTRLREG1_ACTIVE_MASK;
414
415 *active = val;
416
417 return 0;
418 }
419
fxls8974_set_active(const struct device * dev,enum fxls8974_active active)420 int fxls8974_set_active(const struct device *dev, enum fxls8974_active active)
421 {
422 const struct fxls8974_config *cfg = dev->config;
423
424 return cfg->ops->reg_field_update(dev, FXLS8974_REG_CTRLREG1,
425 FXLS8974_CTRLREG1_ACTIVE_MASK, active);
426 }
427
fxls8974_print_config(const struct device * dev)428 static void fxls8974_print_config(const struct device *dev)
429 {
430 const struct fxls8974_config *cfg = dev->config;
431 uint8_t regVal[5];
432
433 if (cfg->ops->read(dev, FXLS8974_REG_CTRLREG1, regVal, 5)) {
434 LOG_ERR("Failed to read config registers");
435 }
436 LOG_DBG("Current config:\n\r"
437 "CFG: 0x%02x CFG2: 0x%02x CFG3: 0x%02x CFG4: 0x%02x CFG5: 0x%02x",
438 regVal[0], regVal[1], regVal[2], regVal[3], regVal[4]);
439 }
440
fxls8974_init(const struct device * dev)441 static int fxls8974_init(const struct device *dev)
442 {
443 const struct fxls8974_config *cfg = dev->config;
444 struct fxls8974_data *data = dev->data;
445 struct sensor_value odr = {.val1 = 6, .val2 = 250000};
446 uint8_t regVal;
447
448 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
449 const struct i2c_dt_spec i2c_spec = cfg->bus_cfg.i2c;
450
451 if (cfg->inst_on_bus == FXLS8974_BUS_I2C) {
452 if (!i2c_is_ready_dt(&i2c_spec)) {
453 LOG_ERR("I2C bus device not ready");
454 return -ENODEV;
455 }
456 }
457 #endif
458
459 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
460 const struct spi_dt_spec spi_spec = cfg->bus_cfg.spi;
461
462 if (cfg->inst_on_bus == FXLS8974_BUS_SPI) {
463 if (!spi_is_ready_dt(&spi_spec)) {
464 LOG_ERR("SPI bus device not ready");
465 return -ENODEV;
466 }
467 }
468 #endif
469
470 /* Software reset the sensor. Upon issuing a software
471 * reset command over the I2C interface, the sensor
472 * immediately resets and does not send any
473 * acknowledgment (ACK) of the written byte to the
474 * master. Therefore, do not check the return code of
475 * the I2C transaction.
476 */
477 cfg->ops->byte_write(dev, FXLS8974_REG_CTRLREG1,
478 FXLS8974_CTRLREG1_RST_MASK);
479
480 /* The sensor requires us to wait 1 ms after a reset before
481 * attempting further communications.
482 */
483 k_busy_wait(USEC_PER_MSEC);
484
485 /*
486 * Read the WHOAMI register to make sure we are talking to FXLS8974 or
487 * compatible device and not some other type of device that happens to
488 * have the same I2C address.
489 */
490 if (cfg->ops->byte_read(dev, FXLS8974_REG_WHOAMI,
491 &data->whoami)) {
492 LOG_ERR("Could not get WHOAMI value");
493 return -EIO;
494 }
495
496 if (data->whoami == WHOAMI_ID_FXLS8974) {
497 LOG_DBG("Device ID 0x%x, FXLS8974", data->whoami);
498 } else {
499 LOG_ERR("Unknown Device ID 0x%x", data->whoami);
500 return -EIO;
501 }
502
503 if (fxls8974_get_active(dev, (enum fxls8974_active *)®Val)) {
504 LOG_ERR("Failed to set standby mode");
505 return -EIO;
506 }
507
508 if (regVal != FXLS8974_ACTIVE_OFF) {
509 LOG_ERR("Not in standby mode");
510 return -EIO;
511 }
512
513 if (cfg->ops->byte_write(dev, FXLS8974_REG_CTRLREG4,
514 FXLS8974_CTRLREG4_INT_POL_HIGH)) {
515 LOG_ERR("Could not set up register 4");
516 return -EIO;
517 }
518 if (cfg->ops->byte_read(dev, FXLS8974_REG_CTRLREG4, ®Val)) {
519 LOG_ERR("Could not get CTRL_REG4 value");
520 return -EIO;
521 }
522
523 if (regVal != FXLS8974_CTRLREG4_INT_POL_HIGH) {
524 LOG_ERR("CTRLREG4 is not set up properly");
525 return -EIO;
526 }
527
528 if (fxls8974_set_odr(dev, &odr, FXLS8974_WAKE)) {
529 LOG_ERR("Could not set default data rate");
530 return -EIO;
531 }
532
533 /* Set the +-2G mode */
534 if (cfg->ops->byte_write(dev, FXLS8974_REG_CTRLREG1,
535 FXLS8974_CTRLREG1_FSR_2G)) {
536 LOG_ERR("Could not set range");
537 return -EIO;
538 }
539
540 if (cfg->ops->byte_read(dev, FXLS8974_REG_CTRLREG1,
541 ®Val)) {
542 LOG_ERR("Could not ret CTRL_REG1 value");
543 return -EIO;
544 }
545
546 if ((regVal & FXLS8974_CTRLREG1_FSR_MASK) != FXLS8974_CTRLREG1_FSR_2G) {
547 LOG_ERR("Wrong range selected!");
548 return -EIO;
549 }
550
551 k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT);
552
553 #if CONFIG_FXLS8974_TRIGGER
554 if (fxls8974_trigger_init(dev)) {
555 LOG_ERR("Could not initialize interrupts");
556 return -EIO;
557 }
558 #endif
559
560 if (fxls8974_set_active(dev, FXLS8974_ACTIVE_ON)) {
561 LOG_ERR("Could not set active mode");
562 return -EIO;
563 }
564
565 if (fxls8974_get_active(dev, (enum fxls8974_active *)®Val)) {
566 LOG_ERR("Failed to get active mode");
567 return -EIO;
568 }
569
570 if (regVal != FXLS8974_ACTIVE_ON) {
571 LOG_ERR("Not in active mode");
572 return -EIO;
573 }
574
575 fxls8974_print_config(dev);
576 k_sem_give(&data->sem);
577
578 LOG_DBG("Init complete");
579
580 return 0;
581 }
582
583 static DEVICE_API(sensor, fxls8974_driver_api) = {
584 .sample_fetch = fxls8974_sample_fetch,
585 .channel_get = fxls8974_channel_get,
586 .attr_set = fxls8974_attr_set,
587 #if CONFIG_FXLS8974_TRIGGER
588 .trigger_set = fxls8974_trigger_set,
589 #endif
590 };
591
592 #define FXLS8974_CONFIG_I2C(n) \
593 .bus_cfg = { .i2c = I2C_DT_SPEC_INST_GET(n) }, \
594 .ops = &fxls8974_i2c_ops, \
595 .range = DT_INST_PROP(n, range), \
596 .inst_on_bus = FXLS8974_BUS_I2C,
597
598 #define FXLS8974_CONFIG_SPI(n) \
599 .bus_cfg = { .spi = SPI_DT_SPEC_INST_GET(n, \
600 SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0) }, \
601 .ops = &fxls8974_spi_ops, \
602 .range = DT_INST_PROP(n, range), \
603 .inst_on_bus = FXLS8974_BUS_SPI, \
604
605 #define FXLS8974_SPI_OPERATION (SPI_WORD_SET(8) | \
606 SPI_OP_MODE_MASTER) \
607
608 #define FXLS8974_INTM_PROPS(n, m) \
609 .int_gpio = GPIO_DT_SPEC_INST_GET(n, int##m##_gpios),
610
611 #define FXLS8974_INT_PROPS(n) \
612 COND_CODE_1(CONFIG_FXLS8974_DRDY_INT1, \
613 (FXLS8974_INTM_PROPS(n, 1)), \
614 (FXLS8974_INTM_PROPS(n, 2)))
615
616 #define FXLS8974_INT(n) \
617 COND_CODE_1(CONFIG_FXLS8974_TRIGGER, \
618 (FXLS8974_INT_PROPS(n)), \
619 ())
620
621 #define FXLS8974_INIT(n) \
622 static const struct fxls8974_config fxls8974_config_##n = { \
623 COND_CODE_1(DT_INST_ON_BUS(n, spi), \
624 (FXLS8974_CONFIG_SPI(n)), \
625 (FXLS8974_CONFIG_I2C(n))) \
626 FXLS8974_INT(n) \
627 }; \
628 \
629 static struct fxls8974_data fxls8974_data_##n; \
630 \
631 SENSOR_DEVICE_DT_INST_DEFINE(n, \
632 fxls8974_init, \
633 NULL, \
634 &fxls8974_data_##n, \
635 &fxls8974_config_##n, \
636 POST_KERNEL, \
637 CONFIG_SENSOR_INIT_PRIORITY, \
638 &fxls8974_driver_api);
639
640 DT_INST_FOREACH_STATUS_OKAY(FXLS8974_INIT)
641