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
16static 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
23static 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
31const 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};
35EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, IIO_ADXL313);
36
37const 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};
41EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313);
42
43const 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};
47EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, IIO_ADXL313);
48
49static 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
65static 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
98const 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};
124EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, IIO_ADXL313);
125
126static 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
134static 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
143const 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};
147EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, IIO_ADXL313);
148
149const 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};
153EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313);
154
155const 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};
159EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, IIO_ADXL313);
160
161static 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
190static 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
196static 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
215static 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
230unlock_ret:
231	mutex_unlock(&data->lock);
232	return ret;
233}
234
235static 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
251static 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
299static 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
324static 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
330static 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 */
387int 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}
420EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313);
421
422MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>");
423MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver");
424MODULE_LICENSE("GPL v2");
425