On Mar 11, Jimmy Assarsson wrote: > Hi, > > We are working on a project where we want to connect LS6DSM (via SPI), and > connect LIS3MDL via the sensor hub, as I2C slave device. > > We would like to add settings/configuration for LIS3MDL, to the shub > source, since currently only LIS2MDL is supported. We've made an attempt, > see diff at end of this mail. > > 1. LIS2MDL only got a single full scale setting, hence it is not possible > to change. While LIS3MDL got four possible settings. Is it enough to add > a corresponding function like st_lsm6dsx_shub_set_fs_val() and call it > from st_lsm6dsx_shub_write_raw(), when mask == IIO_CHAN_INFO_SCALE? > 2. LIS3MDL got 8 possible ODR settings, however ST_LSM6DSX_ODR_LIST_SIZE is > defined to 6 (st_lsm6dsx.h). Is it fine to increase > ST_LSM6DSX_ODR_LIST_SIZE to 8? This will also affect odr_table in > struct st_lsm6dsx_settings. > 3. In the patch, we've tried to copy the correct registers and values from > magnetometer/st_magn_core.c, does it look ok? > > The IIO subsystem is new to use, we possibly miss fundamental knowledge. > > Regards, > jimmy Hi Jimmy, in order to set the full scale on LIS3MDL you can try the following patch (just compiled, not tested) Regards, Lorenzo diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index 64ef07a30726..fec1dbd5f00d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -518,6 +518,36 @@ st_lsm6dsx_shub_read_raw(struct iio_dev *iio_dev, return ret; } +static int +st_lsm6dsx_shub_set_full_scale(struct st_lsm6dsx_sensor *sensor, + u32 gain) +{ + const struct st_lsm6dsx_fs_table_entry *fs_table; + int i, err; + + fs_table = &sensor->ext_info.settings->fs_table; + if (!fs_table->reg.addr) + return -ENOTSUPP; + + for (i = 0; i < fs_table->fs_len; i++) { + if (fs_table->fs_avl[i].gain == gain) + break; + } + + if (i == fs_table->fs_len) + return -EINVAL; + + err = st_lsm6dsx_shub_write_with_mask(sensor, fs_table->reg.addr, + fs_table->reg.mask, + fs_table->fs_avl[i].val); + if (err < 0) + return err; + + sensor->gain = gain; + + return 0; +} + static int st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev, struct iio_chan_spec const *chan, @@ -552,6 +582,9 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev, } break; } + case IIO_CHAN_INFO_SCALE: + err = st_lsm6dsx_shub_set_full_scale(sensor, val2); + break; default: err = -EINVAL; break; > > --- > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c > index eea5556..8621dba 100644 > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c > @@ -88,6 +88,69 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = { > .len = 6, > }, > }, > + /* LIS3MDL */ > + { > + .i2c_addr = { 0x1e }, > + .wai = { > + .addr = 0x0f, > + .val = 0x3d, > + }, > + .id = ST_LSM6DSX_ID_MAGN, > + .odr_table = { > + .reg = { > + .addr = 0x20, > + .mask = GENMASK(4, 2), > + }, > + .odr_avl[0] = { 1000, 0x0 }, > + .odr_avl[1] = { 2000, 0x1 }, > + .odr_avl[2] = { 3000, 0x2 }, > + .odr_avl[3] = { 5000, 0x3 }, > + .odr_avl[4] = { 10000, 0x4 }, > + .odr_avl[5] = { 20000, 0x5 }, > + .odr_avl[6] = { 40000, 0x6 }, > + .odr_avl[7] = { 80000, 0x7 }, > + .odr_len = 8, > + }, > + .fs_table = { > + .reg = { > + .addr = 0x21, > + .mask = GENMASK(6, 5), > + }, > + .fs_avl[0] = { > + .gain = 146, > + .val = 0x00, > + }, /* 4000 uG/LSB */ > + .fs_avl[1] = { > + .gain = 292, > + .val = 0x01, > + }, /* 8000 uG/LSB */ > + .fs_avl[2] = { > + .gain = 438, > + .val = 0x02, > + }, /* 12000 uG/LSB */ > + .fs_avl[3] = { > + .gain = 584, > + .val = 0x03, > + }, /* 16000 uG/LSB */ > + .fs_len = 4, > + }, > + .pwr_table = { > + .reg = { > + .addr = 0x22, > + .mask = GENMASK(1, 0), > + }, > + .off_val = 0x2, > + .on_val = 0x0, > + }, > + .bdu = { > + .addr = 0x24, > + .mask = BIT(6), > + }, > + .out = { > + .addr = 0x28, > + .len = 6, > + }, > + }, > };
Attachment:
signature.asc
Description: PGP signature