pdaudiocf_pcm.c 8.6 KB

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