input/ajoystick: Fix the event lose between the invocation of poll
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
5af1b671b6
commit
9436a78a5f
@ -99,6 +99,7 @@ struct ajoy_open_s
|
|||||||
* driver events.
|
* driver events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool ao_pollpending;
|
||||||
FAR struct pollfd *ao_fds[CONFIG_INPUT_AJOYSTICK_NPOLLWAITERS];
|
FAR struct pollfd *ao_fds[CONFIG_INPUT_AJOYSTICK_NPOLLWAITERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,7 +175,6 @@ static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv)
|
|||||||
ajoy_buttonset_t press;
|
ajoy_buttonset_t press;
|
||||||
ajoy_buttonset_t release;
|
ajoy_buttonset_t release;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int i;
|
|
||||||
|
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
lower = priv->au_lower;
|
lower = priv->au_lower;
|
||||||
@ -193,19 +193,8 @@ static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv)
|
|||||||
|
|
||||||
for (opriv = priv->au_open; opriv; opriv = opriv->ao_flink)
|
for (opriv = priv->au_open; opriv; opriv = opriv->ao_flink)
|
||||||
{
|
{
|
||||||
/* Are there any poll waiters? */
|
press |= opriv->ao_pollevents.ap_press;
|
||||||
|
release |= opriv->ao_pollevents.ap_release;
|
||||||
for (i = 0; i < CONFIG_INPUT_AJOYSTICK_NPOLLWAITERS; i++)
|
|
||||||
{
|
|
||||||
if (opriv->ao_fds[i])
|
|
||||||
{
|
|
||||||
/* Yes.. OR in the poll event buttons */
|
|
||||||
|
|
||||||
press |= opriv->ao_pollevents.ap_press;
|
|
||||||
release |= opriv->ao_pollevents.ap_release;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OR in the signal events */
|
/* OR in the signal events */
|
||||||
|
|
||||||
@ -285,8 +274,8 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv)
|
|||||||
* newly released.
|
* newly released.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
change = sample ^ priv->au_sample;
|
change = sample ^ priv->au_sample;
|
||||||
press = change & sample;
|
press = change & sample;
|
||||||
|
|
||||||
DEBUGASSERT(lower->al_supported);
|
DEBUGASSERT(lower->al_supported);
|
||||||
release = change & (lower->al_supported(lower) & ~sample);
|
release = change & (lower->al_supported(lower) & ~sample);
|
||||||
@ -300,6 +289,8 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv)
|
|||||||
if ((press & opriv->ao_pollevents.ap_press) != 0 ||
|
if ((press & opriv->ao_pollevents.ap_press) != 0 ||
|
||||||
(release & opriv->ao_pollevents.ap_release) != 0)
|
(release & opriv->ao_pollevents.ap_release) != 0)
|
||||||
{
|
{
|
||||||
|
opriv->ao_pollpending = true;
|
||||||
|
|
||||||
/* Yes.. Notify all waiters */
|
/* Yes.. Notify all waiters */
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_INPUT_AJOYSTICK_NPOLLWAITERS; i++)
|
for (i = 0; i < CONFIG_INPUT_AJOYSTICK_NPOLLWAITERS; i++)
|
||||||
@ -385,6 +376,10 @@ static int ajoy_open(FAR struct file *filep)
|
|||||||
opriv->ao_flink = priv->au_open;
|
opriv->ao_flink = priv->au_open;
|
||||||
priv->au_open = opriv;
|
priv->au_open = opriv;
|
||||||
|
|
||||||
|
/* Enable/disable interrupt handling */
|
||||||
|
|
||||||
|
ajoy_enable(priv);
|
||||||
|
|
||||||
/* Attach the open structure to the file structure */
|
/* Attach the open structure to the file structure */
|
||||||
|
|
||||||
filep->f_priv = (FAR void *)opriv;
|
filep->f_priv = (FAR void *)opriv;
|
||||||
@ -498,11 +493,13 @@ static ssize_t ajoy_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
|
FAR struct ajoy_open_s *opriv;
|
||||||
FAR struct ajoy_upperhalf_s *priv;
|
FAR struct ajoy_upperhalf_s *priv;
|
||||||
FAR const struct ajoy_lowerhalf_s *lower;
|
FAR const struct ajoy_lowerhalf_s *lower;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(filep && filep->f_inode);
|
DEBUGASSERT(filep && filep->f_inode);
|
||||||
|
opriv = filep->f_priv;
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
DEBUGASSERT(inode->i_private);
|
DEBUGASSERT(inode->i_private);
|
||||||
priv = (FAR struct ajoy_upperhalf_s *)inode->i_private;
|
priv = (FAR struct ajoy_upperhalf_s *)inode->i_private;
|
||||||
@ -535,6 +532,7 @@ static ssize_t ajoy_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
ret = lower->al_sample(lower, (FAR struct ajoy_sample_s *)buffer);
|
ret = lower->al_sample(lower, (FAR struct ajoy_sample_s *)buffer);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
|
opriv->ao_pollpending = false;
|
||||||
ret = sizeof(struct ajoy_sample_s);
|
ret = sizeof(struct ajoy_sample_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,6 +715,19 @@ static int ajoy_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
|||||||
|
|
||||||
opriv->ao_fds[i] = fds;
|
opriv->ao_fds[i] = fds;
|
||||||
fds->priv = &opriv->ao_fds[i];
|
fds->priv = &opriv->ao_fds[i];
|
||||||
|
|
||||||
|
/* Report if the event is pending */
|
||||||
|
|
||||||
|
if (opriv->ao_pollpending)
|
||||||
|
{
|
||||||
|
fds->revents |= (fds->events & POLLIN);
|
||||||
|
if (fds->revents != 0)
|
||||||
|
{
|
||||||
|
iinfo("Report events: %02x\n", fds->revents);
|
||||||
|
nxsem_post(fds->sem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -769,7 +780,7 @@ errout_with_dusem:
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* devname - The name of the analog joystick device to be registers.
|
* devname - The name of the analog joystick device to be registers.
|
||||||
* This should be a string of the form "/priv/ajoyN" where N is the
|
* This should be a string of the form "/dev/ajoyN" where N is the
|
||||||
* minor device number.
|
* minor device number.
|
||||||
* lower - An instance of the platform-specific analog joystick lower
|
* lower - An instance of the platform-specific analog joystick lower
|
||||||
* half driver.
|
* half driver.
|
||||||
|
Loading…
Reference in New Issue
Block a user