1 /* ST Microelectronics IIS2ICLX 2-axis accelerometer sensor driver
2 *
3 * Copyright (c) 2020 STMicroelectronics
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Datasheet:
8 * https://www.st.com/resource/en/datasheet/iis2iclx.pdf
9 */
10
11 #define DT_DRV_COMPAT st_iis2iclx
12
13 #include <zephyr/drivers/sensor.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/device.h>
16 #include <zephyr/init.h>
17 #include <string.h>
18 #include <zephyr/sys/__assert.h>
19 #include <zephyr/logging/log.h>
20
21 #include "iis2iclx.h"
22
23 LOG_MODULE_REGISTER(IIS2ICLX, CONFIG_SENSOR_LOG_LEVEL);
24
25 static const uint16_t iis2iclx_odr_map[] = {0, 12, 26, 52, 104, 208, 416, 833,
26 1660, 3330, 6660};
27
iis2iclx_freq_to_odr_val(uint16_t freq)28 static int iis2iclx_freq_to_odr_val(uint16_t freq)
29 {
30 size_t i;
31
32 for (i = 0; i < ARRAY_SIZE(iis2iclx_odr_map); i++) {
33 if (freq <= iis2iclx_odr_map[i]) {
34 return i;
35 }
36 }
37
38 return -EINVAL;
39 }
40
iis2iclx_odr_to_freq_val(uint16_t odr)41 static int iis2iclx_odr_to_freq_val(uint16_t odr)
42 {
43 /* for valid index, return value from map */
44 if (odr < ARRAY_SIZE(iis2iclx_odr_map)) {
45 return iis2iclx_odr_map[odr];
46 }
47
48 /* invalid index, return last entry */
49 return iis2iclx_odr_map[ARRAY_SIZE(iis2iclx_odr_map) - 1];
50 }
51
52 static const uint16_t iis2iclx_accel_fs_map[] = {500, 3000, 1000, 2000}; /* fs in mg */
53 static const uint16_t iis2iclx_accel_fs_sens[] = {1, 8, 2, 4};
54
iis2iclx_accel_range_to_fs_val(int32_t range)55 static int iis2iclx_accel_range_to_fs_val(int32_t range)
56 {
57 size_t i;
58
59 for (i = 0; i < ARRAY_SIZE(iis2iclx_accel_fs_map); i++) {
60 if (range == iis2iclx_accel_fs_map[i]) {
61 return i;
62 }
63 }
64
65 return -EINVAL;
66 }
67
iis2iclx_reboot(const struct device * dev)68 static inline int iis2iclx_reboot(const struct device *dev)
69 {
70 const struct iis2iclx_config *cfg = dev->config;
71
72 if (iis2iclx_boot_set((stmdev_ctx_t *)&cfg->ctx, 1) < 0) {
73 return -EIO;
74 }
75
76 /* Wait sensor turn-on time as per datasheet */
77 k_msleep(35);
78
79 return 0;
80 }
81
iis2iclx_accel_set_fs_raw(const struct device * dev,uint8_t fs)82 static int iis2iclx_accel_set_fs_raw(const struct device *dev, uint8_t fs)
83 {
84 const struct iis2iclx_config *cfg = dev->config;
85 struct iis2iclx_data *data = dev->data;
86
87 if (iis2iclx_xl_full_scale_set((stmdev_ctx_t *)&cfg->ctx, fs) < 0) {
88 return -EIO;
89 }
90
91 data->accel_fs = fs;
92
93 return 0;
94 }
95
iis2iclx_accel_set_odr_raw(const struct device * dev,uint8_t odr)96 static int iis2iclx_accel_set_odr_raw(const struct device *dev, uint8_t odr)
97 {
98 const struct iis2iclx_config *cfg = dev->config;
99 struct iis2iclx_data *data = dev->data;
100
101 if (iis2iclx_xl_data_rate_set((stmdev_ctx_t *)&cfg->ctx, odr) < 0) {
102 return -EIO;
103 }
104
105 data->accel_freq = iis2iclx_odr_to_freq_val(odr);
106
107 return 0;
108 }
109
iis2iclx_accel_odr_set(const struct device * dev,uint16_t freq)110 static int iis2iclx_accel_odr_set(const struct device *dev, uint16_t freq)
111 {
112 int odr;
113
114 odr = iis2iclx_freq_to_odr_val(freq);
115 if (odr < 0) {
116 return odr;
117 }
118
119 if (iis2iclx_accel_set_odr_raw(dev, odr) < 0) {
120 LOG_ERR("failed to set accelerometer sampling rate");
121 return -EIO;
122 }
123
124 return 0;
125 }
126
iis2iclx_accel_range_set(const struct device * dev,int32_t range)127 static int iis2iclx_accel_range_set(const struct device *dev, int32_t range)
128 {
129 int fs;
130 struct iis2iclx_data *data = dev->data;
131
132 fs = iis2iclx_accel_range_to_fs_val(range * 1000); /* pass range in mg */
133 if (fs < 0) {
134 return fs;
135 }
136
137 if (iis2iclx_accel_set_fs_raw(dev, fs) < 0) {
138 LOG_ERR("failed to set accelerometer full-scale");
139 return -EIO;
140 }
141
142 data->acc_gain = (iis2iclx_accel_fs_sens[fs] * GAIN_UNIT_XL);
143 return 0;
144 }
145
iis2iclx_accel_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)146 static int iis2iclx_accel_config(const struct device *dev,
147 enum sensor_channel chan,
148 enum sensor_attribute attr,
149 const struct sensor_value *val)
150 {
151 switch (attr) {
152 case SENSOR_ATTR_FULL_SCALE:
153 return iis2iclx_accel_range_set(dev, sensor_ms2_to_g(val));
154 case SENSOR_ATTR_SAMPLING_FREQUENCY:
155 return iis2iclx_accel_odr_set(dev, val->val1);
156 default:
157 LOG_ERR("Accel attribute not supported.");
158 return -ENOTSUP;
159 }
160
161 return 0;
162 }
163
iis2iclx_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)164 static int iis2iclx_attr_set(const struct device *dev,
165 enum sensor_channel chan,
166 enum sensor_attribute attr,
167 const struct sensor_value *val)
168 {
169 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
170 struct iis2iclx_data *data = dev->data;
171 #endif /* CONFIG_IIS2ICLX_SENSORHUB */
172
173 switch (chan) {
174 case SENSOR_CHAN_ACCEL_XYZ:
175 return iis2iclx_accel_config(dev, chan, attr, val);
176 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
177 case SENSOR_CHAN_MAGN_XYZ:
178 case SENSOR_CHAN_PRESS:
179 case SENSOR_CHAN_HUMIDITY:
180 if (!data->shub_inited) {
181 LOG_ERR("shub not inited.");
182 return -ENOTSUP;
183 }
184
185 return iis2iclx_shub_config(dev, chan, attr, val);
186 #endif /* CONFIG_IIS2ICLX_SENSORHUB */
187 default:
188 LOG_ERR("attr_set() not supported on this channel.");
189 return -ENOTSUP;
190 }
191
192 return 0;
193 }
194
iis2iclx_sample_fetch_accel(const struct device * dev)195 static int iis2iclx_sample_fetch_accel(const struct device *dev)
196 {
197 const struct iis2iclx_config *cfg = dev->config;
198 struct iis2iclx_data *data = dev->data;
199 int16_t buf[2];
200
201 if (iis2iclx_acceleration_raw_get((stmdev_ctx_t *)&cfg->ctx, buf) < 0) {
202 LOG_ERR("Failed to read sample");
203 return -EIO;
204 }
205
206 data->acc[0] = buf[0];
207 data->acc[1] = buf[1];
208
209 return 0;
210 }
211
212 #if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
iis2iclx_sample_fetch_temp(const struct device * dev)213 static int iis2iclx_sample_fetch_temp(const struct device *dev)
214 {
215 struct iis2iclx_data *data = dev->data;
216 const struct iis2iclx_config *cfg = dev->config;
217 int16_t buf;
218
219 if (iis2iclx_temperature_raw_get((stmdev_ctx_t *)&cfg->ctx, &buf) < 0) {
220 LOG_ERR("Failed to read sample");
221 return -EIO;
222 }
223
224 data->temp_sample = buf;
225
226 return 0;
227 }
228 #endif
229
230 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
iis2iclx_sample_fetch_shub(const struct device * dev)231 static int iis2iclx_sample_fetch_shub(const struct device *dev)
232 {
233 if (iis2iclx_shub_fetch_external_devs(dev) < 0) {
234 LOG_ERR("failed to read ext shub devices");
235 return -EIO;
236 }
237
238 return 0;
239 }
240 #endif /* CONFIG_IIS2ICLX_SENSORHUB */
241
iis2iclx_sample_fetch(const struct device * dev,enum sensor_channel chan)242 static int iis2iclx_sample_fetch(const struct device *dev,
243 enum sensor_channel chan)
244 {
245 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
246 struct iis2iclx_data *data = dev->data;
247 #endif /* CONFIG_IIS2ICLX_SENSORHUB */
248
249 switch (chan) {
250 case SENSOR_CHAN_ACCEL_XYZ:
251 iis2iclx_sample_fetch_accel(dev);
252 break;
253 #if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
254 case SENSOR_CHAN_DIE_TEMP:
255 iis2iclx_sample_fetch_temp(dev);
256 break;
257 #endif
258 case SENSOR_CHAN_ALL:
259 iis2iclx_sample_fetch_accel(dev);
260 #if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
261 iis2iclx_sample_fetch_temp(dev);
262 #endif
263 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
264 if (data->shub_inited) {
265 iis2iclx_sample_fetch_shub(dev);
266 }
267 #endif
268 break;
269 default:
270 return -ENOTSUP;
271 }
272
273 return 0;
274 }
275
iis2iclx_accel_convert(struct sensor_value * val,int raw_val,uint32_t sensitivity)276 static inline void iis2iclx_accel_convert(struct sensor_value *val, int raw_val,
277 uint32_t sensitivity)
278 {
279 int64_t dval;
280
281 /* Sensitivity is exposed in ug/LSB */
282 /* Convert to m/s^2 */
283 dval = (int64_t)(raw_val) * sensitivity;
284 sensor_ug_to_ms2(dval, val);
285 }
286
iis2iclx_accel_get_channel(enum sensor_channel chan,struct sensor_value * val,struct iis2iclx_data * data,uint32_t sensitivity)287 static inline int iis2iclx_accel_get_channel(enum sensor_channel chan,
288 struct sensor_value *val,
289 struct iis2iclx_data *data,
290 uint32_t sensitivity)
291 {
292 uint8_t i;
293
294 switch (chan) {
295 case SENSOR_CHAN_ACCEL_X:
296 iis2iclx_accel_convert(val, data->acc[0], sensitivity);
297 break;
298 case SENSOR_CHAN_ACCEL_Y:
299 iis2iclx_accel_convert(val, data->acc[1], sensitivity);
300 break;
301 case SENSOR_CHAN_ACCEL_XYZ:
302 for (i = 0; i < 2; i++) {
303 iis2iclx_accel_convert(val++, data->acc[i], sensitivity);
304 }
305 break;
306 default:
307 return -ENOTSUP;
308 }
309
310 return 0;
311 }
312
iis2iclx_accel_channel_get(enum sensor_channel chan,struct sensor_value * val,struct iis2iclx_data * data)313 static int iis2iclx_accel_channel_get(enum sensor_channel chan,
314 struct sensor_value *val,
315 struct iis2iclx_data *data)
316 {
317 return iis2iclx_accel_get_channel(chan, val, data, data->acc_gain);
318 }
319
320 #if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
iis2iclx_temp_channel_get(struct sensor_value * val,struct iis2iclx_data * data)321 static void iis2iclx_temp_channel_get(struct sensor_value *val,
322 struct iis2iclx_data *data)
323 {
324 /* val = temp_sample / 256 + 25 */
325 val->val1 = data->temp_sample / 256 + 25;
326 val->val2 = (data->temp_sample % 256) * (1000000 / 256);
327 }
328 #endif
329
330 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
iis2iclx_magn_convert(struct sensor_value * val,int raw_val,uint16_t sensitivity)331 static inline void iis2iclx_magn_convert(struct sensor_value *val, int raw_val,
332 uint16_t sensitivity)
333 {
334 double dval;
335
336 /* Sensitivity is exposed in ugauss/LSB */
337 dval = (double)(raw_val * sensitivity);
338 val->val1 = (int32_t)dval / 1000000;
339 val->val2 = (int32_t)dval % 1000000;
340 }
341
iis2iclx_magn_get_channel(enum sensor_channel chan,struct sensor_value * val,struct iis2iclx_data * data)342 static inline int iis2iclx_magn_get_channel(enum sensor_channel chan,
343 struct sensor_value *val,
344 struct iis2iclx_data *data)
345 {
346 int16_t sample[3];
347 int idx;
348
349 idx = iis2iclx_shub_get_idx(data->dev, SENSOR_CHAN_MAGN_XYZ);
350 if (idx < 0) {
351 LOG_ERR("external magn not supported");
352 return -ENOTSUP;
353 }
354
355
356 sample[0] = (int16_t)(data->ext_data[idx][0] |
357 (data->ext_data[idx][1] << 8));
358 sample[1] = (int16_t)(data->ext_data[idx][2] |
359 (data->ext_data[idx][3] << 8));
360 sample[2] = (int16_t)(data->ext_data[idx][4] |
361 (data->ext_data[idx][5] << 8));
362
363 switch (chan) {
364 case SENSOR_CHAN_MAGN_X:
365 iis2iclx_magn_convert(val, sample[0], data->magn_gain);
366 break;
367 case SENSOR_CHAN_MAGN_Y:
368 iis2iclx_magn_convert(val, sample[1], data->magn_gain);
369 break;
370 case SENSOR_CHAN_MAGN_Z:
371 iis2iclx_magn_convert(val, sample[2], data->magn_gain);
372 break;
373 case SENSOR_CHAN_MAGN_XYZ:
374 iis2iclx_magn_convert(val, sample[0], data->magn_gain);
375 iis2iclx_magn_convert(val + 1, sample[1], data->magn_gain);
376 iis2iclx_magn_convert(val + 2, sample[2], data->magn_gain);
377 break;
378 default:
379 return -ENOTSUP;
380 }
381
382 return 0;
383 }
384
iis2iclx_hum_convert(struct sensor_value * val,struct iis2iclx_data * data)385 static inline void iis2iclx_hum_convert(struct sensor_value *val,
386 struct iis2iclx_data *data)
387 {
388 float rh;
389 int16_t raw_val;
390 struct hts221_data *ht = &data->hts221;
391 int idx;
392
393 idx = iis2iclx_shub_get_idx(data->dev, SENSOR_CHAN_HUMIDITY);
394 if (idx < 0) {
395 LOG_DBG("external press/temp not supported");
396 return;
397 }
398
399 raw_val = ((int16_t)(data->ext_data[idx][0] |
400 (data->ext_data[idx][1] << 8)));
401
402 /* find relative humidty by linear interpolation */
403 rh = (ht->y1 - ht->y0) * raw_val + ht->x1 * ht->y0 - ht->x0 * ht->y1;
404 rh /= (ht->x1 - ht->x0);
405
406 /* convert humidity to integer and fractional part */
407 val->val1 = rh;
408 val->val2 = rh * 1000000;
409 }
410
iis2iclx_press_convert(struct sensor_value * val,struct iis2iclx_data * data)411 static inline void iis2iclx_press_convert(struct sensor_value *val,
412 struct iis2iclx_data *data)
413 {
414 int32_t raw_val;
415 int idx;
416
417 idx = iis2iclx_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
418 if (idx < 0) {
419 LOG_DBG("external press/temp not supported");
420 return;
421 }
422
423 raw_val = (int32_t)(data->ext_data[idx][0] |
424 (data->ext_data[idx][1] << 8) |
425 (data->ext_data[idx][2] << 16));
426
427 /* Pressure sensitivity is 4096 LSB/hPa */
428 /* Convert raw_val to val in kPa */
429 val->val1 = (raw_val >> 12) / 10;
430 val->val2 = (raw_val >> 12) % 10 * 100000 +
431 (((int32_t)((raw_val) & 0x0FFF) * 100000L) >> 12);
432 }
433
iis2iclx_temp_convert(struct sensor_value * val,struct iis2iclx_data * data)434 static inline void iis2iclx_temp_convert(struct sensor_value *val,
435 struct iis2iclx_data *data)
436 {
437 int16_t raw_val;
438 int idx;
439
440 idx = iis2iclx_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
441 if (idx < 0) {
442 LOG_DBG("external press/temp not supported");
443 return;
444 }
445
446 raw_val = (int16_t)(data->ext_data[idx][3] |
447 (data->ext_data[idx][4] << 8));
448
449 /* Temperature sensitivity is 100 LSB/deg C */
450 val->val1 = raw_val / 100;
451 val->val2 = (int32_t)raw_val % 100 * (10000);
452 }
453 #endif
454
iis2iclx_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)455 static int iis2iclx_channel_get(const struct device *dev,
456 enum sensor_channel chan,
457 struct sensor_value *val)
458 {
459 struct iis2iclx_data *data = dev->data;
460
461 switch (chan) {
462 case SENSOR_CHAN_ACCEL_X:
463 case SENSOR_CHAN_ACCEL_Y:
464 case SENSOR_CHAN_ACCEL_Z:
465 case SENSOR_CHAN_ACCEL_XYZ:
466 iis2iclx_accel_channel_get(chan, val, data);
467 break;
468 #if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
469 case SENSOR_CHAN_DIE_TEMP:
470 iis2iclx_temp_channel_get(val, data);
471 break;
472 #endif
473 #if defined(CONFIG_IIS2ICLX_SENSORHUB)
474 case SENSOR_CHAN_MAGN_X:
475 case SENSOR_CHAN_MAGN_Y:
476 case SENSOR_CHAN_MAGN_Z:
477 case SENSOR_CHAN_MAGN_XYZ:
478 if (!data->shub_inited) {
479 LOG_ERR("attr_set() shub not inited.");
480 return -ENOTSUP;
481 }
482
483 iis2iclx_magn_get_channel(chan, val, data);
484 break;
485
486 case SENSOR_CHAN_HUMIDITY:
487 if (!data->shub_inited) {
488 LOG_ERR("attr_set() shub not inited.");
489 return -ENOTSUP;
490 }
491
492 iis2iclx_hum_convert(val, data);
493 break;
494
495 case SENSOR_CHAN_PRESS:
496 if (!data->shub_inited) {
497 LOG_ERR("attr_set() shub not inited.");
498 return -ENOTSUP;
499 }
500
501 iis2iclx_press_convert(val, data);
502 break;
503
504 case SENSOR_CHAN_AMBIENT_TEMP:
505 if (!data->shub_inited) {
506 LOG_ERR("attr_set() shub not inited.");
507 return -ENOTSUP;
508 }
509
510 iis2iclx_temp_convert(val, data);
511 break;
512 #endif
513 default:
514 return -ENOTSUP;
515 }
516
517 return 0;
518 }
519
520 static DEVICE_API(sensor, iis2iclx_driver_api) = {
521 .attr_set = iis2iclx_attr_set,
522 #if CONFIG_IIS2ICLX_TRIGGER
523 .trigger_set = iis2iclx_trigger_set,
524 #endif
525 .sample_fetch = iis2iclx_sample_fetch,
526 .channel_get = iis2iclx_channel_get,
527 };
528
iis2iclx_init_chip(const struct device * dev)529 static int iis2iclx_init_chip(const struct device *dev)
530 {
531 const struct iis2iclx_config * const cfg = dev->config;
532 struct iis2iclx_data *iis2iclx = dev->data;
533 uint8_t chip_id;
534 uint8_t odr = cfg->odr;
535 uint8_t fs = cfg->range;
536
537 iis2iclx->dev = dev;
538
539 if (iis2iclx_device_id_get((stmdev_ctx_t *)&cfg->ctx, &chip_id) < 0) {
540 LOG_ERR("Failed reading chip id");
541 return -EIO;
542 }
543
544 LOG_INF("chip id 0x%x", chip_id);
545
546 if (chip_id != IIS2ICLX_ID) {
547 LOG_ERR("Invalid chip id 0x%x", chip_id);
548 return -EIO;
549 }
550
551 /* reset device */
552 if (iis2iclx_reset_set((stmdev_ctx_t *)&cfg->ctx, 1) < 0) {
553 return -EIO;
554 }
555
556 k_usleep(100);
557
558 LOG_DBG("range is %d", fs);
559 if (iis2iclx_accel_set_fs_raw(dev, fs) < 0) {
560 LOG_ERR("failed to set accelerometer full-scale");
561 return -EIO;
562 }
563 iis2iclx->acc_gain = (iis2iclx_accel_fs_sens[fs] * GAIN_UNIT_XL);
564
565 LOG_DBG("odr is %d", odr);
566 if (iis2iclx_accel_set_odr_raw(dev, odr) < 0) {
567 LOG_ERR("failed to set accelerometer sampling rate");
568 return -EIO;
569 }
570
571 /* Set FIFO bypass mode */
572 if (iis2iclx_fifo_mode_set((stmdev_ctx_t *)&cfg->ctx,
573 IIS2ICLX_BYPASS_MODE) < 0) {
574 LOG_ERR("failed to set FIFO mode");
575 return -EIO;
576 }
577
578 if (iis2iclx_block_data_update_set((stmdev_ctx_t *)&cfg->ctx, 1) < 0) {
579 LOG_ERR("failed to set BDU mode");
580 return -EIO;
581 }
582
583 return 0;
584 }
585
iis2iclx_init(const struct device * dev)586 static int iis2iclx_init(const struct device *dev)
587 {
588 #ifdef CONFIG_IIS2ICLX_TRIGGER
589 const struct iis2iclx_config *cfg = dev->config;
590 #endif
591 struct iis2iclx_data *data = dev->data;
592
593 LOG_INF("Initialize device %s", dev->name);
594 data->dev = dev;
595 if (iis2iclx_init_chip(dev) < 0) {
596 LOG_ERR("failed to initialize chip");
597 return -EIO;
598 }
599
600 #ifdef CONFIG_IIS2ICLX_TRIGGER
601 if (cfg->trig_enabled) {
602 if (iis2iclx_init_interrupt(dev) < 0) {
603 LOG_ERR("Failed to initialize interrupt.");
604 return -EIO;
605 }
606 }
607 #endif
608
609 #ifdef CONFIG_IIS2ICLX_SENSORHUB
610 data->shub_inited = true;
611 if (iis2iclx_shub_init(dev) < 0) {
612 LOG_INF("shub: no external chips found");
613 data->shub_inited = false;
614 }
615 #endif
616
617 return 0;
618 }
619
620 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
621 #warning "IIS2ICLX driver enabled without any devices"
622 #endif
623
624 /*
625 * Device creation macro, shared by IIS2ICLX_DEFINE_SPI() and
626 * IIS2ICLX_DEFINE_I2C().
627 */
628
629 #define IIS2ICLX_DEVICE_INIT(inst) \
630 SENSOR_DEVICE_DT_INST_DEFINE(inst, \
631 iis2iclx_init, \
632 NULL, \
633 &iis2iclx_data_##inst, \
634 &iis2iclx_config_##inst, \
635 POST_KERNEL, \
636 CONFIG_SENSOR_INIT_PRIORITY, \
637 &iis2iclx_driver_api);
638
639 /*
640 * Instantiation macros used when a device is on a SPI bus.
641 */
642
643 #ifdef CONFIG_IIS2ICLX_TRIGGER
644 #define IIS2ICLX_CFG_IRQ(inst) \
645 .trig_enabled = true, \
646 .gpio_drdy = GPIO_DT_SPEC_INST_GET(inst, drdy_gpios), \
647 .int_pin = DT_INST_PROP(inst, int_pin)
648 #else
649 #define IIS2ICLX_CFG_IRQ(inst)
650 #endif /* CONFIG_IIS2ICLX_TRIGGER */
651
652 #define IIS2ICLX_CONFIG_COMMON(inst) \
653 .odr = DT_INST_PROP(inst, odr), \
654 .range = DT_INST_PROP(inst, range), \
655 COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, drdy_gpios), \
656 (IIS2ICLX_CFG_IRQ(inst)), ())
657
658 #define IIS2ICLX_SPI_OPERATION (SPI_WORD_SET(8) | \
659 SPI_OP_MODE_MASTER | \
660 SPI_MODE_CPOL | \
661 SPI_MODE_CPHA) \
662
663 #define IIS2ICLX_CONFIG_SPI(inst) \
664 { \
665 STMEMSC_CTX_SPI(&iis2iclx_config_##inst.stmemsc_cfg), \
666 .stmemsc_cfg = { \
667 .spi = SPI_DT_SPEC_INST_GET(inst, \
668 IIS2ICLX_SPI_OPERATION, \
669 0), \
670 }, \
671 IIS2ICLX_CONFIG_COMMON(inst) \
672 }
673
674 /*
675 * Instantiation macros used when a device is on an I2C bus.
676 */
677
678 #define IIS2ICLX_CONFIG_I2C(inst) \
679 { \
680 STMEMSC_CTX_I2C(&iis2iclx_config_##inst.stmemsc_cfg), \
681 .stmemsc_cfg = { \
682 .i2c = I2C_DT_SPEC_INST_GET(inst), \
683 }, \
684 IIS2ICLX_CONFIG_COMMON(inst) \
685 }
686
687 /*
688 * Main instantiation macro. Use of COND_CODE_1() selects the right
689 * bus-specific macro at preprocessor time.
690 */
691
692 #define IIS2ICLX_DEFINE(inst) \
693 static struct iis2iclx_data iis2iclx_data_##inst; \
694 static const struct iis2iclx_config iis2iclx_config_##inst = \
695 COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
696 (IIS2ICLX_CONFIG_SPI(inst)), \
697 (IIS2ICLX_CONFIG_I2C(inst))); \
698 IIS2ICLX_DEVICE_INIT(inst)
699
700 DT_INST_FOREACH_STATUS_OKAY(IIS2ICLX_DEFINE)
701