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