[ALSA] oxygen: make AC97 codec optional
authorClemens Ladisch <clemens@ladisch.de>
Wed, 16 Jan 2008 07:28:17 +0000 (08:28 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Jan 2008 16:29:59 +0000 (17:29 +0100)
Only initialize and create mixer controls for the first AC97 codec when
one has actually been detected.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/oxygen_mixer.c
sound/pci/oxygen/oxygen_pcm.c

index 4a0c6634ac963589f8aa2e9777eeda8bbfd20f68..66dee95043401ab86965d7cf1f8ad7795baed5c7 100644 (file)
@@ -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];
index 5b77c9439c36dfc9e14a1ffe00f962d32c213e95..ba2bb4995d1eba6d58fba1b9bfbb0263e6a46ef6 100644 (file)
@@ -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)
index aa3a5c53d6055d7f54180c6cba9bb8240229b821..8b08e6d02cc9250350da76f17108d83cecab85b1 100644 (file)
@@ -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;
 }
index 5f67a799a034763ebf94435313cd7ee8f6b1b072..0f67defc2b2df754a192daa69e68e7737e0c0833 100644 (file)
@@ -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;