diff options
Diffstat (limited to 'drivers/staging/iio/Documentation')
-rw-r--r-- | drivers/staging/iio/Documentation/generic_buffer.c | 318 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/iio_utils.h | 396 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c | 238 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/overview.txt | 17 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/ring.txt | 6 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/sysfs-bus-iio | 390 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/sysfs-bus-iio-light | 64 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/sysfs-class-iio | 294 | ||||
-rw-r--r-- | drivers/staging/iio/Documentation/userspace.txt | 56 |
9 files changed, 1177 insertions, 602 deletions
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c new file mode 100644 index 0000000..df23aeb --- /dev/null +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -0,0 +1,318 @@ +/* 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 <sys/dir.h> +#include <linux/types.h> +#include "iio_utils.h" + +const int buf_len = 128; +const int num_loops = 2; + +/** + * 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; +} + +/** + * 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; + for (k = 0; k < num_channels; k++) + switch (infoarray[k].bytes) { + /* only a few cases implemented so far */ + case 2: + if (infoarray[k].is_signed) { + int16_t val = *(int16_t *) + (data + + infoarray[k].location); + if ((val >> infoarray[k].bits_used) & 1) + val = (val & infoarray[k].mask) | + ~infoarray[k].mask; + printf("%05f ", ((float)val + + infoarray[k].offset)* + infoarray[k].scale); + } else { + uint16_t val = *(uint16_t *) + (data + + infoarray[k].location); + val = (val & infoarray[k].mask); + printf("%05f ", ((float)val + + infoarray[k].offset)* + infoarray[k].scale); + } + 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"); +} + +int main(int argc, char **argv) +{ + int ret, c, i, j, toread; + + FILE *fp_ev; + int fp; + + int num_channels; + char *trigger_name = NULL, *device_name = NULL; + char *dev_dir_name, *buf_dir_name; + + int datardytrigger = 1; + char *data; + size_t read_size; + struct iio_event_data dat; + int dev_num, trig_num; + char *buffer_access, *buffer_event; + int scan_size; + + struct iio_channel_info *infoarray; + + while ((c = getopt(argc, argv, "t:n:")) != -1) { + switch (c) { + case 'n': + device_name = optarg; + break; + case 't': + trigger_name = optarg; + datardytrigger = 0; + break; + case '?': + return -1; + } + } + + /* Find the device requested */ + dev_num = find_type_by_name(device_name, "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, "%sdevice%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; + } + } + + /* 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 = build_channel_array(dev_dir_name, &infoarray, &num_channels); + if (ret) { + printf("Problem reading scan element information \n"); + goto error_free_triggername; + } + + /* + * 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, "%sdevice%d:buffer0", 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 */ + ret = write_sysfs_int("length", buf_dir_name, buf_len); + if (ret < 0) + goto error_free_buf_dir_name; + + /* Enable the buffer */ + ret = write_sysfs_int("enable", buf_dir_name, 1); + if (ret < 0) + goto error_free_buf_dir_name; + scan_size = size_from_channelarray(infoarray, num_channels); + data = malloc(scan_size*buf_len); + if (!data) { + ret = -ENOMEM; + goto error_free_buf_dir_name; + } + + ret = asprintf(&buffer_access, + "/dev/device%d:buffer0:access0", + dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_data; + } + + ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num); + if (ret < 0) { + ret = -ENOMEM; + 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_event; + } + /* Attempt to open the event access dev (blocking this time) */ + fp_ev = fopen(buffer_event, "rb"); + if (fp_ev == NULL) { + printf("Failed to open %s\n", buffer_event); + ret = -errno; + goto error_close_buffer_access; + } + + /* Wait for events 10 times */ + for (j = 0; j < num_loops; j++) { + read_size = fread(&dat, 1, sizeof(struct iio_event_data), + fp_ev); + switch (dat.id) { + case IIO_EVENT_CODE_RING_100_FULL: + toread = buf_len; + break; + case IIO_EVENT_CODE_RING_75_FULL: + toread = buf_len*3/4; + break; + case IIO_EVENT_CODE_RING_50_FULL: + toread = buf_len/2; + break; + default: + printf("Unexpecteded event code\n"); + continue; + } + read_size = read(fp, + data, + toread*scan_size); + if (read_size == -EAGAIN) { + printf("nothing available\n"); + continue; + } + for (i = 0; i < read_size/scan_size; i++) + process_scan(data + scan_size*i, + infoarray, + num_channels); + } + + /* Stop the ring buffer */ + ret = write_sysfs_int("enable", buf_dir_name, 0); + if (ret < 0) + goto error_close_buffer_event; + + /* Disconnect from the trigger - just write a dummy name.*/ + write_sysfs_string("trigger/current_trigger", + dev_dir_name, "NULL"); + +error_close_buffer_event: + fclose(fp_ev); +error_close_buffer_access: + close(fp); +error_free_data: + free(data); +error_free_buffer_access: + free(buffer_access); +error_free_buffer_event: + free(buffer_event); +error_free_buf_dir_name: + free(buf_dir_name); +error_free_triggername: + if (datardytrigger) + free(trigger_name); +error_ret: + return ret; +} diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 014f6684..0372424 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -10,12 +10,23 @@ /* Made up value to limit allocation sizes */ #include <string.h> #include <stdlib.h> +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> #define IIO_MAX_NAME_LENGTH 30 -#define IIO_EVENT_CODE_RING_50_FULL 200 -#define IIO_EVENT_CODE_RING_75_FULL 201 -#define IIO_EVENT_CODE_RING_100_FULL 202 +#define IIO_EV_CLASS_BUFFER 0 +#define IIO_BUFFER_EVENT_CODE(code) \ + (IIO_EV_CLASS_BUFFER | (code << 8)) + +#define IIO_EVENT_CODE_RING_50_FULL IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_RING_75_FULL IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_RING_100_FULL IIO_BUFFER_EVENT_CODE(2) + + +#define FORMAT_SCAN_ELEMENTS_DIR "%s:buffer0/scan_elements" +#define FORMAT_TYPE_FILE "%s_type" const char *iio_dir = "/sys/bus/iio/devices/"; @@ -25,6 +36,380 @@ struct iio_event_data { }; /** + * 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; + uint64_t mask; + 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 + * @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, + uint64_t *mask, + 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; + unsigned sizeint, 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; + } + fscanf(sysfsfp, + "%c%u/%u", &signchar, bits_used, &padint); + *bytes = padint / 8; + if (sizeint == 64) + *mask = ~0; + else + *mask = (1 << *bits_used) - 1; + if (signchar == 's') + *is_signed = 1; + else + *is_signed = 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; +} + + +/** + * 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 = 0, temp, 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); + 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; + } + seekdir(dp, 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", ¤t->enabled); + fclose(sysfsfp); + free(filename); + 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, + ¤t->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", ¤t->index); + fclose(sysfsfp); + free(filename); + /* Find the scale */ + ret = iioutils_get_param_float(¤t->scale, + "scale", + device_dir, + current->name, + current->generic_name); + if (ret < 0) + goto error_cleanup_array; + ret = iioutils_get_param_float(¤t->offset, + "offset", + device_dir, + current->name, + current->generic_name); + if (ret < 0) + goto error_cleanup_array; + ret = iioutils_get_type(¤t->is_signed, + ¤t->bytes, + ¤t->bits_used, + ¤t->mask, + device_dir, + current->name, + current->generic_name); + } + } + /* reorder so that the array is in index order*/ + current = malloc(sizeof(**ci_array)**counter); + if (current == NULL) { + ret = -ENOMEM; + goto error_cleanup_array; + } + closedir(dp); + count = 0; + temp = 0; + while (count < *counter) + for (i = 0; i < *counter; i++) + if ((*ci_array)[i].index == temp) { + memcpy(¤t[count++], + &(*ci_array)[i], + sizeof(*current)); + temp++; + break; + } + free(*ci_array); + *ci_array = current; + + 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; +} + +/** * find_type_by_name() - function to match top level types by name * @name: top level type instance name * @type: the type of top level instance being sort @@ -40,7 +425,6 @@ inline int find_type_by_name(const char *name, const char *type) DIR *dp; char thisname[IIO_MAX_NAME_LENGTH]; char *filename; - struct stat Stat; dp = opendir(iio_dir); if (dp == NULL) { @@ -134,7 +518,7 @@ int write_sysfs_int_and_verify(char *filename, char *basedir, int val) int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) { - int ret; + int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); if (temp == NULL) { @@ -153,6 +537,7 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) if (verify) { sysfsfp = fopen(temp, "r"); if (sysfsfp == NULL) { + printf("could not open file to verify\n"); ret = -errno; goto error_free; } @@ -173,6 +558,7 @@ error_free: return ret; } + /** * write_sysfs_string_and_verify() - string write, readback and verify * @filename: name of file to write to diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c deleted file mode 100644 index 3a58028..0000000 --- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Industrialio ring buffer with a lis3l02dq accelerometer - * - * 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. - */ - -#include <dirent.h> -#include <fcntl.h> -#include <stdio.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/dir.h> -#include <linux/types.h> -#include "iio_utils.h" - -const char *device_name = "lis3l02dq"; -const char *trigger_name_base = "lis3l02dq-dev"; -const int num_vals = 3; -const int scan_ts = 1; -const int buf_len = 128; -const int num_loops = 10; - -/* - * Could get this from ring bps, but only after starting the ring - * which is a bit late for it to be useful. - * - * Todo: replace with much more generic version based on scan_elements - * directory. - */ -int size_from_scanmode(int num_vals, int timestamp) -{ - if (num_vals && timestamp) - return 16; - else if (timestamp) - return 8; - else - return num_vals*2; -} - -int main(int argc, char **argv) -{ - int ret; - int i, j, k, toread; - FILE *fp_ev; - int fp; - - char *trigger_name, *dev_dir_name, *buf_dir_name; - char *data; - size_t read_size; - struct iio_event_data dat; - int dev_num, trig_num; - - char *buffer_access, *buffer_event; - const char *iio_dir = "/sys/bus/iio/devices/"; - int scan_size; - float gain = 1; - - - /* Find out which iio device is the accelerometer. */ - dev_num = find_type_by_name(device_name, "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, "%sdevice%d", iio_dir, dev_num); - - /* - * Build the trigger name. - * In this case we want the lis3l02dq's data ready trigger - * for this lis3l02dq. The naming is lis3l02dq_dev[n], where - * n matches the device number found above. - */ - ret = asprintf(&trigger_name, "%s%d", trigger_name_base, dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_dev_dir_name; - } - - /* - * Find the trigger by name. - * This is techically unecessary here as we only need to - * refer to the trigger by name and that name is already - * known. - */ - trig_num = find_type_by_name(trigger_name, "trigger"); - if (trig_num < 0) { - printf("Failed to find the %s\n", trigger_name); - ret = -ENODEV; - goto error_free_triggername; - } - printf("iio trigger number being used is %d\n", trig_num); - - /* - * Read in the scale value - in a more generic case, first - * check for accel_scale, then the indivual channel scales - */ - ret = read_sysfs_float("accel_scale", dev_dir_name, &gain); - if (ret) - goto error_free_triggername;; - - /* - * 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, "%sdevice%d:buffer0", iio_dir, dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_triggername; - } - /* 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 */ - ret = write_sysfs_int("length", buf_dir_name, buf_len); - if (ret < 0) - goto error_free_buf_dir_name; - - /* Enable the buffer */ - ret = write_sysfs_int("ring_enable", buf_dir_name, 1); - if (ret < 0) - goto error_free_buf_dir_name; - - data = malloc(size_from_scanmode(num_vals, scan_ts)*buf_len); - if (!data) { - ret = -ENOMEM; - goto error_free_buf_dir_name; - } - - ret = asprintf(&buffer_access, - "/dev/device%d:buffer0:access0", - dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_data; - } - - ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_data; - } - /* 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_event; - } - /* Attempt to open the event access dev (blocking this time) */ - fp_ev = fopen(buffer_event, "rb"); - if (fp_ev == NULL) { - printf("Failed to open %s\n", buffer_event); - ret = -errno; - goto error_close_buffer_access; - } - - /* Wait for events 10 times */ - for (j = 0; j < num_loops; j++) { - read_size = fread(&dat, 1, sizeof(struct iio_event_data), - fp_ev); - switch (dat.id) { - case IIO_EVENT_CODE_RING_100_FULL: - toread = buf_len; - break; - case IIO_EVENT_CODE_RING_75_FULL: - toread = buf_len*3/4; - break; - case IIO_EVENT_CODE_RING_50_FULL: - toread = buf_len/2; - break; - default: - printf("Unexpecteded event code\n"); - continue; - } - read_size = read(fp, - data, - toread*size_from_scanmode(num_vals, scan_ts)); - if (read_size == -EAGAIN) { - printf("nothing available\n"); - continue; - } - scan_size = size_from_scanmode(num_vals, scan_ts); - for (i = 0; i < read_size/scan_size; i++) { - for (k = 0; k < num_vals; k++) { - __s16 val = *(__s16 *)(&data[i*scan_size - + (k)*2]); - printf("%05f ", (float)val*gain); - } - printf(" %lld\n", - *(__s64 *)(&data[(i + 1) - *size_from_scanmode(num_vals, - scan_ts) - - sizeof(__s64)])); - } - } - - /* Stop the ring buffer */ - ret = write_sysfs_int("ring_enable", buf_dir_name, 0); - if (ret < 0) - goto error_close_buffer_event; - - /* Disconnect from the trigger - just write a dummy name.*/ - write_sysfs_string("trigger/current_trigger", - dev_dir_name, "NULL"); - -error_close_buffer_event: - fclose(fp_ev); -error_close_buffer_access: - close(fp); -error_free_data: - free(data); -error_free_buffer_access: - free(buffer_access); -error_free_buffer_event: - free(buffer_event); -error_free_buf_dir_name: - free(buf_dir_name); -error_free_triggername: - free(trigger_name); -error_free_dev_dir_name: - free(dev_dir_name); -error_ret: - return ret; -} diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt index cc6ecad..d97106c 100644 --- a/drivers/staging/iio/Documentation/overview.txt +++ b/drivers/staging/iio/Documentation/overview.txt @@ -1,8 +1,8 @@ Overview of IIO -The Industrial I/O subsytem is intended to provide support for devices -that in some sense are analog to digital convertors (ADCs). As many -actual devices combine some ADCs with digital to analog convertors +The Industrial I/O subsystem is intended to provide support for devices +that in some sense are analog to digital converters (ADCs). As many +actual devices combine some ADCs with digital to analog converters (DACs) the intention is to add that functionality at a future date (hence the name). @@ -46,18 +46,17 @@ external signal (trigger). These triggers might be a data ready signal, a gpio line connected to some external system or an on processor periodic interrupt. A single trigger may initialize data capture or reading from a number of sensors. These triggers are -used in iio to fill software ring buffers acting in a very similar +used in IIO to fill software ring buffers acting in a very similar fashion to the hardware buffers described above. Other documentation: -userspace.txt - overview of ring buffer reading from userspace +userspace.txt - overview of ring buffer reading from userspace. -device.txt - elemennts of a typical device driver. +device.txt - elements of a typical device driver. trigger.txt - elements of a typical trigger driver. -ring.txt - additional elements required for ring buffer support - - +ring.txt - additional elements required for ring buffer support. +sysfs-bus-iio - abi documentation file. diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt index d2ca683..3696c36 100644 --- a/drivers/staging/iio/Documentation/ring.txt +++ b/drivers/staging/iio/Documentation/ring.txt @@ -47,10 +47,8 @@ request_update If parameters have changed that require reinitialization or configuration of the ring buffer this will trigger it. -get_bpd, set_bpd - Get/set the number of bytes for a given reading (single element, not sample set) - The value of bps (bytes per set) is created from a combination of this and the - enabled scan elements. +get_bytes_per_datum, set_bytes_per_datum + Get/set the number of bytes for a complete scan. (All samples + timestamp) get_length / set_length Get/set the number of sample sets that may be held by the buffer. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio new file mode 100644 index 0000000..fdb017a --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -0,0 +1,390 @@ +What: /sys/bus/iio/devices/device[n] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware chip or device accessed by on communication port. + Corresponds to a grouping of sensor channels. + +What: /sys/bus/iio/devices/trigger[n] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + An event driven driver of data capture to an in kernel buffer. + May be provided by a device driver that also has an IIO device + based on hardware generated events (e.g. data ready) or + provided by a separate driver for other hardware (e.g. + periodic timer, gpio or high resolution timer). + Contains trigger type specific elements. These do not + generalize well and hence are not documented in this file. + +What: /sys/bus/iio/devices/device[n]:buffer +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Link to /sys/class/iio/device[n]/device[n]:buffer. n indicates + the device with which this buffer buffer is associated. + +What: /sys/.../device[n]/name +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Description of the physical chip / device. Typically a part + number. + +What: /sys/.../device[n]/sampling_frequency +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Some devices have internal clocks. This parameter sets the + resulting sampling frequency. In many devices this + parameter has an effect on input filters etc rather than + simply controlling when the input is sampled. As this + effects datardy triggers, hardware buffers and the sysfs + direct access interfaces, it may be found in any of the + relevant directories. If it effects all of the above + then it is to be found in the base device directory as here. + +What: /sys/.../device[n]/sampling_frequency_available +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + When the internal sampling clock can only take a small + discrete set of values, this file lists those availale. + +What: /sys/.../device[n]/in[m][_name]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc) voltage measurement from + channel m. name is used in special cases where this does + not correspond to externally available input (e.g. supply + voltage monitoring in which case the file is in_supply_raw). + If the device supports events on this channel then m must be + specified (even on named channels) so as to allow the source + of event codes to be identified. + +What: /sys/.../device[n]/in[m][_name]_offset +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, offset to be added to in[m]_raw prior + to scaling by in[_name][m]_scale in order to obtain voltage in + millivolts. Not present if the offset is always 0 or unknown. + If m is not present, then voltage offset applies to all in + channels. May be writable if a variable offset is controlled + by the device. Note that this is different to calibbias which + is for devices that apply offsets to compensate for variation + between different instances of the part, typically adjusted by + using some hardware supported calibration procedure. + +What: /sys/.../device[n]/in[m][_name]_offset_available +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If a small number of discrete offset values are available, this + will be a space separated list. If these are independant (but + options the same) for individual offsets then m should not be + present. + +What: /sys/.../device[n]/in[m][_name]_offset_[min|max] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If a more or less continuous range of voltage offsets are + supported then these specify the minimum and maximum. If shared + by all in channels then m is not present. + +What: /sys/.../device[n]/in[m][_name]_calibbias +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration offset. (assumed to fix production + inaccuracies) + +What /sys/.../device[n]/in[m][_name]_calibscale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration scale factor. (assumed to fix + production inaccuracies) + +What: /sys/.../device[n]/in[m][_name]_scale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, scale to be applied to volt[m]_raw post + addition of in[_name][m]_offset in order to obtain the measured + voltage in millivolts. If shared across all in channels then + m is not present. + +What: /sys/.../device[n]/in[m]-in[o]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled) differential voltage measurement equivalent to + channel m - channel o where these channel numbers apply to the + physically equivalent inputs when non differential readings are + separately available. In differential only parts, then all that + is required is a consistent labelling. + +What: /sys/.../device[n]/accel[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Acceleration in direction x, y or z (may be arbitrarily assigned + but should match other such assignments on device) + channel m (not present if only one accelerometer channel at + this orientation). Has all of the equivalent parameters as per + in[m]. Units after application of scale and offset are m/s^2. + +What: /sys/.../device[n]/gyro[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Angular velocity about axis x, y or z (may be arbitrarily + assigned) channel m (not present if only one gyroscope at + this orientation). + Data converted by application of offset then scale to + radians per second. Has all the equivalent parameters as + per in[m]. + +What: /sys/.../device[n]/incli[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Inclination raw reading about axis x, y or z (may be arbitarily + assigned) channel m (not present if only one inclinometer at + this orientation). Data converted by application of offset + and scale to Degrees. + +What: /sys/.../device[n]/magn[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Magnetic field along axis x, y or z (may be arbitrarily + assigned) channel m (not present if only one magnetometer + at this orientation). Data converted by application of + offset then scale to Gauss. Has all the equivalent modifiers + as per in[m]. + +What: /sys/.../device[n]/device[n]:event[m] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Configuration of which hardware generated events are passed up to + userspace. Some of these are a bit complex to generalize so this + section is a work in progress. + +What: /sys/.../device[n]:event[m]/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + major:minor character device numbers for the event line. + +Taking accel_x0 as an example + +What: /sys/.../device[n]:event[m]/accel_x0_thresh[_rising|_falling]_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Event generated when accel_x0 passes a threshold in the specfied + (_rising|_falling) direction. If the direction is not specified, + then either the device will report an event which ever direction + a single threshold value is called in (e.g. + accel_x0_<raw|input>_thresh_value) or + accel_x0_<raw|input>_thresh_rising_value and + accel_x0_<raw|input>_thresh_falling_value may take different + values, but the device can only enable both thresholds or + neither. + Note the driver will assume the last p events requested are + to be enabled where p is however many it supports (which may + vary depending on the exact set requested. So if you want to be + sure you have set what you think you have, check the contents of + these attributes after everything is configured. Drivers may + have to buffer any parameters so that they are consistent when + a given event type is enabled a future point (and not those for + whatever event was previously enabled). + +What: /sys/.../accel_x0_<raw|input>_thresh[_rising|_falling]_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the value of threshold that the device is comparing + against for the events enabled by + accel_x0_<raw|input>_thresh[_rising|falling]_en. + If seperate exist for the two directions, but direction is + not specified for this attribute, then a single threshold value + applies to both directions. + The raw or input element of the name indicates whether the + value is in raw device units or in processed units (as _raw + and _input do on sysfs direct channel read attributes). + +What: /sys/.../accel_x0_thresh[_rising|_falling]_meanperiod +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) over which the raw channel value + is averaged before being compared with the threshold set in + accel_x0_thresh[_rising|_falling]_meanperiod. If direction is + not specified then this mean period applies to both directions. + +What: /sys/.../accel_x0_thresh[_rising|_falling]_period +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) for which the threshold must be + passed before an event is generated. If direction is not + specified then this period applies to both directions. + +What: /sys/.../device[n]:event[m]/accel_x0_mag[_rising|_falling]_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Similar to accel_x0_thresh[_rising|_falling]_en, but here the + magnitude of the channel is compared to the threshold, not its + signed value. + +What: /sys/.../accel_x0_<raw|input>_mag[_rising|_falling]_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + The value to which the magnitude of the channel is compared. + +What: /sys/.../accel_x0_mag[_rising|_falling]_meanperiod +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) over which the value of the channel + is averaged before being compared to the threshold + +What: /sys/.../accel_x0_mag[_rising|_falling]_period +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) for which the condition must be true + before an event occurs. + +What: /sys/.../device[n]:event[m]/accel_x0_roc[_rising|_falling]_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Similar to accel_x0_thresh[_rising|_falling]_en, but here the + first differential is compared with the threshold. + +What: /sys/.../accel_x0_<raw|input>_roc[_rising|_falling]_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + The value to which the first differential of the channel is + compared. + +What: /sys/.../accel_x0_roc[_rising|_falling]_meanperiod +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) over which the value of the channel + is averaged before being compared to the threshold + +What: /sys/.../accel_x0_roc[_rising|_falling]_period +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) for which the condition must be true + before an event occurs. + +What: /sys/.../device[n]/device[n]:buffer:event/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Buffer for device n event character device major:minor numbers. + +What: /sys/.../device[n]/device[n]:buffer:access/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Buffer for device n access character device o major:minor numbers. + +What: /sys/.../device[n]:buffer/trigger +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + The name of the trigger source being used, as per string given + in /sys/class/iio/trigger[n]/name. + +What: /sys/.../device[n]:buffer/length +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Number of scans contained by the buffer. + +What: /sys/.../device[n]:buffer/bytes_per_datum +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Bytes per scan. Due to alignment fun, the scan may be larger + than implied directly by the scan_element parameters. + +What: /sys/.../device[n]:buffer/enable +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Actually start the buffer capture up. Will start trigger + if first device and appropriate. + +What: /sys/.../device[n]:buffer/alignment +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Minimum data alignment. Scan elements larger than this are + aligned to the nearest power of 2 times this. (may not be + true in weird hardware buffers that pack data well) + +What: /sys/.../device[n]/buffer/scan_elements +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Directory containing interfaces for elements that will be + captured for a single triggered sample set in the buffer. + +What: /sys/.../device[n]/buffer/scan_elements/accel_x0_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Scan element control for triggered data capture. + +What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_type +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Description of the scan element data storage within the buffer + and hence the form in which it is read from userspace. + Form is [s|u]bits/storagebits. s or u specifies if signed + (2's complement) or unsigned. bits is the number of bits of + data and storagebits is the space (after padding) that it + occupies in the buffer. Note that some devices will have + additional information in the unused bits so to get a clean + value, the bits value must be used to mask the buffer output + value appropriately. The storagebits value also specifies the + data alignment. So s48/64 will be a signed 48 bit integer + stored in a 64 bit location aligned to a a64 bit boundary. + For other storage combinations this attribute will be extended + appropriately. + +What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_index +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + A single positive integer specifying the position of this + scan element in the buffer. Note these are not dependant on + what is enabled and may not be contiguous. Thus for userspace + to establish the full layout these must be used in conjunction + with all _en attributes to establish which channels are present, + and the relevant _type attributes to establish the data storage + format. + +What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + A bit shift (to right) that must be applied prior to + extracting the bits specified by accel[_x0]_precision. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light new file mode 100644 index 0000000..5d84856 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -0,0 +1,64 @@ + +What: /sys/bus/iio/devices/device[n]/range +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent ADC Full Scale Range used for some ambient + light sensors in calculating lux. + +What: /sys/bus/iio/devices/device[n]/range_available +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent supported vales for ADC Full Scale Range. + +What: /sys/bus/iio/devices/device[n]/adc_resolution +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent ADC resolution of the ambient light sensor + used in calculating the lux. + +What: /sys/bus/iio/devices/device[n]/adc_resolution_available +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent list of possible values supported for the + adc_resolution of the given sensor. + +What: /sys/bus/iio/devices/device[n]/illuminance0[_input|_raw] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + This should return the calculated lux from the light sensor. If + it comes back in SI units, it should also include _input else it + should include _raw to signify it is not in SI units. + +What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_supression +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent mode for an ALS device to calculate the value + in proximity mode. When this is enabled, then the device should + use a infrared sensor reading to remove infrared noise from the + proximity reading. If this is not enabled, the driver can still + do this calculation manually by reading the infrared sensor + value and doing the negation in sw. + +What: /sys/bus/iio/devices/device[n]/proximity[_input|_raw] +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + This property is supported by proximity sensors and should be + used to return the value of a reading by the sensor. If this + value is returned in SI units, it should also include _input + but if it is not, then it should include _raw. + +What: /sys/bus/iio/devices/device[n]/intensity_infrared[_input|_raw] +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + This property is supported by sensors that have an infrared + sensing mode. This value should be the output from a reading + and if expressed in SI units, should include _input. If this + value is not in SI units, then it should include _raw. diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio deleted file mode 100644 index 714b4c5..0000000 --- a/drivers/staging/iio/Documentation/sysfs-class-iio +++ /dev/null @@ -1,294 +0,0 @@ - -What: /sys/bus/iio/devices/device[n] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware chip or device accessed by on communication port. - Corresponds to a grouping of sensor channels. - -What: /sys/bus/iio/devices/trigger[n] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - An event driven driver of data capture to an in kernel buffer. - May be provided by a device driver that also has an IIO device - based on hardware generated events (e.g. data ready) or - provided by a separate driver for other hardware (e.g. - periodic timer, gpio or high resolution timer). - Contains trigger type specific elements. These do not - generalize well and hence are not documented in this file. - -What: /sys/bus/iio/devices/device[n]:buffer -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Link to /sys/class/iio/device[n]/device[n]:buffer. n indicates the - device with which this buffer buffer is associated. - -What: /sys/.../device[n]/name -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Description of the physical chip / device. Typically a part - number. - -What: /sys/.../device[n]/sampling_frequency -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Some devices have internal clocks. This parameter sets the - resulting sampling frequency. In many devices this - parameter has an effect on input filters etc rather than - simply controlling when the input is sampled. As this - effects datardy triggers, hardware buffers and the sysfs - direct access interfaces, it may be found in any of the - relevant directories. If it effects all of the above - then it is to be found in the base device directory as here. - -What: /sys/.../device[n]/sampling_frequency_available -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - When the internal sampling clock can only take a small - discrete set of values, this file lists those availale. - -What: /sys/.../device[n]/in[_name][m]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled no bias removal etc) voltage measurement from - channel m. name is used in special cases where this does - not correspond to externally available input (e.g. supply - voltage monitoring in which case the file is in_supply_raw). - -What: /sys/.../device[n]/in[_name][m]_offset -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, offset to be added to in[m]_raw prior - to scaling by in[_name][m]_scale in order to obtain voltage in - millivolts. Not present if the offset is always 0 or unknown. - If m is not present, then voltage offset applies to all in - channels. May be writable if a variable offset is controlled - by the device. Note that this is different to calibbias which - is for devices that apply offsets to compensate for variation - between different instances of the part, typically adjusted by - using some hardware supported calibration procedure. - -What: /sys/.../device[n]/in[_name][m]_offset_available -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If a small number of discrete offset values are available, this - will be a space separated list. If these are independant (but - options the same) for individual offsets then m should not be - present. - -What: /sys/.../device[n]/in[_name][m]_offset_[min|max] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If a more or less continuous range of voltage offsets are supported - then these specify the minimum and maximum. If shared by all - in channels then m is not present. - -What: /sys/.../device[n]/in[_name][m]_calibbias -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration offset. (assumed to fix production - inaccuracies) - -What /sys/.../device[n]/in[_name][m]_calibscale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration scale factor. (assumed to fix production - inaccuracies) - -What: /sys/.../device[n]/in[_name][m]_scale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, scale to be applied to volt[m]_raw post - addition of in[_name][m]_offset in order to obtain the measured - voltage in millivolts. If shared across all in channels then m is not present. - -What: /sys/.../device[n]/in[m]-in[o]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled) differential voltage measurement equivalent to - channel m - channel o where these channel numbers apply to the physically - equivalent inputs when non differential readings are separately available. - In differential only parts, then all that is required is a consistent - labelling. - -What: /sys/.../device[n]/accel[_x|_y|_z][m]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Acceleration in direction x, y or z (may be arbitrarily assigned - but should match other such assignments on device) - channel m (not present if only one accelerometer channel at - this orientation). Has all of the equivalent parameters as per in[m]. - Units after application of scale and offset are m/s^2. - -What: /sys/.../device[n]/gyro[_x|_y|_z][m]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Angular velocity about axis x, y or z (may be arbitrarily assigned) - channel m (not present if only one gyroscope at this orientation). - Data converted by application of offset then scale to - radians per second. Has all the equivalent parameters as per in[m]. - -What: /sys/.../device[n]/incli[_x|_y|_z][m]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Inclination raw reading about axis x, y or z (may be arbitarily - assigned) channel m (not present if only one inclinometer at - this orientation). Data converted by application of offset - and scale to Degrees. - -What: /sys/.../device[n]/magn[_x|_y|_z][m]_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Magnetic field along axis x, y or z (may be arbitrarily assigned) - channel m (not present if only one magnetometer at this orientation). - Data converted by application of offset then scale to Gauss - Has all the equivalent modifiers as per in[m]. - -What: /sys/.../device[n]/device[n]:event[m] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Configuration of which hardware generated events are passed up to - userspace. Some of these are a bit complex to generalize so this - section is a work in progress. - -What: /sys/.../device[n]:event[m]/dev -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - major:minor character device numbers for the event line. - -Taking accel_x0 as an example - -What: /sys/.../device[n]:event[m]/accel_x0_thresh[_high|_low]_en -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Event generated when accel_x0 passes a threshold in correction direction - (or stays beyond one). If direction isn't specified, either triggers it. - Note driver will assume last p events requested are enabled where p is - however many it supports. So if you want to be sure you have - set what you think you have, check the contents of these. Drivers - may have to buffer any parameters so that they are consistent when a - given event type is enabled a future point (and not those for whatever - alarm was previously enabled). - -What: /sys/.../device[n]:event[m]/accel_x0_roc[_high|_low]_en -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Same as above but based on the first differential of the value. - - -What: /sys/.../device[n]:event[m]/accel_x0[_thresh|_roc][_high|_low]_period -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - A period of time (microsecs) for which the condition must be broken - before an interrupt is triggered. Applies to all alarms if type is not - specified. - -What: /sys/.../device[n]:event[m]/accel_x0[_thresh|_roc][_high|_low]_value -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - The actual value of the threshold in raw device units obtained by - reverse application of scale and offfset to the acceleration in m/s^2. - -What: /sys/.../device[n]/scan_elements -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Directory containing interfaces for elements that will be captured - for a single triggered sample set in the buffer. - -What: /sys/.../device[n]/scan_elements/[m]_accel_x0_en -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Scan element control for triggered data capture. m implies the - ordering within the buffer. Next the type is specified with - modifier and channel number as per the sysfs single channel - access above. - -What: /sys/.../device[n]/scan_elements/accel[_x0]_precision -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Scan element precision within the buffer. Note that the - data alignment must restrictions must be read from within - buffer to work out full data alignment for data read - via buffer_access chrdev. _x0 dropped if shared across all - acceleration channels. - -What: /sys/.../device[n]/scan_elements/accel[_x0]_shift -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - A bit shift (to right) that must be applied prior to - extracting the bits specified by accel[_x0]_precision. - -What: /sys/.../device[n]/device[n]:buffer:event/dev -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Buffer for device n event character device major:minor numbers. - -What: /sys/.../device[n]/device[n]:buffer:access/dev -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Buffer for device n access character device o major:minor numbers. - -What: /sys/.../device[n]:buffer/trigger -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - The name of the trigger source being used, as per string given - in /sys/class/iio/trigger[n]/name. - -What: /sys/.../device[n]:buffer/length -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Number of scans contained by the buffer. - -What: /sys/.../device[n]:buffer/bps -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Bytes per scan. Due to alignment fun, the scan may be larger - than implied directly by the scan_element parameters. - -What: /sys/.../device[n]:buffer/enable -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Actually start the buffer capture up. Will start trigger - if first device and appropriate. - -What: /sys/.../device[n]:buffer/alignment -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Minimum data alignment. Scan elements larger than this are aligned - to the nearest power of 2 times this. (may not be true in weird - hardware buffers that pack data well) - diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt index 4838818..ff06e5d 100644 --- a/drivers/staging/iio/Documentation/userspace.txt +++ b/drivers/staging/iio/Documentation/userspace.txt @@ -1,60 +1,12 @@ Userspace access to IIO -Example, ST Microelectronics LIS3L02DQ accelerometer. - -Typical sysfs entries (pruned for clarity) - -/sys/class/iio - device0 - iio_dev related elements - name - driver specific identifier (here lis3l02dq) - accel_x - polled (or from ring) raw readout of acceleration - accel_x_gain - hardware gain (calibration) - accel_x_offset - hardware offset (calibration) - available_sampling_frequency - - available_sampling_frequency - what options are there - sampling_frequency - control of internal sampling frequency - scan_elements - controls which channels will be stored in the ring buffer - scan_en_accel_x - scan_en_accel_y - scan_en_timestamp - device - link to underlying hardware device - uevent - udev related element - - thresh - unified threshold used for detection on all axis - event_line0_sources - which events are enabled - accel_x_high - enable x axis high threshold event - accel_x_low - enable x axis low threshold event - - event_line0 - event interface - dev - major:minor for the chrdev (note major allocation dynamic) - trigger - consumer attachement - current_trigger - name based association with a trigger - ring_buffer0 - ring buffer interface - bps - byptes per sample (read only), dependant on scan element selection - length - (rw) specificy length fo software ring buffer (typically ro in hw case) - ring_enable - turn the ring on. If its the first to be enabled attached to this - trigger will also enable the trigger. - ring_access0 - dev - major:minor for ring buffer access chrdev - ring_event_line0 - dev - major:minor for ring buffer event chrdev - - trigger0 - data ready trigger elements - name - unqiue name of trigger +The sysfs attributes are documented in sysfs-bus-iio. Udev will create the following entries under /dev by default: -ring_access0 - ring access chrdev -ring_event0 - ring event chrdev -event_line0 - general event chrdev. - -For the example code we assume the following rules have been used to ensure -unique and consistent naming of these for the lis3l02dq in question: - -KERNEL="ring_event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_event" -KERNEL="event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_event" -KERNEL="ring_access*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_access" +device0:buffer0:access0 - ring access chrdev +device0:buffer0:event0 - ring event chrdev +device0:event0 - general event chrdev. The files, lis3l02dqbuffersimple.c and iio_utils.h in this directory provide an example of how to use the ring buffer and event interfaces. |