Skip to content

Commit

Permalink
[ALSA] oxygen: make AC97 codec optional
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Clemens Ladisch authored and Jaroslav Kysela committed Jan 31, 2008
1 parent 12b74c8 commit 31c7764
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 36 deletions.
3 changes: 2 additions & 1 deletion sound/pci/oxygen/oxygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
82 changes: 50 additions & 32 deletions sound/pci/oxygen/oxygen_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
25 changes: 23 additions & 2 deletions sound/pci/oxygen/oxygen_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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] =
Expand All @@ -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;
Expand All @@ -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;
}
2 changes: 1 addition & 1 deletion sound/pci/oxygen/oxygen_pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 31c7764

Please sign in to comment.