drivers/video/isx012: Add exclusive controls for I2C access
Add exclusive control to prevent from I2C write(for sending requst) and I2C read(for receiving response).
This commit is contained in:
parent
bea6d3a7ef
commit
1613ded060
@ -30,6 +30,7 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
@ -168,6 +169,7 @@ typedef struct isx012_reg_s isx012_reg_t;
|
||||
|
||||
struct isx012_dev_s
|
||||
{
|
||||
sem_t i2c_lock;
|
||||
FAR struct i2c_master_s *i2c; /* I2C interface */
|
||||
uint8_t i2c_addr; /* I2C address */
|
||||
int i2c_freq; /* Frequency */
|
||||
@ -635,6 +637,16 @@ static struct imgsensor_ops_s g_isx012_ops =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void i2c_lock(void)
|
||||
{
|
||||
nxsem_wait_uninterruptible(&g_isx012_private.i2c_lock);
|
||||
}
|
||||
|
||||
static void i2c_unlock(void)
|
||||
{
|
||||
nxsem_post(&g_isx012_private.i2c_lock);
|
||||
}
|
||||
|
||||
static uint16_t isx012_getreg(isx012_dev_t *priv,
|
||||
uint16_t regaddr, uint16_t regsize)
|
||||
{
|
||||
@ -651,25 +663,32 @@ static uint16_t isx012_getreg(isx012_dev_t *priv,
|
||||
buffer[0] = regaddr >> 8;
|
||||
buffer[1] = regaddr & 0xff;
|
||||
|
||||
i2c_lock();
|
||||
|
||||
/* Write the register address */
|
||||
|
||||
ret = i2c_write(priv->i2c, &config, (uint8_t *)buffer, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
verr("i2c_write failed: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart and read 16bits from the register */
|
||||
|
||||
ret = i2c_read(priv->i2c, &config, (uint8_t *)buffer, regsize);
|
||||
if (ret < 0)
|
||||
else
|
||||
{
|
||||
verr("i2c_read failed: %d\n", ret);
|
||||
return 0;
|
||||
/* Restart and read 16bits from the register */
|
||||
|
||||
ret = i2c_read(priv->i2c, &config, (uint8_t *)buffer, regsize);
|
||||
if (ret < 0)
|
||||
{
|
||||
verr("i2c_read failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)®val, (uint8_t *)buffer, regsize);
|
||||
i2c_unlock();
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
memcpy((uint8_t *)®val, (uint8_t *)buffer, regsize);
|
||||
}
|
||||
|
||||
return regval;
|
||||
}
|
||||
@ -694,6 +713,8 @@ static int isx012_putreg(isx012_dev_t *priv,
|
||||
|
||||
memcpy((uint8_t *)&buffer[2], (uint8_t *)®val, regsize);
|
||||
|
||||
i2c_lock();
|
||||
|
||||
/* And do it */
|
||||
|
||||
ret = i2c_write(priv->i2c, &config,
|
||||
@ -703,6 +724,8 @@ static int isx012_putreg(isx012_dev_t *priv,
|
||||
verr("i2c_write failed: %d\n", ret);
|
||||
}
|
||||
|
||||
i2c_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2924,6 +2947,8 @@ int isx012_initialize(void)
|
||||
|
||||
priv->state = STATE_ISX012_POWEROFF;
|
||||
|
||||
nxsem_init(&priv->i2c_lock, 0, 1);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user