Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

Commit

Permalink
IIO: Support oversampling_ratio configuration in IIO node
Browse files Browse the repository at this point in the history
Signed-off-by: Gu Chaojie <[email protected]>
  • Loading branch information
guchaojie committed Jan 24, 2017
1 parent 80a008e commit 11f9cbc
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/lib/io/include/sol-iio.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <sol-buffer.h>
#include <sol-common-buildopts.h>
#include <sol-str-table.h>

#include <linux/limits.h>

Expand Down Expand Up @@ -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;

/**
Expand Down
29 changes: 29 additions & 0 deletions src/lib/io/sol-iio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);

Expand Down
18 changes: 18 additions & 0 deletions src/modules/flow/iio/iio.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
52 changes: 51 additions & 1 deletion src/modules/flow/iio/nodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down

0 comments on commit 11f9cbc

Please sign in to comment.