On 2020-03-19 18:40, Lorenzo Bianconi wrote:
On 2020-03-14 13:43, Lorenzo Bianconi wrote: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, jimmyHi Jimmy, in order to set the full scale on LIS3MDL you can try the following patch (just compiled, not tested) Regards, LorenzoHi Lorenzo, Sorry for the late response and thanks for the patch!Hi Jimmy, ok, I will post the patch, thx for testing.
Great, you can add Tested-by: Jimmy Assarsson <jimmyassarsson@xxxxxxxxx>
The patches seems to work. Are there any specific tests that we should carry out? Via the sysfs interface, we've tested reading raw values of each channel and configuring ODR and full scale.you can try to enable batching in the hw FIFO doing something like: $echo 1 > /sys/bus/iio/devices/<iio-magn>/scan_elements/in_magn_x_en $echo 1 > /sys/bus/iio/devices/<iio-magn>/scan_elements/in_magn_y_en $echo 1 > /sys/bus/iio/devices/<iio-magn>/scan_elements/in_magn_z_en $echo 1 > /sys/bus/iio/devices/<iio-magn>/scan_elements/in_timestamp_en $watermark=64 $echo $((2*watermark)) > /sys/bus/iio/devices/<iio-magn>/buffer/length $echo $watermark > /sys/bus/iio/devices/<iio-magn>/buffer/watermark $generic_buffer -gn lsm6dsm_magn -c <# of samples>
Ok. I don't got any scan_elements nor buffer directory, for any of the devices. I guess it is not possible to use the FIFO without configuring any interrupt? We got the following dts: &spi1 { #address-cells = <1>; #size-cells = <0>; lsm6dsm@0 { compatible = "st,lsm6dsm"; reg = <0x0>; spi-max-frequency = <500000>; st,pullups = "true"; }; }; I'll look into this tomorrow or in the beginning of next week, thanks for the help. Regards, jimmy
Regards, LorenzoRegards, jimmydiff --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, + }, + }, };