root/sound/pci/au88x0/au88x0_a3d.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. a3dsrc_SetTimeConsts
  2. a3dsrc_GetTimeConsts
  3. a3dsrc_SetAtmosTarget
  4. a3dsrc_SetAtmosCurrent
  5. a3dsrc_SetAtmosState
  6. a3dsrc_GetAtmosTarget
  7. a3dsrc_GetAtmosCurrent
  8. a3dsrc_GetAtmosState
  9. a3dsrc_SetHrtfTarget
  10. a3dsrc_SetHrtfCurrent
  11. a3dsrc_SetHrtfState
  12. a3dsrc_SetHrtfOutput
  13. a3dsrc_GetHrtfTarget
  14. a3dsrc_GetHrtfCurrent
  15. a3dsrc_GetHrtfState
  16. a3dsrc_GetHrtfOutput
  17. a3dsrc_SetItdTarget
  18. a3dsrc_SetItdCurrent
  19. a3dsrc_SetItdDline
  20. a3dsrc_GetItdTarget
  21. a3dsrc_GetItdCurrent
  22. a3dsrc_GetItdDline
  23. a3dsrc_SetGainTarget
  24. a3dsrc_SetGainCurrent
  25. a3dsrc_GetGainTarget
  26. a3dsrc_GetGainCurrent
  27. CA3dIO_WriteReg
  28. a3dsrc_SetA3DSampleRate
  29. a3dsrc_EnableA3D
  30. a3dsrc_DisableA3D
  31. a3dsrc_SetA3DControlReg
  32. a3dsrc_SetA3DPointerReg
  33. a3dsrc_GetA3DSampleRate
  34. a3dsrc_GetA3DControlReg
  35. a3dsrc_GetA3DPointerReg
  36. a3dsrc_ZeroSliceIO
  37. a3dsrc_ZeroState
  38. a3dsrc_ZeroStateA3D
  39. a3dsrc_ProgramPipe
  40. a3dsrc_ClearVDBData
  41. vortex_A3dSourceHw_Initialize
  42. Vort3DRend_Initialize
  43. vortex_Vort3D_enable
  44. vortex_Vort3D_disable
  45. vortex_Vort3D_connect
  46. vortex_Vort3D_InitializeSource
  47. vortex_a3d_coord2hrtf
  48. vortex_a3d_coord2itd
  49. vortex_a3d_coord2ild
  50. vortex_a3d_translate_filter
  51. snd_vortex_a3d_hrtf_info
  52. snd_vortex_a3d_itd_info
  53. snd_vortex_a3d_ild_info
  54. snd_vortex_a3d_filter_info
  55. snd_vortex_a3d_get
  56. snd_vortex_a3d_hrtf_put
  57. snd_vortex_a3d_itd_put
  58. snd_vortex_a3d_ild_put
  59. snd_vortex_a3d_filter_put
  60. vortex_a3d_register_controls
  61. vortex_a3d_unregister_controls

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /***************************************************************************
   3  *            au88x0_a3d.c
   4  *
   5  *  Fri Jul 18 14:16:22 2003
   6  *  Copyright  2003  mjander
   7  *  mjander@users.sourceforge.net
   8  *
   9  * A3D. You may think i'm crazy, but this may work someday. Who knows...
  10  ****************************************************************************/
  11 
  12 /*
  13  */
  14 
  15 #include "au88x0_a3d.h"
  16 #include "au88x0_a3ddata.c"
  17 #include "au88x0_xtalk.h"
  18 #include "au88x0.h"
  19 
  20 static void
  21 a3dsrc_SetTimeConsts(a3dsrc_t * a, short HrtfTrack, short ItdTrack,
  22                      short GTrack, short CTrack)
  23 {
  24         vortex_t *vortex = (vortex_t *) (a->vortex);
  25         hwwrite(vortex->mmio,
  26                 a3d_addrA(a->slice, a->source, A3D_A_HrtfTrackTC), HrtfTrack);
  27         hwwrite(vortex->mmio,
  28                 a3d_addrA(a->slice, a->source, A3D_A_ITDTrackTC), ItdTrack);
  29         hwwrite(vortex->mmio,
  30                 a3d_addrA(a->slice, a->source, A3D_A_GainTrackTC), GTrack);
  31         hwwrite(vortex->mmio,
  32                 a3d_addrA(a->slice, a->source, A3D_A_CoeffTrackTC), CTrack);
  33 }
  34 
  35 #if 0
  36 static void
  37 a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack,
  38                      short *GTrack, short *CTrack)
  39 {
  40         // stub!
  41 }
  42 
  43 #endif
  44 /* Atmospheric absorption. */
  45 
  46 static void
  47 a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d,
  48                       short e)
  49 {
  50         vortex_t *vortex = (vortex_t *) (a->vortex);
  51         hwwrite(vortex->mmio,
  52                 a3d_addrB(a->slice, a->source, A3D_B_A21Target),
  53                 (e << 0x10) | d);
  54         hwwrite(vortex->mmio,
  55                 a3d_addrB(a->slice, a->source, A3D_B_B10Target),
  56                 (b << 0x10) | aa);
  57         hwwrite(vortex->mmio,
  58                 a3d_addrB(a->slice, a->source, A3D_B_B2Target), c);
  59 }
  60 
  61 static void
  62 a3dsrc_SetAtmosCurrent(a3dsrc_t * a, short aa, short b, short c, short d,
  63                        short e)
  64 {
  65         vortex_t *vortex = (vortex_t *) (a->vortex);
  66         hwwrite(vortex->mmio,
  67                 a3d_addrB(a->slice, a->source, A3D_B_A12Current),
  68                 (e << 0x10) | d);
  69         hwwrite(vortex->mmio,
  70                 a3d_addrB(a->slice, a->source, A3D_B_B01Current),
  71                 (b << 0x10) | aa);
  72         hwwrite(vortex->mmio,
  73                 a3d_addrB(a->slice, a->source, A3D_B_B2Current), c);
  74 }
  75 
  76 static void
  77 a3dsrc_SetAtmosState(a3dsrc_t * a, short x1, short x2, short y1, short y2)
  78 {
  79         vortex_t *vortex = (vortex_t *) (a->vortex);
  80         hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x1), x1);
  81         hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x2), x2);
  82         hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y1), y1);
  83         hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y2), y2);
  84 }
  85 
  86 #if 0
  87 static void
  88 a3dsrc_GetAtmosTarget(a3dsrc_t * a, short *aa, short *b, short *c,
  89                       short *d, short *e)
  90 {
  91 }
  92 static void
  93 a3dsrc_GetAtmosCurrent(a3dsrc_t * a, short *bb01, short *ab01, short *b2,
  94                        short *aa12, short *ba12)
  95 {
  96         vortex_t *vortex = (vortex_t *) (a->vortex);
  97         *aa12 =
  98             hwread(vortex->mmio,
  99                    a3d_addrA(a->slice, a->source, A3D_A_A12Current));
 100         *ba12 =
 101             hwread(vortex->mmio,
 102                    a3d_addrB(a->slice, a->source, A3D_B_A12Current));
 103         *ab01 =
 104             hwread(vortex->mmio,
 105                    a3d_addrA(a->slice, a->source, A3D_A_B01Current));
 106         *bb01 =
 107             hwread(vortex->mmio,
 108                    a3d_addrB(a->slice, a->source, A3D_B_B01Current));
 109         *b2 =
 110             hwread(vortex->mmio,
 111                    a3d_addrA(a->slice, a->source, A3D_A_B2Current));
 112 }
 113 
 114 static void
 115 a3dsrc_GetAtmosState(a3dsrc_t * a, short *x1, short *x2, short *y1, short *y2)
 116 {
 117 
 118 }
 119 
 120 #endif
 121 /* HRTF */
 122 
 123 static void
 124 a3dsrc_SetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
 125 {
 126         vortex_t *vortex = (vortex_t *) (a->vortex);
 127         int i;
 128 
 129         for (i = 0; i < HRTF_SZ; i++)
 130                 hwwrite(vortex->mmio,
 131                         a3d_addrB(a->slice, a->source,
 132                                   A3D_B_HrtfTarget) + (i << 2),
 133                         (b[i] << 0x10) | aa[i]);
 134 }
 135 
 136 static void
 137 a3dsrc_SetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
 138 {
 139         vortex_t *vortex = (vortex_t *) (a->vortex);
 140         int i;
 141 
 142         for (i = 0; i < HRTF_SZ; i++)
 143                 hwwrite(vortex->mmio,
 144                         a3d_addrB(a->slice, a->source,
 145                                   A3D_B_HrtfCurrent) + (i << 2),
 146                         (b[i] << 0x10) | aa[i]);
 147 }
 148 
 149 static void
 150 a3dsrc_SetHrtfState(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
 151 {
 152         vortex_t *vortex = (vortex_t *) (a->vortex);
 153         int i;
 154 
 155         for (i = 0; i < HRTF_SZ; i++)
 156                 hwwrite(vortex->mmio,
 157                         a3d_addrB(a->slice, a->source,
 158                                   A3D_B_HrtfDelayLine) + (i << 2),
 159                         (b[i] << 0x10) | aa[i]);
 160 }
 161 
 162 static void a3dsrc_SetHrtfOutput(a3dsrc_t * a, short left, short right)
 163 {
 164         vortex_t *vortex = (vortex_t *) (a->vortex);
 165         hwwrite(vortex->mmio,
 166                 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL), left);
 167         hwwrite(vortex->mmio,
 168                 a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR), right);
 169 }
 170 
 171 #if 0
 172 static void a3dsrc_GetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
 173 {
 174         vortex_t *vortex = (vortex_t *) (a->vortex);
 175         int i;
 176 
 177         for (i = 0; i < HRTF_SZ; i++)
 178                 aa[i] =
 179                     hwread(vortex->mmio,
 180                            a3d_addrA(a->slice, a->source,
 181                                      A3D_A_HrtfTarget + (i << 2)));
 182         for (i = 0; i < HRTF_SZ; i++)
 183                 b[i] =
 184                     hwread(vortex->mmio,
 185                            a3d_addrB(a->slice, a->source,
 186                                      A3D_B_HrtfTarget + (i << 2)));
 187 }
 188 
 189 static void a3dsrc_GetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
 190 {
 191         vortex_t *vortex = (vortex_t *) (a->vortex);
 192         int i;
 193 
 194         for (i = 0; i < HRTF_SZ; i++)
 195                 aa[i] =
 196                     hwread(vortex->mmio,
 197                            a3d_addrA(a->slice, a->source,
 198                                      A3D_A_HrtfCurrent + (i << 2)));
 199         for (i = 0; i < HRTF_SZ; i++)
 200                 b[i] =
 201                     hwread(vortex->mmio,
 202                            a3d_addrB(a->slice, a->source,
 203                                      A3D_B_HrtfCurrent + (i << 2)));
 204 }
 205 
 206 static void a3dsrc_GetHrtfState(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
 207 {
 208         vortex_t *vortex = (vortex_t *) (a->vortex);
 209         int i;
 210         // FIXME: verify this!
 211         for (i = 0; i < HRTF_SZ; i++)
 212                 aa[i] =
 213                     hwread(vortex->mmio,
 214                            a3d_addrA(a->slice, a->source,
 215                                      A3D_A_HrtfDelayLine + (i << 2)));
 216         for (i = 0; i < HRTF_SZ; i++)
 217                 b[i] =
 218                     hwread(vortex->mmio,
 219                            a3d_addrB(a->slice, a->source,
 220                                      A3D_B_HrtfDelayLine + (i << 2)));
 221 }
 222 
 223 static void a3dsrc_GetHrtfOutput(a3dsrc_t * a, short *left, short *right)
 224 {
 225         vortex_t *vortex = (vortex_t *) (a->vortex);
 226         *left =
 227             hwread(vortex->mmio,
 228                    a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL));
 229         *right =
 230             hwread(vortex->mmio,
 231                    a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR));
 232 }
 233 
 234 #endif
 235 
 236 /* Interaural Time Difference. 
 237  * "The other main clue that humans use to locate sounds, is called 
 238  * Interaural Time Difference (ITD). The differences in distance from 
 239  * the sound source to a listeners ears means  that the sound will 
 240  * reach one ear slightly before the other....", found somewhere with google.*/
 241 static void a3dsrc_SetItdTarget(a3dsrc_t * a, short litd, short ritd)
 242 {
 243         vortex_t *vortex = (vortex_t *) (a->vortex);
 244 
 245         if (litd < 0)
 246                 litd = 0;
 247         if (litd > 0x57FF)
 248                 litd = 0x57FF;
 249         if (ritd < 0)
 250                 ritd = 0;
 251         if (ritd > 0x57FF)
 252                 ritd = 0x57FF;
 253         hwwrite(vortex->mmio,
 254                 a3d_addrB(a->slice, a->source, A3D_B_ITDTarget),
 255                 (ritd << 0x10) | litd);
 256         //hwwrite(vortex->mmio, addr(0x191DF+5, this04, this08), (ritd<<0x10)|litd);
 257 }
 258 
 259 static void a3dsrc_SetItdCurrent(a3dsrc_t * a, short litd, short ritd)
 260 {
 261         vortex_t *vortex = (vortex_t *) (a->vortex);
 262 
 263         if (litd < 0)
 264                 litd = 0;
 265         if (litd > 0x57FF)
 266                 litd = 0x57FF;
 267         if (ritd < 0)
 268                 ritd = 0;
 269         if (ritd > 0x57FF)
 270                 ritd = 0x57FF;
 271         hwwrite(vortex->mmio,
 272                 a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent),
 273                 (ritd << 0x10) | litd);
 274         //hwwrite(vortex->mmio, addr(0x191DF+1, this04, this08), (ritd<<0x10)|litd);
 275 }
 276 
 277 static void a3dsrc_SetItdDline(a3dsrc_t * a, a3d_ItdDline_t const dline)
 278 {
 279         vortex_t *vortex = (vortex_t *) (a->vortex);
 280         int i;
 281         /* 45 != 40 -> Check this ! */
 282         for (i = 0; i < DLINE_SZ; i++)
 283                 hwwrite(vortex->mmio,
 284                         a3d_addrA(a->slice, a->source,
 285                                   A3D_A_ITDDelayLine) + (i << 2), dline[i]);
 286 }
 287 
 288 #if 0
 289 static void a3dsrc_GetItdTarget(a3dsrc_t * a, short *litd, short *ritd)
 290 {
 291         vortex_t *vortex = (vortex_t *) (a->vortex);
 292         *ritd =
 293             hwread(vortex->mmio,
 294                    a3d_addrA(a->slice, a->source, A3D_A_ITDTarget));
 295         *litd =
 296             hwread(vortex->mmio,
 297                    a3d_addrB(a->slice, a->source, A3D_B_ITDTarget));
 298 }
 299 
 300 static void a3dsrc_GetItdCurrent(a3dsrc_t * a, short *litd, short *ritd)
 301 {
 302         vortex_t *vortex = (vortex_t *) (a->vortex);
 303 
 304         *ritd =
 305             hwread(vortex->mmio,
 306                    a3d_addrA(a->slice, a->source, A3D_A_ITDCurrent));
 307         *litd =
 308             hwread(vortex->mmio,
 309                    a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent));
 310 }
 311 
 312 static void a3dsrc_GetItdDline(a3dsrc_t * a, a3d_ItdDline_t dline)
 313 {
 314         vortex_t *vortex = (vortex_t *) (a->vortex);
 315         int i;
 316 
 317         for (i = 0; i < DLINE_SZ; i++)
 318                 dline[i] =
 319                     hwread(vortex->mmio,
 320                            a3d_addrA(a->slice, a->source,
 321                                      A3D_A_ITDDelayLine + (i << 2)));
 322 }
 323 
 324 #endif
 325 /* This is may be used for ILD Interaural Level Difference. */
 326 
 327 static void a3dsrc_SetGainTarget(a3dsrc_t * a, short left, short right)
 328 {
 329         vortex_t *vortex = (vortex_t *) (a->vortex);
 330         hwwrite(vortex->mmio,
 331                 a3d_addrB(a->slice, a->source, A3D_B_GainTarget),
 332                 (right << 0x10) | left);
 333 }
 334 
 335 static void a3dsrc_SetGainCurrent(a3dsrc_t * a, short left, short right)
 336 {
 337         vortex_t *vortex = (vortex_t *) (a->vortex);
 338         hwwrite(vortex->mmio,
 339                 a3d_addrB(a->slice, a->source, A3D_B_GainCurrent),
 340                 (right << 0x10) | left);
 341 }
 342 
 343 #if 0
 344 static void a3dsrc_GetGainTarget(a3dsrc_t * a, short *left, short *right)
 345 {
 346         vortex_t *vortex = (vortex_t *) (a->vortex);
 347         *right =
 348             hwread(vortex->mmio,
 349                    a3d_addrA(a->slice, a->source, A3D_A_GainTarget));
 350         *left =
 351             hwread(vortex->mmio,
 352                    a3d_addrB(a->slice, a->source, A3D_B_GainTarget));
 353 }
 354 
 355 static void a3dsrc_GetGainCurrent(a3dsrc_t * a, short *left, short *right)
 356 {
 357         vortex_t *vortex = (vortex_t *) (a->vortex);
 358         *right =
 359             hwread(vortex->mmio,
 360                    a3d_addrA(a->slice, a->source, A3D_A_GainCurrent));
 361         *left =
 362             hwread(vortex->mmio,
 363                    a3d_addrB(a->slice, a->source, A3D_B_GainCurrent));
 364 }
 365 
 366 /* CA3dIO this func seems to be inlined all over this place. */
 367 static void CA3dIO_WriteReg(a3dsrc_t * a, unsigned long addr, short aa, short b)
 368 {
 369         vortex_t *vortex = (vortex_t *) (a->vortex);
 370         hwwrite(vortex->mmio, addr, (aa << 0x10) | b);
 371 }
 372 
 373 #endif
 374 /* Generic A3D stuff */
 375 
 376 static void a3dsrc_SetA3DSampleRate(a3dsrc_t * a, int sr)
 377 {
 378         vortex_t *vortex = (vortex_t *) (a->vortex);
 379         int esp0 = 0;
 380 
 381         esp0 = (((esp0 & 0x7fffffff) | 0xB8000000) & 0x7) | ((sr & 0x1f) << 3);
 382         hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), esp0);
 383         //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), esp0);
 384 }
 385 
 386 static void a3dsrc_EnableA3D(a3dsrc_t * a)
 387 {
 388         vortex_t *vortex = (vortex_t *) (a->vortex);
 389         hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
 390                 0xF0000001);
 391         //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), 0xF0000001);
 392 }
 393 
 394 static void a3dsrc_DisableA3D(a3dsrc_t * a)
 395 {
 396         vortex_t *vortex = (vortex_t *) (a->vortex);
 397         hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
 398                 0xF0000000);
 399 }
 400 
 401 static void a3dsrc_SetA3DControlReg(a3dsrc_t * a, unsigned long ctrl)
 402 {
 403         vortex_t *vortex = (vortex_t *) (a->vortex);
 404         hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), ctrl);
 405 }
 406 
 407 static void a3dsrc_SetA3DPointerReg(a3dsrc_t * a, unsigned long ptr)
 408 {
 409         vortex_t *vortex = (vortex_t *) (a->vortex);
 410         hwwrite(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd), ptr);
 411 }
 412 
 413 #if 0
 414 static void a3dsrc_GetA3DSampleRate(a3dsrc_t * a, int *sr)
 415 {
 416         vortex_t *vortex = (vortex_t *) (a->vortex);
 417         *sr = ((hwread(vortex->mmio, A3D_SLICE_Control + (a->slice << 0xd))
 418                 >> 3) & 0x1f);
 419         //*sr = ((hwread(vortex->mmio, 0x19C38 + (this08<<0xd))>>3)&0x1f);
 420 }
 421 
 422 static void a3dsrc_GetA3DControlReg(a3dsrc_t * a, unsigned long *ctrl)
 423 {
 424         vortex_t *vortex = (vortex_t *) (a->vortex);
 425         *ctrl = hwread(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd));
 426 }
 427 
 428 static void a3dsrc_GetA3DPointerReg(a3dsrc_t * a, unsigned long *ptr)
 429 {
 430         vortex_t *vortex = (vortex_t *) (a->vortex);
 431         *ptr = hwread(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd));
 432 }
 433 
 434 #endif
 435 static void a3dsrc_ZeroSliceIO(a3dsrc_t * a)
 436 {
 437         vortex_t *vortex = (vortex_t *) (a->vortex);
 438         int i;
 439 
 440         for (i = 0; i < 8; i++)
 441                 hwwrite(vortex->mmio,
 442                         A3D_SLICE_VDBDest +
 443                         ((((a->slice) << 0xb) + i) << 2), 0);
 444         for (i = 0; i < 4; i++)
 445                 hwwrite(vortex->mmio,
 446                         A3D_SLICE_VDBSource +
 447                         ((((a->slice) << 0xb) + i) << 2), 0);
 448 }
 449 
 450 /* Reset Single A3D source. */
 451 static void a3dsrc_ZeroState(a3dsrc_t * a)
 452 {
 453         /*
 454         pr_debug( "vortex: ZeroState slice: %d, source %d\n",
 455                a->slice, a->source);
 456         */
 457         a3dsrc_SetAtmosState(a, 0, 0, 0, 0);
 458         a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros);
 459         a3dsrc_SetItdDline(a, A3dItdDlineZeros);
 460         a3dsrc_SetHrtfOutput(a, 0, 0);
 461         a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
 462 
 463         a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0);
 464         a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0);
 465         a3dsrc_SetItdCurrent(a, 0, 0);
 466         a3dsrc_SetItdTarget(a, 0, 0);
 467         a3dsrc_SetGainCurrent(a, 0, 0);
 468         a3dsrc_SetGainTarget(a, 0, 0);
 469 
 470         a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros);
 471         a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros);
 472 }
 473 
 474 /* Reset entire A3D engine */
 475 static void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v)
 476 {
 477         int i, var, var2;
 478 
 479         if ((a->vortex) == NULL) {
 480                 dev_err(v->card->dev,
 481                         "ZeroStateA3D: ERROR: a->vortex is NULL\n");
 482                 return;
 483         }
 484 
 485         a3dsrc_SetA3DControlReg(a, 0);
 486         a3dsrc_SetA3DPointerReg(a, 0);
 487 
 488         var = a->slice;
 489         var2 = a->source;
 490         for (i = 0; i < 4; i++) {
 491                 a->slice = i;
 492                 a3dsrc_ZeroSliceIO(a);
 493                 //a3dsrc_ZeroState(a);
 494         }
 495         a->source = var2;
 496         a->slice = var;
 497 }
 498 
 499 /* Program A3D block as pass through */
 500 static void a3dsrc_ProgramPipe(a3dsrc_t * a)
 501 {
 502         a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
 503         a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0);
 504         a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0);
 505         a3dsrc_SetItdCurrent(a, 0, 0);
 506         a3dsrc_SetItdTarget(a, 0, 0);
 507         a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff);
 508         a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff);
 509 
 510         /* SET HRTF HERE */
 511 
 512         /* Single spike leads to identity transfer function. */
 513         a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse);
 514         a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse);
 515 
 516         /* Test: Sounds saturated. */
 517         //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest);
 518         //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest);      
 519 }
 520 
 521 /* VDB = Vortex audio Dataflow Bus */
 522 #if 0
 523 static void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa)
 524 {
 525         vortex_t *vortex = (vortex_t *) (a->vortex);
 526 
 527         // ((aa >> 2) << 8) - (aa >> 2)
 528         hwwrite(vortex->mmio,
 529                 a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0);
 530         hwwrite(vortex->mmio,
 531                 a3d_addrS(a->slice,
 532                           A3D_SLICE_VDBDest + 4) + (a->source << 2), 0);
 533         /*
 534            hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0);
 535            hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0);
 536          */
 537 }
 538 #endif
 539 
 540 /* A3D HwSource stuff. */
 541 
 542 static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice)
 543 {
 544         a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]);
 545         //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]);
 546 
 547         a3dsrc->vortex = (void *)v;
 548         a3dsrc->source = source;        /* source */
 549         a3dsrc->slice = slice;  /* slice */
 550         a3dsrc_ZeroState(a3dsrc);
 551         /* Added by me. */
 552         a3dsrc_SetA3DSampleRate(a3dsrc, 0x11);
 553 }
 554 
 555 static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
 556 {
 557         v->xt_mode = mode;      /* this_14 */
 558 
 559         vortex_XtalkHw_init(v);
 560         vortex_XtalkHw_SetGainsAllChan(v);
 561         switch (v->xt_mode) {
 562         case XT_SPEAKER0:
 563                 vortex_XtalkHw_ProgramXtalkNarrow(v);
 564                 break;
 565         case XT_SPEAKER1:
 566                 vortex_XtalkHw_ProgramXtalkWide(v);
 567                 break;
 568         default:
 569         case XT_HEADPHONE:
 570                 vortex_XtalkHw_ProgramPipe(v);
 571                 break;
 572         case XT_DIAMOND:
 573                 vortex_XtalkHw_ProgramDiamondXtalk(v);
 574                 break;
 575         }
 576         vortex_XtalkHw_SetSampleRate(v, 0x11);
 577         vortex_XtalkHw_Enable(v);
 578         return 0;
 579 }
 580 
 581 /* 3D Sound entry points. */
 582 
 583 static int vortex_a3d_register_controls(vortex_t * vortex);
 584 static void vortex_a3d_unregister_controls(vortex_t * vortex);
 585 /* A3D base support init/shudown */
 586 static void vortex_Vort3D_enable(vortex_t *v)
 587 {
 588         int i;
 589 
 590         Vort3DRend_Initialize(v, XT_HEADPHONE);
 591         for (i = 0; i < NR_A3D; i++) {
 592                 vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2);
 593                 a3dsrc_ZeroStateA3D(&v->a3d[0], v);
 594         }
 595         /* Register ALSA controls */
 596         vortex_a3d_register_controls(v);
 597 }
 598 
 599 static void vortex_Vort3D_disable(vortex_t * v)
 600 {
 601         vortex_XtalkHw_Disable(v);
 602         vortex_a3d_unregister_controls(v);
 603 }
 604 
 605 /* Make A3D subsystem connections. */
 606 static void vortex_Vort3D_connect(vortex_t * v, int en)
 607 {
 608         int i;
 609         
 610 // Disable AU8810 routes, since they seem to be wrong (in au8810.h).
 611 #ifdef CHIP_AU8810
 612         return;
 613 #endif
 614         
 615 #if 1
 616         /* Alloc Xtalk mixin resources */
 617         v->mixxtlk[0] =
 618             vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
 619         if (v->mixxtlk[0] < 0) {
 620                 dev_warn(v->card->dev,
 621                          "vortex_Vort3D: ERROR: not enough free mixer resources.\n");
 622                 return;
 623         }
 624         v->mixxtlk[1] =
 625             vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
 626         if (v->mixxtlk[1] < 0) {
 627                 dev_warn(v->card->dev,
 628                          "vortex_Vort3D: ERROR: not enough free mixer resources.\n");
 629                 return;
 630         }
 631 #endif
 632 
 633         /* Connect A3D -> XTALK */
 634         for (i = 0; i < 4; i++) {
 635                 // 2 outputs per each A3D slice. 
 636                 vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i));
 637                 vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i));
 638         }
 639 #if 0
 640         vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2));
 641         vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3));
 642 #else
 643         /* Connect XTalk -> mixer */
 644         vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0]));
 645         vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1]));
 646         vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0);
 647         vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0);
 648         vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0],
 649                                       en ? MIX_DEFIGAIN : VOL_MIN);
 650         vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1],
 651                                       en ? MIX_DEFIGAIN : VOL_MIN);
 652         if (VORTEX_IS_QUAD(v)) {
 653                 vortex_connection_mixin_mix(v, en, v->mixxtlk[0],
 654                                             v->mixplayb[2], 0);
 655                 vortex_connection_mixin_mix(v, en, v->mixxtlk[1],
 656                                             v->mixplayb[3], 0);
 657                 vortex_mix_setinputvolumebyte(v, v->mixplayb[2],
 658                                               v->mixxtlk[0],
 659                                               en ? MIX_DEFIGAIN : VOL_MIN);
 660                 vortex_mix_setinputvolumebyte(v, v->mixplayb[3],
 661                                               v->mixxtlk[1],
 662                                               en ? MIX_DEFIGAIN : VOL_MIN);
 663         }
 664 #endif
 665 }
 666 
 667 /* Initialize one single A3D source. */
 668 static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v)
 669 {
 670         if (a->vortex == NULL) {
 671                 dev_warn(v->card->dev,
 672                          "Vort3D_InitializeSource: A3D source not initialized\n");
 673                 return;
 674         }
 675         if (en) {
 676                 a3dsrc_ProgramPipe(a);
 677                 a3dsrc_SetA3DSampleRate(a, 0x11);
 678                 a3dsrc_SetTimeConsts(a, HrtfTCDefault,
 679                                      ItdTCDefault, GainTCDefault,
 680                                      CoefTCDefault);
 681                 /* Remark: zero gain is muted. */
 682                 //a3dsrc_SetGainTarget(a,0,0);
 683                 //a3dsrc_SetGainCurrent(a,0,0);
 684                 a3dsrc_EnableA3D(a);
 685         } else {
 686                 a3dsrc_DisableA3D(a);
 687                 a3dsrc_ZeroState(a);
 688         }
 689 }
 690 
 691 /* Conversion of coordinates into 3D parameters. */
 692 
 693 static void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord)
 694 {
 695         /* FIXME: implement this. */
 696 
 697 }
 698 static void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord)
 699 {
 700         /* FIXME: implement this. */
 701 
 702 }
 703 static void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right)
 704 {
 705         /* FIXME: implement this. */
 706 
 707 }
 708 static void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params)
 709 {
 710         /* FIXME: implement this. */
 711 
 712 }
 713 
 714 /* ALSA control interface.  */
 715 
 716 static int
 717 snd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 718 {
 719         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 720         uinfo->count = 6;
 721         uinfo->value.integer.min = 0x00000000;
 722         uinfo->value.integer.max = 0xffffffff;
 723         return 0;
 724 }
 725 static int
 726 snd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 727 {
 728         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 729         uinfo->count = 2;
 730         uinfo->value.integer.min = 0x00000000;
 731         uinfo->value.integer.max = 0xffffffff;
 732         return 0;
 733 }
 734 static int
 735 snd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 736 {
 737         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 738         uinfo->count = 2;
 739         uinfo->value.integer.min = 0x00000000;
 740         uinfo->value.integer.max = 0xffffffff;
 741         return 0;
 742 }
 743 static int
 744 snd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol,
 745                            struct snd_ctl_elem_info *uinfo)
 746 {
 747         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 748         uinfo->count = 4;
 749         uinfo->value.integer.min = 0x00000000;
 750         uinfo->value.integer.max = 0xffffffff;
 751         return 0;
 752 }
 753 
 754 static int
 755 snd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 756 {
 757         //a3dsrc_t *a = kcontrol->private_data;
 758         /* No read yet. Would this be really useable/needed ? */
 759 
 760         return 0;
 761 }
 762 
 763 static int
 764 snd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol,
 765                         struct snd_ctl_elem_value *ucontrol)
 766 {
 767         a3dsrc_t *a = kcontrol->private_data;
 768         int i;
 769         int coord[6];
 770         for (i = 0; i < 6; i++)
 771                 coord[i] = ucontrol->value.integer.value[i];
 772         /* Translate orientation coordinates to a3d params. */
 773         vortex_a3d_coord2hrtf(a->hrtf[0], coord);
 774         vortex_a3d_coord2hrtf(a->hrtf[1], coord);
 775         a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]);
 776         a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]);
 777         return 1;
 778 }
 779 
 780 static int
 781 snd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol,
 782                        struct snd_ctl_elem_value *ucontrol)
 783 {
 784         a3dsrc_t *a = kcontrol->private_data;
 785         int coord[6];
 786         int i;
 787         for (i = 0; i < 6; i++)
 788                 coord[i] = ucontrol->value.integer.value[i];
 789         /* Translate orientation coordinates to a3d params. */
 790         vortex_a3d_coord2itd(a->hrtf[0], coord);
 791         vortex_a3d_coord2itd(a->hrtf[1], coord);
 792         /* Inter aural time difference. */
 793         a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]);
 794         a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]);
 795         a3dsrc_SetItdDline(a, a->dline);
 796         return 1;
 797 }
 798 
 799 static int
 800 snd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol,
 801                        struct snd_ctl_elem_value *ucontrol)
 802 {
 803         a3dsrc_t *a = kcontrol->private_data;
 804         int l, r;
 805         /* There may be some scale tranlation needed here. */
 806         l = ucontrol->value.integer.value[0];
 807         r = ucontrol->value.integer.value[1];
 808         vortex_a3d_coord2ild(a->ild, l, r);
 809         /* Left Right panning. */
 810         a3dsrc_SetGainTarget(a, l, r);
 811         a3dsrc_SetGainCurrent(a, l, r);
 812         return 1;
 813 }
 814 
 815 static int
 816 snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
 817                           struct snd_ctl_elem_value *ucontrol)
 818 {
 819         a3dsrc_t *a = kcontrol->private_data;
 820         int i;
 821         int params[6];
 822         for (i = 0; i < 6; i++)
 823                 params[i] = ucontrol->value.integer.value[i];
 824         /* Translate generic filter params to a3d filter params. */
 825         vortex_a3d_translate_filter(a->filter, params);
 826         /* Atmospheric absorption and filtering. */
 827         a3dsrc_SetAtmosTarget(a, a->filter[0],
 828                               a->filter[1], a->filter[2],
 829                               a->filter[3], a->filter[4]);
 830         a3dsrc_SetAtmosCurrent(a, a->filter[0],
 831                                a->filter[1], a->filter[2],
 832                                a->filter[3], a->filter[4]);
 833         return 1;
 834 }
 835 
 836 static const struct snd_kcontrol_new vortex_a3d_kcontrol = {
 837         .iface = SNDRV_CTL_ELEM_IFACE_PCM,
 838         .name = "Playback PCM advanced processing",
 839         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 840         .info = snd_vortex_a3d_hrtf_info,
 841         .get = snd_vortex_a3d_get,
 842         .put = snd_vortex_a3d_hrtf_put,
 843 };
 844 
 845 /* Control (un)registration. */
 846 static int vortex_a3d_register_controls(vortex_t *vortex)
 847 {
 848         struct snd_kcontrol *kcontrol;
 849         int err, i;
 850         /* HRTF controls. */
 851         for (i = 0; i < NR_A3D; i++) {
 852                 if ((kcontrol =
 853                      snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
 854                         return -ENOMEM;
 855                 kcontrol->id.numid = CTRLID_HRTF;
 856                 kcontrol->info = snd_vortex_a3d_hrtf_info;
 857                 kcontrol->put = snd_vortex_a3d_hrtf_put;
 858                 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
 859                         return err;
 860         }
 861         /* ITD controls. */
 862         for (i = 0; i < NR_A3D; i++) {
 863                 if ((kcontrol =
 864                      snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
 865                         return -ENOMEM;
 866                 kcontrol->id.numid = CTRLID_ITD;
 867                 kcontrol->info = snd_vortex_a3d_itd_info;
 868                 kcontrol->put = snd_vortex_a3d_itd_put;
 869                 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
 870                         return err;
 871         }
 872         /* ILD (gains) controls. */
 873         for (i = 0; i < NR_A3D; i++) {
 874                 if ((kcontrol =
 875                      snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
 876                         return -ENOMEM;
 877                 kcontrol->id.numid = CTRLID_GAINS;
 878                 kcontrol->info = snd_vortex_a3d_ild_info;
 879                 kcontrol->put = snd_vortex_a3d_ild_put;
 880                 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
 881                         return err;
 882         }
 883         /* Filter controls. */
 884         for (i = 0; i < NR_A3D; i++) {
 885                 if ((kcontrol =
 886                      snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
 887                         return -ENOMEM;
 888                 kcontrol->id.numid = CTRLID_FILTER;
 889                 kcontrol->info = snd_vortex_a3d_filter_info;
 890                 kcontrol->put = snd_vortex_a3d_filter_put;
 891                 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
 892                         return err;
 893         }
 894         return 0;
 895 }
 896 
 897 static void vortex_a3d_unregister_controls(vortex_t * vortex)
 898 {
 899 
 900 }
 901 
 902 /* End of File*/

/* [<][>][^][v][top][bottom][index][help] */