]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sound/pcm/ac97.c
wpa: Import wpa 2.10.
[FreeBSD/FreeBSD.git] / sys / dev / sound / pcm / ac97.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #ifdef HAVE_KERNEL_OPTION_HEADERS
30 #include "opt_snd.h"
31 #endif
32
33 #include <dev/sound/pcm/sound.h>
34 #include <dev/sound/pcm/ac97.h>
35 #include <dev/sound/pcm/ac97_patch.h>
36
37 #include <dev/pci/pcivar.h>
38
39 #include "mixer_if.h"
40
41 SND_DECLARE_FILE("$FreeBSD$");
42
43 static MALLOC_DEFINE(M_AC97, "ac97", "ac97 codec");
44
45 struct ac97mixtable_entry {
46         int reg;                /* register index               */
47                                 /* reg < 0 if inverted polarity */
48         unsigned bits:4;        /* width of control field       */
49         unsigned ofs:4;         /* offset (only if stereo=0)    */
50         unsigned stereo:1;      /* set for stereo controls      */
51         unsigned mute:1;        /* bit15 is MUTE                */
52         unsigned recidx:4;      /* index in rec mux             */
53         unsigned mask:1;        /* use only masked bits         */
54         unsigned enable:1;      /* entry is enabled             */
55 };
56
57 #define AC97_MIXER_SIZE         SOUND_MIXER_NRDEVICES
58
59 struct ac97_info {
60         kobj_t methods;
61         device_t dev;
62         void *devinfo;
63         u_int32_t id;
64         u_int32_t subvendor;
65         unsigned count, caps, se, extcaps, extid, extstat, noext:1;
66         u_int32_t flags;
67         struct ac97mixtable_entry mix[AC97_MIXER_SIZE];
68         char name[16];
69         struct mtx *lock;
70 };
71
72 struct ac97_vendorid {
73         u_int32_t   id;
74         const char *name;
75 };
76
77 struct ac97_codecid {
78         u_int32_t  id;
79         u_int8_t   stepmask;
80         u_int8_t   noext:1;
81         char      *name;
82         ac97_patch patch;
83 };
84
85 static const struct ac97mixtable_entry ac97mixtable_default[AC97_MIXER_SIZE] = {
86     /*  [offset]                        reg          bits of st mu re mk en */
87         [SOUND_MIXER_VOLUME]    = { AC97_MIX_MASTER,    5, 0, 1, 1, 6, 0, 1 },
88         [SOUND_MIXER_OGAIN]     = { AC97_MIX_AUXOUT,    5, 0, 1, 1, 0, 0, 0 },
89         [SOUND_MIXER_PHONEOUT]  = { AC97_MIX_MONO,      5, 0, 0, 1, 7, 0, 0 },
90         [SOUND_MIXER_BASS]      = { AC97_MIX_TONE,      4, 8, 0, 0, 0, 1, 0 },
91         [SOUND_MIXER_TREBLE]    = { AC97_MIX_TONE,      4, 0, 0, 0, 0, 1, 0 },
92         [SOUND_MIXER_PCM]       = { AC97_MIX_PCM,       5, 0, 1, 1, 0, 0, 1 },
93         [SOUND_MIXER_SPEAKER]   = { AC97_MIX_BEEP,      4, 1, 0, 1, 0, 0, 0 },
94         [SOUND_MIXER_LINE]      = { AC97_MIX_LINE,      5, 0, 1, 1, 5, 0, 1 },
95         [SOUND_MIXER_PHONEIN]   = { AC97_MIX_PHONE,     5, 0, 0, 1, 8, 0, 0 },
96         [SOUND_MIXER_MIC]       = { AC97_MIX_MIC,       5, 0, 0, 1, 1, 1, 1 },
97         /* use igain for the mic 20dB boost */
98         [SOUND_MIXER_IGAIN]     = { -AC97_MIX_MIC,      1, 6, 0, 0, 0, 1, 1 },
99         [SOUND_MIXER_CD]        = { AC97_MIX_CD,        5, 0, 1, 1, 2, 0, 1 },
100         [SOUND_MIXER_LINE1]     = { AC97_MIX_AUX,       5, 0, 1, 1, 4, 0, 0 },
101         [SOUND_MIXER_VIDEO]     = { AC97_MIX_VIDEO,     5, 0, 1, 1, 3, 0, 0 },
102         [SOUND_MIXER_RECLEV]    = { -AC97_MIX_RGAIN,    4, 0, 1, 1, 0, 0, 1 }
103 };
104
105 static const struct ac97_vendorid ac97vendorid[] = {
106         { 0x41445300, "Analog Devices" },
107         { 0x414b4d00, "Asahi Kasei" },
108         { 0x414c4300, "Realtek" },
109         { 0x414c4700, "Avance Logic" },
110         { 0x43525900, "Cirrus Logic" },
111         { 0x434d4900, "C-Media Electronics" },
112         { 0x43585400, "Conexant" },
113         { 0x44543000, "Diamond Technology" },
114         { 0x454d4300, "eMicro" },
115         { 0x45838300, "ESS Technology" },
116         { 0x48525300, "Intersil" },
117         { 0x49434500, "ICEnsemble" },
118         { 0x49544500, "ITE, Inc." },
119         { 0x4e534300, "National Semiconductor" },
120         { 0x50534300, "Philips Semiconductor" },
121         { 0x83847600, "SigmaTel" },
122         { 0x53494c00, "Silicon Laboratories" },
123         { 0x54524100, "TriTech" },
124         { 0x54584e00, "Texas Instruments" },
125         { 0x56494100, "VIA Technologies" },
126         { 0x57454300, "Winbond" },
127         { 0x574d4c00, "Wolfson" },
128         { 0x594d4800, "Yamaha" },
129         /* 
130          * XXX This is a fluke, really! The real vendor
131          * should be SigmaTel, not this! This should be
132          * removed someday!
133          */
134         { 0x01408300, "Creative" },
135         { 0x00000000, NULL }
136 };
137
138 static struct ac97_codecid ac97codecid[] = {
139         { 0x41445303, 0x00, 0, "AD1819",        0 },
140         { 0x41445340, 0x00, 0, "AD1881",        0 },
141         { 0x41445348, 0x00, 0, "AD1881A",       0 },
142         { 0x41445360, 0x00, 0, "AD1885",        0 },
143         { 0x41445361, 0x00, 0, "AD1886",        ad1886_patch },
144         { 0x41445362, 0x00, 0, "AD1887",        0 },
145         { 0x41445363, 0x00, 0, "AD1886A",       0 },
146         { 0x41445368, 0x00, 0, "AD1888",        ad198x_patch },
147         { 0x41445370, 0x00, 0, "AD1980",        ad198x_patch },
148         { 0x41445372, 0x00, 0, "AD1981A",       0 },
149         { 0x41445374, 0x00, 0, "AD1981B",       ad1981b_patch },
150         { 0x41445375, 0x00, 0, "AD1985",        ad198x_patch },
151         { 0x41445378, 0x00, 0, "AD1986",        ad198x_patch },
152         { 0x414b4d00, 0x00, 1, "AK4540",        0 },
153         { 0x414b4d01, 0x00, 1, "AK4542",        0 },
154         { 0x414b4d02, 0x00, 1, "AK4543",        0 },
155         { 0x414b4d06, 0x00, 0, "AK4544A",       0 },
156         { 0x454b4d07, 0x00, 0, "AK4545",        0 },
157         { 0x414c4320, 0x0f, 0, "ALC100",        0 },
158         { 0x414c4730, 0x0f, 0, "ALC101",        0 },
159         { 0x414c4710, 0x0f, 0, "ALC200",        0 },
160         { 0x414c4740, 0x0f, 0, "ALC202",        0 },
161         { 0x414c4720, 0x0f, 0, "ALC650",        0 },
162         { 0x414c4752, 0x0f, 0, "ALC250",        0 },
163         { 0x414c4760, 0x0f, 0, "ALC655",        alc655_patch },
164         { 0x414c4770, 0x0f, 0, "ALC203",        0 },
165         { 0x414c4780, 0x0f, 0, "ALC658",        0 },
166         { 0x414c4790, 0x0f, 0, "ALC850",        0 },
167         { 0x43525900, 0x07, 0, "CS4297",        0 },
168         { 0x43525910, 0x07, 0, "CS4297A",       0 },
169         { 0x43525920, 0x07, 0, "CS4294/98",     0 },
170         { 0x4352592d, 0x07, 0, "CS4294",        0 },
171         { 0x43525930, 0x07, 0, "CS4299",        0 },
172         { 0x43525940, 0x07, 0, "CS4201",        0 },
173         { 0x43525958, 0x07, 0, "CS4205",        0 },
174         { 0x43525960, 0x07, 0, "CS4291A",       0 },
175         { 0x434d4961, 0x00, 0, "CMI9739",       cmi9739_patch },
176         { 0x434d4941, 0x00, 0, "CMI9738",       0 },
177         { 0x434d4978, 0x00, 0, "CMI9761",       0 },
178         { 0x434d4982, 0x00, 0, "CMI9761",       0 },
179         { 0x434d4983, 0x00, 0, "CMI9761",       0 },
180         { 0x43585421, 0x00, 0, "HSD11246",      0 },
181         { 0x43585428, 0x07, 0, "CX20468",       0 },
182         { 0x43585430, 0x00, 0, "CX20468-21",    0 },
183         { 0x44543000, 0x00, 0, "DT0398",        0 },
184         { 0x454d4323, 0x00, 0, "EM28023",       0 },
185         { 0x454d4328, 0x00, 0, "EM28028",       0 },
186         { 0x45838308, 0x00, 0, "ES1988",        0 }, /* Formerly ES1921(?) */
187         { 0x48525300, 0x00, 0, "HMP9701",       0 },
188         { 0x49434501, 0x00, 0, "ICE1230",       0 },
189         { 0x49434511, 0x00, 0, "ICE1232",       0 },
190         { 0x49434514, 0x00, 0, "ICE1232A",      0 },
191         { 0x49434551, 0x03, 0, "VT1616",        0 }, /* Via badged ICE */
192         { 0x49544520, 0x00, 0, "ITE2226E",      0 },
193         { 0x49544560, 0x07, 0, "ITE2646E",      0 }, /* XXX: patch needed */
194         { 0x4e534340, 0x00, 0, "LM4540",        0 }, /* Spec blank on revid */
195         { 0x4e534343, 0x00, 0, "LM4543",        0 }, /* Ditto */
196         { 0x4e534346, 0x00, 0, "LM4546A",       0 },
197         { 0x4e534348, 0x00, 0, "LM4548A",       0 },
198         { 0x4e534331, 0x00, 0, "LM4549",        0 },
199         { 0x4e534349, 0x00, 0, "LM4549A",       0 },
200         { 0x4e534350, 0x00, 0, "LM4550",        0 },
201         { 0x50534301, 0x00, 0, "UCB1510",       0 },
202         { 0x50534304, 0x00, 0, "UCB1400",       0 },
203         { 0x83847600, 0x00, 0, "STAC9700/83/84",        0 },
204         { 0x83847604, 0x00, 0, "STAC9701/03/04/05", 0 },
205         { 0x83847605, 0x00, 0, "STAC9704",      0 },
206         { 0x83847608, 0x00, 0, "STAC9708/11",   0 },
207         { 0x83847609, 0x00, 0, "STAC9721/23",   0 },
208         { 0x83847644, 0x00, 0, "STAC9744/45",   0 },
209         { 0x83847650, 0x00, 0, "STAC9750/51",   0 },
210         { 0x83847652, 0x00, 0, "STAC9752/53",   0 },
211         { 0x83847656, 0x00, 0, "STAC9756/57",   0 },
212         { 0x83847658, 0x00, 0, "STAC9758/59",   0 },
213         { 0x83847660, 0x00, 0, "STAC9760/61",   0 }, /* Extrapolated */
214         { 0x83847662, 0x00, 0, "STAC9762/63",   0 }, /* Extrapolated */
215         { 0x83847666, 0x00, 0, "STAC9766/67",   0 },
216         { 0x53494c22, 0x00, 0, "Si3036",        0 },
217         { 0x53494c23, 0x00, 0, "Si3038",        0 },
218         { 0x54524103, 0x00, 0, "TR28023",       0 }, /* Extrapolated */
219         { 0x54524106, 0x00, 0, "TR28026",       0 },
220         { 0x54524108, 0x00, 0, "TR28028",       0 },
221         { 0x54524123, 0x00, 0, "TR28602",       0 },
222         { 0x54524e03, 0x07, 0, "TLV320AIC27",   0 },
223         { 0x54584e20, 0x00, 0, "TLC320AD90",    0 },
224         { 0x56494161, 0x00, 0, "VIA1612A",      0 },
225         { 0x56494170, 0x00, 0, "VIA1617A",      0 },
226         { 0x574d4c00, 0x00, 0, "WM9701A",       0 },
227         { 0x574d4c03, 0x00, 0, "WM9703/4/7/8",  0 },
228         { 0x574d4c04, 0x00, 0, "WM9704Q",       0 },
229         { 0x574d4c05, 0x00, 0, "WM9705/10",     0 },
230         { 0x574d4d09, 0x00, 0, "WM9709",        0 },
231         { 0x574d4c12, 0x00, 0, "WM9711/12",     0 }, /* XXX: patch needed */
232         { 0x57454301, 0x00, 0, "W83971D",       0 },
233         { 0x594d4800, 0x00, 0, "YMF743",        0 },
234         { 0x594d4802, 0x00, 0, "YMF752",        0 },
235         { 0x594d4803, 0x00, 0, "YMF753",        0 },
236         /* 
237          * XXX This is a fluke, really! The real codec
238          * should be STAC9704, not this! This should be
239          * removed someday!
240          */
241         { 0x01408384, 0x00, 0, "EV1938",        0 },
242         { 0, 0, 0, NULL, 0 }
243 };
244
245 static char *ac97enhancement[] = {
246         "no 3D Stereo Enhancement",
247         "Analog Devices Phat Stereo",
248         "Creative Stereo Enhancement",
249         "National Semi 3D Stereo Enhancement",
250         "Yamaha Ymersion",
251         "BBE 3D Stereo Enhancement",
252         "Crystal Semi 3D Stereo Enhancement",
253         "Qsound QXpander",
254         "Spatializer 3D Stereo Enhancement",
255         "SRS 3D Stereo Enhancement",
256         "Platform Tech 3D Stereo Enhancement",
257         "AKM 3D Audio",
258         "Aureal Stereo Enhancement",
259         "Aztech 3D Enhancement",
260         "Binaura 3D Audio Enhancement",
261         "ESS Technology Stereo Enhancement",
262         "Harman International VMAx",
263         "Nvidea 3D Stereo Enhancement",
264         "Philips Incredible Sound",
265         "Texas Instruments 3D Stereo Enhancement",
266         "VLSI Technology 3D Stereo Enhancement",
267         "TriTech 3D Stereo Enhancement",
268         "Realtek 3D Stereo Enhancement",
269         "Samsung 3D Stereo Enhancement",
270         "Wolfson Microelectronics 3D Enhancement",
271         "Delta Integration 3D Enhancement",
272         "SigmaTel 3D Enhancement",
273         "Reserved 27",
274         "Rockwell 3D Stereo Enhancement",
275         "Reserved 29",
276         "Reserved 30",
277         "Reserved 31"
278 };
279
280 static char *ac97feature[] = {
281         "mic channel",
282         "reserved",
283         "tone",
284         "simulated stereo",
285         "headphone",
286         "bass boost",
287         "18 bit DAC",
288         "20 bit DAC",
289         "18 bit ADC",
290         "20 bit ADC"
291 };
292
293 static char *ac97extfeature[] = {
294         "variable rate PCM",
295         "double rate PCM",
296         "reserved 1",
297         "variable rate mic",
298         "reserved 2",
299         "reserved 3",
300         "center DAC",
301         "surround DAC",
302         "LFE DAC",
303         "AMAP",
304         "reserved 4",
305         "reserved 5",
306         "reserved 6",
307         "reserved 7",
308 };
309
310 u_int16_t
311 ac97_rdcd(struct ac97_info *codec, int reg)
312 {
313         if (codec->flags & AC97_F_RDCD_BUG) {
314                 u_int16_t i[2], j = 100;
315
316                 i[0] = AC97_READ(codec->methods, codec->devinfo, reg);
317                 i[1] = AC97_READ(codec->methods, codec->devinfo, reg);
318                 while (i[0] != i[1] && j)
319                         i[j-- & 1] = AC97_READ(codec->methods, codec->devinfo, reg);
320 #if 0
321                 if (j < 100) {
322                         device_printf(codec->dev, "%s(): Inconsistent register value at"
323                                         " 0x%08x (retry: %d)\n", __func__, reg, 100 - j);
324                 }
325 #endif
326                 return i[!(j & 1)];
327         }
328         return AC97_READ(codec->methods, codec->devinfo, reg);
329 }
330
331 void
332 ac97_wrcd(struct ac97_info *codec, int reg, u_int16_t val)
333 {
334         AC97_WRITE(codec->methods, codec->devinfo, reg, val);
335 }
336
337 static void
338 ac97_reset(struct ac97_info *codec)
339 {
340         u_int32_t i, ps;
341         ac97_wrcd(codec, AC97_REG_RESET, 0);
342         for (i = 0; i < 500; i++) {
343                 ps = ac97_rdcd(codec, AC97_REG_POWER) & AC97_POWER_STATUS;
344                 if (ps == AC97_POWER_STATUS)
345                         return;
346                 DELAY(1000);
347         }
348         device_printf(codec->dev, "AC97 reset timed out.\n");
349 }
350
351 int
352 ac97_setrate(struct ac97_info *codec, int which, int rate)
353 {
354         u_int16_t v;
355
356         switch(which) {
357         case AC97_REGEXT_FDACRATE:
358         case AC97_REGEXT_SDACRATE:
359         case AC97_REGEXT_LDACRATE:
360         case AC97_REGEXT_LADCRATE:
361         case AC97_REGEXT_MADCRATE:
362                 break;
363
364         default:
365                 return -1;
366         }
367
368         snd_mtxlock(codec->lock);
369         if (rate != 0) {
370                 v = rate;
371                 if (codec->extstat & AC97_EXTCAP_DRA)
372                         v >>= 1;
373                 ac97_wrcd(codec, which, v);
374         }
375         v = ac97_rdcd(codec, which);
376         if (codec->extstat & AC97_EXTCAP_DRA)
377                 v <<= 1;
378         snd_mtxunlock(codec->lock);
379         return v;
380 }
381
382 int
383 ac97_setextmode(struct ac97_info *codec, u_int16_t mode)
384 {
385         mode &= AC97_EXTCAPS;
386         if ((mode & ~codec->extcaps) != 0) {
387                 device_printf(codec->dev, "ac97 invalid mode set 0x%04x\n",
388                               mode);
389                 return -1;
390         }
391         snd_mtxlock(codec->lock);
392         ac97_wrcd(codec, AC97_REGEXT_STAT, mode);
393         codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS;
394         snd_mtxunlock(codec->lock);
395         return (mode == codec->extstat)? 0 : -1;
396 }
397
398 u_int16_t
399 ac97_getextmode(struct ac97_info *codec)
400 {
401         return codec->extstat;
402 }
403
404 u_int16_t
405 ac97_getextcaps(struct ac97_info *codec)
406 {
407         return codec->extcaps;
408 }
409
410 u_int16_t
411 ac97_getcaps(struct ac97_info *codec)
412 {
413         return codec->caps;
414 }
415
416 u_int32_t
417 ac97_getsubvendor(struct ac97_info *codec)
418 {
419         return codec->subvendor;
420 }
421
422 static int
423 ac97_setrecsrc(struct ac97_info *codec, int channel)
424 {
425         struct ac97mixtable_entry *e = &codec->mix[channel];
426
427         if (e->recidx > 0) {
428                 int val = e->recidx - 1;
429                 val |= val << 8;
430                 snd_mtxlock(codec->lock);
431                 ac97_wrcd(codec, AC97_REG_RECSEL, val);
432                 snd_mtxunlock(codec->lock);
433                 return 0;
434         } else
435                 return -1;
436 }
437
438 static int
439 ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned right)
440 {
441         struct ac97mixtable_entry *e = &codec->mix[channel];
442
443         if (e->reg && e->enable && e->bits) {
444                 int mask, max, val, reg;
445
446                 reg = (e->reg >= 0) ? e->reg : -e->reg; /* AC97 register    */
447                 max = (1 << e->bits) - 1;               /* actual range     */
448                 mask = (max << 8) | max;                /* bits of interest */
449
450                 if (!e->stereo)
451                         right = left;
452
453                 /*
454                  * Invert the range if the polarity requires so,
455                  * then scale to 0..max-1 to compute the value to
456                  * write into the codec, and scale back to 0..100
457                  * for the return value.
458                  */
459                 if (e->reg > 0) {
460                         left = 100 - left;
461                         right = 100 - right;
462                 }
463
464                 left = (left * max) / 100;
465                 right = (right * max) / 100;
466
467                 val = (left << 8) | right;
468
469                 left = (left * 100) / max;
470                 right = (right * 100) / max;
471
472                 if (e->reg > 0) {
473                         left = 100 - left;
474                         right = 100 - right;
475                 }
476
477                 /*
478                  * For mono controls, trim val and mask, also taking
479                  * care of e->ofs (offset of control field).
480                  */
481                 if (e->ofs) {
482                         val &= max;
483                         val <<= e->ofs;
484                         mask = (max << e->ofs);
485                 }
486
487                 /*
488                  * If we have a mute bit, add it to the mask and
489                  * update val and set mute if both channels require a
490                  * zero volume.
491                  */
492                 if (e->mute == 1) {
493                         mask |= AC97_MUTE;
494                         if (left == 0 && right == 0)
495                                 val = AC97_MUTE;
496                 }
497
498                 /*
499                  * If the mask bit is set, do not alter the other bits.
500                  */
501                 snd_mtxlock(codec->lock);
502                 if (e->mask) {
503                         int cur = ac97_rdcd(codec, reg);
504                         val |= cur & ~(mask);
505                 }
506                 ac97_wrcd(codec, reg, val);
507                 snd_mtxunlock(codec->lock);
508                 return left | (right << 8);
509         } else {
510 #if 0
511                 printf("ac97_setmixer: reg=%d, bits=%d, enable=%d\n", e->reg, e->bits, e->enable);
512 #endif
513                 return -1;
514         }
515 }
516
517 static void
518 ac97_fix_auxout(struct ac97_info *codec)
519 {
520         int keep_ogain;
521
522         /*
523          * By default, The ac97 aux_out register (0x04) corresponds to OSS's
524          * OGAIN setting.
525          *
526          * We first check whether aux_out is a valid register.  If not
527          * we may not want to keep ogain.
528          */
529         keep_ogain = ac97_rdcd(codec, AC97_MIX_AUXOUT) & 0x8000;
530
531         /*
532          * Determine what AUX_OUT really means, it can be:
533          *
534          * 1. Headphone out.
535          * 2. 4-Channel Out
536          * 3. True line level out (effectively master volume).
537          *
538          * See Sections 5.2.1 and 5.27 for AUX_OUT Options in AC97r2.{2,3}.
539          */
540         if (codec->extcaps & AC97_EXTCAP_SDAC &&
541             ac97_rdcd(codec, AC97_MIXEXT_SURROUND) == 0x8080) {
542                 codec->mix[SOUND_MIXER_OGAIN].reg = AC97_MIXEXT_SURROUND;
543                 keep_ogain = 1;
544         }
545
546         if (keep_ogain == 0) {
547                 bzero(&codec->mix[SOUND_MIXER_OGAIN],
548                       sizeof(codec->mix[SOUND_MIXER_OGAIN]));
549         }
550 }
551
552 static void
553 ac97_fix_tone(struct ac97_info *codec)
554 {
555         /*
556          * YMF chips does not indicate tone and 3D enhancement capability
557          * in the AC97_REG_RESET register.
558          */
559         switch (codec->id) {
560         case 0x594d4800:        /* YMF743 */
561         case 0x594d4803:        /* YMF753 */
562                 codec->caps |= AC97_CAP_TONE;
563                 codec->se |= 0x04;
564                 break;
565         case 0x594d4802:        /* YMF752 */
566                 codec->se |= 0x04;
567                 break;
568         default:
569                 break;
570         }
571
572         /* Hide treble and bass if they don't exist */
573         if ((codec->caps & AC97_CAP_TONE) == 0) {
574                 bzero(&codec->mix[SOUND_MIXER_BASS],
575                       sizeof(codec->mix[SOUND_MIXER_BASS]));
576                 bzero(&codec->mix[SOUND_MIXER_TREBLE],
577                       sizeof(codec->mix[SOUND_MIXER_TREBLE]));
578         }
579 }
580
581 static const char*
582 ac97_hw_desc(u_int32_t id, const char* vname, const char* cname, char* buf)
583 {
584         if (cname == NULL) {
585                 sprintf(buf, "Unknown AC97 Codec (id = 0x%08x)", id);
586                 return buf;
587         }
588
589         if (vname == NULL) vname = "Unknown";
590
591         if (bootverbose) {
592                 sprintf(buf, "%s %s AC97 Codec (id = 0x%08x)", vname, cname, id);
593         } else {
594                 sprintf(buf, "%s %s AC97 Codec", vname, cname);
595         }
596         return buf;
597 }
598
599 static unsigned
600 ac97_initmixer(struct ac97_info *codec)
601 {
602         ac97_patch codec_patch;
603         const char *cname, *vname;
604         char desc[80];
605         device_t pdev;
606         u_int8_t model, step;
607         unsigned i, j, k, bit, old;
608         u_int32_t id;
609         int reg;
610
611         snd_mtxlock(codec->lock);
612         codec->count = AC97_INIT(codec->methods, codec->devinfo);
613         if (codec->count == 0) {
614                 device_printf(codec->dev, "ac97 codec init failed\n");
615                 snd_mtxunlock(codec->lock);
616                 return ENODEV;
617         }
618
619         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
620         ac97_reset(codec);
621         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
622
623         i = ac97_rdcd(codec, AC97_REG_RESET);
624         j = ac97_rdcd(codec, AC97_REG_RESET);
625         k = ac97_rdcd(codec, AC97_REG_RESET);
626         /*
627          * Let see if this codec can return consistent value.
628          * If not, turn on aggressive read workaround
629          * (STAC9704 comes in mind).
630          */
631         if (i != j || j != k) {
632                 codec->flags |= AC97_F_RDCD_BUG;
633                 i = ac97_rdcd(codec, AC97_REG_RESET);
634         }
635         codec->caps = i & 0x03ff;
636         codec->se =  (i & 0x7c00) >> 10;
637
638         id = (ac97_rdcd(codec, AC97_REG_ID1) << 16) | ac97_rdcd(codec, AC97_REG_ID2);
639         if (id == 0 || id == 0xffffffff) {
640                 device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id);
641                 snd_mtxunlock(codec->lock);
642                 return ENODEV;
643         }
644
645         pdev = codec->dev;
646         while (strcmp(device_get_name(device_get_parent(pdev)), "pci") != 0) {
647                 /* find the top-level PCI device handler */
648                 pdev = device_get_parent(pdev);
649         }
650         codec->id = id;
651         codec->subvendor = (u_int32_t)pci_get_subdevice(pdev) << 16;
652         codec->subvendor |= (u_int32_t)pci_get_subvendor(pdev) &
653             0x0000ffff;
654         codec->noext = 0;
655         codec_patch = NULL;
656
657         cname = NULL;
658         model = step = 0;
659         for (i = 0; ac97codecid[i].id; i++) {
660                 u_int32_t modelmask = 0xffffffff ^ ac97codecid[i].stepmask;
661                 if ((ac97codecid[i].id & modelmask) == (id & modelmask)) {
662                         codec->noext = ac97codecid[i].noext;
663                         codec_patch = ac97codecid[i].patch;
664                         cname = ac97codecid[i].name;
665                         model = (id & modelmask) & 0xff;
666                         step = (id & ~modelmask) & 0xff;
667                         break;
668                 }
669         }
670
671         vname = NULL;
672         for (i = 0; ac97vendorid[i].id; i++) {
673                 if (ac97vendorid[i].id == (id & 0xffffff00)) {
674                         vname = ac97vendorid[i].name;
675                         break;
676                 }
677         }
678
679         codec->extcaps = 0;
680         codec->extid = 0;
681         codec->extstat = 0;
682         if (!codec->noext) {
683                 i = ac97_rdcd(codec, AC97_REGEXT_ID);
684                 if (i != 0xffff) {
685                         codec->extcaps = i & 0x3fff;
686                         codec->extid =  (i & 0xc000) >> 14;
687                         codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS;
688                 }
689         }
690
691         for (i = 0; i < AC97_MIXER_SIZE; i++) {
692                 codec->mix[i] = ac97mixtable_default[i];
693         }
694         ac97_fix_auxout(codec);
695         ac97_fix_tone(codec);
696         if (codec_patch)
697                 codec_patch(codec);
698
699         for (i = 0; i < AC97_MIXER_SIZE; i++) {
700                 k = codec->noext? codec->mix[i].enable : 1;
701                 reg = codec->mix[i].reg;
702                 if (reg < 0)
703                         reg = -reg;
704                 if (k && reg) {
705                         j = old = ac97_rdcd(codec, reg);
706                         /*
707                          * Test for mute bit (except for AC97_MIX_TONE,
708                          * where we simply assume it as available).
709                          */
710                         if (codec->mix[i].mute) {
711                                 ac97_wrcd(codec, reg, j | 0x8000);
712                                 j = ac97_rdcd(codec, reg);
713                         } else
714                                 j |= 0x8000;
715                         if ((j & 0x8000)) {
716                                 /*
717                                  * Test whether the control width should be
718                                  * 4, 5 or 6 bit. For 5bit register, we should
719                                  * test it whether it's really 5 or 6bit. Leave
720                                  * 4bit register alone, because sometimes an
721                                  * attempt to write past 4th bit may cause
722                                  * incorrect result especially for AC97_MIX_BEEP
723                                  * (ac97 2.3).
724                                  */
725                                 bit = codec->mix[i].bits;
726                                 if (bit == 5)
727                                         bit++;
728                                 j = ((1 << bit) - 1) << codec->mix[i].ofs;
729                                 ac97_wrcd(codec, reg,
730                                         j | (codec->mix[i].mute ? 0x8000 : 0));
731                                 k = ac97_rdcd(codec, reg) & j;
732                                 k >>= codec->mix[i].ofs;
733                                 if (reg == AC97_MIX_TONE &&
734                                                         ((k & 0x0001) == 0x0000))
735                                         k >>= 1;
736                                 for (j = 0; k >> j; j++)
737                                         ;
738                                 if (j != 0) {
739 #if 0
740                                         device_printf(codec->dev, "%2d: [ac97_rdcd() = %d] [Testbit = %d] %d -> %d\n",
741                                                 i, k, bit, codec->mix[i].bits, j);
742 #endif
743                                         codec->mix[i].enable = 1;
744                                         codec->mix[i].bits = j;
745                                 } else if (reg == AC97_MIX_BEEP) {
746                                         /*
747                                          * Few codec such as CX20468-21 does
748                                          * have this control register, although
749                                          * the only usable part is the mute bit.
750                                          */
751                                         codec->mix[i].enable = 1;
752                                 } else
753                                         codec->mix[i].enable = 0;
754                         } else
755                                 codec->mix[i].enable = 0;
756                         ac97_wrcd(codec, reg, old);
757                 }
758 #if 0
759                 printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits);
760 #endif
761         }
762
763         device_printf(codec->dev, "<%s>\n",
764                       ac97_hw_desc(codec->id, vname, cname, desc));
765
766         if (bootverbose) {
767                 if (codec->flags & AC97_F_RDCD_BUG)
768                         device_printf(codec->dev, "Buggy AC97 Codec: aggressive ac97_rdcd() workaround enabled\n");
769                 device_printf(codec->dev, "Codec features ");
770                 for (i = j = 0; i < 10; i++)
771                         if (codec->caps & (1 << i))
772                                 printf("%s%s", j++? ", " : "", ac97feature[i]);
773                 printf("%s%d bit master volume", j++? ", " : "", codec->mix[SOUND_MIXER_VOLUME].bits);
774                 printf("%s%s\n", j? ", " : "", ac97enhancement[codec->se]);
775
776                 if (codec->extcaps != 0 || codec->extid) {
777                         device_printf(codec->dev, "%s codec",
778                                       codec->extid? "Secondary" : "Primary");
779                         if (codec->extcaps)
780                                 printf(" extended features ");
781                         for (i = j = 0; i < 14; i++)
782                                 if (codec->extcaps & (1 << i))
783                                         printf("%s%s", j++? ", " : "", ac97extfeature[i]);
784                         printf("\n");
785                 }
786         }
787
788         i = 0;
789         while ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) {
790                 if (++i == 100) {
791                         device_printf(codec->dev, "ac97 codec reports dac not ready\n");
792                         break;
793                 }
794                 DELAY(1000);
795         }
796         if (bootverbose)
797                 device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i);
798         snd_mtxunlock(codec->lock);
799         return 0;
800 }
801
802 static unsigned
803 ac97_reinitmixer(struct ac97_info *codec)
804 {
805         snd_mtxlock(codec->lock);
806         codec->count = AC97_INIT(codec->methods, codec->devinfo);
807         if (codec->count == 0) {
808                 device_printf(codec->dev, "ac97 codec init failed\n");
809                 snd_mtxunlock(codec->lock);
810                 return ENODEV;
811         }
812
813         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
814         ac97_reset(codec);
815         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
816
817         if (!codec->noext) {
818                 ac97_wrcd(codec, AC97_REGEXT_STAT, codec->extstat);
819                 if ((ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS)
820                     != codec->extstat)
821                         device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n",
822                                       codec->extstat,
823                                       ac97_rdcd(codec, AC97_REGEXT_STAT) &
824                                       AC97_EXTCAPS);
825         }
826
827         if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0)
828                 device_printf(codec->dev, "ac97 codec reports dac not ready\n");
829         snd_mtxunlock(codec->lock);
830         return 0;
831 }
832
833 struct ac97_info *
834 ac97_create(device_t dev, void *devinfo, kobj_class_t cls)
835 {
836         struct ac97_info *codec;
837         int i;
838
839         codec = malloc(sizeof(*codec), M_AC97, M_WAITOK | M_ZERO);
840         snprintf(codec->name, sizeof(codec->name), "%s:ac97",
841             device_get_nameunit(dev));
842         codec->lock = snd_mtxcreate(codec->name, "ac97 codec");
843         codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO);
844         codec->dev = dev;
845         codec->devinfo = devinfo;
846         codec->flags = 0;
847
848         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
849             "eapdinv", &i) == 0 && i != 0)
850                 codec->flags |= AC97_F_EAPD_INV;
851
852         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
853             "softpcmvol", &i) == 0 && i != 0)
854                 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SOFTPCMVOL);
855
856         return codec;
857 }
858
859 void
860 ac97_destroy(struct ac97_info *codec)
861 {
862         snd_mtxlock(codec->lock);
863         if (codec->methods != NULL)
864                 kobj_delete(codec->methods, M_AC97);
865         snd_mtxfree(codec->lock);
866         free(codec, M_AC97);
867 }
868
869 void
870 ac97_setflags(struct ac97_info *codec, u_int32_t val)
871 {
872         codec->flags = val;
873 }
874
875 u_int32_t
876 ac97_getflags(struct ac97_info *codec)
877 {
878         return codec->flags;
879 }
880
881 /* -------------------------------------------------------------------- */
882
883 static int
884 sysctl_hw_snd_ac97_eapd(SYSCTL_HANDLER_ARGS)
885 {
886         struct ac97_info *codec;
887         int ea, inv, err = 0;
888         u_int16_t val;
889
890         codec = oidp->oid_arg1;
891         if (codec == NULL || codec->id == 0 || codec->lock == NULL)
892                 return EINVAL;
893         snd_mtxlock(codec->lock);
894         val = ac97_rdcd(codec, AC97_REG_POWER);
895         inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1;
896         ea = (val >> 15) ^ inv;
897         snd_mtxunlock(codec->lock);
898         err = sysctl_handle_int(oidp, &ea, 0, req);
899         if (err == 0 && req->newptr != NULL) {
900                 if (ea != 0 && ea != 1)
901                         return EINVAL;
902                 if (ea != ((val >> 15) ^ inv)) {
903                         snd_mtxlock(codec->lock);
904                         ac97_wrcd(codec, AC97_REG_POWER, val ^ 0x8000);
905                         snd_mtxunlock(codec->lock);
906                 }
907         }
908         return err;
909 }
910
911 static void
912 ac97_init_sysctl(struct ac97_info *codec)
913 {
914         u_int16_t orig, val;
915
916         if (codec == NULL || codec->dev == NULL)
917                 return;
918         snd_mtxlock(codec->lock);
919         orig = ac97_rdcd(codec, AC97_REG_POWER);
920         ac97_wrcd(codec, AC97_REG_POWER, orig ^ 0x8000);
921         val = ac97_rdcd(codec, AC97_REG_POWER);
922         ac97_wrcd(codec, AC97_REG_POWER, orig);
923         snd_mtxunlock(codec->lock);
924         if ((val & 0x8000) == (orig & 0x8000))
925                 return;
926         SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev),
927             SYSCTL_CHILDREN(device_get_sysctl_tree(codec->dev)),
928             OID_AUTO, "eapd",
929             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
930             codec, sizeof(codec), sysctl_hw_snd_ac97_eapd,
931             "I", "AC97 External Amplifier");
932 }
933
934 static int
935 ac97mix_init(struct snd_mixer *m)
936 {
937         struct ac97_info *codec = mix_getdevinfo(m);
938         u_int32_t i, mask;
939
940         if (codec == NULL)
941                 return -1;
942
943         if (ac97_initmixer(codec))
944                 return -1;
945
946         switch (codec->id) {
947         case 0x41445374:        /* AD1981B */
948                 switch (codec->subvendor) {
949                 case 0x02d91014:
950                         /*
951                          * IBM Thinkcentre:
952                          *
953                          * Tie "ogain" and "phout" to "vol" since its
954                          * master volume is basically useless and can't
955                          * control anything.
956                          */
957                         mask = 0;
958                         if (codec->mix[SOUND_MIXER_OGAIN].enable)
959                                 mask |= SOUND_MASK_OGAIN;
960                         if (codec->mix[SOUND_MIXER_PHONEOUT].enable)
961                                 mask |= SOUND_MASK_PHONEOUT;
962                         if (codec->mix[SOUND_MIXER_VOLUME].enable)
963                                 mix_setparentchild(m, SOUND_MIXER_VOLUME,
964                                     mask);
965                         else {
966                                 mix_setparentchild(m, SOUND_MIXER_VOLUME,
967                                     mask);
968                                 mix_setrealdev(m, SOUND_MIXER_VOLUME,
969                                     SOUND_MIXER_NONE);
970                         }
971                         break;
972                 case 0x099c103c:
973                         /*
974                          * HP nx6110:
975                          *
976                          * By default, "vol" is controlling internal speakers
977                          * (not a master volume!) and "ogain" is controlling
978                          * headphone. Enable dummy "phout" so it can be
979                          * remapped to internal speakers and virtualize
980                          * "vol" to control both.
981                          */
982                         codec->mix[SOUND_MIXER_OGAIN].enable = 1;
983                         codec->mix[SOUND_MIXER_PHONEOUT].enable = 1;
984                         mix_setrealdev(m, SOUND_MIXER_PHONEOUT,
985                             SOUND_MIXER_VOLUME);
986                         mix_setrealdev(m, SOUND_MIXER_VOLUME,
987                             SOUND_MIXER_NONE);
988                         mix_setparentchild(m, SOUND_MIXER_VOLUME,
989                             SOUND_MASK_OGAIN | SOUND_MASK_PHONEOUT);
990                         break;
991                 default:
992                         break;
993                 }
994                 break;
995         case 0x434d4941:        /* CMI9738 */
996         case 0x434d4961:        /* CMI9739 */
997         case 0x434d4978:        /* CMI9761 */
998         case 0x434d4982:        /* CMI9761 */
999         case 0x434d4983:        /* CMI9761 */
1000                 bzero(&codec->mix[SOUND_MIXER_PCM],
1001                     sizeof(codec->mix[SOUND_MIXER_PCM]));
1002                 pcm_setflags(codec->dev, pcm_getflags(codec->dev) |
1003                     SD_F_SOFTPCMVOL);
1004                 /* XXX How about master volume ? */
1005                 break;
1006         default:
1007                 break;
1008         }
1009
1010         if (pcm_getflags(codec->dev) & SD_F_SOFTPCMVOL)
1011                 ac97_wrcd(codec, AC97_MIX_PCM, 0);
1012 #if 0
1013         /* XXX For the sake of debugging purposes */
1014         mix_setparentchild(m, SOUND_MIXER_VOLUME,
1015             SOUND_MASK_PCM | SOUND_MASK_CD);
1016         mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
1017         ac97_wrcd(codec, AC97_MIX_MASTER, 0);
1018 #endif
1019
1020         mask = 0;
1021         for (i = 0; i < AC97_MIXER_SIZE; i++)
1022                 mask |= codec->mix[i].enable? 1 << i : 0;
1023         mix_setdevs(m, mask);
1024
1025         mask = 0;
1026         for (i = 0; i < AC97_MIXER_SIZE; i++)
1027                 mask |= codec->mix[i].recidx? 1 << i : 0;
1028         mix_setrecdevs(m, mask);
1029
1030         ac97_init_sysctl(codec);
1031
1032         return 0;
1033 }
1034
1035 static int
1036 ac97mix_uninit(struct snd_mixer *m)
1037 {
1038         struct ac97_info *codec = mix_getdevinfo(m);
1039
1040         if (codec == NULL)
1041                 return -1;
1042         /*
1043         if (ac97_uninitmixer(codec))
1044                 return -1;
1045         */
1046         ac97_destroy(codec);
1047         return 0;
1048 }
1049
1050 static int
1051 ac97mix_reinit(struct snd_mixer *m)
1052 {
1053         struct ac97_info *codec = mix_getdevinfo(m);
1054
1055         if (codec == NULL)
1056                 return -1;
1057         return ac97_reinitmixer(codec);
1058 }
1059
1060 static int
1061 ac97mix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
1062 {
1063         struct ac97_info *codec = mix_getdevinfo(m);
1064
1065         if (codec == NULL || dev >= AC97_MIXER_SIZE)
1066                 return -1;
1067         return ac97_setmixer(codec, dev, left, right);
1068 }
1069
1070 static u_int32_t
1071 ac97mix_setrecsrc(struct snd_mixer *m, u_int32_t src)
1072 {
1073         int i;
1074         struct ac97_info *codec = mix_getdevinfo(m);
1075
1076         if (codec == NULL)
1077                 return -1;
1078         for (i = 0; i < AC97_MIXER_SIZE; i++)
1079                 if ((src & (1 << i)) != 0)
1080                         break;
1081         return (ac97_setrecsrc(codec, i) == 0)? 1U << i : 0xffffffffU;
1082 }
1083
1084 static kobj_method_t ac97mixer_methods[] = {
1085         KOBJMETHOD(mixer_init,          ac97mix_init),
1086         KOBJMETHOD(mixer_uninit,        ac97mix_uninit),
1087         KOBJMETHOD(mixer_reinit,        ac97mix_reinit),
1088         KOBJMETHOD(mixer_set,           ac97mix_set),
1089         KOBJMETHOD(mixer_setrecsrc,     ac97mix_setrecsrc),
1090         KOBJMETHOD_END
1091 };
1092 MIXER_DECLARE(ac97mixer);
1093
1094 /* -------------------------------------------------------------------- */
1095
1096 kobj_class_t
1097 ac97_getmixerclass(void)
1098 {
1099         return &ac97mixer_class;
1100 }