nuttx/audio: Add audio_poll

support poll notify read/write enable

Signed-off-by: yangyalei <yangyalei@xiaomi.com>
This commit is contained in:
yangyalei
2025-07-21 19:52:35 +08:00
committed by Alan C. Assis
parent 9c35b01cd8
commit bc718c605d
+70 -2
View File
@@ -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 */