Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/au88x0/au88x0_eq.c
10817 views
1
/***************************************************************************
2
* au88x0_eq.c
3
* Aureal Vortex Hardware EQ control/access.
4
*
5
* Sun Jun 8 18:19:19 2003
6
* 2003 Manuel Jander ([email protected])
7
*
8
* 02 July 2003: First time something works :)
9
* November 2003: A3D Bypass code completed but untested.
10
*
11
* TODO:
12
* - Debug (testing)
13
* - Test peak visualization support.
14
*
15
****************************************************************************/
16
17
/*
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.
22
*
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.
27
*
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.
31
*/
32
33
/*
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).
37
*/
38
39
#include "au88x0.h"
40
#include "au88x0_eq.h"
41
#include "au88x0_eqdata.c"
42
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)
47
48
#define VORTEX_BAND_COEFF_SIZE 0x30
49
50
/* CEqHw.s */
51
static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
52
{
53
hwwrite(vortex->mmio, 0x2b3c4, gain);
54
hwwrite(vortex->mmio, 0x2b3c8, level);
55
}
56
57
static inline u16 sign_invert(u16 a)
58
{
59
/* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
60
if (a == (u16)-32768)
61
return 32767;
62
else
63
return -a;
64
}
65
66
static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
67
{
68
eqhw_t *eqhw = &(vortex->eq.this04);
69
int i = 0, n /*esp2c */;
70
71
for (n = 0; n < eqhw->this04; n++) {
72
hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]);
73
hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
74
75
if (eqhw->this08 == 0) {
76
hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
77
hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
78
hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]);
79
} else {
80
hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]));
81
hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]));
82
hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]));
83
}
84
i += 5;
85
}
86
}
87
88
static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
89
{
90
eqhw_t *eqhw = &(vortex->eq.this04);
91
int i = 0, n /*esp2c */;
92
93
for (n = 0; n < eqhw->this04; n++) {
94
hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]);
95
hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
96
97
if (eqhw->this08 == 0) {
98
hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
99
hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
100
hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]);
101
} else {
102
hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]));
103
hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]));
104
hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]));
105
}
106
i += 5;
107
}
108
109
}
110
111
static void vortex_EqHw_SetLeftStates(vortex_t * vortex, u16 a[], u16 b[])
112
{
113
eqhw_t *eqhw = &(vortex->eq.this04);
114
int i = 0, ebx;
115
116
hwwrite(vortex->mmio, 0x2b3fc, a[0]);
117
hwwrite(vortex->mmio, 0x2b400, a[1]);
118
119
for (ebx = 0; ebx < eqhw->this04; ebx++) {
120
hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]);
121
hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]);
122
hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]);
123
hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]);
124
i += 4;
125
}
126
}
127
128
static void vortex_EqHw_SetRightStates(vortex_t * vortex, u16 a[], u16 b[])
129
{
130
eqhw_t *eqhw = &(vortex->eq.this04);
131
int i = 0, ebx;
132
133
hwwrite(vortex->mmio, 0x2b404, a[0]);
134
hwwrite(vortex->mmio, 0x2b408, a[1]);
135
136
for (ebx = 0; ebx < eqhw->this04; ebx++) {
137
hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]);
138
hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]);
139
hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]);
140
hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]);
141
i += 4;
142
}
143
}
144
145
#if 0
146
static void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b)
147
{
148
*a = hwread(vortex->mmio, 0x2b3c4);
149
*b = hwread(vortex->mmio, 0x2b3c8);
150
}
151
152
static void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[])
153
{
154
155
}
156
157
static void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[])
158
{
159
160
}
161
162
static void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[])
163
{
164
165
}
166
167
static void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[])
168
{
169
170
}
171
172
#endif
173
/* Mix Gains */
174
static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
175
{
176
eqhw_t *eqhw = &(vortex->eq.this04);
177
if (eqhw->this08 == 0) {
178
hwwrite(vortex->mmio, 0x2b3d4, a);
179
hwwrite(vortex->mmio, 0x2b3ec, b);
180
} else {
181
hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a));
182
hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b));
183
}
184
}
185
186
static void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
187
{
188
189
hwwrite(vortex->mmio, 0x2b3e0, a);
190
hwwrite(vortex->mmio, 0x2b3f8, b);
191
}
192
193
#if 0
194
static void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b)
195
{
196
197
hwwrite(vortex->mmio, 0x2b3d0, a);
198
hwwrite(vortex->mmio, 0x2b3e8, b);
199
}
200
201
static void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
202
{
203
204
hwwrite(vortex->mmio, 0x2b3dc, a);
205
hwwrite(vortex->mmio, 0x2b3f4, b);
206
}
207
208
#endif
209
static void
210
vortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
211
{
212
hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b);
213
}
214
215
static void
216
vortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
217
{
218
hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b);
219
}
220
221
static void vortex_EqHw_SetLeftGainsTarget(vortex_t * vortex, u16 a[])
222
{
223
eqhw_t *eqhw = &(vortex->eq.this04);
224
int ebx;
225
226
for (ebx = 0; ebx < eqhw->this04; ebx++) {
227
hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]);
228
}
229
}
230
231
static void vortex_EqHw_SetRightGainsTarget(vortex_t * vortex, u16 a[])
232
{
233
eqhw_t *eqhw = &(vortex->eq.this04);
234
int ebx;
235
236
for (ebx = 0; ebx < eqhw->this04; ebx++) {
237
hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]);
238
}
239
}
240
241
static void vortex_EqHw_SetLeftGainsCurrent(vortex_t * vortex, u16 a[])
242
{
243
eqhw_t *eqhw = &(vortex->eq.this04);
244
int ebx;
245
246
for (ebx = 0; ebx < eqhw->this04; ebx++) {
247
hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]);
248
}
249
}
250
251
static void vortex_EqHw_SetRightGainsCurrent(vortex_t * vortex, u16 a[])
252
{
253
eqhw_t *eqhw = &(vortex->eq.this04);
254
int ebx;
255
256
for (ebx = 0; ebx < eqhw->this04; ebx++) {
257
hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]);
258
}
259
}
260
261
#if 0
262
static void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[])
263
{
264
eqhw_t *eqhw = &(vortex->eq.this04);
265
int ebx = 0;
266
267
if (eqhw->this04 < 0)
268
return;
269
270
do {
271
a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30);
272
ebx++;
273
}
274
while (ebx < eqhw->this04);
275
}
276
277
static void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[])
278
{
279
eqhw_t *eqhw = &(vortex->eq.this04);
280
int ebx = 0;
281
282
if (eqhw->this04 < 0)
283
return;
284
285
do {
286
a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30);
287
ebx++;
288
}
289
while (ebx < eqhw->this04);
290
}
291
292
static void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[])
293
{
294
eqhw_t *eqhw = &(vortex->eq.this04);
295
int ebx = 0;
296
297
if (eqhw->this04 < 0)
298
return;
299
300
do {
301
a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30);
302
ebx++;
303
}
304
while (ebx < eqhw->this04);
305
}
306
307
static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[])
308
{
309
eqhw_t *eqhw = &(vortex->eq.this04);
310
int ebx = 0;
311
312
if (eqhw->this04 < 0)
313
return;
314
315
do {
316
a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30);
317
ebx++;
318
}
319
while (ebx < eqhw->this04);
320
}
321
322
#endif
323
/* EQ band levels settings */
324
static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[])
325
{
326
eqhw_t *eqhw = &(vortex->eq.this04);
327
int i;
328
329
/* set left peaks */
330
for (i = 0; i < eqhw->this04; i++) {
331
hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]);
332
}
333
334
hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]);
335
hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]);
336
337
/* set right peaks */
338
for (i = 0; i < eqhw->this04; i++) {
339
hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE,
340
peaks[i + (eqhw->this04 + 2)]);
341
}
342
343
hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]);
344
hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);
345
}
346
347
#if 0
348
static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[])
349
{
350
eqhw_t *eqhw = &(vortex->eq.this04);
351
int ebx;
352
353
if (eqhw->this04 < 0)
354
return;
355
356
ebx = 0;
357
do {
358
a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30);
359
ebx++;
360
}
361
while (ebx < eqhw->this04);
362
363
a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc);
364
a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8);
365
366
ebx = 0;
367
do {
368
a[ebx + (eqhw->this04 + 2)] =
369
hwread(vortex->mmio, 0x2b204 + ebx * 0x30);
370
ebx++;
371
}
372
while (ebx < eqhw->this04);
373
374
a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4);
375
a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0);
376
}
377
378
#endif
379
/* Global Control */
380
static void vortex_EqHw_SetControlReg(vortex_t * vortex, u32 reg)
381
{
382
hwwrite(vortex->mmio, 0x2b440, reg);
383
}
384
385
static void vortex_EqHw_SetSampleRate(vortex_t * vortex, u32 sr)
386
{
387
hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800);
388
}
389
390
#if 0
391
static void vortex_EqHw_GetControlReg(vortex_t * vortex, u32 *reg)
392
{
393
*reg = hwread(vortex->mmio, 0x2b440);
394
}
395
396
static void vortex_EqHw_GetSampleRate(vortex_t * vortex, u32 *sr)
397
{
398
*sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f;
399
}
400
401
#endif
402
static void vortex_EqHw_Enable(vortex_t * vortex)
403
{
404
hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001);
405
}
406
407
static void vortex_EqHw_Disable(vortex_t * vortex)
408
{
409
hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000);
410
}
411
412
/* Reset (zero) buffers */
413
static void vortex_EqHw_ZeroIO(vortex_t * vortex)
414
{
415
int i;
416
for (i = 0; i < 0x8; i++)
417
hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
418
for (i = 0; i < 0x4; i++)
419
hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0);
420
}
421
422
static void vortex_EqHw_ZeroA3DIO(vortex_t * vortex)
423
{
424
int i;
425
for (i = 0; i < 0x4; i++)
426
hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
427
}
428
429
static void vortex_EqHw_ZeroState(vortex_t * vortex)
430
{
431
432
vortex_EqHw_SetControlReg(vortex, 0);
433
vortex_EqHw_ZeroIO(vortex);
434
hwwrite(vortex->mmio, 0x2b3c0, 0);
435
436
vortex_EqHw_SetTimeConsts(vortex, 0, 0);
437
438
vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros);
439
vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros);
440
441
vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero);
442
vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero);
443
vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero);
444
vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero);
445
446
vortex_EqHw_SetBypassGain(vortex, 0, 0);
447
//vortex_EqHw_SetCurrBypassGain(vortex, 0, 0);
448
vortex_EqHw_SetA3DBypassGain(vortex, 0, 0);
449
//vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0);
450
vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros);
451
vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros);
452
vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels);
453
}
454
455
/* Program coeficients as pass through */
456
static void vortex_EqHw_ProgramPipe(vortex_t * vortex)
457
{
458
vortex_EqHw_SetTimeConsts(vortex, 0, 0);
459
460
vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes);
461
vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes);
462
463
vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current);
464
vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current);
465
vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current);
466
vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current);
467
}
468
469
/* Program EQ block as 10 band Equalizer */
470
static void
471
vortex_EqHw_Program10Band(vortex_t * vortex, auxxEqCoeffSet_t * coefset)
472
{
473
474
vortex_EqHw_SetTimeConsts(vortex, 0xc, 0x7fe0);
475
476
vortex_EqHw_SetLeftCoefs(vortex, coefset->LeftCoefs);
477
vortex_EqHw_SetRightCoefs(vortex, coefset->RightCoefs);
478
479
vortex_EqHw_SetLeftGainsCurrent(vortex, coefset->LeftGains);
480
481
vortex_EqHw_SetRightGainsTarget(vortex, coefset->RightGains);
482
vortex_EqHw_SetLeftGainsTarget(vortex, coefset->LeftGains);
483
484
vortex_EqHw_SetRightGainsCurrent(vortex, coefset->RightGains);
485
}
486
487
/* Read all EQ peaks. (think VU meter) */
488
static void vortex_EqHw_GetTenBandLevels(vortex_t * vortex, u16 peaks[])
489
{
490
eqhw_t *eqhw = &(vortex->eq.this04);
491
int i;
492
493
if (eqhw->this04 <= 0)
494
return;
495
496
for (i = 0; i < eqhw->this04; i++)
497
peaks[i] = hwread(vortex->mmio, 0x2B024 + i * 0x30);
498
for (i = 0; i < eqhw->this04; i++)
499
peaks[i + eqhw->this04] =
500
hwread(vortex->mmio, 0x2B204 + i * 0x30);
501
}
502
503
/* CEqlzr.s */
504
505
static int vortex_Eqlzr_GetLeftGain(vortex_t * vortex, u16 index, u16 * gain)
506
{
507
eqlzr_t *eq = &(vortex->eq);
508
509
if (eq->this28) {
510
*gain = eq->this130[index];
511
return 0;
512
}
513
return 1;
514
}
515
516
static void vortex_Eqlzr_SetLeftGain(vortex_t * vortex, u16 index, u16 gain)
517
{
518
eqlzr_t *eq = &(vortex->eq);
519
520
if (eq->this28 == 0)
521
return;
522
523
eq->this130[index] = gain;
524
if (eq->this54)
525
return;
526
527
vortex_EqHw_SetLeftGainsSingleTarget(vortex, index, gain);
528
}
529
530
static int vortex_Eqlzr_GetRightGain(vortex_t * vortex, u16 index, u16 * gain)
531
{
532
eqlzr_t *eq = &(vortex->eq);
533
534
if (eq->this28) {
535
*gain = eq->this130[index + eq->this10];
536
return 0;
537
}
538
return 1;
539
}
540
541
static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain)
542
{
543
eqlzr_t *eq = &(vortex->eq);
544
545
if (eq->this28 == 0)
546
return;
547
548
eq->this130[index + eq->this10] = gain;
549
if (eq->this54)
550
return;
551
552
vortex_EqHw_SetRightGainsSingleTarget(vortex, index, gain);
553
}
554
555
#if 0
556
static int
557
vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, s32 *cnt)
558
{
559
eqlzr_t *eq = &(vortex->eq);
560
int si = 0;
561
562
if (eq->this10 == 0)
563
return 1;
564
565
{
566
if (vortex_Eqlzr_GetLeftGain(vortex, si, &gains[si]))
567
return 1;
568
if (vortex_Eqlzr_GetRightGain
569
(vortex, si, &gains[si + eq->this10]))
570
return 1;
571
si++;
572
}
573
while (eq->this10 > si) ;
574
*cnt = si * 2;
575
return 0;
576
}
577
#endif
578
static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex)
579
{
580
eqlzr_t *eq = &(vortex->eq);
581
582
vortex_EqHw_SetLeftGainsTarget(vortex, eq->this130);
583
vortex_EqHw_SetRightGainsTarget(vortex, &(eq->this130[eq->this10]));
584
585
return 0;
586
}
587
588
static int
589
vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], s32 count)
590
{
591
eqlzr_t *eq = &(vortex->eq);
592
int i;
593
594
if (((eq->this10) * 2 != count) || (eq->this28 == 0))
595
return 1;
596
597
for (i = 0; i < count; i++) {
598
eq->this130[i] = gains[i];
599
}
600
601
if (eq->this54)
602
return 0;
603
return vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
604
}
605
606
static void
607
vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b)
608
{
609
eqlzr_t *eq = &(vortex->eq);
610
u32 eax, ebx;
611
612
eq->this58 = a;
613
eq->this5c = b;
614
if (eq->this54)
615
eax = eq->this0e;
616
else
617
eax = eq->this0a;
618
ebx = (eax * eq->this58) >> 0x10;
619
eax = (eax * eq->this5c) >> 0x10;
620
vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
621
}
622
623
static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex)
624
{
625
eqlzr_t *eq = &(vortex->eq);
626
u32 eax, ebx;
627
628
if (eq->this54)
629
eax = eq->this0e;
630
else
631
eax = eq->this0a;
632
ebx = (eax * eq->this58) >> 0x10;
633
eax = (eax * eq->this5c) >> 0x10;
634
vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
635
}
636
637
static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex)
638
{
639
if (vortex != NULL)
640
vortex_EqHw_ZeroA3DIO(vortex);
641
}
642
643
static void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp)
644
{
645
eqlzr_t *eq = &(vortex->eq);
646
647
if ((eq->this28) && (bp == 0)) {
648
/* EQ enabled */
649
vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
650
vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08);
651
} else {
652
/* EQ disabled. */
653
vortex_EqHw_SetLeftGainsTarget(vortex, eq->this14_array);
654
vortex_EqHw_SetRightGainsTarget(vortex, eq->this14_array);
655
vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c);
656
}
657
vortex_Eqlzr_ProgramA3dBypassGain(vortex);
658
}
659
660
static void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex)
661
{
662
eqlzr_t *eq = &(vortex->eq);
663
664
/* Set EQ BiQuad filter coeficients */
665
memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t));
666
/* Set EQ Band gain levels and dump into hardware registers. */
667
vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2);
668
}
669
670
static int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count)
671
{
672
eqlzr_t *eq = &(vortex->eq);
673
674
if (eq->this10 == 0)
675
return 1;
676
*count = eq->this10 * 2;
677
vortex_EqHw_GetTenBandLevels(vortex, peaks);
678
return 0;
679
}
680
681
#if 0
682
static auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex)
683
{
684
eqlzr_t *eq = &(vortex->eq);
685
686
return (&(eq->coefset));
687
}
688
#endif
689
static void vortex_Eqlzr_init(vortex_t * vortex)
690
{
691
eqlzr_t *eq = &(vortex->eq);
692
693
/* Object constructor */
694
//eq->this04 = 0;
695
eq->this08 = 0; /* Bypass gain with EQ in use. */
696
eq->this0a = 0x5999;
697
eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */
698
eq->this0e = 0x5999;
699
700
eq->this10 = 0xa; /* 10 eq frequency bands. */
701
eq->this04.this04 = eq->this10;
702
eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */
703
eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */
704
eq->this58 = 0xffff;
705
eq->this5c = 0xffff;
706
707
/* Set gains. */
708
memset(eq->this14_array, 0, sizeof(eq->this14_array));
709
710
/* Actual init. */
711
vortex_EqHw_ZeroState(vortex);
712
vortex_EqHw_SetSampleRate(vortex, 0x11);
713
vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex);
714
715
vortex_EqHw_Program10Band(vortex, &(eq->coefset));
716
vortex_Eqlzr_SetBypass(vortex, eq->this54);
717
vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0);
718
vortex_EqHw_Enable(vortex);
719
}
720
721
static void vortex_Eqlzr_shutdown(vortex_t * vortex)
722
{
723
vortex_Eqlzr_ShutDownA3d(vortex);
724
vortex_EqHw_ProgramPipe(vortex);
725
vortex_EqHw_Disable(vortex);
726
}
727
728
/* ALSA interface */
729
730
/* Control interface */
731
#define snd_vortex_eqtoggle_info snd_ctl_boolean_mono_info
732
733
static int
734
snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol,
735
struct snd_ctl_elem_value *ucontrol)
736
{
737
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
738
eqlzr_t *eq = &(vortex->eq);
739
//int i = kcontrol->private_value;
740
741
ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1;
742
743
return 0;
744
}
745
746
static int
747
snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol,
748
struct snd_ctl_elem_value *ucontrol)
749
{
750
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
751
eqlzr_t *eq = &(vortex->eq);
752
//int i = kcontrol->private_value;
753
754
eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1;
755
vortex_Eqlzr_SetBypass(vortex, eq->this54);
756
757
return 1; /* Allways changes */
758
}
759
760
static struct snd_kcontrol_new vortex_eqtoggle_kcontrol __devinitdata = {
761
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
762
.name = "EQ Enable",
763
.index = 0,
764
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
765
.private_value = 0,
766
.info = snd_vortex_eqtoggle_info,
767
.get = snd_vortex_eqtoggle_get,
768
.put = snd_vortex_eqtoggle_put
769
};
770
771
static int
772
snd_vortex_eq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
773
{
774
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
775
uinfo->count = 2;
776
uinfo->value.integer.min = 0x0000;
777
uinfo->value.integer.max = 0x7fff;
778
return 0;
779
}
780
781
static int
782
snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
783
{
784
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
785
int i = kcontrol->private_value;
786
u16 gainL = 0, gainR = 0;
787
788
vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
789
vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
790
ucontrol->value.integer.value[0] = gainL;
791
ucontrol->value.integer.value[1] = gainR;
792
return 0;
793
}
794
795
static int
796
snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
797
{
798
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
799
int changed = 0, i = kcontrol->private_value;
800
u16 gainL = 0, gainR = 0;
801
802
vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
803
vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
804
805
if (gainL != ucontrol->value.integer.value[0]) {
806
vortex_Eqlzr_SetLeftGain(vortex, i,
807
ucontrol->value.integer.value[0]);
808
changed = 1;
809
}
810
if (gainR != ucontrol->value.integer.value[1]) {
811
vortex_Eqlzr_SetRightGain(vortex, i,
812
ucontrol->value.integer.value[1]);
813
changed = 1;
814
}
815
return changed;
816
}
817
818
static struct snd_kcontrol_new vortex_eq_kcontrol __devinitdata = {
819
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
820
.name = " .",
821
.index = 0,
822
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
823
.private_value = 0,
824
.info = snd_vortex_eq_info,
825
.get = snd_vortex_eq_get,
826
.put = snd_vortex_eq_put
827
};
828
829
static int
830
snd_vortex_peaks_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
831
{
832
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
833
uinfo->count = 20;
834
uinfo->value.integer.min = 0x0000;
835
uinfo->value.integer.max = 0x7fff;
836
return 0;
837
}
838
839
static int
840
snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
841
{
842
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
843
int i, count = 0;
844
u16 peaks[20];
845
846
vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
847
if (count != 20) {
848
printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
849
return -1;
850
}
851
for (i = 0; i < 20; i++)
852
ucontrol->value.integer.value[i] = peaks[i];
853
854
return 0;
855
}
856
857
static struct snd_kcontrol_new vortex_levels_kcontrol __devinitdata = {
858
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
859
.name = "EQ Peaks",
860
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
861
.info = snd_vortex_peaks_info,
862
.get = snd_vortex_peaks_get,
863
};
864
865
/* EQ band gain labels. */
866
static char *EqBandLabels[10] __devinitdata = {
867
"EQ0 31Hz\0",
868
"EQ1 63Hz\0",
869
"EQ2 125Hz\0",
870
"EQ3 250Hz\0",
871
"EQ4 500Hz\0",
872
"EQ5 1KHz\0",
873
"EQ6 2KHz\0",
874
"EQ7 4KHz\0",
875
"EQ8 8KHz\0",
876
"EQ9 16KHz\0",
877
};
878
879
/* ALSA driver entry points. Init and exit. */
880
static int __devinit vortex_eq_init(vortex_t * vortex)
881
{
882
struct snd_kcontrol *kcontrol;
883
int err, i;
884
885
vortex_Eqlzr_init(vortex);
886
887
if ((kcontrol =
888
snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL)
889
return -ENOMEM;
890
kcontrol->private_value = 0;
891
if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
892
return err;
893
894
/* EQ gain controls */
895
for (i = 0; i < 10; i++) {
896
if ((kcontrol =
897
snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
898
return -ENOMEM;
899
snprintf(kcontrol->id.name, sizeof(kcontrol->id.name),
900
"%s Playback Volume", EqBandLabels[i]);
901
kcontrol->private_value = i;
902
if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
903
return err;
904
//vortex->eqctrl[i] = kcontrol;
905
}
906
/* EQ band levels */
907
if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
908
return -ENOMEM;
909
if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
910
return err;
911
912
return 0;
913
}
914
915
static int vortex_eq_free(vortex_t * vortex)
916
{
917
/*
918
//FIXME: segfault because vortex->eqctrl[i] == 4
919
int i;
920
for (i=0; i<10; i++) {
921
if (vortex->eqctrl[i])
922
snd_ctl_remove(vortex->card, vortex->eqctrl[i]);
923
}
924
*/
925
vortex_Eqlzr_shutdown(vortex);
926
return 0;
927
}
928
929
/* End */
930
931