mirror of
https://github.com/apache/nuttx.git
synced 2026-05-23 14:58:13 +08:00
nuttx/audio: Add audio_poll
support poll notify read/write enable Signed-off-by: yangyalei <yangyalei@xiaomi.com>
This commit is contained in:
+70
-2
@@ -81,6 +81,7 @@ struct audio_upperhalf_s
|
||||
uint8_t periods; /* Ap buffers number */
|
||||
FAR struct ap_buffer_s **apbs; /* Ap buffers list */
|
||||
FAR struct audio_lowerhalf_s *dev; /* lower-half state */
|
||||
FAR struct pollfd *fd; /* Poll fd */
|
||||
struct audio_status_s *status; /* lowerhalf driver status */
|
||||
struct file *usermq; /* User mode app's message queue */
|
||||
};
|
||||
@@ -102,6 +103,8 @@ static int audio_ioctl(FAR struct file *filep,
|
||||
unsigned long arg);
|
||||
static int audio_mmap(FAR struct file *filep,
|
||||
FAR struct mm_map_entry_s *map);
|
||||
static int audio_poll(FAR struct file *filep,
|
||||
FAR struct pollfd *fds, bool setup);
|
||||
static int audio_allocbuffer(FAR struct audio_upperhalf_s *upper,
|
||||
FAR struct audio_buf_desc_s * bufdesc);
|
||||
static int audio_freebuffer(FAR struct audio_upperhalf_s *upper,
|
||||
@@ -135,6 +138,8 @@ static const struct file_operations g_audioops =
|
||||
NULL, /* seek */
|
||||
audio_ioctl, /* ioctl */
|
||||
audio_mmap, /* mmap */
|
||||
NULL, /* truncate */
|
||||
audio_poll, /* poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -224,7 +229,7 @@ static int audio_close(FAR struct file *filep)
|
||||
ret = nxmutex_lock(&upper->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Decrement the references to the driver. If the reference count will
|
||||
@@ -257,7 +262,6 @@ static int audio_close(FAR struct file *filep)
|
||||
ret = OK;
|
||||
nxmutex_unlock(&upper->lock);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -826,6 +830,55 @@ static int audio_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: audio_poll
|
||||
*
|
||||
* Description:
|
||||
* Wait for framebuffer to be writable.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int audio_poll(FAR struct file *filep,
|
||||
FAR struct pollfd *fds, bool setup)
|
||||
{
|
||||
FAR struct inode *inode = filep->f_inode;
|
||||
FAR struct audio_upperhalf_s *upper = inode->i_private;
|
||||
pollevent_t eventset;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(upper != NULL);
|
||||
|
||||
flags = spin_lock_irqsave_nopreempt(&upper->spinlock);
|
||||
|
||||
if (setup)
|
||||
{
|
||||
upper->fd = fds;
|
||||
fds->priv = &upper->fd;
|
||||
|
||||
if (upper->hwptr->head - upper->hwptr->tail != upper->periods)
|
||||
{
|
||||
eventset = POLLIN | POLLOUT;
|
||||
if ((long)(priv->head - upper->status->tail) <= 0)
|
||||
{
|
||||
eventset |= POLLERR;
|
||||
}
|
||||
|
||||
poll_notify(&fds, 1, eventset);
|
||||
}
|
||||
}
|
||||
else if (fds->priv != NULL)
|
||||
{
|
||||
/* This is a request to tear down the poll. */
|
||||
|
||||
FAR struct pollfd **slot = (FAR struct pollfd **)fds->priv;
|
||||
*slot = NULL;
|
||||
fds->priv = NULL;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore_nopreempt(&upper->spinlock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: audio_allocbuffer
|
||||
*
|
||||
@@ -970,12 +1023,27 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper,
|
||||
#endif
|
||||
{
|
||||
struct audio_msg_s msg;
|
||||
pollevent_t eventset;
|
||||
irqstate_t flags;
|
||||
|
||||
audinfo("Entry\n");
|
||||
|
||||
flags = spin_lock_irqsave_nopreempt(&upper->spinlock);
|
||||
upper->status->tail++;
|
||||
if (upper->fd)
|
||||
{
|
||||
if (priv->fd > 0)
|
||||
{
|
||||
eventset = POLLIN | POLLOUT;
|
||||
if ((long)(priv->head - upper->status->tail) <= 0)
|
||||
{
|
||||
eventset |= POLLERR;
|
||||
}
|
||||
|
||||
poll_notify(&priv->fd, 1, eventset);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore_nopreempt(&upper->spinlock, flags);
|
||||
|
||||
/* Send a dequeue message to the user if a message queue is registered */
|
||||
|
||||
Reference in New Issue
Block a user