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