initial commit with v2.6.9
[linux-2.6.9-moxart.git] / sound / pci / au88x0 / au88x0_eq.c
blobf8f52638ccaa4ad0a411ef39601dbb531d796db5
1 /***************************************************************************
2 * au88x0_eq.c
3 * Aureal Vortex Hardware EQ control/access.
5 * Sun Jun 8 18:19:19 2003
6 * 2003 Manuel Jander (mjander@users.sourceforge.net)
7 *
8 * 02 July 2003: First time something works :)
9 * November 2003: A3D Bypass code completed but untested.
11 * TODO:
12 * - Debug (testing)
13 * - Test peak visualization support.
15 ****************************************************************************/
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Library General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 The Aureal Hardware EQ is found on AU8810 and AU8830 chips only.
35 it has 4 inputs (2 for general mix, 2 for A3D) and 2 outputs (supposed
36 to be routed to the codec).
39 #include "au88x0.h"
40 #include "au88x0_eq.h"
41 #include "au88x0_eqdata.c"
43 #define VORTEX_EQ_BASE 0x2b000
44 #define VORTEX_EQ_DEST (VORTEX_EQ_BASE + 0x410)
45 #define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)
46 #define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440)
48 /* CEqHw.s */
49 static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
51 hwwrite(vortex->mmio, 0x2b3c4, gain);
52 hwwrite(vortex->mmio, 0x2b3c8, level);
55 static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
57 eqhw_t *eqhw = &(vortex->eq.this04);
58 int eax, i = 0, n /*esp2c */;
60 for (n = 0; n < eqhw->this04; n++) {
61 hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]);
62 hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
64 if (eqhw->this08 == 0) {
65 hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
66 hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
67 eax = coefs[i + 4]; //esp24;
68 } else {
69 if (coefs[2 + i] == 0x8000)
70 eax = 0x7fff;
71 else
72 eax = ~coefs[2 + i];
73 hwwrite(vortex->mmio, 0x2b008 + n * 0x30, eax & 0xffff);
74 if (coefs[3 + i] == 0x8000)
75 eax = 0x7fff;
76 else
77 eax = ~coefs[3 + i];
78 hwwrite(vortex->mmio, 0x2b00c + n * 0x30, eax & 0xffff);
79 if (coefs[4 + i] == 0x8000)
80 eax = 0x7fff;
81 else
82 eax = ~coefs[4 + i];
84 hwwrite(vortex->mmio, 0x2b010 + n * 0x30, eax);
86 i += 5;
90 static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
92 eqhw_t *eqhw = &(vortex->eq.this04);
93 int i = 0, n /*esp2c */, eax;
95 for (n = 0; n < eqhw->this04; n++) {
96 hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]);
97 hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
99 if (eqhw->this08 == 0) {
100 hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
101 hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
102 eax = coefs[4 + i]; //*esp24;
103 } else {
104 if (coefs[2 + i] == 0x8000)
105 eax = 0x7fff;
106 else
107 eax = ~(coefs[2 + i]);
108 hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, eax & 0xffff);
109 if (coefs[3 + i] == 0x8000)
110 eax = 0x7fff;
111 else
112 eax = ~coefs[3 + i];
113 hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, eax & 0xffff);
114 if (coefs[4 + i] == 0x8000)
115 eax = 0x7fff;
116 else
117 eax = ~coefs[4 + i];
119 hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, eax);
120 i += 5;
125 static void vortex_EqHw_SetLeftStates(vortex_t * vortex, u16 a[], u16 b[])
127 eqhw_t *eqhw = &(vortex->eq.this04);
128 int i = 0, ebx;
130 hwwrite(vortex->mmio, 0x2b3fc, a[0]);
131 hwwrite(vortex->mmio, 0x2b400, a[1]);
133 for (ebx = 0; ebx < eqhw->this04; ebx++) {
134 hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]);
135 hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]);
136 hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]);
137 hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]);
138 i += 4;
142 static void vortex_EqHw_SetRightStates(vortex_t * vortex, u16 a[], u16 b[])
144 eqhw_t *eqhw = &(vortex->eq.this04);
145 int i = 0, ebx;
147 hwwrite(vortex->mmio, 0x2b404, a[0]);
148 hwwrite(vortex->mmio, 0x2b408, a[1]);
150 for (ebx = 0; ebx < eqhw->this04; ebx++) {
151 hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]);
152 hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]);
153 hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]);
154 hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]);
155 i += 4;
159 #if 0
160 static void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b)
162 *a = hwread(vortex->mmio, 0x2b3c4);
163 *b = hwread(vortex->mmio, 0x2b3c8);
166 static void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[])
171 static void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[])
176 static void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[])
181 static void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[])
186 #endif
187 /* Mix Gains */
188 static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
190 eqhw_t *eqhw = &(vortex->eq.this04);
191 int eax;
193 if (eqhw->this08 == 0) {
194 hwwrite(vortex->mmio, 0x2b3d4, a);
195 hwwrite(vortex->mmio, 0x2b3ec, b);
196 } else {
197 if (a == 0x8000)
198 eax = 0x7fff;
199 else
200 eax = ~a;
201 hwwrite(vortex->mmio, 0x2b3d4, eax & 0xffff);
202 if (b == 0x8000)
203 eax = 0x7fff;
204 else
205 eax = ~b;
206 hwwrite(vortex->mmio, 0x2b3ec, eax & 0xffff);
210 static void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
213 hwwrite(vortex->mmio, 0x2b3e0, a);
214 hwwrite(vortex->mmio, 0x2b3f8, b);
217 #if 0
218 static void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b)
221 hwwrite(vortex->mmio, 0x2b3d0, a);
222 hwwrite(vortex->mmio, 0x2b3e8, b);
225 static void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
228 hwwrite(vortex->mmio, 0x2b3dc, a);
229 hwwrite(vortex->mmio, 0x2b3f4, b);
232 #endif
233 static void
234 vortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
236 hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b);
239 static void
240 vortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
242 hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b);
245 static void vortex_EqHw_SetLeftGainsTarget(vortex_t * vortex, u16 a[])
247 eqhw_t *eqhw = &(vortex->eq.this04);
248 int ebx;
250 for (ebx = 0; ebx < eqhw->this04; ebx++) {
251 hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]);
255 static void vortex_EqHw_SetRightGainsTarget(vortex_t * vortex, u16 a[])
257 eqhw_t *eqhw = &(vortex->eq.this04);
258 int ebx;
260 for (ebx = 0; ebx < eqhw->this04; ebx++) {
261 hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]);
265 static void vortex_EqHw_SetLeftGainsCurrent(vortex_t * vortex, u16 a[])
267 eqhw_t *eqhw = &(vortex->eq.this04);
268 int ebx;
270 for (ebx = 0; ebx < eqhw->this04; ebx++) {
271 hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]);
275 static void vortex_EqHw_SetRightGainsCurrent(vortex_t * vortex, u16 a[])
277 eqhw_t *eqhw = &(vortex->eq.this04);
278 int ebx;
280 for (ebx = 0; ebx < eqhw->this04; ebx++) {
281 hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]);
285 #if 0
286 static void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[])
288 eqhw_t *eqhw = &(vortex->eq.this04);
289 int ebx = 0;
291 if (eqhw->this04 < 0)
292 return;
294 do {
295 a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30);
296 ebx++;
298 while (ebx < eqhw->this04);
301 static void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[])
303 eqhw_t *eqhw = &(vortex->eq.this04);
304 int ebx = 0;
306 if (eqhw->this04 < 0)
307 return;
309 do {
310 a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30);
311 ebx++;
313 while (ebx < eqhw->this04);
316 static void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[])
318 eqhw_t *eqhw = &(vortex->eq.this04);
319 int ebx = 0;
321 if (eqhw->this04 < 0)
322 return;
324 do {
325 a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30);
326 ebx++;
328 while (ebx < eqhw->this04);
331 static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[])
333 eqhw_t *eqhw = &(vortex->eq.this04);
334 int ebx = 0;
336 if (eqhw->this04 < 0)
337 return;
339 do {
340 a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30);
341 ebx++;
343 while (ebx < eqhw->this04);
346 #endif
347 /* EQ band levels settings */
348 static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 a[])
350 eqhw_t *eqhw = &(vortex->eq.this04);
351 int ebx;
353 for (ebx = 0; ebx < eqhw->this04; ebx++) {
354 hwwrite(vortex->mmio, 0x2b024 + ebx * 0x30, a[ebx]);
357 hwwrite(vortex->mmio, 0x2b3cc, a[eqhw->this04]);
358 hwwrite(vortex->mmio, 0x2b3d8, a[eqhw->this04 + 1]);
360 for (ebx = 0; ebx < eqhw->this04; ebx++) {
361 hwwrite(vortex->mmio, 0x2b204 + ebx * 0x30,
362 a[ebx + (eqhw->this04 + 2)]);
365 hwwrite(vortex->mmio, 0x2b3e4, a[2 + (eqhw->this04 * 2)]);
366 hwwrite(vortex->mmio, 0x2b3f0, a[3 + (eqhw->this04 * 2)]);
369 #if 0
370 static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[])
372 eqhw_t *eqhw = &(vortex->eq.this04);
373 int ebx;
375 if (eqhw->this04 < 0)
376 return;
378 ebx = 0;
379 do {
380 a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30);
381 ebx++;
383 while (ebx < eqhw->this04);
385 a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc);
386 a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8);
388 ebx = 0;
389 do {
390 a[ebx + (eqhw->this04 + 2)] =
391 hwread(vortex->mmio, 0x2b204 + ebx * 0x30);
392 ebx++;
394 while (ebx < eqhw->this04);
396 a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4);
397 a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0);
400 #endif
401 /* Global Control */
402 static void vortex_EqHw_SetControlReg(vortex_t * vortex, unsigned long reg)
404 hwwrite(vortex->mmio, 0x2b440, reg);
407 static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int sr)
409 hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800);
412 #if 0
413 static void vortex_EqHw_GetControlReg(vortex_t * vortex, unsigned long *reg)
415 *reg = hwread(vortex->mmio, 0x2b440);
418 static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *sr)
420 *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f;
423 #endif
424 static void vortex_EqHw_Enable(vortex_t * vortex)
426 hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001);
429 static void vortex_EqHw_Disable(vortex_t * vortex)
431 hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000);
434 /* Reset (zero) buffers */
435 static void vortex_EqHw_ZeroIO(vortex_t * vortex)
437 int i;
438 for (i = 0; i < 0x8; i++)
439 hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
440 for (i = 0; i < 0x4; i++)
441 hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0);
444 static void vortex_EqHw_ZeroA3DIO(vortex_t * vortex)
446 int i;
447 for (i = 0; i < 0x4; i++)
448 hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
451 static void vortex_EqHw_ZeroState(vortex_t * vortex)
454 vortex_EqHw_SetControlReg(vortex, 0);
455 vortex_EqHw_ZeroIO(vortex);
456 hwwrite(vortex->mmio, 0x2b3c0, 0);
458 vortex_EqHw_SetTimeConsts(vortex, 0, 0);
460 vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros);
461 vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros);
463 vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero);
464 vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero);
465 vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero);
466 vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero);
468 vortex_EqHw_SetBypassGain(vortex, 0, 0);
469 //vortex_EqHw_SetCurrBypassGain(vortex, 0, 0);
470 vortex_EqHw_SetA3DBypassGain(vortex, 0, 0);
471 //vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0);
472 vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros);
473 vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros);
474 vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels);
477 /* Program coeficients as pass through */
478 static void vortex_EqHw_ProgramPipe(vortex_t * vortex)
480 vortex_EqHw_SetTimeConsts(vortex, 0, 0);
482 vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes);
483 vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes);
485 vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current);
486 vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current);
487 vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current);
488 vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current);
491 /* Program EQ block as 10 band Equalizer */
492 static void
493 vortex_EqHw_Program10Band(vortex_t * vortex, auxxEqCoeffSet_t * coefset)
496 vortex_EqHw_SetTimeConsts(vortex, 0xc, 0x7fe0);
498 vortex_EqHw_SetLeftCoefs(vortex, coefset->LeftCoefs);
499 vortex_EqHw_SetRightCoefs(vortex, coefset->RightCoefs);
501 vortex_EqHw_SetLeftGainsCurrent(vortex, coefset->LeftGains);
503 vortex_EqHw_SetRightGainsTarget(vortex, coefset->RightGains);
504 vortex_EqHw_SetLeftGainsTarget(vortex, coefset->LeftGains);
506 vortex_EqHw_SetRightGainsCurrent(vortex, coefset->RightGains);
509 /* Read all EQ peaks. (think VU meter) */
510 static void vortex_EqHw_GetTenBandLevels(vortex_t * vortex, u16 peaks[])
512 eqhw_t *eqhw = &(vortex->eq.this04);
513 int i;
515 if (eqhw->this04 <= 0)
516 return;
518 for (i = 0; i < eqhw->this04; i++)
519 peaks[i] = hwread(vortex->mmio, 0x2B024 + i * 0x30);
520 for (i = 0; i < eqhw->this04; i++)
521 peaks[i + eqhw->this04] =
522 hwread(vortex->mmio, 0x2B204 + i * 0x30);
525 /* CEqlzr.s */
527 static int vortex_Eqlzr_GetLeftGain(vortex_t * vortex, u16 index, u16 * gain)
529 eqlzr_t *eq = &(vortex->eq);
531 if (eq->this28) {
532 *gain = eq->this130[index];
533 return 0;
535 return 1;
538 static void vortex_Eqlzr_SetLeftGain(vortex_t * vortex, u16 index, u16 gain)
540 eqlzr_t *eq = &(vortex->eq);
542 if (eq->this28 == 0)
543 return;
545 eq->this130[index] = gain;
546 if (eq->this54)
547 return;
549 vortex_EqHw_SetLeftGainsSingleTarget(vortex, index, gain);
552 static int vortex_Eqlzr_GetRightGain(vortex_t * vortex, u16 index, u16 * gain)
554 eqlzr_t *eq = &(vortex->eq);
556 if (eq->this28) {
557 *gain = eq->this130[index + eq->this10];
558 return 0;
560 return 1;
563 static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain)
565 eqlzr_t *eq = &(vortex->eq);
567 if (eq->this28 == 0)
568 return;
570 eq->this130[index + eq->this10] = gain;
571 if (eq->this54)
572 return;
574 vortex_EqHw_SetRightGainsSingleTarget(vortex, index, gain);
577 #if 0
578 static int
579 vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, unsigned long *cnt)
581 eqlzr_t *eq = &(vortex->eq);
582 int si = 0;
584 if (eq->this10 == 0)
585 return 1;
588 if (vortex_Eqlzr_GetLeftGain(vortex, si, &gains[si]))
589 return 1;
590 if (vortex_Eqlzr_GetRightGain
591 (vortex, si, &gains[si + eq->this10]))
592 return 1;
593 si++;
595 while (eq->this10 > si) ;
596 *cnt = si * 2;
597 return 0;
599 #endif
600 static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex)
602 eqlzr_t *eq = &(vortex->eq);
604 vortex_EqHw_SetLeftGainsTarget(vortex, eq->this130);
605 vortex_EqHw_SetRightGainsTarget(vortex, &(eq->this130[eq->this10]));
607 return 0;
610 static int
611 vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], unsigned long count)
613 eqlzr_t *eq = &(vortex->eq);
614 int i;
616 if (((eq->this10) * 2 != count) || (eq->this28 == 0))
617 return 1;
619 for (i = 0; i < count; i++) {
620 eq->this130[i] = gains[i];
623 if (eq->this54)
624 return 0;
625 return vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
628 static void
629 vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, unsigned long a,
630 unsigned long b)
632 eqlzr_t *eq = &(vortex->eq);
633 int eax, ebx;
635 eq->this58 = a;
636 eq->this5c = b;
637 if (eq->this54)
638 eax = eq->this0e;
639 else
640 eax = eq->this0a;
641 ebx = (eax * eq->this58) >> 0x10;
642 eax = (eax * eq->this5c) >> 0x10;
643 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
646 static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex)
648 eqlzr_t *eq = &(vortex->eq);
649 int eax, ebx;
651 if (eq->this54)
652 eax = eq->this0e;
653 else
654 eax = eq->this0a;
655 ebx = (eax * eq->this58) >> 0x10;
656 eax = (eax * eq->this5c) >> 0x10;
657 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
660 static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex)
662 if (vortex != NULL)
663 vortex_EqHw_ZeroA3DIO(vortex);
666 static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp)
668 eqlzr_t *eq = &(vortex->eq);
670 if ((eq->this28) && (bp == 0)) {
671 /* EQ enabled */
672 vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
673 vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08);
674 } else {
675 /* EQ disabled. */
676 vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14));
677 vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14));
678 vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c);
680 vortex_Eqlzr_ProgramA3dBypassGain(vortex);
683 static void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex)
685 eqlzr_t *eq = &(vortex->eq);
687 /* Set EQ BiQuad filter coeficients */
688 memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t));
689 /* Set EQ Band gain levels and dump into hardware registers. */
690 vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2);
693 static int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count)
695 eqlzr_t *eq = &(vortex->eq);
697 if (eq->this10 == 0)
698 return 1;
699 *count = eq->this10 * 2;
700 vortex_EqHw_GetTenBandLevels(vortex, peaks);
701 return 0;
704 #if 0
705 static auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex)
707 eqlzr_t *eq = &(vortex->eq);
709 return (&(eq->coefset));
711 #endif
712 static void vortex_Eqlzr_init(vortex_t * vortex)
714 eqlzr_t *eq = &(vortex->eq);
716 /* Object constructor */
717 //eq->this04 = 0;
718 eq->this08 = 0; /* Bypass gain with EQ in use. */
719 eq->this0a = 0x5999;
720 eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */
721 eq->this0e = 0x5999;
723 eq->this10 = 0xa; /* 10 eq frequency bands. */
724 eq->this04.this04 = eq->this10;
725 eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */
726 eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */
727 eq->this58 = 0xffff;
728 eq->this5c = 0xffff;
730 /* Set gains. */
731 memset(eq->this14, 0, 2 * 10);
733 /* Actual init. */
734 vortex_EqHw_ZeroState(vortex);
735 vortex_EqHw_SetSampleRate(vortex, 0x11);
736 vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex);
738 vortex_EqHw_Program10Band(vortex, &(eq->coefset));
739 vortex_Eqlzr_SetBypass(vortex, eq->this54);
740 vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0);
741 vortex_EqHw_Enable(vortex);
744 static void vortex_Eqlzr_shutdown(vortex_t * vortex)
746 vortex_Eqlzr_ShutDownA3d(vortex);
747 vortex_EqHw_ProgramPipe(vortex);
748 vortex_EqHw_Disable(vortex);
751 /* ALSA interface */
753 /* Control interface */
754 static int
755 snd_vortex_eqtoggle_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
757 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
758 uinfo->count = 1;
759 uinfo->value.integer.min = 0;
760 uinfo->value.integer.max = 1;
761 return 0;
764 static int
765 snd_vortex_eqtoggle_get(snd_kcontrol_t * kcontrol,
766 snd_ctl_elem_value_t * ucontrol)
768 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
769 eqlzr_t *eq = &(vortex->eq);
770 //int i = kcontrol->private_value;
772 ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1;
774 return 0;
777 static int
778 snd_vortex_eqtoggle_put(snd_kcontrol_t * kcontrol,
779 snd_ctl_elem_value_t * ucontrol)
781 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
782 eqlzr_t *eq = &(vortex->eq);
783 //int i = kcontrol->private_value;
785 eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1;
786 vortex_Eqlzr_SetBypass(vortex, eq->this54);
788 return 1; /* Allways changes */
791 static snd_kcontrol_new_t vortex_eqtoggle_kcontrol __devinitdata = {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "EQ Enable",
794 .index = 0,
795 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
796 .private_value = 0,
797 .info = snd_vortex_eqtoggle_info,
798 .get = snd_vortex_eqtoggle_get,
799 .put = snd_vortex_eqtoggle_put
802 static int
803 snd_vortex_eq_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
805 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
806 uinfo->count = 2;
807 uinfo->value.integer.min = 0x0000;
808 uinfo->value.integer.max = 0x7fff;
809 return 0;
812 static int
813 snd_vortex_eq_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
815 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
816 int i = kcontrol->private_value;
817 u16 gainL, gainR;
819 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
820 vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
821 ucontrol->value.integer.value[0] = gainL;
822 ucontrol->value.integer.value[1] = gainR;
823 return 0;
826 static int
827 snd_vortex_eq_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
829 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
830 int changed = 0, i = kcontrol->private_value;
831 u16 gainL, gainR;
833 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
834 vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
836 if (gainL != ucontrol->value.integer.value[0]) {
837 vortex_Eqlzr_SetLeftGain(vortex, i,
838 ucontrol->value.integer.value[0]);
839 changed = 1;
841 if (gainR != ucontrol->value.integer.value[1]) {
842 vortex_Eqlzr_SetRightGain(vortex, i,
843 ucontrol->value.integer.value[1]);
844 changed = 1;
846 return changed;
849 static snd_kcontrol_new_t vortex_eq_kcontrol __devinitdata = {
850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
851 .name = " .",
852 .index = 0,
853 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
854 .private_value = 0,
855 .info = snd_vortex_eq_info,
856 .get = snd_vortex_eq_get,
857 .put = snd_vortex_eq_put
860 static int
861 snd_vortex_peaks_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
863 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
864 uinfo->count = 20;
865 uinfo->value.integer.min = 0x0000;
866 uinfo->value.integer.max = 0x7fff;
867 return 0;
870 static int
871 snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
873 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
874 int i, count;
875 u16 peaks[20];
877 vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
878 if (count != 20) {
879 printk("vortex: peak count error 20 != %d \n", count);
880 return -1;
882 for (i = 0; i < 20; i++)
883 ucontrol->value.integer.value[i] = peaks[i];
885 return 0;
888 static snd_kcontrol_new_t vortex_levels_kcontrol __devinitdata = {
889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
890 .name = "EQ Peaks",
891 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
892 .info = snd_vortex_peaks_info,
893 .get = snd_vortex_peaks_get,
896 /* EQ band gain labels. */
897 static char *EqBandLabels[10] __devinitdata = {
898 "EQ0 31Hz\0",
899 "EQ1 63Hz\0",
900 "EQ2 125Hz\0",
901 "EQ3 250Hz\0",
902 "EQ4 500Hz\0",
903 "EQ5 1KHz\0",
904 "EQ6 2KHz\0",
905 "EQ7 4KHz\0",
906 "EQ8 8KHz\0",
907 "EQ9 16KHz\0",
910 /* ALSA driver entry points. Init and exit. */
911 static int vortex_eq_init(vortex_t * vortex)
913 snd_kcontrol_t *kcontrol;
914 int err, i;
916 vortex_Eqlzr_init(vortex);
918 if ((kcontrol =
919 snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL)
920 return -ENOMEM;
921 kcontrol->private_value = 0;
922 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
923 return err;
925 /* EQ gain controls */
926 for (i = 0; i < 10; i++) {
927 if ((kcontrol =
928 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
929 return -ENOMEM;
930 strcpy(kcontrol->id.name, EqBandLabels[i]);
931 kcontrol->private_value = i;
932 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
933 return err;
934 //vortex->eqctrl[i] = kcontrol;
936 /* EQ band levels */
937 if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
938 return -ENOMEM;
939 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
940 return err;
942 return 0;
945 static int vortex_eq_free(vortex_t * vortex)
948 //FIXME: segfault because vortex->eqctrl[i] == 4
949 int i;
950 for (i=0; i<10; i++) {
951 if (vortex->eqctrl[i])
952 snd_ctl_remove(vortex->card, vortex->eqctrl[i]);
955 vortex_Eqlzr_shutdown(vortex);
956 return 0;
959 /* End */