xref: /openbmc/linux/sound/pci/au88x0/au88x0_a3d.c (revision 70c84418)
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