2 #include "../port/lib.h"
7 #include "../port/error.h"
8 #include "../port/audioif.h"
10 enum { Maxbusywait = 500000 };
48 Extiddsa0 = 0<<4, /* extid only */
49 Extiddsa1 = 1<<4, /* extid only */
50 Extiddsa2 = 2<<4, /* extid only */
51 Extiddsa3 = 3<<4, /* extid only */
52 Extcsrspsa34 = 0<<4, /* extcsr only */
53 Extcsrspsa78 = 1<<4, /* extcsr only */
54 Extcsrspsa69 = 2<<4, /* extcsr only */
55 ExtcsrspsaAB = 3<<4, /* extcsr only */
59 Extidamap = 1<<9, /* extid only */
60 Extidrev11 = 0<<10, /* extid only */
61 Extidrev22 = 1<<10, /* extid only */
62 Extidrev23 = 2<<10, /* extid only */
63 Extidprim = 0<<14, /* extid only */
64 Extidsec0 = 1<<14, /* extid only */
65 Extidsec1 = 2<<14, /* extid only */
66 Extidsec2 = 3<<14, /* extid only */
67 Extcsrmadc = 1<<9, /* extcsr only */
68 Extcsrspcv = 1<<10, /* extcsr only */
69 Extcsrpri = 1<<11, /* extcsr only */
70 Extcsrprj = 1<<12, /* extcsr only */
71 Extcsrprk = 1<<13, /* extcsr only */
72 Extcsrprl = 1<<14, /* extcsr only */
73 Extcsrvcfg = 1<<15, /* extcsr only */
74 Pcmfrontdacrate = 0x2C,
75 Pcmsurrounddacrate = 0x2E,
116 static Volume voltab[] = {
117 [Vmaster] "master", 0x02, 63, Stereo, 0,
118 [Vaudio] "audio", 0x18, 31, Stereo, 0,
119 [Vhead] "head", 0x04, 31, Stereo, Capheadphones,
120 [Vbass] "bass", 0x08, 15, Left, Captonectl,
121 [Vtreb] "treb", 0x08, 15, Right, Captonectl,
122 [Vbeep] "beep", 0x0a, 31, Right, 0,
123 [Vphone] "phone", 0x0c, 31, Right, 0,
124 [Vmic] "mic", 0x0e, 31, Right, Capmic,
125 [Vline] "line", 0x10, 31, Stereo, 0,
126 [Vcd] "cd", 0x12, 31, Stereo, 0,
127 [Vvideo] "video", 0x14, 31, Stereo, 0,
128 [Vaux] "aux", 0x16, 63, Stereo, 0,
129 [Vrecgain] "recgain", 0x1c, 15, Stereo, 0,
130 [Vmicgain] "micgain", 0x1e, 15, Right, Capmic,
131 [Vspeed] "speed", 0x2c, 0, Absolute, 0,
132 [Vdelay] "delay", 0, 0, Absolute, 0,
136 typedef struct Mixer Mixer;
139 ushort (*rr)(Audio *, int);
140 void (*wr)(Audio *, int, ushort);
145 ac97volget(Audio *adev, int x, int a[2])
147 Mixer *m = adev->mixer;
158 a[0] = m->rr(adev, vol->reg);
161 v = m->rr(adev, vol->reg);
166 a[0] = vol->range - ((v>>8) & 0x7f);
167 a[1] = vol->range - (v & 0x7f);
174 ac97volset(Audio *adev, int x, int a[2])
176 Mixer *m = adev->mixer;
187 m->wr(adev, vol->reg, a[0]);
189 adev->speed = m->rr(adev, vol->reg);
192 v = (vol->range - a[0]) & 0x7f;
193 w = m->rr(adev, vol->reg) & 0x7f;
194 m->wr(adev, vol->reg, (v<<8)|w);
197 v = m->rr(adev, vol->reg) & 0x7f00;
198 w = (vol->range - a[1]) & 0x7f;
199 m->wr(adev, vol->reg, v|w);
202 v = (vol->range - a[0]) & 0x7f;
203 w = (vol->range - a[1]) & 0x7f;
204 m->wr(adev, vol->reg, (v<<8)|w);
212 ac97mixread(Audio *adev, void *a, long n, vlong)
214 Mixer *m = adev->mixer;
217 caps = m->rr(adev, Reset);
218 caps |= m->rr(adev, Extid) << 16;
219 return genaudiovolread(adev, a, n, 0, voltab, ac97volget, caps);
223 ac97mixwrite(Audio *adev, void *a, long n, vlong)
225 Mixer *m = adev->mixer;
228 caps = m->rr(adev, Reset);
229 caps |= m->rr(adev, Extid) << 16;
230 return genaudiovolwrite(adev, a, n, 0, voltab, ac97volset, caps);
234 ac97mixreset(Audio *adev, void (*wr)(Audio*,int,ushort), ushort (*rr)(Audio*,int))
240 m = malloc(sizeof(Mixer));
242 print("ac97mix: no memory for Mixer\n");
247 m->wr(adev, Reset, 0);
248 m->wr(adev, Powerdowncsr, 0);
250 t = (Adcpower | Dacpower | Anlpower | Refpower);
251 for(i = 0; i < Maxbusywait; i++){
252 if((m->rr(adev, Powerdowncsr) & t) == t)
257 print("#A%d: ac97 exhausted waiting powerup\n", adev->ctlrno);
259 t = m->rr(adev, Extid);
260 print("#A%d: ac97 codec ext:%s%s%s%s%s%s%s\n", adev->ctlrno,
261 (t & Extvra) ? " vra" : "",
262 (t & Extdra) ? " dra" : "",
263 (t & Extspdif) ? " spdif" : "",
264 (t & Extvrm) ? " vrm" : "",
265 (t & Extcdac) ? " cdac" : "",
266 (t & Extsdac) ? " sdac" : "",
267 (t & Extldac) ? " ldac" : "");
270 m->wr(adev, Extcsr, Extvra);
273 print("#A%d: ac97 vra extension not supported\n", adev->ctlrno);
278 adev->volread = ac97mixread;
279 adev->volwrite = ac97mixwrite;