add simple wm8994 codec driver
This commit is contained in:
parent
b1a042734f
commit
fbb3cd660b
@ -82,8 +82,8 @@ extern uint32_t _vectors[]; /* See stm32_vectors.S */
|
||||
* Name: stm32_mco1config
|
||||
*
|
||||
* Description:
|
||||
* Selects the clock source to output on MCO1 pin (PA8). PA8 should be configured in
|
||||
* alternate function mode.
|
||||
* Selects the clock source to output on MCO1 pin (PA8). PA8 should be configured
|
||||
* in alternate function mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* source - One of the definitions for the RCC_CFGR_MCO1 definitions from
|
||||
@ -103,7 +103,7 @@ static inline void stm32_mco1config(uint32_t source, uint32_t div)
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(STM32_RCC_CFGR);
|
||||
regval &= ~(RCC_CFGR_MCO1_MASK|RCC_CFGR_MCO1PRE_MASK);
|
||||
regval &= ~(RCC_CFGR_MCO1_MASK | RCC_CFGR_MCO1PRE_MASK);
|
||||
regval |= (source | div);
|
||||
putreg32(regval, STM32_RCC_CFGR);
|
||||
}
|
||||
@ -112,8 +112,8 @@ static inline void stm32_mco1config(uint32_t source, uint32_t div)
|
||||
* Name: stm32_mco2config
|
||||
*
|
||||
* Description:
|
||||
* Selects the clock source to output on MCO2 pin (PC9). PC9 should be configured in
|
||||
* alternate function mode.
|
||||
* Selects the clock source to output on MCO2 pin (PC9). PC9 should be configured
|
||||
* in alternate function mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* source - One of the definitions for the RCC_CFGR_MCO2 definitions from
|
||||
@ -133,7 +133,7 @@ static inline void stm32_mco2config(uint32_t source, uint32_t div)
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(STM32_RCC_CFGR);
|
||||
regval &= ~(RCC_CFGR_MCO2_MASK|RCC_CFGR_MCO2PRE_MASK);
|
||||
regval &= ~(RCC_CFGR_MCO2_MASK | RCC_CFGR_MCO2PRE_MASK);
|
||||
regval |= (source | div);
|
||||
putreg32(regval, STM32_RCC_CFGR);
|
||||
}
|
||||
@ -223,44 +223,44 @@ void stm32_clockenable(void);
|
||||
|
||||
void stm32_rcc_enablelse(void);
|
||||
|
||||
/****************************************************************************
|
||||
/************************************************************************************
|
||||
* Name: stm32_rcc_enablelsi
|
||||
*
|
||||
* Description:
|
||||
* Enable the Internal Low-Speed (LSI) RC Oscillator.
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
void stm32_rcc_enablelsi(void);
|
||||
|
||||
/****************************************************************************
|
||||
/************************************************************************************
|
||||
* Name: stm32_rcc_disablelsi
|
||||
*
|
||||
* Description:
|
||||
* Disable the Internal Low-Speed (LSI) RC Oscillator.
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
void stm32_rcc_disablelsi(void);
|
||||
|
||||
#if defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
|
||||
/****************************************************************************
|
||||
/************************************************************************************
|
||||
* Name: stm32f7x9_rcc_dsisrcphy
|
||||
*
|
||||
* Description:
|
||||
* Set DSI clock source to DSI PHY
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
void stm32f7x9_rcc_dsisrcphy(void);
|
||||
|
||||
/****************************************************************************
|
||||
/************************************************************************************
|
||||
* Name: stm32f7x9_rcc_dsisrcpllr
|
||||
*
|
||||
* Description:
|
||||
* Set DSI clock source to PLLR
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
void stm32f7x9_rcc_dsisrcpllr(void);
|
||||
#endif
|
||||
|
@ -236,10 +236,8 @@ struct stm32f7_sai_s
|
||||
|
||||
#ifdef CONFIG_DEBUG_I2S_INFO
|
||||
static void sai_dump_regs(struct stm32f7_sai_s *priv, const char *msg);
|
||||
static void rcc_dump_regs(const char *msg);
|
||||
#else
|
||||
# define sai_dump_regs(s,m)
|
||||
# define rcc_dump_regs(m)
|
||||
#endif
|
||||
|
||||
/* Semaphore helpers */
|
||||
@ -704,51 +702,6 @@ static void sai_dump_regs(struct stm32f7_sai_s *priv, const char *msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rcc_dump_regs
|
||||
*
|
||||
* Description:
|
||||
* Dump the contents of all rcc block registers
|
||||
*
|
||||
* Input Parameters:
|
||||
* msg - Message to print before the register data
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_I2S_INFO
|
||||
static void rcc_dump_regs(const char *msg)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
i2sinfo("%s\n", msg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* RCC_PLLSAICFGR */
|
||||
|
||||
uint32_t pll_sai_cfgr = getreg32(STM32_RCC_PLLSAICFGR);
|
||||
i2sinfo("PLLSAICFGR = %08x\n", pll_sai_cfgr);
|
||||
|
||||
uint32_t pllsain = (pll_sai_cfgr & RCC_PLLSAICFGR_PLLSAIN_MASK) >>
|
||||
RCC_PLLSAICFGR_PLLSAIN_SHIFT;
|
||||
i2sinfo("\t\tPLLSAICFGR PLLSAIN[14:6] = %d\n", pllsain);
|
||||
uint32_t pllsaip = (pll_sai_cfgr & RCC_PLLSAICFGR_PLLSAIP_MASK) >>
|
||||
RCC_PLLSAICFGR_PLLSAIP_SHIFT;
|
||||
i2sinfo("\t\tPLLSAICFGR PLLSAIP[17:16] = %d\n", pllsaip);
|
||||
uint32_t pllsaiq = (pll_sai_cfgr & RCC_PLLSAICFGR_PLLSAIQ_MASK) >>
|
||||
RCC_PLLSAICFGQ_PLLSAIP_SHIFT;
|
||||
i2sinfo("\t\tPLLSAICFGR PLLSAIQ[27:24] = %d\n", pllsaiq);
|
||||
|
||||
uint32_t pllsair = (pll_sai_cfgr & RCC_PLLSAICFGR_PLLSAIR_MASK) >>
|
||||
RCC_PLLSAICFGR_PLLSAIP_SHIFT;
|
||||
i2sinfo("\t\tPLLSAICFGR PLLSAIR[30:28] = %d\n", pllsair);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sai_exclsem_take
|
||||
*
|
||||
|
@ -241,7 +241,7 @@ static inline void rcc_enableahb1(void)
|
||||
|
||||
regval |= RCC_AHB1ENR_OTGHSEN;
|
||||
#endif
|
||||
#endif /* CONFIG_STM32F7_OTGFSHS */
|
||||
#endif /* CONFIG_STM32F7_OTGFSHS */
|
||||
|
||||
putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */
|
||||
}
|
||||
@ -857,7 +857,8 @@ static void stm32_stdclockconfig(void)
|
||||
|
||||
/* Wait until the PLL source is used as the system clock source */
|
||||
|
||||
while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL)
|
||||
while ((getreg32(STM32_RCC_CFGR)
|
||||
& RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1001,7 +1002,3 @@ static inline void rcc_enableperipherals(void)
|
||||
rcc_enableapb1();
|
||||
rcc_enableapb2();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
82
boards/arm/stm32f7/stm32f746g-disco/configs/audio/defconfig
Normal file
82
boards/arm/stm32f7/stm32f746g-disco/configs/audio/defconfig
Normal file
@ -0,0 +1,82 @@
|
||||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_ARCH_FPU is not set
|
||||
# CONFIG_SPI_CALLBACK is not set
|
||||
CONFIG_ARCH="arm"
|
||||
CONFIG_ARCH_BOARD="stm32f746g-disco"
|
||||
CONFIG_ARCH_BOARD_STM32F746G_DISCO=y
|
||||
CONFIG_ARCH_BUTTONS=y
|
||||
CONFIG_ARCH_CHIP="stm32f7"
|
||||
CONFIG_ARCH_CHIP_STM32F746NG=y
|
||||
CONFIG_ARCH_CHIP_STM32F7=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARMV7M_DCACHE=y
|
||||
CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
|
||||
CONFIG_ARMV7M_DTCM=y
|
||||
CONFIG_ARMV7M_ICACHE=y
|
||||
CONFIG_AUDIO_I2S=y
|
||||
CONFIG_AUDIO_WM8994=y
|
||||
CONFIG_BOARD_LATE_INITIALIZE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=43103
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_ASSERTIONS=y
|
||||
CONFIG_DEBUG_AUDIO=y
|
||||
CONFIG_DEBUG_AUDIO_ERROR=y
|
||||
CONFIG_DEBUG_AUDIO_INFO=y
|
||||
CONFIG_DEBUG_AUDIO_WARN=y
|
||||
CONFIG_DEBUG_ERROR=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_I2C=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_MEMCARD=y
|
||||
CONFIG_DEBUG_MEMCARD_ERROR=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_WARN=y
|
||||
CONFIG_DRIVERS_AUDIO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_MAX_TASKS=16
|
||||
CONFIG_MMCSD=y
|
||||
CONFIG_MM_REGIONS=3
|
||||
CONFIG_NFILE_DESCRIPTORS=8
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_LINELEN=64
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_RAM_SIZE=245760
|
||||
CONFIG_RAM_START=0x20010000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_START_DAY=6
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2011
|
||||
CONFIG_STM32F7_DMA2=y
|
||||
CONFIG_STM32F7_I2C3=y
|
||||
CONFIG_STM32F7_SAI2=y
|
||||
CONFIG_STM32F7_SAI2_A=y
|
||||
CONFIG_STM32F7_SAI2_B=y
|
||||
CONFIG_STM32F7_SAI2_B_SYNC_WITH_A=y
|
||||
CONFIG_STM32F7_USART1=y
|
||||
CONFIG_SYSLOG_CHAR=y
|
||||
CONFIG_SYSLOG_DEVPATH="/dev/ttyS0"
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_VI=y
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
CONFIG_USART1_SERIAL_CONSOLE=y
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
CONFIG_WM8994_REGDUMP=y
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
/*****************************************************************************************
|
||||
* boards/arm/stm32f7/stm32f746g-disco/include/board.h
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,14 +31,14 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
*****************************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM_STM32F7_STM32F746G_DISCO_INCLUDE_BOARD_H
|
||||
#define __BOARDS_ARM_STM32F7_STM32F746G_DISCO_INCLUDE_BOARD_H
|
||||
|
||||
/****************************************************************************
|
||||
/*****************************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
*****************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
@ -48,11 +48,11 @@
|
||||
|
||||
/* No not include STM32 F7 header files here. */
|
||||
|
||||
/****************************************************************************
|
||||
/*****************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
*****************************************************************************************/
|
||||
|
||||
/* Clocking *****************************************************************/
|
||||
/* Clocking */
|
||||
|
||||
/* The STM32F7 Discovery board provides the following clock sources:
|
||||
*
|
||||
@ -154,15 +154,22 @@
|
||||
|
||||
/* Configure factors for PLLSAI clock */
|
||||
|
||||
#define CONFIG_STM32F7_PLLSAI 1
|
||||
#define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(BOARD_LTDC_PLLSAIN)
|
||||
#define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(2)
|
||||
#define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(2)
|
||||
#define STM32_RCC_PLLSAICFGR_PLLSAIR RCC_PLLSAICFGR_PLLSAIR(BOARD_LTDC_PLLSAIR)
|
||||
|
||||
/* SAIx input frequency = 25 / M * N / Q / P
|
||||
* 25000000 / 25 * 192 / 2 / 1
|
||||
*/
|
||||
#define STM32F7_SAI1_FREQUENCY (96000000)
|
||||
#define STM32F7_SAI2_FREQUENCY (96000000)
|
||||
|
||||
/* Configure Dedicated Clock Configuration Register */
|
||||
|
||||
#define STM32_RCC_DCKCFGR1_PLLI2SDIVQ RCC_DCKCFGR1_PLLI2SDIVQ(1)
|
||||
#define STM32_RCC_DCKCFGR1_PLLSAIDIVQ RCC_DCKCFGR1_PLLSAIDIVQ(1)
|
||||
#define STM32_RCC_DCKCFGR1_PLLSAIDIVQ RCC_DCKCFGR1_PLLSAIDIVQ(0)
|
||||
#define STM32_RCC_DCKCFGR1_PLLSAIDIVR RCC_DCKCFGR1_PLLSAIDIVR(1)
|
||||
#define STM32_RCC_DCKCFGR1_SAI1SRC RCC_DCKCFGR1_SAI1SEL(0)
|
||||
#define STM32_RCC_DCKCFGR1_SAI2SRC RCC_DCKCFGR1_SAI2SEL(0)
|
||||
@ -172,6 +179,7 @@
|
||||
|
||||
/* Configure factors for PLLI2S clock */
|
||||
|
||||
#define CONFIG_STM32F7_PLLI2S 1
|
||||
#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192)
|
||||
#define STM32_RCC_PLLI2SCFGR_PLLI2SP RCC_PLLI2SCFGR_PLLI2SP(2)
|
||||
#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2)
|
||||
@ -253,7 +261,7 @@
|
||||
|
||||
#define BOARD_FLASH_WAITSTATES 7
|
||||
|
||||
/* LED definitions **********************************************************/
|
||||
/* LED definitions */
|
||||
|
||||
/* The STM32F746G-DISCO board has numerous LEDs but only one, LD1 located
|
||||
* near the reset button, that can be controlled by software (LD2 is a power
|
||||
@ -306,7 +314,7 @@
|
||||
#define LED_ASSERTION 2 /* LD1=no change */
|
||||
#define LED_PANIC 3 /* LD1=flashing */
|
||||
|
||||
/* Button definitions *******************************************************/
|
||||
/* Button definitions */
|
||||
|
||||
/* The STM32F7 Discovery supports one button:
|
||||
* Pushbutton B1, labelled "User", is connected to GPIO PI11.
|
||||
@ -317,7 +325,7 @@
|
||||
#define NUM_BUTTONS 1
|
||||
#define BUTTON_USER_BIT (1 << BUTTON_USER)
|
||||
|
||||
/* Alternate function pin selections ****************************************/
|
||||
/* Alternate function pin selections */
|
||||
|
||||
/* USART6:
|
||||
*
|
||||
@ -361,12 +369,13 @@
|
||||
|
||||
/* I2C - There is a FT5336 TouchPanel on I2C3 using these pins: */
|
||||
|
||||
#define GPIO_I2C3_SCL GPIO_I2C3_SCL_2
|
||||
#define GPIO_I2C3_SDA GPIO_I2C3_SDA_2
|
||||
#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_100MHz))
|
||||
#define GPIO_I2C3_SCL ADJ_SLEW_RATE(GPIO_I2C3_SCL_2)
|
||||
#define GPIO_I2C3_SDA ADJ_SLEW_RATE(GPIO_I2C3_SDA_2)
|
||||
|
||||
#define GPIO_TP_INT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTI|GPIO_PIN13)
|
||||
|
||||
#define FT5x06_I2C_ADDRESS 0x38
|
||||
#define FT5x06_I2C_ADDRESS (0x70 >> 1)
|
||||
|
||||
/* The STM32 F7 connects to a SMSC LAN8742A PHY using these pins:
|
||||
*
|
||||
@ -394,7 +403,7 @@
|
||||
#define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2
|
||||
#define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_2
|
||||
|
||||
/* LCD definitions **********************************************************/
|
||||
/* LCD definitions */
|
||||
|
||||
#define BOARD_LTDC_WIDTH 480
|
||||
#define BOARD_LTDC_HEIGHT 272
|
||||
@ -513,4 +522,21 @@
|
||||
# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
|
||||
#endif
|
||||
|
||||
#endif /* __BOARDS_ARM_STM32F7_STM32F746G_DISCO_INCLUDE_BOARD_H */
|
||||
/* SAI2 pinset */
|
||||
#if defined(CONFIG_STM32F7_SAI2) && defined(CONFIG_STM32F7_SAI2_A)
|
||||
#define GPIO_SAI2_SD_A GPIO_SAI2_SD_A_2
|
||||
#define GPIO_SAI2_FS_A GPIO_SAI2_FS_A_2
|
||||
#define GPIO_SAI2_SCK_A GPIO_SAI2_SCK_A_2
|
||||
#define GPIO_SAI2_MCLK_A GPIO_SAI2_MCLK_A_2
|
||||
#define GPIO_SAI2_SD_B GPIO_SAI2_SD_B_4
|
||||
|
||||
#define DMACHAN_SAI2_A DMAMAP_SAI2_A
|
||||
#define DMACHAN_SAI2_B DMAMAP_SAI2_B
|
||||
|
||||
#else
|
||||
|
||||
#define GPIO_SAI1_SD_B GPIO_SAI1_SD_B_1
|
||||
#define DMACHAN_SAI1_B DMAMAP_SAI1_B
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# boards/arm/stm32f7/stm32f746g-disco/src/Makefile
|
||||
#
|
||||
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -83,4 +83,8 @@ ifeq ($(CONFIG_STM32F7_SDMMC), y)
|
||||
CSRCS += stm32_sdmmc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_WM8994), y)
|
||||
CSRCS += stm32_wm8994.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
@ -154,6 +154,14 @@ int stm32_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_WM8994
|
||||
ret = stm32_wm8994_initialize(0);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: stm32_wm8994_initialize failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
UNUSED(ret); /* May not be used */
|
||||
return OK;
|
||||
}
|
||||
|
216
boards/arm/stm32f7/stm32f746g-disco/src/stm32_wm8994.c
Normal file
216
boards/arm/stm32f7/stm32f746g-disco/src/stm32_wm8994.c
Normal file
@ -0,0 +1,216 @@
|
||||
/****************************************************************************
|
||||
* boards/arm/stm32f7/stm32f746g-disco/src/stm32_wm8994.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 <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/audio/i2s.h>
|
||||
#include <nuttx/audio/wm8994.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "stm32f746g-disco.h"
|
||||
#include "stm32_i2c.h"
|
||||
#include "stm32_sai.h"
|
||||
|
||||
#define HAVE_WM8994
|
||||
#define WM8994_I2C_ADDRESS (0x34 >> 1)
|
||||
#define WM8994_I2C_BUS 3
|
||||
#define WM8994_SAI_BUS 2
|
||||
|
||||
#ifdef HAVE_WM8994
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_mwinfo_s
|
||||
{
|
||||
/* Standard ADAU1961 interface */
|
||||
|
||||
struct wm8994_lower_s lower;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int wm8994_attach(FAR const struct wm8994_lower_s *lower,
|
||||
wm8994_handler_t isr, FAR void *arg)
|
||||
{
|
||||
audinfo("TODO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool wm8994_enable(FAR const struct wm8994_lower_s *lower,
|
||||
bool enable)
|
||||
{
|
||||
audinfo("TODO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void wm8994_hw_reset(FAR const struct wm8994_lower_s *lower)
|
||||
{
|
||||
audinfo("TODO\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* A reference to a structure of this type must be passed to the ADAU1961
|
||||
* driver. This structure provides information about the configuration
|
||||
* of the ADAU1961 and provides some board-specific hooks.
|
||||
*
|
||||
* Memory for this structure is provided by the caller. It is not copied
|
||||
* by the driver and is presumed to persist while the driver is active.
|
||||
*/
|
||||
|
||||
static struct stm32_mwinfo_s g_wm8994 =
|
||||
{
|
||||
.lower =
|
||||
{
|
||||
.address = WM8994_I2C_ADDRESS,
|
||||
.frequency = I2C_SPEED_FAST, /* 100 kHz */
|
||||
.mclk = 12000000, /* see MCO1 configuration */
|
||||
.attach = wm8994_attach,
|
||||
.enable = wm8994_enable,
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_wm8994_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function is called by platform-specific, setup logic to configure
|
||||
* and register the ADAU1961 device. This function will register the driver
|
||||
* as /dev/audio/pcm[x] where x is determined by the minor device number.
|
||||
*
|
||||
* Input Parameters:
|
||||
* minor - The input device minor number
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_wm8994_initialize(int minor)
|
||||
{
|
||||
FAR struct audio_lowerhalf_s *wm8994;
|
||||
FAR struct i2c_master_s *i2c;
|
||||
FAR struct i2s_dev_s *i2s;
|
||||
static bool initialized = false;
|
||||
char devname[12];
|
||||
int ret;
|
||||
|
||||
audinfo("minor %d\n", minor);
|
||||
DEBUGASSERT(minor >= 0 && minor <= 25);
|
||||
|
||||
/* Initialize the CODEC if we have not already done so */
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/* Configure MC01 to drive the master clock of the CODEC at 8MHz */
|
||||
|
||||
/* stm32_configgpio(GPIO_MCO1);
|
||||
* stm32_mco1config(RCC_CFGR_MCO1_HSE, RCC_CFGR_MCO1PRE_NONE);
|
||||
*/
|
||||
|
||||
/* Get an instance of the I2C interface for the CODEC */
|
||||
|
||||
i2c = stm32_i2cbus_initialize(WM8994_I2C_BUS);
|
||||
if (!i2c)
|
||||
{
|
||||
auderr("stm32_i2cbus_initialize failed\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Get an instance of the I2S interface for the CODEC data streams */
|
||||
|
||||
i2s = stm32_sai_initialize(WM8994_SAI_BUS);
|
||||
if (!i2s)
|
||||
{
|
||||
auderr("stm32_sai_initialize failed\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Now we can use these I2C and I2S interfaces to initialize the
|
||||
* CODEC which will return an audio interface.
|
||||
*/
|
||||
|
||||
wm8994 = wm8994_initialize(i2c, i2s, &g_wm8994.lower);
|
||||
if (!wm8994)
|
||||
{
|
||||
auderr("wm8994_initialize failed\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create a device name */
|
||||
|
||||
snprintf(devname, 12, "pcm%d", minor);
|
||||
#if 0
|
||||
/* Finally, we can register the ADAU1961/I2C/I2S audio device. */
|
||||
|
||||
ret = audio_register(devname, wm8994);
|
||||
if (ret < 0)
|
||||
{
|
||||
auderr("failed to register /dev/%s device: %d\n", devname, ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Now we are initialized */
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
/* Error exits. Unfortunately there is no mechanism in place now to
|
||||
* recover resources from most errors on initialization failures.
|
||||
*/
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_WM8994 */
|
@ -1,4 +1,4 @@
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* boards/arm/stm32f7/stm32f746g-disco/src/stm32f746g-disco.h
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||
@ -31,22 +31,22 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM_STM32F7_STM32F746G_DISCO_SRC_STM32F746G_DISCO__H
|
||||
#define __BOARDS_ARM_STM32F7_STM32F746G_DISCO_SRC_STM32F746G_DISCO__H
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
/* procfs File System */
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
#undef HAVE_SDIO
|
||||
#endif
|
||||
|
||||
/* STM32F736G Discovery GPIOs ***********************************************/
|
||||
/* STM32F736G Discovery GPIOs */
|
||||
|
||||
/* The STM32F746G-DISCO board has numerous LEDs but only one,
|
||||
* LD1 located near the reset button, that can be controlled by software
|
||||
@ -120,17 +120,13 @@
|
||||
#define SDIO_SLOTNO 0
|
||||
#define SDIO_MINOR 0
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Public data
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: stm32_bringup
|
||||
*
|
||||
* Description:
|
||||
@ -142,70 +138,72 @@
|
||||
* CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y :
|
||||
* Called from the NSH library
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
int stm32_bringup(void);
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: stm32_adc_setup
|
||||
*
|
||||
* Description:
|
||||
* Initialize ADC and register the ADC driver.
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADC
|
||||
int stm32_adc_setup(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: stm32_spidev_initialize
|
||||
*
|
||||
* Description:
|
||||
* Called to configure SPI chip select GPIO pins for the stm32f746g-disco board.
|
||||
* Called to configure SPI chip select GPIO pins for the
|
||||
* stm32f746g-disco board.
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
void weak_function stm32_spidev_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: arch_sporadic_initialize
|
||||
*
|
||||
* Description:
|
||||
* This configuration has been used for evaluating the NuttX sporadic scheduler.
|
||||
* This configuration has been used for evaluating the NuttX sporadic
|
||||
* scheduler.
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
|
||||
void arch_sporadic_initialize(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
* Name: stm32_enablefmc
|
||||
*
|
||||
* Description:
|
||||
* enable clocking to the FMC module
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_FMC
|
||||
void stm32_enablefmc(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: stm32_disablefmc
|
||||
*
|
||||
* Description:
|
||||
* disable clocking to the FMC module
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_FMC
|
||||
void stm32_disablefmc(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
/*******************************************************************************
|
||||
* Name: stm32_tsc_setup
|
||||
*
|
||||
* Description:
|
||||
@ -220,7 +218,7 @@ void stm32_disablefmc(void);
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_INPUT_FT5X06
|
||||
int stm32_tsc_setup(int minor);
|
||||
@ -234,6 +232,10 @@ int stm32_n25qxxx_setup(void);
|
||||
int stm32_sdio_initialize(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_WM8994
|
||||
int stm32_wm8994_initialize(int minor);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __BOARDS_ARM_STM32F7_STM32F746G_DISCO_SRC_STM32F746G_DISCO_H */
|
||||
|
@ -234,6 +234,67 @@ config WM8776_SWAP_HPOUT
|
||||
|
||||
endif # AUDIO_WM8776
|
||||
|
||||
config AUDIO_WM8994
|
||||
bool "WM8994 audio chip"
|
||||
default n
|
||||
depends on AUDIO
|
||||
---help---
|
||||
Select to enable support for the WM8994 Audio codec by Wolfson
|
||||
Microelectonics. This chip is a lower level audio chip.. basically
|
||||
an exotic D-to-A. It includes no built-in support for audio CODECS
|
||||
The WM8994 provides:
|
||||
|
||||
- Low power consumption
|
||||
- High SNR
|
||||
- Stereo digital microphone input
|
||||
- Digital Dynamic Range Controller (compressor / limiter)
|
||||
- Digital sidetone mixing
|
||||
- Ground-referenced headphone driver
|
||||
- Ground-referenced line outputs
|
||||
|
||||
NOTE: This driver also depends on both I2C and I2S support although
|
||||
that dependency is not explicit here.
|
||||
|
||||
if AUDIO_WM8994
|
||||
|
||||
config WM8994_INITVOLUME
|
||||
int "WM8994 initial volume setting"
|
||||
default 250
|
||||
|
||||
config WM8994_INFLIGHT
|
||||
int "WM8994 maximum in-flight audio buffers"
|
||||
default 2
|
||||
|
||||
config WM8994_MSG_PRIO
|
||||
int "WM8994 message priority"
|
||||
default 1
|
||||
|
||||
config WM8994_BUFFER_SIZE
|
||||
int "WM8994 preferred buffer size"
|
||||
default 8192
|
||||
|
||||
config WM8994_NUM_BUFFERS
|
||||
int "WM8994 preferred number of buffers"
|
||||
default 4
|
||||
|
||||
config WM8994_WORKER_STACKSIZE
|
||||
int "WM8994 worker thread stack size"
|
||||
default 768
|
||||
|
||||
config WM8994_REGDUMP
|
||||
bool "WM8994 register dump"
|
||||
default n
|
||||
---help---
|
||||
Enable logic to dump the contents of all WM8994 registers.
|
||||
|
||||
config WM8994_CLKDEBUG
|
||||
bool "WM8994 clock analysis"
|
||||
default n
|
||||
---help---
|
||||
Enable logic to analyze WM8994 clock configuation.
|
||||
|
||||
endif # AUDIO_WM8994
|
||||
|
||||
config AUDIO_WM8904
|
||||
bool "WM8904 audio chip"
|
||||
default n
|
||||
|
@ -65,6 +65,17 @@ ifeq ($(CONFIG_AUDIO_CS4344),y)
|
||||
CSRCS += cs4344.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_WM8994),y)
|
||||
CSRCS += wm8994.c
|
||||
ifeq ($(CONFIG_WM8994_REGDUMP),y)
|
||||
CSRCS += wm8994_debug.c
|
||||
else
|
||||
ifeq ($(CONFIG_WM8994_CLKDEBUG),y)
|
||||
CSRCS += wm8994_debug.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_WM8904),y)
|
||||
CSRCS += wm8904.c
|
||||
ifeq ($(CONFIG_WM8904_REGDUMP),y)
|
||||
|
2011
drivers/audio/wm8994.c
Normal file
2011
drivers/audio/wm8994.c
Normal file
File diff suppressed because it is too large
Load Diff
1635
drivers/audio/wm8994.h
Normal file
1635
drivers/audio/wm8994.h
Normal file
File diff suppressed because it is too large
Load Diff
543
drivers/audio/wm8994_debug.c
Normal file
543
drivers/audio/wm8994_debug.c
Normal file
@ -0,0 +1,543 @@
|
||||
/*****************************************************************************************
|
||||
* drivers/audio/wm8994_debug.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 <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <fixedmath.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <nuttx/audio/wm8904.h>
|
||||
|
||||
#include "wm8994.h"
|
||||
|
||||
/*****************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_REGDUMP
|
||||
struct wb8994_regdump_s
|
||||
{
|
||||
FAR const char *regname;
|
||||
uint16_t regaddr;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*****************************************************************************************
|
||||
* Private Function Prototypes
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_REGDUMP
|
||||
static const struct wb8994_regdump_s g_wm8994_debug[] =
|
||||
{
|
||||
{"ID", WM8994_ID},
|
||||
{"PM1", WM8994_PM1},
|
||||
{"PM2", WM8994_PM2},
|
||||
{"PM3", WM8994_PM3},
|
||||
{"PM4", WM8994_PM4},
|
||||
{"PM5", WM8994_PM5},
|
||||
{"PM6", WM8994_PM6},
|
||||
{"INPUT_MIXER1", WM8994_INPUT_MIXER1},
|
||||
{"LEFTLINE_12_VOL", WM8994_LEFTLINE_12_VOL},
|
||||
{"LEFTLINE_34_VOL", WM8994_LEFTLINE_34_VOL},
|
||||
{"RIGHTLINE_12_VOL", WM8994_RIGHTLINE_12_VOL},
|
||||
{"RIGHTLINE_34_VOL", WM8994_RIGHTLINE_34_VOL},
|
||||
{"LEFT_OUTPUT_VOL", WM8994_LEFT_OUTPUT_VOL},
|
||||
{"RIGHT_OUTPUT_VOL", WM8994_RIGHT_OUTPUT_VOL},
|
||||
{"LINE_OUTPUTS_VOL", WM8994_LINE_OUTPUTS_VOL},
|
||||
{"HPOUT2_VOL", WM8994_HPOUT2_VOL},
|
||||
{"LEFT_OPGA_VOL", WM8994_LEFT_OPGA_VOL},
|
||||
{"RIGHT_OPGA_VOL", WM8994_RIGHT_OPGA_VOL},
|
||||
{"SPKMIXL_ATT", WM8994_SPKMIXL_ATT},
|
||||
{"SPKMIXR_ATT", WM8994_SPKMIXR_ATT},
|
||||
{"SPKOUT_MIXERS", WM8994_SPKOUT_MIXERS},
|
||||
{"CLASS_D", WM8994_CLASS_D},
|
||||
{"SPEAKER_VOL_LEFT", WM8994_SPEAKER_VOL_LEFT},
|
||||
{"SPEAKER_VOL_RIGHT", WM8994_SPEAKER_VOL_RIGHT},
|
||||
{"INPUT_MIXER2", WM8994_INPUT_MIXER2},
|
||||
{"INPUT_MIXER3", WM8994_INPUT_MIXER3},
|
||||
{"INPUT_MIXER4", WM8994_INPUT_MIXER4},
|
||||
{"INPUT_MIXER5", WM8994_INPUT_MIXER5},
|
||||
{"INPUT_MIXER6", WM8994_INPUT_MIXER6},
|
||||
{"OUTPUT_MIXER1", WM8994_OUTPUT_MIXER1},
|
||||
{"OUTPUT_MIXER2", WM8994_OUTPUT_MIXER2},
|
||||
{"OUTPUT_MIXER3", WM8994_OUTPUT_MIXER3},
|
||||
{"OUTPUT_MIXER4", WM8994_OUTPUT_MIXER4},
|
||||
{"OUTPUT_MIXER5", WM8994_OUTPUT_MIXER5},
|
||||
{"OUTPUT_MIXER6", WM8994_OUTPUT_MIXER6},
|
||||
{"HPOUT2_MIXER", WM8994_HPOUT2_MIXER},
|
||||
{"LINE_MIXER1", WM8994_LINE_MIXER1},
|
||||
{"LINE_MIXER2", WM8994_LINE_MIXER2},
|
||||
{"SPEAKER_MIXER", WM8994_SPEAKER_MIXER},
|
||||
{"ADDITIONAL_CTL", WM8994_ADDITIONAL_CTL},
|
||||
{"ANTI_POP1", WM8994_ANTI_POP1},
|
||||
{"ANTI_POP2", WM8994_ANTI_POP2},
|
||||
{"MIC_BIAS", WM8994_MIC_BIAS},
|
||||
{"LDO_1", WM8994_LDO_1},
|
||||
{"LDO_2", WM8994_LDO_2},
|
||||
{"CHARGE_PUMP1", WM8994_CHARGE_PUMP1},
|
||||
{"CHARGE_PUMP2", WM8994_CHARGE_PUMP2},
|
||||
{"CLASS_W_1", WM8994_CLASS_W_1},
|
||||
{"DC_SERVO1", WM8994_DC_SERVO1},
|
||||
{"DC_SERVO2", WM8994_DC_SERVO2},
|
||||
{"DC_SERVO_BB", WM8994_DC_SERVO_RB},
|
||||
{"DC_SERVO4", WM8994_DC_SERVO4},
|
||||
{"ANA_HP1", WM8994_ANA_HP1},
|
||||
{"CHIP_REV", WM8994_CHIP_REV},
|
||||
{"CTL_IF", WM8994_CTL_IF},
|
||||
{"WR_CTL_SEQ1", WM8994_WR_CTL_SEQ1},
|
||||
{"WR_CTL_SEQ2", WM8994_WR_CTL_SEQ2},
|
||||
{"AIF1_CLK1", WM8994_AIF1_CLK1},
|
||||
{"AIF1_CLK2", WM8994_AIF1_CLK2},
|
||||
{"AIF2_CLK1", WM8994_AIF2_CLK1},
|
||||
{"AIF2_CLK2", WM8994_AIF2_CLK2},
|
||||
{"CLK1", WM8994_CLK1},
|
||||
{"CLK2", WM8994_CLK2},
|
||||
{"AIF1_RATE", WM8994_AIF1_RATE},
|
||||
{"AIF2_RATE", WM8994_AIF2_RATE},
|
||||
{"RATE_STATUS", WM8994_RATE_STATUS},
|
||||
{"PLL1_CTL1", WM8994_PLL1_CTL1},
|
||||
{"PLL1_CTL2", WM8994_PLL1_CTL2},
|
||||
{"PLL1_CTL3", WM8994_PLL1_CTL3},
|
||||
{"PLL1_CTL4", WM8994_PLL1_CTL4},
|
||||
{"PLL1_CTL5", WM8994_PLL1_CTL5},
|
||||
{"PLL2_CTL1", WM8994_PLL2_CTL1},
|
||||
{"PLL2_CTL2", WM8994_PLL2_CTL2},
|
||||
{"PLL2_CTL3", WM8994_PLL2_CTL3},
|
||||
{"PLL2_CTL4", WM8994_PLL2_CTL4},
|
||||
{"PLL2_CTL5", WM8994_PLL2_CTL5},
|
||||
{"AIF1_CTL1", WM8994_AIF1_CTL1},
|
||||
{"AIF1_CTL2", WM8994_AIF1_CTL2},
|
||||
{"AIF1_MASTER_SLAVE", WM8994_AIF1_MASTER_SLAVE},
|
||||
{"AIF1_BCLK", WM8994_AIF1_BCLK},
|
||||
{"AIF1_ADC_LRCLK", WM8994_AIF1_ADC_LRCLK},
|
||||
{"AIF1_DAC_LRCLK", WM8994_AIF1_DAC_LRCLK},
|
||||
{"AIF1_DAC_DATA", WM8994_AIF1_DAC_DATA},
|
||||
{"AIF1_ADC_DATA", WM8994_AIF1_ADC_DATA},
|
||||
{"AIF2_CTL1", WM8994_AIF2_CTL1},
|
||||
{"AIF2_CTL2", WM8994_AIF2_CTL2},
|
||||
{"AIF2_MASTER_SLAVE", WM8994_AIF2_MASTER_SLAVE},
|
||||
{"AIF2_BCLKK", WM8994_AIF2_BCLK},
|
||||
{"AIF2_ADC_LRCLK", WM8994_AIF2_ADC_LRCLK},
|
||||
{"AIF2_DAC_LRCLK", WM8994_AIF2_DAC_LRCLK},
|
||||
{"AIF2_DAC_DATA", WM8994_AIF2_DAC_DATA},
|
||||
{"AIF2_ADC_DATA", WM8994_AIF2_ADC_DATA},
|
||||
{"AIF1_ADC1_LEFT_VOL", WM8994_AIF1_ADC1_LEFT_VOL},
|
||||
{"AIF1_ADC1_RIGHT_VOL", WM8994_AIF1_ADC1_RIGHT_VOL},
|
||||
{"AIF1_DAC1_LEFT_VOL", WM8994_AIF1_DAC1_LEFT_VOL},
|
||||
{"AIF1_DAC1_RIGHT_VOL", WM8994_AIF1_DAC1_RIGHT_VOL},
|
||||
{"AIF1_ADC2_LEFT_VOL", WM8994_AIF1_ADC2_LEFT_VOL},
|
||||
{"AIF1_ADC2_RIGHT_VOL", WM8994_AIF1_ADC2_RIGHT_VOL},
|
||||
{"AIF1_DAC2_LEFT_VOL", WM8994_AIF1_DAC2_LEFT_VOL},
|
||||
{"AIF1_DAC2_RIGHT_VOL", WM8994_AIF1_DAC2_RIGHT_VOL},
|
||||
{"AIF1_ADC1_FILTERS", WM8994_AIF1_ADC1_FILTERS},
|
||||
{"AIF1_ADC2_FILTERS", WM8994_AIF1_ADC2_FILTERS},
|
||||
{"AIF1_DAC1_FILTERS1", WM8994_AIF1_DAC1_FILTERS1},
|
||||
{"AIF1_DAC1_FILTERS2", WM8994_AIF1_DAC1_FILTERS2},
|
||||
{"AIF1_DAC2_FILTERS1", WM8994_AIF1_DAC2_FILTERS1},
|
||||
{"AIF1_DAC2_FILTERS2", WM8994_AIF1_DAC2_FILTERS2},
|
||||
{"AIF1_DRC1_1", WM8994_AIF1_DRC1_1},
|
||||
{"AIF1_DRC1_2", WM8994_AIF1_DRC1_2},
|
||||
{"AIF1_DRC1_3", WM8994_AIF1_DRC1_3},
|
||||
{"AIF1_DRC1_4", WM8994_AIF1_DRC1_4},
|
||||
{"AIF1_DRC1_5", WM8994_AIF1_DRC1_5},
|
||||
{"AIF1_DRC2_1", WM8994_AIF1_DRC2_1},
|
||||
{"AIF1_DRC2_2", WM8994_AIF1_DRC2_2},
|
||||
{"AIF1_DRC2_3", WM8994_AIF1_DRC2_3},
|
||||
{"AIF1_DRC2_4", WM8994_AIF1_DRC2_4},
|
||||
{"AIF1_DRC2_5", WM8994_AIF1_DRC2_5},
|
||||
{"AIF1_DAC1_EQ_GAINS_1", WM8994_AIF1_DAC1_EQ_GAINS_1},
|
||||
{"AIF1_DAC1_EQ_GAINS_2", WM8994_AIF1_DAC1_EQ_GAINS_2},
|
||||
{"AIF1_DAC1_EQ_BAND_1A", WM8994_AIF1_DAC1_EQ_BAND_1A},
|
||||
{"AIF1_DAC1_EQ_BAND_1B", WM8994_AIF1_DAC1_EQ_BAND_1B},
|
||||
{"AIF1_DAC1_EQ_BAND_1PG", WM8994_AIF1_DAC1_EQ_BAND_1PG},
|
||||
{"AIF1_DAC1_EQ_BAND_2A", WM8994_AIF1_DAC1_EQ_BAND_2A},
|
||||
{"AIF1_DAC1_EQ_BAND_2B", WM8994_AIF1_DAC1_EQ_BAND_2B},
|
||||
{"AIF1_DAC1_EQ_BAND_2C", WM8994_AIF1_DAC1_EQ_BAND_2C},
|
||||
{"AIF1_DAC1_EQ_BAND_2PG", WM8994_AIF1_DAC1_EQ_BAND_2PG},
|
||||
{"AIF1_DAC1_EQ_BAND_3A", WM8994_AIF1_DAC1_EQ_BAND_3A},
|
||||
{"AIF1_DAC1_EQ_BAND_3B", WM8994_AIF1_DAC1_EQ_BAND_3B},
|
||||
{"AIF1_DAC1_EQ_BAND_3C", WM8994_AIF1_DAC1_EQ_BAND_3C},
|
||||
{"AIF1_DAC1_EQ_BAND_3PG", WM8994_AIF1_DAC1_EQ_BAND_3PG},
|
||||
{"AIF1_DAC1_EQ_BAND_4A", WM8994_AIF1_DAC1_EQ_BAND_4A},
|
||||
{"AIF1_DAC1_EQ_BAND_4B", WM8994_AIF1_DAC1_EQ_BAND_4B},
|
||||
{"AIF1_DAC1_EQ_BAND_4C", WM8994_AIF1_DAC1_EQ_BAND_4C},
|
||||
{"AIF1_DAC1_EQ_BAND_4PG", WM8994_AIF1_DAC1_EQ_BAND_4PG},
|
||||
{"AIF1_DAC1_EQ_BAND_5A", WM8994_AIF1_DAC1_EQ_BAND_5A},
|
||||
{"AIF1_DAC1_EQ_BAND_5B", WM8994_AIF1_DAC1_EQ_BAND_5B},
|
||||
{"AIF1_DAC1_EQ_BAND_5PG", WM8994_AIF1_DAC1_EQ_BAND_5PG},
|
||||
{"AIF1_DAC2_EQ_GAINS_1", WM8994_AIF1_DAC2_EQ_GAINS_1},
|
||||
{"AIF1_DAC2_EQ_GAINS_2", WM8994_AIF1_DAC2_EQ_GAINS_2},
|
||||
{"AIF1_DAC2_EQ_BAND_1A", WM8994_AIF1_DAC2_EQ_BAND_1A},
|
||||
{"AIF1_DAC2_EQ_BAND_1B", WM8994_AIF1_DAC2_EQ_BAND_1B},
|
||||
{"AIF1_DAC2_EQ_BAND_1PG", WM8994_AIF1_DAC2_EQ_BAND_1PG},
|
||||
{"AIF1_DAC2_EQ_BAND_2A", WM8994_AIF1_DAC2_EQ_BAND_2A},
|
||||
{"AIF1_DAC2_EQ_BAND_2B", WM8994_AIF1_DAC2_EQ_BAND_2B},
|
||||
{"AIF1_DAC2_EQ_BAND_2C", WM8994_AIF1_DAC2_EQ_BAND_2C},
|
||||
{"AIF1_DAC2_EQ_BAND_2PG", WM8994_AIF1_DAC2_EQ_BAND_2PG},
|
||||
{"AIF1_DAC2_EQ_BAND_3A", WM8994_AIF1_DAC2_EQ_BAND_3A},
|
||||
{"AIF1_DAC2_EQ_BAND_3B", WM8994_AIF1_DAC2_EQ_BAND_3B},
|
||||
{"AIF1_DAC2_EQ_BAND_3C", WM8994_AIF1_DAC2_EQ_BAND_3C},
|
||||
{"AIF1_DAC2_EQ_BAND_3PG", WM8994_AIF1_DAC2_EQ_BAND_3PG},
|
||||
{"AIF1_DAC2_EQ_BAND_4A", WM8994_AIF1_DAC2_EQ_BAND_4A},
|
||||
{"AIF1_DAC2_EQ_BAND_4B", WM8994_AIF1_DAC2_EQ_BAND_4B},
|
||||
{"AIF1_DAC2_EQ_BAND_4C", WM8994_AIF1_DAC2_EQ_BAND_4C},
|
||||
{"AIF1_DAC2_EQ_BAND_4PG", WM8994_AIF1_DAC2_EQ_BAND_4PG},
|
||||
{"AIF1_DAC2_EQ_BAND_5A", WM8994_AIF1_DAC2_EQ_BAND_5A},
|
||||
{"AIF1_DAC2_EQ_BAND_5B", WM8994_AIF1_DAC2_EQ_BAND_5B},
|
||||
{"AIF1_DAC2_EQ_BAND_5PG", WM8994_AIF1_DAC2_EQ_BAND_5PG},
|
||||
{"AIF2_ADC1_LEFT_VOL", WM8994_AIF2_ADC1_LEFT_VOL},
|
||||
{"AIF2_ADC1_RIGHT_VOL", WM8994_AIF2_ADC1_RIGHT_VOL},
|
||||
{"AIF2_DAC1_LEFT_VOL", WM8994_AIF2_DAC1_LEFT_VOL},
|
||||
{"AIF2_DAC1_RIGHT_VOL", WM8994_AIF2_DAC1_RIGHT_VOL},
|
||||
{"AIF2_ADC_FILTERS", WM8994_AIF2_ADC_FILTERS},
|
||||
{"AIF2_DAC_FILTERS1", WM8994_AIF2_DAC_FILTERS1},
|
||||
{"AIF2_DAC_FILTERS2", WM8994_AIF2_DAC_FILTERS2},
|
||||
{"AIF2_DRC_1", WM8994_AIF2_DRC_1},
|
||||
{"AIF2_DRC_2", WM8994_AIF2_DRC_2},
|
||||
{"AIF2_DRC_3", WM8994_AIF2_DRC_3},
|
||||
{"AIF2_DRC_4", WM8994_AIF2_DRC_4},
|
||||
{"AIF2_DRC_5", WM8994_AIF2_DRC_5},
|
||||
{"AIF2_EQ_GAINS_1", WM8994_AIF2_EQ_GAINS_1},
|
||||
{"AIF2_EQ_GAINS_2", WM8994_AIF2_EQ_GAINS_2},
|
||||
{"AIF2_EQ_BAND_1A", WM8994_AIF2_EQ_BAND_1A},
|
||||
{"AIF2_EQ_BAND_1B", WM8994_AIF2_EQ_BAND_1B},
|
||||
{"AIF2_EQ_BAND_1PG", WM8994_AIF2_EQ_BAND_1PG},
|
||||
{"AIF2_EQ_BAND_2A", WM8994_AIF2_EQ_BAND_2A},
|
||||
{"AIF2_EQ_BAND_2B", WM8994_AIF2_EQ_BAND_2B},
|
||||
{"AIF2_EQ_BAND_2C", WM8994_AIF2_EQ_BAND_2C},
|
||||
{"AIF2_EQ_BAND_2PG", WM8994_AIF2_EQ_BAND_2PG},
|
||||
{"AIF2_EQ_BAND_3A", WM8994_AIF2_EQ_BAND_3A},
|
||||
{"AIF2_EQ_BAND_3B", WM8994_AIF2_EQ_BAND_3B},
|
||||
{"AIF2_EQ_BAND_3C", WM8994_AIF2_EQ_BAND_3C},
|
||||
{"AIF2_EQ_BAND_3PG", WM8994_AIF2_EQ_BAND_3PG},
|
||||
{"AIF2_EQ_BAND_4A", WM8994_AIF2_EQ_BAND_4A},
|
||||
{"AIF2_EQ_BAND_4B", WM8994_AIF2_EQ_BAND_4B},
|
||||
{"AIF2_EQ_BAND_4C", WM8994_AIF2_EQ_BAND_4C},
|
||||
{"AIF2_EQ_BAND_4PG", WM8994_AIF2_EQ_BAND_4PG},
|
||||
{"AIF2_EQ_BAND_5A", WM8994_AIF2_EQ_BAND_5A},
|
||||
{"AIF2_EQ_BAND_5B", WM8994_AIF2_EQ_BAND_5B},
|
||||
{"AIF2_EQ_BAND_5PG", WM8994_AIF2_EQ_BAND_5PG},
|
||||
{"DAC1_MIXER_VOLS", WM8994_DAC1_MIXER_VOLS},
|
||||
{"DAC1_LEFT_MIXER_ROUTING", WM8994_DAC1_LEFT_MIXER_ROUTING},
|
||||
{"DAC1_RIGHT_MIXER_ROUTING", WM8994_DAC1_RIGHT_MIXER_ROUTING},
|
||||
{"DAC2_MIXER_VOLS", WM8994_DAC2_MIXER_VOLS},
|
||||
{"DAC2_LEFT_MIXER_ROUTING", WM8994_DAC2_LEFT_MIXER_ROUTING},
|
||||
{"DAC2_RIGHT_MIXER_ROUTING", WM8994_DAC2_RIGHT_MIXER_ROUTING},
|
||||
{"ADC1_LEFT_MIXER_ROUTING", WM8994_ADC1_LEFT_MIXER_ROUTING},
|
||||
{"ADC1_RIGHT_MIXER_ROUTING", WM8994_ADC1_RIGHT_MIXER_ROUTING},
|
||||
{"ADC2_LEFT_MIXER_ROUTING", WM8994_ADC2_LEFT_MIXER_ROUTING},
|
||||
{"ADC2_RIGHT_MIXER_ROUTING", WM8994_ADC2_RIGHT_MIXER_ROUTING},
|
||||
{"DAC1_LEFT_VOL", WM8994_DAC1_LEFT_VOL},
|
||||
{"DAC1_RIGHT_VOL", WM8994_DAC1_RIGHT_VOL},
|
||||
{"DAC2_LEFT_VOL", WM8994_DAC2_LEFT_VOL},
|
||||
{"DAC2_RIGHT_VOL", WM8994_DAC2_RIGHT_VOL},
|
||||
{"DAC_SOFT_MUTE", WM8994_DAC_SOFT_MUTE},
|
||||
{"OVER_SAMPLING", WM8994_OVER_SAMPLING},
|
||||
{"SIDE_TONE", WM8994_SIDE_TONE},
|
||||
{"GPIO1", WM8994_GPIO1},
|
||||
{"GPIO2", WM8994_GPIO2},
|
||||
{"GPIO3", WM8994_GPIO3},
|
||||
{"GPIO4", WM8994_GPIO4},
|
||||
{"GPIO5", WM8994_GPIO5},
|
||||
{"GPIO6", WM8994_GPIO6},
|
||||
{"GPIO7", WM8994_GPIO7},
|
||||
{"GPIO8", WM8994_GPIO8},
|
||||
{"GPIO9", WM8994_GPIO9},
|
||||
{"GPIO10", WM8994_GPIO10},
|
||||
{"GPIO11", WM8994_GPIO11},
|
||||
{"PULL_CTL1", WM8994_PULL_CTL1},
|
||||
{"PULL_CTL2", WM8994_PULL_CTL2},
|
||||
{"INT_STATUS1", WM8994_INT_STATUS1},
|
||||
{"INT_STATUS2", WM8994_INT_STATUS2},
|
||||
{"INT_RAW_STATUS2", WM8994_INT_RAW_STATUS2},
|
||||
{"INT_STATUS1_MASK", WM8994_INT_STATUS1_MASK},
|
||||
{"INT_STATUS2_MASK", WM8994_INT_STATUS2_MASK},
|
||||
{"INT_CTL", WM8994_INT_CTL},
|
||||
{"INT_DEBOUNCE", WM8994_INT_DEBOUNCE},
|
||||
};
|
||||
|
||||
# define WM8994_NREGISTERS (sizeof(g_wm8994_debug)/sizeof(struct wb8994_regdump_s))
|
||||
#endif /* CONFIG_WM8994_REGDUMP */
|
||||
|
||||
/*****************************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Name: wm8994_dump_registers
|
||||
*
|
||||
* Description:
|
||||
* Dump the contents of all WM8994 registers to the syslog device
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by wm8994_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
*****************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_REGDUMP
|
||||
void wm8994_dump_registers(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg)
|
||||
{
|
||||
int i;
|
||||
|
||||
syslog(LOG_INFO, "WM8994 Registers: %s\n", msg);
|
||||
for (i = 0; i < WM8994_NREGISTERS; i++)
|
||||
{
|
||||
syslog(LOG_INFO, "%24s[%04x]: %04x\n",
|
||||
g_wm8994_debug[i].regname, g_wm8994_debug[i].regaddr,
|
||||
wm8994_readreg((FAR struct wm8994_dev_s *)dev,
|
||||
g_wm8994_debug[i].regaddr));
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_WM8994_REGDUMP */
|
||||
|
||||
/*****************************************************************************************
|
||||
* Name: wm8994_clock_analysis
|
||||
*
|
||||
* Description:
|
||||
* Analyze the settings in the clock chain and dump to syslog.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by wm8994_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
*****************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_CLKDEBUG
|
||||
void wm8994_clock_analysis(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg)
|
||||
{
|
||||
FAR struct wm8994_dev_s *priv = (FAR struct wm8994_dev_s *)dev;
|
||||
uint32_t sysclk;
|
||||
uint32_t bclk;
|
||||
uint32_t lrclk;
|
||||
uint16_t regval;
|
||||
unsigned int tmp;
|
||||
double ftmp;
|
||||
|
||||
syslog(LOG_INFO, "WM8994 Clock Analysis: %s\n", msg);
|
||||
DEBUGASSERT(priv && priv->lower);
|
||||
syslog(LOG_INFO, " MCLK: %lu Hz\n",
|
||||
(unsigned long)priv->lower->mclk);
|
||||
|
||||
/* Is the SYSCLK source the FLL? Or MCK? */
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_CLKRATE2);
|
||||
if ((regval & WM8994_SYSCLK_SRC) == WM8994_SYSCLK_SRCMCLK)
|
||||
{
|
||||
/* The SYSCLK divider bypasses the FLL and takes its input
|
||||
* directly from MCLK.
|
||||
*/
|
||||
|
||||
sysclk = priv->lower->mclk;
|
||||
syslog(LOG_INFO, " SYSCLK Source: MCLK (%s)\n",
|
||||
(regval & WM8994_MCLK_INV) != 0 ? "inverted" : "not inverted");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t fref;
|
||||
uint32_t fvco;
|
||||
uint32_t fout;
|
||||
unsigned int outdiv;
|
||||
unsigned int frndx;
|
||||
unsigned int flln;
|
||||
unsigned int fllk;
|
||||
unsigned int fratio;
|
||||
double nk;
|
||||
|
||||
/* Assume that the Fref input to the FLL is MCLK */
|
||||
|
||||
fref = priv->lower->mclk;
|
||||
|
||||
/* Now get the real FLL input source */
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_FLL_CTRL5);
|
||||
switch (regval & WM8994_FLL_CLK_REF_SRC_MASK)
|
||||
{
|
||||
case WM8994_FLL_CLK_REF_SRC_MCLK:
|
||||
syslog(LOG_INFO, " FLL Source: MCLK\n");
|
||||
break;
|
||||
|
||||
case WM8994_FLL_CLK_REF_SRC_BCLK:
|
||||
syslog(LOG_INFO, " ERROR: FLL source is BCLK: %04x\n",
|
||||
regval);
|
||||
break;
|
||||
|
||||
case WM8994_FLL_CLK_REF_SRC_LRCLK:
|
||||
syslog(LOG_INFO, " ERROR: FLL source is LRCLK: %04x\n",
|
||||
regval);
|
||||
break;
|
||||
|
||||
default:
|
||||
syslog(LOG_INFO, " ERROR: Unrecognized FLL source: %04x\n",
|
||||
regval);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, " Fref: %lu Hz (before divider)\n",
|
||||
fref);
|
||||
switch (regval & WM8994_FLL_CLK_REF_DIV_MASK)
|
||||
{
|
||||
case WM8994_FLL_CLK_REF_DIV1:
|
||||
syslog(LOG_INFO, " FLL_CLK_REF_DIV: 1\n");
|
||||
break;
|
||||
|
||||
case WM8994_FLL_CLK_REF_DIV2:
|
||||
syslog(LOG_INFO, " FLL_CLK_REF_DIV: 2\n");
|
||||
fref >>= 1;
|
||||
break;
|
||||
|
||||
case WM8994_FLL_CLK_REF_DIV4:
|
||||
syslog(LOG_INFO, " FLL_CLK_REF_DIV: 4\n");
|
||||
fref >>= 2;
|
||||
break;
|
||||
|
||||
case WM8994_FLL_CLK_REF_DIV8:
|
||||
syslog(LOG_INFO, " FLL_CLK_REF_DIV: 8\n");
|
||||
fref >>= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, " Fref: %lu Hz (after divider)\n", fref);
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_FLL_CTRL2);
|
||||
frndx = (regval & WM8994_FLL_FRATIO_MASK) >> WM8994_FLL_FRATIO_SHIFT;
|
||||
tmp = (regval & WM8994_FLL_CTRL_RATE_MASK) >> WM8994_FLL_CTRL_RATE_SHIFT;
|
||||
outdiv = ((regval & WM8994_FLL_OUTDIV_MASK) >> WM8994_FLL_OUTDIV_SHIFT) + 1;
|
||||
|
||||
syslog(LOG_INFO, " FLL_CTRL_RATE: Fvco / %u\n", tmp + 1);
|
||||
|
||||
regval = wm8904_readreg(priv, WM8994_FLL_CTRL4);
|
||||
flln = (regval & WM8994_FLL_N_MASK) >> WM8994_FLL_N_SHIFT;
|
||||
tmp = (regval & WM8994_FLL_GAIN_MASK) >> WM8994_FLL_GAIN_SHIFT;
|
||||
|
||||
syslog(LOG_INFO, " FLL_GAIN: %u\n", (1 << tmp));
|
||||
|
||||
fllk = wm8994_readreg(priv, WM8994_FLL_CTRL3);
|
||||
nk = (double)flln + ((double)fllk / 65536.0);
|
||||
fratio = g_fllratio[frndx];
|
||||
|
||||
syslog(LOG_INFO, " FLL_FRATIO: %u\n", fratio);
|
||||
syslog(LOG_INFO, " FLL_OUTDIV: %u\n", outdiv);
|
||||
syslog(LOG_INFO, " FLL_N.K: %u.%05u\n", flln, fllk);
|
||||
|
||||
ftmp = nk * (double)fref * (double)fratio;
|
||||
fvco = (uint32_t)ftmp;
|
||||
|
||||
syslog(LOG_INFO, " Fvco: %lu Hz\n", (unsigned long)fvco);
|
||||
|
||||
fout = fvco / outdiv;
|
||||
syslog(LOG_INFO, " Fout: %lu Hz\n", (unsigned long)fout);
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_FLL_CTRL1);
|
||||
|
||||
syslog(LOG_INFO, " FLL_FRACN_ENA: %s\n",
|
||||
(regval & WM8994_FLL_FRACN_ENA) != 0 ? "Enabled" : "Disabled");
|
||||
syslog(LOG_INFO, " FLL_OSC_ENA: %s\n",
|
||||
(regval & WM8994_FLL_OSC_ENA) != 0 ? "Enabled" : "Disabled");
|
||||
syslog(LOG_INFO, " FLL_ENA: %s\n",
|
||||
(regval & WM8994_FLL_ENA) != 0 ? "Enabled" : "Disabled");
|
||||
|
||||
if ((regval & WM8994_FLL_ENA) == 0)
|
||||
{
|
||||
syslog(LOG_INFO, " No SYSCLK\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sysclk = fout;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, " SYSCLK: %lu Hz (before divider)\n",
|
||||
(unsigned long)sysclk);
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_CLKRATE0);
|
||||
if ((regval & WM8994_MCLK_DIV) == WM8994_MCLK_DIV1)
|
||||
{
|
||||
syslog(LOG_INFO, " MCLK_DIV: 1\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, " MCLK_DIV: 2\n");
|
||||
sysclk >>= 1;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, " SYSCLK: %lu (after divider)\n", (unsigned long)sysclk);
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_CLKRATE2);
|
||||
|
||||
syslog(LOG_INFO, " CLK_SYS_ENA: %s\n",
|
||||
(regval & WM8994_CLK_SYS_ENA) != 0 ? "Enabled" : "Disabled");
|
||||
|
||||
if ((regval & WM8994_CLK_SYS_ENA) == 0)
|
||||
{
|
||||
syslog(LOG_INFO, " No SYSCLK\n");
|
||||
return;
|
||||
}
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_AIF2);
|
||||
tmp = (regval & WM8994_BCLK_DIV_MASK) >> WM8994_BCLK_DIV_SHIFT;
|
||||
tmp = g_sysclk_scaleb1[tmp];
|
||||
ftmp = (double)tmp / 2.0;
|
||||
|
||||
syslog(LOG_INFO, " BCLK_DIV: SYSCLK / %u.%01u\n",
|
||||
(unsigned int)(tmp >> 1), (unsigned int)(5 * (tmp & 1)));
|
||||
|
||||
bclk = (uint32_t)(sysclk / ftmp);
|
||||
|
||||
syslog(LOG_INFO, " BCLK: %lu Hz\n", (unsigned long)bclk);
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_AIF1);
|
||||
syslog(LOG_INFO, " BCLK_DIR: %s\n",
|
||||
(regval & WM8994_BCLK_DIR) != 0 ? "Output" : "Input");
|
||||
|
||||
regval = wm8994_readreg(priv, WM8994_AIF3);
|
||||
tmp = (regval & WM8994_LRCLK_RATE_MASK) >> WM8994_LRCLK_RATE_SHIFT;
|
||||
|
||||
lrclk = bclk / tmp;
|
||||
|
||||
syslog(LOG_INFO, " LRCLK_RATE: BCLK / %lu\n", (unsigned long)tmp);
|
||||
syslog(LOG_INFO, " LRCLK: %lu Hz\n", (unsigned long)lrclk);
|
||||
syslog(LOG_INFO, " LRCLK_DIR: %s\n",
|
||||
(regval & WM8994_LRCLK_DIR) != 0 ? "Output" : "Input");
|
||||
}
|
||||
#endif /* CONFIG_WM8994_CLKDEBUG */
|
260
include/nuttx/audio/wm8994.h
Normal file
260
include/nuttx/audio/wm8994.h
Normal file
@ -0,0 +1,260 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/audio/wm8994.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_AUDIO_WM8994_H
|
||||
#define __INCLUDE_NUTTX_AUDIO_WM8994_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#ifdef CONFIG_AUDIO_WM8994
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************
|
||||
*
|
||||
* CONFIG_AUDIO_WM8994 - Enables WM8994 support
|
||||
* CONFIG_WM8994_INITVOLUME - The initial volume level in the range {0..1000}
|
||||
* CONFIG_WM8994_INFLIGHT - Maximum number of buffers that the WM8994 driver
|
||||
* will send to the I2S driver before any have completed.
|
||||
* CONFIG_WM8994_MSG_PRIO - Priority of messages sent to the WM8994 worker
|
||||
* thread.
|
||||
* CONFIG_WM8994_BUFFER_SIZE - Preferred buffer size
|
||||
* CONFIG_WM8994_NUM_BUFFERS - Preferred number of buffers
|
||||
* CONFIG_WM8994_WORKER_STACKSIZE - Stack size to use when creating the
|
||||
* WM8994 worker thread.
|
||||
* CONFIG_WM8994_REGDUMP - Enable logic to dump all WM8994 registers to
|
||||
* the SYSLOG device.
|
||||
*/
|
||||
|
||||
/* Pre-requisites */
|
||||
|
||||
#ifndef CONFIG_AUDIO
|
||||
# error CONFIG_AUDIO is required for audio subsystem support
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_I2S
|
||||
# error CONFIG_I2S is required by the WM8994 driver
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_I2C
|
||||
# error CONFIG_I2C is required by the WM8994 driver
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SCHED_WORKQUEUE
|
||||
# error CONFIG_SCHED_WORKQUEUE is required by the WM8994 driver
|
||||
#endif
|
||||
|
||||
/* Default configuration values */
|
||||
|
||||
#ifndef CONFIG_WM8994_INITVOLUME
|
||||
# define CONFIG_WM8994_INITVOLUME 250
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WM8994_INFLIGHT
|
||||
# define CONFIG_WM8994_INFLIGHT 2
|
||||
#endif
|
||||
|
||||
#if CONFIG_WM8994_INFLIGHT > 255
|
||||
# error CONFIG_WM8994_INFLIGHT must fit in a uint8_t
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WM8994_MSG_PRIO
|
||||
# define CONFIG_WM8994_MSG_PRIO 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WM8994_BUFFER_SIZE
|
||||
# define CONFIG_WM8994_BUFFER_SIZE 8192
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WM8994_NUM_BUFFERS
|
||||
# define CONFIG_WM8994_NUM_BUFFERS 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_WM8994_WORKER_STACKSIZE
|
||||
# define CONFIG_WM8994_WORKER_STACKSIZE 768
|
||||
#endif
|
||||
|
||||
/* Helper macros ************************************************************/
|
||||
|
||||
#define WM8994_ATTACH(s,isr,arg) ((s)->attach(s,isr,arg))
|
||||
#define WM8994_DETACH(s) ((s)->attach(s,NULL,NULL))
|
||||
#define WM8994_ENABLE(s) ((s)->enable(s,true))
|
||||
#define WM8994_DISABLE(s) ((s)->enable(s,false))
|
||||
#define WM8994_RESTORE(s,e) ((s)->enable(s,e))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the type of the WM8994 interrupt handler. The lower level code
|
||||
* will intercept the interrupt and provide the upper level with the private
|
||||
* data that was provided when the interrupt was attached.
|
||||
*/
|
||||
|
||||
struct wm8994_lower_s; /* Forward reference. Defined below */
|
||||
|
||||
typedef CODE int (*wm8994_handler_t)(FAR const struct wm8994_lower_s *lower,
|
||||
FAR void *arg);
|
||||
|
||||
/* A reference to a structure of this type must be passed to the WM8994
|
||||
* driver. This structure provides information about the configuration
|
||||
* of the WM8994 and provides some board-specific hooks.
|
||||
*
|
||||
* Memory for this structure is provided by the caller. It is not copied
|
||||
* by the driver and is presumed to persist while the driver is active.
|
||||
*/
|
||||
|
||||
struct wm8994_lower_s
|
||||
{
|
||||
/* I2C characterization */
|
||||
|
||||
uint32_t frequency; /* Initial I2C frequency */
|
||||
uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */
|
||||
|
||||
/* Clocking is provided via MCLK. The WM8994 driver will need to know
|
||||
* the frequency of MCLK in order to generate the correct bitrates.
|
||||
*/
|
||||
|
||||
uint32_t mclk; /* W8994 Master clock frequency */
|
||||
|
||||
/* IRQ/GPIO access callbacks. These operations all hidden behind
|
||||
* callbacks to isolate the WM8994 driver from differences in GPIO
|
||||
* interrupt handling by varying boards and MCUs. If possible,
|
||||
* interrupts should be configured on both rising and falling edges
|
||||
* so that contact and loss-of-contact events can be detected.
|
||||
*
|
||||
* attach - Attach or detach the WM8994 interrupt handler to the GPIO
|
||||
* interrupt
|
||||
* enable - Enable or disable the GPIO interrupt. Returns the
|
||||
* previous interrupt state.
|
||||
*/
|
||||
|
||||
CODE int (*attach)(FAR const struct wm8994_lower_s *lower,
|
||||
wm8994_handler_t isr, FAR void *arg);
|
||||
CODE bool (*enable)(FAR const struct wm8994_lower_s *lower, bool enable);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: wm8994_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the WM8994 device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* i2c - An I2C driver instance
|
||||
* i2s - An I2S driver instance
|
||||
* lower - Persistent board configuration data
|
||||
*
|
||||
* Returned Value:
|
||||
* A new lower half audio interface for the WM8994 device is returned on
|
||||
* success; NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct i2c_master_s; /* Forward reference. Defined in include/nuttx/i2c/i2c_master.h */
|
||||
struct i2s_dev_s; /* Forward reference. Defined in include/nuttx/audio/i2s.h */
|
||||
struct audio_lowerhalf_s; /* Forward reference. Defined in nuttx/audio/audio.h */
|
||||
|
||||
FAR struct audio_lowerhalf_s *
|
||||
wm8994_initialize(FAR struct i2c_master_s *i2c, FAR struct i2s_dev_s *i2s,
|
||||
FAR const struct wm8994_lower_s *lower);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: wm8994_dump_registers
|
||||
*
|
||||
* Description:
|
||||
* Dump the contents of all WM8994 registers to the syslog device
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by wm8994_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_REGDUMP
|
||||
void wm8994_dump_registers(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg);
|
||||
#else
|
||||
/* This eliminates the need for any conditional compilation in the
|
||||
* including file.
|
||||
*/
|
||||
|
||||
# define wm8994_dump_registers(d,m)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: wm8994_clock_analysis
|
||||
*
|
||||
* Description:
|
||||
* Analyze the settings in the clock chain and dump to syslog.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by wm8994_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WM8994_CLKDEBUG
|
||||
void wm8994_clock_analysis(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg);
|
||||
#else
|
||||
/* This eliminates the need for any conditional compilation in the
|
||||
* including file.
|
||||
*/
|
||||
|
||||
# define wm8994_clock_analysis(d,m)
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_AUDIO_WM8994 */
|
||||
#endif /* __INCLUDE_NUTTX_AUDIO_WM8994_H */
|
Loading…
x
Reference in New Issue
Block a user