au88x0_a3d.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  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 absorption. */
  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. /*
  411. printk(KERN_DEBUG "vortex: ZeroState slice: %d, source %d\n",
  412. a->slice, a->source);
  413. */
  414. a3dsrc_SetAtmosState(a, 0, 0, 0, 0);
  415. a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros);
  416. a3dsrc_SetItdDline(a, A3dItdDlineZeros);
  417. a3dsrc_SetHrtfOutput(a, 0, 0);
  418. a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
  419. a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0);
  420. a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0);
  421. a3dsrc_SetItdCurrent(a, 0, 0);
  422. a3dsrc_SetItdTarget(a, 0, 0);
  423. a3dsrc_SetGainCurrent(a, 0, 0);
  424. a3dsrc_SetGainTarget(a, 0, 0);
  425. a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros);
  426. a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros);
  427. }
  428. /* Reset entire A3D engine */
  429. static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
  430. {
  431. int i, var, var2;
  432. if ((a->vortex) == NULL) {
  433. printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
  434. return;
  435. }
  436. a3dsrc_SetA3DControlReg(a, 0);
  437. a3dsrc_SetA3DPointerReg(a, 0);
  438. var = a->slice;
  439. var2 = a->source;
  440. for (i = 0; i < 4; i++) {
  441. a->slice = i;
  442. a3dsrc_ZeroSliceIO(a);
  443. //a3dsrc_ZeroState(a);
  444. }
  445. a->source = var2;
  446. a->slice = var;
  447. }
  448. /* Program A3D block as pass through */
  449. static void a3dsrc_ProgramPipe(a3dsrc_t * a)
  450. {
  451. a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
  452. a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0);
  453. a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0);
  454. a3dsrc_SetItdCurrent(a, 0, 0);
  455. a3dsrc_SetItdTarget(a, 0, 0);
  456. a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff);
  457. a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff);
  458. /* SET HRTF HERE */
  459. /* Single spike leads to identity transfer function. */
  460. a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse);
  461. a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse);
  462. /* Test: Sounds saturated. */
  463. //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest);
  464. //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest);
  465. }
  466. /* VDB = Vortex audio Dataflow Bus */
  467. #if 0
  468. static void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa)
  469. {
  470. vortex_t *vortex = (vortex_t *) (a->vortex);
  471. // ((aa >> 2) << 8) - (aa >> 2)
  472. hwwrite(vortex->mmio,
  473. a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0);
  474. hwwrite(vortex->mmio,
  475. a3d_addrS(a->slice,
  476. A3D_SLICE_VDBDest + 4) + (a->source << 2), 0);
  477. /*
  478. hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0);
  479. hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0);
  480. */
  481. }
  482. #endif
  483. /* A3D HwSource stuff. */
  484. static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice)
  485. {
  486. a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]);
  487. //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]);
  488. a3dsrc->vortex = (void *)v;
  489. a3dsrc->source = source; /* source */
  490. a3dsrc->slice = slice; /* slice */
  491. a3dsrc_ZeroState(a3dsrc);
  492. /* Added by me. */
  493. a3dsrc_SetA3DSampleRate(a3dsrc, 0x11);
  494. }
  495. static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
  496. {
  497. v->xt_mode = mode; /* this_14 */
  498. vortex_XtalkHw_init(v);
  499. vortex_XtalkHw_SetGainsAllChan(v);
  500. switch (v->xt_mode) {
  501. case XT_SPEAKER0:
  502. vortex_XtalkHw_ProgramXtalkNarrow(v);
  503. break;
  504. case XT_SPEAKER1:
  505. vortex_XtalkHw_ProgramXtalkWide(v);
  506. break;
  507. default:
  508. case XT_HEADPHONE:
  509. vortex_XtalkHw_ProgramPipe(v);
  510. break;
  511. case XT_DIAMOND:
  512. vortex_XtalkHw_ProgramDiamondXtalk(v);
  513. break;
  514. }
  515. vortex_XtalkHw_SetSampleRate(v, 0x11);
  516. vortex_XtalkHw_Enable(v);
  517. return 0;
  518. }
  519. /* 3D Sound entry points. */
  520. static int vortex_a3d_register_controls(vortex_t * vortex);
  521. static void vortex_a3d_unregister_controls(vortex_t * vortex);
  522. /* A3D base support init/shudown */
  523. static void __devinit vortex_Vort3D_enable(vortex_t * v)
  524. {
  525. int i;
  526. Vort3DRend_Initialize(v, XT_HEADPHONE);
  527. for (i = 0; i < NR_A3D; i++) {
  528. vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2);
  529. a3dsrc_ZeroStateA3D(&(v->a3d[0]));
  530. }
  531. /* Register ALSA controls */
  532. vortex_a3d_register_controls(v);
  533. }
  534. static void vortex_Vort3D_disable(vortex_t * v)
  535. {
  536. vortex_XtalkHw_Disable(v);
  537. vortex_a3d_unregister_controls(v);
  538. }
  539. /* Make A3D subsystem connections. */
  540. static void vortex_Vort3D_connect(vortex_t * v, int en)
  541. {
  542. int i;
  543. // Disable AU8810 routes, since they seem to be wrong (in au8810.h).
  544. #ifdef CHIP_AU8810
  545. return;
  546. #endif
  547. #if 1
  548. /* Alloc Xtalk mixin resources */
  549. v->mixxtlk[0] =
  550. vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
  551. if (v->mixxtlk[0] < 0) {
  552. printk
  553. ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
  554. return;
  555. }
  556. v->mixxtlk[1] =
  557. vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
  558. if (v->mixxtlk[1] < 0) {
  559. printk
  560. ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
  561. return;
  562. }
  563. #endif
  564. /* Connect A3D -> XTALK */
  565. for (i = 0; i < 4; i++) {
  566. // 2 outputs per each A3D slice.
  567. vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i));
  568. vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i));
  569. }
  570. #if 0
  571. vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2));
  572. vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3));
  573. #else
  574. /* Connect XTalk -> mixer */
  575. vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0]));
  576. vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1]));
  577. vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0);
  578. vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0);
  579. vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0],
  580. en ? MIX_DEFIGAIN : VOL_MIN);
  581. vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1],
  582. en ? MIX_DEFIGAIN : VOL_MIN);
  583. if (VORTEX_IS_QUAD(v)) {
  584. vortex_connection_mixin_mix(v, en, v->mixxtlk[0],
  585. v->mixplayb[2], 0);
  586. vortex_connection_mixin_mix(v, en, v->mixxtlk[1],
  587. v->mixplayb[3], 0);
  588. vortex_mix_setinputvolumebyte(v, v->mixplayb[2],
  589. v->mixxtlk[0],
  590. en ? MIX_DEFIGAIN : VOL_MIN);
  591. vortex_mix_setinputvolumebyte(v, v->mixplayb[3],
  592. v->mixxtlk[1],
  593. en ? MIX_DEFIGAIN : VOL_MIN);
  594. }
  595. #endif
  596. }
  597. /* Initialize one single A3D source. */
  598. static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en)
  599. {
  600. if (a->vortex == NULL) {
  601. printk
  602. ("vortex: Vort3D_InitializeSource: A3D source not initialized\n");
  603. return;
  604. }
  605. if (en) {
  606. a3dsrc_ProgramPipe(a);
  607. a3dsrc_SetA3DSampleRate(a, 0x11);
  608. a3dsrc_SetTimeConsts(a, HrtfTCDefault,
  609. ItdTCDefault, GainTCDefault,
  610. CoefTCDefault);
  611. /* Remark: zero gain is muted. */
  612. //a3dsrc_SetGainTarget(a,0,0);
  613. //a3dsrc_SetGainCurrent(a,0,0);
  614. a3dsrc_EnableA3D(a);
  615. } else {
  616. a3dsrc_DisableA3D(a);
  617. a3dsrc_ZeroState(a);
  618. }
  619. }
  620. /* Conversion of coordinates into 3D parameters. */
  621. static void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord)
  622. {
  623. /* FIXME: implement this. */
  624. }
  625. static void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord)
  626. {
  627. /* FIXME: implement this. */
  628. }
  629. static void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right)
  630. {
  631. /* FIXME: implement this. */
  632. }
  633. static void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params)
  634. {
  635. /* FIXME: implement this. */
  636. }
  637. /* ALSA control interface. */
  638. static int
  639. snd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  640. {
  641. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  642. uinfo->count = 6;
  643. uinfo->value.integer.min = 0x00000000;
  644. uinfo->value.integer.max = 0xffffffff;
  645. return 0;
  646. }
  647. static int
  648. snd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  649. {
  650. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  651. uinfo->count = 2;
  652. uinfo->value.integer.min = 0x00000000;
  653. uinfo->value.integer.max = 0xffffffff;
  654. return 0;
  655. }
  656. static int
  657. snd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  658. {
  659. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  660. uinfo->count = 2;
  661. uinfo->value.integer.min = 0x00000000;
  662. uinfo->value.integer.max = 0xffffffff;
  663. return 0;
  664. }
  665. static int
  666. snd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol,
  667. struct snd_ctl_elem_info *uinfo)
  668. {
  669. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  670. uinfo->count = 4;
  671. uinfo->value.integer.min = 0x00000000;
  672. uinfo->value.integer.max = 0xffffffff;
  673. return 0;
  674. }
  675. static int
  676. snd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  677. {
  678. //a3dsrc_t *a = kcontrol->private_data;
  679. /* No read yet. Would this be really useable/needed ? */
  680. return 0;
  681. }
  682. static int
  683. snd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol,
  684. struct snd_ctl_elem_value *ucontrol)
  685. {
  686. a3dsrc_t *a = kcontrol->private_data;
  687. int changed = 1, i;
  688. int coord[6];
  689. for (i = 0; i < 6; i++)
  690. coord[i] = ucontrol->value.integer.value[i];
  691. /* Translate orientation coordinates to a3d params. */
  692. vortex_a3d_coord2hrtf(a->hrtf[0], coord);
  693. vortex_a3d_coord2hrtf(a->hrtf[1], coord);
  694. a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]);
  695. a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]);
  696. return changed;
  697. }
  698. static int
  699. snd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol,
  700. struct snd_ctl_elem_value *ucontrol)
  701. {
  702. a3dsrc_t *a = kcontrol->private_data;
  703. int coord[6];
  704. int i, changed = 1;
  705. for (i = 0; i < 6; i++)
  706. coord[i] = ucontrol->value.integer.value[i];
  707. /* Translate orientation coordinates to a3d params. */
  708. vortex_a3d_coord2itd(a->hrtf[0], coord);
  709. vortex_a3d_coord2itd(a->hrtf[1], coord);
  710. /* Inter aural time difference. */
  711. a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]);
  712. a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]);
  713. a3dsrc_SetItdDline(a, a->dline);
  714. return changed;
  715. }
  716. static int
  717. snd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol,
  718. struct snd_ctl_elem_value *ucontrol)
  719. {
  720. a3dsrc_t *a = kcontrol->private_data;
  721. int changed = 1;
  722. int l, r;
  723. /* There may be some scale tranlation needed here. */
  724. l = ucontrol->value.integer.value[0];
  725. r = ucontrol->value.integer.value[1];
  726. vortex_a3d_coord2ild(a->ild, l, r);
  727. /* Left Right panning. */
  728. a3dsrc_SetGainTarget(a, l, r);
  729. a3dsrc_SetGainCurrent(a, l, r);
  730. return changed;
  731. }
  732. static int
  733. snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
  734. struct snd_ctl_elem_value *ucontrol)
  735. {
  736. a3dsrc_t *a = kcontrol->private_data;
  737. int i, changed = 1;
  738. int params[6];
  739. for (i = 0; i < 6; i++)
  740. params[i] = ucontrol->value.integer.value[i];
  741. /* Translate generic filter params to a3d filter params. */
  742. vortex_a3d_translate_filter(a->filter, params);
  743. /* Atmospheric absorption and filtering. */
  744. a3dsrc_SetAtmosTarget(a, a->filter[0],
  745. a->filter[1], a->filter[2],
  746. a->filter[3], a->filter[4]);
  747. a3dsrc_SetAtmosCurrent(a, a->filter[0],
  748. a->filter[1], a->filter[2],
  749. a->filter[3], a->filter[4]);
  750. return changed;
  751. }
  752. static struct snd_kcontrol_new vortex_a3d_kcontrol __devinitdata = {
  753. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  754. .name = "Playback PCM advanced processing",
  755. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
  756. .info = snd_vortex_a3d_hrtf_info,
  757. .get = snd_vortex_a3d_get,
  758. .put = snd_vortex_a3d_hrtf_put,
  759. };
  760. /* Control (un)registration. */
  761. static int __devinit vortex_a3d_register_controls(vortex_t * vortex)
  762. {
  763. struct snd_kcontrol *kcontrol;
  764. int err, i;
  765. /* HRTF controls. */
  766. for (i = 0; i < NR_A3D; i++) {
  767. if ((kcontrol =
  768. snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
  769. return -ENOMEM;
  770. kcontrol->id.numid = CTRLID_HRTF;
  771. kcontrol->info = snd_vortex_a3d_hrtf_info;
  772. kcontrol->put = snd_vortex_a3d_hrtf_put;
  773. if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
  774. return err;
  775. }
  776. /* ITD controls. */
  777. for (i = 0; i < NR_A3D; i++) {
  778. if ((kcontrol =
  779. snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
  780. return -ENOMEM;
  781. kcontrol->id.numid = CTRLID_ITD;
  782. kcontrol->info = snd_vortex_a3d_itd_info;
  783. kcontrol->put = snd_vortex_a3d_itd_put;
  784. if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
  785. return err;
  786. }
  787. /* ILD (gains) controls. */
  788. for (i = 0; i < NR_A3D; i++) {
  789. if ((kcontrol =
  790. snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
  791. return -ENOMEM;
  792. kcontrol->id.numid = CTRLID_GAINS;
  793. kcontrol->info = snd_vortex_a3d_ild_info;
  794. kcontrol->put = snd_vortex_a3d_ild_put;
  795. if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
  796. return err;
  797. }
  798. /* Filter controls. */
  799. for (i = 0; i < NR_A3D; i++) {
  800. if ((kcontrol =
  801. snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
  802. return -ENOMEM;
  803. kcontrol->id.numid = CTRLID_FILTER;
  804. kcontrol->info = snd_vortex_a3d_filter_info;
  805. kcontrol->put = snd_vortex_a3d_filter_put;
  806. if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
  807. return err;
  808. }
  809. return 0;
  810. }
  811. static void vortex_a3d_unregister_controls(vortex_t * vortex)
  812. {
  813. }
  814. /* End of File*/