diff options
| author | Bob Cousins <bobc@rockbox.org> | 2009-11-01 22:58:08 +0000 |
|---|---|---|
| committer | Bob Cousins <bobc@rockbox.org> | 2009-11-01 22:58:08 +0000 |
| commit | 33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679 (patch) | |
| tree | b985669b775e9f482ca1d724f09d8a5cc74cd1cb | |
| parent | 5d40b9a24a5ffe096691fbc117c718561d4bb30c (diff) | |
| download | rockbox-33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679.zip rockbox-33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679.tar.gz rockbox-33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679.tar.bz2 rockbox-33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679.tar.xz | |
Improvements to mini2440/UDA1341 audio
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23478 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | firmware/drivers/audio/uda1341.c | 76 | ||||
| -rw-r--r-- | firmware/export/uda1341.h | 35 | ||||
| -rw-r--r-- | firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c | 15 |
3 files changed, 109 insertions, 17 deletions
diff --git a/firmware/drivers/audio/uda1341.c b/firmware/drivers/audio/uda1341.c index f9d95ef..0171169 100644 --- a/firmware/drivers/audio/uda1341.c +++ b/firmware/drivers/audio/uda1341.c @@ -33,9 +33,9 @@ const struct sound_settings_info audiohw_settings[] = { [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25},
[SOUND_BASS] = {"dB", 0, 2, 0, 24, 0},
[SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0},
- [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
- [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
- [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
+ [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, /* not used */ + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, /* not used */ + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, /* not used */ #ifdef HAVE_RECORDING
[SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
[SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
@@ -43,6 +43,17 @@ const struct sound_settings_info audiohw_settings[] = { #endif
};
+/* convert tenth of dB volume (-600..0) to master volume register value */ +int tenthdb2master(int db) +{ + if (db < -600) + return 63; + else /* 1 dB steps */ + return -(db / 10) + 1; +} + +static unsigned short uda_regs[NUM_REG_ID]; + /****************************************************************************/
/* ------------------------------------------------- */
@@ -59,7 +70,7 @@ const struct sound_settings_info audiohw_settings[] = { static void l3_init (void)
{
L3PORT |= L3MODE | L3CLOCK;
- L3PORT &= L3DATA;
+ L3PORT &= ~L3DATA; S3C2440_GPIO_CONFIG (GPBCON, 2, GPIO_OUTPUT); /* L3 MODE */
S3C2440_GPIO_CONFIG (GPBCON, 3, GPIO_OUTPUT); /* L3 DATA */
@@ -72,8 +83,8 @@ static void l3_init (void) static void bit_delay (void)
{
- int j;
- for (j=0; j<4; j++)
+ volatile int j; + for (j=0; j<5; j++) ;
}
@@ -86,6 +97,7 @@ static void l3_write_byte (unsigned char data, bool address_mode) L3PORT &= ~L3MODE;
else
L3PORT |= L3MODE;
+ bit_delay(); for (bit=0; bit < 8; bit++)
{
@@ -144,41 +156,91 @@ static void udacodec_reset(void) I2S_IFMT_IIS);
udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | UDA_SYSCLK_256FS | I2S_IFMT_IIS);
udacodec_write (UDA_REG_STATUS, UDA_STATUS_1 | UDA_POWER_DAC_ON);
+ + uda_regs[UDA_REG_ID_CTRL2] = UDA_PEAK_DETECT_POS_AFTER | + UDA_DE_EMPHASIS_NONE | UDA_MUTE_OFF | UDA_MODE_SWITCH_FLAT; + }
/****************************************************************************/
/* Audio API functions */
+/* This table must match the table in pcm-xxxx.c if using Master mode */ +/* [reserved, master clock rate] */ +static const unsigned char uda_freq_parms[HW_NUM_FREQ][2] = +{ + [HW_FREQ_64] = { 0, UDA_SYSCLK_256FS }, + [HW_FREQ_44] = { 0, UDA_SYSCLK_384FS }, + [HW_FREQ_22] = { 0, UDA_SYSCLK_256FS }, + [HW_FREQ_11] = { 0, UDA_SYSCLK_256FS }, +}; + void audiohw_init(void)
{
udacodec_reset();
+ + audiohw_set_bass (0); + audiohw_set_treble (0); + audiohw_set_master_vol (26, 26); /* -25 dB */ }
+void audiohw_postinit(void) +{ +} + void audiohw_close(void)
{
+ /* DAC, ADC off */ + udacodec_write (UDA_REG_STATUS, UDA_STATUS_1 | 0); }
void audiohw_set_bass(int value)
{
+ uda_regs [UDA_REG_ID_CTRL1] &= UDA_BASS_BOOST (UDA_BASS_BOOST_MASK); + uda_regs [UDA_REG_ID_CTRL1] |= UDA_BASS_BOOST (value & UDA_BASS_BOOST_MASK); + + udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL1 | uda_regs [UDA_REG_ID_CTRL1] ); }
void audiohw_set_treble(int value)
{
+ uda_regs [UDA_REG_ID_CTRL1] &= UDA_TREBLE (UDA_TREBLE_MASK); + uda_regs [UDA_REG_ID_CTRL1] |= UDA_TREBLE (value & UDA_TREBLE_MASK); + + udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL1 | uda_regs [UDA_REG_ID_CTRL1] ); }
void audiohw_mute(bool mute)
{
+ if (mute) + uda_regs [UDA_REG_ID_CTRL2] |= UDA_MUTE_ON; + else + uda_regs [UDA_REG_ID_CTRL2] &= ~UDA_MUTE_ON; + + udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL2 | uda_regs [UDA_REG_ID_CTRL2] ); }
void audiohw_set_prescaler(int val)
{
+ (void)val; }
-void audiohw_postinit(void)
+/** + * Sets left and right master volume (1(max) to 62(muted)) + */ +void audiohw_set_master_vol(int vol_l, int vol_r) {
+ uda_regs[UDA_REG_ID_CTRL0] = (vol_l + vol_r) / 2; + udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL0 | uda_regs[UDA_REG_ID_CTRL0]); }
void audiohw_set_frequency(int fsel)
{
+ if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; + + uda_regs[UDA_REG_ID_STATUS_0] = I2S_IFMT_IIS | uda_freq_parms[fsel][1]; + + udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | uda_regs[UDA_REG_ID_STATUS_0]); }
diff --git a/firmware/export/uda1341.h b/firmware/export/uda1341.h index dcbbeef..a43d33a 100644 --- a/firmware/export/uda1341.h +++ b/firmware/export/uda1341.h @@ -26,7 +26,7 @@ #define VOLUME_MIN -840 #define VOLUME_MAX 0 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) extern int tenthdb2master(int db); extern int tenthdb2mixer(int db); @@ -34,6 +34,23 @@ extern int tenthdb2mixer(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_mixer_vol(int channel1, int channel2); +/* These are logical register numbers for driver */ +enum uda_register { + UDA_REG_ID_STATUS_0, + UDA_REG_ID_STATUS_1, + UDA_REG_ID_CTRL0, + UDA_REG_ID_CTRL1, + UDA_REG_ID_CTRL2, + UDA_REG_ID_EXT_0, + UDA_REG_ID_EXT_1, + UDA_REG_ID_EXT_2, + UDA_REG_ID_EXT_4, + UDA_REG_ID_EXT_5, + UDA_REG_ID_EXT_6, + NUM_REG_ID +}; + + /* Address byte */ #define UDA1341_ADDR 0x14 #define UDA_REG_DATA0 0x00 @@ -67,23 +84,27 @@ extern void audiohw_set_mixer_vol(int channel1, int channel2); #define UDA_POWER_DAC_ON (1 << 0) /* DATA0 */ -#define UDA_DATA_CTRL0 (0 << 6) -#define UDA_DATA_CTRL1 (1 << 6) -#define UDA_DATA_CTRL2 (2 << 6) +#define UDA_DATA_CTRL0 (0 << 6) /* volume */ +#define UDA_DATA_CTRL1 (1 << 6) /* bass, treble */ +#define UDA_DATA_CTRL2 (2 << 6) /* peak det pos, de-emp, mute */ #define UDA_DATA_EXT_ADDR (6 << 5) #define UDA_DATA_EXT_DATA (7 << 5) -#define UDA_VOLUME(x) ((x) << 8) /* 1=0dB, 61=-60dB */ +#define UDA_VOLUME(x) ((x) << 0) /* 1=0dB, 61=-60dB */ #define UDA_BASS_BOOST(x) ((x) << 2) /* see datasheet */ +#define UDA_BASS_BOOST_MASK 0x0F #define UDA_TREBLE(x) ((x) << 0) /* see datasheet */ +#define UDA_TREBLE_MASK 0x03 -#define UDA_PEAK_DETECT_POS (1 << 5) +#define UDA_PEAK_DETECT_POS_BEFORE (0 << 5) +#define UDA_PEAK_DETECT_POS_AFTER (1 << 5) #define UDA_DE_EMPHASIS_NONE (0 << 3) #define UDA_DE_EMPHASIS_32 (1 << 3) #define UDA_DE_EMPHASIS_44_1 (2 << 3) #define UDA_DE_EMPHASIS_48 (3 << 3) -#define UDA_MUTE (1 << 2) +#define UDA_MUTE_ON (1 << 2) +#define UDA_MUTE_OFF (0 << 2) #define UDA_MODE_SWITCH_FLAT (0 << 0) #define UDA_MODE_SWITCH_MIN (1 << 0) #define UDA_MODE_SWITCH_MAX (3 << 0) diff --git a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c index 237bf26..9c898f8 100644 --- a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c +++ b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include <stdlib.h> +#include "config.h" #include "system.h" #include "kernel.h" #include "logf.h" @@ -48,7 +49,7 @@ static struct static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = { [HW_FREQ_64] = { 2, IISMOD_MASTER_CLOCK_256FS }, - [HW_FREQ_44] = { 3, IISMOD_MASTER_CLOCK_384FS }, + [HW_FREQ_44] = { 2, IISMOD_MASTER_CLOCK_384FS }, [HW_FREQ_22] = { 8, IISMOD_MASTER_CLOCK_256FS }, [HW_FREQ_11] = { 17, IISMOD_MASTER_CLOCK_256FS }, }; @@ -127,9 +128,12 @@ void pcm_postinit(void) void pcm_dma_apply_settings(void) { #ifdef HAVE_UDA1341 + unsigned int reg_val; /* set prescaler and master clock rate according to freq */ - IISPSR = (pcm_freq_parms [pcm_fsel][0] * IISPSR_PRESCALER_A) | pcm_freq_parms [pcm_fsel][0]; - IISMOD |= ~IISMOD_MASTER_CLOCK_384FS | pcm_freq_parms [pcm_fsel][1] ; + reg_val = (pcm_freq_parms [pcm_fsel][0] << 5) | pcm_freq_parms [pcm_fsel][0]; + + IISMOD = (IISMOD & ~IISMOD_MASTER_CLOCK_384FS) | pcm_freq_parms [pcm_fsel][1] ; + IISPSR = reg_val; #endif audiohw_set_frequency(pcm_fsel); @@ -156,6 +160,11 @@ static void play_start_pcm(void) /* turn off the idle */ IISCON &= ~(1<<3); +#ifdef HAVE_UDA1341 + IISMOD = (IISMOD & ~IISMOD_MASTER_CLOCK_384FS) | pcm_freq_parms [pcm_fsel][1] ; + IISPSR = (pcm_freq_parms [pcm_fsel][0] << 5) | pcm_freq_parms [pcm_fsel][0]; +#endif + /* start the IIS */ IISCON |= (1<<0); } |