changeset 3901:7bf75f759731

gpio: deprecated device_gpio_map_set_mode and device_res_gpio_map, added device_gpio_setup
author Alexandre Becoulet <alexandre.becoulet@free.fr>
date Wed, 18 Apr 2018 15:40:48 +0200
parents 50eb437029a1
children 702115f01b20
files libdevice/device_gpio.c libdevice/include/device/class/gpio.h
diffstat 2 files changed, 91 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/libdevice/device_gpio.c	Wed Apr 18 15:38:49 2018 +0200
+++ b/libdevice/device_gpio.c	Wed Apr 18 15:40:48 2018 +0200
@@ -80,8 +80,19 @@
 error_t device_res_gpio_map(struct device_s *dev, const char *pin_list,
                             gpio_id_t *map, gpio_width_t *wmap)
 {
+  return device_gpio_setup(NULL, dev, pin_list, map, wmap);
+}
+
+error_t device_gpio_setup(const struct device_gpio_s *gpio,
+                          struct device_s *dev, const char *pin_list,
+                          gpio_id_t *map, gpio_width_t *wmap)
+{
   while (*pin_list)
     {
+      enum dev_pin_driving_e dir = device_io_mode_symbol(*pin_list);
+      if (dir)
+        pin_list++;
+
       struct dev_resource_s *r = device_res_get_from_name(dev, DEV_RES_GPIO, 0, pin_list);
 
       while (*pin_list && *pin_list != ':' && *pin_list != '?' && *pin_list != ' ')
@@ -92,14 +103,27 @@
       else if (!r)
         return -ENOENT;
 
-      *map++ = r ? r->u.gpio.id : GPIO_INVALID_ID;
+      gpio_id_t id = GPIO_INVALID_ID;
+      gpio_width_t w = 0;
+
+      if (r)
+        {
+          id = r->u.gpio.id;
+          w = r->u.gpio.width;
+
+          if (dir != DEV_PIN_DISABLED &&
+              DEVICE_OP(gpio, set_mode, id, id + w - 1, dev_gpio_mask1, dir))
+            return -EIO;
+        }
+
+      *map++ = id;
       if (wmap)
-        *wmap++ = r ? r->u.gpio.width : 0;
+        *wmap++ = w;
 
       if (*pin_list == ':')
         {
-          uint_fast8_t w = strtoul(pin_list + 1, (char**)&pin_list, 0);
-          if (r && r->u.gpio.width != w)
+          if (r && r->u.gpio.width !=
+              strtoul(pin_list + 1, (char**)&pin_list, 0))
             return -ERANGE;
         }
 
@@ -110,6 +134,20 @@
   return 0;
 }
 
+error_t device_gpio_get_setup(struct device_gpio_s *gpio,
+                              struct device_s *dev, const char *pin_list,
+                              gpio_id_t *map, gpio_width_t *wmap)
+{
+  if (device_get_param_dev_accessor(dev, "gpio", &gpio->base, DRIVER_CLASS_GPIO))
+    return -ENOENT;
+
+  error_t err = device_gpio_setup(gpio, dev, pin_list, map, wmap);
+  if (err)
+    device_put_accessor(&gpio->base);
+
+  return err;
+}
+
 DEV_GPIO_REQUEST(dev_gpio_request_async_to_sync)
 {
   switch (rq->type) {
--- a/libdevice/include/device/class/gpio.h	Wed Apr 18 15:38:49 2018 +0200
+++ b/libdevice/include/device/class/gpio.h	Wed Apr 18 15:40:48 2018 +0200
@@ -454,13 +454,6 @@
   return rq.error;
 })
 
-/** @This changes the mode of multiple GPIO pins using the synchronous API. */
-config_depend(CONFIG_DEVICE_GPIO)
-error_t device_gpio_map_set_mode(struct device_gpio_s *accessor,
-                                 const gpio_id_t *map, const gpio_width_t *wmap,
-                                 uint_fast8_t count, /* enum dev_pin_driving_e */ ...);
-
-
 /** @This adds a GPIO pins binding to the device resources list.
     @csee DEV_RES_GPIO @see #DEV_STATIC_RES_GPIO */
 config_depend_and2_alwaysinline(CONFIG_DEVICE_GPIO, CONFIG_DEVICE_RESOURCE_ALLOC,
@@ -512,23 +505,64 @@
 #endif
 
 /**
-   This initializes an array of GPIO ids from a list of pin labels. If
-   the @tt wmap parameter is not @tt NULL, the associated size of pin
-   range is also stored.
+   @This retrieves index of GPIO pins declared device resources from
+   a list of pin labels. It can optionally set the mode of the pins.
+
+   The index of the pins named in the @tt pin_list string are stored
+   in the @tt map array. If the @tt wmap parameter is not @tt NULL,
+   the associated size of pin range is also stored.
 
    The list is composed by space separated pin label names. All pin
    names present in the list must match an available device resource
-   unless the name is suffixed by @tt{?}. A value of -1 is stored in
-   the array if the pin is not available in the device tree.
+   unless the name is suffixed by @tt{?}. The value @ref
+   GPIO_INVALID_ID is stored in the @tt map array if an optional pin
+   is not declared.
 
    If a label in the list is suffixed by @em {:width}, the pin width
-   declared in the resource must match the @em width number.
+   declared in the resource must match the specified width.
+
+   If a label is prefixed by a pin direction symbol, the mode of the
+   associated pins is changed accordingly. The @tt accessor parameter
+   may be @tt NULL if this feature is not used.
+
+   @section {Examples}
+   @code
+   gpio_id_t map[3];
+   device_res_gpio_map(&gpio, dev, "<irq:1 >rst:1 <bus:8 >sleep?:1", map, NULL);
+   @end code
+
+   @code
+   gpio_id_t map[2];
+   gpio_width_t wmap[2];
+   device_res_gpio_map(NULL, dev, "ioa iob?", map, wmap);
+   @end code
+   @end section
+
+   @see dev_pin_driving_e @see device_gpio_get_setup
 */
 config_depend(CONFIG_DEVICE_GPIO)
+error_t device_gpio_setup(const struct device_gpio_s *accessor,
+                          struct device_s *dev, const char *pin_list,
+                          gpio_id_t *map, gpio_width_t *wmap);
+
+/** @This setups an accessor to the gpio device declared using @ref
+    #DEV_STATIC_RES_DEV_GPIO in the resources then calls the @ref
+    device_gpio_setup function.
+
+    When the function succeed, the accessor is left initialized and
+    must be released by the caller. */
+config_depend(CONFIG_DEVICE_GPIO)
+error_t device_gpio_get_setup(struct device_gpio_s *accessor,
+                              struct device_s *dev, const char *pin_list,
+                              gpio_id_t *map, gpio_width_t *wmap);
+
+__attribute__((deprecated("use the device_gpio_setup* function instead")))
 error_t device_res_gpio_map(struct device_s *dev, const char *pin_list,
                             gpio_id_t *map, gpio_width_t *wmap);
 
+__attribute__((deprecated("pass direction symbols to the device_gpio_setup* function instead")))
+error_t device_gpio_map_set_mode(struct device_gpio_s *accessor,
+                                 const gpio_id_t *map, const gpio_width_t *wmap,
+                                 uint_fast8_t count, /* enum dev_pin_driving_e */ ...);
 
 #endif
-
-