summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-06-16 08:03:43 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-06-16 08:03:43 +0000
commit60983f59ce5189fa98645c1f05bca017fb913e67 (patch)
tree386ed7e3ce5e9668396c739db2da5d9f224b0de9 /sys/dev
parent82199e5ddea2a3ad122d02302ce7374f38b5b2aa (diff)
- generic_mixer_default()
set the default pin direction depending on the pin's device, not color - ALC882: - add usingdac and usingadc - remove alc882_init_widget() because it has no effect any more - codec-specific mixer initialization for Realtek ALC882 - fix audio_format allocation for recording From kent NetBSD
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/azalia.c20
-rw-r--r--sys/dev/pci/azalia_codec.c312
2 files changed, 274 insertions, 58 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index 28eeed4b7f2..19a4df5300e 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.c,v 1.13 2006/06/16 06:00:46 brad Exp $ */
+/* $OpenBSD: azalia.c,v 1.14 2006/06/16 08:03:42 brad Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
@@ -1103,7 +1103,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
uint32_t bits_rates;
int prev_dac, prev_adc;
int pvariation, rvariation;
- int nbits, dac, chan, i, err;
+ int nbits, c, chan, i, err;
nid_t nid;
prev_dac = this->dacs.cur;
@@ -1150,7 +1150,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
return -1;
#endif
}
- rvariation = nbits;
+ rvariation = group->nconv * nbits;
if (this->formats != NULL)
free(this->formats, M_DEVBUF);
@@ -1170,18 +1170,22 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
nid = group->conv[0];
chan = 0;
bits_rates = this->w[nid].d.audio.bits_rates;
- for (dac = 0; dac < group->nconv; dac++) {
- for (chan = 0, i = 0; i <= dac; i++)
- chan += WIDGET_CHANNELS(&this->w[group->conv[dac]]);
+ for (c = 0; c < group->nconv; c++) {
+ for (chan = 0, i = 0; i <= c; i++)
+ chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
azalia_codec_add_bits(this, chan, bits_rates, AUMODE_PLAY);
}
/* register formats for recording */
group = &this->adcs.groups[this->adcs.cur];
nid = group->conv[0];
- chan = WIDGET_CHANNELS(&this->w[nid]);
+ chan = 0;
bits_rates = this->w[nid].d.audio.bits_rates;
- azalia_codec_add_bits(this, chan, bits_rates, AUMODE_RECORD);
+ for (c = 0; c < group->nconv; c++) {
+ for (chan = 0, i = 0; i <= c; i++)
+ chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
+ azalia_codec_add_bits(this, chan, bits_rates, AUMODE_RECORD);
+ }
err = azalia_create_encodings(this->formats, this->nformats,
&this->encodings);
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c
index 4c507e38fc9..a0a25e53d78 100644
--- a/sys/dev/pci/azalia_codec.c
+++ b/sys/dev/pci/azalia_codec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia_codec.c,v 1.12 2006/06/16 07:29:24 brad Exp $ */
+/* $OpenBSD: azalia_codec.c,v 1.13 2006/06/16 08:03:42 brad Exp $ */
/* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */
/*-
@@ -50,16 +50,19 @@ __KERNEL_RCSID(0, "$NetBSD: azalia_codec.c,v 1.3 2005/09/29 04:14:03 kent Exp $"
#include <dev/pci/azalia.h>
#define XNAME(co) (((struct device *)co->az)->dv_xname)
-#define AZ_CLASS_INPUT 0
-#define AZ_CLASS_OUTPUT 1
-#define AZ_CLASS_RECORD 2
-#define ENUM_OFFON .un.e={2, {{{AudioNoff}, 0}, {{AudioNon}, 1}}}
-#define ENUM_IO .un.e={2, {{{"input"}, 0}, {{"output"}, 1}}}
#ifdef MAX_VOLUME_255
# define MIXER_DELTA(n) (AUDIO_MAX_GAIN / (n))
#else
# define MIXER_DELTA(n) (1)
#endif
+#define AZ_CLASS_INPUT 0
+#define AZ_CLASS_OUTPUT 1
+#define AZ_CLASS_RECORD 2
+#define ENUM_OFFON .un.e={2, {{{AudioNoff}, 0}, {{AudioNon}, 1}}}
+#define ENUM_IO .un.e={2, {{{"input"}, 0}, {{"output"}, 1}}}
+#define AzaliaNfront "front"
+#define AzaliaNclfe "clfe"
+#define AzaliaNside "side"
int azalia_generic_codec_init_dacgroup(codec_t *);
@@ -89,7 +92,9 @@ int azalia_alc260_init_dacgroup(codec_t *);
int azalia_alc260_set_port(codec_t *, mixer_ctrl_t *);
int azalia_alc880_init_dacgroup(codec_t *);
int azalia_alc882_init_dacgroup(codec_t *);
-int azalia_alc882_init_widget(const codec_t *, widget_t *, nid_t);
+int azalia_alc882_mixer_init(codec_t *);
+int azalia_alc882_set_port(codec_t *, mixer_ctrl_t *);
+int azalia_alc882_get_port(codec_t *, mixer_ctrl_t *);
#if 0
int azalia_ad1981hd_init_widget(const codec_t *, widget_t *, nid_t);
#endif
@@ -124,7 +129,9 @@ azalia_codec_init_vtbl(codec_t *this)
case 0x10ec0882:
this->name = "Realtek ALC882";
this->init_dacgroup = azalia_alc882_init_dacgroup;
- this->init_widget = azalia_alc882_init_widget;
+ this->mixer_init = azalia_alc882_mixer_init;
+ this->get_port = azalia_alc882_get_port;
+ this->set_port = azalia_alc882_set_port;
break;
case 0x11d41981:
/* http://www.analog.com/en/prod/0,2877,AD1981HD,00.html */
@@ -775,9 +782,9 @@ azalia_generic_mixer_default(codec_t *this)
}
/*
- * for bidirectional pins,
- * green=front, orange=surround, gray=c/lfe, black=side --> output
- * blue=line-in, pink=mic-in --> input
+ * For bidirectional pins,
+ * Output: lineout, speaker, headphone, spdifout, digitalout, other
+ * Input: others
*/
DPRINTF(("%s: process bidirectional pins\n", __func__));
for (i = 0; i < this->nmixers; i++) {
@@ -788,11 +795,13 @@ azalia_generic_mixer_default(codec_t *this)
continue;
mc.dev = i;
mc.type = AUDIO_MIXER_ENUM;
- switch (this->w[m->nid].d.pin.color) {
- case CORB_CD_GREEN:
- case CORB_CD_ORANGE:
- case CORB_CD_GRAY:
- case CORB_CD_BLACK:
+ switch (this->w[m->nid].d.pin.device) {
+ case CORB_CD_LINEOUT:
+ case CORB_CD_SPEAKER:
+ case CORB_CD_HEADPHONE:
+ case CORB_CD_SPDIFOUT:
+ case CORB_CD_DIGITALOUT:
+ case CORB_CD_DEVICE_OTHER:
mc.un.ord = 1;
break;
default:
@@ -1614,14 +1623,187 @@ azalia_alc880_init_dacgroup(codec_t *this)
* Realtek ALC882
* ---------------------------------------------------------------- */
+static const mixer_item_t alc882_mixer_items[] = {
+ {{AZ_CLASS_INPUT, {AudioCinputs}, AUDIO_MIXER_CLASS, AZ_CLASS_INPUT, 0, 0}, 0},
+ {{AZ_CLASS_OUTPUT, {AudioCoutputs}, AUDIO_MIXER_CLASS, AZ_CLASS_OUTPUT, 0, 0}, 0},
+ {{AZ_CLASS_RECORD, {AudioCrecord}, AUDIO_MIXER_CLASS, AZ_CLASS_RECORD, 0, 0}, 0},
+
+ /* 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x14,0x15,0x16,0x17 */
+ {{0, {"mic1."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0b, MI_TARGET_INAMP(0)},
+ {{0, {"mic1"}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0b, MI_TARGET_INAMP(0)},
+ {{0, {"mic2."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0b, MI_TARGET_INAMP(1)},
+ {{0, {"mic2"}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0b, MI_TARGET_INAMP(1)},
+ {{0, {AudioNline"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0b, MI_TARGET_INAMP(2)},
+ {{0, {AudioNline}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0b, MI_TARGET_INAMP(2)},
+ {{0, {AudioNcd"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0b, MI_TARGET_INAMP(4)},
+ {{0, {AudioNcd}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0b, MI_TARGET_INAMP(4)},
+ {{0, {AudioNspeaker"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0b, MI_TARGET_INAMP(5)},
+ {{0, {AudioNspeaker}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{""}, 1, MIXER_DELTA(31)}}, 0x0b, MI_TARGET_INAMP(5)},
+
+ {{0, {AudioNmaster}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0c, MI_TARGET_OUTAMP},
+ {{0, {AudioNmaster"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x14, MI_TARGET_OUTAMP},
+ {{0, {AudioNmaster".boost"}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x14, MI_TARGET_PINBOOST},
+ {{0, {AudioNheadphone"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x1b, MI_TARGET_OUTAMP},
+ {{0, {AudioNheadphone".boost"}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x1b, MI_TARGET_PINBOOST},
+ {{0, {AzaliaNfront".dac.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0c, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNfront".mixer.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0c, MI_TARGET_INAMP(1)},
+
+ {{0, {AudioNsurround}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0d, MI_TARGET_OUTAMP},
+ {{0, {AudioNsurround"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x15, MI_TARGET_OUTAMP},
+ {{0, {AudioNsurround".boost"}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x15, MI_TARGET_PINBOOST},
+ {{0, {AudioNsurround".dac.mut"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0d, MI_TARGET_INAMP(0)},
+ {{0, {AudioNsurround".mixer.m"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0d, MI_TARGET_INAMP(1)},
+
+ {{0, {AzaliaNclfe}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0e, MI_TARGET_OUTAMP},
+ {{0, {AzaliaNclfe"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x16, MI_TARGET_OUTAMP},
+ {{0, {AzaliaNclfe".boost"}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x16, MI_TARGET_PINBOOST},
+ {{0, {AzaliaNclfe".dac.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0e, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNclfe".mixer.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0e, MI_TARGET_INAMP(1)},
+
+ {{0, {AzaliaNside}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x0f, MI_TARGET_OUTAMP},
+ {{0, {AzaliaNside"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x17, MI_TARGET_OUTAMP},
+ {{0, {AzaliaNside".boost"}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x17, MI_TARGET_PINBOOST},
+ {{0, {AzaliaNside".dac.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0f, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNside".mixer.mute"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x0f, MI_TARGET_INAMP(1)},
+
+ /* 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x14,0x15,0x16,0x17,0xb */
+#define ALC882_MIC1 0x001
+#define ALC882_MIC2 0x002
+#define ALC882_LINE 0x004
+#define ALC882_CD 0x010
+#define ALC882_BEEP 0x020
+#define ALC882_MIX 0x400
+#define ALC882_MASK 0x437
+ {{0, {AzaliaNfront"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD,
+ 0, 0, ENUM_OFFON}, 0x07, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNfront}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x07, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNfront"."AudioNsource}, AUDIO_MIXER_SET, AZ_CLASS_RECORD,
+ 0, 0, .un.s={6, {{{"mic1"}, ALC882_MIC1}, {{"mic2"}, ALC882_MIC2},
+ {{AudioNline}, ALC882_LINE}, {{AudioNcd}, ALC882_CD},
+ {{AudioNspeaker}, ALC882_BEEP},
+ {{AudioNmixerout}, ALC882_MIX}}}}, 0x24, -1},
+ {{0, {AudioNsurround"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD,
+ 0, 0, ENUM_OFFON}, 0x08, MI_TARGET_INAMP(0)},
+ {{0, {AudioNsurround}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x08, MI_TARGET_INAMP(0)},
+ {{0, {AudioNsurround"."AudioNsource}, AUDIO_MIXER_SET, AZ_CLASS_RECORD,
+ 0, 0, .un.s={6, {{{"mic1"}, ALC882_MIC1}, {{"mic2"}, ALC882_MIC2},
+ {{AudioNline}, ALC882_LINE}, {{AudioNcd}, ALC882_CD},
+ {{AudioNspeaker}, ALC882_BEEP},
+ {{AudioNmixerout}, ALC882_MIX}}}}, 0x23, -1},
+ {{0, {AzaliaNclfe"."AudioNmute}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD,
+ 0, 0, ENUM_OFFON}, 0x09, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNclfe}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{""}, 2, MIXER_DELTA(31)}}, 0x09, MI_TARGET_INAMP(0)},
+ {{0, {AzaliaNclfe"."AudioNsource}, AUDIO_MIXER_SET, AZ_CLASS_RECORD,
+ 0, 0, .un.s={6, {{{"mic1"}, ALC882_MIC1}, {{"mic2"}, ALC882_MIC2},
+ {{AudioNline}, ALC882_LINE}, {{AudioNcd}, ALC882_CD},
+ {{AudioNspeaker}, ALC882_BEEP},
+ {{AudioNmixerout}, ALC882_MIX}}}}, 0x22, -1},
+
+ {{0, {"usingdac"}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT, 0, 0,
+ .un.e={2, {{{"analog"}, 0}, {{"digital"}, 1}}}}, 0, MI_TARGET_DAC},
+ {{0, {"usingadc"}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD, 0, 0,
+ .un.e={2, {{{"analog"}, 0}, {{"digital"}, 1}}}}, 0, MI_TARGET_ADC},
+};
+
+int
+azalia_alc882_mixer_init(codec_t *this)
+{
+ mixer_ctrl_t mc;
+
+ this->nmixers = sizeof(alc882_mixer_items) / sizeof(mixer_item_t);
+ this->mixers = malloc(sizeof(mixer_item_t) * this->nmixers,
+ M_DEVBUF, M_NOWAIT);
+ if (this->mixers == NULL) {
+ printf("%s: out of memory in %s\n", XNAME(this), __func__);
+ return ENOMEM;
+ }
+ bzero(this->mixers, sizeof(mixer_item_t) * this->maxmixers);
+ memcpy(this->mixers, alc882_mixer_items,
+ sizeof(mixer_item_t) * this->nmixers);
+ azalia_generic_mixer_fix_indexes(this);
+ azalia_generic_mixer_default(this);
+
+ mc.dev = -1;
+ mc.type = AUDIO_MIXER_ENUM;
+ mc.un.ord = 1; /* pindir: output */
+ azalia_generic_mixer_set(this, 0x14, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x1b, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x15, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x16, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x17, MI_TARGET_PINDIR, &mc);
+ mc.un.ord = 0; /* [0] 0x0c */
+ azalia_generic_mixer_set(this, 0x14, MI_TARGET_CONNLIST, &mc);
+ azalia_generic_mixer_set(this, 0x1b, MI_TARGET_CONNLIST, &mc);
+ mc.un.ord = 1; /* [1] 0x0d */
+ azalia_generic_mixer_set(this, 0x15, MI_TARGET_CONNLIST, &mc);
+ mc.un.ord = 2; /* [2] 0x0e */
+ azalia_generic_mixer_set(this, 0x16, MI_TARGET_CONNLIST, &mc);
+ mc.un.ord = 2; /* [3] 0x0fb */
+ azalia_generic_mixer_set(this, 0x17, MI_TARGET_CONNLIST, &mc);
+
+ mc.un.ord = 0; /* pindir: input */
+ azalia_generic_mixer_set(this, 0x18, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x19, MI_TARGET_PINDIR, &mc);
+ azalia_generic_mixer_set(this, 0x1a, MI_TARGET_PINDIR, &mc);
+ /* XXX: inamp for 18/19/1a */
+
+ mc.un.ord = 0; /* unmute */
+ azalia_generic_mixer_set(this, 0x24, MI_TARGET_INAMP(0), &mc);
+ azalia_generic_mixer_set(this, 0x23, MI_TARGET_INAMP(1), &mc);
+ azalia_generic_mixer_set(this, 0x22, MI_TARGET_INAMP(2), &mc);
+ return 0;
+}
+
int
azalia_alc882_init_dacgroup(codec_t *this)
{
+#if 0
static const convgroupset_t dacs = {
-1, 3,
{{4, {0x02, 0x03, 0x04, 0x05}}, /* analog 8ch */
{1, {0x06}}, /* digital */
{1, {0x25}}}}; /* another analog */
+#else
+ static const convgroupset_t dacs = {
+ -1, 2,
+ {{4, {0x02, 0x03, 0x04, 0x05}}, /* analog 8ch */
+ {1, {0x06}}}}; /* digital */
+#endif
static const convgroupset_t adcs = {
-1, 2,
{{3, {0x07, 0x08, 0x09}}, /* analog 6ch */
@@ -1633,42 +1815,72 @@ azalia_alc882_init_dacgroup(codec_t *this)
}
int
-azalia_alc882_init_widget(const codec_t *this, widget_t *w, nid_t nid)
+azalia_alc882_set_port(codec_t *this, mixer_ctrl_t *mc)
{
- switch (nid) {
- case 0x14:
- strlcpy(w->name, "green", sizeof(w->name));
- break;
- case 0x15:
- strlcpy(w->name, "gray", sizeof(w->name));
- break;
- case 0x16:
- strlcpy(w->name, "orange", sizeof(w->name));
- break;
- case 0x17:
- strlcpy(w->name, "black", sizeof(w->name));
- break;
- case 0x18:
- strlcpy(w->name, "mic1", sizeof(w->name));
- break;
- case 0x19:
- strlcpy(w->name, "mic2", sizeof(w->name));
- break;
- case 0x1a:
- strlcpy(w->name, AudioNline, sizeof(w->name));
- break;
- case 0x1b:
- /* AudioNheadphone is too long */
- strlcpy(w->name, "hp", sizeof(w->name));
- break;
- case 0x1c:
- strlcpy(w->name, AudioNcd, sizeof(w->name));
- break;
- case 0x1d:
- strlcpy(w->name, AudioNspeaker, sizeof(w->name));
- break;
+ const mixer_item_t *m;
+ mixer_ctrl_t mc2;
+ uint32_t mask, bit;
+ int i, err;
+
+ if (mc->dev >= this->nmixers)
+ return ENXIO;
+ m = &this->mixers[mc->dev];
+ if (mc->type != m->devinfo.type)
+ return EINVAL;
+ if (mc->type == AUDIO_MIXER_CLASS)
+ return 0;
+ if ((m->nid == 0x22 || m->nid == 0x23 || m->nid == 0x24)
+ && m->target == -1) {
+ DPRINTF(("%s: hook for record.*.source\n", __func__));
+ mc2.dev = -1;
+ mc2.type = AUDIO_MIXER_ENUM;
+ bit = 1;
+ mask = mc->un.mask & ALC882_MASK;
+ for (i = 0; i < this->w[m->nid].nconnections && i < 32; i++) {
+ mc2.un.ord = (mask & bit) ? 0 : 1;
+ err = azalia_generic_mixer_set(this, m->nid,
+ MI_TARGET_INAMP(i), &mc2);
+ if (err)
+ return err;
+ bit = bit << 1;
+ }
+ return 0;
}
- return 0;
+ return azalia_generic_mixer_set(this, m->nid, m->target, mc);
+}
+
+int
+azalia_alc882_get_port(codec_t *this, mixer_ctrl_t *mc)
+{
+ const mixer_item_t *m;
+ uint32_t mask, bit, result;
+ int i, err;
+
+ if (mc->dev >= this->nmixers)
+ return ENXIO;
+ m = &this->mixers[mc->dev];
+ mc->type = m->devinfo.type;
+ if (mc->type == AUDIO_MIXER_CLASS)
+ return 0;
+ if ((m->nid == 0x22 || m->nid == 0x23 || m->nid == 0x24)
+ && m->target == -1) {
+ DPRINTF(("%s: hook for record.*.source\n", __func__));
+ mask = 0;
+ bit = 1;
+ for (i = 0; i < this->w[m->nid].nconnections && i < 32; i++) {
+ err = this->comresp(this, m->nid, CORB_GET_AMPLIFIER_GAIN_MUTE,
+ CORB_GAGM_INPUT | CORB_GAGM_LEFT |
+ i, &result);
+ if (err)
+ return err;
+ if ((result & CORB_GAGM_MUTE) == 0)
+ mask |= bit;
+ bit = bit << 1;
+ }
+ mc->un.mask = mask & ALC882_MASK;
+ return 0;
+ }
+ return azalia_generic_mixer_get(this, m->nid, m->target, mc);
}
/* ----------------------------------------------------------------