summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/aic3x.c7
-rw-r--r--firmware/drivers/audio/ak4537.c27
-rw-r--r--firmware/drivers/audio/as3514.c42
-rw-r--r--firmware/drivers/audio/audiohw-swcodec.c76
-rw-r--r--firmware/drivers/audio/cs42l55.c30
-rw-r--r--firmware/drivers/audio/dac3550a.c9
-rw-r--r--firmware/drivers/audio/dummy_codec.c12
-rw-r--r--firmware/drivers/audio/imx233-codec.c26
-rw-r--r--firmware/drivers/audio/mas35xx.c71
-rw-r--r--firmware/drivers/audio/rk27xx_codec.c19
-rw-r--r--firmware/drivers/audio/sdl.c105
-rw-r--r--firmware/drivers/audio/tlv320.c9
-rw-r--r--firmware/drivers/audio/tsc2100.c41
-rw-r--r--firmware/drivers/audio/uda1341.c26
-rw-r--r--firmware/drivers/audio/uda1380.c37
-rw-r--r--firmware/drivers/audio/wm8731.c55
-rw-r--r--firmware/drivers/audio/wm8751.c75
-rw-r--r--firmware/drivers/audio/wm8758.c37
-rw-r--r--firmware/drivers/audio/wm8975.c51
-rw-r--r--firmware/drivers/audio/wm8978.c77
-rw-r--r--firmware/drivers/audio/wm8985.c46
21 files changed, 248 insertions, 630 deletions
diff --git a/firmware/drivers/audio/aic3x.c b/firmware/drivers/audio/aic3x.c
index 97eb17ebef..08c4db3f53 100644
--- a/firmware/drivers/audio/aic3x.c
+++ b/firmware/drivers/audio/aic3x.c
@@ -44,7 +44,7 @@ const struct sound_settings_info audiohw_settings[] = {
44}; 44};
45 45
46/* convert tenth of dB volume to master volume register value */ 46/* convert tenth of dB volume to master volume register value */
47int tenthdb2master(int db) 47static int vol_tenthdb2hw(int db)
48{ 48{
49 /* 0 to -63.0dB in 1dB steps, aic3x can goto -63.5 in 0.5dB steps */ 49 /* 0 to -63.0dB in 1dB steps, aic3x can goto -63.5 in 0.5dB steps */
50 if (db < VOLUME_MIN) 50 if (db < VOLUME_MIN)
@@ -270,8 +270,11 @@ void audiohw_set_frequency(int fsel)
270 /* TODO */ 270 /* TODO */
271} 271}
272 272
273void audiohw_set_headphone_vol(int vol_l, int vol_r) 273void audiohw_set_volume(int vol_l, int vol_r)
274{ 274{
275 vol_l = vol_tenthdb2hw(vol_l);
276 vol_r = vol_tenthdb2hw(vol_r);
277
275 if ((volume_left & 0x7F) == (vol_l & 0x7F) && 278 if ((volume_left & 0x7F) == (vol_l & 0x7F) &&
276 (volume_right & 0x7F) == (vol_r & 0x7F)) 279 (volume_right & 0x7F) == (vol_r & 0x7F))
277 { 280 {
diff --git a/firmware/drivers/audio/ak4537.c b/firmware/drivers/audio/ak4537.c
index c3ce02a3af..4a9010d4e7 100644
--- a/firmware/drivers/audio/ak4537.c
+++ b/firmware/drivers/audio/ak4537.c
@@ -80,7 +80,7 @@ static void codec_set_active(int active)
80#endif 80#endif
81 81
82/* convert tenth of dB volume (-1270..0) to master volume register value */ 82/* convert tenth of dB volume (-1270..0) to master volume register value */
83int tenthdb2master(int db) 83static int vol_tenthdb2hw(int db)
84{ 84{
85 if (db < VOLUME_MIN) 85 if (db < VOLUME_MIN)
86 return 0xff; /* mute */ 86 return 0xff; /* mute */
@@ -90,29 +90,6 @@ int tenthdb2master(int db)
90 return ((-db)/5); 90 return ((-db)/5);
91} 91}
92 92
93int sound_val2phys(int setting, int value)
94{
95 int result;
96
97 switch(setting)
98 {
99#ifdef HAVE_RECORDING
100 case SOUND_LEFT_GAIN:
101 case SOUND_RIGHT_GAIN:
102 result = (value - 23) * 15; /* fix */
103 break;
104 case SOUND_MIC_GAIN:
105 result = value * 200; /* fix */
106 break;
107#endif
108 default:
109 result = value;
110 break;
111 }
112
113 return result;
114}
115
116/*static void audiohw_mute(bool mute) 93/*static void audiohw_mute(bool mute)
117{ 94{
118 if (mute) 95 if (mute)
@@ -232,6 +209,8 @@ void audiohw_close(void)
232 209
233void audiohw_set_master_vol(int vol_l, int vol_r) 210void audiohw_set_master_vol(int vol_l, int vol_r)
234{ 211{
212 vol_l = vol_tenthdb2hw(vol_l);
213 vol_r = vol_tenthdb2hw(vol_r);
235 akc_write(AK4537_ATTL, vol_l & 0xff); 214 akc_write(AK4537_ATTL, vol_l & 0xff);
236 akc_write(AK4537_ATTR, vol_r & 0xff); 215 akc_write(AK4537_ATTR, vol_r & 0xff);
237} 216}
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c
index 5f18bc6ec1..b9118f9fcf 100644
--- a/firmware/drivers/audio/as3514.c
+++ b/firmware/drivers/audio/as3514.c
@@ -63,21 +63,6 @@
63 63
64#endif 64#endif
65 65
66const struct sound_settings_info audiohw_settings[] = {
67 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, 6, -25},
68 /* HAVE_SW_TONE_CONTROLS */
69 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
70 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
71 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
72 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
73 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
74#ifdef HAVE_RECORDING
75 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 39, 23},
76 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
77 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
78#endif
79};
80
81/* Shadow registers */ 66/* Shadow registers */
82static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ 67static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */
83 68
@@ -112,7 +97,7 @@ static void as3514_write_masked(unsigned int reg, unsigned int bits,
112} 97}
113 98
114/* convert tenth of dB volume to master volume register value */ 99/* convert tenth of dB volume to master volume register value */
115int tenthdb2master(int db) 100static int vol_tenthdb2hw(int db)
116{ 101{
117 /* +6 to -73.5dB (or -81.0 dB) in 1.5dB steps == 53 (or 58) levels */ 102 /* +6 to -73.5dB (or -81.0 dB) in 1.5dB steps == 53 (or 58) levels */
118 if (db < VOLUME_MIN) { 103 if (db < VOLUME_MIN) {
@@ -124,22 +109,6 @@ int tenthdb2master(int db)
124 } 109 }
125} 110}
126 111
127int sound_val2phys(int setting, int value)
128{
129 switch(setting)
130 {
131#if defined(HAVE_RECORDING)
132 case SOUND_LEFT_GAIN:
133 case SOUND_RIGHT_GAIN:
134 case SOUND_MIC_GAIN:
135 return (value - 23) * 15;
136#endif
137
138 default:
139 return value;
140 }
141}
142
143/* 112/*
144 * Initialise the PP I2C and I2S. 113 * Initialise the PP I2C and I2S.
145 */ 114 */
@@ -276,6 +245,9 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
276 unsigned int hph_r, hph_l; 245 unsigned int hph_r, hph_l;
277 unsigned int mix_l, mix_r; 246 unsigned int mix_l, mix_r;
278 247
248 vol_l = vol_tenthdb2hw(vol_l);
249 vol_r = vol_tenthdb2hw(vol_r);
250
279 if (vol_l == 0 && vol_r == 0) { 251 if (vol_l == 0 && vol_r == 0) {
280 audiohw_mute(true); 252 audiohw_mute(true);
281 return; 253 return;
@@ -322,12 +294,14 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
322} 294}
323 295
324#if 0 /* unused */ 296#if 0 /* unused */
325void audiohw_set_lineout_vol(int vol_l, int vol_r) 297void audiohw_set_lineout_volume(int vol_l, int vol_r)
326{ 298{
327#ifdef HAVE_AS3543 299#ifdef HAVE_AS3543
328 /* line out volume is set in the same registers */ 300 /* line out volume is set in the same registers */
329 audiohw_set_master_vol(vol_l, vol_r); 301 audiohw_set_master_volume(vol_l, vol_r);
330#else 302#else
303 vol_l = vol_tenthdb2hw(vol_l);
304 vol_r = vol_tenthdb2hw(vol_r);
331 as3514_write_masked(AS3514_LINE_OUT_R, vol_r, AS3514_VOL_MASK); 305 as3514_write_masked(AS3514_LINE_OUT_R, vol_r, AS3514_VOL_MASK);
332 as3514_write_masked(AS3514_LINE_OUT_L, vol_l, AS3514_VOL_MASK); 306 as3514_write_masked(AS3514_LINE_OUT_L, vol_l, AS3514_VOL_MASK);
333#endif 307#endif
diff --git a/firmware/drivers/audio/audiohw-swcodec.c b/firmware/drivers/audio/audiohw-swcodec.c
new file mode 100644
index 0000000000..45b21183ad
--- /dev/null
+++ b/firmware/drivers/audio/audiohw-swcodec.c
@@ -0,0 +1,76 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Thom Johansen
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "system.h"
23#include "sound.h"
24#include "dsp_misc.h"
25
26/* Linking audio hardware calls to SWCODEC DSP emulation */
27
28static audiohw_swcodec_cb_type callback = NULL;
29
30void audiohw_swcodec_set_callback(audiohw_swcodec_cb_type func)
31{
32 callback = func;
33}
34
35/** Functions exported by audiohw.h **/
36
37void audiohw_set_channel(int value)
38{
39 callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
40}
41
42void audiohw_set_stereo_width(int value)
43{
44 callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
45}
46
47#ifdef HAVE_SW_TONE_CONTROLS
48void audiohw_set_bass(int value)
49{
50 callback(DSP_CALLBACK_SET_BASS, value);
51}
52
53void audiohw_set_treble(int value)
54{
55 callback(DSP_CALLBACK_SET_TREBLE, value);
56}
57#endif /* HAVE_SW_TONE_CONTROLS */
58
59#ifndef AUDIOHW_HAVE_PRESCALER
60void audiohw_set_prescaler(int value)
61{
62 callback(DSP_CALLBACK_SET_PRESCALE, value);
63}
64#endif /* AUDIOHW_HAVE_PRESCALER */
65
66#ifdef HAVE_PITCHCONTROL
67void audiohw_set_pitch(int32_t value)
68{
69 callback(DSP_CALLBACK_SET_PITCH, value);
70}
71
72int32_t audiohw_get_pitch(void)
73{
74 return callback(DSP_CALLBACK_GET_PITCH, 0);
75}
76#endif /* HAVE_PITCHCONTROL */
diff --git a/firmware/drivers/audio/cs42l55.c b/firmware/drivers/audio/cs42l55.c
index 38380d5a54..75fcd80b77 100644
--- a/firmware/drivers/audio/cs42l55.c
+++ b/firmware/drivers/audio/cs42l55.c
@@ -29,27 +29,15 @@
29#include "cscodec.h" 29#include "cscodec.h"
30#include "cs42l55.h" 30#include "cs42l55.h"
31 31
32const struct sound_settings_info audiohw_settings[] = {
33 [SOUND_VOLUME] = {"dB", 0, 1, -60, 12, -25},
34 [SOUND_BASS] = {"dB", 1, 15,-105, 120, 0},
35 [SOUND_TREBLE] = {"dB", 1, 15,-105, 120, 0},
36 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
37 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
38 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
39 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 2},
40 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
41};
42
43static int bass, treble; 32static int bass, treble;
44 33
45/* convert tenth of dB volume (-600..120) to master volume register value */ 34/* convert tenth of dB volume (-600..120) to volume register value */
46int tenthdb2master(int db) 35static int vol_tenthdb2hw(int db)
47{ 36{
48 /* -60dB to +12dB in 1dB steps */ 37 /* -60dB to +12dB in 1dB steps */
49 /* 0001100 == +12dB (0xc) */ 38 /* 0001100 == +12dB (0xc) */
50 /* 0000000 == 0dB (0x0) */ 39 /* 0000000 == 0dB (0x0) */
51 /* 1000100 == -60dB (0x44, this is actually -58dB) */ 40 /* 1000100 == -60dB (0x44, this is actually -58dB) */
52
53 if (db < VOLUME_MIN) return HPACTL_HPAMUTE; 41 if (db < VOLUME_MIN) return HPACTL_HPAMUTE;
54 return (db / 10) & HPACTL_HPAVOL_MASK; 42 return (db / 10) & HPACTL_HPAVOL_MASK;
55} 43}
@@ -125,11 +113,8 @@ void audiohw_postinit(void)
125 113
126void audiohw_set_master_vol(int vol_l, int vol_r) 114void audiohw_set_master_vol(int vol_l, int vol_r)
127{ 115{
128 /* -60dB to +12dB in 1dB steps */ 116 vol_l = vol_tenthdb2hw(vol_l);
129 /* 0001100 == +12dB (0xc) */ 117 vol_r = vol_tenthdb2hw(vol_r);
130 /* 0000000 == 0dB (0x0) */
131 /* 1000100 == -60dB (0x44, this is actually -58dB) */
132
133 cscodec_setbits(HPACTL, HPACTL_HPAVOL_MASK | HPACTL_HPAMUTE, 118 cscodec_setbits(HPACTL, HPACTL_HPAVOL_MASK | HPACTL_HPAMUTE,
134 vol_l << HPACTL_HPAVOL_SHIFT); 119 vol_l << HPACTL_HPAVOL_SHIFT);
135 cscodec_setbits(HPBCTL, HPBCTL_HPBVOL_MASK | HPBCTL_HPBMUTE, 120 cscodec_setbits(HPBCTL, HPBCTL_HPBVOL_MASK | HPBCTL_HPBMUTE,
@@ -138,11 +123,8 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
138 123
139void audiohw_set_lineout_vol(int vol_l, int vol_r) 124void audiohw_set_lineout_vol(int vol_l, int vol_r)
140{ 125{
141 /* -60dB to +12dB in 1dB steps */ 126 vol_l = vol_tenthdb2hw(vol_l);
142 /* 0001100 == +12dB (0xc) */ 127 vol_r = vol_tenthdb2hw(vol_r);
143 /* 0000000 == 0dB (0x0) */
144 /* 1000100 == -60dB (0x44, this is actually -58dB) */
145
146 cscodec_setbits(LINEACTL, LINEACTL_LINEAVOL_MASK | LINEACTL_LINEAMUTE, 128 cscodec_setbits(LINEACTL, LINEACTL_LINEAVOL_MASK | LINEACTL_LINEAMUTE,
147 vol_l << LINEACTL_LINEAVOL_SHIFT); 129 vol_l << LINEACTL_LINEAVOL_SHIFT);
148 cscodec_setbits(LINEBCTL, LINEBCTL_LINEBVOL_MASK | LINEBCTL_LINEBMUTE, 130 cscodec_setbits(LINEBCTL, LINEBCTL_LINEBVOL_MASK | LINEBCTL_LINEBMUTE,
diff --git a/firmware/drivers/audio/dac3550a.c b/firmware/drivers/audio/dac3550a.c
index 9c6dfbb292..0ff5d8ad21 100644
--- a/firmware/drivers/audio/dac3550a.c
+++ b/firmware/drivers/audio/dac3550a.c
@@ -27,15 +27,6 @@
27static bool line_in_enabled = false; 27static bool line_in_enabled = false;
28static bool dac_enabled = false; 28static bool dac_enabled = false;
29 29
30/* convert tenth of dB volume (-780..+180) to dac3550 register value */
31int tenthdb2reg(int db)
32{
33 if (db < -540) /* 3 dB steps */
34 return (db + 780) / 30;
35 else /* 1.5 dB steps */
36 return (db + 660) / 15;
37}
38
39int dac_volume(unsigned int left, unsigned int right, bool deemph) 30int dac_volume(unsigned int left, unsigned int right, bool deemph)
40{ 31{
41 int ret = 0; 32 int ret = 0;
diff --git a/firmware/drivers/audio/dummy_codec.c b/firmware/drivers/audio/dummy_codec.c
index 94ba04b56a..3e73137eb9 100644
--- a/firmware/drivers/audio/dummy_codec.c
+++ b/firmware/drivers/audio/dummy_codec.c
@@ -26,16 +26,6 @@
26#include "system.h" 26#include "system.h"
27#include "pcm_sw_volume.h" 27#include "pcm_sw_volume.h"
28 28
29const struct sound_settings_info audiohw_settings[] = {
30 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, 0},
31 /* HAVE_SW_TONE_CONTROLS */
32 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
33 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
34 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
35 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
36 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
37};
38
39void audiohw_preinit(void) { } 29void audiohw_preinit(void) { }
40 30
41void audiohw_postinit(void) { } 31void audiohw_postinit(void) { }
@@ -48,7 +38,7 @@ void audiohw_set_frequency(int fsel)
48} 38}
49 39
50#ifdef HAVE_SW_VOLUME_CONTROL 40#ifdef HAVE_SW_VOLUME_CONTROL
51void audiohw_set_master_vol(int vol_l, int vol_r) 41void audiohw_set_volume(int vol_l, int vol_r)
52{ 42{
53 /* SW volume for <= 1.0 gain, HW at unity, < VOLUME_MIN == MUTE */ 43 /* SW volume for <= 1.0 gain, HW at unity, < VOLUME_MIN == MUTE */
54 int sw_volume_l = vol_l < VOLUME_MIN ? PCM_MUTE_LEVEL : MIN(vol_l, 0); 44 int sw_volume_l = vol_l < VOLUME_MIN ? PCM_MUTE_LEVEL : MIN(vol_l, 0);
diff --git a/firmware/drivers/audio/imx233-codec.c b/firmware/drivers/audio/imx233-codec.c
index 20edf005e8..ef4e3ca1d5 100644
--- a/firmware/drivers/audio/imx233-codec.c
+++ b/firmware/drivers/audio/imx233-codec.c
@@ -25,30 +25,6 @@
25#include "audioout-imx233.h" 25#include "audioout-imx233.h"
26#include "audioin-imx233.h" 26#include "audioin-imx233.h"
27 27
28const struct sound_settings_info audiohw_settings[] =
29{
30 /* i.MX233 has half dB steps */
31 [SOUND_VOLUME] = {"dB", 0, 5, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
32 /* HAVE_SW_TONE_CONTROLS */
33 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
34 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
35 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
36 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
37 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
38#ifdef HAVE_RECORDING
39 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
40 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
41 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0},
42#endif
43 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
44};
45
46int tenthdb2master(int tdb)
47{
48 /* Just go from tenth of dB to half to dB */
49 return tdb / 5;
50}
51
52void audiohw_preinit(void) 28void audiohw_preinit(void)
53{ 29{
54 imx233_audioout_preinit(); 30 imx233_audioout_preinit();
@@ -69,7 +45,7 @@ void audiohw_close(void)
69 45
70void audiohw_set_headphone_vol(int vol_l, int vol_r) 46void audiohw_set_headphone_vol(int vol_l, int vol_r)
71{ 47{
72 imx233_audioout_set_hp_vol(vol_l, vol_r); 48 imx233_audioout_set_hp_vol(vol_l / 5, vol_r / 5);
73} 49}
74 50
75void audiohw_set_frequency(int fsel) 51void audiohw_set_frequency(int fsel)
diff --git a/firmware/drivers/audio/mas35xx.c b/firmware/drivers/audio/mas35xx.c
index e6cc665109..deb9223187 100644
--- a/firmware/drivers/audio/mas35xx.c
+++ b/firmware/drivers/audio/mas35xx.c
@@ -26,36 +26,6 @@
26#include "system.h" /* MAX MIN macros */ 26#include "system.h" /* MAX MIN macros */
27#include "audiohw.h" 27#include "audiohw.h"
28 28
29const struct sound_settings_info audiohw_settings[] = {
30#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
31 [SOUND_VOLUME] = {"dB", 0, 1,-100, 12, -25},
32 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 6},
33 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 6},
34#elif CONFIG_CODEC == MAS3507D
35 [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18},
36 [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7},
37 [SOUND_TREBLE] = {"dB", 0, 1, -15, 15, 7},
38#endif
39 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
40 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
41 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
42#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
43 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
44 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
45 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
46 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
47 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
48 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
49 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
50 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
51#endif
52#if CONFIG_CODEC == MAS3587F && defined(HAVE_RECORDING)
53 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 15, 8},
54 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 15, 8},
55 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 15, 2},
56#endif
57};
58
59int channel_configuration = SOUND_CHAN_STEREO; 29int channel_configuration = SOUND_CHAN_STEREO;
60int stereo_width = 100; 30int stereo_width = 100;
61 31
@@ -65,7 +35,6 @@ unsigned long loudness_shadow = 0;
65unsigned long shadow_io_control_main; 35unsigned long shadow_io_control_main;
66#endif 36#endif
67 37
68
69static void set_channel_config(void) 38static void set_channel_config(void)
70{ 39{
71 /* default values: stereo */ 40 /* default values: stereo */
@@ -185,6 +154,22 @@ void audiohw_set_treble(int val)
185#endif 154#endif
186} 155}
187 156
157#if (CONFIG_CODEC == MAS3507D)
158/* convert tenth of dB volume (-780..+180) to dac3550 register value */
159static unsigned int tenthdb2reg(int db)
160{
161 if (db < -540) /* 3 dB steps */
162 return (db + 780) / 30;
163 else /* 1.5 dB steps */
164 return (db + 660) / 15;
165}
166
167void audiohw_set_volume(int vol_l, int vol_r)
168{
169 dac_volume(tenthdb2reg(vol_l), tenthdb2reg(vol_r), false);
170}
171#endif /* CONFIG_CODEC == MAS3507D */
172
188#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 173#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
189void audiohw_set_volume(int val) 174void audiohw_set_volume(int val)
190{ 175{
@@ -268,14 +253,32 @@ void audiohw_set_balance(int val)
268 mas_codec_writereg(MAS_REG_BALANCE, tmp); 253 mas_codec_writereg(MAS_REG_BALANCE, tmp);
269} 254}
270 255
271void audiohw_set_pitch(unsigned long val) 256/* This functionality works by telling the decoder that we have another
257 crystal frequency than we actually have. It will adjust its internal
258 parameters and the result is that the audio is played at another pitch.
259*/
260static int32_t last_pitch = PITCH_SPEED_100;
261
262void audiohw_set_pitch(int32_t val)
272{ 263{
273 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); 264 if (val == last_pitch)
265 return;
266
267 /* Calculate the new (bogus) frequency */
268 unsigned long reg = 18432 * PITCH_SPEED_100 / val;
269 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &reg, 1);
274 270
275 /* We must tell the MAS that the frequency has changed. 271 /* We must tell the MAS that the frequency has changed.
276 * This will unfortunately cause a short silence. */ 272 * This will unfortunately cause a short silence. */
273 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN,
274 &shadow_io_control_main, 1);
275
276 last_pitch = val;
277}
277 278
278 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); 279int32_t audiohw_get_pitch(void)
280{
281 return last_pitch;
279} 282}
280 283
281#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */ 284#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */
diff --git a/firmware/drivers/audio/rk27xx_codec.c b/firmware/drivers/audio/rk27xx_codec.c
index 6f71214df4..aada17cc0a 100644
--- a/firmware/drivers/audio/rk27xx_codec.c
+++ b/firmware/drivers/audio/rk27xx_codec.c
@@ -27,21 +27,6 @@
27#include "system.h" 27#include "system.h"
28#include "i2c-rk27xx.h" 28#include "i2c-rk27xx.h"
29 29
30const struct sound_settings_info audiohw_settings[] = {
31 [SOUND_VOLUME] = {"dB", 0, 1, -34, 4, -25},
32 /* HAVE_SW_TONE_CONTROLS */
33 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
34 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
35 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
36 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
37 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
38#ifdef HAVE_RECORDING /* disabled for now */
39 [SOUND_LEFT_GAIN] = {"dB", 2, 75, -1725, 3000, 0},
40 [SOUND_RIGHT_GAIN] = {"dB", 2, 75, -1725, 3000, 0},
41 [SOUND_MIC_GAIN] = {"dB", 0, 1, 0, 20, 20},
42#endif
43};
44
45/* private functions to read/write codec registers */ 30/* private functions to read/write codec registers */
46static int codec_write(uint8_t reg, uint8_t val) 31static int codec_write(uint8_t reg, uint8_t val)
47{ 32{
@@ -66,7 +51,7 @@ static void audiohw_mute(bool mute)
66} 51}
67 52
68/* public functions */ 53/* public functions */
69int tenthdb2master(int tdb) 54static int vol_tenthdb2hw(int tdb)
70{ 55{
71 /* we lie here a bit and present 0.5dB gain steps 56 /* we lie here a bit and present 0.5dB gain steps
72 * but codec has 'variable' gain steps (0.5, 1.0, 2.0) 57 * but codec has 'variable' gain steps (0.5, 1.0, 2.0)
@@ -150,6 +135,8 @@ void audiohw_set_frequency(int fsel)
150 135
151void audiohw_set_master_vol(int vol_l, int vol_r) 136void audiohw_set_master_vol(int vol_l, int vol_r)
152{ 137{
138 vol_l = vol_tenthdb2hw(vol_l);
139 vol_r = vol_tenthdb2hw(vol_r);
153 140
154 if (vol_l > 31 || vol_r > 31) 141 if (vol_l > 31 || vol_r > 31)
155 { 142 {
diff --git a/firmware/drivers/audio/sdl.c b/firmware/drivers/audio/sdl.c
index 3c7cc55ce9..eea10ad12c 100644
--- a/firmware/drivers/audio/sdl.c
+++ b/firmware/drivers/audio/sdl.c
@@ -32,107 +32,32 @@
32#ifdef HAVE_SW_VOLUME_CONTROL 32#ifdef HAVE_SW_VOLUME_CONTROL
33#include "pcm_sw_volume.h" 33#include "pcm_sw_volume.h"
34 34
35void audiohw_set_master_vol(int vol_l, int vol_r) 35void audiohw_set_volume(int vol_l, int vol_r)
36{ 36{
37 pcm_set_master_volume(vol_l, vol_r); 37 pcm_set_master_volume(vol_l, vol_r);
38} 38}
39
39#else /* ndef HAVE_SW_VOLUME_CONTROL */ 40#else /* ndef HAVE_SW_VOLUME_CONTROL */
41
40extern void pcm_set_mixer_volume(int); 42extern void pcm_set_mixer_volume(int);
41 43
42void audiohw_set_volume(int volume) 44void audiohw_set_volume(int volume)
43{ 45{
44#if CONFIG_CODEC == SWCODEC 46#if CONFIG_CODEC == SWCODEC
45#if (CONFIG_PLATFORM & PLATFORM_MAEMO5) 47#if !(CONFIG_PLATFORM & PLATFORM_MAEMO5)
48 if (volume < VOLUME_MIN)
49 volume = 0;
50 else
51 volume = SDL_MIX_MAXVOLUME * (volume - VOLUME_MIN + ONE_DB) /
52 (VOLUME_RANGE + ONE_DB);
53#endif /* !(CONFIG_PLATFORM & PLATFORM_MAEMO5) */
54
46 pcm_set_mixer_volume(volume); 55 pcm_set_mixer_volume(volume);
47#else
48 pcm_set_mixer_volume(
49 SDL_MIX_MAXVOLUME * ((volume - VOLUME_MIN) / 10) / (VOLUME_RANGE / 10));
50#endif /* (CONFIG_PLATFORM & PLATFORM_MAEMO5) */
51#else
52 (void)volume;
53#endif /* CONFIG_CODEC == SWCODEC */ 56#endif /* CONFIG_CODEC == SWCODEC */
57 (void)volume;
54} 58}
55#endif /* HAVE_SW_VOLUME_CONTROL */ 59#endif /* HAVE_SW_VOLUME_CONTROL */
56 60
57const struct sound_settings_info audiohw_settings[] = {
58 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
59/* Bass and treble tone controls */
60#ifdef AUDIOHW_HAVE_BASS
61 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
62#endif
63#ifdef AUDIOHW_HAVE_TREBLE
64 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
65#endif
66 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
67 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
68 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
69#if defined(HAVE_RECORDING)
70 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
71 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
72 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
73#endif
74#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
75 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
76#endif
77#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
78 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
79#endif
80#if defined(AUDIOHW_HAVE_DEPTH_3D)
81 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
82#endif
83/* Hardware EQ tone controls */
84#if defined(AUDIOHW_HAVE_EQ_BAND1)
85 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
86#endif
87#if defined(AUDIOHW_HAVE_EQ_BAND2)
88 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
89#endif
90#if defined(AUDIOHW_HAVE_EQ_BAND3)
91 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
92#endif
93#if defined(AUDIOHW_HAVE_EQ_BAND4)
94 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
95#endif
96#if defined(AUDIOHW_HAVE_EQ_BAND5)
97 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
98#endif
99#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
100 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1},
101#endif
102#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
103 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1},
104#endif
105#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
106 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1},
107#endif
108#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
109 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1},
110#endif
111#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
112 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1},
113#endif
114#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
115 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
116#endif
117#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
118 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
119#endif
120#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
121 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
122#endif
123
124#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
125 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
126 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
127 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
128 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
129 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
130 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
131 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
132 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
133#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
134};
135
136/** 61/**
137 * stubs here, for the simulator 62 * stubs here, for the simulator
138 **/ 63 **/
@@ -149,12 +74,14 @@ void audiohw_set_prescaler(int value)
149#if defined(AUDIOHW_HAVE_BALANCE) 74#if defined(AUDIOHW_HAVE_BALANCE)
150void audiohw_set_balance(int value) { (void)value; } 75void audiohw_set_balance(int value) { (void)value; }
151#endif 76#endif
77#ifndef HAVE_SW_TONE_CONTROLS
152#if defined(AUDIOHW_HAVE_BASS) 78#if defined(AUDIOHW_HAVE_BASS)
153void audiohw_set_bass(int value) { (void)value; } 79void audiohw_set_bass(int value) { (void)value; }
154#endif 80#endif
155#if defined(AUDIOHW_HAVE_TREBLE) 81#if defined(AUDIOHW_HAVE_TREBLE)
156void audiohw_set_treble(int value) { (void)value; } 82void audiohw_set_treble(int value) { (void)value; }
157#endif 83#endif
84#endif /* HAVE_SW_TONE_CONTROLS */
158#if CONFIG_CODEC != SWCODEC 85#if CONFIG_CODEC != SWCODEC
159void audiohw_set_channel(int value) { (void)value; } 86void audiohw_set_channel(int value) { (void)value; }
160void audiohw_set_stereo_width(int value){ (void)value; } 87void audiohw_set_stereo_width(int value){ (void)value; }
@@ -182,6 +109,10 @@ void audiohw_set_eq_band_width(unsigned int band, int value)
182void audiohw_set_depth_3d(int value) 109void audiohw_set_depth_3d(int value)
183 { (void)value; } 110 { (void)value; }
184#endif 111#endif
112#if defined(AUDIOHW_HAVE_LINEOUT)
113void audiohw_set_lineout_volume(int vol_l, int vol_r)
114 { (void)vol_l; (void)vol_r; }
115#endif
185 116
186void audiohw_close(void) {} 117void audiohw_close(void) {}
187 118
diff --git a/firmware/drivers/audio/tlv320.c b/firmware/drivers/audio/tlv320.c
index 6b96ed212f..23d2fea3a1 100644
--- a/firmware/drivers/audio/tlv320.c
+++ b/firmware/drivers/audio/tlv320.c
@@ -46,8 +46,8 @@ const struct sound_settings_info audiohw_settings[] = {
46#endif 46#endif
47}; 47};
48 48
49/* convert tenth of dB volume (-840..0) to master volume register value */ 49/* convert tenth of dB volume (-73..6) to master volume register value */
50int tenthdb2master(int db) 50static int vol_tenthdb2hw(int db)
51{ 51{
52 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 52 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
53 /* 1111111 == +6dB (0x7f) */ 53 /* 1111111 == +6dB (0x7f) */
@@ -210,8 +210,11 @@ void audiohw_set_frequency(int fsel)
210 * 210 *
211 * Left & Right: 48 .. 121 .. 127 => Volume -73dB (mute) .. +0 dB .. +6 dB 211 * Left & Right: 48 .. 121 .. 127 => Volume -73dB (mute) .. +0 dB .. +6 dB
212 */ 212 */
213void audiohw_set_headphone_vol(int vol_l, int vol_r) 213void audiohw_set_volume(int vol_l, int vol_r)
214{ 214{
215 vol_l = vol_tenthdb2hw(vol_l);
216 vol_r = vol_tenthdb2hw(vol_r);
217
215 unsigned value_dap = tlv320_regs[REG_DAP]; 218 unsigned value_dap = tlv320_regs[REG_DAP];
216 unsigned value_dap_last = value_dap; 219 unsigned value_dap_last = value_dap;
217 unsigned value_l = LHV_LHV(vol_l); 220 unsigned value_l = LHV_LHV(vol_l);
diff --git a/firmware/drivers/audio/tsc2100.c b/firmware/drivers/audio/tsc2100.c
index 6479f84b34..41327ae3d7 100644
--- a/firmware/drivers/audio/tsc2100.c
+++ b/firmware/drivers/audio/tsc2100.c
@@ -29,18 +29,9 @@
29#include "sound.h" 29#include "sound.h"
30#include "tsc2100.h" 30#include "tsc2100.h"
31 31
32const struct sound_settings_info audiohw_settings[] = {
33 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, -25},
34 /* HAVE_SW_TONE_CONTROLS */
35 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
36 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
37 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
38 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
39 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
40};
41static bool is_muted = false; 32static bool is_muted = false;
42/* convert tenth of dB volume to master volume register value */ 33/* convert tenth of dB volume to volume register value */
43int tenthdb2master(int db) 34static int vol_tenthdb2hw(int db)
44{ 35{
45 /* 0 to -63.0dB in 1dB steps, tsc2100 can goto -63.5 in 0.5dB steps */ 36 /* 0 to -63.0dB in 1dB steps, tsc2100 can goto -63.5 in 0.5dB steps */
46 if (db < VOLUME_MIN) { 37 if (db < VOLUME_MIN) {
@@ -52,27 +43,6 @@ int tenthdb2master(int db)
52 } 43 }
53} 44}
54 45
55int sound_val2phys(int setting, int value)
56{
57 int result;
58
59 switch(setting)
60 {
61#if 0
62 case SOUND_LEFT_GAIN:
63 case SOUND_RIGHT_GAIN:
64 case SOUND_MIC_GAIN:
65 result = (value - 23) * 15;
66 break;
67#endif
68 default:
69 result = value;
70 break;
71 }
72
73 return result;
74}
75
76void audiohw_init(void) 46void audiohw_init(void)
77{ 47{
78 short val = tsc2100_readreg(TSAC4_PAGE, TSAC4_ADDRESS); 48 short val = tsc2100_readreg(TSAC4_PAGE, TSAC4_ADDRESS);
@@ -104,9 +74,12 @@ void audiohw_postinit(void)
104 audiohw_mute(false); 74 audiohw_mute(false);
105} 75}
106 76
107void audiohw_set_master_vol(int vol_l, int vol_r) 77void audiohw_set_master_volume(int vol_l, int vol_r)
108{ 78{
109 tsc2100_writereg(TSDACGAIN_PAGE, TSDACGAIN_ADDRESS, (short)((vol_l<<8) | vol_r) ); 79 vol_l = vol_tenthdb2hw(vol_l);
80 vol_r = vol_tenthdb2hw(vol_r);
81 tsc2100_writereg(TSDACGAIN_PAGE, TSDACGAIN_ADDRESS,
82 (short)((vol_l<<8) | vol_r) );
110} 83}
111 84
112void audiohw_close(void) 85void audiohw_close(void)
diff --git a/firmware/drivers/audio/uda1341.c b/firmware/drivers/audio/uda1341.c
index 6b38353afe..ac3bcedb7d 100644
--- a/firmware/drivers/audio/uda1341.c
+++ b/firmware/drivers/audio/uda1341.c
@@ -28,23 +28,8 @@
28 28
29#include "audiohw.h" 29#include "audiohw.h"
30 30
31 31/* convert tenth of dB volume (-600..0) to volume register value */
32const struct sound_settings_info audiohw_settings[] = { 32static int vol_tenthdb2hw(int db)
33 [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25},
34 [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0},
35 [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0},
36 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, /* not used */
37 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, /* not used */
38 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, /* not used */
39#ifdef HAVE_RECORDING
40 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
41 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
42 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
43#endif
44};
45
46/* convert tenth of dB volume (-600..0) to master volume register value */
47int tenthdb2master(int db)
48{ 33{
49 if (db < -600) 34 if (db < -600)
50 return 63; 35 return 63;
@@ -229,11 +214,12 @@ void audiohw_set_prescaler(int val)
229#endif /* AUDIOHW_HAVE_PRESCALER */ 214#endif /* AUDIOHW_HAVE_PRESCALER */
230 215
231/** 216/**
232 * Sets left and right master volume (1(max) to 62(muted)) 217 * Set master volume (1(max) to 62(muted))
233 */ 218 */
234void audiohw_set_master_vol(int vol_l, int vol_r) 219void audiohw_set_volume(int volume)
235{ 220{
236 uda_regs[UDA_REG_ID_CTRL0] = (vol_l + vol_r) / 2; 221 volume = vol_tenthdb2hw(volume) / 2;
222 uda_regs[UDA_REG_ID_CTRL0] = volume;
237 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL0 | uda_regs[UDA_REG_ID_CTRL0]); 223 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL0 | uda_regs[UDA_REG_ID_CTRL0]);
238} 224}
239 225
diff --git a/firmware/drivers/audio/uda1380.c b/firmware/drivers/audio/uda1380.c
index fd32b398ca..9d6ece105b 100644
--- a/firmware/drivers/audio/uda1380.c
+++ b/firmware/drivers/audio/uda1380.c
@@ -40,22 +40,8 @@
40#define USE_WSPLL 40#define USE_WSPLL
41#endif 41#endif
42 42
43const struct sound_settings_info audiohw_settings[] = {
44 [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25},
45 [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0},
46 [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0},
47 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
48 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
49 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
50#ifdef HAVE_RECORDING
51 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
52 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
53 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
54#endif
55};
56
57/* convert tenth of dB volume (-840..0) to master volume register value */ 43/* convert tenth of dB volume (-840..0) to master volume register value */
58int tenthdb2master(int db) 44static int vol_tenthdb2hw(int db)
59{ 45{
60 if (db < -720) /* 1.5 dB steps */ 46 if (db < -720) /* 1.5 dB steps */
61 return (2940 - db) / 15; 47 return (2940 - db) / 15;
@@ -68,7 +54,7 @@ int tenthdb2master(int db)
68} 54}
69 55
70/* convert tenth of dB volume (-780..0) to mixer volume register value */ 56/* convert tenth of dB volume (-780..0) to mixer volume register value */
71int tenthdb2mixer(int db) 57static int mixer_tenthdb2hw(int db)
72{ 58{
73 if (db < -660) /* 1.5 dB steps */ 59 if (db < -660) /* 1.5 dB steps */
74 return (2640 - db) / 15; 60 return (2640 - db) / 15;
@@ -138,19 +124,12 @@ static int uda1380_write_reg(unsigned char reg, unsigned short value)
138/** 124/**
139 * Sets left and right master volume (0(max) to 252(muted)) 125 * Sets left and right master volume (0(max) to 252(muted))
140 */ 126 */
141void audiohw_set_master_vol(int vol_l, int vol_r) 127void audiohw_set_volume(int vol_l, int vol_r)
142{ 128{
129 vol_l = vol_tenthdb2hw(vol_l);
130 vol_r = vol_tenthdb2hw(vol_r);
143 uda1380_write_reg(REG_MASTER_VOL, 131 uda1380_write_reg(REG_MASTER_VOL,
144 MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); 132 MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r));
145}
146
147/**
148 * Sets mixer volume for both channels (0(max) to 228(muted))
149 */
150void audiohw_set_mixer_vol(int channel1, int channel2)
151{
152 uda1380_write_reg(REG_MIX_VOL,
153 MIX_VOL_CH_1(channel1) | MIX_VOL_CH_2(channel2));
154} 133}
155 134
156/** 135/**
@@ -285,7 +264,9 @@ void audiohw_postinit(void)
285 264
286void audiohw_set_prescaler(int val) 265void audiohw_set_prescaler(int val)
287{ 266{
288 audiohw_set_mixer_vol(tenthdb2mixer(-val), tenthdb2mixer(-val)); 267 val = mixer_tenthdb2hw(-val);
268 uda1380_write_reg(REG_MIX_VOL,
269 MIX_VOL_CH_1(val) | MIX_VOL_CH_2(val));
289} 270}
290 271
291/* Nice shutdown of UDA1380 codec */ 272/* Nice shutdown of UDA1380 codec */
diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c
index 71050454f3..3689a28f31 100644
--- a/firmware/drivers/audio/wm8731.c
+++ b/firmware/drivers/audio/wm8731.c
@@ -37,22 +37,6 @@
37#include "wmcodec.h" 37#include "wmcodec.h"
38#include "sound.h" 38#include "sound.h"
39 39
40
41const struct sound_settings_info audiohw_settings[] = {
42 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
43 /* HAVE_SW_TONE_CONTROLS */
44 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
45 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
46 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
47 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
48 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
49#if defined(HAVE_WM8731) && defined(HAVE_RECORDING)
50 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
51 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
52 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0},
53#endif
54};
55
56/* Init values/shadows 40/* Init values/shadows
57 * Ignore bit 8 since that only specifies "both" for updating 41 * Ignore bit 8 since that only specifies "both" for updating
58 * gains - "RESET" (15h) not included */ 42 * gains - "RESET" (15h) not included */
@@ -109,22 +93,6 @@ static void wmc_write_masked(int reg, unsigned bits, unsigned mask)
109 wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask)); 93 wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask));
110} 94}
111 95
112/* convert tenth of dB volume (-730..60) to master volume register value */
113int tenthdb2master(int db)
114{
115 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
116 /* 1111111 == +6dB (0x7f) */
117 /* 1111001 == 0dB (0x79) */
118 /* 0110000 == -73dB (0x30 */
119 /* 0101111 == mute (0x2f) */
120
121 if (db < VOLUME_MIN) {
122 return 0x2f;
123 } else {
124 return((db/10)+0x30+73);
125 }
126}
127
128int sound_val2phys(int setting, int value) 96int sound_val2phys(int setting, int value)
129{ 97{
130 int result; 98 int result;
@@ -148,6 +116,21 @@ int sound_val2phys(int setting, int value)
148 return result; 116 return result;
149} 117}
150 118
119/* convert tenth of dB volume (-730..60) to master volume register value */
120static int vol_tenthdb2hw(int db)
121{
122 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
123 /* 1111111 == +6dB (0x7f) */
124 /* 1111001 == 0dB (0x79) */
125 /* 0110000 == -73dB (0x30) */
126 /* 0101111 == mute (0x2f) */
127 if (db < VOLUME_MIN) {
128 return 0x2f;
129 } else {
130 return((db/10)+0x30+73);
131 }
132}
133
151static void audiohw_mute(bool mute) 134static void audiohw_mute(bool mute)
152{ 135{
153 if (mute) { 136 if (mute) {
@@ -207,13 +190,11 @@ void audiohw_postinit(void)
207#endif 190#endif
208} 191}
209 192
210void audiohw_set_master_vol(int vol_l, int vol_r) 193void audiohw_set_volume(int vol_l, int vol_r)
211{ 194{
212 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 195 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
213 /* 1111111 == +6dB */ 196 vol_l = vol_tenthdb2hw(vol_l);
214 /* 1111001 == 0dB */ 197 vol_r = vol_tenthdb2hw(vol_r);
215 /* 0110000 == -73dB */
216 /* 0101111 == mute (0x2f) */
217 wmc_write_masked(LOUTVOL, vol_l, WMC_OUT_VOL_MASK); 198 wmc_write_masked(LOUTVOL, vol_l, WMC_OUT_VOL_MASK);
218 wmc_write_masked(ROUTVOL, vol_r, WMC_OUT_VOL_MASK); 199 wmc_write_masked(ROUTVOL, vol_r, WMC_OUT_VOL_MASK);
219} 200}
diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c
index 4cb85db436..feba05e504 100644
--- a/firmware/drivers/audio/wm8751.c
+++ b/firmware/drivers/audio/wm8751.c
@@ -32,35 +32,6 @@
32#include "system.h" 32#include "system.h"
33#include "sound.h" 33#include "sound.h"
34 34
35const struct sound_settings_info audiohw_settings[] = {
36 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
37 [SOUND_BASS] = {"dB", 1, 15, -60, 90, 0},
38 [SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0},
39 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
40 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
41 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
42#ifdef HAVE_RECORDING
43 /* PGA -17.25dB to 30.0dB in 0.75dB increments 64 steps
44 * digital gain 0dB to 30.0dB in 0.5dB increments
45 * we use 0.75dB fake steps through whole range
46 *
47 * This combined gives -17.25 to 60.0dB
48 */
49 [SOUND_LEFT_GAIN] = {"dB", 2, 75, -1725, 6000, 0},
50 [SOUND_RIGHT_GAIN] = {"dB", 2, 75, -1725, 6000, 0},
51 [SOUND_MIC_GAIN] = {"dB", 2, 75, -1725, 6000, 3000},
52#endif
53#ifdef AUDIOHW_HAVE_BASS_CUTOFF
54 [SOUND_BASS_CUTOFF] = {"Hz", 0, 70, 130, 200, 200},
55#endif
56#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
57 [SOUND_TREBLE_CUTOFF] = {"kHz", 0, 4, 4, 8, 4},
58#endif
59#ifdef AUDIOHW_HAVE_DEPTH_3D
60 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
61#endif
62};
63
64static uint16_t wmcodec_regs[WM_NUM_REGS] = 35static uint16_t wmcodec_regs[WM_NUM_REGS] =
65{ 36{
66 [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */ 37 [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */
@@ -139,7 +110,7 @@ static void wmcodec_set_masked(unsigned int reg, unsigned int val,
139} 110}
140 111
141/* convert tenth of dB volume (-730..60) to master volume register value */ 112/* convert tenth of dB volume (-730..60) to master volume register value */
142int tenthdb2master(int db) 113static int vol_tenthdb2hw(int db)
143{ 114{
144 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 115 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
145 /* 1111111 == +6dB (0x7f) */ 116 /* 1111111 == +6dB (0x7f) */
@@ -186,25 +157,6 @@ void audiohw_set_treble_cutoff(int val)
186} 157}
187#endif 158#endif
188 159
189
190int sound_val2phys(int setting, int value)
191{
192 int result;
193
194 switch (setting)
195 {
196#ifdef AUDIOHW_HAVE_DEPTH_3D
197 case SOUND_DEPTH_3D:
198 result = (100 * value + 8) / 15;
199 break;
200#endif
201 default:
202 result = value;
203 }
204
205 return result;
206}
207
208static void audiohw_mute(bool mute) 160static void audiohw_mute(bool mute)
209{ 161{
210 /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */ 162 /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */
@@ -335,40 +287,39 @@ void audiohw_postinit(void)
335#endif 287#endif
336} 288}
337 289
338void audiohw_set_master_vol(int vol_l, int vol_r) 290void audiohw_set_volume(int vol_l, int vol_r)
339{ 291{
340 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 292 vol_l = vol_tenthdb2hw(vol_l);
341 /* 1111111 == +6dB */ 293 vol_r = vol_tenthdb2hw(vol_r);
342 /* 1111001 == 0dB */
343 /* 0110000 == -73dB */
344 /* 0101111 == mute (0x2f) */
345
346 wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l), 294 wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l),
347 LOUT1_LOUT1VOL_MASK); 295 LOUT1_LOUT1VOL_MASK);
348 wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r), 296 wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r),
349 ROUT1_ROUT1VOL_MASK); 297 ROUT1_ROUT1VOL_MASK);
350} 298}
351 299
352#ifdef TOSHIBA_GIGABEAT_F 300#ifdef AUDIOHW_HAVE_LINEOUT
353void audiohw_set_lineout_vol(int vol_l, int vol_r) 301void audiohw_set_lineout_volume(int vol_l, int vol_r)
354{ 302{
303 vol_l = vol_tenthdb2hw(vol_l);
304 vol_r = vol_tenthdb2hw(vol_r);
355 wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l), 305 wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l),
356 LOUT2_LOUT2VOL_MASK); 306 LOUT2_LOUT2VOL_MASK);
357 wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r), 307 wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r),
358 ROUT2_ROUT2VOL_MASK); 308 ROUT2_ROUT2VOL_MASK);
359} 309}
360#endif 310#endif /* AUDIOHW_HAVE_LINEOUT */
361 311
362void audiohw_set_bass(int value) 312void audiohw_set_bass(int value)
363{ 313{
364 wmcodec_set_masked(BASSCTRL, 314 value = tone_tenthdb2hw(value);
365 BASSCTRL_BASS(tone_tenthdb2hw(value)), 315 wmcodec_set_masked(BASSCTRL, BASSCTRL_BASS(value),
366 BASSCTRL_BASS_MASK); 316 BASSCTRL_BASS_MASK);
367} 317}
368 318
369void audiohw_set_treble(int value) 319void audiohw_set_treble(int value)
370{ 320{
371 wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(tone_tenthdb2hw(value)), 321 value = tone_tenthdb2hw(value);
322 wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(value),
372 TREBCTRL_TREB_MASK); 323 TREBCTRL_TREB_MASK);
373} 324}
374 325
diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c
index aa78a7710d..3e0c88c55c 100644
--- a/firmware/drivers/audio/wm8758.c
+++ b/firmware/drivers/audio/wm8758.c
@@ -33,22 +33,6 @@
33#include "audiohw.h" 33#include "audiohw.h"
34#include "sound.h" 34#include "sound.h"
35 35
36const struct sound_settings_info audiohw_settings[] = {
37 [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25},
38 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0},
39 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0},
40 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
41 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
42 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
43#ifdef HAVE_RECORDING
44 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 63, 16},
45 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 63, 16},
46 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 63, 16},
47#endif
48 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
49 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
50};
51
52/* shadow registers */ 36/* shadow registers */
53static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0); 37static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0);
54static unsigned short eq5_reg = EQ_GAIN_VALUE(0); 38static unsigned short eq5_reg = EQ_GAIN_VALUE(0);
@@ -96,27 +80,6 @@ static void get_volume_params(int db, int *dac, int *amp)
96 } 80 }
97} 81}
98 82
99int sound_val2phys(int setting, int value)
100{
101 int result;
102
103 switch(setting)
104 {
105#ifdef HAVE_RECORDING
106 case SOUND_LEFT_GAIN:
107 case SOUND_RIGHT_GAIN:
108 case SOUND_MIC_GAIN:
109 result = ((value - 16) * 15) / 2;
110 break;
111#endif
112 default:
113 result = value;
114 break;
115 }
116
117 return result;
118}
119
120static void audiohw_mute(bool mute) 83static void audiohw_mute(bool mute)
121{ 84{
122 if (mute) { 85 if (mute) {
diff --git a/firmware/drivers/audio/wm8975.c b/firmware/drivers/audio/wm8975.c
index c46dab79de..3b9fef0dbc 100644
--- a/firmware/drivers/audio/wm8975.c
+++ b/firmware/drivers/audio/wm8975.c
@@ -34,20 +34,6 @@
34#include "wmcodec.h" 34#include "wmcodec.h"
35#include "audiohw.h" 35#include "audiohw.h"
36 36
37const struct sound_settings_info audiohw_settings[] = {
38 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
39 [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0},
40 [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0},
41 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
42 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
43 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
44#ifdef HAVE_RECORDING
45 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 63, 23},
46 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 63, 23},
47 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 63, 0},
48#endif
49};
50
51static unsigned short wm8975_regs[WM8975_NUM_REGISTERS] = 37static unsigned short wm8975_regs[WM8975_NUM_REGISTERS] =
52{ 38{
53 [LINVOL] = LINVOL_LZCEN | 23, /* 0dB */ 39 [LINVOL] = LINVOL_LZCEN | 23, /* 0dB */
@@ -85,7 +71,7 @@ static void wm8975_write_or(int reg, unsigned bits)
85} 71}
86 72
87/* convert tenth of dB volume (-730..60) to master volume register value */ 73/* convert tenth of dB volume (-730..60) to master volume register value */
88int tenthdb2master(int db) 74static int vol_tenthdb2hw(int db)
89{ 75{
90 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 76 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
91 /* 1111111 == +6dB (0x7f) */ 77 /* 1111111 == +6dB (0x7f) */
@@ -100,29 +86,6 @@ int tenthdb2master(int db)
100 } 86 }
101} 87}
102 88
103int sound_val2phys(int setting, int value)
104{
105 int result;
106
107 switch(setting)
108 {
109#ifdef HAVE_RECORDING
110 case SOUND_LEFT_GAIN:
111 case SOUND_RIGHT_GAIN:
112 result = ((value - 23) * 15) / 2;
113 break;
114 case SOUND_MIC_GAIN:
115 result = ((value - 23) * 15) / 2 + 200;
116 break;
117#endif
118 default:
119 result = value;
120 break;
121 }
122
123 return result;
124}
125
126static void audiohw_mute(bool mute) 89static void audiohw_mute(bool mute)
127{ 90{
128 if (mute) { 91 if (mute) {
@@ -205,13 +168,10 @@ void audiohw_postinit(void)
205} 168}
206#endif 169#endif
207 170
208void audiohw_set_master_vol(int vol_l, int vol_r) 171void audiohw_set_volume(int vol_l, int vol_r)
209{ 172{
210 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ 173 vol_l = vol_tenthdb2hw(vol_l);
211 /* 1111111 == +6dB */ 174 vol_r = vol_tenthdb2hw(vol_r);
212 /* 1111001 == 0dB */
213 /* 0110000 == -73dB */
214 /* 0101111 == mute (0x2f) */
215 175
216 /* OUT1 */ 176 /* OUT1 */
217 wm8975_write(LOUT1VOL, LOUT1VOL_LO1ZC | vol_l); 177 wm8975_write(LOUT1VOL, LOUT1VOL_LO1ZC | vol_l);
@@ -220,6 +180,9 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
220 180
221void audiohw_set_lineout_vol(int vol_l, int vol_r) 181void audiohw_set_lineout_vol(int vol_l, int vol_r)
222{ 182{
183 vol_l = vol_tenthdb2hw(vol_l);
184 vol_r = vol_tenthdb2hw(vol_r);
185
223 /* OUT2 */ 186 /* OUT2 */
224 wm8975_write(LOUT2VOL, LOUT2VOL_LO2ZC | vol_l); 187 wm8975_write(LOUT2VOL, LOUT2VOL_LO2ZC | vol_l);
225 wm8975_write(ROUT2VOL, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | vol_r); 188 wm8975_write(ROUT2VOL, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | vol_r);
diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c
index 3602bf9cb3..3a86ef204e 100644
--- a/firmware/drivers/audio/wm8978.c
+++ b/firmware/drivers/audio/wm8978.c
@@ -36,39 +36,6 @@
36 * file it may break things. */ 36 * file it may break things. */
37extern void audiohw_enable_headphone_jack(bool enable); 37extern void audiohw_enable_headphone_jack(bool enable);
38 38
39const struct sound_settings_info audiohw_settings[] =
40{
41 [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25},
42 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
43 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
44 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
45 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
46 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
47 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
48 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
49 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
50 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 0, 3, 0},
51 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 0, 3, 0},
52 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 0, 3, 0},
53 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 0, 3, 0},
54 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 0, 3, 0},
55 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
56 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
57 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
58 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
59#ifdef HAVE_RECORDING
60 /* Digital: -119.0dB to +8.0dB in 0.5dB increments
61 * Analog: Relegated to volume control
62 * Circumstances unfortunately do not allow a great deal of positive
63 * gain. */
64 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0},
65 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0},
66#if 0
67 [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0},
68#endif
69#endif
70};
71
72static uint16_t wmc_regs[WMC_NUM_REGISTERS] = 39static uint16_t wmc_regs[WMC_NUM_REGISTERS] =
73{ 40{
74 /* Initialized with post-reset default values - the 2-wire interface 41 /* Initialized with post-reset default values - the 2-wire interface
@@ -184,9 +151,9 @@ static void wmc_write_masked(unsigned int reg, unsigned int bits,
184 wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask)); 151 wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask));
185} 152}
186 153
187/* convert tenth of dB volume (-890..60) to master volume register value 154/* convert tenth of dB volume (-890..60) to volume register value
188 * (000000...111111) */ 155 * (000000...111111) */
189int tenthdb2master(int db) 156static int vol_tenthdb2hw(int db)
190{ 157{
191 /* -90dB to +6dB 1dB steps (96 levels) 7bits */ 158 /* -90dB to +6dB 1dB steps (96 levels) 7bits */
192 /* 1100000 == +6dB (0x60,96) */ 159 /* 1100000 == +6dB (0x60,96) */
@@ -194,7 +161,7 @@ int tenthdb2master(int db)
194 /* 1000001 == -57dB (0x21,33,DAC) */ 161 /* 1000001 == -57dB (0x21,33,DAC) */
195 /* 0000001 == -89dB (0x01,01) */ 162 /* 0000001 == -89dB (0x01,01) */
196 /* 0000000 == -90dB (0x00,00,Mute) */ 163 /* 0000000 == -90dB (0x00,00,Mute) */
197 if (db <= VOLUME_MIN) 164 if (db < VOLUME_MIN)
198 { 165 {
199 return 0x0; 166 return 0x0;
200 } 167 }
@@ -204,39 +171,6 @@ int tenthdb2master(int db)
204 } 171 }
205} 172}
206 173
207int sound_val2phys(int setting, int value)
208{
209 int result;
210
211 switch (setting)
212 {
213#ifdef HAVE_RECORDING
214 case SOUND_LEFT_GAIN:
215 case SOUND_RIGHT_GAIN:
216 case SOUND_MIC_GAIN:
217 result = value * 5;
218 break;
219#endif
220
221 case SOUND_EQ_BAND1_GAIN+0x10000:
222 case SOUND_EQ_BAND2_GAIN+0x10000:
223 case SOUND_EQ_BAND3_GAIN+0x10000:
224 case SOUND_EQ_BAND4_GAIN+0x10000:
225 case SOUND_EQ_BAND5_GAIN+0x10000:
226 result = value * 10;
227 break;
228
229 case SOUND_DEPTH_3D:
230 result = (100 * value + 8) / 15;
231 break;
232
233 default:
234 result = value;
235 }
236
237 return result;
238}
239
240void audiohw_preinit(void) 174void audiohw_preinit(void)
241{ 175{
242 /* 1. Turn on external power supplies. Wait for supply voltage to settle. */ 176 /* 1. Turn on external power supplies. Wait for supply voltage to settle. */
@@ -350,13 +284,16 @@ static void sync_prescaler(void)
350 WMC_DVOL); 284 WMC_DVOL);
351} 285}
352 286
353void audiohw_set_headphone_vol(int vol_l, int vol_r) 287void audiohw_set_volume(int vol_l, int vol_r)
354{ 288{
355 int prev_l = wmc_vol.vol_l; 289 int prev_l = wmc_vol.vol_l;
356 int prev_r = wmc_vol.vol_r; 290 int prev_r = wmc_vol.vol_r;
357 int dac_l, dac_r, hp_l, hp_r; 291 int dac_l, dac_r, hp_l, hp_r;
358 int mix_l, mix_r, boost_l, boost_r; 292 int mix_l, mix_r, boost_l, boost_r;
359 293
294 vol_l = vol_tenthdb2hw(vol_l);
295 vol_r = vol_tenthdb2hw(vol_r);
296
360 wmc_vol.vol_l = vol_l; 297 wmc_vol.vol_l = vol_l;
361 wmc_vol.vol_r = vol_r; 298 wmc_vol.vol_r = vol_r;
362 299
diff --git a/firmware/drivers/audio/wm8985.c b/firmware/drivers/audio/wm8985.c
index 06b3fa3b44..2d49e706c8 100644
--- a/firmware/drivers/audio/wm8985.c
+++ b/firmware/drivers/audio/wm8985.c
@@ -88,32 +88,12 @@
88#define OUT4MIX 0x39 88#define OUT4MIX 0x39
89#define BIASCTL 0x3d 89#define BIASCTL 0x3d
90 90
91const struct sound_settings_info audiohw_settings[] = {
92 [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25},
93 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0},
94 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0},
95 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
96 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
97 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
98#ifdef HAVE_RECORDING
99 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
100 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
101 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
102#endif
103#ifdef AUDIOHW_HAVE_BASS_CUTOFF
104 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
105#endif
106#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
107 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
108#endif
109};
110
111/* shadow registers */ 91/* shadow registers */
112static unsigned int eq1_reg; 92static unsigned int eq1_reg;
113static unsigned int eq5_reg; 93static unsigned int eq5_reg;
114 94
115/* convert tenth of dB volume (-89..6) to master volume register value */ 95/* convert tenth of dB volume (-89..6) to master volume register value */
116int tenthdb2master(int db) 96static int vol_tenthdb2hw(int db)
117{ 97{
118 /* Might have no sense, taken from wm8758.c : 98 /* Might have no sense, taken from wm8758.c :
119 att DAC AMP result 99 att DAC AMP result
@@ -216,9 +196,13 @@ void audiohw_postinit(void)
216 audiohw_mute(0); 196 audiohw_mute(0);
217} 197}
218 198
219void audiohw_set_headphone_vol(int vol_l, int vol_r) 199void audiohw_set_volume(int vol_l, int vol_r)
220{ 200{
221 int dac_l, amp_l, dac_r, amp_r; 201 int dac_l, amp_l, dac_r, amp_r;
202
203 vol_l = vol_tenthdb2hw(vol_l);
204 vol_r = vol_tenthdb2hw(vol_r);
205
222 get_volume_params(vol_l, &dac_l, &amp_l); 206 get_volume_params(vol_l, &dac_l, &amp_l);
223 get_volume_params(vol_r, &dac_r, &amp_r); 207 get_volume_params(vol_r, &dac_r, &amp_r);
224 208
@@ -232,15 +216,19 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r)
232 wmcodec_write(ROUT1VOL, amp_r | 0x180); 216 wmcodec_write(ROUT1VOL, amp_r | 0x180);
233} 217}
234 218
235void audiohw_set_lineout_vol(int vol_l, int vol_r) 219void audiohw_set_lineout_volume(int vol_l, int vol_r)
236{ 220{
237 int dac_l, amp_l, dac_r, amp_r; 221 int dac_l, amp_l, dac_r, amp_r;
238 get_volume_params(vol_l, &dac_l, &amp_l); 222
239 get_volume_params(vol_r, &dac_r, &amp_r); 223 vol_l = vol_tenthdb2hw(vol_l);
224 vol_r = vol_tenthdb2hw(vol_r);
225
226 get_volume_params(vol_l, &dac_l, &amp_l);
227 get_volume_params(vol_r, &dac_r, &amp_r);
240 228
241 /* set lineout amp OUT2 */ 229 /* set lineout amp OUT2 */
242 wmcodec_write(LOUT2VOL, amp_l); 230 wmcodec_write(LOUT2VOL, amp_l);
243 wmcodec_write(ROUT2VOL, amp_r | 0x100); 231 wmcodec_write(ROUT2VOL, amp_r | 0x100);
244} 232}
245 233
246void audiohw_set_aux_vol(int vol_l, int vol_r) 234void audiohw_set_aux_vol(int vol_l, int vol_r)