root/sound/pci/au88x0/au88x0_eq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vortex_EqHw_SetTimeConsts
  2. sign_invert
  3. vortex_EqHw_SetLeftCoefs
  4. vortex_EqHw_SetRightCoefs
  5. vortex_EqHw_SetLeftStates
  6. vortex_EqHw_SetRightStates
  7. vortex_EqHw_GetTimeConsts
  8. vortex_EqHw_GetLeftCoefs
  9. vortex_EqHw_GetRightCoefs
  10. vortex_EqHw_GetLeftStates
  11. vortex_EqHw_GetRightStates
  12. vortex_EqHw_SetBypassGain
  13. vortex_EqHw_SetA3DBypassGain
  14. vortex_EqHw_SetCurrBypassGain
  15. vortex_EqHw_SetCurrA3DBypassGain
  16. vortex_EqHw_SetLeftGainsSingleTarget
  17. vortex_EqHw_SetRightGainsSingleTarget
  18. vortex_EqHw_SetLeftGainsTarget
  19. vortex_EqHw_SetRightGainsTarget
  20. vortex_EqHw_SetLeftGainsCurrent
  21. vortex_EqHw_SetRightGainsCurrent
  22. vortex_EqHw_GetLeftGainsTarget
  23. vortex_EqHw_GetRightGainsTarget
  24. vortex_EqHw_GetLeftGainsCurrent
  25. vortex_EqHw_GetRightGainsCurrent
  26. vortex_EqHw_SetLevels
  27. vortex_EqHw_GetLevels
  28. vortex_EqHw_SetControlReg
  29. vortex_EqHw_SetSampleRate
  30. vortex_EqHw_GetControlReg
  31. vortex_EqHw_GetSampleRate
  32. vortex_EqHw_Enable
  33. vortex_EqHw_Disable
  34. vortex_EqHw_ZeroIO
  35. vortex_EqHw_ZeroA3DIO
  36. vortex_EqHw_ZeroState
  37. vortex_EqHw_ProgramPipe
  38. vortex_EqHw_Program10Band
  39. vortex_EqHw_GetTenBandLevels
  40. vortex_Eqlzr_GetLeftGain
  41. vortex_Eqlzr_SetLeftGain
  42. vortex_Eqlzr_GetRightGain
  43. vortex_Eqlzr_SetRightGain
  44. vortex_Eqlzr_GetAllBands
  45. vortex_Eqlzr_SetAllBandsFromActiveCoeffSet
  46. vortex_Eqlzr_SetAllBands
  47. vortex_Eqlzr_SetA3dBypassGain
  48. vortex_Eqlzr_ProgramA3dBypassGain
  49. vortex_Eqlzr_ShutDownA3d
  50. vortex_Eqlzr_SetBypass
  51. vortex_Eqlzr_ReadAndSetActiveCoefSet
  52. vortex_Eqlzr_GetAllPeaks
  53. vortex_Eqlzr_GetActiveCoefSet
  54. vortex_Eqlzr_init
  55. vortex_Eqlzr_shutdown
  56. snd_vortex_eqtoggle_get
  57. snd_vortex_eqtoggle_put
  58. snd_vortex_eq_info
  59. snd_vortex_eq_get
  60. snd_vortex_eq_put
  61. snd_vortex_peaks_info
  62. snd_vortex_peaks_get
  63. vortex_eq_init
  64. vortex_eq_free

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

/* [<][>][^][v][top][bottom][index][help] */