Squashed commit of the following:
driver/ioexpander: Add gpio_pin_unregister function to GPIO driver driver/ioexpander: Add pinset struct to GPIO driver for interrupt pins larger than 64 driver/ioexpander: Initialize pintype/inttype when registering ioexpander device driver/ioexpander: Add SETPINTYPE ioctl command to the GPIO driver
This commit is contained in:
parent
b5f8c035a6
commit
459d9f2851
@ -189,4 +189,15 @@ config GPIO_LOWER_HALF
|
|||||||
Enable support for a lower half driver that provides GPIO driver
|
Enable support for a lower half driver that provides GPIO driver
|
||||||
support for I/O expander pins.
|
support for I/O expander pins.
|
||||||
|
|
||||||
|
if GPIO_LOWER_HALF
|
||||||
|
|
||||||
|
config GPIO_LOWER_HALF_INTTYPE
|
||||||
|
int "default interrupt type for GPIO_INTERRUPT_PIN pintype"
|
||||||
|
default 14
|
||||||
|
---help---
|
||||||
|
This is the default interrupt type (IOEXPANDER_VAL_BOTH) for
|
||||||
|
GPIO_INTERRUPT_PIN pintype in gplf driver register.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
endmenu # IO Expander/GPIO Support
|
endmenu # IO Expander/GPIO Support
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/ioexpander/gpio.c
|
* drivers/ioexpander/gpio.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -55,7 +55,7 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int gpio_handler(FAR struct gpio_dev_s *dev);
|
static int gpio_handler(FAR struct gpio_dev_s *dev, uint8_t pin);
|
||||||
static int gpio_open(FAR struct file *filep);
|
static int gpio_open(FAR struct file *filep);
|
||||||
static int gpio_close(FAR struct file *filep);
|
static int gpio_close(FAR struct file *filep);
|
||||||
static ssize_t gpio_read(FAR struct file *filep, FAR char *buffer,
|
static ssize_t gpio_read(FAR struct file *filep, FAR char *buffer,
|
||||||
@ -97,7 +97,7 @@ static const struct file_operations g_gpio_drvrops =
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int gpio_handler(FAR struct gpio_dev_s *dev)
|
static int gpio_handler(FAR struct gpio_dev_s *dev, uint8_t pin)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
(void)nxsig_kill(dev->gp_pid, dev->gp_signo);
|
(void)nxsig_kill(dev->gp_pid, dev->gp_signo);
|
||||||
@ -296,6 +296,17 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Command: GPIOC_SETPINTYPE
|
||||||
|
* Description: Set the GPIO pin type.
|
||||||
|
* Argument: The enum gpio_pintype_e type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case GPIOC_SETPINTYPE:
|
||||||
|
{
|
||||||
|
ret = dev->gp_ops->go_setpintype(dev, arg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Unrecognized command */
|
/* Unrecognized command */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -378,4 +389,54 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor)
|
|||||||
return register_driver(devname, &g_gpio_drvrops, 0666, dev);
|
return register_driver(devname, &g_gpio_drvrops, 0666, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gpio_pin_unregister
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unregister GPIO pin device driver.
|
||||||
|
*
|
||||||
|
* - Input pin types will be registered at /dev/gpinN
|
||||||
|
* - Output pin types will be registered at /dev/gpoutN
|
||||||
|
* - Interrupt pin types will be registered at /dev/gpintN
|
||||||
|
*
|
||||||
|
* Where N is the provided minor number in the range of 0-99.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void gpio_pin_unregister(FAR struct gpio_dev_s *dev, int minor)
|
||||||
|
{
|
||||||
|
FAR const char *fmt;
|
||||||
|
char devname[16];
|
||||||
|
|
||||||
|
switch (dev->gp_pintype)
|
||||||
|
{
|
||||||
|
case GPIO_INPUT_PIN:
|
||||||
|
{
|
||||||
|
fmt = "/dev/gpin%u";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_OUTPUT_PIN:
|
||||||
|
{
|
||||||
|
fmt = "/dev/gpout%u";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_INTERRUPT_PIN:
|
||||||
|
{
|
||||||
|
fmt = "/dev/gpint%u";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(devname, 16, fmt, (unsigned int)minor);
|
||||||
|
gpioinfo("Unregistering %s\n", devname);
|
||||||
|
|
||||||
|
(void)unregister_driver(devname);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DEV_GPIO */
|
#endif /* CONFIG_DEV_GPIO */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/ioexpander/gpio_lower_half.c
|
* drivers/ioexpander/gpio_lower_half.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -88,6 +88,8 @@ static int gplh_write(FAR struct gpio_dev_s *gpio, bool value);
|
|||||||
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);
|
static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable);
|
||||||
#endif
|
#endif
|
||||||
|
static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
|
||||||
|
enum gpio_pintype_e pintype);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@ -106,6 +108,22 @@ static const struct gpio_operations_s g_gplh_ops =
|
|||||||
NULL, /* attach */
|
NULL, /* attach */
|
||||||
NULL, /* enable */
|
NULL, /* enable */
|
||||||
#endif
|
#endif
|
||||||
|
gplh_setpintype,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* REVISIT: The following violates the NuttX coding standard requirement
|
||||||
|
* for C89 compatibility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint32_t g_gplh_inttype[] =
|
||||||
|
{
|
||||||
|
[GPIO_INPUT_PIN] = 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,
|
||||||
|
[GPIO_INTERRUPT_RISING_PIN] = IOEXPANDER_VAL_RISING,
|
||||||
|
[GPIO_INTERRUPT_FALLING_PIN] = IOEXPANDER_VAL_FALLING,
|
||||||
|
[GPIO_INTERRUPT_BOTH_PIN] = IOEXPANDER_VAL_BOTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -135,7 +153,7 @@ static int gplh_handler(FAR struct ioexpander_dev_s *ioe,
|
|||||||
* upper half GPIO driver via its callback.
|
* upper half GPIO driver via its callback.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return priv->callback(&priv->gpio);
|
return priv->callback(&priv->gpio, priv->pin);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -258,7 +276,11 @@ static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable)
|
|||||||
|
|
||||||
else if (priv->handle == NULL)
|
else if (priv->handle == NULL)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_IOEXPANDER_NPINS <= 64
|
||||||
ioe_pinset_t pinset = ((ioe_pinset_t)1 << priv->pin);
|
ioe_pinset_t pinset = ((ioe_pinset_t)1 << priv->pin);
|
||||||
|
#else
|
||||||
|
ioe_pinset_t pinset = ((ioe_pinset_t)priv->pin);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We have a callback and the callback is not yet attached.
|
/* We have a callback and the callback is not yet attached.
|
||||||
* do it now.
|
* do it now.
|
||||||
@ -302,6 +324,39 @@ static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gplh_setpintype
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set I/O expander pin to an appointed gpiopintype
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
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;
|
||||||
|
uint8_t pin = priv->pin;
|
||||||
|
|
||||||
|
if (pintype >= GPIO_NPINTYPES)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
else if (pintype == GPIO_OUTPUT_PIN)
|
||||||
|
{
|
||||||
|
IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
|
||||||
|
IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_INTCFG,
|
||||||
|
(FAR void *)g_gplh_inttype[pintype]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio->gp_pintype = pintype;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -360,6 +415,17 @@ int gpio_lower_half(FAR struct ioexpander_dev_s *ioe, unsigned int pin,
|
|||||||
gpio->gp_pintype = (uint8_t)pintype;
|
gpio->gp_pintype = (uint8_t)pintype;
|
||||||
gpio->gp_ops = &g_gplh_ops;
|
gpio->gp_ops = &g_gplh_ops;
|
||||||
|
|
||||||
|
if (pintype == GPIO_OUTPUT_PIN)
|
||||||
|
{
|
||||||
|
IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
|
||||||
|
IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_INTCFG,
|
||||||
|
(FAR void *)g_gplh_inttype[pintype]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register the GPIO driver */
|
/* Register the GPIO driver */
|
||||||
|
|
||||||
ret = gpio_pin_register(gpio, minor);
|
ret = gpio_pin_register(gpio, minor);
|
||||||
|
@ -75,6 +75,11 @@
|
|||||||
* Command: GPIOC_UNREGISTER
|
* Command: GPIOC_UNREGISTER
|
||||||
* Description: Stop receiving signals for pin interrupts.
|
* Description: Stop receiving signals for pin interrupts.
|
||||||
* Argument: None.
|
* Argument: None.
|
||||||
|
*
|
||||||
|
* Command: GPIOC_SETPINTYPE
|
||||||
|
* Description: Set the GPIO pin type.
|
||||||
|
* Argument: The enum gpio_pintype_e type.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GPIOC_WRITE _GPIOC(1)
|
#define GPIOC_WRITE _GPIOC(1)
|
||||||
@ -82,6 +87,7 @@
|
|||||||
#define GPIOC_PINTYPE _GPIOC(3)
|
#define GPIOC_PINTYPE _GPIOC(3)
|
||||||
#define GPIOC_REGISTER _GPIOC(4)
|
#define GPIOC_REGISTER _GPIOC(4)
|
||||||
#define GPIOC_UNREGISTER _GPIOC(5)
|
#define GPIOC_UNREGISTER _GPIOC(5)
|
||||||
|
#define GPIOC_SETPINTYPE _GPIOC(6)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@ -94,6 +100,11 @@ enum gpio_pintype_e
|
|||||||
GPIO_INPUT_PIN = 0,
|
GPIO_INPUT_PIN = 0,
|
||||||
GPIO_OUTPUT_PIN,
|
GPIO_OUTPUT_PIN,
|
||||||
GPIO_INTERRUPT_PIN,
|
GPIO_INTERRUPT_PIN,
|
||||||
|
GPIO_INTERRUPT_HIGH_PIN,
|
||||||
|
GPIO_INTERRUPT_LOW_PIN,
|
||||||
|
GPIO_INTERRUPT_RISING_PIN,
|
||||||
|
GPIO_INTERRUPT_FALLING_PIN,
|
||||||
|
GPIO_INTERRUPT_BOTH_PIN,
|
||||||
GPIO_NPINTYPES
|
GPIO_NPINTYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,6 +121,7 @@ typedef CODE int (*pin_interrupt_t)(FAR struct gpio_dev_s *dev);
|
|||||||
* for other pin types may be NULL.
|
* for other pin types may be NULL.
|
||||||
* - go_attach and gp_eanble. Required only the GPIO_INTERRUPT_PIN pin
|
* - go_attach and gp_eanble. Required only the GPIO_INTERRUPT_PIN pin
|
||||||
* type. Unused for other pin types may be NULL.
|
* type. Unused for other pin types may be NULL.
|
||||||
|
* - go_setpinytype. Required for all all pin types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct gpio_dev_s;
|
struct gpio_dev_s;
|
||||||
@ -122,6 +134,8 @@ struct gpio_operations_s
|
|||||||
CODE int (*go_attach)(FAR struct gpio_dev_s *dev,
|
CODE int (*go_attach)(FAR struct gpio_dev_s *dev,
|
||||||
pin_interrupt_t callback);
|
pin_interrupt_t callback);
|
||||||
CODE int (*go_enable)(FAR struct gpio_dev_s *dev, bool enable);
|
CODE int (*go_enable)(FAR struct gpio_dev_s *dev, bool enable);
|
||||||
|
CODE int (*go_setpintype)(FAR struct gpio_dev_s *dev,
|
||||||
|
enum gpio_pintype_e pintype);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Pin interface definition. Must lie in writable memory. */
|
/* Pin interface definition. Must lie in writable memory. */
|
||||||
@ -177,6 +191,23 @@ extern "C"
|
|||||||
|
|
||||||
int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor);
|
int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gpio_pin_unregister
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unregister GPIO pin device driver.
|
||||||
|
*
|
||||||
|
* - Input pin types will be registered at /dev/gpinN
|
||||||
|
* - Output pin types will be registered at /dev/gpoutN
|
||||||
|
* - Interrupt pin types will be registered at /dev/gpintN
|
||||||
|
*
|
||||||
|
* Where N is the provided minor number in the range of 0-99.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void gpio_pin_unregister(FAR struct gpio_dev_s *dev, int minor);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: gpio_lower_half
|
* Name: gpio_lower_half
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/nuttx/ioexpander/ioexpander.h
|
* include/nuttx/ioexpander/ioexpander.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -41,6 +41,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef CONFIG_IOEXPANDER
|
#ifdef CONFIG_IOEXPANDER
|
||||||
@ -55,10 +56,6 @@
|
|||||||
# define CONFIG_IOEXPANDER_NPINS 16
|
# define CONFIG_IOEXPANDER_NPINS 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IOEXPANDER_NPINS > 64
|
|
||||||
# error No support for devices with more than 64 pins
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Pin definitions **********************************************************/
|
/* Pin definitions **********************************************************/
|
||||||
|
|
||||||
#define IOEXPANDER_DIRECTION_IN 0
|
#define IOEXPANDER_DIRECTION_IN 0
|
||||||
@ -101,7 +98,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define IOEXP_SETDIRECTION(dev,pin,dir) ((dev)->ops->ioe_direction(dev,pin,dir))
|
#define IOEXP_SETDIRECTION(dev,pin,dir) ((dev)->ops->ioe_direction(dev,pin,dir))
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: IOEXP_SETOPTION
|
* Name: IOEXP_SETOPTION
|
||||||
@ -293,7 +290,11 @@
|
|||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This type represents a bitmap of pins */
|
/* This type represents a bitmap of pins
|
||||||
|
*
|
||||||
|
* For IOE NPINS greater than 64, ioe_pinset_t represent one interrupt pin
|
||||||
|
* number instead of a bitmap of pins.
|
||||||
|
*/
|
||||||
|
|
||||||
#if CONFIG_IOEXPANDER_NPINS <= 8
|
#if CONFIG_IOEXPANDER_NPINS <= 8
|
||||||
typedef uint8_t ioe_pinset_t;
|
typedef uint8_t ioe_pinset_t;
|
||||||
@ -301,8 +302,10 @@ typedef uint8_t ioe_pinset_t;
|
|||||||
typedef uint16_t ioe_pinset_t;
|
typedef uint16_t ioe_pinset_t;
|
||||||
#elif CONFIG_IOEXPANDER_NPINS <= 32
|
#elif CONFIG_IOEXPANDER_NPINS <= 32
|
||||||
typedef uint32_t ioe_pinset_t;
|
typedef uint32_t ioe_pinset_t;
|
||||||
#else /* if CONFIG_IOEXPANDER_NPINS <= 64 */
|
#elif CONFIG_IOEXPANDER_NPINS <= 64
|
||||||
typedef uint64_t ioe_pinset_t;
|
typedef uint64_t ioe_pinset_t;
|
||||||
|
#else
|
||||||
|
typedef uint8_t ioe_pinset_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
|
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
|
||||||
|
Loading…
Reference in New Issue
Block a user