You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2020/07/07 13:34:33 UTC

[incubator-nuttx] branch master updated: gpio: extend gpio_pintype_e for pulldown/up and opendrain

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new a349595  gpio: extend gpio_pintype_e for pulldown/up and opendrain
a349595 is described below

commit a349595316562ff7bef8147215c1442f9ffa1e54
Author: Beat Küng <be...@gmx.net>
AuthorDate: Thu Jul 2 12:47:58 2020 +0200

    gpio: extend gpio_pintype_e for pulldown/up and opendrain
    
    - fix code style
    - fix bool conversion when calling go_read()
---
 arch/sim/src/sim/up_ioexpander.c      | 10 +++++++---
 drivers/analog/lmp92001.c             | 10 +++++++---
 drivers/ioexpander/gpio.c             | 14 +++++++++++---
 drivers/ioexpander/gpio_lower_half.c  | 26 +++++++++++++++++++++++---
 drivers/ioexpander/pca9538.c          |  6 ++++++
 drivers/ioexpander/pca9555.c          |  6 ++++++
 drivers/ioexpander/pcf8574.c          | 10 +++++++---
 drivers/ioexpander/skeleton.c         | 14 ++++++++++----
 drivers/ioexpander/tca64xx.c          | 10 +++++++---
 include/nuttx/ioexpander/gpio.h       |  9 ++++++---
 include/nuttx/ioexpander/ioexpander.h | 18 +++++++++++-------
 11 files changed, 101 insertions(+), 32 deletions(-)

diff --git a/arch/sim/src/sim/up_ioexpander.c b/arch/sim/src/sim/up_ioexpander.c
index 0371c89..578216d 100644
--- a/arch/sim/src/sim/up_ioexpander.c
+++ b/arch/sim/src/sim/up_ioexpander.c
@@ -199,9 +199,13 @@ static int sim_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
 {
   FAR struct sim_dev_s *priv = (FAR struct sim_dev_s *)dev;
 
-  DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS &&
-              (direction == IOEXPANDER_DIRECTION_IN ||
-               direction == IOEXPANDER_DIRECTION_OUT));
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
+  DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS);
 
   gpioinfo("pin=%u direction=%s\n",
            pin, (direction == IOEXPANDER_DIRECTION_IN) ? "IN" : "OUT");
