From ea929a3e4547e9c709560803d2cea760ffe3e6a3 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 8 Dec 2008 21:09:56 +0000 Subject: 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 --- firmware/SOURCES | 6 +- firmware/drivers/audio/wm8721.c | 184 ---------------------------------- firmware/drivers/audio/wm8731.c | 194 +++++++++++++++++++----------------- firmware/export/audiohw.h | 5 +- firmware/export/config-ipodmini.h | 2 +- firmware/export/config-ipodmini2g.h | 4 +- firmware/export/wm8721.h | 106 -------------------- firmware/export/wm8731.h | 139 ++++++++++++++++++-------- firmware/sound.c | 19 ++-- firmware/target/arm/pcm-pp.c | 3 +- 10 files changed, 220 insertions(+), 442 deletions(-) delete mode 100644 firmware/drivers/audio/wm8721.c delete mode 100644 firmware/export/wm8721.h (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index 752db73b01..3fadec005e 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 3f14ca467e..0000000000 --- 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 2f882e8fe1..3cfd3e4b92 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 b82c27e2fb..51aec65c4c 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 c2d6376706..5d7781a486 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 6d6ebf1a9a..dbbbc4356c 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 814535621a..0000000000 --- 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 2ea479fff7..9d5b61833f 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 4d109b3900..fb377f6f6d 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 2c4a6ac87d..3157cffaec 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; -- cgit v1.2.3