1 /*
2 * Copyright (c) 2016 Freescale Semiconductor, Inc.
3 * Copyright (c) 2018 Phytec Messtechnik GmbH
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT nxp_fxos8700
9
10 #include "fxos8700.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(FXOS8700, CONFIG_SENSOR_LOG_LEVEL);
17
18 /* Convert the range (8g, 4g, 2g) to the encoded FS register field value */
19 #define RANGE2FS(x) (__builtin_ctz(x) - 1)
20
21 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
22 #define DIR_READ(a) ((a) & 0x7f)
23 #define DIR_WRITE(a) ((a) | BIT(7))
24 #define ADDR_7(a) ((a) & BIT(7))
25
fxos8700_transceive(const struct device * dev,void * data,size_t length)26 int fxos8700_transceive(const struct device *dev,
27 void *data, size_t length)
28 {
29 const struct fxos8700_config *cfg = dev->config;
30 const struct spi_buf buf = { .buf = data, .len = length };
31 const struct spi_buf_set s = { .buffers = &buf, .count = 1 };
32
33 return spi_transceive_dt(&cfg->bus_cfg.spi, &s, &s);
34 }
35
fxos8700_read_spi(const struct device * dev,uint8_t reg,void * data,size_t length)36 int fxos8700_read_spi(const struct device *dev,
37 uint8_t reg,
38 void *data,
39 size_t length)
40 {
41 const struct fxos8700_config *cfg = dev->config;
42
43 /* Reads must clock out a dummy byte after sending the address. */
44 uint8_t reg_buf[3] = { DIR_READ(reg), ADDR_7(reg), 0 };
45 const struct spi_buf buf[2] = {
46 { .buf = reg_buf, .len = 3 },
47 { .buf = data, .len = length }
48 };
49 const struct spi_buf_set tx = { .buffers = buf, .count = 1 };
50 const struct spi_buf_set rx = { .buffers = buf, .count = 2 };
51
52 return spi_transceive_dt(&cfg->bus_cfg.spi, &tx, &rx);
53 }
54
fxos8700_byte_read_spi(const struct device * dev,uint8_t reg,uint8_t * byte)55 int fxos8700_byte_read_spi(const struct device *dev,
56 uint8_t reg,
57 uint8_t *byte)
58 {
59 /* Reads must clock out a dummy byte after sending the address. */
60 uint8_t data[] = { DIR_READ(reg), ADDR_7(reg), 0};
61 int ret;
62
63 ret = fxos8700_transceive(dev, data, sizeof(data));
64
65 *byte = data[2];
66
67 return ret;
68 }
69
fxos8700_byte_write_spi(const struct device * dev,uint8_t reg,uint8_t byte)70 int fxos8700_byte_write_spi(const struct device *dev,
71 uint8_t reg,
72 uint8_t byte)
73 {
74 uint8_t data[] = { DIR_WRITE(reg), ADDR_7(reg), byte };
75
76 return fxos8700_transceive(dev, data, sizeof(data));
77 }
78
fxos8700_reg_field_update_spi(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)79 int fxos8700_reg_field_update_spi(const struct device *dev,
80 uint8_t reg,
81 uint8_t mask,
82 uint8_t val)
83 {
84 uint8_t old_val;
85
86 if (fxos8700_byte_read_spi(dev, reg, &old_val) < 0) {
87 return -EIO;
88 }
89
90 return fxos8700_byte_write_spi(dev, reg, (old_val & ~mask) | (val & mask));
91 }
92
93 static const struct fxos8700_io_ops fxos8700_spi_ops = {
94 .read = fxos8700_read_spi,
95 .byte_read = fxos8700_byte_read_spi,
96 .byte_write = fxos8700_byte_write_spi,
97 .reg_field_update = fxos8700_reg_field_update_spi,
98 };
99 #endif
100
101 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
fxos8700_read_i2c(const struct device * dev,uint8_t reg,void * data,size_t length)102 int fxos8700_read_i2c(const struct device *dev,
103 uint8_t reg,
104 void *data,
105 size_t length)
106 {
107 const struct fxos8700_config *config = dev->config;
108
109 return i2c_burst_read_dt(&config->bus_cfg.i2c, reg, data, length);
110 }
111
fxos8700_byte_read_i2c(const struct device * dev,uint8_t reg,uint8_t * byte)112 int fxos8700_byte_read_i2c(const struct device *dev,
113 uint8_t reg,
114 uint8_t *byte)
115 {
116 const struct fxos8700_config *config = dev->config;
117
118 return i2c_reg_read_byte_dt(&config->bus_cfg.i2c, reg, byte);
119 }
120
fxos8700_byte_write_i2c(const struct device * dev,uint8_t reg,uint8_t byte)121 int fxos8700_byte_write_i2c(const struct device *dev,
122 uint8_t reg,
123 uint8_t byte)
124 {
125 const struct fxos8700_config *config = dev->config;
126
127 return i2c_reg_write_byte_dt(&config->bus_cfg.i2c, reg, byte);
128 }
129
fxos8700_reg_field_update_i2c(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)130 int fxos8700_reg_field_update_i2c(const struct device *dev,
131 uint8_t reg,
132 uint8_t mask,
133 uint8_t val)
134 {
135 const struct fxos8700_config *config = dev->config;
136
137 return i2c_reg_update_byte_dt(&config->bus_cfg.i2c, reg, mask, val);
138 }
139 static const struct fxos8700_io_ops fxos8700_i2c_ops = {
140 .read = fxos8700_read_i2c,
141 .byte_read = fxos8700_byte_read_i2c,
142 .byte_write = fxos8700_byte_write_i2c,
143 .reg_field_update = fxos8700_reg_field_update_i2c,
144 };
145 #endif
146
fxos8700_set_odr(const struct device * dev,const struct sensor_value * val)147 static int fxos8700_set_odr(const struct device *dev,
148 const struct sensor_value *val)
149 {
150 const struct fxos8700_config *config = dev->config;
151 uint8_t dr;
152 enum fxos8700_power power;
153
154 #ifdef CONFIG_FXOS8700_MODE_HYBRID
155 /* ODR is halved in hybrid mode */
156 if (val->val1 == 400 && val->val2 == 0) {
157 dr = FXOS8700_CTRLREG1_DR_RATE_800;
158 } else if (val->val1 == 200 && val->val2 == 0) {
159 dr = FXOS8700_CTRLREG1_DR_RATE_400;
160 } else if (val->val1 == 100 && val->val2 == 0) {
161 dr = FXOS8700_CTRLREG1_DR_RATE_200;
162 } else if (val->val1 == 50 && val->val2 == 0) {
163 dr = FXOS8700_CTRLREG1_DR_RATE_100;
164 } else if (val->val1 == 25 && val->val2 == 0) {
165 dr = FXOS8700_CTRLREG1_DR_RATE_50;
166 } else if (val->val1 == 6 && val->val2 == 250000) {
167 dr = FXOS8700_CTRLREG1_DR_RATE_12_5;
168 } else if (val->val1 == 3 && val->val2 == 125000) {
169 dr = FXOS8700_CTRLREG1_DR_RATE_6_25;
170 } else if (val->val1 == 0 && val->val2 == 781300) {
171 dr = FXOS8700_CTRLREG1_DR_RATE_1_56;
172 } else {
173 return -EINVAL;
174 }
175 #else
176 if (val->val1 == 800 && val->val2 == 0) {
177 dr = FXOS8700_CTRLREG1_DR_RATE_800;
178 } else if (val->val1 == 400 && val->val2 == 0) {
179 dr = FXOS8700_CTRLREG1_DR_RATE_400;
180 } else if (val->val1 == 200 && val->val2 == 0) {
181 dr = FXOS8700_CTRLREG1_DR_RATE_200;
182 } else if (val->val1 == 100 && val->val2 == 0) {
183 dr = FXOS8700_CTRLREG1_DR_RATE_100;
184 } else if (val->val1 == 50 && val->val2 == 0) {
185 dr = FXOS8700_CTRLREG1_DR_RATE_50;
186 } else if (val->val1 == 12 && val->val2 == 500000) {
187 dr = FXOS8700_CTRLREG1_DR_RATE_12_5;
188 } else if (val->val1 == 6 && val->val2 == 250000) {
189 dr = FXOS8700_CTRLREG1_DR_RATE_6_25;
190 } else if (val->val1 == 1 && val->val2 == 562500) {
191 dr = FXOS8700_CTRLREG1_DR_RATE_1_56;
192 } else {
193 return -EINVAL;
194 }
195 #endif
196
197 LOG_DBG("Set ODR to 0x%x", dr);
198
199 /*
200 * Modify FXOS8700_REG_CTRLREG1 can only occur when the device
201 * is in standby mode. Get the current power mode to restore it later.
202 */
203 if (fxos8700_get_power(dev, &power)) {
204 LOG_ERR("Could not get power mode");
205 return -EIO;
206 }
207
208 /* Set standby power mode */
209 if (fxos8700_set_power(dev, FXOS8700_POWER_STANDBY)) {
210 LOG_ERR("Could not set standby");
211 return -EIO;
212 }
213
214 /* Change the attribute and restore power mode. */
215 return config->ops->reg_field_update(dev, FXOS8700_REG_CTRLREG1,
216 FXOS8700_CTRLREG1_DR_MASK | FXOS8700_CTRLREG1_ACTIVE_MASK,
217 dr | power);
218 }
219
fxos8700_set_mt_ths(const struct device * dev,const struct sensor_value * val)220 static int fxos8700_set_mt_ths(const struct device *dev,
221 const struct sensor_value *val)
222 {
223 #ifdef CONFIG_FXOS8700_MOTION
224 const struct fxos8700_config *config = dev->config;
225 uint64_t micro_ms2 = abs(val->val1 * 1000000LL + val->val2);
226 uint64_t ths = micro_ms2 / FXOS8700_FF_MT_THS_SCALE;
227
228 if (ths > FXOS8700_FF_MT_THS_MASK) {
229 LOG_ERR("Threshold value is out of range");
230 return -EINVAL;
231 }
232
233 LOG_DBG("Set FF_MT_THS to %d", (uint8_t)ths);
234
235 return config->ops->reg_field_update(dev, FXOS8700_REG_FF_MT_THS,
236 FXOS8700_FF_MT_THS_MASK, (uint8_t)ths);
237 #else
238 return -ENOTSUP;
239 #endif
240 }
241
fxos8700_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)242 static int fxos8700_attr_set(const struct device *dev,
243 enum sensor_channel chan,
244 enum sensor_attribute attr,
245 const struct sensor_value *val)
246 {
247 if (chan != SENSOR_CHAN_ALL) {
248 return -ENOTSUP;
249 }
250
251 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
252 return fxos8700_set_odr(dev, val);
253 } else if (attr == SENSOR_ATTR_SLOPE_TH) {
254 return fxos8700_set_mt_ths(dev, val);
255 } else {
256 return -ENOTSUP;
257 }
258
259 return 0;
260 }
261
fxos8700_sample_fetch(const struct device * dev,enum sensor_channel chan)262 static int fxos8700_sample_fetch(const struct device *dev,
263 enum sensor_channel chan)
264 {
265 const struct fxos8700_config *config = dev->config;
266 struct fxos8700_data *data = dev->data;
267 uint8_t buffer[FXOS8700_MAX_NUM_BYTES];
268 uint8_t num_bytes;
269 int16_t *raw;
270 int ret = 0;
271 int i;
272
273 if (chan != SENSOR_CHAN_ALL) {
274 LOG_ERR("Unsupported sensor channel");
275 return -ENOTSUP;
276 }
277
278 k_sem_take(&data->sem, K_FOREVER);
279
280 /* Read all the channels in one I2C/SPI transaction. The number of bytes to
281 * read and the starting register address depend on the mode
282 * configuration (accel-only, mag-only, or hybrid).
283 */
284 num_bytes = config->num_channels * FXOS8700_BYTES_PER_CHANNEL_NORMAL;
285
286 __ASSERT(num_bytes <= sizeof(buffer), "Too many bytes to read");
287
288 if (config->ops->read(dev, config->start_addr, buffer, num_bytes)) {
289 LOG_ERR("Could not fetch sample");
290 ret = -EIO;
291 goto exit;
292 }
293
294 /* Parse the buffer into raw channel data (16-bit integers). To save
295 * RAM, store the data in raw format and wait to convert to the
296 * normalized sensor_value type until later.
297 */
298 __ASSERT(config->start_channel + config->num_channels
299 <= ARRAY_SIZE(data->raw),
300 "Too many channels");
301
302 raw = &data->raw[config->start_channel];
303
304 for (i = 0; i < num_bytes; i += 2) {
305 *raw++ = (buffer[i] << 8) | (buffer[i+1]);
306 }
307
308 #ifdef CONFIG_FXOS8700_TEMP
309 if (config->ops->byte_read(dev, FXOS8700_REG_TEMP,
310 &data->temp)) {
311 LOG_ERR("Could not fetch temperature");
312 ret = -EIO;
313 goto exit;
314 }
315 #endif
316
317 exit:
318 k_sem_give(&data->sem);
319
320 return ret;
321 }
322
fxos8700_accel_convert(struct sensor_value * val,int16_t raw,uint8_t range)323 static void fxos8700_accel_convert(struct sensor_value *val, int16_t raw,
324 uint8_t range)
325 {
326 uint8_t frac_bits;
327 int64_t micro_ms2;
328
329 /* The range encoding is convenient to compute the number of fractional
330 * bits:
331 * - 2g mode (fs = 0) has 14 fractional bits
332 * - 4g mode (fs = 1) has 13 fractional bits
333 * - 8g mode (fs = 2) has 12 fractional bits
334 */
335 frac_bits = 14 - RANGE2FS(range);
336
337 /* Convert units to micro m/s^2. Intermediate results before the shift
338 * are 40 bits wide.
339 */
340 micro_ms2 = (raw * SENSOR_G) >> frac_bits;
341
342 /* The maximum possible value is 8g, which in units of micro m/s^2
343 * always fits into 32-bits. Cast down to int32_t so we can use a
344 * faster divide.
345 */
346 val->val1 = (int32_t) micro_ms2 / 1000000;
347 val->val2 = (int32_t) micro_ms2 % 1000000;
348 }
349
fxos8700_magn_convert(struct sensor_value * val,int16_t raw)350 static void fxos8700_magn_convert(struct sensor_value *val, int16_t raw)
351 {
352 int32_t micro_g;
353
354 /* Convert units to micro Gauss. Raw magnetic data always has a
355 * resolution of 0.1 uT/LSB, which is equivalent to 0.001 G/LSB.
356 */
357 micro_g = raw * 1000;
358
359 val->val1 = micro_g / 1000000;
360 val->val2 = micro_g % 1000000;
361 }
362
363 #ifdef CONFIG_FXOS8700_TEMP
fxos8700_temp_convert(struct sensor_value * val,int8_t raw)364 static void fxos8700_temp_convert(struct sensor_value *val, int8_t raw)
365 {
366 int32_t micro_c;
367
368 /* Convert units to micro Celsius. Raw temperature data always has a
369 * resolution of 0.96 deg C/LSB.
370 */
371 micro_c = raw * 960 * 1000;
372
373 val->val1 = micro_c / 1000000;
374 val->val2 = micro_c % 1000000;
375 }
376 #endif
377
fxos8700_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)378 static int fxos8700_channel_get(const struct device *dev,
379 enum sensor_channel chan,
380 struct sensor_value *val)
381 {
382 const struct fxos8700_config *config = dev->config;
383 struct fxos8700_data *data = dev->data;
384 int start_channel;
385 int num_channels;
386 int16_t *raw;
387 int ret;
388 int i;
389
390 k_sem_take(&data->sem, K_FOREVER);
391
392 /* Start with an error return code by default, then clear it if we find
393 * a supported sensor channel.
394 */
395 ret = -ENOTSUP;
396
397 /* If we're in an accelerometer-enabled mode (accel-only or hybrid),
398 * then convert raw accelerometer data to the normalized sensor_value
399 * type.
400 */
401 if (config->mode != FXOS8700_MODE_MAGN) {
402 switch (chan) {
403 case SENSOR_CHAN_ACCEL_X:
404 start_channel = FXOS8700_CHANNEL_ACCEL_X;
405 num_channels = 1;
406 break;
407 case SENSOR_CHAN_ACCEL_Y:
408 start_channel = FXOS8700_CHANNEL_ACCEL_Y;
409 num_channels = 1;
410 break;
411 case SENSOR_CHAN_ACCEL_Z:
412 start_channel = FXOS8700_CHANNEL_ACCEL_Z;
413 num_channels = 1;
414 break;
415 case SENSOR_CHAN_ACCEL_XYZ:
416 start_channel = FXOS8700_CHANNEL_ACCEL_X;
417 num_channels = 3;
418 break;
419 default:
420 start_channel = 0;
421 num_channels = 0;
422 break;
423 }
424
425 raw = &data->raw[start_channel];
426 for (i = 0; i < num_channels; i++) {
427 fxos8700_accel_convert(val++, *raw++, config->range);
428 }
429
430 if (num_channels > 0) {
431 ret = 0;
432 }
433 }
434
435 /* If we're in an magnetometer-enabled mode (mag-only or hybrid), then
436 * convert raw magnetometer data to the normalized sensor_value type.
437 */
438 if (config->mode != FXOS8700_MODE_ACCEL) {
439 switch (chan) {
440 case SENSOR_CHAN_MAGN_X:
441 start_channel = FXOS8700_CHANNEL_MAGN_X;
442 num_channels = 1;
443 break;
444 case SENSOR_CHAN_MAGN_Y:
445 start_channel = FXOS8700_CHANNEL_MAGN_Y;
446 num_channels = 1;
447 break;
448 case SENSOR_CHAN_MAGN_Z:
449 start_channel = FXOS8700_CHANNEL_MAGN_Z;
450 num_channels = 1;
451 break;
452 case SENSOR_CHAN_MAGN_XYZ:
453 start_channel = FXOS8700_CHANNEL_MAGN_X;
454 num_channels = 3;
455 break;
456 default:
457 start_channel = 0;
458 num_channels = 0;
459 break;
460 }
461
462 raw = &data->raw[start_channel];
463 for (i = 0; i < num_channels; i++) {
464 fxos8700_magn_convert(val++, *raw++);
465 }
466
467 if (num_channels > 0) {
468 ret = 0;
469 }
470 #ifdef CONFIG_FXOS8700_TEMP
471 if (chan == SENSOR_CHAN_DIE_TEMP) {
472 fxos8700_temp_convert(val, data->temp);
473 ret = 0;
474 }
475 #endif
476 }
477
478 if (ret != 0) {
479 LOG_ERR("Unsupported sensor channel");
480 }
481
482 k_sem_give(&data->sem);
483
484 return ret;
485 }
486
fxos8700_get_power(const struct device * dev,enum fxos8700_power * power)487 int fxos8700_get_power(const struct device *dev, enum fxos8700_power *power)
488 {
489 const struct fxos8700_config *config = dev->config;
490 uint8_t val;
491
492 if (config->ops->byte_read(dev, FXOS8700_REG_CTRLREG1, &val)) {
493 LOG_ERR("Could not get power setting");
494 return -EIO;
495 }
496 val &= FXOS8700_M_CTRLREG1_MODE_MASK;
497 *power = val;
498
499 return 0;
500 }
501
fxos8700_set_power(const struct device * dev,enum fxos8700_power power)502 int fxos8700_set_power(const struct device *dev, enum fxos8700_power power)
503 {
504 const struct fxos8700_config *config = dev->config;
505
506 return config->ops->reg_field_update(dev, FXOS8700_REG_CTRLREG1,
507 FXOS8700_CTRLREG1_ACTIVE_MASK, power);
508 }
509
fxos8700_init(const struct device * dev)510 static int fxos8700_init(const struct device *dev)
511 {
512 const struct fxos8700_config *config = dev->config;
513 struct fxos8700_data *data = dev->data;
514 struct sensor_value odr = {.val1 = 6, .val2 = 250000};
515
516 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
517 if (config->inst_on_bus == FXOS8700_BUS_I2C) {
518 if (!device_is_ready(config->bus_cfg.i2c.bus)) {
519 LOG_ERR("I2C bus device not ready");
520 return -ENODEV;
521 }
522 }
523 #endif
524
525 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
526 if (config->inst_on_bus == FXOS8700_BUS_SPI) {
527 if (!device_is_ready(config->bus_cfg.spi.bus)) {
528 LOG_ERR("SPI bus device not ready");
529 return -ENODEV;
530 }
531 }
532 #endif
533
534 if (config->reset_gpio.port) {
535 /* Pulse RST pin high to perform a hardware reset of
536 * the sensor.
537 */
538
539 if (!gpio_is_ready_dt(&config->reset_gpio)) {
540 LOG_ERR("GPIO device not ready");
541 return -ENODEV;
542 }
543
544 gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE);
545
546 gpio_pin_set_dt(&config->reset_gpio, 1);
547 /* The datasheet does not mention how long to pulse
548 * the RST pin high in order to reset. Stay on the
549 * safe side and pulse for 1 millisecond.
550 */
551 k_busy_wait(USEC_PER_MSEC);
552 gpio_pin_set_dt(&config->reset_gpio, 0);
553 } else {
554 /* Software reset the sensor. Upon issuing a software
555 * reset command over the I2C interface, the sensor
556 * immediately resets and does not send any
557 * acknowledgment (ACK) of the written byte to the
558 * master. Therefore, do not check the return code of
559 * the I2C transaction.
560 */
561 config->ops->byte_write(dev, FXOS8700_REG_CTRLREG2,
562 FXOS8700_CTRLREG2_RST_MASK);
563 }
564
565 /* The sensor requires us to wait 1 ms after a reset before
566 * attempting further communications.
567 */
568 k_busy_wait(USEC_PER_MSEC);
569
570 /*
571 * Read the WHOAMI register to make sure we are talking to FXOS8700 or
572 * compatible device and not some other type of device that happens to
573 * have the same I2C address.
574 */
575 if (config->ops->byte_read(dev, FXOS8700_REG_WHOAMI,
576 &data->whoami)) {
577 LOG_ERR("Could not get WHOAMI value");
578 return -EIO;
579 }
580
581 switch (data->whoami) {
582 case WHOAMI_ID_MMA8451:
583 case WHOAMI_ID_MMA8652:
584 case WHOAMI_ID_MMA8653:
585 if (config->mode != FXOS8700_MODE_ACCEL) {
586 LOG_ERR("Device 0x%x supports only "
587 "accelerometer mode",
588 data->whoami);
589 return -EIO;
590 }
591 break;
592 case WHOAMI_ID_FXOS8700:
593 LOG_DBG("Device ID 0x%x", data->whoami);
594 break;
595 default:
596 LOG_ERR("Unknown Device ID 0x%x", data->whoami);
597 return -EIO;
598 }
599
600 if (fxos8700_set_odr(dev, &odr)) {
601 LOG_ERR("Could not set default data rate");
602 return -EIO;
603 }
604
605 if (config->ops->reg_field_update(dev, FXOS8700_REG_CTRLREG2,
606 FXOS8700_CTRLREG2_MODS_MASK,
607 config->power_mode)) {
608 LOG_ERR("Could not set power scheme");
609 return -EIO;
610 }
611
612 /* Set the mode (accel-only, mag-only, or hybrid) */
613 if (config->ops->reg_field_update(dev, FXOS8700_REG_M_CTRLREG1,
614 FXOS8700_M_CTRLREG1_MODE_MASK,
615 config->mode)) {
616 LOG_ERR("Could not set mode");
617 return -EIO;
618 }
619
620 /* Set hybrid autoincrement so we can read accel and mag channels in
621 * one I2C/SPI transaction.
622 */
623 if (config->ops->reg_field_update(dev, FXOS8700_REG_M_CTRLREG2,
624 FXOS8700_M_CTRLREG2_AUTOINC_MASK,
625 FXOS8700_M_CTRLREG2_AUTOINC_MASK)) {
626 LOG_ERR("Could not set hybrid autoincrement");
627 return -EIO;
628 }
629
630 /* Set the full-scale range */
631 if (config->ops->reg_field_update(dev, FXOS8700_REG_XYZ_DATA_CFG,
632 FXOS8700_XYZ_DATA_CFG_FS_MASK,
633 RANGE2FS(config->range))) {
634 LOG_ERR("Could not set range");
635 return -EIO;
636 }
637
638 k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT);
639
640 #if CONFIG_FXOS8700_TRIGGER
641 if (fxos8700_trigger_init(dev)) {
642 LOG_ERR("Could not initialize interrupts");
643 return -EIO;
644 }
645 #endif
646
647 /* Set active */
648 if (fxos8700_set_power(dev, FXOS8700_POWER_ACTIVE)) {
649 LOG_ERR("Could not set active");
650 return -EIO;
651 }
652 k_sem_give(&data->sem);
653
654 LOG_DBG("Init complete");
655
656 return 0;
657 }
658
659 static const struct sensor_driver_api fxos8700_driver_api = {
660 .sample_fetch = fxos8700_sample_fetch,
661 .channel_get = fxos8700_channel_get,
662 .attr_set = fxos8700_attr_set,
663 #if CONFIG_FXOS8700_TRIGGER
664 .trigger_set = fxos8700_trigger_set,
665 #endif
666 };
667
668 #define FXOS8700_MODE_PROPS_ACCEL \
669 .mode = FXOS8700_MODE_ACCEL, \
670 .start_addr = FXOS8700_REG_OUTXMSB, \
671 .start_channel = FXOS8700_CHANNEL_ACCEL_X, \
672 .num_channels = FXOS8700_NUM_ACCEL_CHANNELS,
673
674 #define FXOS8700_MODE_PROPS_MAGN \
675 .mode = FXOS8700_MODE_MAGN, \
676 .start_addr = FXOS8700_REG_M_OUTXMSB, \
677 .start_channel = FXOS8700_CHANNEL_MAGN_X, \
678 .num_channels = FXOS8700_NUM_MAG_CHANNELS,
679
680 #define FXOS8700_MODE_PROPS_HYBRID \
681 .mode = FXOS8700_MODE_HYBRID, \
682 .start_addr = FXOS8700_REG_OUTXMSB, \
683 .start_channel = FXOS8700_CHANNEL_ACCEL_X, \
684 .num_channels = FXOS8700_NUM_HYBRID_CHANNELS, \
685
686 #define FXOS8700_MODE(n) \
687 COND_CODE_1(CONFIG_FXOS8700_MODE_ACCEL, \
688 (FXOS8700_MODE_PROPS_ACCEL), \
689 (COND_CODE_1(CONFIG_FXOS8700_MODE_MAGN, \
690 (FXOS8700_MODE_PROPS_MAGN), \
691 (FXOS8700_MODE_PROPS_HYBRID))))
692
693 #define FXOS8700_RESET_PROPS(n) \
694 .reset_gpio = GPIO_DT_SPEC_INST_GET(n, reset_gpios),
695
696 #define FXOS8700_RESET(n) \
697 COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reset_gpios), \
698 (FXOS8700_RESET_PROPS(n)), \
699 ())
700
701 #define FXOS8700_INTM_PROPS(n, m) \
702 .int_gpio = GPIO_DT_SPEC_INST_GET(n, int##m##_gpios),
703
704 #define FXOS8700_INT_PROPS(n) \
705 COND_CODE_1(CONFIG_FXOS8700_DRDY_INT1, \
706 (FXOS8700_INTM_PROPS(n, 1)), \
707 (FXOS8700_INTM_PROPS(n, 2)))
708
709 #define FXOS8700_INT(n) \
710 COND_CODE_1(CONFIG_FXOS8700_TRIGGER, \
711 (FXOS8700_INT_PROPS(n)), \
712 ())
713
714 #define FXOS8700_PULSE_PROPS(n) \
715 .pulse_cfg = DT_INST_PROP(n, pulse_cfg), \
716 .pulse_ths[0] = DT_INST_PROP(n, pulse_thsx), \
717 .pulse_ths[1] = DT_INST_PROP(n, pulse_thsy), \
718 .pulse_ths[2] = DT_INST_PROP(n, pulse_thsz), \
719 .pulse_tmlt = DT_INST_PROP(n, pulse_tmlt), \
720 .pulse_ltcy = DT_INST_PROP(n, pulse_ltcy), \
721 .pulse_wind = DT_INST_PROP(n, pulse_wind),
722
723 #define FXOS8700_PULSE(n) \
724 COND_CODE_1(CONFIG_FXOS8700_PULSE, \
725 (FXOS8700_PULSE_PROPS(n)), \
726 ())
727
728 #define FXOS8700_MAG_VECM_PROPS(n) \
729 .mag_vecm_cfg = DT_INST_PROP(n, mag_vecm_cfg), \
730 .mag_vecm_ths[0] = DT_INST_PROP(n, mag_vecm_ths_msb), \
731 .mag_vecm_ths[1] = DT_INST_PROP(n, mag_vecm_ths_lsb),
732
733 #define FXOS8700_MAG_VECM(n) \
734 COND_CODE_1(CONFIG_FXOS8700_MAG_VECM, \
735 (FXOS8700_MAG_VECM_PROPS(n)), \
736 ())
737
738 #define FXOS8700_CONFIG_I2C(n) \
739 .bus_cfg = { .i2c = I2C_DT_SPEC_INST_GET(n) }, \
740 .ops = &fxos8700_i2c_ops, \
741 .power_mode = DT_INST_PROP(n, power_mode), \
742 .range = DT_INST_PROP(n, range), \
743 .inst_on_bus = FXOS8700_BUS_I2C,
744
745 #define FXOS8700_CONFIG_SPI(n) \
746 .bus_cfg = { .spi = SPI_DT_SPEC_INST_GET(n, \
747 SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0) }, \
748 .ops = &fxos8700_spi_ops, \
749 .power_mode = DT_INST_PROP(n, power_mode), \
750 .range = DT_INST_PROP(n, range), \
751 .inst_on_bus = FXOS8700_BUS_SPI, \
752
753 #define FXOS8700_SPI_OPERATION (SPI_WORD_SET(8) | \
754 SPI_OP_MODE_MASTER) \
755
756 #define FXOS8700_INIT(n) \
757 static const struct fxos8700_config fxos8700_config_##n = { \
758 COND_CODE_1(DT_INST_ON_BUS(n, spi), \
759 (FXOS8700_CONFIG_SPI(n)), \
760 (FXOS8700_CONFIG_I2C(n))) \
761 FXOS8700_RESET(n) \
762 FXOS8700_MODE(n) \
763 FXOS8700_INT(n) \
764 FXOS8700_PULSE(n) \
765 FXOS8700_MAG_VECM(n) \
766 }; \
767 \
768 static struct fxos8700_data fxos8700_data_##n; \
769 \
770 SENSOR_DEVICE_DT_INST_DEFINE(n, \
771 fxos8700_init, \
772 NULL, \
773 &fxos8700_data_##n, \
774 &fxos8700_config_##n, \
775 POST_KERNEL, \
776 CONFIG_SENSOR_INIT_PRIORITY, \
777 &fxos8700_driver_api);
778
779 DT_INST_FOREACH_STATUS_OKAY(FXOS8700_INIT)
780