diff --git a/drivers/ioexpander/pca9555.c b/drivers/ioexpander/pca9555.c index db068bb801..2dc6865185 100644 --- a/drivers/ioexpander/pca9555.c +++ b/drivers/ioexpander/pca9555.c @@ -369,15 +369,21 @@ static int pca9555_option(FAR struct ioexpander_dev_s *dev, uint8_t pin, int opt, FAR void *val) { FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; - int ival = (int)((intptr_t)val); int ret = -EINVAL; - if (opt == IOEXPANDER_OPTION_INVERT) + if ((opt & IOEXPANDER_OPTION_INVVAL) != 0) { + unsigned int ival = (unsigned int)((uintptr_t)val); + int setting; + + /* Set or clear the bit */ + + setting = ((ival & IOEXPANDER_OPTION_INVMASK) == IOEXPANDER_OPTION_INVERT); + /* Get exclusive access to the PCA555 */ pca9555_lock(pca); - ret = pca9555_setbit(pca, PCA9555_REG_POLINV, pin, ival); + ret = pca9555_setbit(pca, PCA9555_REG_POLINV, pin, setting); pca9555_unlock(pca); } diff --git a/drivers/ioexpander/skeleton.c b/drivers/ioexpander/skeleton.c index da2cc887fb..4ecd68a228 100644 --- a/drivers/ioexpander/skeleton.c +++ b/drivers/ioexpander/skeleton.c @@ -735,6 +735,7 @@ FAR struct ioexpander_dev_s *skel_initialize(void) priv = (FAR struct skel_dev_s *)kmm_zalloc(sizeof(struct skel_dev_s)); if (!priv) { + gpioerr("ERROR: Failed to allocate driver instance\n"); return NULL; } #else diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h index aa3d703b3a..2ea7b4b9e0 100644 --- a/include/nuttx/ioexpander/ioexpander.h +++ b/include/nuttx/ioexpander/ioexpander.h @@ -66,7 +66,18 @@ /* Pin options */ -#define IOEXPANDER_OPTION_INVERT 1 /* Set the "active" level for the line */ +#define IOEXPANDER_OPTION_INVMASK (3 << 0) /* Bits 0-1: Normal vs Inverted */ +# define IOEXPANDER_OPTION_INVVAL (1 << 0) /* x1: Inversion valid */ +# define IOEXPANDER_OPTION_INVNONE (1 << 0) /* 01: No inversion */ +# define IOEXPANDER_OPTION_INVERT (3 << 0) /* 11: Inverted */ +#define IOEXPANDER_OPTION_INTMASK (15 << 2) /* Bits 2-5: Interrupt settings */ +# define IOEXPANDER_OPTION_INTVAL (1 << 2) /* xxx1 Interrupt valid */ +# define IOEXPANDER_OPTION_LEVEL (2 << 2) /* xx1x Interrupt on level (vs. edge) */ +# define IOEXPANDER_OPTION_HIGH (3 << 2) /* 0011 Interrupt on high level */ +# define IOEXPANDER_OPTION_LOW (7 << 2) /* 0111 Interrupt on low level */ +# define IOEXPANDER_OPTION_RISING (5 << 2) /* 0101 Interrupt rising edge */ +# define IOEXPANDER_OPTION_FALLING (9 << 2) /* 1001 Interrupt falling edge */ +# define IOEXPANDER_OPTION_BOTH (13 << 2) /* 1101 Interrupt both edges */ /* Access macros ************************************************************/ @@ -267,6 +278,7 @@ typedef uint16_t ioe_pinset_t; typedef uint32_t ioe_pinset_t; #else /* if CONFIG_IOEXPANDER_NPINS <= 64 */ typedef uint64_t ioe_pinset_t; +#endif #ifdef CONFIG_IOEXPANDER_INT_ENABLE /* This type represents a pin interrupt callback function */ diff --git a/include/nuttx/ioexpander/pca9555.h b/include/nuttx/ioexpander/pca9555.h index 3a99a7def3..151b9fed36 100644 --- a/include/nuttx/ioexpander/pca9555.h +++ b/include/nuttx/ioexpander/pca9555.h @@ -69,12 +69,11 @@ struct pca9555_config_s uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */ uint32_t frequency; /* I2C or SPI frequency */ +#ifdef CONFIG_IOEXPANDER_INT_ENABLE /* If multiple PCA9555 devices are supported, then an IRQ number must * be provided for each so that their interrupts can be distinguished. */ -#ifndef CONFIG_PCA9555_INT_DISABLE - #ifdef CONFIG_PCA9555_MULTIPLE int irq; /* IRQ number received by interrupt handler. */ #endif