From 9581ad39ec15cf20350d01d2787dea0c7db6074d Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Mon, 13 Feb 2006 13:48:08 +0000 Subject: iPod: Audio driver for iPod Video/5G. Rename wm8971_* functions to wmcodec_* to enable unification of the audio code for WM codecs git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8676 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 2 + firmware/drivers/wm8758.c | 276 +++++++++++++++++++++++++++++++++++++ firmware/drivers/wm8975.c | 36 ++--- firmware/export/config-ipodvideo.h | 4 +- firmware/export/wm8758.h | 74 ++++++++++ firmware/export/wm8975.h | 31 ++--- firmware/pcm_playback.c | 14 +- firmware/sound.c | 72 ++++++++-- 8 files changed, 453 insertions(+), 56 deletions(-) create mode 100644 firmware/drivers/wm8758.c create mode 100644 firmware/export/wm8758.h diff --git a/firmware/SOURCES b/firmware/SOURCES index 53923b3c35..15a5de8b7c 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -165,6 +165,8 @@ drivers/lcd-h100-remote.c drivers/uda1380.c #elif defined(HAVE_WM8975) && !defined(SIMULATOR) drivers/wm8975.c +#elif defined(HAVE_WM8758) && !defined(SIMULATOR) +drivers/wm8758.c #elif defined(HAVE_WM8731L) && !defined(SIMULATOR) drivers/wm8731l.c #elif defined(HAVE_TLV320) && !defined(SIMULATOR) diff --git a/firmware/drivers/wm8758.c b/firmware/drivers/wm8758.c new file mode 100644 index 0000000000..3069b3cba7 --- /dev/null +++ b/firmware/drivers/wm8758.c @@ -0,0 +1,276 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Driver for WM8758 audio codec + * + * Based on code from the ipodlinux project - http://ipodlinux.org/ + * Adapted for Rockbox in December 2005 + * + * Original file: linux/arch/armnommu/mach-ipod/audio.c + * + * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "lcd.h" +#include "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "power.h" +#include "debug.h" +#include "system.h" +#include "sprintf.h" +#include "button.h" +#include "string.h" +#include "file.h" +#include "buffer.h" +#include "audio.h" + +#include "i2c-pp5020.h" +#include "wm8758.h" +#include "pcf50605.h" + +void wmcodec_reset(void); + +#define IPOD_PCM_LEVEL 0x65 /* -6dB */ + +//#define BASSCTRL 0x +//#define TREBCTRL 0x0b + +/* + * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit + */ +static void i2s_reset(void) +{ + /* PP502x */ + + /* I2S soft reset */ + outl(inl(0x70002800) | 0x80000000, 0x70002800); + outl(inl(0x70002800) & ~0x80000000, 0x70002800); + + /* BIT.FORMAT [11:10] = I2S (default) */ + outl(inl(0x70002800) & ~0xc00, 0x70002800); + /* BIT.SIZE [9:8] = 16bit (default) */ + outl(inl(0x70002800) & ~0x300, 0x70002800); + + /* FIFO.FORMAT [6:4] = 32 bit LSB */ + /* since BIT.SIZ < FIFO.FORMAT low 16 bits will be 0 */ + outl(inl(0x70002800) | 0x30, 0x70002800); + + /* RX_ATN_LVL=1 == when 12 slots full */ + /* TX_ATN_LVL=1 == when 12 slots empty */ + outl(inl(0x7000280c) | 0x33, 0x7000280c); + + /* Rx.CLR = 1, TX.CLR = 1 */ + outl(inl(0x7000280c) | 0x1100, 0x7000280c); +} + +void wm8758_write(int reg, int data) +{ + ipod_i2c_send(0x1a, (reg<<1) | ((data&0x100)>>8),data&0xff); +} + +/* + * Initialise the WM8758 for playback via headphone and line out. + * Note, I'm using the WM8750 datasheet as its apparently close. + */ +int wmcodec_init(void) { + /* reset I2C */ + i2c_init(); + + /* normal outputs for CDI and I2S pin groups */ + outl(inl(0x70000020) & ~0x300, 0x70000020); + + /*mini2?*/ + outl(inl(0x70000010) & ~0x3000000, 0x70000010); + /*mini2?*/ + + /* device reset */ + outl(inl(0x60006004) | 0x800, 0x60006004); + outl(inl(0x60006004) & ~0x800, 0x60006004); + + /* device enable */ + outl(inl(0x6000600C) | 0x807, 0x6000600C); + + /* enable external dev clock clocks */ + outl(inl(0x6000600c) | 0x2, 0x6000600c); + + /* external dev clock to 24MHz */ + outl(inl(0x70000018) & ~0xc, 0x70000018); + + return 0; +} + +/* Silently enable / disable audio output */ +void wmcodec_enable_output(bool enable) +{ + if (enable) + { + /* reset the I2S controller into known state */ + i2s_reset(); + + wm8758_write(RESET, 0x1ff); /*Reset*/ + + wm8758_write(PWRMGMT1, 0x2b); + wm8758_write(PWRMGMT2, 0x180); + wm8758_write(PWRMGMT3, 0x6f); + + wm8758_write(AINTFCE, 0x10); + wm8758_write(CLKCTRL, 0x49); + + wm8758_write(OUTCTRL, 1 | (0x3 << 5)); + + /* The iPod can handle multiple frequencies, but fix at 44.1KHz + for now */ + wmcodec_set_sample_rate(WM8758_44100HZ); + + wm8758_write(LOUTMIX,0x1); /* Enable mixer */ + wm8758_write(ROUTMIX,0x1); /* Enable mixer */ + wmcodec_mute(0); + } else { + wmcodec_mute(1); + } +} + +int wmcodec_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) */ + + /* OUT1 */ + wm8758_write(LOUT1VOL, vol_l); + wm8758_write(ROUT1VOL, 0x100 | vol_r); + + /* OUT2 */ + wm8758_write(LOUT2VOL, vol_l); + wm8758_write(ROUT2VOL, 0x100 | vol_r); + + return 0; +} + +int wmcodec_set_mixer_vol(int channel1, int channel2) +{ + (void)channel1; + (void)channel2; + + return 0; +} + +/* We are using Linear bass control */ +void wmcodec_set_bass(int value) +{ + (void)value; +#if 0 + /* Not yet implemented - this is the wm8975 code*/ + int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; + + if ((value >= -6) && (value <= 9)) { + /* We use linear bass control with 130Hz cutoff */ + wm8758_write(BASSCTRL, regvalues[value+6]); + } +#endif +} + +void wmcodec_set_treble(int value) +{ + (void)value; +#if 0 + /* Not yet implemented - this is the wm8975 code*/ + int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; + + if ((value >= -6) && (value <= 9)) { + /* We use a 8Khz cutoff */ + wm8758_write(TREBCTRL, regvalues[value+6]); + } +#endif + +} + +int wmcodec_mute(int mute) +{ + if (mute) + { + /* Set DACMU = 1 to soft-mute the audio DACs. */ + wm8758_write(DACCTRL, 0x40); + } else { + /* Set DACMU = 0 to soft-un-mute the audio DACs. */ + wm8758_write(DACCTRL, 0x0); + } + + return 0; +} + +/* Nice shutdown of WM8758 codec */ +void wmcodec_close(void) +{ + wmcodec_mute(1); + + wm8758_write(PWRMGMT3, 0x0); + + wm8758_write(PWRMGMT1, 0x0); + + wm8758_write(PWRMGMT2, 0x40); +} + +/* Change the order of the noise shaper, 5th order is recommended above 32kHz */ +void wmcodec_set_nsorder(int order) +{ + (void)order; +} + +/* Note: Disable output before calling this function */ +void wmcodec_set_sample_rate(int sampling_control) +{ + /**** We force 44.1KHz for now. ****/ + (void)sampling_control; + + /* set clock div */ + wm8758_write(CLKCTRL, 1 | (0 << 2) | (2 << 5)); + + /* setup PLL for MHZ=11.2896 */ + wm8758_write(PLLN, (1 << 4) | 0x7); + wm8758_write(PLLK1, 0x21); + wm8758_write(PLLK2, 0x161); + wm8758_write(PLLK3, 0x26); + + /* set clock div */ + wm8758_write(CLKCTRL, 1 | (0 << 2) | (2 << 5) | (1 << 8)); + + /* set srate */ + wm8758_write(SRATECTRL, (0 << 1)); +} + +void wmcodec_enable_recording(bool source_mic) +{ + (void)source_mic; +} + +void wmcodec_disable_recording(void) { + +} + +void wmcodec_set_recvol(int left, int right, int type) { + + (void)left; + (void)right; + (void)type; +} + +void wmcodec_set_monitor(int enable) { + + (void)enable; +} diff --git a/firmware/drivers/wm8975.c b/firmware/drivers/wm8975.c index 54e245b61a..51c12f1505 100644 --- a/firmware/drivers/wm8975.c +++ b/firmware/drivers/wm8975.c @@ -41,7 +41,7 @@ #include "wm8975.h" #include "pcf50605.h" -void wm8975_reset(void); +void wmcodec_reset(void); #define IPOD_PCM_LEVEL 0x65 /* -6dB */ @@ -82,7 +82,7 @@ void wm8975_write(int reg, int data) * Initialise the WM8975 for playback via headphone and line out. * Note, I'm using the WM8750 datasheet as its apparently close. */ -int wm8975_init(void) { +int wmcodec_init(void) { /* reset I2C */ i2c_init(); @@ -110,7 +110,7 @@ int wm8975_init(void) { } /* Silently enable / disable audio output */ -void wm8975_enable_output(bool enable) +void wmcodec_enable_output(bool enable) { if (enable) { @@ -141,7 +141,7 @@ void wm8975_enable_output(bool enable) wm8975_write(AINTFCE, 0x42); /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */ - wm8975_set_sample_rate(WM8975_44100HZ); + wmcodec_set_sample_rate(WM8975_44100HZ); /* set the volume to -6dB */ wm8975_write(LOUT1VOL, IPOD_PCM_LEVEL); @@ -158,13 +158,13 @@ void wm8975_enable_output(bool enable) wm8975_write(MOUTMIX1, 0x0); /* Mono out Mix */ wm8975_write(MOUTMIX2, 0x0); - wm8975_mute(0); + wmcodec_mute(0); } else { - wm8975_mute(1); + wmcodec_mute(1); } } -int wm8975_set_master_vol(int vol_l, int vol_r) +int wmcodec_set_master_vol(int vol_l, int vol_r) { /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ /* 1111111 == +6dB */ @@ -183,7 +183,7 @@ int wm8975_set_master_vol(int vol_l, int vol_r) return 0; } -int wm8975_set_mixer_vol(int channel1, int channel2) +int wmcodec_set_mixer_vol(int channel1, int channel2) { (void)channel1; (void)channel2; @@ -192,7 +192,7 @@ int wm8975_set_mixer_vol(int channel1, int channel2) } /* We are using Linear bass control */ -void wm8975_set_bass(int value) +void wmcodec_set_bass(int value) { int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; @@ -202,7 +202,7 @@ void wm8975_set_bass(int value) } } -void wm8975_set_treble(int value) +void wmcodec_set_treble(int value) { int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; @@ -212,7 +212,7 @@ void wm8975_set_treble(int value) } } -int wm8975_mute(int mute) +int wmcodec_mute(int mute) { if (mute) { @@ -227,7 +227,7 @@ int wm8975_mute(int mute) } /* Nice shutdown of WM8975 codec */ -void wm8975_close(void) +void wmcodec_close(void) { /* 1. Set DACMU = 1 to soft-mute the audio DACs. */ wm8975_write(DACCTRL, 0x8); @@ -240,35 +240,35 @@ void wm8975_close(void) } /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ -void wm8975_set_nsorder(int order) +void wmcodec_set_nsorder(int order) { (void)order; } /* Note: Disable output before calling this function */ -void wm8975_set_sample_rate(int sampling_control) { +void wmcodec_set_sample_rate(int sampling_control) { wm8975_write(0x08, sampling_control); } -void wm8975_enable_recording(bool source_mic) { +void wmcodec_enable_recording(bool source_mic) { (void)source_mic; } -void wm8975_disable_recording(void) { +void wmcodec_disable_recording(void) { } -void wm8975_set_recvol(int left, int right, int type) { +void wmcodec_set_recvol(int left, int right, int type) { (void)left; (void)right; (void)type; } -void wm8975_set_monitor(int enable) { +void wmcodec_set_monitor(int enable) { (void)enable; } diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h index 160a2db383..2bf0396a21 100644 --- a/firmware/export/config-ipodvideo.h +++ b/firmware/export/config-ipodvideo.h @@ -42,8 +42,8 @@ /* The number of bytes reserved for loadable plugins */ #define PLUGIN_BUFFER_SIZE 0x80000 -/* Define this if you have the WM8975 audio codec */ -#define HAVE_WM8975 +/* Define this if you have the WM8758 audio codec */ +#define HAVE_WM8758 /* Define this for LCD backlight available */ #define CONFIG_BACKLIGHT BL_IPODNANO /* port controlled */ diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h new file mode 100644 index 0000000000..adc17f86d7 --- /dev/null +++ b/firmware/export/wm8758.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Dave Chapman + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _WM8758_H +#define _WM8758_H + +extern void wmcodec_reset(void); +extern int wmcodec_init(void); +extern void wmcodec_enable_output(bool enable); +extern int wmcodec_set_master_vol(int vol_l, int vol_r); +extern int wmcodec_set_mixer_vol(int channel1, int channel2); +extern void wmcodec_set_bass(int value); +extern void wmcodec_set_treble(int value); +extern int wmcodec_mute(int mute); +extern void wmcodec_close(void); +extern void wmcodec_set_nsorder(int order); +extern void wmcodec_set_sample_rate(int sampling_control); + +extern void wmcodec_enable_recording(bool source_mic); +extern void wmcodec_disable_recording(void); +extern void wmcodec_set_recvol(int left, int right, int type); +extern void wmcodec_set_monitor(int enable); + +#define RESET 0x00 +#define PWRMGMT1 0x01 +#define PWRMGMT2 0x02 +#define PWRMGMT3 0x03 +#define AINTFCE 0x04 +#define CLKCTRL 0x06 +#define SRATECTRL 0x07 +#define DACCTRL 0x0a +#define OUTCTRL 0x31 +#define LOUTMIX 0x32 +#define ROUTMIX 0x33 + +#define LOUT1VOL 0x34 +#define ROUT1VOL 0x35 +#define LOUT2VOL 0x36 +#define ROUT2VOL 0x37 + +#define PLLN 0x24 +#define PLLK1 0x25 +#define PLLK2 0x26 +#define PLLK3 0x27 + +/* Register settings for the supported samplerates: */ +#define WM8758_8000HZ 0x4d +#define WM8758_12000HZ 0x61 +#define WM8758_16000HZ 0x55 +#define WM8758_22050HZ 0x77 +#define WM8758_24000HZ 0x79 +#define WM8758_32000HZ 0x59 +#define WM8758_44100HZ 0x63 +#define WM8758_48000HZ 0x41 +#define WM8758_88200HZ 0x7f +#define WM8758_96000HZ 0x5d + +#endif /* _WM8758_H */ diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index 1d63159748..4d575c3d90 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h @@ -20,22 +20,22 @@ #ifndef _WM8975_H #define _WM8975_H -extern void wm8975_reset(void); -extern int wm8975_init(void); -extern void wm8975_enable_output(bool enable); -extern int wm8975_set_master_vol(int vol_l, int vol_r); -extern int wm8975_set_mixer_vol(int channel1, int channel2); -extern void wm8975_set_bass(int value); -extern void wm8975_set_treble(int value); -extern int wm8975_mute(int mute); -extern void wm8975_close(void); -extern void wm8975_set_nsorder(int order); -extern void wm8975_set_sample_rate(int sampling_control); +extern void wmcodec_reset(void); +extern int wmcodec_init(void); +extern void wmcodec_enable_output(bool enable); +extern int wmcodec_set_master_vol(int vol_l, int vol_r); +extern int wmcodec_set_mixer_vol(int channel1, int channel2); +extern void wmcodec_set_bass(int value); +extern void wmcodec_set_treble(int value); +extern int wmcodec_mute(int mute); +extern void wmcodec_close(void); +extern void wmcodec_set_nsorder(int order); +extern void wmcodec_set_sample_rate(int sampling_control); -extern void wm8975_enable_recording(bool source_mic); -extern void wm8975_disable_recording(void); -extern void wm8975_set_recvol(int left, int right, int type); -extern void wm8975_set_monitor(int enable); +extern void wmcodec_enable_recording(bool source_mic); +extern void wmcodec_disable_recording(void); +extern void wmcodec_set_recvol(int left, int right, int type); +extern void wmcodec_set_monitor(int enable); /* Register addresses */ #define LOUT1VOL 0x02 @@ -56,7 +56,6 @@ extern void wm8975_set_monitor(int enable); #define LOUT2VOL 0x28 #define ROUT2VOL 0x29 - /* Register settings for the supported samplerates: */ #define WM8975_8000HZ 0x4d #define WM8975_12000HZ 0x61 diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index c55b48699b..1e9cac31f5 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c @@ -28,6 +28,8 @@ #include "uda1380.h" #elif defined(HAVE_WM8975) #include "wm8975.h" +#elif defined(HAVE_WM8758) +#include "wm8758.h" #elif defined(HAVE_TLV320) #include "tlv320.h" #elif defined(HAVE_WM8731L) @@ -314,7 +316,7 @@ void pcm_init(void) dma_stop(); } -#elif defined(HAVE_WM8975) +#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) /* We need to unify this code with the uda1380 code as much as possible, but we will keep it separate during early development. @@ -408,7 +410,7 @@ size_t pcm_get_bytes_waiting(void) void pcm_mute(bool mute) { - wm8975_mute(mute); + wmcodec_mute(mute); if (mute) sleep(HZ/16); } @@ -532,15 +534,15 @@ void pcm_init(void) pcm_paused = false; /* Initialize default register values. */ - wm8975_init(); + wmcodec_init(); /* The uda1380 needs a sleep(HZ) here - do we need one? */ /* Power on */ - wm8975_enable_output(true); + wmcodec_enable_output(true); /* Unmute the master channel (DAC should be at zero point now). */ - wm8975_mute(false); + wmcodec_mute(false); /* Call dma_stop to initialize everything. */ dma_stop(); @@ -625,7 +627,7 @@ void pcm_calculate_peaks(int *left, int *right) #ifdef HAVE_UDA1380 long samples = (BCR0 & 0xffffff) / 4; short *addr = (short *) (SAR0 & ~3); -#elif defined(HAVE_WM8975) +#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) long samples = p_size / 4; short *addr = p; #elif defined(HAVE_WM8731L) diff --git a/firmware/sound.c b/firmware/sound.c index 110c2c91b8..a039cca609 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -28,6 +28,8 @@ #include "uda1380.h" #elif defined(HAVE_WM8975) #include "wm8975.h" +#elif defined(HAVE_WM8758) +#include "wm8758.h" #elif defined(HAVE_TLV320) #include "tlv320.h" #endif @@ -71,6 +73,10 @@ static const struct sound_settings_info sound_settings_table[] = { [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -25, sound_set_volume}, [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, +#elif defined(HAVE_WM8758) + [SOUND_VOLUME] = {"dB", 0, 1, -57, 6, -25, sound_set_volume}, + [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, + [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, #else /* MAS3507D */ [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume}, [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, @@ -276,7 +282,8 @@ static int tenthdb2mixer(int db) return -db * 2 / 5; } -#elif defined(HAVE_WM8975) /* volume/balance/treble/bass interdependency */ +#elif defined(HAVE_WM8975) +/* volume/balance/treble/bass interdependency */ #define VOLUME_MIN -730 #define VOLUME_MAX 60 @@ -290,9 +297,43 @@ static int tenthdb2master(int db) /* 0101111 == mute (0x2f) */ if (db <= -730) { - return 0x2f; + return 0x0; } else { - return((db/10)+74+0x2f); + return((db/10)+73+0x2f); + } +} + +/* convert tenth of dB volume (-780..0) to mixer volume register value */ +static int tenthdb2mixer(int db) +{ + if (db < -660) /* 1.5 dB steps */ + return (2640 - db) / 15; + else if (db < -600) /* 0.75 dB steps */ + return (990 - db) * 2 / 15; + else if (db < -460) /* 0.5 dB steps */ + return (460 - db) / 5; + else /* 0.25 dB steps */ + return -db * 2 / 5; +} + +#elif defined(HAVE_WM8758) +/* volume/balance/treble/bass interdependency */ +#define VOLUME_MIN -730 +#define VOLUME_MAX 60 + +/* convert tenth of dB volume (-730..60) to master volume register value */ +static 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 <= -570) { + return 0x0; + } else { + return((db/10)+57); } } @@ -311,7 +352,8 @@ static int tenthdb2mixer(int db) #endif -#if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || defined HAVE_WM8975 +#if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ + defined HAVE_WM8975 || defined HAVE_WM8758 /* volume/balance/treble/bass interdependency main part */ #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) @@ -341,8 +383,8 @@ static void set_prescaled_volume(void) mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); #elif defined(HAVE_UDA1380) uda1380_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); -#elif defined(HAVE_WM8975) - wm8975_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); +#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) + wmcodec_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); #endif if (current_volume == VOLUME_MIN) @@ -367,8 +409,8 @@ static void set_prescaled_volume(void) dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); #elif defined(HAVE_UDA1380) uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); -#elif defined(HAVE_WM8975) - wm8975_set_master_vol(tenthdb2master(l), tenthdb2master(r)); +#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) + wmcodec_set_master_vol(tenthdb2master(l), tenthdb2master(r)); #endif } #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ @@ -468,7 +510,8 @@ void sound_set_volume(int value) #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8; mas_codec_writereg(0x10, tmp); -#elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || defined HAVE_WM8975 +#elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ + defined HAVE_WM8975 || defined HAVE_WM8758 current_volume = value * 10; /* tenth of dB */ set_prescaled_volume(); #elif CONFIG_CPU == PNX0101 @@ -484,7 +527,8 @@ void sound_set_balance(int value) #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8; mas_codec_writereg(0x11, tmp); -#elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || defined HAVE_WM8975 +#elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || \ + defined HAVE_WM8975 || defined HAVE_WM8758 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ set_prescaled_volume(); #elif CONFIG_CPU == PNX0101 @@ -508,9 +552,9 @@ void sound_set_bass(int value) uda1380_set_bass(value >> 1); current_bass = value * 10; set_prescaled_volume(); -#elif defined(HAVE_WM8975) +#elif defined HAVE_WM8975 || defined HAVE_WM8758 current_bass = value * 10; - wm8975_set_bass(value); + wmcodec_set_bass(value); set_prescaled_volume(); #elif CONFIG_CPU == PNX0101 /* TODO: implement for iFP */ @@ -533,8 +577,8 @@ void sound_set_treble(int value) uda1380_set_treble(value >> 1); current_treble = value * 10; set_prescaled_volume(); -#elif defined(HAVE_WM8975) - wm8975_set_treble(value); +#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) + wmcodec_set_treble(value); current_treble = value * 10; set_prescaled_volume(); #elif CONFIG_CPU == PNX0101 -- cgit v1.2.3