Merge tag 'opp-updates-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
[linux-2.6-microblaze.git] / drivers / iio / accel / adxl313_core.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ADXL313 3-Axis Digital Accelerometer
4  *
5  * Copyright (c) 2021 Lucas Stankus <lucas.p.stankus@gmail.com>
6  *
7  * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL313.pdf
8  */
9
10 #include <linux/bitfield.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13
14 #include "adxl313.h"
15
16 static const struct regmap_range adxl312_readable_reg_range[] = {
17         regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_DEVID0),
18         regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
19         regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
20         regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS),
21 };
22
23 static const struct regmap_range adxl313_readable_reg_range[] = {
24         regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_XID),
25         regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET),
26         regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
27         regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
28         regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS),
29 };
30
31 const struct regmap_access_table adxl312_readable_regs_table = {
32         .yes_ranges = adxl312_readable_reg_range,
33         .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range),
34 };
35 EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, IIO_ADXL313);
36
37 const struct regmap_access_table adxl313_readable_regs_table = {
38         .yes_ranges = adxl313_readable_reg_range,
39         .n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range),
40 };
41 EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313);
42
43 const struct regmap_access_table adxl314_readable_regs_table = {
44         .yes_ranges = adxl312_readable_reg_range,
45         .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range),
46 };
47 EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, IIO_ADXL313);
48
49 static int adxl312_check_id(struct device *dev,
50                             struct adxl313_data *data)
51 {
52         unsigned int regval;
53         int ret;
54
55         ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, &regval);
56         if (ret)
57                 return ret;
58
59         if (regval != ADXL313_DEVID0_ADXL312_314)
60                 dev_warn(dev, "Invalid manufacturer ID: %#02x\n", regval);
61
62         return 0;
63 }
64
65 static int adxl313_check_id(struct device *dev,
66                             struct adxl313_data *data)
67 {
68         unsigned int regval;
69         int ret;
70
71         ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, &regval);
72         if (ret)
73                 return ret;
74
75         if (regval != ADXL313_DEVID0)
76                 dev_warn(dev, "Invalid manufacturer ID: 0x%02x\n", regval);
77
78         /* Check DEVID1 and PARTID */
79         if (regval == ADXL313_DEVID0) {
80                 ret = regmap_read(data->regmap, ADXL313_REG_DEVID1, &regval);
81                 if (ret)
82                         return ret;
83
84                 if (regval != ADXL313_DEVID1)
85                         dev_warn(dev, "Invalid mems ID: 0x%02x\n", regval);
86
87                 ret = regmap_read(data->regmap, ADXL313_REG_PARTID, &regval);
88                 if (ret)
89                         return ret;
90
91                 if (regval != ADXL313_PARTID)
92                         dev_warn(dev, "Invalid device ID: 0x%02x\n", regval);
93         }
94
95         return 0;
96 }
97
98 const struct adxl313_chip_info adxl31x_chip_info[] = {
99         [ADXL312] = {
100                 .name = "adxl312",
101                 .type = ADXL312,
102                 .scale_factor = 28425072,
103                 .variable_range = true,
104                 .soft_reset = false,
105                 .check_id = &adxl312_check_id,
106         },
107         [ADXL313] = {
108                 .name = "adxl313",
109                 .type = ADXL313,
110                 .scale_factor = 9576806,
111                 .variable_range = true,
112                 .soft_reset = true,
113                 .check_id = &adxl313_check_id,
114         },
115         [ADXL314] = {
116                 .name = "adxl314",
117                 .type = ADXL314,
118                 .scale_factor = 478858719,
119                 .variable_range = false,
120                 .soft_reset = false,
121                 .check_id = &adxl312_check_id,
122         },
123 };
124 EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, IIO_ADXL313);
125
126 static const struct regmap_range adxl312_writable_reg_range[] = {
127         regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
128         regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
129         regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP),
130         regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT),
131         regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL),
132 };
133
134 static const struct regmap_range adxl313_writable_reg_range[] = {
135         regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET),
136         regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
137         regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
138         regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP),
139         regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT),
140         regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL),
141 };
142
143 const struct regmap_access_table adxl312_writable_regs_table = {
144         .yes_ranges = adxl312_writable_reg_range,
145         .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range),
146 };
147 EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, IIO_ADXL313);
148
149 const struct regmap_access_table adxl313_writable_regs_table = {
150         .yes_ranges = adxl313_writable_reg_range,
151         .n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range),
152 };
153 EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313);
154
155 const struct regmap_access_table adxl314_writable_regs_table = {
156         .yes_ranges = adxl312_writable_reg_range,
157         .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range),
158 };
159 EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, IIO_ADXL313);
160
161 static const int adxl313_odr_freqs[][2] = {
162         [0] = { 6, 250000 },
163         [1] = { 12, 500000 },
164         [2] = { 25, 0 },
165         [3] = { 50, 0 },
166         [4] = { 100, 0 },
167         [5] = { 200, 0 },
168         [6] = { 400, 0 },
169         [7] = { 800, 0 },
170         [8] = { 1600, 0 },
171         [9] = { 3200, 0 },
172 };
173
174 #define ADXL313_ACCEL_CHANNEL(index, axis) {                            \
175         .type = IIO_ACCEL,                                              \
176         .address = index,                                               \
177         .modified = 1,                                                  \
178         .channel2 = IIO_MOD_##axis,                                     \
179         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |                  \
180                               BIT(IIO_CHAN_INFO_CALIBBIAS),             \
181         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
182                                     BIT(IIO_CHAN_INFO_SAMP_FREQ),       \
183         .info_mask_shared_by_type_available =                           \
184                 BIT(IIO_CHAN_INFO_SAMP_FREQ),                           \
185         .scan_type = {                                                  \
186                 .realbits = 13,                                         \
187         },                                                              \
188 }
189
190 static const struct iio_chan_spec adxl313_channels[] = {
191         ADXL313_ACCEL_CHANNEL(0, X),
192         ADXL313_ACCEL_CHANNEL(1, Y),
193         ADXL313_ACCEL_CHANNEL(2, Z),
194 };
195
196 static int adxl313_set_odr(struct adxl313_data *data,
197                            unsigned int freq1, unsigned int freq2)
198 {
199         unsigned int i;
200
201         for (i = 0; i < ARRAY_SIZE(adxl313_odr_freqs); i++) {
202                 if (adxl313_odr_freqs[i][0] == freq1 &&
203                     adxl313_odr_freqs[i][1] == freq2)
204                         break;
205         }
206
207         if (i == ARRAY_SIZE(adxl313_odr_freqs))
208                 return -EINVAL;
209
210         return regmap_update_bits(data->regmap, ADXL313_REG_BW_RATE,
211                                   ADXL313_RATE_MSK,
212                                   FIELD_PREP(ADXL313_RATE_MSK, ADXL313_RATE_BASE + i));
213 }
214
215 static int adxl313_read_axis(struct adxl313_data *data,
216                              struct iio_chan_spec const *chan)
217 {
218         int ret;
219
220         mutex_lock(&data->lock);
221
222         ret = regmap_bulk_read(data->regmap,
223                                ADXL313_REG_DATA_AXIS(chan->address),
224                                &data->transf_buf, sizeof(data->transf_buf));
225         if (ret)
226                 goto unlock_ret;
227
228         ret = le16_to_cpu(data->transf_buf);
229
230 unlock_ret:
231         mutex_unlock(&data->lock);
232         return ret;
233 }
234
235 static int adxl313_read_freq_avail(struct iio_dev *indio_dev,
236                                    struct iio_chan_spec const *chan,
237                                    const int **vals, int *type, int *length,
238                                    long mask)
239 {
240         switch (mask) {
241         case IIO_CHAN_INFO_SAMP_FREQ:
242                 *vals = (const int *)adxl313_odr_freqs;
243                 *length = ARRAY_SIZE(adxl313_odr_freqs) * 2;
244                 *type = IIO_VAL_INT_PLUS_MICRO;
245                 return IIO_AVAIL_LIST;
246         default:
247                 return -EINVAL;
248         }
249 }
250
251 static int adxl313_read_raw(struct iio_dev *indio_dev,
252                             struct iio_chan_spec const *chan,
253                             int *val, int *val2, long mask)
254 {
255         struct adxl313_data *data = iio_priv(indio_dev);
256         unsigned int regval;
257         int ret;
258
259         switch (mask) {
260         case IIO_CHAN_INFO_RAW:
261                 ret = adxl313_read_axis(data, chan);
262                 if (ret < 0)
263                         return ret;
264
265                 *val = sign_extend32(ret, chan->scan_type.realbits - 1);
266                 return IIO_VAL_INT;
267         case IIO_CHAN_INFO_SCALE:
268                 *val = 0;
269
270                 *val2 = data->chip_info->scale_factor;
271
272                 return IIO_VAL_INT_PLUS_NANO;
273         case IIO_CHAN_INFO_CALIBBIAS:
274                 ret = regmap_read(data->regmap,
275                                   ADXL313_REG_OFS_AXIS(chan->address), &regval);
276                 if (ret)
277                         return ret;
278
279                 /*
280                  * 8-bit resolution at minimum range, that is 4x accel data scale
281                  * factor at full resolution
282                  */
283                 *val = sign_extend32(regval, 7) * 4;
284                 return IIO_VAL_INT;
285         case IIO_CHAN_INFO_SAMP_FREQ:
286                 ret = regmap_read(data->regmap, ADXL313_REG_BW_RATE, &regval);
287                 if (ret)
288                         return ret;
289
290                 ret = FIELD_GET(ADXL313_RATE_MSK, regval) - ADXL313_RATE_BASE;
291                 *val = adxl313_odr_freqs[ret][0];
292                 *val2 = adxl313_odr_freqs[ret][1];
293                 return IIO_VAL_INT_PLUS_MICRO;
294         default:
295                 return -EINVAL;
296         }
297 }
298
299 static int adxl313_write_raw(struct iio_dev *indio_dev,
300                              struct iio_chan_spec const *chan,
301                              int val, int val2, long mask)
302 {
303         struct adxl313_data *data = iio_priv(indio_dev);
304
305         switch (mask) {
306         case IIO_CHAN_INFO_CALIBBIAS:
307                 /*
308                  * 8-bit resolution at minimum range, that is 4x accel data scale
309                  * factor at full resolution
310                  */
311                 if (clamp_val(val, -128 * 4, 127 * 4) != val)
312                         return -EINVAL;
313
314                 return regmap_write(data->regmap,
315                                     ADXL313_REG_OFS_AXIS(chan->address),
316                                     val / 4);
317         case IIO_CHAN_INFO_SAMP_FREQ:
318                 return adxl313_set_odr(data, val, val2);
319         default:
320                 return -EINVAL;
321         }
322 }
323
324 static const struct iio_info adxl313_info = {
325         .read_raw       = adxl313_read_raw,
326         .write_raw      = adxl313_write_raw,
327         .read_avail     = adxl313_read_freq_avail,
328 };
329
330 static int adxl313_setup(struct device *dev, struct adxl313_data *data,
331                          int (*setup)(struct device *, struct regmap *))
332 {
333         int ret;
334
335         /*
336          * If sw reset available, ensures the device is in a consistent
337          * state after start up
338          */
339         if (data->chip_info->soft_reset) {
340                 ret = regmap_write(data->regmap, ADXL313_REG_SOFT_RESET,
341                                    ADXL313_SOFT_RESET);
342                 if (ret)
343                         return ret;
344         }
345
346         if (setup) {
347                 ret = setup(dev, data->regmap);
348                 if (ret)
349                         return ret;
350         }
351
352         ret = data->chip_info->check_id(dev, data);
353         if (ret)
354                 return ret;
355
356         /* Sets the range to maximum, full resolution, if applicable */
357         if (data->chip_info->variable_range) {
358                 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
359                                          ADXL313_RANGE_MSK,
360                                          FIELD_PREP(ADXL313_RANGE_MSK, ADXL313_RANGE_MAX));
361                 if (ret)
362                         return ret;
363
364                 /* Enables full resolution */
365                 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
366                                          ADXL313_FULL_RES, ADXL313_FULL_RES);
367                 if (ret)
368                         return ret;
369         }
370
371         /* Enables measurement mode */
372         return regmap_update_bits(data->regmap, ADXL313_REG_POWER_CTL,
373                                   ADXL313_POWER_CTL_MSK,
374                                   ADXL313_MEASUREMENT_MODE);
375 }
376
377 /**
378  * adxl313_core_probe() - probe and setup for adxl313 accelerometer
379  * @dev:        Driver model representation of the device
380  * @regmap:     Register map of the device
381  * @chip_info:  Structure containing device specific data
382  * @setup:      Setup routine to be executed right before the standard device
383  *              setup, can also be set to NULL if not required
384  *
385  * Return: 0 on success, negative errno on error cases
386  */
387 int adxl313_core_probe(struct device *dev,
388                        struct regmap *regmap,
389                        const struct adxl313_chip_info *chip_info,
390                        int (*setup)(struct device *, struct regmap *))
391 {
392         struct adxl313_data *data;
393         struct iio_dev *indio_dev;
394         int ret;
395
396         indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
397         if (!indio_dev)
398                 return -ENOMEM;
399
400         data = iio_priv(indio_dev);
401         data->regmap = regmap;
402         data->chip_info = chip_info;
403
404         mutex_init(&data->lock);
405
406         indio_dev->name = chip_info->name;
407         indio_dev->info = &adxl313_info;
408         indio_dev->modes = INDIO_DIRECT_MODE;
409         indio_dev->channels = adxl313_channels;
410         indio_dev->num_channels = ARRAY_SIZE(adxl313_channels);
411
412         ret = adxl313_setup(dev, data, setup);
413         if (ret) {
414                 dev_err(dev, "ADXL313 setup failed\n");
415                 return ret;
416         }
417
418         return devm_iio_device_register(dev, indio_dev);
419 }
420 EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313);
421
422 MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>");
423 MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver");
424 MODULE_LICENSE("GPL v2");