Lines Matching +full:hw +full:- +full:channels

1 // SPDX-License-Identifier: GPL-2.0-only
5 * LSM6DS3/LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
9 * - 1st data set is reserved for gyroscope data
10 * - 2nd data set is reserved for accelerometer data
21 * source (gyroscope, accelerometer, hw timer).
24 * - BYPASS: FIFO disabled
25 * - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
86 u32 decimator = max_odr / sensor->odr; in st_lsm6dsx_get_decimator_val()
97 sensor->decimator = decimator; in st_lsm6dsx_get_decimator_val()
101 static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, in st_lsm6dsx_get_max_min_odr() argument
109 if (!hw->iio_devs[i]) in st_lsm6dsx_get_max_min_odr()
112 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_get_max_min_odr()
114 if (!(hw->enable_mask & BIT(sensor->id))) in st_lsm6dsx_get_max_min_odr()
117 *max_odr = max_t(u32, *max_odr, sensor->odr); in st_lsm6dsx_get_max_min_odr()
118 *min_odr = min_t(u32, *min_odr, sensor->odr); in st_lsm6dsx_get_max_min_odr()
124 u8 sip = sensor->odr / min_odr; in st_lsm6dsx_get_sip()
129 static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_update_decimators() argument
138 st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr); in st_lsm6dsx_update_decimators()
143 if (!hw->iio_devs[i]) in st_lsm6dsx_update_decimators()
146 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_update_decimators()
148 if (hw->enable_mask & BIT(sensor->id)) { in st_lsm6dsx_update_decimators()
149 sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr); in st_lsm6dsx_update_decimators()
152 sensor->sip = 0; in st_lsm6dsx_update_decimators()
155 ts_sip = max_t(u16, ts_sip, sensor->sip); in st_lsm6dsx_update_decimators()
157 dec_reg = &hw->settings->decimator[sensor->id]; in st_lsm6dsx_update_decimators()
158 if (dec_reg->addr) { in st_lsm6dsx_update_decimators()
159 int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask); in st_lsm6dsx_update_decimators()
161 err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr, in st_lsm6dsx_update_decimators()
162 dec_reg->mask, in st_lsm6dsx_update_decimators()
167 sip += sensor->sip; in st_lsm6dsx_update_decimators()
169 hw->sip = sip + ts_sip; in st_lsm6dsx_update_decimators()
170 hw->ts_sip = ts_sip; in st_lsm6dsx_update_decimators()
173 * update hw ts decimator if necessary. Decimator for hw timestamp in st_lsm6dsx_update_decimators()
177 ts_dec_reg = &hw->settings->ts_settings.decimator; in st_lsm6dsx_update_decimators()
178 if (ts_dec_reg->addr) { in st_lsm6dsx_update_decimators()
179 int val, ts_dec = !!hw->ts_sip; in st_lsm6dsx_update_decimators()
181 val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask); in st_lsm6dsx_update_decimators()
182 err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr, in st_lsm6dsx_update_decimators()
183 ts_dec_reg->mask, val); in st_lsm6dsx_update_decimators()
188 static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, in st_lsm6dsx_set_fifo_mode() argument
194 return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR, in st_lsm6dsx_set_fifo_mode()
201 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_set_fifo_odr() local
205 batch_reg = &hw->settings->batch[sensor->id]; in st_lsm6dsx_set_fifo_odr()
206 if (batch_reg->addr) { in st_lsm6dsx_set_fifo_odr()
212 err = st_lsm6dsx_check_odr(sensor, sensor->odr, in st_lsm6dsx_set_fifo_odr()
219 val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask); in st_lsm6dsx_set_fifo_odr()
220 return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr, in st_lsm6dsx_set_fifo_odr()
221 batch_reg->mask, val); in st_lsm6dsx_set_fifo_odr()
223 data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0; in st_lsm6dsx_set_fifo_odr()
224 return st_lsm6dsx_update_bits_locked(hw, in st_lsm6dsx_set_fifo_odr()
235 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_watermark() local
240 if (!hw->sip) in st_lsm6dsx_update_watermark()
244 if (!hw->iio_devs[i]) in st_lsm6dsx_update_watermark()
247 cur_sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_update_watermark()
249 if (!(hw->enable_mask & BIT(cur_sensor->id))) in st_lsm6dsx_update_watermark()
253 : cur_sensor->watermark; in st_lsm6dsx_update_watermark()
258 fifo_watermark = max_t(u16, fifo_watermark, hw->sip); in st_lsm6dsx_update_watermark()
259 fifo_watermark = (fifo_watermark / hw->sip) * hw->sip; in st_lsm6dsx_update_watermark()
260 fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; in st_lsm6dsx_update_watermark()
262 mutex_lock(&hw->page_lock); in st_lsm6dsx_update_watermark()
263 err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1, in st_lsm6dsx_update_watermark()
268 fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; in st_lsm6dsx_update_watermark()
273 err = regmap_bulk_write(hw->regmap, in st_lsm6dsx_update_watermark()
274 hw->settings->fifo_ops.fifo_th.addr, in st_lsm6dsx_update_watermark()
277 mutex_unlock(&hw->page_lock); in st_lsm6dsx_update_watermark()
281 static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_reset_hw_ts() argument
286 /* reset hw ts counter */ in st_lsm6dsx_reset_hw_ts()
287 err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR, in st_lsm6dsx_reset_hw_ts()
293 if (!hw->iio_devs[i]) in st_lsm6dsx_reset_hw_ts()
296 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_reset_hw_ts()
299 * hw timestamp in st_lsm6dsx_reset_hw_ts()
301 sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]); in st_lsm6dsx_reset_hw_ts()
306 int st_lsm6dsx_resume_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_resume_fifo() argument
310 /* reset hw ts counter */ in st_lsm6dsx_resume_fifo()
311 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_resume_fifo()
315 return st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); in st_lsm6dsx_resume_fifo()
322 static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr, in st_lsm6dsx_read_block() argument
330 word_len = min_t(unsigned int, data_len - read_len, in st_lsm6dsx_read_block()
332 err = st_lsm6dsx_read_locked(hw, addr, data + read_len, in st_lsm6dsx_read_block()
344 * st_lsm6dsx_read_fifo() - hw FIFO read routine
345 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
347 * Read samples from the hw FIFO and push them to IIO buffers.
351 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_read_fifo() argument
355 u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; in st_lsm6dsx_read_fifo()
356 u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; in st_lsm6dsx_read_fifo()
361 err = st_lsm6dsx_read_locked(hw, in st_lsm6dsx_read_fifo()
362 hw->settings->fifo_ops.fifo_diff.addr, in st_lsm6dsx_read_fifo()
365 dev_err(hw->dev, "failed to read fifo status (err=%d)\n", in st_lsm6dsx_read_fifo()
377 acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); in st_lsm6dsx_read_fifo()
378 gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]); in st_lsm6dsx_read_fifo()
379 if (hw->iio_devs[ST_LSM6DSX_ID_EXT0]) in st_lsm6dsx_read_fifo()
380 ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]); in st_lsm6dsx_read_fifo()
383 err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR, in st_lsm6dsx_read_fifo()
384 hw->buff, pattern_len, in st_lsm6dsx_read_fifo()
387 dev_err(hw->dev, in st_lsm6dsx_read_fifo()
403 * - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz in st_lsm6dsx_read_fifo()
406 * - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, .. in st_lsm6dsx_read_fifo()
408 ext_sip = ext_sensor ? ext_sensor->sip : 0; in st_lsm6dsx_read_fifo()
409 gyro_sip = gyro_sensor->sip; in st_lsm6dsx_read_fifo()
410 acc_sip = acc_sensor->sip; in st_lsm6dsx_read_fifo()
411 ts_sip = hw->ts_sip; in st_lsm6dsx_read_fifo()
416 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { in st_lsm6dsx_read_fifo()
417 memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, in st_lsm6dsx_read_fifo()
418 &hw->buff[offset], in st_lsm6dsx_read_fifo()
419 sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); in st_lsm6dsx_read_fifo()
420 offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); in st_lsm6dsx_read_fifo()
422 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { in st_lsm6dsx_read_fifo()
423 memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, in st_lsm6dsx_read_fifo()
424 &hw->buff[offset], in st_lsm6dsx_read_fifo()
425 sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); in st_lsm6dsx_read_fifo()
426 offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); in st_lsm6dsx_read_fifo()
428 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { in st_lsm6dsx_read_fifo()
429 memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, in st_lsm6dsx_read_fifo()
430 &hw->buff[offset], in st_lsm6dsx_read_fifo()
431 sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); in st_lsm6dsx_read_fifo()
432 offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); in st_lsm6dsx_read_fifo()
435 if (ts_sip-- > 0) { in st_lsm6dsx_read_fifo()
438 memcpy(data, &hw->buff[offset], sizeof(data)); in st_lsm6dsx_read_fifo()
440 * hw timestamp is 3B long and it is stored in st_lsm6dsx_read_fifo()
447 * check if hw timestamp engine is going to in st_lsm6dsx_read_fifo()
449 * to signal the hw timestamp will reset in in st_lsm6dsx_read_fifo()
454 ts *= hw->ts_gain; in st_lsm6dsx_read_fifo()
459 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { in st_lsm6dsx_read_fifo()
464 if (gyro_sensor->samples_to_discard > 0) in st_lsm6dsx_read_fifo()
465 gyro_sensor->samples_to_discard--; in st_lsm6dsx_read_fifo()
468 hw->iio_devs[ST_LSM6DSX_ID_GYRO], in st_lsm6dsx_read_fifo()
469 &hw->scan[ST_LSM6DSX_ID_GYRO], in st_lsm6dsx_read_fifo()
470 gyro_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
471 gyro_sip--; in st_lsm6dsx_read_fifo()
473 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { in st_lsm6dsx_read_fifo()
478 if (acc_sensor->samples_to_discard > 0) in st_lsm6dsx_read_fifo()
479 acc_sensor->samples_to_discard--; in st_lsm6dsx_read_fifo()
482 hw->iio_devs[ST_LSM6DSX_ID_ACC], in st_lsm6dsx_read_fifo()
483 &hw->scan[ST_LSM6DSX_ID_ACC], in st_lsm6dsx_read_fifo()
484 acc_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
485 acc_sip--; in st_lsm6dsx_read_fifo()
487 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { in st_lsm6dsx_read_fifo()
489 hw->iio_devs[ST_LSM6DSX_ID_EXT0], in st_lsm6dsx_read_fifo()
490 &hw->scan[ST_LSM6DSX_ID_EXT0], in st_lsm6dsx_read_fifo()
491 ext_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
492 ext_sip--; in st_lsm6dsx_read_fifo()
499 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_read_fifo()
501 dev_err(hw->dev, "failed to reset hw ts (err=%d)\n", in st_lsm6dsx_read_fifo()
511 st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, in st_lsm6dsx_push_tagged_data() argument
520 return -EINVAL; in st_lsm6dsx_push_tagged_data()
530 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO]; in st_lsm6dsx_push_tagged_data()
533 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC]; in st_lsm6dsx_push_tagged_data()
536 if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) in st_lsm6dsx_push_tagged_data()
537 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0]; in st_lsm6dsx_push_tagged_data()
538 else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)) in st_lsm6dsx_push_tagged_data()
539 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; in st_lsm6dsx_push_tagged_data()
541 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
544 if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) && in st_lsm6dsx_push_tagged_data()
545 (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))) in st_lsm6dsx_push_tagged_data()
546 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; in st_lsm6dsx_push_tagged_data()
548 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
551 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
554 return -EINVAL; in st_lsm6dsx_push_tagged_data()
559 ts + sensor->ts_ref); in st_lsm6dsx_push_tagged_data()
565 * st_lsm6dsx_read_tagged_fifo() - tagged hw FIFO read routine
566 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
568 * Read samples from the hw FIFO and push them to IIO buffers.
572 int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_read_tagged_fifo() argument
574 u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; in st_lsm6dsx_read_tagged_fifo()
589 err = st_lsm6dsx_read_locked(hw, in st_lsm6dsx_read_tagged_fifo()
590 hw->settings->fifo_ops.fifo_diff.addr, in st_lsm6dsx_read_tagged_fifo()
593 dev_err(hw->dev, "failed to read fifo status (err=%d)\n", in st_lsm6dsx_read_tagged_fifo()
598 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; in st_lsm6dsx_read_tagged_fifo()
605 err = st_lsm6dsx_read_block(hw, in st_lsm6dsx_read_tagged_fifo()
607 hw->buff, pattern_len, in st_lsm6dsx_read_tagged_fifo()
610 dev_err(hw->dev, in st_lsm6dsx_read_tagged_fifo()
618 memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE], in st_lsm6dsx_read_tagged_fifo()
621 tag = hw->buff[i] >> 3; in st_lsm6dsx_read_tagged_fifo()
624 * hw timestamp is 4B long and it is stored in st_lsm6dsx_read_tagged_fifo()
631 * check if hw timestamp engine is going to in st_lsm6dsx_read_tagged_fifo()
633 * to signal the hw timestamp will reset in in st_lsm6dsx_read_tagged_fifo()
638 ts *= hw->ts_gain; in st_lsm6dsx_read_tagged_fifo()
640 st_lsm6dsx_push_tagged_data(hw, tag, iio_buff, in st_lsm6dsx_read_tagged_fifo()
647 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_read_tagged_fifo()
654 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_flush_fifo() argument
658 if (!hw->settings->fifo_ops.read_fifo) in st_lsm6dsx_flush_fifo()
659 return -ENOTSUPP; in st_lsm6dsx_flush_fifo()
661 mutex_lock(&hw->fifo_lock); in st_lsm6dsx_flush_fifo()
663 hw->settings->fifo_ops.read_fifo(hw); in st_lsm6dsx_flush_fifo()
664 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS); in st_lsm6dsx_flush_fifo()
666 mutex_unlock(&hw->fifo_lock); in st_lsm6dsx_flush_fifo()
675 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_samples_to_discard() local
678 if (sensor->id != ST_LSM6DSX_ID_GYRO && in st_lsm6dsx_update_samples_to_discard()
679 sensor->id != ST_LSM6DSX_ID_ACC) in st_lsm6dsx_update_samples_to_discard()
682 /* check if drdy mask is supported in hw */ in st_lsm6dsx_update_samples_to_discard()
683 if (hw->settings->drdy_mask.addr) in st_lsm6dsx_update_samples_to_discard()
686 data = &hw->settings->samples_to_discard[sensor->id]; in st_lsm6dsx_update_samples_to_discard()
688 if (data->val[i].milli_hz == sensor->odr) { in st_lsm6dsx_update_samples_to_discard()
689 sensor->samples_to_discard = data->val[i].samples; in st_lsm6dsx_update_samples_to_discard()
697 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_fifo() local
701 mutex_lock(&hw->conf_lock); in st_lsm6dsx_update_fifo()
704 fifo_mask = hw->fifo_mask | BIT(sensor->id); in st_lsm6dsx_update_fifo()
706 fifo_mask = hw->fifo_mask & ~BIT(sensor->id); in st_lsm6dsx_update_fifo()
708 if (hw->fifo_mask) { in st_lsm6dsx_update_fifo()
709 err = st_lsm6dsx_flush_fifo(hw); in st_lsm6dsx_update_fifo()
725 err = st_lsm6dsx_update_decimators(hw); in st_lsm6dsx_update_fifo()
729 err = st_lsm6dsx_update_watermark(sensor, sensor->watermark); in st_lsm6dsx_update_fifo()
734 err = st_lsm6dsx_resume_fifo(hw); in st_lsm6dsx_update_fifo()
739 hw->fifo_mask = fifo_mask; in st_lsm6dsx_update_fifo()
742 mutex_unlock(&hw->conf_lock); in st_lsm6dsx_update_fifo()
750 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_buffer_preenable() local
752 if (!hw->settings->fifo_ops.update_fifo) in st_lsm6dsx_buffer_preenable()
753 return -ENOTSUPP; in st_lsm6dsx_buffer_preenable()
755 return hw->settings->fifo_ops.update_fifo(sensor, true); in st_lsm6dsx_buffer_preenable()
761 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_buffer_postdisable() local
763 if (!hw->settings->fifo_ops.update_fifo) in st_lsm6dsx_buffer_postdisable()
764 return -ENOTSUPP; in st_lsm6dsx_buffer_postdisable()
766 return hw->settings->fifo_ops.update_fifo(sensor, false); in st_lsm6dsx_buffer_postdisable()
774 int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_fifo_setup() argument
779 if (!hw->iio_devs[i]) in st_lsm6dsx_fifo_setup()
782 ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i], in st_lsm6dsx_fifo_setup()