summaryrefslogtreecommitdiffstats
path: root/libsensors_iio/software/simple_apps/mpu_iio
diff options
context:
space:
mode:
Diffstat (limited to 'libsensors_iio/software/simple_apps/mpu_iio')
-rw-r--r--libsensors_iio/software/simple_apps/mpu_iio/build/android/inv_mpu_iio-sharedbin0 -> 25516 bytes
-rw-r--r--libsensors_iio/software/simple_apps/mpu_iio/build/android/shared.mk96
-rw-r--r--libsensors_iio/software/simple_apps/mpu_iio/build/filelist.mk12
-rw-r--r--libsensors_iio/software/simple_apps/mpu_iio/iio_utils.h643
-rw-r--r--libsensors_iio/software/simple_apps/mpu_iio/mpu_iio.c685
5 files changed, 1436 insertions, 0 deletions
diff --git a/libsensors_iio/software/simple_apps/mpu_iio/build/android/inv_mpu_iio-shared b/libsensors_iio/software/simple_apps/mpu_iio/build/android/inv_mpu_iio-shared
new file mode 100644
index 0000000..14ca523
--- /dev/null
+++ b/libsensors_iio/software/simple_apps/mpu_iio/build/android/inv_mpu_iio-shared
Binary files differ
diff --git a/libsensors_iio/software/simple_apps/mpu_iio/build/android/shared.mk b/libsensors_iio/software/simple_apps/mpu_iio/build/android/shared.mk
new file mode 100644
index 0000000..cd79cfa
--- /dev/null
+++ b/libsensors_iio/software/simple_apps/mpu_iio/build/android/shared.mk
@@ -0,0 +1,96 @@
+EXEC = inv_mpu_iio$(SHARED_APP_SUFFIX)
+
+MK_NAME = $(notdir $(CURDIR)/$(firstword $(MAKEFILE_LIST)))
+
+CROSS ?= $(ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
+COMP ?= $(CROSS)gcc
+LINK ?= $(CROSS)gcc
+
+OBJFOLDER = $(CURDIR)/obj
+
+INV_ROOT = ../../../../..
+APP_DIR = $(CURDIR)/../..
+MLLITE_DIR = $(INV_ROOT)/software/core/mllite
+MPL_DIR = $(INV_ROOT)/software/core/mpl
+
+include $(INV_ROOT)/software/build/android/common.mk
+
+CFLAGS += $(CMDLINE_CFLAGS)
+CFLAGS += $(ANDROID_COMPILE)
+CFLAGS += -Wall
+CFLAGS += -fpic
+CFLAGS += -nostdlib
+CFLAGS += -DNDEBUG
+CFLAGS += -D_REENTRANT
+CFLAGS += -DLINUX
+CFLAGS += -DANDROID
+CFLAGS += -mthumb-interwork
+CFLAGS += -fno-exceptions
+CFLAGS += -ffunction-sections
+CFLAGS += -funwind-tables
+CFLAGS += -fstack-protector
+CFLAGS += -fno-short-enums
+CFLAGS += -fmessage-length=0
+CFLAGS += -I$(MLLITE_DIR)
+CFLAGS += -I$(MPL_DIR)
+CFLAGS += -I$(COMMON_DIR)
+CFLAGS += -I$(HAL_DIR)/include
+CFLAGS += $(INV_INCLUDES)
+CFLAGS += $(INV_DEFINES)
+
+LLINK = -lc
+LLINK += -lm
+LLINK += -lutils
+LLINK += -lcutils
+LLINK += -lgcc
+LLINK += -ldl
+LLINK += -lstdc++
+LLINK += -llog
+LLINK += -lz
+
+LFLAGS += $(CMDLINE_LFLAGS)
+LFLAGS += $(ANDROID_LINK_EXECUTABLE)
+
+LRPATH = -Wl,-rpath,$(ANDROID_ROOT)/out/target/product/$(PRODUCT)/obj/lib:$(ANDROID_ROOT)/out/target/product/$(PRODUCT)/system/lib
+
+####################################################################################################
+## sources
+
+INV_LIBS = $(MPL_DIR)/build/$(TARGET)/$(LIB_PREFIX)$(MPL_LIB_NAME).$(SHARED_LIB_EXT)
+INV_LIBS += $(MLLITE_DIR)/build/$(TARGET)/$(LIB_PREFIX)$(MLLITE_LIB_NAME).$(SHARED_LIB_EXT)
+
+#INV_SOURCES and VPATH provided by Makefile.filelist
+include ../filelist.mk
+
+INV_OBJS := $(addsuffix .o,$(INV_SOURCES))
+INV_OBJS_DST = $(addprefix $(OBJFOLDER)/,$(addsuffix .o, $(notdir $(INV_SOURCES))))
+
+####################################################################################################
+## rules
+
+.PHONY: all clean cleanall install
+
+all: $(EXEC) $(MK_NAME)
+
+$(EXEC) : $(OBJFOLDER) $(INV_OBJS_DST) $(INV_LIBS) $(MK_NAME)
+ @$(call echo_in_colors, "\n<linking $(EXEC) with objects $(INV_OBJS_DST) $(PREBUILT_OBJS) and libraries $(INV_LIBS)\n")
+ $(LINK) $(INV_OBJS_DST) -o $(EXEC) $(LFLAGS) $(LLINK) $(INV_LIBS) $(LLINK) $(LRPATH)
+
+$(OBJFOLDER) :
+ @$(call echo_in_colors, "\n<creating object's folder 'obj/'>\n")
+ mkdir obj
+
+$(INV_OBJS_DST) : $(OBJFOLDER)/%.c.o : %.c $(MK_NAME)
+ @$(call echo_in_colors, "\n<compile $< to $(OBJFOLDER)/$(notdir $@)>\n")
+ $(COMP) $(ANDROID_INCLUDES) $(KERNEL_INCLUDES) $(INV_INCLUDES) $(CFLAGS) -o $@ -c $<
+
+clean :
+ rm -fR $(OBJFOLDER)
+
+cleanall :
+ rm -fR $(EXEC) $(OBJFOLDER)
+
+install : $(EXEC)
+ cp -f $(EXEC) $(INSTALL_DIR)
+
+
diff --git a/libsensors_iio/software/simple_apps/mpu_iio/build/filelist.mk b/libsensors_iio/software/simple_apps/mpu_iio/build/filelist.mk
new file mode 100644
index 0000000..8a3977a
--- /dev/null
+++ b/libsensors_iio/software/simple_apps/mpu_iio/build/filelist.mk
@@ -0,0 +1,12 @@
+#### filelist.mk for mpu_iio ####
+
+# headers
+#HEADERS += $(HAL_DIR)/include/inv_sysfs_utils.h
+HEADERS += $(APP_DIR)/iio_utils.h
+
+# sources
+SOURCES := $(APP_DIR)/mpu_iio.c
+
+INV_SOURCES += $(SOURCES)
+
+VPATH += $(APP_DIR) $(COMMON_DIR) $(HAL_DIR)/linux
diff --git a/libsensors_iio/software/simple_apps/mpu_iio/iio_utils.h b/libsensors_iio/software/simple_apps/mpu_iio/iio_utils.h
new file mode 100644
index 0000000..773ff2c
--- /dev/null
+++ b/libsensors_iio/software/simple_apps/mpu_iio/iio_utils.h
@@ -0,0 +1,643 @@
+/* IIO - useful set of util functionality
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+/* Made up value to limit allocation sizes */
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <dirent.h>
+
+#define IIO_MAX_NAME_LENGTH 30
+
+#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
+#define FORMAT_TYPE_FILE "%s_type"
+
+const char *iio_dir = "/sys/bus/iio/devices/";
+
+/**
+ * iioutils_break_up_name() - extract generic name from full channel name
+ * @full_name: the full channel name
+ * @generic_name: the output generic channel name
+ **/
+static int iioutils_break_up_name(const char *full_name,
+ char **generic_name)
+{
+ char *current;
+ char *w, *r;
+ char *working;
+ current = strdup(full_name);
+ working = strtok(current, "_\0");
+ w = working;
+ r = working;
+
+ while (*r != '\0') {
+ if (!isdigit(*r)) {
+ *w = *r;
+ w++;
+ }
+ r++;
+ }
+ *w = '\0';
+ *generic_name = strdup(working);
+ free(current);
+
+ return 0;
+}
+
+/**
+ * struct iio_channel_info - information about a given channel
+ * @name: channel name
+ * @generic_name: general name for channel type
+ * @scale: scale factor to be applied for conversion to si units
+ * @offset: offset to be applied for conversion to si units
+ * @index: the channel index in the buffer output
+ * @bytes: number of bytes occupied in buffer output
+ * @mask: a bit mask for the raw output
+ * @is_signed: is the raw value stored signed
+ * @enabled: is this channel enabled
+ **/
+struct iio_channel_info {
+ char *name;
+ char *generic_name;
+ float scale;
+ float offset;
+ unsigned index;
+ unsigned bytes;
+ unsigned bits_used;
+ unsigned shift;
+ uint64_t mask;
+ unsigned be;
+ unsigned is_signed;
+ unsigned enabled;
+ unsigned location;
+};
+
+/**
+ * iioutils_get_type() - find and process _type attribute data
+ * @is_signed: output whether channel is signed
+ * @bytes: output how many bytes the channel storage occupies
+ * @mask: output a bit mask for the raw data
+ * @be: big endian
+ * @device_dir: the iio device directory
+ * @name: the channel name
+ * @generic_name: the channel type name
+ **/
+inline int iioutils_get_type(unsigned *is_signed,
+ unsigned *bytes,
+ unsigned *bits_used,
+ unsigned *shift,
+ uint64_t *mask,
+ unsigned *be,
+ const char *device_dir,
+ const char *name,
+ const char *generic_name)
+{
+ FILE *sysfsfp;
+ int ret;
+ DIR *dp;
+ char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
+ char signchar, endianchar;
+ unsigned padint;
+ const struct dirent *ent;
+
+ ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_free_scan_el_dir;
+ }
+ ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_free_builtname;
+ }
+
+ dp = opendir(scan_el_dir);
+ if (dp == NULL) {
+ ret = -errno;
+ goto error_free_builtname_generic;
+ }
+ while (ent = readdir(dp), ent != NULL)
+ /*
+ * Do we allow devices to override a generic name with
+ * a specific one?
+ */
+ if ((strcmp(builtname, ent->d_name) == 0) ||
+ (strcmp(builtname_generic, ent->d_name) == 0)) {
+ ret = asprintf(&filename,
+ "%s/%s", scan_el_dir, ent->d_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_closedir;
+ }
+ sysfsfp = fopen(filename, "r");
+ if (sysfsfp == NULL) {
+ printf("failed to open %s\n", filename);
+ ret = -errno;
+ goto error_free_filename;
+ }
+
+ ret = fscanf(sysfsfp,
+ "%ce:%c%u/%u>>%u",
+ &endianchar,
+ &signchar,
+ bits_used,
+ &padint, shift);
+ if (ret < 0) {
+ printf("failed to pass scan type description\n");
+ return ret;
+ }
+ *be = (endianchar == 'b');
+ *bytes = padint / 8;
+ if (*bits_used == 64)
+ *mask = ~0;
+ else
+ *mask = (1 << *bits_used) - 1;
+ if (signchar == 's')
+ *is_signed = 1;
+ else
+ *is_signed = 0;
+ fclose(sysfsfp);
+ free(filename);
+
+ filename = 0;
+ }
+error_free_filename:
+ if (filename)
+ free(filename);
+error_closedir:
+ closedir(dp);
+error_free_builtname_generic:
+ free(builtname_generic);
+error_free_builtname:
+ free(builtname);
+error_free_scan_el_dir:
+ free(scan_el_dir);
+error_ret:
+ return ret;
+}
+
+inline int iioutils_get_param_float(float *output,
+ const char *param_name,
+ const char *device_dir,
+ const char *name,
+ const char *generic_name)
+{
+ FILE *sysfsfp;
+ int ret;
+ DIR *dp;
+ char *builtname, *builtname_generic;
+ char *filename = NULL;
+ const struct dirent *ent;
+
+ ret = asprintf(&builtname, "%s_%s", name, param_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ ret = asprintf(&builtname_generic,
+ "%s_%s", generic_name, param_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_free_builtname;
+ }
+ dp = opendir(device_dir);
+ if (dp == NULL) {
+ ret = -errno;
+ goto error_free_builtname_generic;
+ }
+ while (ent = readdir(dp), ent != NULL)
+ if ((strcmp(builtname, ent->d_name) == 0) ||
+ (strcmp(builtname_generic, ent->d_name) == 0)) {
+ ret = asprintf(&filename,
+ "%s/%s", device_dir, ent->d_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_closedir;
+ }
+ sysfsfp = fopen(filename, "r");
+ if (!sysfsfp) {
+ ret = -errno;
+ goto error_free_filename;
+ }
+ fscanf(sysfsfp, "%f", output);
+ break;
+ }
+error_free_filename:
+ if (filename)
+ free(filename);
+error_closedir:
+ closedir(dp);
+error_free_builtname_generic:
+ free(builtname_generic);
+error_free_builtname:
+ free(builtname);
+error_ret:
+ return ret;
+}
+
+/**
+ * bsort_channel_array_by_index() - reorder so that the array is in index order
+ *
+ **/
+
+inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
+ int cnt)
+{
+
+ struct iio_channel_info temp;
+ int x, y;
+
+ for (x = 0; x < cnt; x++)
+ for (y = 0; y < (cnt - 1); y++)
+ if ((*ci_array)[y].index > (*ci_array)[y+1].index) {
+ temp = (*ci_array)[y + 1];
+ (*ci_array)[y + 1] = (*ci_array)[y];
+ (*ci_array)[y] = temp;
+ }
+}
+
+/**
+ * build_channel_array() - function to figure out what channels are present
+ * @device_dir: the IIO device directory in sysfs
+ * @
+ **/
+inline int build_channel_array(const char *device_dir,
+ struct iio_channel_info **ci_array,
+ int *counter)
+{
+ DIR *dp;
+ FILE *sysfsfp;
+ int count, i;
+ struct iio_channel_info *current;
+ int ret;
+ const struct dirent *ent;
+ char *scan_el_dir;
+ char *filename;
+
+ *counter = 0;
+ ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ dp = opendir(scan_el_dir);
+ if (dp == NULL) {
+ ret = -errno;
+ goto error_free_name;
+ }
+ while (ent = readdir(dp), ent != NULL)
+ if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
+ "_en") == 0) {
+ ret = asprintf(&filename,
+ "%s/%s", scan_el_dir, ent->d_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_close_dir;
+ }
+ sysfsfp = fopen(filename, "r");
+ if (sysfsfp == NULL) {
+ ret = -errno;
+ free(filename);
+ goto error_close_dir;
+ }
+ fscanf(sysfsfp, "%u", &ret);
+ printf("%s, %d\n", filename, ret);
+ if (ret == 1)
+ (*counter)++;
+ fclose(sysfsfp);
+ free(filename);
+ }
+ *ci_array = malloc(sizeof(**ci_array) * (*counter));
+ if (*ci_array == NULL) {
+ ret = -ENOMEM;
+ goto error_close_dir;
+ }
+ closedir(dp);
+ dp = opendir(scan_el_dir);
+ //seekdir(dp, 0);
+ count = 0;
+ while (ent = readdir(dp), ent != NULL) {
+ if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
+ "_en") == 0) {
+ current = &(*ci_array)[count++];
+ ret = asprintf(&filename,
+ "%s/%s", scan_el_dir, ent->d_name);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ /* decrement count to avoid freeing name */
+ count--;
+ goto error_cleanup_array;
+ }
+ sysfsfp = fopen(filename, "r");
+ if (sysfsfp == NULL) {
+ free(filename);
+ ret = -errno;
+ goto error_cleanup_array;
+ }
+ fscanf(sysfsfp, "%u", &current->enabled);
+ fclose(sysfsfp);
+
+ if (!current->enabled) {
+ free(filename);
+ count--;
+ continue;
+ }
+
+ current->scale = 1.0;
+ current->offset = 0;
+ current->name = strndup(ent->d_name,
+ strlen(ent->d_name) -
+ strlen("_en"));
+ if (current->name == NULL) {
+ free(filename);
+ ret = -ENOMEM;
+ goto error_cleanup_array;
+ }
+ /* Get the generic and specific name elements */
+ ret = iioutils_break_up_name(current->name,
+ &current->generic_name);
+ if (ret) {
+ free(filename);
+ goto error_cleanup_array;
+ }
+ ret = asprintf(&filename,
+ "%s/%s_index",
+ scan_el_dir,
+ current->name);
+ if (ret < 0) {
+ free(filename);
+ ret = -ENOMEM;
+ goto error_cleanup_array;
+ }
+ sysfsfp = fopen(filename, "r");
+ fscanf(sysfsfp, "%u", &current->index);
+ fclose(sysfsfp);
+ free(filename);
+ /* Find the scale */
+ ret = iioutils_get_param_float(&current->scale,
+ "scale",
+ device_dir,
+ current->name,
+ current->generic_name);
+ if (ret < 0)
+ goto error_cleanup_array;
+ ret = iioutils_get_param_float(&current->offset,
+ "offset",
+ device_dir,
+ current->name,
+ current->generic_name);
+ if (ret < 0)
+ goto error_cleanup_array;
+ ret = iioutils_get_type(&current->is_signed,
+ &current->bytes,
+ &current->bits_used,
+ &current->shift,
+ &current->mask,
+ &current->be,
+ device_dir,
+ current->name,
+ current->generic_name);
+ }
+ }
+
+ closedir(dp);
+ /* reorder so that the array is in index order */
+ bsort_channel_array_by_index(ci_array, *counter);
+
+ return 0;
+
+error_cleanup_array:
+ for (i = count - 1; i >= 0; i--)
+ free((*ci_array)[i].name);
+ free(*ci_array);
+error_close_dir:
+ closedir(dp);
+error_free_name:
+ free(scan_el_dir);
+error_ret:
+ return ret;
+}
+
+inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
+{
+ int ret;
+ FILE *sysfsfp;
+ int test;
+ char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
+ if (temp == NULL)
+ return -ENOMEM;
+ sprintf(temp, "%s/%s", basedir, filename);
+ sysfsfp = fopen(temp, "w");
+ if (sysfsfp == NULL) {
+ printf("failed to open %s\n", temp);
+ ret = -errno;
+ goto error_free;
+ }
+ fprintf(sysfsfp, "%d", val);
+ fclose(sysfsfp);
+ if (verify) {
+ sysfsfp = fopen(temp, "r");
+ if (sysfsfp == NULL) {
+ printf("failed to open %s\n", temp);
+ ret = -errno;
+ goto error_free;
+ }
+ fscanf(sysfsfp, "%d", &test);
+ if (test != val) {
+ printf("Possible failure in int write %d to %s%s\n",
+ val,
+ basedir,
+ filename);
+ ret = -1;
+ }
+ }
+error_free:
+ free(temp);
+ return ret;
+}
+
+int write_sysfs_int(char *filename, char *basedir, int val)
+{
+ return _write_sysfs_int(filename, basedir, val, 0);
+}
+
+int write_sysfs_int_and_verify(char *filename, char *basedir, int val)
+{
+ return _write_sysfs_int(filename, basedir, val, 1);
+}
+
+int _write_sysfs_string(char *filename, char *basedir, char *val, int verify)
+{
+ int ret = 0;
+ FILE *sysfsfp;
+ char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
+ if (temp == NULL) {
+ printf("Memory allocation failed\n");
+ return -ENOMEM;
+ }
+ sprintf(temp, "%s/%s", basedir, filename);
+ sysfsfp = fopen(temp, "w");
+ if (sysfsfp == NULL) {
+ printf("Could not open %s\n", temp);
+ ret = -errno;
+ goto error_free;
+ }
+ fprintf(sysfsfp, "%s", val);
+ fclose(sysfsfp);
+ if (verify) {
+ sysfsfp = fopen(temp, "r");
+ if (sysfsfp == NULL) {
+ printf("could not open file to verify\n");
+ ret = -errno;
+ goto error_free;
+ }
+ fscanf(sysfsfp, "%s", temp);
+ if (strcmp(temp, val) != 0) {
+ printf("Possible failure in string write of %s "
+ "Should be %s "
+ "written to %s\%s\n",
+ temp,
+ val,
+ basedir,
+ filename);
+ ret = -1;
+ }
+ }
+error_free:
+ free(temp);
+
+ return ret;
+}
+
+/**
+ * write_sysfs_string_and_verify() - string write, readback and verify
+ * @filename: name of file to write to
+ * @basedir: the sysfs directory in which the file is to be found
+ * @val: the string to write
+ **/
+int write_sysfs_string_and_verify(char *filename, char *basedir, char *val)
+{
+ return _write_sysfs_string(filename, basedir, val, 1);
+}
+
+int write_sysfs_string(char *filename, char *basedir, char *val)
+{
+ return _write_sysfs_string(filename, basedir, val, 0);
+}
+
+int read_sysfs_posint(char *filename, char *basedir)
+{
+ int ret;
+ FILE *sysfsfp;
+ char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
+ if (temp == NULL) {
+ printf("Memory allocation failed");
+ return -ENOMEM;
+ }
+ sprintf(temp, "%s/%s", basedir, filename);
+ sysfsfp = fopen(temp, "r");
+ if (sysfsfp == NULL) {
+ ret = -errno;
+ goto error_free;
+ }
+ fscanf(sysfsfp, "%d\n", &ret);
+ fclose(sysfsfp);
+error_free:
+ free(temp);
+ return ret;
+}
+
+int read_sysfs_float(char *filename, char *basedir, float *val)
+{
+ float ret = 0;
+ FILE *sysfsfp;
+ char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
+ if (temp == NULL) {
+ printf("Memory allocation failed");
+ return -ENOMEM;
+ }
+ sprintf(temp, "%s/%s", basedir, filename);
+ sysfsfp = fopen(temp, "r");
+ if (sysfsfp == NULL) {
+ ret = -errno;
+ goto error_free;
+ }
+ fscanf(sysfsfp, "%f\n", val);
+ fclose(sysfsfp);
+error_free:
+ free(temp);
+ return ret;
+}
+int enable(const char *device_dir,
+ struct iio_channel_info **ci_array,
+ int *counter)
+{
+ DIR *dp;
+ int ret;
+ const struct dirent *ent;
+ char *scan_el_dir;
+
+ *counter = 0;
+ ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ dp = opendir(scan_el_dir);
+ if (dp == NULL) {
+ ret = -errno;
+ goto error_free_name;
+ }
+ while (ent = readdir(dp), ent != NULL)
+ if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
+ "_en") == 0) {
+ write_sysfs_int_and_verify((char *)ent->d_name, scan_el_dir, 1);
+ }
+ return 0;
+error_ret:
+error_free_name:
+ return -1;
+}
+int disable_q_out(const char *device_dir,
+ struct iio_channel_info **ci_array,
+ int *counter) {
+ DIR *dp;
+ int ret;
+ const struct dirent *ent;
+ char *scan_el_dir;
+
+ *counter = 0;
+ ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ dp = opendir(scan_el_dir);
+ if (dp == NULL) {
+ ret = -errno;
+ goto error_free_name;
+ }
+ while (ent = readdir(dp), ent != NULL)
+ if (strncmp(ent->d_name, "in_quaternion", strlen("in_quaternion")) == 0) {
+ write_sysfs_int_and_verify((char *)ent->d_name, scan_el_dir, 0);
+ }
+ return 0;
+error_ret:
+error_free_name:
+ return -1;
+
+}
+
diff --git a/libsensors_iio/software/simple_apps/mpu_iio/mpu_iio.c b/libsensors_iio/software/simple_apps/mpu_iio/mpu_iio.c
new file mode 100644
index 0000000..b3d323c
--- /dev/null
+++ b/libsensors_iio/software/simple_apps/mpu_iio/mpu_iio.c
@@ -0,0 +1,685 @@
+/* Industrialio buffer test code.
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is primarily intended as an example application.
+ * Reads the current buffer setup from sysfs and starts a short capture
+ * from the specified device, pretty printing the result after appropriate
+ * conversion.
+ *
+ * Command line parameters
+ * generic_buffer -n <device_name> -t <trigger_name>
+ * If trigger name is not specified the program assumes you want a dataready
+ * trigger associated with the device and goes looking for it.
+ *
+ */
+
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/types.h>
+#include <string.h>
+#include <poll.h>
+#include "iio_utils.h"
+#include "ml_load_dmp.h"
+#include "ml_sysfs_helper.h"
+#include "authenticate.h"
+
+#define FLICK_SUPPORTED (0)
+
+/**
+ * size_from_channelarray() - calculate the storage size of a scan
+ * @channels: the channel info array
+ * @num_channels: size of the channel info array
+ *
+ * Has the side effect of filling the channels[i].location values used
+ * in processing the buffer output.
+ **/
+int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
+{
+ int bytes = 0;
+ int i = 0;
+ while (i < num_channels) {
+ if (bytes % channels[i].bytes == 0)
+ channels[i].location = bytes;
+ else
+ channels[i].location = bytes - bytes%channels[i].bytes
+ + channels[i].bytes;
+ bytes = channels[i].location + channels[i].bytes;
+ i++;
+ }
+ return bytes;
+}
+
+void print2byte(int input, struct iio_channel_info *info)
+{
+ /* shift before conversion to avoid sign extension
+ of left aligned data */
+ input = input >> info->shift;
+ if (info->is_signed) {
+ int16_t val = input;
+ val &= (1 << info->bits_used) - 1;
+ val = (int16_t)(val << (16 - info->bits_used)) >>
+ (16 - info->bits_used);
+ /*printf("%d, %05f, scale=%05f", val,
+ (float)(val + info->offset)*info->scale, info->scale);*/
+ printf("%d, ", val);
+
+ } else {
+ uint16_t val = input;
+ val &= (1 << info->bits_used) - 1;
+ printf("%05f ", ((float)val + info->offset)*info->scale);
+ }
+}
+/**
+ * process_scan() - print out the values in SI units
+ * @data: pointer to the start of the scan
+ * @infoarray: information about the channels. Note
+ * size_from_channelarray must have been called first to fill the
+ * location offsets.
+ * @num_channels: the number of active channels
+ **/
+void process_scan(char *data,
+ struct iio_channel_info *infoarray,
+ int num_channels)
+{
+ int k;
+ //char *tmp;
+ for (k = 0; k < num_channels; k++) {
+ switch (infoarray[k].bytes) {
+ /* only a few cases implemented so far */
+ case 2:
+ print2byte(*(uint16_t *)(data + infoarray[k].location),
+ &infoarray[k]);
+ //tmp = data + infoarray[k].location;
+ break;
+ case 4:
+ if (infoarray[k].is_signed) {
+ int32_t val = *(int32_t *)
+ (data +
+ infoarray[k].location);
+ if ((val >> infoarray[k].bits_used) & 1)
+ val = (val & infoarray[k].mask) |
+ ~infoarray[k].mask;
+ /* special case for timestamp */
+ printf(" %d ", val);
+ }
+ break;
+ case 8:
+ if (infoarray[k].is_signed) {
+ int64_t val = *(int64_t *)
+ (data +
+ infoarray[k].location);
+ if ((val >> infoarray[k].bits_used) & 1)
+ val = (val & infoarray[k].mask) |
+ ~infoarray[k].mask;
+ /* special case for timestamp */
+ if (infoarray[k].scale == 1.0f &&
+ infoarray[k].offset == 0.0f)
+ printf(" %lld", val);
+ else
+ printf("%05f ", ((float)val +
+ infoarray[k].offset)*
+ infoarray[k].scale);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ printf("\n");
+}
+
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+void enable_flick(char *p, int on){
+ int ret;
+ printf("flick:%s\n", p);
+ ret = write_sysfs_int_and_verify("flick_int_on", p, on);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("flick_upper", p, 3147790);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("flick_lower", p, -3147790);
+ if (ret < 0)
+ return;
+
+ ret = write_sysfs_int_and_verify("flick_counter", p, 50);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("flick_message_on", p, 0);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("flick_axis", p, 0);
+}
+#endif
+
+void HandleOrient(int orient)
+{
+ if (orient & 0x01)
+ printf("INV_X_UP\n");
+ if (orient & 0x02)
+ printf("INV_X_DOWN\n");
+ if (orient & 0x04)
+ printf("INV_Y_UP\n");
+ if (orient & 0x08)
+ printf("INV_Y_DOWN\n");
+ if (orient & 0x10)
+ printf("INV_Z_UP\n");
+ if (orient & 0x20)
+ printf("INV_Z_DOWN\n");
+ if (orient & 0x40)
+ printf("INV_ORIENTATION_FLIP\n");
+}
+
+void HandleTap(int tap)
+{
+ int tap_dir = tap/8;
+ int tap_num = tap%8 + 1;
+
+ switch (tap_dir) {
+ case 1:
+ printf("INV_TAP_AXIS_X_POS\n");
+ break;
+ case 2:
+ printf("INV_TAP_AXIS_X_NEG\n");
+ break;
+ case 3:
+ printf("INV_TAP_AXIS_Y_POS\n");
+ break;
+ case 4:
+ printf("INV_TAP_AXIS_Y_NEG\n");
+ break;
+ case 5:
+ printf("INV_TAP_AXIS_Z_POS\n");
+ break;
+ case 6:
+ printf("INV_TAP_AXIS_Z_NEG\n");
+ break;
+ default:
+ break;
+ }
+ printf("Tap number: %d\n", tap_num);
+}
+#define DMP_CODE_SIZE 3060
+void verify_img(char *dmp_path){
+ FILE *fp;
+ int i;
+ char dmp_img[DMP_CODE_SIZE];
+ if ((fp = fopen(dmp_path, "rb")) < 0 ) {
+ perror("dmp fail");
+ }
+ i = fread(dmp_img, 1, DMP_CODE_SIZE, fp);
+ printf("Result=%d\n", i);
+ fclose(fp);
+ fp = fopen("/dev/read_img.h", "wt");
+ fprintf(fp, "char rec[]={\n");
+ for(i=0; i<DMP_CODE_SIZE; i++) {
+ fprintf(fp, "0x%02x, ", dmp_img[i]);
+ if(((i+1)%16) == 0) {
+ fprintf(fp, "\n");
+ }
+ }
+ fprintf(fp, "};\n ");
+ fclose(fp);
+}
+
+void setup_dmp(char *dev_path, int p_event){
+ char sysfs_path[200];
+ char dmp_path[200];
+ int ret;
+ FILE *fd;
+ sprintf(sysfs_path, "%s", dev_path);
+ printf("sysfs: %s\n", sysfs_path);
+ ret = write_sysfs_int_and_verify("power_state", sysfs_path, 1);
+ if (ret < 0)
+ return;
+
+ ret = write_sysfs_int("in_accel_scale", dev_path, 0);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int("in_anglvel_scale", dev_path, 2);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int("sampling_frequency", sysfs_path, 200);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("firmware_loaded", sysfs_path, 0);
+ if (ret < 0)
+ return;
+ sprintf(dmp_path, "%s/dmp_firmware", dev_path);
+ if ((fd = fopen(dmp_path, "wb")) < 0 ) {
+ perror("dmp fail");
+ }
+ inv_load_dmp(fd);
+ fclose(fd);
+ printf("firmware_loaded=%d\n", read_sysfs_posint("firmware_loaded", sysfs_path));
+ ret = write_sysfs_int_and_verify("in_accel_x_offset", sysfs_path, 0xabcd0000);
+ ret = write_sysfs_int_and_verify("in_accel_y_offset", sysfs_path, 0xffff0000);
+ ret = write_sysfs_int_and_verify("in_accel_z_offset", sysfs_path, 0xcdef0000);
+
+ ret = write_sysfs_int_and_verify("dmp_on", sysfs_path, 1);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("dmp_int_on", sysfs_path, 1);
+ if (ret < 0)
+ return;
+ /* selelct which event to enable and interrupt on/off here */
+ //enable_flick(sysfs_path, 1);
+ ret = write_sysfs_int_and_verify("tap_on", sysfs_path, 1);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("display_orientation_on", sysfs_path, 1);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("orientation_on", sysfs_path, 1);
+ if (ret < 0)
+ return;
+ printf("rate\n");
+ ret = write_sysfs_int_and_verify("dmp_output_rate", sysfs_path, 25);
+ if (ret < 0)
+ return;
+ ret = write_sysfs_int_and_verify("dmp_event_int_on", sysfs_path, p_event);
+ if (ret < 0)
+ return;
+ //verify_img(dmp_path);
+}
+
+void get_dmp_event(char *dev_dir_name)
+{
+ char file_name[100];
+ int i;
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ int fp_tap, fp_orient, fp_disp, fp_flick;
+ const int n_gest = 6;
+#else
+ int fp_tap, fp_orient, fp_disp, fp_motion;
+ //int fp_no_motion;
+ const int n_gest = 4;
+#endif
+ int data;
+ char d[6];
+ FILE *fp;
+ struct pollfd pfd[4];
+ printf("%s\n", dev_dir_name);
+ while(1) {
+ sprintf(file_name, "%s/event_tap", dev_dir_name);
+ fp_tap = open(file_name, O_RDONLY | O_NONBLOCK);
+ sprintf(file_name, "%s/event_orientation", dev_dir_name);
+ fp_orient = open(file_name, O_RDONLY | O_NONBLOCK);
+ sprintf(file_name, "%s/event_display_orientation", dev_dir_name);
+ fp_disp = open(file_name, O_RDONLY | O_NONBLOCK);
+
+ //sprintf(file_name, "%s/event_accel_motion", dev_dir_name);
+ sprintf(file_name, "%s/event_accel_wom", dev_dir_name);
+ fp_motion = open(file_name, O_RDONLY | O_NONBLOCK);
+ //sprintf(file_name, "%s/event_accel_no_motion", dev_dir_name);
+ //fp_no_motion = open(file_name, O_RDONLY | O_NONBLOCK);
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ sprintf(file_name, "%s/event_flick", dev_dir_name);
+ fp_flick = open(file_name, O_RDONLY | O_NONBLOCK);
+#endif
+
+ pfd[0].fd = fp_tap;
+ pfd[0].events = POLLPRI|POLLERR,
+ pfd[0].revents = 0;
+
+ pfd[1].fd = fp_orient;
+ pfd[1].events = POLLPRI|POLLERR,
+ pfd[1].revents = 0;
+
+ pfd[2].fd = fp_disp;
+ pfd[2].events = POLLPRI|POLLERR,
+ pfd[2].revents = 0;
+
+ pfd[3].fd = fp_motion;
+ pfd[3].events = POLLPRI|POLLERR,
+ pfd[3].revents = 0;
+
+ //pfd[4].fd = fp_no_motion;
+ //pfd[4].events = POLLPRI|POLLERR,
+ //pfd[4].revents = 0;
+
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ pfd[5].fd = fp_flick;
+ pfd[5].events = POLLPRI|POLLERR,
+ pfd[5].revents = 0;
+#endif
+
+ read(fp_tap, d, 4);
+ read(fp_orient, d, 4);
+ read(fp_disp, d, 4);
+ read(fp_motion, d, 4);
+ //read(fp_no_motion, d, 4);
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ read(fp_flick, d, 4);
+#endif
+
+ poll(pfd, n_gest, -1);
+ close(fp_tap);
+ close(fp_orient);
+ close(fp_disp);
+ close(fp_motion);
+ //close(fp_no_motion);
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ close(fp_flick);
+#endif
+ for (i = 0; i < ARRAY_SIZE(pfd); i++) {
+ if(pfd[i].revents != 0) {
+ switch (i){
+ case 0:
+ sprintf(file_name, "%s/event_tap", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("tap=%x\n", data);
+ HandleTap(data);
+ fclose(fp);
+ break;
+ case 1:
+ sprintf(file_name, "%s/event_orientation", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("orient=%x\n", data);
+ HandleOrient(data);
+ fclose(fp);
+ break;
+ case 2:
+ sprintf(file_name, "%s/event_display_orientation", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("display_orient=%x\n", data);
+ fclose(fp);
+ break;
+ case 3:
+ sprintf(file_name, "%s/event_accel_wom", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("motion=%x\n", data);
+ fclose(fp);
+ break;
+ case 4:
+ sprintf(file_name, "%s/event_accel_no_motion", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("No motion=%x\n", data);
+ fclose(fp);
+ break;
+
+#if FLICK_SUPPORTED /* hide flick, not offially supported */
+ case 5:
+ sprintf(file_name, "%s/event_flick", dev_dir_name);
+ fp = fopen(file_name, "rt");
+ fscanf(fp, "%d\n", &data);
+ printf("flick=%x\n", data);
+ fclose(fp);
+ break;
+#endif
+ }
+ }
+ }
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ unsigned long num_loops = 2;
+ unsigned long timedelay = 100000;
+ unsigned long buf_len = 128;
+
+ int ret, c, i, j, toread;
+ int fp;
+
+ int num_channels;
+ char *trigger_name = NULL;
+ char *dev_dir_name, *buf_dir_name;
+
+ int datardytrigger = 1;
+ char *data;
+ int read_size;
+ int dev_num, trig_num;
+ char *buffer_access;
+ int scan_size;
+ int noevents = 0;
+ int p_event = 0, nodmp = 0;
+ char *dummy;
+ char chip_name[10];
+ char device_name[10];
+ char sysfs[100];
+
+ struct iio_channel_info *infoarray;
+ /* -r means no DMP is enabled (raw) -> should be used for mpu3050.
+ -p means no print of data */
+ /* when using -p, 1 means orientation, 2 means tap, 3 means flick */
+ while ((c = getopt(argc, argv, "l:w:c:pret:")) != -1) {
+ switch (c) {
+ case 't':
+ trigger_name = optarg;
+ datardytrigger = 0;
+ break;
+ case 'e':
+ noevents = 1;
+ break;
+ case 'p':
+ p_event = 1;
+ break;
+ case 'r':
+ nodmp = 1;
+ break;
+ case 'c':
+ num_loops = strtoul(optarg, &dummy, 10);
+ break;
+ case 'w':
+ timedelay = strtoul(optarg, &dummy, 10);
+ break;
+ case 'l':
+ buf_len = strtoul(optarg, &dummy, 10);
+ break;
+ case '?':
+ return -1;
+ }
+ }
+ inv_get_sysfs_path(sysfs);
+ printf("sss:::%s\n", sysfs);
+ if (inv_get_chip_name(chip_name) != INV_SUCCESS) {
+ printf("get chip name fail\n");
+ exit(0);
+ }
+ printf("chip_name=%s\n", chip_name);
+ if (INV_SUCCESS != inv_check_key())
+ printf("key check fail\n");
+ else
+ printf("key authenticated\n");
+
+ for (i=0; i<strlen(chip_name); i++) {
+ device_name[i] = tolower(chip_name[i]);
+ }
+ device_name[strlen(chip_name)] = '\0';
+ printf("device name: %s\n", device_name);
+
+ /* Find the device requested */
+ dev_num = find_type_by_name(device_name, "iio:device");
+ if (dev_num < 0) {
+ printf("Failed to find the %s\n", device_name);
+ ret = -ENODEV;
+ goto error_ret;
+ }
+ printf("iio device number being used is %d\n", dev_num);
+ asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
+ if (trigger_name == NULL) {
+ /*
+ * Build the trigger name. If it is device associated it's
+ * name is <device_name>_dev[n] where n matches the device
+ * number found above
+ */
+ ret = asprintf(&trigger_name,
+ "%s-dev%d", device_name, dev_num);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+ }
+ ret = write_sysfs_int("buffer/enable", dev_dir_name, 0);
+
+ ret = write_sysfs_int_and_verify("power_state", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("accl_enable", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("compass_enable", dev_dir_name, 1);
+/*
+ ret = write_sysfs_int_and_verify("zero_motion_on", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("zero_motion_dur", dev_dir_name, 12);
+ ret = write_sysfs_int_and_verify("zero_motion_threshold", dev_dir_name, 13);
+
+ ret = write_sysfs_int_and_verify("motion_on", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("motion_dur", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("motion_threshold", dev_dir_name, 1);
+*/
+ ret = write_sysfs_int_and_verify("accel_wom_on", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("accel_wom_threshold", dev_dir_name, 100);
+ /* Verify the trigger exists */
+ trig_num = find_type_by_name(trigger_name, "trigger");
+ if (trig_num < 0) {
+ printf("Failed to find the trigger %s\n", trigger_name);
+ ret = -ENODEV;
+ goto error_free_triggername;
+ }
+ printf("iio trigger number being used is %d\n", trig_num);
+ /*
+ * Parse the files in scan_elements to identify what channels are
+ * present
+ */
+ ret = 0;
+ ret = enable(dev_dir_name, &infoarray, &num_channels);
+ if (ret) {
+ printf("error enable\n");
+ goto error_free_triggername;
+ }
+ if (!nodmp)
+ setup_dmp(dev_dir_name, p_event);
+
+ /*
+ * Construct the directory name for the associated buffer.
+ * As we know that the lis3l02dq has only one buffer this may
+ * be built rather than found.
+ */
+ ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_free_triggername;
+ }
+ printf("%s %s\n", dev_dir_name, trigger_name);
+
+ /* Set the device trigger to be the data rdy trigger found above */
+ ret = write_sysfs_string_and_verify("trigger/current_trigger",
+ dev_dir_name,
+ trigger_name);
+ if (ret < 0) {
+ printf("Failed to write current_trigger file\n");
+ goto error_free_buf_dir_name;
+ }
+ /* Setup ring buffer parameters */
+ /* length must be even number because iio_store_to_sw_ring is expecting
+ half pointer to be equal to the read pointer, which is impossible
+ when buflen is odd number. This is actually a bug in the code */
+ ret = write_sysfs_int("length", buf_dir_name, buf_len*2);
+ if (ret < 0)
+ goto exit_here;
+ ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, 1);
+ ret = write_sysfs_int_and_verify("accl_enable", dev_dir_name, 1);
+ //ret = write_sysfs_int_and_verify("compass_enable", dev_dir_name, 0);
+ if (nodmp == 0) {
+ ret = write_sysfs_int_and_verify("quaternion_on", dev_dir_name, 1);
+ } else {
+ ret = disable_q_out(dev_dir_name, &infoarray, &num_channels);
+ ret = write_sysfs_int_and_verify("dmp_on", dev_dir_name, 0);
+ }
+ ret = build_channel_array(dev_dir_name, &infoarray, &num_channels);
+ if (ret) {
+ printf("Problem reading scan element information\n");
+ goto exit_here;
+ }
+
+ /* Enable the buffer */
+ ret = write_sysfs_int("enable", buf_dir_name, 1);
+ if (ret < 0)
+ goto exit_here;
+ scan_size = size_from_channelarray(infoarray, num_channels);
+ data = malloc(scan_size*buf_len);
+ if (!data) {
+ ret = -ENOMEM;
+ goto exit_here;
+ }
+
+ ret = asprintf(&buffer_access,
+ "/dev/iio:device%d",
+ dev_num);
+ if (ret < 0) {
+ ret = -ENOMEM;
+ goto error_free_data;
+ }
+ if (p_event) {
+ get_dmp_event(dev_dir_name);
+ goto error_free_buffer_access;
+ }
+ /* Attempt to open non blocking the access dev */
+ fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
+ if (fp == -1) { /*If it isn't there make the node */
+ printf("Failed to open %s\n", buffer_access);
+ ret = -errno;
+ goto error_free_buffer_access;
+ }
+ /* Wait for events 10 times */
+ for (j = 0; j < num_loops; j++) {
+ if (!noevents) {
+ struct pollfd pfd = {
+ .fd = fp,
+ .events = POLLIN,
+ };
+ poll(&pfd, 1, -1);
+ toread = 1;
+ if ((j%128)==0)
+ usleep(timedelay);
+
+ } else {
+ usleep(timedelay);
+ toread = 1;
+ }
+ read_size = read(fp,
+ data,
+ toread*scan_size);
+ if (read_size == -EAGAIN) {
+ printf("nothing available\n");
+ continue;
+ }
+ if (0 == p_event) {
+ for (i = 0; i < read_size/scan_size; i++)
+ process_scan(data + scan_size*i,
+ infoarray,
+ num_channels);
+ }
+ }
+ close(fp);
+error_free_buffer_access:
+ free(buffer_access);
+error_free_data:
+ free(data);
+exit_here:
+ /* Stop the ring buffer */
+ ret = write_sysfs_int("enable", buf_dir_name, 0);
+
+error_free_buf_dir_name:
+ free(buf_dir_name);
+error_free_triggername:
+ if (datardytrigger)
+ free(trigger_name);
+error_ret:
+ return ret;
+}