1 /*
2 * Copyright (c) 2017, NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_fxas21002
8
9 #include "fxas21002.h"
10 #include <zephyr/sys/util.h>
11 #include <zephyr/sys/__assert.h>
12 #include <zephyr/logging/log.h>
13
14 LOG_MODULE_REGISTER(FXAS21002, CONFIG_SENSOR_LOG_LEVEL);
15
16 /* Sample period in microseconds, indexed by output data rate encoding (DR) */
17 static const uint32_t sample_period[] = {
18 1250, 2500, 5000, 10000, 20000, 40000, 80000, 80000
19 };
20
21 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
22 #define DIR_READ(a) ((a) | BIT(7))
23 #define DIR_WRITE(a) ((a) & 0x7f)
24
fxas21002_transceive(const struct device * dev,void * data,size_t length)25 static int fxas21002_transceive(const struct device *dev,
26 void *data, size_t length)
27 {
28 const struct fxas21002_config *cfg = dev->config;
29 const struct spi_buf buf = { .buf = data, .len = length };
30 const struct spi_buf_set s = { .buffers = &buf, .count = 1 };
31
32 return spi_transceive_dt(&cfg->bus_cfg.spi, &s, &s);
33 }
34
fxas21002_read_spi(const struct device * dev,uint8_t reg,void * data,size_t length)35 int fxas21002_read_spi(const struct device *dev,
36 uint8_t reg,
37 void *data,
38 size_t length)
39 {
40 const struct fxas21002_config *cfg = dev->config;
41
42 /* Reads must clock out a dummy byte after sending the address. */
43 uint8_t reg_buf[2] = { DIR_READ(reg), 0 };
44 const struct spi_buf buf[2] = {
45 { .buf = reg_buf, .len = 3 },
46 { .buf = data, .len = length }
47 };
48 const struct spi_buf_set tx = { .buffers = buf, .count = 1 };
49 const struct spi_buf_set rx = { .buffers = buf, .count = 2 };
50
51 return spi_transceive_dt(&cfg->bus_cfg.spi, &tx, &rx);
52 }
53
fxas21002_byte_read_spi(const struct device * dev,uint8_t reg,uint8_t * byte)54 int fxas21002_byte_read_spi(const struct device *dev,
55 uint8_t reg,
56 uint8_t *byte)
57 {
58 /* Reads must clock out a dummy byte after sending the address. */
59 uint8_t data[] = { DIR_READ(reg), 0};
60 int ret;
61
62 ret = fxas21002_transceive(dev, data, sizeof(data));
63
64 *byte = data[1];
65
66 return ret;
67 }
68
fxas21002_byte_write_spi(const struct device * dev,uint8_t reg,uint8_t byte)69 int fxas21002_byte_write_spi(const struct device *dev,
70 uint8_t reg,
71 uint8_t byte)
72 {
73 uint8_t data[] = { DIR_WRITE(reg), byte };
74
75 return fxas21002_transceive(dev, data, sizeof(data));
76 }
77
fxas21002_reg_field_update_spi(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)78 int fxas21002_reg_field_update_spi(const struct device *dev,
79 uint8_t reg,
80 uint8_t mask,
81 uint8_t val)
82 {
83 uint8_t old_val;
84 int rc = 0;
85
86 rc = fxas21002_byte_read_spi(dev, reg, &old_val);
87 if (rc != 0) {
88 return rc;
89 }
90
91 return fxas21002_byte_write_spi(dev, reg, (old_val & ~mask) | (val & mask));
92 }
93
94 static const struct fxas21002_io_ops fxas21002_spi_ops = {
95 .read = fxas21002_read_spi,
96 .byte_read = fxas21002_byte_read_spi,
97 .byte_write = fxas21002_byte_write_spi,
98 .reg_field_update = fxas21002_reg_field_update_spi,
99 };
100 #endif
101
102 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
fxas21002_read_i2c(const struct device * dev,uint8_t reg,void * data,size_t length)103 int fxas21002_read_i2c(const struct device *dev,
104 uint8_t reg,
105 void *data,
106 size_t length)
107 {
108 const struct fxas21002_config *config = dev->config;
109
110 return i2c_burst_read_dt(&config->bus_cfg.i2c, reg, data, length);
111 }
112
fxas21002_byte_read_i2c(const struct device * dev,uint8_t reg,uint8_t * byte)113 int fxas21002_byte_read_i2c(const struct device *dev,
114 uint8_t reg,
115 uint8_t *byte)
116 {
117 const struct fxas21002_config *config = dev->config;
118
119 return i2c_reg_read_byte_dt(&config->bus_cfg.i2c, reg, byte);
120 }
121
fxas21002_byte_write_i2c(const struct device * dev,uint8_t reg,uint8_t byte)122 int fxas21002_byte_write_i2c(const struct device *dev,
123 uint8_t reg,
124 uint8_t byte)
125 {
126 const struct fxas21002_config *config = dev->config;
127
128 return i2c_reg_write_byte_dt(&config->bus_cfg.i2c, reg, byte);
129 }
130
fxas21002_reg_field_update_i2c(const struct device * dev,uint8_t reg,uint8_t mask,uint8_t val)131 int fxas21002_reg_field_update_i2c(const struct device *dev,
132 uint8_t reg,
133 uint8_t mask,
134 uint8_t val)
135 {
136 const struct fxas21002_config *config = dev->config;
137
138 return i2c_reg_update_byte_dt(&config->bus_cfg.i2c, reg, mask, val);
139 }
140 static const struct fxas21002_io_ops fxas21002_i2c_ops = {
141 .read = fxas21002_read_i2c,
142 .byte_read = fxas21002_byte_read_i2c,
143 .byte_write = fxas21002_byte_write_i2c,
144 .reg_field_update = fxas21002_reg_field_update_i2c,
145 };
146 #endif
147
fxas21002_sample_fetch(const struct device * dev,enum sensor_channel chan)148 static int fxas21002_sample_fetch(const struct device *dev,
149 enum sensor_channel chan)
150 {
151 const struct fxas21002_config *config = dev->config;
152 struct fxas21002_data *data = dev->data;
153 uint8_t buffer[FXAS21002_MAX_NUM_BYTES];
154 int16_t *raw;
155 int ret = 0;
156 int i;
157
158 if (chan != SENSOR_CHAN_ALL) {
159 LOG_ERR("Unsupported sensor channel");
160 return -ENOTSUP;
161 }
162
163 k_sem_take(&data->sem, K_FOREVER);
164
165 /* Read all the channels in one I2C transaction. */
166 if (config->ops->read(dev, FXAS21002_REG_OUTXMSB, buffer,
167 sizeof(buffer))) {
168 LOG_ERR("Could not fetch sample");
169 ret = -EIO;
170 goto exit;
171 }
172
173 /* Parse the buffer into raw channel data (16-bit integers). To save
174 * RAM, store the data in raw format and wait to convert to the
175 * normalized sensor_value type until later.
176 */
177 raw = &data->raw[0];
178
179 for (i = 0; i < sizeof(buffer); i += 2) {
180 *raw++ = (buffer[i] << 8) | (buffer[i+1]);
181 }
182
183 exit:
184 k_sem_give(&data->sem);
185
186 return ret;
187 }
188
fxas21002_convert(struct sensor_value * val,int16_t raw,enum fxas21002_range range)189 static void fxas21002_convert(struct sensor_value *val, int16_t raw,
190 enum fxas21002_range range)
191 {
192 int32_t micro_rad;
193
194 /* Convert units to micro radians per second.
195 * 62500 micro dps * 2*pi/360 = 1091 micro radians per second
196 */
197 micro_rad = (raw * 1091) >> range;
198
199 val->val1 = micro_rad / 1000000;
200 val->val2 = micro_rad % 1000000;
201 }
202
fxas21002_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)203 static int fxas21002_channel_get(const struct device *dev,
204 enum sensor_channel chan,
205 struct sensor_value *val)
206 {
207 const struct fxas21002_config *config = dev->config;
208 struct fxas21002_data *data = dev->data;
209 int start_channel;
210 int num_channels;
211 int16_t *raw;
212 int ret;
213 int i;
214
215 k_sem_take(&data->sem, K_FOREVER);
216
217 /* Start with an error return code by default, then clear it if we find
218 * a supported sensor channel.
219 */
220 ret = -ENOTSUP;
221
222 /* Convert raw gyroscope data to the normalized sensor_value type. */
223 switch (chan) {
224 case SENSOR_CHAN_GYRO_X:
225 start_channel = FXAS21002_CHANNEL_GYRO_X;
226 num_channels = 1;
227 break;
228 case SENSOR_CHAN_GYRO_Y:
229 start_channel = FXAS21002_CHANNEL_GYRO_Y;
230 num_channels = 1;
231 break;
232 case SENSOR_CHAN_GYRO_Z:
233 start_channel = FXAS21002_CHANNEL_GYRO_Z;
234 num_channels = 1;
235 break;
236 case SENSOR_CHAN_GYRO_XYZ:
237 start_channel = FXAS21002_CHANNEL_GYRO_X;
238 num_channels = 3;
239 break;
240 default:
241 start_channel = 0;
242 num_channels = 0;
243 break;
244 }
245
246 raw = &data->raw[start_channel];
247 for (i = 0; i < num_channels; i++) {
248 fxas21002_convert(val++, *raw++, config->range);
249 }
250
251 if (num_channels > 0) {
252 ret = 0;
253 }
254
255 if (ret != 0) {
256 LOG_ERR("Unsupported sensor channel");
257 }
258
259 k_sem_give(&data->sem);
260
261 return ret;
262 }
263
fxas21002_get_power(const struct device * dev,enum fxas21002_power * power)264 int fxas21002_get_power(const struct device *dev, enum fxas21002_power *power)
265 {
266 const struct fxas21002_config *config = dev->config;
267 uint8_t val = *power;
268
269 if (config->ops->byte_read(dev, FXAS21002_REG_CTRLREG1, &val)) {
270 LOG_ERR("Could not get power setting");
271 return -EIO;
272 }
273 val &= FXAS21002_CTRLREG1_POWER_MASK;
274 *power = val;
275
276 return 0;
277 }
278
fxas21002_set_power(const struct device * dev,enum fxas21002_power power)279 int fxas21002_set_power(const struct device *dev, enum fxas21002_power power)
280 {
281 const struct fxas21002_config *config = dev->config;
282
283 return config->ops->reg_field_update(dev, FXAS21002_REG_CTRLREG1,
284 FXAS21002_CTRLREG1_POWER_MASK, power);
285 }
286
fxas21002_get_transition_time(enum fxas21002_power start,enum fxas21002_power end,uint8_t dr)287 uint32_t fxas21002_get_transition_time(enum fxas21002_power start,
288 enum fxas21002_power end,
289 uint8_t dr)
290 {
291 uint32_t transition_time;
292
293 /* If not transitioning to active mode, then don't need to wait */
294 if (end != FXAS21002_POWER_ACTIVE) {
295 return 0;
296 }
297
298 /* Otherwise, the transition time depends on which state we're
299 * transitioning from. These times are defined by the datasheet.
300 */
301 transition_time = sample_period[dr];
302
303 if (start == FXAS21002_POWER_READY) {
304 transition_time += 5000U;
305 } else {
306 transition_time += 60000U;
307 }
308
309 return transition_time;
310 }
311
fxas21002_init(const struct device * dev)312 static int fxas21002_init(const struct device *dev)
313 {
314 const struct fxas21002_config *config = dev->config;
315 struct fxas21002_data *data = dev->data;
316 uint32_t transition_time;
317 uint8_t whoami;
318
319 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
320 uint8_t ctrlreg1;
321
322 if (config->inst_on_bus == FXAS21002_BUS_I2C) {
323 if (!device_is_ready(config->bus_cfg.i2c.bus)) {
324 LOG_ERR("I2C bus device not ready");
325 return -ENODEV;
326 }
327 }
328 #endif
329
330 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
331 if (config->inst_on_bus == FXAS21002_BUS_SPI) {
332 if (!device_is_ready(config->bus_cfg.spi.bus)) {
333 LOG_ERR("SPI bus device not ready");
334 return -ENODEV;
335 }
336
337 if (config->reset_gpio.port) {
338 /* Pulse RST pin high to perform a hardware reset of
339 * the sensor.
340 */
341 if (!gpio_is_ready_dt(&config->reset_gpio)) {
342 LOG_ERR("GPIO device not ready");
343 return -ENODEV;
344 }
345
346 gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE);
347
348 gpio_pin_set_dt(&config->reset_gpio, 1);
349 /* The datasheet does not mention how long to pulse
350 * the RST pin high in order to reset. Stay on the
351 * safe side and pulse for 1 millisecond.
352 */
353 k_busy_wait(USEC_PER_MSEC);
354 gpio_pin_set_dt(&config->reset_gpio, 0);
355 k_busy_wait(USEC_PER_MSEC);
356 }
357 }
358 #endif
359
360 /* Read the WHOAMI register to make sure we are talking to FXAS21002
361 * and not some other type of device that happens to have the same I2C
362 * address.
363 */
364 if (config->ops->byte_read(dev, FXAS21002_REG_WHOAMI, &whoami)) {
365 LOG_ERR("Could not get WHOAMI value");
366 return -EIO;
367 }
368
369 if (whoami != config->whoami) {
370 LOG_ERR("WHOAMI value received 0x%x, expected 0x%x",
371 whoami, config->whoami);
372 return -EIO;
373 }
374
375 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
376 if (config->inst_on_bus == FXAS21002_BUS_I2C) {
377 /* Reset the sensor. Upon issuing a software reset command over the I2C
378 * interface, the sensor immediately resets and does not send any
379 * acknowledgment (ACK) of the written byte to the master. Therefore,
380 * do not check the return code of the I2C transaction.
381 */
382 config->ops->byte_write(dev, FXAS21002_REG_CTRLREG1,
383 FXAS21002_CTRLREG1_RST_MASK);
384
385 /* Wait for the reset sequence to complete */
386 do {
387 if (config->ops->byte_read(dev, FXAS21002_REG_CTRLREG1,
388 &ctrlreg1)) {
389 LOG_ERR("Could not get ctrlreg1 value");
390 return -EIO;
391 }
392 } while (ctrlreg1 & FXAS21002_CTRLREG1_RST_MASK);
393 }
394 #endif
395
396 /* Set the full-scale range */
397 if (config->ops->reg_field_update(dev, FXAS21002_REG_CTRLREG0,
398 FXAS21002_CTRLREG0_FS_MASK, config->range)) {
399 LOG_ERR("Could not set range");
400 return -EIO;
401 }
402
403 /* Set the output data rate */
404 if (config->ops->reg_field_update(dev, FXAS21002_REG_CTRLREG1,
405 FXAS21002_CTRLREG1_DR_MASK,
406 config->dr << FXAS21002_CTRLREG1_DR_SHIFT)) {
407 LOG_ERR("Could not set output data rate");
408 return -EIO;
409 }
410
411 k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT);
412
413 #if CONFIG_FXAS21002_TRIGGER
414 if (config->int_gpio.port) {
415 if (fxas21002_trigger_init(dev)) {
416 LOG_ERR("Could not initialize interrupts");
417 return -EIO;
418 }
419 }
420 #endif
421
422 /* Set active */
423 if (fxas21002_set_power(dev, FXAS21002_POWER_ACTIVE)) {
424 LOG_ERR("Could not set active");
425 return -EIO;
426 }
427
428 /* Wait the transition time from standby to active mode */
429 transition_time = fxas21002_get_transition_time(FXAS21002_POWER_STANDBY,
430 FXAS21002_POWER_ACTIVE,
431 config->dr);
432 k_busy_wait(transition_time);
433 k_sem_give(&data->sem);
434
435 LOG_DBG("Init complete");
436
437 return 0;
438 }
439
440 static DEVICE_API(sensor, fxas21002_driver_api) = {
441 .sample_fetch = fxas21002_sample_fetch,
442 .channel_get = fxas21002_channel_get,
443 #if CONFIG_FXAS21002_TRIGGER
444 .trigger_set = fxas21002_trigger_set,
445 #endif
446 };
447
448 #define FXAS21002_CONFIG_I2C(inst) \
449 .bus_cfg = { .i2c = I2C_DT_SPEC_INST_GET(inst) }, \
450 .ops = &fxas21002_i2c_ops, \
451 .inst_on_bus = FXAS21002_BUS_I2C, \
452
453 #define FXAS21002_CONFIG_SPI(inst) \
454 .bus_cfg = {.spi = SPI_DT_SPEC_INST_GET(inst, \
455 SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0) }, \
456 .ops = &fxas21002_spi_ops, \
457 .reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios), \
458 .inst_on_bus = FXAS21002_BUS_SPI, \
459
460 #define FXAS21002_DEFINE(inst) \
461 static struct fxas21002_data fxas21002_data_##inst; \
462 \
463 static const struct fxas21002_config fxas21002_config_##inst = { \
464 COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
465 (FXAS21002_CONFIG_SPI(inst)), \
466 (FXAS21002_CONFIG_I2C(inst))) \
467 .whoami = CONFIG_FXAS21002_WHOAMI, \
468 .range = CONFIG_FXAS21002_RANGE, \
469 .dr = CONFIG_FXAS21002_DR, \
470 IF_ENABLED(CONFIG_FXAS21002_TRIGGER, \
471 (COND_CODE_1(CONFIG_FXAS21002_DRDY_INT1, \
472 (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, \
473 { 0 }),), \
474 (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, \
475 { 0 }),)))) \
476 }; \
477 \
478 SENSOR_DEVICE_DT_INST_DEFINE(inst, fxas21002_init, NULL, \
479 &fxas21002_data_##inst, &fxas21002_config_##inst, \
480 POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
481 &fxas21002_driver_api); \
482
483 DT_INST_FOREACH_STATUS_OKAY(FXAS21002_DEFINE)
484