Merge tag 'reset-for-v5.3' of git://git.pengutronix.de/git/pza/linux into arm/drivers
[sfrench/cifs-2.6.git] / drivers / iio / accel / adis16209.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer
4  *
5  * Copyright 2010 Analog Devices Inc.
6  */
7
8 #include <linux/device.h>
9 #include <linux/kernel.h>
10 #include <linux/list.h>
11 #include <linux/module.h>
12 #include <linux/spi/spi.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15
16 #include <linux/iio/iio.h>
17 #include <linux/iio/imu/adis.h>
18
19 #define ADIS16209_STARTUP_DELAY_MS      220
20 #define ADIS16209_FLASH_CNT_REG         0x00
21
22 /* Data Output Register Definitions */
23 #define ADIS16209_SUPPLY_OUT_REG        0x02
24 #define ADIS16209_XACCL_OUT_REG         0x04
25 #define ADIS16209_YACCL_OUT_REG         0x06
26 /* Output, auxiliary ADC input */
27 #define ADIS16209_AUX_ADC_REG           0x08
28 /* Output, temperature */
29 #define ADIS16209_TEMP_OUT_REG          0x0A
30 /* Output, +/- 90 degrees X-axis inclination */
31 #define ADIS16209_XINCL_OUT_REG         0x0C
32 #define ADIS16209_YINCL_OUT_REG         0x0E
33 /* Output, +/-180 vertical rotational position */
34 #define ADIS16209_ROT_OUT_REG           0x10
35
36 /*
37  * Calibration Register Definitions.
38  * Acceleration, inclination or rotation offset null.
39  */
40 #define ADIS16209_XACCL_NULL_REG        0x12
41 #define ADIS16209_YACCL_NULL_REG        0x14
42 #define ADIS16209_XINCL_NULL_REG        0x16
43 #define ADIS16209_YINCL_NULL_REG        0x18
44 #define ADIS16209_ROT_NULL_REG          0x1A
45
46 /* Alarm Register Definitions */
47 #define ADIS16209_ALM_MAG1_REG          0x20
48 #define ADIS16209_ALM_MAG2_REG          0x22
49 #define ADIS16209_ALM_SMPL1_REG         0x24
50 #define ADIS16209_ALM_SMPL2_REG         0x26
51 #define ADIS16209_ALM_CTRL_REG          0x28
52
53 #define ADIS16209_AUX_DAC_REG           0x30
54 #define ADIS16209_GPIO_CTRL_REG         0x32
55 #define ADIS16209_SMPL_PRD_REG          0x36
56 #define ADIS16209_AVG_CNT_REG           0x38
57 #define ADIS16209_SLP_CNT_REG           0x3A
58
59 #define ADIS16209_MSC_CTRL_REG                  0x34
60 #define  ADIS16209_MSC_CTRL_PWRUP_SELF_TEST     BIT(10)
61 #define  ADIS16209_MSC_CTRL_SELF_TEST_EN        BIT(8)
62 #define  ADIS16209_MSC_CTRL_DATA_RDY_EN         BIT(2)
63 /* Data-ready polarity: 1 = active high, 0 = active low */
64 #define  ADIS16209_MSC_CTRL_ACTIVE_HIGH         BIT(1)
65 #define  ADIS16209_MSC_CTRL_DATA_RDY_DIO2       BIT(0)
66
67 #define ADIS16209_STAT_REG                      0x3C
68 #define  ADIS16209_STAT_ALARM2                  BIT(9)
69 #define  ADIS16209_STAT_ALARM1                  BIT(8)
70 #define  ADIS16209_STAT_SELFTEST_FAIL_BIT       5
71 #define  ADIS16209_STAT_SPI_FAIL_BIT            3
72 #define  ADIS16209_STAT_FLASH_UPT_FAIL_BIT      2
73 /* Power supply above 3.625 V */
74 #define  ADIS16209_STAT_POWER_HIGH_BIT          1
75 /* Power supply below 3.15 V */
76 #define  ADIS16209_STAT_POWER_LOW_BIT           0
77
78 #define ADIS16209_CMD_REG                       0x3E
79 #define  ADIS16209_CMD_SW_RESET                 BIT(7)
80 #define  ADIS16209_CMD_CLEAR_STAT               BIT(4)
81 #define  ADIS16209_CMD_FACTORY_CAL              BIT(1)
82
83 #define ADIS16209_ERROR_ACTIVE                  BIT(14)
84
85 enum adis16209_scan {
86         ADIS16209_SCAN_SUPPLY,
87         ADIS16209_SCAN_ACC_X,
88         ADIS16209_SCAN_ACC_Y,
89         ADIS16209_SCAN_AUX_ADC,
90         ADIS16209_SCAN_TEMP,
91         ADIS16209_SCAN_INCLI_X,
92         ADIS16209_SCAN_INCLI_Y,
93         ADIS16209_SCAN_ROT,
94 };
95
96 static const u8 adis16209_addresses[8][1] = {
97         [ADIS16209_SCAN_SUPPLY] = { },
98         [ADIS16209_SCAN_AUX_ADC] = { },
99         [ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL_REG },
100         [ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL_REG },
101         [ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL_REG },
102         [ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL_REG },
103         [ADIS16209_SCAN_ROT] = { },
104         [ADIS16209_SCAN_TEMP] = { },
105 };
106
107 static int adis16209_write_raw(struct iio_dev *indio_dev,
108                                struct iio_chan_spec const *chan,
109                                int val,
110                                int val2,
111                                long mask)
112 {
113         struct adis *st = iio_priv(indio_dev);
114         int m;
115
116         if (mask != IIO_CHAN_INFO_CALIBBIAS)
117                 return -EINVAL;
118
119         switch (chan->type) {
120         case IIO_ACCEL:
121         case IIO_INCLI:
122                 m = GENMASK(13, 0);
123                 break;
124         default:
125                 return -EINVAL;
126         }
127
128         return adis_write_reg_16(st, adis16209_addresses[chan->scan_index][0],
129                                  val & m);
130 }
131
132 static int adis16209_read_raw(struct iio_dev *indio_dev,
133                               struct iio_chan_spec const *chan,
134                               int *val, int *val2,
135                               long mask)
136 {
137         struct adis *st = iio_priv(indio_dev);
138         int ret;
139         int bits;
140         u8 addr;
141         s16 val16;
142
143         switch (mask) {
144         case IIO_CHAN_INFO_RAW:
145                 return adis_single_conversion(indio_dev, chan,
146                         ADIS16209_ERROR_ACTIVE, val);
147         case IIO_CHAN_INFO_SCALE:
148                 switch (chan->type) {
149                 case IIO_VOLTAGE:
150                         *val = 0;
151                         switch (chan->channel) {
152                         case 0:
153                                 *val2 = 305180; /* 0.30518 mV */
154                                 break;
155                         case 1:
156                                 *val2 = 610500; /* 0.6105 mV */
157                                 break;
158                         default:
159                                 return -EINVAL;
160                         }
161                         return IIO_VAL_INT_PLUS_MICRO;
162                 case IIO_TEMP:
163                         *val = -470;
164                         *val2 = 0;
165                         return IIO_VAL_INT_PLUS_MICRO;
166                 case IIO_ACCEL:
167                         /*
168                          * IIO base unit for sensitivity of accelerometer
169                          * is milli g.
170                          * 1 LSB represents 0.244 mg.
171                          */
172                         *val = 0;
173                         *val2 = IIO_G_TO_M_S_2(244140);
174                         return IIO_VAL_INT_PLUS_NANO;
175                 case IIO_INCLI:
176                 case IIO_ROT:
177                         /*
178                          * IIO base units for rotation are degrees.
179                          * 1 LSB represents 0.025 milli degrees.
180                          */
181                         *val = 0;
182                         *val2 = 25000;
183                         return IIO_VAL_INT_PLUS_MICRO;
184                 default:
185                         return -EINVAL;
186                 }
187                 break;
188         case IIO_CHAN_INFO_OFFSET:
189                 /*
190                  * The raw ADC value is 0x4FE when the temperature
191                  * is 45 degrees and the scale factor per milli
192                  * degree celcius is -470.
193                  */
194                 *val = 25000 / -470 - 0x4FE;
195                 return IIO_VAL_INT;
196         case IIO_CHAN_INFO_CALIBBIAS:
197                 switch (chan->type) {
198                 case IIO_ACCEL:
199                         bits = 14;
200                         break;
201                 default:
202                         return -EINVAL;
203                 }
204                 addr = adis16209_addresses[chan->scan_index][0];
205                 ret = adis_read_reg_16(st, addr, &val16);
206                 if (ret)
207                         return ret;
208
209                 *val = sign_extend32(val16, bits - 1);
210                 return IIO_VAL_INT;
211         }
212         return -EINVAL;
213 }
214
215 static const struct iio_chan_spec adis16209_channels[] = {
216         ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT_REG, ADIS16209_SCAN_SUPPLY,
217                          0, 14),
218         ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT_REG, ADIS16209_SCAN_TEMP, 0, 12),
219         ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT_REG, ADIS16209_SCAN_ACC_X,
220                         BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
221         ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT_REG, ADIS16209_SCAN_ACC_Y,
222                         BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
223         ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC_REG, ADIS16209_SCAN_AUX_ADC, 0, 12),
224         ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT_REG, ADIS16209_SCAN_INCLI_X,
225                         0, 0, 14),
226         ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT_REG, ADIS16209_SCAN_INCLI_Y,
227                         0, 0, 14),
228         ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT_REG, ADIS16209_SCAN_ROT, 0, 0, 14),
229         IIO_CHAN_SOFT_TIMESTAMP(8)
230 };
231
232 static const struct iio_info adis16209_info = {
233         .read_raw = adis16209_read_raw,
234         .write_raw = adis16209_write_raw,
235         .update_scan_mode = adis_update_scan_mode,
236 };
237
238 static const char * const adis16209_status_error_msgs[] = {
239         [ADIS16209_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
240         [ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure",
241         [ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed",
242         [ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
243         [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
244 };
245
246 static const struct adis_data adis16209_data = {
247         .read_delay = 30,
248         .msc_ctrl_reg = ADIS16209_MSC_CTRL_REG,
249         .glob_cmd_reg = ADIS16209_CMD_REG,
250         .diag_stat_reg = ADIS16209_STAT_REG,
251
252         .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN,
253         .self_test_no_autoclear = true,
254         .startup_delay = ADIS16209_STARTUP_DELAY_MS,
255
256         .status_error_msgs = adis16209_status_error_msgs,
257         .status_error_mask = BIT(ADIS16209_STAT_SELFTEST_FAIL_BIT) |
258                 BIT(ADIS16209_STAT_SPI_FAIL_BIT) |
259                 BIT(ADIS16209_STAT_FLASH_UPT_FAIL_BIT) |
260                 BIT(ADIS16209_STAT_POWER_HIGH_BIT) |
261                 BIT(ADIS16209_STAT_POWER_LOW_BIT),
262 };
263
264 static int adis16209_probe(struct spi_device *spi)
265 {
266         struct iio_dev *indio_dev;
267         struct adis *st;
268         int ret;
269
270         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
271         if (!indio_dev)
272                 return -ENOMEM;
273
274         st = iio_priv(indio_dev);
275         spi_set_drvdata(spi, indio_dev);
276
277         indio_dev->name = spi->dev.driver->name;
278         indio_dev->dev.parent = &spi->dev;
279         indio_dev->info = &adis16209_info;
280         indio_dev->channels = adis16209_channels;
281         indio_dev->num_channels = ARRAY_SIZE(adis16209_channels);
282         indio_dev->modes = INDIO_DIRECT_MODE;
283
284         ret = adis_init(st, indio_dev, spi, &adis16209_data);
285         if (ret)
286                 return ret;
287
288         ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
289         if (ret)
290                 return ret;
291
292         ret = adis_initial_startup(st);
293         if (ret)
294                 goto error_cleanup_buffer_trigger;
295         ret = iio_device_register(indio_dev);
296         if (ret)
297                 goto error_cleanup_buffer_trigger;
298
299         return 0;
300
301 error_cleanup_buffer_trigger:
302         adis_cleanup_buffer_and_trigger(st, indio_dev);
303         return ret;
304 }
305
306 static int adis16209_remove(struct spi_device *spi)
307 {
308         struct iio_dev *indio_dev = spi_get_drvdata(spi);
309         struct adis *st = iio_priv(indio_dev);
310
311         iio_device_unregister(indio_dev);
312         adis_cleanup_buffer_and_trigger(st, indio_dev);
313
314         return 0;
315 }
316
317 static struct spi_driver adis16209_driver = {
318         .driver = {
319                 .name = "adis16209",
320         },
321         .probe = adis16209_probe,
322         .remove = adis16209_remove,
323 };
324 module_spi_driver(adis16209_driver);
325
326 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
327 MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer");
328 MODULE_LICENSE("GPL v2");
329 MODULE_ALIAS("spi:adis16209");