summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-12-08 21:09:56 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-12-08 21:09:56 +0000
commitea929a3e4547e9c709560803d2cea760ffe3e6a3 (patch)
tree103138e5dae99ed1c7d2ae7c9da72cbbf072de60
parented96b2a4ddf39b91621e125a95380d3a23a1cc73 (diff)
downloadrockbox-ea929a3e4547e9c709560803d2cea760ffe3e6a3.zip
rockbox-ea929a3e4547e9c709560803d2cea760ffe3e6a3.tar.gz
rockbox-ea929a3e4547e9c709560803d2cea760ffe3e6a3.tar.bz2
rockbox-ea929a3e4547e9c709560803d2cea760ffe3e6a3.tar.xz
Have drivers merged for WM8711/21/31 since they are so similar but respect all register differences between codecs. Change minis to #define the actual codec type. If anything breaks check if OSCPD and CLKOUTPD need to be clear for the target- H10 is fine. A nice naming convention suggestion for WM codec multidrivers would be welcome rather than naming for a specific chip.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19367 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES6
-rw-r--r--firmware/drivers/audio/wm8721.c184
-rw-r--r--firmware/drivers/audio/wm8731.c194
-rw-r--r--firmware/export/audiohw.h5
-rw-r--r--firmware/export/config-ipodmini.h2
-rw-r--r--firmware/export/config-ipodmini2g.h4
-rw-r--r--firmware/export/wm8721.h106
-rw-r--r--firmware/export/wm8731.h139
-rw-r--r--firmware/sound.c19
-rw-r--r--firmware/target/arm/pcm-pp.c3
10 files changed, 220 insertions, 442 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 752db73..3fadec0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -230,9 +230,9 @@ drivers/audio/wm8975.c
drivers/audio/wm8985.c
#elif defined(HAVE_WM8758)
drivers/audio/wm8758.c
-#elif defined(HAVE_WM8721)
-drivers/audio/wm8721.c
-#elif defined(HAVE_WM8731)
+#elif defined(HAVE_WM8711) \
+ || defined(HAVE_WM8721) \
+ || defined(HAVE_WM8731)
drivers/audio/wm8731.c
#elif defined(HAVE_AS3514)
drivers/audio/as3514.c
diff --git a/firmware/drivers/audio/wm8721.c b/firmware/drivers/audio/wm8721.c
deleted file mode 100644
index 3f14ca4..0000000
--- a/firmware/drivers/audio/wm8721.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Driver for WM8721 audio codec
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in January 2006
- *
- * Original file: linux/arch/armnommu/mach-ipod/audio.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "config.h"
-#include "logf.h"
-#include "system.h"
-#include "string.h"
-#include "audio.h"
-
-#include "wmcodec.h"
-#include "audiohw.h"
-
-#define IPOD_PCM_LEVEL 0x65 /* -6dB */
-
-/* use zero crossing to reduce clicks during volume changes */
-#define VOLUME_ZC_WAIT (1<<7)
-
-const struct sound_settings_info audiohw_settings[] = {
- [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
- /* HAVE_SW_TONE_CONTROLS */
- [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
- [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
- [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
- [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
- [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
-};
-
-/* convert tenth of dB volume (-730..60) to master volume register value */
-int tenthdb2master(int db)
-{
- /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
- /* 1111111 == +6dB (0x7f) */
- /* 1111001 == 0dB (0x79) */
- /* 0110000 == -73dB (0x30 */
- /* 0101111 == mute (0x2f) */
-
- if (db < VOLUME_MIN) {
- return 0x2f;
- } else {
- return((db/10)+0x30+73);
- }
-}
-
-void audiohw_mute(bool mute)
-{
- if (mute)
- {
- /* Set DACMU = 1 to soft-mute the audio DACs. */
- wmcodec_write(DAPCTRL, 0x8);
- } else {
- /* Set DACMU = 0 to soft-un-mute the audio DACs. */
- wmcodec_write(DAPCTRL, 0x0);
- }
-}
-
-/** From ipodLinux **/
-static void codec_set_active(int active)
-{
- /* set active to 0x0 or 0x1 */
- if (active) {
- wmcodec_write(ACTIVECTRL, 0x01);
- } else {
- wmcodec_write(ACTIVECTRL, 0x00);
- }
-}
-
-
-/* Silently enable / disable audio output */
-void audiohw_preinit(void)
-{
- wmcodec_write(RESET, 0x0); /*Reset*/
-
- codec_set_active(0x0);
-
- /* DACSEL=1 */
- wmcodec_write(0x4, 0x10);
-
- /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */
- wmcodec_write(PDCTRL, 0x67);
-
- /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
- /* IWL=00(16 bit) FORMAT=10(I2S format) */
- wmcodec_write(AINTFCE, 0x42);
-
- audiohw_set_sample_rate(WM8721_USB24_44100HZ);
-
- /* set the volume to -6dB */
- wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL);
- wmcodec_write(ROUTVOL, 0x100 | IPOD_PCM_LEVEL);
-
- /* ACTIVE=1 */
- codec_set_active(1);
-
- /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */
- wmcodec_write(DAPCTRL, 0x0);
-}
-
-void audiohw_postinit(void)
-{
- audiohw_mute(0);
-}
-
-void audiohw_set_master_vol(int vol_l, int vol_r)
-{
- /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
- /* 1111111 == +6dB */
- /* 1111001 == 0dB */
- /* 0110000 == -73dB */
- /* 0101111 == mute (0x2f) */
- wmcodec_write(LOUTVOL, VOLUME_ZC_WAIT | vol_l);
- wmcodec_write(ROUTVOL, VOLUME_ZC_WAIT | vol_r);
-}
-
-/* Nice shutdown of WM8721 codec */
-void audiohw_close(void)
-{
- /* set DACMU=1 DEEMPH=0 */
- wmcodec_write(DAPCTRL, 0x8);
-
- /* ACTIVE=0 */
- codec_set_active(0x0);
-
- /* set DACSEL=0, MUTEMIC=1 */
- wmcodec_write(0x4, 0x2);
-
- /* set POWEROFF=0 OUTPD=0 DACPD=1 */
- wmcodec_write(PDCTRL, 0x6f);
-
- /* set POWEROFF=1 OUTPD=1 DACPD=1 */
- wmcodec_write(PDCTRL, 0xff);
-}
-
-void audiohw_set_sample_rate(int sampling_control)
-{
- int rate = 0;
- switch(sampling_control)
- {
- case SAMPR_96:
- rate = WM8721_USB24_96000HZ;
- break;
- case SAMPR_88:
- rate = WM8721_USB24_88200HZ;
- break;
- case SAMPR_48:
- rate = WM8721_USB24_48000HZ;
- break;
- case SAMPR_44:
- rate = WM8721_USB24_44100HZ;
- break;
- case SAMPR_32:
- rate = WM8721_USB24_32000HZ;
- break;
- case SAMPR_8:
- rate = WM8721_USB24_8000HZ;
- break;
- }
- codec_set_active(0x0);
- wmcodec_write(SAMPCTRL, rate);
- codec_set_active(0x1);
-}
diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c
index 2f882e8..3cfd3e4 100644
--- a/firmware/drivers/audio/wm8731.c
+++ b/firmware/drivers/audio/wm8731.c
@@ -7,7 +7,7 @@
* \/ \/ \/ \/ \/
* $Id$
*
- * Driver for WM8731L audio codec
+ * Driver for WM8711/WM8721/WM8731 audio codecs
*
* Based on code from the ipodlinux project - http://ipodlinux.org/
* Adapted for Rockbox in January 2006
@@ -43,7 +43,7 @@ const struct sound_settings_info audiohw_settings[] = {
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
-#ifdef HAVE_RECORDING
+#if defined(HAVE_WM8731) && defined(HAVE_RECORDING)
[SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
[SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
[SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0},
@@ -53,42 +53,57 @@ const struct sound_settings_info audiohw_settings[] = {
/* Init values/shadows
* Ignore bit 8 since that only specifies "both" for updating
* gains - "RESET" (15h) not included */
-static unsigned char wm8731_regs[WM8731_NUM_REGS] =
+static unsigned char wmc_regs[WMC_NUM_REGS] =
{
- [LINVOL] = 0x97,
- [RINVOL] = 0x97,
- [LOUTVOL] = 0x79 | ROUTVOL_RZCEN,
- [ROUTVOL] = 0x79 | ROUTVOL_RZCEN,
- [AAPCTRL] = 0x0a,
- [DAPCTRL] = 0x08,
- [PDCTRL] = 0x9f,
- [AINTFCE] = 0x0a,
- [SAMPCTRL] = 0x00,
- [ACTIVECTRL] = 0x00,
+#ifdef HAVE_WM8731
+ [LINVOL] = LINVOL_DEFAULT,
+ [RINVOL] = RINVOL_DEFAULT,
+#endif
+ [LOUTVOL] = LOUTVOL_DEFAULT | WMC_OUT_ZCEN,
+ [ROUTVOL] = LOUTVOL_DEFAULT | WMC_OUT_ZCEN,
+#if defined(HAVE_WM8711) || defined(HAVE_WM8731)
+ /* BYPASS on by default - OFF until needed */
+ [AAPCTRL] = AAPCTRL_DEFAULT & ~AAPCTRL_BYPASS,
+ /* CLKOUT and OSC on by default - OFF unless needed by a target */
+ [PDCTRL] = PDCTRL_DEFAULT | PDCTRL_CLKOUTPD | PDCTRL_OSCPD,
+#elif defined(HAVE_WM8721)
+ /* No BYPASS */
+ [AAPCTRL] = AAPCTRL_DEFAULT,
+ /* No CLKOUT or OSC */
+ [PDCTRL] = PDCTRL_DEFAULT,
+#endif
+ [DAPCTRL] = DAPCTRL_DEFAULT,
+#ifndef CODEC_SLAVE
+ [AINTFCE] = AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT | AINTFCE_MS,
+#else
+ [AINTFCE] = AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT,
+#endif
+ [SAMPCTRL] = SAMPCTRL_DEFAULT,
+ [ACTIVECTRL] = ACTIVECTRL_DEFAULT,
};
-static void wm8731_write(int reg, unsigned val)
+static void wmc_write(int reg, unsigned val)
{
- if ((unsigned)reg >= WM8731_NUM_REGS)
+ if ((unsigned)reg >= WMC_NUM_REGS)
return;
- wm8731_regs[reg] = (unsigned char)val;
+ wmc_regs[reg] = (unsigned char)val;
wmcodec_write(reg, val);
}
-static void wm8731_set(int reg, unsigned bits)
+static void wmc_set(int reg, unsigned bits)
{
- wm8731_write(reg, wm8731_regs[reg] | bits);
+ wmc_write(reg, wmc_regs[reg] | bits);
}
-static void wm8731_clear(int reg, unsigned bits)
+static void wmc_clear(int reg, unsigned bits)
{
- wm8731_write(reg, wm8731_regs[reg] & ~bits);
+ wmc_write(reg, wmc_regs[reg] & ~bits);
}
-static void wm8731_write_masked(int reg, unsigned bits, unsigned mask)
+static void wmc_write_masked(int reg, unsigned bits, unsigned mask)
{
- wm8731_write(reg, (wm8731_regs[reg] & ~mask) | (bits & mask));
+ wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask));
}
/* convert tenth of dB volume (-730..60) to master volume register value */
@@ -134,54 +149,50 @@ void audiohw_mute(bool mute)
{
if (mute) {
/* Set DACMU = 1 to soft-mute the audio DACs. */
- wm8731_set(DAPCTRL, DAPCTRL_DACMU);
+ wmc_set(DAPCTRL, DAPCTRL_DACMU);
} else {
/* Set DACMU = 0 to soft-un-mute the audio DACs. */
- wm8731_clear(DAPCTRL, DAPCTRL_DACMU);
+ wmc_clear(DAPCTRL, DAPCTRL_DACMU);
}
}
static void codec_set_active(int active)
{
/* set active to 0x0 or 0x1 */
- wm8731_write(ACTIVECTRL, active ? ACTIVECTRL_ACTIVE : 0);
+ wmc_write(ACTIVECTRL, active ? ACTIVECTRL_ACTIVE : 0);
}
void audiohw_preinit(void)
{
/* POWER UP SEQUENCE */
- /* 1) Switch on power supplies. By default the WM8731 is in Standby Mode,
+ /* 1) Switch on power supplies. By default the WM codec is in Standby Mode,
* the DAC is digitally muted and the Audio Interface and Outputs are
* all OFF. */
wmcodec_write(RESET, RESET_RESET);
/* 2) Set all required bits in the Power Down register (0Ch) to '0';
* EXCEPT the OUTPD bit, this should be set to '1' (Default). */
- wm8731_clear(PDCTRL, PDCTRL_DACPD | PDCTRL_POWEROFF);
+ wmc_clear(PDCTRL, PDCTRL_DACPD | PDCTRL_POWEROFF);
/* 3) Set required values in all other registers except 12h (Active). */
- wm8731_write(AINTFCE,
-#ifndef CODEC_SLAVE
- AINTFCE_MS |
-#endif
- AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT);
+ wmc_set(AINTFCE, 0); /* Set no bits - write init/shadow value */
- wm8731_set(AAPCTRL, AAPCTRL_DACSEL);
- wm8731_write(SAMPCTRL, WM8731_USB24_44100HZ);
+ wmc_set(AAPCTRL, AAPCTRL_DACSEL);
+ wmc_write(SAMPCTRL, WMC_USB24_44100HZ);
+
+ /* 4) Set the 'Active' bit in register 12h. */
+ codec_set_active(true);
/* 5) The last write of the sequence should be setting OUTPD to '0'
* (active) in register 0Ch, enabling the DAC signal path, free
* of any significant power-up noise. */
- wm8731_clear(PDCTRL, PDCTRL_OUTPD);
+ wmc_clear(PDCTRL, PDCTRL_OUTPD);
}
void audiohw_postinit(void)
{
sleep(HZ);
- /* 4) Set the 'Active' bit in register 12h. */
- codec_set_active(true);
-
audiohw_mute(false);
#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
@@ -197,51 +208,53 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
/* 1111001 == 0dB */
/* 0110000 == -73dB */
/* 0101111 == mute (0x2f) */
- wm8731_write_masked(LOUTVOL, vol_l, LOUTVOL_LHPVOL_MASK);
- wm8731_write_masked(ROUTVOL, vol_r, ROUTVOL_RHPVOL_MASK);
+ wmc_write_masked(LOUTVOL, vol_l, WMC_OUT_VOL_MASK);
+ wmc_write_masked(ROUTVOL, vol_r, WMC_OUT_VOL_MASK);
}
-/* Nice shutdown of WM8731 codec */
+/* Nice shutdown of WM codec */
void audiohw_close(void)
{
/* POWER DOWN SEQUENCE */
/* 1) Set the OUTPD bit to '1' (power down). */
- wm8731_set(PDCTRL, PDCTRL_OUTPD);
- /* 2) Remove the WM8731 supplies. */
+ wmc_set(PDCTRL, PDCTRL_OUTPD);
+ /* 2) Remove the WM codec supplies. */
}
void audiohw_set_sample_rate(int sampling_control)
{
- int rate = 0;
+ int rate;
switch(sampling_control)
{
case SAMPR_96:
- rate = WM8731_USB24_96000HZ;
+ rate = WMC_USB24_96000HZ;
break;
case SAMPR_88:
- rate = WM8731_USB24_88200HZ;
+ rate = WMC_USB24_88200HZ;
break;
case SAMPR_48:
- rate = WM8731_USB24_48000HZ;
+ rate = WMC_USB24_48000HZ;
break;
+ default:
case SAMPR_44:
- rate = WM8731_USB24_44100HZ;
+ rate = WMC_USB24_44100HZ;
break;
case SAMPR_32:
- rate = WM8731_USB24_32000HZ;
+ rate = WMC_USB24_32000HZ;
break;
case SAMPR_8:
- rate = WM8731_USB24_8000HZ;
+ rate = WMC_USB24_8000HZ;
break;
}
codec_set_active(false);
- wm8731_write(SAMPCTRL, rate);
+ wmc_write(SAMPCTRL, rate);
codec_set_active(true);
}
-#ifdef HAVE_RECORDING
+#if defined(HAVE_WM8731) && defined(HAVE_RECORDING)
+/* WM8731 only */
void audiohw_enable_recording(bool source_mic)
{
/* NOTE: When switching to digital monitoring we will not want
@@ -250,27 +263,27 @@ void audiohw_enable_recording(bool source_mic)
codec_set_active(false);
if (source_mic) {
- wm8731_set(LINVOL, LINVOL_LINMUTE);
- wm8731_set(RINVOL, RINVOL_RINMUTE);
-
- wm8731_write_masked(PDCTRL, PDCTRL_LINEINPD | PDCTRL_DACPD,
- PDCTRL_LINEINPD | PDCTRL_MICPD |
- PDCTRL_ADCPD | PDCTRL_DACPD);
- wm8731_write_masked(AAPCTRL, AAPCTRL_INSEL | AAPCTRL_SIDETONE,
- AAPCTRL_MUTEMIC | AAPCTRL_INSEL |
- AAPCTRL_BYPASS | AAPCTRL_DACSEL |
- AAPCTRL_SIDETONE);
+ wmc_set(LINVOL, WMC_IN_MUTE);
+ wmc_set(RINVOL, WMC_IN_MUTE);
+
+ wmc_write_masked(PDCTRL, PDCTRL_LINEINPD | PDCTRL_DACPD,
+ PDCTRL_LINEINPD | PDCTRL_MICPD |
+ PDCTRL_ADCPD | PDCTRL_DACPD);
+ wmc_write_masked(AAPCTRL, AAPCTRL_INSEL | AAPCTRL_SIDETONE,
+ AAPCTRL_MUTEMIC | AAPCTRL_INSEL |
+ AAPCTRL_BYPASS | AAPCTRL_DACSEL |
+ AAPCTRL_SIDETONE);
} else {
- wm8731_write_masked(PDCTRL, PDCTRL_MICPD | PDCTRL_DACPD,
- PDCTRL_LINEINPD | PDCTRL_MICPD |
- PDCTRL_ADCPD | PDCTRL_DACPD);
- wm8731_write_masked(AAPCTRL, AAPCTRL_MUTEMIC | AAPCTRL_BYPASS,
- AAPCTRL_MUTEMIC | AAPCTRL_INSEL |
- AAPCTRL_BYPASS | AAPCTRL_DACSEL |
- AAPCTRL_SIDETONE);
-
- wm8731_clear(LINVOL, LINVOL_LINMUTE);
- wm8731_clear(RINVOL, RINVOL_RINMUTE);
+ wmc_write_masked(PDCTRL, PDCTRL_MICPD | PDCTRL_DACPD,
+ PDCTRL_LINEINPD | PDCTRL_MICPD |
+ PDCTRL_ADCPD | PDCTRL_DACPD);
+ wmc_write_masked(AAPCTRL, AAPCTRL_MUTEMIC | AAPCTRL_BYPASS,
+ AAPCTRL_MUTEMIC | AAPCTRL_INSEL |
+ AAPCTRL_BYPASS | AAPCTRL_DACSEL |
+ AAPCTRL_SIDETONE);
+
+ wmc_clear(LINVOL, WMC_IN_MUTE);
+ wmc_clear(RINVOL, WMC_IN_MUTE);
}
codec_set_active(true);
@@ -281,21 +294,21 @@ void audiohw_disable_recording(void)
codec_set_active(false);
/* Mute line inputs */
- wm8731_set(LINVOL, LINVOL_LINMUTE);
- wm8731_set(RINVOL, RINVOL_RINMUTE);
- wm8731_set(AAPCTRL, AAPCTRL_MUTEMIC);
+ wmc_set(LINVOL, WMC_IN_MUTE);
+ wmc_set(RINVOL, WMC_IN_MUTE);
+ wmc_set(AAPCTRL, AAPCTRL_MUTEMIC);
/* Turn off input analog audio paths */
- wm8731_clear(AAPCTRL, AAPCTRL_BYPASS | AAPCTRL_SIDETONE);
+ wmc_clear(AAPCTRL, AAPCTRL_BYPASS | AAPCTRL_SIDETONE);
/* Set power config */
- wm8731_write_masked(PDCTRL,
- PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_ADCPD,
- PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_DACPD |
- PDCTRL_ADCPD);
+ wmc_write_masked(PDCTRL,
+ PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_ADCPD,
+ PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_DACPD |
+ PDCTRL_ADCPD);
/* Select DAC */
- wm8731_set(AAPCTRL, AAPCTRL_DACSEL);
+ wmc_set(AAPCTRL, AAPCTRL_DACSEL);
codec_set_active(true);
}
@@ -306,15 +319,15 @@ void audiohw_set_recvol(int left, int right, int type)
{
case AUDIO_GAIN_MIC:
if (left > 0) {
- wm8731_set(AAPCTRL, AAPCTRL_MIC_BOOST);
+ wmc_set(AAPCTRL, AAPCTRL_MIC_BOOST);
}
else {
- wm8731_clear(AAPCTRL, AAPCTRL_MIC_BOOST);
+ wmc_clear(AAPCTRL, AAPCTRL_MIC_BOOST);
}
break;
case AUDIO_GAIN_LINEIN:
- wm8731_write_masked(LINVOL, left, LINVOL_MASK);
- wm8731_write_masked(RINVOL, right, RINVOL_MASK);
+ wmc_write_masked(LINVOL, left, WMC_IN_VOL_MASK);
+ wmc_write_masked(RINVOL, right, WMC_IN_VOL_MASK);
break;
default:
return;
@@ -324,13 +337,12 @@ void audiohw_set_recvol(int left, int right, int type)
void audiohw_set_monitor(bool enable)
{
if(enable) {
- wm8731_clear(PDCTRL, PDCTRL_LINEINPD);
- wm8731_set(AAPCTRL, AAPCTRL_BYPASS);
+ wmc_clear(PDCTRL, PDCTRL_LINEINPD);
+ wmc_set(AAPCTRL, AAPCTRL_BYPASS);
}
else {
- wm8731_clear(AAPCTRL, AAPCTRL_BYPASS);
- wm8731_set(PDCTRL, PDCTRL_LINEINPD);
+ wmc_clear(AAPCTRL, AAPCTRL_BYPASS);
+ wmc_set(PDCTRL, PDCTRL_LINEINPD);
}
}
-#endif /* HAVE_RECORDING */
-
+#endif /* HAVE_WM8731 && HAVE_RECORDING */
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index b82c27e..51aec65 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -46,9 +46,8 @@
#include "wm8985.h"
#elif defined(HAVE_WM8758)
#include "wm8758.h"
-#elif defined(HAVE_WM8721)
-#include "wm8721.h"
-#elif defined(HAVE_WM8731)
+#elif defined(HAVE_WM8711) || defined(HAVE_WM8721) || \
+ defined(HAVE_WM8731)
#include "wm8731.h"
#elif defined(HAVE_TLV320)
#include "tlv320.h"
diff --git a/firmware/export/config-ipodmini.h b/firmware/export/config-ipodmini.h
index c2d6376..5d7781a 100644
--- a/firmware/export/config-ipodmini.h
+++ b/firmware/export/config-ipodmini.h
@@ -85,7 +85,7 @@
#define PLUGIN_BUFFER_SIZE 0x80000
/* Define this if you have the WM8721 audio codec */
-#define HAVE_WM8721 /* actually WM8731 but no recording */
+#define HAVE_WM8731
/* WM8721 has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
diff --git a/firmware/export/config-ipodmini2g.h b/firmware/export/config-ipodmini2g.h
index 6d6ebf1..dbbbc43 100644
--- a/firmware/export/config-ipodmini2g.h
+++ b/firmware/export/config-ipodmini2g.h
@@ -84,8 +84,8 @@
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
-/* Define this if you have the WM8721 audio codec */
-#define HAVE_WM8721 /* actually WM8731 but no recording */
+/* Define this if you have the WM8711 audio codec */
+#define HAVE_WM8711
/* WM8721 has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
diff --git a/firmware/export/wm8721.h b/firmware/export/wm8721.h
deleted file mode 100644
index 8145356..0000000
--- a/firmware/export/wm8721.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2005 by Dave Chapman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#ifndef _WM8721_H
-#define _WM8721_H
-
-/* volume/balance/treble/bass interdependency */
-#define VOLUME_MIN -730
-#define VOLUME_MAX 60
-
-extern int tenthdb2master(int db);
-
-extern void audiohw_set_master_vol(int vol_l, int vol_r);
-extern void audiohw_set_sample_rate(int sampling_control);
-
-/* Register addresses and bits */
-#define LOUTVOL 0x02
-#define LOUTVOL_LHPVOL_MASK 0x7f
-#define LOUTVOL_LZCEN (1 << 7)
-#define LOUTVOL_LRHPBOTH (1 << 8)
-
-#define ROUTVOL 0x03
-#define ROUTVOL_RHPVOL_MASK 0x7f
-#define ROUTVOL_RZCEN (1 << 7)
-#define ROUTVOL_RLHPBOTH (1 << 8)
-
-#define AAPCTRL 0x04 /* Analog audio path control */
-#define AAPCTRL_DACSEL (1 << 4)
-
-#define DAPCTRL 0x05 /* Digital audio path control */
-#define DAPCTRL_DEEMP_DISABLE (0 << 2)
-#define DAPCTRL_DEEMP_32KHz (1 << 2)
-#define DAPCTRL_DEEMP_44KHz (2 << 2)
-#define DAPCTRL_DEEMP_48KHz (3 << 2)
-#define DAPCTRL_DEEMP_MASK (3 << 2)
-#define DAPCTRL_DACMU (1 << 3)
-
-#define PDCTRL 0x06
-#define PDCTRL_DACPD (1 << 3)
-#define PDCTRL_OUTPD (1 << 4)
-#define PDCTRL_POWEROFF (1 << 7)
-
-#define AINTFCE 0x07
-#define AINTFCE_FORMAT_MSB_RJUST (0 << 0)
-#define AINTFCE_FORMAT_MSB_LJUST (1 << 0)
-#define AINTFCE_FORMAT_I2S (2 << 0)
-#define AINTFCE_FORMAT_DSP (3 << 0)
-#define AINTFCE_FORMAT_MASK (3 << 0)
-#define AINTFCE_IWL_16BIT (0 << 2)
-#define AINTFCE_IWL_20BIT (1 << 2)
-#define AINTFCE_IWL_24BIT (2 << 2)
-#define AINTFCE_IWL_32BIT (3 << 2)
-#define AINTFCE_IWL_MASK (3 << 2)
-#define AINTFCE_LRP_I2S_RLO (0 << 4)
-#define AINTFCE_LRP_I2S_RHI (1 << 4)
-#define AINTFCE_DSP_MODE_B (0 << 4)
-#define AINTFCE_DSP_MODE_A (1 << 4)
-#define AINTFCE_LRSWAP (1 << 5)
-#define AINTFCE_MS (1 << 6)
-#define AINTFCE_BCLKINV (1 << 7)
-
-#define SAMPCTRL 0x08
-#define SAMPCTRL_USB (1 << 0)
-#define SAMPCTRL_BOSR_NOR_256fs (0 << 1)
-#define SAMPCTRL_BOSR_NOR_384fs (1 << 1)
-#define SAMPCTRL_BOSR_USB_250fs (0 << 1)
-#define SAMPCTRL_BOSR_USB_272fs (1 << 1)
-/* Bits 2-5:
- * Sample rate setting are device-specific. See WM8721 datasheet
- * for proper settings for the device's clocking */
-#define SAMPCTRL_SR_MASK (0xf << 2)
-#define SAMPCTRL_CLKIDIV2 (1 << 6)
-
-#define ACTIVECTRL 0x09
-#define ACTIVECTRL_ACTIVE (1 << 0)
-
-#define RESET 0x0f
-#define RESET_RESET 0x0
-
-/* SAMPCTRL values for the supported samplerates (24MHz MCLK/USB): */
-#define WM8721_USB24_8000HZ 0x4d
-#define WM8721_USB24_32000HZ 0x59
-#define WM8721_USB24_44100HZ 0x63
-#define WM8721_USB24_48000HZ 0x41
-#define WM8721_USB24_88200HZ 0x7f
-#define WM8721_USB24_96000HZ 0x5d
-
-#endif /* _WM8721_H */
diff --git a/firmware/export/wm8731.h b/firmware/export/wm8731.h
index 2ea479f..9d5b618 100644
--- a/firmware/export/wm8731.h
+++ b/firmware/export/wm8731.h
@@ -9,6 +9,8 @@
*
* Copyright (C) 2005 by Dave Chapman
*
+ * Header file for WM8711/WM8721/WM8731 codecs.
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -31,105 +33,154 @@ extern int tenthdb2master(int db);
extern void audiohw_set_master_vol(int vol_l, int vol_r);
extern void audiohw_set_sample_rate(int sampling_control);
+/* Common register bits */
+#ifdef HAVE_WM8731
+#define WMC_IN_VOL_MASK 0x1f
+#define WMC_IN_VOL(x) ((x) & WMC_IN_VOL_MASK)
+#define WMC_IN_MUTE (1 << 7)
+#endif /* WM8731 */
+
+#define WMC_OUT_VOL_MASK 0x7f
+#define WMC_OUT_VOL(x) ((x) & WMC_OUT_VOL_MASK)
+#define WMC_OUT_ZCEN (1 << 7)
+
+#define WMC_BOTH (1 << 8)
+
/* Register addresses and bits */
+#ifdef HAVE_WM8731
#define LINVOL 0x00
-#define LINVOL_MASK 0x1f
-#define LINVOL_LRINBOTH (1 << 8)
-#define LINVOL_LINMUTE (1 << 7)
+#define LINVOL_DEFAULT 0x79
+/* Use IN common bits */
#define RINVOL 0x01
-#define RINVOL_MASK 0x1f
-#define RINVOL_RINMUTE (1 << 7)
-#define RINVOL_RLINBOTH (1 << 8)
+#define RINVOL_DEFAULT 0x79
+/* Use IN common bits */
+#endif /* WM8731 */
#define LOUTVOL 0x02
-#define LOUTVOL_LHPVOL_MASK 0x7f
-#define LOUTVOL_LZCEN (1 << 7)
-#define LOUTVOL_LRHP_BOTH (1 << 8)
+#define LOUTVOL_DEFAULT 0x079
+/* Use OUT common bits */
#define ROUTVOL 0x03
-#define ROUTVOL_RHPVOL_MASK 0x7f
-#define ROUTVOL_RZCEN (1 << 7)
-#define ROUTVOL_RLHP_BOTH (1 << 8)
+#define ROUTVOL_DEFAULT 0x079
+/* Use OUT common bits */
#define AAPCTRL 0x04 /* Analog audio path control */
+#define AAPCTRL_DACSEL (1 << 4)
+#if defined(HAVE_WM8711)
+#define AAPCTRL_DEFAULT 0x008 /* BYPASS enabled */
+#define AAPCTRL_BYPASS (1 << 3)
+#elif defined(HAVE_WM8721)
+#define AAPCTRL_DEFAULT 0x000
+#elif defined(HAVE_WM8731)
+#define AAPCTRL_DEFAULT 0x00a /* BYPASS enabled, MUTEMIC */
#define AAPCTRL_MIC_BOOST (1 << 0)
#define AAPCTRL_MUTEMIC (1 << 1)
#define AAPCTRL_INSEL (1 << 2)
#define AAPCTRL_BYPASS (1 << 3)
-#define AAPCTRL_DACSEL (1 << 4)
#define AAPCTRL_SIDETONE (1 << 5)
-#define AAPCTRL_SIDEATT_6dB (3 << 6)
+#define AAPCTRL_SIDEATT_MASK (3 << 6)
+#define AAPCTRL_SIDEATT_6dB (0 << 6)
#define AAPCTRL_SIDEATT_9dB (1 << 6)
#define AAPCTRL_SIDEATT_12dB (2 << 6)
#define AAPCTRL_SIDEATT_15dB (3 << 6)
+#endif /* WM87x1 */
#define DAPCTRL 0x05 /* Digital audio path control */
-#define DAPCTRL_ADCHPD (1 << 0)
+#define DAPCTRL_DEFAULT 0x008
#define DAPCTRL_DEEMP_DISABLE (0 << 1)
#define DAPCTRL_DEEMP_32KHz (1 << 1)
#define DAPCTRL_DEEMP_44KHz (2 << 1)
#define DAPCTRL_DEEMP_48KHz (3 << 1)
#define DAPCTRL_DEEMP_MASK (3 << 1)
#define DAPCTRL_DACMU (1 << 3)
+#if defined(HAVE_WM8731)
+#define DAPCTRL_ADCHPD (1 << 0)
#define DAPCTRL_HPOR (1 << 4)
+#endif /* WM8731 */
#define PDCTRL 0x06
+#define PDCTRL_DACPD (1 << 3)
+#define PDCTRL_OUTPD (1 << 4)
+#define PDCTRL_POWEROFF (1 << 7)
+#if defined(HAVE_WM8711)
+#define PDCTRL_DEFAULT 0x09f /* CLKPD, OSCPD not off */
+#define PDCTRL_OSCPD (1 << 5)
+#define PDCTRL_CLKOUTPD (1 << 6)
+/* These bits should always be '1' */
+#define PDCTRL_ALWAYS_SET 0x007
+#elif defined(HAVE_WM8721)
+#define PDCTRL_DEFAULT 0x0ff
+/* These bits should always be '1' */
+#define PDCTRL_ALWAYS_SET 0x067
+#elif defined(HAVE_WM8731)
+#define PDCTRL_DEFAULT 0x09f /* CLKPD, OSCPD not off */
#define PDCTRL_LINEINPD (1 << 0)
#define PDCTRL_MICPD (1 << 1)
#define PDCTRL_ADCPD (1 << 2)
-#define PDCTRL_DACPD (1 << 3)
-#define PDCTRL_OUTPD (1 << 4)
#define PDCTRL_OSCPD (1 << 5)
#define PDCTRL_CLKOUTPD (1 << 6)
-#define PDCTRL_POWEROFF (1 << 7)
+/* These bits should always be '1' */
+#define PDCTRL_ALWAYS_SET 0x000
+#endif
-#define AINTFCE 0x07
+#define AINTFCE 0x07
+#define AINTFCE_DEFAULT 0x00a
#define AINTFCE_FORMAT_MSB_RJUST (0 << 0)
#define AINTFCE_FORMAT_MSB_LJUST (1 << 0)
-#define AINTFCE_FORMAT_I2S (2 << 0)
-#define AINTFCE_FORMAT_DSP (3 << 0)
-#define AINTFCE_FORMAT_MASK (3 << 0)
-#define AINTFCE_IWL_16BIT (0 << 2)
-#define AINTFCE_IWL_20BIT (1 << 2)
-#define AINTFCE_IWL_24BIT (2 << 2)
-#define AINTFCE_IWL_32BIT (3 << 2)
-#define AINTFCE_IWL_MASK (3 << 2)
-#define AINTFCE_LRP_I2S_RLO (0 << 4)
-#define AINTFCE_LRP_I2S_RHI (1 << 4)
-#define AINTFCE_DSP_MODE_B (0 << 4)
-#define AINTFCE_DSP_MODE_A (1 << 4)
-#define AINTFCE_LRSWAP (1 << 5)
-#define AINTFCE_MS (1 << 6)
-#define AINTFCE_BCLKINV (1 << 7)
+#define AINTFCE_FORMAT_I2S (2 << 0)
+#define AINTFCE_FORMAT_DSP (3 << 0)
+#define AINTFCE_FORMAT_MASK (3 << 0)
+#define AINTFCE_IWL_16BIT (0 << 2)
+#define AINTFCE_IWL_20BIT (1 << 2)
+#define AINTFCE_IWL_24BIT (2 << 2)
+#define AINTFCE_IWL_32BIT (3 << 2)
+#define AINTFCE_IWL_MASK (3 << 2)
+#define AINTFCE_LRP_I2S_RLO (0 << 4)
+#define AINTFCE_LRP_I2S_RHI (1 << 4)
+#define AINTFCE_DSP_MODE_B (0 << 4)
+#define AINTFCE_DSP_MODE_A (1 << 4)
+#define AINTFCE_LRSWAP (1 << 5)
+#define AINTFCE_MS (1 << 6)
+#define AINTFCE_BCLKINV (1 << 7)
#define SAMPCTRL 0x08
+#define SAMPCTRL_DEFAULT 0x000
#define SAMPCTRL_USB (1 << 0)
+/* For 88.2, 96 */
+#define SAMPCTRL_BOSR_NOR_128fs (0 << 1)
+#define SAMPCTRL_BOSR_NOR_192fs (1 << 1)
+/* */
#define SAMPCTRL_BOSR_NOR_256fs (0 << 1)
#define SAMPCTRL_BOSR_NOR_384fs (1 << 1)
#define SAMPCTRL_BOSR_USB_250fs (0 << 1)
#define SAMPCTRL_BOSR_USB_272fs (1 << 1)
/* Bits 2-5:
- * Sample rate setting are device-specific. See WM8731(L) datasheet
- * for proper settings for the device's clocking */
+ * Sample rate setting are device-specific.
+ * See WM8711/WM8721/WM8731 datasheet for proper settings for the
+ * device's clocking */
#define SAMPCTRL_SR_MASK (0xf << 2)
#define SAMPCTRL_CLKIDIV2 (1 << 6)
+#if defined(HAVE_WM8711) || defined(HAVE_WM8731)
#define SAMPCTRL_CLKODIV2 (1 << 7)
+#endif
#define ACTIVECTRL 0x09
+#define ACTIVECTRL_DEFAULT 0x000
#define ACTIVECTRL_ACTIVE (1 << 0)
#define RESET 0x0f
-#define RESET_RESET 0x0
+/* No reset default */
+#define RESET_RESET 0x000
-#define WM8731_NUM_REGS 0x0a /* RESET not included */
+#define WMC_NUM_REGS 0x0a /* RESET not included */
/* SAMPCTRL values for the supported samplerates (24MHz MCLK/USB): */
-#define WM8731_USB24_8000HZ 0x4d
-#define WM8731_USB24_32000HZ 0x59
-#define WM8731_USB24_44100HZ 0x63
-#define WM8731_USB24_48000HZ 0x41
-#define WM8731_USB24_88200HZ 0x7f
-#define WM8731_USB24_96000HZ 0x5d
+#define WMC_USB24_8000HZ 0x4d
+#define WMC_USB24_32000HZ 0x59
+#define WMC_USB24_44100HZ 0x63
+#define WMC_USB24_48000HZ 0x41
+#define WMC_USB24_88200HZ 0x7f
+#define WMC_USB24_96000HZ 0x5d
#endif /* _WM8731_H */
diff --git a/firmware/sound.c b/firmware/sound.c
index 4d109b3..fb377f6 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -256,8 +256,9 @@ static void set_prescaled_volume(void)
/* The WM codecs listed don't have suitable prescaler functionality, so we let
* the prescaler stay at 0 for these unless SW tone controls are in use */
#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
- || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
- || defined(HAVE_WM8758) || defined(HAVE_WM8985)) || defined(HAVE_TSC2100)
+ || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
+ || defined(HAVE_WM8751) || defined(HAVE_WM8758) || defined(HAVE_WM8985)) \
+ || defined(HAVE_TSC2100)
prescale = MAX(current_bass, current_treble);
if (prescale < 0)
@@ -298,8 +299,8 @@ static void set_prescaled_volume(void)
#if CONFIG_CODEC == MAS3507D
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
- || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
- || defined(HAVE_AS3514) || defined(HAVE_TSC2100)
+ || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
+ || defined(HAVE_WM8751) || defined(HAVE_AS3514) || defined(HAVE_TSC2100)
audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
|| (defined(HAVE_WM8751) && !defined(MROBE_100)) \
@@ -625,8 +626,11 @@ void sound_set(int setting, int value)
sound_set_val(value);
}
-#if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731) && !defined(HAVE_WM8975) \
- && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100)) || defined(SIMULATOR)
+#if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \
+ && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
+ && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
+ && !defined (HAVE_WM8731)) \
+ || defined(SIMULATOR)
int sound_val2phys(int setting, int value)
{
#if CONFIG_CODEC == MAS3587F
@@ -664,7 +668,8 @@ int sound_val2phys(int setting, int value)
break;
}
return result;
-#elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
+#elif defined(HAVE_TLV320) || defined(HAVE_WM8711) \
+ || defined(HAVE_WM8721) || defined(HAVE_WM8731)
int result = 0;
switch(setting)
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c
index 2c4a6ac..3157cff 100644
--- a/firmware/target/arm/pcm-pp.c
+++ b/firmware/target/arm/pcm-pp.c
@@ -112,7 +112,8 @@ void pcm_apply_settings(void)
audiohw_set_frequency(sr_ctrl);
#endif
-#if defined(HAVE_WM8731) || defined(HAVE_WM8721)
+#if defined(HAVE_WM8711) || defined(HAVE_WM8721) \
+ || defined(HAVE_WM8731)
audiohw_set_sample_rate(pcm_freq);
#endif
pcm_curr_sampr = pcm_freq;