diff --git a/drivers/analog/lmp92001.c b/drivers/analog/lmp92001.c
index 212cb04..47469f7 100644
--- a/drivers/analog/lmp92001.c
+++ b/drivers/analog/lmp92001.c
@@ -1214,9 +1214,13 @@ static int lmp92001_gpio_direction(FAR struct ioexpander_dev_s *dev,
 
   int ret;
 
-  DEBUGASSERT(priv != NULL && pin < LMP92001_GPIO_MAX_PINS &&
-              (direction == IOEXPANDER_DIRECTION_IN ||
-               direction == IOEXPANDER_DIRECTION_OUT));
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
+  DEBUGASSERT(priv != NULL && pin < LMP92001_GPIO_MAX_PINS);
 
   gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
            priv->addr, pin,
diff --git a/drivers/ioexpander/gpio.c b/drivers/ioexpander/gpio.c
index 864e4d7..4b17d55 100644
--- a/drivers/ioexpander/gpio.c
+++ b/drivers/ioexpander/gpio.c
@@ -187,7 +187,7 @@ static ssize_t gpio_read(FAR struct file *filep, FAR char *buffer,
 
   /* Read the GPIO value */
 
-  ret = dev->gp_ops->go_read(dev, (FAR uint8_t *)&buffer[0]);
+  ret = dev->gp_ops->go_read(dev, (FAR bool *)&buffer[0]);
   if (ret < 0)
     {
       return ret;
@@ -229,7 +229,8 @@ static ssize_t gpio_write(FAR struct file *filep, FAR const char *buffer,
 
   /* Check if this pin is write-able */
 
-  if (dev->gp_pintype != GPIO_OUTPUT_PIN)
+  if (dev->gp_pintype != GPIO_OUTPUT_PIN &&
+      dev->gp_pintype != GPIO_OUTPUT_PIN_OPENDRAIN)
     {
       return -EACCES;
     }
@@ -336,7 +337,8 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
        */
 
       case GPIOC_WRITE:
-        if (dev->gp_pintype == GPIO_OUTPUT_PIN)
+        if (dev->gp_pintype == GPIO_OUTPUT_PIN ||
+            dev->gp_pintype == GPIO_OUTPUT_PIN_OPENDRAIN)
           {
             DEBUGASSERT(arg == 0ul || arg == 1ul);
             ret = dev->gp_ops->go_write(dev, (bool)arg);
@@ -544,6 +546,8 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor)
   switch (dev->gp_pintype)
     {
       case GPIO_INPUT_PIN:
+      case GPIO_INPUT_PIN_PULLUP:
+      case GPIO_INPUT_PIN_PULLDOWN:
         {
           DEBUGASSERT(dev->gp_ops->go_read != NULL);
           fmt = "/dev/gpin%u";
@@ -551,6 +555,7 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor)
         break;
 
       case GPIO_OUTPUT_PIN:
+      case GPIO_OUTPUT_PIN_OPENDRAIN:
         {
           DEBUGASSERT(dev->gp_ops->go_read != NULL &&
                      dev->gp_ops->go_write != NULL);
@@ -606,12 +611,15 @@ void gpio_pin_unregister(FAR struct gpio_dev_s *dev, int minor)
   switch (dev->gp_pintype)
     {
       case GPIO_INPUT_PIN:
+      case GPIO_INPUT_PIN_PULLUP:
+      case GPIO_INPUT_PIN_PULLDOWN:
         {
           fmt = "/dev/gpin%u";
         }
         break;
 
       case GPIO_OUTPUT_PIN:
+      case GPIO_OUTPUT_PIN_OPENDRAIN:
         {
           fmt = "/dev/gpout%u";
         }
diff --git a/drivers/ioexpander/gpio_lower_half.c b/drivers/ioexpander/gpio_lower_half.c
index 3a58951..fad949e 100644
--- a/drivers/ioexpander/gpio_lower_half.c
+++ b/drivers/ioexpander/gpio_lower_half.c
@@ -85,7 +85,8 @@ static int gplh_handler(FAR struct ioexpander_dev_s *ioe,
 static int gplh_read(FAR struct gpio_dev_s *gpio, FAR bool *value);
 static int gplh_write(FAR struct gpio_dev_s *gpio, bool value);
 #ifdef CONFIG_IOEXPANDER_INT_ENABLE
-static int gplh_attach(FAR struct gpio_dev_s *gpio, pin_interrupt_t callback);
+static int gplh_attach(FAR struct gpio_dev_s *gpio,
+                       pin_interrupt_t callback);
 static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable);
 #endif
 static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
@@ -118,6 +119,8 @@ static const struct gpio_operations_s g_gplh_ops =
 static const uint32_t g_gplh_inttype[] =
 {
   [GPIO_INPUT_PIN]              = IOEXPANDER_VAL_DISABLE,
+  [GPIO_INPUT_PIN_PULLUP]       = IOEXPANDER_VAL_DISABLE,
+  [GPIO_INPUT_PIN_PULLDOWN]     = IOEXPANDER_VAL_DISABLE,
   [GPIO_INTERRUPT_PIN]          = CONFIG_GPIO_LOWER_HALF_INTTYPE,
   [GPIO_INTERRUPT_HIGH_PIN]     = IOEXPANDER_VAL_HIGH,
   [GPIO_INTERRUPT_LOW_PIN]      = IOEXPANDER_VAL_LOW,
@@ -332,7 +335,8 @@ static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable)
  *
  ****************************************************************************/
 
-static int gplh_setpintype(FAR struct gpio_dev_s *gpio, enum gpio_pintype_e pintype)
+static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
+                           enum gpio_pintype_e pintype)
 {
   FAR struct gplh_dev_s *priv = (FAR struct gplh_dev_s *)gpio;
   FAR struct ioexpander_dev_s *ioe = priv->ioe;
@@ -346,9 +350,25 @@ static int gplh_setpintype(FAR struct gpio_dev_s *gpio, enum gpio_pintype_e pint
     {
       IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT);
     }
+  else if (pintype == GPIO_OUTPUT_PIN_OPENDRAIN)
+    {
+      IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT_OPENDRAIN);
+    }
   else
     {
-      IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
+      if (pintype == GPIO_INPUT_PIN)
+        {
+          IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
+        }
+      else if (pintype == GPIO_INPUT_PIN_PULLUP)
+        {
+          IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN_PULLUP);
+        }
+      else
+        {
+          IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN_PULLDOWN);
+        }
+
       IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_INTCFG,
                       (FAR void *)g_gplh_inttype[pintype]);
     }
diff --git a/drivers/ioexpander/pca9538.c b/drivers/ioexpander/pca9538.c
index e6edc7f..e4d70b9 100644
--- a/drivers/ioexpander/pca9538.c
+++ b/drivers/ioexpander/pca9538.c
@@ -309,6 +309,12 @@ static int pca9538_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
   FAR struct pca9538_dev_s *pca = (FAR struct pca9538_dev_s *)dev;
   int ret;
 
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
   /* Get exclusive access to the PCA555 */
 
   ret = pca9538_lock(pca);
diff --git a/drivers/ioexpander/pca9555.c b/drivers/ioexpander/pca9555.c
index 07a45d0..916c6d6 100644
--- a/drivers/ioexpander/pca9555.c
+++ b/drivers/ioexpander/pca9555.c
@@ -337,6 +337,12 @@ static int pca9555_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
   FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev;
   int ret;
 
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
   /* Get exclusive access to the PCA555 */
 
   ret = pca9555_lock(pca);
diff --git a/drivers/ioexpander/pcf8574.c b/drivers/ioexpander/pcf8574.c
index 4824f50..886fef9 100644
--- a/drivers/ioexpander/pcf8574.c
+++ b/drivers/ioexpander/pcf8574.c
@@ -256,9 +256,13 @@ static int pcf8574_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
   FAR struct pcf8574_dev_s *priv = (FAR struct pcf8574_dev_s *)dev;
   int ret;
 
-  DEBUGASSERT(priv != NULL && priv->config != NULL && pin < 8 &&
-              (direction == IOEXPANDER_DIRECTION_IN ||
-               direction == IOEXPANDER_DIRECTION_OUT));
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
+  DEBUGASSERT(priv != NULL && priv->config != NULL && pin < 8);
 
   gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
            priv->config->address, pin,
diff --git a/drivers/ioexpander/skeleton.c b/drivers/ioexpander/skeleton.c
index 7269482..90b7e0d 100644
--- a/drivers/ioexpander/skeleton.c
+++ b/drivers/ioexpander/skeleton.c
@@ -193,12 +193,16 @@ static int skel_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
   FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
   int ret;
 
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
   gpioinfo("pin=%u direction=%s\n",
            pin, (direction == IOEXPANDER_DIRECTION_IN) ? "IN" : "OUT");
 
-  DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS &&
-              (direction == IOEXPANDER_DIRECTION_IN ||
-               direction == IOEXPANDER_DIRECTION_IN));
+  DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS);
 
   /* Get exclusive access to the I/O Expander */
 
@@ -730,7 +734,9 @@ static void skel_interrupt(FAR void *arg)
       /* Disable interrupts */
 #warning Missing logic
 
-      /* Schedule interrupt related work on the high priority worker thread. */
+      /* Schedule interrupt related work on the high priority worker
+       * thread.
+       */
 
       work_queue(HPWORK, &priv->work, skel_irqworker,
                  (FAR void *)priv, 0);
diff --git a/drivers/ioexpander/tca64xx.c b/drivers/ioexpander/tca64xx.c
index 5de8763..215244a 100644
--- a/drivers/ioexpander/tca64xx.c
+++ b/drivers/ioexpander/tca64xx.c
@@ -419,10 +419,14 @@ static int tca64_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
   uint8_t regval;
   int ret;
 
+  if (direction != IOEXPANDER_DIRECTION_IN &&
+      direction != IOEXPANDER_DIRECTION_OUT)
+    {
+      return -EINVAL;
+    }
+
   DEBUGASSERT(priv != NULL && priv->config != NULL &&
-              pin < CONFIG_IOEXPANDER_NPINS &&
-              (direction == IOEXPANDER_DIRECTION_IN ||
-               direction == IOEXPANDER_DIRECTION_OUT));
+              pin < CONFIG_IOEXPANDER_NPINS);
 
   gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
            priv->config->address, pin,
