2023-08-04 07:09:36

by Ramona Bolboaca

[permalink] [raw]
Subject: [PATCH v3 0/3] Add new channels for adis16475

changes in v3:
new patches: 1,2 which add IIO_DELTA_ANGL and IIO_DELTA_VELOCITY channel types
patch3:
- added new flag for presence of delta measuremets in burst data
- removed available scan mask, a simple check is performed in
adis16475_update_scan_mode to see if the scan mask is valid and to configure
the burst data selection based on the scan mask.

Ramona Bolboaca (3):
iio: Add IIO_DELTA_ANGL channel type
iio: Add IIO_DELTA_VELOCITY channel type
iio: imu: adis16475.c: Add delta angle and delta velocity channels

Documentation/ABI/testing/sysfs-bus-iio | 29 +++++
drivers/iio/imu/adis16475.c | 165 +++++++++++++++++++++---
drivers/iio/industrialio-core.c | 2 +
include/uapi/linux/iio/types.h | 2 +
tools/iio/iio_event_monitor.c | 4 +
5 files changed, 183 insertions(+), 19 deletions(-)

--
2.25.1



2023-08-04 07:10:49

by Ramona Bolboaca

[permalink] [raw]
Subject: [PATCH v3 2/3] iio: Add IIO_DELTA_VELOCITY channel type

The delta velocity is defined as a piece-wise integration of
acceleration data. The delta velocity represents the linear velocity
change between two consecutive measurements and it
is measured in m / s (meters per second).

In order to track the total linear velocity change during a desired
period of time, simply sum-up the delta velocity samples acquired
during that time.

IIO currently does not offer a suitable channel type for this
type of measurements hence this patch adds it.

Signed-off-by: Ramona Bolboaca <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 15 +++++++++++++++
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
tools/iio/iio_event_monitor.c | 2 ++
4 files changed, 19 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 1561c33b05a1..dab53d5d7dcf 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -293,6 +293,21 @@ Description:
angle samples acquired during that time.
Units after application of scale and offset are angles.

+What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_x_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_y_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_z_raw
+KernelVersion: 6.5
+Contact: [email protected]
+Description:
+ The linear velocity change between two consecutive samples on x,
+ y or z (may be arbitrarily assigned but should match other such
+ assignments on device).
+ In order to compute the total linear velocity change during a
+ desired period of time, the application should sum-up the delta
+ velocity samples acquired during that time.
+ Units after application of scale and offset are meters per
+ second.
+
What: /sys/bus/iio/devices/iio:deviceX/in_angl_raw
What: /sys/bus/iio/devices/iio:deviceX/in_anglY_raw
KernelVersion: 4.17
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 2e2fd0be2504..ba694b049629 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -90,6 +90,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_PHASE] = "phase",
[IIO_MASSCONCENTRATION] = "massconcentration",
[IIO_DELTA_ANGL] = "deltaangl",
+ [IIO_DELTA_VELOCITY] = "deltavelocity",
};

static const char * const iio_modifier_names[] = {
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index 55666a17d311..9a341bd07702 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -48,6 +48,7 @@ enum iio_chan_type {
IIO_PHASE,
IIO_MASSCONCENTRATION,
IIO_DELTA_ANGL,
+ IIO_DELTA_VELOCITY,
};

enum iio_modifier {
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index 3505450060e6..7e6761612246 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -60,6 +60,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_PHASE] = "phase",
[IIO_MASSCONCENTRATION] = "massconcentration",
[IIO_DELTA_ANGL] = "deltaangl",
+ [IIO_DELTA_VELOCITY] = "deltavelocity",
};

