162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/*************************************************************************** 362306a36Sopenharmony_ci * au88x0_eq.c 462306a36Sopenharmony_ci * Aureal Vortex Hardware EQ control/access. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Sun Jun 8 18:19:19 2003 762306a36Sopenharmony_ci * 2003 Manuel Jander (mjander@users.sourceforge.net) 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * 02 July 2003: First time something works :) 1062306a36Sopenharmony_ci * November 2003: A3D Bypass code completed but untested. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * TODO: 1362306a36Sopenharmony_ci * - Debug (testing) 1462306a36Sopenharmony_ci * - Test peak visualization support. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci ****************************************************************************/ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci The Aureal Hardware EQ is found on AU8810 and AU8830 chips only. 2362306a36Sopenharmony_ci it has 4 inputs (2 for general mix, 2 for A3D) and 2 outputs (supposed 2462306a36Sopenharmony_ci to be routed to the codec). 2562306a36Sopenharmony_ci*/ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "au88x0.h" 2862306a36Sopenharmony_ci#include "au88x0_eq.h" 2962306a36Sopenharmony_ci#include "au88x0_eqdata.c" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define VORTEX_EQ_BASE 0x2b000 3262306a36Sopenharmony_ci#define VORTEX_EQ_DEST (VORTEX_EQ_BASE + 0x410) 3362306a36Sopenharmony_ci#define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430) 3462306a36Sopenharmony_ci#define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define VORTEX_BAND_COEFF_SIZE 0x30 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* CEqHw.s */ 3962306a36Sopenharmony_cistatic void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3c4, gain); 4262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3c8, level); 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic inline u16 sign_invert(u16 a) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci /* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */ 4862306a36Sopenharmony_ci if (a == (u16)-32768) 4962306a36Sopenharmony_ci return 32767; 5062306a36Sopenharmony_ci else 5162306a36Sopenharmony_ci return -a; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic void vortex_EqHw_SetLeftCoefs(vortex_t *vortex, const u16 coefs[]) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 5762306a36Sopenharmony_ci int i = 0, n /*esp2c */; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci for (n = 0; n < eqhw->this04; n++) { 6062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]); 6162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (eqhw->this08 == 0) { 6462306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]); 6562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]); 6662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]); 6762306a36Sopenharmony_ci } else { 6862306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i])); 6962306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i])); 7062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i])); 7162306a36Sopenharmony_ci } 7262306a36Sopenharmony_ci i += 5; 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic void vortex_EqHw_SetRightCoefs(vortex_t *vortex, const u16 coefs[]) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 7962306a36Sopenharmony_ci int i = 0, n /*esp2c */; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci for (n = 0; n < eqhw->this04; n++) { 8262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]); 8362306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci if (eqhw->this08 == 0) { 8662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]); 8762306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]); 8862306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]); 8962306a36Sopenharmony_ci } else { 9062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i])); 9162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i])); 9262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i])); 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci i += 5; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistatic void vortex_EqHw_SetLeftStates(vortex_t *vortex, const u16 a[], const u16 b[]) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 10262306a36Sopenharmony_ci int i = 0, ebx; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3fc, a[0]); 10562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b400, a[1]); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 10862306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]); 10962306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]); 11062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]); 11162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]); 11262306a36Sopenharmony_ci i += 4; 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic void vortex_EqHw_SetRightStates(vortex_t *vortex, const u16 a[], const u16 b[]) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 11962306a36Sopenharmony_ci int i = 0, ebx; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b404, a[0]); 12262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b408, a[1]); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 12562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]); 12662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]); 12762306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]); 12862306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]); 12962306a36Sopenharmony_ci i += 4; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci#if 0 13462306a36Sopenharmony_cistatic void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci *a = hwread(vortex->mmio, 0x2b3c4); 13762306a36Sopenharmony_ci *b = hwread(vortex->mmio, 0x2b3c8); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[]) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[]) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[]) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[]) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci#endif 16162306a36Sopenharmony_ci/* Mix Gains */ 16262306a36Sopenharmony_cistatic void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 16562306a36Sopenharmony_ci if (eqhw->this08 == 0) { 16662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3d4, a); 16762306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3ec, b); 16862306a36Sopenharmony_ci } else { 16962306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a)); 17062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b)); 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3e0, a); 17862306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3f8, b); 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#if 0 18262306a36Sopenharmony_cistatic void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3d0, a); 18662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3e8, b); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3dc, a); 19362306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3f4, b); 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#endif 19762306a36Sopenharmony_cistatic void 19862306a36Sopenharmony_civortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b); 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic void 20462306a36Sopenharmony_civortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b); 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic void vortex_EqHw_SetLeftGainsTarget(vortex_t *vortex, const u16 a[]) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 21262306a36Sopenharmony_ci int ebx; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 21562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]); 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic void vortex_EqHw_SetRightGainsTarget(vortex_t *vortex, const u16 a[]) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 22262306a36Sopenharmony_ci int ebx; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 22562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]); 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistatic void vortex_EqHw_SetLeftGainsCurrent(vortex_t *vortex, const u16 a[]) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 23262306a36Sopenharmony_ci int ebx; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 23562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]); 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic void vortex_EqHw_SetRightGainsCurrent(vortex_t *vortex, const u16 a[]) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 24262306a36Sopenharmony_ci int ebx; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci for (ebx = 0; ebx < eqhw->this04; ebx++) { 24562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]); 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#if 0 25062306a36Sopenharmony_cistatic void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[]) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 25362306a36Sopenharmony_ci int ebx = 0; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci if (eqhw->this04 < 0) 25662306a36Sopenharmony_ci return; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci do { 25962306a36Sopenharmony_ci a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30); 26062306a36Sopenharmony_ci ebx++; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci while (ebx < eqhw->this04); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[]) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 26862306a36Sopenharmony_ci int ebx = 0; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci if (eqhw->this04 < 0) 27162306a36Sopenharmony_ci return; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci do { 27462306a36Sopenharmony_ci a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30); 27562306a36Sopenharmony_ci ebx++; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci while (ebx < eqhw->this04); 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[]) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 28362306a36Sopenharmony_ci int ebx = 0; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (eqhw->this04 < 0) 28662306a36Sopenharmony_ci return; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci do { 28962306a36Sopenharmony_ci a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30); 29062306a36Sopenharmony_ci ebx++; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci while (ebx < eqhw->this04); 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[]) 29662306a36Sopenharmony_ci{ 29762306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 29862306a36Sopenharmony_ci int ebx = 0; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if (eqhw->this04 < 0) 30162306a36Sopenharmony_ci return; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci do { 30462306a36Sopenharmony_ci a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30); 30562306a36Sopenharmony_ci ebx++; 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci while (ebx < eqhw->this04); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci#endif 31162306a36Sopenharmony_ci/* EQ band levels settings */ 31262306a36Sopenharmony_cistatic void vortex_EqHw_SetLevels(vortex_t *vortex, const u16 peaks[]) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 31562306a36Sopenharmony_ci int i; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* set left peaks */ 31862306a36Sopenharmony_ci for (i = 0; i < eqhw->this04; i++) { 31962306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]); 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]); 32362306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci /* set right peaks */ 32662306a36Sopenharmony_ci for (i = 0; i < eqhw->this04; i++) { 32762306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE, 32862306a36Sopenharmony_ci peaks[i + (eqhw->this04 + 2)]); 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]); 33262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]); 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci#if 0 33662306a36Sopenharmony_cistatic void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[]) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 33962306a36Sopenharmony_ci int ebx; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci if (eqhw->this04 < 0) 34262306a36Sopenharmony_ci return; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci ebx = 0; 34562306a36Sopenharmony_ci do { 34662306a36Sopenharmony_ci a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30); 34762306a36Sopenharmony_ci ebx++; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci while (ebx < eqhw->this04); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc); 35262306a36Sopenharmony_ci a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci ebx = 0; 35562306a36Sopenharmony_ci do { 35662306a36Sopenharmony_ci a[ebx + (eqhw->this04 + 2)] = 35762306a36Sopenharmony_ci hwread(vortex->mmio, 0x2b204 + ebx * 0x30); 35862306a36Sopenharmony_ci ebx++; 35962306a36Sopenharmony_ci } 36062306a36Sopenharmony_ci while (ebx < eqhw->this04); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4); 36362306a36Sopenharmony_ci a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0); 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci#endif 36762306a36Sopenharmony_ci/* Global Control */ 36862306a36Sopenharmony_cistatic void vortex_EqHw_SetControlReg(vortex_t * vortex, u32 reg) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b440, reg); 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistatic void vortex_EqHw_SetSampleRate(vortex_t * vortex, u32 sr) 37462306a36Sopenharmony_ci{ 37562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800); 37662306a36Sopenharmony_ci} 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci#if 0 37962306a36Sopenharmony_cistatic void vortex_EqHw_GetControlReg(vortex_t * vortex, u32 *reg) 38062306a36Sopenharmony_ci{ 38162306a36Sopenharmony_ci *reg = hwread(vortex->mmio, 0x2b440); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cistatic void vortex_EqHw_GetSampleRate(vortex_t * vortex, u32 *sr) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f; 38762306a36Sopenharmony_ci} 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci#endif 39062306a36Sopenharmony_cistatic void vortex_EqHw_Enable(vortex_t * vortex) 39162306a36Sopenharmony_ci{ 39262306a36Sopenharmony_ci hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001); 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistatic void vortex_EqHw_Disable(vortex_t * vortex) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000); 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci/* Reset (zero) buffers */ 40162306a36Sopenharmony_cistatic void vortex_EqHw_ZeroIO(vortex_t * vortex) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci int i; 40462306a36Sopenharmony_ci for (i = 0; i < 0x8; i++) 40562306a36Sopenharmony_ci hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0); 40662306a36Sopenharmony_ci for (i = 0; i < 0x4; i++) 40762306a36Sopenharmony_ci hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0); 40862306a36Sopenharmony_ci} 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_cistatic void vortex_EqHw_ZeroA3DIO(vortex_t * vortex) 41162306a36Sopenharmony_ci{ 41262306a36Sopenharmony_ci int i; 41362306a36Sopenharmony_ci for (i = 0; i < 0x4; i++) 41462306a36Sopenharmony_ci hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0); 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_cistatic void vortex_EqHw_ZeroState(vortex_t * vortex) 41862306a36Sopenharmony_ci{ 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci vortex_EqHw_SetControlReg(vortex, 0); 42162306a36Sopenharmony_ci vortex_EqHw_ZeroIO(vortex); 42262306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x2b3c0, 0); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci vortex_EqHw_SetTimeConsts(vortex, 0, 0); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros); 42762306a36Sopenharmony_ci vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero); 43062306a36Sopenharmony_ci vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero); 43162306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero); 43262306a36Sopenharmony_ci vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci vortex_EqHw_SetBypassGain(vortex, 0, 0); 43562306a36Sopenharmony_ci //vortex_EqHw_SetCurrBypassGain(vortex, 0, 0); 43662306a36Sopenharmony_ci vortex_EqHw_SetA3DBypassGain(vortex, 0, 0); 43762306a36Sopenharmony_ci //vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0); 43862306a36Sopenharmony_ci vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros); 43962306a36Sopenharmony_ci vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros); 44062306a36Sopenharmony_ci vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/* Program coeficients as pass through */ 44462306a36Sopenharmony_cistatic void vortex_EqHw_ProgramPipe(vortex_t * vortex) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci vortex_EqHw_SetTimeConsts(vortex, 0, 0); 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes); 44962306a36Sopenharmony_ci vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current); 45262306a36Sopenharmony_ci vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current); 45362306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current); 45462306a36Sopenharmony_ci vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current); 45562306a36Sopenharmony_ci} 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci/* Program EQ block as 10 band Equalizer */ 45862306a36Sopenharmony_cistatic void 45962306a36Sopenharmony_civortex_EqHw_Program10Band(vortex_t * vortex, auxxEqCoeffSet_t * coefset) 46062306a36Sopenharmony_ci{ 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci vortex_EqHw_SetTimeConsts(vortex, 0xc, 0x7fe0); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci vortex_EqHw_SetLeftCoefs(vortex, coefset->LeftCoefs); 46562306a36Sopenharmony_ci vortex_EqHw_SetRightCoefs(vortex, coefset->RightCoefs); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsCurrent(vortex, coefset->LeftGains); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci vortex_EqHw_SetRightGainsTarget(vortex, coefset->RightGains); 47062306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsTarget(vortex, coefset->LeftGains); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci vortex_EqHw_SetRightGainsCurrent(vortex, coefset->RightGains); 47362306a36Sopenharmony_ci} 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci/* Read all EQ peaks. (think VU meter) */ 47662306a36Sopenharmony_cistatic void vortex_EqHw_GetTenBandLevels(vortex_t * vortex, u16 peaks[]) 47762306a36Sopenharmony_ci{ 47862306a36Sopenharmony_ci eqhw_t *eqhw = &(vortex->eq.this04); 47962306a36Sopenharmony_ci int i; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci if (eqhw->this04 <= 0) 48262306a36Sopenharmony_ci return; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci for (i = 0; i < eqhw->this04; i++) 48562306a36Sopenharmony_ci peaks[i] = hwread(vortex->mmio, 0x2B024 + i * 0x30); 48662306a36Sopenharmony_ci for (i = 0; i < eqhw->this04; i++) 48762306a36Sopenharmony_ci peaks[i + eqhw->this04] = 48862306a36Sopenharmony_ci hwread(vortex->mmio, 0x2B204 + i * 0x30); 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci/* CEqlzr.s */ 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_cistatic int vortex_Eqlzr_GetLeftGain(vortex_t * vortex, u16 index, u16 * gain) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci if (eq->this28) { 49862306a36Sopenharmony_ci *gain = eq->this130[index]; 49962306a36Sopenharmony_ci return 0; 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci return 1; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic void vortex_Eqlzr_SetLeftGain(vortex_t * vortex, u16 index, u16 gain) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci if (eq->this28 == 0) 50962306a36Sopenharmony_ci return; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci eq->this130[index] = gain; 51262306a36Sopenharmony_ci if (eq->this54) 51362306a36Sopenharmony_ci return; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsSingleTarget(vortex, index, gain); 51662306a36Sopenharmony_ci} 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistatic int vortex_Eqlzr_GetRightGain(vortex_t * vortex, u16 index, u16 * gain) 51962306a36Sopenharmony_ci{ 52062306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci if (eq->this28) { 52362306a36Sopenharmony_ci *gain = eq->this130[index + eq->this10]; 52462306a36Sopenharmony_ci return 0; 52562306a36Sopenharmony_ci } 52662306a36Sopenharmony_ci return 1; 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (eq->this28 == 0) 53462306a36Sopenharmony_ci return; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci eq->this130[index + eq->this10] = gain; 53762306a36Sopenharmony_ci if (eq->this54) 53862306a36Sopenharmony_ci return; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci vortex_EqHw_SetRightGainsSingleTarget(vortex, index, gain); 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci#if 0 54462306a36Sopenharmony_cistatic int 54562306a36Sopenharmony_civortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, s32 *cnt) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 54862306a36Sopenharmony_ci int si = 0; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci if (eq->this10 == 0) 55162306a36Sopenharmony_ci return 1; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci { 55462306a36Sopenharmony_ci if (vortex_Eqlzr_GetLeftGain(vortex, si, &gains[si])) 55562306a36Sopenharmony_ci return 1; 55662306a36Sopenharmony_ci if (vortex_Eqlzr_GetRightGain 55762306a36Sopenharmony_ci (vortex, si, &gains[si + eq->this10])) 55862306a36Sopenharmony_ci return 1; 55962306a36Sopenharmony_ci si++; 56062306a36Sopenharmony_ci } 56162306a36Sopenharmony_ci while (eq->this10 > si) ; 56262306a36Sopenharmony_ci *cnt = si * 2; 56362306a36Sopenharmony_ci return 0; 56462306a36Sopenharmony_ci} 56562306a36Sopenharmony_ci#endif 56662306a36Sopenharmony_cistatic int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex) 56762306a36Sopenharmony_ci{ 56862306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsTarget(vortex, eq->this130); 57162306a36Sopenharmony_ci vortex_EqHw_SetRightGainsTarget(vortex, &(eq->this130[eq->this10])); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci return 0; 57462306a36Sopenharmony_ci} 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_cistatic int 57762306a36Sopenharmony_civortex_Eqlzr_SetAllBands(vortex_t *vortex, const u16 gains[], s32 count) 57862306a36Sopenharmony_ci{ 57962306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 58062306a36Sopenharmony_ci int i; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci if (((eq->this10) * 2 != count) || (eq->this28 == 0)) 58362306a36Sopenharmony_ci return 1; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci for (i = 0; i < count; i++) { 58662306a36Sopenharmony_ci eq->this130[i] = gains[i]; 58762306a36Sopenharmony_ci } 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci if (eq->this54) 59062306a36Sopenharmony_ci return 0; 59162306a36Sopenharmony_ci return vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex); 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic void 59562306a36Sopenharmony_civortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b) 59662306a36Sopenharmony_ci{ 59762306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 59862306a36Sopenharmony_ci u32 eax, ebx; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci eq->this58 = a; 60162306a36Sopenharmony_ci eq->this5c = b; 60262306a36Sopenharmony_ci if (eq->this54) 60362306a36Sopenharmony_ci eax = eq->this0e; 60462306a36Sopenharmony_ci else 60562306a36Sopenharmony_ci eax = eq->this0a; 60662306a36Sopenharmony_ci ebx = (eax * eq->this58) >> 0x10; 60762306a36Sopenharmony_ci eax = (eax * eq->this5c) >> 0x10; 60862306a36Sopenharmony_ci vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax); 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex) 61262306a36Sopenharmony_ci{ 61362306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 61462306a36Sopenharmony_ci u32 eax, ebx; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci if (eq->this54) 61762306a36Sopenharmony_ci eax = eq->this0e; 61862306a36Sopenharmony_ci else 61962306a36Sopenharmony_ci eax = eq->this0a; 62062306a36Sopenharmony_ci ebx = (eax * eq->this58) >> 0x10; 62162306a36Sopenharmony_ci eax = (eax * eq->this5c) >> 0x10; 62262306a36Sopenharmony_ci vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax); 62362306a36Sopenharmony_ci} 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistatic void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex) 62662306a36Sopenharmony_ci{ 62762306a36Sopenharmony_ci if (vortex != NULL) 62862306a36Sopenharmony_ci vortex_EqHw_ZeroA3DIO(vortex); 62962306a36Sopenharmony_ci} 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_cistatic void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp) 63262306a36Sopenharmony_ci{ 63362306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci if ((eq->this28) && (bp == 0)) { 63662306a36Sopenharmony_ci /* EQ enabled */ 63762306a36Sopenharmony_ci vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex); 63862306a36Sopenharmony_ci vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08); 63962306a36Sopenharmony_ci } else { 64062306a36Sopenharmony_ci /* EQ disabled. */ 64162306a36Sopenharmony_ci vortex_EqHw_SetLeftGainsTarget(vortex, eq->this14_array); 64262306a36Sopenharmony_ci vortex_EqHw_SetRightGainsTarget(vortex, eq->this14_array); 64362306a36Sopenharmony_ci vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c); 64462306a36Sopenharmony_ci } 64562306a36Sopenharmony_ci vortex_Eqlzr_ProgramA3dBypassGain(vortex); 64662306a36Sopenharmony_ci} 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_cistatic void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex) 64962306a36Sopenharmony_ci{ 65062306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* Set EQ BiQuad filter coeficients */ 65362306a36Sopenharmony_ci memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t)); 65462306a36Sopenharmony_ci /* Set EQ Band gain levels and dump into hardware registers. */ 65562306a36Sopenharmony_ci vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2); 65662306a36Sopenharmony_ci} 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_cistatic int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count) 65962306a36Sopenharmony_ci{ 66062306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci if (eq->this10 == 0) 66362306a36Sopenharmony_ci return 1; 66462306a36Sopenharmony_ci *count = eq->this10 * 2; 66562306a36Sopenharmony_ci vortex_EqHw_GetTenBandLevels(vortex, peaks); 66662306a36Sopenharmony_ci return 0; 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci#if 0 67062306a36Sopenharmony_cistatic auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex) 67162306a36Sopenharmony_ci{ 67262306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci return (&(eq->coefset)); 67562306a36Sopenharmony_ci} 67662306a36Sopenharmony_ci#endif 67762306a36Sopenharmony_cistatic void vortex_Eqlzr_init(vortex_t * vortex) 67862306a36Sopenharmony_ci{ 67962306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci /* Object constructor */ 68262306a36Sopenharmony_ci //eq->this04 = 0; 68362306a36Sopenharmony_ci eq->this08 = 0; /* Bypass gain with EQ in use. */ 68462306a36Sopenharmony_ci eq->this0a = 0x5999; 68562306a36Sopenharmony_ci eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */ 68662306a36Sopenharmony_ci eq->this0e = 0x5999; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci eq->this10 = 0xa; /* 10 eq frequency bands. */ 68962306a36Sopenharmony_ci eq->this04.this04 = eq->this10; 69062306a36Sopenharmony_ci eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */ 69162306a36Sopenharmony_ci eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */ 69262306a36Sopenharmony_ci eq->this58 = 0xffff; 69362306a36Sopenharmony_ci eq->this5c = 0xffff; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci /* Set gains. */ 69662306a36Sopenharmony_ci memset(eq->this14_array, 0, sizeof(eq->this14_array)); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci /* Actual init. */ 69962306a36Sopenharmony_ci vortex_EqHw_ZeroState(vortex); 70062306a36Sopenharmony_ci vortex_EqHw_SetSampleRate(vortex, 0x11); 70162306a36Sopenharmony_ci vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci vortex_EqHw_Program10Band(vortex, &(eq->coefset)); 70462306a36Sopenharmony_ci vortex_Eqlzr_SetBypass(vortex, eq->this54); 70562306a36Sopenharmony_ci vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0); 70662306a36Sopenharmony_ci vortex_EqHw_Enable(vortex); 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cistatic void vortex_Eqlzr_shutdown(vortex_t * vortex) 71062306a36Sopenharmony_ci{ 71162306a36Sopenharmony_ci vortex_Eqlzr_ShutDownA3d(vortex); 71262306a36Sopenharmony_ci vortex_EqHw_ProgramPipe(vortex); 71362306a36Sopenharmony_ci vortex_EqHw_Disable(vortex); 71462306a36Sopenharmony_ci} 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci/* ALSA interface */ 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci/* Control interface */ 71962306a36Sopenharmony_ci#define snd_vortex_eqtoggle_info snd_ctl_boolean_mono_info 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_cistatic int 72262306a36Sopenharmony_cisnd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol, 72362306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci vortex_t *vortex = snd_kcontrol_chip(kcontrol); 72662306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 72762306a36Sopenharmony_ci //int i = kcontrol->private_value; 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1; 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci return 0; 73262306a36Sopenharmony_ci} 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_cistatic int 73562306a36Sopenharmony_cisnd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol, 73662306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 73762306a36Sopenharmony_ci{ 73862306a36Sopenharmony_ci vortex_t *vortex = snd_kcontrol_chip(kcontrol); 73962306a36Sopenharmony_ci eqlzr_t *eq = &(vortex->eq); 74062306a36Sopenharmony_ci //int i = kcontrol->private_value; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1; 74362306a36Sopenharmony_ci vortex_Eqlzr_SetBypass(vortex, eq->this54); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci return 1; /* Allways changes */ 74662306a36Sopenharmony_ci} 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_cistatic const struct snd_kcontrol_new vortex_eqtoggle_kcontrol = { 74962306a36Sopenharmony_ci .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 75062306a36Sopenharmony_ci .name = "EQ Enable", 75162306a36Sopenharmony_ci .index = 0, 75262306a36Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 75362306a36Sopenharmony_ci .private_value = 0, 75462306a36Sopenharmony_ci .info = snd_vortex_eqtoggle_info, 75562306a36Sopenharmony_ci .get = snd_vortex_eqtoggle_get, 75662306a36Sopenharmony_ci .put = snd_vortex_eqtoggle_put 75762306a36Sopenharmony_ci}; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_cistatic int 76062306a36Sopenharmony_cisnd_vortex_eq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 76162306a36Sopenharmony_ci{ 76262306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 76362306a36Sopenharmony_ci uinfo->count = 2; 76462306a36Sopenharmony_ci uinfo->value.integer.min = 0x0000; 76562306a36Sopenharmony_ci uinfo->value.integer.max = 0x7fff; 76662306a36Sopenharmony_ci return 0; 76762306a36Sopenharmony_ci} 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_cistatic int 77062306a36Sopenharmony_cisnd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 77162306a36Sopenharmony_ci{ 77262306a36Sopenharmony_ci vortex_t *vortex = snd_kcontrol_chip(kcontrol); 77362306a36Sopenharmony_ci int i = kcontrol->private_value; 77462306a36Sopenharmony_ci u16 gainL = 0, gainR = 0; 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); 77762306a36Sopenharmony_ci vortex_Eqlzr_GetRightGain(vortex, i, &gainR); 77862306a36Sopenharmony_ci ucontrol->value.integer.value[0] = gainL; 77962306a36Sopenharmony_ci ucontrol->value.integer.value[1] = gainR; 78062306a36Sopenharmony_ci return 0; 78162306a36Sopenharmony_ci} 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_cistatic int 78462306a36Sopenharmony_cisnd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 78562306a36Sopenharmony_ci{ 78662306a36Sopenharmony_ci vortex_t *vortex = snd_kcontrol_chip(kcontrol); 78762306a36Sopenharmony_ci int changed = 0, i = kcontrol->private_value; 78862306a36Sopenharmony_ci u16 gainL = 0, gainR = 0; 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); 79162306a36Sopenharmony_ci vortex_Eqlzr_GetRightGain(vortex, i, &gainR); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci if (gainL != ucontrol->value.integer.value[0]) { 79462306a36Sopenharmony_ci vortex_Eqlzr_SetLeftGain(vortex, i, 79562306a36Sopenharmony_ci ucontrol->value.integer.value[0]); 79662306a36Sopenharmony_ci changed = 1; 79762306a36Sopenharmony_ci } 79862306a36Sopenharmony_ci if (gainR != ucontrol->value.integer.value[1]) { 79962306a36Sopenharmony_ci vortex_Eqlzr_SetRightGain(vortex, i, 80062306a36Sopenharmony_ci ucontrol->value.integer.value[1]); 80162306a36Sopenharmony_ci changed = 1; 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci return changed; 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_cistatic const struct snd_kcontrol_new vortex_eq_kcontrol = { 80762306a36Sopenharmony_ci .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 80862306a36Sopenharmony_ci .name = " .", 80962306a36Sopenharmony_ci .index = 0, 81062306a36Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 81162306a36Sopenharmony_ci .private_value = 0, 81262306a36Sopenharmony_ci .info = snd_vortex_eq_info, 81362306a36Sopenharmony_ci .get = snd_vortex_eq_get, 81462306a36Sopenharmony_ci .put = snd_vortex_eq_put 81562306a36Sopenharmony_ci}; 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_cistatic int 81862306a36Sopenharmony_cisnd_vortex_peaks_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 82162306a36Sopenharmony_ci uinfo->count = 20; 82262306a36Sopenharmony_ci uinfo->value.integer.min = 0x0000; 82362306a36Sopenharmony_ci uinfo->value.integer.max = 0x7fff; 82462306a36Sopenharmony_ci return 0; 82562306a36Sopenharmony_ci} 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_cistatic int 82862306a36Sopenharmony_cisnd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 82962306a36Sopenharmony_ci{ 83062306a36Sopenharmony_ci vortex_t *vortex = snd_kcontrol_chip(kcontrol); 83162306a36Sopenharmony_ci int i, count = 0; 83262306a36Sopenharmony_ci u16 peaks[20]; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); 83562306a36Sopenharmony_ci if (count != 20) { 83662306a36Sopenharmony_ci dev_err(vortex->card->dev, 83762306a36Sopenharmony_ci "peak count error 20 != %d\n", count); 83862306a36Sopenharmony_ci return -1; 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci for (i = 0; i < 20; i++) 84162306a36Sopenharmony_ci ucontrol->value.integer.value[i] = peaks[i]; 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci return 0; 84462306a36Sopenharmony_ci} 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_cistatic const struct snd_kcontrol_new vortex_levels_kcontrol = { 84762306a36Sopenharmony_ci .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 84862306a36Sopenharmony_ci .name = "EQ Peaks", 84962306a36Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 85062306a36Sopenharmony_ci .info = snd_vortex_peaks_info, 85162306a36Sopenharmony_ci .get = snd_vortex_peaks_get, 85262306a36Sopenharmony_ci}; 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci/* EQ band gain labels. */ 85562306a36Sopenharmony_cistatic const char * const EqBandLabels[10] = { 85662306a36Sopenharmony_ci "EQ0 31Hz\0", 85762306a36Sopenharmony_ci "EQ1 63Hz\0", 85862306a36Sopenharmony_ci "EQ2 125Hz\0", 85962306a36Sopenharmony_ci "EQ3 250Hz\0", 86062306a36Sopenharmony_ci "EQ4 500Hz\0", 86162306a36Sopenharmony_ci "EQ5 1KHz\0", 86262306a36Sopenharmony_ci "EQ6 2KHz\0", 86362306a36Sopenharmony_ci "EQ7 4KHz\0", 86462306a36Sopenharmony_ci "EQ8 8KHz\0", 86562306a36Sopenharmony_ci "EQ9 16KHz\0", 86662306a36Sopenharmony_ci}; 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci/* ALSA driver entry points. Init and exit. */ 86962306a36Sopenharmony_cistatic int vortex_eq_init(vortex_t *vortex) 87062306a36Sopenharmony_ci{ 87162306a36Sopenharmony_ci struct snd_kcontrol *kcontrol; 87262306a36Sopenharmony_ci int err, i; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci vortex_Eqlzr_init(vortex); 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex); 87762306a36Sopenharmony_ci if (!kcontrol) 87862306a36Sopenharmony_ci return -ENOMEM; 87962306a36Sopenharmony_ci kcontrol->private_value = 0; 88062306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 88162306a36Sopenharmony_ci if (err < 0) 88262306a36Sopenharmony_ci return err; 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci /* EQ gain controls */ 88562306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 88662306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_eq_kcontrol, vortex); 88762306a36Sopenharmony_ci if (!kcontrol) 88862306a36Sopenharmony_ci return -ENOMEM; 88962306a36Sopenharmony_ci snprintf(kcontrol->id.name, sizeof(kcontrol->id.name), 89062306a36Sopenharmony_ci "%s Playback Volume", EqBandLabels[i]); 89162306a36Sopenharmony_ci kcontrol->private_value = i; 89262306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 89362306a36Sopenharmony_ci if (err < 0) 89462306a36Sopenharmony_ci return err; 89562306a36Sopenharmony_ci //vortex->eqctrl[i] = kcontrol; 89662306a36Sopenharmony_ci } 89762306a36Sopenharmony_ci /* EQ band levels */ 89862306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex); 89962306a36Sopenharmony_ci if (!kcontrol) 90062306a36Sopenharmony_ci return -ENOMEM; 90162306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 90262306a36Sopenharmony_ci if (err < 0) 90362306a36Sopenharmony_ci return err; 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci return 0; 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistatic int vortex_eq_free(vortex_t * vortex) 90962306a36Sopenharmony_ci{ 91062306a36Sopenharmony_ci /* 91162306a36Sopenharmony_ci //FIXME: segfault because vortex->eqctrl[i] == 4 91262306a36Sopenharmony_ci int i; 91362306a36Sopenharmony_ci for (i=0; i<10; i++) { 91462306a36Sopenharmony_ci if (vortex->eqctrl[i]) 91562306a36Sopenharmony_ci snd_ctl_remove(vortex->card, vortex->eqctrl[i]); 91662306a36Sopenharmony_ci } 91762306a36Sopenharmony_ci */ 91862306a36Sopenharmony_ci vortex_Eqlzr_shutdown(vortex); 91962306a36Sopenharmony_ci return 0; 92062306a36Sopenharmony_ci} 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci/* End */ 923