File Index
Files and directories
Sign in
FILE

smi330_core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/imu/smi330/smi330_core.c C
  1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2/*
  3 * Copyright (c) 2025 Robert Bosch GmbH.
  4 */
  5#include <linux/bitfield.h>
  6#include <linux/delay.h>
  7#include <linux/interrupt.h>
  8#include <linux/irq.h>
  9#include <linux/module.h>
 10#include <linux/property.h>
 11#include <linux/regmap.h>
 12#include <linux/string.h>
 13#include <linux/units.h>
 14
 15#include <linux/iio/buffer.h>
 16#include <linux/iio/iio.h>
 17#include <linux/iio/trigger.h>
 18#include <linux/iio/trigger_consumer.h>
 19#include <linux/iio/triggered_buffer.h>
 20
 21#include "smi330.h"
 22
 23/* Register map */
 24#define SMI330_CHIP_ID_REG 0x00
 25#define SMI330_ERR_REG 0x01
 26#define SMI330_STATUS_REG 0x02
 27#define SMI330_ACCEL_X_REG 0x03
 28#define SMI330_GYRO_X_REG 0x06
 29#define SMI330_TEMP_REG 0x09
 30#define SMI330_INT1_STATUS_REG 0x0D
 31#define SMI330_ACCEL_CFG_REG 0x20
 32#define SMI330_GYRO_CFG_REG 0x21
 33#define SMI330_IO_INT_CTRL_REG 0x38
 34#define SMI330_INT_CONF_REG 0x39
 35#define SMI330_INT_MAP1_REG 0x3A
 36#define SMI330_INT_MAP2_REG 0x3B
 37#define SMI330_CMD_REG 0x7E
 38
 39/* Register mask */
 40#define SMI330_CHIP_ID_MASK GENMASK(7, 0)
 41#define SMI330_ERR_FATAL_MASK BIT(0)
 42#define SMI330_ERR_ACC_CONF_MASK BIT(5)
 43#define SMI330_ERR_GYR_CONF_MASK BIT(6)
 44#define SMI330_STATUS_POR_MASK BIT(0)
 45#define SMI330_INT_STATUS_ACC_GYR_DRDY_MASK GENMASK(13, 12)
 46#define SMI330_CFG_ODR_MASK GENMASK(3, 0)
 47#define SMI330_CFG_RANGE_MASK GENMASK(6, 4)
 48#define SMI330_CFG_BW_MASK BIT(7)
 49#define SMI330_CFG_AVG_NUM_MASK GENMASK(10, 8)
 50#define SMI330_CFG_MODE_MASK GENMASK(14, 12)
 51#define SMI330_IO_INT_CTRL_INT1_MASK GENMASK(2, 0)
 52#define SMI330_IO_INT_CTRL_INT2_MASK GENMASK(10, 8)
 53#define SMI330_INT_CONF_LATCH_MASK BIT(0)
 54#define SMI330_INT_MAP2_ACC_DRDY_MASK GENMASK(11, 10)
 55#define SMI330_INT_MAP2_GYR_DRDY_MASK GENMASK(9, 8)
 56
 57/* Register values */
 58#define SMI330_IO_INT_CTRL_LVL BIT(0)
 59#define SMI330_IO_INT_CTRL_OD BIT(1)
 60#define SMI330_IO_INT_CTRL_EN BIT(2)
 61#define SMI330_CMD_SOFT_RESET 0xDEAF
 62
 63/* T°C = (temp / 512) + 23 */
 64#define SMI330_TEMP_OFFSET 11776 /* 23 * 512 */
 65#define SMI330_TEMP_SCALE 1953125 /* (1 / 512) * 1e9 */
 66
 67#define SMI330_CHIP_ID 0x42
 68#define SMI330_SOFT_RESET_DELAY 2000
 69
 70/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
 71#define smi330_field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
 72#define smi330_field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
 73
 74#define SMI330_ACCEL_CHANNEL(_axis) {					\
 75	.type = IIO_ACCEL,						\
 76	.modified = 1,							\
 77	.channel2 = IIO_MOD_##_axis,					\
 78	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
 79	.info_mask_shared_by_type =					\
 80		BIT(IIO_CHAN_INFO_SAMP_FREQ) |				\
 81		BIT(IIO_CHAN_INFO_SCALE) |				\
 82		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |			\
 83		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 84	.info_mask_shared_by_type_available =				\
 85		BIT(IIO_CHAN_INFO_SCALE) |				\
 86		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |			\
 87		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 88	.info_mask_shared_by_dir_available =				\
 89		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 90	.scan_index = SMI330_SCAN_ACCEL_##_axis,			\
 91	.scan_type = {							\
 92		.sign = 's',						\
 93		.realbits = 16,						\
 94		.storagebits = 16,					\
 95		.endianness = IIO_LE,					\
 96	},								\
 97}
 98
 99#define SMI330_GYRO_CHANNEL(_axis) {					\