static const char * const iio_ev_type_text[] = {
@@ -175,6 +176,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_PHASE:
case IIO_MASSCONCENTRATION:
case IIO_DELTA_ANGL:
+ case IIO_DELTA_VELOCITY:
break;
default:
return false;
--
2.25.1


2023-08-04 07:16:07

by Ramona Bolboaca

[permalink] [raw]
Subject: [PATCH v3 3/3] iio: imu: adis16475.c: Add delta angle and delta velocity channels

Add support for delta angle and delta velocity raw and buffer
readings to adis16475 driver.

Signed-off-by: Ramona Bolboaca <[email protected]>
---
drivers/iio/imu/adis16475.c | 165 +++++++++++++++++++++++++++++++-----
1 file changed, 146 insertions(+), 19 deletions(-)

diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
index 17275a53ca2c..dbbeb80c4d23 100644
--- a/drivers/iio/imu/adis16475.c
+++ b/drivers/iio/imu/adis16475.c
@@ -31,6 +31,12 @@
#define ADIS16475_REG_Y_ACCEL_L 0x14
#define ADIS16475_REG_Z_ACCEL_L 0x18
#define ADIS16475_REG_TEMP_OUT 0x1c
+#define ADIS16475_REG_X_DELTANG_L 0x24
+#define ADIS16475_REG_Y_DELTANG_L 0x28
+#define ADIS16475_REG_Z_DELTANG_L 0x2C
+#define ADIS16475_REG_X_DELTVEL_L 0x30
+#define ADIS16475_REG_Y_DELTVEL_L 0x34
+#define ADIS16475_REG_Z_DELTVEL_L 0x38
#define ADIS16475_REG_X_GYRO_BIAS_L 0x40
#define ADIS16475_REG_Y_GYRO_BIAS_L 0x44
#define ADIS16475_REG_Z_GYRO_BIAS_L 0x48
@@ -55,6 +61,8 @@
#define ADIS16475_REG_PROD_ID 0x72
#define ADIS16475_REG_SERIAL_NUM 0x74
#define ADIS16475_REG_FLASH_CNT 0x7c
+#define ADIS16500_BURST_DATA_SEL_MASK BIT(8)
+#define ADIS16500_BURST_DATA_SEL(x) FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, x)
#define ADIS16500_BURST32_MASK BIT(9)
#define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BURST32_MASK, x)
/* number of data elements in burst mode */
@@ -65,6 +73,10 @@
#define ADIS16475_BURST_MAX_SPEED 1000000
#define ADIS16475_LSB_DEC_MASK BIT(0)
#define ADIS16475_LSB_FIR_MASK BIT(1)
+#define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0)
+#define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7)
+#define ADIS16475_HAS_BURST32 BIT(0)
+#define ADIS16475_HAS_BURST_DELTA_DATA BIT(1)

enum {
ADIS16475_SYNC_DIRECT = 1,
@@ -84,16 +96,18 @@ struct adis16475_chip_info {
const struct adis16475_sync *sync;
const struct adis_data adis_data;
const char *name;
+ const long flags;
u32 num_channels;
u32 gyro_max_val;
u32 gyro_max_scale;
u32 accel_max_val;
u32 accel_max_scale;
u32 temp_scale;
+ u32 deltang_max_val;
+ u32 deltvel_max_val;
u32 int_clk;
u16 max_dec;
u8 num_sync;
- bool has_burst32;
};

struct adis16475 {
@@ -115,6 +129,12 @@ enum {
ADIS16475_SCAN_ACCEL_Y,
ADIS16475_SCAN_ACCEL_Z,
ADIS16475_SCAN_TEMP,
+ ADIS16475_SCAN_DELTANG_X,
+ ADIS16475_SCAN_DELTANG_Y,
+ ADIS16475_SCAN_DELTANG_Z,
+ ADIS16475_SCAN_DELTVEL_X,
+ ADIS16475_SCAN_DELTVEL_Y,
+ ADIS16475_SCAN_DELTVEL_Z,
};

static bool low_rate_allow;
@@ -451,6 +471,14 @@ static int adis16475_read_raw(struct iio_dev *indio_dev,
case IIO_TEMP:
*val = st->info->temp_scale;
return IIO_VAL_INT;
+ case IIO_DELTA_ANGL:
+ *val = st->info->deltang_max_val;
+ *val2 = 31;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_DELTA_VELOCITY:
+ *val = st->info->deltvel_max_val;
+ *val2 = 31;
+ return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
@@ -551,6 +579,32 @@ static int adis16475_write_raw(struct iio_dev *indio_dev,
}, \
}

+#define ADIS16475_MOD_CHAN_DELTA(_type, _mod, _address, _si, _r_bits, _s_bits) { \
+ .type = (_type), \
+ .modified = 1, \
+ .channel2 = (_mod), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .address = (_address), \
+ .scan_index = _si, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (_r_bits), \
+ .storagebits = (_s_bits), \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define ADIS16475_DELTANG_CHAN(_mod) \
+ ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_ANGL, IIO_MOD_ ## _mod, \
+ ADIS16475_REG_ ## _mod ## _DELTANG_L, ADIS16475_SCAN_DELTANG_ ## _mod, 32, 32)
+
+#define ADIS16475_DELTVEL_CHAN(_mod) \
+ ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_VELOCITY, IIO_MOD_ ## _mod, \
+ ADIS16475_REG_ ## _mod ## _DELTVEL_L, ADIS16475_SCAN_DELTVEL_ ## _mod, 32, 32)
+
static const struct iio_chan_spec adis16475_channels[] = {
ADIS16475_GYRO_CHANNEL(X),
ADIS16475_GYRO_CHANNEL(Y),
@@ -559,7 +613,13 @@ static const struct iio_chan_spec adis16475_channels[] = {
ADIS16475_ACCEL_CHANNEL(Y),
ADIS16475_ACCEL_CHANNEL(Z),
ADIS16475_TEMP_CHANNEL(),
- IIO_CHAN_SOFT_TIMESTAMP(7)
+ ADIS16475_DELTANG_CHAN(X),
+ ADIS16475_DELTANG_CHAN(Y),
+ ADIS16475_DELTANG_CHAN(Z),
+ ADIS16475_DELTVEL_CHAN(X),
+ ADIS16475_DELTVEL_CHAN(Y),
+ ADIS16475_DELTVEL_CHAN(Z),
+ IIO_CHAN_SOFT_TIMESTAMP(13)
};

enum adis16475_variant {
@@ -662,6 +722,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -677,6 +739,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -692,6 +756,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -707,6 +773,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -722,11 +790,13 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
.num_sync = ARRAY_SIZE(adis16475_sync_mode),
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
},
[ADIS16477_2] = {
@@ -738,11 +808,13 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
.num_sync = ARRAY_SIZE(adis16475_sync_mode),
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
},
[ADIS16477_3] = {
@@ -754,11 +826,13 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
.num_sync = ARRAY_SIZE(adis16475_sync_mode),
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
},
[ADIS16465_1] = {
@@ -770,6 +844,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -785,6 +861,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -800,6 +878,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -815,6 +895,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -830,6 +912,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -845,6 +929,8 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 1,
.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
@@ -860,12 +946,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 392,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16500, &adis1650x_timeouts),
},
[ADIS16505_1] = {
@@ -877,12 +965,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 78,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
},
[ADIS16505_2] = {
@@ -894,12 +984,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 78,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
},
[ADIS16505_3] = {
@@ -911,12 +1003,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 78,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 100,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
},
[ADIS16507_1] = {
@@ -928,12 +1022,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 392,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 360,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
},
[ADIS16507_2] = {
@@ -945,12 +1041,14 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 392,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 720,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
},
[ADIS16507_3] = {
@@ -962,20 +1060,46 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
.accel_max_val = 392,
.accel_max_scale = 32000 << 16,
.temp_scale = 100,
+ .deltang_max_val = 2160,
+ .deltvel_max_val = 400,
.int_clk = 2000,
.max_dec = 1999,
.sync = adis16475_sync_mode,
/* pulse sync not supported */
.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
- .has_burst32 = true,
+ .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,
.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
},
};

+static int adis16475_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ u16 en;
+ int ret;
+ struct adis16475 *st = iio_priv(indio_dev);
+
+ if (st->info->flags & ADIS16475_HAS_BURST_DELTA_DATA) {
+ if ((*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) && (*scan_mask & ADIS16500_BURST_DATA_SEL_1_CHN_MASK))
+ return -EINVAL;
+ if (*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK)
+ en = ADIS16500_BURST_DATA_SEL(0);
+ else
+ en = ADIS16500_BURST_DATA_SEL(1);
+
+ ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
+ ADIS16500_BURST_DATA_SEL_MASK, en);
+ if (ret)
+ return ret;
+ }
+
+ return adis_update_scan_mode(indio_dev, scan_mask);
+}
+
static const struct iio_info adis16475_info = {
.read_raw = &adis16475_read_raw,
.write_raw = &adis16475_write_raw,
- .update_scan_mode = adis_update_scan_mode,
+ .update_scan_mode = adis16475_update_scan_mode,
.debugfs_reg_access = adis_debugfs_reg_access,
};

