diff options
| author | Linus Walleij <linus.walleij@linaro.org> | 2016-04-14 04:26:47 -0400 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2016-04-19 14:58:13 -0400 |
| commit | 5f991a921a08279f573fa5ecf84261a3a6fac0cc (patch) | |
| tree | 03a33955b0dc98110f0fb4a16ea98bd90968b73c /tools/iio | |
| parent | 0e6f6871a1591f4bb0971809c45bc91a991f1967 (diff) | |
iio: tools: generic_buffer: auto-enable channels
If no channels are enabled when we run generic_buffer on a
device, add a command-line option to just enable all of them,
run the sampling and disable them all again afterwards.
This is extremely useful when I'm low-level testing my
sensors with interrupts and triggers, sample session:
root@Ux500:/ lsiio
Device 000: lsm303dlh_accel
Device 001: lis331dl_accel
Device 002: l3g4200d
Device 003: lsm303dlh_magn
Device 004: lps001wp
Trigger 000: lsm303dlh_accel-trigger
Trigger 001: lis331dl_accel-trigger
Trigger 002: l3g4200d-trigger
root@Ux500:/ generic_buffer -a -c 10 -n l3g4200d
iio device number being used is 2
iio trigger number being used is 2
No channels are enabled, enabling all channels
Enabling: in_anglvel_x_en
Enabling: in_anglvel_y_en
Enabling: in_anglvel_z_en
Enabling: in_timestamp_en
/sys/bus/iio/devices/iio:device2 l3g4200d-trigger
-3.593664 -0.713133 4.870143 946684863662292480
3.225546 0.867357 -4.945878 946684863671875000
-0.676413 0.127296 0.106641 946684863681488037
-0.661113 0.110160 0.128826 946684863690673828
-0.664173 0.113067 0.123471 946684863700683593
-0.664938 0.109395 0.124848 946684863710144042
-0.664173 0.110619 0.130203 946684863719512939
-0.666162 0.111231 0.132651 946684863729125976
-0.668610 0.111690 0.130662 946684863738739013
-0.660501 0.110466 0.131733 946684863748565673
Disabling: in_anglvel_x_en
Disabling: in_anglvel_y_en
Disabling: in_anglvel_z_en
Disabling: in_timestamp_en
Pure awesomeness. If some channels have been enabled through
scripts or manual interaction, nothing happens.
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Acked-by: Daniel Baluta <daniel.baluta@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'tools/iio')
| -rw-r--r-- | tools/iio/generic_buffer.c | 102 | ||||
| -rw-r--r-- | tools/iio/iio_utils.h | 7 |
2 files changed, 105 insertions, 4 deletions
diff --git a/tools/iio/generic_buffer.c b/tools/iio/generic_buffer.c index c42b7f836b48..2429c78de940 100644 --- a/tools/iio/generic_buffer.c +++ b/tools/iio/generic_buffer.c | |||
| @@ -35,6 +35,15 @@ | |||
| 35 | #include "iio_utils.h" | 35 | #include "iio_utils.h" |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * enum autochan - state for the automatic channel enabling mechanism | ||
| 39 | */ | ||
| 40 | enum autochan { | ||
| 41 | AUTOCHANNELS_DISABLED, | ||
| 42 | AUTOCHANNELS_ENABLED, | ||
| 43 | AUTOCHANNELS_ACTIVE, | ||
| 44 | }; | ||
| 45 | |||
| 46 | /** | ||
| 38 | * size_from_channelarray() - calculate the storage size of a scan | 47 | * size_from_channelarray() - calculate the storage size of a scan |
| 39 | * @channels: the channel info array | 48 | * @channels: the channel info array |
| 40 | * @num_channels: number of channels | 49 | * @num_channels: number of channels |
| @@ -191,10 +200,51 @@ void process_scan(char *data, | |||
| 191 | printf("\n"); | 200 | printf("\n"); |
| 192 | } | 201 | } |
| 193 | 202 | ||
| 203 | static int enable_disable_all_channels(char *dev_dir_name, int enable) | ||
| 204 | { | ||
| 205 | const struct dirent *ent; | ||
| 206 | char scanelemdir[256]; | ||
| 207 | DIR *dp; | ||
| 208 | int ret; | ||
| 209 | |||
| 210 | snprintf(scanelemdir, sizeof(scanelemdir), | ||
| 211 | FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name); | ||
| 212 | scanelemdir[sizeof(scanelemdir)-1] = '\0'; | ||
| 213 | |||
| 214 | dp = opendir(scanelemdir); | ||
| 215 | if (!dp) { | ||
| 216 | fprintf(stderr, "Enabling/disabling channels: can't open %s\n", | ||
| 217 | scanelemdir); | ||
| 218 | return -EIO; | ||
| 219 | } | ||
| 220 | |||
| 221 | ret = -ENOENT; | ||
| 222 | while (ent = readdir(dp), ent) { | ||
| 223 | if (iioutils_check_suffix(ent->d_name, "_en")) { | ||
| 224 | printf("%sabling: %s\n", | ||
| 225 | enable ? "En" : "Dis", | ||
| 226 | ent->d_name); | ||
| 227 | ret = write_sysfs_int(ent->d_name, scanelemdir, | ||
| 228 | enable); | ||
| 229 | if (ret < 0) | ||
| 230 | fprintf(stderr, "Failed to enable/disable %s\n", | ||
| 231 | ent->d_name); | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | if (closedir(dp) == -1) { | ||
| 236 | perror("Enabling/disabling channels: " | ||
| 237 | "Failed to close directory"); | ||
| 238 | return -errno; | ||
| 239 | } | ||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 194 | void print_usage(void) | 243 | void print_usage(void) |
| 195 | { | 244 | { |
| 196 | fprintf(stderr, "Usage: generic_buffer [options]...\n" | 245 | fprintf(stderr, "Usage: generic_buffer [options]...\n" |
| 197 | "Capture, convert and output data from IIO device buffer\n" | 246 | "Capture, convert and output data from IIO device buffer\n" |
| 247 | " -a Auto-activate all available channels\n" | ||
| 198 | " -c <n> Do n conversions\n" | 248 | " -c <n> Do n conversions\n" |
| 199 | " -e Disable wait for event (new data)\n" | 249 | " -e Disable wait for event (new data)\n" |
| 200 | " -g Use trigger-less mode\n" | 250 | " -g Use trigger-less mode\n" |
| @@ -225,12 +275,16 @@ int main(int argc, char **argv) | |||
| 225 | int scan_size; | 275 | int scan_size; |
| 226 | int noevents = 0; | 276 | int noevents = 0; |
| 227 | int notrigger = 0; | 277 | int notrigger = 0; |
| 278 | enum autochan autochannels = AUTOCHANNELS_DISABLED; | ||
| 228 | char *dummy; | 279 | char *dummy; |
| 229 | 280 | ||
| 230 | struct iio_channel_info *channels; | 281 | struct iio_channel_info *channels; |
| 231 | 282 | ||
| 232 | while ((c = getopt(argc, argv, "c:egl:n:t:w:")) != -1) { | 283 | while ((c = getopt(argc, argv, "ac:egl:n:t:w:")) != -1) { |
| 233 | switch (c) { | 284 | switch (c) { |
| 285 | case 'a': | ||
| 286 | autochannels = AUTOCHANNELS_ENABLED; | ||
| 287 | break; | ||
| 234 | case 'c': | 288 | case 'c': |
| 235 | errno = 0; | 289 | errno = 0; |
| 236 | num_loops = strtoul(optarg, &dummy, 10); | 290 | num_loops = strtoul(optarg, &dummy, 10); |
| @@ -340,12 +394,47 @@ int main(int argc, char **argv) | |||
| 340 | "diag %s\n", dev_dir_name); | 394 | "diag %s\n", dev_dir_name); |
| 341 | goto error_free_triggername; | 395 | goto error_free_triggername; |
| 342 | } | 396 | } |
| 343 | if (!num_channels) { | 397 | if (num_channels && autochannels == AUTOCHANNELS_ENABLED) { |
| 398 | fprintf(stderr, "Auto-channels selected but some channels " | ||
| 399 | "are already activated in sysfs\n"); | ||
| 400 | fprintf(stderr, "Proceeding without activating any channels\n"); | ||
| 401 | } | ||
| 402 | |||
| 403 | if (!num_channels && autochannels == AUTOCHANNELS_ENABLED) { | ||
| 404 | fprintf(stderr, | ||
| 405 | "No channels are enabled, enabling all channels\n"); | ||
| 406 | |||
| 407 | ret = enable_disable_all_channels(dev_dir_name, 1); | ||
| 408 | if (ret) { | ||
| 409 | fprintf(stderr, "Failed to enable all channels\n"); | ||
| 410 | goto error_free_triggername; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* This flags that we need to disable the channels again */ | ||
| 414 | autochannels = AUTOCHANNELS_ACTIVE; | ||
| 415 | |||
| 416 | ret = build_channel_array(dev_dir_name, &channels, | ||
| 417 | &num_channels); | ||
| 418 | if (ret) { | ||
| 419 | fprintf(stderr, "Problem reading scan element " | ||
| 420 | "information\n" | ||
| 421 | "diag %s\n", dev_dir_name); | ||
| 422 | goto error_disable_channels; | ||
| 423 | } | ||
| 424 | if (!num_channels) { | ||
| 425 | fprintf(stderr, "Still no channels after " | ||
| 426 | "auto-enabling, giving up\n"); | ||
| 427 | goto error_disable_channels; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) { | ||
| 344 | fprintf(stderr, | 432 | fprintf(stderr, |
| 345 | "No channels are enabled, we have nothing to scan.\n"); | 433 | "No channels are enabled, we have nothing to scan.\n"); |
| 346 | fprintf(stderr, "Enable channels manually in " | 434 | fprintf(stderr, "Enable channels manually in " |
| 347 | FORMAT_SCAN_ELEMENTS_DIR | 435 | FORMAT_SCAN_ELEMENTS_DIR |
| 348 | "/*_en and try again.\n", dev_dir_name); | 436 | "/*_en or pass -a to autoenable channels and " |
| 437 | "try again.\n", dev_dir_name); | ||
| 349 | ret = -ENOENT; | 438 | ret = -ENOENT; |
| 350 | goto error_free_triggername; | 439 | goto error_free_triggername; |
| 351 | } | 440 | } |
| @@ -479,7 +568,12 @@ error_free_channels: | |||
| 479 | error_free_triggername: | 568 | error_free_triggername: |
| 480 | if (datardytrigger) | 569 | if (datardytrigger) |
| 481 | free(trigger_name); | 570 | free(trigger_name); |
| 482 | 571 | error_disable_channels: | |
| 572 | if (autochannels == AUTOCHANNELS_ACTIVE) { | ||
| 573 | ret = enable_disable_all_channels(dev_dir_name, 0); | ||
| 574 | if (ret) | ||
| 575 | fprintf(stderr, "Failed to disable all channels\n"); | ||
| 576 | } | ||
| 483 | error_free_dev_dir_name: | 577 | error_free_dev_dir_name: |
| 484 | free(dev_dir_name); | 578 | free(dev_dir_name); |
| 485 | 579 | ||
diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h index e3503bfe538b..780f2014f8fa 100644 --- a/tools/iio/iio_utils.h +++ b/tools/iio/iio_utils.h | |||
| @@ -52,6 +52,13 @@ struct iio_channel_info { | |||
| 52 | unsigned location; | 52 | unsigned location; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | static inline int iioutils_check_suffix(const char *str, const char *suffix) | ||
| 56 | { | ||
| 57 | return strlen(str) >= strlen(suffix) && | ||
| 58 | strncmp(str+strlen(str)-strlen(suffix), | ||
| 59 | suffix, strlen(suffix)) == 0; | ||
| 60 | } | ||
| 61 | |||
| 55 | int iioutils_break_up_name(const char *full_name, char **generic_name); | 62 | int iioutils_break_up_name(const char *full_name, char **generic_name); |
| 56 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, | 63 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, |
| 57 | unsigned *shift, uint64_t *mask, unsigned *be, | 64 | unsigned *shift, uint64_t *mask, unsigned *be, |
