You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/04/16 18:50:21 UTC

[incubator-nuttx] 05/06: boards: cxd56: enable Nuttx audio driver

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

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

commit 5fb835b1df38cc3151f1c6cd2245fb6b20c36db6
Author: Tobias Johansson <to...@sony.com>
AuthorDate: Tue Apr 7 07:50:38 2020 +0200

    boards: cxd56: enable Nuttx audio driver
    
    Adds an initial Nuttx audio driver supporting the Spresense CXD56.
    Being a work in progress the driver has a number of limitations:
    - Audio playback only, no recording yet.
    - Only 16 bit stereo playback is supported.
    - In practice only 48kHz playback is supported due to missing SRC.
---
 boards/arm/cxd56xx/common/src/Make.defs            |  4 ++
 boards/arm/cxd56xx/common/src/cxd56_audio.c        | 62 +++++++++++++++++++++-
 boards/arm/cxd56xx/spresense/include/cxd56_audio.h | 11 ++++
 boards/arm/cxd56xx/spresense/src/cxd56_bringup.c   |  9 ++++
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/boards/arm/cxd56xx/common/src/Make.defs b/boards/arm/cxd56xx/common/src/Make.defs
index ba10e21..5b427b1 100644
--- a/boards/arm/cxd56xx/common/src/Make.defs
+++ b/boards/arm/cxd56xx/common/src/Make.defs
@@ -34,6 +34,10 @@
 
 CSRCS += cxd56_boot.c
 
+ifeq ($(CONFIG_AUDIO_CXD56), y)
+CSRCS += cxd56_audio.c
+endif
+
 ifeq ($(CONFIG_CXD56_AUDIO), y)
 CSRCS += cxd56_audio.c
 endif
diff --git a/boards/arm/cxd56xx/common/src/cxd56_audio.c b/boards/arm/cxd56xx/common/src/cxd56_audio.c
index 58ccb66..0b90945 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_audio.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_audio.c
@@ -47,6 +47,9 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
+#include <nuttx/audio/audio.h>
+#include <nuttx/audio/cxd56.h>
+#include <nuttx/audio/pcm.h>
 #include <nuttx/signal.h>
 #include <arch/chip/audio.h>
 
@@ -216,6 +219,7 @@ int board_aca_power_control(int target, bool en)
           board_power_control(POWER_AUDIO_AVDD, true);
           avdd_on = true;
         }
+
       if (!dvdd_on && (target & CXD5247_DVDD))
         {
           board_power_control(POWER_AUDIO_DVDD, true);
@@ -242,12 +246,14 @@ int board_aca_power_control(int target, bool en)
           board_power_control(POWER_AUDIO_AVDD, false);
           avdd_on = false;
         }
+
       if (dvdd_on && (target & CXD5247_DVDD))
         {
           board_power_control(POWER_AUDIO_DVDD, false);
           dvdd_on = false;
         }
     }
+
   return ret;
 }
 
@@ -268,6 +274,7 @@ bool board_aca_power_monitor(int target)
     {
       avdd_stat = board_power_monitor(POWER_AUDIO_AVDD);
     }
+
   if (target & CXD5247_DVDD)
     {
       dvdd_stat = board_power_monitor(POWER_AUDIO_DVDD);
@@ -277,7 +284,7 @@ bool board_aca_power_monitor(int target)
 }
 
 #define MUTE_OFF_DELAY  (1250 * 1000) /* ms */
-#define MUTE_ON_DELAY   (150 * 1000) /* ms */
+#define MUTE_ON_DELAY   (150 * 1000)  /* ms */
 
 /****************************************************************************
  * Name: board_external_amp_mute_control
@@ -460,3 +467,56 @@ void board_audio_finalize(void)
 
   board_audio_i2s_disable();
 }
+
+/****************************************************************************
+ * Name: board_audio_initialize_driver
+ *
+ * Description:
+ *   Initialize and register the CXD56 audio driver.
+ *
+ ****************************************************************************/
+
+static struct cxd56_lower_s g_cxd56_lower;
+
+int board_audio_initialize_driver(int minor)
+{
+  FAR struct audio_lowerhalf_s *cxd56;
+  FAR struct audio_lowerhalf_s *pcm;
+  char devname[12];
+  int ret;
+
+  /* Initialize CXD56 device driver */
+
+  cxd56 = cxd56_initialize(&g_cxd56_lower);
+  if (!cxd56)
+    {
+      auderr("ERROR: Failed to initialize the CXD56 audio\n");
+
+      return -ENODEV;
+    }
+
+  /* Initialize a PCM decoder with the CXD56 instance. */
+
+  pcm = pcm_decode_initialize(cxd56);
+  if (!pcm)
+    {
+      auderr("ERROR: Failed create the PCM decoder\n");
+
+      return -ENODEV;
+    }
+
+  /* Create a device name */
+
+  snprintf(devname, 12, "pcm%d",  minor);
+
+  /* Finally, we can register the PCM/CXD56 audio device. */
+
+  ret = audio_register(devname, pcm);
+  if (ret < 0)
+    {
+      auderr("ERROR: Failed to register /dev/%s device: %d\n",
+             devname, ret);
+    }
+
+  return ret;
+}
diff --git a/boards/arm/cxd56xx/spresense/include/cxd56_audio.h b/boards/arm/cxd56xx/spresense/include/cxd56_audio.h
index 28ad54b..f9b082c 100644
--- a/boards/arm/cxd56xx/spresense/include/cxd56_audio.h
+++ b/boards/arm/cxd56xx/spresense/include/cxd56_audio.h
@@ -161,6 +161,17 @@ void board_audio_initialize(void);
 
 void board_audio_finalize(void);
 
+/****************************************************************************
+ * Name: board_audio_initialize_driver
+ *
+ * Description:
+ *   Initializes a CXD56 audio device driver node with the given number.
+ *   Used by the audio driver. Should not be used by users.
+ *
+ ****************************************************************************/
+
+int board_audio_initialize_driver(int minor);
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
index 99049d2..019d2f6 100644
--- a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
+++ b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c
@@ -176,6 +176,7 @@ static void timer_initialize(void)
       snprintf(devname, sizeof(devname), "/dev/timer%d", i);
       cxd56_timer_initialize(devname, i);
     }
+
   return;
 }
 #endif
@@ -343,6 +344,14 @@ int cxd56_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_AUDIO_CXD56
+  ret = board_audio_initialize_driver(1);
+  if (ret < 0)
+    {
+      _err("ERROR: Failed to initialize audio. %d\n", ret);
+    }
+#endif
+
 #ifdef CONFIG_VIDEO_ISX012
   ret = board_isx012_initialize(IMAGER_I2C);
   if (ret < 0)