aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2008-01-16 02:28:17 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:59 -0500
commit31c77643a06313b3a26f4c38c75ceec2a89ad31a (patch)
treeb38b6be831ebf4ebd20df512b1544938a3cbd224
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>
-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 {
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
232static void oxygen_card_free(struct snd_card *card) 250static 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
602static 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
620int oxygen_mixer_init(struct oxygen *chip) 623static 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
662int 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;