2 #include "../port/lib.h"
7 #include "../port/error.h"
8 #include "../port/audioif.h"
46 Extiddsa0 = 0<<4, /* extid only */
47 Extiddsa1 = 1<<4, /* extid only */
48 Extiddsa2 = 2<<4, /* extid only */
49 Extiddsa3 = 3<<4, /* extid only */
50 Extcsrspsa34 = 0<<4, /* extcsr only */
51 Extcsrspsa78 = 1<<4, /* extcsr only */
52 Extcsrspsa69 = 2<<4, /* extcsr only */
53 ExtcsrspsaAB = 3<<4, /* extcsr only */
57 Extidamap = 1<<9, /* extid only */
58 Extidrev11 = 0<<10, /* extid only */
59 Extidrev22 = 1<<10, /* extid only */
60 Extidrev23 = 2<<10, /* extid only */
61 Extidprim = 0<<14, /* extid only */
62 Extidsec0 = 1<<14, /* extid only */
63 Extidsec1 = 2<<14, /* extid only */
64 Extidsec2 = 3<<14, /* extid only */
65 Extcsrmadc = 1<<9, /* extcsr only */
66 Extcsrspcv = 1<<10, /* extcsr only */
67 Extcsrpri = 1<<11, /* extcsr only */
68 Extcsrprj = 1<<12, /* extcsr only */
69 Extcsrprk = 1<<13, /* extcsr only */
70 Extcsrprl = 1<<14, /* extcsr only */
71 Extcsrvcfg = 1<<15, /* extcsr only */
72 Pcmfrontdacrate = 0x2C,
73 Pcmsurrounddacrate = 0x2E,
114 static Volume voltab[] = {
115 [Vmaster] "master", 0x02, -63, Stereo, 0,
116 [Vaudio] "audio", 0x18, -31, Stereo, 0,
117 [Vhead] "head", 0x04, -31, Stereo, Capheadphones,
118 [Vbass] "bass", 0x08, 15, Left, Captonectl,
119 [Vtreb] "treb", 0x08, 15, Right, Captonectl,
120 [Vbeep] "beep", 0x0a, -31, Right, 0,
121 [Vphone] "phone", 0x0c, -31, Right, 0,
122 [Vmic] "mic", 0x0e, -31, Right, Capmic,
123 [Vline] "line", 0x10, -31, Stereo, 0,
124 [Vcd] "cd", 0x12, -31, Stereo, 0,
125 [Vvideo] "video", 0x14, -31, Stereo, 0,
126 [Vaux] "aux", 0x16, -63, Stereo, 0,
127 [Vrecgain] "recgain", 0x1c, 15, Stereo, 0,
128 [Vmicgain] "micgain", 0x1e, 15, Right, Capmic,
129 [Vspeed] "speed", 0x2c, 0, Absolute, 0,
130 [Vdelay] "delay", 0, 0, Absolute, 0,
134 typedef struct Mixer Mixer;
137 ushort (*rr)(Audio *, int);
138 void (*wr)(Audio *, int, ushort);
143 ac97volget(Audio *adev, int x, int a[2])
145 Mixer *m = adev->mixer;
156 a[0] = m->rr(adev, vol->reg);
159 v = m->rr(adev, vol->reg);
161 a[0] = a[1] = vol->range < 0 ? 0x7f : 0;
163 a[0] = ((v>>8) & 0x7f);
171 ac97volset(Audio *adev, int x, int a[2])
173 Mixer *m = adev->mixer;
184 m->wr(adev, vol->reg, a[0]);
186 m->wr(adev, 0x32, a[0]); /* adc rate */
187 adev->speed = m->rr(adev, vol->reg);
192 w = m->rr(adev, vol->reg) & 0x7f;
193 m->wr(adev, vol->reg, (v<<8)|w);
196 v = m->rr(adev, vol->reg) & 0x7f00;
198 m->wr(adev, vol->reg, v|w);
203 m->wr(adev, vol->reg, (v<<8)|w);
211 ac97mixread(Audio *adev, void *a, long n, vlong)
213 Mixer *m = adev->mixer;
216 caps = m->rr(adev, Reset);
217 caps |= m->rr(adev, Extid) << 16;
218 return genaudiovolread(adev, a, n, 0, voltab, ac97volget, caps);
222 ac97mixwrite(Audio *adev, void *a, long n, vlong)
224 Mixer *m = adev->mixer;
227 caps = m->rr(adev, Reset);
228 caps |= m->rr(adev, Extid) << 16;
229 return genaudiovolwrite(adev, a, n, 0, voltab, ac97volset, caps);
233 ac97mixreset(Audio *adev, void (*wr)(Audio*,int,ushort), ushort (*rr)(Audio*,int))
238 m = malloc(sizeof(Mixer));
240 print("ac97mix: no memory for Mixer\n");
245 m->wr(adev, Reset, 0);
246 m->wr(adev, Powerdowncsr, 0);
248 t = (Adcpower | Dacpower | Anlpower | Refpower);
249 if((m->rr(adev, Powerdowncsr) & t) != t)
250 print("#A%d: ac97 exhausted waiting powerup\n", adev->ctlrno);
252 t = m->rr(adev, Extid);
253 print("#A%d: ac97 codec ext:%s%s%s%s%s%s%s\n", adev->ctlrno,
254 (t & Extvra) ? " vra" : "",
255 (t & Extdra) ? " dra" : "",
256 (t & Extspdif) ? " spdif" : "",
257 (t & Extvrm) ? " vrm" : "",
258 (t & Extcdac) ? " cdac" : "",
259 (t & Extsdac) ? " sdac" : "",
260 (t & Extldac) ? " ldac" : "");
263 m->wr(adev, Extcsr, Extvra);
266 print("#A%d: ac97 vra extension not supported\n", adev->ctlrno);
271 adev->volread = ac97mixread;
272 adev->volwrite = ac97mixwrite;