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, unsigned long reg) 381 { 382 hwwrite(vortex->mmio, 0x2b440, reg); 383 } 384 385 static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int 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, unsigned long *reg) 392 { 393 *reg = hwread(vortex->mmio, 0x2b440); 394 } 395 396 static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *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, unsigned long *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[], unsigned long 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, unsigned long a, 608 unsigned long b) 609 { 610 eqlzr_t *eq = &(vortex->eq); 611 int eax, ebx; 612 613 eq->this58 = a; 614 eq->this5c = b; 615 if (eq->this54) 616 eax = eq->this0e; 617 else 618 eax = eq->this0a; 619 ebx = (eax * eq->this58) >> 0x10; 620 eax = (eax * eq->this5c) >> 0x10; 621 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax); 622 } 623 624 static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex) 625 { 626 eqlzr_t *eq = &(vortex->eq); 627 int eax, ebx; 628 629 if (eq->this54) 630 eax = eq->this0e; 631 else 632 eax = eq->this0a; 633 ebx = (eax * eq->this58) >> 0x10; 634 eax = (eax * eq->this5c) >> 0x10; 635 vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax); 636 } 637 638 static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex) 639 { 640 if (vortex != NULL) 641 vortex_EqHw_ZeroA3DIO(vortex); 642 } 643 644 static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp) 645 { 646 eqlzr_t *eq = &(vortex->eq); 647 648 if ((eq->this28) && (bp == 0)) { 649 /* EQ enabled */ 650 vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex); 651 vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08); 652 } else { 653 /* EQ disabled. */ 654 vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14)); 655 vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14)); 656 vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c); 657 } 658 vortex_Eqlzr_ProgramA3dBypassGain(vortex); 659 } 660 661 static void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex) 662 { 663 eqlzr_t *eq = &(vortex->eq); 664 665 /* Set EQ BiQuad filter coeficients */ 666 memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t)); 667 /* Set EQ Band gain levels and dump into hardware registers. */ 668 vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2); 669 } 670 671 static int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count) 672 { 673 eqlzr_t *eq = &(vortex->eq); 674 675 if (eq->this10 == 0) 676 return 1; 677 *count = eq->this10 * 2; 678 vortex_EqHw_GetTenBandLevels(vortex, peaks); 679 return 0; 680 } 681 682 #if 0 683 static auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex) 684 { 685 eqlzr_t *eq = &(vortex->eq); 686 687 return (&(eq->coefset)); 688 } 689 #endif 690 static void vortex_Eqlzr_init(vortex_t * vortex) 691 { 692 eqlzr_t *eq = &(vortex->eq); 693 694 /* Object constructor */ 695 //eq->this04 = 0; 696 eq->this08 = 0; /* Bypass gain with EQ in use. */ 697 eq->this0a = 0x5999; 698 eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */ 699 eq->this0e = 0x5999; 700 701 eq->this10 = 0xa; /* 10 eq frequency bands. */ 702 eq->this04.this04 = eq->this10; 703 eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */ 704 eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */ 705 eq->this58 = 0xffff; 706 eq->this5c = 0xffff; 707 708 /* Set gains. */ 709 memset(eq->this14, 0, 2 * 10); 710 711 /* Actual init. */ 712 vortex_EqHw_ZeroState(vortex); 713 vortex_EqHw_SetSampleRate(vortex, 0x11); 714 vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex); 715 716 vortex_EqHw_Program10Band(vortex, &(eq->coefset)); 717 vortex_Eqlzr_SetBypass(vortex, eq->this54); 718 vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0); 719 vortex_EqHw_Enable(vortex); 720 } 721 722 static void vortex_Eqlzr_shutdown(vortex_t * vortex) 723 { 724 vortex_Eqlzr_ShutDownA3d(vortex); 725 vortex_EqHw_ProgramPipe(vortex); 726 vortex_EqHw_Disable(vortex); 727 } 728 729 /* ALSA interface */ 730 731 /* Control interface */ 732 static int 733 snd_vortex_eqtoggle_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 734 { 735 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 736 uinfo->count = 1; 737 uinfo->value.integer.min = 0; 738 uinfo->value.integer.max = 1; 739 return 0; 740 } 741 742 static int 743 snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol, 744 struct snd_ctl_elem_value *ucontrol) 745 { 746 vortex_t *vortex = snd_kcontrol_chip(kcontrol); 747 eqlzr_t *eq = &(vortex->eq); 748 //int i = kcontrol->private_value; 749 750 ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1; 751 752 return 0; 753 } 754 755 static int 756 snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol, 757 struct snd_ctl_elem_value *ucontrol) 758 { 759 vortex_t *vortex = snd_kcontrol_chip(kcontrol); 760 eqlzr_t *eq = &(vortex->eq); 761 //int i = kcontrol->private_value; 762 763 eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1; 764 vortex_Eqlzr_SetBypass(vortex, eq->this54); 765 766 return 1; /* Allways changes */ 767 } 768 769 static struct snd_kcontrol_new vortex_eqtoggle_kcontrol __devinitdata = { 770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 771 .name = "EQ Enable", 772 .index = 0, 773 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 774 .private_value = 0, 775 .info = snd_vortex_eqtoggle_info, 776 .get = snd_vortex_eqtoggle_get, 777 .put = snd_vortex_eqtoggle_put 778 }; 779 780 static int 781 snd_vortex_eq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 782 { 783 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 784 uinfo->count = 2; 785 uinfo->value.integer.min = 0x0000; 786 uinfo->value.integer.max = 0x7fff; 787 return 0; 788 } 789 790 static int 791 snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 792 { 793 vortex_t *vortex = snd_kcontrol_chip(kcontrol); 794 int i = kcontrol->private_value; 795 u16 gainL, gainR; 796 797 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); 798 vortex_Eqlzr_GetRightGain(vortex, i, &gainR); 799 ucontrol->value.integer.value[0] = gainL; 800 ucontrol->value.integer.value[1] = gainR; 801 return 0; 802 } 803 804 static int 805 snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 806 { 807 vortex_t *vortex = snd_kcontrol_chip(kcontrol); 808 int changed = 0, i = kcontrol->private_value; 809 u16 gainL, gainR; 810 811 vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); 812 vortex_Eqlzr_GetRightGain(vortex, i, &gainR); 813 814 if (gainL != ucontrol->value.integer.value[0]) { 815 vortex_Eqlzr_SetLeftGain(vortex, i, 816 ucontrol->value.integer.value[0]); 817 changed = 1; 818 } 819 if (gainR != ucontrol->value.integer.value[1]) { 820 vortex_Eqlzr_SetRightGain(vortex, i, 821 ucontrol->value.integer.value[1]); 822 changed = 1; 823 } 824 return changed; 825 } 826 827 static struct snd_kcontrol_new vortex_eq_kcontrol __devinitdata = { 828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 829 .name = " .", 830 .index = 0, 831 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 832 .private_value = 0, 833 .info = snd_vortex_eq_info, 834 .get = snd_vortex_eq_get, 835 .put = snd_vortex_eq_put 836 }; 837 838 static int 839 snd_vortex_peaks_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 840 { 841 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 842 uinfo->count = 20; 843 uinfo->value.integer.min = 0x0000; 844 uinfo->value.integer.max = 0x7fff; 845 return 0; 846 } 847 848 static int 849 snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 850 { 851 vortex_t *vortex = snd_kcontrol_chip(kcontrol); 852 int i, count; 853 u16 peaks[20]; 854 855 vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); 856 if (count != 20) { 857 printk(KERN_ERR "vortex: peak count error 20 != %d \n", count); 858 return -1; 859 } 860 for (i = 0; i < 20; i++) 861 ucontrol->value.integer.value[i] = peaks[i]; 862 863 return 0; 864 } 865 866 static struct snd_kcontrol_new vortex_levels_kcontrol __devinitdata = { 867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 868 .name = "EQ Peaks", 869 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 870 .info = snd_vortex_peaks_info, 871 .get = snd_vortex_peaks_get, 872 }; 873 874 /* EQ band gain labels. */ 875 static char *EqBandLabels[10] __devinitdata = { 876 "EQ0 31Hz\0", 877 "EQ1 63Hz\0", 878 "EQ2 125Hz\0", 879 "EQ3 250Hz\0", 880 "EQ4 500Hz\0", 881 "EQ5 1KHz\0", 882 "EQ6 2KHz\0", 883 "EQ7 4KHz\0", 884 "EQ8 8KHz\0", 885 "EQ9 16KHz\0", 886 }; 887 888 /* ALSA driver entry points. Init and exit. */ 889 static int vortex_eq_init(vortex_t * vortex) 890 { 891 struct snd_kcontrol *kcontrol; 892 int err, i; 893 894 vortex_Eqlzr_init(vortex); 895 896 if ((kcontrol = 897 snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL) 898 return -ENOMEM; 899 kcontrol->private_value = 0; 900 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 901 return err; 902 903 /* EQ gain controls */ 904 for (i = 0; i < 10; i++) { 905 if ((kcontrol = 906 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL) 907 return -ENOMEM; 908 strcpy(kcontrol->id.name, EqBandLabels[i]); 909 kcontrol->private_value = i; 910 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 911 return err; 912 //vortex->eqctrl[i] = kcontrol; 913 } 914 /* EQ band levels */ 915 if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL) 916 return -ENOMEM; 917 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 918 return err; 919 920 return 0; 921 } 922 923 static int vortex_eq_free(vortex_t * vortex) 924 { 925 /* 926 //FIXME: segfault because vortex->eqctrl[i] == 4 927 int i; 928 for (i=0; i<10; i++) { 929 if (vortex->eqctrl[i]) 930 snd_ctl_remove(vortex->card, vortex->eqctrl[i]); 931 } 932 */ 933 vortex_Eqlzr_shutdown(vortex); 934 return 0; 935 } 936 937 /* End */ 938