I/O Expander Interface: Add argument to interrupt callback. Add a method to detach the interrupt.

This commit is contained in:
Gregory Nutt 2016-08-01 07:26:04 -06:00
parent fb84e51d5b
commit 91b1006d42
5 changed files with 130 additions and 28 deletions

View File

@ -93,8 +93,10 @@ static int pca9555_multireadbuf(FAR struct ioexpander_dev_s *dev,
FAR uint8_t *pins, FAR bool *values, int count);
#endif
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
static int pca9555_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback);
static FAR void *pca9555_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback, FAR void *arg);
static int pca9555_detach(FAR struct ioexpander_dev_s *dev,
FAR void *handle);
#endif
/****************************************************************************
@ -130,6 +132,7 @@ static const struct ioexpander_ops_s g_pca9555_ops =
#endif
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
, pca9555_attach
, pca9555_detach
#endif
};
@ -701,24 +704,27 @@ static int pca9555_multireadbuf(FAR struct ioexpander_dev_s *dev,
* Name: pca9555_attach
*
* Description:
* Attach a pin interrupt callback function.
* Attach and enable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* pinset - The set of pin events that will generate the callback
* callback - The pointer to callback function. NULL will detach the
* callback.
* arg - User-provided callback argument
*
* Returned Value:
* 0 on success, else a negative error code
* A non-NULL handle value is returned on success. This handle may be
* used later to detach and disable the pin interrupt.
*
****************************************************************************/
static int pca9555_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback)
static FAR void *pca9555_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback,
FAR void *arg)
{
FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev;
int ret;
FAR void *handle = NULL;
int i;
/* Get exclusive access to the PCA555 */
@ -727,7 +733,6 @@ static int pca9555_attach(FAR struct ioexpander_dev_s *dev,
/* Find and available in entry in the callback table */
ret = -ENOSPC;
for (i = 0; i < CONFIG_PCA9555_INT_NCALLBACKS; i++)
{
/* Is this entry available (i.e., no callback attached) */
@ -738,14 +743,47 @@ static int pca9555_attach(FAR struct ioexpander_dev_s *dev,
pca->cb[i].pinset = pinset;
pca->cb[i].cbfunc = callback;
ret = OK;
pca->cb[i].cbarg = arg;
handle = &pca->cb[i];
break;
}
}
/* Add this callback to the table */
pca9555_unlock(pca);
return ret;
return handle;
}
/****************************************************************************
* Name: pca9555_detach
*
* Description:
* Detach and disable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* handle - The non-NULL opaque value return by pca9555_attch()
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
static int pca9555_detach(FAR struct ioexpander_dev_s *dev, FAR void *handle)
{
FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev;
FAR struct pca9555_callback_s *cb = (FAR struct pca9555_callback_s *)handle;
DEBUGASSERT(pca != NULL && cb != NULL);
DEBUGASSERT((uintptr_t)cb >= (uintptr_t)&pca->cb[0] &&
(uintptr_t)cb <= (uintptr_t)&pca->cb[CONFIG_TCA64XX_INT_NCALLBACKS-1]);
UNUSED(pca);
cb->pinset = 0;
cb->cbfunc = NULL;
cb->cbarg = NULL;
return OK;
}
/****************************************************************************
@ -798,7 +836,8 @@ static void pca9555_irqworker(void *arg)
{
/* Yes.. perform the callback */
(void)pca->cb[i].cbfunc(&pca->dev, match);
(void)pca->cb[i].cbfunc(&pca->dev, match,
pca->cb[i].cbarg);
}
}
}

View File

@ -134,6 +134,7 @@ struct pca9555_callback_s
ioe_pinset_t pinset; /* Set of pin interrupts that will generate
* the callback. */
ioe_callback_t cbfunc; /* The saved callback function pointer */
FAR void *cbarg; /* Callback argument */
};
#endif

View File

