Linux-IIO Archive on lore.kernel.org
 help / color / Atom feed
* Use LIS3MDL with LSM6DSM sensor-hub
@ 2020-03-11 20:50 Jimmy Assarsson
  2020-03-12  8:51 ` Lorenzo Bianconi
  2020-03-14 12:43 ` Lorenzo Bianconi
  0 siblings, 2 replies; 11+ messages in thread
From: Jimmy Assarsson @ 2020-03-11 20:50 UTC (permalink / raw)
  To: Lorenzo Bianconi, linux-iio

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

---
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,
+		},
+	},
  };

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-11 20:50 Use LIS3MDL with LSM6DSM sensor-hub Jimmy Assarsson
@ 2020-03-12  8:51 ` Lorenzo Bianconi
  2020-03-14 12:43 ` Lorenzo Bianconi
  1 sibling, 0 replies; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-12  8:51 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 3184 bytes --]

> Hi,

Hi Jimmy,

> 
> 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?

I think so, the other routines are already there

> 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.

I think it is ok since the real table size is indicated in the odr_len field

> 3. In the patch, we've tried to copy the correct registers and values from
>    magnetometer/st_magn_core.c, does it look ok?

I have not double checked, but I guess they should be ok if you copied them
from st_magn_core.c

Does it work?

Regards,
Lorenzo

> 
> The IIO subsystem is new to use, we possibly miss fundamental knowledge.
> 
> Regards,
> jimmy
> 
> ---
> 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-11 20:50 Use LIS3MDL with LSM6DSM sensor-hub Jimmy Assarsson
  2020-03-12  8:51 ` Lorenzo Bianconi
@ 2020-03-14 12:43 ` Lorenzo Bianconi
  2020-03-19 14:41   ` Jimmy Assarsson
  1 sibling, 1 reply; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-14 12:43 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 4420 bytes --]

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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-14 12:43 ` Lorenzo Bianconi
@ 2020-03-19 14:41   ` Jimmy Assarsson
  2020-03-19 17:40     ` Lorenzo Bianconi
  0 siblings, 1 reply; 11+ messages in thread
From: Jimmy Assarsson @ 2020-03-19 14:41 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-iio

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,
>> jimmy
> 
> Hi Jimmy,
> 
> in order to set the full scale on LIS3MDL you can try the following patch (just
> compiled, not tested)
> 
> Regards,
> Lorenzo

Hi Lorenzo,

Sorry for the late response and thanks for the patch!

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.

Regards,
jimmy

> 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,
>> +		},
>> +	},
>>   };

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-19 14:41   ` Jimmy Assarsson
@ 2020-03-19 17:40     ` Lorenzo Bianconi
  2020-03-19 18:45       ` Jimmy Assarsson
  0 siblings, 1 reply; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-19 17:40 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 6086 bytes --]

> 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,
> > > jimmy
> > 
> > Hi Jimmy,
> > 
> > in order to set the full scale on LIS3MDL you can try the following patch (just
> > compiled, not tested)
> > 
> > Regards,
> > Lorenzo
> 
> Hi Lorenzo,
> 
> Sorry for the late response and thanks for the patch!

Hi Jimmy,

ok, I will post the patch, thx for testing.

> 
> 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>

Regards,
Lorenzo

> 
> Regards,
> jimmy
> 
> > 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-19 17:40     ` Lorenzo Bianconi
@ 2020-03-19 18:45       ` Jimmy Assarsson
  2020-03-19 20:49         ` Lorenzo Bianconi
  0 siblings, 1 reply; 11+ messages in thread
From: Jimmy Assarsson @ 2020-03-19 18:45 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-iio

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,
>>>> jimmy
>>>
>>> Hi Jimmy,
>>>
>>> in order to set the full scale on LIS3MDL you can try the following patch (just
>>> compiled, not tested)
>>>
>>> Regards,
>>> Lorenzo
>>
>> Hi 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@gmail.com>

>> 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,
> Lorenzo
> 
>>
>> Regards,
>> jimmy
>>
>>> 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,
>>>> +		},
>>>> +	},
>>>>    };

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-19 18:45       ` Jimmy Assarsson
@ 2020-03-19 20:49         ` Lorenzo Bianconi
  2020-03-23 15:21           ` Jimmy Assarsson
  0 siblings, 1 reply; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-19 20:49 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 6421 bytes --]

> 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,
> > > > > 

[...]

> > > > Hi Jimmy,
> > > > 
> > > > in order to set the full scale on LIS3MDL you can try the following patch (just
> > > > compiled, not tested)
> > > > 
> > > > Regards,
> > > > Lorenzo
> > > 
> > > Hi 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@gmail.com>
> 
> > > 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";

yes, you need to provide the interrupt line doing something like (this is from
the dts on my rpi):

	lsm6dsm@0 {
		...
		interrupt-parent = <&gpio>;
		interrupts = <21 0x4>;
		...
	};

> 	};
> };
> 
> I'll look into this tomorrow or in the beginning of next week, thanks for the help.
> 
> Regards,
> jimmy
> 
> > 
> > Regards,
> > Lorenzo
> > 
> > > 
> > > Regards,
> > > jimmy
> > > 
> > > > 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-19 20:49         ` Lorenzo Bianconi
@ 2020-03-23 15:21           ` Jimmy Assarsson
  2020-03-24  8:20             ` Lorenzo Bianconi
  0 siblings, 1 reply; 11+ messages in thread
