summaryrefslogtreecommitdiff
path: root/sys/dev/pci/azalia_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/azalia_codec.c')
-rw-r--r--sys/dev/pci/azalia_codec.c184
1 files changed, 183 insertions, 1 deletions
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c
index 240737f145c..67007d0e8e4 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.21 2007/06/19 00:39:33 deanna Exp $ */
+/* $OpenBSD: azalia_codec.c,v 1.22 2007/07/07 16:33:38 deanna Exp $ */
/* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */
/*-
@@ -95,6 +95,8 @@ int azalia_alc882_init_dacgroup(codec_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 *);
+int azalia_alc883_init_dacgroup(codec_t *);
+int azalia_alc883_mixer_init(codec_t *);
int azalia_ad1981hd_init_widget(const codec_t *, widget_t *, nid_t);
int azalia_ad1981hd_mixer_init(codec_t *);
int azalia_cmi9880_init_dacgroup(codec_t *);
@@ -139,6 +141,14 @@ azalia_codec_init_vtbl(codec_t *this)
this->get_port = azalia_alc882_get_port;
this->set_port = azalia_alc882_set_port;
break;
+ case 0x10ec0883:
+ /* ftp://209.216.61.149/pc/audio/ALC883_DataSheet_1.3.pdf */
+ this->name = "Realtek ALC883";
+ this->init_dacgroup = azalia_alc883_init_dacgroup;
+ this->mixer_init = azalia_alc883_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 */
this->name = "Analog Devices AD1981HD";
@@ -1947,6 +1957,178 @@ azalia_alc882_get_port(codec_t *this, mixer_ctrl_t *mc)
}
/* ----------------------------------------------------------------
+ * Realtek ALC883
+ * ALC882 without adc07 and mix24.
+ * ---------------------------------------------------------------- */
+
+int
+azalia_alc883_init_dacgroup(codec_t *this)
+{
+ static const convgroupset_t dacs = {
+ -1, 2,
+ {{4, {0x02, 0x03, 0x04, 0x05}}, /* analog 8ch */
+ {1, {0x06}}}}; /* digital */
+
+ static const convgroupset_t adcs = {
+ -1, 2,
+ {{2, {0x08, 0x09}}, /* analog 4ch */
+ {1, {0x0a}}}}; /* digital */
+
+ this->dacs = dacs;
+ this->adcs = adcs;
+ return 0;
+}
+
+static const mixer_item_t alc883_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)},
+
+ {{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_alc883_mixer_init(codec_t *this)
+{
+ mixer_ctrl_t mc;
+
+ this->nmixers = sizeof(alc883_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, alc883_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, 0x23, MI_TARGET_INAMP(1), &mc);
+ azalia_generic_mixer_set(this, 0x22, MI_TARGET_INAMP(2), &mc);
+ return 0;
+}
+
+
+/* ----------------------------------------------------------------
* Analog Devices AD1981HD
* ---------------------------------------------------------------- */