Subject: ad1983 azalia
To: None <tech-kern@netbsd.org>
From: Mark Davies <mark@mcs.vuw.ac.nz>
List: tech-kern
Date: 08/15/2007 19:46:52
--Boundary-00=_s9qwGAl1oG5BrPg
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Having now got the Dell Optiplex 745 running with azalia defined (but
without ehci) I'd like to have it work so I've made a first stab at
azalia_codec.c support for the AD1983. Its based on the existing
AD1981HD support and the differences as inferred from
http://www.analog.com/en/prod/0,2877,AD{1981HD,1983},00.html.
It works in that I can get audio out from various KDE apps and can
adjust the line-out, headphones and master volumes but not sure about
the input side of things and inamp or the names/class for some of the
items and there is no headphone jack detection (and probably other
things I haven't thought about).
Attached is the dmesg output with AZALIA_DEBUG defined, mixerctl -av
output and my current azalia_codec.c diff.
cheers
mark
--Boundary-00=_s9qwGAl1oG5BrPg
Content-Type: text/plain;
charset="us-ascii";
name="dmesg-azalia.out"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="dmesg-azalia.out"
azalia0 at pci0 dev 27 function 0: Generic High Definition Audio Controller
azalia0: interrupting at ioapic0 pin 16 (irq 11)
azalia0: host: Intel 82801H High Definition Audio Controller (rev. 2)
azalia0: host: High Definition Audio rev. 1.0
azalia0: host: 4 output, 4 input, and 0 bidi streams
azalia_attach: resetting
azalia_attach: reset counter = 5000
azalia_attach: reset counter = 4984
azalia0: found a codec at #0
azalia_init_corb: CORB allocation succeeded.
azalia_init_corb: CORBWP=0; size=256
azalia_init_rirb: RIRB allocation succeeded.
azalia_init_rirb: RIRBRP=0, size=256
azalia0: information of codec[0] follows:
azalia_codec_init_vtbl: vid=11d41983 subid=01da1028
azalia0: codec[0]: Analog Devices AD1983 (rev. 4.0)
azalia0: codec[0]: High Definition Audio rev. 1.0
azalia_codec_init: nidstart=1 #functions=1
azalia_codec_init: FTYPE result = 0x00000001
azalia_codec_init: There are 20 widgets in the audio function.
azalia0: encodings=1<PCM>
azalia0: PCM formats=e007f<24bit,20bit,16bit,48kHz,44.1kHz,32kHz,22.05kHz,16kHz,11.025kHz,8kHz>
azalia0: inamp: mute=0 size=0 steps=0 offset=0
azalia0: outamp: mute=1 size=5 steps=63 offset=61
azalia0: dac02 wcap=30311<DIGITAL,CONNLIST,FORMATOV,STEREO>
azalia0: encodings=5<AC3,PCM>
azalia0: PCM formats=20060<16bit,48kHz,44.1kHz>
azalia0: connections=0x1,0x4; selected=0x1
azalia0: dac03 wcap=441<POWER,PROC,STEREO>
azalia0: encodings=1<PCM>
azalia0: PCM formats=e007f<24bit,20bit,16bit,48kHz,44.1kHz,32kHz,22.05kHz,16kHz,11.025kHz,8kHz>
azalia0: adc04 wcap=100501<POWER,CONNLIST,STEREO>
azalia0: encodings=1<PCM>
azalia0: PCM formats=e007f<24bit,20bit,16bit,48kHz,44.1kHz,32kHz,22.05kHz,16kHz,11.025kHz,8kHz>
azalia0: connections=0x14; selected=0x14
azalia0: green05 wcap=400185<CONNLIST,UNSOL,OUTAMP,STEREO>
azalia0: pin config; device=line-out color=green assoc=1 seq=0 cap=17<OUTPUT,PRESENCE,TRIGGER,IMPEDANCE>
azalia0: connections=0x3,0xe; selected=0x3
azalia0: outamp: mute=1 size=5 steps=63 offset=61
azalia0: black06 wcap=400185<CONNLIST,UNSOL,OUTAMP,STEREO>
azalia0: pin config; device=headphones color=black assoc=1 seq=15 cap=1f<OUTPUT,HEADPHONE,PRESENCE,TRIGGER,IMPEDANCE>
azalia0: connections=0x3,0xe; selected=0x3
azalia0: outamp: mute=1 size=5 steps=63 offset=61
azalia0: unknown07 wcap=400104<CONNLIST,OUTAMP>
azalia0: pin config; device=speaker color=unknown assoc=15 seq=0 cap=10<OUTPUT>
azalia0: connections=0xf; selected=0xf
azalia0: outamp: mute=1 size=5 steps=63 offset=61
azalia0: black08 wcap=400081<UNSOL,STEREO>
azalia0: pin config; device=mic color=black assoc=2 seq=0 cap=1727<INPUT,PRESENCE,TRIGGER,IMPEDANCE>
azalia0: blue09 wcap=400081<UNSOL,STEREO>
azalia0: pin config; device=line-in color=blue assoc=2 seq=14 cap=1727<INPUT,PRESENCE,TRIGGER,IMPEDANCE>
azalia0: black0a wcap=400301<DIGITAL,CONNLIST,STEREO>
azalia0: pin config; device=SPDIF-out color=black assoc=15 seq=0 cap=10<OUTPUT>
azalia0: connections=0x2; selected=0x2
azalia0: sel0b wcap=300101<CONNLIST,STEREO>
azalia0: connections=0x3,0xc,0xd,0xe; selected=0x3
azalia0: sel0c wcap=30010d<CONNLIST,AMPOV,OUTAMP,STEREO>
azalia0: connections=0x8,0x9; selected=0x8
azalia0: outamp: mute=0 size=39 steps=3 offset=0
azalia0: sel0d wcap=300101<CONNLIST,STEREO>
azalia0: connections=0x9,0x8; selected=0x9
azalia0: mix0e wcap=200101<CONNLIST,STEREO>
azalia0: connections=0x11,0x12,0x13; selected=0x11
azalia0: mix0f wcap=200100<CONNLIST>
azalia0: connections=0xb; selected=0xb
azalia0: beep10 wcap=70000c<AMPOV,OUTAMP>
azalia0: outamp: mute=1 size=11 steps=15 offset=15
azalia0: sel11 wcap=30010d<CONNLIST,AMPOV,OUTAMP,STEREO>
azalia0: connections=0x3; selected=0x3
azalia0: outamp: mute=1 size=5 steps=31 offset=23
azalia0: sel12 wcap=30010d<CONNLIST,AMPOV,OUTAMP,STEREO>
azalia0: connections=0xc; selected=0xc
azalia0: outamp: mute=1 size=5 steps=31 offset=23
azalia0: sel13 wcap=30010d<CONNLIST,AMPOV,OUTAMP,STEREO>
azalia0: connections=0xd; selected=0xd
azalia0: outamp: mute=1 size=5 steps=31 offset=23
azalia0: sel14 wcap=30010d<CONNLIST,AMPOV,OUTAMP,STEREO>
azalia0: connections=0xc,0xd,0xe,0xf; selected=0xc
azalia0: outamp: mute=1 size=5 steps=15 offset=0
azalia0: pow15 wcap=500500<POWER,CONNLIST>
azalia0: connections=0x5,0x89,0xb,0x94; selected=0x5
azalia_codec_init: dacgroup[0]: 03
azalia_codec_init: dacgroup[1]: 02
azalia0: playback: max channels=2, encodings=1<PCM>
azalia0: playback: PCM formats=e007f<24bit,20bit,16bit,48kHz,44.1kHz,32kHz,22.05kHz,16kHz,11.025kHz,8kHz>
azalia0: recording: max channels=2, encodings=1<PCM>
azalia0: recording: PCM formats=e007f<24bit,20bit,16bit,48kHz,44.1kHz,32kHz,22.05kHz,16kHz,11.025kHz,8kHz>
azalia0: using the #0 codec
audio0 at azalia0: full duplex, independent
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_open: flags=0x7
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 1536
azalia_round_blocksize: resultant block size = 8704
azalia_round_blocksize: resultant block size = 8704
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_trigger_output: this=0xc3110000 start=0xcccd5000 end=0xccce5000 blk=4096 {enc=6 2ch 16/16bit 44100Hz}
azalia_codec_connect_stream: fmt=0x4011 number=1
azalia_codec_connect_stream: leave with 0
azalia_halt_output
azalia_close
azalia_open: flags=0x7
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_trigger_output: this=0xc3110000 start=0xcccd5000 end=0xccce5000 blk=4096 {enc=6 2ch 16/16bit 44100Hz}
azalia_codec_connect_stream: fmt=0x4011 number=1
azalia_codec_connect_stream: leave with 0
azalia_halt_output
azalia_close
azalia_open: flags=0x7
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_round_blocksize: resultant block size = 4096
azalia_trigger_output: this=0xc3110000 start=0xcccd5000 end=0xccce5000 blk=4096 {enc=6 2ch 16/16bit 44100Hz}
azalia_codec_connect_stream: fmt=0x4011 number=1
azalia_codec_connect_stream: leave with 0
--Boundary-00=_s9qwGAl1oG5BrPg
Content-Type: text/plain;
charset="us-ascii";
name="mixerctl.out"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="mixerctl.out"
outputs.spdif.source=os [ os adc ]
outputs.lineout.source=dac [ dac mixerout ]
outputs.lineout.mute=off [ off on ]
outputs.lineout=125,125 delta=17
outputs.lineout.dir=input [ input output ]
outputs.lineout.boost=off [ off on ]
outputs.headphones.src=dac [ dac mixerout ]
outputs.headphones.mute=off [ off on ]
outputs.headphones=255,255 delta=63
outputs.headphones.boost=on [ off on ]
outputs.mono.mute=off [ off on ]
outputs.mono=125 delta=63
outputs.mono.source=dac [ dac mic linein mixerout ]
inputs.beep.mute=off [ off on ]
inputs.beep=119 delta=15
inputs.dac.mute=off [ off on ]
inputs.dac=255,255 delta=31
inputs.mic.mute=off [ off on ]
inputs.mic=115,115 delta=31
inputs.linein.mute=off [ off on ]
inputs.linein=123,123 delta=31
record.source=mic [ mic linein mixerout mono ]
record.mute=off [ off on ]
record.master=153,153 delta=15
playback.mode=analog [ analog spdif ]
--Boundary-00=_s9qwGAl1oG5BrPg
Content-Type: text/x-diff;
charset="us-ascii";
name="azalia_codec.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="azalia_codec.diff"
Index: azalia_codec.c
===================================================================
RCS file: /src/cvs/netbsd/src/sys/dev/pci/azalia_codec.c,v
retrieving revision 1.42
diff -u -r1.42 azalia_codec.c
--- azalia_codec.c 13 May 2007 03:28:19 -0000 1.42
+++ azalia_codec.c 14 Aug 2007 02:48:28 -0000
@@ -124,6 +124,7 @@
static int alc888_init_dacgroup(codec_t *);
static int ad1981hd_init_widget(const codec_t *, widget_t *, nid_t);
static int ad1981hd_mixer_init(codec_t *);
+static int ad1983_mixer_init(codec_t *);
static int ad1988_init_dacgroup(codec_t *);
static int cmi9880_init_dacgroup(codec_t *);
static int cmi9880_mixer_init(codec_t *);
@@ -207,6 +208,7 @@
case 0x11d41983:
/* http://www.analog.com/en/prod/0,2877,AD1983,00.html */
this->name = "Analog Devices AD1983";
+ this->mixer_init = ad1983_mixer_init;
break;
case 0x11d41988:
/* http://www.analog.com/en/prod/0,2877,AD1988A,00.html */
@@ -2721,6 +2723,120 @@
}
/* ----------------------------------------------------------------
+ * Analog Devices AD1983
+ * ---------------------------------------------------------------- */
+
+static const mixer_item_t ad1983_mixer_items[] = {
+ AZ_MIXER_CLASSES,
+
+ {{0, {AzaliaNdigital "." AudioNsource, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, .un.e={2, {{{"os", 0}, 0}, {{"adc", 0}, 1}}}}, 0x02, MI_TARGET_CONNLIST},
+
+ {{0, {"lineout." AudioNsource, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, .un.e={2, {{{AudioNdac, 0}, 0}, {{AudioNmixerout, 0}, 1}}}},
+ 0x05, MI_TARGET_CONNLIST},
+ {{0, {"lineout." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x05, MI_TARGET_OUTAMP},
+ {{0, {"lineout", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(15)}}, 0x05, MI_TARGET_OUTAMP},
+#if 0
+ {{0, {"lineout", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(3)}}, 0x05, MI_TARGET_INAMP(0)},
+#endif
+ {{0, {"lineout.dir", 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_IO}, 0x05, MI_TARGET_PINDIR},
+ {{0, {"lineout.boost", 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x05, MI_TARGET_PINBOOST},
+
+
+ {{0, {AudioNheadphone ".src", 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, .un.e={2, {{{AudioNdac, 0}, 0}, {{AudioNmixerout, 0}, 1}}}},
+ 0x06, MI_TARGET_CONNLIST},
+ {{0, {AudioNheadphone "." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x06, MI_TARGET_OUTAMP},
+ {{0, {AudioNheadphone, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(4)}}, 0x06, MI_TARGET_OUTAMP},
+ {{0, {AudioNheadphone ".boost", 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x06, MI_TARGET_PINBOOST},
+
+ {{0, {AudioNmono "." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x07, MI_TARGET_OUTAMP},
+ {{0, {AudioNmono, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{"", 0}, 1, MIXER_DELTA(4)}}, 0x07, MI_TARGET_OUTAMP},
+
+#if 0
+ {{0, {AudioNmicrophone, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(3)}}, 0x08, MI_TARGET_INAMP(0)},
+#endif
+
+#if 0
+ {{0, {"linein." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_OFFON}, 0x09, MI_TARGET_OUTAMP},
+ {{0, {"linein", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_OUTPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(63)}}, 0x09, MI_TARGET_OUTAMP},
+ {{0, {"linein", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(3)}}, 0x09, MI_TARGET_INAMP(0)},
+ {{0, {"linein.dir", 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, ENUM_IO}, 0x09, MI_TARGET_PINDIR},
+#endif
+
+ {{0, {AudioNmono "." AudioNsource, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_OUTPUT,
+ 0, 0, .un.e={4, {{{AudioNdac, 0}, 0}, {{AudioNmicrophone, 0}, 1},
+ {{"linein", 0}, 2}, {{AudioNmixerout, 0}, 3}}}},
+ 0x0b, MI_TARGET_CONNLIST},
+
+ {{0, {"beep." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x10, MI_TARGET_OUTAMP},
+ {{0, {"beep", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{"", 0}, 1, MIXER_DELTA(17)}}, 0x10, MI_TARGET_OUTAMP},
+
+ {{0, {AudioNdac "." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x11, MI_TARGET_OUTAMP},
+ {{0, {AudioNdac, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(8)}}, 0x11, MI_TARGET_OUTAMP},
+
+ {{0, {AudioNmicrophone "." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x12, MI_TARGET_OUTAMP},
+ {{0, {AudioNmicrophone, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(8)}}, 0x12, MI_TARGET_OUTAMP},
+
+ {{0, {"linein." AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_INPUT,
+ 0, 0, ENUM_OFFON}, 0x13, MI_TARGET_OUTAMP},
+ {{0, {"linein", 0}, AUDIO_MIXER_VALUE, AZ_CLASS_INPUT,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(8)}}, 0x13, MI_TARGET_OUTAMP},
+
+ {{0, {AudioNsource, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD,
+ 0, 0, .un.e={4, {{{AudioNmicrophone, 0}, 0}, {{"linein", 0}, 1},
+ {{AudioNmixerout, 0}, 2}, {{AudioNmono, 0}, 3}}}},
+ 0x14, MI_TARGET_CONNLIST},
+ {{0, {AudioNmute, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_RECORD,
+ 0, 0, ENUM_OFFON}, 0x14, MI_TARGET_OUTAMP},
+ {{0, {AudioNmaster, 0}, AUDIO_MIXER_VALUE, AZ_CLASS_RECORD,
+ 0, 0, .un.v={{"", 0}, 2, MIXER_DELTA(17)}}, 0x14, MI_TARGET_OUTAMP},
+
+ {{0, {AudioNmode, 0}, AUDIO_MIXER_ENUM, AZ_CLASS_PLAYBACK, 0, 0,
+ .un.e={2, {{{"analog", 0}, 0}, {{AzaliaNdigital, 0}, 1}}}}, 0, MI_TARGET_DAC},
+};
+
+static int
+ad1983_mixer_init(codec_t *this)
+{
+ this->nmixers = sizeof(ad1983_mixer_items) / sizeof(mixer_item_t);
+ this->mixers = malloc(sizeof(mixer_item_t) * this->nmixers,
+ M_DEVBUF, M_ZERO | M_NOWAIT);
+ if (this->mixers == NULL) {
+ aprint_error("%s: out of memory in %s\n", XNAME(this), __func__);
+ return ENOMEM;
+ }
+ memcpy(this->mixers, ad1983_mixer_items,
+ sizeof(mixer_item_t) * this->nmixers);
+ generic_mixer_fix_indexes(this);
+ generic_mixer_default(this);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------
* Analog Devices AD1988A/AD1988B
* ---------------------------------------------------------------- */
--Boundary-00=_s9qwGAl1oG5BrPg--