cardwi.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. **********************************************************************
  3. * cardwi.c - PCM input HAL for emu10k1 driver
  4. * Copyright 1999, 2000 Creative Labs, Inc.
  5. *
  6. **********************************************************************
  7. *
  8. * Date Author Summary of changes
  9. * ---- ------ ------------------
  10. * October 20, 1999 Bertrand Lee base code release
  11. *
  12. **********************************************************************
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public
  25. * License along with this program; if not, write to the Free
  26. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  27. * USA.
  28. *
  29. **********************************************************************
  30. */
  31. #include <linux/poll.h>
  32. #include "hwaccess.h"
  33. #include "timer.h"
  34. #include "recmgr.h"
  35. #include "audio.h"
  36. #include "cardwi.h"
  37. /**
  38. * query_format - returns a valid sound format
  39. *
  40. * This function will return a valid sound format as close
  41. * to the requested one as possible.
  42. */
  43. static void query_format(int recsrc, struct wave_format *wave_fmt)
  44. {
  45. switch (recsrc) {
  46. case WAVERECORD_AC97:
  47. if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
  48. wave_fmt->channels = 2;
  49. if (wave_fmt->samplingrate >= (0xBB80 + 0xAC44) / 2)
  50. wave_fmt->samplingrate = 0xBB80;
  51. else if (wave_fmt->samplingrate >= (0xAC44 + 0x7D00) / 2)
  52. wave_fmt->samplingrate = 0xAC44;
  53. else if (wave_fmt->samplingrate >= (0x7D00 + 0x5DC0) / 2)
  54. wave_fmt->samplingrate = 0x7D00;
  55. else if (wave_fmt->samplingrate >= (0x5DC0 + 0x5622) / 2)
  56. wave_fmt->samplingrate = 0x5DC0;
  57. else if (wave_fmt->samplingrate >= (0x5622 + 0x3E80) / 2)
  58. wave_fmt->samplingrate = 0x5622;
  59. else if (wave_fmt->samplingrate >= (0x3E80 + 0x2B11) / 2)
  60. wave_fmt->samplingrate = 0x3E80;
  61. else if (wave_fmt->samplingrate >= (0x2B11 + 0x1F40) / 2)
  62. wave_fmt->samplingrate = 0x2B11;
  63. else
  64. wave_fmt->samplingrate = 0x1F40;
  65. switch (wave_fmt->id) {
  66. case AFMT_S16_LE:
  67. wave_fmt->bitsperchannel = 16;
  68. break;
  69. case AFMT_U8:
  70. wave_fmt->bitsperchannel = 8;
  71. break;
  72. default:
  73. wave_fmt->id = AFMT_S16_LE;
  74. wave_fmt->bitsperchannel = 16;
  75. break;
  76. }
  77. break;
  78. /* these can't be changed from the original values */
  79. case WAVERECORD_MIC:
  80. case WAVERECORD_FX:
  81. break;
  82. default:
  83. BUG();
  84. break;
  85. }
  86. wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
  87. wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
  88. wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
  89. wave_fmt->bytespervoicesample = wave_fmt->bytespersample;
  90. }
  91. static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
  92. {
  93. buffer->addr = pci_alloc_consistent(card->pci_dev, buffer->size * buffer->cov,
  94. &buffer->dma_handle);
  95. if (buffer->addr == NULL)
  96. return -1;
  97. return 0;
  98. }
  99. static void free_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
  100. {
  101. if (buffer->addr != NULL)
  102. pci_free_consistent(card->pci_dev, buffer->size * buffer->cov,
  103. buffer->addr, buffer->dma_handle);
  104. }
  105. int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
  106. {
  107. struct emu10k1_card *card = wave_dev->card;
  108. struct wiinst *wiinst = wave_dev->wiinst;
  109. struct wiinst **wiinst_tmp = NULL;
  110. u16 delay;
  111. unsigned long flags;
  112. DPF(2, "emu10k1_wavein_open()\n");
  113. switch (wiinst->recsrc) {
  114. case WAVERECORD_AC97:
  115. wiinst_tmp = &card->wavein.ac97;
  116. break;
  117. case WAVERECORD_MIC:
  118. wiinst_tmp = &card->wavein.mic;
  119. break;
  120. case WAVERECORD_FX:
  121. wiinst_tmp = &card->wavein.fx;
  122. break;
  123. default:
  124. BUG();
  125. break;
  126. }
  127. spin_lock_irqsave(&card->lock, flags);
  128. if (*wiinst_tmp != NULL) {
  129. spin_unlock_irqrestore(&card->lock, flags);
  130. return -1;
  131. }
  132. *wiinst_tmp = wiinst;
  133. spin_unlock_irqrestore(&card->lock, flags);
  134. /* handle 8 bit recording */
  135. if (wiinst->format.bytesperchannel == 1) {
  136. if (wiinst->buffer.size > 0x8000) {
  137. wiinst->buffer.size = 0x8000;
  138. wiinst->buffer.sizeregval = 0x1f;
  139. } else
  140. wiinst->buffer.sizeregval += 4;
  141. wiinst->buffer.cov = 2;
  142. } else
  143. wiinst->buffer.cov = 1;
  144. if (alloc_buffer(card, &wiinst->buffer) < 0) {
  145. ERROR();
  146. return -1;
  147. }
  148. emu10k1_set_record_src(card, wiinst);
  149. emu10k1_reset_record(card, &wiinst->buffer);
  150. wiinst->buffer.hw_pos = 0;
  151. wiinst->buffer.pos = 0;
  152. wiinst->buffer.bytestocopy = 0;
  153. delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
  154. emu10k1_timer_install(card, &wiinst->timer, delay / 2);
  155. wiinst->state = WAVE_STATE_OPEN;
  156. return 0;
  157. }
  158. void emu10k1_wavein_close(struct emu10k1_wavedevice *wave_dev)
  159. {
  160. struct emu10k1_card *card = wave_dev->card;
  161. struct wiinst *wiinst = wave_dev->wiinst;
  162. unsigned long flags;
  163. DPF(2, "emu10k1_wavein_close()\n");
  164. emu10k1_wavein_stop(wave_dev);
  165. emu10k1_timer_uninstall(card, &wiinst->timer);
  166. free_buffer(card, &wiinst->buffer);
  167. spin_lock_irqsave(&card->lock, flags);
  168. switch (wave_dev->wiinst->recsrc) {
  169. case WAVERECORD_AC97:
  170. card->wavein.ac97 = NULL;
  171. break;
  172. case WAVERECORD_MIC:
  173. card->wavein.mic = NULL;
  174. break;
  175. case WAVERECORD_FX:
  176. card->wavein.fx = NULL;
  177. break;
  178. default:
  179. BUG();
  180. break;
  181. }
  182. spin_unlock_irqrestore(&card->lock, flags);
  183. wiinst->state = WAVE_STATE_CLOSED;
  184. }
  185. void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
  186. {
  187. struct emu10k1_card *card = wave_dev->card;
  188. struct wiinst *wiinst = wave_dev->wiinst;
  189. DPF(2, "emu10k1_wavein_start()\n");
  190. emu10k1_start_record(card, &wiinst->buffer);
  191. emu10k1_timer_enable(wave_dev->card, &wiinst->timer);
  192. wiinst->state |= WAVE_STATE_STARTED;
  193. }
  194. void emu10k1_wavein_stop(struct emu10k1_wavedevice *wave_dev)
  195. {
  196. struct emu10k1_card *card = wave_dev->card;
  197. struct wiinst *wiinst = wave_dev->wiinst;
  198. DPF(2, "emu10k1_wavein_stop()\n");
  199. if (!(wiinst->state & WAVE_STATE_STARTED))
  200. return;
  201. emu10k1_timer_disable(card, &wiinst->timer);
  202. emu10k1_stop_record(card, &wiinst->buffer);
  203. wiinst->state &= ~WAVE_STATE_STARTED;
  204. }
  205. int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
  206. {
  207. struct emu10k1_card *card = wave_dev->card;
  208. struct wiinst *wiinst = wave_dev->wiinst;
  209. u16 delay;
  210. DPF(2, "emu10k1_wavein_setformat()\n");
  211. if (wiinst->state & WAVE_STATE_STARTED)
  212. return -1;
  213. query_format(wiinst->recsrc, format);
  214. if ((wiinst->format.samplingrate != format->samplingrate)
  215. || (wiinst->format.bitsperchannel != format->bitsperchannel)
  216. || (wiinst->format.channels != format->channels)) {
  217. wiinst->format = *format;
  218. if (wiinst->state == WAVE_STATE_CLOSED)
  219. return 0;
  220. wiinst->buffer.size *= wiinst->buffer.cov;
  221. if (wiinst->format.bytesperchannel == 1) {
  222. wiinst->buffer.cov = 2;
  223. wiinst->buffer.size /= wiinst->buffer.cov;
  224. } else
  225. wiinst->buffer.cov = 1;
  226. emu10k1_timer_uninstall(card, &wiinst->timer);
  227. delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
  228. emu10k1_timer_install(card, &wiinst->timer, delay / 2);
  229. }
  230. return 0;
  231. }
  232. void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
  233. {
  234. struct wavein_buffer *buffer = &wiinst->buffer;
  235. *size = buffer->bytestocopy;
  236. if (wiinst->mmapped)
  237. return;
  238. if (*size > buffer->size) {
  239. *size = buffer->size;
  240. buffer->pos = buffer->hw_pos;
  241. buffer->bytestocopy = buffer->size;
  242. DPF(1, "buffer overrun\n");
  243. }
  244. }
  245. static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov)
  246. {
  247. if (cov == 1)
  248. __copy_to_user(dst, src + str, len);
  249. else {
  250. u8 byte;
  251. u32 i;
  252. src += 1 + 2 * str;
  253. for (i = 0; i < len; i++) {
  254. byte = src[2 * i] ^ 0x80;
  255. __copy_to_user(dst + i, &byte, 1);
  256. }
  257. }
  258. }
  259. void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size)
  260. {
  261. struct wavein_buffer *buffer = &wiinst->buffer;
  262. u32 sizetocopy, sizetocopy_now, start;
  263. unsigned long flags;
  264. sizetocopy = min_t(u32, buffer->size, *size);
  265. *size = sizetocopy;
  266. if (!sizetocopy)
  267. return;
  268. spin_lock_irqsave(&wiinst->lock, flags);
  269. start = buffer->pos;
  270. buffer->pos += sizetocopy;
  271. buffer->pos %= buffer->size;
  272. buffer->bytestocopy -= sizetocopy;
  273. sizetocopy_now = buffer->size - start;
  274. spin_unlock_irqrestore(&wiinst->lock, flags);
  275. if (sizetocopy > sizetocopy_now) {
  276. sizetocopy -= sizetocopy_now;
  277. copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov);
  278. copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov);
  279. } else {
  280. copy_block(data, buffer->addr, start, sizetocopy, buffer->cov);
  281. }
  282. }
  283. void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst)
  284. {
  285. u32 hw_pos;
  286. u32 diff;
  287. /* There is no actual start yet */
  288. if (!(wiinst->state & WAVE_STATE_STARTED)) {
  289. hw_pos = wiinst->buffer.hw_pos;
  290. } else {
  291. /* hw_pos in byte units */
  292. hw_pos = sblive_readptr(card, wiinst->buffer.idxreg, 0) / wiinst->buffer.cov;
  293. }
  294. diff = (wiinst->buffer.size + hw_pos - wiinst->buffer.hw_pos) % wiinst->buffer.size;
  295. wiinst->total_recorded += diff;
  296. wiinst->buffer.bytestocopy += diff;
  297. wiinst->buffer.hw_pos = hw_pos;
  298. }