dynamify- probe codec for supported channels

add channel mappings for mixer
This commit is contained in:
Cameron Grant 2000-09-17 23:51:00 +00:00
parent 7dfc932548
commit 341f16cc60

View File

@ -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++)