@@ -998,7 +1122,7 @@ static void adis16475_burst32_check(struct adis16475 *st)
int ret;
struct adis *adis = &st->adis;

- if (!st->info->has_burst32)
+ if (!(st->info->flags & ADIS16475_HAS_BURST32))
return;

if (st->lsb_flag && !st->burst32) {
@@ -1044,7 +1168,7 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16475 *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
- int ret, bit, i = 0;
+ int ret, bit, buff_offset = 0, i = 0;
__be16 *buffer;
u16 crc;
bool valid;
@@ -1074,6 +1198,9 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p)
case ADIS16475_SCAN_TEMP:
st->data[i++] = buffer[offset];
break;
+ case ADIS16475_SCAN_DELTANG_X ... ADIS16475_SCAN_DELTVEL_Z:
+ buff_offset = ADIS16475_SCAN_DELTANG_X;
+ fallthrough;
case ADIS16475_SCAN_GYRO_X ... ADIS16475_SCAN_ACCEL_Z:
/*
* The first 2 bytes on the received data are the
@@ -1081,18 +1208,18 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p)
*/
if (st->burst32) {
/* upper 16 */
- st->data[i++] = buffer[bit * 2 + 2];
+ st->data[i++] = buffer[(bit - buff_offset) * 2 + 2];
/* lower 16 */
- st->data[i++] = buffer[bit * 2 + 1];
+ st->data[i++] = buffer[(bit - buff_offset) * 2 + 1];
} else {
- st->data[i++] = buffer[bit + 1];
+ st->data[i++] = buffer[(bit - buff_offset) + 1];
/*
* Don't bother in doing the manual read if the
* device supports burst32. burst32 will be
* enabled in the next call to
* adis16475_burst32_check()...
*/
- if (st->lsb_flag && !st->info->has_burst32) {
+ if (st->lsb_flag && !(st->info->flags & ADIS16475_HAS_BURST32)) {
u16 val = 0;
const u32 reg = ADIS16475_REG_X_GYRO_L +
bit * 4;
--
2.25.1


2023-08-04 07:30:46

by Ramona Bolboaca

[permalink] [raw]
Subject: [PATCH v3 1/3] iio: Add IIO_DELTA_ANGL channel type

The delta angle is defined as a piece-wise integration of angular
velocity data. The delta angle represents the amount of
angular displacement between two consecutive measurements and it
is measured in degrees.

In order to track the total angular displacement during a desired
period of time, simply sum-up the delta angle samples acquired
during that time.

IIO currently does not offer a suitable channel type for this
type of measurements hence this patch adds it.

Signed-off-by: Ramona Bolboaca <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 14 ++++++++++++++
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
tools/iio/iio_event_monitor.c | 2 ++
4 files changed, 18 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index a2854dc9a839..1561c33b05a1 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -279,6 +279,20 @@ Description:
but should match other such assignments on device).
Units after application of scale and offset are m/s^2.

+What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_x_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_y_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_z_raw
+KernelVersion: 6.5
+Contact: [email protected]
+Description:
+ Angular displacement between two consecutive samples on x, y or
+ z (may be arbitrarily assigned but should match other such
+ assignments on device).
+ In order to compute the total angular displacement during a
+ desired period of time, the application should sum-up the delta
+ angle samples acquired during that time.
+ Units after application of scale and offset are angles.
+
What: /sys/bus/iio/devices/iio:deviceX/in_angl_raw
What: /sys/bus/iio/devices/iio:deviceX/in_anglY_raw
KernelVersion: 4.17
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index a92b8b6ad647..2e2fd0be2504 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -89,6 +89,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_POSITIONRELATIVE] = "positionrelative",
[IIO_PHASE] = "phase",
[IIO_MASSCONCENTRATION] = "massconcentration",
+ [IIO_DELTA_ANGL] = "deltaangl",
};

