162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/*************************************************************************** 362306a36Sopenharmony_ci * au88x0_a3d.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Fri Jul 18 14:16:22 2003 662306a36Sopenharmony_ci * Copyright 2003 mjander 762306a36Sopenharmony_ci * mjander@users.sourceforge.net 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * A3D. You may think i'm crazy, but this may work someday. Who knows... 1062306a36Sopenharmony_ci ****************************************************************************/ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "au88x0_a3d.h" 1662306a36Sopenharmony_ci#include "au88x0_a3ddata.c" 1762306a36Sopenharmony_ci#include "au88x0_xtalk.h" 1862306a36Sopenharmony_ci#include "au88x0.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic void 2162306a36Sopenharmony_cia3dsrc_SetTimeConsts(a3dsrc_t * a, short HrtfTrack, short ItdTrack, 2262306a36Sopenharmony_ci short GTrack, short CTrack) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 2562306a36Sopenharmony_ci hwwrite(vortex->mmio, 2662306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_HrtfTrackTC), HrtfTrack); 2762306a36Sopenharmony_ci hwwrite(vortex->mmio, 2862306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_ITDTrackTC), ItdTrack); 2962306a36Sopenharmony_ci hwwrite(vortex->mmio, 3062306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_GainTrackTC), GTrack); 3162306a36Sopenharmony_ci hwwrite(vortex->mmio, 3262306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_CoeffTrackTC), CTrack); 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#if 0 3662306a36Sopenharmony_cistatic void 3762306a36Sopenharmony_cia3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack, 3862306a36Sopenharmony_ci short *GTrack, short *CTrack) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci // stub! 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#endif 4462306a36Sopenharmony_ci/* Atmospheric absorption. */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic void 4762306a36Sopenharmony_cia3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d, 4862306a36Sopenharmony_ci short e) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 5162306a36Sopenharmony_ci hwwrite(vortex->mmio, 5262306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_A21Target), 5362306a36Sopenharmony_ci (e << 0x10) | d); 5462306a36Sopenharmony_ci hwwrite(vortex->mmio, 5562306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_B10Target), 5662306a36Sopenharmony_ci (b << 0x10) | aa); 5762306a36Sopenharmony_ci hwwrite(vortex->mmio, 5862306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_B2Target), c); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic void 6262306a36Sopenharmony_cia3dsrc_SetAtmosCurrent(a3dsrc_t * a, short aa, short b, short c, short d, 6362306a36Sopenharmony_ci short e) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 6662306a36Sopenharmony_ci hwwrite(vortex->mmio, 6762306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_A12Current), 6862306a36Sopenharmony_ci (e << 0x10) | d); 6962306a36Sopenharmony_ci hwwrite(vortex->mmio, 7062306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_B01Current), 7162306a36Sopenharmony_ci (b << 0x10) | aa); 7262306a36Sopenharmony_ci hwwrite(vortex->mmio, 7362306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_B2Current), c); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic void 7762306a36Sopenharmony_cia3dsrc_SetAtmosState(a3dsrc_t * a, short x1, short x2, short y1, short y2) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 8062306a36Sopenharmony_ci hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x1), x1); 8162306a36Sopenharmony_ci hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x2), x2); 8262306a36Sopenharmony_ci hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y1), y1); 8362306a36Sopenharmony_ci hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y2), y2); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#if 0 8762306a36Sopenharmony_cistatic void 8862306a36Sopenharmony_cia3dsrc_GetAtmosTarget(a3dsrc_t * a, short *aa, short *b, short *c, 8962306a36Sopenharmony_ci short *d, short *e) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_cistatic void 9362306a36Sopenharmony_cia3dsrc_GetAtmosCurrent(a3dsrc_t * a, short *bb01, short *ab01, short *b2, 9462306a36Sopenharmony_ci short *aa12, short *ba12) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 9762306a36Sopenharmony_ci *aa12 = 9862306a36Sopenharmony_ci hwread(vortex->mmio, 9962306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_A12Current)); 10062306a36Sopenharmony_ci *ba12 = 10162306a36Sopenharmony_ci hwread(vortex->mmio, 10262306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_A12Current)); 10362306a36Sopenharmony_ci *ab01 = 10462306a36Sopenharmony_ci hwread(vortex->mmio, 10562306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_B01Current)); 10662306a36Sopenharmony_ci *bb01 = 10762306a36Sopenharmony_ci hwread(vortex->mmio, 10862306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_B01Current)); 10962306a36Sopenharmony_ci *b2 = 11062306a36Sopenharmony_ci hwread(vortex->mmio, 11162306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_B2Current)); 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic void 11562306a36Sopenharmony_cia3dsrc_GetAtmosState(a3dsrc_t * a, short *x1, short *x2, short *y1, short *y2) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#endif 12162306a36Sopenharmony_ci/* HRTF */ 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic void 12462306a36Sopenharmony_cia3dsrc_SetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 12762306a36Sopenharmony_ci int i; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 13062306a36Sopenharmony_ci hwwrite(vortex->mmio, 13162306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 13262306a36Sopenharmony_ci A3D_B_HrtfTarget) + (i << 2), 13362306a36Sopenharmony_ci (b[i] << 0x10) | aa[i]); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic void 13762306a36Sopenharmony_cia3dsrc_SetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 14062306a36Sopenharmony_ci int i; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 14362306a36Sopenharmony_ci hwwrite(vortex->mmio, 14462306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 14562306a36Sopenharmony_ci A3D_B_HrtfCurrent) + (i << 2), 14662306a36Sopenharmony_ci (b[i] << 0x10) | aa[i]); 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic void 15062306a36Sopenharmony_cia3dsrc_SetHrtfState(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 15362306a36Sopenharmony_ci int i; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 15662306a36Sopenharmony_ci hwwrite(vortex->mmio, 15762306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 15862306a36Sopenharmony_ci A3D_B_HrtfDelayLine) + (i << 2), 15962306a36Sopenharmony_ci (b[i] << 0x10) | aa[i]); 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic void a3dsrc_SetHrtfOutput(a3dsrc_t * a, short left, short right) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 16562306a36Sopenharmony_ci hwwrite(vortex->mmio, 16662306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL), left); 16762306a36Sopenharmony_ci hwwrite(vortex->mmio, 16862306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR), right); 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#if 0 17262306a36Sopenharmony_cistatic void a3dsrc_GetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 17562306a36Sopenharmony_ci int i; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 17862306a36Sopenharmony_ci aa[i] = 17962306a36Sopenharmony_ci hwread(vortex->mmio, 18062306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, 18162306a36Sopenharmony_ci A3D_A_HrtfTarget + (i << 2))); 18262306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 18362306a36Sopenharmony_ci b[i] = 18462306a36Sopenharmony_ci hwread(vortex->mmio, 18562306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 18662306a36Sopenharmony_ci A3D_B_HrtfTarget + (i << 2))); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic void a3dsrc_GetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 19262306a36Sopenharmony_ci int i; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 19562306a36Sopenharmony_ci aa[i] = 19662306a36Sopenharmony_ci hwread(vortex->mmio, 19762306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, 19862306a36Sopenharmony_ci A3D_A_HrtfCurrent + (i << 2))); 19962306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 20062306a36Sopenharmony_ci b[i] = 20162306a36Sopenharmony_ci hwread(vortex->mmio, 20262306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 20362306a36Sopenharmony_ci A3D_B_HrtfCurrent + (i << 2))); 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic void a3dsrc_GetHrtfState(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 20962306a36Sopenharmony_ci int i; 21062306a36Sopenharmony_ci // FIXME: verify this! 21162306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 21262306a36Sopenharmony_ci aa[i] = 21362306a36Sopenharmony_ci hwread(vortex->mmio, 21462306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, 21562306a36Sopenharmony_ci A3D_A_HrtfDelayLine + (i << 2))); 21662306a36Sopenharmony_ci for (i = 0; i < HRTF_SZ; i++) 21762306a36Sopenharmony_ci b[i] = 21862306a36Sopenharmony_ci hwread(vortex->mmio, 21962306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, 22062306a36Sopenharmony_ci A3D_B_HrtfDelayLine + (i << 2))); 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cistatic void a3dsrc_GetHrtfOutput(a3dsrc_t * a, short *left, short *right) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 22662306a36Sopenharmony_ci *left = 22762306a36Sopenharmony_ci hwread(vortex->mmio, 22862306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL)); 22962306a36Sopenharmony_ci *right = 23062306a36Sopenharmony_ci hwread(vortex->mmio, 23162306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR)); 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci#endif 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/* Interaural Time Difference. 23762306a36Sopenharmony_ci * "The other main clue that humans use to locate sounds, is called 23862306a36Sopenharmony_ci * Interaural Time Difference (ITD). The differences in distance from 23962306a36Sopenharmony_ci * the sound source to a listeners ears means that the sound will 24062306a36Sopenharmony_ci * reach one ear slightly before the other....", found somewhere with google.*/ 24162306a36Sopenharmony_cistatic void a3dsrc_SetItdTarget(a3dsrc_t * a, short litd, short ritd) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (litd < 0) 24662306a36Sopenharmony_ci litd = 0; 24762306a36Sopenharmony_ci if (litd > 0x57FF) 24862306a36Sopenharmony_ci litd = 0x57FF; 24962306a36Sopenharmony_ci if (ritd < 0) 25062306a36Sopenharmony_ci ritd = 0; 25162306a36Sopenharmony_ci if (ritd > 0x57FF) 25262306a36Sopenharmony_ci ritd = 0x57FF; 25362306a36Sopenharmony_ci hwwrite(vortex->mmio, 25462306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_ITDTarget), 25562306a36Sopenharmony_ci (ritd << 0x10) | litd); 25662306a36Sopenharmony_ci //hwwrite(vortex->mmio, addr(0x191DF+5, this04, this08), (ritd<<0x10)|litd); 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic void a3dsrc_SetItdCurrent(a3dsrc_t * a, short litd, short ritd) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (litd < 0) 26462306a36Sopenharmony_ci litd = 0; 26562306a36Sopenharmony_ci if (litd > 0x57FF) 26662306a36Sopenharmony_ci litd = 0x57FF; 26762306a36Sopenharmony_ci if (ritd < 0) 26862306a36Sopenharmony_ci ritd = 0; 26962306a36Sopenharmony_ci if (ritd > 0x57FF) 27062306a36Sopenharmony_ci ritd = 0x57FF; 27162306a36Sopenharmony_ci hwwrite(vortex->mmio, 27262306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent), 27362306a36Sopenharmony_ci (ritd << 0x10) | litd); 27462306a36Sopenharmony_ci //hwwrite(vortex->mmio, addr(0x191DF+1, this04, this08), (ritd<<0x10)|litd); 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic void a3dsrc_SetItdDline(a3dsrc_t * a, a3d_ItdDline_t const dline) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 28062306a36Sopenharmony_ci int i; 28162306a36Sopenharmony_ci /* 45 != 40 -> Check this ! */ 28262306a36Sopenharmony_ci for (i = 0; i < DLINE_SZ; i++) 28362306a36Sopenharmony_ci hwwrite(vortex->mmio, 28462306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, 28562306a36Sopenharmony_ci A3D_A_ITDDelayLine) + (i << 2), dline[i]); 28662306a36Sopenharmony_ci} 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci#if 0 28962306a36Sopenharmony_cistatic void a3dsrc_GetItdTarget(a3dsrc_t * a, short *litd, short *ritd) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 29262306a36Sopenharmony_ci *ritd = 29362306a36Sopenharmony_ci hwread(vortex->mmio, 29462306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_ITDTarget)); 29562306a36Sopenharmony_ci *litd = 29662306a36Sopenharmony_ci hwread(vortex->mmio, 29762306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_ITDTarget)); 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic void a3dsrc_GetItdCurrent(a3dsrc_t * a, short *litd, short *ritd) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci *ritd = 30562306a36Sopenharmony_ci hwread(vortex->mmio, 30662306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_ITDCurrent)); 30762306a36Sopenharmony_ci *litd = 30862306a36Sopenharmony_ci hwread(vortex->mmio, 30962306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent)); 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cistatic void a3dsrc_GetItdDline(a3dsrc_t * a, a3d_ItdDline_t dline) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 31562306a36Sopenharmony_ci int i; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci for (i = 0; i < DLINE_SZ; i++) 31862306a36Sopenharmony_ci dline[i] = 31962306a36Sopenharmony_ci hwread(vortex->mmio, 32062306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, 32162306a36Sopenharmony_ci A3D_A_ITDDelayLine + (i << 2))); 32262306a36Sopenharmony_ci} 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci#endif 32562306a36Sopenharmony_ci/* This is may be used for ILD Interaural Level Difference. */ 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic void a3dsrc_SetGainTarget(a3dsrc_t * a, short left, short right) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 33062306a36Sopenharmony_ci hwwrite(vortex->mmio, 33162306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_GainTarget), 33262306a36Sopenharmony_ci (right << 0x10) | left); 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_cistatic void a3dsrc_SetGainCurrent(a3dsrc_t * a, short left, short right) 33662306a36Sopenharmony_ci{ 33762306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 33862306a36Sopenharmony_ci hwwrite(vortex->mmio, 33962306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_GainCurrent), 34062306a36Sopenharmony_ci (right << 0x10) | left); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci#if 0 34462306a36Sopenharmony_cistatic void a3dsrc_GetGainTarget(a3dsrc_t * a, short *left, short *right) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 34762306a36Sopenharmony_ci *right = 34862306a36Sopenharmony_ci hwread(vortex->mmio, 34962306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_GainTarget)); 35062306a36Sopenharmony_ci *left = 35162306a36Sopenharmony_ci hwread(vortex->mmio, 35262306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_GainTarget)); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic void a3dsrc_GetGainCurrent(a3dsrc_t * a, short *left, short *right) 35662306a36Sopenharmony_ci{ 35762306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 35862306a36Sopenharmony_ci *right = 35962306a36Sopenharmony_ci hwread(vortex->mmio, 36062306a36Sopenharmony_ci a3d_addrA(a->slice, a->source, A3D_A_GainCurrent)); 36162306a36Sopenharmony_ci *left = 36262306a36Sopenharmony_ci hwread(vortex->mmio, 36362306a36Sopenharmony_ci a3d_addrB(a->slice, a->source, A3D_B_GainCurrent)); 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci/* CA3dIO this func seems to be inlined all over this place. */ 36762306a36Sopenharmony_cistatic void CA3dIO_WriteReg(a3dsrc_t * a, unsigned long addr, short aa, short b) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 37062306a36Sopenharmony_ci hwwrite(vortex->mmio, addr, (aa << 0x10) | b); 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci#endif 37462306a36Sopenharmony_ci/* Generic A3D stuff */ 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic void a3dsrc_SetA3DSampleRate(a3dsrc_t * a, int sr) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 37962306a36Sopenharmony_ci int esp0 = 0; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci esp0 = (((esp0 & 0x7fffffff) | 0xB8000000) & 0x7) | ((sr & 0x1f) << 3); 38262306a36Sopenharmony_ci hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), esp0); 38362306a36Sopenharmony_ci //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), esp0); 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic void a3dsrc_EnableA3D(a3dsrc_t * a) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 38962306a36Sopenharmony_ci hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), 39062306a36Sopenharmony_ci 0xF0000001); 39162306a36Sopenharmony_ci //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), 0xF0000001); 39262306a36Sopenharmony_ci} 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_cistatic void a3dsrc_DisableA3D(a3dsrc_t * a) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 39762306a36Sopenharmony_ci hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), 39862306a36Sopenharmony_ci 0xF0000000); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic void a3dsrc_SetA3DControlReg(a3dsrc_t * a, unsigned long ctrl) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 40462306a36Sopenharmony_ci hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), ctrl); 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic void a3dsrc_SetA3DPointerReg(a3dsrc_t * a, unsigned long ptr) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 41062306a36Sopenharmony_ci hwwrite(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd), ptr); 41162306a36Sopenharmony_ci} 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci#if 0 41462306a36Sopenharmony_cistatic void a3dsrc_GetA3DSampleRate(a3dsrc_t * a, int *sr) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 41762306a36Sopenharmony_ci *sr = ((hwread(vortex->mmio, A3D_SLICE_Control + (a->slice << 0xd)) 41862306a36Sopenharmony_ci >> 3) & 0x1f); 41962306a36Sopenharmony_ci //*sr = ((hwread(vortex->mmio, 0x19C38 + (this08<<0xd))>>3)&0x1f); 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic void a3dsrc_GetA3DControlReg(a3dsrc_t * a, unsigned long *ctrl) 42362306a36Sopenharmony_ci{ 42462306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 42562306a36Sopenharmony_ci *ctrl = hwread(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd)); 42662306a36Sopenharmony_ci} 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic void a3dsrc_GetA3DPointerReg(a3dsrc_t * a, unsigned long *ptr) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 43162306a36Sopenharmony_ci *ptr = hwread(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd)); 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci#endif 43562306a36Sopenharmony_cistatic void a3dsrc_ZeroSliceIO(a3dsrc_t * a) 43662306a36Sopenharmony_ci{ 43762306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 43862306a36Sopenharmony_ci int i; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci for (i = 0; i < 8; i++) 44162306a36Sopenharmony_ci hwwrite(vortex->mmio, 44262306a36Sopenharmony_ci A3D_SLICE_VDBDest + 44362306a36Sopenharmony_ci ((((a->slice) << 0xb) + i) << 2), 0); 44462306a36Sopenharmony_ci for (i = 0; i < 4; i++) 44562306a36Sopenharmony_ci hwwrite(vortex->mmio, 44662306a36Sopenharmony_ci A3D_SLICE_VDBSource + 44762306a36Sopenharmony_ci ((((a->slice) << 0xb) + i) << 2), 0); 44862306a36Sopenharmony_ci} 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci/* Reset Single A3D source. */ 45162306a36Sopenharmony_cistatic void a3dsrc_ZeroState(a3dsrc_t * a) 45262306a36Sopenharmony_ci{ 45362306a36Sopenharmony_ci /* 45462306a36Sopenharmony_ci pr_debug( "vortex: ZeroState slice: %d, source %d\n", 45562306a36Sopenharmony_ci a->slice, a->source); 45662306a36Sopenharmony_ci */ 45762306a36Sopenharmony_ci a3dsrc_SetAtmosState(a, 0, 0, 0, 0); 45862306a36Sopenharmony_ci a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros); 45962306a36Sopenharmony_ci a3dsrc_SetItdDline(a, A3dItdDlineZeros); 46062306a36Sopenharmony_ci a3dsrc_SetHrtfOutput(a, 0, 0); 46162306a36Sopenharmony_ci a3dsrc_SetTimeConsts(a, 0, 0, 0, 0); 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0); 46462306a36Sopenharmony_ci a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0); 46562306a36Sopenharmony_ci a3dsrc_SetItdCurrent(a, 0, 0); 46662306a36Sopenharmony_ci a3dsrc_SetItdTarget(a, 0, 0); 46762306a36Sopenharmony_ci a3dsrc_SetGainCurrent(a, 0, 0); 46862306a36Sopenharmony_ci a3dsrc_SetGainTarget(a, 0, 0); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros); 47162306a36Sopenharmony_ci a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros); 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci/* Reset entire A3D engine */ 47562306a36Sopenharmony_cistatic void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v) 47662306a36Sopenharmony_ci{ 47762306a36Sopenharmony_ci int i, var, var2; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci if ((a->vortex) == NULL) { 48062306a36Sopenharmony_ci dev_err(v->card->dev, 48162306a36Sopenharmony_ci "ZeroStateA3D: ERROR: a->vortex is NULL\n"); 48262306a36Sopenharmony_ci return; 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci a3dsrc_SetA3DControlReg(a, 0); 48662306a36Sopenharmony_ci a3dsrc_SetA3DPointerReg(a, 0); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci var = a->slice; 48962306a36Sopenharmony_ci var2 = a->source; 49062306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 49162306a36Sopenharmony_ci a->slice = i; 49262306a36Sopenharmony_ci a3dsrc_ZeroSliceIO(a); 49362306a36Sopenharmony_ci //a3dsrc_ZeroState(a); 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci a->source = var2; 49662306a36Sopenharmony_ci a->slice = var; 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci/* Program A3D block as pass through */ 50062306a36Sopenharmony_cistatic void a3dsrc_ProgramPipe(a3dsrc_t * a) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci a3dsrc_SetTimeConsts(a, 0, 0, 0, 0); 50362306a36Sopenharmony_ci a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0); 50462306a36Sopenharmony_ci a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0); 50562306a36Sopenharmony_ci a3dsrc_SetItdCurrent(a, 0, 0); 50662306a36Sopenharmony_ci a3dsrc_SetItdTarget(a, 0, 0); 50762306a36Sopenharmony_ci a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff); 50862306a36Sopenharmony_ci a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff); 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci /* SET HRTF HERE */ 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci /* Single spike leads to identity transfer function. */ 51362306a36Sopenharmony_ci a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse); 51462306a36Sopenharmony_ci a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse); 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci /* Test: Sounds saturated. */ 51762306a36Sopenharmony_ci //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest); 51862306a36Sopenharmony_ci //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest); 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci/* VDB = Vortex audio Dataflow Bus */ 52262306a36Sopenharmony_ci#if 0 52362306a36Sopenharmony_cistatic void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa) 52462306a36Sopenharmony_ci{ 52562306a36Sopenharmony_ci vortex_t *vortex = (vortex_t *) (a->vortex); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci // ((aa >> 2) << 8) - (aa >> 2) 52862306a36Sopenharmony_ci hwwrite(vortex->mmio, 52962306a36Sopenharmony_ci a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0); 53062306a36Sopenharmony_ci hwwrite(vortex->mmio, 53162306a36Sopenharmony_ci a3d_addrS(a->slice, 53262306a36Sopenharmony_ci A3D_SLICE_VDBDest + 4) + (a->source << 2), 0); 53362306a36Sopenharmony_ci /* 53462306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0); 53562306a36Sopenharmony_ci hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0); 53662306a36Sopenharmony_ci */ 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci#endif 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/* A3D HwSource stuff. */ 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice) 54362306a36Sopenharmony_ci{ 54462306a36Sopenharmony_ci a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]); 54562306a36Sopenharmony_ci //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci a3dsrc->vortex = (void *)v; 54862306a36Sopenharmony_ci a3dsrc->source = source; /* source */ 54962306a36Sopenharmony_ci a3dsrc->slice = slice; /* slice */ 55062306a36Sopenharmony_ci a3dsrc_ZeroState(a3dsrc); 55162306a36Sopenharmony_ci /* Added by me. */ 55262306a36Sopenharmony_ci a3dsrc_SetA3DSampleRate(a3dsrc, 0x11); 55362306a36Sopenharmony_ci} 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistatic int Vort3DRend_Initialize(vortex_t * v, unsigned short mode) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci v->xt_mode = mode; /* this_14 */ 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci vortex_XtalkHw_init(v); 56062306a36Sopenharmony_ci vortex_XtalkHw_SetGainsAllChan(v); 56162306a36Sopenharmony_ci switch (v->xt_mode) { 56262306a36Sopenharmony_ci case XT_SPEAKER0: 56362306a36Sopenharmony_ci vortex_XtalkHw_ProgramXtalkNarrow(v); 56462306a36Sopenharmony_ci break; 56562306a36Sopenharmony_ci case XT_SPEAKER1: 56662306a36Sopenharmony_ci vortex_XtalkHw_ProgramXtalkWide(v); 56762306a36Sopenharmony_ci break; 56862306a36Sopenharmony_ci default: 56962306a36Sopenharmony_ci case XT_HEADPHONE: 57062306a36Sopenharmony_ci vortex_XtalkHw_ProgramPipe(v); 57162306a36Sopenharmony_ci break; 57262306a36Sopenharmony_ci case XT_DIAMOND: 57362306a36Sopenharmony_ci vortex_XtalkHw_ProgramDiamondXtalk(v); 57462306a36Sopenharmony_ci break; 57562306a36Sopenharmony_ci } 57662306a36Sopenharmony_ci vortex_XtalkHw_SetSampleRate(v, 0x11); 57762306a36Sopenharmony_ci vortex_XtalkHw_Enable(v); 57862306a36Sopenharmony_ci return 0; 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci/* 3D Sound entry points. */ 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_cistatic int vortex_a3d_register_controls(vortex_t * vortex); 58462306a36Sopenharmony_cistatic void vortex_a3d_unregister_controls(vortex_t * vortex); 58562306a36Sopenharmony_ci/* A3D base support init/shudown */ 58662306a36Sopenharmony_cistatic void vortex_Vort3D_enable(vortex_t *v) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci int i; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci Vort3DRend_Initialize(v, XT_HEADPHONE); 59162306a36Sopenharmony_ci for (i = 0; i < NR_A3D; i++) { 59262306a36Sopenharmony_ci vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2); 59362306a36Sopenharmony_ci a3dsrc_ZeroStateA3D(&v->a3d[0], v); 59462306a36Sopenharmony_ci } 59562306a36Sopenharmony_ci /* Register ALSA controls */ 59662306a36Sopenharmony_ci vortex_a3d_register_controls(v); 59762306a36Sopenharmony_ci} 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_cistatic void vortex_Vort3D_disable(vortex_t * v) 60062306a36Sopenharmony_ci{ 60162306a36Sopenharmony_ci vortex_XtalkHw_Disable(v); 60262306a36Sopenharmony_ci vortex_a3d_unregister_controls(v); 60362306a36Sopenharmony_ci} 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci/* Make A3D subsystem connections. */ 60662306a36Sopenharmony_cistatic void vortex_Vort3D_connect(vortex_t * v, int en) 60762306a36Sopenharmony_ci{ 60862306a36Sopenharmony_ci int i; 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci// Disable AU8810 routes, since they seem to be wrong (in au8810.h). 61162306a36Sopenharmony_ci#ifdef CHIP_AU8810 61262306a36Sopenharmony_ci return; 61362306a36Sopenharmony_ci#endif 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci#if 1 61662306a36Sopenharmony_ci /* Alloc Xtalk mixin resources */ 61762306a36Sopenharmony_ci v->mixxtlk[0] = 61862306a36Sopenharmony_ci vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); 61962306a36Sopenharmony_ci if (v->mixxtlk[0] < 0) { 62062306a36Sopenharmony_ci dev_warn(v->card->dev, 62162306a36Sopenharmony_ci "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); 62262306a36Sopenharmony_ci return; 62362306a36Sopenharmony_ci } 62462306a36Sopenharmony_ci v->mixxtlk[1] = 62562306a36Sopenharmony_ci vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); 62662306a36Sopenharmony_ci if (v->mixxtlk[1] < 0) { 62762306a36Sopenharmony_ci dev_warn(v->card->dev, 62862306a36Sopenharmony_ci "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); 62962306a36Sopenharmony_ci return; 63062306a36Sopenharmony_ci } 63162306a36Sopenharmony_ci#endif 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci /* Connect A3D -> XTALK */ 63462306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 63562306a36Sopenharmony_ci // 2 outputs per each A3D slice. 63662306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i)); 63762306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i)); 63862306a36Sopenharmony_ci } 63962306a36Sopenharmony_ci#if 0 64062306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2)); 64162306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3)); 64262306a36Sopenharmony_ci#else 64362306a36Sopenharmony_ci /* Connect XTalk -> mixer */ 64462306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0])); 64562306a36Sopenharmony_ci vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1])); 64662306a36Sopenharmony_ci vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0); 64762306a36Sopenharmony_ci vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0); 64862306a36Sopenharmony_ci vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0], 64962306a36Sopenharmony_ci en ? MIX_DEFIGAIN : VOL_MIN); 65062306a36Sopenharmony_ci vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1], 65162306a36Sopenharmony_ci en ? MIX_DEFIGAIN : VOL_MIN); 65262306a36Sopenharmony_ci if (VORTEX_IS_QUAD(v)) { 65362306a36Sopenharmony_ci vortex_connection_mixin_mix(v, en, v->mixxtlk[0], 65462306a36Sopenharmony_ci v->mixplayb[2], 0); 65562306a36Sopenharmony_ci vortex_connection_mixin_mix(v, en, v->mixxtlk[1], 65662306a36Sopenharmony_ci v->mixplayb[3], 0); 65762306a36Sopenharmony_ci vortex_mix_setinputvolumebyte(v, v->mixplayb[2], 65862306a36Sopenharmony_ci v->mixxtlk[0], 65962306a36Sopenharmony_ci en ? MIX_DEFIGAIN : VOL_MIN); 66062306a36Sopenharmony_ci vortex_mix_setinputvolumebyte(v, v->mixplayb[3], 66162306a36Sopenharmony_ci v->mixxtlk[1], 66262306a36Sopenharmony_ci en ? MIX_DEFIGAIN : VOL_MIN); 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci#endif 66562306a36Sopenharmony_ci} 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci/* Initialize one single A3D source. */ 66862306a36Sopenharmony_cistatic void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci if (a->vortex == NULL) { 67162306a36Sopenharmony_ci dev_warn(v->card->dev, 67262306a36Sopenharmony_ci "Vort3D_InitializeSource: A3D source not initialized\n"); 67362306a36Sopenharmony_ci return; 67462306a36Sopenharmony_ci } 67562306a36Sopenharmony_ci if (en) { 67662306a36Sopenharmony_ci a3dsrc_ProgramPipe(a); 67762306a36Sopenharmony_ci a3dsrc_SetA3DSampleRate(a, 0x11); 67862306a36Sopenharmony_ci a3dsrc_SetTimeConsts(a, HrtfTCDefault, 67962306a36Sopenharmony_ci ItdTCDefault, GainTCDefault, 68062306a36Sopenharmony_ci CoefTCDefault); 68162306a36Sopenharmony_ci /* Remark: zero gain is muted. */ 68262306a36Sopenharmony_ci //a3dsrc_SetGainTarget(a,0,0); 68362306a36Sopenharmony_ci //a3dsrc_SetGainCurrent(a,0,0); 68462306a36Sopenharmony_ci a3dsrc_EnableA3D(a); 68562306a36Sopenharmony_ci } else { 68662306a36Sopenharmony_ci a3dsrc_DisableA3D(a); 68762306a36Sopenharmony_ci a3dsrc_ZeroState(a); 68862306a36Sopenharmony_ci } 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci/* Conversion of coordinates into 3D parameters. */ 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_cistatic void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord) 69462306a36Sopenharmony_ci{ 69562306a36Sopenharmony_ci /* FIXME: implement this. */ 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci} 69862306a36Sopenharmony_cistatic void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord) 69962306a36Sopenharmony_ci{ 70062306a36Sopenharmony_ci /* FIXME: implement this. */ 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci} 70362306a36Sopenharmony_cistatic void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right) 70462306a36Sopenharmony_ci{ 70562306a36Sopenharmony_ci /* FIXME: implement this. */ 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_cistatic void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params) 70962306a36Sopenharmony_ci{ 71062306a36Sopenharmony_ci /* FIXME: implement this. */ 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci} 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci/* ALSA control interface. */ 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_cistatic int 71762306a36Sopenharmony_cisnd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 71862306a36Sopenharmony_ci{ 71962306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 72062306a36Sopenharmony_ci uinfo->count = 6; 72162306a36Sopenharmony_ci uinfo->value.integer.min = 0x00000000; 72262306a36Sopenharmony_ci uinfo->value.integer.max = 0xffffffff; 72362306a36Sopenharmony_ci return 0; 72462306a36Sopenharmony_ci} 72562306a36Sopenharmony_cistatic int 72662306a36Sopenharmony_cisnd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 72762306a36Sopenharmony_ci{ 72862306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 72962306a36Sopenharmony_ci uinfo->count = 2; 73062306a36Sopenharmony_ci uinfo->value.integer.min = 0x00000000; 73162306a36Sopenharmony_ci uinfo->value.integer.max = 0xffffffff; 73262306a36Sopenharmony_ci return 0; 73362306a36Sopenharmony_ci} 73462306a36Sopenharmony_cistatic int 73562306a36Sopenharmony_cisnd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 73662306a36Sopenharmony_ci{ 73762306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 73862306a36Sopenharmony_ci uinfo->count = 2; 73962306a36Sopenharmony_ci uinfo->value.integer.min = 0x00000000; 74062306a36Sopenharmony_ci uinfo->value.integer.max = 0xffffffff; 74162306a36Sopenharmony_ci return 0; 74262306a36Sopenharmony_ci} 74362306a36Sopenharmony_cistatic int 74462306a36Sopenharmony_cisnd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol, 74562306a36Sopenharmony_ci struct snd_ctl_elem_info *uinfo) 74662306a36Sopenharmony_ci{ 74762306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 74862306a36Sopenharmony_ci uinfo->count = 4; 74962306a36Sopenharmony_ci uinfo->value.integer.min = 0x00000000; 75062306a36Sopenharmony_ci uinfo->value.integer.max = 0xffffffff; 75162306a36Sopenharmony_ci return 0; 75262306a36Sopenharmony_ci} 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_cistatic int 75562306a36Sopenharmony_cisnd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 75662306a36Sopenharmony_ci{ 75762306a36Sopenharmony_ci //a3dsrc_t *a = kcontrol->private_data; 75862306a36Sopenharmony_ci /* No read yet. Would this be really useable/needed ? */ 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci return 0; 76162306a36Sopenharmony_ci} 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic int 76462306a36Sopenharmony_cisnd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol, 76562306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 76662306a36Sopenharmony_ci{ 76762306a36Sopenharmony_ci a3dsrc_t *a = kcontrol->private_data; 76862306a36Sopenharmony_ci int i; 76962306a36Sopenharmony_ci int coord[6]; 77062306a36Sopenharmony_ci for (i = 0; i < 6; i++) 77162306a36Sopenharmony_ci coord[i] = ucontrol->value.integer.value[i]; 77262306a36Sopenharmony_ci /* Translate orientation coordinates to a3d params. */ 77362306a36Sopenharmony_ci vortex_a3d_coord2hrtf(a->hrtf[0], coord); 77462306a36Sopenharmony_ci vortex_a3d_coord2hrtf(a->hrtf[1], coord); 77562306a36Sopenharmony_ci a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]); 77662306a36Sopenharmony_ci a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]); 77762306a36Sopenharmony_ci return 1; 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_cistatic int 78162306a36Sopenharmony_cisnd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol, 78262306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 78362306a36Sopenharmony_ci{ 78462306a36Sopenharmony_ci a3dsrc_t *a = kcontrol->private_data; 78562306a36Sopenharmony_ci int coord[6]; 78662306a36Sopenharmony_ci int i; 78762306a36Sopenharmony_ci for (i = 0; i < 6; i++) 78862306a36Sopenharmony_ci coord[i] = ucontrol->value.integer.value[i]; 78962306a36Sopenharmony_ci /* Translate orientation coordinates to a3d params. */ 79062306a36Sopenharmony_ci vortex_a3d_coord2itd(a->hrtf[0], coord); 79162306a36Sopenharmony_ci vortex_a3d_coord2itd(a->hrtf[1], coord); 79262306a36Sopenharmony_ci /* Inter aural time difference. */ 79362306a36Sopenharmony_ci a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]); 79462306a36Sopenharmony_ci a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]); 79562306a36Sopenharmony_ci a3dsrc_SetItdDline(a, a->dline); 79662306a36Sopenharmony_ci return 1; 79762306a36Sopenharmony_ci} 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_cistatic int 80062306a36Sopenharmony_cisnd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol, 80162306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci a3dsrc_t *a = kcontrol->private_data; 80462306a36Sopenharmony_ci int l, r; 80562306a36Sopenharmony_ci /* There may be some scale tranlation needed here. */ 80662306a36Sopenharmony_ci l = ucontrol->value.integer.value[0]; 80762306a36Sopenharmony_ci r = ucontrol->value.integer.value[1]; 80862306a36Sopenharmony_ci vortex_a3d_coord2ild(a->ild, l, r); 80962306a36Sopenharmony_ci /* Left Right panning. */ 81062306a36Sopenharmony_ci a3dsrc_SetGainTarget(a, l, r); 81162306a36Sopenharmony_ci a3dsrc_SetGainCurrent(a, l, r); 81262306a36Sopenharmony_ci return 1; 81362306a36Sopenharmony_ci} 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_cistatic int 81662306a36Sopenharmony_cisnd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol, 81762306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 81862306a36Sopenharmony_ci{ 81962306a36Sopenharmony_ci a3dsrc_t *a = kcontrol->private_data; 82062306a36Sopenharmony_ci int i; 82162306a36Sopenharmony_ci int params[6]; 82262306a36Sopenharmony_ci for (i = 0; i < 6; i++) 82362306a36Sopenharmony_ci params[i] = ucontrol->value.integer.value[i]; 82462306a36Sopenharmony_ci /* Translate generic filter params to a3d filter params. */ 82562306a36Sopenharmony_ci vortex_a3d_translate_filter(a->filter, params); 82662306a36Sopenharmony_ci /* Atmospheric absorption and filtering. */ 82762306a36Sopenharmony_ci a3dsrc_SetAtmosTarget(a, a->filter[0], 82862306a36Sopenharmony_ci a->filter[1], a->filter[2], 82962306a36Sopenharmony_ci a->filter[3], a->filter[4]); 83062306a36Sopenharmony_ci a3dsrc_SetAtmosCurrent(a, a->filter[0], 83162306a36Sopenharmony_ci a->filter[1], a->filter[2], 83262306a36Sopenharmony_ci a->filter[3], a->filter[4]); 83362306a36Sopenharmony_ci return 1; 83462306a36Sopenharmony_ci} 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_cistatic const struct snd_kcontrol_new vortex_a3d_kcontrol = { 83762306a36Sopenharmony_ci .iface = SNDRV_CTL_ELEM_IFACE_PCM, 83862306a36Sopenharmony_ci .name = "Playback PCM advanced processing", 83962306a36Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 84062306a36Sopenharmony_ci .info = snd_vortex_a3d_hrtf_info, 84162306a36Sopenharmony_ci .get = snd_vortex_a3d_get, 84262306a36Sopenharmony_ci .put = snd_vortex_a3d_hrtf_put, 84362306a36Sopenharmony_ci}; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci/* Control (un)registration. */ 84662306a36Sopenharmony_cistatic int vortex_a3d_register_controls(vortex_t *vortex) 84762306a36Sopenharmony_ci{ 84862306a36Sopenharmony_ci struct snd_kcontrol *kcontrol; 84962306a36Sopenharmony_ci int err, i; 85062306a36Sopenharmony_ci /* HRTF controls. */ 85162306a36Sopenharmony_ci for (i = 0; i < NR_A3D; i++) { 85262306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]); 85362306a36Sopenharmony_ci if (!kcontrol) 85462306a36Sopenharmony_ci return -ENOMEM; 85562306a36Sopenharmony_ci kcontrol->id.numid = CTRLID_HRTF; 85662306a36Sopenharmony_ci kcontrol->info = snd_vortex_a3d_hrtf_info; 85762306a36Sopenharmony_ci kcontrol->put = snd_vortex_a3d_hrtf_put; 85862306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 85962306a36Sopenharmony_ci if (err < 0) 86062306a36Sopenharmony_ci return err; 86162306a36Sopenharmony_ci } 86262306a36Sopenharmony_ci /* ITD controls. */ 86362306a36Sopenharmony_ci for (i = 0; i < NR_A3D; i++) { 86462306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]); 86562306a36Sopenharmony_ci if (!kcontrol) 86662306a36Sopenharmony_ci return -ENOMEM; 86762306a36Sopenharmony_ci kcontrol->id.numid = CTRLID_ITD; 86862306a36Sopenharmony_ci kcontrol->info = snd_vortex_a3d_itd_info; 86962306a36Sopenharmony_ci kcontrol->put = snd_vortex_a3d_itd_put; 87062306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 87162306a36Sopenharmony_ci if (err < 0) 87262306a36Sopenharmony_ci return err; 87362306a36Sopenharmony_ci } 87462306a36Sopenharmony_ci /* ILD (gains) controls. */ 87562306a36Sopenharmony_ci for (i = 0; i < NR_A3D; i++) { 87662306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]); 87762306a36Sopenharmony_ci if (!kcontrol) 87862306a36Sopenharmony_ci return -ENOMEM; 87962306a36Sopenharmony_ci kcontrol->id.numid = CTRLID_GAINS; 88062306a36Sopenharmony_ci kcontrol->info = snd_vortex_a3d_ild_info; 88162306a36Sopenharmony_ci kcontrol->put = snd_vortex_a3d_ild_put; 88262306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 88362306a36Sopenharmony_ci if (err < 0) 88462306a36Sopenharmony_ci return err; 88562306a36Sopenharmony_ci } 88662306a36Sopenharmony_ci /* Filter controls. */ 88762306a36Sopenharmony_ci for (i = 0; i < NR_A3D; i++) { 88862306a36Sopenharmony_ci kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]); 88962306a36Sopenharmony_ci if (!kcontrol) 89062306a36Sopenharmony_ci return -ENOMEM; 89162306a36Sopenharmony_ci kcontrol->id.numid = CTRLID_FILTER; 89262306a36Sopenharmony_ci kcontrol->info = snd_vortex_a3d_filter_info; 89362306a36Sopenharmony_ci kcontrol->put = snd_vortex_a3d_filter_put; 89462306a36Sopenharmony_ci err = snd_ctl_add(vortex->card, kcontrol); 89562306a36Sopenharmony_ci if (err < 0) 89662306a36Sopenharmony_ci return err; 89762306a36Sopenharmony_ci } 89862306a36Sopenharmony_ci return 0; 89962306a36Sopenharmony_ci} 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_cistatic void vortex_a3d_unregister_controls(vortex_t * vortex) 90262306a36Sopenharmony_ci{ 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci} 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci/* End of File*/ 907