summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-08-01 21:38:18 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-08-01 21:38:18 +0000
commit3c7c79189e2912ac179deab21c92ffb3448b128b (patch)
treedce0b4d5b3f49965172c896e72cd5e40264d1606 /firmware
parent1ace06a67d5ec4df3a0295a341124677782baf70 (diff)
downloadrockbox-3c7c79189e2912ac179deab21c92ffb3448b128b.tar.gz
rockbox-3c7c79189e2912ac179deab21c92ffb3448b128b.tar.bz2
rockbox-3c7c79189e2912ac179deab21c92ffb3448b128b.zip
* Move DSP_CALLBACK_* enum to sound.h
* Add software based volume control for a certain range (SW_VOLUME_MIN -> SW_VOLUME_MAX) * Make Onda VX747 use it * Don't change volume or frequency in Ingenic Jz4740 codec driver when they're already set git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22106 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-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
4 files changed, 38 insertions, 24 deletions
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 @@
/* has no tone controls, so we use the software ones */
#define HAVE_SW_TONE_CONTROLS
+/* has no volume control, so we use the software ones */
+#define HAVE_SW_VOLUME_CONTROL
+
+/* software controlled volume ranges from -73 -> 0 dB, other than that
+ is controlled by hardware */
+#define SW_VOLUME_MIN -73
+#define SW_VOLUME_MAX 0
+
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
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 @@
#include <inttypes.h>
#include <audiohw.h>
+#if CONFIG_CODEC == SWCODEC
+enum {
+ DSP_CALLBACK_SET_PRESCALE = 0,
+ DSP_CALLBACK_SET_BASS,
+ DSP_CALLBACK_SET_TREBLE,
+ DSP_CALLBACK_SET_CHANNEL_CONFIG,
+ DSP_CALLBACK_SET_STEREO_WIDTH,
+#ifdef HAVE_SW_VOLUME_CONTROL
+ DSP_CALLBACK_SET_SW_VOLUME,
+#endif
+};
+#endif
+
typedef void sound_set_type(int value);
const 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)
}
#if CONFIG_CODEC == SWCODEC
-/* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
-
-enum {
- DSP_CALLBACK_SET_PRESCALE = 0,
- DSP_CALLBACK_SET_BASS,
- DSP_CALLBACK_SET_TREBLE,
- DSP_CALLBACK_SET_CHANNEL_CONFIG,
- DSP_CALLBACK_SET_STEREO_WIDTH
-};
-
static int (*dsp_callback)(int, intptr_t) = NULL;
void sound_set_dsp_callback(int (*func)(int, intptr_t))
@@ -251,6 +241,10 @@ static void set_prescaled_volume(void)
r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
}
+#ifdef HAVE_SW_VOLUME_CONTROL
+ dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0);
+#endif
+
#if CONFIG_CODEC == MAS3507D
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
#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 @@
/* TODO */
const struct sound_settings_info audiohw_settings[] = {
- [SOUND_VOLUME] = {"dB", 0, 2, 0, 6, 0},
+ /* HAVE_SW_VOLUME_CONTROL */
+ [SOUND_VOLUME] = {"dB", 0, 1, SW_VOLUME_MIN, 6, 0},
/* HAVE_SW_TONE_CONTROLS */
[SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
[SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
@@ -79,7 +80,7 @@ static void i2s_codec_init(void)
REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST);
- REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(14) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44)
+ REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44)
| ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0));
mdelay(15);
@@ -287,9 +288,14 @@ void audiohw_init(void)
void audiohw_set_volume(int v)
{
- /* 0 <= v <= 60 */
- unsigned int codec_volume = v / 20;
- REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | ICDC_CDCCR2_HPVOL(codec_volume);
+ if(v >= 0)
+ {
+ /* 0 <= v <= 60 */
+ unsigned int codec_volume = ICDC_CDCCR2_HPVOL(v / 20);
+
+ if((REG_ICDC_CDCCR2 & ICDC_CDCCR2_HPVOL(0x3)) != codec_volume)
+ REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | codec_volume;
+ }
}
void audiohw_set_frequency(int freq)
@@ -329,7 +335,8 @@ void audiohw_set_frequency(int freq)
return;
}
- REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed;
+ if((REG_ICDC_CDCCR2 & ICDC_CDCCR2_SMPR(0xF)) != speed)
+ REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed;
}
int audio_channels = 2;
@@ -356,20 +363,16 @@ void audio_input_mux(int source, unsigned flags)
case AUDIO_SRC_PLAYBACK:
audio_channels = 2;
if(source != last_source)
- {
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE))
| (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON);
- }
break;
#if INPUT_SRC_CAPS & SRC_CAP_MIC
case AUDIO_SRC_MIC: /* recording only */
audio_channels = 1;
if(source != last_source)
- {
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE))
| (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_EMIC);
- }
break;
#endif
@@ -383,15 +386,11 @@ void audio_input_mux(int source, unsigned flags)
last_recording = recording;
if(recording)
- {
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE))
| (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ);
- }
else
- {
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_EADC |
ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ);
- }
break;
#endif
} /* end switch */