summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-02-13 13:48:08 +0000
committerDave Chapman <dave@dchapman.com>2006-02-13 13:48:08 +0000
commit9581ad39ec15cf20350d01d2787dea0c7db6074d (patch)
tree28ead339e852346eb9f4e947e3494353cb687d72
parentb55f20a12d6b68d0f4f53ab19db76e8b5388d8bb (diff)
downloadrockbox-9581ad39ec15cf20350d01d2787dea0c7db6074d.tar.gz
rockbox-9581ad39ec15cf20350d01d2787dea0c7db6074d.tar.bz2
rockbox-9581ad39ec15cf20350d01d2787dea0c7db6074d.zip
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
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/drivers/wm8758.c276
-rw-r--r--firmware/drivers/wm8975.c36
-rw-r--r--firmware/export/config-ipodvideo.h4
-rw-r--r--firmware/export/wm8758.h74
-rw-r--r--firmware/export/wm8975.h31
-rw-r--r--firmware/pcm_playback.c14
-rw-r--r--firmware/sound.c72
8 files changed, 453 insertions, 56 deletions
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