100	.type = IIO_ANGL_VEL,						\
101	.modified = 1,							\
102	.channel2 = IIO_MOD_##_axis,					\
103	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
104	.info_mask_shared_by_type =					\
105		BIT(IIO_CHAN_INFO_SAMP_FREQ) |				\
106		BIT(IIO_CHAN_INFO_SCALE) |				\
107		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |			\
108		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
109	.info_mask_shared_by_type_available =				\
110		BIT(IIO_CHAN_INFO_SCALE) |				\
111		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |			\
112		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
113	.info_mask_shared_by_dir_available =				\
114		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
115	.scan_index = SMI330_SCAN_GYRO_##_axis,				\
116	.scan_type = {							\
117		.sign = 's',						\
118		.realbits = 16,						\
119		.storagebits = 16,					\
120		.endianness = IIO_LE,					\
121	},								\
122}
123
124#define SMI330_TEMP_CHANNEL(_index) {			\
125	.type = IIO_TEMP,				\
126	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
127		BIT(IIO_CHAN_INFO_OFFSET) |		\
128		BIT(IIO_CHAN_INFO_SCALE),		\
129	.scan_index = _index,				\
130	.scan_type = {					\
131		.sign = 's',				\
132		.realbits = 16,				\
133		.storagebits = 16,			\
134		.endianness = IIO_LE,			\
135	},						\
136}
137
138enum smi330_accel_range {
139	SMI330_ACCEL_RANGE_2G = 0x00,
140	SMI330_ACCEL_RANGE_4G = 0x01,
141	SMI330_ACCEL_RANGE_8G = 0x02,
142	SMI330_ACCEL_RANGE_16G = 0x03
143};
144
145enum smi330_gyro_range {
146	SMI330_GYRO_RANGE_125 = 0x0,
147	SMI330_GYRO_RANGE_250 = 0x01,
148	SMI330_GYRO_RANGE_500 = 0x02
149};
150
151enum smi330_odr {
152	SMI330_ODR_12_5_HZ = 0x05,
153	SMI330_ODR_25_HZ = 0x06,
154	SMI330_ODR_50_HZ = 0x07,
155	SMI330_ODR_100_HZ = 0x08,
156	SMI330_ODR_200_HZ = 0x09,
157	SMI330_ODR_400_HZ = 0x0A,
158	SMI330_ODR_800_HZ = 0x0B,
159	SMI330_ODR_1600_HZ = 0x0C,
160	SMI330_ODR_3200_HZ = 0x0D,
161	SMI330_ODR_6400_HZ = 0x0E
162};
163
164enum smi330_avg_num {
165	SMI330_AVG_NUM_1 = 0x00,
166	SMI330_AVG_NUM_2 = 0x01,
167	SMI330_AVG_NUM_4 = 0x02,
168	SMI330_AVG_NUM_8 = 0x03,
169	SMI330_AVG_NUM_16 = 0x04,
170	SMI330_AVG_NUM_32 = 0x05,
171	SMI330_AVG_NUM_64 = 0x06
172};
173
174enum smi330_mode {
175	SMI330_MODE_SUSPEND = 0x00,
176	SMI330_MODE_GYRO_DRIVE = 0x01,
177	SMI330_MODE_LOW_POWER = 0x03,
178	SMI330_MODE_NORMAL = 0x04,
179	SMI330_MODE_HIGH_PERF = 0x07
180};
181
182enum smi330_bw {
183	SMI330_BW_2 = 0x00, /* ODR/2 */
184	SMI330_BW_4 = 0x01 /* ODR/4 */
185};
186
187enum smi330_operation_mode {
188	SMI330_POLLING,
189	SMI330_DATA_READY,
190};
191
192enum smi330_sensor {
193	SMI330_ACCEL,
194	SMI330_GYRO,
195};
196
197enum smi330_sensor_conf_select {
198	SMI330_ODR,
199	SMI330_RANGE,
200	SMI330_BW,
201	SMI330_AVG_NUM,
202};
203
204enum smi330_int_out {
205	SMI330_INT_DISABLED,
206	SMI330_INT_1,
207	SMI330_INT_2,
208};
209
210struct smi330_attributes {
211	int *reg_vals;
212	int *vals;
213	int len;
214	int type;
215	int mask;
216};
217
218struct smi330_cfg {
219	enum smi330_operation_mode op_mode;
220	enum smi330_int_out data_irq;
221};
222
223struct smi330_data {
224	struct regmap *regmap;
225	struct smi330_cfg cfg;
226	struct iio_trigger *trig;
227	IIO_DECLARE_BUFFER_WITH_TS(__le16, buf, SMI330_SCAN_LEN);
228};
229
230const struct regmap_config smi330_regmap_config = {
231	.reg_bits = 8,
232	.val_bits = 16,
233	.val_format_endian = REGMAP_ENDIAN_LITTLE,
234};
235EXPORT_SYMBOL_NS_GPL(smi330_regmap_config, "IIO_SMI330");
236
237static const struct iio_chan_spec smi330_channels[] = {
238	SMI330_ACCEL_CHANNEL(X),
239	SMI330_ACCEL_CHANNEL(Y),
240	SMI330_ACCEL_CHANNEL(Z),
241	SMI330_GYRO_CHANNEL(X),
242	SMI330_GYRO_CHANNEL(Y),
243	SMI330_GYRO_CHANNEL(Z),
244	SMI330_TEMP_CHANNEL(-1), /* No buffer support */
245	IIO_CHAN_SOFT_TIMESTAMP(SMI330_SCAN_TIMESTAMP),
246};
247
248static const unsigned long smi330_avail_scan_masks[] = {
249	(BIT(SMI330_SCAN_ACCEL_X) | BIT(SMI330_SCAN_ACCEL_Y) |
250	 BIT(SMI330_SCAN_ACCEL_Z) | BIT(SMI330_SCAN_GYRO_X) |
251	 BIT(SMI330_SCAN_GYRO_Y) | BIT(SMI330_SCAN_GYRO_Z)),
252	0
253};
254
255static const struct smi330_attributes smi330_accel_scale_attr = {
256	.reg_vals = (int[]){ SMI330_ACCEL_RANGE_2G, SMI330_ACCEL_RANGE_4G,
257			     SMI330_ACCEL_RANGE_8G, SMI330_ACCEL_RANGE_16G },
258	.vals = (int[]){ 0, 61035, 0, 122070, 0, 244140, 0, 488281 },
259	.len = 8,
260	.type = IIO_VAL_INT_PLUS_NANO,
261	.mask = SMI330_CFG_RANGE_MASK
262};
263
264static const struct smi330_attributes smi330_gyro_scale_attr = {
265	.reg_vals = (int[]){ SMI330_GYRO_RANGE_125, SMI330_GYRO_RANGE_250,
266			     SMI330_GYRO_RANGE_500 },
267	.vals = (int[]){ 0, 3814697, 0, 7629395, 0, 15258789 },
268	.len = 6,
269	.type = IIO_VAL_INT_PLUS_NANO,
270	.mask = SMI330_CFG_RANGE_MASK
271};
272
273static const struct smi330_attributes smi330_average_attr = {
274	.reg_vals = (int[]){ SMI330_AVG_NUM_1, SMI330_AVG_NUM_2,
275			     SMI330_AVG_NUM_4, SMI330_AVG_NUM_8,
276			     SMI330_AVG_NUM_16, SMI330_AVG_NUM_32,
277			     SMI330_AVG_NUM_64 },
278	.vals = (int[]){ 1, 2, 4, 8, 16, 32, 64 },
279	.len = 7,
280	.type = IIO_VAL_INT,
281	.mask = SMI330_CFG_AVG_NUM_MASK
282};
283
284static const struct smi330_attributes smi330_bandwidth_attr = {
285	.reg_vals = (int[]){ SMI330_BW_2, SMI330_BW_4 },
286	.vals = (int[]){ 2, 4 },
287	.len = 2,
288	.type = IIO_VAL_INT,
289	.mask = SMI330_CFG_BW_MASK
290};
291
292static const struct smi330_attributes smi330_odr_attr = {
293	.reg_vals = (int[]){ SMI330_ODR_12_5_HZ, SMI330_ODR_25_HZ,
294			     SMI330_ODR_50_HZ, SMI330_ODR_100_HZ,
295			     SMI330_ODR_200_HZ, SMI330_ODR_400_HZ,
296			     SMI330_ODR_800_HZ, SMI330_ODR_1600_HZ,
297			     SMI330_ODR_3200_HZ, SMI330_ODR_6400_HZ },
298	.vals = (int[]){ 12, 25, 50, 100, 200, 400, 800, 1600, 3200, 6400 },
299	.len = 10,
300	.type = IIO_VAL_INT,
301	.mask = SMI330_CFG_ODR_MASK
302};
303
304static int smi330_get_attributes(enum smi330_sensor_conf_select config,
305				 enum smi330_sensor sensor,
306				 const struct smi330_attributes **attr)
307{
308	switch (config) {
309	case SMI330_ODR:
310		*attr = &smi330_odr_attr;
311		return 0;
312	case SMI330_RANGE:
313		if (sensor == SMI330_ACCEL)
314			*attr = &smi330_accel_scale_attr;
315		else
316			*attr = &smi330_gyro_scale_attr;
317		return 0;
318	case SMI330_BW:
319		*attr = &smi330_bandwidth_attr;
320		return 0;
321	case SMI330_AVG_NUM:
322		*attr = &smi330_average_attr;
323		return 0;
324	default:
325		return -EINVAL;
326	}
327}
328
329static int smi330_get_config_reg(enum smi330_sensor sensor, int *reg)
330{
331	switch (sensor) {
332	case SMI330_ACCEL:
333		*reg = SMI330_ACCEL_CFG_REG;
334		return 0;
335	case SMI330_GYRO:
336		*reg = SMI330_GYRO_CFG_REG;
337		return 0;
338	default:
339		return -EINVAL;
340	}
341}
342
343static int smi330_get_sensor_config(struct smi330_data *data,
344				    enum smi330_sensor sensor,
345				    enum smi330_sensor_conf_select config,
346				    int *value)
347
348{
349	int ret, reg, reg_val, i;
350	const struct smi330_attributes *attr;
351
352	ret = smi330_get_config_reg(sensor, &reg);
353	if (ret)
354		return ret;
355
356	ret = regmap_read(data->regmap, reg, &reg_val);
357	if (ret)
358		return ret;
359
360	ret = smi330_get_attributes(config, sensor, &attr);
361	if (ret)
362		return ret;
363
364	reg_val = smi330_field_get(attr->mask, reg_val);
365
366	if (attr->type == IIO_VAL_INT) {
367		for (i = 0; i < attr->len; i++) {
368			if (attr->reg_vals[i] == reg_val) {
369				*value = attr->vals[i];
370				return 0;
371			}
372		}
373	} else {
374		for (i = 0; i < attr->len / 2; i++) {
375			if (attr->reg_vals[i] == reg_val) {
376				*value = attr->vals[2 * i + 1];
377				return 0;
378			}
379		}
380	}
381
382	return -EINVAL;
383}
384
385static int smi330_set_sensor_config(struct smi330_data *data,
386				    enum smi330_sensor sensor,
387				    enum smi330_sensor_conf_select config,
388				    int value)
389{
390	int ret, i, reg, reg_val, error;
391	const struct smi330_attributes *attr;
392
393	ret = smi330_get_attributes(config, sensor, &attr);
394	if (ret)
395		return ret;
396
397	for (i = 0; i < attr->len; i++) {
398		if (attr->vals[i] == value) {
399			if (attr->type == IIO_VAL_INT)
400				reg_val = attr->reg_vals[i];
401			else
402				reg_val = attr->reg_vals[i / 2];
403			break;
404		}
405	}
406	if (i == attr->len)
407		return -EINVAL;
408
409	ret = smi330_get_config_reg(sensor, &reg);
410	if (ret)
411		return ret;
412
413	reg_val = smi330_field_prep(attr->mask, reg_val);
414	ret = regmap_update_bits(data->regmap, reg, attr->mask, reg_val);
415	if (ret)
416		return ret;
417
418	ret = regmap_read(data->regmap, SMI330_ERR_REG, &error);
419	if (ret)
420		return ret;
421
422	if (FIELD_GET(SMI330_ERR_ACC_CONF_MASK, error) ||
423	    FIELD_GET(SMI330_ERR_GYR_CONF_MASK, error))
424		return -EIO;
425
426	return 0;
427}
428
429static int smi330_get_data(struct smi330_data *data, int chan_type, int axis,
430			   int *val)
431{
432	u8 reg;
433	int ret, sample;
434
435	switch (chan_type) {
436	case IIO_ACCEL:
437		reg = SMI330_ACCEL_X_REG + (axis - IIO_MOD_X);
438		break;
439	case IIO_ANGL_VEL:
440		reg = SMI330_GYRO_X_REG + (axis - IIO_MOD_X);
441		break;
442	case IIO_TEMP:
443		reg = SMI330_TEMP_REG;
444		break;
445	default:
446		return -EINVAL;
447	}
448
449	ret = regmap_read(data->regmap, reg, &sample);
450	if (ret)
451		return ret;
452
453	*val = sign_extend32(sample, 15);
454
455	return 0;
456}
457
458static int smi330_read_avail(struct iio_dev *indio_dev,
459			     struct iio_chan_spec const *chan, const int **vals,
460			     int *type, int *length, long mask)
461{
462	switch (mask) {
463	case IIO_CHAN_INFO_SCALE:
464		if (chan->type == IIO_ACCEL) {
465			*vals = smi330_accel_scale_attr.vals;
466			*length = smi330_accel_scale_attr.len;
467			*type = smi330_accel_scale_attr.type;
468		} else {
469			*vals = smi330_gyro_scale_attr.vals;
470			*length = smi330_gyro_scale_attr.len;
471			*type = smi330_gyro_scale_attr.type;
472		}
473		return IIO_AVAIL_LIST;
474	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
475		*vals = smi330_average_attr.vals;
476		*length = smi330_average_attr.len;
477		*type = smi330_average_attr.type;
478		*type = IIO_VAL_INT;
479		return IIO_AVAIL_LIST;
480	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
481		*vals = smi330_bandwidth_attr.vals;
482		*length = smi330_bandwidth_attr.len;
483		*type = smi330_bandwidth_attr.type;
484		return IIO_AVAIL_LIST;
485	case IIO_CHAN_INFO_SAMP_FREQ:
486		*vals = smi330_odr_attr.vals;
487		*length = smi330_odr_attr.len;
488		*type = smi330_odr_attr.type;
489		return IIO_AVAIL_LIST;
490	default:
491		return -EINVAL;
492	}
493}
494
495static int smi330_read_raw(struct iio_dev *indio_dev,
496			   struct iio_chan_spec const *chan, int *val,
497			   int *val2, long mask)
498{
499	int ret;
500	struct smi330_data *data = iio_priv(indio_dev);
501	enum smi330_sensor sensor;
502
503	/* valid for all channel types */
504	switch (mask) {
505	case IIO_CHAN_INFO_RAW:
506		if (!iio_device_claim_direct(indio_dev))
507			return -EBUSY;
508		ret = smi330_get_data(data, chan->type, chan->channel2, val);
509		iio_device_release_direct(indio_dev);
510		return ret ? ret : IIO_VAL_INT;
511	default:
512		break;
513	}
514
515	switch (chan->type) {
516	case IIO_ACCEL:
517		sensor = SMI330_ACCEL;
518		break;
519	case IIO_ANGL_VEL:
520		sensor = SMI330_GYRO;
521		break;
522	case IIO_TEMP:
523		switch (mask) {
524		case IIO_CHAN_INFO_SCALE:
525			*val = SMI330_TEMP_SCALE / GIGA;
526			*val2 = SMI330_TEMP_SCALE % GIGA;
527			return IIO_VAL_INT_PLUS_NANO;
528		case IIO_CHAN_INFO_OFFSET:
529			*val = SMI330_TEMP_OFFSET;
530			return IIO_VAL_INT;
531		default:
532			return -EINVAL;
533		}
534	default:
535		return -EINVAL;
536	}
537
538	/* valid for acc and gyro channels */
539	switch (mask) {
540	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
541		ret = smi330_get_sensor_config(data, sensor, SMI330_AVG_NUM,
542					       val);
543		return ret ? ret : IIO_VAL_INT;
544
545	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
546		ret = smi330_get_sensor_config(data, sensor, SMI330_BW, val);
547		return ret ? ret : IIO_VAL_INT;
548
549	case IIO_CHAN_INFO_SAMP_FREQ:
550		ret = smi330_get_sensor_config(data, sensor, SMI330_ODR, val);
551		return ret ? ret : IIO_VAL_INT;
552
553	case IIO_CHAN_INFO_SCALE:
554		*val = 0;
555		ret = smi330_get_sensor_config(data, sensor, SMI330_RANGE,
556					       val2);
557		return ret ? ret : IIO_VAL_INT_PLUS_NANO;
558
559	default:
560		return -EINVAL;
561	}
562}
563
564static int smi330_write_raw(struct iio_dev *indio_dev,
565			    struct iio_chan_spec const *chan, int val, int val2,
566			    long mask)
567{
568	struct smi330_data *data = iio_priv(indio_dev);
569	enum smi330_sensor sensor;
570
571	switch (chan->type) {
572	case IIO_ACCEL:
573		sensor = SMI330_ACCEL;
574		break;
575	case IIO_ANGL_VEL:
576		sensor = SMI330_GYRO;
577		break;
578	default:
579		return -EINVAL;
580	}
581
582	switch (mask) {
583	case IIO_CHAN_INFO_SCALE:
584		return smi330_set_sensor_config(data, sensor, SMI330_RANGE,
585						val2);
586	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
587		return smi330_set_sensor_config(data, sensor, SMI330_AVG_NUM,
588						val);
589	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
590		return smi330_set_sensor_config(data, sensor, SMI330_BW, val);
591	case IIO_CHAN_INFO_SAMP_FREQ:
592		return smi330_set_sensor_config(data, sensor, SMI330_ODR, val);
593	default:
594		return -EINVAL;
595	}
596}
597
598static int smi330_write_raw_get_fmt(struct iio_dev *indio_dev,
599				    struct iio_chan_spec const *chan, long info)
600{
601	switch (info) {
602	case IIO_CHAN_INFO_SCALE:
603		return IIO_VAL_INT_PLUS_NANO;
604	default:
605		return IIO_VAL_INT_PLUS_MICRO;
606	}
607}
608
609static int smi330_soft_reset(struct smi330_data *data)
610{
611	int ret, dummy_byte;
612
613	ret = regmap_write(data->regmap, SMI330_CMD_REG, SMI330_CMD_SOFT_RESET);
614	if (ret)
615		return ret;
616	fsleep(SMI330_SOFT_RESET_DELAY);
617
618	/* Performing a dummy read after a soft-reset */
619	regmap_read(data->regmap, SMI330_CHIP_ID_REG, &dummy_byte);
620
621	return 0;
622}
623
624static irqreturn_t smi330_trigger_handler(int irq, void *p)
625{
626	int ret;
627	struct iio_poll_func *pf = p;
628	struct iio_dev *indio_dev = pf->indio_dev;
629	struct smi330_data *data = iio_priv(indio_dev);
630
631	ret = regmap_bulk_read(data->regmap, SMI330_ACCEL_X_REG, data->buf,
632			       SMI330_SCAN_LEN);
633	if (ret)
634		goto out;
635
636	iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp);
637
638out:
639	iio_trigger_notify_done(indio_dev->trig);
640
641	return IRQ_HANDLED;
642}
643
644static irqreturn_t smi330_irq_thread_handler(int irq, void *indio_dev_)
645{
646	int ret, int_stat;
647	s16 int_status[2] = { 0 };
648	struct iio_dev *indio_dev = indio_dev_;
649	struct smi330_data *data = iio_priv(indio_dev);
650
651	ret = regmap_bulk_read(data->regmap, SMI330_INT1_STATUS_REG, int_status, 2);
652	if (ret)
653		return IRQ_NONE;
654
655	int_stat = int_status[0] | int_status[1];
656
657	if (FIELD_GET(SMI330_INT_STATUS_ACC_GYR_DRDY_MASK, int_stat)) {
658		indio_dev->pollfunc->timestamp = iio_get_time_ns(indio_dev);
659		iio_trigger_poll_nested(data->trig);
660	}
661
662	return IRQ_HANDLED;
663}
664
665static int smi330_set_int_pin_config(struct smi330_data *data,
666				     enum smi330_int_out irq_num,
667				     bool active_high, bool open_drain,
668				     bool latch)
669{
670	int ret, val;
671
672	val = active_high ? SMI330_IO_INT_CTRL_LVL : 0;
673	val |= open_drain ? SMI330_IO_INT_CTRL_OD : 0;
674	val |= SMI330_IO_INT_CTRL_EN;
675
676	switch (irq_num) {
677	case SMI330_INT_1:
678		val = FIELD_PREP(SMI330_IO_INT_CTRL_INT1_MASK, val);
679		ret = regmap_update_bits(data->regmap, SMI330_IO_INT_CTRL_REG,
680					 SMI330_IO_INT_CTRL_INT1_MASK, val);
681		if (ret)
682			return ret;
683		break;
684	case SMI330_INT_2:
685		val = FIELD_PREP(SMI330_IO_INT_CTRL_INT2_MASK, val);
686		ret = regmap_update_bits(data->regmap, SMI330_IO_INT_CTRL_REG,
687					 SMI330_IO_INT_CTRL_INT2_MASK, val);
688		if (ret)
689			return ret;
690		break;
691	default:
692		return -EINVAL;
693	}
694
695	return regmap_update_bits(data->regmap, SMI330_INT_CONF_REG,
696				  SMI330_INT_CONF_LATCH_MASK,
697				  FIELD_PREP(SMI330_INT_CONF_LATCH_MASK,
698					     latch));
699}
700
701static int smi330_setup_irq(struct device *dev, struct iio_dev *indio_dev,
702			    int irq, enum smi330_int_out irq_num)
703{
704	int ret, irq_type;
705	bool open_drain, active_high, latch;
706	struct smi330_data *data = iio_priv(indio_dev);
707	struct irq_data *desc;
708
709	desc = irq_get_irq_data(irq);
710	if (!desc)
711		return -EINVAL;
712
713	irq_type = irqd_get_trigger_type(desc);
714	switch (irq_type) {
715	case IRQF_TRIGGER_RISING:
716		latch = false;
717		active_high = true;
718		break;
719	case IRQF_TRIGGER_HIGH:
720		latch = true;
721		active_high = true;
722		break;
723	case IRQF_TRIGGER_FALLING:
724		latch = false;
725		active_high = false;
726		break;
727	case IRQF_TRIGGER_LOW:
728		latch = true;
729		active_high = false;
730		break;
731	default:
732		return -EINVAL;
733	}
734
735	open_drain = device_property_read_bool(dev, "drive-open-drain");
736
737	ret = smi330_set_int_pin_config(data, irq_num, active_high, open_drain,
738					latch);
739	if (ret)
740		return ret;
741
742	return devm_request_threaded_irq(dev, irq, NULL,
743					 smi330_irq_thread_handler,
744					 irq_type | IRQF_ONESHOT,
745					 indio_dev->name, indio_dev);
746}
747
748static int smi330_register_irq(struct device *dev, struct iio_dev *indio_dev)
749{
750	int ret, irq;
751	struct smi330_data *data = iio_priv(indio_dev);
752	struct fwnode_handle *fwnode;
753
754	fwnode = dev_fwnode(dev);
755	if (!fwnode)
756		return -ENODEV;
757
758	data->cfg.data_irq = SMI330_INT_DISABLED;
759
760	irq = fwnode_irq_get_byname(fwnode, "INT1");
761	if (irq > 0) {
762		ret = smi330_setup_irq(dev, indio_dev, irq, SMI330_INT_1);
763		if (ret)
764			return ret;
765		data->cfg.data_irq = SMI330_INT_1;
766	} else {
767		irq = fwnode_irq_get_byname(fwnode, "INT2");
768		if (irq > 0) {
769			ret = smi330_setup_irq(dev, indio_dev, irq,
770					       SMI330_INT_2);
771			if (ret)
772				return ret;
773			data->cfg.data_irq = SMI330_INT_2;
774		}
775	}
776
777	return 0;
778}
779
780static int smi330_set_drdy_trigger_state(struct iio_trigger *trig, bool enable)
781{
782	int val;
783	struct smi330_data *data = iio_trigger_get_drvdata(trig);
784
785	if (enable)
786		data->cfg.op_mode = SMI330_DATA_READY;
787	else
788		data->cfg.op_mode = SMI330_POLLING;
789
790	val = FIELD_PREP(SMI330_INT_MAP2_ACC_DRDY_MASK,
791			 enable ? data->cfg.data_irq : 0);
792	val |= FIELD_PREP(SMI330_INT_MAP2_GYR_DRDY_MASK,
793			  enable ? data->cfg.data_irq : 0);
794	return regmap_update_bits(data->regmap, SMI330_INT_MAP2_REG,
795				  SMI330_INT_MAP2_ACC_DRDY_MASK |
796					  SMI330_INT_MAP2_GYR_DRDY_MASK,
797				  val);
798}
799
800static const struct iio_trigger_ops smi330_trigger_ops = {
801	.set_trigger_state = &smi330_set_drdy_trigger_state,
802};
803
804static struct iio_info smi330_info = {
805	.read_avail = smi330_read_avail,
806	.read_raw = smi330_read_raw,
807	.write_raw = smi330_write_raw,
808	.write_raw_get_fmt = smi330_write_raw_get_fmt,
809};
810
811static int smi330_dev_init(struct smi330_data *data)
812{
813	int ret, chip_id, val, mode;
814	struct device *dev = regmap_get_device(data->regmap);
815
816	ret = regmap_read(data->regmap, SMI330_CHIP_ID_REG, &chip_id);
817	if (ret)
818		return ret;
819
820	chip_id = FIELD_GET(SMI330_CHIP_ID_MASK, chip_id);
821	if (chip_id != SMI330_CHIP_ID)
822		dev_info(dev, "Unknown chip id: 0x%04x\n", chip_id);
823
824	ret = regmap_read(data->regmap, SMI330_ERR_REG, &val);
825	if (ret)
826		return ret;
827	if (FIELD_GET(SMI330_ERR_FATAL_MASK, val))
828		return -ENODEV;
829
830	ret = regmap_read(data->regmap, SMI330_STATUS_REG, &val);
831	if (ret)
832		return ret;
833	if (FIELD_GET(SMI330_STATUS_POR_MASK, val) == 0)
834		return -ENODEV;
835
836	mode = FIELD_PREP(SMI330_CFG_MODE_MASK, SMI330_MODE_NORMAL);
837
838	ret = regmap_update_bits(data->regmap, SMI330_ACCEL_CFG_REG,
839				 SMI330_CFG_MODE_MASK, mode);
840	if (ret)
841		return ret;
842
843	return regmap_update_bits(data->regmap, SMI330_GYRO_CFG_REG,
844				  SMI330_CFG_MODE_MASK, mode);
845}
846
847int smi330_core_probe(struct device *dev, struct regmap *regmap)
848{
849	int ret;
850	struct iio_dev *indio_dev;
851	struct smi330_data *data;
852
853	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
854	if (!indio_dev)
855		return -ENOMEM;
856
857	data = iio_priv(indio_dev);
858	data->regmap = regmap;
859
860	ret = smi330_soft_reset(data);
861	if (ret)
862		return dev_err_probe(dev, ret, "Soft reset failed\n");
863
864	indio_dev->channels = smi330_channels;
865	indio_dev->num_channels = ARRAY_SIZE(smi330_channels);
866	indio_dev->available_scan_masks = smi330_avail_scan_masks;
867	indio_dev->name = "smi330";
868	indio_dev->modes = INDIO_DIRECT_MODE;
869	indio_dev->info = &smi330_info;
870
871	data->cfg.op_mode = SMI330_POLLING;
872
873	ret = smi330_dev_init(data);
874	if (ret)
875		return dev_err_probe(dev, ret, "Init failed\n");
876
877	ret = smi330_register_irq(dev, indio_dev);
878	if (ret)
879		return dev_err_probe(dev, ret, "Register IRQ failed\n");
880
881	if (data->cfg.data_irq != SMI330_INT_DISABLED) {
882		data->trig = devm_iio_trigger_alloc(dev, "%s-drdy-trigger",
883						    indio_dev->name);
884		if (!data->trig)
885			return -ENOMEM;
886
887		data->trig->ops = &smi330_trigger_ops;
888		iio_trigger_set_drvdata(data->trig, data);
889
890		ret = devm_iio_trigger_register(dev, data->trig);
891		if (ret)
892			return dev_err_probe(dev, ret,
893					     "IIO register trigger failed\n");
894
895		/* Set default operation mode to data ready. */
896		indio_dev->trig = iio_trigger_get(data->trig);
897	}
898
899	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
900					      iio_pollfunc_store_time,
901					      smi330_trigger_handler, NULL);
902	if (ret)
903		return dev_err_probe(dev, ret, "IIO buffer setup failed\n");
904
905	ret = devm_iio_device_register(dev, indio_dev);
906	if (ret)
907		return dev_err_probe(dev, ret, "Register IIO device failed\n");
908
909	return 0;
910}
911EXPORT_SYMBOL_NS_GPL(smi330_core_probe, "IIO_SMI330");
912
913MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@de.bosch.com>");
914MODULE_AUTHOR("Roman Huber <roman.huber@de.bosch.com>");
915MODULE_AUTHOR("Filip Andrei <Andrei.Filip@ro.bosch.com>");
916MODULE_AUTHOR("Drimbarean Avram Andrei <Avram-Andrei.Drimbarean@ro.bosch.com>");
917MODULE_DESCRIPTION("Bosch SMI330 IMU driver");
918MODULE_LICENSE("Dual BSD/GPL");
~/ Read-only file preview.