From: Jimmy Assarsson @ 2020-03-23 15:21 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-iio

On 2020-03-19 21:49, Lorenzo Bianconi wrote:
>> 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,
>>>>>>
> 
> [...]
> 
>>>>> Hi Jimmy,
>>>>>
>>>>> in order to set the full scale on LIS3MDL you can try the following patch (just
>>>>> compiled, not tested)
>>>>>
>>>>> Regards,
>>>>> Lorenzo
>>>>
>>>> Hi 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@gmail.com>
>>
>>>> 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";
> 
> yes, you need to provide the interrupt line doing something like (this is from
> the dts on my rpi):
> 
> 	lsm6dsm@0 {
> 		...
> 		interrupt-parent = <&gpio>;
> 		interrupts = <21 0x4>;
> 		...
> 	};
> 
>> 	};
>> };
>>
>> I'll look into this tomorrow or in the beginning of next week, thanks for the help.

Now I've tested this. It looks fine, except for the very first sample:
$ ./iio_generic_buffer -gn lsm6dsm_magn -c 1
iio device number being used is 3
trigger-less mode selected
-3.250836 -2.796192 10.212408 1584976428879020199
1.893036 2.343738 -0.853224 1584976428917070199
1.888218 2.343300 -0.852786 1584976428955095199
1.888218 2.343300 -0.852786 1584976428993145199
1.889532 2.345490 -0.851472 1584976429031170199

Is this expected?

Regards,
jimmy

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-23 15:21           ` Jimmy Assarsson
@ 2020-03-24  8:20             ` Lorenzo Bianconi
  2020-03-24 13:47               ` Jimmy Assarsson
  0 siblings, 1 reply; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-24  8:20 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 3147 bytes --]

> On 2020-03-19 21:49, Lorenzo Bianconi wrote:
> > > 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,
> > > > > > > 
> > 
> > [...]
> > 
> > > > > > Hi Jimmy,
> > > > > > 
> > > > > > in order to set the full scale on LIS3MDL you can try the following patch (just
> > > > > > compiled, not tested)
> > > > > > 
> > > > > > Regards,
> > > > > > Lorenzo
> > > > > 
> > > > > Hi 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@gmail.com>
> > > 
> > > > > 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";
> > 
> > yes, you need to provide the interrupt line doing something like (this is from
> > the dts on my rpi):
> > 
> > 	lsm6dsm@0 {
> > 		...
> > 		interrupt-parent = <&gpio>;
> > 		interrupts = <21 0x4>;
> > 		...
> > 	};
> > 
> > > 	};
> > > };
> > > 
> > > I'll look into this tomorrow or in the beginning of next week, thanks for the help.
> 
> Now I've tested this. It looks fine, except for the very first sample:
> $ ./iio_generic_buffer -gn lsm6dsm_magn -c 1
> iio device number being used is 3
> trigger-less mode selected
> -3.250836 -2.796192 10.212408 1584976428879020199
> 1.893036 2.343738 -0.853224 1584976428917070199
> 1.888218 2.343300 -0.852786 1584976428955095199
> 1.888218 2.343300 -0.852786 1584976428993145199
> 1.889532 2.345490 -0.851472 1584976429031170199

values seems reasonable but I guess it depends on sensor calibration and how is
oriented. Do you have any app to test it?

Regards,
Lorenzo

> 
> Is this expected?
> 
> Regards,
> jimmy

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-24  8:20             ` Lorenzo Bianconi
@ 2020-03-24 13:47               ` Jimmy Assarsson
  2020-03-24 14:09                 ` Lorenzo Bianconi
  0 siblings, 1 reply; 11+ messages in thread
From: Jimmy Assarsson @ 2020-03-24 13:47 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-iio

