diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2008-01-16 02:28:17 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:59 -0500 |
commit | 31c77643a06313b3a26f4c38c75ceec2a89ad31a (patch) | |
tree | b38b6be831ebf4ebd20df512b1544938a3cbd224 | |
parent | 12b74c80cc20dec27b9f9eeb24ee86170c34e5a1 (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>
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 3 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 82 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 25 | ||||
-rw-r--r-- | 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 4a0c6634ac96..66dee9504340 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -56,7 +56,8 @@ struct oxygen { | |||
56 | u8 spdif_playback_enable; | 56 | u8 spdif_playback_enable; |
57 | u8 ak4396_reg1; | 57 | u8 ak4396_reg1; |
58 | u8 revision; | 58 | u8 revision; |
59 | u8 has_2nd_ac97_codec; | 59 | u8 has_ac97_0; |
60 | u8 has_ac97_1; | ||
60 | u32 spdif_bits; | 61 | u32 spdif_bits; |
61 | u32 spdif_pcm_bits; | 62 | u32 spdif_pcm_bits; |
62 | struct snd_pcm_substream *streams[PCM_COUNT]; | 63 | 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, | |||
142 | } | 142 | } |
143 | if (mutex_lock_interruptible(&chip->mutex) < 0) | 143 | if (mutex_lock_interruptible(&chip->mutex) < 0) |
144 | return; | 144 | return; |
145 | snd_iprintf(buffer, "\nAC97\n"); | 145 | if (chip->has_ac97_0) { |
146 | for (i = 0; i < 0x80; i += 0x10) { | 146 | snd_iprintf(buffer, "\nAC97\n"); |
147 | snd_iprintf(buffer, "%02x:", i); | 147 | for (i = 0; i < 0x80; i += 0x10) { |
148 | for (j = 0; j < 0x10; j += 2) | 148 | snd_iprintf(buffer, "%02x:", i); |
149 | snd_iprintf(buffer, " %04x", | 149 | for (j = 0; j < 0x10; j += 2) |
150 | oxygen_read_ac97(chip, 0, i + j)); | 150 | snd_iprintf(buffer, " %04x", |
151 | snd_iprintf(buffer, "\n"); | 151 | oxygen_read_ac97(chip, 0, i + j)); |
152 | snd_iprintf(buffer, "\n"); | ||
153 | } | ||
154 | } | ||
155 | if (chip->has_ac97_1) { | ||
156 | snd_iprintf(buffer, "\nAC97 2\n"); | ||
157 | for (i = 0; i < 0x80; i += 0x10) { | ||
158 | snd_iprintf(buffer, "%02x:", i); | ||
159 | for (j = 0; j < 0x10; j += 2) | ||
160 | snd_iprintf(buffer, " %04x", | ||
161 | oxygen_read_ac97(chip, 1, i + j)); | ||
162 | snd_iprintf(buffer, "\n"); | ||
163 | } | ||
152 | } | 164 | } |
153 | mutex_unlock(&chip->mutex); | 165 | mutex_unlock(&chip->mutex); |
154 | } | 166 | } |
@@ -184,6 +196,10 @@ static void __devinit oxygen_init(struct oxygen *chip) | |||
184 | if (chip->revision == 1) | 196 | if (chip->revision == 1) |
185 | oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC); | 197 | oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC); |
186 | 198 | ||
199 | i = oxygen_read16(chip, OXYGEN_AC97_CONTROL); | ||
200 | chip->has_ac97_0 = (i & OXYGEN_AC97_CODEC_0) != 0; | ||
201 | chip->has_ac97_1 = (i & OXYGEN_AC97_CODEC_1) != 0; | ||
202 | |||
187 | oxygen_set_bits8(chip, OXYGEN_FUNCTION, | 203 | oxygen_set_bits8(chip, OXYGEN_FUNCTION, |
188 | OXYGEN_FUNCTION_RESET_CODEC | | 204 | OXYGEN_FUNCTION_RESET_CODEC | |
189 | OXYGEN_FUNCTION_ENABLE_SPI_4_5); | 205 | OXYGEN_FUNCTION_ENABLE_SPI_4_5); |
@@ -202,31 +218,33 @@ static void __devinit oxygen_init(struct oxygen *chip) | |||
202 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); | 218 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); |
203 | 219 | ||
204 | oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00); | 220 | oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00); |
205 | oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG, | 221 | if (chip->has_ac97_0) { |
206 | OXYGEN_AC97_OUT_MAGIC3); | 222 | oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG, |
207 | oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG, | 223 | OXYGEN_AC97_OUT_MAGIC3); |
208 | OXYGEN_AC97_IN_MAGIC3); | 224 | oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG, |
209 | oxygen_write_ac97(chip, 0, AC97_RESET, 0); | 225 | OXYGEN_AC97_IN_MAGIC3); |
210 | msleep(1); | 226 | oxygen_write_ac97(chip, 0, AC97_RESET, 0); |
211 | oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); | 227 | msleep(1); |
212 | oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); | 228 | oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); |
213 | oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); | 229 | oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); |
214 | oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); | 230 | oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); |
215 | oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); | 231 | oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); |
216 | oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); | 232 | oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); |
217 | oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808); | 233 | oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); |
218 | oxygen_write_ac97(chip, 0, AC97_CD, 0x8808); | 234 | oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808); |
219 | oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808); | 235 | oxygen_write_ac97(chip, 0, AC97_CD, 0x8808); |
220 | oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808); | 236 | oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808); |
221 | oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); | 237 | oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808); |
222 | oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); | 238 | oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); |
223 | oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); | 239 | oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); |
224 | oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); | 240 | oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); |
225 | /* power down unused ADCs and DACs */ | 241 | oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); |
226 | oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, | 242 | /* power down unused ADCs and DACs */ |
227 | AC97_PD_PR0 | AC97_PD_PR1); | 243 | oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, |
228 | oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS, | 244 | AC97_PD_PR0 | AC97_PD_PR1); |
229 | AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK); | 245 | oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS, |
246 | AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK); | ||
247 | } | ||
230 | } | 248 | } |
231 | 249 | ||
232 | static void oxygen_card_free(struct snd_card *card) | 250 | 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[] = { | |||
597 | .info = spdif_info, | 597 | .info = spdif_info, |
598 | .get = spdif_input_default_get, | 598 | .get = spdif_input_default_get, |
599 | }, | 599 | }, |
600 | }; | ||
601 | |||
602 | static const struct snd_kcontrol_new ac97_controls[] = { | ||
600 | AC97_VOLUME("Mic Capture Volume", AC97_MIC), | 603 | AC97_VOLUME("Mic Capture Volume", AC97_MIC), |
601 | AC97_SWITCH("Mic Capture Switch", AC97_MIC, 15, 1), | 604 | AC97_SWITCH("Mic Capture Switch", AC97_MIC, 15, 1), |
602 | AC97_SWITCH("Mic Boost (+20dB)", AC97_MIC, 6, 0), | 605 | AC97_SWITCH("Mic Boost (+20dB)", AC97_MIC, 6, 0), |
@@ -617,7 +620,9 @@ static void oxygen_any_ctl_free(struct snd_kcontrol *ctl) | |||
617 | chip->controls[i] = NULL; | 620 | chip->controls[i] = NULL; |
618 | } | 621 | } |
619 | 622 | ||
620 | int oxygen_mixer_init(struct oxygen *chip) | 623 | static int add_controls(struct oxygen *chip, |
624 | const struct snd_kcontrol_new controls[], | ||
625 | unsigned int count) | ||
621 | { | 626 | { |
622 | static const char *const known_ctl_names[CONTROL_COUNT] = { | 627 | static const char *const known_ctl_names[CONTROL_COUNT] = { |
623 | [CONTROL_SPDIF_PCM] = | 628 | [CONTROL_SPDIF_PCM] = |
@@ -633,7 +638,7 @@ int oxygen_mixer_init(struct oxygen *chip) | |||
633 | struct snd_kcontrol *ctl; | 638 | struct snd_kcontrol *ctl; |
634 | int err; | 639 | int err; |
635 | 640 | ||
636 | for (i = 0; i < ARRAY_SIZE(controls); ++i) { | 641 | for (i = 0; i < count; ++i) { |
637 | ctl = snd_ctl_new1(&controls[i], chip); | 642 | ctl = snd_ctl_new1(&controls[i], chip); |
638 | if (!ctl) | 643 | if (!ctl) |
639 | return -ENOMEM; | 644 | return -ENOMEM; |
@@ -651,5 +656,21 @@ int oxygen_mixer_init(struct oxygen *chip) | |||
651 | ctl->private_free = oxygen_any_ctl_free; | 656 | ctl->private_free = oxygen_any_ctl_free; |
652 | } | 657 | } |
653 | } | 658 | } |
659 | return 0; | ||
660 | } | ||
661 | |||
662 | int oxygen_mixer_init(struct oxygen *chip) | ||
663 | { | ||
664 | int err; | ||
665 | |||
666 | err = add_controls(chip, controls, ARRAY_SIZE(controls)); | ||
667 | if (err < 0) | ||
668 | return err; | ||
669 | if (chip->has_ac97_0) { | ||
670 | err = add_controls(chip, ac97_controls, | ||
671 | ARRAY_SIZE(ac97_controls)); | ||
672 | if (err < 0) | ||
673 | return err; | ||
674 | } | ||
654 | return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0; | 675 | return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0; |
655 | } | 676 | } |
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) | |||
714 | snd_dma_pci_data(chip->pci), | 714 | snd_dma_pci_data(chip->pci), |
715 | 128 * 1024, 256 * 1024); | 715 | 128 * 1024, 256 * 1024); |
716 | 716 | ||
717 | if (chip->has_2nd_ac97_codec) { | 717 | if (chip->has_ac97_1) { |
718 | err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm); | 718 | err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm); |
719 | if (err < 0) | 719 | if (err < 0) |
720 | return err; | 720 | return err; |