273 lines
6.8 KiB
C
273 lines
6.8 KiB
C
#include "mixer.h"
|
|
|
|
#ifdef MIXER_AK4531
|
|
u8_t mixer_value[] = {
|
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
|
|
0x7e, 0x3d, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00,
|
|
0x00, 0x01
|
|
};
|
|
int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
|
|
int max_level, cmd_left, cmd_right;
|
|
|
|
max_level = 0x1f;
|
|
/* Check device */
|
|
switch (level->device) {
|
|
case Master:
|
|
cmd_left = MASTER_VOLUME_LCH;
|
|
cmd_right = MASTER_VOLUME_RCH;
|
|
break;
|
|
case Dac:
|
|
return EINVAL;
|
|
case Fm:
|
|
cmd_left = FM_VOLUME_LCH;
|
|
cmd_right = FM_VOLUME_RCH;
|
|
break;
|
|
case Cd:
|
|
cmd_left = CD_AUDIO_VOLUME_LCH;
|
|
cmd_right = CD_AUDIO_VOLUME_RCH;
|
|
break;
|
|
case Line:
|
|
cmd_left = LINE_VOLUME_LCH;
|
|
cmd_right = LINE_VOLUME_RCH;
|
|
break;
|
|
case Mic:
|
|
cmd_left = cmd_right = MIC_VOLUME;
|
|
break;
|
|
case Speaker:
|
|
cmd_left = cmd_right = MONO_OUT_VOLUME;
|
|
max_level = 0x03;
|
|
break;
|
|
case Treble:
|
|
return EINVAL;
|
|
case Bass:
|
|
return EINVAL;
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
/* Set volume */
|
|
if (flag) {
|
|
if (level->right < 0)
|
|
level->right = 0;
|
|
else if (level->right > max_level)
|
|
level->right = max_level;
|
|
if (level->left < 0)
|
|
level->left = 0;
|
|
else if (level->left > max_level)
|
|
level->left = max_level;
|
|
/* ### WRITE_MIXER_REG ### */
|
|
dev_mixer_write(base, cmd_left, 0x1f - level->left);
|
|
/* ### WRITE_MIXER_REG ### */
|
|
dev_mixer_write(base, cmd_right, 0x1f - level->right);
|
|
mixer_value[cmd_left] = 0x1f - level->left;
|
|
mixer_value[cmd_right] = 0x1f - level->right;
|
|
}
|
|
/* Get volume (mixer register can not be read in ak4531 codec) */
|
|
else {
|
|
/* ### READ_MIXER_REG ### */
|
|
dev_mixer_read(base, cmd_left);
|
|
/* ### READ_MIXER_REG ### */
|
|
dev_mixer_read(base, cmd_right);
|
|
level->left = 0x1f - mixer_value[cmd_left];
|
|
level->right = 0x1f - mixer_value[cmd_right];
|
|
}
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
#ifdef MIXER_SB16
|
|
int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
|
|
int max_level, shift, cmd_left, cmd_right;
|
|
|
|
max_level = 0x0f;
|
|
shift = 4;
|
|
/* Check device */
|
|
switch (level->device) {
|
|
case Master:
|
|
cmd_left = SB16_MASTER_LEFT;
|
|
cmd_right = SB16_MASTER_RIGHT;
|
|
break;
|
|
case Dac:
|
|
cmd_left = SB16_DAC_LEFT;
|
|
cmd_right = SB16_DAC_RIGHT;
|
|
break;
|
|
case Fm:
|
|
cmd_left = SB16_FM_LEFT;
|
|
cmd_right = SB16_FM_RIGHT;
|
|
break;
|
|
case Cd:
|
|
cmd_left = SB16_CD_LEFT;
|
|
cmd_right = SB16_CD_RIGHT;
|
|
break;
|
|
case Line:
|
|
cmd_left = SB16_LINE_LEFT;
|
|
cmd_left = SB16_LINE_RIGHT;
|
|
break;
|
|
case Mic:
|
|
cmd_left = cmd_right = SB16_MIC_LEVEL;
|
|
break;
|
|
case Speaker:
|
|
cmd_left = cmd_right = SB16_PC_LEVEL;
|
|
shift = 6;
|
|
max_level = 0x03;
|
|
break;
|
|
case Treble:
|
|
cmd_left = SB16_TREBLE_LEFT;
|
|
cmd_right = SB16_TREBLE_RIGHT;
|
|
shift = 4;
|
|
max_level = 0x0f;
|
|
break;
|
|
case Bass:
|
|
cmd_left = SB16_BASS_LEFT;
|
|
cmd_right = SB16_BASS_RIGHT;
|
|
shift = 4;
|
|
max_level = 0x0f;
|
|
break;
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
/* Set volume */
|
|
if (flag) {
|
|
if (level->right < 0)
|
|
level->right = 0;
|
|
else if (level->right > max_level)
|
|
level->right = max_level;
|
|
if (level->left < 0)
|
|
level->left = 0;
|
|
else if (level->left > max_level)
|
|
level->left = max_level;
|
|
/* ### WRITE_MIXER_REG ### */
|
|
dev_mixer_write(base, cmd_left, level->left << shift);
|
|
/* ### WRITE_MIXER_REG ### */
|
|
dev_mixer_write(base, cmd_right, level->right << shift);
|
|
}
|
|
/* Get volume */
|
|
else {
|
|
/* ### READ_MIXER_REG ### */
|
|
level->left = dev_mixer_read(base, cmd_left);
|
|
/* ### READ_MIXER_REG ### */
|
|
level->right = dev_mixer_read(base, cmd_right);
|
|
level->left >>= shift;
|
|
level->right >>= shift;
|
|
}
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
#ifdef MIXER_AC97
|
|
int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
|
|
int max_level, cmd, data;
|
|
|
|
max_level = 0x1f;
|
|
/* Check device */
|
|
switch (level->device) {
|
|
case Master:
|
|
cmd = AC97_MASTER_VOLUME;
|
|
break;
|
|
case Dac:
|
|
return EINVAL;
|
|
case Fm:
|
|
cmd = AC97_PCM_OUT_VOLUME;
|
|
break;
|
|
case Cd:
|
|
cmd = AC97_CD_VOLUME;
|
|
break;
|
|
case Line:
|
|
cmd = AC97_LINE_IN_VOLUME;
|
|
break;
|
|
case Mic:
|
|
cmd = AC97_MIC_VOLUME;
|
|
break;
|
|
case Speaker:
|
|
return EINVAL;
|
|
case Treble:
|
|
return EINVAL;
|
|
case Bass:
|
|
return EINVAL;
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
/* Set volume */
|
|
if (flag) {
|
|
if (level->right < 0)
|
|
level->right = 0;
|
|
else if (level->right > max_level)
|
|
level->right = max_level;
|
|
if (level->left < 0)
|
|
level->left = 0;
|
|
else if (level->left > max_level)
|
|
level->left = max_level;
|
|
data = (max_level - level->left) << 8 | (max_level - level->right);
|
|
/* ### WRITE_MIXER_REG ### */
|
|
dev_mixer_write(base, cmd, data);
|
|
}
|
|
/* Get volume */
|
|
else {
|
|
/* ### READ_MIXER_REG ### */
|
|
data = dev_mixer_read(base, cmd);
|
|
level->left = (u16_t)(data >> 8);
|
|
level->right = (u16_t)(data & 0xff);
|
|
if (level->right < 0)
|
|
level->right = 0;
|
|
else if (level->right > max_level)
|
|
level->right = max_level;
|
|
if (level->left < 0)
|
|
level->left = 0;
|
|
else if (level->left > max_level)
|
|
level->left = max_level;
|
|
level->left = max_level - level->left;
|
|
level->right = max_level - level->right;
|
|
}
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
/* Set default mixer volume */
|
|
void dev_set_default_volume(u32_t *base) {
|
|
int i;
|
|
#ifdef MIXER_AK4531
|
|
for (i = 0; i <= 0x19; i++)
|
|
dev_mixer_write(base, i, mixer_value[i]);
|
|
#endif
|
|
#ifdef MIXER_SB16
|
|
dev_mixer_write(base, SB16_MASTER_LEFT, 0x18 << 3);
|
|
dev_mixer_write(base, SB16_MASTER_RIGHT, 0x18 << 3);
|
|
dev_mixer_write(base, SB16_DAC_LEFT, 0x0f << 4);
|
|
dev_mixer_write(base, SB16_DAC_RIGHT, 0x0f << 4);
|
|
dev_mixer_write(base, SB16_FM_LEFT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_FM_RIGHT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_CD_LEFT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_CD_RIGHT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_LINE_LEFT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_LINE_RIGHT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_MIC_LEVEL, 0x0f << 4);
|
|
dev_mixer_write(base, SB16_PC_LEVEL, 0x02 << 6);
|
|
dev_mixer_write(base, SB16_TREBLE_LEFT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_TREBLE_RIGHT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_BASS_LEFT, 0x08 << 4);
|
|
dev_mixer_write(base, SB16_BASS_RIGHT, 0x08 << 4);
|
|
#endif
|
|
|
|
#ifdef MIXER_AC97
|
|
dev_mixer_write(base, AC97_POWERDOWN, 0x0000);
|
|
for (i = 0; i < 50000; i++) {
|
|
if (dev_mixer_read(base, AC97_POWERDOWN) & 0x03)
|
|
break;
|
|
micro_delay(100);
|
|
}
|
|
if (i == 50000)
|
|
printf("SDR: AC97 is not ready\n");
|
|
dev_mixer_write(base, AC97_MASTER_VOLUME, 0x0000);
|
|
dev_mixer_write(base, AC97_MONO_VOLUME, 0x8000);
|
|
dev_mixer_write(base, AC97_PHONE_VOLUME, 0x8008);
|
|
dev_mixer_write(base, AC97_MIC_VOLUME, 0x0000);
|
|
dev_mixer_write(base, AC97_LINE_IN_VOLUME, 0x0303);
|
|
dev_mixer_write(base, AC97_CD_VOLUME, 0x0808);
|
|
dev_mixer_write(base, AC97_AUX_IN_VOLUME, 0x0808);
|
|
dev_mixer_write(base, AC97_PCM_OUT_VOLUME, 0x0808);
|
|
dev_mixer_write(base, AC97_RECORD_GAIN_VOLUME, 0x0000);
|
|
dev_mixer_write(base, AC97_RECORD_SELECT, 0x0000);
|
|
dev_mixer_write(base, AC97_GENERAL_PURPOSE, 0x0000);
|
|
#endif
|
|
}
|