static const char * const iio_modifier_names[] = {
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index c79f2f046a0b..55666a17d311 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -47,6 +47,7 @@ enum iio_chan_type {
IIO_POSITIONRELATIVE,
IIO_PHASE,
IIO_MASSCONCENTRATION,
+ IIO_DELTA_ANGL,
};

enum iio_modifier {
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index 0a5c2bb60030..3505450060e6 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -59,6 +59,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_POSITIONRELATIVE] = "positionrelative",
[IIO_PHASE] = "phase",
[IIO_MASSCONCENTRATION] = "massconcentration",
+ [IIO_DELTA_ANGL] = "deltaangl",
};

static const char * const iio_ev_type_text[] = {
@@ -173,6 +174,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_POSITIONRELATIVE:
case IIO_PHASE:
case IIO_MASSCONCENTRATION:
+ case IIO_DELTA_ANGL:
break;
default:
return false;
--
2.25.1


2023-08-05 19:36:02

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] iio: imu: adis16475.c: Add delta angle and delta velocity channels

On Fri, 4 Aug 2023 09:45:59 +0300
Ramona Bolboaca <[email protected]> wrote:

> Add support for delta angle and delta velocity raw and buffer
> readings to adis16475 driver.
>
> Signed-off-by: Ramona Bolboaca <[email protected]>

