core: new set/get value helpers
authorBartosz Golaszewski <bartekgola@gmail.com>
Tue, 17 Jan 2017 08:15:47 +0000 (09:15 +0100)
committerBartosz Golaszewski <bartekgola@gmail.com>
Tue, 17 Jan 2017 08:15:47 +0000 (09:15 +0100)
Implement simple set/get value routines for multiple lines.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
include/gpiod.h
src/lib/core.c

index efd5d4c4e3f96014d33687502ef6c7a57e71e38d..59f0b22689ee980ede485b3135501b73db51b263 100644 (file)
@@ -117,16 +117,55 @@ const char * gpiod_last_strerror(void) GPIOD_API;
  * Simple high-level routines for straightforward GPIO manipulation.
  */
 
+/**
+ * @brief Read current values from a set of GPIO lines.
+ * @param device Name, path or number of the gpiochip.
+ * @param offsets An array of offsets of lines whose values should be read.
+ * @param values A buffer in which the values will be stored.
+ * @param num_lines Number of lines.
+ * @param active_low The active state of the lines - true if low.
+ * @return 0 if the operation succeeds, -1 on error.
+ */
+int gpiod_simple_get_value_multiple(const char *device, unsigned int *offsets,
+                                   int *values, unsigned int num_lines,
+                                   bool active_low) GPIOD_API;
+
 /**
  * @brief Read current value from a single GPIO line.
  * @param device Name, path or number of the gpiochip.
  * @param offset GPIO line offset on the chip.
  * @param active_low The active state of this line - true if low.
- * @return 0 or 1 if the operation succeeds. On error this routine returns -1
- *         and sets the last error number.
+ * @return 0 or 1 (GPIO value) if the operation succeeds, -1 on error.
  */
-int gpiod_simple_get_value(const char *device,
-                          unsigned int offset, bool active_low) GPIOD_API;
+static inline int gpiod_simple_get_value(const char *device,
+                                        unsigned int offset, bool active_low)
+{
+       int value, status;
+
+       status = gpiod_simple_get_value_multiple(device, &offset,
+                                                &value, 1, active_low);
+       if (status < 0)
+               return status;
+
+       return value;
+}
+
+/**
+ * @brief Set values of a set of a set of GPIO lines.
+ * @param device Name, path or number of the gpiochip.
+ * @param offsets An array of offsets of lines whose values should be set.
+ * @param values An array of integers containing new values.
+ * @param num_lines Number of lines.
+ * @param active_low The active state of the lines - true if low.
+ * @param cb Callback function that will be called right after the values are
+ *        set.
+ * @param data User data that will be passed to the callback function.
+ * @return 0 if the operation succeeds, -1 on error.
+ */
+int gpiod_simple_set_value_multiple(const char *device, unsigned int *offsets,
+                                   int *values, unsigned int num_lines,
+                                   bool active_low, void (*cb)(void *),
+                                   void *data) GPIOD_API;
 
 /**
  * @brief Set value of a single GPIO line.
@@ -138,12 +177,16 @@ int gpiod_simple_get_value(const char *device,
  *        set. Users can use this, for example, to pause the execution after
  *        toggling a GPIO.
  * @param data User data that will be passed to the callback function.
- * @return 0 or 1 if the operation succeeds. On error this routine returns -1
- *         and sets the last error number.
+ * @return 0 if the operation succeeds, -1 on error.
  */
-int gpiod_simple_set_value(const char *device, unsigned int offset,
-                          int value, bool active_low, void (*cb)(void *),
-                          void *data) GPIOD_API;
+static inline int gpiod_simple_set_value(const char *device,
+                                        unsigned int offset, int value,
+                                        bool active_low, void (*cb)(void *),
+                                        void *data)
+{
+       return gpiod_simple_set_value_multiple(device, &offset, &value, 1,
+                                              active_low, cb, data);
+}
 
 /**
  * @brief Event types that can be passed to the simple event callback.
index ae8bc23f773ec2b18ed651c3abdcad7cd612e8b8..9ec925fb8803ca5745483d31b6a9b551709fc13d 100644 (file)
@@ -158,56 +158,77 @@ const char * gpiod_last_strerror(void)
        return gpiod_strerror(gpiod_errno());
 }
 
-int gpiod_simple_get_value(const char *device,
-                          unsigned int offset, bool active_low)
+int gpiod_simple_get_value_multiple(const char *device, unsigned int *offsets,
+                                   int *values, unsigned int num_lines,
+                                   bool active_low)
 {
+       struct gpiod_line_bulk bulk;
        struct gpiod_chip *chip;
        struct gpiod_line *line;
-       int status, value;
+       unsigned int i;
+       int status;
 
        chip = gpiod_chip_open_lookup(device);
        if (!chip)
                return -1;
 
-       line = gpiod_chip_get_line(chip, offset);
-       if (!line) {
-               gpiod_chip_close(chip);
-               return -1;
+       gpiod_line_bulk_init(&bulk);
+
+       for (i = 0; i < num_lines; i++) {
+               line = gpiod_chip_get_line(chip, offsets[i]);
+               if (!line) {
+                       gpiod_chip_close(chip);
+                       return -1;
+               }
+
+               gpiod_line_bulk_add(&bulk, line);
        }
 
-       status = gpiod_line_request_input(line, libgpiod_consumer, active_low);
+       status = gpiod_line_request_bulk_input(&bulk,
+                                              libgpiod_consumer, active_low);
        if (status < 0) {
                gpiod_chip_close(chip);
                return -1;
        }
 
-       value = gpiod_line_get_value(line);
+       memset(values, 0, sizeof(*values) * num_lines);
+       status = gpiod_line_get_value_bulk(&bulk, values);
 
-       gpiod_line_release(line);
+       gpiod_line_release_bulk(&bulk);
        gpiod_chip_close(chip);
 
-       return value;
+       return status;
 }
 
-int gpiod_simple_set_value(const char *device, unsigned int offset, int value,
-                          bool active_low, void (*cb)(void *), void *data)
+int gpiod_simple_set_value_multiple(const char *device, unsigned int *offsets,
+                                   int *values, unsigned int num_lines,
+                                   bool active_low, void (*cb)(void *),
+                                   void *data)
 {
+       struct gpiod_line_bulk bulk;
        struct gpiod_chip *chip;
        struct gpiod_line *line;
+       unsigned int i;
        int status;
 
        chip = gpiod_chip_open_lookup(device);
        if (!chip)
                return -1;
 
-       line = gpiod_chip_get_line(chip, offset);
-       if (!line) {
-               gpiod_chip_close(chip);
-               return -1;
+       gpiod_line_bulk_init(&bulk);
+
+       for (i = 0; i < num_lines; i++) {
+               line = gpiod_chip_get_line(chip, offsets[i]);
+               if (!line) {
+                       gpiod_chip_close(chip);
+                       return -1;
+               }
+
+               gpiod_line_bulk_add(&bulk, line);
        }
 
-       status = gpiod_line_request_output(line, libgpiod_consumer,
-                                          active_low, value);
+       status = gpiod_line_request_bulk_output(&bulk, libgpiod_consumer,
+                                               active_low, values);
        if (status < 0) {
                gpiod_chip_close(chip);
                return -1;
@@ -216,7 +237,7 @@ int gpiod_simple_set_value(const char *device, unsigned int offset, int value,
        if (cb)
                cb(data);
 
-       gpiod_line_release(line);
+       gpiod_line_release_bulk(&bulk);
        gpiod_chip_close(chip);
 
        return 0;