aboutsummaryrefslogtreecommitdiffstats
path: root/tools/iio/iio_generic_buffer.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-09 12:15:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-09 12:15:58 -0400
commitaabb406008fc722ff2c992867d755ec2176e55b5 (patch)
treecfac80cb56a9a32ff73c62609b57c05b691ccf4c /tools/iio/iio_generic_buffer.c
parent73e81350ad7a45117c17fb3ec433a266b3fa7d78 (diff)
parentbc2e1126eccb47517b9d1c685020c38600f99a3d (diff)
Merge tag 'iio-for-4.8a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First round of IIO new device support, features and cleanups for the 4.8 cycle. New device support * ads1015 - add ads1115 support * bma220 accelerometer - new driver - triggered buffer support. * bmc150 - add bmm150 support. * bmp280 - bme280 support with addition of humidity channel. * max5487 potentiometer - new driver * MMA7660FC accelerometer. - New driver * st-pressure - support for the lps22hb * loop trigger. - This one is *nasty* but we have real applications (parrot drones) where it is useful. The trigger basically spins as hard as it can firing off a new trigger each time all triggered devices come back to say they are done. It doesn't hang a machine even when doing it on a dummy driver. A lot nicer than having this implemented within lots of device drivers anyway. Core stuff * Add support to create IIO devices via configfs (similar to we did for triggers a while back) + docs. * New channel types - IIO_ELECTRICAL_CONDUCTIVITY * Couple of MAINTAINERS patches to list the device tree bindings. * Make trigger ops structure non optional (comment fix). It hasn't been for an awful long time, but that's not what the description said. New features * ak8975 - support adapters that are limited to byte data only by allowing the emulated block read i2c function that was recently introduced. * atlas-ph - support atlas-ec (electrical conductivity sensor) * bmi160 - add available frequency and scale attributes to make the driver more user friendly (and avoid having to read the datasheet to know what will work). * dummy - move creation to configfs interface. It's not real hardware so we are not that worried about the ABI breakage ;) * mma8452 - oversampling ration support * nau7802 - expose available gains to make life easier for userspace. * st-sensors - allow use of emulation for SMBus block reads as all the st parts support it. * ti-ads1015 - list datasheet names to allow their use by inkernel consumers. * Various module alias additions to help auto probing. Drop one redundant one as well. Cleanups * ad7266, ad7476, ad7887, ad7923, ad799x - use direct mode claim function rather than open coding it during sensor read (prevents switching on buffers mid read). * ad7793, ad7791 - use direct mode claim to prevent frequency changes when buffers running. * afe440x - These are ABI breaking but the driver requires custom userspace code to do anything useful anyway and that is still being written and under control of TI. Ultimately we may have other libraries to do pulse oximetry with these devices but we aren't aware of any yet. - kernel-doc format fixes - drop ifdef fun around of_match_ptr - it's not worth the mess to save a tiny amount of space. - drop some unnecessary register initializations. - drop the weird locked gain modes as they gain us nothing (can just set all gains separately). - remove handling of offset attributes seeing as no channels actually have them (oops) - Drop the LED3 input channel as it's an alias for ALED2. - *big one* remove channel names - an experiment that turned out to not make sense - see patch for details. - use regmap fields to clean up code. - tie the tia gain stages to appropriate channels in the ABI as that is what they really effect. Same with the LED currents. - cleanout some unused defines and fix a missnamed one. * atlas-ph - reorganise to allow support of other similar parts. * bmc150 - document supported chips in kconfig help. * jsa1212 - drop an unneeded i2c functionality check for functionality the driver doesn't use. * mxs-lradc - simply touch screen registration code. - remove the touch screen unregister as all devm based now. - disable only those channels that are masked in hardware stop (others are already dealt with elsewhere) * st-sensors - unexport st_sensors_get_buffer_element as nothing outside the st-sensors core driver uses it. - fix handling of failure to start up regulators. * tpl0102 - drop an i2c functionality test for features that aren't needed. * ti-am335x - use variable name rather than type in sizeof for clarity. - use SIMPLE_DEV_PM_OPS helper macro to tidy up a bit. Tools * Add install / uninstall to makefile. Someone cares, so presumably some people will find it useful! * generic_buffer - rename to iio_generic_buffer to line up with other tools. - handle cleanup when receiving signals - Add a --device-num option and a --trigger-num option rather than relying on naming which doesn't work if you have two of the same part.
Diffstat (limited to 'tools/iio/iio_generic_buffer.c')
-rw-r--r--tools/iio/iio_generic_buffer.c682
1 files changed, 682 insertions, 0 deletions
diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
new file mode 100644
index 000000000000..e8c30521e99c
--- /dev/null
+++ b/tools/iio/iio_generic_buffer.c
@@ -0,0 +1,682 @@
1/* Industrialio buffer test code.
2 *
3 * Copyright (c) 2008 Jonathan Cameron
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is primarily intended as an example application.
10 * Reads the current buffer setup from sysfs and starts a short capture
11 * from the specified device, pretty printing the result after appropriate
12 * conversion.
13 *
14 * Command line parameters
15 * generic_buffer -n <device_name> -t <trigger_name>
16 * If trigger name is not specified the program assumes you want a dataready
17 * trigger associated with the device and goes looking for it.
18 *
19 */
20
21#include <unistd.h>
22#include <stdlib.h>
23#include <dirent.h>
24#include <fcntl.h>
25#include <stdio.h>
26#include <errno.h>
27#include <sys/stat.h>
28#include <sys/dir.h>
29#include <linux/types.h>
30#include <string.h>
31#include <poll.h>
32#include <endian.h>
33#include <getopt.h>
34#include <inttypes.h>
35#include <stdbool.h>
36#include <signal.h>
37#include "iio_utils.h"
38
39/**
40 * enum autochan - state for the automatic channel enabling mechanism
41 */
42enum autochan {
43 AUTOCHANNELS_DISABLED,
44 AUTOCHANNELS_ENABLED,
45 AUTOCHANNELS_ACTIVE,
46};
47
48/**
49 * size_from_channelarray() - calculate the storage size of a scan
50 * @channels: the channel info array
51 * @num_channels: number of channels
52 *
53 * Has the side effect of filling the channels[i].location values used
54 * in processing the buffer output.
55 **/
56int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
57{
58 int bytes = 0;
59 int i = 0;
60
61 while (i < num_channels) {
62 if (bytes % channels[i].bytes == 0)
63 channels[i].location = bytes;
64 else
65 channels[i].location = bytes - bytes % channels[i].bytes
66 + channels[i].bytes;
67
68 bytes = channels[i].location + channels[i].bytes;
69 i++;
70 }
71
72 return bytes;
73}
74
75void print1byte(uint8_t input, struct iio_channel_info *info)
76{
77 /*
78 * Shift before conversion to avoid sign extension
79 * of left aligned data
80 */
81 input >>= info->shift;
82 input &= info->mask;
83 if (info->is_signed) {
84 int8_t val = (int8_t)(input << (8 - info->bits_used)) >>
85 (8 - info->bits_used);
86 printf("%05f ", ((float)val + info->offset) * info->scale);
87 } else {
88 printf("%05f ", ((float)input + info->offset) * info->scale);
89 }
90}
91
92void print2byte(uint16_t input, struct iio_channel_info *info)
93{
94 /* First swap if incorrect endian */
95 if (info->be)
96 input = be16toh(input);
97 else
98 input = le16toh(input);
99
100 /*
101 * Shift before conversion to avoid sign extension
102 * of left aligned data
103 */
104 input >>= info->shift;
105 input &= info->mask;
106 if (info->is_signed) {
107 int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
108 (16 - info->bits_used);
109 printf("%05f ", ((float)val + info->offset) * info->scale);
110 } else {
111 printf("%05f ", ((float)input + info->offset) * info->scale);
112 }
113}
114
115void print4byte(uint32_t input, struct iio_channel_info *info)
116{
117 /* First swap if incorrect endian */
118 if (info->be)
119 input = be32toh(input);
120 else
121 input = le32toh(input);
122
123 /*
124 * Shift before conversion to avoid sign extension
125 * of left aligned data
126 */
127 input >>= info->shift;
128 input &= info->mask;
129 if (info->is_signed) {
130 int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
131 (32 - info->bits_used);
132 printf("%05f ", ((float)val + info->offset) * info->scale);
133 } else {
134 printf("%05f ", ((float)input + info->offset) * info->scale);
135 }
136}
137
138void print8byte(uint64_t input, struct iio_channel_info *info)
139{
140 /* First swap if incorrect endian */
141 if (info->be)
142 input = be64toh(input);
143 else
144 input = le64toh(input);
145
146 /*
147 * Shift before conversion to avoid sign extension
148 * of left aligned data
149 */
150 input >>= info->shift;
151 input &= info->mask;
152 if (info->is_signed) {
153 int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
154 (64 - info->bits_used);
155 /* special case for timestamp */
156 if (info->scale == 1.0f && info->offset == 0.0f)
157 printf("%" PRId64 " ", val);
158 else
159 printf("%05f ",
160 ((float)val + info->offset) * info->scale);
161 } else {
162 printf("%05f ", ((float)input + info->offset) * info->scale);
163 }
164}
165
166/**
167 * process_scan() - print out the values in SI units
168 * @data: pointer to the start of the scan
169 * @channels: information about the channels.
170 * Note: size_from_channelarray must have been called first
171 * to fill the location offsets.
172 * @num_channels: number of channels
173 **/
174void process_scan(char *data,
175 struct iio_channel_info *channels,
176 int num_channels)
177{
178 int k;
179
180 for (k = 0; k < num_channels; k++)
181 switch (channels[k].bytes) {
182 /* only a few cases implemented so far */
183 case 1:
184 print1byte(*(uint8_t *)(data + channels[k].location),
185 &channels[k]);
186 break;
187 case 2:
188 print2byte(*(uint16_t *)(data + channels[k].location),
189 &channels[k]);
190 break;
191 case 4:
192 print4byte(*(uint32_t *)(data + channels[k].location),
193 &channels[k]);
194 break;
195 case 8:
196 print8byte(*(uint64_t *)(data + channels[k].location),
197 &channels[k]);
198 break;
199 default:
200 break;
201 }
202 printf("\n");
203}
204
205static int enable_disable_all_channels(char *dev_dir_name, int enable)
206{
207 const struct dirent *ent;
208 char scanelemdir[256];
209 DIR *dp;
210 int ret;
211
212 snprintf(scanelemdir, sizeof(scanelemdir),
213 FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
214 scanelemdir[sizeof(scanelemdir)-1] = '\0';
215
216 dp = opendir(scanelemdir);
217 if (!dp) {
218 fprintf(stderr, "Enabling/disabling channels: can't open %s\n",
219 scanelemdir);
220 return -EIO;
221 }
222
223 ret = -ENOENT;
224 while (ent = readdir(dp), ent) {
225 if (iioutils_check_suffix(ent->d_name, "_en")) {
226 printf("%sabling: %s\n",
227 enable ? "En" : "Dis",
228 ent->d_name);
229 ret = write_sysfs_int(ent->d_name, scanelemdir,
230 enable);
231 if (ret < 0)
232 fprintf(stderr, "Failed to enable/disable %s\n",
233 ent->d_name);
234 }
235 }
236
237 if (closedir(dp) == -1) {
238 perror("Enabling/disabling channels: "
239 "Failed to close directory");
240 return -errno;
241 }
242 return 0;
243}
244
245void print_usage(void)
246{
247 fprintf(stderr, "Usage: generic_buffer [options]...\n"
248 "Capture, convert and output data from IIO device buffer\n"
249 " -a Auto-activate all available channels\n"
250 " -c <n> Do n conversions\n"
251 " -e Disable wait for event (new data)\n"
252 " -g Use trigger-less mode\n"
253 " -l <n> Set buffer length to n samples\n"
254 " --device-name -n <name>\n"
255 " --device-num -N <num>\n"
256 " Set device by name or number (mandatory)\n"
257 " --trigger-name -t <name>\n"
258 " --trigger-num -T <num>\n"
259 " Set trigger by name or number\n"
260 " -w <n> Set delay between reads in us (event-less mode)\n");
261}
262
263enum autochan autochannels = AUTOCHANNELS_DISABLED;
264char *dev_dir_name = NULL;
265char *buf_dir_name = NULL;
266bool current_trigger_set = false;
267
268void cleanup(void)
269{
270 int ret;
271
272 /* Disable trigger */
273 if (dev_dir_name && current_trigger_set) {
274 /* Disconnect the trigger - just write a dummy name. */
275 ret = write_sysfs_string("trigger/current_trigger",
276 dev_dir_name, "NULL");
277 if (ret < 0)
278 fprintf(stderr, "Failed to disable trigger: %s\n",
279 strerror(-ret));
280 current_trigger_set = false;
281 }
282
283 /* Disable buffer */
284 if (buf_dir_name) {
285 ret = write_sysfs_int("enable", buf_dir_name, 0);
286 if (ret < 0)
287 fprintf(stderr, "Failed to disable buffer: %s\n",
288 strerror(-ret));
289 }
290
291 /* Disable channels if auto-enabled */
292 if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
293 ret = enable_disable_all_channels(dev_dir_name, 0);
294 if (ret)
295 fprintf(stderr, "Failed to disable all channels\n");
296 autochannels = AUTOCHANNELS_DISABLED;
297 }
298}
299
300void sig_handler(int signum)
301{
302 fprintf(stderr, "Caught signal %d\n", signum);
303 cleanup();
304 exit(-signum);
305}
306
307void register_cleanup(void)
308{
309 struct sigaction sa = { .sa_handler = sig_handler };
310 const int signums[] = { SIGINT, SIGTERM, SIGABRT };
311 int ret, i;
312
313 for (i = 0; i < ARRAY_SIZE(signums); ++i) {
314 ret = sigaction(signums[i], &sa, NULL);
315 if (ret) {
316 perror("Failed to register signal handler");
317 exit(-1);
318 }
319 }
320}
321
322static const struct option longopts[] = {
323 { "device-name", 1, 0, 'n' },
324 { "device-num", 1, 0, 'N' },
325 { "trigger-name", 1, 0, 't' },
326 { "trigger-num", 1, 0, 'T' },
327 { },
328};
329
330int main(int argc, char **argv)
331{
332 unsigned long num_loops = 2;
333 unsigned long timedelay = 1000000;
334 unsigned long buf_len = 128;
335
336 int ret, c, i, j, toread;
337 int fp = -1;
338
339 int num_channels = 0;
340 char *trigger_name = NULL, *device_name = NULL;
341
342 char *data = NULL;
343 ssize_t read_size;
344 int dev_num = -1, trig_num;
345 char *buffer_access = NULL;
346 int scan_size;
347 int noevents = 0;
348 int notrigger = 0;
349 char *dummy;
350
351 struct iio_channel_info *channels;
352
353 register_cleanup();
354
355 while ((c = getopt_long(argc, argv, "ac:egl:n:N:t:T:w:", longopts, NULL)) != -1) {
356 switch (c) {
357 case 'a':
358 autochannels = AUTOCHANNELS_ENABLED;
359 break;
360 case 'c':
361 errno = 0;
362 num_loops = strtoul(optarg, &dummy, 10);
363 if (errno) {
364 ret = -errno;
365 goto error;
366 }
367
368 break;
369 case 'e':
370 noevents = 1;
371 break;
372 case 'g':
373 notrigger = 1;
374 break;
375 case 'l':
376 errno = 0;
377 buf_len = strtoul(optarg, &dummy, 10);
378 if (errno) {
379 ret = -errno;
380 goto error;
381 }
382
383 break;
384 case 'n':
385 device_name = strdup(optarg);
386 break;
387 case 'N':
388 errno = 0;
389 dev_num = strtoul(optarg, &dummy, 10);
390 if (errno) {
391 ret = -errno;
392 goto error;
393 }
394 break;
395 case 't':
396 trigger_name = strdup(optarg);
397 break;
398 case 'T':
399 errno = 0;
400 trig_num = strtoul(optarg, &dummy, 10);
401 if (errno)
402 return -errno;
403 break;
404 case 'w':
405 errno = 0;
406 timedelay = strtoul(optarg, &dummy, 10);
407 if (errno) {
408 ret = -errno;
409 goto error;
410 }
411 break;
412 case '?':
413 print_usage();
414 ret = -1;
415 goto error;
416 }
417 }
418
419 /* Find the device requested */
420 if (dev_num < 0 && !device_name) {
421 fprintf(stderr, "Device not set\n");
422 print_usage();
423 ret = -1;
424 goto error;
425 } else if (dev_num >= 0 && device_name) {
426 fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
427 print_usage();
428 ret = -1;
429 goto error;
430 } else if (dev_num < 0) {
431 dev_num = find_type_by_name(device_name, "iio:device");
432 if (dev_num < 0) {
433 fprintf(stderr, "Failed to find the %s\n", device_name);
434 ret = dev_num;
435 goto error;
436 }
437 }
438 printf("iio device number being used is %d\n", dev_num);
439
440 ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
441 if (ret < 0)
442 return -ENOMEM;
443 /* Fetch device_name if specified by number */
444 if (!device_name) {
445 device_name = malloc(IIO_MAX_NAME_LENGTH);
446 if (!device_name) {
447 ret = -ENOMEM;
448 goto error;
449 }
450 ret = read_sysfs_string("name", dev_dir_name, device_name);
451 if (ret < 0) {
452 fprintf(stderr, "Failed to read name of device %d\n", dev_num);
453 goto error;
454 }
455 }
456
457 if (notrigger) {
458 printf("trigger-less mode selected\n");
459 } if (trig_num > 0) {
460 char *trig_dev_name;
461 ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
462 if (ret < 0) {
463 return -ENOMEM;
464 }
465 trigger_name = malloc(IIO_MAX_NAME_LENGTH);
466 ret = read_sysfs_string("name", trig_dev_name, trigger_name);
467 free(trig_dev_name);
468 if (ret < 0) {
469 fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
470 return ret;
471 }
472 printf("iio trigger number being used is %d\n", trig_num);
473 } else {
474 if (!trigger_name) {
475 /*
476 * Build the trigger name. If it is device associated
477 * its name is <device_name>_dev[n] where n matches
478 * the device number found above.
479 */
480 ret = asprintf(&trigger_name,
481 "%s-dev%d", device_name, dev_num);
482 if (ret < 0) {
483 ret = -ENOMEM;
484 goto error;
485 }
486 }
487
488 /* Look for this "-devN" trigger */
489 trig_num = find_type_by_name(trigger_name, "trigger");
490 if (trig_num < 0) {
491 /* OK try the simpler "-trigger" suffix instead */
492 free(trigger_name);
493 ret = asprintf(&trigger_name,
494 "%s-trigger", device_name);
495 if (ret < 0) {
496 ret = -ENOMEM;
497 goto error;
498 }
499 }
500
501 trig_num = find_type_by_name(trigger_name, "trigger");
502 if (trig_num < 0) {
503 fprintf(stderr, "Failed to find the trigger %s\n",
504 trigger_name);
505 ret = trig_num;
506 goto error;
507 }
508
509 printf("iio trigger number being used is %d\n", trig_num);
510 }
511
512 /*
513 * Parse the files in scan_elements to identify what channels are
514 * present
515 */
516 ret = build_channel_array(dev_dir_name, &channels, &num_channels);
517 if (ret) {
518 fprintf(stderr, "Problem reading scan element information\n"
519 "diag %s\n", dev_dir_name);
520 goto error;
521 }
522 if (num_channels && autochannels == AUTOCHANNELS_ENABLED) {
523 fprintf(stderr, "Auto-channels selected but some channels "
524 "are already activated in sysfs\n");
525 fprintf(stderr, "Proceeding without activating any channels\n");
526 }
527
528 if (!num_channels && autochannels == AUTOCHANNELS_ENABLED) {
529 fprintf(stderr,
530 "No channels are enabled, enabling all channels\n");
531
532 ret = enable_disable_all_channels(dev_dir_name, 1);
533 if (ret) {
534 fprintf(stderr, "Failed to enable all channels\n");
535 goto error;
536 }
537
538 /* This flags that we need to disable the channels again */
539 autochannels = AUTOCHANNELS_ACTIVE;
540
541 ret = build_channel_array(dev_dir_name, &channels,
542 &num_channels);
543 if (ret) {
544 fprintf(stderr, "Problem reading scan element "
545 "information\n"
546 "diag %s\n", dev_dir_name);
547 goto error;
548 }
549 if (!num_channels) {
550 fprintf(stderr, "Still no channels after "
551 "auto-enabling, giving up\n");
552 goto error;
553 }
554 }
555
556 if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) {
557 fprintf(stderr,
558 "No channels are enabled, we have nothing to scan.\n");
559 fprintf(stderr, "Enable channels manually in "
560 FORMAT_SCAN_ELEMENTS_DIR
561 "/*_en or pass -a to autoenable channels and "
562 "try again.\n", dev_dir_name);
563 ret = -ENOENT;
564 goto error;
565 }
566
567 /*
568 * Construct the directory name for the associated buffer.
569 * As we know that the lis3l02dq has only one buffer this may
570 * be built rather than found.
571 */
572 ret = asprintf(&buf_dir_name,
573 "%siio:device%d/buffer", iio_dir, dev_num);
574 if (ret < 0) {
575 ret = -ENOMEM;
576 goto error;
577 }
578
579 if (!notrigger) {
580 printf("%s %s\n", dev_dir_name, trigger_name);
581 /*
582 * Set the device trigger to be the data ready trigger found
583 * above
584 */
585 ret = write_sysfs_string_and_verify("trigger/current_trigger",
586 dev_dir_name,
587 trigger_name);
588 if (ret < 0) {
589 fprintf(stderr,
590 "Failed to write current_trigger file\n");
591 goto error;
592 }
593 }
594
595 /* Setup ring buffer parameters */
596 ret = write_sysfs_int("length", buf_dir_name, buf_len);
597 if (ret < 0)
598 goto error;
599
600 /* Enable the buffer */
601 ret = write_sysfs_int("enable", buf_dir_name, 1);
602 if (ret < 0) {
603 fprintf(stderr,
604 "Failed to enable buffer: %s\n", strerror(-ret));
605 goto error;
606 }
607
608 scan_size = size_from_channelarray(channels, num_channels);
609 data = malloc(scan_size * buf_len);
610 if (!data) {
611 ret = -ENOMEM;
612 goto error;
613 }
614
615 ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
616 if (ret < 0) {
617 ret = -ENOMEM;
618 goto error;
619 }
620
621 /* Attempt to open non blocking the access dev */
622 fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
623 if (fp == -1) { /* TODO: If it isn't there make the node */
624 ret = -errno;
625 fprintf(stderr, "Failed to open %s\n", buffer_access);
626 goto error;
627 }
628
629 for (j = 0; j < num_loops; j++) {
630 if (!noevents) {
631 struct pollfd pfd = {
632 .fd = fp,
633 .events = POLLIN,
634 };
635
636 ret = poll(&pfd, 1, -1);
637 if (ret < 0) {
638 ret = -errno;
639 goto error;
640 } else if (ret == 0) {
641 continue;
642 }
643
644 toread = buf_len;
645 } else {
646 usleep(timedelay);
647 toread = 64;
648 }
649
650 read_size = read(fp, data, toread * scan_size);
651 if (read_size < 0) {
652 if (errno == EAGAIN) {
653 fprintf(stderr, "nothing available\n");
654 continue;
655 } else {
656 break;
657 }
658 }
659 for (i = 0; i < read_size / scan_size; i++)
660 process_scan(data + scan_size * i, channels,
661 num_channels);
662 }
663
664error:
665 cleanup();
666
667 if (fp >= 0 && close(fp) == -1)
668 perror("Failed to close buffer");
669 free(buffer_access);
670 free(data);
671 free(buf_dir_name);
672 for (i = num_channels - 1; i >= 0; i--) {
673 free(channels[i].name);
674 free(channels[i].generic_name);
675 }
676 free(channels);
677 free(trigger_name);
678 free(device_name);
679 free(dev_dir_name);
680
681 return ret;
682}