Hi Ramona,

A few trivial comments inline given we need to make that unit change
so you will be doing a v4. Otherwise I might have just done a bit of tidying
up whilst applying.

Thanks,

Jonathan


> ---
> drivers/iio/imu/adis16475.c | 165 +++++++++++++++++++++++++++++++-----
> 1 file changed, 146 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
> index 17275a53ca2c..dbbeb80c4d23 100644
> --- a/drivers/iio/imu/adis16475.c
> +++ b/drivers/iio/imu/adis16475.c
> @@ -31,6 +31,12 @@
> #define ADIS16475_REG_Y_ACCEL_L 0x14
> #define ADIS16475_REG_Z_ACCEL_L 0x18
> #define ADIS16475_REG_TEMP_OUT 0x1c
> +#define ADIS16475_REG_X_DELTANG_L 0x24
> +#define ADIS16475_REG_Y_DELTANG_L 0x28
> +#define ADIS16475_REG_Z_DELTANG_L 0x2C
> +#define ADIS16475_REG_X_DELTVEL_L 0x30
> +#define ADIS16475_REG_Y_DELTVEL_L 0x34
> +#define ADIS16475_REG_Z_DELTVEL_L 0x38
> #define ADIS16475_REG_X_GYRO_BIAS_L 0x40
> #define ADIS16475_REG_Y_GYRO_BIAS_L 0x44
> #define ADIS16475_REG_Z_GYRO_BIAS_L 0x48
> @@ -55,6 +61,8 @@
> #define ADIS16475_REG_PROD_ID 0x72
> #define ADIS16475_REG_SERIAL_NUM 0x74
> #define ADIS16475_REG_FLASH_CNT 0x7c
> +#define ADIS16500_BURST_DATA_SEL_MASK BIT(8)
> +#define ADIS16500_BURST_DATA_SEL(x) FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, x)

I guess this is consistent with other bits of the driver, but I'm not sure
in general that the macro adds anything over directly calling the FIELD_PREP()
which is pretty obvious on it's own.

> #define ADIS16500_BURST32_MASK BIT(9)
> #define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BURST32_MASK, x)
> /* number of data elements in burst mode */
> @@ -65,6 +73,10 @@
> #define ADIS16475_BURST_MAX_SPEED 1000000
> #define ADIS16475_LSB_DEC_MASK BIT(0)
> #define ADIS16475_LSB_FIR_MASK BIT(1)
> +#define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0)
> +#define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7)

Add a blank line here to separate these flag definitions or
see below...

