1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include <linux/module.h>
33#include <linux/iio/kfifo_buf.h>
34#include <linux/iio/iio.h>
35#include <linux/iio/buffer.h>
36#include <linux/regmap.h>
37#include <linux/bitfield.h>
38
39#include <linux/platform_data/st_sensors_pdata.h>
40
41#include "st_lsm6dsx.h"
42
43#define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a
44#define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0)
45#define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3)
46#define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12)
47#define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e
48#define ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR 0x78
49#define ST_LSM6DSX_REG_TS_RESET_ADDR 0x42
50
51#define ST_LSM6DSX_MAX_FIFO_ODR_VAL 0x08
52
53#define ST_LSM6DSX_TS_RESET_VAL 0xaa
54
55struct st_lsm6dsx_decimator_entry {
56 u8 decimator;
57 u8 val;
58};
59
60enum st_lsm6dsx_fifo_tag {
61 ST_LSM6DSX_GYRO_TAG = 0x01,
62 ST_LSM6DSX_ACC_TAG = 0x02,
63 ST_LSM6DSX_TS_TAG = 0x04,
64 ST_LSM6DSX_EXT0_TAG = 0x0f,
65 ST_LSM6DSX_EXT1_TAG = 0x10,
66 ST_LSM6DSX_EXT2_TAG = 0x11,
67};
68
69static const
70struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
71 { 0, 0x0 },
72 { 1, 0x1 },
73 { 2, 0x2 },
74 { 3, 0x3 },
75 { 4, 0x4 },
76 { 8, 0x5 },
77 { 16, 0x6 },
78 { 32, 0x7 },
79};
80
81static int
82st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
83{
84 const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
85 u32 decimator = max_odr / sensor->odr;
86 int i;
87
88 if (decimator > 1)
89 decimator = round_down(decimator, 2);
90
91 for (i = 0; i < max_size; i++) {
92 if (st_lsm6dsx_decimator_table[i].decimator == decimator)
93 break;
94 }
95
96 return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
97}
98
99static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
100 u32 *max_odr, u32 *min_odr)
101{
102 struct st_lsm6dsx_sensor *sensor;
103 int i;
104
105 *max_odr = 0, *min_odr = ~0;
106 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
107 if (!hw->iio_devs[i])
108 continue;
109
110 sensor = iio_priv(hw->iio_devs[i]);
111
112 if (!(hw->enable_mask & BIT(sensor->id)))
113 continue;
114
115 *max_odr = max_t(u32, *max_odr, sensor->odr);
116 *min_odr = min_t(u32, *min_odr, sensor->odr);
117 }
118}
119
120static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr)
121{
122 u8 sip = sensor->odr / min_odr;
123
124 return sip > 1 ? round_down(sip, 2) : sip;
125}
126
127static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
128{
129 const struct st_lsm6dsx_reg *ts_dec_reg;
130 struct st_lsm6dsx_sensor *sensor;
131 u16 sip = 0, ts_sip = 0;
132 u32 max_odr, min_odr;
133 int err = 0, i;
134 u8 data;
135
136 st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
137
138 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
139 const struct st_lsm6dsx_reg *dec_reg;
140
141 if (!hw->iio_devs[i])
142 continue;
143
144 sensor = iio_priv(hw->iio_devs[i]);
145
146 if (hw->enable_mask & BIT(sensor->id)) {
147 sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr);
148 data = st_lsm6dsx_get_decimator_val(sensor, max_odr);
149 } else {
150 sensor->sip = 0;
151 data = 0;
152 }
153 ts_sip = max_t(u16, ts_sip, sensor->sip);
154
155 dec_reg = &hw->settings->decimator[sensor->id];
156 if (dec_reg->addr) {
157 int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask);
158
159 err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr,
160 dec_reg->mask,
161 val);
162 if (err < 0)
163 return err;
164 }
165 sip += sensor->sip;
166 }
167 hw->sip = sip + ts_sip;
168 hw->ts_sip = ts_sip;
169
170
171
172
173
174
175 ts_dec_reg = &hw->settings->ts_settings.decimator;
176 if (ts_dec_reg->addr) {
177 int val, ts_dec = !!hw->ts_sip;
178
179 val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask);
180 err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr,
181 ts_dec_reg->mask, val);
182 }
183 return err;
184}
185
186int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
187 enum st_lsm6dsx_fifo_mode fifo_mode)
188{
189 unsigned int data;
190
191 data = FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode);
192 return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
193 ST_LSM6DSX_FIFO_MODE_MASK, data);
194}
195
196static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
197 bool enable)
198{
199 struct st_lsm6dsx_hw *hw = sensor->hw;
200 const struct st_lsm6dsx_reg *batch_reg;
201 u8 data;
202
203 batch_reg = &hw->settings->batch[sensor->id];
204 if (batch_reg->addr) {
205 int val;
206
207 if (enable) {
208 int err;
209
210 err = st_lsm6dsx_check_odr(sensor, sensor->odr,
211 &data);
212 if (err < 0)
213 return err;
214 } else {
215 data = 0;
216 }
217 val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask);
218 return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr,
219 batch_reg->mask, val);
220 } else {
221 data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0;
222 return st_lsm6dsx_update_bits_locked(hw,
223 ST_LSM6DSX_REG_FIFO_MODE_ADDR,
224 ST_LSM6DSX_FIFO_ODR_MASK,
225 FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK,
226 data));
227 }
228}
229
230int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
231{
232 u16 fifo_watermark = ~0, cur_watermark, fifo_th_mask;
233 struct st_lsm6dsx_hw *hw = sensor->hw;
234 struct st_lsm6dsx_sensor *cur_sensor;
235 int i, err, data;
236 __le16 wdata;
237
238 if (!hw->sip)
239 return 0;
240
241 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
242 if (!hw->iio_devs[i])
243 continue;
244
245 cur_sensor = iio_priv(hw->iio_devs[i]);
246
247 if (!(hw->enable_mask & BIT(cur_sensor->id)))
248 continue;
249
250 cur_watermark = (cur_sensor == sensor) ? watermark
251 : cur_sensor->watermark;
252
253 fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
254 }
255
256 fifo_watermark = max_t(u16, fifo_watermark, hw->sip);
257 fifo_watermark = (fifo_watermark / hw->sip) * hw->sip;
258 fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl;
259
260 mutex_lock(&hw->page_lock);
261 err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1,
262 &data);
263 if (err < 0)
264 goto out;
265
266 fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask;
267 fifo_watermark = ((data << 8) & ~fifo_th_mask) |
268 (fifo_watermark & fifo_th_mask);
269
270 wdata = cpu_to_le16(fifo_watermark);
271 err = regmap_bulk_write(hw->regmap,
272 hw->settings->fifo_ops.fifo_th.addr,
273 &wdata, sizeof(wdata));
274out:
275 mutex_unlock(&hw->page_lock);
276 return err;
277}
278
279static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)
280{
281 struct st_lsm6dsx_sensor *sensor;
282 int i, err;
283
284
285 err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR,
286 ST_LSM6DSX_TS_RESET_VAL);
287 if (err < 0)
288 return err;
289
290 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
291 if (!hw->iio_devs[i])
292 continue;
293
294 sensor = iio_priv(hw->iio_devs[i]);
295
296
297
298
299 sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]);
300 }
301 return 0;
302}
303
304
305
306
307
308static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
309 u8 *data, unsigned int data_len,
310 unsigned int max_word_len)
311{
312 unsigned int word_len, read_len = 0;
313 int err;
314
315 while (read_len < data_len) {
316 word_len = min_t(unsigned int, data_len - read_len,
317 max_word_len);
318 err = st_lsm6dsx_read_locked(hw, addr, data + read_len,
319 word_len);
320 if (err < 0)
321 return err;
322 read_len += word_len;
323 }
324 return 0;
325}
326
327#define ST_LSM6DSX_IIO_BUFF_SIZE (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \
328 sizeof(s64)) + sizeof(s64))
329
330
331
332
333
334
335
336
337int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
338{
339 u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
340 u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
341 int err, acc_sip, gyro_sip, ts_sip, read_len, offset;
342 struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
343 u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
344 u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
345 bool reset_ts = false;
346 __le16 fifo_status;
347 s64 ts = 0;
348
349 err = st_lsm6dsx_read_locked(hw,
350 hw->settings->fifo_ops.fifo_diff.addr,
351 &fifo_status, sizeof(fifo_status));
352 if (err < 0) {
353 dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
354 err);
355 return err;
356 }
357
358 if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
359 return 0;
360
361 fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
362 ST_LSM6DSX_CHAN_SIZE;
363 fifo_len = (fifo_len / pattern_len) * pattern_len;
364
365 acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
366 gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
367
368 for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
369 err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
370 hw->buff, pattern_len,
371 ST_LSM6DSX_MAX_WORD_LEN);
372 if (err < 0) {
373 dev_err(hw->dev,
374 "failed to read pattern from fifo (err=%d)\n",
375 err);
376 return err;
377 }
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 gyro_sip = gyro_sensor->sip;
395 acc_sip = acc_sensor->sip;
396 ts_sip = hw->ts_sip;
397 offset = 0;
398
399 while (acc_sip > 0 || gyro_sip > 0) {
400 if (gyro_sip > 0) {
401 memcpy(gyro_buff, &hw->buff[offset],
402 ST_LSM6DSX_SAMPLE_SIZE);
403 offset += ST_LSM6DSX_SAMPLE_SIZE;
404 }
405 if (acc_sip > 0) {
406 memcpy(acc_buff, &hw->buff[offset],
407 ST_LSM6DSX_SAMPLE_SIZE);
408 offset += ST_LSM6DSX_SAMPLE_SIZE;
409 }
410
411 if (ts_sip-- > 0) {
412 u8 data[ST_LSM6DSX_SAMPLE_SIZE];
413
414 memcpy(data, &hw->buff[offset], sizeof(data));
415
416
417
418
419
420
421 ts = data[1] << 16 | data[0] << 8 | data[3];
422
423
424
425
426
427
428 if (!reset_ts && ts >= 0xff0000)
429 reset_ts = true;
430 ts *= hw->ts_gain;
431
432 offset += ST_LSM6DSX_SAMPLE_SIZE;
433 }
434
435 if (gyro_sip-- > 0)
436 iio_push_to_buffers_with_timestamp(
437 hw->iio_devs[ST_LSM6DSX_ID_GYRO],
438 gyro_buff, gyro_sensor->ts_ref + ts);
439 if (acc_sip-- > 0)
440 iio_push_to_buffers_with_timestamp(
441 hw->iio_devs[ST_LSM6DSX_ID_ACC],
442 acc_buff, acc_sensor->ts_ref + ts);
443 }
444 }
445
446 if (unlikely(reset_ts)) {
447 err = st_lsm6dsx_reset_hw_ts(hw);
448 if (err < 0) {
449 dev_err(hw->dev, "failed to reset hw ts (err=%d)\n",
450 err);
451 return err;
452 }
453 }
454 return read_len;
455}
456
457#define ST_LSM6DSX_INVALID_SAMPLE 0x7ffd
458static int
459st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,
460 u8 *data, s64 ts)
461{
462 s16 val = le16_to_cpu(*(__le16 *)data);
463 struct st_lsm6dsx_sensor *sensor;
464 struct iio_dev *iio_dev;
465
466
467 if (val >= ST_LSM6DSX_INVALID_SAMPLE)
468 return -EINVAL;
469
470
471
472
473
474
475
476 switch (tag) {
477 case ST_LSM6DSX_GYRO_TAG:
478 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO];
479 break;
480 case ST_LSM6DSX_ACC_TAG:
481 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC];
482 break;
483 case ST_LSM6DSX_EXT0_TAG:
484 if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0))
485 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0];
486 else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))
487 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
488 else
489 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
490 break;
491 case ST_LSM6DSX_EXT1_TAG:
492 if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) &&
493 (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)))
494 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
495 else
496 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
497 break;
498 case ST_LSM6DSX_EXT2_TAG:
499 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
500 break;
501 default:
502 return -EINVAL;
503 }
504
505 sensor = iio_priv(iio_dev);
506 iio_push_to_buffers_with_timestamp(iio_dev, data,
507 ts + sensor->ts_ref);
508
509 return 0;
510}
511
512
513
514
515
516
517
518
519
520int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
521{
522 u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
523 u16 fifo_len, fifo_diff_mask;
524 u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag;
525 bool reset_ts = false;
526 int i, err, read_len;
527 __le16 fifo_status;
528 s64 ts = 0;
529
530 err = st_lsm6dsx_read_locked(hw,
531 hw->settings->fifo_ops.fifo_diff.addr,
532 &fifo_status, sizeof(fifo_status));
533 if (err < 0) {
534 dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
535 err);
536 return err;
537 }
538
539 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
540 fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
541 ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
542 if (!fifo_len)
543 return 0;
544
545 for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
546 err = st_lsm6dsx_read_block(hw,
547 ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
548 hw->buff, pattern_len,
549 ST_LSM6DSX_MAX_TAGGED_WORD_LEN);
550 if (err < 0) {
551 dev_err(hw->dev,
552 "failed to read pattern from fifo (err=%d)\n",
553 err);
554 return err;
555 }
556
557 for (i = 0; i < pattern_len;
558 i += ST_LSM6DSX_TAGGED_SAMPLE_SIZE) {
559 memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
560 ST_LSM6DSX_SAMPLE_SIZE);
561
562 tag = hw->buff[i] >> 3;
563 if (tag == ST_LSM6DSX_TS_TAG) {
564
565
566
567
568
569
570 ts = le32_to_cpu(*((__le32 *)iio_buff));
571
572
573
574
575
576
577 if (!reset_ts && ts >= 0xffff0000)
578 reset_ts = true;
579 ts *= hw->ts_gain;
580 } else {
581 st_lsm6dsx_push_tagged_data(hw, tag, iio_buff,
582 ts);
583 }
584 }
585 }
586
587 if (unlikely(reset_ts)) {
588 err = st_lsm6dsx_reset_hw_ts(hw);
589 if (err < 0)
590 return err;
591 }
592 return read_len;
593}
594
595int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
596{
597 int err;
598
599 if (!hw->settings->fifo_ops.read_fifo)
600 return -ENOTSUPP;
601
602 mutex_lock(&hw->fifo_lock);
603
604 hw->settings->fifo_ops.read_fifo(hw);
605 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
606
607 mutex_unlock(&hw->fifo_lock);
608
609 return err;
610}
611
612int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
613{
614 struct st_lsm6dsx_hw *hw = sensor->hw;
615 u8 fifo_mask;
616 int err;
617
618 mutex_lock(&hw->conf_lock);
619
620 if (enable)
621 fifo_mask = hw->fifo_mask | BIT(sensor->id);
622 else
623 fifo_mask = hw->fifo_mask & ~BIT(sensor->id);
624
625 if (hw->fifo_mask) {
626 err = st_lsm6dsx_flush_fifo(hw);
627 if (err < 0)
628 goto out;
629 }
630
631 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
632 sensor->id == ST_LSM6DSX_ID_EXT1 ||
633 sensor->id == ST_LSM6DSX_ID_EXT2) {
634 err = st_lsm6dsx_shub_set_enable(sensor, enable);
635 if (err < 0)
636 goto out;
637 } else {
638 err = st_lsm6dsx_sensor_set_enable(sensor, enable);
639 if (err < 0)
640 goto out;
641
642 err = st_lsm6dsx_set_fifo_odr(sensor, enable);
643 if (err < 0)
644 goto out;
645 }
646
647 err = st_lsm6dsx_update_decimators(hw);
648 if (err < 0)
649 goto out;
650
651 err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
652 if (err < 0)
653 goto out;
654
655 if (fifo_mask) {
656
657 err = st_lsm6dsx_reset_hw_ts(hw);
658 if (err < 0)
659 goto out;
660
661 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
662 if (err < 0)
663 goto out;
664 }
665
666 hw->fifo_mask = fifo_mask;
667
668out:
669 mutex_unlock(&hw->conf_lock);
670
671 return err;
672}
673
674static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
675{
676 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
677 struct st_lsm6dsx_hw *hw = sensor->hw;
678
679 if (!hw->settings->fifo_ops.update_fifo)
680 return -ENOTSUPP;
681
682 return hw->settings->fifo_ops.update_fifo(sensor, true);
683}
684
685static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
686{
687 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
688 struct st_lsm6dsx_hw *hw = sensor->hw;
689
690 if (!hw->settings->fifo_ops.update_fifo)
691 return -ENOTSUPP;
692
693 return hw->settings->fifo_ops.update_fifo(sensor, false);
694}
695
696static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
697 .preenable = st_lsm6dsx_buffer_preenable,
698 .postdisable = st_lsm6dsx_buffer_postdisable,
699};
700
701int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
702{
703 struct iio_buffer *buffer;
704 int i;
705
706 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
707 if (!hw->iio_devs[i])
708 continue;
709
710 buffer = devm_iio_kfifo_allocate(hw->dev);
711 if (!buffer)
712 return -ENOMEM;
713
714 iio_device_attach_buffer(hw->iio_devs[i], buffer);
715 hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
716 hw->iio_devs[i]->setup_ops = &st_lsm6dsx_buffer_ops;
717 }
718
719 return 0;
720}
721