qiaohaijiao commented on code in PR #8775:
URL: https://github.com/apache/nuttx/pull/8775#discussion_r1131841250


##########
drivers/audio/audio_dma.c:
##########
@@ -0,0 +1,607 @@
+/****************************************************************************
+ * drivers/audio/audio_dma.c
+ *
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/audio/audio_dma.h>
+#include <nuttx/kmalloc.h>
+#include <queue.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct audio_dma_s
+{
+  struct audio_lowerhalf_s dev;
+  struct dma_chan_s *chan;
+  uintptr_t src_addr;
+  uintptr_t dst_addr;
+  uint8_t *alloc_addr;
+  uint8_t alloc_index;
+  uint8_t fifo_width;
+  bool playback;
+  bool xrun;
+  struct dq_queue_s pendq;
+  apb_samp_t buffer_size;
+  apb_samp_t buffer_num;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int audio_dma_getcaps(struct audio_lowerhalf_s *dev, int type,
+                             struct audio_caps_s *caps);
+static int audio_dma_shutdown(struct audio_lowerhalf_s *dev);
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               void *session,
+                               const struct audio_caps_s *caps);
+static int audio_dma_start(struct audio_lowerhalf_s *dev,
+                           void *session);
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int audio_dma_stop(struct audio_lowerhalf_s *dev, void *session);
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int audio_dma_pause(struct audio_lowerhalf_s *dev,
+                           void *session);
+static int audio_dma_resume(struct audio_lowerhalf_s *dev,
+                            void *session);
+#endif
+static int audio_dma_reserve(struct audio_lowerhalf_s *dev,
+                             void **session);
+static int audio_dma_release(struct audio_lowerhalf_s *dev,
+                             void *session);
+#else
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               const struct audio_caps_s *caps);
+static int audio_dma_start(struct audio_lowerhalf_s *dev);
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int audio_dma_stop(struct audio_lowerhalf_s *dev);
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int audio_dma_pause(struct audio_lowerhalf_s *dev);
+static int audio_dma_resume(struct audio_lowerhalf_s *dev);
+#endif
+static int audio_dma_reserve(struct audio_lowerhalf_s *dev);
+static int audio_dma_release(struct audio_lowerhalf_s *dev);
+#endif
+static int audio_dma_allocbuffer(struct audio_lowerhalf_s *dev,
+                                 struct audio_buf_desc_s *bufdesc);
+static int audio_dma_freebuffer(struct audio_lowerhalf_s *dev,
+                                struct audio_buf_desc_s *bufdesc);
+static int audio_dma_enqueuebuffer(struct audio_lowerhalf_s *dev,
+                                   struct ap_buffer_s *apb);
+static int audio_dma_ioctl(struct audio_lowerhalf_s *dev, int cmd,
+                           unsigned long arg);
+static void audio_dma_callback(struct dma_chan_s *chan, void *arg,
+                               ssize_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct audio_ops_s g_audio_dma_ops =
+{
+  .getcaps = audio_dma_getcaps,
+  .configure = audio_dma_configure,
+  .shutdown = audio_dma_shutdown,
+  .start = audio_dma_start,
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+  .stop = audio_dma_stop,
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+  .pause = audio_dma_pause,
+  .resume = audio_dma_resume,
+#endif
+  .allocbuffer = audio_dma_allocbuffer,
+  .freebuffer = audio_dma_freebuffer,
+  .enqueuebuffer = audio_dma_enqueuebuffer,
+  .ioctl = audio_dma_ioctl,
+  .reserve = audio_dma_reserve,
+  .release = audio_dma_release,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int audio_dma_getcaps(struct audio_lowerhalf_s *dev, int type,
+                             struct audio_caps_s *caps)
+{
+  struct audio_dma_s *audio_dma = (struct audio_dma_s *)dev;
+
+  /* Validate the structure */
+
+  DEBUGASSERT(caps && caps->ac_len >= sizeof(struct audio_caps_s));
+  audinfo("type=%d ac_type=%d\n", type, caps->ac_type);
+
+  /* Fill in the caller's structure based on requested info */
+
+  caps->ac_format.hw  = 0;
+  caps->ac_controls.w = 0;
+
+  switch (caps->ac_type)
+    {
+      /* Caller is querying for the types of units we support */
+
+      case AUDIO_TYPE_QUERY:
+
+        /* Provide our overall capabilities.  The interfacing software
+         * must then call us back for specific info for each capability.
+         */
+
+        caps->ac_channels = 2;       /* Stereo output */
+
+        switch (caps->ac_subtype)
+          {
+            case AUDIO_TYPE_QUERY:
+
+              /* We don't decode any formats!  Only something above us in
+               * the audio stream can perform decoding on our behalf.
+               */
+
+              /* The types of audio units we implement */
+
+              if (audio_dma->playback)
+                caps->ac_controls.b[0] = AUDIO_TYPE_OUTPUT;
+              else
+                caps->ac_controls.b[0] = AUDIO_TYPE_INPUT;
+              caps->ac_format.hw = 1 << (AUDIO_FMT_PCM - 1);
+              break;
+
+            default:
+              caps->ac_controls.b[0] = AUDIO_SUBFMT_END;
+              break;
+          }
+
+        break;
+
+        /* Provide capabilities of our OUTPUT unit */
+
+      case AUDIO_TYPE_OUTPUT:
+      case AUDIO_TYPE_INPUT:
+
+        caps->ac_channels = 2;
+
+        switch (caps->ac_subtype)
+          {
+            case AUDIO_TYPE_QUERY:
+
+            /* Report the Sample rates we support */
+
+              caps->ac_controls.hw[0] = AUDIO_SAMP_RATE_8K  |
+                                        AUDIO_SAMP_RATE_11K |
+                                        AUDIO_SAMP_RATE_16K |
+                                        AUDIO_SAMP_RATE_22K |
+                                        AUDIO_SAMP_RATE_32K |
+                                        AUDIO_SAMP_RATE_44K |
+                                        AUDIO_SAMP_RATE_48K |
+                                        AUDIO_SAMP_RATE_96K |
+                                        AUDIO_SAMP_RATE_128K |
+                                        AUDIO_SAMP_RATE_160K |
+                                        AUDIO_SAMP_RATE_172K |
+                                        AUDIO_SAMP_RATE_192K;
+              break;
+          }
+
+        break;
+   }
+
+  /* Return the length of the audio_caps_s struct for validation of
+   * proper Audio device type.
+   */
+
+  return caps->ac_len;
+}
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               void *session,
+                               const struct audio_caps_s *caps)
+#else
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               const struct audio_caps_s *caps)
+#endif
+{
+  struct audio_dma_s *audio_dma = (struct audio_dma_s *)dev;
+  struct dma_config_s cfg;
+  int ret = -EINVAL;
+
+  DEBUGASSERT(audio_dma && caps);
+  audinfo("ac_type: %d\n", caps->ac_type);
+
+  /* Process the configure operation */
+
+  switch (caps->ac_type)
+    {
+      case AUDIO_TYPE_OUTPUT:
+        if (audio_dma->playback)
+          {
+            memset(&cfg, 0, sizeof(struct dma_config_s));
+            cfg.direction = DMA_MEM_TO_DEV;

Review Comment:
   It's defined in https://github.com/apache/nuttx/pull/8773.



##########
drivers/audio/audio_dma.c:
##########
@@ -0,0 +1,607 @@
+/****************************************************************************
+ * drivers/audio/audio_dma.c
+ *
+ * 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/audio/audio_dma.h>
+#include <nuttx/kmalloc.h>
+#include <queue.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct audio_dma_s
+{
+  struct audio_lowerhalf_s dev;
+  struct dma_chan_s *chan;
+  uintptr_t src_addr;
+  uintptr_t dst_addr;
+  uint8_t *alloc_addr;
+  uint8_t alloc_index;
+  uint8_t fifo_width;
+  bool playback;
+  bool xrun;
+  struct dq_queue_s pendq;
+  apb_samp_t buffer_size;
+  apb_samp_t buffer_num;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int audio_dma_getcaps(struct audio_lowerhalf_s *dev, int type,
+                             struct audio_caps_s *caps);
+static int audio_dma_shutdown(struct audio_lowerhalf_s *dev);
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               void *session,
+                               const struct audio_caps_s *caps);
+static int audio_dma_start(struct audio_lowerhalf_s *dev,
+                           void *session);
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int audio_dma_stop(struct audio_lowerhalf_s *dev, void *session);
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int audio_dma_pause(struct audio_lowerhalf_s *dev,
+                           void *session);
+static int audio_dma_resume(struct audio_lowerhalf_s *dev,
+                            void *session);
+#endif
+static int audio_dma_reserve(struct audio_lowerhalf_s *dev,
+                             void **session);
+static int audio_dma_release(struct audio_lowerhalf_s *dev,
+                             void *session);
+#else
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               const struct audio_caps_s *caps);
+static int audio_dma_start(struct audio_lowerhalf_s *dev);
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int audio_dma_stop(struct audio_lowerhalf_s *dev);
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int audio_dma_pause(struct audio_lowerhalf_s *dev);
+static int audio_dma_resume(struct audio_lowerhalf_s *dev);
+#endif
+static int audio_dma_reserve(struct audio_lowerhalf_s *dev);
+static int audio_dma_release(struct audio_lowerhalf_s *dev);
+#endif
+static int audio_dma_allocbuffer(struct audio_lowerhalf_s *dev,
+                                 struct audio_buf_desc_s *bufdesc);
+static int audio_dma_freebuffer(struct audio_lowerhalf_s *dev,
+                                struct audio_buf_desc_s *bufdesc);
+static int audio_dma_enqueuebuffer(struct audio_lowerhalf_s *dev,
+                                   struct ap_buffer_s *apb);
+static int audio_dma_ioctl(struct audio_lowerhalf_s *dev, int cmd,
+                           unsigned long arg);
+static void audio_dma_callback(struct dma_chan_s *chan, void *arg,
+                               ssize_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct audio_ops_s g_audio_dma_ops =
+{
+  .getcaps = audio_dma_getcaps,
+  .configure = audio_dma_configure,
+  .shutdown = audio_dma_shutdown,
+  .start = audio_dma_start,
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+  .stop = audio_dma_stop,
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+  .pause = audio_dma_pause,
+  .resume = audio_dma_resume,
+#endif
+  .allocbuffer = audio_dma_allocbuffer,
+  .freebuffer = audio_dma_freebuffer,
+  .enqueuebuffer = audio_dma_enqueuebuffer,
+  .ioctl = audio_dma_ioctl,
+  .reserve = audio_dma_reserve,
+  .release = audio_dma_release,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int audio_dma_getcaps(struct audio_lowerhalf_s *dev, int type,
+                             struct audio_caps_s *caps)
+{
+  struct audio_dma_s *audio_dma = (struct audio_dma_s *)dev;
+
+  /* Validate the structure */
+
+  DEBUGASSERT(caps && caps->ac_len >= sizeof(struct audio_caps_s));
+  audinfo("type=%d ac_type=%d\n", type, caps->ac_type);
+
+  /* Fill in the caller's structure based on requested info */
+
+  caps->ac_format.hw  = 0;
+  caps->ac_controls.w = 0;
+
+  switch (caps->ac_type)
+    {
+      /* Caller is querying for the types of units we support */
+
+      case AUDIO_TYPE_QUERY:
+
+        /* Provide our overall capabilities.  The interfacing software
+         * must then call us back for specific info for each capability.
+         */
+
+        caps->ac_channels = 2;       /* Stereo output */
+
+        switch (caps->ac_subtype)
+          {
+            case AUDIO_TYPE_QUERY:
+
+              /* We don't decode any formats!  Only something above us in
+               * the audio stream can perform decoding on our behalf.
+               */
+
+              /* The types of audio units we implement */
+
+              if (audio_dma->playback)
+                caps->ac_controls.b[0] = AUDIO_TYPE_OUTPUT;
+              else
+                caps->ac_controls.b[0] = AUDIO_TYPE_INPUT;
+              caps->ac_format.hw = 1 << (AUDIO_FMT_PCM - 1);
+              break;
+
+            default:
+              caps->ac_controls.b[0] = AUDIO_SUBFMT_END;
+              break;
+          }
+
+        break;
+
+        /* Provide capabilities of our OUTPUT unit */
+
+      case AUDIO_TYPE_OUTPUT:
+      case AUDIO_TYPE_INPUT:
+
+        caps->ac_channels = 2;
+
+        switch (caps->ac_subtype)
+          {
+            case AUDIO_TYPE_QUERY:
+
+            /* Report the Sample rates we support */
+
+              caps->ac_controls.hw[0] = AUDIO_SAMP_RATE_8K  |
+                                        AUDIO_SAMP_RATE_11K |
+                                        AUDIO_SAMP_RATE_16K |
+                                        AUDIO_SAMP_RATE_22K |
+                                        AUDIO_SAMP_RATE_32K |
+                                        AUDIO_SAMP_RATE_44K |
+                                        AUDIO_SAMP_RATE_48K |
+                                        AUDIO_SAMP_RATE_96K |
+                                        AUDIO_SAMP_RATE_128K |
+                                        AUDIO_SAMP_RATE_160K |
+                                        AUDIO_SAMP_RATE_172K |
+                                        AUDIO_SAMP_RATE_192K;
+              break;
+          }
+
+        break;
+   }
+
+  /* Return the length of the audio_caps_s struct for validation of
+   * proper Audio device type.
+   */
+
+  return caps->ac_len;
+}
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               void *session,
+                               const struct audio_caps_s *caps)
+#else
+static int audio_dma_configure(struct audio_lowerhalf_s *dev,
+                               const struct audio_caps_s *caps)
+#endif
+{
+  struct audio_dma_s *audio_dma = (struct audio_dma_s *)dev;
+  struct dma_config_s cfg;
+  int ret = -EINVAL;
+
+  DEBUGASSERT(audio_dma && caps);
+  audinfo("ac_type: %d\n", caps->ac_type);
+
+  /* Process the configure operation */
+
+  switch (caps->ac_type)
+    {
+      case AUDIO_TYPE_OUTPUT:
+        if (audio_dma->playback)
+          {
+            memset(&cfg, 0, sizeof(struct dma_config_s));
+            cfg.direction = DMA_MEM_TO_DEV;
+            if (audio_dma->fifo_width)
+              cfg.dst_width = audio_dma->fifo_width;
+            else
+              cfg.dst_width = caps->ac_controls.b[2] / 8;
+            ret = DMA_CONFIG(audio_dma->chan, &cfg);

Review Comment:
   It's defined in https://github.com/apache/nuttx/pull/8773.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to