[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190727184844.307255a2@archlinux>
Date: Sat, 27 Jul 2019 18:48:44 +0100
From: Jonathan Cameron <jic23@...nel.org>
To: Martin Kepplinger <martin.kepplinger@...i.sm>
Cc: lorenzo.bianconi83@...il.com, knaack.h@....de, lars@...afoo.de,
pmeerw@...erw.net, linux-iio@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 4/5] iio: imu: st_lsm6dsx: add support for accel/gyro
unit of lsm9sd1
On Thu, 25 Jul 2019 07:31:31 +0200
Martin Kepplinger <martin.kepplinger@...i.sm> wrote:
> The LSM9DS1's accelerometer / gyroscope unit and it's magnetometer (separately
> supported in iio/magnetometer/st_magn*) are located on a separate i2c addresses
> on the bus.
>
> For the datasheet, see https://www.st.com/resource/en/datasheet/lsm9ds1.pdf
>
> Treat it just like the LSM6* devices and, despite it's name, hook it up
> to the st_lsm6dsx driver, using it's basic functionality.
>
> Signed-off-by: Martin Kepplinger <martin.kepplinger@...i.sm>
I'm a little confused on this hardware.
How does buffered output work if these are independently clocked?
I took a quick look at the datasheet, and 'suspect' the answer is that
it runs at the gyro frequencies if both are enable. Is that right?
Code looks fine.
Jonathan
> ---
> drivers/iio/imu/st_lsm6dsx/Kconfig | 1 +
> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +
> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 94 +++++++++++++++++++-
> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 ++
> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 ++
> 5 files changed, 104 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig
> index 2d8b2e1edfce..4a57bfb3c12e 100644
> --- a/drivers/iio/imu/st_lsm6dsx/Kconfig
> +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig
> @@ -11,6 +11,7 @@ config IIO_ST_LSM6DSX
> Say yes here to build support for STMicroelectronics LSM6DSx imu
> sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
> ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c
> + and the accelerometer/gyroscope of lsm9ds1.
>
> To compile this driver as a module, choose M here: the module
> will be called st_lsm6dsx.
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> index 3c47f5d27d30..9a30cc717de2 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> @@ -23,6 +23,7 @@
> #define ST_LSM6DSOX_DEV_NAME "lsm6dsox"
> #define ST_LSM6DSR_DEV_NAME "lsm6dsr"
> #define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c"
> +#define ST_LSM9DS1_DEV_NAME "lsm9ds1"
>
> enum st_lsm6dsx_hw_id {
> ST_LSM6DS3_ID,
> @@ -35,6 +36,7 @@ enum st_lsm6dsx_hw_id {
> ST_LSM6DSOX_ID,
> ST_LSM6DSR_ID,
> ST_LSM6DS3TRC_ID,
> + ST_LSM9DS1_ID,
> ST_LSM6DSX_MAX_ID,
> };
>
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> index e0d2149625cc..2f3d2bf25646 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> @@ -10,6 +10,8 @@
> * +-125/+-245/+-500/+-1000/+-2000 dps
> * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
> * allowing dynamic batching of sensor data.
> + * LSM9DSx series is similar but includes an additional magnetometer, handled
> + * by a different driver.
> *
> * Supported sensors:
> * - LSM6DS3:
> @@ -30,6 +32,13 @@
> * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
> * - FIFO size: 3KB
> *
> + * - LSM9DS1:
> + * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
> + * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
> + * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
> + * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
> + * - FIFO size: 32
> + *
> * Copyright 2016 STMicroelectronics Inc.
> *
> * Lorenzo Bianconi <lorenzo.bianconi@...com>
> @@ -64,7 +73,72 @@
> #define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
> #define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
>
> +#define ST_LSM9DSX_REG_GYRO_OUT_X_L_ADDR 0x18
> +#define ST_LSM9DSX_REG_GYRO_OUT_Y_L_ADDR 0x1a
> +#define ST_LSM9DSX_REG_GYRO_OUT_Z_L_ADDR 0x1c
> +
> static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> + {
> + .wai = 0x68,
> + .int1_addr = 0x0c,
> + .int2_addr = 0x0d,
> + .reset_addr = 0x22,
> + .max_fifo_size = 32,
> + .id = {
> + {
> + .hw_id = ST_LSM9DS1_ID,
> + .name = ST_LSM9DS1_DEV_NAME,
> + },
> + },
> + .odr_table = {
> + [ST_LSM6DSX_ID_ACC] = {
> + .reg = {
> + .addr = 0x20,
> + .mask = GENMASK(7, 5),
> + },
> + .odr_avl[0] = { 10, 0x01 },
> + .odr_avl[1] = { 50, 0x02 },
> + .odr_avl[2] = { 119, 0x03 },
> + .odr_avl[3] = { 238, 0x04 },
> + .odr_avl[4] = { 476, 0x05 },
> + .odr_avl[5] = { 952, 0x06 },
> + },
> + [ST_LSM6DSX_ID_GYRO] = {
> + .reg = {
> + .addr = 0x10,
> + .mask = GENMASK(7, 5),
> + },
> + .odr_avl[0] = { 15, 0x01 },
> + .odr_avl[1] = { 60, 0x02 },
> + .odr_avl[2] = { 119, 0x03 },
> + .odr_avl[3] = { 238, 0x04 },
> + .odr_avl[4] = { 476, 0x05 },
> + .odr_avl[5] = { 952, 0x06 },
> + },
> + },
> + .fs_table = {
> + [ST_LSM6DSX_ID_ACC] = {
> + .reg = {
> + .addr = 0x20,
> + .mask = GENMASK(4, 3),
> + },
> + .fs_avl[0] = { 599, 0x0 },
> + .fs_avl[1] = { 1197, 0x2 },
> + .fs_avl[2] = { 2394, 0x3 },
> + .fs_avl[3] = { 4788, 0x1 },
> + },
> + [ST_LSM6DSX_ID_GYRO] = {
> + .reg = {
> + .addr = 0x10,
> + .mask = GENMASK(4, 3),
> + },
> + .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
> + .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
> + .fs_avl[2] = { IIO_DEGREE_TO_RAD(0), 0x2 },
> + .fs_avl[3] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
> + },
> + },
> + },
> {
> .wai = 0x69,
> .int1_addr = 0x0d,
> @@ -733,6 +807,16 @@ static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
> IIO_CHAN_SOFT_TIMESTAMP(3),
> };
>
> +static const struct iio_chan_spec st_lsm9dsx_gyro_channels[] = {
> + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM9DSX_REG_GYRO_OUT_X_L_ADDR,
> + IIO_MOD_X, 0),
> + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM9DSX_REG_GYRO_OUT_Y_L_ADDR,
> + IIO_MOD_Y, 1),
> + ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM9DSX_REG_GYRO_OUT_Z_L_ADDR,
> + IIO_MOD_Z, 2),
> + IIO_CHAN_SOFT_TIMESTAMP(3),
> +};
> +
> int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
> {
> const struct st_lsm6dsx_shub_settings *hub_settings;
> @@ -1278,7 +1362,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
>
> static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
> enum st_lsm6dsx_sensor_id id,
> - const char *name)
> + const char *name, int hw_id)
> {
> struct st_lsm6dsx_sensor *sensor;
> struct iio_dev *iio_dev;
> @@ -1308,7 +1392,11 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
> name);
> break;
> case ST_LSM6DSX_ID_GYRO:
> - iio_dev->channels = st_lsm6dsx_gyro_channels;
> + if (hw_id == ST_LSM9DS1_ID)
> + iio_dev->channels = st_lsm9dsx_gyro_channels;
> + else
> + iio_dev->channels = st_lsm6dsx_gyro_channels;
> +
> iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels);
> iio_dev->info = &st_lsm6dsx_gyro_info;
>
> @@ -1354,7 +1442,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
> return err;
>
> for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
> - hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
> + hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name, hw_id);
> if (!hw->iio_devs[i])
> return -ENOMEM;
> }
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
> index 28581eb0532c..c36a057c36ee 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
> @@ -79,6 +79,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
> .compatible = "st,lsm6ds3tr-c",
> .data = (void *)ST_LSM6DS3TRC_ID,
> },
> + {
> + .compatible = "st,lsm9ds1",
> + .data = (void *)ST_LSM9DS1_ID,
> + },
> {},
> };
> MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
> @@ -94,6 +98,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
> { ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
> { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
> { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
> + { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
> {},
> };
> MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
> index 0371e8b94a3e..138e3b985865 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
> @@ -79,6 +79,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
> .compatible = "st,lsm6ds3tr-c",
> .data = (void *)ST_LSM6DS3TRC_ID,
> },
> + {
> + .compatible = "st,lsm9ds1",
> + .data = (void *)ST_LSM9DS1_ID,
> + },
> {},
> };
> MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
> @@ -94,6 +98,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
> { ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
> { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
> { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
> + { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
> {},
> };
> MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
Powered by blists - more mailing lists