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

1 // SPDX-License-Identifier: GPL-2.0-only
9 * - 1st data set is reserved for gyroscope data
10 * - 2nd data set is reserved for accelerometer data
18 * - ISM330DLC
19 * - LSM6DS3
20 * - LSM6DS3H
21 * - LSM6DS3TR-C
22 * - LSM6DSL
23 * - LSM6DSM
28 * source (gyroscope, accelerometer, hw timer).
31 * - ASM330LHB
32 * - ASM330LHH
33 * - ASM330LHHX
34 * - ASM330LHHXG1
35 * - ISM330DHCX
36 * - LSM6DSO
37 * - LSM6DSOP
38 * - LSM6DSOX
39 * - LSM6DSR
40 * - LSM6DSRX
41 * - LSM6DST
42 * - LSM6DSTX
43 * - LSM6DSV
46 * - BYPASS: FIFO disabled
47 * - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
108 u32 decimator = max_odr / sensor->odr; in st_lsm6dsx_get_decimator_val()
119 sensor->decimator = decimator; in st_lsm6dsx_get_decimator_val()
123 static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, in st_lsm6dsx_get_max_min_odr() argument
131 if (!hw->iio_devs[i]) in st_lsm6dsx_get_max_min_odr()
134 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_get_max_min_odr()
136 if (!(hw->enable_mask & BIT(sensor->id))) in st_lsm6dsx_get_max_min_odr()
139 *max_odr = max_t(u32, *max_odr, sensor->odr); in st_lsm6dsx_get_max_min_odr()
140 *min_odr = min_t(u32, *min_odr, sensor->odr); in st_lsm6dsx_get_max_min_odr()
146 u8 sip = sensor->odr / min_odr; in st_lsm6dsx_get_sip()
151 static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_update_decimators() argument
160 st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr); in st_lsm6dsx_update_decimators()
165 if (!hw->iio_devs[i]) in st_lsm6dsx_update_decimators()
168 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_update_decimators()
170 if (hw->enable_mask & BIT(sensor->id)) { in st_lsm6dsx_update_decimators()
171 sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr); in st_lsm6dsx_update_decimators()
174 sensor->sip = 0; in st_lsm6dsx_update_decimators()
177 ts_sip = max_t(u16, ts_sip, sensor->sip); in st_lsm6dsx_update_decimators()
179 dec_reg = &hw->settings->decimator[sensor->id]; in st_lsm6dsx_update_decimators()
180 if (dec_reg->addr) { in st_lsm6dsx_update_decimators()
181 int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask); in st_lsm6dsx_update_decimators()
183 err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr, in st_lsm6dsx_update_decimators()
184 dec_reg->mask, in st_lsm6dsx_update_decimators()
189 sip += sensor->sip; in st_lsm6dsx_update_decimators()
191 hw->sip = sip + ts_sip; in st_lsm6dsx_update_decimators()
192 hw->ts_sip = ts_sip; in st_lsm6dsx_update_decimators()
195 * update hw ts decimator if necessary. Decimator for hw timestamp in st_lsm6dsx_update_decimators()
199 ts_dec_reg = &hw->settings->ts_settings.decimator; in st_lsm6dsx_update_decimators()
200 if (ts_dec_reg->addr) { in st_lsm6dsx_update_decimators()
201 int val, ts_dec = !!hw->ts_sip; in st_lsm6dsx_update_decimators()
203 val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask); in st_lsm6dsx_update_decimators()
204 err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr, in st_lsm6dsx_update_decimators()
205 ts_dec_reg->mask, val); in st_lsm6dsx_update_decimators()
210 static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, in st_lsm6dsx_set_fifo_mode() argument
216 return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR, in st_lsm6dsx_set_fifo_mode()
223 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_set_fifo_odr() local
227 batch_reg = &hw->settings->batch[sensor->id]; in st_lsm6dsx_set_fifo_odr()
228 if (batch_reg->addr) { in st_lsm6dsx_set_fifo_odr()
234 err = st_lsm6dsx_check_odr(sensor, sensor->odr, in st_lsm6dsx_set_fifo_odr()
241 val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask); in st_lsm6dsx_set_fifo_odr()
242 return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr, in st_lsm6dsx_set_fifo_odr()
243 batch_reg->mask, val); in st_lsm6dsx_set_fifo_odr()
245 data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0; in st_lsm6dsx_set_fifo_odr()
246 return st_lsm6dsx_update_bits_locked(hw, in st_lsm6dsx_set_fifo_odr()
257 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_watermark() local
262 if (!hw->sip) in st_lsm6dsx_update_watermark()
266 if (!hw->iio_devs[i]) in st_lsm6dsx_update_watermark()
269 cur_sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_update_watermark()
271 if (!(hw->enable_mask & BIT(cur_sensor->id))) in st_lsm6dsx_update_watermark()
275 : cur_sensor->watermark; in st_lsm6dsx_update_watermark()
280 fifo_watermark = max_t(u16, fifo_watermark, hw->sip); in st_lsm6dsx_update_watermark()
281 fifo_watermark = (fifo_watermark / hw->sip) * hw->sip; in st_lsm6dsx_update_watermark()
282 fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; in st_lsm6dsx_update_watermark()
284 mutex_lock(&hw->page_lock); in st_lsm6dsx_update_watermark()
285 err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1, in st_lsm6dsx_update_watermark()
290 fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; in st_lsm6dsx_update_watermark()
295 err = regmap_bulk_write(hw->regmap, in st_lsm6dsx_update_watermark()
296 hw->settings->fifo_ops.fifo_th.addr, in st_lsm6dsx_update_watermark()
299 mutex_unlock(&hw->page_lock); in st_lsm6dsx_update_watermark()
303 static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_reset_hw_ts() argument
308 /* reset hw ts counter */ in st_lsm6dsx_reset_hw_ts()
309 err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR, in st_lsm6dsx_reset_hw_ts()
315 if (!hw->iio_devs[i]) in st_lsm6dsx_reset_hw_ts()
318 sensor = iio_priv(hw->iio_devs[i]); in st_lsm6dsx_reset_hw_ts()
321 * hw timestamp in st_lsm6dsx_reset_hw_ts()
323 sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]); in st_lsm6dsx_reset_hw_ts()
328 int st_lsm6dsx_resume_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_resume_fifo() argument
332 /* reset hw ts counter */ in st_lsm6dsx_resume_fifo()
333 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_resume_fifo()
337 return st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); in st_lsm6dsx_resume_fifo()
344 static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr, in st_lsm6dsx_read_block() argument
352 word_len = min_t(unsigned int, data_len - read_len, in st_lsm6dsx_read_block()
354 err = st_lsm6dsx_read_locked(hw, addr, data + read_len, in st_lsm6dsx_read_block()
366 * st_lsm6dsx_read_fifo() - hw FIFO read routine
367 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
369 * Read samples from the hw FIFO and push them to IIO buffers.
373 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_read_fifo() argument
377 u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; in st_lsm6dsx_read_fifo()
378 u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; in st_lsm6dsx_read_fifo()
383 err = st_lsm6dsx_read_locked(hw, in st_lsm6dsx_read_fifo()
384 hw->settings->fifo_ops.fifo_diff.addr, in st_lsm6dsx_read_fifo()
387 dev_err(hw->dev, "failed to read fifo status (err=%d)\n", in st_lsm6dsx_read_fifo()
399 acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); in st_lsm6dsx_read_fifo()
400 gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]); in st_lsm6dsx_read_fifo()
401 if (hw->iio_devs[ST_LSM6DSX_ID_EXT0]) in st_lsm6dsx_read_fifo()
402 ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]); in st_lsm6dsx_read_fifo()
405 err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR, in st_lsm6dsx_read_fifo()
406 hw->buff, pattern_len, in st_lsm6dsx_read_fifo()
409 dev_err(hw->dev, in st_lsm6dsx_read_fifo()
425 * - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz in st_lsm6dsx_read_fifo()
428 * - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, .. in st_lsm6dsx_read_fifo()
430 ext_sip = ext_sensor ? ext_sensor->sip : 0; in st_lsm6dsx_read_fifo()
431 gyro_sip = gyro_sensor->sip; in st_lsm6dsx_read_fifo()
432 acc_sip = acc_sensor->sip; in st_lsm6dsx_read_fifo()
433 ts_sip = hw->ts_sip; in st_lsm6dsx_read_fifo()
438 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { in st_lsm6dsx_read_fifo()
439 memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, in st_lsm6dsx_read_fifo()
440 &hw->buff[offset], in st_lsm6dsx_read_fifo()
441 sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); in st_lsm6dsx_read_fifo()
442 offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); in st_lsm6dsx_read_fifo()
444 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { in st_lsm6dsx_read_fifo()
445 memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, in st_lsm6dsx_read_fifo()
446 &hw->buff[offset], in st_lsm6dsx_read_fifo()
447 sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); in st_lsm6dsx_read_fifo()
448 offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); in st_lsm6dsx_read_fifo()
450 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { in st_lsm6dsx_read_fifo()
451 memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, in st_lsm6dsx_read_fifo()
452 &hw->buff[offset], in st_lsm6dsx_read_fifo()
453 sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); in st_lsm6dsx_read_fifo()
454 offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); in st_lsm6dsx_read_fifo()
457 if (ts_sip-- > 0) { in st_lsm6dsx_read_fifo()
460 memcpy(data, &hw->buff[offset], sizeof(data)); in st_lsm6dsx_read_fifo()
462 * hw timestamp is 3B long and it is stored in st_lsm6dsx_read_fifo()
469 * check if hw timestamp engine is going to in st_lsm6dsx_read_fifo()
471 * to signal the hw timestamp will reset in in st_lsm6dsx_read_fifo()
476 ts *= hw->ts_gain; in st_lsm6dsx_read_fifo()
481 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { in st_lsm6dsx_read_fifo()
486 if (gyro_sensor->samples_to_discard > 0) in st_lsm6dsx_read_fifo()
487 gyro_sensor->samples_to_discard--; in st_lsm6dsx_read_fifo()
490 hw->iio_devs[ST_LSM6DSX_ID_GYRO], in st_lsm6dsx_read_fifo()
491 &hw->scan[ST_LSM6DSX_ID_GYRO], in st_lsm6dsx_read_fifo()
492 gyro_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
493 gyro_sip--; in st_lsm6dsx_read_fifo()
495 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { in st_lsm6dsx_read_fifo()
500 if (acc_sensor->samples_to_discard > 0) in st_lsm6dsx_read_fifo()
501 acc_sensor->samples_to_discard--; in st_lsm6dsx_read_fifo()
504 hw->iio_devs[ST_LSM6DSX_ID_ACC], in st_lsm6dsx_read_fifo()
505 &hw->scan[ST_LSM6DSX_ID_ACC], in st_lsm6dsx_read_fifo()
506 acc_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
507 acc_sip--; in st_lsm6dsx_read_fifo()
509 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { in st_lsm6dsx_read_fifo()
511 hw->iio_devs[ST_LSM6DSX_ID_EXT0], in st_lsm6dsx_read_fifo()
512 &hw->scan[ST_LSM6DSX_ID_EXT0], in st_lsm6dsx_read_fifo()
513 ext_sensor->ts_ref + ts); in st_lsm6dsx_read_fifo()
514 ext_sip--; in st_lsm6dsx_read_fifo()
521 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_read_fifo()
523 dev_err(hw->dev, "failed to reset hw ts (err=%d)\n", in st_lsm6dsx_read_fifo()
533 st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, in st_lsm6dsx_push_tagged_data() argument
542 return -EINVAL; in st_lsm6dsx_push_tagged_data()
552 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO]; in st_lsm6dsx_push_tagged_data()
555 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC]; in st_lsm6dsx_push_tagged_data()
558 if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) in st_lsm6dsx_push_tagged_data()
559 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0]; in st_lsm6dsx_push_tagged_data()
560 else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)) in st_lsm6dsx_push_tagged_data()
561 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; in st_lsm6dsx_push_tagged_data()
563 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
566 if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) && in st_lsm6dsx_push_tagged_data()
567 (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))) in st_lsm6dsx_push_tagged_data()
568 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; in st_lsm6dsx_push_tagged_data()
570 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
573 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; in st_lsm6dsx_push_tagged_data()
576 return -EINVAL; in st_lsm6dsx_push_tagged_data()
581 ts + sensor->ts_ref); in st_lsm6dsx_push_tagged_data()
587 * st_lsm6dsx_read_tagged_fifo() - tagged hw FIFO read routine
588 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
590 * Read samples from the hw FIFO and push them to IIO buffers.
594 int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_read_tagged_fifo() argument
596 u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; in st_lsm6dsx_read_tagged_fifo()
611 err = st_lsm6dsx_read_locked(hw, in st_lsm6dsx_read_tagged_fifo()
612 hw->settings->fifo_ops.fifo_diff.addr, in st_lsm6dsx_read_tagged_fifo()
615 dev_err(hw->dev, "failed to read fifo status (err=%d)\n", in st_lsm6dsx_read_tagged_fifo()
620 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; in st_lsm6dsx_read_tagged_fifo()
627 err = st_lsm6dsx_read_block(hw, in st_lsm6dsx_read_tagged_fifo()
629 hw->buff, pattern_len, in st_lsm6dsx_read_tagged_fifo()
632 dev_err(hw->dev, in st_lsm6dsx_read_tagged_fifo()
640 memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE], in st_lsm6dsx_read_tagged_fifo()
643 tag = hw->buff[i] >> 3; in st_lsm6dsx_read_tagged_fifo()
646 * hw timestamp is 4B long and it is stored in st_lsm6dsx_read_tagged_fifo()
653 * check if hw timestamp engine is going to in st_lsm6dsx_read_tagged_fifo()
655 * to signal the hw timestamp will reset in in st_lsm6dsx_read_tagged_fifo()
660 ts *= hw->ts_gain; in st_lsm6dsx_read_tagged_fifo()
662 st_lsm6dsx_push_tagged_data(hw, tag, iio_buff, in st_lsm6dsx_read_tagged_fifo()
669 err = st_lsm6dsx_reset_hw_ts(hw); in st_lsm6dsx_read_tagged_fifo()
676 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_flush_fifo() argument
680 if (!hw->settings->fifo_ops.read_fifo) in st_lsm6dsx_flush_fifo()
681 return -ENOTSUPP; in st_lsm6dsx_flush_fifo()
683 mutex_lock(&hw->fifo_lock); in st_lsm6dsx_flush_fifo()
685 hw->settings->fifo_ops.read_fifo(hw); in st_lsm6dsx_flush_fifo()
686 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS); in st_lsm6dsx_flush_fifo()
688 mutex_unlock(&hw->fifo_lock); in st_lsm6dsx_flush_fifo()
697 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_samples_to_discard() local
700 if (sensor->id != ST_LSM6DSX_ID_GYRO && in st_lsm6dsx_update_samples_to_discard()
701 sensor->id != ST_LSM6DSX_ID_ACC) in st_lsm6dsx_update_samples_to_discard()
704 /* check if drdy mask is supported in hw */ in st_lsm6dsx_update_samples_to_discard()
705 if (hw->settings->drdy_mask.addr) in st_lsm6dsx_update_samples_to_discard()
708 data = &hw->settings->samples_to_discard[sensor->id]; in st_lsm6dsx_update_samples_to_discard()
710 if (data->val[i].milli_hz == sensor->odr) { in st_lsm6dsx_update_samples_to_discard()
711 sensor->samples_to_discard = data->val[i].samples; in st_lsm6dsx_update_samples_to_discard()
719 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_update_fifo() local
723 mutex_lock(&hw->conf_lock); in st_lsm6dsx_update_fifo()
726 fifo_mask = hw->fifo_mask | BIT(sensor->id); in st_lsm6dsx_update_fifo()
728 fifo_mask = hw->fifo_mask & ~BIT(sensor->id); in st_lsm6dsx_update_fifo()
730 if (hw->fifo_mask) { in st_lsm6dsx_update_fifo()
731 err = st_lsm6dsx_flush_fifo(hw); in st_lsm6dsx_update_fifo()
747 err = st_lsm6dsx_update_decimators(hw); in st_lsm6dsx_update_fifo()
751 err = st_lsm6dsx_update_watermark(sensor, sensor->watermark); in st_lsm6dsx_update_fifo()
756 err = st_lsm6dsx_resume_fifo(hw); in st_lsm6dsx_update_fifo()
761 hw->fifo_mask = fifo_mask; in st_lsm6dsx_update_fifo()
764 mutex_unlock(&hw->conf_lock); in st_lsm6dsx_update_fifo()
772 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_buffer_preenable() local
774 if (!hw->settings->fifo_ops.update_fifo) in st_lsm6dsx_buffer_preenable()
775 return -ENOTSUPP; in st_lsm6dsx_buffer_preenable()
777 return hw->settings->fifo_ops.update_fifo(sensor, true); in st_lsm6dsx_buffer_preenable()
783 struct st_lsm6dsx_hw *hw = sensor->hw; in st_lsm6dsx_buffer_postdisable() local
785 if (!hw->settings->fifo_ops.update_fifo) in st_lsm6dsx_buffer_postdisable()
786 return -ENOTSUPP; in st_lsm6dsx_buffer_postdisable()
788 return hw->settings->fifo_ops.update_fifo(sensor, false); in st_lsm6dsx_buffer_postdisable()
796 int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) in st_lsm6dsx_fifo_setup() argument
801 if (!hw->iio_devs[i]) in st_lsm6dsx_fifo_setup()
804 ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i], in st_lsm6dsx_fifo_setup()