This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit bc718c605d2742bb3e5ac2683be5ead5260e1c39
Author: yangyalei <[email protected]>
AuthorDate: Mon Jul 21 19:52:35 2025 +0800

    nuttx/audio: Add audio_poll
    
    support poll notify read/write enable
    
    Signed-off-by: yangyalei <[email protected]>
---
 audio/audio.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 828ed5d80af..d9153693f21 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -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 */

Reply via email to