pdaudiocf_pcm.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Driver for Sound Core PDAudioCF soundcards
  3. *
  4. * PCM part
  5. *
  6. * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #include <sound/driver.h>
  23. #include <linux/slab.h>
  24. #include <linux/vmalloc.h>
  25. #include <linux/delay.h>
  26. #include <sound/core.h>
  27. #include <sound/asoundef.h>
  28. #include "pdaudiocf.h"
  29. /*
  30. * we use a vmalloc'ed (sg-)buffer
  31. */
  32. /* get the physical page pointer on the given offset */
  33. static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs, unsigned long offset)
  34. {
  35. void *pageptr = subs->runtime->dma_area + offset;
  36. return vmalloc_to_page(pageptr);
  37. }
  38. /*
  39. * hw_params callback
  40. * NOTE: this may be called not only once per pcm open!
  41. */
  42. static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
  43. {
  44. snd_pcm_runtime_t *runtime = subs->runtime;
  45. if (runtime->dma_area) {
  46. if (runtime->dma_bytes >= size)
  47. return 0; /* already enough large */
  48. vfree_nocheck(runtime->dma_area);
  49. }
  50. runtime->dma_area = vmalloc_nocheck(size);
  51. if (! runtime->dma_area)
  52. return -ENOMEM;
  53. runtime->dma_bytes = size;
  54. return 0;
  55. }
  56. /*
  57. * hw_free callback
  58. * NOTE: this may be called not only once per pcm open!
  59. */
  60. static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
  61. {
  62. snd_pcm_runtime_t *runtime = subs->runtime;
  63. if (runtime->dma_area) {
  64. vfree_nocheck(runtime->dma_area);
  65. runtime->dma_area = NULL;
  66. }
  67. return 0;
  68. }
  69. /*
  70. * clear the SRAM contents
  71. */
  72. static int pdacf_pcm_clear_sram(pdacf_t *chip)
  73. {
  74. int max_loop = 64 * 1024;
  75. while (inw(chip->port + PDAUDIOCF_REG_RDP) != inw(chip->port + PDAUDIOCF_REG_WDP)) {
  76. if (max_loop-- < 0)
  77. return -EIO;
  78. inw(chip->port + PDAUDIOCF_REG_MD);
  79. }
  80. return 0;
  81. }
  82. /*
  83. * pdacf_pcm_trigger - trigger callback for capture
  84. */
  85. static int pdacf_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
  86. {
  87. pdacf_t *chip = snd_pcm_substream_chip(subs);
  88. snd_pcm_runtime_t *runtime = subs->runtime;
  89. int inc, ret = 0, rate;
  90. unsigned short mask, val, tmp;
  91. if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
  92. return -EBUSY;
  93. switch (cmd) {
  94. case SNDRV_PCM_TRIGGER_START:
  95. chip->pcm_hwptr = 0;
  96. chip->pcm_tdone = 0;
  97. /* fall thru */
  98. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  99. case SNDRV_PCM_TRIGGER_RESUME:
  100. mask = 0;
  101. val = PDAUDIOCF_RECORD;
  102. inc = 1;
  103. rate = snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_STAT|AK4117_CHECK_NO_RATE);
  104. break;
  105. case SNDRV_PCM_TRIGGER_STOP:
  106. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  107. case SNDRV_PCM_TRIGGER_SUSPEND:
  108. mask = PDAUDIOCF_RECORD;
  109. val = 0;
  110. inc = -1;
  111. rate = 0;
  112. break;
  113. default:
  114. return -EINVAL;
  115. }
  116. spin_lock(&chip->reg_lock);
  117. chip->pcm_running += inc;
  118. tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
  119. if (chip->pcm_running) {
  120. if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) {
  121. chip->pcm_running -= inc;
  122. ret = -EIO;
  123. goto __end;
  124. }
  125. }
  126. tmp &= ~mask;
  127. tmp |= val;
  128. pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp);
  129. __end:
  130. spin_unlock(&chip->reg_lock);
  131. snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_RATE);
  132. return ret;
  133. }
  134. /*
  135. * pdacf_pcm_hw_params - hw_params callback for playback and capture
  136. */
  137. static int pdacf_pcm_hw_params(snd_pcm_substream_t *subs,
  138. snd_pcm_hw_params_t *hw_params)
  139. {
  140. return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
  141. }
  142. /*
  143. * pdacf_pcm_hw_free - hw_free callback for playback and capture
  144. */
  145. static int pdacf_pcm_hw_free(snd_pcm_substream_t *subs)
  146. {
  147. return snd_pcm_free_vmalloc_buffer(subs);
  148. }
  149. /*
  150. * pdacf_pcm_prepare - prepare callback for playback and capture
  151. */
  152. static int pdacf_pcm_prepare(snd_pcm_substream_t *subs)
  153. {
  154. pdacf_t *chip = snd_pcm_substream_chip(subs);
  155. snd_pcm_runtime_t *runtime = subs->runtime;
  156. u16 val, nval, aval;
  157. if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
  158. return -EBUSY;
  159. chip->pcm_channels = runtime->channels;
  160. chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0;
  161. #ifdef SNDRV_LITTLE_ENDIAN
  162. chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0;
  163. #else
  164. chip->pcm_swab = chip->pcm_little;
  165. #endif
  166. if (snd_pcm_format_unsigned(runtime->format))
  167. chip->pcm_xor = 0x80008000;
  168. if (pdacf_pcm_clear_sram(chip) < 0)
  169. return -EIO;
  170. val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
  171. nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1);
  172. switch (runtime->format) {
  173. case SNDRV_PCM_FORMAT_S16_LE:
  174. case SNDRV_PCM_FORMAT_S16_BE:
  175. break;
  176. default: /* 24-bit */
  177. nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1;
  178. break;
  179. }
  180. aval = 0;
  181. chip->pcm_sample = 4;
  182. switch (runtime->format) {
  183. case SNDRV_PCM_FORMAT_S16_LE:
  184. case SNDRV_PCM_FORMAT_S16_BE:
  185. aval = AK4117_DIF_16R;
  186. chip->pcm_frame = 2;
  187. chip->pcm_sample = 2;
  188. break;
  189. case SNDRV_PCM_FORMAT_S24_3LE:
  190. case SNDRV_PCM_FORMAT_S24_3BE:
  191. chip->pcm_sample = 3;
  192. /* fall trough */
  193. default: /* 24-bit */
  194. aval = AK4117_DIF_24R;
  195. chip->pcm_frame = 3;
  196. chip->pcm_xor &= 0xffff0000;
  197. break;
  198. }
  199. if (val != nval) {
  200. snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval);
  201. pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval);
  202. }
  203. val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER);
  204. val &= ~(PDAUDIOCF_IRQLVLEN1);
  205. val |= PDAUDIOCF_IRQLVLEN0;
  206. pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val);
  207. chip->pcm_size = runtime->buffer_size;
  208. chip->pcm_period = runtime->period_size;
  209. chip->pcm_area = runtime->dma_area;
  210. return 0;
  211. }
  212. /*
  213. * capture hw information
  214. */
  215. static snd_pcm_hardware_t pdacf_pcm_capture_hw = {
  216. .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  217. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
  218. SNDRV_PCM_INFO_MMAP_VALID),
  219. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
  220. SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
  221. SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
  222. .rates = SNDRV_PCM_RATE_32000 |
  223. SNDRV_PCM_RATE_44100 |
  224. SNDRV_PCM_RATE_48000 |
  225. SNDRV_PCM_RATE_88200 |
  226. SNDRV_PCM_RATE_96000 |
  227. SNDRV_PCM_RATE_176400 |
  228. SNDRV_PCM_RATE_192000,
  229. .rate_min = 32000,
  230. .rate_max = 192000,
  231. .channels_min = 1,
  232. .channels_max = 2,
  233. .buffer_bytes_max = (512*1024),
  234. .period_bytes_min = 8*1024,
  235. .period_bytes_max = (64*1024),
  236. .periods_min = 2,
  237. .periods_max = 128,
  238. .fifo_size = 0,
  239. };
  240. /*
  241. * pdacf_pcm_capture_open - open callback for capture
  242. */
  243. static int pdacf_pcm_capture_open(snd_pcm_substream_t *subs)
  244. {
  245. snd_pcm_runtime_t *runtime = subs->runtime;
  246. pdacf_t *chip = snd_pcm_substream_chip(subs);
  247. if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
  248. return -EBUSY;
  249. runtime->hw = pdacf_pcm_capture_hw;
  250. runtime->private_data = chip;
  251. chip->pcm_substream = subs;
  252. return 0;
  253. }
  254. /*
  255. * pdacf_pcm_capture_close - close callback for capture
  256. */
  257. static int pdacf_pcm_capture_close(snd_pcm_substream_t *subs)
  258. {
  259. pdacf_t *chip = snd_pcm_substream_chip(subs);
  260. if (!chip)
  261. return -EINVAL;
  262. pdacf_reinit(chip, 0);
  263. chip->pcm_substream = NULL;
  264. return 0;
  265. }
  266. /*
  267. * pdacf_pcm_capture_pointer - pointer callback for capture
  268. */
  269. static snd_pcm_uframes_t pdacf_pcm_capture_pointer(snd_pcm_substream_t *subs)
  270. {
  271. pdacf_t *chip = snd_pcm_substream_chip(subs);
  272. return chip->pcm_hwptr;
  273. }
  274. /*
  275. * operators for PCM capture
  276. */
  277. static snd_pcm_ops_t pdacf_pcm_capture_ops = {
  278. .open = pdacf_pcm_capture_open,
  279. .close = pdacf_pcm_capture_close,
  280. .ioctl = snd_pcm_lib_ioctl,
  281. .hw_params = pdacf_pcm_hw_params,
  282. .hw_free = pdacf_pcm_hw_free,
  283. .prepare = pdacf_pcm_prepare,
  284. .trigger = pdacf_pcm_trigger,
  285. .pointer = pdacf_pcm_capture_pointer,
  286. .page = snd_pcm_get_vmalloc_page,
  287. };
  288. /*
  289. * free callback for pcm
  290. */
  291. static void snd_pdacf_pcm_free(snd_pcm_t *pcm)
  292. {
  293. pdacf_t *chip = pcm->private_data;
  294. chip->pcm = NULL;
  295. }
  296. /*
  297. * snd_pdacf_pcm_new - create and initialize a pcm
  298. */
  299. int snd_pdacf_pcm_new(pdacf_t *chip)
  300. {
  301. snd_pcm_t *pcm;
  302. int err;
  303. err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm);
  304. if (err < 0)
  305. return err;
  306. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops);
  307. pcm->private_data = chip;
  308. pcm->private_free = snd_pdacf_pcm_free;
  309. pcm->info_flags = 0;
  310. strcpy(pcm->name, chip->card->shortname);
  311. chip->pcm = pcm;
  312. err = snd_ak4117_build(chip->ak4117, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
  313. if (err < 0)
  314. return err;
  315. return 0;
  316. }