From 8fa9b99e7c28e2f133a25727d6261c7845439b31 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 3 Feb 2016 07:32:25 -0600 Subject: [PATCH] I2C driver should support the RESET method as well --- drivers/i2c/i2c_driver.c | 89 ++++++++++++++++++++++------------ include/nuttx/i2c/i2c_master.h | 14 ++++++ 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/drivers/i2c/i2c_driver.c b/drivers/i2c/i2c_driver.c index d720ef3d38..ac53f0f1f1 100644 --- a/drivers/i2c/i2c_driver.c +++ b/drivers/i2c/i2c_driver.c @@ -249,51 +249,76 @@ static ssize_t i2cdrvr_write(FAR struct file *filep, FAR const char *buffer, static int i2cdrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { + FAR struct inode *inode = filep->f_inode; + FAR struct i2c_driver_s *priv; + FAR struct i2c_transfer_s *transfer; + int ret; + i2cvdbg("cmd=%d arg=%lu\n", cmd, arg); - /* Only one command is supported */ + /* Get our private data structure */ - if (cmd == I2CIOC_TRANSFER) + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + + priv = (FAR struct i2c_driver_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Get exclusive access to the I2C driver state structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) { - FAR struct inode *inode = filep->f_inode; - FAR struct i2c_driver_s *priv; - FAR struct i2c_transfer_s *transfer; - int ret; + int errcode = errno; + DEBUGASSERT(errcode < 0); + return -errcode; + } - /* Get our private data structure */ + /* Process the IOCTL command */ - DEBUGASSERT(filep != NULL && filep->f_inode != NULL); - inode = filep->f_inode; + switch (cmd) + { + /* Command: I2CIOC_TRANSFER + * Description: Perform an I2C transfer + * Argument: A reference to an instance of struct i2c_transfer_s. + * Dependencies: CONFIG_I2C_DRIVER + */ - priv = (FAR struct i2c_driver_s *)inode->i_private; - DEBUGASSERT(priv); - - /* Get the reference to the i2c_transfer_s structure */ - - transfer = (FAR struct i2c_transfer_s *)((uintptr_t)arg); - DEBUGASSERT(transfer != NULL); - - /* Get exclusive access to the I2C driver state structure */ - - ret = sem_wait(&priv->exclsem); - if (ret < 0) + case I2CIOC_TRANSFER: { - int errcode = errno; - DEBUGASSERT(errcode < 0); - return -errcode; + /* Get the reference to the i2c_transfer_s structure */ + + transfer = (FAR struct i2c_transfer_s *)((uintptr_t)arg); + DEBUGASSERT(transfer != NULL); + + /* Perform the transfer */ + + ret = I2C_TRANSFER(priv->i2c, transfer->msgv, transfer->msgc); } + break; - /* Perform the transfer */ +#ifdef CONFIG_I2C_RESET + /* Command: I2CIOC_RESET + * Description: Perform an I2C bus reset in an attempt to break loose + * stuck I2C devices. + * Argument: None + * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET + */ - ret = I2C_TRANSFER(priv->i2c, transfer->msgv, transfer->msgc); + case I2CIOC_RESET: + { + ret = I2C_RESET(priv->i2c); + } + break; +#endif - sem_post(&priv->exclsem); - return ret; - } - else - { - return -ENOTTY; + default: + ret = -ENOTTY; + break; } + + sem_post(&priv->exclsem); + return ret; } /**************************************************************************** diff --git a/include/nuttx/i2c/i2c_master.h b/include/nuttx/i2c/i2c_master.h index 330e2e0e9b..868dad15b9 100644 --- a/include/nuttx/i2c/i2c_master.h +++ b/include/nuttx/i2c/i2c_master.h @@ -81,6 +81,11 @@ * (re-)start of transfer */ /* I2C Character Driver IOCTL Commands **************************************/ +/* The I2C driver is intended to support application testing of the I2C bus. + * The I2C driver simply wraps an instance of struct i2c_dev_s and then + * provides the following IOCTL commands to access each method of the I2c + * interface. + */ /* Command: I2CIOC_TRANSFER * Description: Perform an I2C transfer @@ -90,6 +95,15 @@ #define I2CIOC_TRANSFER _I2CIOC(0x0001) +/* Command: I2CIOC_RESET + * Description: Perform an I2C bus reset in an attempt to break loose stuck + * I2C devices. + * Argument: None + * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET + */ + +#define I2CIOC_RESET _I2CIOC(0x0002) + /* Access macros ************************************************************/ /****************************************************************************