xref: /openbsd-src/sys/dev/ic/ac97.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: ac97.c,v 1.70 2008/10/23 21:50:01 jakemsr Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Constantine Sapuntzakis
5  *
6  * Author:	Constantine Sapuntzakis <csapuntz@stanford.edu>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote
17  *    products derived from this software without specific prior written
18  *    permission.
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
29  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30  * DAMAGE.  */
31 
32 /* Partially inspired by FreeBSD's sys/dev/pcm/ac97.c. It came with
33    the following copyright */
34 
35 /*
36  * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  *
60  * $FreeBSD$
61  */
62 
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/malloc.h>
67 #include <sys/device.h>
68 
69 #include <sys/audioio.h>
70 #include <dev/audio_if.h>
71 #include <dev/ic/ac97.h>
72 
73 
74 /* default parameters; supported by all ac97 codecs */
75 const struct audio_params ac97_audio_default = {
76 	48000,		/* sample_rate */
77 	AUDIO_ENCODING_SLINEAR_LE, /* encoding */
78 	16,		/* precision */
79 	2,		/* channels */
80 	NULL,		/* sw_code */
81 	1		/* factor */
82 };
83 
84 const struct audio_mixer_enum ac97_on_off = {
85 	2,
86 	{ { { AudioNoff } , 0 },
87 	{ { AudioNon }  , 1 } }
88 };
89 
90 const struct audio_mixer_enum ac97_mic_select = {
91 	2,
92 	{ { { AudioNmicrophone "0" }, 0 },
93 	{ { AudioNmicrophone "1" }, 1 } }
94 };
95 
96 const struct audio_mixer_enum ac97_mono_select = {
97 	2,
98 	{ { { AudioNmixerout }, 0 },
99 	{ { AudioNmicrophone }, 1 } }
100 };
101 
102 const struct audio_mixer_enum ac97_source = {
103 	8,
104 	{ { { AudioNmicrophone } , 0 },
105 	{ { AudioNcd }, 1 },
106 	{ { "video" }, 2 },
107 	{ { AudioNaux }, 3 },
108 	{ { AudioNline }, 4 },
109 	{ { AudioNmixerout }, 5 },
110 	{ { AudioNmixerout AudioNmono }, 6 },
111 	{ { "phone" }, 7 }}
112 };
113 
114 /*
115  * Due to different values for each source that uses these structures,
116  * the ac97_query_devinfo function sets delta in mixer_devinfo_t using
117  * ac97_source_info.bits.
118  */
119 const struct audio_mixer_value ac97_volume_stereo = {
120 	{ AudioNvolume },
121 	2
122 };
123 
124 const struct audio_mixer_value ac97_volume_mono = {
125 	{ AudioNvolume },
126 	1
127 };
128 
129 #define AudioNspdif	"spdif"
130 
131 #define WRAP(a)  &a, sizeof(a)
132 
133 const struct ac97_source_info {
134 	char *class;
135 	char *device;
136 	char *qualifier;
137 	int  type;
138 
139 	const void *info;
140 	int16_t info_size;
141 
142 	u_int8_t  reg;
143 	u_int16_t default_value;
144 	u_int8_t  bits:3;
145 	u_int8_t  ofs:4;
146 	u_int8_t  mute:1;
147 	u_int8_t  polarity:1;		/* Does 0 == MAX or MIN */
148 	enum {
149 		CHECK_NONE = 0,
150 		CHECK_SURROUND,
151 		CHECK_CENTER,
152 		CHECK_LFE,
153 		CHECK_HEADPHONES,
154 		CHECK_TONE,
155 		CHECK_MIC,
156 		CHECK_LOUDNESS,
157 		CHECK_3D,
158 		CHECK_SPDIF
159 	} req_feature;
160 
161 	int16_t  prev;
162 	int16_t  next;
163 	int16_t  mixer_class;
164 } source_info[] = {
165 	{ AudioCinputs,		NULL,		NULL,
166 	  AUDIO_MIXER_CLASS, },
167 	{ AudioCoutputs,	NULL,		NULL,
168 	  AUDIO_MIXER_CLASS, },
169 	{ AudioCrecord,		NULL,		NULL,
170 	  AUDIO_MIXER_CLASS, },
171 	/* Stereo master volume*/
172 	{ AudioCoutputs,	AudioNmaster,	NULL,
173 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
174 	  AC97_REG_MASTER_VOLUME, 0x8000, 5, 0, 1,
175 	},
176 	/* Mono volume */
177 	{ AudioCoutputs,	AudioNmono,	NULL,
178 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
179 	  AC97_REG_MASTER_VOLUME_MONO, 0x8000, 6, 0, 1,
180 	},
181 	{ AudioCoutputs,	AudioNmono,	AudioNsource,
182 	  AUDIO_MIXER_ENUM, WRAP(ac97_mono_select),
183 	  AC97_REG_GP, 0x0000, 1, 9, 0,
184 	},
185 	/* Headphone volume */
186 	{ AudioCoutputs,	AudioNheadphone, NULL,
187 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
188 	  AC97_REG_HEADPHONE_VOLUME, 0x8000, 6, 0, 1, 0, CHECK_HEADPHONES
189 	},
190 	/* Surround volume - logic hard coded for mute */
191 	{ AudioCoutputs,	AudioNsurround,	NULL,
192 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
193 	  AC97_REG_SURR_MASTER, 0x8080, 5, 0, 1, 0, CHECK_SURROUND
194 	},
195 	/* Center volume*/
196 	{ AudioCoutputs,	AudioNcenter,	NULL,
197 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
198 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 0, 0, 0, CHECK_CENTER
199 	},
200 	{ AudioCoutputs,	AudioNcenter,	AudioNmute,
201 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
202 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 7, 0, 0, CHECK_CENTER
203 	},
204 	/* LFE volume*/
205 	{ AudioCoutputs,	AudioNlfe,	NULL,
206 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
207 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 8, 0, 0, CHECK_LFE
208 	},
209 	{ AudioCoutputs,	AudioNlfe,	AudioNmute,
210 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
211 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 15, 0, 0, CHECK_LFE
212 	},
213 	/* Tone */
214 	{ AudioCoutputs,	"tone",	NULL,
215 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
216 	  AC97_REG_MASTER_TONE, 0x0f0f, 4, 0, 0, 0, CHECK_TONE
217 	},
218 	/* PC Beep Volume */
219 	{ AudioCinputs,		AudioNspeaker,	NULL,
220 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
221 	  AC97_REG_PCBEEP_VOLUME, 0x0000, 4, 1, 1,
222 	},
223 
224 	/* Phone */
225 	{ AudioCinputs,		"phone",	NULL,
226 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
227 	  AC97_REG_PHONE_VOLUME, 0x8008, 5, 0, 1,
228 	},
229 	/* Mic Volume */
230 	{ AudioCinputs,		AudioNmicrophone, NULL,
231 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
232 	  AC97_REG_MIC_VOLUME, 0x8008, 5, 0, 1,
233 	},
234 	{ AudioCinputs,		AudioNmicrophone, AudioNpreamp,
235 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
236 	  AC97_REG_MIC_VOLUME, 0x8008, 1, 6, 0,
237 	},
238 	{ AudioCinputs,		AudioNmicrophone, AudioNsource,
239 	  AUDIO_MIXER_ENUM, WRAP(ac97_mic_select),
240 	  AC97_REG_GP, 0x0000, 1, 8, 0,
241 	},
242 	/* Line in Volume */
243 	{ AudioCinputs,		AudioNline,	NULL,
244 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
245 	  AC97_REG_LINEIN_VOLUME, 0x8808, 5, 0, 1,
246 	},
247 	/* CD Volume */
248 	{ AudioCinputs,		AudioNcd,	NULL,
249 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
250 	  AC97_REG_CD_VOLUME, 0x8808, 5, 0, 1,
251 	},
252 	/* Video Volume */
253 	{ AudioCinputs,		AudioNvideo,	NULL,
254 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
255 	  AC97_REG_VIDEO_VOLUME, 0x8808, 5, 0, 1,
256 	},
257 	/* AUX volume */
258 	{ AudioCinputs,		AudioNaux,	NULL,
259 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
260 	  AC97_REG_AUX_VOLUME, 0x8808, 5, 0, 1,
261 	},
262 	/* PCM out volume */
263 	{ AudioCinputs,		AudioNdac,	NULL,
264 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
265 	  AC97_REG_PCMOUT_VOLUME, 0x8808, 5, 0, 1,
266 	},
267 	/* Record Source - some logic for this is hard coded - see below */
268 	{ AudioCrecord,		AudioNsource,	NULL,
269 	  AUDIO_MIXER_ENUM, WRAP(ac97_source),
270 	  AC97_REG_RECORD_SELECT, 0x0000, 3, 0, 0,
271 	},
272 	/* Record Gain */
273 	{ AudioCrecord,		AudioNvolume,	NULL,
274 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
275 	  AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1,
276 	},
277 	/* Record Gain mic */
278 	{ AudioCrecord,		AudioNmicrophone, NULL,
279 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
280 	  AC97_REG_RECORD_GAIN_MIC, 0x8000, 4, 0, 1, 1, CHECK_MIC
281 	},
282 	/* */
283 	{ AudioCoutputs,	AudioNloudness,	NULL,
284 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
285 	  AC97_REG_GP, 0x0000, 1, 12, 0, 0, CHECK_LOUDNESS
286 	},
287 	{ AudioCoutputs,	AudioNspatial,	NULL,
288 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
289 	  AC97_REG_GP, 0x0000, 1, 13, 0, 1, CHECK_3D
290 	},
291 	{ AudioCoutputs,	AudioNspatial,	"center",
292 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
293 	  AC97_REG_3D_CONTROL, 0x0000, 4, 8, 0, 1, CHECK_3D
294 	},
295 	{ AudioCoutputs,	AudioNspatial,	"depth",
296 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
297 	  AC97_REG_3D_CONTROL, 0x0000, 4, 0, 0, 1, CHECK_3D
298 	},
299 	/* External Amp */
300 	{ AudioCoutputs,	AudioNextamp,	NULL,
301 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
302 	  AC97_REG_POWER, 0x0000, 1, 15, 0, 0
303 	},
304 	/* S/PDIF output enable */
305 	{ AudioCoutputs,	AudioNspdif,	NULL,
306 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
307 	  AC97_REG_EXT_AUDIO_CTRL, 0x0000, 1, 2, 0, 0, CHECK_SPDIF
308 	}
309 
310 	/* Missing features: Simulated Stereo, POP, Loopback mode */
311 };
312 
313 #define SOURCE_INFO_SIZE (sizeof(source_info)/sizeof(source_info[0]))
314 
315 /*
316  * Check out http://www.intel.com/technology/computing/audio/index.htm
317  * for information on AC-97
318  */
319 
320 struct ac97_softc {
321 	/* ac97_codec_if must be at the first of ac97_softc. */
322 	struct ac97_codec_if codec_if;
323 	struct ac97_host_if *host_if;
324 #define MAX_SOURCES	(2 * SOURCE_INFO_SIZE)
325 	struct ac97_source_info source_info[MAX_SOURCES];
326 	int num_source_info;
327 	enum ac97_host_flags host_flags;
328 	unsigned int ac97_clock; /* usually 48000 */
329 #define AC97_STANDARD_CLOCK	48000U
330 	u_int16_t caps;		/* -> AC97_REG_RESET */
331 	u_int16_t ext_id;	/* -> AC97_REG_EXT_AUDIO_ID */
332 	u_int16_t shadow_reg[128];
333 	int lock_counter;
334 };
335 
336 int	ac97_mixer_get_port(struct ac97_codec_if *, mixer_ctrl_t *);
337 int	ac97_mixer_set_port(struct ac97_codec_if *, mixer_ctrl_t *);
338 void	ac97_lock(struct ac97_codec_if *);
339 void	ac97_unlock(struct ac97_codec_if *);
340 int	ac97_query_devinfo(struct ac97_codec_if *, mixer_devinfo_t *);
341 int	ac97_get_portnum_by_name(struct ac97_codec_if *, char *, char *,
342 	    char *);
343 void	ac97_restore_shadow(struct ac97_codec_if *);
344 int	ac97_set_rate(struct ac97_codec_if *codec_if, int target, u_long *rate);
345 void	ac97_set_clock(struct ac97_codec_if *codec_if, unsigned int clock);
346 u_int16_t ac97_get_extcaps(struct ac97_codec_if *codec_if);
347 int	ac97_add_port(struct ac97_softc *as, struct ac97_source_info *src);
348 
349 void	ac97_ad1885_init(struct ac97_softc *);
350 void	ac97_ad1886_init(struct ac97_softc *);
351 void	ac97_ad198x_init(struct ac97_softc *);
352 void	ac97_alc650_init(struct ac97_softc *);
353 void	ac97_cx20468_init(struct ac97_softc *);
354 
355 struct ac97_codec_if_vtbl ac97civ = {
356 	ac97_mixer_get_port,
357 	ac97_mixer_set_port,
358 	ac97_query_devinfo,
359 	ac97_get_portnum_by_name,
360 	ac97_restore_shadow,
361 	ac97_get_extcaps,
362 	ac97_set_rate,
363 	ac97_set_clock,
364 	ac97_lock,
365 	ac97_unlock
366 };
367 
368 const struct ac97_codecid {
369 	u_int8_t id;
370 	u_int8_t mask;
371 	u_int8_t rev;
372 	u_int8_t shift;	/* no use yet */
373 	char * const name;
374 	void (*init)(struct ac97_softc *);
375 }  ac97_ad[] = {
376 	{ 0x03, 0xff, 0, 0,	"AD1819" },
377 	{ 0x40, 0xff, 0, 0,	"AD1881" },
378 	{ 0x48, 0xff, 0, 0,	"AD1881A" },
379 	{ 0x60, 0xff, 0, 0,	"AD1885", 	ac97_ad1885_init },
380 	{ 0x61, 0xff, 0, 0,	"AD1886",	ac97_ad1886_init },
381 	{ 0x63, 0xff, 0, 0,	"AD1886A" },
382 	{ 0x68, 0xff, 0, 0,	"AD1888",	ac97_ad198x_init },
383 	{ 0x70, 0xff, 0, 0,	"AD1980",	ac97_ad198x_init },
384 	{ 0x72, 0xff, 0, 0,	"AD1981A" },
385 	{ 0x74, 0xff, 0, 0,	"AD1981B" },
386 	{ 0x75, 0xff, 0, 0,	"AD1985",	ac97_ad198x_init },
387 }, ac97_ak[] = {
388 	{ 0x00,	0xfe, 1, 0,	"AK4540" },
389 	{ 0x01,	0xfe, 1, 0,	"AK4540" },
390 	{ 0x02,	0xff, 0, 0,	"AK4543" },
391 	{ 0x05,	0xff, 0, 0,	"AK4544" },
392 	{ 0x06,	0xff, 0, 0,	"AK4544A" },
393 	{ 0x07,	0xff, 0, 0,	"AK4545" },
394 }, ac97_av[] = {
395 	{ 0x10, 0xff, 0, 0,	"ALC200" },
396 	{ 0x20, 0xff, 0, 0,	"ALC650" },
397 	{ 0x21, 0xff, 0, 0,	"ALC650D" },
398 	{ 0x22, 0xff, 0, 0,	"ALC650E" },
399 	{ 0x23, 0xff, 0, 0,	"ALC650F" },
400 	{ 0x30, 0xff, 0, 0,	"ALC101" },
401 	{ 0x40, 0xff, 0, 0,	"ALC202" },
402 	{ 0x50, 0xff, 0, 0,	"ALC250" },
403 	{ 0x52, 0xff, 0, 0,	"ALC250A?" },
404 	{ 0x60, 0xf0, 0xf, 0,	"ALC655",	ac97_alc650_init },
405 	{ 0x70, 0xf0, 0xf, 0,	"ALC203" },
406 	{ 0x80, 0xf0, 0xf, 0,	"ALC658",	ac97_alc650_init },
407 	{ 0x90, 0xf0, 0xf, 0,	"ALC850" },
408 }, ac97_rl[] = {
409 	{ 0x00, 0xf0, 0xf, 0,	"RL5306" },
410 	{ 0x10, 0xf0, 0xf, 0,	"RL5382" },
411 	{ 0x20, 0xf0, 0xf, 0,	"RL5383" },
412 }, ac97_cm[] = {
413 	{ 0x41,	0xff, 0, 0,	"CMI9738" },
414 	{ 0x61,	0xff, 0, 0,	"CMI9739" },
415 	{ 0x78,	0xff, 0, 0,	"CMI9761A" },
416 	{ 0x82,	0xff, 0, 0,	"CMI9761B" },
417 	{ 0x83,	0xff, 0, 0,	"CMI9761A+" },
418 }, ac97_cr[] = {
419 	{ 0x84,	0xff, 0, 0,	"EV1938" },
420 }, ac97_cs[] = {
421 	{ 0x00,	0xf8, 7, 0,	"CS4297" },
422 	{ 0x10,	0xf8, 7, 0,	"CS4297A" },
423 	{ 0x20,	0xf8, 7, 0,	"CS4298" },
424 	{ 0x28,	0xf8, 7, 0,	"CS4294" },
425 	{ 0x30,	0xf8, 7, 0,	"CS4299" },
426 	{ 0x48,	0xf8, 7, 0,	"CS4201" },
427 	{ 0x58,	0xf8, 7, 0,	"CS4205" },
428 	{ 0x60,	0xf8, 7, 0,	"CS4291" },
429 	{ 0x70,	0xf8, 7, 0,	"CS4202" },
430 }, ac97_cx[] = {
431 	{ 0x21, 0xff, 0, 0,	"HSD11246" },
432 	{ 0x28, 0xf8, 7, 0,	"CX20468",	ac97_cx20468_init },
433 	{ 0x30, 0xff, 0, 0,	"CXT48", },
434 	{ 0x42, 0xff, 0, 0,	"CXT66", },
435 }, ac97_dt[] = {
436 	{ 0x00, 0xff, 0, 0,	"DT0398" },
437 }, ac97_em[] = {
438 	{ 0x23, 0xff, 0, 0,	"EM28023" },
439 	{ 0x28, 0xff, 0, 0,	"EM28028" },
440 }, ac97_es[] = {
441 	{ 0x08, 0xff, 0, 0,	"ES1921" },
442 }, ac97_is[] = {
443 	{ 0x00, 0xff, 0, 0,	"HMP9701" },
444 }, ac97_ic[] = {
445 	{ 0x01, 0xff, 0, 0,	"ICE1230" },
446 	{ 0x11, 0xff, 0, 0,	"ICE1232" },
447 	{ 0x14, 0xff, 0, 0,	"ICE1232A" },
448 	{ 0x51, 0xff, 0, 0,	"VIA VT1616" },
449 	{ 0x52, 0xff, 0, 0,	"VIA VT1616i" },
450 }, ac97_it[] = {
451 	{ 0x20, 0xff, 0, 0,	"ITE2226E" },
452 	{ 0x60, 0xff, 0, 0,	"ITE2646E" },
453 }, ac97_ns[] = {
454 	{ 0x00,	0xff, 0, 0,	"LM454[03568]" },
455 	{ 0x31,	0xff, 0, 0,	"LM4549" },
456 	{ 0x40, 0xff, 0, 0,	"LM4540" },
457 	{ 0x43, 0xff, 0, 0,	"LM4543" },
458 	{ 0x46, 0xff, 0, 0,	"LM4546A" },
459 	{ 0x48, 0xff, 0, 0,	"LM4548A" },
460 	{ 0x49, 0xff, 0, 0,	"LM4549A" },
461 	{ 0x50, 0xff, 0, 0,	"LM4550" },
462 }, ac97_ps[] = {
463 	{ 0x01,	0xff, 0, 0,	"UCB1510" },
464 	{ 0x04,	0xff, 0, 0,	"UCB1400" },
465 }, ac97_sl[] = {
466 	{ 0x20,	0xe0, 0, 0,	"Si3036/38" },
467 }, ac97_st[] = {
468 	{ 0x00,	0xff, 0, 0,	"STAC9700" },
469 	{ 0x04,	0xff, 0, 0,	"STAC970[135]" },
470 	{ 0x05,	0xff, 0, 0,	"STAC9704" },
471 	{ 0x08,	0xff, 0, 0,	"STAC9708/11" },
472 	{ 0x09,	0xff, 0, 0,	"STAC9721/23" },
473 	{ 0x44,	0xff, 0, 0,	"STAC9744/45" },
474 	{ 0x50,	0xff, 0, 0,	"STAC9750/51" },
475 	{ 0x52,	0xff, 0, 0,	"STAC9752/53" },
476 	{ 0x56,	0xff, 0, 0,	"STAC9756/57" },
477 	{ 0x58,	0xff, 0, 0,	"STAC9758/59" },
478 	{ 0x60,	0xff, 0, 0,	"STAC9760/61" },
479 	{ 0x62,	0xff, 0, 0,	"STAC9762/63" },
480 	{ 0x66,	0xff, 0, 0,	"STAC9766/67" },
481 	{ 0x84,	0xff, 0, 0,	"STAC9784/85" },
482 }, ac97_vi[] = {
483 	{ 0x61, 0xff, 0, 0,	"VT1612A" },
484 }, ac97_tt[] = {
485 	{ 0x02,	0xff, 0, 0,	"TR28022" },
486 	{ 0x03,	0xff, 0, 0,	"TR28023" },
487 	{ 0x06,	0xff, 0, 0,	"TR28026" },
488 	{ 0x08,	0xff, 0, 0,	"TR28028" },
489 	{ 0x23,	0xff, 0, 0,	"TR28602" },
490 }, ac97_ti[] = {
491 	{ 0x20, 0xff, 0, 0,	"TLC320AD9xC" },
492 }, ac97_wb[] = {
493 	{ 0x01, 0xff, 0, 0,	"W83971D" },
494 }, ac97_wo[] = {
495 	{ 0x00,	0xff, 0, 0,	"WM9701A" },
496 	{ 0x03,	0xff, 0, 0,	"WM9704M/Q-0" }, /* & WM9703 */
497 	{ 0x04,	0xff, 0, 0,	"WM9704M/Q-1" },
498 	{ 0x05,	0xff, 0, 0,	"WM9705/10" },
499 	{ 0x09,	0xff, 0, 0,	"WM9709" },
500 	{ 0x12,	0xff, 0, 0,	"WM9711/12" },
501 }, ac97_ym[] = {
502 	{ 0x00, 0xff, 0, 0,	"YMF743-S" },
503 	{ 0x02, 0xff, 0, 0,	"YMF752-S" },
504 	{ 0x03, 0xff, 0, 0,	"YMF753-S" },
505 };
506 
507 #define	cl(n)	n, sizeof(n)/sizeof(n[0])
508 const struct ac97_vendorid {
509 	u_int32_t id;
510 	char * const name;
511 	const struct ac97_codecid * const codecs;
512 	u_int8_t num;
513 } ac97_vendors[] = {
514 	{ 0x01408300, "Creative",		cl(ac97_cr) },
515 	{ 0x41445300, "Analog Devices",		cl(ac97_ad) },
516 	{ 0x414b4D00, "Asahi Kasei",		cl(ac97_ak) },
517 	{ 0x414c4300, "Realtek",		cl(ac97_rl) },
518 	{ 0x414c4700, "Avance Logic",		cl(ac97_av) },
519 	{ 0x434d4900, "C-Media Electronics",	cl(ac97_cm) },
520 	{ 0x43525900, "Cirrus Logic",		cl(ac97_cs) },
521 	{ 0x43585400, "Conexant",		cl(ac97_cx) },
522 	{ 0x44543000, "Diamond Technology",	cl(ac97_dt) },
523 	{ 0x454d4300, "eMicro",			cl(ac97_em) },
524 	{ 0x45838300, "ESS Technology",		cl(ac97_es) },
525 	{ 0x48525300, "Intersil",		cl(ac97_is) },
526 	{ 0x49434500, "ICEnsemble",		cl(ac97_ic) },
527 	{ 0x49544500, "ITE, Inc.",		cl(ac97_it) },
528 	{ 0x4e534300, "National Semiconductor", cl(ac97_ns) },
529 	{ 0x50534300, "Philips Semiconductor",	cl(ac97_ps) },
530 	{ 0x53494c00, "Silicon Laboratory",	cl(ac97_sl) },
531 	{ 0x54524100, "TriTech Microelectronics", cl(ac97_tt) },
532 	{ 0x54584e00, "Texas Instruments",	cl(ac97_ti) },
533 	{ 0x56494100, "VIA Technologies",	cl(ac97_vi) },
534 	{ 0x57454300, "Winbond",		cl(ac97_wb) },
535 	{ 0x574d4c00, "Wolfson",		cl(ac97_wo) },
536 	{ 0x594d4800, "Yamaha",			cl(ac97_ym) },
537 	{ 0x83847600, "SigmaTel",		cl(ac97_st) },
538 };
539 #undef cl
540 
541 const char * const ac97enhancement[] = {
542 	"No 3D Stereo",
543 	"Analog Devices Phat Stereo",
544 	"Creative",
545 	"National Semi 3D",
546 	"Yamaha Ymersion",
547 	"BBE 3D",
548 	"Crystal Semi 3D",
549 	"Qsound QXpander",
550 	"Spatializer 3D",
551 	"SRS 3D",
552 	"Platform Tech 3D",
553 	"AKM 3D",
554 	"Aureal",
555 	"AZTECH 3D",
556 	"Binaura 3D",
557 	"ESS Technology",
558 	"Harman International VMAx",
559 	"Nvidea 3D",
560 	"Philips Incredible Sound",
561 	"Texas Instruments 3D",
562 	"VLSI Technology 3D",
563 	"TriTech 3D",
564 	"Realtek 3D",
565 	"Samsung 3D",
566 	"Wolfson Microelectronics 3D",
567 	"Delta Integration 3D",
568 	"SigmaTel 3D",
569 	"KS Waves 3D",
570 	"Rockwell 3D",
571 	"Unknown 3D",
572 	"Unknown 3D",
573 	"Unknown 3D"
574 };
575 
576 const char * const ac97feature[] = {
577 	"mic channel",
578 	"reserved",
579 	"tone",
580 	"simulated stereo",
581 	"headphone",
582 	"bass boost",
583 	"18 bit DAC",
584 	"20 bit DAC",
585 	"18 bit ADC",
586 	"20 bit ADC"
587 };
588 
589 
590 int	ac97_str_equal(const char *, const char *);
591 int	ac97_check_capability(struct ac97_softc *, int);
592 void	ac97_setup_source_info(struct ac97_softc *);
593 void	ac97_setup_defaults(struct ac97_softc *);
594 int	ac97_read(struct ac97_softc *, u_int8_t, u_int16_t *);
595 int	ac97_write(struct ac97_softc *, u_int8_t, u_int16_t);
596 
597 
598 #ifdef AUDIO_DEBUG
599 #define DPRINTF(x)	if (ac97debug) printf x
600 #define DPRINTFN(n,x)	if (ac97debug>(n)) printf x
601 #ifdef AC97_DEBUG
602 int	ac97debug = 1;
603 #else
604 int	ac97debug = 0;
605 #endif
606 #else
607 #define DPRINTF(x)
608 #define DPRINTFN(n,x)
609 #endif
610 
611 void
612 ac97_get_default_params(struct audio_params *params)
613 {
614 	*params = ac97_audio_default;
615 }
616 
617 int
618 ac97_read(struct ac97_softc *as, u_int8_t reg, u_int16_t *val)
619 {
620 	int error;
621 
622 	if (((as->host_flags & AC97_HOST_DONT_READ) &&
623 	    (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 &&
624 	    reg != AC97_REG_RESET)) ||
625 	    (as->host_flags & AC97_HOST_DONT_READANY)) {
626 		*val = as->shadow_reg[reg >> 1];
627 		return (0);
628 	}
629 
630 	if ((error = as->host_if->read(as->host_if->arg, reg, val)))
631 		*val = as->shadow_reg[reg >> 1];
632 	return (error);
633 }
634 
635 int
636 ac97_write(struct ac97_softc *as, u_int8_t reg, u_int16_t val)
637 {
638 	as->shadow_reg[reg >> 1] = val;
639 	return (as->host_if->write(as->host_if->arg, reg, val));
640 }
641 
642 void
643 ac97_setup_defaults(struct ac97_softc *as)
644 {
645 	int idx;
646 
647 	bzero(as->shadow_reg, sizeof(as->shadow_reg));
648 
649 	for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
650 		const struct ac97_source_info *si = &source_info[idx];
651 
652 		ac97_write(as, si->reg, si->default_value);
653 	}
654 }
655 
656 void
657 ac97_restore_shadow(struct ac97_codec_if *self)
658 {
659 	struct ac97_softc *as = (struct ac97_softc *)self;
660 	int idx;
661 
662 	for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
663 		const struct ac97_source_info *si = &source_info[idx];
664 
665 		ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
666 	}
667 }
668 
669 int
670 ac97_str_equal(const char *a, const char *b)
671 {
672 	return ((a == b) || (a && b && (!strcmp(a, b))));
673 }
674 
675 int
676 ac97_check_capability(struct ac97_softc *as, int check)
677 {
678 	switch (check) {
679 	case CHECK_NONE:
680 		return 1;
681 	case CHECK_SURROUND:
682 		return as->ext_id & AC97_EXT_AUDIO_SDAC;
683 	case CHECK_CENTER:
684 		return as->ext_id & AC97_EXT_AUDIO_CDAC;
685 	case CHECK_LFE:
686 		return as->ext_id & AC97_EXT_AUDIO_LDAC;
687 	case CHECK_SPDIF:
688 		return as->ext_id & AC97_EXT_AUDIO_SPDIF;
689 	case CHECK_HEADPHONES:
690 		return as->caps & AC97_CAPS_HEADPHONES;
691 	case CHECK_TONE:
692 		return as->caps & AC97_CAPS_TONECTRL;
693 	case CHECK_MIC:
694 		return as->caps & AC97_CAPS_MICIN;
695 	case CHECK_LOUDNESS:
696 		return as->caps & AC97_CAPS_LOUDNESS;
697 	case CHECK_3D:
698 		return AC97_CAPS_ENHANCEMENT(as->caps) != 0;
699 	default:
700 		printf("%s: internal error: feature=%d\n", __func__, check);
701 		return 0;
702 	}
703 }
704 
705 void
706 ac97_setup_source_info(struct ac97_softc *as)
707 {
708 	struct ac97_source_info *si, *si2;
709 	int idx, ouridx;
710 
711 	for (idx = 0, ouridx = 0; idx < SOURCE_INFO_SIZE; idx++) {
712 		si = &as->source_info[ouridx];
713 
714 		if (!ac97_check_capability(as, source_info[idx].req_feature))
715 			continue;
716 
717 		bcopy(&source_info[idx], si, sizeof(*si));
718 
719 		switch (si->type) {
720 		case AUDIO_MIXER_CLASS:
721 			si->mixer_class = ouridx;
722 			ouridx++;
723 			break;
724 		case AUDIO_MIXER_VALUE:
725 			/* Todo - Test to see if it works */
726 			ouridx++;
727 
728 			/* Add an entry for mute, if necessary */
729 			if (si->mute) {
730 				si = &as->source_info[ouridx];
731 				bcopy(&source_info[idx], si, sizeof(*si));
732 				si->qualifier = AudioNmute;
733 				si->type = AUDIO_MIXER_ENUM;
734 				si->info = &ac97_on_off;
735 				si->info_size = sizeof(ac97_on_off);
736 				si->bits = 1;
737 				si->ofs = 15;
738 				si->mute = 0;
739 				si->polarity = 0;
740 				ouridx++;
741 			}
742 			break;
743 		case AUDIO_MIXER_ENUM:
744 			/* Todo - Test to see if it works */
745 			ouridx++;
746 			break;
747 		default:
748 			printf ("ac97: shouldn't get here\n");
749 			break;
750 		}
751 	}
752 
753 	as->num_source_info = ouridx;
754 
755 	for (idx = 0; idx < as->num_source_info; idx++) {
756 		int idx2, previdx;
757 
758 		si = &as->source_info[idx];
759 
760 		/* Find mixer class */
761 		for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
762 			si2 = &as->source_info[idx2];
763 
764 			if (si2->type == AUDIO_MIXER_CLASS &&
765 			    ac97_str_equal(si->class, si2->class)) {
766 				si->mixer_class = idx2;
767 			}
768 		}
769 
770 
771 		/* Setup prev and next pointers */
772 		if (si->prev != 0 || si->qualifier)
773 			continue;
774 
775 		si->prev = AUDIO_MIXER_LAST;
776 		previdx = idx;
777 
778 		for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
779 			if (idx2 == idx)
780 				continue;
781 
782 			si2 = &as->source_info[idx2];
783 
784 			if (!si2->prev &&
785 			    ac97_str_equal(si->class, si2->class) &&
786 			    ac97_str_equal(si->device, si2->device)) {
787 				as->source_info[previdx].next = idx2;
788 				as->source_info[idx2].prev = previdx;
789 
790 				previdx = idx2;
791 			}
792 		}
793 
794 		as->source_info[previdx].next = AUDIO_MIXER_LAST;
795 	}
796 }
797 
798 int
799 ac97_attach(struct ac97_host_if *host_if)
800 {
801 	struct ac97_softc *as;
802 	u_int16_t id1, id2, val;
803 	u_int32_t id;
804 	u_int16_t extstat, rate;
805 	mixer_ctrl_t ctl;
806 	int error, i;
807 	void (*initfunc)(struct ac97_softc *);
808 
809 	initfunc = NULL;
810 
811 	if (!(as = malloc(sizeof(*as), M_DEVBUF, M_NOWAIT | M_ZERO)))
812 		return (ENOMEM);
813 
814 	as->codec_if.vtbl = &ac97civ;
815 	as->host_if = host_if;
816 
817 	if ((error = host_if->attach(host_if->arg, &as->codec_if))) {
818 		free(as, M_DEVBUF);
819 		return (error);
820 	}
821 
822 	host_if->reset(host_if->arg);
823 	DELAY(1000);
824 
825 	host_if->write(host_if->arg, AC97_REG_POWER, 0);
826 	host_if->write(host_if->arg, AC97_REG_RESET, 0);
827 	DELAY(10000);
828 
829 	if (host_if->flags)
830 		as->host_flags = host_if->flags(host_if->arg);
831 
832 	ac97_setup_defaults(as);
833 	ac97_read(as, AC97_REG_VENDOR_ID1, &id1);
834 	ac97_read(as, AC97_REG_VENDOR_ID2, &id2);
835 	ac97_read(as, AC97_REG_RESET, &as->caps);
836 
837 	id = (id1 << 16) | id2;
838 	if (id) {
839 		register const struct ac97_vendorid *vendor;
840 		register const struct ac97_codecid *codec;
841 
842 		printf("ac97: codec id 0x%08x", id);
843 		for (vendor = &ac97_vendors[sizeof(ac97_vendors) /
844 		     sizeof(ac97_vendors[0]) - 1];
845 		     vendor >= ac97_vendors; vendor--) {
846 			if (vendor->id == (id & AC97_VENDOR_ID_MASK)) {
847 				printf(" (%s", vendor->name);
848 				for (codec = &vendor->codecs[vendor->num-1];
849 				     codec >= vendor->codecs; codec--) {
850 					if (codec->id == (id & codec->mask))
851 						break;
852 				}
853 				if (codec >= vendor->codecs && codec->mask) {
854 					printf(" %s", codec->name);
855 					initfunc = codec->init;
856 				} else
857 					printf(" <%02x>", id & 0xff);
858 				if (codec >= vendor->codecs && codec->rev)
859 					printf(" rev %d", id & codec->rev);
860 				printf(")");
861 				break;
862 			}
863 		}
864 		printf("\n");
865 	} else
866 		printf("ac97: codec id not read\n");
867 
868 	if (as->caps) {
869 		printf("ac97: codec features ");
870 		for (i = 0; i < 10; i++) {
871 			if (as->caps & (1 << i))
872 				printf("%s, ", ac97feature[i]);
873 		}
874 		printf("%s\n",
875 		    ac97enhancement[AC97_CAPS_ENHANCEMENT(as->caps)]);
876 	}
877 
878 
879 	as->ac97_clock = AC97_STANDARD_CLOCK;
880 	ac97_read(as, AC97_REG_EXT_AUDIO_ID, &as->ext_id);
881 	if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA
882 			  | AC97_EXT_AUDIO_SPDIF | AC97_EXT_AUDIO_VRM
883 			  | AC97_EXT_AUDIO_CDAC | AC97_EXT_AUDIO_SDAC
884 			  | AC97_EXT_AUDIO_LDAC)) {
885 
886 		ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &extstat);
887 		extstat &= ~AC97_EXT_AUDIO_DRA;
888 
889 		if (as->ext_id & AC97_EXT_AUDIO_VRM)
890 			extstat |= AC97_EXT_AUDIO_VRM;
891 
892 		if (as->ext_id & AC97_EXT_AUDIO_LDAC)
893 			extstat |= AC97_EXT_AUDIO_LDAC;
894 		if (as->ext_id & AC97_EXT_AUDIO_SDAC)
895 			extstat |= AC97_EXT_AUDIO_SDAC;
896 		if (as->ext_id & AC97_EXT_AUDIO_CDAC)
897 			extstat |= AC97_EXT_AUDIO_CDAC;
898 		if (as->ext_id & AC97_EXT_AUDIO_SPDIF) {
899 			/* XXX S/PDIF gets same data as DAC?
900 			 * maybe this should be settable?
901 			 * default is SPSAAB (10/11) on AD1980 and ALC codecs.
902 			 */
903 			extstat &= ~AC97_EXT_AUDIO_SPSA_MASK;
904 			extstat |= AC97_EXT_AUDIO_SPSA34;
905 			ac97_read(as, AC97_REG_SPDIF_CTRL, &val);
906 			val = (val & ~AC97_SPDIF_SPSR_MASK) |
907 			    AC97_SPDIF_SPSR_48K;
908 			ac97_write(as, AC97_REG_SPDIF_CTRL, val);
909 		}
910 		if (as->ext_id & AC97_EXT_AUDIO_VRA)
911 			extstat |= AC97_EXT_AUDIO_VRA;
912 		ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, extstat);
913 		if (as->ext_id & AC97_EXT_AUDIO_VRA) {
914 			/* VRA should be enabled. */
915 			/* so it claims to do variable rate, let's make sure */
916 			ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE, 44100);
917 			ac97_read(as, AC97_REG_PCM_FRONT_DAC_RATE, &rate);
918 			if (rate != 44100) {
919 				/* We can't believe ext_id */
920 				as->ext_id = 0;
921 			}
922 			/* restore the default value */
923 			ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE,
924 				   AC97_SINGLE_RATE);
925 		}
926 	}
927 
928 	ac97_setup_source_info(as);
929 
930 	DELAY(900 * 1000);
931 
932 	/* use initfunc for specific device */
933 	if (initfunc != NULL)
934 		initfunc(as);
935 
936 	/* Just enable the DAC and master volumes by default */
937 	bzero(&ctl, sizeof(ctl));
938 
939 	ctl.type = AUDIO_MIXER_ENUM;
940 	ctl.un.ord = 0;  /* off */
941 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
942 	    AudioNmaster, AudioNmute);
943 	ac97_mixer_set_port(&as->codec_if, &ctl);
944 
945 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCinputs,
946 	    AudioNdac, AudioNmute);
947 	ac97_mixer_set_port(&as->codec_if, &ctl);
948 
949 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCrecord,
950 	    AudioNvolume, AudioNmute);
951 	ac97_mixer_set_port(&as->codec_if, &ctl);
952 
953 	ctl.type = AUDIO_MIXER_ENUM;
954 	ctl.un.ord = 0;
955 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCrecord,
956 	    AudioNsource, NULL);
957 	ac97_mixer_set_port(&as->codec_if, &ctl);
958 
959 	return (0);
960 }
961 
962 void
963 ac97_lock(struct ac97_codec_if *codec_if)
964 {
965 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
966 	as->lock_counter++;
967 }
968 
969 void
970 ac97_unlock(struct ac97_codec_if *codec_if)
971 {
972 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
973 	as->lock_counter--;
974 }
975 
976 int
977 ac97_query_devinfo(struct ac97_codec_if *codec_if, mixer_devinfo_t *dip)
978 {
979 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
980 
981 	if (dip->index < as->num_source_info && dip->index >= 0) {
982 		struct ac97_source_info *si = &as->source_info[dip->index];
983 		const char *name;
984 
985 		dip->type = si->type;
986 		dip->mixer_class = si->mixer_class;
987 		dip->prev = si->prev;
988 		dip->next = si->next;
989 
990 		if (si->qualifier)
991 			name = si->qualifier;
992 		else if (si->device)
993 			name = si->device;
994 		else if (si->class)
995 			name = si->class;
996 		else
997 			name = NULL;
998 
999 		if (name)
1000 			strlcpy(dip->label.name, name, sizeof dip->label.name);
1001 
1002 		bcopy(si->info, &dip->un, si->info_size);
1003 
1004 		/* Set the delta for volume sources */
1005 		if (dip->type == AUDIO_MIXER_VALUE)
1006 			dip->un.v.delta = 1 << (8 - si->bits);
1007 
1008 		return (0);
1009 	}
1010 
1011 	return (ENXIO);
1012 }
1013 
1014 int
1015 ac97_mixer_set_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
1016 {
1017 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
1018 	struct ac97_source_info *si = &as->source_info[cp->dev];
1019 	u_int16_t mask;
1020 	u_int16_t val, newval;
1021 	int error, spdif;
1022 
1023 	if (cp->dev < 0 || cp->dev >= as->num_source_info ||
1024 	    cp->type == AUDIO_MIXER_CLASS || cp->type != si->type)
1025 		return (EINVAL);
1026 
1027 	spdif = si->req_feature == CHECK_SPDIF &&
1028 	    si->reg == AC97_REG_EXT_AUDIO_CTRL;
1029 	if (spdif && as->lock_counter >= 0)
1030 		return EBUSY;
1031 
1032 	ac97_read(as, si->reg, &val);
1033 
1034 	DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
1035 
1036 	mask = (1 << si->bits) - 1;
1037 
1038 	switch (cp->type) {
1039 	case AUDIO_MIXER_ENUM:
1040 		if (cp->un.ord > mask || cp->un.ord < 0)
1041 			return (EINVAL);
1042 
1043 		newval = (cp->un.ord << si->ofs);
1044 		if (si->reg == AC97_REG_RECORD_SELECT) {
1045 			newval |= (newval << (8 + si->ofs));
1046 			mask |= (mask << 8);
1047 			mask = mask << si->ofs;
1048 		} else if (si->reg == AC97_REG_SURR_MASTER) {
1049 			newval = cp->un.ord ? 0x8080 : 0x0000;
1050 			mask = 0x8080;
1051 		} else
1052 			mask = mask << si->ofs;
1053 
1054 		if (si->mute) {
1055 			newval |= newval << 8;
1056 			mask |= mask << 8;
1057 		}
1058 
1059 		break;
1060 	case AUDIO_MIXER_VALUE:
1061 	{
1062 		const struct audio_mixer_value *value = si->info;
1063 		u_int16_t  l, r;
1064 
1065 		if (cp->un.value.num_channels <= 0 ||
1066 		    cp->un.value.num_channels > value->num_channels)
1067 			return (EINVAL);
1068 
1069 		if (cp->un.value.num_channels == 1) {
1070 			l = r = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1071 		} else {
1072 			if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
1073 				l = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1074 				r = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1075 			} else {
1076 				r = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1077 				l = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1078 			}
1079 		}
1080 
1081 		if (!si->polarity) {
1082 			l = 255 - l;
1083 			r = 255 - r;
1084 		}
1085 
1086 		l >>= 8 - si->bits;
1087 		r >>= 8 - si->bits;
1088 
1089 		newval = ((l & mask) << si->ofs);
1090 		if (value->num_channels == 2) {
1091 			newval |= ((r & mask) << (si->ofs + 8));
1092 			mask |= (mask << 8);
1093 		}
1094 		mask = mask << si->ofs;
1095 		break;
1096 	}
1097 	default:
1098 		return (EINVAL);
1099 	}
1100 
1101 	error = ac97_write(as, si->reg, (val & ~mask) | newval);
1102 	if (error)
1103 		return (error);
1104 
1105 	if (spdif && as->host_if->spdif_event != NULL)
1106 		as->host_if->spdif_event(as->host_if->arg, cp->un.ord);
1107 
1108 	return (0);
1109 }
1110 
1111 
1112 int
1113 ac97_set_rate(struct ac97_codec_if *codec_if, int target, u_long *rate)
1114 {
1115 	struct ac97_softc *as;
1116 	u_long value;
1117 	u_int16_t ext_stat;
1118 	u_int16_t actual;
1119 	u_int16_t power;
1120 	u_int16_t power_bit;
1121 
1122 	as = (struct ac97_softc *)codec_if;
1123 
1124 	if ((target == AC97_REG_PCM_SURR_DAC_RATE) &&
1125 	    !(as->ext_id & AC97_EXT_AUDIO_SDAC))
1126 			return 0;
1127 	if ((target == AC97_REG_PCM_LFE_DAC_RATE) &&
1128 	    !(as->ext_id & AC97_EXT_AUDIO_LDAC))
1129 			return 0;
1130 	if (target == AC97_REG_PCM_MIC_ADC_RATE) {
1131 		if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) {
1132 			*rate = AC97_SINGLE_RATE;
1133 			return 0;
1134 		}
1135 	} else {
1136 		if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
1137 			*rate = AC97_SINGLE_RATE;
1138 			return 0;
1139 		}
1140 	}
1141 	if (as->ac97_clock == 0)
1142 		as->ac97_clock = AC97_STANDARD_CLOCK;
1143 	value = *rate * AC97_STANDARD_CLOCK / as->ac97_clock;
1144 	ext_stat = 0;
1145 	/*
1146 	 * PCM_FRONT_DAC_RATE/PCM_SURR_DAC_RATE/PCM_LFE_DAC_RATE
1147 	 *	Check VRA, DRA
1148 	 * PCM_LR_ADC_RATE
1149 	 *	Check VRA
1150 	 * PCM_MIC_ADC_RATE
1151 	 *	Check VRM
1152 	 */
1153 	switch (target) {
1154 	case AC97_REG_PCM_FRONT_DAC_RATE:
1155 	case AC97_REG_PCM_SURR_DAC_RATE:
1156 	case AC97_REG_PCM_LFE_DAC_RATE:
1157 		power_bit = AC97_POWER_OUT;
1158 		if (as->ext_id & AC97_EXT_AUDIO_DRA) {
1159 			ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &ext_stat);
1160 			if (value > 0x1ffff) {
1161 				return EINVAL;
1162 			} else if (value > 0xffff) {
1163 				/* Enable DRA */
1164 				ext_stat |= AC97_EXT_AUDIO_DRA;
1165 				ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
1166 				value /= 2;
1167 			} else {
1168 				/* Disable DRA */
1169 				ext_stat &= ~AC97_EXT_AUDIO_DRA;
1170 				ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
1171 			}
1172 		} else {
1173 			if (value > 0xffff)
1174 				return EINVAL;
1175 		}
1176 		break;
1177 	case AC97_REG_PCM_LR_ADC_RATE:
1178 		power_bit = AC97_POWER_IN;
1179 		if (value > 0xffff)
1180 			return EINVAL;
1181 		break;
1182 	case AC97_REG_PCM_MIC_ADC_RATE:
1183 		power_bit = AC97_POWER_IN;
1184 		if (value > 0xffff)
1185 			return EINVAL;
1186 		break;
1187 	default:
1188 		printf("%s: Unknown register: 0x%x\n", __func__, target);
1189 		return EINVAL;
1190 	}
1191 
1192 	ac97_read(as, AC97_REG_POWER, &power);
1193 	ac97_write(as, AC97_REG_POWER, power | power_bit);
1194 
1195 	ac97_write(as, target, (u_int16_t)value);
1196 	ac97_read(as, target, &actual);
1197 	actual = (u_int32_t)actual * as->ac97_clock / AC97_STANDARD_CLOCK;
1198 
1199 	ac97_write(as, AC97_REG_POWER, power);
1200 	if (ext_stat & AC97_EXT_AUDIO_DRA) {
1201 		*rate = actual * 2;
1202 	} else {
1203 		*rate = actual;
1204 	}
1205 	return 0;
1206 }
1207 
1208 void
1209 ac97_set_clock(struct ac97_codec_if *codec_if, unsigned int clock)
1210 {
1211 	struct ac97_softc *as;
1212 
1213 	as = (struct ac97_softc *)codec_if;
1214 	as->ac97_clock = clock;
1215 }
1216 
1217 u_int16_t
1218 ac97_get_extcaps(struct ac97_codec_if *codec_if)
1219 {
1220 	struct ac97_softc *as;
1221 
1222 	as = (struct ac97_softc *)codec_if;
1223 	return as->ext_id;
1224 }
1225 
1226 int
1227 ac97_add_port(struct ac97_softc *as, struct ac97_source_info *src)
1228 {
1229 	struct ac97_source_info *si;
1230 	int ouridx, idx;
1231 
1232 	if (as->num_source_info >= MAX_SOURCES) {
1233 		printf("%s: internal error: increase MAX_SOURCES in %s\n",
1234 		       __func__, __FILE__);
1235 		return -1;
1236 	}
1237 	if (!ac97_check_capability(as, src->req_feature))
1238 		return -1;
1239 	ouridx = as->num_source_info;
1240 	si = &as->source_info[ouridx];
1241 	memcpy(si, src, sizeof(*si));
1242 
1243 	switch (si->type) {
1244 	case AUDIO_MIXER_CLASS:
1245 	case AUDIO_MIXER_VALUE:
1246 		printf("%s: adding class/value is not supported yet.\n",
1247 		       __func__);
1248 		return -1;
1249 	case AUDIO_MIXER_ENUM:
1250 		break;
1251 	default:
1252 		printf("%s: unknown type: %d\n", __func__, si->type);
1253 		return -1;
1254 	}
1255 	as->num_source_info++;
1256 
1257 	si->mixer_class = ac97_get_portnum_by_name(&as->codec_if, si->class,
1258 						   NULL, NULL);
1259 	/* Find the root of the device */
1260 	idx = ac97_get_portnum_by_name(&as->codec_if, si->class,
1261 				       si->device, NULL);
1262 	/* Find the last item */
1263 	while (as->source_info[idx].next != AUDIO_MIXER_LAST)
1264 		idx = as->source_info[idx].next;
1265 	/* Append */
1266 	as->source_info[idx].next = ouridx;
1267 	si->prev = idx;
1268 	si->next = AUDIO_MIXER_LAST;
1269 
1270 	return 0;
1271 }
1272 
1273 int
1274 ac97_get_portnum_by_name(struct ac97_codec_if *codec_if, char *class,
1275     char *device, char *qualifier)
1276 {
1277 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
1278 	int idx;
1279 
1280 	for (idx = 0; idx < as->num_source_info; idx++) {
1281 		struct ac97_source_info *si = &as->source_info[idx];
1282 		if (ac97_str_equal(class, si->class) &&
1283 		    ac97_str_equal(device, si->device) &&
1284 		    ac97_str_equal(qualifier, si->qualifier))
1285 			return (idx);
1286 	}
1287 
1288 	return (-1);
1289 }
1290 
1291 int
1292 ac97_mixer_get_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
1293 {
1294 	struct ac97_softc *as = (struct ac97_softc *)codec_if;
1295 	struct ac97_source_info *si = &as->source_info[cp->dev];
1296 	u_int16_t mask;
1297 	u_int16_t val;
1298 
1299 	if (cp->dev < 0 || cp->dev >= as->num_source_info ||
1300 	    cp->type != si->type)
1301 		return (EINVAL);
1302 
1303 	ac97_read(as, si->reg, &val);
1304 
1305 	DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
1306 
1307 	mask = (1 << si->bits) - 1;
1308 
1309 	switch (cp->type) {
1310 	case AUDIO_MIXER_ENUM:
1311 		cp->un.ord = (val >> si->ofs) & mask;
1312 		DPRINTFN(4, ("AUDIO_MIXER_ENUM: %x %d %x %d\n", val, si->ofs,
1313 		    mask, cp->un.ord));
1314 		break;
1315 	case AUDIO_MIXER_VALUE:
1316 	{
1317 		const struct audio_mixer_value *value = si->info;
1318 		u_int16_t  l, r;
1319 
1320 		if ((cp->un.value.num_channels <= 0) ||
1321 		    (cp->un.value.num_channels > value->num_channels))
1322 			return (EINVAL);
1323 
1324 		if (value->num_channels == 1)
1325 			l = r = (val >> si->ofs) & mask;
1326 		else {
1327 			if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
1328 				l = (val >> si->ofs) & mask;
1329 				r = (val >> (si->ofs + 8)) & mask;
1330 			} else {
1331 				r = (val >> si->ofs) & mask;
1332 				l = (val >> (si->ofs + 8)) & mask;
1333 			}
1334 		}
1335 
1336 		l <<= 8 - si->bits;
1337 		r <<= 8 - si->bits;
1338 		if (!si->polarity) {
1339 			l = 255 - l;
1340 			r = 255 - r;
1341 		}
1342 
1343 		/*
1344 		 * The EAP driver averages l and r for stereo
1345 		 * channels that are requested in MONO mode. Does this
1346 		 * make sense?
1347 		 */
1348 		if (cp->un.value.num_channels == 1) {
1349 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = l;
1350 		} else if (cp->un.value.num_channels == 2) {
1351 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
1352 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
1353 		}
1354 
1355 		break;
1356 	}
1357 	default:
1358 		return (EINVAL);
1359 	}
1360 
1361 	return (0);
1362 }
1363 
1364 
1365 /*
1366  * Codec-dependent initialization
1367  */
1368 
1369 void
1370 ac97_ad1885_init(struct ac97_softc *as)
1371 {
1372 	int i;
1373 
1374 	for (i = 0; i < as->num_source_info; i++) {
1375 		if (as->source_info[i].reg == AC97_REG_HEADPHONE_VOLUME)
1376 			as->source_info[i].reg = AC97_REG_MASTER_VOLUME;
1377 		else if (as->source_info[i].reg == AC97_REG_MASTER_VOLUME)
1378 			as->source_info[i].reg = AC97_REG_HEADPHONE_VOLUME;
1379 	}
1380 }
1381 
1382 #define AC97_AD1886_JACK_SENSE	0x72
1383 
1384 void
1385 ac97_ad1886_init(struct ac97_softc *as)
1386 {
1387 	ac97_write(as, AC97_AD1886_JACK_SENSE, 0x0010);
1388 }
1389 
1390 void
1391 ac97_ad198x_init(struct ac97_softc *as)
1392 {
1393 	int i;
1394 	u_int16_t misc;
1395 
1396 	ac97_read(as, AC97_AD_REG_MISC, &misc);
1397 	ac97_write(as, AC97_AD_REG_MISC,
1398 	    misc|AC97_AD_MISC_HPSEL|AC97_AD_MISC_LOSEL);
1399 
1400 	for (i = 0; i < as->num_source_info; i++) {
1401 		if (as->source_info[i].reg == AC97_REG_SURR_MASTER)
1402 			as->source_info[i].reg = AC97_REG_MASTER_VOLUME;
1403 		else if (as->source_info[i].reg == AC97_REG_MASTER_VOLUME)
1404 			as->source_info[i].reg = AC97_REG_SURR_MASTER;
1405 	}
1406 }
1407 
1408 void
1409 ac97_alc650_init(struct ac97_softc *as)
1410 {
1411 	u_int16_t misc;
1412 
1413 	ac97_read(as, AC97_ALC650_REG_MISC, &misc);
1414 	if (as->host_flags & AC97_HOST_ALC650_PIN47_IS_EAPD)
1415 		misc &= ~AC97_ALC650_MISC_PIN47;
1416 	misc &= ~AC97_ALC650_MISC_VREFDIS;
1417 	ac97_write(as, AC97_ALC650_REG_MISC, misc);
1418 
1419 	struct ac97_source_info sources[3] = {
1420 		{ AudioCoutputs, AudioNsurround, "lineinjack",
1421 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1422 		  AC97_ALC650_REG_MULTI_CHANNEL_CONTROL,
1423 		  0x0000, 1, 9, 0, 0, CHECK_SURROUND },
1424 		{ AudioCoutputs, AudioNcenter, "micjack",
1425 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1426 		  AC97_ALC650_REG_MULTI_CHANNEL_CONTROL,
1427 		  0x0000, 1, 10, 0, 0, CHECK_CENTER },
1428 		{ AudioCoutputs, AudioNlfe, "micjack",
1429 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1430 		  AC97_ALC650_REG_MULTI_CHANNEL_CONTROL,
1431 		  0x0000, 1, 10, 0, 0, CHECK_LFE }};
1432 
1433 	ac97_add_port(as, &sources[0]);
1434 	ac97_add_port(as, &sources[1]);
1435 	ac97_add_port(as, &sources[2]);
1436 }
1437 
1438 void
1439 ac97_cx20468_init(struct ac97_softc *as)
1440 {
1441 	u_int16_t misc;
1442 
1443 	ac97_read(as, AC97_CX_REG_MISC, &misc);
1444 	ac97_write(as, AC97_CX_REG_MISC, misc &
1445 	    ~(AC97_CX_SPDIFEN | AC97_CX_COPYRIGHT | AC97_CX_MASK));
1446 }
1447