au88x0_a3d.c 25 KB

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