Commit 31c77643 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Jaroslav Kysela

[ALSA] oxygen: make AC97 codec optional

Only initialize and create mixer controls for the first AC97 codec when
one has actually been detected.
Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 12b74c80
...@@ -56,7 +56,8 @@ struct oxygen { ...@@ -56,7 +56,8 @@ struct oxygen {
u8 spdif_playback_enable; u8 spdif_playback_enable;
u8 ak4396_reg1; u8 ak4396_reg1;
u8 revision; u8 revision;
u8 has_2nd_ac97_codec; u8 has_ac97_0;
u8 has_ac97_1;
u32 spdif_bits; u32 spdif_bits;
u32 spdif_pcm_bits; u32 spdif_pcm_bits;
struct snd_pcm_substream *streams[PCM_COUNT]; struct snd_pcm_substream *streams[PCM_COUNT];
......
...@@ -142,13 +142,25 @@ static void oxygen_proc_read(struct snd_info_entry *entry, ...@@ -142,13 +142,25 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
} }
if (mutex_lock_interruptible(&chip->mutex) < 0) if (mutex_lock_interruptible(&chip->mutex) < 0)
return; return;
snd_iprintf(buffer, "\nAC97\n"); if (chip->has_ac97_0) {
for (i = 0; i < 0x80; i += 0x10) { snd_iprintf(buffer, "\nAC97\n");
snd_iprintf(buffer, "%02x:", i); for (i = 0; i < 0x80; i += 0x10) {
for (j = 0; j < 0x10; j += 2) snd_iprintf(buffer, "%02x:", i);
snd_iprintf(buffer, " %04x", for (j = 0; j < 0x10; j += 2)
oxygen_read_ac97(chip, 0, i + j)); snd_iprintf(buffer, " %04x",
snd_iprintf(buffer, "\n"); oxygen_read_ac97(chip, 0, i + j));
snd_iprintf(buffer, "\n");
}
}
if (chip->has_ac97_1) {
snd_iprintf(buffer, "\nAC97 2\n");
for (i = 0; i < 0x80; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; j += 2)
snd_iprintf(buffer, " %04x",
oxygen_read_ac97(chip, 1, i + j));
snd_iprintf(buffer, "\n");
}
} }
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
} }
...@@ -184,6 +196,10 @@ static void __devinit oxygen_init(struct oxygen *chip) ...@@ -184,6 +196,10 @@ static void __devinit oxygen_init(struct oxygen *chip)
if (chip->revision == 1) if (chip->revision == 1)
oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC); oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC);
i = oxygen_read16(chip, OXYGEN_AC97_CONTROL);
chip->has_ac97_0 = (i & OXYGEN_AC97_CODEC_0) != 0;
chip->has_ac97_1 = (i & OXYGEN_AC97_CODEC_1) != 0;
oxygen_set_bits8(chip, OXYGEN_FUNCTION, oxygen_set_bits8(chip, OXYGEN_FUNCTION,
OXYGEN_FUNCTION_RESET_CODEC | OXYGEN_FUNCTION_RESET_CODEC |
OXYGEN_FUNCTION_ENABLE_SPI_4_5); OXYGEN_FUNCTION_ENABLE_SPI_4_5);
...@@ -202,31 +218,33 @@ static void __devinit oxygen_init(struct oxygen *chip) ...@@ -202,31 +218,33 @@ static void __devinit oxygen_init(struct oxygen *chip)
oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00); oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00);
oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG, if (chip->has_ac97_0) {
OXYGEN_AC97_OUT_MAGIC3); oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG,
oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG, OXYGEN_AC97_OUT_MAGIC3);
OXYGEN_AC97_IN_MAGIC3); oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG,
oxygen_write_ac97(chip, 0, AC97_RESET, 0); OXYGEN_AC97_IN_MAGIC3);
msleep(1); oxygen_write_ac97(chip, 0, AC97_RESET, 0);
oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); msleep(1);
oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300);
oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043);
oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f);
oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000);
oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000);
oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808); oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808);
oxygen_write_ac97(chip, 0, AC97_CD, 0x8808); oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808);
oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808); oxygen_write_ac97(chip, 0, AC97_CD, 0x8808);
oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808); oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808);
oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808);
oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000);
oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080);
oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080);
/* power down unused ADCs and DACs */ oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001);
oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, /* power down unused ADCs and DACs */
AC97_PD_PR0 | AC97_PD_PR1); oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN,
oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS, AC97_PD_PR0 | AC97_PD_PR1);
AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK); oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS,
AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK);
}
} }
static void oxygen_card_free(struct snd_card *card) static void oxygen_card_free(struct snd_card *card)
......
...@@ -597,6 +597,9 @@ static const struct snd_kcontrol_new controls[] = { ...@@ -597,6 +597,9 @@ static const struct snd_kcontrol_new controls[] = {
.info = spdif_info, .info = spdif_info,
.get = spdif_input_default_get, .get = spdif_input_default_get,
}, },
};
static const struct snd_kcontrol_new ac97_controls[] = {
AC97_VOLUME("Mic Capture Volume", AC97_MIC), AC97_VOLUME("Mic Capture Volume", AC97_MIC),
AC97_SWITCH("Mic Capture Switch", AC97_MIC, 15, 1), AC97_SWITCH("Mic Capture Switch", AC97_MIC, 15, 1),
AC97_SWITCH("Mic Boost (+20dB)", AC97_MIC, 6, 0), AC97_SWITCH("Mic Boost (+20dB)", AC97_MIC, 6, 0),
...@@ -617,7 +620,9 @@ static void oxygen_any_ctl_free(struct snd_kcontrol *ctl) ...@@ -617,7 +620,9 @@ static void oxygen_any_ctl_free(struct snd_kcontrol *ctl)
chip->controls[i] = NULL; chip->controls[i] = NULL;
} }
int oxygen_mixer_init(struct oxygen *chip) static int add_controls(struct oxygen *chip,
const struct snd_kcontrol_new controls[],
unsigned int count)
{ {
static const char *const known_ctl_names[CONTROL_COUNT] = { static const char *const known_ctl_names[CONTROL_COUNT] = {
[CONTROL_SPDIF_PCM] = [CONTROL_SPDIF_PCM] =
...@@ -633,7 +638,7 @@ int oxygen_mixer_init(struct oxygen *chip) ...@@ -633,7 +638,7 @@ int oxygen_mixer_init(struct oxygen *chip)
struct snd_kcontrol *ctl; struct snd_kcontrol *ctl;
int err; int err;
for (i = 0; i < ARRAY_SIZE(controls); ++i) { for (i = 0; i < count; ++i) {
ctl = snd_ctl_new1(&controls[i], chip); ctl = snd_ctl_new1(&controls[i], chip);
if (!ctl) if (!ctl)
return -ENOMEM; return -ENOMEM;
...@@ -651,5 +656,21 @@ int oxygen_mixer_init(struct oxygen *chip) ...@@ -651,5 +656,21 @@ int oxygen_mixer_init(struct oxygen *chip)
ctl->private_free = oxygen_any_ctl_free; ctl->private_free = oxygen_any_ctl_free;
} }
} }
return 0;
}
int oxygen_mixer_init(struct oxygen *chip)
{
int err;
err = add_controls(chip, controls, ARRAY_SIZE(controls));
if (err < 0)
return err;
if (chip->has_ac97_0) {
err = add_controls(chip, ac97_controls,
ARRAY_SIZE(ac97_controls));
if (err < 0)
return err;
}
return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0; return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0;
} }
...@@ -714,7 +714,7 @@ int __devinit oxygen_pcm_init(struct oxygen *chip) ...@@ -714,7 +714,7 @@ int __devinit oxygen_pcm_init(struct oxygen *chip)
snd_dma_pci_data(chip->pci), snd_dma_pci_data(chip->pci),
128 * 1024, 256 * 1024); 128 * 1024, 256 * 1024);
if (chip->has_2nd_ac97_codec) { if (chip->has_ac97_1) {
err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm); err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm);
if (err < 0) if (err < 0)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment