tools: iio: convert iio_generic_buffer to use new IIO buffer API
This change makes use of the new IIO buffer API to read data from an IIO buffer. It doesn't read the /sys/bus/iio/devices/iio:deviceX/scan_elements dir anymore, it reads /sys/bus/iio/devices/iio:deviceX/bufferY, where all the scan_elements have been merged together with the old/classical buffer attributes. And it makes use of the new IIO_BUFFER_GET_FD_IOCTL ioctl to get an FD for the IIO buffer for which to read data from. It also does a quick sanity check to see that -EBUSY is returned if reading the chardev after the ioctl() has succeeded. This was tested with the following cases: 1. Tested buffer0 works with ioctl() 2. Tested that buffer0 can't be opened via /dev/iio:deviceX after ioctl() This check should be omitted under normal operation; it's being done here to check that the driver change is sane 3. Moved valid buffer0 to be buffer1, and tested that data comes from it Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> Link: https://lore.kernel.org/r/20210215104043.91251-25-alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
ebe5112535
commit
8827faab2c
@ -27,6 +27,7 @@ include $(srctree)/tools/build/Makefile.include
|
|||||||
#
|
#
|
||||||
$(OUTPUT)include/linux/iio: ../../include/uapi/linux/iio
|
$(OUTPUT)include/linux/iio: ../../include/uapi/linux/iio
|
||||||
mkdir -p $(OUTPUT)include/linux/iio 2>&1 || true
|
mkdir -p $(OUTPUT)include/linux/iio 2>&1 || true
|
||||||
|
ln -sf $(CURDIR)/../../include/uapi/linux/iio/buffer.h $@
|
||||||
ln -sf $(CURDIR)/../../include/uapi/linux/iio/events.h $@
|
ln -sf $(CURDIR)/../../include/uapi/linux/iio/events.h $@
|
||||||
ln -sf $(CURDIR)/../../include/uapi/linux/iio/types.h $@
|
ln -sf $(CURDIR)/../../include/uapi/linux/iio/types.h $@
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/iio/buffer.h>
|
||||||
#include "iio_utils.h"
|
#include "iio_utils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,7 +199,7 @@ static void process_scan(char *data, struct iio_channel_info *channels,
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enable_disable_all_channels(char *dev_dir_name, int enable)
|
static int enable_disable_all_channels(char *dev_dir_name, int buffer_idx, int enable)
|
||||||
{
|
{
|
||||||
const struct dirent *ent;
|
const struct dirent *ent;
|
||||||
char scanelemdir[256];
|
char scanelemdir[256];
|
||||||
@ -205,7 +207,7 @@ static int enable_disable_all_channels(char *dev_dir_name, int enable)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
snprintf(scanelemdir, sizeof(scanelemdir),
|
snprintf(scanelemdir, sizeof(scanelemdir),
|
||||||
FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
|
FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name, buffer_idx);
|
||||||
scanelemdir[sizeof(scanelemdir)-1] = '\0';
|
scanelemdir[sizeof(scanelemdir)-1] = '\0';
|
||||||
|
|
||||||
dp = opendir(scanelemdir);
|
dp = opendir(scanelemdir);
|
||||||
@ -243,6 +245,7 @@ static void print_usage(void)
|
|||||||
"Capture, convert and output data from IIO device buffer\n"
|
"Capture, convert and output data from IIO device buffer\n"
|
||||||
" -a Auto-activate all available channels\n"
|
" -a Auto-activate all available channels\n"
|
||||||
" -A Force-activate ALL channels\n"
|
" -A Force-activate ALL channels\n"
|
||||||
|
" -b <n> The buffer which to open (by index), default 0\n"
|
||||||
" -c <n> Do n conversions, or loop forever if n < 0\n"
|
" -c <n> Do n conversions, or loop forever if n < 0\n"
|
||||||
" -e Disable wait for event (new data)\n"
|
" -e Disable wait for event (new data)\n"
|
||||||
" -g Use trigger-less mode\n"
|
" -g Use trigger-less mode\n"
|
||||||
@ -259,6 +262,7 @@ static void print_usage(void)
|
|||||||
static enum autochan autochannels = AUTOCHANNELS_DISABLED;
|
static enum autochan autochannels = AUTOCHANNELS_DISABLED;
|
||||||
static char *dev_dir_name = NULL;
|
static char *dev_dir_name = NULL;
|
||||||
static char *buf_dir_name = NULL;
|
static char *buf_dir_name = NULL;
|
||||||
|
static int buffer_idx = 0;
|
||||||
static bool current_trigger_set = false;
|
static bool current_trigger_set = false;
|
||||||
|
|
||||||
static void cleanup(void)
|
static void cleanup(void)
|
||||||
@ -286,7 +290,7 @@ static void cleanup(void)
|
|||||||
|
|
||||||
/* Disable channels if auto-enabled */
|
/* Disable channels if auto-enabled */
|
||||||
if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
|
if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
|
||||||
ret = enable_disable_all_channels(dev_dir_name, 0);
|
ret = enable_disable_all_channels(dev_dir_name, buffer_idx, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
fprintf(stderr, "Failed to disable all channels\n");
|
fprintf(stderr, "Failed to disable all channels\n");
|
||||||
autochannels = AUTOCHANNELS_DISABLED;
|
autochannels = AUTOCHANNELS_DISABLED;
|
||||||
@ -333,7 +337,9 @@ int main(int argc, char **argv)
|
|||||||
unsigned long long j;
|
unsigned long long j;
|
||||||
unsigned long toread;
|
unsigned long toread;
|
||||||
int ret, c;
|
int ret, c;
|
||||||
int fp = -1;
|
struct stat st;
|
||||||
|
int fd = -1;
|
||||||
|
int buf_fd = -1;
|
||||||
|
|
||||||
int num_channels = 0;
|
int num_channels = 0;
|
||||||
char *trigger_name = NULL, *device_name = NULL;
|
char *trigger_name = NULL, *device_name = NULL;
|
||||||
@ -352,7 +358,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
register_cleanup();
|
register_cleanup();
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "aAc:egl:n:N:t:T:w:?", longopts,
|
while ((c = getopt_long(argc, argv, "aAb:c:egl:n:N:t:T:w:?", longopts,
|
||||||
NULL)) != -1) {
|
NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -361,7 +367,20 @@ int main(int argc, char **argv)
|
|||||||
case 'A':
|
case 'A':
|
||||||
autochannels = AUTOCHANNELS_ENABLED;
|
autochannels = AUTOCHANNELS_ENABLED;
|
||||||
force_autochannels = true;
|
force_autochannels = true;
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
errno = 0;
|
||||||
|
buffer_idx = strtoll(optarg, &dummy, 10);
|
||||||
|
if (errno) {
|
||||||
|
ret = -errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (buffer_idx < 0) {
|
||||||
|
ret = -ERANGE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
errno = 0;
|
errno = 0;
|
||||||
num_loops = strtoll(optarg, &dummy, 10);
|
num_loops = strtoll(optarg, &dummy, 10);
|
||||||
@ -518,7 +537,7 @@ int main(int argc, char **argv)
|
|||||||
* Parse the files in scan_elements to identify what channels are
|
* Parse the files in scan_elements to identify what channels are
|
||||||
* present
|
* present
|
||||||
*/
|
*/
|
||||||
ret = build_channel_array(dev_dir_name, &channels, &num_channels);
|
ret = build_channel_array(dev_dir_name, buffer_idx, &channels, &num_channels);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fprintf(stderr, "Problem reading scan element information\n"
|
fprintf(stderr, "Problem reading scan element information\n"
|
||||||
"diag %s\n", dev_dir_name);
|
"diag %s\n", dev_dir_name);
|
||||||
@ -535,7 +554,7 @@ int main(int argc, char **argv)
|
|||||||
(autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) {
|
(autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) {
|
||||||
fprintf(stderr, "Enabling all channels\n");
|
fprintf(stderr, "Enabling all channels\n");
|
||||||
|
|
||||||
ret = enable_disable_all_channels(dev_dir_name, 1);
|
ret = enable_disable_all_channels(dev_dir_name, buffer_idx, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fprintf(stderr, "Failed to enable all channels\n");
|
fprintf(stderr, "Failed to enable all channels\n");
|
||||||
goto error;
|
goto error;
|
||||||
@ -544,7 +563,7 @@ int main(int argc, char **argv)
|
|||||||
/* This flags that we need to disable the channels again */
|
/* This flags that we need to disable the channels again */
|
||||||
autochannels = AUTOCHANNELS_ACTIVE;
|
autochannels = AUTOCHANNELS_ACTIVE;
|
||||||
|
|
||||||
ret = build_channel_array(dev_dir_name, &channels,
|
ret = build_channel_array(dev_dir_name, buffer_idx, &channels,
|
||||||
&num_channels);
|
&num_channels);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fprintf(stderr, "Problem reading scan element "
|
fprintf(stderr, "Problem reading scan element "
|
||||||
@ -565,7 +584,7 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Enable channels manually in "
|
fprintf(stderr, "Enable channels manually in "
|
||||||
FORMAT_SCAN_ELEMENTS_DIR
|
FORMAT_SCAN_ELEMENTS_DIR
|
||||||
"/*_en or pass -a to autoenable channels and "
|
"/*_en or pass -a to autoenable channels and "
|
||||||
"try again.\n", dev_dir_name);
|
"try again.\n", dev_dir_name, buffer_idx);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -576,12 +595,25 @@ int main(int argc, char **argv)
|
|||||||
* be built rather than found.
|
* be built rather than found.
|
||||||
*/
|
*/
|
||||||
ret = asprintf(&buf_dir_name,
|
ret = asprintf(&buf_dir_name,
|
||||||
"%siio:device%d/buffer", iio_dir, dev_num);
|
"%siio:device%d/buffer%d", iio_dir, dev_num, buffer_idx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat(buf_dir_name, &st)) {
|
||||||
|
fprintf(stderr, "Could not stat() '%s', got error %d: %s\n",
|
||||||
|
buf_dir_name, errno, strerror(errno));
|
||||||
|
ret = -errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
|
fprintf(stderr, "File '%s' is not a directory\n", buf_dir_name);
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!notrigger) {
|
if (!notrigger) {
|
||||||
printf("%s %s\n", dev_dir_name, trigger_name);
|
printf("%s %s\n", dev_dir_name, trigger_name);
|
||||||
/*
|
/*
|
||||||
@ -598,6 +630,35 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
|
||||||
|
if (ret < 0) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to open non blocking the access dev */
|
||||||
|
fd = open(buffer_access, O_RDONLY | O_NONBLOCK);
|
||||||
|
if (fd == -1) { /* TODO: If it isn't there make the node */
|
||||||
|
ret = -errno;
|
||||||
|
fprintf(stderr, "Failed to open %s\n", buffer_access);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* specify for which buffer index we want an FD */
|
||||||
|
buf_fd = buffer_idx;
|
||||||
|
|
||||||
|
ret = ioctl(fd, IIO_BUFFER_GET_FD_IOCTL, &buf_fd);
|
||||||
|
if (ret == -1 || buf_fd == -1) {
|
||||||
|
ret = -errno;
|
||||||
|
if (ret == -ENODEV || ret == -EINVAL)
|
||||||
|
fprintf(stderr,
|
||||||
|
"Device does not have this many buffers\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Failed to retrieve buffer fd\n");
|
||||||
|
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup ring buffer parameters */
|
/* Setup ring buffer parameters */
|
||||||
ret = write_sysfs_int("length", buf_dir_name, buf_len);
|
ret = write_sysfs_int("length", buf_dir_name, buf_len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -607,7 +668,8 @@ int main(int argc, char **argv)
|
|||||||
ret = write_sysfs_int("enable", buf_dir_name, 1);
|
ret = write_sysfs_int("enable", buf_dir_name, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to enable buffer: %s\n", strerror(-ret));
|
"Failed to enable buffer '%s': %s\n",
|
||||||
|
buf_dir_name, strerror(-ret));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,24 +680,30 @@ int main(int argc, char **argv)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
|
/**
|
||||||
if (ret < 0) {
|
* This check is being done here for sanity reasons, however it
|
||||||
ret = -ENOMEM;
|
* should be omitted under normal operation.
|
||||||
goto error;
|
* If this is buffer0, we check that we get EBUSY after this point.
|
||||||
|
*/
|
||||||
|
if (buffer_idx == 0) {
|
||||||
|
errno = 0;
|
||||||
|
read_size = read(fd, data, 1);
|
||||||
|
if (read_size > -1 || errno != EBUSY) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
perror("Reading from '%s' should not be possible after ioctl()");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to open non blocking the access dev */
|
/* close now the main chardev FD and let the buffer FD work */
|
||||||
fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
|
if (close(fd) == -1)
|
||||||
if (fp == -1) { /* TODO: If it isn't there make the node */
|
perror("Failed to close character device file");
|
||||||
ret = -errno;
|
fd = -1;
|
||||||
fprintf(stderr, "Failed to open %s\n", buffer_access);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < num_loops || num_loops < 0; j++) {
|
for (j = 0; j < num_loops || num_loops < 0; j++) {
|
||||||
if (!noevents) {
|
if (!noevents) {
|
||||||
struct pollfd pfd = {
|
struct pollfd pfd = {
|
||||||
.fd = fp,
|
.fd = buf_fd,
|
||||||
.events = POLLIN,
|
.events = POLLIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -653,7 +721,7 @@ int main(int argc, char **argv)
|
|||||||
toread = 64;
|
toread = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_size = read(fp, data, toread * scan_size);
|
read_size = read(buf_fd, data, toread * scan_size);
|
||||||
if (read_size < 0) {
|
if (read_size < 0) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
fprintf(stderr, "nothing available\n");
|
fprintf(stderr, "nothing available\n");
|
||||||
@ -670,7 +738,9 @@ int main(int argc, char **argv)
|
|||||||
error:
|
error:
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
if (fp >= 0 && close(fp) == -1)
|
if (fd >= 0 && close(fd) == -1)
|
||||||
|
perror("Failed to close character device");
|
||||||
|
if (buf_fd >= 0 && close(buf_fd) == -1)
|
||||||
perror("Failed to close buffer");
|
perror("Failed to close buffer");
|
||||||
free(buffer_access);
|
free(buffer_access);
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -77,6 +77,7 @@ int iioutils_break_up_name(const char *full_name, char **generic_name)
|
|||||||
* @mask: output a bit mask for the raw data
|
* @mask: output a bit mask for the raw data
|
||||||
* @be: output if data in big endian
|
* @be: output if data in big endian
|
||||||
* @device_dir: the IIO device directory
|
* @device_dir: the IIO device directory
|
||||||
|
* @buffer_idx: the IIO buffer index
|
||||||
* @name: the channel name
|
* @name: the channel name
|
||||||
* @generic_name: the channel type name
|
* @generic_name: the channel type name
|
||||||
*
|
*
|
||||||
@ -85,8 +86,8 @@ int iioutils_break_up_name(const char *full_name, char **generic_name)
|
|||||||
static int iioutils_get_type(unsigned int *is_signed, unsigned int *bytes,
|
static int iioutils_get_type(unsigned int *is_signed, unsigned int *bytes,
|
||||||
unsigned int *bits_used, unsigned int *shift,
|
unsigned int *bits_used, unsigned int *shift,
|
||||||
uint64_t *mask, unsigned int *be,
|
uint64_t *mask, unsigned int *be,
|
||||||
const char *device_dir, const char *name,
|
const char *device_dir, int buffer_idx,
|
||||||
const char *generic_name)
|
const char *name, const char *generic_name)
|
||||||
{
|
{
|
||||||
FILE *sysfsfp;
|
FILE *sysfsfp;
|
||||||
int ret;
|
int ret;
|
||||||
@ -96,7 +97,7 @@ static int iioutils_get_type(unsigned int *is_signed, unsigned int *bytes,
|
|||||||
unsigned padint;
|
unsigned padint;
|
||||||
const struct dirent *ent;
|
const struct dirent *ent;
|
||||||
|
|
||||||
ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
|
ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir, buffer_idx);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -304,12 +305,13 @@ void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt)
|
|||||||
/**
|
/**
|
||||||
* build_channel_array() - function to figure out what channels are present
|
* build_channel_array() - function to figure out what channels are present
|
||||||
* @device_dir: the IIO device directory in sysfs
|
* @device_dir: the IIO device directory in sysfs
|
||||||
|
* @buffer_idx: the IIO buffer for this channel array
|
||||||
* @ci_array: output the resulting array of iio_channel_info
|
* @ci_array: output the resulting array of iio_channel_info
|
||||||
* @counter: output the amount of array elements
|
* @counter: output the amount of array elements
|
||||||
*
|
*
|
||||||
* Returns 0 on success, otherwise a negative error code.
|
* Returns 0 on success, otherwise a negative error code.
|
||||||
**/
|
**/
|
||||||
int build_channel_array(const char *device_dir,
|
int build_channel_array(const char *device_dir, int buffer_idx,
|
||||||
struct iio_channel_info **ci_array, int *counter)
|
struct iio_channel_info **ci_array, int *counter)
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
@ -322,7 +324,7 @@ int build_channel_array(const char *device_dir,
|
|||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
*counter = 0;
|
*counter = 0;
|
||||||
ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
|
ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir, buffer_idx);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -503,6 +505,7 @@ int build_channel_array(const char *device_dir,
|
|||||||
¤t->mask,
|
¤t->mask,
|
||||||
¤t->be,
|
¤t->be,
|
||||||
device_dir,
|
device_dir,
|
||||||
|
buffer_idx,
|
||||||
current->name,
|
current->name,
|
||||||
current->generic_name);
|
current->generic_name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
/* Made up value to limit allocation sizes */
|
/* Made up value to limit allocation sizes */
|
||||||
#define IIO_MAX_NAME_LENGTH 64
|
#define IIO_MAX_NAME_LENGTH 64
|
||||||
|
|
||||||
#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
|
#define FORMAT_SCAN_ELEMENTS_DIR "%s/buffer%d"
|
||||||
#define FORMAT_TYPE_FILE "%s_type"
|
#define FORMAT_TYPE_FILE "%s_type"
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
@ -61,7 +61,7 @@ int iioutils_get_param_float(float *output, const char *param_name,
|
|||||||
const char *device_dir, const char *name,
|
const char *device_dir, const char *name,
|
||||||
const char *generic_name);
|
const char *generic_name);
|
||||||
void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt);
|
void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt);
|
||||||
int build_channel_array(const char *device_dir,
|
int build_channel_array(const char *device_dir, int buffer_idx,
|
||||||
struct iio_channel_info **ci_array, int *counter);
|
struct iio_channel_info **ci_array, int *counter);
|
||||||
int find_type_by_name(const char *name, const char *type);
|
int find_type_by_name(const char *name, const char *type);
|
||||||
int write_sysfs_int(const char *filename, const char *basedir, int val);
|
int write_sysfs_int(const char *filename, const char *basedir, int val);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user