pdaudiocf_pcm.c 7.6 KB

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