xref: /OK3568_Linux_fs/kernel/drivers/iio/gyro/adxrs290.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * ADXRS290 SPI Gyroscope Driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2020 Nishant Malpani <nish.malpani25@gmail.com>
6*4882a593Smuzhiyun  * Copyright (C) 2020 Analog Devices, Inc.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/bitfield.h>
10*4882a593Smuzhiyun #include <linux/bitops.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/spi/spi.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <linux/iio/buffer.h>
18*4882a593Smuzhiyun #include <linux/iio/iio.h>
19*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
20*4882a593Smuzhiyun #include <linux/iio/trigger.h>
21*4882a593Smuzhiyun #include <linux/iio/triggered_buffer.h>
22*4882a593Smuzhiyun #include <linux/iio/trigger_consumer.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define ADXRS290_ADI_ID		0xAD
25*4882a593Smuzhiyun #define ADXRS290_MEMS_ID	0x1D
26*4882a593Smuzhiyun #define ADXRS290_DEV_ID		0x92
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define ADXRS290_REG_ADI_ID	0x00
29*4882a593Smuzhiyun #define ADXRS290_REG_MEMS_ID	0x01
30*4882a593Smuzhiyun #define ADXRS290_REG_DEV_ID	0x02
31*4882a593Smuzhiyun #define ADXRS290_REG_REV_ID	0x03
32*4882a593Smuzhiyun #define ADXRS290_REG_SN0	0x04 /* Serial Number Registers, 4 bytes */
33*4882a593Smuzhiyun #define ADXRS290_REG_DATAX0	0x08 /* Roll Rate o/p Data Regs, 2 bytes */
34*4882a593Smuzhiyun #define ADXRS290_REG_DATAY0	0x0A /* Pitch Rate o/p Data Regs, 2 bytes */
35*4882a593Smuzhiyun #define ADXRS290_REG_TEMP0	0x0C
36*4882a593Smuzhiyun #define ADXRS290_REG_POWER_CTL	0x10
37*4882a593Smuzhiyun #define ADXRS290_REG_FILTER	0x11
38*4882a593Smuzhiyun #define ADXRS290_REG_DATA_RDY	0x12
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define ADXRS290_READ		BIT(7)
41*4882a593Smuzhiyun #define ADXRS290_TSM		BIT(0)
42*4882a593Smuzhiyun #define ADXRS290_MEASUREMENT	BIT(1)
43*4882a593Smuzhiyun #define ADXRS290_DATA_RDY_OUT	BIT(0)
44*4882a593Smuzhiyun #define ADXRS290_SYNC_MASK	GENMASK(1, 0)
45*4882a593Smuzhiyun #define ADXRS290_SYNC(x)	FIELD_PREP(ADXRS290_SYNC_MASK, x)
46*4882a593Smuzhiyun #define ADXRS290_LPF_MASK	GENMASK(2, 0)
47*4882a593Smuzhiyun #define ADXRS290_LPF(x)		FIELD_PREP(ADXRS290_LPF_MASK, x)
48*4882a593Smuzhiyun #define ADXRS290_HPF_MASK	GENMASK(7, 4)
49*4882a593Smuzhiyun #define ADXRS290_HPF(x)		FIELD_PREP(ADXRS290_HPF_MASK, x)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define ADXRS290_READ_REG(reg)	(ADXRS290_READ | (reg))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define ADXRS290_MAX_TRANSITION_TIME_MS 100
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun enum adxrs290_mode {
56*4882a593Smuzhiyun 	ADXRS290_MODE_STANDBY,
57*4882a593Smuzhiyun 	ADXRS290_MODE_MEASUREMENT,
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun enum adxrs290_scan_index {
61*4882a593Smuzhiyun 	ADXRS290_IDX_X,
62*4882a593Smuzhiyun 	ADXRS290_IDX_Y,
63*4882a593Smuzhiyun 	ADXRS290_IDX_TEMP,
64*4882a593Smuzhiyun 	ADXRS290_IDX_TS,
65*4882a593Smuzhiyun };
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun struct adxrs290_state {
68*4882a593Smuzhiyun 	struct spi_device	*spi;
69*4882a593Smuzhiyun 	/* Serialize reads and their subsequent processing */
70*4882a593Smuzhiyun 	struct mutex		lock;
71*4882a593Smuzhiyun 	enum adxrs290_mode	mode;
72*4882a593Smuzhiyun 	unsigned int		lpf_3db_freq_idx;
73*4882a593Smuzhiyun 	unsigned int		hpf_3db_freq_idx;
74*4882a593Smuzhiyun 	struct iio_trigger      *dready_trig;
75*4882a593Smuzhiyun 	/* Ensure correct alignment of timestamp when present */
76*4882a593Smuzhiyun 	struct {
77*4882a593Smuzhiyun 		s16 channels[3];
78*4882a593Smuzhiyun 		s64 ts __aligned(8);
79*4882a593Smuzhiyun 	} buffer;
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /*
83*4882a593Smuzhiyun  * Available cut-off frequencies of the low pass filter in Hz.
84*4882a593Smuzhiyun  * The integer part and fractional part are represented separately.
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun static const int adxrs290_lpf_3db_freq_hz_table[][2] = {
87*4882a593Smuzhiyun 	[0] = {480, 0},
88*4882a593Smuzhiyun 	[1] = {320, 0},
89*4882a593Smuzhiyun 	[2] = {160, 0},
90*4882a593Smuzhiyun 	[3] = {80, 0},
91*4882a593Smuzhiyun 	[4] = {56, 600000},
92*4882a593Smuzhiyun 	[5] = {40, 0},
93*4882a593Smuzhiyun 	[6] = {28, 300000},
94*4882a593Smuzhiyun 	[7] = {20, 0},
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /*
98*4882a593Smuzhiyun  * Available cut-off frequencies of the high pass filter in Hz.
99*4882a593Smuzhiyun  * The integer part and fractional part are represented separately.
100*4882a593Smuzhiyun  */
101*4882a593Smuzhiyun static const int adxrs290_hpf_3db_freq_hz_table[][2] = {
102*4882a593Smuzhiyun 	[0] = {0, 0},
103*4882a593Smuzhiyun 	[1] = {0, 11000},
104*4882a593Smuzhiyun 	[2] = {0, 22000},
105*4882a593Smuzhiyun 	[3] = {0, 44000},
106*4882a593Smuzhiyun 	[4] = {0, 87000},
107*4882a593Smuzhiyun 	[5] = {0, 175000},
108*4882a593Smuzhiyun 	[6] = {0, 350000},
109*4882a593Smuzhiyun 	[7] = {0, 700000},
110*4882a593Smuzhiyun 	[8] = {1, 400000},
111*4882a593Smuzhiyun 	[9] = {2, 800000},
112*4882a593Smuzhiyun 	[10] = {11, 300000},
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
adxrs290_get_rate_data(struct iio_dev * indio_dev,const u8 cmd,int * val)115*4882a593Smuzhiyun static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *val)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
118*4882a593Smuzhiyun 	int ret = 0;
119*4882a593Smuzhiyun 	int temp;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	mutex_lock(&st->lock);
122*4882a593Smuzhiyun 	temp = spi_w8r16(st->spi, cmd);
123*4882a593Smuzhiyun 	if (temp < 0) {
124*4882a593Smuzhiyun 		ret = temp;
125*4882a593Smuzhiyun 		goto err_unlock;
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	*val = sign_extend32(temp, 15);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun err_unlock:
131*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
132*4882a593Smuzhiyun 	return ret;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
adxrs290_get_temp_data(struct iio_dev * indio_dev,int * val)135*4882a593Smuzhiyun static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun 	const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_TEMP0);
138*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
139*4882a593Smuzhiyun 	int ret = 0;
140*4882a593Smuzhiyun 	int temp;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	mutex_lock(&st->lock);
143*4882a593Smuzhiyun 	temp = spi_w8r16(st->spi, cmd);
144*4882a593Smuzhiyun 	if (temp < 0) {
145*4882a593Smuzhiyun 		ret = temp;
146*4882a593Smuzhiyun 		goto err_unlock;
147*4882a593Smuzhiyun 	}
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* extract lower 12 bits temperature reading */
150*4882a593Smuzhiyun 	*val = sign_extend32(temp, 11);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun err_unlock:
153*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
154*4882a593Smuzhiyun 	return ret;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
adxrs290_get_3db_freq(struct iio_dev * indio_dev,u8 * val,u8 * val2)157*4882a593Smuzhiyun static int adxrs290_get_3db_freq(struct iio_dev *indio_dev, u8 *val, u8 *val2)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_FILTER);
160*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
161*4882a593Smuzhiyun 	int ret = 0;
162*4882a593Smuzhiyun 	short temp;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	mutex_lock(&st->lock);
165*4882a593Smuzhiyun 	temp = spi_w8r8(st->spi, cmd);
166*4882a593Smuzhiyun 	if (temp < 0) {
167*4882a593Smuzhiyun 		ret = temp;
168*4882a593Smuzhiyun 		goto err_unlock;
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	*val = FIELD_GET(ADXRS290_LPF_MASK, temp);
172*4882a593Smuzhiyun 	*val2 = FIELD_GET(ADXRS290_HPF_MASK, temp);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun err_unlock:
175*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
176*4882a593Smuzhiyun 	return ret;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
adxrs290_spi_write_reg(struct spi_device * spi,const u8 reg,const u8 val)179*4882a593Smuzhiyun static int adxrs290_spi_write_reg(struct spi_device *spi, const u8 reg,
180*4882a593Smuzhiyun 				  const u8 val)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	u8 buf[2];
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	buf[0] = reg;
185*4882a593Smuzhiyun 	buf[1] = val;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	return spi_write_then_read(spi, buf, ARRAY_SIZE(buf), NULL, 0);
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun 
adxrs290_find_match(const int (* freq_tbl)[2],const int n,const int val,const int val2)190*4882a593Smuzhiyun static int adxrs290_find_match(const int (*freq_tbl)[2], const int n,
191*4882a593Smuzhiyun 			       const int val, const int val2)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	int i;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	for (i = 0; i < n; i++) {
196*4882a593Smuzhiyun 		if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2)
197*4882a593Smuzhiyun 			return i;
198*4882a593Smuzhiyun 	}
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return -EINVAL;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
adxrs290_set_filter_freq(struct iio_dev * indio_dev,const unsigned int lpf_idx,const unsigned int hpf_idx)203*4882a593Smuzhiyun static int adxrs290_set_filter_freq(struct iio_dev *indio_dev,
204*4882a593Smuzhiyun 				    const unsigned int lpf_idx,
205*4882a593Smuzhiyun 				    const unsigned int hpf_idx)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
208*4882a593Smuzhiyun 	u8 val;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	val = ADXRS290_HPF(hpf_idx) | ADXRS290_LPF(lpf_idx);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val);
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
adxrs290_set_mode(struct iio_dev * indio_dev,enum adxrs290_mode mode)215*4882a593Smuzhiyun static int adxrs290_set_mode(struct iio_dev *indio_dev, enum adxrs290_mode mode)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
218*4882a593Smuzhiyun 	int val, ret;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (st->mode == mode)
221*4882a593Smuzhiyun 		return 0;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	mutex_lock(&st->lock);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	ret = spi_w8r8(st->spi, ADXRS290_READ_REG(ADXRS290_REG_POWER_CTL));
226*4882a593Smuzhiyun 	if (ret < 0)
227*4882a593Smuzhiyun 		goto out_unlock;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	val = ret;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	switch (mode) {
232*4882a593Smuzhiyun 	case ADXRS290_MODE_STANDBY:
233*4882a593Smuzhiyun 		val &= ~ADXRS290_MEASUREMENT;
234*4882a593Smuzhiyun 		break;
235*4882a593Smuzhiyun 	case ADXRS290_MODE_MEASUREMENT:
236*4882a593Smuzhiyun 		val |= ADXRS290_MEASUREMENT;
237*4882a593Smuzhiyun 		break;
238*4882a593Smuzhiyun 	default:
239*4882a593Smuzhiyun 		ret = -EINVAL;
240*4882a593Smuzhiyun 		goto out_unlock;
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_POWER_CTL, val);
244*4882a593Smuzhiyun 	if (ret < 0) {
245*4882a593Smuzhiyun 		dev_err(&st->spi->dev, "unable to set mode: %d\n", ret);
246*4882a593Smuzhiyun 		goto out_unlock;
247*4882a593Smuzhiyun 	}
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	/* update cached mode */
250*4882a593Smuzhiyun 	st->mode = mode;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun out_unlock:
253*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
254*4882a593Smuzhiyun 	return ret;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
adxrs290_chip_off_action(void * data)257*4882a593Smuzhiyun static void adxrs290_chip_off_action(void *data)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun 	struct iio_dev *indio_dev = data;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	adxrs290_set_mode(indio_dev, ADXRS290_MODE_STANDBY);
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
adxrs290_initial_setup(struct iio_dev * indio_dev)264*4882a593Smuzhiyun static int adxrs290_initial_setup(struct iio_dev *indio_dev)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
267*4882a593Smuzhiyun 	struct spi_device *spi = st->spi;
268*4882a593Smuzhiyun 	int ret;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	ret = adxrs290_spi_write_reg(spi, ADXRS290_REG_POWER_CTL,
271*4882a593Smuzhiyun 				     ADXRS290_MEASUREMENT | ADXRS290_TSM);
272*4882a593Smuzhiyun 	if (ret < 0)
273*4882a593Smuzhiyun 		return ret;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	st->mode = ADXRS290_MODE_MEASUREMENT;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	return devm_add_action_or_reset(&spi->dev, adxrs290_chip_off_action,
278*4882a593Smuzhiyun 					indio_dev);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
adxrs290_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)281*4882a593Smuzhiyun static int adxrs290_read_raw(struct iio_dev *indio_dev,
282*4882a593Smuzhiyun 			     struct iio_chan_spec const *chan,
283*4882a593Smuzhiyun 			     int *val,
284*4882a593Smuzhiyun 			     int *val2,
285*4882a593Smuzhiyun 			     long mask)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
288*4882a593Smuzhiyun 	unsigned int t;
289*4882a593Smuzhiyun 	int ret;
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	switch (mask) {
292*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
293*4882a593Smuzhiyun 		ret = iio_device_claim_direct_mode(indio_dev);
294*4882a593Smuzhiyun 		if (ret)
295*4882a593Smuzhiyun 			return ret;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 		switch (chan->type) {
298*4882a593Smuzhiyun 		case IIO_ANGL_VEL:
299*4882a593Smuzhiyun 			ret = adxrs290_get_rate_data(indio_dev,
300*4882a593Smuzhiyun 						     ADXRS290_READ_REG(chan->address),
301*4882a593Smuzhiyun 						     val);
302*4882a593Smuzhiyun 			if (ret < 0)
303*4882a593Smuzhiyun 				break;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
306*4882a593Smuzhiyun 			break;
307*4882a593Smuzhiyun 		case IIO_TEMP:
308*4882a593Smuzhiyun 			ret = adxrs290_get_temp_data(indio_dev, val);
309*4882a593Smuzhiyun 			if (ret < 0)
310*4882a593Smuzhiyun 				break;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
313*4882a593Smuzhiyun 			break;
314*4882a593Smuzhiyun 		default:
315*4882a593Smuzhiyun 			ret = -EINVAL;
316*4882a593Smuzhiyun 			break;
317*4882a593Smuzhiyun 		}
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 		iio_device_release_direct_mode(indio_dev);
320*4882a593Smuzhiyun 		return ret;
321*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
322*4882a593Smuzhiyun 		switch (chan->type) {
323*4882a593Smuzhiyun 		case IIO_ANGL_VEL:
324*4882a593Smuzhiyun 			/* 1 LSB = 0.005 degrees/sec */
325*4882a593Smuzhiyun 			*val = 0;
326*4882a593Smuzhiyun 			*val2 = 87266;
327*4882a593Smuzhiyun 			return IIO_VAL_INT_PLUS_NANO;
328*4882a593Smuzhiyun 		case IIO_TEMP:
329*4882a593Smuzhiyun 			/* 1 LSB = 0.1 degrees Celsius */
330*4882a593Smuzhiyun 			*val = 100;
331*4882a593Smuzhiyun 			return IIO_VAL_INT;
332*4882a593Smuzhiyun 		default:
333*4882a593Smuzhiyun 			return -EINVAL;
334*4882a593Smuzhiyun 		}
335*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
336*4882a593Smuzhiyun 		switch (chan->type) {
337*4882a593Smuzhiyun 		case IIO_ANGL_VEL:
338*4882a593Smuzhiyun 			t = st->lpf_3db_freq_idx;
339*4882a593Smuzhiyun 			*val = adxrs290_lpf_3db_freq_hz_table[t][0];
340*4882a593Smuzhiyun 			*val2 = adxrs290_lpf_3db_freq_hz_table[t][1];
341*4882a593Smuzhiyun 			return IIO_VAL_INT_PLUS_MICRO;
342*4882a593Smuzhiyun 		default:
343*4882a593Smuzhiyun 			return -EINVAL;
344*4882a593Smuzhiyun 		}
345*4882a593Smuzhiyun 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
346*4882a593Smuzhiyun 		switch (chan->type) {
347*4882a593Smuzhiyun 		case IIO_ANGL_VEL:
348*4882a593Smuzhiyun 			t = st->hpf_3db_freq_idx;
349*4882a593Smuzhiyun 			*val = adxrs290_hpf_3db_freq_hz_table[t][0];
350*4882a593Smuzhiyun 			*val2 = adxrs290_hpf_3db_freq_hz_table[t][1];
351*4882a593Smuzhiyun 			return IIO_VAL_INT_PLUS_MICRO;
352*4882a593Smuzhiyun 		default:
353*4882a593Smuzhiyun 			return -EINVAL;
354*4882a593Smuzhiyun 		}
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	return -EINVAL;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun 
adxrs290_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)360*4882a593Smuzhiyun static int adxrs290_write_raw(struct iio_dev *indio_dev,
361*4882a593Smuzhiyun 			      struct iio_chan_spec const *chan,
362*4882a593Smuzhiyun 			      int val,
363*4882a593Smuzhiyun 			      int val2,
364*4882a593Smuzhiyun 			      long mask)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
367*4882a593Smuzhiyun 	int ret, lpf_idx, hpf_idx;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	ret = iio_device_claim_direct_mode(indio_dev);
370*4882a593Smuzhiyun 	if (ret)
371*4882a593Smuzhiyun 		return ret;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	switch (mask) {
374*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
375*4882a593Smuzhiyun 		lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table,
376*4882a593Smuzhiyun 					      ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table),
377*4882a593Smuzhiyun 					      val, val2);
378*4882a593Smuzhiyun 		if (lpf_idx < 0) {
379*4882a593Smuzhiyun 			ret = -EINVAL;
380*4882a593Smuzhiyun 			break;
381*4882a593Smuzhiyun 		}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 		/* caching the updated state of the low-pass filter */
384*4882a593Smuzhiyun 		st->lpf_3db_freq_idx = lpf_idx;
385*4882a593Smuzhiyun 		/* retrieving the current state of the high-pass filter */
386*4882a593Smuzhiyun 		hpf_idx = st->hpf_3db_freq_idx;
387*4882a593Smuzhiyun 		ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
388*4882a593Smuzhiyun 		break;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
391*4882a593Smuzhiyun 		hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table,
392*4882a593Smuzhiyun 					      ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table),
393*4882a593Smuzhiyun 					      val, val2);
394*4882a593Smuzhiyun 		if (hpf_idx < 0) {
395*4882a593Smuzhiyun 			ret = -EINVAL;
396*4882a593Smuzhiyun 			break;
397*4882a593Smuzhiyun 		}
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 		/* caching the updated state of the high-pass filter */
400*4882a593Smuzhiyun 		st->hpf_3db_freq_idx = hpf_idx;
401*4882a593Smuzhiyun 		/* retrieving the current state of the low-pass filter */
402*4882a593Smuzhiyun 		lpf_idx = st->lpf_3db_freq_idx;
403*4882a593Smuzhiyun 		ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
404*4882a593Smuzhiyun 		break;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	default:
407*4882a593Smuzhiyun 		ret = -EINVAL;
408*4882a593Smuzhiyun 		break;
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	iio_device_release_direct_mode(indio_dev);
412*4882a593Smuzhiyun 	return ret;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
adxrs290_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)415*4882a593Smuzhiyun static int adxrs290_read_avail(struct iio_dev *indio_dev,
416*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
417*4882a593Smuzhiyun 			       const int **vals, int *type, int *length,
418*4882a593Smuzhiyun 			       long mask)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun 	switch (mask) {
421*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
422*4882a593Smuzhiyun 		*vals = (const int *)adxrs290_lpf_3db_freq_hz_table;
423*4882a593Smuzhiyun 		*type = IIO_VAL_INT_PLUS_MICRO;
424*4882a593Smuzhiyun 		/* Values are stored in a 2D matrix */
425*4882a593Smuzhiyun 		*length = ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table) * 2;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 		return IIO_AVAIL_LIST;
428*4882a593Smuzhiyun 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
429*4882a593Smuzhiyun 		*vals = (const int *)adxrs290_hpf_3db_freq_hz_table;
430*4882a593Smuzhiyun 		*type = IIO_VAL_INT_PLUS_MICRO;
431*4882a593Smuzhiyun 		/* Values are stored in a 2D matrix */
432*4882a593Smuzhiyun 		*length = ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table) * 2;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 		return IIO_AVAIL_LIST;
435*4882a593Smuzhiyun 	default:
436*4882a593Smuzhiyun 		return -EINVAL;
437*4882a593Smuzhiyun 	}
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun 
adxrs290_reg_access_rw(struct spi_device * spi,unsigned int reg,unsigned int * readval)440*4882a593Smuzhiyun static int adxrs290_reg_access_rw(struct spi_device *spi, unsigned int reg,
441*4882a593Smuzhiyun 				  unsigned int *readval)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	int ret;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	ret = spi_w8r8(spi, ADXRS290_READ_REG(reg));
446*4882a593Smuzhiyun 	if (ret < 0)
447*4882a593Smuzhiyun 		return ret;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	*readval = ret;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return 0;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
adxrs290_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)454*4882a593Smuzhiyun static int adxrs290_reg_access(struct iio_dev *indio_dev, unsigned int reg,
455*4882a593Smuzhiyun 			       unsigned int writeval, unsigned int *readval)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	if (readval)
460*4882a593Smuzhiyun 		return adxrs290_reg_access_rw(st->spi, reg, readval);
461*4882a593Smuzhiyun 	else
462*4882a593Smuzhiyun 		return adxrs290_spi_write_reg(st->spi, reg, writeval);
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun 
adxrs290_data_rdy_trigger_set_state(struct iio_trigger * trig,bool state)465*4882a593Smuzhiyun static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig,
466*4882a593Smuzhiyun 					       bool state)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
469*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
470*4882a593Smuzhiyun 	int ret;
471*4882a593Smuzhiyun 	u8 val;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	val = state ? ADXRS290_SYNC(ADXRS290_DATA_RDY_OUT) : 0;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_DATA_RDY, val);
476*4882a593Smuzhiyun 	if (ret < 0)
477*4882a593Smuzhiyun 		dev_err(&st->spi->dev, "failed to start data rdy interrupt\n");
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	return ret;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun 
adxrs290_reset_trig(struct iio_trigger * trig)482*4882a593Smuzhiyun static int adxrs290_reset_trig(struct iio_trigger *trig)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
485*4882a593Smuzhiyun 	int val;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	/*
488*4882a593Smuzhiyun 	 * Data ready interrupt is reset after a read of the data registers.
489*4882a593Smuzhiyun 	 * Here, we only read the 16b DATAY registers as that marks the end of
490*4882a593Smuzhiyun 	 * a read of the data registers and initiates a reset for the interrupt
491*4882a593Smuzhiyun 	 * line.
492*4882a593Smuzhiyun 	 */
493*4882a593Smuzhiyun 	adxrs290_get_rate_data(indio_dev,
494*4882a593Smuzhiyun 			       ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	return 0;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun static const struct iio_trigger_ops adxrs290_trigger_ops = {
500*4882a593Smuzhiyun 	.set_trigger_state = &adxrs290_data_rdy_trigger_set_state,
501*4882a593Smuzhiyun 	.validate_device = &iio_trigger_validate_own_device,
502*4882a593Smuzhiyun 	.try_reenable = &adxrs290_reset_trig,
503*4882a593Smuzhiyun };
504*4882a593Smuzhiyun 
adxrs290_trigger_handler(int irq,void * p)505*4882a593Smuzhiyun static irqreturn_t adxrs290_trigger_handler(int irq, void *p)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun 	struct iio_poll_func *pf = p;
508*4882a593Smuzhiyun 	struct iio_dev *indio_dev = pf->indio_dev;
509*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
510*4882a593Smuzhiyun 	u8 tx = ADXRS290_READ_REG(ADXRS290_REG_DATAX0);
511*4882a593Smuzhiyun 	int ret;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	mutex_lock(&st->lock);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	/* exercise a bulk data capture starting from reg DATAX0... */
516*4882a593Smuzhiyun 	ret = spi_write_then_read(st->spi, &tx, sizeof(tx), st->buffer.channels,
517*4882a593Smuzhiyun 				  sizeof(st->buffer.channels));
518*4882a593Smuzhiyun 	if (ret < 0)
519*4882a593Smuzhiyun 		goto out_unlock_notify;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
522*4882a593Smuzhiyun 					   pf->timestamp);
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun out_unlock_notify:
525*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
526*4882a593Smuzhiyun 	iio_trigger_notify_done(indio_dev->trig);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	return IRQ_HANDLED;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun #define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) {				\
532*4882a593Smuzhiyun 	.type = IIO_ANGL_VEL,						\
533*4882a593Smuzhiyun 	.address = reg,							\
534*4882a593Smuzhiyun 	.modified = 1,							\
535*4882a593Smuzhiyun 	.channel2 = IIO_MOD_##axis,					\
536*4882a593Smuzhiyun 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
537*4882a593Smuzhiyun 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
538*4882a593Smuzhiyun 	BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |		\
539*4882a593Smuzhiyun 	BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),		\
540*4882a593Smuzhiyun 	.info_mask_shared_by_type_available =				\
541*4882a593Smuzhiyun 	BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |		\
542*4882a593Smuzhiyun 	BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),		\
543*4882a593Smuzhiyun 	.scan_index = ADXRS290_IDX_##axis,				\
544*4882a593Smuzhiyun 	.scan_type = {                                                  \
545*4882a593Smuzhiyun 		.sign = 's',                                            \
546*4882a593Smuzhiyun 		.realbits = 16,                                         \
547*4882a593Smuzhiyun 		.storagebits = 16,                                      \
548*4882a593Smuzhiyun 		.endianness = IIO_LE,					\
549*4882a593Smuzhiyun 	},                                                              \
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun static const struct iio_chan_spec adxrs290_channels[] = {
553*4882a593Smuzhiyun 	ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAX0, X),
554*4882a593Smuzhiyun 	ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAY0, Y),
555*4882a593Smuzhiyun 	{
556*4882a593Smuzhiyun 		.type = IIO_TEMP,
557*4882a593Smuzhiyun 		.address = ADXRS290_REG_TEMP0,
558*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
559*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE),
560*4882a593Smuzhiyun 		.scan_index = ADXRS290_IDX_TEMP,
561*4882a593Smuzhiyun 		.scan_type = {
562*4882a593Smuzhiyun 			.sign = 's',
563*4882a593Smuzhiyun 			.realbits = 12,
564*4882a593Smuzhiyun 			.storagebits = 16,
565*4882a593Smuzhiyun 			.endianness = IIO_LE,
566*4882a593Smuzhiyun 		},
567*4882a593Smuzhiyun 	},
568*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(ADXRS290_IDX_TS),
569*4882a593Smuzhiyun };
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun static const unsigned long adxrs290_avail_scan_masks[] = {
572*4882a593Smuzhiyun 	BIT(ADXRS290_IDX_X) | BIT(ADXRS290_IDX_Y) | BIT(ADXRS290_IDX_TEMP),
573*4882a593Smuzhiyun 	0
574*4882a593Smuzhiyun };
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun static const struct iio_info adxrs290_info = {
577*4882a593Smuzhiyun 	.read_raw = &adxrs290_read_raw,
578*4882a593Smuzhiyun 	.write_raw = &adxrs290_write_raw,
579*4882a593Smuzhiyun 	.read_avail = &adxrs290_read_avail,
580*4882a593Smuzhiyun 	.debugfs_reg_access = &adxrs290_reg_access,
581*4882a593Smuzhiyun };
582*4882a593Smuzhiyun 
adxrs290_probe_trigger(struct iio_dev * indio_dev)583*4882a593Smuzhiyun static int adxrs290_probe_trigger(struct iio_dev *indio_dev)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	struct adxrs290_state *st = iio_priv(indio_dev);
586*4882a593Smuzhiyun 	int ret;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	if (!st->spi->irq) {
589*4882a593Smuzhiyun 		dev_info(&st->spi->dev, "no irq, using polling\n");
590*4882a593Smuzhiyun 		return 0;
591*4882a593Smuzhiyun 	}
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d",
594*4882a593Smuzhiyun 						 indio_dev->name,
595*4882a593Smuzhiyun 						 indio_dev->id);
596*4882a593Smuzhiyun 	if (!st->dready_trig)
597*4882a593Smuzhiyun 		return -ENOMEM;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	st->dready_trig->dev.parent = &st->spi->dev;
600*4882a593Smuzhiyun 	st->dready_trig->ops = &adxrs290_trigger_ops;
601*4882a593Smuzhiyun 	iio_trigger_set_drvdata(st->dready_trig, indio_dev);
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	ret = devm_request_irq(&st->spi->dev, st->spi->irq,
604*4882a593Smuzhiyun 			       &iio_trigger_generic_data_rdy_poll,
605*4882a593Smuzhiyun 			       IRQF_ONESHOT, "adxrs290_irq", st->dready_trig);
606*4882a593Smuzhiyun 	if (ret < 0)
607*4882a593Smuzhiyun 		return dev_err_probe(&st->spi->dev, ret,
608*4882a593Smuzhiyun 				     "request irq %d failed\n", st->spi->irq);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	ret = devm_iio_trigger_register(&st->spi->dev, st->dready_trig);
611*4882a593Smuzhiyun 	if (ret) {
612*4882a593Smuzhiyun 		dev_err(&st->spi->dev, "iio trigger register failed\n");
613*4882a593Smuzhiyun 		return ret;
614*4882a593Smuzhiyun 	}
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	indio_dev->trig = iio_trigger_get(st->dready_trig);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	return 0;
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun 
adxrs290_probe(struct spi_device * spi)621*4882a593Smuzhiyun static int adxrs290_probe(struct spi_device *spi)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
624*4882a593Smuzhiyun 	struct adxrs290_state *st;
625*4882a593Smuzhiyun 	u8 val, val2;
626*4882a593Smuzhiyun 	int ret;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
629*4882a593Smuzhiyun 	if (!indio_dev)
630*4882a593Smuzhiyun 		return -ENOMEM;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	st = iio_priv(indio_dev);
633*4882a593Smuzhiyun 	st->spi = spi;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	indio_dev->name = "adxrs290";
636*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
637*4882a593Smuzhiyun 	indio_dev->channels = adxrs290_channels;
638*4882a593Smuzhiyun 	indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels);
639*4882a593Smuzhiyun 	indio_dev->info = &adxrs290_info;
640*4882a593Smuzhiyun 	indio_dev->available_scan_masks = adxrs290_avail_scan_masks;
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	mutex_init(&st->lock);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_ADI_ID));
645*4882a593Smuzhiyun 	if (val != ADXRS290_ADI_ID) {
646*4882a593Smuzhiyun 		dev_err(&spi->dev, "Wrong ADI ID 0x%02x\n", val);
647*4882a593Smuzhiyun 		return -ENODEV;
648*4882a593Smuzhiyun 	}
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_MEMS_ID));
651*4882a593Smuzhiyun 	if (val != ADXRS290_MEMS_ID) {
652*4882a593Smuzhiyun 		dev_err(&spi->dev, "Wrong MEMS ID 0x%02x\n", val);
653*4882a593Smuzhiyun 		return -ENODEV;
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_DEV_ID));
657*4882a593Smuzhiyun 	if (val != ADXRS290_DEV_ID) {
658*4882a593Smuzhiyun 		dev_err(&spi->dev, "Wrong DEV ID 0x%02x\n", val);
659*4882a593Smuzhiyun 		return -ENODEV;
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	/* default mode the gyroscope starts in */
663*4882a593Smuzhiyun 	st->mode = ADXRS290_MODE_STANDBY;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	/* switch to measurement mode and switch on the temperature sensor */
666*4882a593Smuzhiyun 	ret = adxrs290_initial_setup(indio_dev);
667*4882a593Smuzhiyun 	if (ret < 0)
668*4882a593Smuzhiyun 		return ret;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	/* max transition time to measurement mode */
671*4882a593Smuzhiyun 	msleep(ADXRS290_MAX_TRANSITION_TIME_MS);
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	ret = adxrs290_get_3db_freq(indio_dev, &val, &val2);
674*4882a593Smuzhiyun 	if (ret < 0)
675*4882a593Smuzhiyun 		return ret;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	st->lpf_3db_freq_idx = val;
678*4882a593Smuzhiyun 	st->hpf_3db_freq_idx = val2;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
681*4882a593Smuzhiyun 					      &iio_pollfunc_store_time,
682*4882a593Smuzhiyun 					      &adxrs290_trigger_handler, NULL);
683*4882a593Smuzhiyun 	if (ret < 0)
684*4882a593Smuzhiyun 		return dev_err_probe(&spi->dev, ret,
685*4882a593Smuzhiyun 				     "iio triggered buffer setup failed\n");
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	ret = adxrs290_probe_trigger(indio_dev);
688*4882a593Smuzhiyun 	if (ret < 0)
689*4882a593Smuzhiyun 		return ret;
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	return devm_iio_device_register(&spi->dev, indio_dev);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun static const struct of_device_id adxrs290_of_match[] = {
695*4882a593Smuzhiyun 	{ .compatible = "adi,adxrs290" },
696*4882a593Smuzhiyun 	{ }
697*4882a593Smuzhiyun };
698*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, adxrs290_of_match);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun static struct spi_driver adxrs290_driver = {
701*4882a593Smuzhiyun 	.driver = {
702*4882a593Smuzhiyun 		.name = "adxrs290",
703*4882a593Smuzhiyun 		.of_match_table = adxrs290_of_match,
704*4882a593Smuzhiyun 	},
705*4882a593Smuzhiyun 	.probe = adxrs290_probe,
706*4882a593Smuzhiyun };
707*4882a593Smuzhiyun module_spi_driver(adxrs290_driver);
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun MODULE_AUTHOR("Nishant Malpani <nish.malpani25@gmail.com>");
710*4882a593Smuzhiyun MODULE_DESCRIPTION("Analog Devices ADXRS290 Gyroscope SPI driver");
711*4882a593Smuzhiyun MODULE_LICENSE("GPL");
712