diff --git a/src/lib/io/include/sol-iio.h b/src/lib/io/include/sol-iio.h index 572d04dd1..4278e2ec8 100644 --- a/src/lib/io/include/sol-iio.h +++ b/src/lib/io/include/sol-iio.h @@ -20,6 +20,7 @@ #include #include +#include #include @@ -80,6 +81,8 @@ typedef struct sol_iio_config { int buffer_size; /**< The size of reading buffer. 0: use device default; -1: disable buffer and readings will be performed on channel files on sysfs. */ int sampling_frequency; /**< Device sampling frequency. -1 uses device default */ char sampling_frequency_name[NAME_MAX]; /**< Sampling frequency sysfs node name. Some drivers expose the sampling frequency that is shared by channel type. Such as in_magn_sampling_frequency, in_accel_sampling_frequency. */ + struct sol_str_table *oversampling_ratio_table; /**< Hardware applied number of measurements for acquiring one data point. The HW will do [_name]_oversampling_ratio measurements and return the average value as output data. */ + } sol_iio_config; /** diff --git a/src/lib/io/sol-iio.c b/src/lib/io/sol-iio.c index 53937e224..962f2fa8c 100755 --- a/src/lib/io/sol-iio.c +++ b/src/lib/io/sol-iio.c @@ -135,6 +135,8 @@ static struct sol_vector iio_opened_devices = SOL_VECTOR_INIT(struct iio_opened_ #define SAMPLING_FREQUENCY_DEVICE_PATH SYSFS_DEVICES_PATH "/iio:device%d/sampling_frequency" #define CHANNEL_SAMPLING_FREQUENCY_DEVICE_PATH SYSFS_DEVICES_PATH "/iio:device%d/%ssampling_frequency" +#define CHANNEL_OVERSAMPLING_RATIO_DEVICE_PATH SYSFS_DEVICES_PATH "/iio:device%d/%soversampling_ratio" + #define SAMPLING_FREQUENCY_BUFFER_PATH SYSFS_DEVICES_PATH "/iio:device%d/buffer/sampling_frequency" #define SAMPLING_FREQUENCY_TRIGGER_PATH SYSFS_DEVICES_PATH "/trigger%d/sampling_frequency" @@ -653,6 +655,28 @@ channel_get_pure_name(const char *name) return NULL; } +static bool +iio_set_oversampling_ratio(struct sol_iio_device *device, const struct sol_iio_config *config) +{ + char path[PATH_MAX]; + struct sol_str_table *iter; + + SOL_NULL_CHECK(device, false); + + for (iter = config->oversampling_ratio_table; iter->key; iter++) { + if (!iter->val) + continue; + + if (craft_filename_path(path, sizeof(path), CHANNEL_OVERSAMPLING_RATIO_DEVICE_PATH, + device->device_id, iter->key)) { + if (sol_util_write_file(path, "%d", iter->val) <= 0) + return false; + } + } + + return true; +} + static bool iio_set_sampling_frequency(struct sol_iio_device *device, const struct sol_iio_config *config) { @@ -949,6 +973,11 @@ sol_iio_open(int device_id, const struct sol_iio_config *config) SOL_WRN("Could not set device%d sampling frequency", device->device_id); } + if (config->oversampling_ratio_table) { + if (!iio_set_oversampling_ratio(device, config)) + SOL_WRN("Could not set device%d oversampling ratio", device->device_id); + } + device->mount_matrix = calloc(MOUNT_MATRIX_LEN, sizeof(double)); SOL_NULL_CHECK_GOTO(device->mount_matrix, error); diff --git a/src/modules/flow/iio/iio.json b/src/modules/flow/iio/iio.json index 27e117b31..e500fbd18 100644 --- a/src/modules/flow/iio/iio.json +++ b/src/modules/flow/iio/iio.json @@ -217,6 +217,12 @@ "description": "Offset to be added to device raw readings", "name": "offset" }, + { + "data_type": "direction-vector", + "default": {}, + "description": "Oversampling ratio measurement of the sensor", + "name": "oversampling_ratio" + }, { "data_type": "int", "default": -1, @@ -344,6 +350,12 @@ "description": "Offset to be added to device raw readings", "name": "offset" }, + { + "data_type": "int", + "default": 0, + "description": "Oversampling ratio measurement of the sensor", + "name": "oversampling_ratio" + }, { "data_type": "int", "default": -1, @@ -471,6 +483,12 @@ "description": "Offset to be added to device raw readings", "name": "offset" }, + { + "data_type": "int", + "default": 0, + "description": "Oversampling ratio measurement of the sensor", + "name": "oversampling_ratio" + }, { "data_type": "int", "default": -1, diff --git a/src/modules/flow/iio/nodes.c b/src/modules/flow/iio/nodes.c index 8c79b9da0..bf704b00f 100644 --- a/src/modules/flow/iio/nodes.c +++ b/src/modules/flow/iio/nodes.c @@ -111,9 +111,19 @@ static void iio_common_close(struct sol_flow_node *node, void *data) { struct iio_device_config *mdata = data; + struct sol_str_table *iter; free((char *)mdata->config.trigger_name); + if (!mdata->config.oversampling_ratio_table) + goto end; + + for (iter = mdata->config.oversampling_ratio_table; iter->key; iter++) + free(iter->key); + + free(mdata->config.oversampling_ratio_table); + +end: if (mdata->device) sol_iio_close(mdata->device); } @@ -481,6 +491,7 @@ magnet_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_o const struct sol_flow_node_type_iio_magnetometer_options *opts; int device_id, ret; struct iio_node_type *type; + struct sol_str_table *table; type = (struct iio_node_type *)sol_flow_node_get_type(node); @@ -505,6 +516,22 @@ magnet_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_o SOL_INT_CHECK_GOTO(ret, >= (int)sizeof(mdata->iio_base.config.sampling_frequency_name), err); SOL_INT_CHECK_GOTO(ret, < 0, err); + mdata->iio_base.config.oversampling_ratio_table = calloc(4, sizeof(struct sol_str_table)); + SOL_NULL_CHECK(mdata->iio_base.config.oversampling_ratio_table, -ENOMEM); + + table = mdata->iio_base.config.oversampling_ratio_table; + table->key = strdup("in_magn_x_"); + table->len = strlen(table->key); + table->val = (int16_t)opts->oversampling_ratio.x; + table++; + table->key = strdup("in_magn_y_"); + table->len = strlen(table->key); + table->val = (int16_t)opts->oversampling_ratio.y; + table++; + table->key = strdup("in_magn_z_"); + table->len = strlen(table->key); + table->val = (int16_t)opts->oversampling_ratio.z; + if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; @@ -558,8 +585,9 @@ temperature_open(struct sol_flow_node *node, void *data, const struct sol_flow_n { struct iio_double_data *mdata = data; const struct sol_flow_node_type_iio_thermometer_options *opts; - int device_id; + int device_id, ret; struct iio_node_type *type; + struct sol_str_table *table; type = (struct iio_node_type *)sol_flow_node_get_type(node); @@ -579,6 +607,19 @@ temperature_open(struct sol_flow_node *node, void *data, const struct sol_flow_n mdata->iio_base.data_type = DOUBLE; mdata->iio_base.config.buffer_size = opts->buffer_size; mdata->iio_base.config.sampling_frequency = opts->sampling_frequency; + ret = snprintf(mdata->iio_base.config.sampling_frequency_name, + sizeof(mdata->iio_base.config.sampling_frequency_name), "%s", "in_temp_"); + SOL_INT_CHECK_GOTO(ret, >= (int)sizeof(mdata->iio_base.config.sampling_frequency_name), err); + SOL_INT_CHECK_GOTO(ret, < 0, err); + + mdata->iio_base.config.oversampling_ratio_table = calloc(2, sizeof(struct sol_str_table)); + SOL_NULL_CHECK(mdata->iio_base.config.oversampling_ratio_table, -ENOMEM); + + table = mdata->iio_base.config.oversampling_ratio_table; + table->key = strdup("in_temp_"); + table->len = strlen(table->key); + table->val = opts->oversampling_ratio; + if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; @@ -635,6 +676,7 @@ pressure_open(struct sol_flow_node *node, void *data, const struct sol_flow_node const struct sol_flow_node_type_iio_pressure_sensor_options *opts; int device_id, ret; struct iio_node_type *type; + struct sol_str_table *table; type = (struct iio_node_type *)sol_flow_node_get_type(node); @@ -659,6 +701,14 @@ pressure_open(struct sol_flow_node *node, void *data, const struct sol_flow_node SOL_INT_CHECK_GOTO(ret, >= (int)sizeof(mdata->iio_base.config.sampling_frequency_name), err); SOL_INT_CHECK_GOTO(ret, < 0, err); + mdata->iio_base.config.oversampling_ratio_table = calloc(2, sizeof(struct sol_str_table)); + SOL_NULL_CHECK(mdata->iio_base.config.oversampling_ratio_table, -ENOMEM); + + table = mdata->iio_base.config.oversampling_ratio_table; + table->key = strdup("in_pressure_"); + table->len = strlen(table->key); + table->val = opts->oversampling_ratio; + if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node;