11da177e4SLinus Torvalds /*************************************************************************** 21da177e4SLinus Torvalds * au88x0_a3d.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Fri Jul 18 14:16:22 2003 51da177e4SLinus Torvalds * Copyright 2003 mjander 61da177e4SLinus Torvalds * mjander@users.sourceforge.net 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * A3D. You may think i'm crazy, but this may work someday. Who knows... 91da177e4SLinus Torvalds ****************************************************************************/ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds /* 121da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 131da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 141da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 151da177e4SLinus Torvalds * (at your option) any later version. 161da177e4SLinus Torvalds * 171da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 181da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 191da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 201da177e4SLinus Torvalds * GNU Library General Public License for more details. 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 231da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 241da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include "au88x0_a3d.h" 281da177e4SLinus Torvalds #include "au88x0_a3ddata.c" 291da177e4SLinus Torvalds #include "au88x0_xtalk.h" 301da177e4SLinus Torvalds #include "au88x0.h" 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds static void 331da177e4SLinus Torvalds a3dsrc_SetTimeConsts(a3dsrc_t * a, short HrtfTrack, short ItdTrack, 341da177e4SLinus Torvalds short GTrack, short CTrack) 351da177e4SLinus Torvalds { 361da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 371da177e4SLinus Torvalds hwwrite(vortex->mmio, 381da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_HrtfTrackTC), HrtfTrack); 391da177e4SLinus Torvalds hwwrite(vortex->mmio, 401da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_ITDTrackTC), ItdTrack); 411da177e4SLinus Torvalds hwwrite(vortex->mmio, 421da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_GainTrackTC), GTrack); 431da177e4SLinus Torvalds hwwrite(vortex->mmio, 441da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_CoeffTrackTC), CTrack); 451da177e4SLinus Torvalds } 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds #if 0 481da177e4SLinus Torvalds static void 491da177e4SLinus Torvalds a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack, 501da177e4SLinus Torvalds short *GTrack, short *CTrack) 511da177e4SLinus Torvalds { 521da177e4SLinus Torvalds // stub! 531da177e4SLinus Torvalds } 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds #endif 5625985edcSLucas De Marchi /* Atmospheric absorption. */ 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds static void 591da177e4SLinus Torvalds a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d, 601da177e4SLinus Torvalds short e) 611da177e4SLinus Torvalds { 621da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 631da177e4SLinus Torvalds hwwrite(vortex->mmio, 641da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_A21Target), 651da177e4SLinus Torvalds (e << 0x10) | d); 661da177e4SLinus Torvalds hwwrite(vortex->mmio, 671da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_B10Target), 681da177e4SLinus Torvalds (b << 0x10) | aa); 691da177e4SLinus Torvalds hwwrite(vortex->mmio, 701da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_B2Target), c); 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds static void 741da177e4SLinus Torvalds a3dsrc_SetAtmosCurrent(a3dsrc_t * a, short aa, short b, short c, short d, 751da177e4SLinus Torvalds short e) 761da177e4SLinus Torvalds { 771da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 781da177e4SLinus Torvalds hwwrite(vortex->mmio, 791da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_A12Current), 801da177e4SLinus Torvalds (e << 0x10) | d); 811da177e4SLinus Torvalds hwwrite(vortex->mmio, 821da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_B01Current), 831da177e4SLinus Torvalds (b << 0x10) | aa); 841da177e4SLinus Torvalds hwwrite(vortex->mmio, 851da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_B2Current), c); 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds static void 891da177e4SLinus Torvalds a3dsrc_SetAtmosState(a3dsrc_t * a, short x1, short x2, short y1, short y2) 901da177e4SLinus Torvalds { 911da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 921da177e4SLinus Torvalds hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x1), x1); 931da177e4SLinus Torvalds hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x2), x2); 941da177e4SLinus Torvalds hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y1), y1); 951da177e4SLinus Torvalds hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y2), y2); 961da177e4SLinus Torvalds } 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds #if 0 991da177e4SLinus Torvalds static void 1001da177e4SLinus Torvalds a3dsrc_GetAtmosTarget(a3dsrc_t * a, short *aa, short *b, short *c, 1011da177e4SLinus Torvalds short *d, short *e) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds } 1041da177e4SLinus Torvalds static void 1051da177e4SLinus Torvalds a3dsrc_GetAtmosCurrent(a3dsrc_t * a, short *bb01, short *ab01, short *b2, 1061da177e4SLinus Torvalds short *aa12, short *ba12) 1071da177e4SLinus Torvalds { 1081da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1091da177e4SLinus Torvalds *aa12 = 1101da177e4SLinus Torvalds hwread(vortex->mmio, 1111da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_A12Current)); 1121da177e4SLinus Torvalds *ba12 = 1131da177e4SLinus Torvalds hwread(vortex->mmio, 1141da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_A12Current)); 1151da177e4SLinus Torvalds *ab01 = 1161da177e4SLinus Torvalds hwread(vortex->mmio, 1171da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_B01Current)); 1181da177e4SLinus Torvalds *bb01 = 1191da177e4SLinus Torvalds hwread(vortex->mmio, 1201da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_B01Current)); 1211da177e4SLinus Torvalds *b2 = 1221da177e4SLinus Torvalds hwread(vortex->mmio, 1231da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_B2Current)); 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds static void 1271da177e4SLinus Torvalds a3dsrc_GetAtmosState(a3dsrc_t * a, short *x1, short *x2, short *y1, short *y2) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds } 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds #endif 1331da177e4SLinus Torvalds /* HRTF */ 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds static void 1361da177e4SLinus Torvalds a3dsrc_SetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 1371da177e4SLinus Torvalds { 1381da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1391da177e4SLinus Torvalds int i; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 1421da177e4SLinus Torvalds hwwrite(vortex->mmio, 1431da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 1441da177e4SLinus Torvalds A3D_B_HrtfTarget) + (i << 2), 1451da177e4SLinus Torvalds (b[i] << 0x10) | aa[i]); 1461da177e4SLinus Torvalds } 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds static void 1491da177e4SLinus Torvalds a3dsrc_SetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 1501da177e4SLinus Torvalds { 1511da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1521da177e4SLinus Torvalds int i; 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 1551da177e4SLinus Torvalds hwwrite(vortex->mmio, 1561da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 1571da177e4SLinus Torvalds A3D_B_HrtfCurrent) + (i << 2), 1581da177e4SLinus Torvalds (b[i] << 0x10) | aa[i]); 1591da177e4SLinus Torvalds } 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds static void 1621da177e4SLinus Torvalds a3dsrc_SetHrtfState(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b) 1631da177e4SLinus Torvalds { 1641da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1651da177e4SLinus Torvalds int i; 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 1681da177e4SLinus Torvalds hwwrite(vortex->mmio, 1691da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 1701da177e4SLinus Torvalds A3D_B_HrtfDelayLine) + (i << 2), 1711da177e4SLinus Torvalds (b[i] << 0x10) | aa[i]); 1721da177e4SLinus Torvalds } 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds static void a3dsrc_SetHrtfOutput(a3dsrc_t * a, short left, short right) 1751da177e4SLinus Torvalds { 1761da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1771da177e4SLinus Torvalds hwwrite(vortex->mmio, 1781da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL), left); 1791da177e4SLinus Torvalds hwwrite(vortex->mmio, 1801da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR), right); 1811da177e4SLinus Torvalds } 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds #if 0 1841da177e4SLinus Torvalds static void a3dsrc_GetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 1851da177e4SLinus Torvalds { 1861da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 1871da177e4SLinus Torvalds int i; 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 1901da177e4SLinus Torvalds aa[i] = 1911da177e4SLinus Torvalds hwread(vortex->mmio, 1921da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, 1931da177e4SLinus Torvalds A3D_A_HrtfTarget + (i << 2))); 1941da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 1951da177e4SLinus Torvalds b[i] = 1961da177e4SLinus Torvalds hwread(vortex->mmio, 1971da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 1981da177e4SLinus Torvalds A3D_B_HrtfTarget + (i << 2))); 1991da177e4SLinus Torvalds } 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds static void a3dsrc_GetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 2021da177e4SLinus Torvalds { 2031da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2041da177e4SLinus Torvalds int i; 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 2071da177e4SLinus Torvalds aa[i] = 2081da177e4SLinus Torvalds hwread(vortex->mmio, 2091da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, 2101da177e4SLinus Torvalds A3D_A_HrtfCurrent + (i << 2))); 2111da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 2121da177e4SLinus Torvalds b[i] = 2131da177e4SLinus Torvalds hwread(vortex->mmio, 2141da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 2151da177e4SLinus Torvalds A3D_B_HrtfCurrent + (i << 2))); 2161da177e4SLinus Torvalds } 2171da177e4SLinus Torvalds 2181da177e4SLinus Torvalds static void a3dsrc_GetHrtfState(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b) 2191da177e4SLinus Torvalds { 2201da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2211da177e4SLinus Torvalds int i; 2221da177e4SLinus Torvalds // FIXME: verify this! 2231da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 2241da177e4SLinus Torvalds aa[i] = 2251da177e4SLinus Torvalds hwread(vortex->mmio, 2261da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, 2271da177e4SLinus Torvalds A3D_A_HrtfDelayLine + (i << 2))); 2281da177e4SLinus Torvalds for (i = 0; i < HRTF_SZ; i++) 2291da177e4SLinus Torvalds b[i] = 2301da177e4SLinus Torvalds hwread(vortex->mmio, 2311da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, 2321da177e4SLinus Torvalds A3D_B_HrtfDelayLine + (i << 2))); 2331da177e4SLinus Torvalds } 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds static void a3dsrc_GetHrtfOutput(a3dsrc_t * a, short *left, short *right) 2361da177e4SLinus Torvalds { 2371da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2381da177e4SLinus Torvalds *left = 2391da177e4SLinus Torvalds hwread(vortex->mmio, 2401da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL)); 2411da177e4SLinus Torvalds *right = 2421da177e4SLinus Torvalds hwread(vortex->mmio, 2431da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR)); 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds #endif 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds /* Interaural Time Difference. 2491da177e4SLinus Torvalds * "The other main clue that humans use to locate sounds, is called 2501da177e4SLinus Torvalds * Interaural Time Difference (ITD). The differences in distance from 2511da177e4SLinus Torvalds * the sound source to a listeners ears means that the sound will 2521da177e4SLinus Torvalds * reach one ear slightly before the other....", found somewhere with google.*/ 2531da177e4SLinus Torvalds static void a3dsrc_SetItdTarget(a3dsrc_t * a, short litd, short ritd) 2541da177e4SLinus Torvalds { 2551da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds if (litd < 0) 2581da177e4SLinus Torvalds litd = 0; 2591da177e4SLinus Torvalds if (litd > 0x57FF) 2601da177e4SLinus Torvalds litd = 0x57FF; 2611da177e4SLinus Torvalds if (ritd < 0) 2621da177e4SLinus Torvalds ritd = 0; 2631da177e4SLinus Torvalds if (ritd > 0x57FF) 2641da177e4SLinus Torvalds ritd = 0x57FF; 2651da177e4SLinus Torvalds hwwrite(vortex->mmio, 2661da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_ITDTarget), 2671da177e4SLinus Torvalds (ritd << 0x10) | litd); 2681da177e4SLinus Torvalds //hwwrite(vortex->mmio, addr(0x191DF+5, this04, this08), (ritd<<0x10)|litd); 2691da177e4SLinus Torvalds } 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds static void a3dsrc_SetItdCurrent(a3dsrc_t * a, short litd, short ritd) 2721da177e4SLinus Torvalds { 2731da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds if (litd < 0) 2761da177e4SLinus Torvalds litd = 0; 2771da177e4SLinus Torvalds if (litd > 0x57FF) 2781da177e4SLinus Torvalds litd = 0x57FF; 2791da177e4SLinus Torvalds if (ritd < 0) 2801da177e4SLinus Torvalds ritd = 0; 2811da177e4SLinus Torvalds if (ritd > 0x57FF) 2821da177e4SLinus Torvalds ritd = 0x57FF; 2831da177e4SLinus Torvalds hwwrite(vortex->mmio, 2841da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent), 2851da177e4SLinus Torvalds (ritd << 0x10) | litd); 2861da177e4SLinus Torvalds //hwwrite(vortex->mmio, addr(0x191DF+1, this04, this08), (ritd<<0x10)|litd); 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds static void a3dsrc_SetItdDline(a3dsrc_t * a, a3d_ItdDline_t const dline) 2901da177e4SLinus Torvalds { 2911da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 2921da177e4SLinus Torvalds int i; 2931da177e4SLinus Torvalds /* 45 != 40 -> Check this ! */ 2941da177e4SLinus Torvalds for (i = 0; i < DLINE_SZ; i++) 2951da177e4SLinus Torvalds hwwrite(vortex->mmio, 2961da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, 2971da177e4SLinus Torvalds A3D_A_ITDDelayLine) + (i << 2), dline[i]); 2981da177e4SLinus Torvalds } 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds #if 0 3011da177e4SLinus Torvalds static void a3dsrc_GetItdTarget(a3dsrc_t * a, short *litd, short *ritd) 3021da177e4SLinus Torvalds { 3031da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3041da177e4SLinus Torvalds *ritd = 3051da177e4SLinus Torvalds hwread(vortex->mmio, 3061da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_ITDTarget)); 3071da177e4SLinus Torvalds *litd = 3081da177e4SLinus Torvalds hwread(vortex->mmio, 3091da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_ITDTarget)); 3101da177e4SLinus Torvalds } 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds static void a3dsrc_GetItdCurrent(a3dsrc_t * a, short *litd, short *ritd) 3131da177e4SLinus Torvalds { 3141da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3151da177e4SLinus Torvalds 3161da177e4SLinus Torvalds *ritd = 3171da177e4SLinus Torvalds hwread(vortex->mmio, 3181da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_ITDCurrent)); 3191da177e4SLinus Torvalds *litd = 3201da177e4SLinus Torvalds hwread(vortex->mmio, 3211da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent)); 3221da177e4SLinus Torvalds } 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds static void a3dsrc_GetItdDline(a3dsrc_t * a, a3d_ItdDline_t dline) 3251da177e4SLinus Torvalds { 3261da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3271da177e4SLinus Torvalds int i; 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvalds for (i = 0; i < DLINE_SZ; i++) 3301da177e4SLinus Torvalds dline[i] = 3311da177e4SLinus Torvalds hwread(vortex->mmio, 3321da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, 3331da177e4SLinus Torvalds A3D_A_ITDDelayLine + (i << 2))); 3341da177e4SLinus Torvalds } 3351da177e4SLinus Torvalds 3361da177e4SLinus Torvalds #endif 3371da177e4SLinus Torvalds /* This is may be used for ILD Interaural Level Difference. */ 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds static void a3dsrc_SetGainTarget(a3dsrc_t * a, short left, short right) 3401da177e4SLinus Torvalds { 3411da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3421da177e4SLinus Torvalds hwwrite(vortex->mmio, 3431da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_GainTarget), 3441da177e4SLinus Torvalds (right << 0x10) | left); 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds static void a3dsrc_SetGainCurrent(a3dsrc_t * a, short left, short right) 3481da177e4SLinus Torvalds { 3491da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3501da177e4SLinus Torvalds hwwrite(vortex->mmio, 3511da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_GainCurrent), 3521da177e4SLinus Torvalds (right << 0x10) | left); 3531da177e4SLinus Torvalds } 3541da177e4SLinus Torvalds 3551da177e4SLinus Torvalds #if 0 3561da177e4SLinus Torvalds static void a3dsrc_GetGainTarget(a3dsrc_t * a, short *left, short *right) 3571da177e4SLinus Torvalds { 3581da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3591da177e4SLinus Torvalds *right = 3601da177e4SLinus Torvalds hwread(vortex->mmio, 3611da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_GainTarget)); 3621da177e4SLinus Torvalds *left = 3631da177e4SLinus Torvalds hwread(vortex->mmio, 3641da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_GainTarget)); 3651da177e4SLinus Torvalds } 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds static void a3dsrc_GetGainCurrent(a3dsrc_t * a, short *left, short *right) 3681da177e4SLinus Torvalds { 3691da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3701da177e4SLinus Torvalds *right = 3711da177e4SLinus Torvalds hwread(vortex->mmio, 3721da177e4SLinus Torvalds a3d_addrA(a->slice, a->source, A3D_A_GainCurrent)); 3731da177e4SLinus Torvalds *left = 3741da177e4SLinus Torvalds hwread(vortex->mmio, 3751da177e4SLinus Torvalds a3d_addrB(a->slice, a->source, A3D_B_GainCurrent)); 3761da177e4SLinus Torvalds } 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds /* CA3dIO this func seems to be inlined all over this place. */ 3791da177e4SLinus Torvalds static void CA3dIO_WriteReg(a3dsrc_t * a, unsigned long addr, short aa, short b) 3801da177e4SLinus Torvalds { 3811da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3821da177e4SLinus Torvalds hwwrite(vortex->mmio, addr, (aa << 0x10) | b); 3831da177e4SLinus Torvalds } 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvalds #endif 3861da177e4SLinus Torvalds /* Generic A3D stuff */ 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds static void a3dsrc_SetA3DSampleRate(a3dsrc_t * a, int sr) 3891da177e4SLinus Torvalds { 3901da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 3911da177e4SLinus Torvalds int esp0 = 0; 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds esp0 = (((esp0 & 0x7fffffff) | 0xB8000000) & 0x7) | ((sr & 0x1f) << 3); 3941da177e4SLinus Torvalds hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), esp0); 3951da177e4SLinus Torvalds //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), esp0); 3961da177e4SLinus Torvalds } 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds static void a3dsrc_EnableA3D(a3dsrc_t * a) 3991da177e4SLinus Torvalds { 4001da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4011da177e4SLinus Torvalds hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), 4021da177e4SLinus Torvalds 0xF0000001); 4031da177e4SLinus Torvalds //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), 0xF0000001); 4041da177e4SLinus Torvalds } 4051da177e4SLinus Torvalds 4061da177e4SLinus Torvalds static void a3dsrc_DisableA3D(a3dsrc_t * a) 4071da177e4SLinus Torvalds { 4081da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4091da177e4SLinus Torvalds hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), 4101da177e4SLinus Torvalds 0xF0000000); 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds 4131da177e4SLinus Torvalds static void a3dsrc_SetA3DControlReg(a3dsrc_t * a, unsigned long ctrl) 4141da177e4SLinus Torvalds { 4151da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4161da177e4SLinus Torvalds hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), ctrl); 4171da177e4SLinus Torvalds } 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds static void a3dsrc_SetA3DPointerReg(a3dsrc_t * a, unsigned long ptr) 4201da177e4SLinus Torvalds { 4211da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4221da177e4SLinus Torvalds hwwrite(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd), ptr); 4231da177e4SLinus Torvalds } 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvalds #if 0 4261da177e4SLinus Torvalds static void a3dsrc_GetA3DSampleRate(a3dsrc_t * a, int *sr) 4271da177e4SLinus Torvalds { 4281da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4291da177e4SLinus Torvalds *sr = ((hwread(vortex->mmio, A3D_SLICE_Control + (a->slice << 0xd)) 4301da177e4SLinus Torvalds >> 3) & 0x1f); 4311da177e4SLinus Torvalds //*sr = ((hwread(vortex->mmio, 0x19C38 + (this08<<0xd))>>3)&0x1f); 4321da177e4SLinus Torvalds } 4331da177e4SLinus Torvalds 4341da177e4SLinus Torvalds static void a3dsrc_GetA3DControlReg(a3dsrc_t * a, unsigned long *ctrl) 4351da177e4SLinus Torvalds { 4361da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4371da177e4SLinus Torvalds *ctrl = hwread(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd)); 4381da177e4SLinus Torvalds } 4391da177e4SLinus Torvalds 4401da177e4SLinus Torvalds static void a3dsrc_GetA3DPointerReg(a3dsrc_t * a, unsigned long *ptr) 4411da177e4SLinus Torvalds { 4421da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4431da177e4SLinus Torvalds *ptr = hwread(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd)); 4441da177e4SLinus Torvalds } 4451da177e4SLinus Torvalds 4461da177e4SLinus Torvalds #endif 4471da177e4SLinus Torvalds static void a3dsrc_ZeroSliceIO(a3dsrc_t * a) 4481da177e4SLinus Torvalds { 4491da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 4501da177e4SLinus Torvalds int i; 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds for (i = 0; i < 8; i++) 4531da177e4SLinus Torvalds hwwrite(vortex->mmio, 4541da177e4SLinus Torvalds A3D_SLICE_VDBDest + 4551da177e4SLinus Torvalds ((((a->slice) << 0xb) + i) << 2), 0); 4561da177e4SLinus Torvalds for (i = 0; i < 4; i++) 4571da177e4SLinus Torvalds hwwrite(vortex->mmio, 4581da177e4SLinus Torvalds A3D_SLICE_VDBSource + 4591da177e4SLinus Torvalds ((((a->slice) << 0xb) + i) << 2), 0); 4601da177e4SLinus Torvalds } 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds /* Reset Single A3D source. */ 4631da177e4SLinus Torvalds static void a3dsrc_ZeroState(a3dsrc_t * a) 4641da177e4SLinus Torvalds { 465ee419653STakashi Iwai /* 466e7e69265SSudip Mukherjee pr_debug( "vortex: ZeroState slice: %d, source %d\n", 467ee419653STakashi Iwai a->slice, a->source); 468ee419653STakashi Iwai */ 4691da177e4SLinus Torvalds a3dsrc_SetAtmosState(a, 0, 0, 0, 0); 4701da177e4SLinus Torvalds a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros); 4711da177e4SLinus Torvalds a3dsrc_SetItdDline(a, A3dItdDlineZeros); 4721da177e4SLinus Torvalds a3dsrc_SetHrtfOutput(a, 0, 0); 4731da177e4SLinus Torvalds a3dsrc_SetTimeConsts(a, 0, 0, 0, 0); 4741da177e4SLinus Torvalds 4751da177e4SLinus Torvalds a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0); 4761da177e4SLinus Torvalds a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0); 4771da177e4SLinus Torvalds a3dsrc_SetItdCurrent(a, 0, 0); 4781da177e4SLinus Torvalds a3dsrc_SetItdTarget(a, 0, 0); 4791da177e4SLinus Torvalds a3dsrc_SetGainCurrent(a, 0, 0); 4801da177e4SLinus Torvalds a3dsrc_SetGainTarget(a, 0, 0); 4811da177e4SLinus Torvalds 4821da177e4SLinus Torvalds a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros); 4831da177e4SLinus Torvalds a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros); 4841da177e4SLinus Torvalds } 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds /* Reset entire A3D engine */ 4876a40dc5aSSudip Mukherjee static void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v) 4881da177e4SLinus Torvalds { 4891da177e4SLinus Torvalds int i, var, var2; 4901da177e4SLinus Torvalds 4911da177e4SLinus Torvalds if ((a->vortex) == NULL) { 49270c84418SSudip Mukherjee dev_err(v->card->dev, 49370c84418SSudip Mukherjee "ZeroStateA3D: ERROR: a->vortex is NULL\n"); 4941da177e4SLinus Torvalds return; 4951da177e4SLinus Torvalds } 4961da177e4SLinus Torvalds 4971da177e4SLinus Torvalds a3dsrc_SetA3DControlReg(a, 0); 4981da177e4SLinus Torvalds a3dsrc_SetA3DPointerReg(a, 0); 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds var = a->slice; 5011da177e4SLinus Torvalds var2 = a->source; 5021da177e4SLinus Torvalds for (i = 0; i < 4; i++) { 5031da177e4SLinus Torvalds a->slice = i; 5041da177e4SLinus Torvalds a3dsrc_ZeroSliceIO(a); 5051da177e4SLinus Torvalds //a3dsrc_ZeroState(a); 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds a->source = var2; 5081da177e4SLinus Torvalds a->slice = var; 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5111da177e4SLinus Torvalds /* Program A3D block as pass through */ 5121da177e4SLinus Torvalds static void a3dsrc_ProgramPipe(a3dsrc_t * a) 5131da177e4SLinus Torvalds { 5141da177e4SLinus Torvalds a3dsrc_SetTimeConsts(a, 0, 0, 0, 0); 5151da177e4SLinus Torvalds a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0); 5161da177e4SLinus Torvalds a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0); 5171da177e4SLinus Torvalds a3dsrc_SetItdCurrent(a, 0, 0); 5181da177e4SLinus Torvalds a3dsrc_SetItdTarget(a, 0, 0); 5191da177e4SLinus Torvalds a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff); 5201da177e4SLinus Torvalds a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff); 5211da177e4SLinus Torvalds 5221da177e4SLinus Torvalds /* SET HRTF HERE */ 5231da177e4SLinus Torvalds 5241da177e4SLinus Torvalds /* Single spike leads to identity transfer function. */ 5251da177e4SLinus Torvalds a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse); 5261da177e4SLinus Torvalds a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse); 5271da177e4SLinus Torvalds 5281da177e4SLinus Torvalds /* Test: Sounds saturated. */ 5291da177e4SLinus Torvalds //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest); 5301da177e4SLinus Torvalds //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest); 5311da177e4SLinus Torvalds } 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds /* VDB = Vortex audio Dataflow Bus */ 5341da177e4SLinus Torvalds #if 0 5351da177e4SLinus Torvalds static void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa) 5361da177e4SLinus Torvalds { 5371da177e4SLinus Torvalds vortex_t *vortex = (vortex_t *) (a->vortex); 5381da177e4SLinus Torvalds 5391da177e4SLinus Torvalds // ((aa >> 2) << 8) - (aa >> 2) 5401da177e4SLinus Torvalds hwwrite(vortex->mmio, 5411da177e4SLinus Torvalds a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0); 5421da177e4SLinus Torvalds hwwrite(vortex->mmio, 5431da177e4SLinus Torvalds a3d_addrS(a->slice, 5441da177e4SLinus Torvalds A3D_SLICE_VDBDest + 4) + (a->source << 2), 0); 5451da177e4SLinus Torvalds /* 5461da177e4SLinus Torvalds hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0); 5471da177e4SLinus Torvalds hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0); 5481da177e4SLinus Torvalds */ 5491da177e4SLinus Torvalds } 5501da177e4SLinus Torvalds #endif 5511da177e4SLinus Torvalds 5521da177e4SLinus Torvalds /* A3D HwSource stuff. */ 5531da177e4SLinus Torvalds 5541da177e4SLinus Torvalds static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice) 5551da177e4SLinus Torvalds { 5561da177e4SLinus Torvalds a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]); 5571da177e4SLinus Torvalds //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]); 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds a3dsrc->vortex = (void *)v; 5601da177e4SLinus Torvalds a3dsrc->source = source; /* source */ 5611da177e4SLinus Torvalds a3dsrc->slice = slice; /* slice */ 5621da177e4SLinus Torvalds a3dsrc_ZeroState(a3dsrc); 5631da177e4SLinus Torvalds /* Added by me. */ 5641da177e4SLinus Torvalds a3dsrc_SetA3DSampleRate(a3dsrc, 0x11); 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode) 5681da177e4SLinus Torvalds { 5691da177e4SLinus Torvalds v->xt_mode = mode; /* this_14 */ 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds vortex_XtalkHw_init(v); 5721da177e4SLinus Torvalds vortex_XtalkHw_SetGainsAllChan(v); 5731da177e4SLinus Torvalds switch (v->xt_mode) { 5741da177e4SLinus Torvalds case XT_SPEAKER0: 5751da177e4SLinus Torvalds vortex_XtalkHw_ProgramXtalkNarrow(v); 5761da177e4SLinus Torvalds break; 5771da177e4SLinus Torvalds case XT_SPEAKER1: 5781da177e4SLinus Torvalds vortex_XtalkHw_ProgramXtalkWide(v); 5791da177e4SLinus Torvalds break; 5801da177e4SLinus Torvalds default: 5811da177e4SLinus Torvalds case XT_HEADPHONE: 5821da177e4SLinus Torvalds vortex_XtalkHw_ProgramPipe(v); 5831da177e4SLinus Torvalds break; 5841da177e4SLinus Torvalds case XT_DIAMOND: 5851da177e4SLinus Torvalds vortex_XtalkHw_ProgramDiamondXtalk(v); 5861da177e4SLinus Torvalds break; 5871da177e4SLinus Torvalds } 5881da177e4SLinus Torvalds vortex_XtalkHw_SetSampleRate(v, 0x11); 5891da177e4SLinus Torvalds vortex_XtalkHw_Enable(v); 5901da177e4SLinus Torvalds return 0; 5911da177e4SLinus Torvalds } 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds /* 3D Sound entry points. */ 5941da177e4SLinus Torvalds 5951da177e4SLinus Torvalds static int vortex_a3d_register_controls(vortex_t * vortex); 5961da177e4SLinus Torvalds static void vortex_a3d_unregister_controls(vortex_t * vortex); 5971da177e4SLinus Torvalds /* A3D base support init/shudown */ 598e23e7a14SBill Pemberton static void vortex_Vort3D_enable(vortex_t *v) 5991da177e4SLinus Torvalds { 6001da177e4SLinus Torvalds int i; 601f40b6890STakashi Iwai 6021da177e4SLinus Torvalds Vort3DRend_Initialize(v, XT_HEADPHONE); 6031da177e4SLinus Torvalds for (i = 0; i < NR_A3D; i++) { 6041da177e4SLinus Torvalds vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2); 6056a40dc5aSSudip Mukherjee a3dsrc_ZeroStateA3D(&v->a3d[0], v); 6061da177e4SLinus Torvalds } 6071da177e4SLinus Torvalds /* Register ALSA controls */ 6081da177e4SLinus Torvalds vortex_a3d_register_controls(v); 6091da177e4SLinus Torvalds } 610f40b6890STakashi Iwai 611f40b6890STakashi Iwai static void vortex_Vort3D_disable(vortex_t * v) 612f40b6890STakashi Iwai { 613f40b6890STakashi Iwai vortex_XtalkHw_Disable(v); 614f40b6890STakashi Iwai vortex_a3d_unregister_controls(v); 6151da177e4SLinus Torvalds } 6161da177e4SLinus Torvalds 6171da177e4SLinus Torvalds /* Make A3D subsystem connections. */ 6181da177e4SLinus Torvalds static void vortex_Vort3D_connect(vortex_t * v, int en) 6191da177e4SLinus Torvalds { 6201da177e4SLinus Torvalds int i; 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds // Disable AU8810 routes, since they seem to be wrong (in au8810.h). 6231da177e4SLinus Torvalds #ifdef CHIP_AU8810 6241da177e4SLinus Torvalds return; 6251da177e4SLinus Torvalds #endif 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds #if 1 6281da177e4SLinus Torvalds /* Alloc Xtalk mixin resources */ 6291da177e4SLinus Torvalds v->mixxtlk[0] = 6301da177e4SLinus Torvalds vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); 6311da177e4SLinus Torvalds if (v->mixxtlk[0] < 0) { 63270c84418SSudip Mukherjee dev_warn(v->card->dev, 63370c84418SSudip Mukherjee "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); 6341da177e4SLinus Torvalds return; 6351da177e4SLinus Torvalds } 6361da177e4SLinus Torvalds v->mixxtlk[1] = 6371da177e4SLinus Torvalds vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); 6381da177e4SLinus Torvalds if (v->mixxtlk[1] < 0) { 63970c84418SSudip Mukherjee dev_warn(v->card->dev, 64070c84418SSudip Mukherjee "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); 6411da177e4SLinus Torvalds return; 6421da177e4SLinus Torvalds } 6431da177e4SLinus Torvalds #endif 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds /* Connect A3D -> XTALK */ 6461da177e4SLinus Torvalds for (i = 0; i < 4; i++) { 6471da177e4SLinus Torvalds // 2 outputs per each A3D slice. 6481da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i)); 6491da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i)); 6501da177e4SLinus Torvalds } 6511da177e4SLinus Torvalds #if 0 6521da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2)); 6531da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3)); 6541da177e4SLinus Torvalds #else 6551da177e4SLinus Torvalds /* Connect XTalk -> mixer */ 6561da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0])); 6571da177e4SLinus Torvalds vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1])); 6581da177e4SLinus Torvalds vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0); 6591da177e4SLinus Torvalds vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0); 6601da177e4SLinus Torvalds vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0], 6611da177e4SLinus Torvalds en ? MIX_DEFIGAIN : VOL_MIN); 6621da177e4SLinus Torvalds vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1], 6631da177e4SLinus Torvalds en ? MIX_DEFIGAIN : VOL_MIN); 6641da177e4SLinus Torvalds if (VORTEX_IS_QUAD(v)) { 6651da177e4SLinus Torvalds vortex_connection_mixin_mix(v, en, v->mixxtlk[0], 6661da177e4SLinus Torvalds v->mixplayb[2], 0); 6671da177e4SLinus Torvalds vortex_connection_mixin_mix(v, en, v->mixxtlk[1], 6681da177e4SLinus Torvalds v->mixplayb[3], 0); 6691da177e4SLinus Torvalds vortex_mix_setinputvolumebyte(v, v->mixplayb[2], 6701da177e4SLinus Torvalds v->mixxtlk[0], 6711da177e4SLinus Torvalds en ? MIX_DEFIGAIN : VOL_MIN); 6721da177e4SLinus Torvalds vortex_mix_setinputvolumebyte(v, v->mixplayb[3], 6731da177e4SLinus Torvalds v->mixxtlk[1], 6741da177e4SLinus Torvalds en ? MIX_DEFIGAIN : VOL_MIN); 6751da177e4SLinus Torvalds } 6761da177e4SLinus Torvalds #endif 6771da177e4SLinus Torvalds } 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds /* Initialize one single A3D source. */ 6806a40dc5aSSudip Mukherjee static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v) 6811da177e4SLinus Torvalds { 6821da177e4SLinus Torvalds if (a->vortex == NULL) { 68370c84418SSudip Mukherjee dev_warn(v->card->dev, 68470c84418SSudip Mukherjee "Vort3D_InitializeSource: A3D source not initialized\n"); 6851da177e4SLinus Torvalds return; 6861da177e4SLinus Torvalds } 6871da177e4SLinus Torvalds if (en) { 6881da177e4SLinus Torvalds a3dsrc_ProgramPipe(a); 6891da177e4SLinus Torvalds a3dsrc_SetA3DSampleRate(a, 0x11); 6901da177e4SLinus Torvalds a3dsrc_SetTimeConsts(a, HrtfTCDefault, 6911da177e4SLinus Torvalds ItdTCDefault, GainTCDefault, 6921da177e4SLinus Torvalds CoefTCDefault); 6931da177e4SLinus Torvalds /* Remark: zero gain is muted. */ 6941da177e4SLinus Torvalds //a3dsrc_SetGainTarget(a,0,0); 6951da177e4SLinus Torvalds //a3dsrc_SetGainCurrent(a,0,0); 6961da177e4SLinus Torvalds a3dsrc_EnableA3D(a); 6971da177e4SLinus Torvalds } else { 6981da177e4SLinus Torvalds a3dsrc_DisableA3D(a); 6991da177e4SLinus Torvalds a3dsrc_ZeroState(a); 7001da177e4SLinus Torvalds } 7011da177e4SLinus Torvalds } 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds /* Conversion of coordinates into 3D parameters. */ 7041da177e4SLinus Torvalds 7051da177e4SLinus Torvalds static void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord) 7061da177e4SLinus Torvalds { 7071da177e4SLinus Torvalds /* FIXME: implement this. */ 7081da177e4SLinus Torvalds 7091da177e4SLinus Torvalds } 7101da177e4SLinus Torvalds static void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord) 7111da177e4SLinus Torvalds { 7121da177e4SLinus Torvalds /* FIXME: implement this. */ 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds } 7151da177e4SLinus Torvalds static void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right) 7161da177e4SLinus Torvalds { 7171da177e4SLinus Torvalds /* FIXME: implement this. */ 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds } 7201da177e4SLinus Torvalds static void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params) 7211da177e4SLinus Torvalds { 7221da177e4SLinus Torvalds /* FIXME: implement this. */ 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds } 7251da177e4SLinus Torvalds 7261da177e4SLinus Torvalds /* ALSA control interface. */ 7271da177e4SLinus Torvalds 7281da177e4SLinus Torvalds static int 7292fd16874STakashi Iwai snd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 7301da177e4SLinus Torvalds { 7311da177e4SLinus Torvalds uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 7321da177e4SLinus Torvalds uinfo->count = 6; 7331da177e4SLinus Torvalds uinfo->value.integer.min = 0x00000000; 7341da177e4SLinus Torvalds uinfo->value.integer.max = 0xffffffff; 7351da177e4SLinus Torvalds return 0; 7361da177e4SLinus Torvalds } 7371da177e4SLinus Torvalds static int 7382fd16874STakashi Iwai snd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 7391da177e4SLinus Torvalds { 7401da177e4SLinus Torvalds uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 7411da177e4SLinus Torvalds uinfo->count = 2; 7421da177e4SLinus Torvalds uinfo->value.integer.min = 0x00000000; 7431da177e4SLinus Torvalds uinfo->value.integer.max = 0xffffffff; 7441da177e4SLinus Torvalds return 0; 7451da177e4SLinus Torvalds } 7461da177e4SLinus Torvalds static int 7472fd16874STakashi Iwai snd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 7481da177e4SLinus Torvalds { 7491da177e4SLinus Torvalds uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 7501da177e4SLinus Torvalds uinfo->count = 2; 7511da177e4SLinus Torvalds uinfo->value.integer.min = 0x00000000; 7521da177e4SLinus Torvalds uinfo->value.integer.max = 0xffffffff; 7531da177e4SLinus Torvalds return 0; 7541da177e4SLinus Torvalds } 7551da177e4SLinus Torvalds static int 7562fd16874STakashi Iwai snd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol, 7572fd16874STakashi Iwai struct snd_ctl_elem_info *uinfo) 7581da177e4SLinus Torvalds { 7591da177e4SLinus Torvalds uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 7601da177e4SLinus Torvalds uinfo->count = 4; 7611da177e4SLinus Torvalds uinfo->value.integer.min = 0x00000000; 7621da177e4SLinus Torvalds uinfo->value.integer.max = 0xffffffff; 7631da177e4SLinus Torvalds return 0; 7641da177e4SLinus Torvalds } 7651da177e4SLinus Torvalds 7661da177e4SLinus Torvalds static int 7672fd16874STakashi Iwai snd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 7681da177e4SLinus Torvalds { 7691da177e4SLinus Torvalds //a3dsrc_t *a = kcontrol->private_data; 7701da177e4SLinus Torvalds /* No read yet. Would this be really useable/needed ? */ 7711da177e4SLinus Torvalds 7721da177e4SLinus Torvalds return 0; 7731da177e4SLinus Torvalds } 7741da177e4SLinus Torvalds 7751da177e4SLinus Torvalds static int 7762fd16874STakashi Iwai snd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol, 7772fd16874STakashi Iwai struct snd_ctl_elem_value *ucontrol) 7781da177e4SLinus Torvalds { 7791da177e4SLinus Torvalds a3dsrc_t *a = kcontrol->private_data; 7801da177e4SLinus Torvalds int changed = 1, i; 7811da177e4SLinus Torvalds int coord[6]; 7821da177e4SLinus Torvalds for (i = 0; i < 6; i++) 7831da177e4SLinus Torvalds coord[i] = ucontrol->value.integer.value[i]; 7841da177e4SLinus Torvalds /* Translate orientation coordinates to a3d params. */ 7851da177e4SLinus Torvalds vortex_a3d_coord2hrtf(a->hrtf[0], coord); 7861da177e4SLinus Torvalds vortex_a3d_coord2hrtf(a->hrtf[1], coord); 7871da177e4SLinus Torvalds a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]); 7881da177e4SLinus Torvalds a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]); 7891da177e4SLinus Torvalds return changed; 7901da177e4SLinus Torvalds } 7911da177e4SLinus Torvalds 7921da177e4SLinus Torvalds static int 7932fd16874STakashi Iwai snd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol, 7942fd16874STakashi Iwai struct snd_ctl_elem_value *ucontrol) 7951da177e4SLinus Torvalds { 7961da177e4SLinus Torvalds a3dsrc_t *a = kcontrol->private_data; 7971da177e4SLinus Torvalds int coord[6]; 7981da177e4SLinus Torvalds int i, changed = 1; 7991da177e4SLinus Torvalds for (i = 0; i < 6; i++) 8001da177e4SLinus Torvalds coord[i] = ucontrol->value.integer.value[i]; 8011da177e4SLinus Torvalds /* Translate orientation coordinates to a3d params. */ 8021da177e4SLinus Torvalds vortex_a3d_coord2itd(a->hrtf[0], coord); 8031da177e4SLinus Torvalds vortex_a3d_coord2itd(a->hrtf[1], coord); 8041da177e4SLinus Torvalds /* Inter aural time difference. */ 8051da177e4SLinus Torvalds a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]); 8061da177e4SLinus Torvalds a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]); 8071da177e4SLinus Torvalds a3dsrc_SetItdDline(a, a->dline); 8081da177e4SLinus Torvalds return changed; 8091da177e4SLinus Torvalds } 8101da177e4SLinus Torvalds 8111da177e4SLinus Torvalds static int 8122fd16874STakashi Iwai snd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol, 8132fd16874STakashi Iwai struct snd_ctl_elem_value *ucontrol) 8141da177e4SLinus Torvalds { 8151da177e4SLinus Torvalds a3dsrc_t *a = kcontrol->private_data; 8161da177e4SLinus Torvalds int changed = 1; 8171da177e4SLinus Torvalds int l, r; 8181da177e4SLinus Torvalds /* There may be some scale tranlation needed here. */ 8191da177e4SLinus Torvalds l = ucontrol->value.integer.value[0]; 8201da177e4SLinus Torvalds r = ucontrol->value.integer.value[1]; 8211da177e4SLinus Torvalds vortex_a3d_coord2ild(a->ild, l, r); 8221da177e4SLinus Torvalds /* Left Right panning. */ 8231da177e4SLinus Torvalds a3dsrc_SetGainTarget(a, l, r); 8241da177e4SLinus Torvalds a3dsrc_SetGainCurrent(a, l, r); 8251da177e4SLinus Torvalds return changed; 8261da177e4SLinus Torvalds } 8271da177e4SLinus Torvalds 8281da177e4SLinus Torvalds static int 8292fd16874STakashi Iwai snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol, 8302fd16874STakashi Iwai struct snd_ctl_elem_value *ucontrol) 8311da177e4SLinus Torvalds { 8321da177e4SLinus Torvalds a3dsrc_t *a = kcontrol->private_data; 8331da177e4SLinus Torvalds int i, changed = 1; 8341da177e4SLinus Torvalds int params[6]; 8351da177e4SLinus Torvalds for (i = 0; i < 6; i++) 8361da177e4SLinus Torvalds params[i] = ucontrol->value.integer.value[i]; 8371da177e4SLinus Torvalds /* Translate generic filter params to a3d filter params. */ 8381da177e4SLinus Torvalds vortex_a3d_translate_filter(a->filter, params); 83925985edcSLucas De Marchi /* Atmospheric absorption and filtering. */ 8401da177e4SLinus Torvalds a3dsrc_SetAtmosTarget(a, a->filter[0], 8411da177e4SLinus Torvalds a->filter[1], a->filter[2], 8421da177e4SLinus Torvalds a->filter[3], a->filter[4]); 8431da177e4SLinus Torvalds a3dsrc_SetAtmosCurrent(a, a->filter[0], 8441da177e4SLinus Torvalds a->filter[1], a->filter[2], 8451da177e4SLinus Torvalds a->filter[3], a->filter[4]); 8461da177e4SLinus Torvalds return changed; 8471da177e4SLinus Torvalds } 8481da177e4SLinus Torvalds 849e23e7a14SBill Pemberton static struct snd_kcontrol_new vortex_a3d_kcontrol = { 8501da177e4SLinus Torvalds .iface = SNDRV_CTL_ELEM_IFACE_PCM, 8511da177e4SLinus Torvalds .name = "Playback PCM advanced processing", 8521da177e4SLinus Torvalds .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 8531da177e4SLinus Torvalds .info = snd_vortex_a3d_hrtf_info, 8541da177e4SLinus Torvalds .get = snd_vortex_a3d_get, 8551da177e4SLinus Torvalds .put = snd_vortex_a3d_hrtf_put, 8561da177e4SLinus Torvalds }; 8571da177e4SLinus Torvalds 8581da177e4SLinus Torvalds /* Control (un)registration. */ 859e23e7a14SBill Pemberton static int vortex_a3d_register_controls(vortex_t *vortex) 8601da177e4SLinus Torvalds { 8612fd16874STakashi Iwai struct snd_kcontrol *kcontrol; 8621da177e4SLinus Torvalds int err, i; 8631da177e4SLinus Torvalds /* HRTF controls. */ 8641da177e4SLinus Torvalds for (i = 0; i < NR_A3D; i++) { 8651da177e4SLinus Torvalds if ((kcontrol = 8661da177e4SLinus Torvalds snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL) 8671da177e4SLinus Torvalds return -ENOMEM; 8681da177e4SLinus Torvalds kcontrol->id.numid = CTRLID_HRTF; 8691da177e4SLinus Torvalds kcontrol->info = snd_vortex_a3d_hrtf_info; 8701da177e4SLinus Torvalds kcontrol->put = snd_vortex_a3d_hrtf_put; 8711da177e4SLinus Torvalds if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 8721da177e4SLinus Torvalds return err; 8731da177e4SLinus Torvalds } 8741da177e4SLinus Torvalds /* ITD controls. */ 8751da177e4SLinus Torvalds for (i = 0; i < NR_A3D; i++) { 8761da177e4SLinus Torvalds if ((kcontrol = 8771da177e4SLinus Torvalds snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL) 8781da177e4SLinus Torvalds return -ENOMEM; 8791da177e4SLinus Torvalds kcontrol->id.numid = CTRLID_ITD; 8801da177e4SLinus Torvalds kcontrol->info = snd_vortex_a3d_itd_info; 8811da177e4SLinus Torvalds kcontrol->put = snd_vortex_a3d_itd_put; 8821da177e4SLinus Torvalds if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 8831da177e4SLinus Torvalds return err; 8841da177e4SLinus Torvalds } 8851da177e4SLinus Torvalds /* ILD (gains) controls. */ 8861da177e4SLinus Torvalds for (i = 0; i < NR_A3D; i++) { 8871da177e4SLinus Torvalds if ((kcontrol = 8881da177e4SLinus Torvalds snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL) 8891da177e4SLinus Torvalds return -ENOMEM; 8901da177e4SLinus Torvalds kcontrol->id.numid = CTRLID_GAINS; 8911da177e4SLinus Torvalds kcontrol->info = snd_vortex_a3d_ild_info; 8921da177e4SLinus Torvalds kcontrol->put = snd_vortex_a3d_ild_put; 8931da177e4SLinus Torvalds if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 8941da177e4SLinus Torvalds return err; 8951da177e4SLinus Torvalds } 8961da177e4SLinus Torvalds /* Filter controls. */ 8971da177e4SLinus Torvalds for (i = 0; i < NR_A3D; i++) { 8981da177e4SLinus Torvalds if ((kcontrol = 8991da177e4SLinus Torvalds snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL) 9001da177e4SLinus Torvalds return -ENOMEM; 9011da177e4SLinus Torvalds kcontrol->id.numid = CTRLID_FILTER; 9021da177e4SLinus Torvalds kcontrol->info = snd_vortex_a3d_filter_info; 9031da177e4SLinus Torvalds kcontrol->put = snd_vortex_a3d_filter_put; 9041da177e4SLinus Torvalds if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 9051da177e4SLinus Torvalds return err; 9061da177e4SLinus Torvalds } 9071da177e4SLinus Torvalds return 0; 9081da177e4SLinus Torvalds } 9091da177e4SLinus Torvalds 9101da177e4SLinus Torvalds static void vortex_a3d_unregister_controls(vortex_t * vortex) 9111da177e4SLinus Torvalds { 9121da177e4SLinus Torvalds 9131da177e4SLinus Torvalds } 9141da177e4SLinus Torvalds 9151da177e4SLinus Torvalds /* End of File*/ 916