From 31c77643a06313b3a26f4c38c75ceec2a89ad31a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 16 Jan 2008 08:28:17 +0100 Subject: [PATCH] [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: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/oxygen/oxygen.h | 3 +- sound/pci/oxygen/oxygen_lib.c | 82 ++++++++++++++++++++------------- sound/pci/oxygen/oxygen_mixer.c | 25 +++++++++- sound/pci/oxygen/oxygen_pcm.c | 2 +- 4 files changed, 76 insertions(+), 36 deletions(-) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 4a0c6634ac..66dee95043 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -56,7 +56,8 @@ struct oxygen { u8 spdif_playback_enable; u8 ak4396_reg1; u8 revision; - u8 has_2nd_ac97_codec; + u8 has_ac97_0; + u8 has_ac97_1; u32 spdif_bits; u32 spdif_pcm_bits; struct snd_pcm_substream *streams[PCM_COUNT]; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 5b77c9439c..ba2bb4995d 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -142,13 +142,25 @@ static void oxygen_proc_read(struct snd_info_entry *entry, } if (mutex_lock_interruptible(&chip->mutex) < 0) return; - snd_iprintf(buffer, "\nAC97\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, 0, i + j)); - snd_iprintf(buffer, "\n"); + if (chip->has_ac97_0) { + snd_iprintf(buffer, "\nAC97\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, 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); } @@ -184,6 +196,10 @@ static void __devinit oxygen_init(struct oxygen *chip) if (chip->revision == 1) 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_FUNCTION_RESET_CODEC | OXYGEN_FUNCTION_ENABLE_SPI_4_5); @@ -202,31 +218,33 @@ static void __devinit oxygen_init(struct oxygen *chip) oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00); - oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG, - OXYGEN_AC97_OUT_MAGIC3); - oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG, - OXYGEN_AC97_IN_MAGIC3); - oxygen_write_ac97(chip, 0, AC97_RESET, 0); - msleep(1); - oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); - oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); - oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); - oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); - oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); - oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); - oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808); - oxygen_write_ac97(chip, 0, AC97_CD, 0x8808); - oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808); - oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808); - oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); - oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); - oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); - oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); - /* power down unused ADCs and DACs */ - oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, - AC97_PD_PR0 | AC97_PD_PR1); - oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS, - AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK); + if (chip->has_ac97_0) { + oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG, + OXYGEN_AC97_OUT_MAGIC3); + oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG, + OXYGEN_AC97_IN_MAGIC3); + oxygen_write_ac97(chip, 0, AC97_RESET, 0); + msleep(1); + oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); + oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); + oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); + oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); + oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); + oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); + oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808); + oxygen_write_ac97(chip, 0, AC97_CD, 0x8808); + oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808); + oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808); + oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); + oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); + oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); + oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); + /* power down unused ADCs and DACs */ + oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, + AC97_PD_PR0 | AC97_PD_PR1); + 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) diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index aa3a5c53d6..8b08e6d02c 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -597,6 +597,9 @@ static const struct snd_kcontrol_new controls[] = { .info = spdif_info, .get = spdif_input_default_get, }, +}; + +static const struct snd_kcontrol_new ac97_controls[] = { AC97_VOLUME("Mic Capture Volume", AC97_MIC), AC97_SWITCH("Mic Capture Switch", AC97_MIC, 15, 1), AC97_SWITCH("Mic Boost (+20dB)", AC97_MIC, 6, 0), @@ -617,7 +620,9 @@ static void oxygen_any_ctl_free(struct snd_kcontrol *ctl) 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] = { [CONTROL_SPDIF_PCM] = @@ -633,7 +638,7 @@ int oxygen_mixer_init(struct oxygen *chip) struct snd_kcontrol *ctl; int err; - for (i = 0; i < ARRAY_SIZE(controls); ++i) { + for (i = 0; i < count; ++i) { ctl = snd_ctl_new1(&controls[i], chip); if (!ctl) return -ENOMEM; @@ -651,5 +656,21 @@ int oxygen_mixer_init(struct oxygen *chip) 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; } diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 5f67a799a0..0f67defc2b 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -714,7 +714,7 @@ int __devinit oxygen_pcm_init(struct oxygen *chip) snd_dma_pci_data(chip->pci), 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); if (err < 0) return err; -- 2.39.5