@ -105,8 +105,9 @@ static int tca64_multireadpin(FAR struct ioexpander_dev_s *dev,
FAR uint8_t *pins, FAR bool *values, int count);
#endif
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
static int tca64_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback);
static FAR void *tca64_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback, FAR void *arg);
static int tca64_detach(FAR struct ioexpander_dev_s *dev, FAR void *handle);
#endif
#ifdef CONFIG_TCA64XX_INT_ENABLE
@ -148,6 +149,7 @@ static const struct ioexpander_ops_s g_tca64_ops =
#endif
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
, tca64_attach
, tca64_detach
#endif
};
@ -932,25 +934,28 @@ errout_with_lock:
* Name: tca64_attach
*
* Description:
* Attach a pin interrupt callback function.
* Attach and enable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* pinset - The set of pin events that will generate the callback
* callback - The pointer to callback function. NULL will detach the
* callback.
* arg - User-provided callback argument
*
* Returned Value:
* 0 on success, else a negative error code
* A non-NULL handle value is returned on success. This handle may be
* used later to detach and disable the pin interrupt.
*
****************************************************************************/
#ifdef CONFIG_TCA64XX_INT_ENABLE
static int tca64_attach(FAR struct ioexpander_dev_s *dev, ioe_pinset_t pinset,
ioe_callback_t callback)
static FAR void *tca64_attach(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback,
FAR void *arg)
{
FAR struct tca64_dev_s *priv = (FAR struct tca64_dev_s *)dev;
int ret;
FAR void *handle = NULL;
int i;
/* Get exclusive access to the I/O Expander */
@ -959,7 +964,6 @@ static int tca64_attach(FAR struct ioexpander_dev_s *dev, ioe_pinset_t pinset,
/* Find and available in entry in the callback table */
ret = -ENOSPC;
for (i = 0; i < CONFIG_TCA64XX_INT_NCALLBACKS; i++)
{
/* Is this entry available (i.e., no callback attached) */
@ -970,16 +974,48 @@ static int tca64_attach(FAR struct ioexpander_dev_s *dev, ioe_pinset_t pinset,
priv->cb[i].pinset = pinset;
priv->cb[i].cbfunc = callback;
ret = OK;
priv->cb[i].cbarg = arg;
handle = &priv->cb[i];
break;
}
}
tca64_unlock(priv);
return ret;
return handle;
}
#endif
/****************************************************************************
* Name: tca64_detach
*
* Description:
* Detach and disable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* handle - The non-NULL opaque value return by tca64_attch()
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
static int tca64_detach(FAR struct ioexpander_dev_s *dev, FAR void *handle)
{
FAR struct tca64_dev_s *priv = (FAR struct tca64_dev_s *)dev;
FAR struct tca64_callback_s *cb = (FAR struct tca64_callback_s *)handle;
DEBUGASSERT(priv != NULL && cb != NULL);
DEBUGASSERT((uintptr_t)cb >= (uintptr_t)&priv->cb[0] &&
(uintptr_t)cb <= (uintptr_t)&priv->cb[CONFIG_TCA64XX_INT_NCALLBACKS-1]);
UNUSED(priv);
cb->pinset = 0;
cb->cbfunc = NULL;
cb->cbarg = NULL;
return OK;
}
/****************************************************************************
* Name: tca64_int_update
*
@ -1170,7 +1206,8 @@ static void tca64_irqworker(void *arg)
{
/* Yes.. perform the callback */
(void)priv->cb[i].cbfunc(&priv->dev, match);
(void)priv->cb[i].cbfunc(&priv->dev, match,
priv->cb[i].cbarg);
}
}
}

View File

@ -231,6 +231,7 @@ struct tca64_callback_s
ioe_pinset_t pinset; /* Set of pin interrupts that will generate
* the callback. */
ioe_callback_t cbfunc; /* The saved callback function pointer */
FAR void *cbarg; /* Callback argument */
};
#endif

View File

@ -247,13 +247,35 @@
* Name: IOEP_ATTACH
*
* Description:
* Attach a pin interrupt callback function.
* Attach and enable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* pinset - The set of pin events that will generate the callback
* callback - The pointer to callback function. NULL will detach the
* callback.
* arg - User-provided callback argument
*
* Returned Value:
* A non-NULL handle value is returned on success. This handle may be
* used later to detach and disable the pin interrupt.
*
****************************************************************************/
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
#define IOEP_ATTACH(dev,pinset,callback,arg) \
((dev)->ops->ioe_attach(dev,pins,callback,arg))
#endif
/****************************************************************************
* Name: IOEP_DETACH
*
* Description:
* Detach and disable a pin interrupt callback function.
*
* Input Parameters:
* dev - Device-specific state data
* handle - The non-NULL opaque value return by IOEP_ATTACH
*
* Returned Value:
* 0 on success, else a negative error code
@ -261,8 +283,7 @@
****************************************************************************/
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
#define IOEP_ATTACH(dev,pinset,callback) \
((dev)->ops->ioe_attach(dev,pins,callback))
#define IOEP_DETACH(dev,handle) (dev)->ops->ioe_detach(dev,handle))
#endif
/****************************************************************************
@ -286,7 +307,7 @@ typedef uint64_t ioe_pinset_t;
struct ioexpander_dev_s;
typedef int (*ioe_callback_t)(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset);
ioe_pinset_t pinset, FAR void *arg);
#endif /* CONFIG_IOEXPANDER_INT_ENABLE */
/* I/O expander interface methods */
@ -313,8 +334,11 @@ struct ioexpander_ops_s
uint8_t *pins, bool *values, int count);
#endif
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
CODE int (*ioe_attach)(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset, ioe_callback_t callback);
CODE FAR void *(*ioe_attach)(FAR struct ioexpander_dev_s *dev,
ioe_pinset_t pinset,
ioe_callback_t callback, FAR void *arg);
CODE int (*ioe_detach)(FAR struct ioexpander_dev_s *dev,
FAR void *handle);
#endif
};