au88x0_a3d.c 25 KB

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