This source file includes following definitions.
- adxl372_read_axis
- adxl372_set_op_mode
- adxl372_set_odr
- adxl372_find_closest_match
- adxl372_set_bandwidth
- adxl372_set_act_proc_mode
- adxl372_set_activity_threshold
- adxl372_set_activity_time_ms
- adxl372_set_inactivity_time_ms
- adxl372_set_interrupts
- adxl372_configure_fifo
- adxl372_get_status
- adxl372_trigger_handler
- adxl372_setup
- adxl372_reg_access
- adxl372_read_raw
- adxl372_write_raw
- adxl372_show_filter_freq_avail
- adxl372_get_fifo_enabled
- adxl372_get_fifo_watermark
- adxl372_set_watermark
- adxl372_buffer_postenable
- adxl372_buffer_predisable
- adxl372_dready_trig_set_state
- adxl372_validate_trigger
- adxl372_readable_noinc_reg
- adxl372_probe
1
2
3
4
5
6
7
8 #include <linux/bitops.h>
9 #include <linux/interrupt.h>
10 #include <linux/irq.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13 #include <linux/spi/spi.h>
14
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/iio/buffer.h>
18 #include <linux/iio/events.h>
19 #include <linux/iio/trigger.h>
20 #include <linux/iio/trigger_consumer.h>
21 #include <linux/iio/triggered_buffer.h>
22
23 #include "adxl372.h"
24
25
26 #define ADXL372_DEVID 0x00
27 #define ADXL372_DEVID_MST 0x01
28 #define ADXL372_PARTID 0x02
29 #define ADXL372_STATUS_1 0x04
30 #define ADXL372_STATUS_2 0x05
31 #define ADXL372_FIFO_ENTRIES_2 0x06
32 #define ADXL372_FIFO_ENTRIES_1 0x07
33 #define ADXL372_X_DATA_H 0x08
34 #define ADXL372_X_DATA_L 0x09
35 #define ADXL372_Y_DATA_H 0x0A
36 #define ADXL372_Y_DATA_L 0x0B
37 #define ADXL372_Z_DATA_H 0x0C
38 #define ADXL372_Z_DATA_L 0x0D
39 #define ADXL372_X_MAXPEAK_H 0x15
40 #define ADXL372_X_MAXPEAK_L 0x16
41 #define ADXL372_Y_MAXPEAK_H 0x17
42 #define ADXL372_Y_MAXPEAK_L 0x18
43 #define ADXL372_Z_MAXPEAK_H 0x19
44 #define ADXL372_Z_MAXPEAK_L 0x1A
45 #define ADXL372_OFFSET_X 0x20
46 #define ADXL372_OFFSET_Y 0x21
47 #define ADXL372_OFFSET_Z 0x22
48 #define ADXL372_X_THRESH_ACT_H 0x23
49 #define ADXL372_X_THRESH_ACT_L 0x24
50 #define ADXL372_Y_THRESH_ACT_H 0x25
51 #define ADXL372_Y_THRESH_ACT_L 0x26
52 #define ADXL372_Z_THRESH_ACT_H 0x27
53 #define ADXL372_Z_THRESH_ACT_L 0x28
54 #define ADXL372_TIME_ACT 0x29
55 #define ADXL372_X_THRESH_INACT_H 0x2A
56 #define ADXL372_X_THRESH_INACT_L 0x2B
57 #define ADXL372_Y_THRESH_INACT_H 0x2C
58 #define ADXL372_Y_THRESH_INACT_L 0x2D
59 #define ADXL372_Z_THRESH_INACT_H 0x2E
60 #define ADXL372_Z_THRESH_INACT_L 0x2F
61 #define ADXL372_TIME_INACT_H 0x30
62 #define ADXL372_TIME_INACT_L 0x31
63 #define ADXL372_X_THRESH_ACT2_H 0x32
64 #define ADXL372_X_THRESH_ACT2_L 0x33
65 #define ADXL372_Y_THRESH_ACT2_H 0x34
66 #define ADXL372_Y_THRESH_ACT2_L 0x35
67 #define ADXL372_Z_THRESH_ACT2_H 0x36
68 #define ADXL372_Z_THRESH_ACT2_L 0x37
69 #define ADXL372_HPF 0x38
70 #define ADXL372_FIFO_SAMPLES 0x39
71 #define ADXL372_FIFO_CTL 0x3A
72 #define ADXL372_INT1_MAP 0x3B
73 #define ADXL372_INT2_MAP 0x3C
74 #define ADXL372_TIMING 0x3D
75 #define ADXL372_MEASURE 0x3E
76 #define ADXL372_POWER_CTL 0x3F
77 #define ADXL372_SELF_TEST 0x40
78 #define ADXL372_RESET 0x41
79 #define ADXL372_FIFO_DATA 0x42
80
81 #define ADXL372_DEVID_VAL 0xAD
82 #define ADXL372_PARTID_VAL 0xFA
83 #define ADXL372_RESET_CODE 0x52
84
85
86 #define ADXL372_POWER_CTL_MODE_MSK GENMASK_ULL(1, 0)
87 #define ADXL372_POWER_CTL_MODE(x) (((x) & 0x3) << 0)
88
89
90 #define ADXL372_MEASURE_LINKLOOP_MSK GENMASK_ULL(5, 4)
91 #define ADXL372_MEASURE_LINKLOOP_MODE(x) (((x) & 0x3) << 4)
92 #define ADXL372_MEASURE_BANDWIDTH_MSK GENMASK_ULL(2, 0)
93 #define ADXL372_MEASURE_BANDWIDTH_MODE(x) (((x) & 0x7) << 0)
94
95
96 #define ADXL372_TIMING_ODR_MSK GENMASK_ULL(7, 5)
97 #define ADXL372_TIMING_ODR_MODE(x) (((x) & 0x7) << 5)
98
99
100 #define ADXL372_FIFO_CTL_FORMAT_MSK GENMASK(5, 3)
101 #define ADXL372_FIFO_CTL_FORMAT_MODE(x) (((x) & 0x7) << 3)
102 #define ADXL372_FIFO_CTL_MODE_MSK GENMASK(2, 1)
103 #define ADXL372_FIFO_CTL_MODE_MODE(x) (((x) & 0x3) << 1)
104 #define ADXL372_FIFO_CTL_SAMPLES_MSK BIT(1)
105 #define ADXL372_FIFO_CTL_SAMPLES_MODE(x) (((x) > 0xFF) ? 1 : 0)
106
107
108 #define ADXL372_STATUS_1_DATA_RDY(x) (((x) >> 0) & 0x1)
109 #define ADXL372_STATUS_1_FIFO_RDY(x) (((x) >> 1) & 0x1)
110 #define ADXL372_STATUS_1_FIFO_FULL(x) (((x) >> 2) & 0x1)
111 #define ADXL372_STATUS_1_FIFO_OVR(x) (((x) >> 3) & 0x1)
112 #define ADXL372_STATUS_1_USR_NVM_BUSY(x) (((x) >> 5) & 0x1)
113 #define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1)
114 #define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1)
115
116
117 #define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0)
118 #define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0)
119 #define ADXL372_INT1_MAP_FIFO_RDY_MSK BIT(1)
120 #define ADXL372_INT1_MAP_FIFO_RDY_MODE(x) (((x) & 0x1) << 1)
121 #define ADXL372_INT1_MAP_FIFO_FULL_MSK BIT(2)
122 #define ADXL372_INT1_MAP_FIFO_FULL_MODE(x) (((x) & 0x1) << 2)
123 #define ADXL372_INT1_MAP_FIFO_OVR_MSK BIT(3)
124 #define ADXL372_INT1_MAP_FIFO_OVR_MODE(x) (((x) & 0x1) << 3)
125 #define ADXL372_INT1_MAP_INACT_MSK BIT(4)
126 #define ADXL372_INT1_MAP_INACT_MODE(x) (((x) & 0x1) << 4)
127 #define ADXL372_INT1_MAP_ACT_MSK BIT(5)
128 #define ADXL372_INT1_MAP_ACT_MODE(x) (((x) & 0x1) << 5)
129 #define ADXL372_INT1_MAP_AWAKE_MSK BIT(6)
130 #define ADXL372_INT1_MAP_AWAKE_MODE(x) (((x) & 0x1) << 6)
131 #define ADXL372_INT1_MAP_LOW_MSK BIT(7)
132 #define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7)
133
134
135 #define ADXL372_FIFO_SIZE 512
136
137
138
139
140
141 #define ADXL372_USCALE 958241
142
143 enum adxl372_op_mode {
144 ADXL372_STANDBY,
145 ADXL372_WAKE_UP,
146 ADXL372_INSTANT_ON,
147 ADXL372_FULL_BW_MEASUREMENT,
148 };
149
150 enum adxl372_act_proc_mode {
151 ADXL372_DEFAULT,
152 ADXL372_LINKED,
153 ADXL372_LOOPED,
154 };
155
156 enum adxl372_th_activity {
157 ADXL372_ACTIVITY,
158 ADXL372_ACTIVITY2,
159 ADXL372_INACTIVITY,
160 };
161
162 enum adxl372_odr {
163 ADXL372_ODR_400HZ,
164 ADXL372_ODR_800HZ,
165 ADXL372_ODR_1600HZ,
166 ADXL372_ODR_3200HZ,
167 ADXL372_ODR_6400HZ,
168 };
169
170 enum adxl372_bandwidth {
171 ADXL372_BW_200HZ,
172 ADXL372_BW_400HZ,
173 ADXL372_BW_800HZ,
174 ADXL372_BW_1600HZ,
175 ADXL372_BW_3200HZ,
176 };
177
178 static const unsigned int adxl372_th_reg_high_addr[3] = {
179 [ADXL372_ACTIVITY] = ADXL372_X_THRESH_ACT_H,
180 [ADXL372_ACTIVITY2] = ADXL372_X_THRESH_ACT2_H,
181 [ADXL372_INACTIVITY] = ADXL372_X_THRESH_INACT_H,
182 };
183
184 enum adxl372_fifo_format {
185 ADXL372_XYZ_FIFO,
186 ADXL372_X_FIFO,
187 ADXL372_Y_FIFO,
188 ADXL372_XY_FIFO,
189 ADXL372_Z_FIFO,
190 ADXL372_XZ_FIFO,
191 ADXL372_YZ_FIFO,
192 ADXL372_XYZ_PEAK_FIFO,
193 };
194
195 enum adxl372_fifo_mode {
196 ADXL372_FIFO_BYPASSED,
197 ADXL372_FIFO_STREAMED,
198 ADXL372_FIFO_TRIGGERED,
199 ADXL372_FIFO_OLD_SAVED
200 };
201
202 static const int adxl372_samp_freq_tbl[5] = {
203 400, 800, 1600, 3200, 6400,
204 };
205
206 static const int adxl372_bw_freq_tbl[5] = {
207 200, 400, 800, 1600, 3200,
208 };
209
210 struct adxl372_axis_lookup {
211 unsigned int bits;
212 enum adxl372_fifo_format fifo_format;
213 };
214
215 static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = {
216 { BIT(0), ADXL372_X_FIFO },
217 { BIT(1), ADXL372_Y_FIFO },
218 { BIT(2), ADXL372_Z_FIFO },
219 { BIT(0) | BIT(1), ADXL372_XY_FIFO },
220 { BIT(0) | BIT(2), ADXL372_XZ_FIFO },
221 { BIT(1) | BIT(2), ADXL372_YZ_FIFO },
222 { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO },
223 };
224
225 #define ADXL372_ACCEL_CHANNEL(index, reg, axis) { \
226 .type = IIO_ACCEL, \
227 .address = reg, \
228 .modified = 1, \
229 .channel2 = IIO_MOD_##axis, \
230 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
231 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
232 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
233 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
234 .scan_index = index, \
235 .scan_type = { \
236 .sign = 's', \
237 .realbits = 12, \
238 .storagebits = 16, \
239 .shift = 4, \
240 .endianness = IIO_BE, \
241 }, \
242 }
243
244 static const struct iio_chan_spec adxl372_channels[] = {
245 ADXL372_ACCEL_CHANNEL(0, ADXL372_X_DATA_H, X),
246 ADXL372_ACCEL_CHANNEL(1, ADXL372_Y_DATA_H, Y),
247 ADXL372_ACCEL_CHANNEL(2, ADXL372_Z_DATA_H, Z),
248 };
249
250 struct adxl372_state {
251 int irq;
252 struct device *dev;
253 struct regmap *regmap;
254 struct iio_trigger *dready_trig;
255 enum adxl372_fifo_mode fifo_mode;
256 enum adxl372_fifo_format fifo_format;
257 enum adxl372_op_mode op_mode;
258 enum adxl372_act_proc_mode act_proc_mode;
259 enum adxl372_odr odr;
260 enum adxl372_bandwidth bw;
261 u32 act_time_ms;
262 u32 inact_time_ms;
263 u8 fifo_set_size;
264 u8 int1_bitmask;
265 u8 int2_bitmask;
266 u16 watermark;
267 __be16 fifo_buf[ADXL372_FIFO_SIZE];
268 };
269
270 static const unsigned long adxl372_channel_masks[] = {
271 BIT(0), BIT(1), BIT(2),
272 BIT(0) | BIT(1),
273 BIT(0) | BIT(2),
274 BIT(1) | BIT(2),
275 BIT(0) | BIT(1) | BIT(2),
276 0
277 };
278
279 static int adxl372_read_axis(struct adxl372_state *st, u8 addr)
280 {
281 __be16 regval;
282 int ret;
283
284 ret = regmap_bulk_read(st->regmap, addr, ®val, sizeof(regval));
285 if (ret < 0)
286 return ret;
287
288 return be16_to_cpu(regval);
289 }
290
291 static int adxl372_set_op_mode(struct adxl372_state *st,
292 enum adxl372_op_mode op_mode)
293 {
294 int ret;
295
296 ret = regmap_update_bits(st->regmap, ADXL372_POWER_CTL,
297 ADXL372_POWER_CTL_MODE_MSK,
298 ADXL372_POWER_CTL_MODE(op_mode));
299 if (ret < 0)
300 return ret;
301
302 st->op_mode = op_mode;
303
304 return ret;
305 }
306
307 static int adxl372_set_odr(struct adxl372_state *st,
308 enum adxl372_odr odr)
309 {
310 int ret;
311
312 ret = regmap_update_bits(st->regmap, ADXL372_TIMING,
313 ADXL372_TIMING_ODR_MSK,
314 ADXL372_TIMING_ODR_MODE(odr));
315 if (ret < 0)
316 return ret;
317
318 st->odr = odr;
319
320 return ret;
321 }
322
323 static int adxl372_find_closest_match(const int *array,
324 unsigned int size, int val)
325 {
326 int i;
327
328 for (i = 0; i < size; i++) {
329 if (val <= array[i])
330 return i;
331 }
332
333 return size - 1;
334 }
335
336 static int adxl372_set_bandwidth(struct adxl372_state *st,
337 enum adxl372_bandwidth bw)
338 {
339 int ret;
340
341 ret = regmap_update_bits(st->regmap, ADXL372_MEASURE,
342 ADXL372_MEASURE_BANDWIDTH_MSK,
343 ADXL372_MEASURE_BANDWIDTH_MODE(bw));
344 if (ret < 0)
345 return ret;
346
347 st->bw = bw;
348
349 return ret;
350 }
351
352 static int adxl372_set_act_proc_mode(struct adxl372_state *st,
353 enum adxl372_act_proc_mode mode)
354 {
355 int ret;
356
357 ret = regmap_update_bits(st->regmap,
358 ADXL372_MEASURE,
359 ADXL372_MEASURE_LINKLOOP_MSK,
360 ADXL372_MEASURE_LINKLOOP_MODE(mode));
361 if (ret < 0)
362 return ret;
363
364 st->act_proc_mode = mode;
365
366 return ret;
367 }
368
369 static int adxl372_set_activity_threshold(struct adxl372_state *st,
370 enum adxl372_th_activity act,
371 bool ref_en, bool enable,
372 unsigned int threshold)
373 {
374 unsigned char buf[6];
375 unsigned char th_reg_high_val, th_reg_low_val, th_reg_high_addr;
376
377
378 th_reg_high_val = (threshold / 100) >> 3;
379 th_reg_low_val = ((threshold / 100) << 5) | (ref_en << 1) | enable;
380 th_reg_high_addr = adxl372_th_reg_high_addr[act];
381
382 buf[0] = th_reg_high_val;
383 buf[1] = th_reg_low_val;
384 buf[2] = th_reg_high_val;
385 buf[3] = th_reg_low_val;
386 buf[4] = th_reg_high_val;
387 buf[5] = th_reg_low_val;
388
389 return regmap_bulk_write(st->regmap, th_reg_high_addr,
390 buf, ARRAY_SIZE(buf));
391 }
392
393 static int adxl372_set_activity_time_ms(struct adxl372_state *st,
394 unsigned int act_time_ms)
395 {
396 unsigned int reg_val, scale_factor;
397 int ret;
398
399
400
401
402
403 if (st->odr == ADXL372_ODR_6400HZ)
404 scale_factor = 3300;
405 else
406 scale_factor = 6600;
407
408 reg_val = DIV_ROUND_CLOSEST(act_time_ms * 1000, scale_factor);
409
410
411 if (reg_val > 0xFF)
412 reg_val = 0xFF;
413
414 ret = regmap_write(st->regmap, ADXL372_TIME_ACT, reg_val);
415 if (ret < 0)
416 return ret;
417
418 st->act_time_ms = act_time_ms;
419
420 return ret;
421 }
422
423 static int adxl372_set_inactivity_time_ms(struct adxl372_state *st,
424 unsigned int inact_time_ms)
425 {
426 unsigned int reg_val_h, reg_val_l, res, scale_factor;
427 int ret;
428
429
430
431
432
433 if (st->odr == ADXL372_ODR_6400HZ)
434 scale_factor = 13;
435 else
436 scale_factor = 26;
437
438 res = DIV_ROUND_CLOSEST(inact_time_ms, scale_factor);
439 reg_val_h = (res >> 8) & 0xFF;
440 reg_val_l = res & 0xFF;
441
442 ret = regmap_write(st->regmap, ADXL372_TIME_INACT_H, reg_val_h);
443 if (ret < 0)
444 return ret;
445
446 ret = regmap_write(st->regmap, ADXL372_TIME_INACT_L, reg_val_l);
447 if (ret < 0)
448 return ret;
449
450 st->inact_time_ms = inact_time_ms;
451
452 return ret;
453 }
454
455 static int adxl372_set_interrupts(struct adxl372_state *st,
456 unsigned char int1_bitmask,
457 unsigned char int2_bitmask)
458 {
459 int ret;
460
461 ret = regmap_write(st->regmap, ADXL372_INT1_MAP, int1_bitmask);
462 if (ret < 0)
463 return ret;
464
465 return regmap_write(st->regmap, ADXL372_INT2_MAP, int2_bitmask);
466 }
467
468 static int adxl372_configure_fifo(struct adxl372_state *st)
469 {
470 unsigned int fifo_samples, fifo_ctl;
471 int ret;
472
473
474 ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
475 if (ret < 0)
476 return ret;
477
478
479
480
481
482 fifo_samples = (st->watermark * st->fifo_set_size);
483 fifo_ctl = ADXL372_FIFO_CTL_FORMAT_MODE(st->fifo_format) |
484 ADXL372_FIFO_CTL_MODE_MODE(st->fifo_mode) |
485 ADXL372_FIFO_CTL_SAMPLES_MODE(fifo_samples);
486
487 ret = regmap_write(st->regmap,
488 ADXL372_FIFO_SAMPLES, fifo_samples & 0xFF);
489 if (ret < 0)
490 return ret;
491
492 ret = regmap_write(st->regmap, ADXL372_FIFO_CTL, fifo_ctl);
493 if (ret < 0)
494 return ret;
495
496 return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
497 }
498
499 static int adxl372_get_status(struct adxl372_state *st,
500 u8 *status1, u8 *status2,
501 u16 *fifo_entries)
502 {
503 __be32 buf;
504 u32 val;
505 int ret;
506
507
508 ret = regmap_bulk_read(st->regmap, ADXL372_STATUS_1,
509 &buf, sizeof(buf));
510 if (ret < 0)
511 return ret;
512
513 val = be32_to_cpu(buf);
514
515 *status1 = (val >> 24) & 0x0F;
516 *status2 = (val >> 16) & 0x0F;
517
518
519
520
521 *fifo_entries = val & 0x3FF;
522
523 return ret;
524 }
525
526 static irqreturn_t adxl372_trigger_handler(int irq, void *p)
527 {
528 struct iio_poll_func *pf = p;
529 struct iio_dev *indio_dev = pf->indio_dev;
530 struct adxl372_state *st = iio_priv(indio_dev);
531 u8 status1, status2;
532 u16 fifo_entries;
533 int i, ret;
534
535 ret = adxl372_get_status(st, &status1, &status2, &fifo_entries);
536 if (ret < 0)
537 goto err;
538
539 if (st->fifo_mode != ADXL372_FIFO_BYPASSED &&
540 ADXL372_STATUS_1_FIFO_FULL(status1)) {
541
542
543
544
545
546
547 fifo_entries -= st->fifo_set_size;
548
549
550 ret = regmap_noinc_read(st->regmap, ADXL372_FIFO_DATA,
551 st->fifo_buf,
552 fifo_entries * sizeof(u16));
553 if (ret < 0)
554 goto err;
555
556
557 for (i = 0; i < fifo_entries; i += st->fifo_set_size)
558 iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
559 }
560 err:
561 iio_trigger_notify_done(indio_dev->trig);
562 return IRQ_HANDLED;
563 }
564
565 static int adxl372_setup(struct adxl372_state *st)
566 {
567 unsigned int regval;
568 int ret;
569
570 ret = regmap_read(st->regmap, ADXL372_DEVID, ®val);
571 if (ret < 0)
572 return ret;
573
574 if (regval != ADXL372_DEVID_VAL) {
575 dev_err(st->dev, "Invalid chip id %x\n", regval);
576 return -ENODEV;
577 }
578
579
580
581
582
583 ret = regmap_write(st->regmap, ADXL372_RESET, ADXL372_RESET_CODE);
584 if (ret < 0)
585 return ret;
586
587 ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
588 if (ret < 0)
589 return ret;
590
591
592 ret = adxl372_set_activity_threshold(st, ADXL372_ACTIVITY,
593 true, true, 1000);
594 if (ret < 0)
595 return ret;
596
597
598 ret = adxl372_set_activity_threshold(st, ADXL372_INACTIVITY,
599 true, true, 100);
600 if (ret < 0)
601 return ret;
602
603
604 ret = adxl372_set_act_proc_mode(st, ADXL372_LOOPED);
605 if (ret < 0)
606 return ret;
607
608 ret = adxl372_set_odr(st, ADXL372_ODR_6400HZ);
609 if (ret < 0)
610 return ret;
611
612 ret = adxl372_set_bandwidth(st, ADXL372_BW_3200HZ);
613 if (ret < 0)
614 return ret;
615
616
617 ret = adxl372_set_activity_time_ms(st, 1);
618 if (ret < 0)
619 return ret;
620
621
622 ret = adxl372_set_inactivity_time_ms(st, 10000);
623 if (ret < 0)
624 return ret;
625
626
627 return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
628 }
629
630 static int adxl372_reg_access(struct iio_dev *indio_dev,
631 unsigned int reg,
632 unsigned int writeval,
633 unsigned int *readval)
634 {
635 struct adxl372_state *st = iio_priv(indio_dev);
636
637 if (readval)
638 return regmap_read(st->regmap, reg, readval);
639 else
640 return regmap_write(st->regmap, reg, writeval);
641 }
642
643 static int adxl372_read_raw(struct iio_dev *indio_dev,
644 struct iio_chan_spec const *chan,
645 int *val, int *val2, long info)
646 {
647 struct adxl372_state *st = iio_priv(indio_dev);
648 int ret;
649
650 switch (info) {
651 case IIO_CHAN_INFO_RAW:
652 ret = iio_device_claim_direct_mode(indio_dev);
653 if (ret)
654 return ret;
655
656 ret = adxl372_read_axis(st, chan->address);
657 iio_device_release_direct_mode(indio_dev);
658 if (ret < 0)
659 return ret;
660
661 *val = sign_extend32(ret >> chan->scan_type.shift,
662 chan->scan_type.realbits - 1);
663 return IIO_VAL_INT;
664 case IIO_CHAN_INFO_SCALE:
665 *val = 0;
666 *val2 = ADXL372_USCALE;
667 return IIO_VAL_INT_PLUS_MICRO;
668 case IIO_CHAN_INFO_SAMP_FREQ:
669 *val = adxl372_samp_freq_tbl[st->odr];
670 return IIO_VAL_INT;
671 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
672 *val = adxl372_bw_freq_tbl[st->bw];
673 return IIO_VAL_INT;
674 }
675
676 return -EINVAL;
677 }
678
679 static int adxl372_write_raw(struct iio_dev *indio_dev,
680 struct iio_chan_spec const *chan,
681 int val, int val2, long info)
682 {
683 struct adxl372_state *st = iio_priv(indio_dev);
684 int odr_index, bw_index, ret;
685
686 switch (info) {
687 case IIO_CHAN_INFO_SAMP_FREQ:
688 odr_index = adxl372_find_closest_match(adxl372_samp_freq_tbl,
689 ARRAY_SIZE(adxl372_samp_freq_tbl),
690 val);
691 ret = adxl372_set_odr(st, odr_index);
692 if (ret < 0)
693 return ret;
694
695
696
697
698 ret = adxl372_set_activity_time_ms(st, st->act_time_ms);
699 if (ret < 0)
700 return ret;
701
702
703
704
705 ret = adxl372_set_inactivity_time_ms(st, st->inact_time_ms);
706 if (ret < 0)
707 return ret;
708
709
710
711
712 if (st->bw > odr_index)
713 ret = adxl372_set_bandwidth(st, odr_index);
714
715 return ret;
716 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
717 bw_index = adxl372_find_closest_match(adxl372_bw_freq_tbl,
718 ARRAY_SIZE(adxl372_bw_freq_tbl),
719 val);
720 return adxl372_set_bandwidth(st, bw_index);
721 default:
722 return -EINVAL;
723 }
724 }
725
726 static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
727 struct device_attribute *attr,
728 char *buf)
729 {
730 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
731 struct adxl372_state *st = iio_priv(indio_dev);
732 int i;
733 size_t len = 0;
734
735 for (i = 0; i <= st->odr; i++)
736 len += scnprintf(buf + len, PAGE_SIZE - len,
737 "%d ", adxl372_bw_freq_tbl[i]);
738
739 buf[len - 1] = '\n';
740
741 return len;
742 }
743
744 static ssize_t adxl372_get_fifo_enabled(struct device *dev,
745 struct device_attribute *attr,
746 char *buf)
747 {
748 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
749 struct adxl372_state *st = iio_priv(indio_dev);
750
751 return sprintf(buf, "%d\n", st->fifo_mode);
752 }
753
754 static ssize_t adxl372_get_fifo_watermark(struct device *dev,
755 struct device_attribute *attr,
756 char *buf)
757 {
758 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
759 struct adxl372_state *st = iio_priv(indio_dev);
760
761 return sprintf(buf, "%d\n", st->watermark);
762 }
763
764 static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
765 static IIO_CONST_ATTR(hwfifo_watermark_max,
766 __stringify(ADXL372_FIFO_SIZE));
767 static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
768 adxl372_get_fifo_watermark, NULL, 0);
769 static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
770 adxl372_get_fifo_enabled, NULL, 0);
771
772 static const struct attribute *adxl372_fifo_attributes[] = {
773 &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
774 &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
775 &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
776 &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
777 NULL,
778 };
779
780 static int adxl372_set_watermark(struct iio_dev *indio_dev, unsigned int val)
781 {
782 struct adxl372_state *st = iio_priv(indio_dev);
783
784 if (val > ADXL372_FIFO_SIZE)
785 val = ADXL372_FIFO_SIZE;
786
787 st->watermark = val;
788
789 return 0;
790 }
791
792 static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
793 {
794 struct adxl372_state *st = iio_priv(indio_dev);
795 unsigned int mask;
796 int i, ret;
797
798 ret = iio_triggered_buffer_postenable(indio_dev);
799 if (ret < 0)
800 return ret;
801
802 ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0);
803 if (ret < 0)
804 goto err;
805
806 mask = *indio_dev->active_scan_mask;
807
808 for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) {
809 if (mask == adxl372_axis_lookup_table[i].bits)
810 break;
811 }
812
813 if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) {
814 ret = -EINVAL;
815 goto err;
816 }
817
818 st->fifo_format = adxl372_axis_lookup_table[i].fifo_format;
819 st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask,
820 indio_dev->masklength);
821
822
823
824
825
826
827 if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE)
828 st->watermark = (ADXL372_FIFO_SIZE / st->fifo_set_size);
829
830 st->fifo_mode = ADXL372_FIFO_STREAMED;
831
832 ret = adxl372_configure_fifo(st);
833 if (ret < 0) {
834 st->fifo_mode = ADXL372_FIFO_BYPASSED;
835 adxl372_set_interrupts(st, 0, 0);
836 goto err;
837 }
838
839 return 0;
840
841 err:
842 iio_triggered_buffer_predisable(indio_dev);
843 return ret;
844 }
845
846 static int adxl372_buffer_predisable(struct iio_dev *indio_dev)
847 {
848 struct adxl372_state *st = iio_priv(indio_dev);
849
850 adxl372_set_interrupts(st, 0, 0);
851 st->fifo_mode = ADXL372_FIFO_BYPASSED;
852 adxl372_configure_fifo(st);
853
854 return iio_triggered_buffer_predisable(indio_dev);
855 }
856
857 static const struct iio_buffer_setup_ops adxl372_buffer_ops = {
858 .postenable = adxl372_buffer_postenable,
859 .predisable = adxl372_buffer_predisable,
860 };
861
862 static int adxl372_dready_trig_set_state(struct iio_trigger *trig,
863 bool state)
864 {
865 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
866 struct adxl372_state *st = iio_priv(indio_dev);
867 unsigned long int mask = 0;
868
869 if (state)
870 mask = ADXL372_INT1_MAP_FIFO_FULL_MSK;
871
872 return adxl372_set_interrupts(st, mask, 0);
873 }
874
875 static int adxl372_validate_trigger(struct iio_dev *indio_dev,
876 struct iio_trigger *trig)
877 {
878 struct adxl372_state *st = iio_priv(indio_dev);
879
880 if (st->dready_trig != trig)
881 return -EINVAL;
882
883 return 0;
884 }
885
886 static const struct iio_trigger_ops adxl372_trigger_ops = {
887 .validate_device = &iio_trigger_validate_own_device,
888 .set_trigger_state = adxl372_dready_trig_set_state,
889 };
890
891 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400");
892 static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
893 0444, adxl372_show_filter_freq_avail, NULL, 0);
894
895 static struct attribute *adxl372_attributes[] = {
896 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
897 &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
898 NULL,
899 };
900
901 static const struct attribute_group adxl372_attrs_group = {
902 .attrs = adxl372_attributes,
903 };
904
905 static const struct iio_info adxl372_info = {
906 .validate_trigger = &adxl372_validate_trigger,
907 .attrs = &adxl372_attrs_group,
908 .read_raw = adxl372_read_raw,
909 .write_raw = adxl372_write_raw,
910 .debugfs_reg_access = &adxl372_reg_access,
911 .hwfifo_set_watermark = adxl372_set_watermark,
912 };
913
914 bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
915 {
916 return (reg == ADXL372_FIFO_DATA);
917 }
918 EXPORT_SYMBOL_GPL(adxl372_readable_noinc_reg);
919
920 int adxl372_probe(struct device *dev, struct regmap *regmap,
921 int irq, const char *name)
922 {
923 struct iio_dev *indio_dev;
924 struct adxl372_state *st;
925 int ret;
926
927 indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
928 if (!indio_dev)
929 return -ENOMEM;
930
931 st = iio_priv(indio_dev);
932 dev_set_drvdata(dev, indio_dev);
933
934 st->dev = dev;
935 st->regmap = regmap;
936 st->irq = irq;
937
938 indio_dev->channels = adxl372_channels;
939 indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
940 indio_dev->available_scan_masks = adxl372_channel_masks;
941 indio_dev->dev.parent = dev;
942 indio_dev->name = name;
943 indio_dev->info = &adxl372_info;
944 indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
945
946 ret = adxl372_setup(st);
947 if (ret < 0) {
948 dev_err(dev, "ADXL372 setup failed\n");
949 return ret;
950 }
951
952 ret = devm_iio_triggered_buffer_setup(dev,
953 indio_dev, NULL,
954 adxl372_trigger_handler,
955 &adxl372_buffer_ops);
956 if (ret < 0)
957 return ret;
958
959 iio_buffer_set_attrs(indio_dev->buffer, adxl372_fifo_attributes);
960
961 if (st->irq) {
962 st->dready_trig = devm_iio_trigger_alloc(dev,
963 "%s-dev%d",
964 indio_dev->name,
965 indio_dev->id);
966 if (st->dready_trig == NULL)
967 return -ENOMEM;
968
969 st->dready_trig->ops = &adxl372_trigger_ops;
970 st->dready_trig->dev.parent = dev;
971 iio_trigger_set_drvdata(st->dready_trig, indio_dev);
972 ret = devm_iio_trigger_register(dev, st->dready_trig);
973 if (ret < 0)
974 return ret;
975
976 indio_dev->trig = iio_trigger_get(st->dready_trig);
977
978 ret = devm_request_threaded_irq(dev, st->irq,
979 iio_trigger_generic_data_rdy_poll,
980 NULL,
981 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
982 indio_dev->name, st->dready_trig);
983 if (ret < 0)
984 return ret;
985 }
986
987 return devm_iio_device_register(dev, indio_dev);
988 }
989 EXPORT_SYMBOL_GPL(adxl372_probe);
990
991 MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
992 MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver");
993 MODULE_LICENSE("GPL");