> +#define ADIS16475_HAS_BURST32 BIT(0)
> +#define ADIS16475_HAS_BURST_DELTA_DATA BIT(1)
>
> enum {
> ADIS16475_SYNC_DIRECT = 1,
> @@ -84,16 +96,18 @@ struct adis16475_chip_info {
> const struct adis16475_sync *sync;
> const struct adis_data adis_data;
> const char *name;
> + const long flags;
I would put the two flag definitions here. Then it's obvious what
they are used for.
> u32 num_channels;
> u32 gyro_max_val;
> u32 gyro_max_scale;
> u32 accel_max_val;
> u32 accel_max_scale;
> u32 temp_scale;
> + u32 deltang_max_val;
> + u32 deltvel_max_val;
> u32 int_clk;
> u16 max_dec;
> u8 num_sync;
> - bool has_burst32;
> };
>
> struct adis16475 {
> @@ -115,6 +129,12 @@ enum {
> ADIS16475_SCAN_ACCEL_Y,
> ADIS16475_SCAN_ACCEL_Z,
> ADIS16475_SCAN_TEMP,
> + ADIS16475_SCAN_DELTANG_X,
> + ADIS16475_SCAN_DELTANG_Y,
> + ADIS16475_SCAN_DELTANG_Z,
> + ADIS16475_SCAN_DELTVEL_X,
> + ADIS16475_SCAN_DELTVEL_Y,
> + ADIS16475_SCAN_DELTVEL_Z,
> };
>

> [ADIS16507_3] = {
> @@ -962,20 +1060,46 @@ static const struct adis16475_chip_info adis16475_chip_info[] = {
> .accel_max_val = 392,
> .accel_max_scale = 32000 << 16,
> .temp_scale = 100,
> + .deltang_max_val = 2160,
> + .deltvel_max_val = 400,
> .int_clk = 2000,
> .max_dec = 1999,
> .sync = adis16475_sync_mode,
> /* pulse sync not supported */
> .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
> - .has_burst32 = true,
> + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA,

In the ideal world, a precursor patch would have made the change to have
a flags field, then this one would have just added the new flags.

However it would have made a huge difference to readability of this patch
so I'm not that bothered about not having it broken out.

> .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
> },
> };
>
> +static int adis16475_update_scan_mode(struct iio_dev *indio_dev,
> + const unsigned long *scan_mask)
> +{
> + u16 en;
> + int ret;
> + struct adis16475 *st = iio_priv(indio_dev);
> +
> + if (st->info->flags & ADIS16475_HAS_BURST_DELTA_DATA) {
> + if ((*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) && (*scan_mask & ADIS16500_BURST_DATA_SEL_1_CHN_MASK))

Very long line. No obvious reason not to break it after the &&

> + return -EINVAL;
> + if (*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK)
> + en = ADIS16500_BURST_DATA_SEL(0);
> + else
> + en = ADIS16500_BURST_DATA_SEL(1);
> +
> + ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
> + ADIS16500_BURST_DATA_SEL_MASK, en);
> + if (ret)
> + return ret;
> + }
> +
> + return adis_update_scan_mode(indio_dev, scan_mask);
> +}


2023-08-05 19:52:03

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] iio: Add IIO_DELTA_VELOCITY channel type

On Fri, 4 Aug 2023 09:45:58 +0300
Ramona Bolboaca <[email protected]> wrote:

> The delta velocity is defined as a piece-wise integration of
> acceleration data. The delta velocity represents the linear velocity
> change between two consecutive measurements and it
> is measured in m / s (meters per second).
>
> In order to track the total linear velocity change during a desired
> period of time, simply sum-up the delta velocity samples acquired
> during that time.
>
> IIO currently does not offer a suitable channel type for this
> type of measurements hence this patch adds it.
>
> Signed-off-by: Ramona Bolboaca <[email protected]>
This one looks good to me - I'll pick it up once we reach agreement on
the rest of the series.

Jonathan

2023-08-05 20:19:58

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] Add new channels for adis16475

On Fri, 4 Aug 2023 09:45:56 +0300
Ramona Bolboaca <[email protected]> wrote:

> changes in v3:
> new patches: 1,2 which add IIO_DELTA_ANGL and IIO_DELTA_VELOCITY channel types
> patch3:
> - added new flag for presence of delta measuremets in burst data
> - removed available scan mask, a simple check is performed in
> adis16475_update_scan_mode to see if the scan mask is valid and to configure
> the burst data selection based on the scan mask.

