Re: [PATCH] iio: imu: st_lsm6dsx: add hw timestamp support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> On Sun, 14 Jan 2018 12:51:57 +0100
> Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx> wrote:
>
>> > On Sat, 13 Jan 2018 18:57:56 +0100
>> > Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx> wrote:
>> >
>> >> Introduce hw timestamp support instead of compute sample timestamps
>> >> according to interrupt rate and configured watermark. LSM6DSx based
>> >> devices are able to queue in hw FIFO the time reference of data
>> >> sampling
>> >>
>> >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx>
>> >
>> > I am curious, how good is the clock?  Do you see significant jumps when
>> > the timer reset happens and you rebase on the cpu timestamp?
>>
>> At the moment I do not have an answer to that question but I can carry
>> out some tests :)
>>
>> >
>> > The patch looks good to me, but I'd like to let it sit on the list
>> > a little longer given its more or less a new feature to IIO.
>> >
>>
>> Sure, fine for me
> Long enough.  Applied to the togreg branch of iio.git and pushed out
> as testing for the autobuilders to play with it.
>

-ETIMEDOUT :-)

Regards,
Lorenzo

> Thanks,
>
> Jonathan
>
>> Regards,
>>
>> Lorenzo
>>
>> > Jonathan
>> >> ---
>> >>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h        |  29 +++--
>> >>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 161 ++++++++++++++++---------
>> >>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c   | 104 +++++++++++++++-
>> >>  3 files changed, 224 insertions(+), 70 deletions(-)
>> >>
>> >> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> >> index 8fdd723afa05..a3cc7cd97026 100644
>> >> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> >> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> >> @@ -27,7 +27,7 @@ enum st_lsm6dsx_hw_id {
>> >>       ST_LSM6DSX_MAX_ID,
>> >>  };
>> >>
>> >> -#define ST_LSM6DSX_BUFF_SIZE         256
>> >> +#define ST_LSM6DSX_BUFF_SIZE         400
>> >>  #define ST_LSM6DSX_CHAN_SIZE         2
>> >>  #define ST_LSM6DSX_SAMPLE_SIZE               6
>> >>  #define ST_LSM6DSX_MAX_WORD_LEN              ((32 / ST_LSM6DSX_SAMPLE_SIZE) * \
>> >> @@ -57,6 +57,20 @@ struct st_lsm6dsx_fifo_ops {
>> >>       u8 th_wl;
>> >>  };
>> >>
>> >> +/**
>> >> + * struct st_lsm6dsx_hw_ts_settings - ST IMU hw timer settings
>> >> + * @timer_en: Hw timer enable register info (addr + mask).
>> >> + * @hr_timer: Hw timer resolution register info (addr + mask).
>> >> + * @fifo_en: Hw timer FIFO enable register info (addr + mask).
>> >> + * @decimator: Hw timer FIFO decimator register info (addr + mask).
>> >> + */
>> >> +struct st_lsm6dsx_hw_ts_settings {
>> >> +     struct st_lsm6dsx_reg timer_en;
>> >> +     struct st_lsm6dsx_reg hr_timer;
>> >> +     struct st_lsm6dsx_reg fifo_en;
>> >> +     struct st_lsm6dsx_reg decimator;
>> >> +};
>> >> +
>> >>  /**
>> >>   * struct st_lsm6dsx_settings - ST IMU sensor settings
>> >>   * @wai: Sensor WhoAmI default value.
>> >> @@ -64,6 +78,7 @@ struct st_lsm6dsx_fifo_ops {
>> >>   * @id: List of hw id supported by the driver configuration.
>> >>   * @decimator: List of decimator register info (addr + mask).
>> >>   * @fifo_ops: Sensor hw FIFO parameters.
>> >> + * @ts_settings: Hw timer related settings.
>> >>   */
>> >>  struct st_lsm6dsx_settings {
>> >>       u8 wai;
>> >> @@ -71,6 +86,7 @@ struct st_lsm6dsx_settings {
>> >>       enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID];
>> >>       struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
>> >>       struct st_lsm6dsx_fifo_ops fifo_ops;
>> >> +     struct st_lsm6dsx_hw_ts_settings ts_settings;
>> >>  };
>> >>
>> >>  enum st_lsm6dsx_sensor_id {
>> >> @@ -94,8 +110,7 @@ enum st_lsm6dsx_fifo_mode {
>> >>   * @watermark: Sensor watermark level.
>> >>   * @sip: Number of samples in a given pattern.
>> >>   * @decimator: FIFO decimation factor.
>> >> - * @delta_ts: Delta time between two consecutive interrupts.
>> >> - * @ts: Latest timestamp from the interrupt handler.
>> >> + * @ts_ref: Sensor timestamp reference for hw one.
>> >>   */
>> >>  struct st_lsm6dsx_sensor {
>> >>       char name[32];
>> >> @@ -108,9 +123,7 @@ struct st_lsm6dsx_sensor {
>> >>       u16 watermark;
>> >>       u8 sip;
>> >>       u8 decimator;
>> >> -
>> >> -     s64 delta_ts;
>> >> -     s64 ts;
>> >> +     s64 ts_ref;
>> >>  };
>> >>
>> >>  /**
>> >> @@ -122,7 +135,8 @@ struct st_lsm6dsx_sensor {
>> >>   * @conf_lock: Mutex to prevent concurrent FIFO configuration update.
>> >>   * @fifo_mode: FIFO operating mode supported by the device.
>> >>   * @enable_mask: Enabled sensor bitmask.
>> >> - * @sip: Total number of samples (acc/gyro) in a given pattern.
>> >> + * @ts_sip: Total number of timestamp samples in a given pattern.
>> >> + * @sip: Total number of samples (acc/gyro/ts) in a given pattern.
>> >>   * @buff: Device read buffer.
>> >>   * @iio_devs: Pointers to acc/gyro iio_dev instances.
>> >>   * @settings: Pointer to the specific sensor settings in use.
>> >> @@ -137,6 +151,7 @@ struct st_lsm6dsx_hw {
>> >>
>> >>       enum st_lsm6dsx_fifo_mode fifo_mode;
>> >>       u8 enable_mask;
>> >> +     u8 ts_sip;
>> >>       u8 sip;
>> >>
>> >>       u8 *buff;
>> >> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> >> index 1d6aa9b1a4cf..1045e025e92b 100644
>> >> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> >> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> >> @@ -46,9 +46,13 @@
>> >>  #define ST_LSM6DSX_FIFO_ODR_MASK             GENMASK(6, 3)
>> >>  #define ST_LSM6DSX_FIFO_EMPTY_MASK           BIT(12)
>> >>  #define ST_LSM6DSX_REG_FIFO_OUTL_ADDR                0x3e
>> >> +#define ST_LSM6DSX_REG_TS_RESET_ADDR         0x42
>> >>
>> >>  #define ST_LSM6DSX_MAX_FIFO_ODR_VAL          0x08
>> >>
>> >> +#define ST_LSM6DSX_TS_SENSITIVITY            25000UL /* 25us */
>> >> +#define ST_LSM6DSX_TS_RESET_VAL                      0xaa
>> >> +
>> >>  struct st_lsm6dsx_decimator_entry {
>> >>       u8 decimator;
>> >>       u8 val;
>> >> @@ -98,9 +102,10 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
>> >>
>> >>  static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
>> >>  {
>> >> +     u16 max_odr, min_odr, sip = 0, ts_sip = 0;
>> >> +     const struct st_lsm6dsx_reg *ts_dec_reg;
>> >>       struct st_lsm6dsx_sensor *sensor;
>> >> -     u16 max_odr, min_odr, sip = 0;
>> >> -     int err, i;
>> >> +     int err = 0, i;
>> >>       u8 data;
>> >>
>> >>       st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
>> >> @@ -119,6 +124,7 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
>> >>                       sensor->decimator = 0;
>> >>                       data = 0;
>> >>               }
>> >> +             ts_sip = max_t(u16, ts_sip, sensor->sip);
>> >>
>> >>               dec_reg = &hw->settings->decimator[sensor->id];
>> >>               if (dec_reg->addr) {
>> >> @@ -131,9 +137,23 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
>> >>               }
>> >>               sip += sensor->sip;
>> >>       }
>> >> -     hw->sip = sip;
>> >> +     hw->sip = sip + ts_sip;
>> >> +     hw->ts_sip = ts_sip;
>> >>
>> >> -     return 0;
>> >> +     /*
>> >> +      * update hw ts decimator if necessary. Decimator for hw timestamp
>> >> +      * is always 1 or 0 in order to have a ts sample for each data
>> >> +      * sample in FIFO
>> >> +      */
>> >> +     ts_dec_reg = &hw->settings->ts_settings.decimator;
>> >> +     if (ts_dec_reg->addr) {
>> >> +             int val, ts_dec = !!hw->ts_sip;
>> >> +
>> >> +             val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask);
>> >> +             err = regmap_update_bits(hw->regmap, ts_dec_reg->addr,
>> >> +                                      ts_dec_reg->mask, val);
>> >> +     }
>> >> +     return err;
>> >>  }
>> >>
>> >>  int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
>> >> @@ -208,6 +228,28 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
>> >>                                &wdata, sizeof(wdata));
>> >>  }
>> >>
>> >> +static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)
>> >> +{
>> >> +     struct st_lsm6dsx_sensor *sensor;
>> >> +     int i, err;
>> >> +
>> >> +     /* reset hw ts counter */
>> >> +     err = regmap_write(hw->regmap, ST_LSM6DSX_REG_TS_RESET_ADDR,
>> >> +                        ST_LSM6DSX_TS_RESET_VAL);
>> >> +     if (err < 0)
>> >> +             return err;
>> >> +
>> >> +     for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
>> >> +             sensor = iio_priv(hw->iio_devs[i]);
>> >> +             /*
>> >> +              * store enable buffer timestamp as reference for
>> >> +              * hw timestamp
>> >> +              */
>> >> +             sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]);
>> >> +     }
>> >> +     return 0;
>> >> +}
>> >> +
>> >>  /*
>> >>   * Set max bulk read to ST_LSM6DSX_MAX_WORD_LEN in order to avoid
>> >>   * a kmalloc for each bus access
>> >> @@ -231,6 +273,8 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 *data,
>> >>       return 0;
>> >>  }
>> >>
>> >> +#define ST_LSM6DSX_IIO_BUFF_SIZE     (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \
>> >> +                                            sizeof(s64)) + sizeof(s64))
>> >>  /**
>> >>   * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DS3H-LSM6DSL-LSM6DSM read FIFO routine
>> >>   * @hw: Pointer to instance of struct st_lsm6dsx_hw.
>> >> @@ -243,11 +287,13 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> >>  {
>> >>       u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
>> >>       u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
>> >> -     int err, acc_sip, gyro_sip, read_len, samples, offset;
>> >> +     int err, acc_sip, gyro_sip, ts_sip, read_len, offset;
>> >>       struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
>> >> -     s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts;
>> >> -     u8 iio_buff[ALIGN(ST_LSM6DSX_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)];
>> >> +     u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
>> >> +     u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
>> >> +     bool reset_ts = false;
>> >>       __le16 fifo_status;
>> >> +     s64 ts = 0;
>> >>
>> >>       err = regmap_bulk_read(hw->regmap,
>> >>                              hw->settings->fifo_ops.fifo_diff.addr,
>> >> @@ -260,23 +306,10 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> >>
>> >>       fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
>> >>                  ST_LSM6DSX_CHAN_SIZE;
>> >> -     samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE;
>> >>       fifo_len = (fifo_len / pattern_len) * pattern_len;
>> >>
>> >> -     /*
>> >> -      * compute delta timestamp between two consecutive samples
>> >> -      * in order to estimate queueing time of data generated
>> >> -      * by the sensor
>> >> -      */
>> >>       acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
>> >> -     acc_ts = acc_sensor->ts - acc_sensor->delta_ts;
>> >> -     acc_delta_ts = div_s64(acc_sensor->delta_ts * acc_sensor->decimator,
>> >> -                            samples);
>> >> -
>> >>       gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
>> >> -     gyro_ts = gyro_sensor->ts - gyro_sensor->delta_ts;
>> >> -     gyro_delta_ts = div_s64(gyro_sensor->delta_ts * gyro_sensor->decimator,
>> >> -                             samples);
>> >>
>> >>       for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
>> >>               err = st_lsm6dsx_read_block(hw, hw->buff, pattern_len);
>> >> @@ -287,7 +320,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> >>                * Data are written to the FIFO with a specific pattern
>> >>                * depending on the configured ODRs. The first sequence of data
>> >>                * stored in FIFO contains the data of all enabled sensors
>> >> -              * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated
>> >> +              * (e.g. Gx, Gy, Gz, Ax, Ay, Az, Ts), then data are repeated
>> >>                * depending on the value of the decimation factor set for each
>> >>                * sensor.
>> >>                *
>> >> @@ -296,35 +329,65 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> >>                *   - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz
>> >>                * Since the gyroscope ODR is twice the accelerometer one, the
>> >>                * following pattern is repeated every 9 samples:
>> >> -              *   - Gx, Gy, Gz, Ax, Ay, Az, Gx, Gy, Gz
>> >> +              *   - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, ..
>> >>                */
>> >>               gyro_sip = gyro_sensor->sip;
>> >>               acc_sip = acc_sensor->sip;
>> >> +             ts_sip = hw->ts_sip;
>> >>               offset = 0;
>> >>
>> >>               while (acc_sip > 0 || gyro_sip > 0) {
>> >> -                     if (gyro_sip-- > 0) {
>> >> -                             memcpy(iio_buff, &hw->buff[offset],
>> >> +                     if (gyro_sip > 0) {
>> >> +                             memcpy(gyro_buff, &hw->buff[offset],
>> >>                                      ST_LSM6DSX_SAMPLE_SIZE);
>> >> -                             iio_push_to_buffers_with_timestamp(
>> >> -                                     hw->iio_devs[ST_LSM6DSX_ID_GYRO],
>> >> -                                     iio_buff, gyro_ts);
>> >>                               offset += ST_LSM6DSX_SAMPLE_SIZE;
>> >> -                             gyro_ts += gyro_delta_ts;
>> >>                       }
>> >> -
>> >> -                     if (acc_sip-- > 0) {
>> >> -                             memcpy(iio_buff, &hw->buff[offset],
>> >> +                     if (acc_sip > 0) {
>> >> +                             memcpy(acc_buff, &hw->buff[offset],
>> >>                                      ST_LSM6DSX_SAMPLE_SIZE);
>> >> -                             iio_push_to_buffers_with_timestamp(
>> >> -                                     hw->iio_devs[ST_LSM6DSX_ID_ACC],
>> >> -                                     iio_buff, acc_ts);
>> >>                               offset += ST_LSM6DSX_SAMPLE_SIZE;
>> >> -                             acc_ts += acc_delta_ts;
>> >>                       }
>> >> +
>> >> +                     if (ts_sip-- > 0) {
>> >> +                             u8 data[ST_LSM6DSX_SAMPLE_SIZE];
>> >> +
>> >> +                             memcpy(data, &hw->buff[offset], sizeof(data));
>> >> +                             /*
>> >> +                              * hw timestamp is 3B long and it is stored
>> >> +                              * in FIFO using 6B as 4th FIFO data set
>> >> +                              * according to this schema:
>> >> +                              * B0 = ts[15:8], B1 = ts[23:16], B3 = ts[7:0]
>> >> +                              */
>> >> +                             ts = data[1] << 16 | data[0] << 8 | data[3];
>> >> +                             /*
>> >> +                              * check if hw timestamp engine is going to
>> >> +                              * reset (the sensor generates an interrupt
>> >> +                              * to signal the hw timestamp will reset in
>> >> +                              * 1.638s)
>> >> +                              */
>> >> +                             if (!reset_ts && ts >= 0xff0000)
>> >> +                                     reset_ts = true;
>> >> +                             ts *= ST_LSM6DSX_TS_SENSITIVITY;
>> >> +
>> >> +                             offset += ST_LSM6DSX_SAMPLE_SIZE;
>> >> +                     }
>> >> +
>> >> +                     if (gyro_sip-- > 0)
>> >> +                             iio_push_to_buffers_with_timestamp(
>> >> +                                     hw->iio_devs[ST_LSM6DSX_ID_GYRO],
>> >> +                                     gyro_buff, gyro_sensor->ts_ref + ts);
>> >> +                     if (acc_sip-- > 0)
>> >> +                             iio_push_to_buffers_with_timestamp(
>> >> +                                     hw->iio_devs[ST_LSM6DSX_ID_ACC],
>> >> +                                     acc_buff, acc_sensor->ts_ref + ts);
>> >>               }
>> >>       }
>> >>
>> >> +     if (unlikely(reset_ts)) {
>> >> +             err = st_lsm6dsx_reset_hw_ts(hw);
>> >> +             if (err < 0)
>> >> +                     return err;
>> >> +     }
>> >>       return read_len;
>> >>  }
>> >>
>> >> @@ -379,15 +442,12 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
>> >>               goto out;
>> >>
>> >>       if (hw->enable_mask) {
>> >> -             err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
>> >> +             /* reset hw ts counter */
>> >> +             err = st_lsm6dsx_reset_hw_ts(hw);
>> >>               if (err < 0)
>> >>                       goto out;
>> >>
>> >> -             /*
>> >> -              * store enable buffer timestamp as reference to compute
>> >> -              * first delta timestamp
>> >> -              */
>> >> -             sensor->ts = iio_get_time_ns(iio_dev);
>> >> +             err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
>> >>       }
>> >>
>> >>  out:
>> >> @@ -399,25 +459,8 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
>> >>  static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
>> >>  {
>> >>       struct st_lsm6dsx_hw *hw = private;
>> >> -     struct st_lsm6dsx_sensor *sensor;
>> >> -     int i;
>> >> -
>> >> -     if (!hw->sip)
>> >> -             return IRQ_NONE;
>> >> -
>> >> -     for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
>> >> -             sensor = iio_priv(hw->iio_devs[i]);
>> >> -
>> >> -             if (sensor->sip > 0) {
>> >> -                     s64 timestamp;
>> >> -
>> >> -                     timestamp = iio_get_time_ns(hw->iio_devs[i]);
>> >> -                     sensor->delta_ts = timestamp - sensor->ts;
>> >> -                     sensor->ts = timestamp;
>> >> -             }
>> >> -     }
>> >>
>> >> -     return IRQ_WAKE_THREAD;
>> >> +     return hw->sip > 0 ? IRQ_WAKE_THREAD : IRQ_NONE;
>> >>  }
>> >>
>> >>  static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
>> >> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> >> index c2fa3239b9c6..8656d72ef4ee 100644
>> >> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> >> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> >> @@ -181,6 +181,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
>> >>                       },
>> >>                       .th_wl = 3, /* 1LSB = 2B */
>> >>               },
>> >> +             .ts_settings = {
>> >> +                     .timer_en = {
>> >> +                             .addr = 0x58,
>> >> +                             .mask = BIT(7),
>> >> +                     },
>> >> +                     .hr_timer = {
>> >> +                             .addr = 0x5c,
>> >> +                             .mask = BIT(4),
>> >> +                     },
>> >> +                     .fifo_en = {
>> >> +                             .addr = 0x07,
>> >> +                             .mask = BIT(7),
>> >> +                     },
>> >> +                     .decimator = {
>> >> +                             .addr = 0x09,
>> >> +                             .mask = GENMASK(5, 3),
>> >> +                     },
>> >> +             },
>> >>       },
>> >>       {
>> >>               .wai = 0x69,
>> >> @@ -209,6 +227,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
>> >>                       },
>> >>                       .th_wl = 3, /* 1LSB = 2B */
>> >>               },
>> >> +             .ts_settings = {
>> >> +                     .timer_en = {
>> >> +                             .addr = 0x58,
>> >> +                             .mask = BIT(7),
>> >> +                     },
>> >> +                     .hr_timer = {
>> >> +                             .addr = 0x5c,
>> >> +                             .mask = BIT(4),
>> >> +                     },
>> >> +                     .fifo_en = {
>> >> +                             .addr = 0x07,
>> >> +                             .mask = BIT(7),
>> >> +                     },
>> >> +                     .decimator = {
>> >> +                             .addr = 0x09,
>> >> +                             .mask = GENMASK(5, 3),
>> >> +                     },
>> >> +             },
>> >>       },
>> >>       {
>> >>               .wai = 0x6a,
>> >> @@ -238,6 +274,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
>> >>                       },
>> >>                       .th_wl = 3, /* 1LSB = 2B */
>> >>               },
>> >> +             .ts_settings = {
>> >> +                     .timer_en = {
>> >> +                             .addr = 0x19,
>> >> +                             .mask = BIT(5),
>> >> +                     },
>> >> +                     .hr_timer = {
>> >> +                             .addr = 0x5c,
>> >> +                             .mask = BIT(4),
>> >> +                     },
>> >> +                     .fifo_en = {
>> >> +                             .addr = 0x07,
>> >> +                             .mask = BIT(7),
>> >> +                     },
>> >> +                     .decimator = {
>> >> +                             .addr = 0x09,
>> >> +                             .mask = GENMASK(5, 3),
>> >> +                     },
>> >> +             },
>> >>       },
>> >>  };
>> >>
>> >> @@ -630,6 +684,44 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
>> >>       return err;
>> >>  }
>> >>
>> >> +static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
>> >> +{
>> >> +     const struct st_lsm6dsx_hw_ts_settings *ts_settings;
>> >> +     int err, val;
>> >> +
>> >> +     ts_settings = &hw->settings->ts_settings;
>> >> +     /* enable hw timestamp generation if necessary */
>> >> +     if (ts_settings->timer_en.addr) {
>> >> +             val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
>> >> +             err = regmap_update_bits(hw->regmap,
>> >> +                                      ts_settings->timer_en.addr,
>> >> +                                      ts_settings->timer_en.mask, val);
>> >> +             if (err < 0)
>> >> +                     return err;
>> >> +     }
>> >> +
>> >> +     /* enable high resolution for hw ts timer if necessary */
>> >> +     if (ts_settings->hr_timer.addr) {
>> >> +             val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
>> >> +             err = regmap_update_bits(hw->regmap,
>> >> +                                      ts_settings->hr_timer.addr,
>> >> +                                      ts_settings->hr_timer.mask, val);
>> >> +             if (err < 0)
>> >> +                     return err;
>> >> +     }
>> >> +
>> >> +     /* enable ts queueing in FIFO if necessary */
>> >> +     if (ts_settings->fifo_en.addr) {
>> >> +             val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
>> >> +             err = regmap_update_bits(hw->regmap,
>> >> +                                      ts_settings->fifo_en.addr,
>> >> +                                      ts_settings->fifo_en.mask, val);
>> >> +             if (err < 0)
>> >> +                     return err;
>> >> +     }
>> >> +     return 0;
>> >> +}
>> >> +
>> >>  static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
>> >>  {
>> >>       u8 drdy_int_reg;
>> >> @@ -654,10 +746,14 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
>> >>       if (err < 0)
>> >>               return err;
>> >>
>> >> -     return regmap_update_bits(hw->regmap, drdy_int_reg,
>> >> -                               ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
>> >> -                               FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
>> >> -                                          1));
>> >> +     err = regmap_update_bits(hw->regmap, drdy_int_reg,
>> >> +                              ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
>> >> +                              FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
>> >> +                                         1));
>> >> +     if (err < 0)
>> >> +             return err;
>> >> +
>> >> +     return st_lsm6dsx_init_hw_timer(hw);
>> >>  }
>> >>
>> >>  static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
>> >
>
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux