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