Remove spinlock, change to i2c_readwrite where appropriate , and consolidate i2c read and write calls.

This commit is contained in:
TimJTi 2023-08-31 13:05:03 +01:00 committed by Petro Karashchenko
parent c27c33e9a9
commit 3b4ea52a79
2 changed files with 51 additions and 109 deletions

View File

@ -33,7 +33,6 @@
#include <nuttx/compiler.h>
#include <nuttx/fs/fs.h>
#include <nuttx/spinlock.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/i2c/i2c_master.h>
@ -254,7 +253,7 @@ struct apds9922_dev_s
struct apds9922_als_setup_s als_setup; /* Device ALS config */
struct apds9922_ps_setup_s ps_setup; /* Device PS config */
int als; /* ALS data */
FAR struct apds9922_ps_data *ps_data; /* PS data */
struct apds9922_ps_data ps_data; /* PS data */
uint8_t devid; /* Device ID read at startup */
int crefs; /* Number of opens, als or ps */
};
@ -276,14 +275,9 @@ static void apds9922_worker(FAR void *arg);
static int apds9922_i2c_read(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr, FAR uint8_t *regval,
int len);
static int apds9922_i2c_read8(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr,
FAR uint8_t *regval);
static int apds9922_i2c_write(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr,
uint8_t const *data, int len);
static int apds9922_i2c_write8(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr, uint8_t regval);
/* local functions */
@ -294,14 +288,14 @@ static int apds9922_reset(FAR struct apds9922_dev_s *priv);
static int apds9922_als_config(FAR struct apds9922_dev_s *priv,
FAR struct apds9922_als_setup_s *config);
static int apds9922_lux_calc(FAR struct apds9922_dev_s *priv);
static int apds9922_als_gain(FAR struct apds9922_dev_s *priv, int gain);
static int apds9922_als_gain(FAR struct apds9922_dev_s *priv, uint8_t gain);
static int apds9922_autogain(FAR struct apds9922_dev_s *priv, bool enable);
static int apds9922_als_resolution(FAR struct apds9922_dev_s *priv, int res);
static int apds9922_als_rate(FAR struct apds9922_dev_s *priv, int rate);
static int apds9922_als_persistance(FAR struct apds9922_dev_s *priv,
uint8_t persistance);
static int apds9922_als_variance(FAR struct apds9922_dev_s *priv,
int variance);
uint8_t variance);
static int apds9922_als_thresh(FAR struct apds9922_dev_s *priv,
FAR struct adps9922_als_thresh thresholds);
static int apds9922_als_int_mode(FAR struct apds9922_dev_s *priv, int mode);
@ -412,7 +406,7 @@ static void apds9922_worker(FAR void *arg)
DEBUGASSERT(priv);
ret = apds9922_i2c_read8(priv, APDS9922_MAIN_STATUS, &status);
ret = apds9922_i2c_read(priv, APDS9922_MAIN_STATUS, &status, 1);
if (ret < 0)
{
snerr("Failed to read status: %d\n", ret);
@ -444,19 +438,19 @@ static void apds9922_worker(FAR void *arg)
goto err_out;
}
priv->ps_data->ps = APDS9922_PACK_TO_UINT16(data) & 0x0fff;
priv->ps_data.ps = APDS9922_PACK_TO_UINT16(data) & 0x0fff;
notify_ps = true;
}
if ((priv->ps_setup.notify != PS_PROXIMITY_DATA_ONLY) &&
(priv->ps_data->close != (status & PS_LOGIC_STATUS)))
(priv->ps_data.close != (status & PS_LOGIC_STATUS)))
{
notify_ps = true;
priv->ps_data->close = (status & PS_LOGIC_STATUS) ? true : false;
priv->ps_data.close = (status & PS_LOGIC_STATUS) ? true : false;
}
sninfo("INFO: ps=0x%x\t close=%d\n",
priv->ps_data->ps, priv->ps_data->close);
priv->ps_data.ps, priv->ps_data.close);
if (notify_ps)
{
@ -472,8 +466,8 @@ err_out:
if (ret < 0)
{
priv->als = ret;
priv->ps_data->ps = ret;
priv->als = ret;
priv->ps_data.ps = ret;
snerr("ERR: Error while dealing with worker \n");
poll_notify(priv->fds_als, CONFIG_APDS9922_ALS_NPOLLWAITERS, POLLIN);
@ -538,8 +532,9 @@ static int apds9922_int_handler(int irq, FAR void *context, FAR void *arg)
static int apds9922_reset(FAR struct apds9922_dev_s *priv)
{
int ret;
const uint8_t reset = APDS9922_SW_RESET;
ret = apds9922_i2c_write8(priv, APDS9922_MAIN_CTRL, APDS9922_SW_RESET);
ret = apds9922_i2c_write(priv, APDS9922_MAIN_CTRL, &reset, 1);
if (ret < 0)
{
snerr("ERROR: Failed to reset the APDS9922\n");
@ -599,7 +594,7 @@ static int apds9922_probe(FAR struct apds9922_dev_s *priv)
int ret;
uint8_t id = 0;
ret = apds9922_i2c_read8(priv, APDS9922_ID, &id);
ret = apds9922_i2c_read(priv, APDS9922_ID, &id, 1);
if (ret < 0)
{
snerr("ERROR: Failed to probe the APDS9922\n");
@ -730,7 +725,7 @@ static int apds9922_als_resolution(FAR struct apds9922_dev_s *priv, int res)
uint8_t regval;
int ret;
ret = apds9922_i2c_read8(priv, APDS9922_ALS_MEAS_RATE, &regval);
ret = apds9922_i2c_read(priv, APDS9922_ALS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -738,7 +733,7 @@ static int apds9922_als_resolution(FAR struct apds9922_dev_s *priv, int res)
regval &= ~ALS_RESOLUTION_MASK;
regval |= ALS_SET_RESOLUTION(res);
ret = apds9922_i2c_write8(priv, APDS9922_ALS_MEAS_RATE, regval);
ret = apds9922_i2c_write(priv, APDS9922_ALS_MEAS_RATE, &regval, 1);
priv->als_setup.res = res;
return ret;
@ -769,7 +764,7 @@ static int apds9922_als_channel(FAR struct apds9922_dev_s *priv, int channel)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_INT_CFG, &regval);
ret = apds9922_i2c_read(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
return ret;
@ -778,7 +773,7 @@ static int apds9922_als_channel(FAR struct apds9922_dev_s *priv, int channel)
regval &= ~ALS_INT_SRC_MASK;
regval |= ALS_INT_SET_SRC(channel);
ret = apds9922_i2c_write8(priv, APDS9922_INT_CFG, regval);
ret = apds9922_i2c_write(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
return ret;
@ -870,7 +865,7 @@ static int apds9922_als_int_mode(FAR struct apds9922_dev_s *priv, int mode)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_INT_CFG, &regval);
ret = apds9922_i2c_read(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
return ret;
@ -891,7 +886,7 @@ static int apds9922_als_int_mode(FAR struct apds9922_dev_s *priv, int mode)
break;
}
ret = apds9922_i2c_write8(priv, APDS9922_INT_CFG, regval);
ret = apds9922_i2c_write(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
@ -975,7 +970,7 @@ static int apds9922_als_thresh(FAR struct apds9922_dev_s *priv,
****************************************************************************/
static int apds9922_als_variance(FAR struct apds9922_dev_s *priv,
int variance)
uint8_t variance)
{
int ret;
@ -984,7 +979,7 @@ static int apds9922_als_variance(FAR struct apds9922_dev_s *priv,
return -EINVAL;
}
ret = apds9922_i2c_write8(priv, APDS9922_ALS_THRESH_VAR, variance);
ret = apds9922_i2c_write(priv, APDS9922_ALS_THRESH_VAR, &variance, 1);
if (ret < 0)
{
return ret;
@ -1021,7 +1016,7 @@ static int apds9922_als_persistance(FAR struct apds9922_dev_s *priv,
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_INT_PERSIST, &regval);
ret = apds9922_i2c_read(priv, APDS9922_INT_PERSIST, &regval, 1);
if (ret < 0)
{
return ret;
@ -1029,7 +1024,7 @@ static int apds9922_als_persistance(FAR struct apds9922_dev_s *priv,
regval &= ~ALS_PERSISTANCE_MASK;
regval |= ALS_SET_PERSISTANCE(persistance);
ret = apds9922_i2c_write8(priv, APDS9922_INT_PERSIST, regval);
ret = apds9922_i2c_write(priv, APDS9922_INT_PERSIST, &regval, 1);
if (ret < 0)
{
return ret;
@ -1065,7 +1060,7 @@ static int apds9922_als_rate(FAR struct apds9922_dev_s *priv, int rate)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_ALS_MEAS_RATE, &regval);
ret = apds9922_i2c_read(priv, APDS9922_ALS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1073,7 +1068,7 @@ static int apds9922_als_rate(FAR struct apds9922_dev_s *priv, int rate)
regval &= ~ALS_MEASURERATE_MASK;
regval |= ALS_SET_MEASURERATE(rate);
ret = apds9922_i2c_write8(priv, APDS9922_ALS_MEAS_RATE, regval);
ret = apds9922_i2c_write(priv, APDS9922_ALS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1131,7 +1126,7 @@ static int apds9922_autogain(FAR struct apds9922_dev_s *priv,
*
****************************************************************************/
static int apds9922_als_gain(FAR struct apds9922_dev_s *priv, int gain)
static int apds9922_als_gain(FAR struct apds9922_dev_s *priv, uint8_t gain)
{
int ret;
@ -1140,7 +1135,7 @@ static int apds9922_als_gain(FAR struct apds9922_dev_s *priv, int gain)
return -EINVAL;
}
ret = apds9922_i2c_write8(priv, APDS9922_ALS_GAIN, gain);
ret = apds9922_i2c_write(priv, APDS9922_ALS_GAIN, &gain, 1);
if (ret < 0)
{
return ret;
@ -1342,7 +1337,7 @@ static int apds9922_ps_resolution(FAR struct apds9922_dev_s *priv, int res)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_PS_MEAS_RATE, &regval);
ret = apds9922_i2c_read(priv, APDS9922_PS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1350,7 +1345,7 @@ static int apds9922_ps_resolution(FAR struct apds9922_dev_s *priv, int res)
regval &= ~PS_RESOLUTION_MASK;
regval |= PS_SET_RESOLUTION(res);
ret = apds9922_i2c_write8(priv, APDS9922_PS_MEAS_RATE, regval);
ret = apds9922_i2c_write(priv, APDS9922_PS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1386,7 +1381,7 @@ static int apds9922_ps_rate(FAR struct apds9922_dev_s *priv, int rate)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_PS_MEAS_RATE, &regval);
ret = apds9922_i2c_read(priv, APDS9922_PS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1394,7 +1389,7 @@ static int apds9922_ps_rate(FAR struct apds9922_dev_s *priv, int rate)
regval &= ~PS_MEASURERATE_MASK;
regval |= PS_SET_MEASURERATE(rate);
ret = apds9922_i2c_write8(priv, APDS9922_PS_MEAS_RATE, regval);
ret = apds9922_i2c_write(priv, APDS9922_PS_MEAS_RATE, &regval, 1);
if (ret < 0)
{
return ret;
@ -1430,7 +1425,7 @@ static int apds9922_ps_ledf(FAR struct apds9922_dev_s *priv, int freq)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_PS_LED, &regval);
ret = apds9922_i2c_read(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1438,7 +1433,7 @@ static int apds9922_ps_ledf(FAR struct apds9922_dev_s *priv, int freq)
regval &= ~PS_LED_FREQ_MASK;
regval |= PS_SET_LED_FREQ(freq);
ret = apds9922_i2c_write8(priv, APDS9922_PS_LED, regval);
ret = apds9922_i2c_write(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1474,7 +1469,7 @@ static int apds9922_ps_ledi(FAR struct apds9922_dev_s *priv, int current)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_PS_LED, &regval);
ret = apds9922_i2c_read(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1482,7 +1477,7 @@ static int apds9922_ps_ledi(FAR struct apds9922_dev_s *priv, int current)
regval &= ~PS_LED_CURRENT_MASK;
regval |= PS_SET_LED_CURRENT(current);
ret = apds9922_i2c_write8(priv, APDS9922_PS_LED, regval);
ret = apds9922_i2c_write(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1513,7 +1508,7 @@ static int apds9922_ps_ledpk(FAR struct apds9922_dev_s *priv, bool enable)
uint8_t regval;
int ret;
ret = apds9922_i2c_read8(priv, APDS9922_PS_LED, &regval);
ret = apds9922_i2c_read(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1528,7 +1523,7 @@ static int apds9922_ps_ledpk(FAR struct apds9922_dev_s *priv, bool enable)
regval &= ~PS_LED_PEAKING_ON;
}
ret = apds9922_i2c_write8(priv, APDS9922_PS_LED, regval);
ret = apds9922_i2c_write(priv, APDS9922_PS_LED, &regval, 1);
if (ret < 0)
{
return ret;
@ -1558,7 +1553,7 @@ static int apds9922_ps_pulses(FAR struct apds9922_dev_s *priv, uint8_t num_p)
{
int ret;
ret = apds9922_i2c_write8(priv, APDS9922_PS_PULSES, num_p);
ret = apds9922_i2c_write(priv, APDS9922_PS_PULSES, &num_p, 1);
if (ret < 0)
{
@ -1691,7 +1686,7 @@ static int apds9922_ps_int_mode(FAR struct apds9922_dev_s *priv, int mode)
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_INT_CFG, &regval);
ret = apds9922_i2c_read(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
@ -1713,7 +1708,7 @@ static int apds9922_ps_int_mode(FAR struct apds9922_dev_s *priv, int mode)
break;
}
ret = apds9922_i2c_write8(priv, APDS9922_INT_CFG, regval);
ret = apds9922_i2c_write(priv, APDS9922_INT_CFG, &regval, 1);
if (ret < 0)
{
return ret;
@ -1750,7 +1745,7 @@ static int apds9922_ps_persistance(FAR struct apds9922_dev_s *priv,
return -EINVAL;
}
ret = apds9922_i2c_read8(priv, APDS9922_INT_PERSIST, &regval);
ret = apds9922_i2c_read(priv, APDS9922_INT_PERSIST, &regval, 1);
if (ret < 0)
{
return ret;
@ -1758,7 +1753,7 @@ static int apds9922_ps_persistance(FAR struct apds9922_dev_s *priv,
regval &= ~PS_PERSISTANCE_MASK;
regval |= PS_SET_PERSISTANCE(persistance);
ret = apds9922_i2c_write8(priv, APDS9922_INT_PERSIST, regval);
ret = apds9922_i2c_write(priv, APDS9922_INT_PERSIST, &regval, 1);
if (ret < 0)
{
return ret;
@ -1813,7 +1808,6 @@ static int apds9922_i2c_read(FAR struct apds9922_dev_s *priv,
{
struct i2c_config_s config;
int ret;
irqstate_t flags;
DEBUGASSERT(priv);
@ -1825,47 +1819,16 @@ static int apds9922_i2c_read(FAR struct apds9922_dev_s *priv,
/* Write the register address to read from */
flags = spin_lock_irqsave(NULL);
ret = i2c_write(priv->config->i2c, &config, &regaddr, 1);
spin_unlock_irqrestore(NULL, flags);
ret = i2c_writeread(priv->config->i2c, &config, &regaddr, 1, regval, len);
if (ret < 0)
{
snerr ("i2c_write failed: %d\n", ret);
return ret;
}
/* Read "len" bytes from regaddr */
flags = spin_lock_irqsave(NULL);
ret = i2c_read(priv->config->i2c, &config, regval, len);
spin_unlock_irqrestore(NULL, flags);
if (ret < 0)
{
snerr ("i2c_read failed: %d\n", ret);
snerr ("i2c_writeread failed: %d\n", ret);
return ret;
}
return OK;
}
/****************************************************************************
* Name: apds9922_i2c_read8
*
* Description:
* Read 8-bit register
*
****************************************************************************/
static int apds9922_i2c_read8(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr, FAR uint8_t *regval)
{
int ret;
ret = apds9922_i2c_read(priv, regaddr, regval, 1);
return ret;
}
/****************************************************************************
* Name: apds9922_i2c_write
*
@ -1880,7 +1843,6 @@ static int apds9922_i2c_write(FAR struct apds9922_dev_s *priv,
{
struct i2c_config_s config;
int ret;
irqstate_t flags;
uint8_t *buffer;
buffer = kmm_malloc((len + 1) * sizeof(uint8_t));
@ -1901,9 +1863,7 @@ static int apds9922_i2c_write(FAR struct apds9922_dev_s *priv,
/* Write the data */
flags = spin_lock_irqsave(NULL);
ret = i2c_write(priv->config->i2c, &config, buffer, len + 1);
spin_unlock_irqrestore(NULL, flags);
if (ret < 0)
{
snerr("ERROR: i2c_write failed: %d\n", ret);
@ -1914,24 +1874,6 @@ static int apds9922_i2c_write(FAR struct apds9922_dev_s *priv,
return ret;
}
/****************************************************************************
* Name: apds9922_i2c_write8
*
* Description:
* Write an single byte of date to regaddr.
*
****************************************************************************/
static int apds9922_i2c_write8(FAR struct apds9922_dev_s *priv,
uint8_t const regaddr, uint8_t regval)
{
int ret;
ret = apds9922_i2c_write(priv, regaddr, &regval, 1);
return ret;
}
/****************************************************************************
* Name: apds9922_open
*
@ -2286,7 +2228,7 @@ static ssize_t apds9922_ps_read(FAR struct file *filep, FAR char *buffer,
return ret;
}
*ptr = *priv->ps_data;
*ptr = priv->ps_data;
nxmutex_unlock(&priv->devlock);
@ -2534,7 +2476,7 @@ int apds9922_register(FAR const char *devpath_als,
regval = (devpath_ps != NULL) ? PS_ACTIVE : 0;
regval |= (devpath_als != NULL) ? ALS_ACTIVE : regval;
ret = apds9922_i2c_write8(priv, APDS9922_MAIN_CTRL, regval);
ret = apds9922_i2c_write(priv, APDS9922_MAIN_CTRL, &regval, 1);
if (ret < 0)
{
snerr("ERROR: Failed to enable als and/or ps.\n");
@ -2582,8 +2524,8 @@ int apds9922_register(FAR const char *devpath_als,
}
}
priv->ps_data->close = false;
priv->ps_data->ps = 0;
priv->ps_data.close = false;
priv->ps_data.ps = 0;
priv->als = 0;
priv->crefs = 0;

View File

@ -191,10 +191,10 @@ struct apds9922_als_setup_s
{
int rate; /* als measurement rate */
int res; /* als resolution */
int gain; /* als gain */
uint8_t gain; /* als gain */
struct adps9922_als_thresh
thresh; /* Upper and lower thresholds */
int thresh_var; /* threshold variation */
uint8_t thresh_var; /* threshold variation */
int int_mode; /* Interrupt mode */
uint8_t persistance; /* Num events before interrupt */
uint32_t als_factor; /* Lux correction factor applied */
@ -227,7 +227,7 @@ struct apds9922_ps_setup_s
struct apds9922_ps_data
{
uint16_t ps; /* Current prximity measure */
uint16_t ps; /* Current proximity measure */
bool close; /* Object is far (false) or close */
};