ac97.c revision 1.80 1 /* $NetBSD: ac97.c,v 1.80 2006/04/15 21:18:34 jmcneill Exp $ */
2 /* $OpenBSD: ac97.c,v 1.8 2000/07/19 09:01:35 csapuntz Exp $ */
3
4 /*
5 * Copyright (c) 1999, 2000 Constantine Sapuntzakis
6 *
7 * Author: Constantine Sapuntzakis <csapuntz (at) stanford.edu>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
30 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 * DAMAGE
32 */
33
34 /* Partially inspired by FreeBSD's sys/dev/pcm/ac97.c. It came with
35 the following copyright */
36
37 /*
38 * Copyright (c) 1999 Cameron Grant <gandalf (at) vilnya.demon.co.uk>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE.
61 *
62 * $FreeBSD$
63 */
64
65 #include <sys/cdefs.h>
66 __KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.80 2006/04/15 21:18:34 jmcneill Exp $");
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/malloc.h>
72 #include <sys/device.h>
73 #include <sys/sysctl.h>
74
75 #include <sys/audioio.h>
76 #include <dev/audio_if.h>
77
78 #include <dev/ic/ac97reg.h>
79 #include <dev/ic/ac97var.h>
80
81 struct ac97_softc;
82 struct ac97_source_info;
83 static int ac97_mixer_get_port(struct ac97_codec_if *, mixer_ctrl_t *);
84 static int ac97_mixer_set_port(struct ac97_codec_if *, mixer_ctrl_t *);
85 static void ac97_detach(struct ac97_codec_if *);
86 static int ac97_query_devinfo(struct ac97_codec_if *, mixer_devinfo_t *);
87 static int ac97_get_portnum_by_name(struct ac97_codec_if *, const char *,
88 const char *, const char *);
89 static void ac97_restore_shadow(struct ac97_codec_if *);
90 static int ac97_set_rate(struct ac97_codec_if *, int, u_int *);
91 static void ac97_set_clock(struct ac97_codec_if *, unsigned int);
92 static uint16_t ac97_get_extcaps(struct ac97_codec_if *);
93 static int ac97_add_port(struct ac97_softc *,
94 const struct ac97_source_info *);
95 static int ac97_str_equal(const char *, const char *);
96 static int ac97_check_capability(struct ac97_softc *, int);
97 static void ac97_setup_source_info(struct ac97_softc *);
98 static void ac97_read(struct ac97_softc *, uint8_t, uint16_t *);
99 static void ac97_setup_defaults(struct ac97_softc *);
100 static int ac97_write(struct ac97_softc *, uint8_t, uint16_t);
101
102 static void ac97_ad198x_init(struct ac97_softc *);
103 static void ac97_alc650_init(struct ac97_softc *);
104 static void ac97_vt1616_init(struct ac97_softc *);
105
106 static int ac97_modem_offhook_set(struct ac97_softc *, int, int);
107 static int ac97_sysctl_verify(SYSCTLFN_ARGS);
108
109 #define Ac97Nphone "phone"
110 #define Ac97Nline1 "line1"
111 #define Ac97Nline2 "line2"
112 #define Ac97Nhandset "handset"
113
114 static const struct audio_mixer_enum
115 ac97_on_off = { 2, { { { AudioNoff } , 0 },
116 { { AudioNon } , 1 } } };
117
118 static const struct audio_mixer_enum
119 ac97_mic_select = { 2, { { { AudioNmicrophone "0" }, 0 },
120 { { AudioNmicrophone "1" }, 1 } } };
121
122 static const struct audio_mixer_enum
123 ac97_mono_select = { 2, { { { AudioNmixerout }, 0 },
124 { { AudioNmicrophone }, 1 } } };
125
126 static const struct audio_mixer_enum
127 ac97_source = { 8, { { { AudioNmicrophone } , 0 },
128 { { AudioNcd }, 1 },
129 { { AudioNvideo }, 2 },
130 { { AudioNaux }, 3 },
131 { { AudioNline }, 4 },
132 { { AudioNmixerout }, 5 },
133 { { AudioNmixerout AudioNmono }, 6 },
134 { { Ac97Nphone }, 7 } } };
135
136 /*
137 * Due to different values for each source that uses these structures,
138 * the ac97_query_devinfo function sets delta in mixer_devinfo_t using
139 * ac97_source_info.bits.
140 */
141 static const struct audio_mixer_value
142 ac97_volume_stereo = { { AudioNvolume }, 2 };
143
144 static const struct audio_mixer_value
145 ac97_volume_mono = { { AudioNvolume }, 1 };
146
147 #define WRAP(a) &a, sizeof(a)
148
149 struct ac97_source_info {
150 const char *class;
151 const char *device;
152 const char *qualifier;
153
154 int type;
155 const void *info;
156 int info_size;
157
158 uint8_t reg;
159 uint16_t default_value;
160 uint8_t bits:3;
161 uint8_t ofs:4;
162 uint8_t mute:1;
163 uint8_t polarity:1; /* Does 0 == MAX or MIN */
164 enum {
165 CHECK_NONE = 0,
166 CHECK_SURROUND,
167 CHECK_CENTER,
168 CHECK_LFE,
169 CHECK_HEADPHONES,
170 CHECK_TONE,
171 CHECK_MIC,
172 CHECK_LOUDNESS,
173 CHECK_3D,
174 CHECK_LINE1,
175 CHECK_LINE2,
176 CHECK_HANDSET
177 } req_feature;
178
179 int prev;
180 int next;
181 int mixer_class;
182 };
183
184 static const struct ac97_source_info audio_source_info[] = {
185 { AudioCinputs, NULL, NULL,
186 AUDIO_MIXER_CLASS, },
187 { AudioCoutputs, NULL, NULL,
188 AUDIO_MIXER_CLASS, },
189 { AudioCrecord, NULL, NULL,
190 AUDIO_MIXER_CLASS, },
191 /* Stereo master volume*/
192 { AudioCoutputs, AudioNmaster, NULL,
193 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
194 AC97_REG_MASTER_VOLUME, 0x8000, 5, 0, 1,
195 },
196 /* Mono volume */
197 { AudioCoutputs, AudioNmono, NULL,
198 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
199 AC97_REG_MASTER_VOLUME_MONO, 0x8000, 6, 0, 1,
200 },
201 { AudioCoutputs, AudioNmono, AudioNsource,
202 AUDIO_MIXER_ENUM, WRAP(ac97_mono_select),
203 AC97_REG_GP, 0x0000, 1, 9, 0,
204 },
205 /* Headphone volume */
206 { AudioCoutputs, AudioNheadphone, NULL,
207 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
208 AC97_REG_HEADPHONE_VOLUME, 0x8000, 6, 0, 1, 0, CHECK_HEADPHONES
209 },
210 /* Surround volume - logic hard coded for mute */
211 { AudioCoutputs, AudioNsurround, NULL,
212 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
213 AC97_REG_SURR_MASTER, 0x8080, 5, 0, 1, 0, CHECK_SURROUND
214 },
215 /* Center volume*/
216 { AudioCoutputs, AudioNcenter, NULL,
217 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
218 AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 0, 0, 0, CHECK_CENTER
219 },
220 { AudioCoutputs, AudioNcenter, AudioNmute,
221 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
222 AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 7, 0, 0, CHECK_CENTER
223 },
224 /* LFE volume*/
225 { AudioCoutputs, AudioNlfe, NULL,
226 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
227 AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 8, 0, 0, CHECK_LFE
228 },
229 { AudioCoutputs, AudioNlfe, AudioNmute,
230 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
231 AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 15, 0, 0, CHECK_LFE
232 },
233 /* Tone - bass */
234 { AudioCoutputs, AudioNbass, NULL,
235 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
236 AC97_REG_MASTER_TONE, 0x0f0f, 4, 8, 0, 0, CHECK_TONE
237 },
238 /* Tone - treble */
239 { AudioCoutputs, AudioNtreble, NULL,
240 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
241 AC97_REG_MASTER_TONE, 0x0f0f, 4, 0, 0, 0, CHECK_TONE
242 },
243 /* PC Beep Volume */
244 { AudioCinputs, AudioNspeaker, NULL,
245 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
246 AC97_REG_PCBEEP_VOLUME, 0x0000, 4, 1, 1,
247 },
248
249 /* Phone */
250 { AudioCinputs, Ac97Nphone, NULL,
251 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
252 AC97_REG_PHONE_VOLUME, 0x8008, 5, 0, 1,
253 },
254 /* Mic Volume */
255 { AudioCinputs, AudioNmicrophone, NULL,
256 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
257 AC97_REG_MIC_VOLUME, 0x8008, 5, 0, 1,
258 },
259 { AudioCinputs, AudioNmicrophone, AudioNpreamp,
260 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
261 AC97_REG_MIC_VOLUME, 0x8008, 1, 6, 0,
262 },
263 { AudioCinputs, AudioNmicrophone, AudioNsource,
264 AUDIO_MIXER_ENUM, WRAP(ac97_mic_select),
265 AC97_REG_GP, 0x0000, 1, 8, 0,
266 },
267 /* Line in Volume */
268 { AudioCinputs, AudioNline, NULL,
269 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
270 AC97_REG_LINEIN_VOLUME, 0x8808, 5, 0, 1,
271 },
272 /* CD Volume */
273 { AudioCinputs, AudioNcd, NULL,
274 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
275 AC97_REG_CD_VOLUME, 0x8808, 5, 0, 1,
276 },
277 /* Video Volume */
278 { AudioCinputs, AudioNvideo, NULL,
279 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
280 AC97_REG_VIDEO_VOLUME, 0x8808, 5, 0, 1,
281 },
282 /* AUX volume */
283 { AudioCinputs, AudioNaux, NULL,
284 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
285 AC97_REG_AUX_VOLUME, 0x8808, 5, 0, 1,
286 },
287 /* PCM out volume */
288 { AudioCinputs, AudioNdac, NULL,
289 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
290 AC97_REG_PCMOUT_VOLUME, 0x8808, 5, 0, 1,
291 },
292 /* Record Source - some logic for this is hard coded - see below */
293 { AudioCrecord, AudioNsource, NULL,
294 AUDIO_MIXER_ENUM, WRAP(ac97_source),
295 AC97_REG_RECORD_SELECT, 0x0000, 3, 0, 0,
296 },
297 /* Record Gain */
298 { AudioCrecord, AudioNvolume, NULL,
299 AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
300 AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1, 1,
301 },
302 /* Record Gain mic */
303 { AudioCrecord, AudioNmicrophone, NULL,
304 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
305 AC97_REG_RECORD_GAIN_MIC, 0x8000, 4, 0, 1, 1, CHECK_MIC
306 },
307 /* */
308 { AudioCoutputs, AudioNloudness, NULL,
309 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
310 AC97_REG_GP, 0x0000, 1, 12, 0, 0, CHECK_LOUDNESS
311 },
312 { AudioCoutputs, AudioNspatial, NULL,
313 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
314 AC97_REG_GP, 0x0000, 1, 13, 0, 1, CHECK_3D
315 },
316 { AudioCoutputs, AudioNspatial, "center",
317 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
318 AC97_REG_3D_CONTROL, 0x0000, 4, 8, 0, 1, CHECK_3D
319 },
320 { AudioCoutputs, AudioNspatial, "depth",
321 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
322 AC97_REG_3D_CONTROL, 0x0000, 4, 0, 0, 1, CHECK_3D
323 },
324
325 /* Missing features: Simulated Stereo, POP, Loopback mode */
326 };
327
328 static const struct ac97_source_info modem_source_info[] = {
329 /* Classes */
330 { AudioCinputs, NULL, NULL,
331 AUDIO_MIXER_CLASS, },
332 { AudioCoutputs, NULL, NULL,
333 AUDIO_MIXER_CLASS, },
334 { AudioCinputs, Ac97Nline1, NULL,
335 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
336 AC97_REG_LINE1_LEVEL, 0x8080, 4, 0, 0, 1, CHECK_LINE1
337 },
338 { AudioCoutputs, Ac97Nline1, NULL,
339 AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
340 AC97_REG_LINE1_LEVEL, 0x8080, 4, 8, 0, 1, CHECK_LINE1
341 },
342 { AudioCinputs, Ac97Nline1, AudioNmute,
343 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
344 AC97_REG_LINE1_LEVEL, 0x8080, 1, 7, 0, 0, CHECK_LINE1
345 },
346 { AudioCoutputs, Ac97Nline1, AudioNmute,
347 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
348 AC97_REG_LINE1_LEVEL, 0x8080, 1, 15, 0, 0, CHECK_LINE1
349 },
350 };
351
352 #define AUDIO_SOURCE_INFO_SIZE \
353 (sizeof(audio_source_info)/sizeof(audio_source_info[0]))
354 #define MODEM_SOURCE_INFO_SIZE \
355 (sizeof(modem_source_info)/sizeof(modem_source_info[0]))
356 #define SOURCE_INFO_SIZE(as) ((as)->type == AC97_CODEC_TYPE_MODEM ? \
357 MODEM_SOURCE_INFO_SIZE : AUDIO_SOURCE_INFO_SIZE)
358
359 /*
360 * Check out http://developer.intel.com/pc-supp/platform/ac97/ for
361 * information on AC-97
362 */
363
364 struct ac97_softc {
365 /* ac97_codec_if must be at the first of ac97_softc. */
366 struct ac97_codec_if codec_if;
367
368 struct ac97_host_if *host_if;
369
370 #define AUDIO_MAX_SOURCES (2 * AUDIO_SOURCE_INFO_SIZE)
371 #define MODEM_MAX_SOURCES (2 * MODEM_SOURCE_INFO_SIZE)
372 struct ac97_source_info audio_source_info[AUDIO_MAX_SOURCES];
373 struct ac97_source_info modem_source_info[MODEM_MAX_SOURCES];
374 struct ac97_source_info *source_info;
375 int num_source_info;
376
377 enum ac97_host_flags host_flags;
378 unsigned int ac97_clock; /* usually 48000 */
379 #define AC97_STANDARD_CLOCK 48000U
380 uint16_t power_all;
381 uint16_t power_reg; /* -> AC97_REG_POWER */
382 uint16_t caps; /* -> AC97_REG_RESET */
383 uint16_t ext_id; /* -> AC97_REG_EXT_AUDIO_ID */
384 uint16_t ext_mid; /* -> AC97_REG_EXT_MODEM_ID */
385 uint16_t shadow_reg[128];
386
387 int type;
388
389 /* sysctl */
390 struct sysctllog *log;
391 int offhook_line1_mib;
392 int offhook_line2_mib;
393 int offhook_line1;
394 int offhook_line2;
395 };
396
397 static struct ac97_codec_if_vtbl ac97civ = {
398 ac97_mixer_get_port,
399 ac97_mixer_set_port,
400 ac97_query_devinfo,
401 ac97_get_portnum_by_name,
402 ac97_restore_shadow,
403 ac97_get_extcaps,
404 ac97_set_rate,
405 ac97_set_clock,
406 ac97_detach,
407 };
408
409 static const struct ac97_codecid {
410 uint32_t id;
411 uint32_t mask;
412 const char *name;
413 void (*init)(struct ac97_softc *);
414 } ac97codecid[] = {
415 /*
416 * Analog Devices SoundMAX
417 * http://www.soundmax.com/products/information/codecs.html
418 * http://www.analog.com/productSelection/pdf/AD1881A_0.pdf
419 * http://www.analog.com/productSelection/pdf/AD1885_0.pdf
420 * http://www.analog.com/UploadedFiles/Data_Sheets/206585810AD1980_0.pdf
421 * http://www.analog.com/productSelection/pdf/AD1981A_0.pdf
422 * http://www.analog.com/productSelection/pdf/AD1981B_0.pdf
423 * http://www.analog.com/UploadedFiles/Data_Sheets/180644528AD1985_0.pdf
424 */
425 { AC97_CODEC_ID('A', 'D', 'S', 3),
426 0xffffffff, "Analog Devices AD1819B" },
427 { AC97_CODEC_ID('A', 'D', 'S', 0x40),
428 0xffffffff, "Analog Devices AD1881" },
429 { AC97_CODEC_ID('A', 'D', 'S', 0x48),
430 0xffffffff, "Analog Devices AD1881A" },
431 { AC97_CODEC_ID('A', 'D', 'S', 0x60),
432 0xffffffff, "Analog Devices AD1885" },
433 { AC97_CODEC_ID('A', 'D', 'S', 0x61),
434 0xffffffff, "Analog Devices AD1886" },
435 { AC97_CODEC_ID('A', 'D', 'S', 0x63),
436 0xffffffff, "Analog Devices AD1886A" },
437 { AC97_CODEC_ID('A', 'D', 'S', 0x68),
438 0xffffffff, "Analog Devices AD1888", ac97_ad198x_init },
439 { AC97_CODEC_ID('A', 'D', 'S', 0x70),
440 0xffffffff, "Analog Devices AD1980", ac97_ad198x_init },
441 { AC97_CODEC_ID('A', 'D', 'S', 0x72),
442 0xffffffff, "Analog Devices AD1981A" },
443 { AC97_CODEC_ID('A', 'D', 'S', 0x74),
444 0xffffffff, "Analog Devices AD1981B" },
445 { AC97_CODEC_ID('A', 'D', 'S', 0x75),
446 0xffffffff, "Analog Devices AD1985", ac97_ad198x_init },
447 { AC97_CODEC_ID('A', 'D', 'S', 0),
448 AC97_VENDOR_ID_MASK, "Analog Devices unknown" },
449
450 /*
451 * Datasheets:
452 * http://www.asahi-kasei.co.jp/akm/usa/product/ak4541/ek4541.pdf
453 * http://www.asahi-kasei.co.jp/akm/usa/product/ak4543/ek4543.pdf
454 * http://www.asahi-kasei.co.jp/akm/usa/product/ak4544a/ek4544a.pdf
455 * http://www.asahi-kasei.co.jp/akm/usa/product/ak4545/ek4545.pdf
456 */
457 { AC97_CODEC_ID('A', 'K', 'M', 0),
458 0xffffffff, "Asahi Kasei AK4540" },
459 { AC97_CODEC_ID('A', 'K', 'M', 1),
460 0xffffffff, "Asahi Kasei AK4542" },
461 { AC97_CODEC_ID('A', 'K', 'M', 2),
462 0xffffffff, "Asahi Kasei AK4541/AK4543" },
463 { AC97_CODEC_ID('A', 'K', 'M', 5),
464 0xffffffff, "Asahi Kasei AK4544" },
465 { AC97_CODEC_ID('A', 'K', 'M', 6),
466 0xffffffff, "Asahi Kasei AK4544A" },
467 { AC97_CODEC_ID('A', 'K', 'M', 7),
468 0xffffffff, "Asahi Kasei AK4545" },
469 { AC97_CODEC_ID('A', 'K', 'M', 0),
470 AC97_VENDOR_ID_MASK, "Asahi Kasei unknown" },
471
472 /*
473 * Realtek & Avance Logic
474 * http://www.realtek.com.tw/downloads/downloads1-3.aspx?lineid=5&famid=All&series=All&Spec=True
475 *
476 * ALC650 and ALC658 support VRA, but it supports only 8000, 11025,
477 * 12000, 16000, 22050, 24000, 32000, 44100, and 48000 Hz.
478 */
479 { AC97_CODEC_ID('A', 'L', 'C', 0x00),
480 0xfffffff0, "Realtek RL5306" },
481 { AC97_CODEC_ID('A', 'L', 'C', 0x10),
482 0xfffffff0, "Realtek RL5382" },
483 { AC97_CODEC_ID('A', 'L', 'C', 0x20),
484 0xfffffff0, "Realtek RL5383/RL5522/ALC100" },
485 { AC97_CODEC_ID('A', 'L', 'G', 0x10),
486 0xffffffff, "Avance Logic ALC200/ALC201" },
487 { AC97_CODEC_ID('A', 'L', 'G', 0x20),
488 0xfffffff0, "Avance Logic ALC650", ac97_alc650_init },
489 { AC97_CODEC_ID('A', 'L', 'G', 0x30),
490 0xffffffff, "Avance Logic ALC101" },
491 { AC97_CODEC_ID('A', 'L', 'G', 0x40),
492 0xffffffff, "Avance Logic ALC202" },
493 { AC97_CODEC_ID('A', 'L', 'G', 0x50),
494 0xffffffff, "Avance Logic ALC250" },
495 { AC97_CODEC_ID('A', 'L', 'G', 0x60),
496 0xfffffff0, "Avance Logic ALC655" },
497 { AC97_CODEC_ID('A', 'L', 'G', 0x80),
498 0xfffffff0, "Avance Logic ALC658" },
499 { AC97_CODEC_ID('A', 'L', 'G', 0x90),
500 0xfffffff0, "Avance Logic ALC850" },
501 { AC97_CODEC_ID('A', 'L', 'C', 0),
502 AC97_VENDOR_ID_MASK, "Realtek unknown" },
503 { AC97_CODEC_ID('A', 'L', 'G', 0),
504 AC97_VENDOR_ID_MASK, "Avance Logic unknown" },
505
506 /**
507 * C-Media Electronics Inc.
508 * http://www.cmedia.com.tw/doc/CMI9739%206CH%20Audio%20Codec%20SPEC_Ver12.pdf
509 */
510 { AC97_CODEC_ID('C', 'M', 'I', 0x61),
511 0xffffffff, "C-Media CMI9739" },
512 { AC97_CODEC_ID('C', 'M', 'I', 0),
513 AC97_VENDOR_ID_MASK, "C-Media unknown" },
514
515 /* Cirrus Logic, Crystal series:
516 * 'C' 'R' 'Y' 0x0[0-7] - CS4297
517 * 0x1[0-7] - CS4297A
518 * 0x2[0-7] - CS4298
519 * 0x2[8-f] - CS4294
520 * 0x3[0-7] - CS4299
521 * 0x4[8-f] - CS4201
522 * 0x5[8-f] - CS4205
523 * 0x6[0-7] - CS4291
524 * 0x7[0-7] - CS4202
525 * Datasheets:
526 * http://www.cirrus.com/pubs/cs4297A-5.pdf?DocumentID=593
527 * http://www.cirrus.com/pubs/cs4294.pdf?DocumentID=32
528 * http://www.cirrus.com/pubs/cs4299-5.pdf?DocumentID=594
529 * http://www.cirrus.com/pubs/cs4201-2.pdf?DocumentID=492
530 * http://www.cirrus.com/pubs/cs4205-2.pdf?DocumentID=492
531 * http://www.cirrus.com/pubs/cs4202-1.pdf?DocumentID=852
532 */
533 { AC97_CODEC_ID('C', 'R', 'Y', 0x00),
534 0xfffffff8, "Crystal CS4297", },
535 { AC97_CODEC_ID('C', 'R', 'Y', 0x10),
536 0xfffffff8, "Crystal CS4297A", },
537 { AC97_CODEC_ID('C', 'R', 'Y', 0x20),
538 0xfffffff8, "Crystal CS4298", },
539 { AC97_CODEC_ID('C', 'R', 'Y', 0x28),
540 0xfffffff8, "Crystal CS4294", },
541 { AC97_CODEC_ID('C', 'R', 'Y', 0x30),
542 0xfffffff8, "Crystal CS4299", },
543 { AC97_CODEC_ID('C', 'R', 'Y', 0x48),
544 0xfffffff8, "Crystal CS4201", },
545 { AC97_CODEC_ID('C', 'R', 'Y', 0x58),
546 0xfffffff8, "Crystal CS4205", },
547 { AC97_CODEC_ID('C', 'R', 'Y', 0x60),
548 0xfffffff8, "Crystal CS4291", },
549 { AC97_CODEC_ID('C', 'R', 'Y', 0x70),
550 0xfffffff8, "Crystal CS4202", },
551 { AC97_CODEC_ID('C', 'R', 'Y', 0),
552 AC97_VENDOR_ID_MASK, "Cirrus Logic unknown", },
553
554 { 0x45838308, 0xffffffff, "ESS Technology ES1921", },
555 { 0x45838300, AC97_VENDOR_ID_MASK, "ESS Technology unknown", },
556
557 { AC97_CODEC_ID('H', 'R', 'S', 0),
558 0xffffffff, "Intersil HMP9701", },
559 { AC97_CODEC_ID('H', 'R', 'S', 0),
560 AC97_VENDOR_ID_MASK, "Intersil unknown", },
561
562 /*
563 * IC Ensemble (VIA)
564 * http://www.viatech.com/en/datasheet/DS1616.pdf
565 */
566 { AC97_CODEC_ID('I', 'C', 'E', 0x01),
567 0xffffffff, "ICEnsemble ICE1230/VT1611", },
568 { AC97_CODEC_ID('I', 'C', 'E', 0x11),
569 0xffffffff, "ICEnsemble ICE1232/VT1611A", },
570 { AC97_CODEC_ID('I', 'C', 'E', 0x14),
571 0xffffffff, "ICEnsemble ICE1232A", },
572 { AC97_CODEC_ID('I', 'C', 'E', 0x51),
573 0xffffffff, "VIA Technologies VT1616", ac97_vt1616_init },
574 { AC97_CODEC_ID('I', 'C', 'E', 0x52),
575 0xffffffff, "VIA Technologies VT1616i", ac97_vt1616_init },
576 { AC97_CODEC_ID('I', 'C', 'E', 0),
577 AC97_VENDOR_ID_MASK, "ICEnsemble/VIA unknown", },
578
579 { AC97_CODEC_ID('N', 'S', 'C', 0),
580 0xffffffff, "National Semiconductor LM454[03568]", },
581 { AC97_CODEC_ID('N', 'S', 'C', 49),
582 0xffffffff, "National Semiconductor LM4549", },
583 { AC97_CODEC_ID('N', 'S', 'C', 0),
584 AC97_VENDOR_ID_MASK, "National Semiconductor unknown", },
585
586 { AC97_CODEC_ID('P', 'S', 'C', 4),
587 0xffffffff, "Philips Semiconductor UCB1400", },
588 { AC97_CODEC_ID('P', 'S', 'C', 0),
589 AC97_VENDOR_ID_MASK, "Philips Semiconductor unknown", },
590
591 { AC97_CODEC_ID('S', 'I', 'L', 34),
592 0xffffffff, "Silicon Laboratory Si3036", },
593 { AC97_CODEC_ID('S', 'I', 'L', 35),
594 0xffffffff, "Silicon Laboratory Si3038", },
595 { AC97_CODEC_ID('S', 'I', 'L', 0),
596 AC97_VENDOR_ID_MASK, "Silicon Laboratory unknown", },
597
598 { AC97_CODEC_ID('T', 'R', 'A', 2),
599 0xffffffff, "TriTech TR28022", },
600 { AC97_CODEC_ID('T', 'R', 'A', 3),
601 0xffffffff, "TriTech TR28023", },
602 { AC97_CODEC_ID('T', 'R', 'A', 6),
603 0xffffffff, "TriTech TR28026", },
604 { AC97_CODEC_ID('T', 'R', 'A', 8),
605 0xffffffff, "TriTech TR28028", },
606 { AC97_CODEC_ID('T', 'R', 'A', 35),
607 0xffffffff, "TriTech TR28602", },
608 { AC97_CODEC_ID('T', 'R', 'A', 0),
609 AC97_VENDOR_ID_MASK, "TriTech unknown", },
610
611 { AC97_CODEC_ID('T', 'X', 'N', 0x20),
612 0xffffffff, "Texas Instruments TLC320AD9xC", },
613 { AC97_CODEC_ID('T', 'X', 'N', 0),
614 AC97_VENDOR_ID_MASK, "Texas Instruments unknown", },
615
616 /*
617 * VIA
618 * http://www.viatech.com/en/multimedia/audio.jsp
619 */
620 { AC97_CODEC_ID('V', 'I', 'A', 0x61),
621 0xffffffff, "VIA Technologies VT1612A", },
622 { AC97_CODEC_ID('V', 'I', 'A', 0),
623 AC97_VENDOR_ID_MASK, "VIA Technologies unknown", },
624
625 { AC97_CODEC_ID('W', 'E', 'C', 1),
626 0xffffffff, "Winbond W83971D", },
627 { AC97_CODEC_ID('W', 'E', 'C', 0),
628 AC97_VENDOR_ID_MASK, "Winbond unknown", },
629
630 /*
631 * http://www.wolfsonmicro.com/product_list.asp?cid=64
632 * http://www.wolfsonmicro.com/download.asp/did.56/WM9701A.pdf - 00
633 * http://www.wolfsonmicro.com/download.asp/did.57/WM9703.pdf - 03
634 * http://www.wolfsonmicro.com/download.asp/did.58/WM9704M.pdf - 04
635 * http://www.wolfsonmicro.com/download.asp/did.59/WM9704Q.pdf - 04
636 * http://www.wolfsonmicro.com/download.asp/did.184/WM9705_Rev34.pdf - 05
637 * http://www.wolfsonmicro.com/download.asp/did.60/WM9707.pdf - 03
638 * http://www.wolfsonmicro.com/download.asp/did.136/WM9708.pdf - 03
639 * http://www.wolfsonmicro.com/download.asp/did.243/WM9710.pdf - 05
640 */
641 { AC97_CODEC_ID('W', 'M', 'L', 0),
642 0xffffffff, "Wolfson WM9701A", },
643 { AC97_CODEC_ID('W', 'M', 'L', 3),
644 0xffffffff, "Wolfson WM9703/WM9707/WM9708", },
645 { AC97_CODEC_ID('W', 'M', 'L', 4),
646 0xffffffff, "Wolfson WM9704", },
647 { AC97_CODEC_ID('W', 'M', 'L', 5),
648 0xffffffff, "Wolfson WM9705/WM9710", },
649 { AC97_CODEC_ID('W', 'M', 'L', 0),
650 AC97_VENDOR_ID_MASK, "Wolfson unknown", },
651
652 /*
653 * http://www.yamaha.co.jp/english/product/lsi/us/products/pcaudio.html
654 * Datasheets:
655 * http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF743A20.pdf
656 * http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF753A20.pdf
657 */
658 { AC97_CODEC_ID('Y', 'M', 'H', 0),
659 0xffffffff, "Yamaha YMF743-S", },
660 { AC97_CODEC_ID('Y', 'M', 'H', 3),
661 0xffffffff, "Yamaha YMF753-S", },
662 { AC97_CODEC_ID('Y', 'M', 'H', 0),
663 AC97_VENDOR_ID_MASK, "Yamaha unknown", },
664
665 /*
666 * http://www.sigmatel.com/products/technical_docs.htm
667 * and
668 * http://www.sigmatel.com/documents/c-major-brochure-9-0.pdf
669 */
670 { 0x83847600, 0xffffffff, "SigmaTel STAC9700", },
671 { 0x83847604, 0xffffffff, "SigmaTel STAC9701/3/4/5", },
672 { 0x83847605, 0xffffffff, "SigmaTel STAC9704", },
673 { 0x83847608, 0xffffffff, "SigmaTel STAC9708", },
674 { 0x83847609, 0xffffffff, "SigmaTel STAC9721/23", },
675 { 0x83847644, 0xffffffff, "SigmaTel STAC9744/45", },
676 { 0x83847650, 0xffffffff, "SigmaTel STAC9750/51", },
677 { 0x83847652, 0xffffffff, "SigmaTel STAC9752/53", },
678 { 0x83847656, 0xffffffff, "SigmaTel STAC9756/57", },
679 { 0x83847658, 0xffffffff, "SigmaTel STAC9758/59", },
680 { 0x83847666, 0xffffffff, "SigmaTel STAC9766/67", },
681 { 0x83847684, 0xffffffff, "SigmaTel STAC9783/84", },
682 { 0x83847600, AC97_VENDOR_ID_MASK, "SigmaTel unknown", },
683
684 /* Conexant AC'97 modems -- good luck finding datasheets! */
685 { AC97_CODEC_ID('C', 'X', 'T', 33),
686 0xffffffff, "Conexant HSD11246", },
687 { AC97_CODEC_ID('C', 'X', 'T', 34),
688 0xffffffff, "Conexant D480 MDC V.92 Modem", },
689 { AC97_CODEC_ID('C', 'X', 'T', 48),
690 0xffffffff, "Conexant CXT48", },
691 { AC97_CODEC_ID('C', 'X', 'T', 0),
692 AC97_VENDOR_ID_MASK, "Conexant unknown", },
693
694 { 0,
695 0, NULL, }
696 };
697
698 static const char * const ac97enhancement[] = {
699 "no 3D stereo",
700 "Analog Devices Phat Stereo",
701 "Creative",
702 "National Semi 3D",
703 "Yamaha Ymersion",
704 "BBE 3D",
705 "Crystal Semi 3D",
706 "Qsound QXpander",
707 "Spatializer 3D",
708 "SRS 3D",
709 "Platform Tech 3D",
710 "AKM 3D",
711 "Aureal",
712 "AZTECH 3D",
713 "Binaura 3D",
714 "ESS Technology",
715 "Harman International VMAx",
716 "Nvidea 3D",
717 "Philips Incredible Sound",
718 "Texas Instruments' 3D",
719 "VLSI Technology 3D",
720 "TriTech 3D",
721 "Realtek 3D",
722 "Samsung 3D",
723 "Wolfson Microelectronics 3D",
724 "Delta Integration 3D",
725 "SigmaTel 3D",
726 "KS Waves 3D",
727 "Rockwell 3D",
728 "Unknown 3D",
729 "Unknown 3D",
730 "Unknown 3D",
731 };
732
733 static const char * const ac97feature[] = {
734 "dedicated mic channel",
735 "reserved",
736 "tone",
737 "simulated stereo",
738 "headphone",
739 "bass boost",
740 "18 bit DAC",
741 "20 bit DAC",
742 "18 bit ADC",
743 "20 bit ADC"
744 };
745
746
747 /* #define AC97_DEBUG 10 */
748 /* #define AC97_IO_DEBUG */
749
750 #ifdef AUDIO_DEBUG
751 #define DPRINTF(x) if (ac97debug) printf x
752 #define DPRINTFN(n,x) if (ac97debug>(n)) printf x
753 #ifdef AC97_DEBUG
754 int ac97debug = AC97_DEBUG;
755 #else
756 int ac97debug = 0;
757 #endif
758 #else
759 #define DPRINTF(x)
760 #define DPRINTFN(n,x)
761 #endif
762
763 #ifdef AC97_IO_DEBUG
764 static const char *ac97_register_names[0x80 / 2] = {
765 "RESET", "MASTER_VOLUME", "HEADPHONE_VOLUME", "MASTER_VOLUME_MONO",
766 "MASTER_TONE", "PCBEEP_VOLUME", "PHONE_VOLUME", "MIC_VOLUME",
767 "LINEIN_VOLUME", "CD_VOLUME", "VIDEO_VOLUME", "AUX_VOLUME",
768 "PCMOUT_VOLUME", "RECORD_SELECT", "RECORD_GATIN", "RECORD_GAIN_MIC",
769 "GP", "3D_CONTROL", "AUDIO_INT", "POWER",
770 "EXT_AUDIO_ID", "EXT_AUDIO_CTRL", "PCM_FRONT_DAC_RATE", "PCM_SURR_DAC_RATE",
771 "PCM_LFE_DAC_RATE", "PCM_LR_ADC_RATE", "PCM_MIC_ADC_RATE", "CENTER_LFE_MASTER",
772 "SURR_MASTER", "SPDIF_CTRL", "EXT_MODEM_ID", "EXT_MODEM_CTRL",
773 "LINE1_RATE", "LINE2_RATE", "HANDSET_RATE", "LINE1_LEVEL",
774 "LINE2_LEVEL", "HANDSET_LEVEL", "GPIO_PIN_CONFIG", "GPIO_PIN_POLARITY",
775 "GPIO_PIN_STICKY", "GPIO_PIN_WAKEUP", "GPIO_PIN_STATUS", "MISC_MODEM_CTRL",
776 "0x58", "VENDOR-5A", "VENDOR-5C", "VENDOR-5E",
777 "0x60", "0x62", "0x64", "0x66",
778 "0x68", "0x6a", "0x6c", "0x6e",
779 "VENDOR-70", "VENDOR-72", "VENDOR-74", "VENDOR-76",
780 "VENDOR-78", "VENDOR-7A", "VENDOR_ID1", "VENDOR_ID2"
781 };
782 #endif
783
784 /*
785 * XXX Some cards have an inverted AC97_POWER_EAMP bit.
786 * These cards will produce no sound unless AC97_HOST_INVERTED_EAMP is set.
787 */
788
789 #define POWER_EAMP_ON(as) ((as->host_flags & AC97_HOST_INVERTED_EAMP) \
790 ? AC97_POWER_EAMP : 0)
791 #define POWER_EAMP_OFF(as) ((as->host_flags & AC97_HOST_INVERTED_EAMP) \
792 ? 0 : AC97_POWER_EAMP)
793
794 static void
795 ac97_read(struct ac97_softc *as, uint8_t reg, uint16_t *val)
796 {
797 if (as->host_flags & AC97_HOST_DONT_READ &&
798 (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 &&
799 reg != AC97_REG_RESET)) {
800 *val = as->shadow_reg[reg >> 1];
801 return;
802 }
803
804 if (as->host_if->read(as->host_if->arg, reg, val)) {
805 *val = as->shadow_reg[reg >> 1];
806 }
807 }
808
809 static int
810 ac97_write(struct ac97_softc *as, uint8_t reg, uint16_t val)
811 {
812 #ifndef AC97_IO_DEBUG
813 as->shadow_reg[reg >> 1] = val;
814 return as->host_if->write(as->host_if->arg, reg, val);
815 #else
816 int ret;
817 uint16_t actual;
818
819 as->shadow_reg[reg >> 1] = val;
820 ret = as->host_if->write(as->host_if->arg, reg, val);
821 as->host_if->read(as->host_if->arg, reg, &actual);
822 if (val != actual && reg < 0x80) {
823 printf("ac97_write: reg=%s, written=0x%04x, read=0x%04x\n",
824 ac97_register_names[reg / 2], val, actual);
825 }
826 return ret;
827 #endif
828 }
829
830 static void
831 ac97_setup_defaults(struct ac97_softc *as)
832 {
833 int idx;
834 const struct ac97_source_info *si;
835
836 memset(as->shadow_reg, 0, sizeof(as->shadow_reg));
837
838 for (idx = 0; idx < AUDIO_SOURCE_INFO_SIZE; idx++) {
839 si = &audio_source_info[idx];
840 ac97_write(as, si->reg, si->default_value);
841 }
842 for (idx = 0; idx < MODEM_SOURCE_INFO_SIZE; idx++) {
843 si = &modem_source_info[idx];
844 ac97_write(as, si->reg, si->default_value);
845 }
846 }
847
848 static void
849 ac97_restore_shadow(struct ac97_codec_if *self)
850 {
851 struct ac97_softc *as;
852 const struct ac97_source_info *si;
853 int idx;
854 uint16_t val;
855
856 as = (struct ac97_softc *) self;
857
858 if (as->type == AC97_CODEC_TYPE_AUDIO) {
859 /* restore AC97_REG_POWER */
860 ac97_write(as, AC97_REG_POWER, as->power_reg);
861 /* make sure chip is fully operational */
862 for (idx = 50000; idx >= 0; idx--) {
863 ac97_read(as, AC97_REG_POWER, &val);
864 if ((val & as->power_all) == as->power_all)
865 break;
866 DELAY(10);
867 }
868
869 /*
870 * actually try changing a value!
871 * The default value of AC97_REG_MASTER_VOLUME is 0x8000.
872 */
873 for (idx = 50000; idx >= 0; idx--) {
874 ac97_write(as, AC97_REG_MASTER_VOLUME, 0x1010);
875 ac97_read(as, AC97_REG_MASTER_VOLUME, &val);
876 if (val == 0x1010)
877 break;
878 DELAY(10);
879 }
880 }
881
882 for (idx = 0; idx < SOURCE_INFO_SIZE(as); idx++) {
883 if (as->type == AC97_CODEC_TYPE_MODEM)
884 si = &modem_source_info[idx];
885 else
886 si = &audio_source_info[idx];
887 /* don't "restore" to the reset reg! */
888 if (si->reg != AC97_REG_RESET)
889 ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
890 }
891
892 if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA
893 | AC97_EXT_AUDIO_SPDIF | AC97_EXT_AUDIO_VRM
894 | AC97_EXT_AUDIO_CDAC | AC97_EXT_AUDIO_SDAC
895 | AC97_EXT_AUDIO_LDAC)) {
896 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL,
897 as->shadow_reg[AC97_REG_EXT_AUDIO_CTRL >> 1]);
898 }
899 if (as->ext_mid & (AC97_EXT_MODEM_LINE1 | AC97_EXT_MODEM_LINE2
900 | AC97_EXT_MODEM_HANDSET | AC97_EXT_MODEM_CID1
901 | AC97_EXT_MODEM_CID2 | AC97_EXT_MODEM_ID0
902 | AC97_EXT_MODEM_ID1)) {
903 ac97_write(as, AC97_REG_EXT_MODEM_CTRL,
904 as->shadow_reg[AC97_REG_EXT_MODEM_CTRL >> 1]);
905 }
906 }
907
908 static int
909 ac97_str_equal(const char *a, const char *b)
910 {
911 return (a == b) || (a && b && (!strcmp(a, b)));
912 }
913
914 static int
915 ac97_check_capability(struct ac97_softc *as, int check)
916 {
917 switch (check) {
918 case CHECK_NONE:
919 return 1;
920 case CHECK_SURROUND:
921 return as->ext_id & AC97_EXT_AUDIO_SDAC;
922 case CHECK_CENTER:
923 return as->ext_id & AC97_EXT_AUDIO_CDAC;
924 case CHECK_LFE:
925 return as->ext_id & AC97_EXT_AUDIO_LDAC;
926 case CHECK_HEADPHONES:
927 return as->caps & AC97_CAPS_HEADPHONES;
928 case CHECK_TONE:
929 return as->caps & AC97_CAPS_TONECTRL;
930 case CHECK_MIC:
931 return as->caps & AC97_CAPS_MICIN;
932 case CHECK_LOUDNESS:
933 return as->caps & AC97_CAPS_LOUDNESS;
934 case CHECK_3D:
935 return AC97_CAPS_ENHANCEMENT(as->caps) != 0;
936 case CHECK_LINE1:
937 return as->ext_mid & AC97_EXT_MODEM_LINE1;
938 case CHECK_LINE2:
939 return as->ext_mid & AC97_EXT_MODEM_LINE2;
940 case CHECK_HANDSET:
941 return as->ext_mid & AC97_EXT_MODEM_HANDSET;
942 default:
943 printf("%s: internal error: feature=%d\n", __func__, check);
944 return 0;
945 }
946 }
947
948 static void
949 ac97_setup_source_info(struct ac97_softc *as)
950 {
951 int idx, ouridx;
952 struct ac97_source_info *si, *si2;
953
954 for (idx = 0, ouridx = 0; idx < SOURCE_INFO_SIZE(as); idx++) {
955 si = &as->source_info[ouridx];
956 if (as->type == AC97_CODEC_TYPE_MODEM) {
957 if (!ac97_check_capability(as,
958 modem_source_info[idx].req_feature))
959 continue;
960 memcpy(si, &modem_source_info[idx], sizeof(*si));
961 } else {
962 if (!ac97_check_capability(as,
963 audio_source_info[idx].req_feature))
964 continue;
965 memcpy(si, &audio_source_info[idx], sizeof(*si));
966 }
967
968 switch (si->type) {
969 case AUDIO_MIXER_CLASS:
970 si->mixer_class = ouridx;
971 ouridx++;
972 break;
973 case AUDIO_MIXER_VALUE:
974 /* Todo - Test to see if it works */
975 ouridx++;
976
977 /* Add an entry for mute, if necessary */
978 if (si->mute) {
979 si = &as->source_info[ouridx];
980 if (as->type == AC97_CODEC_TYPE_MODEM)
981 memcpy(si, &modem_source_info[idx],
982 sizeof(*si));
983 else
984 memcpy(si, &audio_source_info[idx],
985 sizeof(*si));
986 si->qualifier = AudioNmute;
987 si->type = AUDIO_MIXER_ENUM;
988 si->info = &ac97_on_off;
989 si->info_size = sizeof(ac97_on_off);
990 si->bits = 1;
991 si->ofs = 15;
992 si->mute = 0;
993 si->polarity = 0;
994 ouridx++;
995 }
996 break;
997 case AUDIO_MIXER_ENUM:
998 /* Todo - Test to see if it works */
999 ouridx++;
1000 break;
1001 default:
1002 aprint_error ("ac97: shouldn't get here\n");
1003 break;
1004 }
1005 }
1006
1007 as->num_source_info = ouridx;
1008
1009 for (idx = 0; idx < as->num_source_info; idx++) {
1010 int idx2, previdx;
1011
1012 si = &as->source_info[idx];
1013
1014 /* Find mixer class */
1015 for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
1016 si2 = &as->source_info[idx2];
1017
1018 if (si2->type == AUDIO_MIXER_CLASS &&
1019 ac97_str_equal(si->class,
1020 si2->class)) {
1021 si->mixer_class = idx2;
1022 }
1023 }
1024
1025
1026 /* Setup prev and next pointers */
1027 if (si->prev != 0)
1028 continue;
1029
1030 if (si->qualifier)
1031 continue;
1032
1033 si->prev = AUDIO_MIXER_LAST;
1034 previdx = idx;
1035
1036 for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
1037 if (idx2 == idx)
1038 continue;
1039
1040 si2 = &as->source_info[idx2];
1041
1042 if (!si2->prev &&
1043 ac97_str_equal(si->class, si2->class) &&
1044 ac97_str_equal(si->device, si2->device)) {
1045 as->source_info[previdx].next = idx2;
1046 as->source_info[idx2].prev = previdx;
1047
1048 previdx = idx2;
1049 }
1050 }
1051
1052 as->source_info[previdx].next = AUDIO_MIXER_LAST;
1053 }
1054 }
1055
1056 /* backward compatibility */
1057 int
1058 ac97_attach(struct ac97_host_if *host_if, struct device *sc_dev)
1059 {
1060 return ac97_attach_type(host_if, sc_dev, AC97_CODEC_TYPE_AUDIO);
1061 }
1062
1063 int
1064 ac97_attach_type(struct ac97_host_if *host_if, struct device *sc_dev, int type)
1065 {
1066 struct ac97_softc *as;
1067 int error, i, j;
1068 uint32_t id;
1069 uint16_t id1, id2;
1070 uint16_t extstat, rate;
1071 uint16_t val;
1072 mixer_ctrl_t ctl;
1073 void (*initfunc)(struct ac97_softc *);
1074 #define FLAGBUFLEN 140
1075 char flagbuf[FLAGBUFLEN];
1076
1077 initfunc = NULL;
1078 as = malloc(sizeof(struct ac97_softc), M_DEVBUF, M_WAITOK|M_ZERO);
1079
1080 if (as == NULL)
1081 return ENOMEM;
1082
1083 as->codec_if.vtbl = &ac97civ;
1084 as->host_if = host_if;
1085 as->type = type;
1086
1087 if ((error = host_if->attach(host_if->arg, &as->codec_if))) {
1088 free(as, M_DEVBUF);
1089 return error;
1090 }
1091
1092 if (host_if->reset != NULL) {
1093 if ((error = host_if->reset(host_if->arg))) {
1094 free(as, M_DEVBUF);
1095 return error;
1096 }
1097 }
1098
1099 if (host_if->flags)
1100 as->host_flags = host_if->flags(host_if->arg);
1101
1102 /*
1103 * Assume codec has all four power bits.
1104 * XXXSCW: what to do for modems?
1105 */
1106 as->power_all = AC97_POWER_REF | AC97_POWER_ANL | AC97_POWER_DAC |
1107 AC97_POWER_ADC;
1108 if (as->type == AC97_CODEC_TYPE_AUDIO) {
1109 host_if->write(host_if->arg, AC97_REG_RESET, 0);
1110
1111 /*
1112 * Power-up everything except the analogue mixer.
1113 * If this codec doesn't support analogue mixer power-down,
1114 * AC97_POWER_MIXER will read back as zero.
1115 */
1116 host_if->write(host_if->arg, AC97_REG_POWER, AC97_POWER_MIXER);
1117 ac97_read(as, AC97_REG_POWER, &val);
1118 if ((val & AC97_POWER_MIXER) == 0) {
1119 /* Codec doesn't support analogue mixer power-down */
1120 as->power_all &= ~AC97_POWER_ANL;
1121 }
1122 host_if->write(host_if->arg, AC97_REG_POWER, POWER_EAMP_ON(as));
1123
1124 for (i = 500000; i >= 0; i--) {
1125 ac97_read(as, AC97_REG_POWER, &val);
1126 if ((val & as->power_all) == as->power_all)
1127 break;
1128 DELAY(1);
1129 }
1130
1131 /* save AC97_REG_POWER so that we can restore it later */
1132 ac97_read(as, AC97_REG_POWER, &as->power_reg);
1133 } else if (as->type == AC97_CODEC_TYPE_MODEM) {
1134 host_if->write(host_if->arg, AC97_REG_EXT_MODEM_ID, 0);
1135 }
1136
1137 ac97_setup_defaults(as);
1138 if (as->type == AC97_CODEC_TYPE_AUDIO)
1139 ac97_read(as, AC97_REG_RESET, &as->caps);
1140 ac97_read(as, AC97_REG_VENDOR_ID1, &id1);
1141 ac97_read(as, AC97_REG_VENDOR_ID2, &id2);
1142
1143 id = (id1 << 16) | id2;
1144 aprint_normal("%s: ac97: ", sc_dev->dv_xname);
1145
1146 for (i = 0; ; i++) {
1147 if (ac97codecid[i].id == 0) {
1148 char pnp[4];
1149
1150 AC97_GET_CODEC_ID(id, pnp);
1151 #define ISASCII(c) ((c) >= ' ' && (c) < 0x7f)
1152 if (ISASCII(pnp[0]) && ISASCII(pnp[1]) &&
1153 ISASCII(pnp[2]))
1154 aprint_normal("%c%c%c%d",
1155 pnp[0], pnp[1], pnp[2], pnp[3]);
1156 else
1157 aprint_normal("unknown (0x%08x)", id);
1158 break;
1159 }
1160 if (ac97codecid[i].id == (id & ac97codecid[i].mask)) {
1161 aprint_normal("%s", ac97codecid[i].name);
1162 if (ac97codecid[i].mask == AC97_VENDOR_ID_MASK) {
1163 aprint_normal(" (0x%08x)", id);
1164 }
1165 initfunc = ac97codecid[i].init;
1166 break;
1167 }
1168 }
1169 aprint_normal(" codec; ");
1170 for (i = j = 0; i < 10; i++) {
1171 if (as->caps & (1 << i)) {
1172 aprint_normal("%s%s", j ? ", " : "", ac97feature[i]);
1173 j++;
1174 }
1175 }
1176 aprint_normal("%s%s\n", j ? ", " : "",
1177 ac97enhancement[AC97_CAPS_ENHANCEMENT(as->caps)]);
1178
1179 as->ac97_clock = AC97_STANDARD_CLOCK;
1180
1181 if (as->type == AC97_CODEC_TYPE_AUDIO) {
1182 ac97_read(as, AC97_REG_EXT_AUDIO_ID, &as->ext_id);
1183 if (as->ext_id != 0) {
1184 /* Print capabilities */
1185 bitmask_snprintf(as->ext_id,
1186 "\20\20SECONDARY10\17SECONDARY01"
1187 "\14AC97_23\13AC97_22\12AMAP\11LDAC\10SDAC"
1188 "\7CDAC\4VRM\3SPDIF\2DRA\1VRA",
1189 flagbuf, FLAGBUFLEN);
1190 aprint_normal("%s: ac97: ext id %s\n", sc_dev->dv_xname,
1191 flagbuf);
1192
1193 /* Print unusual settings */
1194 if (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) {
1195 aprint_normal("%s: ac97: Slot assignment: ",
1196 sc_dev->dv_xname);
1197 switch (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) {
1198 case AC97_EXT_AUDIO_DSA01:
1199 aprint_normal("7&8, 6&9, 10&11.\n");
1200 break;
1201 case AC97_EXT_AUDIO_DSA10:
1202 aprint_normal("6&9, 10&11, 3&4.\n");
1203 break;
1204 case AC97_EXT_AUDIO_DSA11:
1205 aprint_normal("10&11, 3&4, 7&8.\n");
1206 break;
1207 }
1208 }
1209 if (as->host_flags & AC97_HOST_INVERTED_EAMP) {
1210 aprint_normal("%s: ac97: using inverted "
1211 "AC97_POWER_EAMP bit\n",
1212 sc_dev->dv_xname);
1213 }
1214
1215 /* Enable and disable features */
1216 ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &extstat);
1217 extstat &= ~AC97_EXT_AUDIO_DRA;
1218 if (as->ext_id & AC97_EXT_AUDIO_LDAC)
1219 extstat |= AC97_EXT_AUDIO_LDAC;
1220 if (as->ext_id & AC97_EXT_AUDIO_SDAC)
1221 extstat |= AC97_EXT_AUDIO_SDAC;
1222 if (as->ext_id & AC97_EXT_AUDIO_CDAC)
1223 extstat |= AC97_EXT_AUDIO_CDAC;
1224 if (as->ext_id & AC97_EXT_AUDIO_VRM)
1225 extstat |= AC97_EXT_AUDIO_VRM;
1226 if (as->ext_id & AC97_EXT_AUDIO_SPDIF) {
1227 /* Output the same data as DAC to SPDIF output */
1228 extstat &= ~AC97_EXT_AUDIO_SPSA_MASK;
1229 extstat |= AC97_EXT_AUDIO_SPSA34;
1230 }
1231 if (as->ext_id & AC97_EXT_AUDIO_VRA)
1232 extstat |= AC97_EXT_AUDIO_VRA;
1233 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, extstat);
1234 if (as->ext_id & AC97_EXT_AUDIO_VRA) {
1235 /* VRA should be enabled. */
1236 /* so it claims to do variable rate, let's make sure */
1237 ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE,
1238 44100);
1239 ac97_read(as, AC97_REG_PCM_FRONT_DAC_RATE,
1240 &rate);
1241 if (rate != 44100) {
1242 /* We can't believe ext_id */
1243 as->ext_id = 0;
1244 aprint_normal(
1245 "%s: Ignore these capabilities.\n",
1246 sc_dev->dv_xname);
1247 }
1248 /* restore the default value */
1249 ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE,
1250 AC97_SINGLE_RATE);
1251 }
1252 }
1253 } else if (as->type == AC97_CODEC_TYPE_MODEM) {
1254 const struct sysctlnode *node;
1255 const struct sysctlnode *node_line1;
1256 const struct sysctlnode *node_line2;
1257 uint16_t xrate = 8000;
1258 uint16_t xval, reg;
1259 int err;
1260
1261 ac97_read(as, AC97_REG_EXT_MODEM_ID, &as->ext_mid);
1262 if (as->ext_mid == 0 || as->ext_mid == 0xffff) {
1263 aprint_normal("%s: no modem codec found\n",
1264 sc_dev->dv_xname);
1265 return ENXIO;
1266 }
1267 as->type = AC97_CODEC_TYPE_MODEM;
1268
1269 /* Print capabilities */
1270 bitmask_snprintf(as->ext_mid,
1271 "\20\5CID2\4CID1\3HANDSET\2LINE2\1LINE1",
1272 flagbuf, FLAGBUFLEN);
1273 aprint_normal("%s: ac97: ext mid %s", sc_dev->dv_xname,
1274 flagbuf);
1275 aprint_normal(", %s codec\n",
1276 (as->ext_mid & 0xc000) == 0 ?
1277 "primary" : "secondary");
1278
1279 /* Setup modem and sysctls */
1280 err = sysctl_createv(&as->log, 0, NULL, NULL, 0, CTLTYPE_NODE,
1281 "hw", NULL, NULL, 0, NULL, 0, CTL_HW,
1282 CTL_EOL);
1283 if (err != 0)
1284 goto setup_modem;
1285 err = sysctl_createv(&as->log, 0, NULL, &node, 0,
1286 CTLTYPE_NODE, sc_dev->dv_xname, NULL,
1287 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE,
1288 CTL_EOL);
1289 if (err != 0)
1290 goto setup_modem;
1291 setup_modem:
1292 /* reset */
1293 ac97_write(as, AC97_REG_EXT_MODEM_ID, 1);
1294
1295 /* program rates */
1296 xval = 0xff00 & ~AC97_EXT_MODEM_CTRL_PRA;
1297 if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
1298 ac97_write(as, AC97_REG_LINE1_RATE, xrate);
1299 xval &= ~(AC97_EXT_MODEM_CTRL_PRC |
1300 AC97_EXT_MODEM_CTRL_PRD);
1301 }
1302 if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
1303 ac97_write(as, AC97_REG_LINE2_RATE, xrate);
1304 xval &= ~(AC97_EXT_MODEM_CTRL_PRE |
1305 AC97_EXT_MODEM_CTRL_PRF);
1306 }
1307 if (as->ext_mid & AC97_EXT_MODEM_HANDSET) {
1308 ac97_write(as, AC97_REG_HANDSET_RATE, xrate);
1309 xval &= ~(AC97_EXT_MODEM_CTRL_PRG |
1310 AC97_EXT_MODEM_CTRL_PRH);
1311 }
1312
1313 /* power-up everything */
1314 ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 0);
1315 for (i = 5000; i >= 0; i--) {
1316 ac97_read(as, AC97_REG_EXT_MODEM_CTRL, ®);
1317 if ((reg & /*XXXval*/0xf) == /*XXXval*/0xf)
1318 break;
1319 DELAY(1);
1320 }
1321 if (i <= 0) {
1322 printf("%s: codec not responding, status=0x%x\n",
1323 sc_dev->dv_xname, reg);
1324 return ENXIO;
1325 }
1326
1327 /* setup sysctls */
1328 if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
1329 ac97_read(as, AC97_REG_GPIO_CFG, ®);
1330 reg &= ~AC97_GPIO_LINE1_OH;
1331 ac97_write(as, AC97_REG_GPIO_CFG, reg);
1332 ac97_read(as, AC97_REG_GPIO_POLARITY, ®);
1333 reg &= ~AC97_GPIO_LINE1_OH;
1334 ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
1335
1336 err = sysctl_createv(&as->log, 0, NULL, &node_line1,
1337 CTLFLAG_READWRITE, CTLTYPE_INT,
1338 "line1",
1339 SYSCTL_DESCR("off-hook line1"),
1340 ac97_sysctl_verify, 0, as, 0,
1341 CTL_HW, node->sysctl_num,
1342 CTL_CREATE, CTL_EOL);
1343 if (err != 0)
1344 goto sysctl_err;
1345 as->offhook_line1_mib = node_line1->sysctl_num;
1346 }
1347 if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
1348 ac97_read(as, AC97_REG_GPIO_CFG, ®);
1349 reg &= ~AC97_GPIO_LINE2_OH;
1350 ac97_write(as, AC97_REG_GPIO_CFG, reg);
1351 ac97_read(as, AC97_REG_GPIO_POLARITY, ®);
1352 reg &= ~AC97_GPIO_LINE2_OH;
1353 ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
1354
1355 err = sysctl_createv(&as->log, 0, NULL, &node_line2,
1356 CTLFLAG_READWRITE, CTLTYPE_INT,
1357 "line2",
1358 SYSCTL_DESCR("off-hook line2"),
1359 ac97_sysctl_verify, 0, as, 0,
1360 CTL_HW, node->sysctl_num,
1361 CTL_CREATE, CTL_EOL);
1362 if (err != 0)
1363 goto sysctl_err;
1364 as->offhook_line2_mib = node_line2->sysctl_num;
1365 }
1366 sysctl_err:
1367
1368 ac97_write(as, AC97_REG_GPIO_STICKY, 0xffff);
1369 ac97_write(as, AC97_REG_GPIO_WAKEUP, 0x0);
1370 ac97_write(as, AC97_REG_MISC_AFE, 0x0);
1371 }
1372
1373 as->source_info = (as->type == AC97_CODEC_TYPE_MODEM ?
1374 as->modem_source_info : as->audio_source_info);
1375 ac97_setup_source_info(as);
1376
1377 memset(&ctl, 0, sizeof(ctl));
1378 /* disable mutes */
1379 for (i = 0; i < 11; i++) {
1380 static struct {
1381 const char *class, *device;
1382 } d[11] = {
1383 { AudioCoutputs, AudioNmaster},
1384 { AudioCoutputs, AudioNheadphone},
1385 { AudioCoutputs, AudioNsurround},
1386 { AudioCoutputs, AudioNcenter},
1387 { AudioCoutputs, AudioNlfe},
1388 { AudioCinputs, AudioNdac},
1389 { AudioCinputs, AudioNcd},
1390 { AudioCinputs, AudioNline},
1391 { AudioCinputs, AudioNaux},
1392 { AudioCinputs, AudioNvideo},
1393 { AudioCrecord, AudioNvolume},
1394 };
1395
1396 ctl.type = AUDIO_MIXER_ENUM;
1397 ctl.un.ord = 0;
1398
1399 ctl.dev = ac97_get_portnum_by_name(&as->codec_if,
1400 d[i].class, d[i].device, AudioNmute);
1401 ac97_mixer_set_port(&as->codec_if, &ctl);
1402 }
1403 ctl.type = AUDIO_MIXER_ENUM;
1404 ctl.un.ord = 0;
1405 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCrecord,
1406 AudioNsource, NULL);
1407 ac97_mixer_set_port(&as->codec_if, &ctl);
1408
1409 /* set a reasonable default volume */
1410 ctl.type = AUDIO_MIXER_VALUE;
1411 ctl.un.value.num_channels = 2;
1412 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = \
1413 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127;
1414 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
1415 AudioNmaster, NULL);
1416 ac97_mixer_set_port(&as->codec_if, &ctl);
1417 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
1418 AudioNsurround, NULL);
1419 ac97_mixer_set_port(&as->codec_if, &ctl);
1420 ctl.un.value.num_channels = 1;
1421 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
1422 AudioNcenter, NULL);
1423 ac97_mixer_set_port(&as->codec_if, &ctl);
1424 ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
1425 AudioNlfe, NULL);
1426 ac97_mixer_set_port(&as->codec_if, &ctl);
1427
1428 if (initfunc != NULL)
1429 initfunc(as);
1430
1431 /* restore AC97_REG_POWER */
1432 if (as->type == AC97_CODEC_TYPE_AUDIO)
1433 ac97_write(as, AC97_REG_POWER, as->power_reg);
1434
1435 return 0;
1436 }
1437
1438 static void
1439 ac97_detach(struct ac97_codec_if *codec_if)
1440 {
1441 struct ac97_softc *as;
1442
1443 as = (struct ac97_softc *)codec_if;
1444 ac97_write(as, AC97_REG_POWER, AC97_POWER_IN | AC97_POWER_OUT
1445 | AC97_POWER_MIXER | AC97_POWER_MIXER_VREF
1446 | AC97_POWER_ACLINK | AC97_POWER_CLK | AC97_POWER_AUX
1447 | POWER_EAMP_OFF(as));
1448 free(as, M_DEVBUF);
1449 }
1450
1451 static int
1452 ac97_query_devinfo(struct ac97_codec_if *codec_if, mixer_devinfo_t *dip)
1453 {
1454 struct ac97_softc *as;
1455 struct ac97_source_info *si;
1456 const char *name;
1457
1458 as = (struct ac97_softc *)codec_if;
1459 if (dip->index < as->num_source_info) {
1460 si = &as->source_info[dip->index];
1461 dip->type = si->type;
1462 dip->mixer_class = si->mixer_class;
1463 dip->prev = si->prev;
1464 dip->next = si->next;
1465
1466 if (si->qualifier)
1467 name = si->qualifier;
1468 else if (si->device)
1469 name = si->device;
1470 else if (si->class)
1471 name = si->class;
1472 else
1473 name = 0;
1474
1475 if (name)
1476 strcpy(dip->label.name, name);
1477
1478 memcpy(&dip->un, si->info, si->info_size);
1479
1480 /* Set the delta for volume sources */
1481 if (dip->type == AUDIO_MIXER_VALUE)
1482 dip->un.v.delta = 1 << (8 - si->bits);
1483
1484 return 0;
1485 }
1486
1487 return ENXIO;
1488 }
1489
1490 static int
1491 ac97_mixer_set_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
1492 {
1493 struct ac97_softc *as;
1494 struct ac97_source_info *si;
1495 uint16_t mask;
1496 uint16_t val, newval;
1497 int error;
1498
1499 as = (struct ac97_softc *)codec_if;
1500 si = &as->source_info[cp->dev];
1501 if (cp->dev < 0 || cp->dev >= as->num_source_info)
1502 return EINVAL;
1503
1504 if (cp->type != si->type)
1505 return EINVAL;
1506
1507 ac97_read(as, si->reg, &val);
1508
1509 DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
1510
1511 mask = (1 << si->bits) - 1;
1512
1513 switch (cp->type) {
1514 case AUDIO_MIXER_ENUM:
1515 if (cp->un.ord > mask || cp->un.ord < 0)
1516 return EINVAL;
1517
1518 newval = (cp->un.ord << si->ofs);
1519 if (si->reg == AC97_REG_RECORD_SELECT) {
1520 newval |= (newval << (8 + si->ofs));
1521 mask |= (mask << 8);
1522 mask = mask << si->ofs;
1523 } else if (si->reg == AC97_REG_SURR_MASTER) {
1524 newval = cp->un.ord ? 0x8080 : 0x0000;
1525 mask = 0x8080;
1526 } else
1527 mask = mask << si->ofs;
1528 break;
1529 case AUDIO_MIXER_VALUE:
1530 {
1531 const struct audio_mixer_value *value = si->info;
1532 uint16_t l, r, ol, or;
1533 int deltal, deltar;
1534
1535 if ((cp->un.value.num_channels <= 0) ||
1536 (cp->un.value.num_channels > value->num_channels))
1537 return EINVAL;
1538
1539 if (cp->un.value.num_channels == 1) {
1540 l = r = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1541 } else {
1542 if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
1543 l = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1544 r = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1545 } else { /* left/right is reversed here */
1546 r = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1547 l = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1548 }
1549
1550 }
1551
1552 if (!si->polarity) {
1553 l = 255 - l;
1554 r = 255 - r;
1555 }
1556
1557 ol = (val >> (8+si->ofs)) & mask;
1558 or = (val >> si->ofs) & mask;
1559
1560 deltal = (ol << (8 - si->bits)) - l;
1561 deltar = (or << (8 - si->bits)) - r;
1562
1563 l = l >> (8 - si->bits);
1564 r = r >> (8 - si->bits);
1565
1566 if (deltal && ol == l)
1567 l += (deltal > 0) ? (l ? -1 : 0) : (l < mask ? 1 : 0);
1568 if (deltar && or == r)
1569 r += (deltar > 0) ? (r ? -1 : 0) : (r < mask ? 1 : 0);
1570
1571 newval = ((r & mask) << si->ofs);
1572 if (value->num_channels == 2) {
1573 newval = newval | ((l & mask) << (si->ofs+8));
1574 mask |= (mask << 8);
1575 }
1576 mask = mask << si->ofs;
1577 break;
1578 }
1579 default:
1580 return EINVAL;
1581 }
1582
1583 error = ac97_write(as, si->reg, (val & ~mask) | newval);
1584 if (error)
1585 return error;
1586
1587 return 0;
1588 }
1589
1590 static int
1591 ac97_get_portnum_by_name(struct ac97_codec_if *codec_if, const char *class,
1592 const char *device, const char *qualifier)
1593 {
1594 struct ac97_softc *as;
1595 int idx;
1596
1597 as = (struct ac97_softc *)codec_if;
1598 for (idx = 0; idx < as->num_source_info; idx++) {
1599 struct ac97_source_info *si = &as->source_info[idx];
1600 if (ac97_str_equal(class, si->class) &&
1601 ac97_str_equal(device, si->device) &&
1602 ac97_str_equal(qualifier, si->qualifier))
1603 return idx;
1604 }
1605
1606 return -1;
1607 }
1608
1609 static int
1610 ac97_mixer_get_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
1611 {
1612 struct ac97_softc *as;
1613 struct ac97_source_info *si;
1614 uint16_t mask;
1615 uint16_t val;
1616
1617 as = (struct ac97_softc *)codec_if;
1618 si = &as->source_info[cp->dev];
1619 if (cp->dev < 0 || cp->dev >= as->num_source_info)
1620 return EINVAL;
1621
1622 if (cp->type != si->type)
1623 return EINVAL;
1624
1625 ac97_read(as, si->reg, &val);
1626
1627 DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
1628
1629 mask = (1 << si->bits) - 1;
1630
1631 switch (cp->type) {
1632 case AUDIO_MIXER_ENUM:
1633 cp->un.ord = (val >> si->ofs) & mask;
1634 DPRINTFN(4, ("AUDIO_MIXER_ENUM: %x %d %x %d\n",
1635 val, si->ofs, mask, cp->un.ord));
1636 break;
1637 case AUDIO_MIXER_VALUE:
1638 {
1639 const struct audio_mixer_value *value = si->info;
1640 uint16_t l, r;
1641
1642 if ((cp->un.value.num_channels <= 0) ||
1643 (cp->un.value.num_channels > value->num_channels))
1644 return EINVAL;
1645
1646 if (value->num_channels == 1) {
1647 l = r = (val >> si->ofs) & mask;
1648 } else {
1649 if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
1650 l = (val >> (si->ofs + 8)) & mask;
1651 r = (val >> si->ofs) & mask;
1652 } else { /* host has reversed channels */
1653 r = (val >> (si->ofs + 8)) & mask;
1654 l = (val >> si->ofs) & mask;
1655 }
1656 }
1657
1658 l = (l << (8 - si->bits));
1659 r = (r << (8 - si->bits));
1660 if (!si->polarity) {
1661 l = 255 - l;
1662 r = 255 - r;
1663 }
1664
1665 /* The EAP driver averages l and r for stereo
1666 channels that are requested in MONO mode. Does this
1667 make sense? */
1668 if (cp->un.value.num_channels == 1) {
1669 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = l;
1670 } else if (cp->un.value.num_channels == 2) {
1671 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
1672 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
1673 }
1674
1675 break;
1676 }
1677 default:
1678 return EINVAL;
1679 }
1680
1681 return 0;
1682 }
1683
1684
1685 static int
1686 ac97_set_rate(struct ac97_codec_if *codec_if, int target, u_int *rate)
1687 {
1688 struct ac97_softc *as;
1689 u_int value;
1690 uint16_t ext_stat;
1691 uint16_t actual;
1692 uint16_t power;
1693 uint16_t power_bit;
1694
1695 as = (struct ac97_softc *)codec_if;
1696 if (target == AC97_REG_PCM_MIC_ADC_RATE) {
1697 if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) {
1698 *rate = AC97_SINGLE_RATE;
1699 return 0;
1700 }
1701 } else {
1702 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
1703 *rate = AC97_SINGLE_RATE;
1704 return 0;
1705 }
1706 }
1707 value = *rate * AC97_STANDARD_CLOCK / as->ac97_clock;
1708 ext_stat = 0;
1709 /*
1710 * PCM_FRONT_DAC_RATE/PCM_SURR_DAC_RATE/PCM_LFE_DAC_RATE
1711 * Check VRA, DRA
1712 * PCM_LR_ADC_RATE
1713 * Check VRA
1714 * PCM_MIC_ADC_RATE
1715 * Check VRM
1716 */
1717 switch (target) {
1718 case AC97_REG_PCM_FRONT_DAC_RATE:
1719 case AC97_REG_PCM_SURR_DAC_RATE:
1720 case AC97_REG_PCM_LFE_DAC_RATE:
1721 power_bit = AC97_POWER_OUT;
1722 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
1723 *rate = AC97_SINGLE_RATE;
1724 return 0;
1725 }
1726 if (as->ext_id & AC97_EXT_AUDIO_DRA) {
1727 ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &ext_stat);
1728 if (value > 0x1ffff) {
1729 return EINVAL;
1730 } else if (value > 0xffff) {
1731 /* Enable DRA */
1732 ext_stat |= AC97_EXT_AUDIO_DRA;
1733 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
1734 value /= 2;
1735 } else {
1736 /* Disable DRA */
1737 ext_stat &= ~AC97_EXT_AUDIO_DRA;
1738 ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
1739 }
1740 } else {
1741 if (value > 0xffff)
1742 return EINVAL;
1743 }
1744 break;
1745 case AC97_REG_PCM_LR_ADC_RATE:
1746 power_bit = AC97_POWER_IN;
1747 if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
1748 *rate = AC97_SINGLE_RATE;
1749 return 0;
1750 }
1751 if (value > 0xffff)
1752 return EINVAL;
1753 break;
1754 case AC97_REG_PCM_MIC_ADC_RATE:
1755 power_bit = AC97_POWER_IN;
1756 if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) {
1757 *rate = AC97_SINGLE_RATE;
1758 return 0;
1759 }
1760 if (value > 0xffff)
1761 return EINVAL;
1762 break;
1763 default:
1764 printf("%s: Unknown register: 0x%x\n", __func__, target);
1765 return EINVAL;
1766 }
1767
1768 ac97_read(as, AC97_REG_POWER, &power);
1769 ac97_write(as, AC97_REG_POWER, power | power_bit);
1770
1771 ac97_write(as, target, (uint16_t)value);
1772 ac97_read(as, target, &actual);
1773 actual = (uint32_t)actual * as->ac97_clock / AC97_STANDARD_CLOCK;
1774
1775 ac97_write(as, AC97_REG_POWER, power);
1776 if (ext_stat & AC97_EXT_AUDIO_DRA) {
1777 *rate = actual * 2;
1778 } else {
1779 *rate = actual;
1780 }
1781 return 0;
1782 }
1783
1784 static void
1785 ac97_set_clock(struct ac97_codec_if *codec_if, unsigned int clock)
1786 {
1787 struct ac97_softc *as;
1788
1789 as = (struct ac97_softc *)codec_if;
1790 as->ac97_clock = clock;
1791 }
1792
1793 static uint16_t
1794 ac97_get_extcaps(struct ac97_codec_if *codec_if)
1795 {
1796 struct ac97_softc *as;
1797
1798 as = (struct ac97_softc *)codec_if;
1799 return as->ext_id;
1800 }
1801
1802 static int
1803 ac97_add_port(struct ac97_softc *as, const struct ac97_source_info *src)
1804 {
1805 struct ac97_source_info *si;
1806 int ouridx, idx;
1807
1808 if ((as->type == AC97_CODEC_TYPE_AUDIO &&
1809 as->num_source_info >= AUDIO_MAX_SOURCES) ||
1810 (as->type == AC97_CODEC_TYPE_MODEM &&
1811 as->num_source_info >= MODEM_MAX_SOURCES)) {
1812 printf("%s: internal error: increase MAX_SOURCES in %s\n",
1813 __func__, __FILE__);
1814 return -1;
1815 }
1816 if (!ac97_check_capability(as, src->req_feature))
1817 return -1;
1818 ouridx = as->num_source_info;
1819 si = &as->source_info[ouridx];
1820 memcpy(si, src, sizeof(*si));
1821
1822 switch (si->type) {
1823 case AUDIO_MIXER_CLASS:
1824 case AUDIO_MIXER_VALUE:
1825 printf("%s: adding class/value is not supported yet.\n",
1826 __func__);
1827 return -1;
1828 case AUDIO_MIXER_ENUM:
1829 break;
1830 default:
1831 printf("%s: unknown type: %d\n", __func__, si->type);
1832 return -1;
1833 }
1834 as->num_source_info++;
1835
1836 si->mixer_class = ac97_get_portnum_by_name(&as->codec_if, si->class,
1837 NULL, NULL);
1838 /* Find the root of the device */
1839 idx = ac97_get_portnum_by_name(&as->codec_if, si->class,
1840 si->device, NULL);
1841 /* Find the last item */
1842 while (as->source_info[idx].next != AUDIO_MIXER_LAST)
1843 idx = as->source_info[idx].next;
1844 /* Append */
1845 as->source_info[idx].next = ouridx;
1846 si->prev = idx;
1847 si->next = AUDIO_MIXER_LAST;
1848
1849 return 0;
1850 }
1851
1852 /**
1853 * Codec-dependent initialization
1854 */
1855
1856 #define AD1980_REG_MISC 0x76
1857 #define AD1980_MISC_MBG0 0x0001 /* 0 1888/1980/1981 /1985 */
1858 #define AD1980_MISC_MBG1 0x0002 /* 1 1888/1980/1981 /1985 */
1859 #define AD1980_MISC_VREFD 0x0004 /* 2 1888/1980/1981 /1985 */
1860 #define AD1980_MISC_VREFH 0x0008 /* 3 1888/1980/1981 /1985 */
1861 #define AD1980_MISC_SRU 0x0010 /* 4 1888/1980 /1985 */
1862 #define AD1980_MISC_LOSEL 0x0020 /* 5 1888/1980/1981 /1985 */
1863 #define AD1980_MISC_2CMIC 0x0040 /* 6 1980/1981B/1985 */
1864 #define AD1980_MISC_SPRD 0x0080 /* 7 1888/1980 /1985 */
1865 #define AD1980_MISC_DMIX0 0x0100 /* 8 1888/1980 /1985 */
1866 #define AD1980_MISC_DMIX1 0x0200 /* 9 1888/1980 /1985 */
1867 #define AD1980_MISC_HPSEL 0x0400 /*10 1888/1980 /1985 */
1868 #define AD1980_MISC_CLDIS 0x0800 /*11 1888/1980 /1985 */
1869 #define AD1980_MISC_LODIS 0x1000 /*12 1888/1980/1981 /1985 */
1870 #define AD1980_MISC_MSPLT 0x2000 /*13 1888/1980/1981 /1985 */
1871 #define AD1980_MISC_AC97NC 0x4000 /*14 1888/1980 /1985 */
1872 #define AD1980_MISC_DACZ 0x8000 /*15 1888/1980/1981 /1985 */
1873 #define AD1981_REG_MISC 0x76
1874 #define AD1981_MISC_MADST 0x0010 /* 4 */
1875 #define AD1981A_MISC_MADPD 0x0040 /* 6 */
1876 #define AD1981B_MISC_MADPD 0x0080 /* 7 */
1877 #define AD1981_MISC_FMXE 0x0200 /* 9 */
1878 #define AD1981_MISC_DAM 0x0800 /*11 */
1879 static void
1880 ac97_ad198x_init(struct ac97_softc *as)
1881 {
1882 int i;
1883 uint16_t misc;
1884
1885 ac97_read(as, AD1980_REG_MISC, &misc);
1886 ac97_write(as, AD1980_REG_MISC,
1887 misc | AD1980_MISC_LOSEL | AD1980_MISC_HPSEL);
1888
1889 for (i = 0; i < as->num_source_info; i++) {
1890 if (as->source_info[i].type != AUDIO_MIXER_VALUE)
1891 continue;
1892
1893 if (as->source_info[i].reg == AC97_REG_MASTER_VOLUME)
1894 as->source_info[i].reg = AC97_REG_SURR_MASTER;
1895 else if (as->source_info[i].reg == AC97_REG_SURR_MASTER)
1896 as->source_info[i].reg = AC97_REG_MASTER_VOLUME;
1897 }
1898 }
1899
1900 #define ALC650_REG_MULTI_CHANNEL_CONTROL 0x6a
1901 #define ALC650_MCC_SLOT_MODIFY_MASK 0xc000
1902 #define ALC650_MCC_FRONTDAC_FROM_SPDIFIN 0x2000 /* 13 */
1903 #define ALC650_MCC_SPDIFOUT_FROM_ADC 0x1000 /* 12 */
1904 #define ALC650_MCC_PCM_FROM_SPDIFIN 0x0800 /* 11 */
1905 #define ALC650_MCC_MIC_OR_CENTERLFE 0x0400 /* 10 */
1906 #define ALC650_MCC_LINEIN_OR_SURROUND 0x0200 /* 9 */
1907 #define ALC650_MCC_INDEPENDENT_MASTER_L 0x0080 /* 7 */
1908 #define ALC650_MCC_INDEPENDENT_MASTER_R 0x0040 /* 6 */
1909 #define ALC650_MCC_ANALOG_TO_CENTERLFE 0x0020 /* 5 */
1910 #define ALC650_MCC_ANALOG_TO_SURROUND 0x0010 /* 4 */
1911 #define ALC650_MCC_EXCHANGE_CENTERLFE 0x0008 /* 3 */
1912 #define ALC650_MCC_CENTERLFE_DOWNMIX 0x0004 /* 2 */
1913 #define ALC650_MCC_SURROUND_DOWNMIX 0x0002 /* 1 */
1914 #define ALC650_MCC_LINEOUT_TO_SURROUND 0x0001 /* 0 */
1915 static void
1916 ac97_alc650_init(struct ac97_softc *as)
1917 {
1918 static const struct ac97_source_info sources[6] = {
1919 { AudioCoutputs, AudioNsurround, "lineinjack",
1920 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1921 ALC650_REG_MULTI_CHANNEL_CONTROL,
1922 0x0000, 1, 9, 0, 0, CHECK_SURROUND },
1923 { AudioCoutputs, AudioNsurround, "mixtofront",
1924 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1925 ALC650_REG_MULTI_CHANNEL_CONTROL,
1926 0x0000, 1, 1, 0, 0, CHECK_SURROUND },
1927 { AudioCoutputs, AudioNcenter, "micjack",
1928 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1929 ALC650_REG_MULTI_CHANNEL_CONTROL,
1930 0x0000, 1, 10, 0, 0, CHECK_CENTER },
1931 { AudioCoutputs, AudioNlfe, "micjack",
1932 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1933 ALC650_REG_MULTI_CHANNEL_CONTROL,
1934 0x0000, 1, 10, 0, 0, CHECK_LFE },
1935 { AudioCoutputs, AudioNcenter, "mixtofront",
1936 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1937 ALC650_REG_MULTI_CHANNEL_CONTROL,
1938 0x0000, 1, 2, 0, 0, CHECK_CENTER },
1939 { AudioCoutputs, AudioNlfe, "mixtofront",
1940 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1941 ALC650_REG_MULTI_CHANNEL_CONTROL,
1942 0x0000, 1, 2, 0, 0, CHECK_LFE },
1943 };
1944
1945 ac97_add_port(as, &sources[0]);
1946 ac97_add_port(as, &sources[1]);
1947 ac97_add_port(as, &sources[2]);
1948 ac97_add_port(as, &sources[3]);
1949 ac97_add_port(as, &sources[4]);
1950 ac97_add_port(as, &sources[5]);
1951 }
1952
1953 #define VT1616_REG_IO_CONTROL 0x5a
1954 #define VT1616_IC_LVL (1 << 15)
1955 #define VT1616_IC_LFECENTER_TO_FRONT (1 << 12)
1956 #define VT1616_IC_SURROUND_TO_FRONT (1 << 11)
1957 #define VT1616_IC_BPDC (1 << 10)
1958 #define VT1616_IC_DC (1 << 9)
1959 #define VT1616_IC_IB_MASK 0x000c
1960 static void
1961 ac97_vt1616_init(struct ac97_softc *as)
1962 {
1963 static const struct ac97_source_info sources[3] = {
1964 { AudioCoutputs, AudioNsurround, "mixtofront",
1965 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1966 VT1616_REG_IO_CONTROL,
1967 0x0000, 1, 11, 0, 0, CHECK_SURROUND },
1968 { AudioCoutputs, AudioNcenter, "mixtofront",
1969 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1970 VT1616_REG_IO_CONTROL,
1971 0x0000, 1, 12, 0, 0, CHECK_CENTER },
1972 { AudioCoutputs, AudioNlfe, "mixtofront",
1973 AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
1974 VT1616_REG_IO_CONTROL,
1975 0x0000, 1, 12, 0, 0, CHECK_LFE },
1976 };
1977
1978 ac97_add_port(as, &sources[0]);
1979 ac97_add_port(as, &sources[1]);
1980 ac97_add_port(as, &sources[2]);
1981 }
1982
1983 static int
1984 ac97_modem_offhook_set(struct ac97_softc *as, int line, int newval)
1985 {
1986 uint16_t val;
1987
1988 val = as->shadow_reg[AC97_REG_GPIO_STATUS >> 1];
1989 switch (newval) {
1990 case 0:
1991 val &= ~line;
1992 break;
1993 case 1:
1994 val |= line;
1995 break;
1996 }
1997 ac97_write(as, AC97_REG_GPIO_STATUS, val);
1998
1999 return 0;
2000 }
2001
2002 static int
2003 ac97_sysctl_verify(SYSCTLFN_ARGS)
2004 {
2005 int error, tmp;
2006 struct sysctlnode node;
2007 struct ac97_softc *as;
2008
2009 node = *rnode;
2010 as = rnode->sysctl_data;
2011 if (node.sysctl_num == as->offhook_line1_mib) {
2012 tmp = as->offhook_line1;
2013 node.sysctl_data = &tmp;
2014 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2015 if (error || newp == NULL)
2016 return error;
2017
2018 if (tmp < 0 || tmp > 1)
2019 return EINVAL;
2020
2021 as->offhook_line1 = tmp;
2022 ac97_modem_offhook_set(as, AC97_GPIO_LINE1_OH, tmp);
2023 } else if (node.sysctl_num == as->offhook_line2_mib) {
2024 tmp = as->offhook_line2;
2025 node.sysctl_data = &tmp;
2026 error = sysctl_lookup(SYSCTLFN_CALL(&node));
2027 if (error || newp == NULL)
2028 return error;
2029
2030 if (tmp < 0 || tmp > 1)
2031 return EINVAL;
2032
2033 as->offhook_line2 = tmp;
2034 ac97_modem_offhook_set(as, AC97_GPIO_LINE2_OH, tmp);
2035 }
2036
2037 return 0;
2038 }
2039