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