On 2020-03-24 09:20, Lorenzo Bianconi wrote:
>> On 2020-03-19 21:49, Lorenzo Bianconi wrote:
>>>> 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,
>>>>>>>>
>>>
>>> [...]
>>>
>>>>>>> Hi Jimmy,
>>>>>>>
>>>>>>> in order to set the full scale on LIS3MDL you can try the following patch (just
>>>>>>> compiled, not tested)
>>>>>>>
>>>>>>> Regards,
>>>>>>> Lorenzo
>>>>>>
>>>>>> Hi 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@gmail.com>
>>>>
>>>>>> 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";
>>>
>>> yes, you need to provide the interrupt line doing something like (this is from
>>> the dts on my rpi):
>>>
>>> 	lsm6dsm@0 {
>>> 		...
>>> 		interrupt-parent = <&gpio>;
>>> 		interrupts = <21 0x4>;
>>> 		...
>>> 	};
>>>
>>>> 	};
>>>> };
>>>>
>>>> I'll look into this tomorrow or in the beginning of next week, thanks for the help.
>>
>> Now I've tested this. It looks fine, except for the very first sample:
>> $ ./iio_generic_buffer -gn lsm6dsm_magn -c 1
>> iio device number being used is 3
>> trigger-less mode selected
>> -3.250836 -2.796192 10.212408 1584976428879020199
>> 1.893036 2.343738 -0.853224 1584976428917070199
>> 1.888218 2.343300 -0.852786 1584976428955095199
>> 1.888218 2.343300 -0.852786 1584976428993145199
>> 1.889532 2.345490 -0.851472 1584976429031170199
> 
> values seems reasonable but I guess it depends on sensor calibration and how is
> oriented. Do you have any app to test it?

I think the values are correct. If I rotate the sensor the values change.
And I get similar values when the sensor reach the same orientation as before.
The only thing that looks strange, is the very first sample (-3.250836 -2.796192 10.212408),
which is not close to any of the other samples. When I plot the samples, the other samples
form a circle, while the first sample is way outside of the circle.

What about calibration? Is there any functionality in iio for calibration, or in libiio, or will
this always be part of the application?

Unfortunately we don't got any app for this yet.

Regards,
jimmy

> Regards,
> Lorenzo
> 
>>
>> Is this expected?
>>
>> Regards,
>> jimmy

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Use LIS3MDL with LSM6DSM sensor-hub
  2020-03-24 13:47               ` Jimmy Assarsson
@ 2020-03-24 14:09                 ` Lorenzo Bianconi
  0 siblings, 0 replies; 11+ messages in thread
From: Lorenzo Bianconi @ 2020-03-24 14:09 UTC (permalink / raw)
  To: Jimmy Assarsson; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 1685 bytes --]

[...]

> > > > > };
> > > > > 
> > > > > I'll look into this tomorrow or in the beginning of next week, thanks for the help.
> > > 
> > > Now I've tested this. It looks fine, except for the very first sample:
> > > $ ./iio_generic_buffer -gn lsm6dsm_magn -c 1
> > > iio device number being used is 3
> > > trigger-less mode selected
> > > -3.250836 -2.796192 10.212408 1584976428879020199
> > > 1.893036 2.343738 -0.853224 1584976428917070199
> > > 1.888218 2.343300 -0.852786 1584976428955095199
> > > 1.888218 2.343300 -0.852786 1584976428993145199
> > > 1.889532 2.345490 -0.851472 1584976429031170199
> > 
> > values seems reasonable but I guess it depends on sensor calibration and how is
> > oriented. Do you have any app to test it?
> 
> I think the values are correct. If I rotate the sensor the values change.
> And I get similar values when the sensor reach the same orientation as before.
> The only thing that looks strange, is the very first sample (-3.250836 -2.796192 10.212408),
> which is not close to any of the other samples. When I plot the samples, the other samples
> form a circle, while the first sample is way outside of the circle.

I think this can be due to sensor start-up time

> 
> What about calibration? Is there any functionality in iio for calibration, or in libiio, or will
> this always be part of the application?

AFAIK calibration libraries are done in userspace and usually they are not
open source.

Regards,
Lorenzo

> 
> Unfortunately we don't got any app for this yet.
> 
> Regards,
> jimmy
> 
> > Regards,
> > Lorenzo
> > 
> > > 
> > > Is this expected?
> > > 
> > > Regards,
> > > jimmy

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, back to index

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-11 20:50 Use LIS3MDL with LSM6DSM sensor-hub Jimmy Assarsson
2020-03-12  8:51 ` Lorenzo Bianconi
2020-03-14 12:43 ` Lorenzo Bianconi
2020-03-19 14:41   ` Jimmy Assarsson
2020-03-19 17:40     ` Lorenzo Bianconi
2020-03-19 18:45       ` Jimmy Assarsson
2020-03-19 20:49         ` Lorenzo Bianconi
2020-03-23 15:21           ` Jimmy Assarsson
2020-03-24  8:20             ` Lorenzo Bianconi
2020-03-24 13:47               ` Jimmy Assarsson
2020-03-24 14:09                 ` Lorenzo Bianconi

Linux-IIO Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-iio/0 linux-iio/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-iio linux-iio/ https://lore.kernel.org/linux-iio \
		linux-iio@vger.kernel.org
	public-inbox-index linux-iio

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-iio


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git