diff options
author | cg <cg@FreeBSD.org> | 2000-09-17 23:51:00 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2000-09-17 23:51:00 +0000 |
commit | 9bd1dd51e891dac2ce769ee3a6a6917efb9fe430 (patch) | |
tree | 507ffb23f2a3a716d3451bf6a3f95df23601d4c9 /sys/dev/sound/pcm/ac97.c | |
parent | 2078d1f36cd4d10d7fba4191624fd6b5bac4ccc7 (diff) | |
download | FreeBSD-src-9bd1dd51e891dac2ce769ee3a6a6917efb9fe430.zip FreeBSD-src-9bd1dd51e891dac2ce769ee3a6a6917efb9fe430.tar.gz |
dynamify- probe codec for supported channels
add channel mappings for mixer
Diffstat (limited to 'sys/dev/sound/pcm/ac97.c')
-rw-r--r-- | sys/dev/sound/pcm/ac97.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c index 8fe3662..a5aaccb 100644 --- a/sys/dev/sound/pcm/ac97.c +++ b/sys/dev/sound/pcm/ac97.c @@ -37,6 +37,7 @@ struct ac97mixtable_entry { unsigned mute:1; unsigned recidx:4; unsigned mask:1; + unsigned enable:1; }; struct ac97_info { @@ -57,29 +58,22 @@ struct ac97_codecid { }; static const struct ac97mixtable_entry ac97mixtable_default[32] = { - [SOUND_MIXER_VOLUME] = { AC97_MIX_MASTER, 5, 0, 1, 1, 6, 0 }, - [SOUND_MIXER_BASS] = { AC97_MIX_TONE, 4, 8, 0, 0, 0, 1 }, - [SOUND_MIXER_TREBLE] = { AC97_MIX_TONE, 4, 0, 0, 0, 0, 1 }, - [SOUND_MIXER_PCM] = { AC97_MIX_PCM, 5, 0, 1, 1, 0, 0 }, - [SOUND_MIXER_SPEAKER] = { AC97_MIX_BEEP, 4, 1, 0, 1, 0, 0 }, - [SOUND_MIXER_LINE] = { AC97_MIX_LINE, 5, 0, 1, 1, 5, 0 }, - [SOUND_MIXER_MIC] = { AC97_MIX_MIC, 5, 0, 0, 1, 1, 0 }, - [SOUND_MIXER_CD] = { AC97_MIX_CD, 5, 0, 1, 1, 2, 0 }, - [SOUND_MIXER_LINE1] = { AC97_MIX_AUX, 5, 0, 1, 1, 4, 0 }, - [SOUND_MIXER_VIDEO] = { AC97_MIX_VIDEO, 5, 0, 1, 1, 3, 0 }, - [SOUND_MIXER_RECLEV] = { -AC97_MIX_RGAIN, 4, 0, 1, 1, 0, 0 } + [SOUND_MIXER_VOLUME] = { AC97_MIX_MASTER, 5, 0, 1, 1, 6, 0, 1 }, + [SOUND_MIXER_MONITOR] = { AC97_MIX_PHONES, 5, 0, 1, 1, 0, 0, 0 }, + [SOUND_MIXER_PHONEOUT] = { AC97_MIX_MONO, 5, 0, 0, 1, 7, 0, 0 }, + [SOUND_MIXER_BASS] = { AC97_MIX_TONE, 4, 8, 0, 0, 0, 1, 0 }, + [SOUND_MIXER_TREBLE] = { AC97_MIX_TONE, 4, 0, 0, 0, 0, 1, 0 }, + [SOUND_MIXER_PCM] = { AC97_MIX_PCM, 5, 0, 1, 1, 0, 0, 1 }, + [SOUND_MIXER_SPEAKER] = { AC97_MIX_BEEP, 4, 1, 0, 1, 0, 0, 0 }, + [SOUND_MIXER_LINE] = { AC97_MIX_LINE, 5, 0, 1, 1, 5, 0, 1 }, + [SOUND_MIXER_PHONEIN] = { AC97_MIX_PHONE, 5, 0, 0, 1, 8, 0, 0 }, + [SOUND_MIXER_MIC] = { AC97_MIX_MIC, 5, 0, 0, 1, 1, 0, 1 }, + [SOUND_MIXER_CD] = { AC97_MIX_CD, 5, 0, 1, 1, 2, 0, 1 }, + [SOUND_MIXER_LINE1] = { AC97_MIX_AUX, 5, 0, 1, 1, 4, 0, 0 }, + [SOUND_MIXER_VIDEO] = { AC97_MIX_VIDEO, 5, 0, 1, 1, 3, 0, 0 }, + [SOUND_MIXER_RECLEV] = { -AC97_MIX_RGAIN, 4, 0, 1, 1, 0, 0, 1 } }; -static const unsigned ac97mixdevs = - SOUND_MASK_VOLUME | - SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | - SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_LINE1 | - SOUND_MASK_VIDEO | SOUND_MASK_RECLEV; - -static const unsigned ac97recdevs = - SOUND_MASK_VOLUME | SOUND_MASK_LINE | SOUND_MASK_MIC | - SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_VIDEO; - static struct ac97_codecid ac97codecid[] = { { 0x414b4d00, 1, "Asahi Kasei AK4540 rev 0" }, { 0x414b4d01, 1, "Asahi Kasei AK4540 rev 1" }, @@ -213,6 +207,7 @@ static int ac97_setrecsrc(struct ac97_info *codec, int channel) { struct ac97mixtable_entry *e = &codec->mix[channel]; + if (e->recidx > 0) { int val = e->recidx - 1; val |= val << 8; @@ -226,7 +221,8 @@ static int ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned right) { struct ac97mixtable_entry *e = &codec->mix[channel]; - if (e->reg != 0) { + + if (e->reg && e->enable && e->bits) { int max, val, reg = (e->reg >= 0)? e->reg : -e->reg; if (!e->stereo) @@ -262,8 +258,10 @@ ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned val = AC97_MUTE; wrcd(codec, reg, val); return left | (right << 8); - } else + } else { + /* printf("ac97_setmixer: reg=%d, bits=%d, enable=%d\n", e->reg, e->bits, e->enable); */ return -1; + } } #if 0 @@ -293,7 +291,7 @@ ac97_getmixer(struct ac97_info *codec, int channel) static unsigned ac97_initmixer(struct ac97_info *codec) { - unsigned i, j; + unsigned i, j, k, old; u_int32_t id; for (i = 0; i < 32; i++) @@ -342,10 +340,18 @@ ac97_initmixer(struct ac97_info *codec) codec->extstat = rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; } - wrcd(codec, AC97_MIX_MASTER, 0x20); - if ((rdcd(codec, AC97_MIX_MASTER) & 0x20) == 0x20) - codec->mix[SOUND_MIXER_VOLUME].bits++; - wrcd(codec, AC97_MIX_MASTER, 0x00); + for (i = 0; i < 32; i++) { + if (codec->mix[i].reg > 0) { + old = rdcd(codec, codec->mix[i].reg); + wrcd(codec, codec->mix[i].reg, 0x3f); + j = rdcd(codec, codec->mix[i].reg); + wrcd(codec, codec->mix[i].reg, old); + codec->mix[i].enable = j? 1 : 0; + for (k = 1; j & (1 << k); k++); + codec->mix[i].bits = j? k - codec->mix[i].ofs : 0; + } + /* printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits); */ + } if (bootverbose) { device_printf(codec->dev, "ac97 codec id 0x%08x", id); @@ -402,12 +408,23 @@ static int ac97mix_init(snd_mixer *m) { struct ac97_info *codec = mix_getdevinfo(m); + u_int32_t i, mask; + if (codec == NULL) return -1; + if (ac97_initmixer(codec)) return -1; - mix_setdevs(m, ac97mixdevs | ((codec->caps & 4)? SOUND_MASK_BASS | SOUND_MASK_TREBLE : 0)); - mix_setrecdevs(m, ac97recdevs); + + mask = 0; + for (i = 0; i < 32; i++) + mask |= codec->mix[i].enable? 1 << i : 0; + mix_setdevs(m, mask); + + mask = 0; + for (i = 0; i < 32; i++) + mask |= codec->mix[i].recidx? 1 << i : 0; + mix_setrecdevs(m, mask); return 0; } @@ -415,6 +432,7 @@ static int ac97mix_uninit(snd_mixer *m) { struct ac97_info *codec = mix_getdevinfo(m); + if (codec == NULL) return -1; /* @@ -429,6 +447,7 @@ static int ac97mix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct ac97_info *codec = mix_getdevinfo(m); + if (codec == NULL) return -1; return ac97_setmixer(codec, dev, left, right); @@ -439,6 +458,7 @@ ac97mix_setrecsrc(snd_mixer *m, u_int32_t src) { int i; struct ac97_info *codec = mix_getdevinfo(m); + if (codec == NULL) return -1; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) |