Not that it hugely matters as they don't end up in the git record, but good to
spell check cover letters (I often forget to do so as well!)

>
> Ramona Bolboaca (3):
> iio: Add IIO_DELTA_ANGL channel type
> iio: Add IIO_DELTA_VELOCITY channel type
> iio: imu: adis16475.c: Add delta angle and delta velocity channels
>
> Documentation/ABI/testing/sysfs-bus-iio | 29 +++++
> drivers/iio/imu/adis16475.c | 165 +++++++++++++++++++++---
> drivers/iio/industrialio-core.c | 2 +
> include/uapi/linux/iio/types.h | 2 +
> tools/iio/iio_event_monitor.c | 4 +
> 5 files changed, 183 insertions(+), 19 deletions(-)
>


2023-08-05 20:25:57

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 1/3] iio: Add IIO_DELTA_ANGL channel type

On Fri, 4 Aug 2023 09:45:57 +0300
Ramona Bolboaca <[email protected]> wrote:

> The delta angle is defined as a piece-wise integration of angular
> velocity data. The delta angle represents the amount of
> angular displacement between two consecutive measurements and it
> is measured in degrees.

That's not consistent with angl and it should be.
Hence should be radians, with appropriate changes in the scale
exposed by the driver.

>
> In order to track the total angular displacement during a desired
> period of time, simply sum-up the delta angle samples acquired
> during that time.
>
> IIO currently does not offer a suitable channel type for this
> type of measurements hence this patch adds it.
>
> Signed-off-by: Ramona Bolboaca <[email protected]>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 14 ++++++++++++++
> drivers/iio/industrialio-core.c | 1 +
> include/uapi/linux/iio/types.h | 1 +
> tools/iio/iio_event_monitor.c | 2 ++
> 4 files changed, 18 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index a2854dc9a839..1561c33b05a1 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -279,6 +279,20 @@ Description:
> but should match other such assignments on device).
> Units after application of scale and offset are m/s^2.
>
> +What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_x_raw
> +What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_y_raw
> +What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_z_raw
> +KernelVersion: 6.5
> +Contact: [email protected]
> +Description:
> + Angular displacement between two consecutive samples on x, y or
> + z (may be arbitrarily assigned but should match other such
> + assignments on device).
> + In order to compute the total angular displacement during a
> + desired period of time, the application should sum-up the delta
> + angle samples acquired during that time.
> + Units after application of scale and offset are angles.

Units above are degrees, but should be radians.

> +
> What: /sys/bus/iio/devices/iio:deviceX/in_angl_raw
> What: /sys/bus/iio/devices/iio:deviceX/in_anglY_raw
> KernelVersion: 4.17
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index a92b8b6ad647..2e2fd0be2504 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -89,6 +89,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_POSITIONRELATIVE] = "positionrelative",
> [IIO_PHASE] = "phase",
> [IIO_MASSCONCENTRATION] = "massconcentration",
> + [IIO_DELTA_ANGL] = "deltaangl",
> };
>
> static const char * const iio_modifier_names[] = {
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index c79f2f046a0b..55666a17d311 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -47,6 +47,7 @@ enum iio_chan_type {
> IIO_POSITIONRELATIVE,
> IIO_PHASE,
> IIO_MASSCONCENTRATION,
> + IIO_DELTA_ANGL,
> };
>
> enum iio_modifier {
> diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
> index 0a5c2bb60030..3505450060e6 100644
> --- a/tools/iio/iio_event_monitor.c
> +++ b/tools/iio/iio_event_monitor.c
> @@ -59,6 +59,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_POSITIONRELATIVE] = "positionrelative",
> [IIO_PHASE] = "phase",
> [IIO_MASSCONCENTRATION] = "massconcentration",
> + [IIO_DELTA_ANGL] = "deltaangl",
> };
>
> static const char * const iio_ev_type_text[] = {
> @@ -173,6 +174,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_POSITIONRELATIVE:
> case IIO_PHASE:
> case IIO_MASSCONCENTRATION:
> + case IIO_DELTA_ANGL:
> break;
> default:
> return false;