summaryrefslogtreecommitdiff
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2008-01-16 08:28:17 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:59 +0100
commit31c77643a06313b3a26f4c38c75ceec2a89ad31a (patch)
treeb38b6be831ebf4ebd20df512b1544938a3cbd224 /sound/pci/oxygen
parent12b74c80cc20dec27b9f9eeb24ee86170c34e5a1 (diff)
[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 <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/oxygen.h3
-rw-r--r--sound/pci/oxygen/oxygen_lib.c82
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c25
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c2
4 files changed, 76 insertions, 36 deletions
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 4a0c6634ac96..66dee9504340 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 5b77c9439c36..ba2bb4995d1e 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 aa3a5c53d605..8b08e6d02cc9 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 5f67a799a034..0f67defc2b2d 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;