]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sound/pcm/ac97.c
Merge ^/head r339813 through r340125.
[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         u_int8_t model, step;
606         unsigned i, j, k, bit, old;
607         u_int32_t id;
608         int reg;
609
610         snd_mtxlock(codec->lock);
611         codec->count = AC97_INIT(codec->methods, codec->devinfo);
612         if (codec->count == 0) {
613                 device_printf(codec->dev, "ac97 codec init failed\n");
614                 snd_mtxunlock(codec->lock);
615                 return ENODEV;
616         }
617
618         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
619         ac97_reset(codec);
620         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
621
622         i = ac97_rdcd(codec, AC97_REG_RESET);
623         j = ac97_rdcd(codec, AC97_REG_RESET);
624         k = ac97_rdcd(codec, AC97_REG_RESET);
625         /*
626          * Let see if this codec can return consistent value.
627          * If not, turn on aggressive read workaround
628          * (STAC9704 comes in mind).
629          */
630         if (i != j || j != k) {
631                 codec->flags |= AC97_F_RDCD_BUG;
632                 i = ac97_rdcd(codec, AC97_REG_RESET);
633         }
634         codec->caps = i & 0x03ff;
635         codec->se =  (i & 0x7c00) >> 10;
636
637         id = (ac97_rdcd(codec, AC97_REG_ID1) << 16) | ac97_rdcd(codec, AC97_REG_ID2);
638         if (id == 0 || id == 0xffffffff) {
639                 device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id);
640                 snd_mtxunlock(codec->lock);
641                 return ENODEV;
642         }
643
644         codec->id = id;
645         codec->subvendor = (u_int32_t)pci_get_subdevice(codec->dev) << 16;
646         codec->subvendor |= (u_int32_t)pci_get_subvendor(codec->dev) &
647             0x0000ffff;
648         codec->noext = 0;
649         codec_patch = NULL;
650
651         cname = NULL;
652         model = step = 0;
653         for (i = 0; ac97codecid[i].id; i++) {
654                 u_int32_t modelmask = 0xffffffff ^ ac97codecid[i].stepmask;
655                 if ((ac97codecid[i].id & modelmask) == (id & modelmask)) {
656                         codec->noext = ac97codecid[i].noext;
657                         codec_patch = ac97codecid[i].patch;
658                         cname = ac97codecid[i].name;
659                         model = (id & modelmask) & 0xff;
660                         step = (id & ~modelmask) & 0xff;
661                         break;
662                 }
663         }
664
665         vname = NULL;
666         for (i = 0; ac97vendorid[i].id; i++) {
667                 if (ac97vendorid[i].id == (id & 0xffffff00)) {
668                         vname = ac97vendorid[i].name;
669                         break;
670                 }
671         }
672
673         codec->extcaps = 0;
674         codec->extid = 0;
675         codec->extstat = 0;
676         if (!codec->noext) {
677                 i = ac97_rdcd(codec, AC97_REGEXT_ID);
678                 if (i != 0xffff) {
679                         codec->extcaps = i & 0x3fff;
680                         codec->extid =  (i & 0xc000) >> 14;
681                         codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS;
682                 }
683         }
684
685         for (i = 0; i < AC97_MIXER_SIZE; i++) {
686                 codec->mix[i] = ac97mixtable_default[i];
687         }
688         ac97_fix_auxout(codec);
689         ac97_fix_tone(codec);
690         if (codec_patch)
691                 codec_patch(codec);
692
693         for (i = 0; i < AC97_MIXER_SIZE; i++) {
694                 k = codec->noext? codec->mix[i].enable : 1;
695                 reg = codec->mix[i].reg;
696                 if (reg < 0)
697                         reg = -reg;
698                 if (k && reg) {
699                         j = old = ac97_rdcd(codec, reg);
700                         /*
701                          * Test for mute bit (except for AC97_MIX_TONE,
702                          * where we simply assume it as available).
703                          */
704                         if (codec->mix[i].mute) {
705                                 ac97_wrcd(codec, reg, j | 0x8000);
706                                 j = ac97_rdcd(codec, reg);
707                         } else
708                                 j |= 0x8000;
709                         if ((j & 0x8000)) {
710                                 /*
711                                  * Test whether the control width should be
712                                  * 4, 5 or 6 bit. For 5bit register, we should
713                                  * test it whether it's really 5 or 6bit. Leave
714                                  * 4bit register alone, because sometimes an
715                                  * attempt to write past 4th bit may cause
716                                  * incorrect result especially for AC97_MIX_BEEP
717                                  * (ac97 2.3).
718                                  */
719                                 bit = codec->mix[i].bits;
720                                 if (bit == 5)
721                                         bit++;
722                                 j = ((1 << bit) - 1) << codec->mix[i].ofs;
723                                 ac97_wrcd(codec, reg,
724                                         j | (codec->mix[i].mute ? 0x8000 : 0));
725                                 k = ac97_rdcd(codec, reg) & j;
726                                 k >>= codec->mix[i].ofs;
727                                 if (reg == AC97_MIX_TONE &&
728                                                         ((k & 0x0001) == 0x0000))
729                                         k >>= 1;
730                                 for (j = 0; k >> j; j++)
731                                         ;
732                                 if (j != 0) {
733 #if 0
734                                         device_printf(codec->dev, "%2d: [ac97_rdcd() = %d] [Testbit = %d] %d -> %d\n",
735                                                 i, k, bit, codec->mix[i].bits, j);
736 #endif
737                                         codec->mix[i].enable = 1;
738                                         codec->mix[i].bits = j;
739                                 } else if (reg == AC97_MIX_BEEP) {
740                                         /*
741                                          * Few codec such as CX20468-21 does
742                                          * have this control register, although
743                                          * the only usable part is the mute bit.
744                                          */
745                                         codec->mix[i].enable = 1;
746                                 } else
747                                         codec->mix[i].enable = 0;
748                         } else
749                                 codec->mix[i].enable = 0;
750                         ac97_wrcd(codec, reg, old);
751                 }
752 #if 0
753                 printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits);
754 #endif
755         }
756
757         device_printf(codec->dev, "<%s>\n",
758                       ac97_hw_desc(codec->id, vname, cname, desc));
759
760         if (bootverbose) {
761                 if (codec->flags & AC97_F_RDCD_BUG)
762                         device_printf(codec->dev, "Buggy AC97 Codec: aggressive ac97_rdcd() workaround enabled\n");
763                 device_printf(codec->dev, "Codec features ");
764                 for (i = j = 0; i < 10; i++)
765                         if (codec->caps & (1 << i))
766                                 printf("%s%s", j++? ", " : "", ac97feature[i]);
767                 printf("%s%d bit master volume", j++? ", " : "", codec->mix[SOUND_MIXER_VOLUME].bits);
768                 printf("%s%s\n", j? ", " : "", ac97enhancement[codec->se]);
769
770                 if (codec->extcaps != 0 || codec->extid) {
771                         device_printf(codec->dev, "%s codec",
772                                       codec->extid? "Secondary" : "Primary");
773                         if (codec->extcaps)
774                                 printf(" extended features ");
775                         for (i = j = 0; i < 14; i++)
776                                 if (codec->extcaps & (1 << i))
777                                         printf("%s%s", j++? ", " : "", ac97extfeature[i]);
778                         printf("\n");
779                 }
780         }
781
782         i = 0;
783         while ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) {
784                 if (++i == 100) {
785                         device_printf(codec->dev, "ac97 codec reports dac not ready\n");
786                         break;
787                 }
788                 DELAY(1000);
789         }
790         if (bootverbose)
791                 device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i);
792         snd_mtxunlock(codec->lock);
793         return 0;
794 }
795
796 static unsigned
797 ac97_reinitmixer(struct ac97_info *codec)
798 {
799         snd_mtxlock(codec->lock);
800         codec->count = AC97_INIT(codec->methods, codec->devinfo);
801         if (codec->count == 0) {
802                 device_printf(codec->dev, "ac97 codec init failed\n");
803                 snd_mtxunlock(codec->lock);
804                 return ENODEV;
805         }
806
807         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
808         ac97_reset(codec);
809         ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
810
811         if (!codec->noext) {
812                 ac97_wrcd(codec, AC97_REGEXT_STAT, codec->extstat);
813                 if ((ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS)
814                     != codec->extstat)
815                         device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n",
816                                       codec->extstat,
817                                       ac97_rdcd(codec, AC97_REGEXT_STAT) &
818                                       AC97_EXTCAPS);
819         }
820
821         if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0)
822                 device_printf(codec->dev, "ac97 codec reports dac not ready\n");
823         snd_mtxunlock(codec->lock);
824         return 0;
825 }
826
827 struct ac97_info *
828 ac97_create(device_t dev, void *devinfo, kobj_class_t cls)
829 {
830         struct ac97_info *codec;
831         int i;
832
833         codec = malloc(sizeof(*codec), M_AC97, M_WAITOK | M_ZERO);
834         snprintf(codec->name, sizeof(codec->name), "%s:ac97",
835             device_get_nameunit(dev));
836         codec->lock = snd_mtxcreate(codec->name, "ac97 codec");
837         codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO);
838         codec->dev = dev;
839         codec->devinfo = devinfo;
840         codec->flags = 0;
841
842         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
843             "eapdinv", &i) == 0 && i != 0)
844                 codec->flags |= AC97_F_EAPD_INV;
845
846         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
847             "softpcmvol", &i) == 0 && i != 0)
848                 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SOFTPCMVOL);
849
850         return codec;
851 }
852
853 void
854 ac97_destroy(struct ac97_info *codec)
855 {
856         snd_mtxlock(codec->lock);
857         if (codec->methods != NULL)
858                 kobj_delete(codec->methods, M_AC97);
859         snd_mtxfree(codec->lock);
860         free(codec, M_AC97);
861 }
862
863 void
864 ac97_setflags(struct ac97_info *codec, u_int32_t val)
865 {
866         codec->flags = val;
867 }
868
869 u_int32_t
870 ac97_getflags(struct ac97_info *codec)
871 {
872         return codec->flags;
873 }
874
875 /* -------------------------------------------------------------------- */
876
877 static int
878 sysctl_hw_snd_ac97_eapd(SYSCTL_HANDLER_ARGS)
879 {
880         struct ac97_info *codec;
881         int ea, inv, err = 0;
882         u_int16_t val;
883
884         codec = oidp->oid_arg1;
885         if (codec == NULL || codec->id == 0 || codec->lock == NULL)
886                 return EINVAL;
887         snd_mtxlock(codec->lock);
888         val = ac97_rdcd(codec, AC97_REG_POWER);
889         inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1;
890         ea = (val >> 15) ^ inv;
891         snd_mtxunlock(codec->lock);
892         err = sysctl_handle_int(oidp, &ea, 0, req);
893         if (err == 0 && req->newptr != NULL) {
894                 if (ea != 0 && ea != 1)
895                         return EINVAL;
896                 if (ea != ((val >> 15) ^ inv)) {
897                         snd_mtxlock(codec->lock);
898                         ac97_wrcd(codec, AC97_REG_POWER, val ^ 0x8000);
899                         snd_mtxunlock(codec->lock);
900                 }
901         }
902         return err;
903 }
904
905 static void
906 ac97_init_sysctl(struct ac97_info *codec)
907 {
908         u_int16_t orig, val;
909
910         if (codec == NULL || codec->dev == NULL)
911                 return;
912         snd_mtxlock(codec->lock);
913         orig = ac97_rdcd(codec, AC97_REG_POWER);
914         ac97_wrcd(codec, AC97_REG_POWER, orig ^ 0x8000);
915         val = ac97_rdcd(codec, AC97_REG_POWER);
916         ac97_wrcd(codec, AC97_REG_POWER, orig);
917         snd_mtxunlock(codec->lock);
918         if ((val & 0x8000) == (orig & 0x8000))
919                 return;
920         SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev),
921             SYSCTL_CHILDREN(device_get_sysctl_tree(codec->dev)),
922             OID_AUTO, "eapd", CTLTYPE_INT | CTLFLAG_RW,
923             codec, sizeof(codec), sysctl_hw_snd_ac97_eapd,
924             "I", "AC97 External Amplifier");
925 }
926
927 static int
928 ac97mix_init(struct snd_mixer *m)
929 {
930         struct ac97_info *codec = mix_getdevinfo(m);
931         u_int32_t i, mask;
932
933         if (codec == NULL)
934                 return -1;
935
936         if (ac97_initmixer(codec))
937                 return -1;
938
939         switch (codec->id) {
940         case 0x41445374:        /* AD1981B */
941                 switch (codec->subvendor) {
942                 case 0x02d91014:
943                         /*
944                          * IBM Thinkcentre:
945                          *
946                          * Tie "ogain" and "phout" to "vol" since its
947                          * master volume is basically useless and can't
948                          * control anything.
949                          */
950                         mask = 0;
951                         if (codec->mix[SOUND_MIXER_OGAIN].enable)
952                                 mask |= SOUND_MASK_OGAIN;
953                         if (codec->mix[SOUND_MIXER_PHONEOUT].enable)
954                                 mask |= SOUND_MASK_PHONEOUT;
955                         if (codec->mix[SOUND_MIXER_VOLUME].enable)
956                                 mix_setparentchild(m, SOUND_MIXER_VOLUME,
957                                     mask);
958                         else {
959                                 mix_setparentchild(m, SOUND_MIXER_VOLUME,
960                                     mask);
961                                 mix_setrealdev(m, SOUND_MIXER_VOLUME,
962                                     SOUND_MIXER_NONE);
963                         }
964                         break;
965                 case 0x099c103c:
966                         /*
967                          * HP nx6110:
968                          *
969                          * By default, "vol" is controlling internal speakers
970                          * (not a master volume!) and "ogain" is controlling
971                          * headphone. Enable dummy "phout" so it can be
972                          * remapped to internal speakers and virtualize
973                          * "vol" to control both.
974                          */
975                         codec->mix[SOUND_MIXER_OGAIN].enable = 1;
976                         codec->mix[SOUND_MIXER_PHONEOUT].enable = 1;
977                         mix_setrealdev(m, SOUND_MIXER_PHONEOUT,
978                             SOUND_MIXER_VOLUME);
979                         mix_setrealdev(m, SOUND_MIXER_VOLUME,
980                             SOUND_MIXER_NONE);
981                         mix_setparentchild(m, SOUND_MIXER_VOLUME,
982                             SOUND_MASK_OGAIN | SOUND_MASK_PHONEOUT);
983                         break;
984                 default:
985                         break;
986                 }
987                 break;
988         case 0x434d4941:        /* CMI9738 */
989         case 0x434d4961:        /* CMI9739 */
990         case 0x434d4978:        /* CMI9761 */
991         case 0x434d4982:        /* CMI9761 */
992         case 0x434d4983:        /* CMI9761 */
993                 bzero(&codec->mix[SOUND_MIXER_PCM],
994                     sizeof(codec->mix[SOUND_MIXER_PCM]));
995                 pcm_setflags(codec->dev, pcm_getflags(codec->dev) |
996                     SD_F_SOFTPCMVOL);
997                 /* XXX How about master volume ? */
998                 break;
999         default:
1000                 break;
1001         }
1002
1003         if (pcm_getflags(codec->dev) & SD_F_SOFTPCMVOL)
1004                 ac97_wrcd(codec, AC97_MIX_PCM, 0);
1005 #if 0
1006         /* XXX For the sake of debugging purposes */
1007         mix_setparentchild(m, SOUND_MIXER_VOLUME,
1008             SOUND_MASK_PCM | SOUND_MASK_CD);
1009         mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
1010         ac97_wrcd(codec, AC97_MIX_MASTER, 0);
1011 #endif
1012
1013         mask = 0;
1014         for (i = 0; i < AC97_MIXER_SIZE; i++)
1015                 mask |= codec->mix[i].enable? 1 << i : 0;
1016         mix_setdevs(m, mask);
1017
1018         mask = 0;
1019         for (i = 0; i < AC97_MIXER_SIZE; i++)
1020                 mask |= codec->mix[i].recidx? 1 << i : 0;
1021         mix_setrecdevs(m, mask);
1022
1023         ac97_init_sysctl(codec);
1024
1025         return 0;
1026 }
1027
1028 static int
1029 ac97mix_uninit(struct snd_mixer *m)
1030 {
1031         struct ac97_info *codec = mix_getdevinfo(m);
1032
1033         if (codec == NULL)
1034                 return -1;
1035         /*
1036         if (ac97_uninitmixer(codec))
1037                 return -1;
1038         */
1039         ac97_destroy(codec);
1040         return 0;
1041 }
1042
1043 static int
1044 ac97mix_reinit(struct snd_mixer *m)
1045 {
1046         struct ac97_info *codec = mix_getdevinfo(m);
1047
1048         if (codec == NULL)
1049                 return -1;
1050         return ac97_reinitmixer(codec);
1051 }
1052
1053 static int
1054 ac97mix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
1055 {
1056         struct ac97_info *codec = mix_getdevinfo(m);
1057
1058         if (codec == NULL || dev >= AC97_MIXER_SIZE)
1059                 return -1;
1060         return ac97_setmixer(codec, dev, left, right);
1061 }
1062
1063 static u_int32_t
1064 ac97mix_setrecsrc(struct snd_mixer *m, u_int32_t src)
1065 {
1066         int i;
1067         struct ac97_info *codec = mix_getdevinfo(m);
1068
1069         if (codec == NULL)
1070                 return -1;
1071         for (i = 0; i < AC97_MIXER_SIZE; i++)
1072                 if ((src & (1 << i)) != 0)
1073                         break;
1074         return (ac97_setrecsrc(codec, i) == 0)? 1U << i : 0xffffffffU;
1075 }
1076
1077 static kobj_method_t ac97mixer_methods[] = {
1078         KOBJMETHOD(mixer_init,          ac97mix_init),
1079         KOBJMETHOD(mixer_uninit,        ac97mix_uninit),
1080         KOBJMETHOD(mixer_reinit,        ac97mix_reinit),
1081         KOBJMETHOD(mixer_set,           ac97mix_set),
1082         KOBJMETHOD(mixer_setrecsrc,     ac97mix_setrecsrc),
1083         KOBJMETHOD_END
1084 };
1085 MIXER_DECLARE(ac97mixer);
1086
1087 /* -------------------------------------------------------------------- */
1088
1089 kobj_class_t
1090 ac97_getmixerclass(void)
1091 {
1092         return &ac97mixer_class;
1093 }