au88x0_pcm.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU Library General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. /*
  17. * Vortex PCM ALSA driver.
  18. *
  19. * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
  20. * It remains stuck,and DMA transfers do not happen.
  21. */
  22. #include <sound/asoundef.h>
  23. #include <linux/time.h>
  24. #include <sound/core.h>
  25. #include <sound/pcm.h>
  26. #include <sound/pcm_params.h>
  27. #include "au88x0.h"
  28. #define VORTEX_PCM_TYPE(x) (x->name[40])
  29. /* hardware definition */
  30. static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
  31. .info =
  32. (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  33. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  34. SNDRV_PCM_INFO_MMAP_VALID),
  35. .formats =
  36. SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  37. SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
  38. .rates = SNDRV_PCM_RATE_CONTINUOUS,
  39. .rate_min = 5000,
  40. .rate_max = 48000,
  41. .channels_min = 1,
  42. .channels_max = 2,
  43. .buffer_bytes_max = 0x10000,
  44. .period_bytes_min = 0x20,
  45. .period_bytes_max = 0x1000,
  46. .periods_min = 2,
  47. .periods_max = 1024,
  48. };
  49. #ifndef CHIP_AU8820
  50. static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
  51. .info =
  52. (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  53. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  54. SNDRV_PCM_INFO_MMAP_VALID),
  55. .formats =
  56. SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  57. SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
  58. .rates = SNDRV_PCM_RATE_CONTINUOUS,
  59. .rate_min = 5000,
  60. .rate_max = 48000,
  61. .channels_min = 1,
  62. .channels_max = 1,
  63. .buffer_bytes_max = 0x10000,
  64. .period_bytes_min = 0x100,
  65. .period_bytes_max = 0x1000,
  66. .periods_min = 2,
  67. .periods_max = 64,
  68. };
  69. #endif
  70. static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
  71. .info =
  72. (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
  73. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
  74. SNDRV_PCM_INFO_MMAP_VALID),
  75. .formats =
  76. SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
  77. SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
  78. SNDRV_PCM_FMTBIT_A_LAW,
  79. .rates =
  80. SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
  81. .rate_min = 32000,
  82. .rate_max = 48000,
  83. .channels_min = 1,
  84. .channels_max = 2,
  85. .buffer_bytes_max = 0x10000,
  86. .period_bytes_min = 0x100,
  87. .period_bytes_max = 0x1000,
  88. .periods_min = 2,
  89. .periods_max = 64,
  90. };
  91. #ifndef CHIP_AU8810
  92. static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
  93. .info = (SNDRV_PCM_INFO_MMAP |
  94. SNDRV_PCM_INFO_INTERLEAVED |
  95. SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
  96. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  97. .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, // SNDRV_PCM_RATE_48000,
  98. .rate_min = 8000,
  99. .rate_max = 48000,
  100. .channels_min = 1,
  101. .channels_max = 2,
  102. .buffer_bytes_max = 0x10000,
  103. .period_bytes_min = 0x0400,
  104. .period_bytes_max = 0x1000,
  105. .periods_min = 2,
  106. .periods_max = 64,
  107. };
  108. #endif
  109. #ifdef CHIP_AU8830
  110. static const unsigned int au8830_channels[3] = {
  111. 1, 2, 4,
  112. };
  113. static const struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
  114. .count = ARRAY_SIZE(au8830_channels),
  115. .list = au8830_channels,
  116. .mask = 0,
  117. };
  118. #endif
  119. static void vortex_notify_pcm_vol_change(struct snd_card *card,
  120. struct snd_kcontrol *kctl, int activate)
  121. {
  122. if (activate)
  123. kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
  124. else
  125. kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
  126. snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
  127. SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
  128. }
  129. /* open callback */
  130. static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
  131. {
  132. vortex_t *vortex = snd_pcm_substream_chip(substream);
  133. struct snd_pcm_runtime *runtime = substream->runtime;
  134. int err;
  135. /* Force equal size periods */
  136. if ((err =
  137. snd_pcm_hw_constraint_integer(runtime,
  138. SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
  139. return err;
  140. /* Avoid PAGE_SIZE boundary to fall inside of a period. */
  141. if ((err =
  142. snd_pcm_hw_constraint_pow2(runtime, 0,
  143. SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
  144. return err;
  145. snd_pcm_hw_constraint_step(runtime, 0,
  146. SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
  147. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  148. #ifndef CHIP_AU8820
  149. if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
  150. runtime->hw = snd_vortex_playback_hw_a3d;
  151. }
  152. #endif
  153. if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
  154. runtime->hw = snd_vortex_playback_hw_spdif;
  155. switch (vortex->spdif_sr) {
  156. case 32000:
  157. runtime->hw.rates = SNDRV_PCM_RATE_32000;
  158. break;
  159. case 44100:
  160. runtime->hw.rates = SNDRV_PCM_RATE_44100;
  161. break;
  162. case 48000:
  163. runtime->hw.rates = SNDRV_PCM_RATE_48000;
  164. break;
  165. }
  166. }
  167. if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
  168. || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
  169. runtime->hw = snd_vortex_playback_hw_adb;
  170. #ifdef CHIP_AU8830
  171. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
  172. VORTEX_IS_QUAD(vortex) &&
  173. VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
  174. runtime->hw.channels_max = 4;
  175. snd_pcm_hw_constraint_list(runtime, 0,
  176. SNDRV_PCM_HW_PARAM_CHANNELS,
  177. &hw_constraints_au8830_channels);
  178. }
  179. #endif
  180. substream->runtime->private_data = NULL;
  181. }
  182. #ifndef CHIP_AU8810
  183. else {
  184. runtime->hw = snd_vortex_playback_hw_wt;
  185. substream->runtime->private_data = NULL;
  186. }
  187. #endif
  188. return 0;
  189. }
  190. /* close callback */
  191. static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
  192. {
  193. //vortex_t *chip = snd_pcm_substream_chip(substream);
  194. stream_t *stream = (stream_t *) substream->runtime->private_data;
  195. // the hardware-specific codes will be here
  196. if (stream != NULL) {
  197. stream->substream = NULL;
  198. stream->nr_ch = 0;
  199. }
  200. substream->runtime->private_data = NULL;
  201. return 0;
  202. }
  203. /* hw_params callback */
  204. static int
  205. snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
  206. struct snd_pcm_hw_params *hw_params)
  207. {
  208. vortex_t *chip = snd_pcm_substream_chip(substream);
  209. stream_t *stream = (stream_t *) (substream->runtime->private_data);
  210. int err;
  211. // Alloc buffer memory.
  212. err =
  213. snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
  214. if (err < 0) {
  215. dev_err(chip->card->dev, "Vortex: pcm page alloc failed!\n");
  216. return err;
  217. }
  218. /*
  219. pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
  220. params_period_bytes(hw_params), params_channels(hw_params));
  221. */
  222. spin_lock_irq(&chip->lock);
  223. // Make audio routes and config buffer DMA.
  224. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  225. int dma, type = VORTEX_PCM_TYPE(substream->pcm);
  226. /* Dealloc any routes. */
  227. if (stream != NULL)
  228. vortex_adb_allocroute(chip, stream->dma,
  229. stream->nr_ch, stream->dir,
  230. stream->type,
  231. substream->number);
  232. /* Alloc routes. */
  233. dma =
  234. vortex_adb_allocroute(chip, -1,
  235. params_channels(hw_params),
  236. substream->stream, type,
  237. substream->number);
  238. if (dma < 0) {
  239. spin_unlock_irq(&chip->lock);
  240. return dma;
  241. }
  242. stream = substream->runtime->private_data = &chip->dma_adb[dma];
  243. stream->substream = substream;
  244. /* Setup Buffers. */
  245. vortex_adbdma_setbuffers(chip, dma,
  246. params_period_bytes(hw_params),
  247. params_periods(hw_params));
  248. if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
  249. chip->pcm_vol[substream->number].active = 1;
  250. vortex_notify_pcm_vol_change(chip->card,
  251. chip->pcm_vol[substream->number].kctl, 1);
  252. }
  253. }
  254. #ifndef CHIP_AU8810
  255. else {
  256. /* if (stream != NULL)
  257. vortex_wt_allocroute(chip, substream->number, 0); */
  258. vortex_wt_allocroute(chip, substream->number,
  259. params_channels(hw_params));
  260. stream = substream->runtime->private_data =
  261. &chip->dma_wt[substream->number];
  262. stream->dma = substream->number;
  263. stream->substream = substream;
  264. vortex_wtdma_setbuffers(chip, substream->number,
  265. params_period_bytes(hw_params),
  266. params_periods(hw_params));
  267. }
  268. #endif
  269. spin_unlock_irq(&chip->lock);
  270. return 0;
  271. }
  272. /* hw_free callback */
  273. static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
  274. {
  275. vortex_t *chip = snd_pcm_substream_chip(substream);
  276. stream_t *stream = (stream_t *) (substream->runtime->private_data);
  277. spin_lock_irq(&chip->lock);
  278. // Delete audio routes.
  279. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  280. if (stream != NULL) {
  281. if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
  282. chip->pcm_vol[substream->number].active = 0;
  283. vortex_notify_pcm_vol_change(chip->card,
  284. chip->pcm_vol[substream->number].kctl,
  285. 0);
  286. }
  287. vortex_adb_allocroute(chip, stream->dma,
  288. stream->nr_ch, stream->dir,
  289. stream->type,
  290. substream->number);
  291. }
  292. }
  293. #ifndef CHIP_AU8810
  294. else {
  295. if (stream != NULL)
  296. vortex_wt_allocroute(chip, stream->dma, 0);
  297. }
  298. #endif
  299. substream->runtime->private_data = NULL;
  300. spin_unlock_irq(&chip->lock);
  301. return snd_pcm_lib_free_pages(substream);
  302. }
  303. /* prepare callback */
  304. static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
  305. {
  306. vortex_t *chip = snd_pcm_substream_chip(substream);
  307. struct snd_pcm_runtime *runtime = substream->runtime;
  308. stream_t *stream = (stream_t *) substream->runtime->private_data;
  309. int dma = stream->dma, fmt, dir;
  310. // set up the hardware with the current configuration.
  311. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  312. dir = 1;
  313. else
  314. dir = 0;
  315. fmt = vortex_alsafmt_aspfmt(runtime->format, chip);
  316. spin_lock_irq(&chip->lock);
  317. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  318. vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
  319. runtime->channels == 1 ? 0 : 1, 0);
  320. vortex_adbdma_setstartbuffer(chip, dma, 0);
  321. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
  322. vortex_adb_setsrc(chip, dma, runtime->rate, dir);
  323. }
  324. #ifndef CHIP_AU8810
  325. else {
  326. vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
  327. // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
  328. vortex_wtdma_setstartbuffer(chip, dma, 0);
  329. }
  330. #endif
  331. spin_unlock_irq(&chip->lock);
  332. return 0;
  333. }
  334. /* trigger callback */
  335. static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  336. {
  337. vortex_t *chip = snd_pcm_substream_chip(substream);
  338. stream_t *stream = (stream_t *) substream->runtime->private_data;
  339. int dma = stream->dma;
  340. spin_lock(&chip->lock);
  341. switch (cmd) {
  342. case SNDRV_PCM_TRIGGER_START:
  343. // do something to start the PCM engine
  344. //printk(KERN_INFO "vortex: start %d\n", dma);
  345. stream->fifo_enabled = 1;
  346. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  347. vortex_adbdma_resetup(chip, dma);
  348. vortex_adbdma_startfifo(chip, dma);
  349. }
  350. #ifndef CHIP_AU8810
  351. else {
  352. dev_info(chip->card->dev, "wt start %d\n", dma);
  353. vortex_wtdma_startfifo(chip, dma);
  354. }
  355. #endif
  356. break;
  357. case SNDRV_PCM_TRIGGER_STOP:
  358. // do something to stop the PCM engine
  359. //printk(KERN_INFO "vortex: stop %d\n", dma);
  360. stream->fifo_enabled = 0;
  361. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
  362. vortex_adbdma_stopfifo(chip, dma);
  363. #ifndef CHIP_AU8810
  364. else {
  365. dev_info(chip->card->dev, "wt stop %d\n", dma);
  366. vortex_wtdma_stopfifo(chip, dma);
  367. }
  368. #endif
  369. break;
  370. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  371. //printk(KERN_INFO "vortex: pause %d\n", dma);
  372. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
  373. vortex_adbdma_pausefifo(chip, dma);
  374. #ifndef CHIP_AU8810
  375. else
  376. vortex_wtdma_pausefifo(chip, dma);
  377. #endif
  378. break;
  379. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  380. //printk(KERN_INFO "vortex: resume %d\n", dma);
  381. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
  382. vortex_adbdma_resumefifo(chip, dma);
  383. #ifndef CHIP_AU8810
  384. else
  385. vortex_wtdma_resumefifo(chip, dma);
  386. #endif
  387. break;
  388. default:
  389. spin_unlock(&chip->lock);
  390. return -EINVAL;
  391. }
  392. spin_unlock(&chip->lock);
  393. return 0;
  394. }
  395. /* pointer callback */
  396. static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
  397. {
  398. vortex_t *chip = snd_pcm_substream_chip(substream);
  399. stream_t *stream = (stream_t *) substream->runtime->private_data;
  400. int dma = stream->dma;
  401. snd_pcm_uframes_t current_ptr = 0;
  402. spin_lock(&chip->lock);
  403. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
  404. current_ptr = vortex_adbdma_getlinearpos(chip, dma);
  405. #ifndef CHIP_AU8810
  406. else
  407. current_ptr = vortex_wtdma_getlinearpos(chip, dma);
  408. #endif
  409. //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
  410. spin_unlock(&chip->lock);
  411. current_ptr = bytes_to_frames(substream->runtime, current_ptr);
  412. if (current_ptr >= substream->runtime->buffer_size)
  413. current_ptr = 0;
  414. return current_ptr;
  415. }
  416. /* operators */
  417. static const struct snd_pcm_ops snd_vortex_playback_ops = {
  418. .open = snd_vortex_pcm_open,
  419. .close = snd_vortex_pcm_close,
  420. .ioctl = snd_pcm_lib_ioctl,
  421. .hw_params = snd_vortex_pcm_hw_params,
  422. .hw_free = snd_vortex_pcm_hw_free,
  423. .prepare = snd_vortex_pcm_prepare,
  424. .trigger = snd_vortex_pcm_trigger,
  425. .pointer = snd_vortex_pcm_pointer,
  426. .page = snd_pcm_sgbuf_ops_page,
  427. };
  428. /*
  429. * definitions of capture are omitted here...
  430. */
  431. static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
  432. CARD_NAME " ADB",
  433. CARD_NAME " SPDIF",
  434. CARD_NAME " A3D",
  435. CARD_NAME " WT",
  436. CARD_NAME " I2S",
  437. };
  438. static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
  439. "adb",
  440. "spdif",
  441. "a3d",
  442. "wt",
  443. "i2s",
  444. };
  445. /* SPDIF kcontrol */
  446. static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  447. {
  448. uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  449. uinfo->count = 1;
  450. return 0;
  451. }
  452. static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  453. {
  454. ucontrol->value.iec958.status[0] = 0xff;
  455. ucontrol->value.iec958.status[1] = 0xff;
  456. ucontrol->value.iec958.status[2] = 0xff;
  457. ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
  458. return 0;
  459. }
  460. static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  461. {
  462. vortex_t *vortex = snd_kcontrol_chip(kcontrol);
  463. ucontrol->value.iec958.status[0] = 0x00;
  464. ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
  465. ucontrol->value.iec958.status[2] = 0x00;
  466. switch (vortex->spdif_sr) {
  467. case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
  468. case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
  469. case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
  470. }
  471. return 0;
  472. }
  473. static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  474. {
  475. vortex_t *vortex = snd_kcontrol_chip(kcontrol);
  476. int spdif_sr = 48000;
  477. switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
  478. case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
  479. case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
  480. case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
  481. }
  482. if (spdif_sr == vortex->spdif_sr)
  483. return 0;
  484. vortex->spdif_sr = spdif_sr;
  485. vortex_spdif_init(vortex, vortex->spdif_sr, 1);
  486. return 1;
  487. }
  488. /* spdif controls */
  489. static struct snd_kcontrol_new snd_vortex_mixer_spdif[] = {
  490. {
  491. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  492. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
  493. .info = snd_vortex_spdif_info,
  494. .get = snd_vortex_spdif_get,
  495. .put = snd_vortex_spdif_put,
  496. },
  497. {
  498. .access = SNDRV_CTL_ELEM_ACCESS_READ,
  499. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  500. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
  501. .info = snd_vortex_spdif_info,
  502. .get = snd_vortex_spdif_mask_get
  503. },
  504. };
  505. /* subdevice PCM Volume control */
  506. static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
  507. struct snd_ctl_elem_info *uinfo)
  508. {
  509. vortex_t *vortex = snd_kcontrol_chip(kcontrol);
  510. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  511. uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
  512. uinfo->value.integer.min = -128;
  513. uinfo->value.integer.max = 32;
  514. return 0;
  515. }
  516. static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
  517. struct snd_ctl_elem_value *ucontrol)
  518. {
  519. int i;
  520. vortex_t *vortex = snd_kcontrol_chip(kcontrol);
  521. int subdev = kcontrol->id.subdevice;
  522. struct pcm_vol *p = &vortex->pcm_vol[subdev];
  523. int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
  524. for (i = 0; i < max_chn; i++)
  525. ucontrol->value.integer.value[i] = p->vol[i];
  526. return 0;
  527. }
  528. static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
  529. struct snd_ctl_elem_value *ucontrol)
  530. {
  531. int i;
  532. int changed = 0;
  533. int mixin;
  534. unsigned char vol;
  535. vortex_t *vortex = snd_kcontrol_chip(kcontrol);
  536. int subdev = kcontrol->id.subdevice;
  537. struct pcm_vol *p = &vortex->pcm_vol[subdev];
  538. int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
  539. for (i = 0; i < max_chn; i++) {
  540. if (p->vol[i] != ucontrol->value.integer.value[i]) {
  541. p->vol[i] = ucontrol->value.integer.value[i];
  542. if (p->active) {
  543. switch (vortex->dma_adb[p->dma].nr_ch) {
  544. case 1:
  545. mixin = p->mixin[0];
  546. break;
  547. case 2:
  548. default:
  549. mixin = p->mixin[(i < 2) ? i : (i - 2)];
  550. break;
  551. case 4:
  552. mixin = p->mixin[i];
  553. break;
  554. }
  555. vol = p->vol[i];
  556. vortex_mix_setinputvolumebyte(vortex,
  557. vortex->mixplayb[i], mixin, vol);
  558. }
  559. changed = 1;
  560. }
  561. }
  562. return changed;
  563. }
  564. static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
  565. static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
  566. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  567. .name = "PCM Playback Volume",
  568. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
  569. SNDRV_CTL_ELEM_ACCESS_TLV_READ |
  570. SNDRV_CTL_ELEM_ACCESS_INACTIVE,
  571. .info = snd_vortex_pcm_vol_info,
  572. .get = snd_vortex_pcm_vol_get,
  573. .put = snd_vortex_pcm_vol_put,
  574. .tlv = { .p = vortex_pcm_vol_db_scale },
  575. };
  576. /* create a pcm device */
  577. static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
  578. {
  579. struct snd_pcm *pcm;
  580. struct snd_kcontrol *kctl;
  581. int i;
  582. int err, nr_capt;
  583. if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
  584. return -ENODEV;
  585. /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
  586. * same dma engine. WT uses it own separate dma engine which can't capture. */
  587. if (idx == VORTEX_PCM_ADB)
  588. nr_capt = nr;
  589. else
  590. nr_capt = 0;
  591. err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
  592. nr_capt, &pcm);
  593. if (err < 0)
  594. return err;
  595. snprintf(pcm->name, sizeof(pcm->name),
  596. "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
  597. chip->pcm[idx] = pcm;
  598. // This is an evil hack, but it saves a lot of duplicated code.
  599. VORTEX_PCM_TYPE(pcm) = idx;
  600. pcm->private_data = chip;
  601. /* set operators */
  602. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  603. &snd_vortex_playback_ops);
  604. if (idx == VORTEX_PCM_ADB)
  605. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  606. &snd_vortex_playback_ops);
  607. /* pre-allocation of Scatter-Gather buffers */
  608. snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
  609. snd_dma_pci_data(chip->pci_dev),
  610. 0x10000, 0x10000);
  611. switch (VORTEX_PCM_TYPE(pcm)) {
  612. case VORTEX_PCM_ADB:
  613. err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  614. snd_pcm_std_chmaps,
  615. VORTEX_IS_QUAD(chip) ? 4 : 2,
  616. 0, NULL);
  617. if (err < 0)
  618. return err;
  619. err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
  620. snd_pcm_std_chmaps, 2, 0, NULL);
  621. if (err < 0)
  622. return err;
  623. break;
  624. #ifdef CHIP_AU8830
  625. case VORTEX_PCM_A3D:
  626. err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  627. snd_pcm_std_chmaps, 1, 0, NULL);
  628. if (err < 0)
  629. return err;
  630. break;
  631. #endif
  632. }
  633. if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
  634. for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
  635. kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
  636. if (!kctl)
  637. return -ENOMEM;
  638. if ((err = snd_ctl_add(chip->card, kctl)) < 0)
  639. return err;
  640. }
  641. }
  642. if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
  643. for (i = 0; i < NR_PCM; i++) {
  644. chip->pcm_vol[i].active = 0;
  645. chip->pcm_vol[i].dma = -1;
  646. kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
  647. if (!kctl)
  648. return -ENOMEM;
  649. chip->pcm_vol[i].kctl = kctl;
  650. kctl->id.device = 0;
  651. kctl->id.subdevice = i;
  652. err = snd_ctl_add(chip->card, kctl);
  653. if (err < 0)
  654. return err;
  655. }
  656. }
  657. return 0;
  658. }