Check return from nxsem_wait_initialize()
Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution: Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly. This commit is only for those files under drivers/input.
This commit is contained in:
parent
d9b42cebe7
commit
4829c3d2ab
@ -100,25 +100,29 @@
|
||||
static void ads7843e_lock(FAR struct spi_dev_s *spi);
|
||||
static void ads7843e_unlock(FAR struct spi_dev_s *spi);
|
||||
|
||||
static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd);
|
||||
static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv,
|
||||
uint8_t cmd);
|
||||
|
||||
/* Interrupts and data sampling */
|
||||
|
||||
static void ads7843e_notify(FAR struct ads7843e_dev_s *priv);
|
||||
static int ads7843e_sample(FAR struct ads7843e_dev_s *priv,
|
||||
static int ads7843e_sample(FAR struct ads7843e_dev_s *priv,
|
||||
FAR struct ads7843e_sample_s *sample);
|
||||
static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv,
|
||||
static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv,
|
||||
FAR struct ads7843e_sample_s *sample);
|
||||
static void ads7843e_worker(FAR void *arg);
|
||||
static int ads7843e_interrupt(int irq, FAR void *context, FAR void *arg);
|
||||
static int ads7843e_interrupt(int irq, FAR void *context, FAR void *arg);
|
||||
|
||||
/* Character driver methods */
|
||||
|
||||
static int ads7843e_open(FAR struct file *filep);
|
||||
static int ads7843e_close(FAR struct file *filep);
|
||||
static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t len);
|
||||
static int ads7843e_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
static int ads7843e_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
|
||||
static int ads7843e_open(FAR struct file *filep);
|
||||
static int ads7843e_close(FAR struct file *filep);
|
||||
static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t len);
|
||||
static int ads7843e_ioctl(FAR struct file *filep, int cmd,
|
||||
unsigned long arg);
|
||||
static int ads7843e_poll(FAR struct file *filep, struct pollfd *fds,
|
||||
bool setup);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@ -252,7 +256,8 @@ static void ads7843e_unlock(FAR struct spi_dev_s *spi)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd)
|
||||
static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv,
|
||||
uint8_t cmd)
|
||||
{
|
||||
uint8_t buffer[2];
|
||||
uint16_t result;
|
||||
@ -302,10 +307,10 @@ static void ads7843e_notify(FAR struct ads7843e_dev_s *priv)
|
||||
nxsem_post(&priv->waitsem);
|
||||
}
|
||||
|
||||
/* If there are threads waiting on poll() for ADS7843E data to become available,
|
||||
* then wake them up now. NOTE: we wake up all waiting threads because we
|
||||
* do not know that they are going to do. If they all try to read the data,
|
||||
* then some make end up blocking after all.
|
||||
/* If there are threads waiting on poll() for ADS7843E data to become
|
||||
* available, then wake them up now. NOTE: we wake up all waiting threads
|
||||
* because we do not know that they are going to do. If they all try to
|
||||
* read the data, then some make end up blocking after all.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_ADS7843E_NPOLLWAITERS; i++)
|
||||
@ -425,8 +430,8 @@ static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv,
|
||||
iinfo("Sampled\n");
|
||||
|
||||
/* Re-acquire the semaphore that manages mutually exclusive access to
|
||||
* the device structure. We may have to wait here. But we have our sample.
|
||||
* Interrupts and pre-emption will be re-enabled while we wait.
|
||||
* the device structure. We may have to wait here. But we have our
|
||||
* sample. Interrupts and pre-emption will be re-enabled while we wait.
|
||||
*/
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
@ -498,7 +503,9 @@ static int ads7843e_schedule(FAR struct ads7843e_dev_s *priv)
|
||||
|
||||
static void ads7843e_wdog(int argc, uint32_t arg1, ...)
|
||||
{
|
||||
FAR struct ads7843e_dev_s *priv = (FAR struct ads7843e_dev_s *)((uintptr_t)arg1);
|
||||
FAR struct ads7843e_dev_s *priv =
|
||||
(FAR struct ads7843e_dev_s *)((uintptr_t)arg1);
|
||||
|
||||
ads7843e_schedule(priv);
|
||||
}
|
||||
|
||||
@ -515,6 +522,7 @@ static void ads7843e_worker(FAR void *arg)
|
||||
uint16_t xdiff;
|
||||
uint16_t ydiff;
|
||||
bool pendown;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -537,7 +545,17 @@ static void ads7843e_worker(FAR void *arg)
|
||||
|
||||
/* Get exclusive access to the driver data structure */
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
do
|
||||
{
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
|
||||
/* This would only fail if something canceled the worker thread?
|
||||
* That is not expected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
/* Check for pen up or down by reading the PENIRQ GPIO. */
|
||||
|
||||
@ -552,8 +570,9 @@ static void ads7843e_worker(FAR void *arg)
|
||||
priv->threshx = INVALID_THRESHOLD;
|
||||
priv->threshy = INVALID_THRESHOLD;
|
||||
|
||||
/* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up
|
||||
* and already reported; CONTACT_UP == pen up, but not reported)
|
||||
/* Ignore the interrupt if the pen was already up (CONTACT_NONE ==
|
||||
* pen up and already reported; CONTACT_UP == pen up, but not
|
||||
* reported)
|
||||
*/
|
||||
|
||||
if (priv->sample.contact == CONTACT_NONE ||
|
||||
@ -571,8 +590,8 @@ static void ads7843e_worker(FAR void *arg)
|
||||
}
|
||||
|
||||
/* It is a pen down event. If the last loss-of-contact event has not been
|
||||
* processed yet, then we have to ignore the pen down event (or else it will
|
||||
* look like a drag event)
|
||||
* processed yet, then we have to ignore the pen down event (or else it
|
||||
* will look like a drag event)
|
||||
*/
|
||||
|
||||
else if (priv->sample.contact == CONTACT_UP)
|
||||
@ -603,17 +622,23 @@ static void ads7843e_worker(FAR void *arg)
|
||||
|
||||
add_ui_randomness((x << 16) | y);
|
||||
|
||||
/* Perform a thresholding operation so that the results will be more stable.
|
||||
* If the difference from the last sample is small, then ignore the event.
|
||||
* REVISIT: Should a large change in pressure also generate a event?
|
||||
/* Perform a thresholding operation so that the results will be more
|
||||
* stable. If the difference from the last sample is small, then
|
||||
* ignore the event. REVISIT: Should a large change in pressure also
|
||||
* generate a event?
|
||||
*/
|
||||
|
||||
xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x);
|
||||
ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y);
|
||||
xdiff = x > priv->threshx ?
|
||||
(x - priv->threshx) :
|
||||
(priv->threshx - x);
|
||||
ydiff = y > priv->threshy ?
|
||||
(y - priv->threshy) :
|
||||
(priv->threshy - y);
|
||||
|
||||
/* Continue to sample the position while the pen is down */
|
||||
|
||||
wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv);
|
||||
wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1,
|
||||
(uint32_t)priv);
|
||||
|
||||
/* Check the thresholds. Bail if there is no significant difference */
|
||||
|
||||
@ -819,7 +844,8 @@ static int ads7843e_close(FAR struct file *filep)
|
||||
* Name: ads7843e_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct ads7843e_dev_s *priv;
|
||||
@ -908,7 +934,8 @@ static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t le
|
||||
|
||||
if (sample.valid)
|
||||
{
|
||||
report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -919,13 +946,15 @@ static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t le
|
||||
{
|
||||
/* First contact */
|
||||
|
||||
report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
else /* if (sample->contact == CONTACT_MOVE) */
|
||||
{
|
||||
/* Movement of the same contact */
|
||||
|
||||
report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
|
||||
iinfo(" id: %d\n", report->point[0].id);
|
||||
@ -1126,7 +1155,8 @@ int ads7843e_register(FAR struct spi_dev_s *spi,
|
||||
#ifndef CONFIG_ADS7843E_MULTIPLE
|
||||
priv = &g_ads7843e;
|
||||
#else
|
||||
priv = (FAR struct ads7843e_dev_s *)kmm_malloc(sizeof(struct ads7843e_dev_s));
|
||||
priv = (FAR struct ads7843e_dev_s *)
|
||||
kmm_malloc(sizeof(struct ads7843e_dev_s));
|
||||
if (!priv)
|
||||
{
|
||||
ierr("ERROR: kmm_malloc(%d) failed\n", sizeof(struct ads7843e_dev_s));
|
||||
|
@ -214,8 +214,8 @@ struct mbr3108_dev_s
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
*****************************************************************************/
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int mbr3108_open(FAR struct file *filep);
|
||||
static int mbr3108_close(FAR struct file *filep);
|
||||
@ -227,8 +227,8 @@ static int mbr3108_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations g_mbr3108_fileops =
|
||||
{
|
||||
@ -242,8 +242,8 @@ static const struct file_operations g_mbr3108_fileops =
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int mbr3108_i2c_write(FAR struct mbr3108_dev_s *dev, uint8_t reg,
|
||||
const uint8_t *buf, size_t buflen)
|
||||
@ -265,11 +265,13 @@ static int mbr3108_i2c_write(FAR struct mbr3108_dev_s *dev, uint8_t reg,
|
||||
.length = buflen
|
||||
}
|
||||
};
|
||||
|
||||
int ret = -EIO;
|
||||
int retries;
|
||||
|
||||
/* MBR3108 will respond with NACK to address when in low-power mode. Host
|
||||
* needs to retry address selection multiple times to get MBR3108 to wake-up.
|
||||
* needs to retry address selection multiple times to get MBR3108 to
|
||||
* wake-up.
|
||||
*/
|
||||
|
||||
for (retries = 0; retries < MBR3108_I2C_RETRIES; retries++)
|
||||
@ -317,11 +319,13 @@ static int mbr3108_i2c_read(FAR struct mbr3108_dev_s *dev, uint8_t reg,
|
||||
.length = buflen
|
||||
}
|
||||
};
|
||||
|
||||
int ret = -EIO;
|
||||
int retries;
|
||||
|
||||
/* MBR3108 will respond with NACK to address when in low-power mode. Host
|
||||
* needs to retry address selection multiple times to get MBR3108 to wake-up.
|
||||
* needs to retry address selection multiple times to get MBR3108 to
|
||||
* wake-up.
|
||||
*/
|
||||
|
||||
for (retries = 0; retries < MBR3108_I2C_RETRIES; retries++)
|
||||
@ -371,7 +375,9 @@ static int mbr3108_check_cmd_status(FAR struct mbr3108_dev_s *dev)
|
||||
const uint8_t start_reg = MBR3108_CTRL_CMD;
|
||||
const uint8_t last_reg = MBR3108_CTRL_CMD_ERR;
|
||||
uint8_t readbuf[MBR3108_CTRL_CMD_ERR - MBR3108_CTRL_CMD + 1];
|
||||
uint8_t cmd, cmd_status, cmd_err;
|
||||
uint8_t cmd;
|
||||
uint8_t cmd_status;
|
||||
uint8_t cmd_err;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(last_reg - start_reg + 1 == sizeof(readbuf));
|
||||
@ -483,7 +489,8 @@ static int mbr3108_clear_latched(FAR struct mbr3108_dev_s *dev)
|
||||
ret = mbr3108_i2c_write(dev, reg, &cmd, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
mbr3108_dbg("MBR3108_CTRL_CMD:MBR3108_CMD_CLEAR_LATCHED write failed.\n");
|
||||
mbr3108_dbg("MBR3108_CTRL_CMD: "
|
||||
"MBR3108_CMD_CLEAR_LATCHED write failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -526,8 +533,9 @@ static int mbr3108_debug_setup(FAR struct mbr3108_dev_s *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbr3108_device_configuration(FAR struct mbr3108_dev_s *dev,
|
||||
FAR const struct mbr3108_sensor_conf_s *conf)
|
||||
static int
|
||||
mbr3108_device_configuration(FAR struct mbr3108_dev_s *dev,
|
||||
FAR const struct mbr3108_sensor_conf_s *conf)
|
||||
{
|
||||
const uint8_t start_reg = MBR3108_SENSOR_EN;
|
||||
const uint8_t last_reg = MBR3108_CONFIG_CRC + 1;
|
||||
@ -580,7 +588,10 @@ static int mbr3108_device_configuration(FAR struct mbr3108_dev_s *dev,
|
||||
static int mbr3108_get_sensor_status(FAR struct mbr3108_dev_s *dev,
|
||||
FAR void *buf)
|
||||
{
|
||||
struct mbr3108_sensor_status_s status = {};
|
||||
struct mbr3108_sensor_status_s status =
|
||||
{
|
||||
};
|
||||
|
||||
const uint8_t start_reg = MBR3108_BUTTON_STAT;
|
||||
const uint8_t last_reg = MBR3108_LATCHED_PROX_STAT;
|
||||
uint8_t readbuf[MBR3108_LATCHED_PROX_STAT - MBR3108_BUTTON_STAT + 1];
|
||||
@ -588,7 +599,7 @@ static int mbr3108_get_sensor_status(FAR struct mbr3108_dev_s *dev,
|
||||
|
||||
DEBUGASSERT(last_reg - start_reg + 1 == sizeof(readbuf));
|
||||
|
||||
/* Attempt to sensor status registers.*/
|
||||
/* Attempt to sensor status registers. */
|
||||
|
||||
ret = mbr3108_i2c_read(dev, start_reg, readbuf, sizeof(readbuf));
|
||||
if (ret < 0)
|
||||
@ -598,14 +609,17 @@ static int mbr3108_get_sensor_status(FAR struct mbr3108_dev_s *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
status.button = (readbuf[MBR3108_BUTTON_STAT + 0 - start_reg]) |
|
||||
(readbuf[MBR3108_BUTTON_STAT + 1 - start_reg] << 8);
|
||||
status.proximity = readbuf[MBR3108_PROX_STAT - start_reg];
|
||||
status.button =
|
||||
(readbuf[MBR3108_BUTTON_STAT + 0 - start_reg]) |
|
||||
(readbuf[MBR3108_BUTTON_STAT + 1 - start_reg] << 8);
|
||||
status.proximity =
|
||||
readbuf[MBR3108_PROX_STAT - start_reg];
|
||||
|
||||
status.latched_button =
|
||||
(readbuf[MBR3108_LATCHED_BUTTON_STAT + 0 - start_reg]) |
|
||||
(readbuf[MBR3108_LATCHED_BUTTON_STAT + 1 - start_reg] << 8);
|
||||
status.latched_proximity = readbuf[MBR3108_LATCHED_PROX_STAT - start_reg];
|
||||
status.latched_button =
|
||||
(readbuf[MBR3108_LATCHED_BUTTON_STAT + 0 - start_reg]) |
|
||||
(readbuf[MBR3108_LATCHED_BUTTON_STAT + 1 - start_reg] << 8);
|
||||
status.latched_proximity =
|
||||
readbuf[MBR3108_LATCHED_PROX_STAT - start_reg];
|
||||
|
||||
memcpy(buf, &status, sizeof(status));
|
||||
|
||||
@ -619,13 +633,17 @@ static int mbr3108_get_sensor_status(FAR struct mbr3108_dev_s *dev,
|
||||
static int mbr3108_get_sensor_debug_data(FAR struct mbr3108_dev_s *dev,
|
||||
FAR void *buf)
|
||||
{
|
||||
struct mbr3108_sensor_debug_s data = {};
|
||||
struct mbr3108_sensor_debug_s data =
|
||||
{
|
||||
};
|
||||
|
||||
const uint8_t start_reg = MBR3108_SYNC_COUNTER1;
|
||||
const uint8_t last_reg = MBR3108_SYNC_COUNTER2;
|
||||
uint8_t readbuf[MBR3108_SYNC_COUNTER2 - MBR3108_SYNC_COUNTER1 + 1];
|
||||
uint8_t sync1;
|
||||
uint8_t sync2;
|
||||
int ret;
|
||||
int retries;
|
||||
uint8_t sync1, sync2;
|
||||
|
||||
DEBUGASSERT(last_reg - start_reg + 1 == sizeof(readbuf));
|
||||
|
||||
@ -692,7 +710,9 @@ static int mbr3108_probe_device(FAR struct mbr3108_dev_s *dev)
|
||||
|
||||
DEBUGASSERT(last_reg - start_reg + 1 == sizeof(readbuf));
|
||||
|
||||
/* Attempt to read device identification registers with multi-byte read.*/
|
||||
/* Attempt to read device identification registers with multi-byte
|
||||
* read.
|
||||
*/
|
||||
|
||||
ret = mbr3108_i2c_read(dev, start_reg, readbuf, sizeof(readbuf));
|
||||
if (ret < 0)
|
||||
@ -719,11 +739,11 @@ static int mbr3108_probe_device(FAR struct mbr3108_dev_s *dev)
|
||||
dev_rev != MBR3108_EXPECTED_DEVICE_REV)
|
||||
{
|
||||
mbr3108_dbg("Probe failed, dev-id mismatch!\n");
|
||||
mbr3108_dbg(
|
||||
" Expected: family_id: 0x%02x, device_id: 0x%04x, device_rev: %d\n",
|
||||
MBR3108_EXPECTED_FAMILY_ID,
|
||||
MBR3108_EXPECTED_DEVICE_ID,
|
||||
MBR3108_EXPECTED_DEVICE_REV);
|
||||
mbr3108_dbg(" Expected: family_id: 0x%02x, device_id: "
|
||||
"0x%04x, device_rev: %d\n",
|
||||
MBR3108_EXPECTED_FAMILY_ID,
|
||||
MBR3108_EXPECTED_DEVICE_ID,
|
||||
MBR3108_EXPECTED_DEVICE_REV);
|
||||
|
||||
return -ENXIO;
|
||||
}
|
||||
@ -874,7 +894,11 @@ static int mbr3108_open(FAR struct file *filep)
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
priv = inode->i_private;
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
use_count = priv->cref + 1;
|
||||
if (use_count == 1)
|
||||
@ -936,6 +960,7 @@ static int mbr3108_close(FAR struct file *filep)
|
||||
FAR struct inode *inode;
|
||||
FAR struct mbr3108_dev_s *priv;
|
||||
int use_count;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep);
|
||||
inode = filep->f_inode;
|
||||
@ -943,7 +968,11 @@ static int mbr3108_close(FAR struct file *filep)
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
priv = inode->i_private;
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
use_count = priv->cref - 1;
|
||||
if (use_count == 0)
|
||||
@ -1025,8 +1054,8 @@ static int mbr3108_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* This is a request to set up the poll. Find an available slot for the
|
||||
* poll structure reference.
|
||||
/* This is a request to set up the poll. Find an available slot for
|
||||
* the poll structure reference.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_INPUT_CYPRESS_MBR3108_NPOLLWAITERS; i++)
|
||||
|
@ -90,6 +90,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/* Driver support ***********************************************************/
|
||||
|
||||
/* This format is used to construct the /dev/input[n] device driver path. It
|
||||
* defined here so that it will be used consistently in all places.
|
||||
*/
|
||||
@ -118,16 +119,16 @@ struct ft5x06_dev_s
|
||||
* has been opened */
|
||||
uint8_t nwaiters; /* Number of threads waiting for
|
||||
* FT5x06 data */
|
||||
volatile bool valid; /* True: New, valid touch data in
|
||||
* touchbuf[] */
|
||||
volatile bool valid; /* True: New, valid touch data
|
||||
* in touchbuf[] */
|
||||
#ifdef CONFIG_FT5X06_SINGLEPOINT
|
||||
uint8_t lastid; /* Last reported touch id */
|
||||
uint8_t lastevent; /* Last reported event */
|
||||
int16_t lastx; /* Last reported X position */
|
||||
int16_t lasty; /* Last reported Y position */
|
||||
#endif
|
||||
sem_t devsem; /* Manages exclusive access to this
|
||||
* structure */
|
||||
sem_t devsem; /* Manages exclusive access to
|
||||
* this structure */
|
||||
sem_t waitsem; /* Used to wait for the
|
||||
* availability of data */
|
||||
uint32_t frequency; /* Current I2C frequency */
|
||||
@ -137,12 +138,12 @@ struct ft5x06_dev_s
|
||||
|
||||
FAR const struct ft5x06_config_s *config; /* Board configuration data */
|
||||
FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */
|
||||
struct work_s work; /* Supports the interrupt handling
|
||||
* "bottom half" */
|
||||
struct work_s work; /* Supports the interrupt
|
||||
* handling "bottom half" */
|
||||
#ifdef CONFIG_FT5X06_POLLMODE
|
||||
WDOG_ID polltimer; /* Poll timer */
|
||||
#endif
|
||||
uint8_t touchbuf[FT5x06_TOUCH_DATA_LEN]; /* Raw touch data */
|
||||
uint8_t touchbuf[FT5X06_TOUCH_DATA_LEN]; /* Raw touch data */
|
||||
|
||||
/* The following is a list if poll structures of threads waiting for
|
||||
* driver events. The 'struct pollfd' reference for each open is also
|
||||
@ -205,10 +206,10 @@ static const struct file_operations ft5x06_fops =
|
||||
|
||||
static const uint8_t g_event_map[4] =
|
||||
{
|
||||
(TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5x06_DOWN */
|
||||
(TOUCH_UP | TOUCH_ID_VALID), /* FT5x06_UP */
|
||||
(TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5x06_CONTACT */
|
||||
TOUCH_ID_VALID /* FT5x06_INVALID */
|
||||
(TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5X06_DOWN */
|
||||
(TOUCH_UP | TOUCH_ID_VALID), /* FT5X06_UP */
|
||||
(TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5X06_CONTACT */
|
||||
TOUCH_ID_VALID /* FT5X06_INVALID */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -236,10 +237,10 @@ static void ft5x06_notify(FAR struct ft5x06_dev_s *priv)
|
||||
nxsem_post(&priv->waitsem);
|
||||
}
|
||||
|
||||
/* If there are threads waiting on poll() for FT5x06 data to become available,
|
||||
* then wake them up now. NOTE: we wake up all waiting threads because we
|
||||
* do not know that they are going to do. If they all try to read the data,
|
||||
* then some make end up blocking after all.
|
||||
/* If there are threads waiting on poll() for FT5x06 data to become
|
||||
* available, then wake them up now. NOTE: we wake up all waiting threads
|
||||
* because we do not know that they are going to do. If they all try to
|
||||
* read the data, then some make end up blocking after all.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_FT5X06_NPOLLWAITERS; i++)
|
||||
@ -276,12 +277,23 @@ static void ft5x06_data_worker(FAR void *arg)
|
||||
* corrupt any read operation that is in place.
|
||||
*/
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
do
|
||||
{
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
|
||||
/* This would only fail if something canceled the worker thread?
|
||||
* That is not expected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
/* Read touch data */
|
||||
|
||||
/* Set up the address write operation */
|
||||
|
||||
regaddr = FT5x06_TOUCH_DATA_STARTREG;
|
||||
regaddr = FT5X06_TOUCH_DATA_STARTREG;
|
||||
|
||||
msg[0].frequency = priv->frequency; /* I2C frequency */
|
||||
msg[0].addr = config->address; /* 7-bit address */
|
||||
@ -300,7 +312,7 @@ static void ft5x06_data_worker(FAR void *arg)
|
||||
msg[1].addr = config->address; /* 7-bit address */
|
||||
msg[1].flags = I2C_M_READ; /* Read transaction with Re-START */
|
||||
msg[1].buffer = priv->touchbuf; /* Read all touch data */
|
||||
msg[1].length = FT5x06_TOUCH_DATA_LEN;
|
||||
msg[1].length = FT5X06_TOUCH_DATA_LEN;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret >= 0)
|
||||
@ -320,7 +332,7 @@ static void ft5x06_data_worker(FAR void *arg)
|
||||
* would save a context switch.
|
||||
*/
|
||||
|
||||
if (sample->tdstatus <= FT5x06_MAX_TOUCHES)
|
||||
if (sample->tdstatus <= FT5X06_MAX_TOUCHES)
|
||||
{
|
||||
/* Notify any waiters that new FT5x06 data is available */
|
||||
|
||||
@ -331,7 +343,7 @@ static void ft5x06_data_worker(FAR void *arg)
|
||||
#ifdef CONFIG_FT5X06_POLLMODE
|
||||
/* Update the poll rate */
|
||||
|
||||
if (sample->tdstatus > 0 && sample->tdstatus <= FT5x06_MAX_TOUCHES)
|
||||
if (sample->tdstatus > 0 && sample->tdstatus <= FT5X06_MAX_TOUCHES)
|
||||
{
|
||||
/* Keep it at the minimum if touches are detected. */
|
||||
|
||||
@ -469,9 +481,9 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||
event = TOUCH_POINT_GET_EVENT(touch[0]);
|
||||
id = TOUCH_POINT_GET_ID(touch[0]);
|
||||
|
||||
if (event == FT5x06_INVALID)
|
||||
if (event == FT5X06_INVALID)
|
||||
{
|
||||
priv->lastevent = FT5x06_INVALID;
|
||||
priv->lastevent = FT5X06_INVALID;
|
||||
goto reset_and_drop;
|
||||
}
|
||||
|
||||
@ -479,7 +491,7 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||
{
|
||||
/* Same ID and event.. Is there positional data? */
|
||||
|
||||
if (raw->tdstatus == 0 || event == FT5x06_UP)
|
||||
if (raw->tdstatus == 0 || event == FT5X06_UP)
|
||||
{
|
||||
/* No... no new touch data */
|
||||
|
||||
@ -579,7 +591,7 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
|
||||
/* Decode number of touches */
|
||||
|
||||
ntouches = raw->tdstatus;
|
||||
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
|
||||
DEBUGASSERT(ntouches <= FT5X06_MAX_TOUCHES);
|
||||
|
||||
if (ntouches > maxtouches)
|
||||
{
|
||||
@ -671,8 +683,8 @@ static ssize_t ft5x06_waitsample(FAR struct ft5x06_dev_s *priv,
|
||||
}
|
||||
|
||||
/* Re-acquire the semaphore that manages mutually exclusive access to
|
||||
* the device structure. We may have to wait here. But we have our sample.
|
||||
* Interrupts and pre-emption will be re-enabled while we wait.
|
||||
* the device structure. We may have to wait here. But we have our
|
||||
* sample. Interrupts and pre-emption will be re-enabled while we wait.
|
||||
*/
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
@ -718,8 +730,8 @@ static int ft5x06_bringup(FAR struct ft5x06_dev_s *priv)
|
||||
|
||||
/* Set device mode to normal operation */
|
||||
|
||||
data[0] = FT5x06_TOUCH_MODE_REG; /* Register address */
|
||||
data[1] = FT5x06_DEV_MODE_WORKING; /* Normal mode */
|
||||
data[0] = FT5X06_TOUCH_MODE_REG; /* Register address */
|
||||
data[1] = FT5X06_DEV_MODE_WORKING; /* Normal mode */
|
||||
|
||||
msg.frequency = priv->frequency; /* I2C frequency */
|
||||
msg.addr = config->address; /* 7-bit address */
|
||||
@ -861,10 +873,10 @@ static int ft5x06_close(FAR struct file *filep)
|
||||
* to the driver and it can be uninitialized.
|
||||
*/
|
||||
|
||||
if (priv->crefs == 0)
|
||||
{
|
||||
ft5x06_shutdown(priv);
|
||||
}
|
||||
if (priv->crefs == 0)
|
||||
{
|
||||
ft5x06_shutdown(priv);
|
||||
}
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
return OK;
|
||||
@ -923,7 +935,7 @@ static ssize_t ft5x06_read(FAR struct file *filep, FAR char *buffer,
|
||||
{
|
||||
ret = -EAGAIN;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for sample data */
|
||||
|
||||
|
@ -65,76 +65,77 @@
|
||||
****************************************************************************/
|
||||
|
||||
/* WARNING: Some definitions may apply only to the FT5336 */
|
||||
|
||||
/* FT5x06 maximum number of simultaneously detected touches. */
|
||||
|
||||
#define FT5x06_MAX_TOUCHES (5)
|
||||
#define FT5X06_MAX_TOUCHES (5)
|
||||
|
||||
/* FT5x06 raw touch data length. */
|
||||
|
||||
#define FT5x06_TOUCH_DATA_LEN (0x20)
|
||||
#define FT5X06_TOUCH_DATA_LEN (0x20)
|
||||
|
||||
/* FT5x06 register addresses */
|
||||
|
||||
#define FT5x06_TOUCH_MODE_REG (0x00) /* Mode register */
|
||||
#define FT5x06_TOUCH_GESTID_REG (0x01) /* Gesture ID register */
|
||||
#define FT5x06_TOUCH_STAT_REG (0x02) /* Touch data status */
|
||||
#define FT5X06_TOUCH_MODE_REG (0x00) /* Mode register */
|
||||
#define FT5X06_TOUCH_GESTID_REG (0x01) /* Gesture ID register */
|
||||
#define FT5X06_TOUCH_STAT_REG (0x02) /* Touch data status */
|
||||
/* See struct ft5x06_touch_point_s */
|
||||
#define FT5x06_TH_GROUP_REG (0x80) /* Threshold for touch detection */
|
||||
#define FT5x06_TH_DIFF_REG (0x85) /* Filter function coefficients */
|
||||
#define FT5x06_CTRL_REG (0x86) /* Control register */
|
||||
#define FT5x06_TIMEENTERMONITOR_REG (0x87) /* Time switching Active to Monitor */
|
||||
#define FT5x06_PERIODACTIVE_REG (0x88) /* Report rate in Active mode */
|
||||
#define FT5x06_PERIODMONITOR_REG (0x89) /* Report rate in Monitor mode */
|
||||
#define FT5x06_RADIAN_VALUE_REG (0x91) /* Minimum allowing angle */
|
||||
#define FT5x06_OFFSET_LEFT_RIGHT_REG (0x92) /* Minimum offset */
|
||||
#define FT5x06_OFFSET_UP_DOWN_REG (0x93) /* Maximum offset */
|
||||
#define FT5x06_DISTANCE_LEFT_RIGHT_REG (0x94) /* Minimum distance */
|
||||
#define FT5x06_DISTANCE_UP_DOWN_REG (0x95) /* Minimum distance */
|
||||
#define FT5x06_DISTANCE_ZOOM_REG (0x96) /* Maximum distance */
|
||||
#define FT5x06_LIB_VER_H_REG (0xa1) /* MS LIB version */
|
||||
#define FT5x06_LIB_VER_L_REG (0xa2) /* LS LIB version */
|
||||
#define FT5x06_CIPHER_REG (0xa3) /* Chip selecting */
|
||||
#define FT5x06_GMODE_REG (0xa4) /* Interrupt mode */
|
||||
#define FT5x06_PWR_MODE_REG (0xa5) /* Power mode */
|
||||
#define FT5x06_FIRMID_REG (0xa6) /* Firmware version */
|
||||
#define FT5x06_CHIP_ID_REG (0xa8) /* Chip ID */
|
||||
#define FT5x06_RELEASE_CODE_ID_REG (0xaf) /* Release code version */
|
||||
#define FT5x06_STATE_REG (0xbc) /* Current operating mode */
|
||||
#define FT5X06_TH_GROUP_REG (0x80) /* Threshold for touch detection */
|
||||
#define FT5X06_TH_DIFF_REG (0x85) /* Filter function coefficients */
|
||||
#define FT5X06_CTRL_REG (0x86) /* Control register */
|
||||
#define FT5X06_TIMEENTERMONITOR_REG (0x87) /* Time switching Active to Monitor */
|
||||
#define FT5X06_PERIODACTIVE_REG (0x88) /* Report rate in Active mode */
|
||||
#define FT5X06_PERIODMONITOR_REG (0x89) /* Report rate in Monitor mode */
|
||||
#define FT5X06_RADIAN_VALUE_REG (0x91) /* Minimum allowing angle */
|
||||
#define FT5X06_OFFSET_LEFT_RIGHT_REG (0x92) /* Minimum offset */
|
||||
#define FT5X06_OFFSET_UP_DOWN_REG (0x93) /* Maximum offset */
|
||||
#define FT5X06_DISTANCE_LEFT_RIGHT_REG (0x94) /* Minimum distance */
|
||||
#define FT5X06_DISTANCE_UP_DOWN_REG (0x95) /* Minimum distance */
|
||||
#define FT5X06_DISTANCE_ZOOM_REG (0x96) /* Maximum distance */
|
||||
#define FT5X06_LIB_VER_H_REG (0xa1) /* MS LIB version */
|
||||
#define FT5X06_LIB_VER_L_REG (0xa2) /* LS LIB version */
|
||||
#define FT5X06_CIPHER_REG (0xa3) /* Chip selecting */
|
||||
#define FT5X06_GMODE_REG (0xa4) /* Interrupt mode */
|
||||
#define FT5X06_PWR_MODE_REG (0xa5) /* Power mode */
|
||||
#define FT5X06_FIRMID_REG (0xa6) /* Firmware version */
|
||||
#define FT5X06_CHIP_ID_REG (0xa8) /* Chip ID */
|
||||
#define FT5X06_RELEASE_CODE_ID_REG (0xaf) /* Release code version */
|
||||
#define FT5X06_STATE_REG (0xbc) /* Current operating mode */
|
||||
|
||||
#define FT5x06_TOUCH_DATA_STARTREG (1) /* Address where data begins */
|
||||
#define FT5X06_TOUCH_DATA_STARTREG (1) /* Address where data begins */
|
||||
|
||||
/* Possible values of the DEV_MODE register */
|
||||
|
||||
#define FT5x06_DEV_MODE_WORKING (0x00)
|
||||
#define FT5x06_DEV_MODE_FACTORY (0x04)
|
||||
#define FT5X06_DEV_MODE_WORKING (0x00)
|
||||
#define FT5X06_DEV_MODE_FACTORY (0x04)
|
||||
|
||||
/* Possible values of the GEST_ID register */
|
||||
|
||||
#define FT5x06_GEST_ID_NO_GESTURE (0x00)
|
||||
#define FT5x06_GEST_ID_MOVE_UP (0x10)
|
||||
#define FT5x06_GEST_ID_MOVE_RIGHT (0x14)
|
||||
#define FT5x06_GEST_ID_MOVE_DOWN (0x18)
|
||||
#define FT5x06_GEST_ID_MOVE_LEFT (0x1C)
|
||||
#define FT5x06_GEST_ID_SINGLE_CLICK (0x20)
|
||||
#define FT5x06_GEST_ID_DOUBLE_CLICK (0x22)
|
||||
#define FT5x06_GEST_ID_ROTATE_CLOCKWISE (0x28)
|
||||
#define FT5x06_GEST_ID_ROTATE_C_CLOCKWISE (0x29)
|
||||
#define FT5x06_GEST_ID_ZOOM_IN (0x40)
|
||||
#define FT5x06_GEST_ID_ZOOM_OUT (0x49)
|
||||
#define FT5X06_GEST_ID_NO_GESTURE (0x00)
|
||||
#define FT5X06_GEST_ID_MOVE_UP (0x10)
|
||||
#define FT5X06_GEST_ID_MOVE_RIGHT (0x14)
|
||||
#define FT5X06_GEST_ID_MOVE_DOWN (0x18)
|
||||
#define FT5X06_GEST_ID_MOVE_LEFT (0x1c)
|
||||
#define FT5X06_GEST_ID_SINGLE_CLICK (0x20)
|
||||
#define FT5X06_GEST_ID_DOUBLE_CLICK (0x22)
|
||||
#define FT5X06_GEST_ID_ROTATE_CLOCKWISE (0x28)
|
||||
#define FT5X06_GEST_ID_ROTATE_C_CLOCKWISE (0x29)
|
||||
#define FT5X06_GEST_ID_ZOOM_IN (0x40)
|
||||
#define FT5X06_GEST_ID_ZOOM_OUT (0x49)
|
||||
|
||||
/* Values related to FT5x06_CTRL_REG */
|
||||
/* Values related to FT5X06_CTRL_REG */
|
||||
|
||||
#define FT5x06_CTRL_KEEP_ACTIVE_MODE (0x00)
|
||||
#define FT5x06_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE (0x01)
|
||||
#define FT5X06_CTRL_KEEP_ACTIVE_MODE (0x00)
|
||||
#define FT5X06_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE (0x01)
|
||||
|
||||
/* Possible values of FT5x06_GMODE_REG */
|
||||
/* Possible values of FT5X06_GMODE_REG */
|
||||
|
||||
#define FT5x06_G_MODE_INTERRUPT_POLLING (0x00)
|
||||
#define FT5x06_G_MODE_INTERRUPT_TRIGGER (0x01)
|
||||
#define FT5X06_G_MODE_INTERRUPT_POLLING (0x00)
|
||||
#define FT5X06_G_MODE_INTERRUPT_TRIGGER (0x01)
|
||||
|
||||
/* Possible values of FT5x06_CHIP_ID_REG */
|
||||
/* Possible values of FT5X06_CHIP_ID_REG */
|
||||
|
||||
#define FT5x06_ID_VALUE (0x51)
|
||||
#define FT5X06_ID_VALUE (0x51)
|
||||
|
||||
/* Operations on struct ft5x06_touch_point_s */
|
||||
|
||||
@ -149,10 +150,10 @@
|
||||
|
||||
enum touch_event_e
|
||||
{
|
||||
FT5x06_DOWN = 0, /* The state changed to touched */
|
||||
FT5x06_UP = 1, /* The state changed to not touched */
|
||||
FT5x06_CONTACT = 2, /* There is a continuous touch being detected */
|
||||
FT5x06_INVALID = 3 /* No touch information available */
|
||||
FT5X06_DOWN = 0, /* The state changed to touched */
|
||||
FT5X06_UP = 1, /* The state changed to not touched */
|
||||
FT5X06_CONTACT = 2, /* There is a continuous touch being detected */
|
||||
FT5X06_INVALID = 3 /* No touch information available */
|
||||
};
|
||||
|
||||
/* Describes on touchpoint returned by the FT5x06 */
|
||||
@ -173,7 +174,7 @@ struct ft5x06_touch_data_s
|
||||
{
|
||||
uint8_t gestid; /* Gesture ID */
|
||||
uint8_t tdstatus; /* Touch status */
|
||||
struct ft5x06_touch_point_s touch[FT5x06_MAX_TOUCHES];
|
||||
struct ft5x06_touch_point_s touch[FT5X06_MAX_TOUCHES];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -87,6 +87,7 @@
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Low-level SPI helpers */
|
||||
|
||||
static void max11802_lock(FAR struct spi_dev_s *spi);
|
||||
@ -237,7 +238,7 @@ static uint16_t max11802_sendcmd(FAR struct max11802_dev_s *priv,
|
||||
SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), false);
|
||||
|
||||
result = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1];
|
||||
*tags = result & 0xF;
|
||||
*tags = result & 0xf;
|
||||
result >>= 4; /* Get rid of tags */
|
||||
|
||||
iinfo("cmd:%02x response:%04x\n", cmd, result);
|
||||
@ -323,11 +324,11 @@ static int max11802_sample(FAR struct max11802_dev_s *priv,
|
||||
priv->id++;
|
||||
}
|
||||
else if (sample->contact == CONTACT_DOWN)
|
||||
{
|
||||
{
|
||||
/* First report -- next report will be a movement */
|
||||
|
||||
priv->sample.contact = CONTACT_MOVE;
|
||||
}
|
||||
priv->sample.contact = CONTACT_MOVE;
|
||||
}
|
||||
|
||||
priv->penchange = false;
|
||||
ret = OK;
|
||||
@ -461,7 +462,9 @@ static int max11802_schedule(FAR struct max11802_dev_s *priv)
|
||||
|
||||
static void max11802_wdog(int argc, uint32_t arg1, ...)
|
||||
{
|
||||
FAR struct max11802_dev_s *priv = (FAR struct max11802_dev_s *)((uintptr_t)arg1);
|
||||
FAR struct max11802_dev_s *priv =
|
||||
(FAR struct max11802_dev_s *)((uintptr_t)arg1);
|
||||
|
||||
max11802_schedule(priv);
|
||||
}
|
||||
|
||||
@ -478,7 +481,8 @@ static void max11802_worker(FAR void *arg)
|
||||
uint16_t xdiff;
|
||||
uint16_t ydiff;
|
||||
bool pendown;
|
||||
int tags, tags2;
|
||||
int tags;
|
||||
int tags2;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -505,7 +509,17 @@ static void max11802_worker(FAR void *arg)
|
||||
|
||||
/* Get exclusive access to the driver data structure */
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
do
|
||||
{
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
|
||||
/* This would only fail if something canceled the worker thread?
|
||||
* That is not expected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
/* Check for pen up or down by reading the PENIRQ GPIO. */
|
||||
|
||||
@ -564,11 +578,11 @@ static void max11802_worker(FAR void *arg)
|
||||
* again later.
|
||||
*/
|
||||
|
||||
iinfo("Previous pen up event still in buffer\n");
|
||||
max11802_notify(priv);
|
||||
wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,
|
||||
(uint32_t)priv);
|
||||
goto ignored;
|
||||
iinfo("Previous pen up event still in buffer\n");
|
||||
max11802_notify(priv);
|
||||
wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,
|
||||
(uint32_t)priv);
|
||||
goto ignored;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -595,7 +609,7 @@ static void max11802_worker(FAR void *arg)
|
||||
x = max11802_sendcmd(priv, MAX11802_CMD_XPOSITION, &tags);
|
||||
y = max11802_sendcmd(priv, MAX11802_CMD_YPOSITION, &tags2);
|
||||
#endif
|
||||
if (tags != 0xF && tags2 != 0xF)
|
||||
if (tags != 0xf && tags2 != 0xf)
|
||||
{
|
||||
readycount++;
|
||||
}
|
||||
@ -876,7 +890,7 @@ static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer,
|
||||
{
|
||||
ret = -EAGAIN;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for sample data */
|
||||
|
||||
@ -912,7 +926,8 @@ static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer,
|
||||
|
||||
if (sample.valid)
|
||||
{
|
||||
report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -923,13 +938,15 @@ static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer,
|
||||
{
|
||||
/* First contact */
|
||||
|
||||
report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
else /* if (sample->contact == CONTACT_MOVE) */
|
||||
{
|
||||
/* Movement of the same contact */
|
||||
|
||||
report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
|
||||
report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID |
|
||||
TOUCH_POS_VALID;
|
||||
}
|
||||
|
||||
iinfo(" id: %d\n", report->point[0].id);
|
||||
@ -1130,7 +1147,8 @@ int max11802_register(FAR struct spi_dev_s *spi,
|
||||
#ifndef CONFIG_MAX11802_MULTIPLE
|
||||
priv = &g_max11802;
|
||||
#else
|
||||
priv = (FAR struct max11802_dev_s *)kmm_malloc(sizeof(struct max11802_dev_s));
|
||||
priv = (FAR struct max11802_dev_s *)
|
||||
kmm_malloc(sizeof(struct max11802_dev_s));
|
||||
if (!priv)
|
||||
{
|
||||
ierr("ERROR: kmm_malloc(%d) failed\n", sizeof(struct max11802_dev_s));
|
||||
@ -1223,10 +1241,10 @@ int max11802_register(FAR struct spi_dev_s *spi,
|
||||
max11802_unlock(spi);
|
||||
|
||||
if (ret != MAX11802_MODE)
|
||||
{
|
||||
ierr("ERROR: max11802 mode readback failed: %02x\n", ret);
|
||||
goto errout_with_priv;
|
||||
}
|
||||
{
|
||||
ierr("ERROR: max11802 mode readback failed: %02x\n", ret);
|
||||
goto errout_with_priv;
|
||||
}
|
||||
|
||||
/* Register the device as an input device */
|
||||
|
||||
|
@ -1,35 +1,20 @@
|
||||
/****************************************************************************
|
||||
* drivers/input/mxt.c
|
||||
*
|
||||
* Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -75,7 +60,9 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Driver support ***********************************************************/
|
||||
|
||||
/* This format is used to construct the /dev/input[n] device driver path. It
|
||||
* defined here so that it will be used consistently in all places.
|
||||
*/
|
||||
@ -105,6 +92,7 @@
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This enumeration describes the state of one contact.
|
||||
*
|
||||
* |
|
||||
@ -219,6 +207,7 @@ struct mxt_dev_s
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* MXT register access */
|
||||
|
||||
static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr,
|
||||
@ -279,6 +268,7 @@ static int mxt_hwinitialize(FAR struct mxt_dev_s *priv);
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This the vtable that supports the character driver interface */
|
||||
|
||||
static const struct file_operations mxt_fops =
|
||||
@ -606,10 +596,10 @@ static void mxt_notify(FAR struct mxt_dev_s *priv)
|
||||
nxsem_post(&priv->waitsem);
|
||||
}
|
||||
|
||||
/* If there are threads waiting on poll() for maXTouch data to become available,
|
||||
* then wake them up now. NOTE: we wake up all waiting threads because we
|
||||
* do not know that they are going to do. If they all try to read the data,
|
||||
* then some make end up blocking after all.
|
||||
/* If there are threads waiting on poll() for maXTouch data to become
|
||||
* available, then wake them up now. NOTE: we wake up all waiting threads
|
||||
* because we do not know that they are going to do. If they all try to
|
||||
* read the data, then some make end up blocking after all.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_MXT_NPOLLWAITERS; i++)
|
||||
@ -708,8 +698,8 @@ static inline int mxt_waitsample(FAR struct mxt_dev_s *priv)
|
||||
}
|
||||
|
||||
/* Re-acquire the semaphore that manages mutually exclusive access to
|
||||
* the device structure. We may have to wait here. But we have our sample.
|
||||
* Interrupts and pre-emption will be re-enabled while we wait.
|
||||
* the device structure. We may have to wait here. But we have our
|
||||
* sample. Interrupts and pre-emption will be re-enabled while we wait.
|
||||
*/
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
@ -742,7 +732,7 @@ static void mxt_button_event(FAR struct mxt_dev_s *priv,
|
||||
* pressed if the corresponding bit is zero.
|
||||
*/
|
||||
|
||||
for (i = 0; i < priv->lower->nbuttons; i++)
|
||||
for (i = 0; i < priv->lower->nbuttons; i++)
|
||||
{
|
||||
uint8_t bit = (MXT_GPIO0_MASK << i);
|
||||
|
||||
@ -778,8 +768,10 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv,
|
||||
|
||||
/* Extract the 12-bit X and Y positions */
|
||||
|
||||
x = ((uint16_t)msg->body[1] << 4) | (((uint16_t)msg->body[3] >> 4) & 0x0f);
|
||||
y = ((uint16_t)msg->body[2] << 4) | (((uint16_t)msg->body[3] & 0x0f));
|
||||
x = ((uint16_t)msg->body[1] << 4) |
|
||||
(((uint16_t)msg->body[3] >> 4) & 0x0f);
|
||||
y = ((uint16_t)msg->body[2] << 4) |
|
||||
(((uint16_t)msg->body[3] & 0x0f));
|
||||
|
||||
/* Swap X/Y as necessary */
|
||||
|
||||
@ -896,8 +888,10 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv,
|
||||
* event?
|
||||
*/
|
||||
|
||||
xdiff = x > sample->lastx ? (x - sample->lastx) : (sample->lastx - x);
|
||||
ydiff = y > sample->lasty ? (y - sample->lasty) : (sample->lasty - y);
|
||||
xdiff = x > sample->lastx ? (x - sample->lastx) :
|
||||
(sample->lastx - x);
|
||||
ydiff = y > sample->lasty ? (y - sample->lasty) :
|
||||
(sample->lasty - y);
|
||||
|
||||
/* Check the thresholds */
|
||||
|
||||
@ -983,7 +977,17 @@ static void mxt_worker(FAR void *arg)
|
||||
|
||||
/* Get exclusive access to the MXT driver data structure */
|
||||
|
||||
nxsem_wait_uninterruptible(&priv->devsem);
|
||||
do
|
||||
{
|
||||
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||
|
||||
/* This would only fail if something canceled the worker thread?
|
||||
* That is not expected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
/* Loop, processing each message from the maXTouch */
|
||||
|
||||
@ -1040,15 +1044,18 @@ static void mxt_worker(FAR void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 0xff marks the end of the messages; any other message IDs are ignored
|
||||
* (after complaining a little).
|
||||
/* 0xff marks the end of the messages; any other message IDs are
|
||||
* ignored (after complaining a little).
|
||||
*/
|
||||
|
||||
else if (msg.id != 0xff)
|
||||
{
|
||||
iinfo("Ignored: id=%u message={%02x %02x %02x %02x %02x %02x %02x}\n",
|
||||
msg.id, msg.body[0], msg.body[1], msg.body[2], msg.body[3],
|
||||
msg.body[4], msg.body[5], msg.body[6]);
|
||||
iinfo("Ignored: id=%u message="
|
||||
"{%02x %02x %02x %02x %02x %02x %02x}\n",
|
||||
msg.id,
|
||||
msg.body[0], msg.body[1], msg.body[2],
|
||||
msg.body[3], msg.body[4], msg.body[5],
|
||||
msg.body[6]);
|
||||
|
||||
retries++;
|
||||
}
|
||||
@ -1056,6 +1063,7 @@ static void mxt_worker(FAR void *arg)
|
||||
while (id != 0xff && retries < 16);
|
||||
|
||||
errout_with_semaphore:
|
||||
|
||||
/* Release our lock on the MXT device */
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
@ -1294,7 +1302,7 @@ static ssize_t mxt_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
{
|
||||
ret = -EAGAIN;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for sample data */
|
||||
|
||||
@ -1354,7 +1362,8 @@ static ssize_t mxt_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
|
||||
if (ncontacts > 0)
|
||||
{
|
||||
FAR struct touch_sample_s *report = (FAR struct touch_sample_s *)buffer;
|
||||
FAR struct touch_sample_s *report =
|
||||
(FAR struct touch_sample_s *)buffer;
|
||||
|
||||
/* Yes, copy the sample data into the user buffer */
|
||||
|
||||
@ -1442,8 +1451,9 @@ static ssize_t mxt_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
|
||||
sample->contact = CONTACT_REPORT;
|
||||
|
||||
/* A pressure measurement of zero means that pressure is not
|
||||
* available */
|
||||
/* A pressure measurement of zero means that pressure is
|
||||
* not available.
|
||||
*/
|
||||
|
||||
if (point->pressure != 0)
|
||||
{
|
||||
@ -1780,8 +1790,8 @@ static int mxt_hwinitialize(FAR struct mxt_dev_s *priv)
|
||||
info->ysize = regval;
|
||||
|
||||
iinfo("Family: %u variant: %u version: %u.%u.%02x\n",
|
||||
info->family, info->variant, info->version >> 4, info->version & 0x0f,
|
||||
info->build);
|
||||
info->family, info->variant, info->version >> 4,
|
||||
info->version & 0x0f, info->build);
|
||||
iinfo("Matrix size: (%u,%u) objects: %u\n",
|
||||
info->xsize, info->ysize, info->nobjects);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user