summaryrefslogtreecommitdiff
path: root/nuttx/drivers
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-07-19 10:20:19 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-07-19 10:20:19 -0600
commit2e8478b428f016c01939b80e3c45dd90b112280c (patch)
tree6abf173dcdd6286c89031b94a31ce7de29329710 /nuttx/drivers
parent2235a952663e4fb9a227d00ebb8655534c22d493 (diff)
downloadpx4-nuttx-2e8478b428f016c01939b80e3c45dd90b112280c.tar.gz
px4-nuttx-2e8478b428f016c01939b80e3c45dd90b112280c.tar.bz2
px4-nuttx-2e8478b428f016c01939b80e3c45dd90b112280c.zip
WM8904: Add initialization logic
Diffstat (limited to 'nuttx/drivers')
-rw-r--r--nuttx/drivers/Kconfig10
-rw-r--r--nuttx/drivers/audio/Kconfig10
-rw-r--r--nuttx/drivers/audio/wm8904.c359
-rw-r--r--nuttx/drivers/audio/wm8904.h108
4 files changed, 456 insertions, 31 deletions
diff --git a/nuttx/drivers/Kconfig b/nuttx/drivers/Kconfig
index 6f591935b..08ca03cc1 100644
--- a/nuttx/drivers/Kconfig
+++ b/nuttx/drivers/Kconfig
@@ -320,10 +320,12 @@ menuconfig AUDIO_DEVICES
bool "Audio Device Support"
default n
---help---
- Enable support for audio device drivers.
- This includes drivers for MP3, WMA and Ogg Vorbis encoding,
- decoding, as well as drivers for interfacing with external
- DSP chips to perform custom audio functions.
+ Enable support for audio device drivers. This includes drivers for
+ MP3, WMA and Ogg Vorbis encoding, decoding, as well as drivers for
+ interfacing with external DSP chips to perform custom audio functions.
+
+ NOTE: All of these drivers depend on support from the audio subsystem
+ enabled with the AUDIO selection.
if AUDIO_DEVICES
source drivers/audio/Kconfig
diff --git a/nuttx/drivers/audio/Kconfig b/nuttx/drivers/audio/Kconfig
index 3e51751f9..53e6c24cf 100644
--- a/nuttx/drivers/audio/Kconfig
+++ b/nuttx/drivers/audio/Kconfig
@@ -6,7 +6,7 @@
config AUDIO_I2SCHAR
bool "I2S character driver (for testing only)"
default n
- depends on I2S
+ depends on I2S && AUDIO
---help---
This selection enables a simple character driver that supports I2S
transfers via a read() and write(). The intent of this driver is to
@@ -38,6 +38,7 @@ endif #AUDIO_I2SCHAR
config VS1053
bool "VS1053 codec chip"
default n
+ depends on AUDIO
---help---
Select to enable support for the VS1053 Audio codec by VLSI Solutions.
This chip provides encoding and decoding of MP3, WMA, AAC and Ogg
@@ -86,11 +87,11 @@ endif # VS1053
config AUDIO_WM8904
bool "WM8904 audio chip"
default n
- depends on EXPERIMENTAL
+ depends on AUDIO && EXPERIMENTAL
---help---
Select to enable support for the WM8904 Audio codec by Wolfson
Microelectonics. This chip is a lower level audio chip.. basically
- an exotic D-to-A. It includes no builtin support for audion CODECS
+ an exotic D-to-A. It includes no built-in support for audio CODECS
The WM8904 provides:
- Low power consumption
@@ -101,6 +102,9 @@ config AUDIO_WM8904
- 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_WM8904
endif # AUDIO_WM8904
diff --git a/nuttx/drivers/audio/wm8904.c b/nuttx/drivers/audio/wm8904.c
index 85ca5eea4..8029316cd 100644
--- a/nuttx/drivers/audio/wm8904.c
+++ b/nuttx/drivers/audio/wm8904.c
@@ -6,11 +6,11 @@
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
- * Reference:
- * "WM8904 Ultra Low Power CODEC for Portable Audio Applications, Pre-
+ * References:
+ * - "WM8904 Ultra Low Power CODEC for Portable Audio Applications, Pre-
* Production", September 2012, Rev 3.3, Wolfson Microelectronics
*
- * The framework for this driver is based on Ken Pettit's VS1053 driver.
+ * - The framework for this driver is based on Ken Pettit's VS1053 driver.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -96,7 +96,7 @@
# define CONFIG_WM8904_WORKER_STACKSIZE 768
#endif
-#define WM8904_DUMMY 0xFF
+#define WM8904_DUMMY 0xff
#define WM8904_DEFAULT_XTALI 12288000
#define WM8904_DATA_FREQ 20000000
#define WM8904_RST_USECS 2000
@@ -199,6 +199,13 @@ static int wm8904_cancelbuffer(FAR struct audio_lowerhalf_s *dev,
static int wm8904_ioctl(FAR struct audio_lowerhalf_s *dev, int cmd,
unsigned long arg);
+/* Initialization */
+
+static void wm8904_audio_output(FAR struct wm8904_dev_s *priv);
+#if 0 /* Not used */
+static void wm8904_audio_input(FAR struct wm8904_dev_s *priv);
+#endif
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -241,11 +248,71 @@ static const struct audio_ops_s g_audioops =
static uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr)
{
- FAR struct i2c_dev_s *i2c = priv->i2c;
- uint16_t regval;
-#warning Missing logic
- audvdbg("Read: %02x -> %04x\n", regaddr, regval);
- return regval;
+ int retries;
+
+ /* Try up to three times to read the register */
+
+ for (retries = 1; retries <= 3; retries++)
+ {
+ struct i2c_msg_s msg[2];
+ uint8_t data[2];
+ int ret;
+
+ /* Set up to write the address */
+
+ msg[0].addr = priv->lower->address;
+ msg[0].flags = 0;
+ msg[0].buffer = &regaddr;
+ msg[0].length = 1;
+
+ /* Followed by the read data */
+
+ msg[1].addr = priv->lower->address;
+ msg[1].flags = I2C_M_READ;
+ msg[1].buffer = data;
+ msg[1].length = 2;
+
+ /* Read the register data. The returned value is the number messages
+ * completed.
+ */
+
+ ret = I2C_TRANSFER(priv->i2c, msg, 2);
+ if (ret < 0)
+ {
+#ifdef CONFIG_I2C_RESET
+ /* Perhaps the I2C bus is locked up? Try to shake the bus free */
+
+ idbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret);
+
+ ret = up_i2creset(priv->i2c);
+ if (ret < 0)
+ {
+ idbg("ERROR: up_i2creset failed: %d\n", ret);
+ break;
+ }
+#else
+ idbg("ERROR: I2C_TRANSFER failed: %d\n", ret);
+#endif
+ }
+ else
+ {
+ uint16_t regval;
+
+ /* The I2C transfer was successful... break out of the loop and
+ * return the value read.
+ */
+
+ regval = ((uint16_t)data[0] << 8) | (uint16_t)data[1]
+ audvdbg("READ: %02x -> %04x\n", regaddr, regval);
+ return regval;
+ }
+
+ ivdbg("retries=%d regaddr=%04x\n", retries, regaddr);
+ }
+
+ /* No error indication is returned on a failure... just return zero */
+
+ return 0;
}
/************************************************************************************
@@ -256,18 +323,70 @@ static uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr)
*
************************************************************************************/
-static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr, uint16_t regval)
+static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr,
+ uint16_t regval)
{
- FAR struct i2c_dev_s *i2c = priv->i2c;
+ int retries;
+
+ /* Try up to three times to read the register */
+
+ for (retries = 1; retries <= 3; retries++)
+ {
+ struct i2c_msg_s msg[2];
+ uint8_t data[2];
+ int ret;
- /* Select the AUDIO_CTRL device on the I2C bus */
+ /* Set up to write the address */
- audvdbg("Write: %02x <- %04x\n", regaddr, regval);
-#warning "Missing logic"
+ msg[0].addr = priv->lower->address;
+ msg[0].flags = 0;
+ msg[0].buffer = &regaddr;
+ msg[0].length = 1;
- /* Short delay after a write for WM8904 processing time */
- /* REVISIT: Necessary for the WM8904? */
- usleep(10);
+ /* Followed by the read data */
+
+ data[0] = regval >> 8;
+ data[1] = regval & 0xff;
+
+ msg[1].addr = priv->lower->address;
+ msg[1].flags = I2C_M_NORESTART;
+ msg[1].buffer = data;
+ msg[1].length = 2;
+
+ /* Read the register data. The returned value is the number messages
+ * completed.
+ */
+
+ ret = I2C_TRANSFER(priv->i2c, msg, 2);
+ if (ret < 0)
+ {
+#ifdef CONFIG_I2C_RESET
+ /* Perhaps the I2C bus is locked up? Try to shake the bus free */
+
+ idbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret);
+
+ ret = up_i2creset(priv->i2c);
+ if (ret < 0)
+ {
+ idbg("ERROR: up_i2creset failed: %d\n", ret);
+ break;
+ }
+#else
+ idbg("ERROR: I2C_TRANSFER failed: %d\n", ret);
+#endif
+ }
+ else
+ {
+ /* The I2C transfer was successful... break out of the loop and
+ * return the value read.
+ */
+
+ audvdbg("Write: %02x <- %04x\n", regaddr, regval);
+ return;
+ }
+
+ ivdbg("retries=%d regaddr=%04x\n", retries, regaddr);
+ }
}
/************************************************************************************
@@ -1458,6 +1577,190 @@ static int wm8904_release(FAR struct audio_lowerhalf_s *dev)
}
/****************************************************************************
+ * Name: wm8904_audio_output
+ *
+ * Description:
+ * Initialize and configure the WM8904 device as an audio output device.
+ *
+ * Input Parameters:
+ * prive - A reference to the driver state structure
+ *
+ * Returned Value:
+ * None. No failures are detected.
+ *
+ ****************************************************************************/
+
+static void wm8904_audio_output(FAR struct wm8904_dev_s *priv)
+{
+ uint16_t regval;
+
+ /* Bias Control.
+ * Preserve undocumented default bit.WM8904_DUMMY
+ */
+
+ regval = WM8904_ISEL_HIGH | WM8904_BIAS_ENA | 0x0010;
+ wm8904_writereg(priv, WM8904_BIAS_CTRL, regval);
+
+ /* VMID Control */
+
+ regval = WM8904_VMID_BUF_ENA | WM8904_VMID_RES_NORMAL | WM8904_VMID_ENA;
+ wm8904_writereg(priv, WM8904_VMID_CTRL, regval);
+
+ /* Mic Bias Control 0 */
+ /* MICDET_ENA=1, MICBIAS_ENA=1 */
+
+ regval = WM8904_MICDET_ENA | WM8904_MICBIAS_ENA;
+ wm8904_writereg(priv, WM8904_MIC_BIAS_CTRL0, regval);
+
+ /* Mic Bias Control 1. */
+
+ wm8904_writereg(priv, WM8904_MIC_BIAS_CTRL1, 0xc000);
+
+ /* Power Management 0 */
+
+ regval = WM8904_INL_ENA | WM8904_INR_ENA;
+ wm8904_writereg(priv, WM8904_PM0, regval);
+
+ /* Power Management 2 */
+
+ regval = WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA;
+ wm8904_writereg(priv, WM8904_PM2, regval);
+
+ /* Power Management 6 */
+ /* DACL_ENA=1, DACR_ENA=1, ADCL_ENA=1, ADCR_ENA=1 */
+
+ regval = WM8904_DACL_ENA | WM8904_DACR_ENA | WM8904_ADCL_ENA | WM8904_ADCR_ENA;
+ wm8904_writereg(priv, WM8904_PM6, regval);
+
+ /* Clock Rates 0.
+ *
+ * This value sets TOCLK_RATE_DIV16=0, TOCLK_RATE_X4=0, and MCLK_DIV=0 while
+ * preserving the state of some undocumented bits (see wm8904.h).
+ */
+
+ wm8904_writereg(priv, WM8904_CLKRATE0, 0x845e);
+
+ /* Clock Rates 2 */
+
+ regval = WM8904_SYSCLK_SRC | WM8904_CLK_SYS_ENA | WM8904_CLK_DSP_ENA;
+ wm8904_writereg(priv, WM8904_CLKRATE2, regval);
+
+ /* Audio Interface 1.
+ *
+ * This value sets AIFADC_TDM=0, AIFADC_TDM_CHAN=0, BCLK_DIR=1 while preserving
+ * the state of some undocumented bits (see wm8904.h).
+ */
+
+ wm8904_writereg(priv, WM8904_AIF1, 0x404A);
+
+ /* Audio Interface 3 */
+
+ regval = WM8904_LRCLK_DIR | WM8904_LRCLK_RATE(64);
+ wm8904_writereg(priv, WM8904_AIF3, regval);
+
+ /* DAC Digital 1 */
+
+ wm8904_writereg(priv, WM8904_DAC_DIGI1, 0);
+
+ /* Analogue Left Input 0 */
+ /* Analogue Right Input 0 */
+
+ regval = WM8904_IN_VOL(5);
+ wm8904_writereg(priv, WM8904_ANA_LEFT_IN0, regval);
+ wm8904_writereg(priv, WM8904_ANA_RIGHT_IN0, regval);
+
+ /* Analogue Left Input 1 */
+
+ wm8904_writereg(priv, WM8904_ANA_LEFT_IN1, 0);
+ wm8904_writereg(priv, WM8904_ANA_RIGHT_IN1, 0);
+
+ /* Analogue OUT1 Right */
+
+ regval = WM8904_HPOUT_MUTE | WM8904_HPOUTZC | WM8904_HPOUT_VOL(29);
+ wm8904_writereg(priv, WM8904_ANA_RIGHT_OUT1, regval);
+
+ /* DC Servo 0 */
+ /* DCS_ENA_CHAN_1=1, DCS_ENA_CHAN_0=1 */
+
+ regval = WM8904_DCS_ENA_CHAN_1 | WM8904_DCS_ENA_CHAN_0;
+ wm8904_writereg(priv, WM8904_DC_SERVO0, regval);
+
+ /* Analogue HP 0 */
+
+ regval = WM8904_HPL_RMV_SHORT | WM8904_HPL_ENA_OUTP | WM8904_HPL_ENA_DLY | WM8904_HPL_ENA |
+ WM8904_HPR_RMV_SHORT | WM8904_HPR_ENA_OUTP | WM8904_HPR_ENA_DLY | WM8904_HPR_ENA;
+ wm8904_writereg(priv, WM8904_ANA_HP0, regval);
+
+ /* Charge Pump 0 */
+
+ wm8904_writereg(priv, WM8904_CHG_PUMP0, WM8904_CP_ENA);
+
+ /* Class W 0 */
+
+ regval = WM8904_CP_DYN_PWR | 0x0004;
+ wm8904_writereg(priv, WM8904_CLASS_W0, regval);
+
+ /* FLL Control 1 */
+
+ wm8904_writereg(priv, WM8904_FLL_CTRL1, 0);
+
+ regval = WM8904_FLL_FRACN_ENA | WM8904_FLL_ENA;
+ wm8904_writereg(priv, WM8904_FLL_CTRL1, regval);
+
+ /* FLL Control 2 */
+
+ regval = WM8904_FLL_OUTDIV(8) | WM8904_FLL_FRATIO_DIV16;
+ wm8904_writereg(priv, WM8904_FLL_CTRL2, regval);
+
+ /* FLL Control 3 */
+
+ wm8904_writereg(priv, WM8904_FLL_CTRL3, 16384);
+
+ /* FLL Control 4 */
+
+ regval = WM8904_FLL_N(187) | WM8904_FLL_GAIN_X1;
+ wm8904_writereg(priv, WM8904_FLL_CTRL4, regval);
+
+ wm8904_writereg(priv, WM8904_DUMMY, 0x55AA);
+}
+
+/****************************************************************************
+ * Name: wm8904_audio_input
+ *
+ * Description:
+ * Initialize and configure the WM8904 device as an audio output device
+ * (Right input only).
+ *
+ * Input Parameters:
+ * prive - A reference to the driver state structure
+ *
+ * Returned Value:
+ * None. No failures are detected.
+ *
+ ****************************************************************************/
+
+#if 0 /* Not used */
+static void wm8904_audio_input(FAR struct wm8904_dev_s *priv)
+{
+ /* Analogue Left Input 0 */
+
+ wm8904_writereg(priv, WM8904_ANA_LEFT_IN0, WM8904_INMUTE);
+
+ /* Analogue Right Input 0 */
+
+ wm8904_writereg(priv, WM8904_ANA_RIGHT_IN0, WM8904_IN_VOL(5));
+
+ /* Analogue Left Input 1 */
+
+ wm8904_writereg(priv, WM8904_ANA_LEFT_IN1, 0);
+
+ /* Analogue Right Input 1 */
+
+ wm8904_writereg(priv, WM8904_ANA_RIGHT_IN1, WM8904_IP_SEL_N_IN2L);
+}
+#endif
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -1485,6 +1788,7 @@ FAR struct audio_lowerhalf_s *
FAR const struct wm8904_lower_s *lower, unsigned int devno)
{
FAR struct wm8904_dev_s *priv;
+ uint16_t regval;
/* Sanity check */
@@ -1527,17 +1831,28 @@ FAR struct audio_lowerhalf_s *
I2C_SETFREQUENCY(i2c, lower->frequency);
I2C_SETADDRESS(i2c, lower->address, 7);
- /* Verify the device ID read from the chip */
-#warning Missing logic
+ /* Software reset */
- /* Initialize the WM8904 hardware */
-#warning Missing logic
+ wm8904_writereg(priv, WM8904_SWRST, 0);
+
+ /* Verify that WM8904 is present and available on this I2C */
+
+ regval = wm8904_readreg(priv, WM8904_ID);
+ if (regval != WM8904_SW_RST_DEV_ID1)
+ {
+ auddbg("ERROR: WM8904 not found: ID=%04x\n", regval);
+ return -ENODEV;
+ }
+WM8904_DUMMY
+ /* Configure the WM8904 hardware as an audio input device */
+
+ wm8904_audio_output(priv);
/* Attach our ISR to this device */
WM8904_ATTACH(lower, wm8904_interrupt, priv);
- /* Put the drive in the 'shutdown' status */
+ /* Put the driver in the 'shutdown' state */
wm8904_shutdown(&priv->dev);
}
diff --git a/nuttx/drivers/audio/wm8904.h b/nuttx/drivers/audio/wm8904.h
index 44829e7d9..366ef22f9 100644
--- a/nuttx/drivers/audio/wm8904.h
+++ b/nuttx/drivers/audio/wm8904.h
@@ -57,7 +57,8 @@
/* Registers Addresses ******************************************************/
-#define WM8904_SWRST_ID 0x00 /* SW Reset and ID */
+#define WM8904_SWRST 0x00 /* SW Reset and ID */
+#define WM8904_ID 0x00 /* SW Reset and ID */
#define WM8904_BIAS_CTRL 0x04 /* Bias Control */
#define WM8904_VMID_CTRL 0x05 /* VMID Control */
#define WM8904_MIC_BIAS_CTRL0 0x06 /* Mic Bias Control 0 */
@@ -77,7 +78,7 @@
#define WM8904_DAC_VOL_LEFT 0x1e /* DAC Digital Volume Left */
#define WM8904_DAC_VOL_RIGHT 0x1f /* DAC Digital Volume Right */
#define WM8904_DAC_DIGI0 0x20 /* DAC Digital 0 */
-#define WM8904_DATA_DIGI1 0x21 /* DAC Digital 1 */
+#define WM8904_DAC_DIGI1 0x21 /* DAC Digital 1 */
#define WM8904_ADC_VOL_LEFT 0x24 /* ADC Digital Volume Left */
#define WM8904_ADC_VOL_RIGHT 0x25 /* ADC Digital Volume Right */
#define WM8904_ADC_DIGI 0x26 /* ADC Digital */
@@ -156,6 +157,109 @@
#define WM8904_FLL_NCO_TEST0 0xf7 /* FLL NCO Test 0 */
#define WM8904_FLL_NCO_TEST1 0xf8 /* FLL NCO Test 1 */
+/* Register Default Values **************************************************/
+/* Registers have some undocumented bits set on power up. These probably
+ * should be retained on writes (?).
+ */
+
+#define WM8904_SWRST_DEFAULT 0x8904
+#define WM8904_ID_DEFAULT 0x0018
+#define WM8904_BIAS_CTRL_DEFAULT 0x0000
+#define WM8904_VMID_CTRL_DEFAULT 0x0000
+#define WM8904_MIC_BIAS_CTRL0_DEFAULT 0x0000
+#define WM8904_MIC_BIAS_CTRL1_DEFAULT 0x0000
+#define WM8904_ANALOG_ADC_DEFAULT 0x0001
+#define WM8904_PM0_DEFAULT 0x0000
+#define WM8904_PM2_DEFAULT 0x0000
+#define WM8904_PM3_DEFAULT 0x0000
+#define WM8904_PM6_DEFAULT 0x0000
+#define WM8904_CLKRATE0_DEFAULT 0x8c5e
+#define WM8904_CLKRATE1_DEFAULT 0x0c05
+#define WM8904_CLKRATE2_DEFAULT 0x0000
+#define WM8904_AIF0_DEFAULT 0x0050
+#define WM8904_AIF1_DEFAULT 0x000a
+#define WM8904_AIF2_DEFAULT 0x00e4
+#define WM8904_AIF3_DEFAULT 0x0040
+#define WM8904_DAC_VOL_LEFT_DEFAULT 0x00c0
+#define WM8904_DAC_VOL_RIGHT_DEFAULT 0x00c0
+#define WM8904_DAC_DIGI0_DEFAULT 0x0000
+#define WM8904_DAC_DIGI1_DEFAULT 0x0004
+#define WM8904_ADC_VOL_LEFT_DEFAULT 0x00c0
+#define WM8904_ADC_VOL_RIGHT_DEFAULT 0x00c0
+#define WM8904_ADC_DIGI_DEFAULT 0x0010
+#define WM8904_MIC_DIGI_DEFAULT 0x0000
+#define WM8904_DRC0_DEFAULT 0x01af
+#define WM8904_DRC1_DEFAULT 0x3248
+#define WM8904_DRC2_DEFAULT 0x0000
+#define WM8904_DRC3_DEFAULT 0x0000
+#define WM8904_ANA_LEFT_IN0_DEFAULT 0x0085
+#define WM8904_ANA_RIGHT_IN0_DEFAULT 0x0085
+#define WM8904_ANA_LEFT_IN1_DEFAULT 0x0044
+#define WM8904_ANA_RIGHT_IN1_DEFAULT 0x0044
+#define WM8904_ANA_LEFT_OUT1_DEFAULT 0x002d
+#define WM8904_ANA_RIGHT_OUT1_DEFAULT 0x002d
+#define WM8904_ANA_LEFT_OUT2_DEFAULT 0x0039
+#define WM8904_ANA_RIGHT_OUT2_DEFAULT 0x0039
+#define WM8904_ANA_OUT12_ZC_DEFAULT 0x0000
+#define WM8904_DC_SERVO0_DEFAULT 0x0000
+#define WM8904_DC_SERVO2_DEFAULT 0xaaaa
+#define WM8904_DC_SERVO4_DEFAULT 0xaaaa
+#define WM8904_DC_SERVO5_DEFAULT 0xaaaa
+#define WM8904_DC_SERVO6_DEFAULT 0x0000
+#define WM8904_DC_SERVO7_DEFAULT 0x0000
+#define WM8904_DC_SERVO8_DEFAULT 0x0000
+#define WM8904_DC_SERVO9_DEFAULT 0x0000
+#define WM8904_DC_SERVO_RDBACK_DEFAULT 0x0000
+#define WM8904_ANA_HP0_DEFAULT 0x0000
+#define WM8904_ANA_LINEOUT0_DEFAULT 0x0000
+#define WM8904_CHG_PUMP0_DEFAULT 0x0000
+#define WM8904_CLASS_W0_DEFAULT 0x0000
+#define WM8904_WR_SEQ0_DEFAULT 0x0000
+#define WM8904_WR_SEQ1_DEFAULT 0x0000
+#define WM8904_WR_SEQ2_DEFAULT 0x0000
+#define WM8904_WR_SEQ3_DEFAULT 0x0000
+#define WM8904_WR_SEQ4_DEFAULT 0x0000
+#define WM8904_FLL_CTRL1_DEFAULT 0x0000
+#define WM8904_FLL_CTRL2_DEFAULT 0x0007
+#define WM8904_FLL_CTRL3_DEFAULT 0x0000
+#define WM8904_FLL_CTRL4_DEFAULT 0x2ee0
+#define WM8904_FLL_CTRL5_DEFAULT 0x0004
+#define WM8904_GPIO_CTRL1_DEFAULT 0x0014
+#define WM8904_GPIO_CTRL2_DEFAULT 0x0010
+#define WM8904_GPIO_CTRL3_DEFAULT 0x0010
+#define WM8904_GPIO_CTRL4_DEFAULT 0x0000
+#define WM8904_DIGI_PULLS_DEFAULT 0x0000
+#define WM8904_INT_MASK_DEFAULT 0xffff
+#define WM8904_INT_POL_DEFAULT 0x0000
+#define WM8904_INT_DEBOUNCE_DEFAULT 0x0000
+#define WM8904_EQ1_DEFAULT 0x0000
+#define WM8904_EQ2_DEFAULT 0x000c
+#define WM8904_EQ3_DEFAULT 0x000c
+#define WM8904_EQ4_DEFAULT 0x000c
+#define WM8904_EQ5_DEFAULT 0x000c
+#define WM8904_EQ6_DEFAULT 0x000c
+#define WM8904_EQ7_DEFAULT 0x0fca
+#define WM8904_EQ8_DEFAULT 0x0400
+#define WM8904_EQ9_DEFAULT 0x00d8
+#define WM8904_EQ10_DEFAULT 0x1eb5
+#define WM8904_EQ11_DEFAULT 0xf145
+#define WM8904_EQ12_DEFAULT 0x0b75
+#define WM8904_EQ13_DEFAULT 0x01c5
+#define WM8904_EQ14_DEFAULT 0x1c54
+#define WM8904_EQ15_DEFAULT 0xf373
+#define WM8904_EQ16_DEFAULT 0x0a54
+#define WM8904_EQ17_DEFAULT 0x0558
+#define WM8904_EQ18_DEFAULT 0x168e
+#define WM8904_EQ19_DEFAULT 0xf829
+#define WM8904_EQ20_DEFAULT 0x07ad
+#define WM8904_EQ21_DEFAULT 0x1103
+#define WM8904_EQ22_DEFAULT 0x0564
+#define WM8904_EQ23_DEFAULT 0x0559
+#define WM8904_EQ24_DEFAULT 0x4000
+#define WM8904_ADC_TEST_DEFAULT 0x0000
+#define WM8904_FLL_NCO_TEST0_DEFAULT 0x0000
+#define WM8904_FLL_NCO_TEST1_DEFAULT 0x0019
+
/* Register Bit Definitions *************************************************/
/* 0x00 SW Reset and ID */