diff --git a/include/nuttx/ioexpander/gpio.h b/include/nuttx/ioexpander/gpio.h
index 5d11e1c..f0a4661 100644
--- a/include/nuttx/ioexpander/gpio.h
+++ b/include/nuttx/ioexpander/gpio.h
@@ -100,8 +100,11 @@
 
 enum gpio_pintype_e
 {
-  GPIO_INPUT_PIN = 0,
-  GPIO_OUTPUT_PIN,
+  GPIO_INPUT_PIN = 0, /* float */
+  GPIO_INPUT_PIN_PULLUP,
+  GPIO_INPUT_PIN_PULLDOWN,
+  GPIO_OUTPUT_PIN, /* push-pull */
+  GPIO_OUTPUT_PIN_OPENDRAIN,
   GPIO_INTERRUPT_PIN,
   GPIO_INTERRUPT_HIGH_PIN,
   GPIO_INTERRUPT_LOW_PIN,
@@ -141,7 +144,7 @@ struct gpio_operations_s
                             enum gpio_pintype_e pintype);
 };
 
- /* Signal information */
+/* Signal information */
 
 struct gpio_signal_s
 {
diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h
index f55aca9..e69bf8a 100644
--- a/include/nuttx/ioexpander/ioexpander.h
+++ b/include/nuttx/ioexpander/ioexpander.h
@@ -58,8 +58,11 @@
 
 /* Pin definitions **********************************************************/
 
-#define IOEXPANDER_DIRECTION_IN    0
-#define IOEXPANDER_DIRECTION_OUT   1
+#define IOEXPANDER_DIRECTION_IN            0  /* float */
+#define IOEXPANDER_DIRECTION_IN_PULLUP     1
+#define IOEXPANDER_DIRECTION_IN_PULLDOWN   2
+#define IOEXPANDER_DIRECTION_OUT           3  /* push-pull */
+#define IOEXPANDER_DIRECTION_OUT_OPENDRAIN 4
 
 #define IOEXPANDER_PINMASK         (((ioe_pinset_t)1 << CONFIG_IOEXPANDER_NPINS) - 1)
 #define PINSET_ALL                 (~((ioe_pinset_t)0))
@@ -144,14 +147,15 @@
  * Name: IOEXP_READPIN
  *
  * Description:
- *   Read the actual PIN level. This can be different from the last value written
- *      to this pin. Required.
+ *   Read the actual PIN level. This can be different from the last value
+ *   written to this pin. Required.
  *
  * Input Parameters:
  *   dev    - Device-specific state data
  *   pin    - The index of the pin
  *   valptr - Pointer to a buffer where the pin level is stored. Usually TRUE
- *            if the pin is high, except if OPTION_INVERT has been set on this pin.
+ *            if the pin is high, except if OPTION_INVERT has been set on
+ *            this pin.
  *
  * Returned Value:
  *   0 on success, else a negative error code
@@ -225,8 +229,8 @@
  * Name: IOEXP_MULTIREADBUF
  *
  * Description:
- *   Read the buffered level of multiple pins. This routine may be faster than
- *   individual pin accesses. Optional.
+ *   Read the buffered level of multiple pins. This routine may be faster
+ *   than individual pin accesses. Optional.
  *
  * Input Parameters:
  *   dev    - Device-specific state data