pdaudiocf_pcm.c 7.6 KB

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