You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2024/08/07 15:13:51 UTC
(nuttx) 07/11: add setup and shutdown for i2c master and slave
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 20930383158fd62c9b61b02d53a20d2215d81fa9
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Nov 23 21:06:50 2023 +0800
add setup and shutdown for i2c master and slave
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/i2c_driver.c | 28 +++++++++++++++++++--
drivers/i2c/i2c_slave_driver.c | 57 ++++++++++++++++++++++++++++++++++++------
include/nuttx/i2c/i2c_master.h | 34 +++++++++++++++++++++++++
include/nuttx/i2c/i2c_slave.h | 34 +++++++++++++++++++++++++
4 files changed, 143 insertions(+), 10 deletions(-)
diff --git a/drivers/i2c/i2c_driver.c b/drivers/i2c/i2c_driver.c
index 06e7a99ee5..1a78a64b2d 100644
--- a/drivers/i2c/i2c_driver.c
+++ b/drivers/i2c/i2c_driver.c
@@ -135,13 +135,25 @@ static int i2cdrvr_open(FAR struct file *filep)
return ret;
}
+ /* I2c master initialize */
+
+ if (priv->i2c->ops->setup != NULL && priv->crefs == 0)
+ {
+ ret = I2C_SETUP(priv->i2c);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Increment the count of open references on the driver */
priv->crefs++;
DEBUGASSERT(priv->crefs > 0);
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
#endif
@@ -171,6 +183,17 @@ static int i2cdrvr_close(FAR struct file *filep)
return ret;
}
+ /* I2c master uninitialize */
+
+ if (priv->i2c->ops->shutdown != NULL && priv->crefs == 1)
+ {
+ ret = I2C_SHUTDOWN(priv->i2c);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Decrement the count of open references on the driver */
DEBUGASSERT(priv->crefs > 0);
@@ -187,8 +210,9 @@ static int i2cdrvr_close(FAR struct file *filep)
return OK;
}
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
#endif
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
index 44160017dd..6403847077 100644
--- a/drivers/i2c/i2c_slave_driver.c
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -103,6 +103,14 @@ struct i2c_slave_driver_s
int16_t crefs;
+ /* I2C Slave address */
+
+ int addr;
+
+ /* The number of address bits provided (7 or 10) */
+
+ int nbits;
+
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
bool unlinked; /* Indicates if the driver has been unlinked */
#endif
@@ -150,6 +158,7 @@ static const struct file_operations g_i2cslavefops =
static int i2c_slave_open(FAR struct file *filep)
{
FAR struct i2c_slave_driver_s *priv;
+ int ret;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -161,13 +170,36 @@ static int i2c_slave_open(FAR struct file *filep)
nxmutex_lock(&priv->lock);
+ /* I2c slave initialize */
+
+ if (priv->dev->ops->setup != NULL && priv->crefs == 0)
+ {
+ ret = I2CS_SETUP(priv->dev);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
+ /* Set i2c slave address */
+
+ ret = I2CS_SETOWNADDRESS(priv->dev, priv->addr, priv->nbits);
+ if (ret < 0)
+ {
+ if (priv->dev->ops->shutdown != NULL)
+ {
+ ret = I2CS_SHUTDOWN(priv->dev);
+ }
+ }
+
/* Increment the count of open references on the driver */
priv->crefs++;
DEBUGASSERT(priv->crefs > 0);
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
/****************************************************************************
@@ -188,6 +220,7 @@ static int i2c_slave_open(FAR struct file *filep)
static int i2c_slave_close(FAR struct file *filep)
{
FAR struct i2c_slave_driver_s *priv;
+ int ret = OK;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -199,6 +232,17 @@ static int i2c_slave_close(FAR struct file *filep)
nxmutex_lock(&priv->lock);
+ /* I2c slave uninitialize */
+
+ if (priv->dev->ops->shutdown != NULL && priv->crefs == 1)
+ {
+ ret = I2CS_SHUTDOWN(priv->dev);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Decrement the count of open references on the driver */
DEBUGASSERT(priv->crefs > 0);
@@ -213,8 +257,9 @@ static int i2c_slave_close(FAR struct file *filep)
}
#endif
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
/****************************************************************************
@@ -494,12 +539,8 @@ int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
nxsem_init(&priv->wait, 0, 0);
nxmutex_init(&priv->lock);
priv->dev = dev;
-
- ret = I2CS_SETOWNADDRESS(priv->dev, addr, nbits);
- if (ret < 0)
- {
- goto out;
- }
+ priv->addr = addr;
+ priv->nbits = nbits;
ret = I2CS_READ(priv->dev, priv->read_buffer,
CONFIG_I2C_SLAVE_READBUFSIZE);
diff --git a/include/nuttx/i2c/i2c_master.h b/include/nuttx/i2c/i2c_master.h
index 39ba782f8b..da74c9faa2 100644
--- a/include/nuttx/i2c/i2c_master.h
+++ b/include/nuttx/i2c/i2c_master.h
@@ -171,6 +171,38 @@
# define I2C_RESET(d) ((d)->ops->reset(d))
#endif
+/****************************************************************************
+ * Name: I2C_SETUP
+ *
+ * Description:
+ * I2c master initialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2C_SETUP(d) ((d)->ops->setup(d))
+
+/****************************************************************************
+ * Name: I2C_SHUTDOWN
+ *
+ * Description:
+ * I2c master uninitialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2C_SHUTDOWN(d) ((d)->ops->shutdown(d))
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -186,6 +218,8 @@ struct i2c_ops_s
#ifdef CONFIG_I2C_RESET
CODE int (*reset)(FAR struct i2c_master_s *dev);
#endif
+ CODE int (*setup)(FAR struct i2c_master_s *dev);
+ CODE int (*shutdown)(FAR struct i2c_master_s *dev);
};
/* This structure contains the full state of I2C as needed for a specific
diff --git a/include/nuttx/i2c/i2c_slave.h b/include/nuttx/i2c/i2c_slave.h
index ee33157958..dd1c6c39c1 100644
--- a/include/nuttx/i2c/i2c_slave.h
+++ b/include/nuttx/i2c/i2c_slave.h
@@ -170,6 +170,38 @@
#define I2CS_REGISTERCALLBACK(d,c,a) ((d)->ops->registercallback(d,c,a))
+/****************************************************************************
+ * Name: I2CS_SETUP
+ *
+ * Description:
+ * I2c slave initialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2CS_SETUP(d) ((d)->ops->setup(d))
+
+/****************************************************************************
+ * Name: I2CS_SHUTDOWN
+ *
+ * Description:
+ * I2c slave uninitialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2CS_SHUTDOWN(d) ((d)->ops->shutdown(d))
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -198,6 +230,8 @@ struct i2c_slaveops_s
int (*registercallback)(FAR struct i2c_slave_s *dev,
i2c_slave_callback_t *callback,
FAR void *arg);
+ int (*setup)(FAR struct i2c_slave_s *dev);
+ int (*shutdown)(FAR struct i2c_slave_s *dev);
};
/* I2C private data. This structure only defines the initial fields of the