diff --git a/configs/sama5d4-ek/include/board.h b/configs/sama5d4-ek/include/board.h index 9f3b8abef5..b1507a5d62 100644 --- a/configs/sama5d4-ek/include/board.h +++ b/configs/sama5d4-ek/include/board.h @@ -243,11 +243,26 @@ #define PIO_SSC0_TD PIO_SSC0_TD_2 -/* PCK0 is provided to the WM8904 audio CODEC via PB26 */ +/* PCK2 is provides the MCLK to the WM8904 audio CODEC via PB10 */ -#ifdef CONFIG_AUDIO_WM8904 -# define PIO_PMC_PCK0 PIO_PMC_PCK0_1 -#endif +#define PIO_PMC_PCK2 PIO_PMC_PCK2_1 + +/* PCK0 and PCK1 are not currently used, but the PCK logic wants these definitions + * anyway. The assignments here are arbitrary and will not be used (at least not + * until we implement ISI of HDMI). + * + * PIO_PMC_PCK0_1: PB26 is used by I2S with the WM8904 (AUDIO_RK0_PB26) + * PIO_PMC_PCK0_2: PD8 is the HDMI MCLK (HDMI_MCK_PD8) + * PIO_PMC_PCK0_3: PA24 is used for the LCD backlight (LCD_PWM_PA24) + * + * PIO_PMC_PCK1_1: PD31 goes to the expansion interface and is not used on-board + * (EXP_PD31). + * PIO_PMC_PCK1_2: PC24 is used for ISI data (ISI_D5) + * PIO_PMC_PCK1_3: PC4 is ISI_MCK_PC4, MCI0_CK_PC4, EXP_PC4 + */ + +#define PIO_PMC_PCK0 PIO_PMC_PCK0_2 +#define PIO_PMC_PCK1 PIO_PMC_PCK1_1 /************************************************************************************ * Assembly Language Macros diff --git a/configs/sama5d4-ek/src/sam_nsh.c b/configs/sama5d4-ek/src/sam_nsh.c index aeb4fe75ba..76ccb28245 100644 --- a/configs/sama5d4-ek/src/sam_nsh.c +++ b/configs/sama5d4-ek/src/sam_nsh.c @@ -87,7 +87,7 @@ int nsh_archinitialize(void) { #if defined(HAVE_NAND) || defined(HAVE_AT25) || defined(HAVE_HSMCI) || \ - defined(HAVE_USBHOST) || defined(HAVE_USBMONITOR) + defined(HAVE_USBHOST) || defined(HAVE_USBMONITOR) || defined(HAVE_WM8904) int ret; #endif @@ -98,7 +98,6 @@ int nsh_archinitialize(void) if (ret < 0) { message("ERROR: sam_nand_automount failed: %d\n", ret); - return ret; } #endif @@ -109,7 +108,6 @@ int nsh_archinitialize(void) if (ret < 0) { message("ERROR: sam_at25_automount failed: %d\n", ret); - return ret; } #endif @@ -122,7 +120,6 @@ int nsh_archinitialize(void) { message("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", HSMCI0_SLOTNO, HSMCI0_MINOR, ret); - return ret; } #endif @@ -134,7 +131,6 @@ int nsh_archinitialize(void) { message("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", HSMCI1_SLOTNO, HSMCI1_MINOR, ret); - return ret; } #endif #endif @@ -148,7 +144,6 @@ int nsh_archinitialize(void) if (ret != OK) { message("ERROR: Failed to initialize USB host: %d\n", ret); - return ret; } #endif @@ -158,9 +153,24 @@ int nsh_archinitialize(void) ret = usbmonitor_start(0, NULL); if (ret != OK) { - message("nsh_archinitialize: Start USB monitor: %d\n", ret); + message("ERROR: Failed to start the USB monitor: %d\n", ret); } #endif +#ifdef HAVE_WM8904 + /* Start the USB Monitor */ + + ret = sam_wm8904_initialize(0); + if (ret != OK) + { + message("ERROR: Failed to initialize WM8904 audio: %d\n", ret); + } +#endif + + /* If we got here then perhaps not all initialization was successful, but + * at least enough succeeded to bring-up NSH with perhaps reduced + * capabilities. + */ + return OK; } diff --git a/configs/sama5d4-ek/src/sam_wm8904.c b/configs/sama5d4-ek/src/sam_wm8904.c index 09ea542ffd..012d33f823 100644 --- a/configs/sama5d4-ek/src/sam_wm8904.c +++ b/configs/sama5d4-ek/src/sam_wm8904.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -220,11 +221,12 @@ static int wm8904_interrupt(int irq, FAR void *context) int sam_wm8904_initialize(int minor) { - FAR struct audio_lowerhalf_s *audio; + FAR struct audio_lowerhalf_s *wm8904; + FAR struct audio_lowerhalf_s *pcm; FAR struct i2c_dev_s *i2c; FAR struct i2s_dev_s *i2s; static bool initialized = false; - char devname[8]; + char devname[12]; int ret; auddbg("minor %d\n", minor); @@ -266,21 +268,20 @@ int sam_wm8904_initialize(int minor) * MW8904 which will return an audio interface. */ - audio = wm8904_initialize(i2c, i2s, &g_mxtinfo.lower, minor); - if (!audio) + wm8904 = wm8904_initialize(i2c, i2s, &g_mxtinfo.lower); + if (!wm8904) { auddbg("Failed to initialize the WM8904\n"); ret = -ENODEV; goto errout_with_i2s; } - /* Configure the DAC master clock. This clock is provided by PCK0 (PB26) - * that is connected to the WM8904 BCLK/GPIO4 and also drives the SSC - * TK0 input clock. + /* Configure the DAC master clock. This clock is provided by PCK2 (PB10) + * that is connected to the WM8904 MCLK. */ sam_sckc_enable(true); - (void)sam_pck_configure(PCK0, PCKSRC_SCK, BOARD_SLOWCLK_FREQUENCY); + (void)sam_pck_configure(PCK2, PCKSRC_SCK, BOARD_SLOWCLK_FREQUENCY); /* Enable the DAC master clock */ @@ -292,21 +293,37 @@ int sam_wm8904_initialize(int minor) ret = irq_attach(IRQ_INT_WM8904, wm8904_interrupt); if (ret < 0) { - auddbg("ERROR: Failed to register WM8904 device: %d\n", ret); + auddbg("ERROR: Failed to attach WM8904 interrupt: %d\n", ret); goto errout_with_audio; } + /* No we can embed the WM8904/I2C/I2S conglomerate into a PCM decoder + * instance so that we will have a PCM front end for the the WM8904 + * driver. + */ + + pcm = pcm_decode_initialize(wm8904); + if (!pcm) + { + auddbg("ERROR: Failed create the PCM decoder\n"); + ret = -ENODEV; + goto errout_with_irq; + } + /* Create a device name */ - snprintf(devname, 8, "wm8904%c", 'a' + minor); + snprintf(devname, 12, "pcm%d", minor); - /* Register the WM8904 audio device */ + /* Finally, we can register the PCM/WM8904/I2C/I2S audio device. + * + * Is anyone young enough to remember Rube Goldberg? + */ - ret = audio_register(devname, audio); + ret = audio_register(devname, pcm); if (ret < 0) { auddbg("ERROR: Failed to register /dev/%s device: %d\n", devname, ret); - goto errout_with_irq; + goto errout_with_pcm; } /* Now we are initialized */ @@ -317,9 +334,10 @@ int sam_wm8904_initialize(int minor) return OK; /* Error exits. Unfortunately there is no mechanism in place now to - * recover errors on initialization failures. + * recover from most errors on initialization failures. */ +errout_with_pcm: errout_with_irq: irq_detach(IRQ_INT_WM8904); errout_with_audio: diff --git a/configs/sama5d4-ek/src/sama5d4-ek.h b/configs/sama5d4-ek/src/sama5d4-ek.h index 5286716b5a..5e6a71d94d 100644 --- a/configs/sama5d4-ek/src/sama5d4-ek.h +++ b/configs/sama5d4-ek/src/sama5d4-ek.h @@ -334,6 +334,11 @@ # undef HAVE_WM8904 # endif +# ifndef CONFIG_AUDIO_FORMAT_PCM +# warning CONFIG_AUDIO_FORMAT_PCM is required for audio support +# undef HAVE_WM8904 +# endif + # ifndef CONFIG_SAMA5D4EK_WM8904_I2CFREQUENCY # warning Defaulting to maximum WM8904 I2C frequency # define CONFIG_SAMA5D4EK_WM8904_I2CFREQUENCY 400000