summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/fixedpoint.c2
-rw-r--r--apps/settings.c2
-rw-r--r--firmware/SOURCES2
-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
-rw-r--r--firmware/export/aic3x.h6
-rw-r--r--firmware/export/ak4537.h4
-rw-r--r--firmware/export/as3514.h39
-rw-r--r--firmware/export/audiohw.h149
-rw-r--r--firmware/export/audiohw_settings.h143
-rw-r--r--firmware/export/cs42l55.h15
-rw-r--r--firmware/export/dac3550a.h1
-rw-r--r--firmware/export/dummy_codec.h2
-rw-r--r--firmware/export/hosted_codec.h30
-rw-r--r--firmware/export/imx233-codec.h15
-rw-r--r--firmware/export/jz4740-codec.h13
-rw-r--r--firmware/export/mas35xx.h59
-rw-r--r--firmware/export/rk27xx_codec.h12
-rw-r--r--firmware/export/sound.h14
-rw-r--r--firmware/export/tlv320.h28
-rw-r--r--firmware/export/tsc2100.h9
-rw-r--r--firmware/export/uda1341.h17
-rw-r--r--firmware/export/uda1380.h19
-rw-r--r--firmware/export/wm8731.h13
-rw-r--r--firmware/export/wm8751.h38
-rw-r--r--firmware/export/wm8758.h25
-rw-r--r--firmware/export/wm8975.h20
-rw-r--r--firmware/export/wm8978.h40
-rw-r--r--firmware/export/wm8985.h22
-rw-r--r--firmware/include/fixedpoint.h5
-rw-r--r--firmware/sound.c489
-rw-r--r--firmware/target/arm/pnx0101/pcm-pnx0101.c6
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c24
-rw-r--r--lib/rbcodec/dsp/dsp_misc.c83
-rw-r--r--lib/rbcodec/dsp/dsp_misc.h16
-rw-r--r--lib/rbcodec/test/warble.c2
55 files changed, 1009 insertions, 1233 deletions
diff --git a/apps/fixedpoint.c b/apps/fixedpoint.c
index 5051cc78e7..b212929245 100644
--- a/apps/fixedpoint.c
+++ b/apps/fixedpoint.c
@@ -353,7 +353,7 @@ long fp16_exp(int x)
353/** FIXED POINT EXP10 353/** FIXED POINT EXP10
354 * Return 10^x as FP integer. Argument is FP integer. 354 * Return 10^x as FP integer. Argument is FP integer.
355 */ 355 */
356static long fp_exp10(long x, unsigned int fracbits) 356long fp_exp10(long x, unsigned int fracbits)
357{ 357{
358 long k; 358 long k;
359 long z; 359 long z;
diff --git a/apps/settings.c b/apps/settings.c
index 1bb6c74b43..0984143dbb 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -723,7 +723,7 @@ void settings_apply_pm_range(void)
723void sound_settings_apply(void) 723void sound_settings_apply(void)
724{ 724{
725#if CONFIG_CODEC == SWCODEC 725#if CONFIG_CODEC == SWCODEC
726 sound_set_dsp_callback(dsp_callback); 726 audiohw_swcodec_set_callback(dsp_callback);
727#endif 727#endif
728#ifdef AUDIOHW_HAVE_BASS 728#ifdef AUDIOHW_HAVE_BASS
729 sound_set(SOUND_BASS, global_settings.bass); 729 sound_set(SOUND_BASS, global_settings.bass);
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 964d57ff5d..e6c0b967d4 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -361,6 +361,8 @@ pcm_sw_volume.c
361#ifdef HAVE_RECORDING 361#ifdef HAVE_RECORDING
362enc_base.c 362enc_base.c
363#endif /* HAVE_RECORDING */ 363#endif /* HAVE_RECORDING */
364
365drivers/audio/audiohw-swcodec.c
364#endif /* BOOTLOADER */ 366#endif /* BOOTLOADER */
365#endif /* SWCODEC */ 367#endif /* SWCODEC */
366 368
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)
diff --git a/firmware/export/aic3x.h b/firmware/export/aic3x.h
index 4cfa0a5535..65e1ebd62c 100644
--- a/firmware/export/aic3x.h
+++ b/firmware/export/aic3x.h
@@ -25,12 +25,10 @@
25#define VOLUME_MIN -630 25#define VOLUME_MIN -630
26#define VOLUME_MAX 0 26#define VOLUME_MAX 0
27 27
28extern int tenthdb2master(int db); 28AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -64, 0, -25)
29 29
30/*** definitions ***/ 30/*** definitions ***/
31extern void audiohw_set_headphone_vol(int vol_l, int vol_r); 31void aic3x_switch_output(bool stereo);
32
33extern void aic3x_switch_output(bool stereo);
34 32
35/* Page 0 registers */ 33/* Page 0 registers */
36#define AIC3X_PAGE_SELECT 0 34#define AIC3X_PAGE_SELECT 0
diff --git a/firmware/export/ak4537.h b/firmware/export/ak4537.h
index 1f272d41fc..abf2a378ae 100644
--- a/firmware/export/ak4537.h
+++ b/firmware/export/ak4537.h
@@ -26,9 +26,7 @@
26#define VOLUME_MIN -1270 26#define VOLUME_MIN -1270
27#define VOLUME_MAX 0 27#define VOLUME_MAX 0
28 28
29extern int tenthdb2master(int db); 29AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -128, 0, -25)
30
31extern void audiohw_set_master_vol(int vol_l, int vol_r);
32 30
33#define AKC_NUM_REGS 0x11 31#define AKC_NUM_REGS 0x11
34 32
diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h
index 85da14493f..e9e48fab63 100644
--- a/firmware/export/as3514.h
+++ b/firmware/export/as3514.h
@@ -24,11 +24,32 @@
24 24
25#include "config.h" 25#include "config.h"
26 26
27extern int tenthdb2master(int db); 27#if 0
28#define AUDIOHW_CAPS (LINEOUT_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
29#endif
30
31#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP)
32
33/*different volume ranges for different AMS chips*/
34#if CONFIG_CPU == AS3525v2
35/* Headphone volume goes from -81.0 ... +6dB */
36#define VOLUME_MIN -810
37#define VOLUME_MAX 60
38AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -82, 6, -25)
39#else /* AS3525v1 */
40/* Headphone volume goes from -73.5 ... +6dB */
41#define VOLUME_MIN -735
42#define VOLUME_MAX 60
43AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25)
44#endif /* CONFIG_CPU == AS3525v2 */
28 45
29extern void audiohw_set_master_vol(int vol_l, int vol_r); 46#ifdef HAVE_RECORDING
30extern void audiohw_set_lineout_vol(int vol_l, int vol_r); 47AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 39, 23, (val - 23) * 15)
31extern void audiohw_set_sampr_dividers(int fsel); 48AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
49AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
50#endif /* HAVE_RECORDING */
51
52void audiohw_set_sampr_dividers(int fsel);
32 53
33/* Register Descriptions */ 54/* Register Descriptions */
34 55
@@ -126,16 +147,6 @@ extern void audiohw_set_sampr_dividers(int fsel);
126#define AS3514_UID_LEN 16 147#define AS3514_UID_LEN 16
127#endif 148#endif
128 149
129/*different volume ranges for different AMS chips*/
130#if CONFIG_CPU == AS3525v2
131/* Headphone volume goes from -81.0 ... +6dB */
132#define VOLUME_MIN -810
133#else
134/* Headphone volume goes from -73.5 ... +6dB */
135#define VOLUME_MIN -735
136#endif
137#define VOLUME_MAX 60
138
139/*** Audio Registers ***/ 150/*** Audio Registers ***/
140 151
141/* 00h (LINE_OUT_R) to 16h (AUDIOSET3) */ 152/* 00h (LINE_OUT_R) to 16h (AUDIOSET3) */
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index 304c5aa460..e18e996282 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -35,6 +35,35 @@
35#define TREBLE_CUTOFF_CAP (1 << 6) 35#define TREBLE_CUTOFF_CAP (1 << 6)
36#define EQ_CAP (1 << 7) 36#define EQ_CAP (1 << 7)
37#define DEPTH_3D_CAP (1 << 8) 37#define DEPTH_3D_CAP (1 << 8)
38#define LINEOUT_CAP (1 << 9)
39#define MONO_VOL_CAP (1 << 10)
40#define LIN_GAIN_CAP (1 << 11)
41#define MIC_GAIN_CAP (1 << 12)
42
43/* Used by every driver to export its min/max/default values for its audio
44 settings. */
45#ifdef AUDIOHW_IS_SOUND_C
46/* This is the master file with the settings table... */
47struct sound_settings_info
48{
49 const char *unit;
50 char numdecimals;
51 char steps;
52 short minval;
53 short maxval;
54 short defaultval;
55};
56
57#define AUDIOHW_SETTING(name, us, nd, st, minv, maxv, defv, expr...) \
58 static const struct sound_settings_info _audiohw_setting_##name = \
59 { .unit = us, .numdecimals = nd, .steps = st, \
60 .minval = minv, .maxval = maxv, .defaultval = defv }; \
61 static inline int _sound_val2phys_##name(int val) \
62 { return #expr[0] ? expr : val; }
63#else
64/* ...otherwise these produce nothing. */
65#define AUDIOHW_SETTING(name, us, nd, st, minv, maxv, defv, expr...)
66#endif
38 67
39#ifdef HAVE_UDA1380 68#ifdef HAVE_UDA1380
40#include "uda1380.h" 69#include "uda1380.h"
@@ -78,17 +107,25 @@
78#include "imx233-codec.h" 107#include "imx233-codec.h"
79#elif defined(HAVE_DUMMY_CODEC) 108#elif defined(HAVE_DUMMY_CODEC)
80#include "dummy_codec.h" 109#include "dummy_codec.h"
81#endif 110#elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO\
82#if (CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO|PLATFORM_PANDORA|PLATFORM_SDL)) 111 | PLATFORM_PANDORA | PLATFORM_SDL))
83/* #include <SDL_audio.h> gives errors in other code areas, 112#include "hosted_codec.h"
84 * we don't really need it here, so don't. but it should maybe be fixed */
85#ifndef SIMULATOR /* simulator gets values from the target .h files */
86#define VOLUME_MIN -990
87#define VOLUME_MAX 0
88#endif
89#endif 113#endif
90 114
115#if defined(SIMULATOR) && !defined(HAVE_SW_VOLUME_CONTROL)
116/* For now, without software volume control, sim only supports mono control */
117#define AUDIOHW_HAVE_MONO_VOLUME
118#endif
91 119
120/* Some values are the same for every codec and can be defined here one
121 time. */
122#ifdef HAVE_SW_TONE_CONTROLS
123AUDIOHW_SETTING(BASS, "dB", 0, 1, -24, 24, 0)
124AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -24, 24, 0)
125#endif /* HAVE_SW_TONE_CONTROLS */
126AUDIOHW_SETTING(BALANCE, "%", 0, 1, -100, 100, 0)
127AUDIOHW_SETTING(CHANNELS, "", 0, 1, 0, 5, 0)
128AUDIOHW_SETTING(STEREO_WIDTH, "%", 0, 5, 0, 250, 100)
92 129
93#define ONE_DB 10 130#define ONE_DB 10
94 131
@@ -246,7 +283,26 @@ enum AUDIOHW_EQ_SETTINGS
246#if (AUDIOHW_CAPS & DEPTH_3D_CAP) 283#if (AUDIOHW_CAPS & DEPTH_3D_CAP)
247#define AUDIOHW_HAVE_DEPTH_3D 284#define AUDIOHW_HAVE_DEPTH_3D
248#endif 285#endif
249#else 286
287#if (AUDIOHW_CAPS & LINEOUT_CAP)
288#define AUDIOHW_HAVE_LINEOUT
289#endif
290
291#if (AUDIOHW_CAPS & MONO_VOL_CAP)
292#define AUDIOHW_HAVE_MONO_VOLUME
293#endif
294
295#ifdef HAVE_RECORDING
296#if (AUDIOHW_CAPS & LIN_GAIN_CAP)
297#define AUDIOHW_HAVE_LIN_GAIN
298#endif
299
300#if (AUDIOHW_CAPS & MIC_GAIN_CAP)
301#define AUDIOHW_HAVE_MIC_GAIN
302#endif
303#endif /* HAVE_RECORDING */
304
305#else /* ndef AUDIOHW_CAPS */
250#if defined (HAVE_SW_TONE_CONTROLS) 306#if defined (HAVE_SW_TONE_CONTROLS)
251/* Needed for proper sound support */ 307/* Needed for proper sound support */
252#define AUDIOHW_HAVE_BASS 308#define AUDIOHW_HAVE_BASS
@@ -255,6 +311,7 @@ enum AUDIOHW_EQ_SETTINGS
255#endif /* AUDIOHW_CAPS */ 311#endif /* AUDIOHW_CAPS */
256 312
257enum { 313enum {
314 /* TODO: Volume shouldn't be needed if device doesn't have digital control */
258 SOUND_VOLUME = 0, 315 SOUND_VOLUME = 0,
259/* Tone control */ 316/* Tone control */
260#if defined(AUDIOHW_HAVE_BASS) 317#if defined(AUDIOHW_HAVE_BASS)
@@ -276,9 +333,11 @@ enum {
276 SOUND_MDB_ENABLE, 333 SOUND_MDB_ENABLE,
277 SOUND_SUPERBASS, 334 SOUND_SUPERBASS,
278#endif 335#endif
279#if defined(HAVE_RECORDING) 336#if defined(AUDIOHW_HAVE_LIN_GAIN)
280 SOUND_LEFT_GAIN, 337 SOUND_LEFT_GAIN,
281 SOUND_RIGHT_GAIN, 338 SOUND_RIGHT_GAIN,
339#endif
340#if defined(AUDIOHW_HAVE_MIC_GAIN)
282 SOUND_MIC_GAIN, 341 SOUND_MIC_GAIN,
283#endif 342#endif
284/* Bass and treble tone controls */ 343/* Bass and treble tone controls */
@@ -339,7 +398,8 @@ enum {
339 SOUND_LAST_SETTING, /* Keep this last */ 398 SOUND_LAST_SETTING, /* Keep this last */
340}; 399};
341 400
342enum Channel { 401enum Channel
402{
343 SOUND_CHAN_STEREO, 403 SOUND_CHAN_STEREO,
344 SOUND_CHAN_MONO, 404 SOUND_CHAN_MONO,
345 SOUND_CHAN_CUSTOM, 405 SOUND_CHAN_CUSTOM,
@@ -349,19 +409,6 @@ enum Channel {
349 SOUND_CHAN_NUM_MODES, 409 SOUND_CHAN_NUM_MODES,
350}; 410};
351 411
352struct sound_settings_info {
353 const char *unit;
354 char numdecimals;
355 char steps;
356 short minval;
357 short maxval;
358 short defaultval;
359};
360
361/* This struct is used by every driver to export its min/max/default values for
362 * its audio settings. Keep in mind that the order must be correct! */
363extern const struct sound_settings_info audiohw_settings[];
364
365/* All usable functions implemented by a audio codec drivers. Most of 412/* All usable functions implemented by a audio codec drivers. Most of
366 * the function in sound settings are only called, when in audio codecs 413 * the function in sound settings are only called, when in audio codecs
367 * .h file suitable defines are added. 414 * .h file suitable defines are added.
@@ -390,17 +437,35 @@ void audiohw_postinit(void);
390 */ 437 */
391void audiohw_close(void); 438void audiohw_close(void);
392 439
393#if defined(AUDIOHW_HAVE_CLIPPING) || defined(HAVE_SDL_AUDIO) || defined(ANDROID) 440#ifdef AUDIOHW_HAVE_MONO_VOLUME
394 /** 441 /**
395 * Set new volume value 442 * Set new volume value
396 * @param val to set. 443 * @param val to set.
397 * NOTE: AUDIOHW_CAPS need to contain 444 * NOTE: AUDIOHW_CAPS need to contain
398 * CLIPPING_CAP 445 * CLIPPING_CAP
399 */ 446 */
400void audiohw_set_volume(int val); 447void audiohw_set_volume(int val);
448#else /* Stereo volume */
449/**
450 * Set new voluem value for each channel
451 * @param vol_l sets left channel volume
452 * @param vol_r sets right channel volume
453 */
454void audiohw_set_volume(int vol_l, int vol_r);
455#endif /* AUDIOHW_HAVE_MONO_VOLUME */
456
457#ifdef AUDIOHW_HAVE_LINEOUT
458 /**
459 * Set new voluem value for each channel
460 * @param vol_l sets left channel volume
461 * @param vol_r sets right channel volume
462 */
463void audiohw_set_lineout_volume(int vol_l, int vol_r);
401#endif 464#endif
402 465
403#ifdef AUDIOHW_HAVE_PRESCALER 466#ifndef AUDIOHW_HAVE_CLIPPING
467#if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE) \
468 || defined(AUDIOHW_HAVE_EQ)
404/** 469/**
405 * Set new prescaler value. 470 * Set new prescaler value.
406 * @param val to set. 471 * @param val to set.
@@ -409,6 +474,7 @@ void audiohw_set_volume(int val);
409 */ 474 */
410void audiohw_set_prescaler(int val); 475void audiohw_set_prescaler(int val);
411#endif 476#endif
477#endif /* !AUDIOHW_HAVE_CLIPPING */
412 478
413#ifdef AUDIOHW_HAVE_BALANCE 479#ifdef AUDIOHW_HAVE_BALANCE
414/** 480/**
@@ -552,31 +618,38 @@ void audiohw_set_recvol(int left, int right, int type);
552void audiohw_set_monitor(bool enable); 618void audiohw_set_monitor(bool enable);
553#endif 619#endif
554 620
555
556
557#if CONFIG_CODEC != SWCODEC
558
559/* functions which are only used by mas35xx codecs, but are also
560 aviable on SWCODECS through dsp */
561
562/** 621/**
563 * Set channel configuration. 622 * Set channel configuration.
564 * @param val new channel value (see enum Channel). 623 * @param val new channel value (see enum Channel).
565 */ 624 */
566void audiohw_set_channel(int val); 625void audiohw_set_channel(int val);
567 626
627#ifdef HAVE_PITCHCONTROL
628/**
629 * Set the pitch ratio
630 * @param ratio to set in .01% units
631 */
632void audiohw_set_pitch(int32_t val);
633
634/**
635 * Return the set pitch ratio
636 */
637int32_t audiohw_get_pitch(void);
638#endif /* HAVE_PITCHCONTROL */
639
568/** 640/**
569 * Set stereo width. 641 * Set stereo width.
570 * @param val new stereo width value. 642 * @param val new stereo width value.
571 */ 643 */
572void audiohw_set_stereo_width(int val); 644void audiohw_set_stereo_width(int val);
573 645
574#endif /* CONFIG_CODEC != SWCODEC */
575
576#ifdef HAVE_SPEAKER 646#ifdef HAVE_SPEAKER
577
578void audiohw_enable_speaker(bool on); 647void audiohw_enable_speaker(bool on);
579
580#endif /* HAVE_SPEAKER */ 648#endif /* HAVE_SPEAKER */
581 649
650#if CONFIG_CODEC == SWCODEC
651typedef int (*audiohw_swcodec_cb_type)(int msg, intptr_t param);
652void audiohw_swcodec_set_callback(audiohw_swcodec_cb_type func);
653#endif /* CONFIG_CODEC == SWCODEC */
654
582#endif /* _AUDIOHW_H_ */ 655#endif /* _AUDIOHW_H_ */
diff --git a/firmware/export/audiohw_settings.h b/firmware/export/audiohw_settings.h
new file mode 100644
index 0000000000..8efbc0dbe7
--- /dev/null
+++ b/firmware/export/audiohw_settings.h
@@ -0,0 +1,143 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 * Copyright (C) 2007 by Christian Gmeiner
12 * Copyright (C) 2013 by Michael Sevakis
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#if defined(AUDIOHW_SOUND_SETTINGS_ENTRIES)
24/* Define sound_setting_entries table */
25
26#define AUDIOHW_SETTINGS(...) \
27 static const struct sound_setting_entry \
28 { \
29 const struct sound_settings_info *info; \
30 sound_set_type *function; \
31 } sound_setting_entries[] = \
32 { \
33 [0 ... SOUND_LAST_SETTING-1] = { NULL, NULL }, \
34 __VA_ARGS__ \
35 };
36
37#define AUDIOHW_SETTING_ENT(name, fn) \
38 [SOUND_##name] = { .info = &_audiohw_setting_##name, .function = fn },
39
40#elif defined(AUDIOHW_SOUND_SETTINGS_VAL2PHYS)
41
42/* Implements sound_val2phys */
43#define AUDIOHW_SETTINGS(...) \
44 int sound_val2phys(int setting, int value) \
45 { \
46 switch (setting) \
47 { \
48 __VA_ARGS__ \
49 default: \
50 return value; \
51 } \
52 }
53
54#define AUDIOHW_SETTING_ENT(name, fn) \
55 case SOUND_##name: return _sound_val2phys_##name(value);
56
57#endif /* setting table type selection */
58
59AUDIOHW_SETTINGS(
60 /* TODO: Volume shouldn't be needed if device doesn't have digital
61 control */
62 AUDIOHW_SETTING_ENT(VOLUME, sound_set_volume)
63#if defined(AUDIOHW_HAVE_BASS)
64 AUDIOHW_SETTING_ENT(BASS, sound_set_bass)
65#endif
66#if defined(AUDIOHW_HAVE_TREBLE)
67 AUDIOHW_SETTING_ENT(TREBLE, sound_set_treble)
68#endif
69 AUDIOHW_SETTING_ENT(BALANCE, sound_set_balance)
70 AUDIOHW_SETTING_ENT(CHANNELS, sound_set_channels)
71 AUDIOHW_SETTING_ENT(STEREO_WIDTH, sound_set_stereo_width)
72#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
73 AUDIOHW_SETTING_ENT(LOUDNESS, sound_set_loudness)
74 AUDIOHW_SETTING_ENT(AVC, sound_set_avc)
75 AUDIOHW_SETTING_ENT(MDB_STRENGTH, sound_set_mdb_strength)
76 AUDIOHW_SETTING_ENT(MDB_HARMONICS, sound_set_mdb_harmonics)
77 AUDIOHW_SETTING_ENT(MDB_CENTER, sound_set_mdb_center)
78 AUDIOHW_SETTING_ENT(MDB_SHAPE, sound_set_mdb_shape)
79 AUDIOHW_SETTING_ENT(MDB_ENABLE, sound_set_mdb_enable)
80 AUDIOHW_SETTING_ENT(SUPERBASS, sound_set_superbass)
81#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
82#if defined(AUDIOHW_HAVE_LIN_GAIN)
83 AUDIOHW_SETTING_ENT(LEFT_GAIN, NULL)
84 AUDIOHW_SETTING_ENT(RIGHT_GAIN, NULL)
85#endif
86#if defined(AUDIOHW_HAVE_MIC_GAIN)
87 AUDIOHW_SETTING_ENT(MIC_GAIN, NULL)
88#endif
89#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
90 AUDIOHW_SETTING_ENT(BASS_CUTOFF, sound_set_bass_cutoff)
91#endif
92#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
93 AUDIOHW_SETTING_ENT(TREBLE_CUTOFF, sound_set_treble_cutoff)
94#endif
95#if defined(AUDIOHW_HAVE_DEPTH_3D)
96 AUDIOHW_SETTING_ENT(DEPTH_3D, sound_set_depth_3d)
97#endif
98/* Hardware EQ tone controls */
99#if defined(AUDIOHW_HAVE_EQ)
100 AUDIOHW_SETTING_ENT(EQ_BAND1_GAIN, sound_set_hw_eq_band1_gain)
101#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
102 AUDIOHW_SETTING_ENT(EQ_BAND1_FREQUENCY, sound_set_hw_eq_band1_frequency)
103#endif
104#if defined(AUDIOHW_HAVE_EQ_BAND2)
105 AUDIOHW_SETTING_ENT(EQ_BAND2_GAIN, sound_set_hw_eq_band2_gain)
106#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
107 AUDIOHW_SETTING_ENT(EQ_BAND2_FREQUENCY, sound_set_hw_eq_band2_frequency)
108#endif
109#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
110 AUDIOHW_SETTING_ENT(EQ_BAND2_WIDTH, sound_set_hw_eq_band2_width)
111#endif
112#endif /* AUDIOHW_HAVE_EQ_BAND2 */
113#if defined(AUDIOHW_HAVE_EQ_BAND3)
114 AUDIOHW_SETTING_ENT(EQ_BAND3_GAIN, sound_set_hw_eq_band3_gain)
115#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
116 AUDIOHW_SETTING_ENT(EQ_BAND3_FREQUENCY, sound_set_hw_eq_band3_frequency)
117#endif
118#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
119 AUDIOHW_SETTING_ENT(EQ_BAND3_WIDTH, sound_set_hw_eq_band3_width)
120#endif
121#endif /* AUDIOHW_HAVE_EQ_BAND3 */
122#if defined(AUDIOHW_HAVE_EQ_BAND4)
123 AUDIOHW_SETTING_ENT(EQ_BAND4_GAIN, sound_set_hw_eq_band4_gain)
124#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
125 AUDIOHW_SETTING_ENT(EQ_BAND4_FREQUENCY, sound_set_hw_eq_band4_frequency)
126#endif
127#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
128 AUDIOHW_SETTING_ENT(EQ_BAND4_WIDTH, sound_set_hw_eq_band4_width)
129#endif
130#endif /* AUDIOHW_HAVE_EQ_BAND4 */
131#if defined(AUDIOHW_HAVE_EQ_BAND5)
132 AUDIOHW_SETTING_ENT(EQ_BAND5_GAIN, sound_set_hw_eq_band5_gain)
133#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
134 AUDIOHW_SETTING_ENT(EQ_BAND5_FREQUENCY, sound_set_hw_eq_band5_frequency)
135#endif
136#endif /* AUDIOHW_HAVE_EQ_BAND5 */
137#endif /* AUDIOHW_HAVE_EQ */
138); /* AUDIOHW_SETTINGS */
139
140#undef AUDIOHW_SETTINGS
141#undef AUDIOHW_SETTING_ENT
142#undef AUDIOHW_SOUND_SETTINGS_ENTRIES
143#undef AUDIOHW_SOUND_SETTINGS_VAL2PHYS
diff --git a/firmware/export/cs42l55.h b/firmware/export/cs42l55.h
index 86b54ef272..4584706dfd 100644
--- a/firmware/export/cs42l55.h
+++ b/firmware/export/cs42l55.h
@@ -26,14 +26,16 @@
26#define VOLUME_MIN -580 26#define VOLUME_MIN -580
27#define VOLUME_MAX 120 27#define VOLUME_MAX 120
28 28
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP \ 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \
30 | TREBLE_CUTOFF_CAP | PRESCALER_CAP) 30 TREBLE_CUTOFF_CAP | PRESCALER_CAP | LINEOUT_CAP)
31 31
32extern int tenthdb2master(int db); 32AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -60, 12, -25)
33AUDIOHW_SETTING(BASS, "dB", 1, 15,-105, 120, 0)
34AUDIOHW_SETTING(TREBLE, "dB", 1, 15,-105, 120, 0)
35AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 2)
36AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1)
33 37
34extern void audiohw_set_master_vol(int vol_l, int vol_r); 38void audiohw_enable_lineout(bool enable);
35extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
36extern void audiohw_enable_lineout(bool enable);
37 39
38/* Register addresses and bits */ 40/* Register addresses and bits */
39 41
@@ -480,5 +482,4 @@ extern void audiohw_enable_lineout(bool enable);
480#define HIDDEN3F 0x3f 482#define HIDDEN3F 0x3f
481#define HIDDEN3F_DEFAULT 0x46 483#define HIDDEN3F_DEFAULT 0x46
482 484
483
484#endif /* __CS42L55_H__ */ 485#endif /* __CS42L55_H__ */
diff --git a/firmware/export/dac3550a.h b/firmware/export/dac3550a.h
index 23c4db9cbc..50bf922e90 100644
--- a/firmware/export/dac3550a.h
+++ b/firmware/export/dac3550a.h
@@ -37,7 +37,6 @@
37#define DAC_GCFG 3 37#define DAC_GCFG 3
38 38
39/* function prototypes */ 39/* function prototypes */
40extern int tenthdb2reg(int db);
41extern int dac_volume(unsigned int left, unsigned int right, bool deemph); 40extern int dac_volume(unsigned int left, unsigned int right, bool deemph);
42extern void dac_enable(bool enable); 41extern void dac_enable(bool enable);
43extern void dac_line_in(bool enable); 42extern void dac_line_in(bool enable);
diff --git a/firmware/export/dummy_codec.h b/firmware/export/dummy_codec.h
index 122b55ef2f..90fd7b03c2 100644
--- a/firmware/export/dummy_codec.h
+++ b/firmware/export/dummy_codec.h
@@ -25,6 +25,6 @@
25#define VOLUME_MIN -730 25#define VOLUME_MIN -730
26#define VOLUME_MAX 0 26#define VOLUME_MAX 0
27 27
28void audiohw_set_master_vol(int vol_l, int vol_r); 28AUDIOHW_SETTING(VOLUME, "dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, 0)
29 29
30#endif /* __DUMMY_CODEC_H_ */ 30#endif /* __DUMMY_CODEC_H_ */
diff --git a/firmware/export/hosted_codec.h b/firmware/export/hosted_codec.h
new file mode 100644
index 0000000000..50d1281394
--- /dev/null
+++ b/firmware/export/hosted_codec.h
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 by Thomas Martitz
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#ifndef HOSTED_CODEC_H
22#define HOSTED_CODEC_H
23
24#define VOLUME_MIN -990
25#define VOLUME_MAX 0
26
27#define AUDIOHW_CAPS (MONO_VOL_CAP)
28AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -100, 0, 0)
29
30#endif /* HOSTED_CODEC_H */ \ No newline at end of file
diff --git a/firmware/export/imx233-codec.h b/firmware/export/imx233-codec.h
index 6c329ccd1a..2fbd8bde59 100644
--- a/firmware/export/imx233-codec.h
+++ b/firmware/export/imx233-codec.h
@@ -27,10 +27,19 @@
27#define VOLUME_MIN -1000 27#define VOLUME_MIN -1000
28#define VOLUME_MAX 60 28#define VOLUME_MAX 60
29 29
30#define AUDIOHW_CAPS (DEPTH_3D_CAP | BASS_CAP | TREBLE_CAP) 30#define AUDIOHW_CAPS (DEPTH_3D_CAP | BASS_CAP | TREBLE_CAP | \
31 LIN_GAIN_CAP | MIC_GAIN_CAP)
31 32
32/* Work with half dB since the i.MX233 doesn't have a better resolution */ 33/* Work with half dB since the i.MX233 doesn't have a better resolution */
33int tenthdb2master(int tdb); 34
34void audiohw_set_headphone_vol(int vol_l, int vol_r); 35/* i.MX233 has half dB steps */
36AUDIOHW_SETTING(VOLUME, "dB", 0, 1,-101, 6, -25)
37/* HAVE_SW_TONE_CONTROLS */
38#ifdef HAVE_RECORDING
39AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23)
40AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23)
41AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1)
42#endif /* HAVE_RECORDING */
43AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0)
35 44
36#endif /* __IMX233_CODEC_H_ */ 45#endif /* __IMX233_CODEC_H_ */
diff --git a/firmware/export/jz4740-codec.h b/firmware/export/jz4740-codec.h
index 3c088f5bf7..fc731fdf50 100644
--- a/firmware/export/jz4740-codec.h
+++ b/firmware/export/jz4740-codec.h
@@ -24,6 +24,17 @@
24#define VOLUME_MIN -730 24#define VOLUME_MIN -730
25#define VOLUME_MAX 60 25#define VOLUME_MAX 60
26 26
27void audiohw_set_master_vol(int vol_l, int vol_r); 27/* TODO */
28#ifdef HAVE_SW_VOLUME_CONTROL
29AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25)
30#else
31AUDIOHW_SETTING(VOLUME, "dB", 0, 1, 0, 6, 0)
32#endif /* HAVE_SW_VOLUME_CONTROL */
33
34#ifdef HAVE_RECORDING
35AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23)
36AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23)
37AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1)
38#endif /* HAVE_RECORDING */
28 39
29#endif /* __JZ4740_CODEC_H_ */ 40#endif /* __JZ4740_CODEC_H_ */
diff --git a/firmware/export/mas35xx.h b/firmware/export/mas35xx.h
index f75658fce1..7643e0efdc 100644
--- a/firmware/export/mas35xx.h
+++ b/firmware/export/mas35xx.h
@@ -39,6 +39,14 @@
39 39
40#if CONFIG_CODEC == MAS3507D 40#if CONFIG_CODEC == MAS3507D
41 41
42#define VOLUME_MIN -780
43#define VOLUME_MAX 180
44#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP)
45
46AUDIOHW_SETTING(SOUND_VOLUME, "dB", 0, 1, -78, 18, -18)
47AUDIOHW_SETTING(SOUND_BASS, "dB", 0, 1, -15, 15, 7)
48AUDIOHW_SETTING(SOUND_TREBLE, "dB", 0, 1, -15, 15, 7)
49
42/* I2C defines */ 50/* I2C defines */
43#define MAS_ADR 0x3a 51#define MAS_ADR 0x3a
44#define MAS_DEV_WRITE (MAS_ADR | 0x00) 52#define MAS_DEV_WRITE (MAS_ADR | 0x00)
@@ -71,10 +79,6 @@
71#define MAS_D0_OUT_RL 0x7fa 79#define MAS_D0_OUT_RL 0x7fa
72#define MAS_D0_OUT_RR 0x7fb 80#define MAS_D0_OUT_RR 0x7fb
73 81
74#define VOLUME_MIN -780
75#define VOLUME_MAX 180
76#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP)
77
78static const unsigned int bass_table[] = 82static const unsigned int bass_table[] =
79{ 83{
80 0x9e400, /* -15dB */ 84 0x9e400, /* -15dB */
@@ -167,6 +171,36 @@ static const unsigned int prescale_table[] =
167 171
168#else /* CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F */ 172#else /* CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F */
169 173
174#define VOLUME_MIN -400
175#define VOLUME_MAX 600
176
177AUDIOHW_SETTING(VOLUME, "dB", 0, 1,-100, 12, -25)
178AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 6)
179AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 6)
180AUDIOHW_SETTING(LOUDNESS, "dB", 0, 1, 0, 17, 0)
181AUDIOHW_SETTING(AVC "", 0, 1, -1, 4, 0)
182AUDIOHW_SETTING(MDB_STRENGTH, "dB", 0, 1, 0, 127, 48)
183AUDIOHW_SETTING(MDB_HARMONICS, "%", 0, 1, 0, 100, 50)
184AUDIOHW_SETTING(MDB_CENTER "Hz", 0, 10, 20, 300, 60)
185AUDIOHW_SETTING(MDB_SHAPE "Hz", 0, 10, 50, 300, 90)
186AUDIOHW_SETTING(MDB_ENABLE "", 0, 1, 0, 1, 0)
187AUDIOHW_SETTING(SUPERBASS "", 0, 1, 0, 1, 0)
188
189#if CONFIG_CODEC == MAS3587F && defined(HAVE_RECORDING)
190/* MAS3587F and MAS3539F handle clipping prevention internally so we do not
191 * need the prescaler -> CLIPPING_CAP */
192#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \
193 MONO_VOL_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
194AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15)
195AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15)
196AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 15, 2, val * 15 + 210)
197#else
198/* MAS3587F and MAS3539F handle clipping prevention internally so we do not
199 * need the prescaler -> CLIPPING_CAP */
200#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \
201 MONO_VOL_CAP)
202#endif /* MAS3587F && HAVE_RECORDING */
203
170/* I2C defines */ 204/* I2C defines */
171#define MAS_ADR 0x3c 205#define MAS_ADR 0x3c
172#define MAS_DEV_WRITE (MAS_ADR | 0x00) 206#define MAS_DEV_WRITE (MAS_ADR | 0x00)
@@ -248,18 +282,7 @@ static const unsigned int prescale_table[] =
248#define MAS_D0_CRC_ERROR_COUNT 0xfd3 282#define MAS_D0_CRC_ERROR_COUNT 0xfd3
249#endif 283#endif
250 284
251/* MAS3587F and MAS3539F handle clipping prevention internally so we do not need
252 * the prescaler -> CLIPPING_CAP
253 */
254
255#define VOLUME_MIN -400
256#define VOLUME_MAX 600
257#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP)
258
259#endif /* CONFIG_CODEC */
260
261/* Function prototypes */ 285/* Function prototypes */
262#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F
263extern void audiohw_set_loudness(int value); 286extern void audiohw_set_loudness(int value);
264extern void audiohw_set_avc(int value); 287extern void audiohw_set_avc(int value);
265extern void audiohw_set_mdb_strength(int value); 288extern void audiohw_set_mdb_strength(int value);
@@ -269,7 +292,9 @@ extern void audiohw_set_mdb_shape(int value);
269extern void audiohw_set_mdb_enable(int value); 292extern void audiohw_set_mdb_enable(int value);
270extern void audiohw_set_superbass(int value); 293extern void audiohw_set_superbass(int value);
271extern void audiohw_set_balance(int val); 294extern void audiohw_set_balance(int val);
272extern void audiohw_set_pitch(unsigned long val); 295extern void audiohw_set_pitch(int32_t val);
273#endif 296extern int audiohw_get_pitch(void);
297
298#endif /* CONFIG_CODEC */
274 299
275#endif /* _MAS35XX_H */ 300#endif /* _MAS35XX_H */
diff --git a/firmware/export/rk27xx_codec.h b/firmware/export/rk27xx_codec.h
index 5fdf0a0061..5a6796d63c 100644
--- a/firmware/export/rk27xx_codec.h
+++ b/firmware/export/rk27xx_codec.h
@@ -26,10 +26,14 @@
26 26
27#define VOLUME_MIN -330 27#define VOLUME_MIN -330
28#define VOLUME_MAX 40 28#define VOLUME_MAX 40
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
30 30
31extern int tenthdb2master(int db); 31AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -34, 4, -25)
32extern void audiohw_set_master_vol(int vol_l, int vol_r); 32#ifdef HAVE_RECORDING /* disabled for now */
33AUDIOHW_SETTING(LEFT_GAIN, "dB", 2, 75, -1725, 3000, 0)
34AUDIOHW_SETTING(RIGHT_GAIN, "dB", 2, 75, -1725, 3000, 0)
35AUDIOHW_SETTING(MIC_GAIN, "dB", 0, 1, 0, 20, 20)
36#endif /* HAVE_RECORDING */
33 37
34#define CODEC_I2C_ADDR 0x4e 38#define CODEC_I2C_ADDR 0x4e
35 39
diff --git a/firmware/export/sound.h b/firmware/export/sound.h
index ebf728c7c7..fa76c67b1f 100644
--- a/firmware/export/sound.h
+++ b/firmware/export/sound.h
@@ -24,17 +24,6 @@
24#include <inttypes.h> 24#include <inttypes.h>
25#include <audiohw.h> 25#include <audiohw.h>
26 26
27
28#if CONFIG_CODEC == SWCODEC
29enum {
30 DSP_CALLBACK_SET_PRESCALE = 0,
31 DSP_CALLBACK_SET_BASS,
32 DSP_CALLBACK_SET_TREBLE,
33 DSP_CALLBACK_SET_CHANNEL_CONFIG,
34 DSP_CALLBACK_SET_STEREO_WIDTH,
35};
36#endif
37
38typedef void sound_set_type(int value); 27typedef void sound_set_type(int value);
39 28
40const char *sound_unit(int setting); 29const char *sound_unit(int setting);
@@ -45,7 +34,6 @@ int sound_max(int setting);
45int sound_default(int setting); 34int sound_default(int setting);
46sound_set_type* sound_get_fn(int setting); 35sound_set_type* sound_get_fn(int setting);
47 36
48void sound_set_dsp_callback(int (*func)(int, intptr_t));
49void sound_set_volume(int value); 37void sound_set_volume(int value);
50void sound_set_balance(int value); 38void sound_set_balance(int value);
51void sound_set_bass(int value); 39void sound_set_bass(int value);
@@ -130,10 +118,8 @@ void sound_set_superbass(int value);
130void sound_set(int setting, int value); 118void sound_set(int setting, int value);
131int sound_val2phys(int setting, int value); 119int sound_val2phys(int setting, int value);
132 120
133#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
134void sound_set_pitch(int32_t pitch); 121void sound_set_pitch(int32_t pitch);
135int32_t sound_get_pitch(void); 122int32_t sound_get_pitch(void);
136#endif
137 123
138#ifdef HAVE_PITCHCONTROL 124#ifdef HAVE_PITCHCONTROL
139/* precision of the pitch and speed variables */ 125/* precision of the pitch and speed variables */
diff --git a/firmware/export/tlv320.h b/firmware/export/tlv320.h
index 66f4d5ca92..99359f72ce 100644
--- a/firmware/export/tlv320.h
+++ b/firmware/export/tlv320.h
@@ -25,15 +25,33 @@
25#define VOLUME_MIN -730 25#define VOLUME_MIN -730
26#define VOLUME_MAX 60 26#define VOLUME_MAX 60
27 27
28extern int tenthdb2master(int db); 28#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP)
29
30AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -20)
31#ifdef HAVE_RECORDING
32 /* (x - 23)/1.5 *10 */
33AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
34AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
35/* 0 or 20 dB */
36AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1, val * 200)
37#endif /* HAVE_RECORDING */
38
39static inline int _param_2_phys(int setting, int value)
40{
41 switch(setting)
42 {
43 default: return value;
44#ifdef HAVE_RECORDING
45 case SOUND_LEFT_GAIN:
46 case SOUND_RIGHT_GAIN: return (value - 23) * 15;
47 case SOUND_MIC_GAIN: return value * 200; /* 0 or 20 dB */
48#endif
49 }
50}
29 51
30/*** definitions ***/ 52/*** definitions ***/
31extern void audiohw_set_headphone_vol(int vol_l, int vol_r);
32
33#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */ 53#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
34 54
35/* ToDo: samplerates */
36
37/* registers */ 55/* registers */
38/* REG_LLIV: Left line input channel volume control */ 56/* REG_LLIV: Left line input channel volume control */
39#define REG_LLIV 0x0 57#define REG_LLIV 0x0
diff --git a/firmware/export/tsc2100.h b/firmware/export/tsc2100.h
index 9566c588df..4e1e7d9287 100644
--- a/firmware/export/tsc2100.h
+++ b/firmware/export/tsc2100.h
@@ -21,6 +21,12 @@
21#ifndef __TSC2100_H_ 21#ifndef __TSC2100_H_
22#define __TSC2100_H_ 22#define __TSC2100_H_
23 23
24/* volume/balance/treble/bass interdependency */
25#define VOLUME_MIN -630
26#define VOLUME_MAX 0
27
28AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -64, 0, -25)
29
24void tsc2100_read_data(void); 30void tsc2100_read_data(void);
25bool tsc2100_read_touch(short *x, short* y, short *z1, short *z2); 31bool tsc2100_read_touch(short *x, short* y, short *z1, short *z2);
26bool tsc2100_read_volt(short *bat1, short *bat2, short *aux); 32bool tsc2100_read_volt(short *bat1, short *bat2, short *aux);
@@ -139,7 +145,4 @@ void tsc2100_keyclick(void);
139#define TSAC5_PAGE 2 145#define TSAC5_PAGE 2
140#define TSAC5_ADDRESS 0x1e 146#define TSAC5_ADDRESS 0x1e
141 147
142extern int tenthdb2master(int db);
143extern void audiohw_set_master_vol(int vol_l, int vol_r);
144
145#endif 148#endif
diff --git a/firmware/export/uda1341.h b/firmware/export/uda1341.h
index a43d33a137..5641bd301f 100644
--- a/firmware/export/uda1341.h
+++ b/firmware/export/uda1341.h
@@ -26,13 +26,16 @@
26#define VOLUME_MIN -840 26#define VOLUME_MIN -840
27#define VOLUME_MAX 0 27#define VOLUME_MAX 0
28 28
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | MIC_GAIN_CAP | LIN_GAIN_CAP)
30 30
31extern int tenthdb2master(int db); 31AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -84, 0, -25)
32extern int tenthdb2mixer(int db); 32AUDIOHW_SETTING(BASS, "dB", 0, 2, 0, 24, 0)
33 33AUDIOHW_SETTING(TREBLE, "dB", 0, 2, 0, 6, 0)
34extern void audiohw_set_master_vol(int vol_l, int vol_r); 34#ifdef HAVE_RECORDING
35extern void audiohw_set_mixer_vol(int channel1, int channel2); 35AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0)
36AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0)
37AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16)
38#endif /* HAVE_RECORDING */
36 39
37/* These are logical register numbers for driver */ 40/* These are logical register numbers for driver */
38enum uda_register { 41enum uda_register {
diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h
index e9292cf466..a2200967dd 100644
--- a/firmware/export/uda1380.h
+++ b/firmware/export/uda1380.h
@@ -26,13 +26,18 @@
26#define VOLUME_MIN -840 26#define VOLUME_MIN -840
27#define VOLUME_MAX 0 27#define VOLUME_MAX 0
28 28
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
30 30 LIN_GAIN_CAP | MIC_GAIN_CAP)
31extern int tenthdb2master(int db); 31
32extern int tenthdb2mixer(int db); 32AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -85, 0, -25)
33 33AUDIOHW_SETTING(BASS, "dB", 0, 2, 0, 24, 0)
34extern void audiohw_set_master_vol(int vol_l, int vol_r); 34AUDIOHW_SETTING(TREBLE, "dB", 0, 2, 0, 6, 0)
35extern void audiohw_set_mixer_vol(int channel1, int channel2); 35#ifdef HAVE_RECORDING
36 /* (1/2) * 10 */
37AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0, val * 5)
38AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0, val * 5)
39AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16, val * 5)
40#endif /* HAVE_RECORDING */
36 41
37#define UDA1380_ADDR 0x30 42#define UDA1380_ADDR 0x30
38 43
diff --git a/firmware/export/wm8731.h b/firmware/export/wm8731.h
index 28d4d3940d..086c847ee1 100644
--- a/firmware/export/wm8731.h
+++ b/firmware/export/wm8731.h
@@ -28,9 +28,16 @@
28#define VOLUME_MIN -730 28#define VOLUME_MIN -730
29#define VOLUME_MAX 60 29#define VOLUME_MAX 60
30 30
31extern int tenthdb2master(int db); 31#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP)
32 32
33extern void audiohw_set_master_vol(int vol_l, int vol_r); 33AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25)
34#if defined(HAVE_WM8731) && defined(HAVE_RECORDING)
35/* (x - 23)/1.5 *10 */
36AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
37AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15)
38/* 0 or 20 dB */
39AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 0, val * 200)
40#endif /* defined(HAVE_WM8731) && defined(HAVE_RECORDING) */
34 41
35/* Common register bits */ 42/* Common register bits */
36#ifdef HAVE_WM8731 43#ifdef HAVE_WM8731
diff --git a/firmware/export/wm8751.h b/firmware/export/wm8751.h
index 3bbf744463..6e7bb245dd 100644
--- a/firmware/export/wm8751.h
+++ b/firmware/export/wm8751.h
@@ -25,23 +25,36 @@
25#define VOLUME_MIN -730 25#define VOLUME_MIN -730
26#define VOLUME_MAX 60 26#define VOLUME_MAX 60
27 27
28#if defined(HAVE_WM8750)
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ 28#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
30 BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \ 29 BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \
31 DEPTH_3D_CAP) 30 DEPTH_3D_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
32#else
33 31
34#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ 32#if defined(HAVE_WM8750)
35 BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) 33AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0, (100 * val + 8) / 15)
36#endif 34#ifdef HAVE_RECORDING
37 35 /* PGA -17.25dB to 30.0dB in 0.75dB increments 64 steps
38extern int tenthdb2master(int db); 36 * digital gain 0dB to 30.0dB in 0.5dB increments
37 * we use 0.75dB fake steps through whole range
38 *
39 * This combined gives -17.25 to 60.0dB
40 */
41AUDIOHW_SETTING(LEFT_GAIN, "dB", 2, 75,-1725, 6000, 0, val * 5)
42AUDIOHW_SETTING(RIGHT_GAIN, "dB", 2, 75,-1725, 6000, 0, val * 5)
43AUDIOHW_SETTING(MIC_GAIN, "dB", 2, 75,-1725, 6000, 3000, val * 5)
39 44
40extern void audiohw_set_master_vol(int vol_l, int vol_r);
41extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
42#if defined(HAVE_WM8750) && defined(HAVE_RECORDING)
43void audiohw_set_recsrc(int source, bool recording); 45void audiohw_set_recsrc(int source, bool recording);
44#endif 46#endif /* HAVE_RECORDING */
47#else /* !HAVE_WM8750 */
48#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
49 BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \
50 LINEOUT_CAP)
51#endif /* HAVE_WM8750 */
52
53AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25)
54AUDIOHW_SETTING(BASS, "dB", 1, 15, -60, 90, 0)
55AUDIOHW_SETTING(TREBLE, "dB", 1, 15, -60, 90, 0)
56AUDIOHW_SETTING(BASS_CUTOFF, "Hz", 0, 70, 130, 200, 200)
57AUDIOHW_SETTING(TREBLE_CUTOFF, "kHz", 0, 4, 4, 8, 4)
45 58
46/* Register addresses and bits */ 59/* Register addresses and bits */
47#define OUTPUT_MUTED 0x2f 60#define OUTPUT_MUTED 0x2f
@@ -348,4 +361,5 @@ void audiohw_set_recsrc(int source, bool recording);
348#define MONOOUT_MOZC (1 << 7) 361#define MONOOUT_MOZC (1 << 7)
349 362
350#define WM_NUM_REGS 0x2b 363#define WM_NUM_REGS 0x2b
364
351#endif /* _WM8751_H */ 365#endif /* _WM8751_H */
diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h
index ef5567e898..89b000cf8c 100644
--- a/firmware/export/wm8758.h
+++ b/firmware/export/wm8758.h
@@ -26,15 +26,22 @@
26#define VOLUME_MIN -890 26#define VOLUME_MIN -890
27#define VOLUME_MAX 60 27#define VOLUME_MAX 60
28 28
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \
30 30 TREBLE_CUTOFF_CAP | LINEOUT_CAP | LIN_GAIN_CAP | \
31extern int tenthdb2master(int db); 31 MIC_GAIN_CAP)
32extern int tenthdb2mixer(int db); 32
33 33AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25)
34extern void audiohw_set_master_vol(int vol_l, int vol_r); 34AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 0)
35extern void audiohw_set_lineout_vol(int vol_l, int vol_r); 35AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 0)
36extern void audiohw_set_mixer_vol(int channel1, int channel2); 36AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 1)
37extern void audiohw_enable_lineout(bool enable); 37AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1)
38#ifdef HAVE_RECORDING
39AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200)
40AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200)
41AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200)
42#endif /* HAVE_RECORDING */
43
44void audiohw_enable_lineout(bool enable);
38 45
39#define RESET 0x00 46#define RESET 0x00
40#define RESET_RESET 0x0 47#define RESET_RESET 0x0
diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h
index c9d0bd1bbe..f4e0d203a1 100644
--- a/firmware/export/wm8975.h
+++ b/firmware/export/wm8975.h
@@ -26,13 +26,19 @@
26#define VOLUME_MIN -730 26#define VOLUME_MIN -730
27#define VOLUME_MAX 60 27#define VOLUME_MAX 60
28 28
29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) 29#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LINEOUT_CAP | \
30 30 LIN_GAIN_CAP | MIC_GAIN_CAP)
31extern int tenthdb2master(int db); 31
32 32AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25)
33extern void audiohw_set_master_vol(int vol_l, int vol_r); 33AUDIOHW_SETTING(BASS, "dB", 0, 1, -6, 9, 0)
34extern void audiohw_set_lineout_vol(int vol_l, int vol_r); 34AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -6, 9, 0)
35extern void audiohw_enable_lineout(bool enable); 35#ifdef HAVE_RECORDING
36AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 63, 23, ((val - 23) * 15) / 2)
37AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 63, 23, ((val - 23) * 15) / 2))
38AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 63, 0, ((val - 23) * 15) / 2 + 200)
39#endif /* HAVE_RECORDING */
40
41void audiohw_enable_lineout(bool enable);
36 42
37/* Register addresses and bits */ 43/* Register addresses and bits */
38 44
diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h
index f591c1b9fb..d5ed8f184c 100644
--- a/firmware/export/wm8978.h
+++ b/firmware/export/wm8978.h
@@ -23,10 +23,17 @@
23#ifndef _WM8978_H 23#ifndef _WM8978_H
24#define _WM8978_H 24#define _WM8978_H
25 25
26#define VOLUME_MIN -900 26#define VOLUME_MIN -890
27#define VOLUME_MAX 60 27#define VOLUME_MAX 60
28 28
29#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP) 29#if 0
30#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP | \
31 LIN_GAIN_CAP | MIC_GAIN_CAP)
32#else
33#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP | \
34 LIN_GAIN_CAP)
35#endif
36
30/* Filter bitmask */ 37/* Filter bitmask */
31#define AUDIOHW_EQ_BAND_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \ 38#define AUDIOHW_EQ_BAND_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \
32 (EQ_CAP << 2) | (EQ_CAP << 3) | \ 39 (EQ_CAP << 2) | (EQ_CAP << 3) | \
@@ -39,8 +46,33 @@
39#define AUDIOHW_EQ_WIDTH_CAPS ((EQ_CAP << 1) | (EQ_CAP << 2) | \ 46#define AUDIOHW_EQ_WIDTH_CAPS ((EQ_CAP << 1) | (EQ_CAP << 2) | \
40 (EQ_CAP << 3)) 47 (EQ_CAP << 3))
41 48
42int tenthdb2master(int db); 49AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25)
43void audiohw_set_headphone_vol(int vol_l, int vol_r); 50AUDIOHW_SETTING(EQ_BAND1_GAIN, "dB", 0, 1, -12, 12, 0)
51AUDIOHW_SETTING(EQ_BAND2_GAIN, "dB", 0, 1, -12, 12, 0)
52AUDIOHW_SETTING(EQ_BAND3_GAIN, "dB", 0, 1, -12, 12, 0)
53AUDIOHW_SETTING(EQ_BAND4_GAIN, "dB", 0, 1, -12, 12, 0)
54AUDIOHW_SETTING(EQ_BAND5_GAIN, "dB", 0, 1, -12, 12, 0)
55AUDIOHW_SETTING(EQ_BAND1_FREQUENCY, "", 0, 1, 0, 3, 0)
56AUDIOHW_SETTING(EQ_BAND2_FREQUENCY, "", 0, 1, 0, 3, 0)
57AUDIOHW_SETTING(EQ_BAND3_FREQUENCY, "", 0, 1, 0, 3, 0)
58AUDIOHW_SETTING(EQ_BAND4_FREQUENCY, "", 0, 1, 0, 3, 0)
59AUDIOHW_SETTING(EQ_BAND5_FREQUENCY, "", 0, 1, 0, 3, 0)
60AUDIOHW_SETTING(EQ_BAND2_WIDTH, "", 0, 1, 0, 1, 0)
61AUDIOHW_SETTING(EQ_BAND3_WIDTH, "", 0, 1, 0, 1, 0)
62AUDIOHW_SETTING(EQ_BAND4_WIDTH, "", 0, 1, 0, 1, 0)
63AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0, (100*val + 8) / 15)
64#ifdef HAVE_RECORDING
65 /* Digital: -119.0dB to +8.0dB in 0.5dB increments
66 * Analog: Relegated to volume control
67 * Circumstances unfortunately do not allow a great deal of positive
68 * gain. */
69AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-238, 16, 0, val * 5)
70AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-238, 16, 0, val * 5)
71#if 0 /* whenever it's needed - none on GBS */
72AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-238, 16, 0, val * 5)
73#endif /* 0 */
74#endif /* HAVE_RECORDING */
75
44void audiohw_set_recsrc(int source, bool recording); 76void audiohw_set_recsrc(int source, bool recording);
45 77
46void wmc_set(unsigned int reg, unsigned int bits); 78void wmc_set(unsigned int reg, unsigned int bits);
diff --git a/firmware/export/wm8985.h b/firmware/export/wm8985.h
index 4538b5edc5..a5eb59f159 100644
--- a/firmware/export/wm8985.h
+++ b/firmware/export/wm8985.h
@@ -29,15 +29,25 @@
29#ifdef COWON_D2 29#ifdef COWON_D2
30/* FIXME: somehow something was out of sync in the .lang, settings and caps. Keep the 30/* FIXME: somehow something was out of sync in the .lang, settings and caps. Keep the
31 * cutoffs disabled until someone with the device works it out. */ 31 * cutoffs disabled until someone with the device works it out. */
32#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) 32#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LINEOUT_CAP | \
33 LIN_GAIN_CAP | MIC_GAIN_CAP)
33#else 34#else
34#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) 35#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \
36 TREBLE_CUTOFF_CAP | LINEOUT_CAP | LIN_GAIN_CAP | \
37 MIC_GAIN_CAP)
38AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 1)
39AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1)
35#endif 40#endif
36 41
37extern int tenthdb2master(int db); 42AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25)
43AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 0)
44AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 0)
45#ifdef HAVE_RECORDING
46AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0)
47AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0)
48AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16)
49#endif /* HAVE_RECORDING */
38 50
39extern void audiohw_set_headphone_vol(int vol_l, int vol_r); 51void audiohw_set_aux_vol(int vol_l, int vol_r);
40extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
41extern void audiohw_set_aux_vol(int vol_l, int vol_r);
42 52
43#endif /* _WM8985_H */ 53#endif /* _WM8985_H */
diff --git a/firmware/include/fixedpoint.h b/firmware/include/fixedpoint.h
index 3e14bdd68e..584bd58d84 100644
--- a/firmware/include/fixedpoint.h
+++ b/firmware/include/fixedpoint.h
@@ -102,6 +102,11 @@ unsigned long isqrt(unsigned long x);
102#define FP_INF (0x7fffffff) 102#define FP_INF (0x7fffffff)
103#define FP_NEGINF -(0x7fffffff) 103#define FP_NEGINF -(0x7fffffff)
104 104
105/** FIXED POINT EXP10
106 * Return 10^x as FP integer. Argument is FP integer.
107 */
108long fp_exp10(long x, unsigned int fracbits);
109
105/* fracbits in range 12 - 22 work well. Higher is better for 110/* fracbits in range 12 - 22 work well. Higher is better for
106 * calculating dB, lower is better for calculating factor. 111 * calculating dB, lower is better for calculating factor.
107 */ 112 */
diff --git a/firmware/sound.c b/firmware/sound.c
index 7c86b0bf05..4c390f4a5b 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -9,6 +9,7 @@
9 * 9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing 10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 * Copyright (C) 2007 by Christian Gmeiner 11 * Copyright (C) 2007 by Christian Gmeiner
12 * Copyright (C) 2013 by Michael Sevakis
12 * 13 *
13 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -19,141 +20,95 @@
19 * KIND, either express or implied. 20 * KIND, either express or implied.
20 * 21 *
21 ****************************************************************************/ 22 ****************************************************************************/
22#include <stdbool.h> 23 /* Indicate it's the sound.c file which affects compilation of audiohw.h */
23#include <stdio.h> 24#define AUDIOHW_IS_SOUND_C
24#include "config.h" 25#include "config.h"
25#include "sound.h"
26#include "logf.h"
27#include "system.h" 26#include "system.h"
28#include "i2c.h" 27#include "sound.h"
28#include "fixedpoint.h"
29#ifdef HAVE_SW_VOLUME_CONTROL 29#ifdef HAVE_SW_VOLUME_CONTROL
30#include "pcm_sw_volume.h" 30#include "pcm_sw_volume.h"
31#endif /* HAVE_SW_VOLUME_CONTROL */ 31#endif /* HAVE_SW_VOLUME_CONTROL */
32 32
33/* TODO 33/* Define sound_setting_entries table */
34 * find a nice way to handle 1.5db steps -> see wm8751 ifdef in sound_set_bass/treble 34#define AUDIOHW_SOUND_SETTINGS_ENTRIES
35*/ 35#include "audiohw_settings.h"
36
37/* Implements sound_val2phys */
38#define AUDIOHW_SOUND_SETTINGS_VAL2PHYS
39#include "audiohw_settings.h"
36 40
37extern bool audio_is_initialized; 41extern bool audio_is_initialized;
38 42
39const char *sound_unit(int setting) 43static const struct sound_setting_entry * get_setting_entry(int setting)
40{ 44{
41 return audiohw_settings[setting].unit; 45 static const struct sound_settings_info default_info =
46 { "", 0, 0, 0, 0, 0 };
47
48 static const struct sound_setting_entry default_entry =
49 { &default_info, NULL };
50
51 if ((unsigned)setting >= ARRAYLEN(sound_setting_entries))
52 return &default_entry;
53
54 const struct sound_setting_entry *e = &sound_setting_entries[setting];
55 return e->info ? e : &default_entry; /* setting valid but not in table? */
56}
57
58static const struct sound_settings_info * get_settings_info(int setting)
59{
60 return get_setting_entry(setting)->info;
61}
62
63const char * sound_unit(int setting)
64{
65 return get_settings_info(setting)->unit;
42} 66}
43 67
44int sound_numdecimals(int setting) 68int sound_numdecimals(int setting)
45{ 69{
46 return audiohw_settings[setting].numdecimals; 70 return get_settings_info(setting)->numdecimals;
47} 71}
48 72
49int sound_steps(int setting) 73int sound_steps(int setting)
50{ 74{
51 return audiohw_settings[setting].steps; 75 return get_settings_info(setting)->steps;
52} 76}
53 77
54int sound_min(int setting) 78int sound_min(int setting)
55{ 79{
56 return audiohw_settings[setting].minval; 80 return get_settings_info(setting)->minval;
57} 81}
58 82
59int sound_max(int setting) 83int sound_max(int setting)
60{ 84{
61 return audiohw_settings[setting].maxval; 85 return get_settings_info(setting)->maxval;
62} 86}
63 87
64int sound_default(int setting) 88int sound_default(int setting)
65{ 89{
66 return audiohw_settings[setting].defaultval; 90 return get_settings_info(setting)->defaultval;
67} 91}
68 92
69static sound_set_type * const sound_set_fns[] = 93sound_set_type * sound_get_fn(int setting)
70{ 94{
71 [0 ... SOUND_LAST_SETTING-1] = NULL, 95 return get_setting_entry(setting)->function;
72 [SOUND_VOLUME] = sound_set_volume, 96}
73#if defined(AUDIOHW_HAVE_BASS)
74 [SOUND_BASS] = sound_set_bass,
75#endif
76#if defined(AUDIOHW_HAVE_TREBLE)
77 [SOUND_TREBLE] = sound_set_treble,
78#endif
79 [SOUND_BALANCE] = sound_set_balance,
80 [SOUND_CHANNELS] = sound_set_channels,
81 [SOUND_STEREO_WIDTH] = sound_set_stereo_width,
82#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
83 [SOUND_LOUDNESS] = sound_set_loudness,
84 [SOUND_AVC] = sound_set_avc,
85 [SOUND_MDB_STRENGTH] = sound_set_mdb_strength,
86 [SOUND_MDB_HARMONICS] = sound_set_mdb_harmonics,
87 [SOUND_MDB_CENTER] = sound_set_mdb_center,
88 [SOUND_MDB_SHAPE] = sound_set_mdb_shape,
89 [SOUND_MDB_ENABLE] = sound_set_mdb_enable,
90 [SOUND_SUPERBASS] = sound_set_superbass,
91#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
92#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
93 [SOUND_BASS_CUTOFF] = sound_set_bass_cutoff,
94#endif
95#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
96 [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff,
97#endif
98#if defined(AUDIOHW_HAVE_DEPTH_3D)
99 [SOUND_DEPTH_3D] = sound_set_depth_3d,
100#endif
101/* Hardware EQ tone controls */
102#if defined(AUDIOHW_HAVE_EQ)
103 [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain,
104#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
105 [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency,
106#endif
107#if defined(AUDIOHW_HAVE_EQ_BAND2)
108 [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain,
109#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
110 [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency,
111#endif
112#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
113 [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width,
114#endif
115#endif /* AUDIOHW_HAVE_EQ_BAND2 */
116#if defined(AUDIOHW_HAVE_EQ_BAND3)
117 [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain,
118#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
119 [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency,
120#endif
121#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
122 [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width,
123#endif
124#endif /* AUDIOHW_HAVE_EQ_BAND3 */
125#if defined(AUDIOHW_HAVE_EQ_BAND4)
126 [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain,
127#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
128 [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency,
129#endif
130#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
131 [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width,
132#endif
133#endif /* AUDIOHW_HAVE_EQ_BAND4 */
134#if defined(AUDIOHW_HAVE_EQ_BAND5)
135 [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain,
136#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
137 [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency,
138#endif
139#endif /* AUDIOHW_HAVE_EQ_BAND5 */
140#endif /* AUDIOHW_HAVE_EQ */
141};
142 97
143sound_set_type* sound_get_fn(int setting) 98void sound_set(int setting, int value)
144{ 99{
145 return ((unsigned)setting >= ARRAYLEN(sound_set_fns)? 100 sound_set_type *sound_set_val = sound_get_fn(setting);
146 NULL : sound_set_fns[setting]);
147}
148 101
149#if CONFIG_CODEC == SWCODEC 102 if (sound_set_val)
150static int (*dsp_callback)(int, intptr_t) = NULL; 103 sound_set_val(value);
104}
151 105
152void sound_set_dsp_callback(int (*func)(int, intptr_t)) 106/* Return the sound value scaled to centibels (tenth-decibels) */
107static int sound_value_to_cb(int setting, int value)
153{ 108{
154 dsp_callback = func; 109 long e = (1 - sound_numdecimals(setting)) << 16;
110 return fp_mul(value, fp_exp10(e, 16), 16);
155} 111}
156#endif
157 112
158#if !defined(AUDIOHW_HAVE_CLIPPING) 113#if !defined(AUDIOHW_HAVE_CLIPPING)
159/* 114/*
@@ -165,39 +120,31 @@ void sound_set_dsp_callback(int (*func)(int, intptr_t))
165 * by 12 dB after processing. 120 * by 12 dB after processing.
166 */ 121 */
167 122
168/* all values in tenth of dB MAS3507D UDA1380 */ 123static int current_volume = 0; /* tenth dB */
169static int current_volume = 0; /* -780..+180 -840.. 0 */ 124static int current_balance = 0; /* percent */
170static int current_balance = 0; /* -960..+960 -840..+840 */
171#ifdef AUDIOHW_HAVE_TREBLE 125#ifdef AUDIOHW_HAVE_TREBLE
172static int current_treble = 0; /* -150..+150 0.. +60 */ 126static int current_treble = 0; /* tenth dB */
173#endif 127#endif
174#ifdef AUDIOHW_HAVE_BASS 128#ifdef AUDIOHW_HAVE_BASS
175static int current_bass = 0; /* -150..+150 0..+240 */ 129static int current_bass = 0; /* tenth dB */
176#endif 130#endif
177#ifdef AUDIOHW_HAVE_EQ 131#ifdef AUDIOHW_HAVE_EQ
178static int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM]; 132static int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM]; /* tenth dB */
179#endif 133#endif
180 134
181static void set_prescaled_volume(void) 135static void set_prescaled_volume(void)
182{ 136{
183 int prescale = 0; 137 int prescale = 0;
184 int l, r;
185 138
186/* The codecs listed use HW tone controls but don't have suitable prescaler 139#if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE) \
187 * functionality, so we let the prescaler stay at 0 for these, unless 140 || defined(AUDIOHW_HAVE_EQ)
188 * SW tone controls are in use. This is to avoid needing the SW DSP just for
189 * the prescaling.
190 */
191#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
192 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
193 || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341))
194 141
142 /* Note: Having Tone + EQ isn't prohibited */
195#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE) 143#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE)
196 prescale = MAX(current_bass, current_treble); 144 prescale = MAX(current_bass, current_treble);
197#endif 145#endif
198#if defined(AUDIOHW_HAVE_EQ) 146#if defined(AUDIOHW_HAVE_EQ)
199 int i; 147 for (int i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
200 for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
201 prescale = MAX(current_eq_band_gain[i], prescale); 148 prescale = MAX(current_eq_band_gain[i], prescale);
202#endif 149#endif
203 150
@@ -210,86 +157,65 @@ static void set_prescaled_volume(void)
210 * instead (might cause clipping). */ 157 * instead (might cause clipping). */
211 if (current_volume + prescale > VOLUME_MAX) 158 if (current_volume + prescale > VOLUME_MAX)
212 prescale = VOLUME_MAX - current_volume; 159 prescale = VOLUME_MAX - current_volume;
213#endif
214 160
215#if defined(AUDIOHW_HAVE_PRESCALER)
216 audiohw_set_prescaler(prescale); 161 audiohw_set_prescaler(prescale);
217#else
218 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
219#endif
220 162
221 if (current_volume <= VOLUME_MIN) 163 if (current_volume < VOLUME_MIN)
222 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */ 164 prescale = 0; /* Make sure the audio gets muted */
165#endif /* AUDIOHW_HAVE_BASS || AUDIOHW_HAVE_TREBLE || AUDIOHW_HAVE_EQ */
223 166
224 l = r = current_volume + prescale; 167#if defined(AUDIOHW_HAVE_MONO_VOLUME)
168 audiohw_set_volume(current_volume);
169#else /* Stereo volume */
170 int l = current_volume + prescale, r = l;
225 171
226 /* Balance the channels scaled by the current volume and min volume. */ 172 /* Balance the channels scaled by the current volume and min volume. */
227 /* Subtract a dB from VOLUME_MIN to get it to a mute level */ 173 /* Subtract a dB from VOLUME_MIN to get it to a mute level */
228 if (current_balance > 0) 174 int volshift = current_balance * VOLUME_RANGE / 100; /* tenth of dB */
175
176 if (volshift > 0)
229 { 177 {
230 l -= ((l - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE; 178 l -= ((l - (VOLUME_MIN - ONE_DB)) * volshift) / VOLUME_RANGE;
231 } 179 }
232 else if (current_balance < 0) 180 else if (volshift < 0)
233 { 181 {
234 r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE; 182 r += ((r - (VOLUME_MIN - ONE_DB)) * volshift) / VOLUME_RANGE;
235 } 183 }
236 184
237/* ypr0 with sdl has separate volume controls */ 185 audiohw_set_volume(l, r);
238#if defined(HAVE_SW_VOLUME_CONTROL) 186#endif /* AUDIOHW_HAVE_MONO_VOLUME */
239 audiohw_set_master_vol(l, r);
240#elif !defined(HAVE_SDL_AUDIO) || defined(SAMSUNG_YPR0)
241#if defined(HAVE_JZ4740_CODEC)
242 audiohw_set_master_vol(l, r);
243#elif CONFIG_CODEC == MAS3507D
244 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
245#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
246 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
247 || defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_AS3514) \
248 || defined(HAVE_TSC2100) || defined(HAVE_AK4537) || defined(HAVE_UDA1341) \
249 || defined(HAVE_CS42L55) || defined(HAVE_RK27XX_CODEC)
250 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
251#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
252 || (defined(HAVE_WM8751) && defined(TOSHIBA_GIGABEAT_F)) \
253 || defined(HAVE_WM8985) || defined(HAVE_CS42L55)
254 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
255#endif
256 187
257#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) || defined(HAVE_IMX233_CODEC) || defined(HAVE_AIC3X) 188#if defined(AUDIOHW_HAVE_LINEOUT)
258 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); 189 /* For now, lineout stays at unity */
259#elif defined(HAVE_SDL_AUDIO) || defined(ANDROID) 190 audiohw_set_lineout_volume(0, 0);
260 audiohw_set_volume(current_volume); 191#endif /* AUDIOHW_HAVE_LINEOUT */
261#endif 192
262#else /* HAVE_SDL_AUDIO */ 193 (void)prescale; /* In case of no tone controls + mono volume */
263 audiohw_set_volume(current_volume);
264#endif /* !HAVE_SDL_AUDIO */
265} 194}
266#endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ 195#endif /* AUDIOIHW_HAVE_CLIPPING */
267 196
268void sound_set_volume(int value) 197void sound_set_volume(int value)
269{ 198{
270 if(!audio_is_initialized) 199 if (!audio_is_initialized)
271 return; 200 return;
272 201
273#if defined(AUDIOHW_HAVE_CLIPPING) 202#if defined(AUDIOHW_HAVE_CLIPPING)
274 audiohw_set_volume(value); 203 audiohw_set_volume(value);
275#elif CONFIG_CPU == PNX0101
276 int tmp = (60 - value * 4) & 0xff;
277 CODECVOL = tmp | (tmp << 8);
278#else 204#else
279 current_volume = value * 10; /* tenth of dB */ 205 current_volume = sound_value_to_cb(SOUND_VOLUME, value);
280 set_prescaled_volume(); 206 set_prescaled_volume();
281#endif 207#endif
282} 208}
283 209
284void sound_set_balance(int value) 210void sound_set_balance(int value)
285{ 211{
286 if(!audio_is_initialized) 212 if (!audio_is_initialized)
287 return; 213 return;
288 214
289#ifdef AUDIOHW_HAVE_BALANCE 215#if defined(AUDIOHW_HAVE_BALANCE)
290 audiohw_set_balance(value); 216 audiohw_set_balance(value);
291#else 217#else
292 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ 218 current_balance = value;
293 set_prescaled_volume(); 219 set_prescaled_volume();
294#endif 220#endif
295} 221}
@@ -297,24 +223,13 @@ void sound_set_balance(int value)
297#ifdef AUDIOHW_HAVE_BASS 223#ifdef AUDIOHW_HAVE_BASS
298void sound_set_bass(int value) 224void sound_set_bass(int value)
299{ 225{
300 if(!audio_is_initialized) 226 if (!audio_is_initialized)
301 return; 227 return;
302 228
303#if !defined(AUDIOHW_HAVE_CLIPPING)
304#if defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_CS42L55)
305 current_bass = value;
306#else
307 current_bass = value * 10;
308#endif
309#endif
310
311#if defined(HAVE_SW_TONE_CONTROLS)
312 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
313#else
314 audiohw_set_bass(value); 229 audiohw_set_bass(value);
315#endif
316 230
317#if !defined(AUDIOHW_HAVE_CLIPPING) 231#if !defined(AUDIOHW_HAVE_CLIPPING)
232 current_bass = sound_value_to_cb(SOUND_BASS, value);
318 set_prescaled_volume(); 233 set_prescaled_volume();
319#endif 234#endif
320} 235}
@@ -323,24 +238,13 @@ void sound_set_bass(int value)
323#ifdef AUDIOHW_HAVE_TREBLE 238#ifdef AUDIOHW_HAVE_TREBLE
324void sound_set_treble(int value) 239void sound_set_treble(int value)
325{ 240{
326 if(!audio_is_initialized) 241 if (!audio_is_initialized)
327 return; 242 return;
328 243
329#if !defined(AUDIOHW_HAVE_CLIPPING)
330#if defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_CS42L55)
331 current_treble = value;
332#else
333 current_treble = value * 10;
334#endif
335#endif
336
337#if defined(HAVE_SW_TONE_CONTROLS)
338 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
339#else
340 audiohw_set_treble(value); 244 audiohw_set_treble(value);
341#endif
342 245
343#if !defined(AUDIOHW_HAVE_CLIPPING) 246#if !defined(AUDIOHW_HAVE_CLIPPING)
247 current_treble = sound_value_to_cb(SOUND_TREBLE, value);
344 set_prescaled_volume(); 248 set_prescaled_volume();
345#endif 249#endif
346} 250}
@@ -349,7 +253,7 @@ void sound_set_treble(int value)
349#if defined(AUDIOHW_HAVE_BASS_CUTOFF) 253#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
350void sound_set_bass_cutoff(int value) 254void sound_set_bass_cutoff(int value)
351{ 255{
352 if(!audio_is_initialized) 256 if (!audio_is_initialized)
353 return; 257 return;
354 258
355 audiohw_set_bass_cutoff(value); 259 audiohw_set_bass_cutoff(value);
@@ -359,7 +263,7 @@ void sound_set_bass_cutoff(int value)
359#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 263#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
360void sound_set_treble_cutoff(int value) 264void sound_set_treble_cutoff(int value)
361{ 265{
362 if(!audio_is_initialized) 266 if (!audio_is_initialized)
363 return; 267 return;
364 268
365 audiohw_set_treble_cutoff(value); 269 audiohw_set_treble_cutoff(value);
@@ -368,32 +272,24 @@ void sound_set_treble_cutoff(int value)
368 272
369void sound_set_channels(int value) 273void sound_set_channels(int value)
370{ 274{
371 if(!audio_is_initialized) 275 if (!audio_is_initialized)
372 return; 276 return;
373 277
374#if CONFIG_CODEC == SWCODEC
375 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
376#else
377 audiohw_set_channel(value); 278 audiohw_set_channel(value);
378#endif
379} 279}
380 280
381void sound_set_stereo_width(int value) 281void sound_set_stereo_width(int value)
382{ 282{
383 if(!audio_is_initialized) 283 if (!audio_is_initialized)
384 return; 284 return;
385 285
386#if CONFIG_CODEC == SWCODEC
387 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
388#else
389 audiohw_set_stereo_width(value); 286 audiohw_set_stereo_width(value);
390#endif
391} 287}
392 288
393#if defined(AUDIOHW_HAVE_DEPTH_3D) 289#if defined(AUDIOHW_HAVE_DEPTH_3D)
394void sound_set_depth_3d(int value) 290void sound_set_depth_3d(int value)
395{ 291{
396 if(!audio_is_initialized) 292 if (!audio_is_initialized)
397 return; 293 return;
398 294
399 audiohw_set_depth_3d(value); 295 audiohw_set_depth_3d(value);
@@ -470,13 +366,11 @@ int sound_enum_hw_eq_band_setting(unsigned int band,
470 366
471static void sound_set_hw_eq_band_gain(unsigned int band, int value) 367static void sound_set_hw_eq_band_gain(unsigned int band, int value)
472{ 368{
473 int setting; 369 if (!audio_is_initialized)
474
475 if(!audio_is_initialized)
476 return; 370 return;
477 371
478 setting = sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN); 372 int setting = sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN);
479 current_eq_band_gain[band] = sound_val2phys(setting + 0x10000, value); 373 current_eq_band_gain[band] = sound_value_to_cb(setting, value);
480 374
481 audiohw_set_eq_band_gain(band, value); 375 audiohw_set_eq_band_gain(band, value);
482 set_prescaled_volume(); 376 set_prescaled_volume();
@@ -518,7 +412,7 @@ void sound_set_hw_eq_band5_gain(int value)
518#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) 412#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
519void sound_set_hw_eq_band1_frequency(int value) 413void sound_set_hw_eq_band1_frequency(int value)
520{ 414{
521 if(!audio_is_initialized) 415 if (!audio_is_initialized)
522 return; 416 return;
523 417
524 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value); 418 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value);
@@ -528,7 +422,7 @@ void sound_set_hw_eq_band1_frequency(int value)
528#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) 422#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
529void sound_set_hw_eq_band2_frequency(int value) 423void sound_set_hw_eq_band2_frequency(int value)
530{ 424{
531 if(!audio_is_initialized) 425 if (!audio_is_initialized)
532 return; 426 return;
533 427
534 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value); 428 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value);
@@ -538,7 +432,7 @@ void sound_set_hw_eq_band2_frequency(int value)
538#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) 432#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
539void sound_set_hw_eq_band3_frequency(int value) 433void sound_set_hw_eq_band3_frequency(int value)
540{ 434{
541 if(!audio_is_initialized) 435 if (!audio_is_initialized)
542 return; 436 return;
543 437
544 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value); 438 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value);
@@ -548,7 +442,7 @@ void sound_set_hw_eq_band3_frequency(int value)
548#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) 442#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
549void sound_set_hw_eq_band4_frequency(int value) 443void sound_set_hw_eq_band4_frequency(int value)
550{ 444{
551 if(!audio_is_initialized) 445 if (!audio_is_initialized)
552 return; 446 return;
553 447
554 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value); 448 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value);
@@ -558,7 +452,7 @@ void sound_set_hw_eq_band4_frequency(int value)
558#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) 452#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
559void sound_set_hw_eq_band5_frequency(int value) 453void sound_set_hw_eq_band5_frequency(int value)
560{ 454{
561 if(!audio_is_initialized) 455 if (!audio_is_initialized)
562 return; 456 return;
563 457
564 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value); 458 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value);
@@ -568,7 +462,7 @@ void sound_set_hw_eq_band5_frequency(int value)
568#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) 462#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
569void sound_set_hw_eq_band2_width(int value) 463void sound_set_hw_eq_band2_width(int value)
570{ 464{
571 if(!audio_is_initialized) 465 if (!audio_is_initialized)
572 return; 466 return;
573 467
574 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value); 468 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value);
@@ -578,7 +472,7 @@ void sound_set_hw_eq_band2_width(int value)
578#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) 472#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
579void sound_set_hw_eq_band3_width(int value) 473void sound_set_hw_eq_band3_width(int value)
580{ 474{
581 if(!audio_is_initialized) 475 if (!audio_is_initialized)
582 return; 476 return;
583 477
584 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value); 478 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value);
@@ -588,7 +482,7 @@ void sound_set_hw_eq_band3_width(int value)
588#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) 482#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
589void sound_set_hw_eq_band4_width(int value) 483void sound_set_hw_eq_band4_width(int value)
590{ 484{
591 if(!audio_is_initialized) 485 if (!audio_is_initialized)
592 return; 486 return;
593 487
594 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value); 488 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value);
@@ -596,10 +490,10 @@ void sound_set_hw_eq_band4_width(int value)
596#endif 490#endif
597#endif /* AUDIOHW_HAVE_EQ */ 491#endif /* AUDIOHW_HAVE_EQ */
598 492
599#if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) 493#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F
600void sound_set_loudness(int value) 494void sound_set_loudness(int value)
601{ 495{
602 if(!audio_is_initialized) 496 if (!audio_is_initialized)
603 return; 497 return;
604 498
605 audiohw_set_loudness(value); 499 audiohw_set_loudness(value);
@@ -607,7 +501,7 @@ void sound_set_loudness(int value)
607 501
608void sound_set_avc(int value) 502void sound_set_avc(int value)
609{ 503{
610 if(!audio_is_initialized) 504 if (!audio_is_initialized)
611 return; 505 return;
612 506
613 audiohw_set_avc(value); 507 audiohw_set_avc(value);
@@ -615,7 +509,7 @@ void sound_set_avc(int value)
615 509
616void sound_set_mdb_strength(int value) 510void sound_set_mdb_strength(int value)
617{ 511{
618 if(!audio_is_initialized) 512 if (!audio_is_initialized)
619 return; 513 return;
620 514
621 audiohw_set_mdb_strength(value); 515 audiohw_set_mdb_strength(value);
@@ -623,7 +517,7 @@ void sound_set_mdb_strength(int value)
623 517
624void sound_set_mdb_harmonics(int value) 518void sound_set_mdb_harmonics(int value)
625{ 519{
626 if(!audio_is_initialized) 520 if (!audio_is_initialized)
627 return; 521 return;
628 522
629 audiohw_set_mdb_harmonics(value); 523 audiohw_set_mdb_harmonics(value);
@@ -631,7 +525,7 @@ void sound_set_mdb_harmonics(int value)
631 525
632void sound_set_mdb_center(int value) 526void sound_set_mdb_center(int value)
633{ 527{
634 if(!audio_is_initialized) 528 if (!audio_is_initialized)
635 return; 529 return;
636 530
637 audiohw_set_mdb_center(value); 531 audiohw_set_mdb_center(value);
@@ -639,7 +533,7 @@ void sound_set_mdb_center(int value)
639 533
640void sound_set_mdb_shape(int value) 534void sound_set_mdb_shape(int value)
641{ 535{
642 if(!audio_is_initialized) 536 if (!audio_is_initialized)
643 return; 537 return;
644 538
645 audiohw_set_mdb_shape(value); 539 audiohw_set_mdb_shape(value);
@@ -647,7 +541,7 @@ void sound_set_mdb_shape(int value)
647 541
648void sound_set_mdb_enable(int value) 542void sound_set_mdb_enable(int value)
649{ 543{
650 if(!audio_is_initialized) 544 if (!audio_is_initialized)
651 return; 545 return;
652 546
653 audiohw_set_mdb_enable(value); 547 audiohw_set_mdb_enable(value);
@@ -655,158 +549,27 @@ void sound_set_mdb_enable(int value)
655 549
656void sound_set_superbass(int value) 550void sound_set_superbass(int value)
657{ 551{
658 if(!audio_is_initialized) 552 if (!audio_is_initialized)
659 return; 553 return;
660 554
661 audiohw_set_superbass(value); 555 audiohw_set_superbass(value);
662} 556}
663#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ 557#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */
664
665void sound_set(int setting, int value)
666{
667 sound_set_type* sound_set_val = sound_get_fn(setting);
668 if (sound_set_val)
669 sound_set_val(value);
670}
671
672#if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \
673 && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
674 && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
675 && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
676 && !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \
677 && !defined(HAVE_AK4537)) || defined(SIMULATOR)
678int sound_val2phys(int setting, int value)
679{
680#if CONFIG_CODEC == MAS3587F
681 int result = 0;
682
683 switch(setting)
684 {
685 case SOUND_LEFT_GAIN:
686 case SOUND_RIGHT_GAIN:
687 result = (value - 2) * 15;
688 break;
689
690 case SOUND_MIC_GAIN:
691 result = value * 15 + 210;
692 break;
693
694 default:
695 result = value;
696 break;
697 }
698 return result;
699#elif defined(HAVE_UDA1380)
700 int result = 0;
701
702 switch(setting)
703 {
704#ifdef HAVE_RECORDING
705 case SOUND_LEFT_GAIN:
706 case SOUND_RIGHT_GAIN:
707 case SOUND_MIC_GAIN:
708 result = value * 5; /* (1/2) * 10 */
709 break;
710#endif
711 default:
712 result = value;
713 break;
714 }
715 return result;
716#elif defined(HAVE_TLV320) || defined(HAVE_WM8711) \
717 || defined(HAVE_WM8721) || defined(HAVE_WM8731)
718 int result = 0;
719
720 switch(setting)
721 {
722#ifdef HAVE_RECORDING
723 case SOUND_LEFT_GAIN:
724 case SOUND_RIGHT_GAIN:
725 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
726 break;
727
728 case SOUND_MIC_GAIN:
729 result = value * 200; /* 0 or 20 dB */
730 break;
731#endif
732 default:
733 result = value;
734 break;
735 }
736 return result;
737#elif defined(HAVE_AS3514)
738 /* This is here for the sim only and the audio driver has its own */
739 int result;
740
741 switch(setting)
742 {
743#ifdef HAVE_RECORDING
744 case SOUND_LEFT_GAIN:
745 case SOUND_RIGHT_GAIN:
746 case SOUND_MIC_GAIN:
747 result = (value - 23) * 15;
748 break;
749#endif
750 default:
751 result = value;
752 break;
753 }
754
755 return result;
756#elif defined(HAVE_WM8978) || defined(HAVE_WM8750) || defined(HAVE_WM8751)
757 int result;
758
759 switch (setting)
760 {
761#ifdef HAVE_RECORDING
762 case SOUND_LEFT_GAIN:
763 case SOUND_RIGHT_GAIN:
764 case SOUND_MIC_GAIN:
765 result = value * 5;
766 break;
767#endif
768#ifdef AUDIOHW_HAVE_DEPTH_3D
769 case SOUND_DEPTH_3D:
770 result = (100 * value + 8) / 15;
771 break;
772#endif
773 default:
774 result = value;
775 }
776
777 return result;
778#else
779 (void)setting;
780 return value;
781#endif
782}
783#endif /* CONFIG_CODECs || PLATFORM_HOSTED */
784
785#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
786/* This function works by telling the decoder that we have another
787 crystal frequency than we actually have. It will adjust its internal
788 parameters and the result is that the audio is played at another pitch.
789*/
790
791static int last_pitch = PITCH_SPEED_100;
792 558
559#ifdef HAVE_PITCHCONTROL
793void sound_set_pitch(int32_t pitch) 560void sound_set_pitch(int32_t pitch)
794{ 561{
795 unsigned long val; 562 if (!audio_is_initialized)
796 563 return;
797 if (pitch != last_pitch)
798 {
799 /* Calculate the new (bogus) frequency */
800 val = 18432 * PITCH_SPEED_100 / pitch;
801
802 audiohw_set_pitch(val);
803 564
804 last_pitch = pitch; 565 audiohw_set_pitch(pitch);
805 }
806} 566}
807 567
808int32_t sound_get_pitch(void) 568int32_t sound_get_pitch(void)
809{ 569{
810 return last_pitch; 570 if (!audio_is_initialized)
571 return PITCH_SPEED_100;
572
573 return audiohw_get_pitch();
811} 574}
812#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ 575#endif /* HAVE_PITCHCONTROL */
diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c
index bb11ad32fe..a2394bc355 100644
--- a/firmware/target/arm/pnx0101/pcm-pnx0101.c
+++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c
@@ -209,3 +209,9 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
209 *count = cnt >> 2; 209 *count = cnt >> 2;
210 return (void *)((addr + 2) & ~3); 210 return (void *)((addr + 2) & ~3);
211} 211}
212
213void audiohw_set_volume(int value)
214{
215 int tmp = (60 - value * 4) & 0xff;
216 CODECVOL = tmp | (tmp << 8);
217}
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
index 065433e12a..eae89cf78b 100644
--- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
@@ -26,30 +26,6 @@
26#include "system.h" 26#include "system.h"
27#include "pcm_sw_volume.h" 27#include "pcm_sw_volume.h"
28 28
29/* TODO */
30const struct sound_settings_info audiohw_settings[] = {
31#ifdef HAVE_SW_VOLUME_CONTROL
32 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
33#else
34 [SOUND_VOLUME] = {"dB", 0, 1, 0, 6, 0},
35#endif
36 /* HAVE_SW_TONE_CONTROLS */
37#ifdef AUDIOHW_HAVE_BASS
38 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
39#endif
40#ifdef AUDIOHW_HAVE_TREBLE
41 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
42#endif
43 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
44 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
45 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
46#ifdef HAVE_RECORDING
47 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23},
48 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23},
49 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 1},
50#endif
51};
52
53#if 0 29#if 0
54static unsigned short codec_volume; 30static unsigned short codec_volume;
55static unsigned short codec_base_gain; 31static unsigned short codec_base_gain;
diff --git a/lib/rbcodec/dsp/dsp_misc.c b/lib/rbcodec/dsp/dsp_misc.c
index a8c9423cfb..672212b267 100644
--- a/lib/rbcodec/dsp/dsp_misc.c
+++ b/lib/rbcodec/dsp/dsp_misc.c
@@ -35,38 +35,6 @@
35#endif 35#endif
36#include <string.h> 36#include <string.h>
37 37
38/** Firmware callback interface **/
39
40/* Hook back from firmware/ part of audio, which can't/shouldn't call apps/
41 * code directly. */
42int dsp_callback(int msg, intptr_t param)
43{
44 switch (msg)
45 {
46#ifdef HAVE_SW_TONE_CONTROLS
47 case DSP_CALLBACK_SET_PRESCALE:
48 tone_set_prescale(param);
49 break;
50 case DSP_CALLBACK_SET_BASS:
51 tone_set_bass(param);
52 break;
53 case DSP_CALLBACK_SET_TREBLE:
54 tone_set_treble(param);
55 break;
56#endif /* HAVE_SW_TONE_CONTROLS */
57 case DSP_CALLBACK_SET_CHANNEL_CONFIG:
58 channel_mode_set_config(param);
59 break;
60 case DSP_CALLBACK_SET_STEREO_WIDTH:
61 channel_mode_custom_set_width(param);
62 break;
63 default:
64 break;
65 }
66
67 return 0;
68}
69
70/** Replaygain settings **/ 38/** Replaygain settings **/
71static struct replaygain_settings current_settings; 39static struct replaygain_settings current_settings;
72static struct dsp_replay_gains current_gains; 40static struct dsp_replay_gains current_gains;
@@ -153,12 +121,7 @@ static void dsp_pitch_update(struct dsp_config *dsp)
153 (int64_t)pitch_ratio * data->format.codec_frequency / PITCH_SPEED_100; 121 (int64_t)pitch_ratio * data->format.codec_frequency / PITCH_SPEED_100;
154} 122}
155 123
156int32_t sound_get_pitch(void) 124static void dsp_set_pitch(int32_t percent)
157{
158 return pitch_ratio;
159}
160
161void sound_set_pitch(int32_t percent)
162{ 125{
163 pitch_ratio = percent > 0 ? percent : PITCH_SPEED_100; 126 pitch_ratio = percent > 0 ? percent : PITCH_SPEED_100;
164 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); 127 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
@@ -167,6 +130,50 @@ void sound_set_pitch(int32_t percent)
167} 130}
168#endif /* HAVE_PITCHCONTROL */ 131#endif /* HAVE_PITCHCONTROL */
169 132
133
134/** Firmware callback interface **/
135
136/* Hook back from firmware/ part of audio, which can't/shouldn't call apps/
137 * code directly. */
138int dsp_callback(int msg, intptr_t param)
139{
140 int retval = 0;
141
142 switch (msg)
143 {
144#ifdef HAVE_SW_TONE_CONTROLS
145 case DSP_CALLBACK_SET_PRESCALE:
146 tone_set_prescale(param);
147 break;
148 case DSP_CALLBACK_SET_BASS:
149 tone_set_bass(param);
150 break;
151 case DSP_CALLBACK_SET_TREBLE:
152 tone_set_treble(param);
153 break;
154#endif /* HAVE_SW_TONE_CONTROLS */
155 case DSP_CALLBACK_SET_CHANNEL_CONFIG:
156 channel_mode_set_config(param);
157 break;
158 case DSP_CALLBACK_SET_STEREO_WIDTH:
159 channel_mode_custom_set_width(param);
160 break;
161#ifdef HAVE_PITCHCONTROL
162 case DSP_CALLBACK_SET_PITCH:
163 dsp_set_pitch(param);
164 break;
165 case DSP_CALLBACK_GET_PITCH:
166 retval = pitch_ratio;
167 break;
168#endif /* HAVE_PITCHCONTROL */
169 default:
170 break;
171 }
172
173 return retval;
174}
175
176
170/* This is a null-processing stage that monitors as an enabled stage but never 177/* This is a null-processing stage that monitors as an enabled stage but never
171 * becomes active in processing samples. It only hooks messages. */ 178 * becomes active in processing samples. It only hooks messages. */
172 179
diff --git a/lib/rbcodec/dsp/dsp_misc.h b/lib/rbcodec/dsp/dsp_misc.h
index d658374eaf..2583f495c3 100644
--- a/lib/rbcodec/dsp/dsp_misc.h
+++ b/lib/rbcodec/dsp/dsp_misc.h
@@ -54,12 +54,18 @@ struct dsp_replay_gains
54 54
55void dsp_replaygain_set_settings(const struct replaygain_settings *settings); 55void dsp_replaygain_set_settings(const struct replaygain_settings *settings);
56 56
57#ifdef HAVE_PITCHCONTROL
58void sound_set_pitch(int32_t ratio);
59int32_t sound_get_pitch(void);
60#endif /* HAVE_PITCHCONTROL */
61
62/* Callback for firmware layers to interface */ 57/* Callback for firmware layers to interface */
58enum
59{
60 DSP_CALLBACK_SET_PRESCALE = 0,
61 DSP_CALLBACK_SET_BASS,
62 DSP_CALLBACK_SET_TREBLE,
63 DSP_CALLBACK_SET_CHANNEL_CONFIG,
64 DSP_CALLBACK_SET_STEREO_WIDTH,
65 DSP_CALLBACK_SET_PITCH,
66 DSP_CALLBACK_GET_PITCH,
67};
68
63int dsp_callback(int msg, intptr_t param); 69int dsp_callback(int msg, intptr_t param);
64 70
65#endif /* DSP_MISC_H */ 71#endif /* DSP_MISC_H */
diff --git a/lib/rbcodec/test/warble.c b/lib/rbcodec/test/warble.c
index d5bc1c5aea..cd73a75542 100644
--- a/lib/rbcodec/test/warble.c
+++ b/lib/rbcodec/test/warble.c
@@ -354,7 +354,7 @@ static void perform_config(void)
354 } else if (!strncmp(name, "offset=", 7)) { 354 } else if (!strncmp(name, "offset=", 7)) {
355 ci.id3->offset = atoi(val); 355 ci.id3->offset = atoi(val);
356 } else if (!strncmp(name, "rate=", 5)) { 356 } else if (!strncmp(name, "rate=", 5)) {
357 sound_set_pitch(atof(val) * PITCH_SPEED_100); 357 dsp_callback(DSP_CALLBACK_SET_PITCH, atof(val) * PITCH_SPEED_100);
358 } else if (!strncmp(name, "seek=", 5)) { 358 } else if (!strncmp(name, "seek=", 5)) {
359 codec_action = CODEC_ACTION_SEEK_TIME; 359 codec_action = CODEC_ACTION_SEEK_TIME;
360 codec_action_param = atoi(val); 360 codec_action_param = atoi(val);