Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 (mjander@users.sourceforge.net)
  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                 strcpy(kcontrol->id.name, EqBandLabels[i]);
900                 kcontrol->private_value = i;
901                 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
902                         return err;
903                 //vortex->eqctrl[i] = kcontrol;
904         }
905         /* EQ band levels */
906         if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
907                 return -ENOMEM;
908         if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
909                 return err;
910 
911         return 0;
912 }
913 
914 static int vortex_eq_free(vortex_t * vortex)
915 {
916         /*
917            //FIXME: segfault because vortex->eqctrl[i] == 4
918            int i;
919            for (i=0; i<10; i++) {
920            if (vortex->eqctrl[i])
921            snd_ctl_remove(vortex->card, vortex->eqctrl[i]);
922            }
923          */
924         vortex_Eqlzr_shutdown(vortex);
925         return 0;
926 }
927 
928 /* End */
929 
  This page was automatically generated by the LXR engine.