summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dsp.c14
-rw-r--r--apps/dsp.h8
-rw-r--r--firmware/export/config-ondavx747.h8
-rw-r--r--firmware/export/sound.h13
-rw-r--r--firmware/sound.c14
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c27
6 files changed, 52 insertions, 32 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index ec59417621..f9b94e8228 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -890,6 +890,15 @@ static void set_gain(struct dsp_config *dsp)
890 (long) (((int64_t) dsp->data.gain * eq_precut) >> 24); 890 (long) (((int64_t) dsp->data.gain * eq_precut) >> 24);
891 } 891 }
892 892
893#ifdef HAVE_SW_VOLUME_CONTROL
894 if (global_settings.volume < SW_VOLUME_MAX ||
895 global_settings.volume > SW_VOLUME_MIN)
896 {
897 int vol_gain = get_replaygain_int(global_settings.volume * 100);
898 dsp->data.gain = (long) (((int64_t) dsp->data.gain * vol_gain) >> 24);
899 }
900#endif
901
893 if (dsp->data.gain == DEFAULT_GAIN) 902 if (dsp->data.gain == DEFAULT_GAIN)
894 { 903 {
895 dsp->data.gain = 0; 904 dsp->data.gain = 0;
@@ -1149,6 +1158,11 @@ int dsp_callback(int msg, intptr_t param)
1149 case DSP_CALLBACK_SET_TREBLE: 1158 case DSP_CALLBACK_SET_TREBLE:
1150 treble = param; 1159 treble = param;
1151 break; 1160 break;
1161#ifdef HAVE_SW_VOLUME_CONTROL
1162 case DSP_CALLBACK_SET_SW_VOLUME:
1163 set_gain(&AUDIO_DSP);
1164 break;
1165#endif
1152#endif 1166#endif
1153 case DSP_CALLBACK_SET_CHANNEL_CONFIG: 1167 case DSP_CALLBACK_SET_CHANNEL_CONFIG:
1154 dsp_set_channel_config(param); 1168 dsp_set_channel_config(param);
diff --git a/apps/dsp.h b/apps/dsp.h
index 7d1e2b3ddc..58a5edb5e2 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -56,14 +56,6 @@ enum
56 DSP_CROSSFEED 56 DSP_CROSSFEED
57}; 57};
58 58
59enum {
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};
66
67struct dsp_config; 59struct dsp_config;
68 60
69int dsp_process(struct dsp_config *dsp, char *dest, 61int dsp_process(struct dsp_config *dsp, char *dest,
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h
index ffcaf67c5a..a04b55f1e3 100644
--- a/firmware/export/config-ondavx747.h
+++ b/firmware/export/config-ondavx747.h
@@ -139,6 +139,14 @@
139/* has no tone controls, so we use the software ones */ 139/* has no tone controls, so we use the software ones */
140#define HAVE_SW_TONE_CONTROLS 140#define HAVE_SW_TONE_CONTROLS
141 141
142/* has no volume control, so we use the software ones */
143#define HAVE_SW_VOLUME_CONTROL
144
145/* software controlled volume ranges from -73 -> 0 dB, other than that
146 is controlled by hardware */
147#define SW_VOLUME_MIN -73
148#define SW_VOLUME_MAX 0
149
142/* define the bitmask of hardware sample rates */ 150/* define the bitmask of hardware sample rates */
143#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ 151#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
144 SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ 152 SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
diff --git a/firmware/export/sound.h b/firmware/export/sound.h
index 3d12a47db3..2e13174516 100644
--- a/firmware/export/sound.h
+++ b/firmware/export/sound.h
@@ -24,6 +24,19 @@
24#include <inttypes.h> 24#include <inttypes.h>
25#include <audiohw.h> 25#include <audiohw.h>
26 26
27#if CONFIG_CODEC == SWCODEC
28enum {
29 DSP_CALLBACK_SET_PRESCALE = 0,
30 DSP_CALLBACK_SET_BASS,
31 DSP_CALLBACK_SET_TREBLE,
32 DSP_CALLBACK_SET_CHANNEL_CONFIG,
33 DSP_CALLBACK_SET_STEREO_WIDTH,
34#ifdef HAVE_SW_VOLUME_CONTROL
35 DSP_CALLBACK_SET_SW_VOLUME,
36#endif
37};
38#endif
39
27typedef void sound_set_type(int value); 40typedef void sound_set_type(int value);
28 41
29const char *sound_unit(int setting); 42const char *sound_unit(int setting);
diff --git a/firmware/sound.c b/firmware/sound.c
index 84ccd2b1bd..b327e3839c 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -158,16 +158,6 @@ sound_set_type* sound_get_fn(int setting)
158} 158}
159 159
160#if CONFIG_CODEC == SWCODEC 160#if CONFIG_CODEC == SWCODEC
161/* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
162
163enum {
164 DSP_CALLBACK_SET_PRESCALE = 0,
165 DSP_CALLBACK_SET_BASS,
166 DSP_CALLBACK_SET_TREBLE,
167 DSP_CALLBACK_SET_CHANNEL_CONFIG,
168 DSP_CALLBACK_SET_STEREO_WIDTH
169};
170
171static int (*dsp_callback)(int, intptr_t) = NULL; 161static int (*dsp_callback)(int, intptr_t) = NULL;
172 162
173void sound_set_dsp_callback(int (*func)(int, intptr_t)) 163void sound_set_dsp_callback(int (*func)(int, intptr_t))
@@ -251,6 +241,10 @@ static void set_prescaled_volume(void)
251 r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE; 241 r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
252 } 242 }
253 243
244#ifdef HAVE_SW_VOLUME_CONTROL
245 dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0);
246#endif
247
254#if CONFIG_CODEC == MAS3507D 248#if CONFIG_CODEC == MAS3507D
255 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); 249 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
256#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \ 250#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
index b91b7fae70..3a124e1356 100644
--- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
@@ -27,7 +27,8 @@
27 27
28/* TODO */ 28/* TODO */
29const struct sound_settings_info audiohw_settings[] = { 29const struct sound_settings_info audiohw_settings[] = {
30 [SOUND_VOLUME] = {"dB", 0, 2, 0, 6, 0}, 30 /* HAVE_SW_VOLUME_CONTROL */
31 [SOUND_VOLUME] = {"dB", 0, 1, SW_VOLUME_MIN, 6, 0},
31 /* HAVE_SW_TONE_CONTROLS */ 32 /* HAVE_SW_TONE_CONTROLS */
32 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, 33 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
33 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, 34 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
@@ -79,7 +80,7 @@ static void i2s_codec_init(void)
79 80
80 REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); 81 REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST);
81 82
82 REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(14) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44) 83 REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44)
83 | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0)); 84 | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0));
84 85
85 mdelay(15); 86 mdelay(15);
@@ -287,9 +288,14 @@ void audiohw_init(void)
287 288
288void audiohw_set_volume(int v) 289void audiohw_set_volume(int v)
289{ 290{
290 /* 0 <= v <= 60 */ 291 if(v >= 0)
291 unsigned int codec_volume = v / 20; 292 {
292 REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | ICDC_CDCCR2_HPVOL(codec_volume); 293 /* 0 <= v <= 60 */
294 unsigned int codec_volume = ICDC_CDCCR2_HPVOL(v / 20);
295
296 if((REG_ICDC_CDCCR2 & ICDC_CDCCR2_HPVOL(0x3)) != codec_volume)
297 REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | codec_volume;
298 }
293} 299}
294 300
295void audiohw_set_frequency(int freq) 301void audiohw_set_frequency(int freq)
@@ -329,7 +335,8 @@ void audiohw_set_frequency(int freq)
329 return; 335 return;
330 } 336 }
331 337
332 REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed; 338 if((REG_ICDC_CDCCR2 & ICDC_CDCCR2_SMPR(0xF)) != speed)
339 REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed;
333} 340}
334 341
335int audio_channels = 2; 342int audio_channels = 2;
@@ -356,20 +363,16 @@ void audio_input_mux(int source, unsigned flags)
356 case AUDIO_SRC_PLAYBACK: 363 case AUDIO_SRC_PLAYBACK:
357 audio_channels = 2; 364 audio_channels = 2;
358 if(source != last_source) 365 if(source != last_source)
359 {
360 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE)) 366 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE))
361 | (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON); 367 | (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON);
362 }
363 break; 368 break;
364 369
365#if INPUT_SRC_CAPS & SRC_CAP_MIC 370#if INPUT_SRC_CAPS & SRC_CAP_MIC
366 case AUDIO_SRC_MIC: /* recording only */ 371 case AUDIO_SRC_MIC: /* recording only */
367 audio_channels = 1; 372 audio_channels = 1;
368 if(source != last_source) 373 if(source != last_source)
369 {
370 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) 374 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE))
371 | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_EMIC); 375 | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_EMIC);
372 }
373 break; 376 break;
374#endif 377#endif
375 378
@@ -383,15 +386,11 @@ void audio_input_mux(int source, unsigned flags)
383 last_recording = recording; 386 last_recording = recording;
384 387
385 if(recording) 388 if(recording)
386 {
387 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) 389 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE))
388 | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ); 390 | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ);
389 }
390 else 391 else
391 {
392 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_EADC | 392 REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_EADC |
393 ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ); 393 ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ);
394 }
395 break; 394 break;
396#endif 395#endif
397 } /* end switch */ 396 } /* end switch */