[PATCH] mark struct file_operations const 9
[linux-2.6/verdex.git] / sound / oss / emu10k1 / audio.c
blobe75ea21eb8117fd67558b4d64328f18c806035be
1 /*
2 **********************************************************************
3 * audio.c -- /dev/dsp interface for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
6 **********************************************************************
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up types/leaks
13 **********************************************************************
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28 * USA.
30 **********************************************************************
33 #include <linux/module.h>
34 #include <linux/poll.h>
35 #include <linux/slab.h>
36 #include <linux/bitops.h>
37 #include <asm/io.h>
38 #include <linux/sched.h>
39 #include <linux/mm.h>
40 #include <linux/smp_lock.h>
42 #include "hwaccess.h"
43 #include "cardwo.h"
44 #include "cardwi.h"
45 #include "recmgr.h"
46 #include "irqmgr.h"
47 #include "audio.h"
48 #include "8010.h"
50 static void calculate_ofrag(struct woinst *);
51 static void calculate_ifrag(struct wiinst *);
53 static void emu10k1_waveout_bh(unsigned long refdata);
54 static void emu10k1_wavein_bh(unsigned long refdata);
56 /* Audio file operations */
57 static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
59 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
60 struct wiinst *wiinst = wave_dev->wiinst;
61 ssize_t ret = 0;
62 unsigned long flags;
64 DPD(3, "emu10k1_audio_read(), buffer=%p, count=%d\n", buffer, (u32) count);
66 if (!access_ok(VERIFY_WRITE, buffer, count))
67 return -EFAULT;
69 spin_lock_irqsave(&wiinst->lock, flags);
71 if (wiinst->mmapped) {
72 spin_unlock_irqrestore(&wiinst->lock, flags);
73 return -ENXIO;
76 if (wiinst->state == WAVE_STATE_CLOSED) {
77 calculate_ifrag(wiinst);
79 while (emu10k1_wavein_open(wave_dev) < 0) {
80 spin_unlock_irqrestore(&wiinst->lock, flags);
82 if (file->f_flags & O_NONBLOCK)
83 return -EAGAIN;
85 interruptible_sleep_on(&wave_dev->card->open_wait);
87 if (signal_pending(current))
88 return -ERESTARTSYS;
90 spin_lock_irqsave(&wiinst->lock, flags);
94 spin_unlock_irqrestore(&wiinst->lock, flags);
96 while (count > 0) {
97 u32 bytestocopy;
99 spin_lock_irqsave(&wiinst->lock, flags);
101 if (!(wiinst->state & WAVE_STATE_STARTED)
102 && (wave_dev->enablebits & PCM_ENABLE_INPUT))
103 emu10k1_wavein_start(wave_dev);
105 emu10k1_wavein_update(wave_dev->card, wiinst);
106 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
108 spin_unlock_irqrestore(&wiinst->lock, flags);
110 DPD(3, "bytestocopy --> %d\n", bytestocopy);
112 if ((bytestocopy >= wiinst->buffer.fragment_size)
113 || (bytestocopy >= count)) {
114 int rc;
116 bytestocopy = min_t(u32, bytestocopy, count);
118 rc = emu10k1_wavein_xferdata(wiinst,
119 (u8 __user *)buffer,
120 &bytestocopy);
121 if (rc)
122 return rc;
124 count -= bytestocopy;
125 buffer += bytestocopy;
126 ret += bytestocopy;
129 if (count > 0) {
130 if ((file->f_flags & O_NONBLOCK)
131 || (!(wave_dev->enablebits & PCM_ENABLE_INPUT)))
132 return (ret ? ret : -EAGAIN);
134 interruptible_sleep_on(&wiinst->wait_queue);
136 if (signal_pending(current))
137 return (ret ? ret : -ERESTARTSYS);
142 DPD(3, "bytes copied -> %d\n", (u32) ret);
144 return ret;
147 static ssize_t emu10k1_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
149 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
150 struct woinst *woinst = wave_dev->woinst;
151 ssize_t ret;
152 unsigned long flags;
154 DPD(3, "emu10k1_audio_write(), buffer=%p, count=%d\n", buffer, (u32) count);
156 if (!access_ok(VERIFY_READ, buffer, count))
157 return -EFAULT;
159 spin_lock_irqsave(&woinst->lock, flags);
161 if (woinst->mmapped) {
162 spin_unlock_irqrestore(&woinst->lock, flags);
163 return -ENXIO;
165 // This is for emu10k1 revs less than 7, we need to go through tram
166 if (woinst->format.passthrough == 1) {
167 int r;
169 woinst->buffer.ossfragshift = PT_BLOCKSIZE_LOG2;
170 woinst->buffer.numfrags = PT_BLOCKCOUNT;
171 calculate_ofrag(woinst);
173 r = emu10k1_pt_write(file, buffer, count);
174 spin_unlock_irqrestore(&woinst->lock, flags);
175 return r;
178 if (woinst->state == WAVE_STATE_CLOSED) {
179 calculate_ofrag(woinst);
181 while (emu10k1_waveout_open(wave_dev) < 0) {
182 spin_unlock_irqrestore(&woinst->lock, flags);
184 if (file->f_flags & O_NONBLOCK)
185 return -EAGAIN;
187 interruptible_sleep_on(&wave_dev->card->open_wait);
189 if (signal_pending(current))
190 return -ERESTARTSYS;
192 spin_lock_irqsave(&woinst->lock, flags);
196 spin_unlock_irqrestore(&woinst->lock, flags);
198 ret = 0;
199 if (count % woinst->format.bytespersample)
200 return -EINVAL;
202 count /= woinst->num_voices;
204 while (count > 0) {
205 u32 bytestocopy;
207 spin_lock_irqsave(&woinst->lock, flags);
208 emu10k1_waveout_update(woinst);
209 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
210 spin_unlock_irqrestore(&woinst->lock, flags);
212 DPD(3, "bytestocopy --> %d\n", bytestocopy);
214 if ((bytestocopy >= woinst->buffer.fragment_size)
215 || (bytestocopy >= count)) {
217 bytestocopy = min_t(u32, bytestocopy, count);
219 emu10k1_waveout_xferdata(woinst, (u8 __user *) buffer, &bytestocopy);
221 count -= bytestocopy;
222 buffer += bytestocopy * woinst->num_voices;
223 ret += bytestocopy * woinst->num_voices;
225 spin_lock_irqsave(&woinst->lock, flags);
226 woinst->total_copied += bytestocopy;
228 if (!(woinst->state & WAVE_STATE_STARTED)
229 && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
230 && (woinst->total_copied >= woinst->buffer.fragment_size))
231 emu10k1_waveout_start(wave_dev);
233 spin_unlock_irqrestore(&woinst->lock, flags);
236 if (count > 0) {
237 if ((file->f_flags & O_NONBLOCK)
238 || (!(wave_dev->enablebits & PCM_ENABLE_OUTPUT)))
239 return (ret ? ret : -EAGAIN);
241 interruptible_sleep_on(&woinst->wait_queue);
243 if (signal_pending(current))
244 return (ret ? ret : -ERESTARTSYS);
248 DPD(3, "bytes copied -> %d\n", (u32) ret);
250 return ret;
253 static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
255 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
256 struct woinst *woinst = NULL;
257 struct wiinst *wiinst = NULL;
258 int val = 0;
259 u32 bytestocopy;
260 unsigned long flags;
261 int __user *p = (int __user *)arg;
263 DPF(4, "emu10k1_audio_ioctl()\n");
265 if (file->f_mode & FMODE_WRITE)
266 woinst = wave_dev->woinst;
268 if (file->f_mode & FMODE_READ)
269 wiinst = wave_dev->wiinst;
271 switch (cmd) {
272 case OSS_GETVERSION:
273 DPF(2, "OSS_GETVERSION:\n");
274 return put_user(SOUND_VERSION, p);
276 case SNDCTL_DSP_RESET:
277 DPF(2, "SNDCTL_DSP_RESET:\n");
278 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
280 if (file->f_mode & FMODE_WRITE) {
281 spin_lock_irqsave(&woinst->lock, flags);
283 if (woinst->state & WAVE_STATE_OPEN) {
284 emu10k1_waveout_close(wave_dev);
287 woinst->mmapped = 0;
288 woinst->total_copied = 0;
289 woinst->total_played = 0;
290 woinst->blocks = 0;
292 spin_unlock_irqrestore(&woinst->lock, flags);
295 if (file->f_mode & FMODE_READ) {
296 spin_lock_irqsave(&wiinst->lock, flags);
298 if (wiinst->state & WAVE_STATE_OPEN) {
299 emu10k1_wavein_close(wave_dev);
302 wiinst->mmapped = 0;
303 wiinst->total_recorded = 0;
304 wiinst->blocks = 0;
305 spin_unlock_irqrestore(&wiinst->lock, flags);
308 break;
310 case SNDCTL_DSP_SYNC:
311 DPF(2, "SNDCTL_DSP_SYNC:\n");
313 if (file->f_mode & FMODE_WRITE) {
315 spin_lock_irqsave(&woinst->lock, flags);
317 if (woinst->state & WAVE_STATE_OPEN) {
319 if (woinst->state & WAVE_STATE_STARTED)
320 while ((woinst->total_played < woinst->total_copied)
321 && !signal_pending(current)) {
322 spin_unlock_irqrestore(&woinst->lock, flags);
323 interruptible_sleep_on(&woinst->wait_queue);
324 spin_lock_irqsave(&woinst->lock, flags);
326 emu10k1_waveout_close(wave_dev);
329 woinst->mmapped = 0;
330 woinst->total_copied = 0;
331 woinst->total_played = 0;
332 woinst->blocks = 0;
334 spin_unlock_irqrestore(&woinst->lock, flags);
337 if (file->f_mode & FMODE_READ) {
338 spin_lock_irqsave(&wiinst->lock, flags);
340 if (wiinst->state & WAVE_STATE_OPEN) {
341 emu10k1_wavein_close(wave_dev);
344 wiinst->mmapped = 0;
345 wiinst->total_recorded = 0;
346 wiinst->blocks = 0;
347 spin_unlock_irqrestore(&wiinst->lock, flags);
350 break;
352 case SNDCTL_DSP_SETDUPLEX:
353 DPF(2, "SNDCTL_DSP_SETDUPLEX:\n");
354 break;
356 case SNDCTL_DSP_GETCAPS:
357 DPF(2, "SNDCTL_DSP_GETCAPS:\n");
358 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
359 DSP_CAP_TRIGGER | DSP_CAP_MMAP |
360 DSP_CAP_COPROC| DSP_CAP_MULTI, p);
361 case SNDCTL_DSP_SPEED:
362 DPF(2, "SNDCTL_DSP_SPEED:\n");
364 if (get_user(val, p))
365 return -EFAULT;
367 DPD(2, "val is %d\n", val);
369 if (val > 0) {
370 if (file->f_mode & FMODE_READ) {
371 struct wave_format format;
373 spin_lock_irqsave(&wiinst->lock, flags);
375 format = wiinst->format;
376 format.samplingrate = val;
378 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
379 spin_unlock_irqrestore(&wiinst->lock, flags);
380 return -EINVAL;
383 val = wiinst->format.samplingrate;
385 spin_unlock_irqrestore(&wiinst->lock, flags);
387 DPD(2, "set recording sampling rate -> %d\n", val);
390 if (file->f_mode & FMODE_WRITE) {
391 struct wave_format format;
393 spin_lock_irqsave(&woinst->lock, flags);
395 format = woinst->format;
396 format.samplingrate = val;
398 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
399 spin_unlock_irqrestore(&woinst->lock, flags);
400 return -EINVAL;
403 val = woinst->format.samplingrate;
405 spin_unlock_irqrestore(&woinst->lock, flags);
407 DPD(2, "set playback sampling rate -> %d\n", val);
410 return put_user(val, p);
411 } else {
412 if (file->f_mode & FMODE_READ)
413 val = wiinst->format.samplingrate;
414 else if (file->f_mode & FMODE_WRITE)
415 val = woinst->format.samplingrate;
417 return put_user(val, p);
419 break;
421 case SNDCTL_DSP_STEREO:
422 DPF(2, "SNDCTL_DSP_STEREO:\n");
424 if (get_user(val, p))
425 return -EFAULT;
427 DPD(2, " val is %d\n", val);
429 if (file->f_mode & FMODE_READ) {
430 struct wave_format format;
432 spin_lock_irqsave(&wiinst->lock, flags);
434 format = wiinst->format;
435 format.channels = val ? 2 : 1;
437 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
438 spin_unlock_irqrestore(&wiinst->lock, flags);
439 return -EINVAL;
442 val = wiinst->format.channels - 1;
444 spin_unlock_irqrestore(&wiinst->lock, flags);
445 DPD(2, "set recording stereo -> %d\n", val);
448 if (file->f_mode & FMODE_WRITE) {
449 struct wave_format format;
451 spin_lock_irqsave(&woinst->lock, flags);
453 format = woinst->format;
454 format.channels = val ? 2 : 1;
456 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
457 spin_unlock_irqrestore(&woinst->lock, flags);
458 return -EINVAL;
461 val = woinst->format.channels - 1;
463 spin_unlock_irqrestore(&woinst->lock, flags);
465 DPD(2, "set playback stereo -> %d\n", val);
468 return put_user(val, p);
470 break;
472 case SNDCTL_DSP_CHANNELS:
473 DPF(2, "SNDCTL_DSP_CHANNELS:\n");
475 if (get_user(val, p))
476 return -EFAULT;
478 DPD(2, " val is %d\n", val);
480 if (val > 0) {
481 if (file->f_mode & FMODE_READ) {
482 struct wave_format format;
484 spin_lock_irqsave(&wiinst->lock, flags);
486 format = wiinst->format;
487 format.channels = val;
489 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
490 spin_unlock_irqrestore(&wiinst->lock, flags);
491 return -EINVAL;
493 val = wiinst->format.channels;
495 spin_unlock_irqrestore(&wiinst->lock, flags);
496 DPD(2, "set recording number of channels -> %d\n", val);
499 if (file->f_mode & FMODE_WRITE) {
500 struct wave_format format;
502 spin_lock_irqsave(&woinst->lock, flags);
504 format = woinst->format;
505 format.channels = val;
507 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
508 spin_unlock_irqrestore(&woinst->lock, flags);
509 return -EINVAL;
512 val = woinst->format.channels;
514 spin_unlock_irqrestore(&woinst->lock, flags);
515 DPD(2, "set playback number of channels -> %d\n", val);
518 return put_user(val, p);
519 } else {
520 if (file->f_mode & FMODE_READ)
521 val = wiinst->format.channels;
522 else if (file->f_mode & FMODE_WRITE)
523 val = woinst->format.channels;
525 return put_user(val, p);
527 break;
529 case SNDCTL_DSP_GETFMTS:
530 DPF(2, "SNDCTL_DSP_GETFMTS:\n");
532 if (file->f_mode & FMODE_READ)
533 val = AFMT_S16_LE;
534 else if (file->f_mode & FMODE_WRITE) {
535 val = AFMT_S16_LE | AFMT_U8;
536 if (emu10k1_find_control_gpr(&wave_dev->card->mgr,
537 wave_dev->card->pt.patch_name,
538 wave_dev->card->pt.enable_gpr_name) >= 0)
539 val |= AFMT_AC3;
541 return put_user(val, p);
543 case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
544 DPF(2, "SNDCTL_DSP_SETFMT:\n");
546 if (get_user(val, p))
547 return -EFAULT;
549 DPD(2, " val is %d\n", val);
551 if (val != AFMT_QUERY) {
552 if (file->f_mode & FMODE_READ) {
553 struct wave_format format;
555 spin_lock_irqsave(&wiinst->lock, flags);
557 format = wiinst->format;
558 format.id = val;
560 if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
561 spin_unlock_irqrestore(&wiinst->lock, flags);
562 return -EINVAL;
565 val = wiinst->format.id;
567 spin_unlock_irqrestore(&wiinst->lock, flags);
568 DPD(2, "set recording format -> %d\n", val);
571 if (file->f_mode & FMODE_WRITE) {
572 struct wave_format format;
574 spin_lock_irqsave(&woinst->lock, flags);
576 format = woinst->format;
577 format.id = val;
579 if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
580 spin_unlock_irqrestore(&woinst->lock, flags);
581 return -EINVAL;
584 val = woinst->format.id;
586 spin_unlock_irqrestore(&woinst->lock, flags);
587 DPD(2, "set playback format -> %d\n", val);
590 return put_user(val, p);
591 } else {
592 if (file->f_mode & FMODE_READ)
593 val = wiinst->format.id;
594 else if (file->f_mode & FMODE_WRITE)
595 val = woinst->format.id;
597 return put_user(val, p);
599 break;
601 case SOUND_PCM_READ_BITS:
603 if (file->f_mode & FMODE_READ)
604 val = wiinst->format.bitsperchannel;
605 else if (file->f_mode & FMODE_WRITE)
606 val = woinst->format.bitsperchannel;
608 return put_user(val, p);
610 case SOUND_PCM_READ_RATE:
612 if (file->f_mode & FMODE_READ)
613 val = wiinst->format.samplingrate;
614 else if (file->f_mode & FMODE_WRITE)
615 val = woinst->format.samplingrate;
617 return put_user(val, p);
619 case SOUND_PCM_READ_CHANNELS:
621 if (file->f_mode & FMODE_READ)
622 val = wiinst->format.channels;
623 else if (file->f_mode & FMODE_WRITE)
624 val = woinst->format.channels;
626 return put_user(val, p);
628 case SOUND_PCM_WRITE_FILTER:
629 DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
630 break;
632 case SOUND_PCM_READ_FILTER:
633 DPF(2, "SOUND_PCM_READ_FILTER: not implemented\n");
634 break;
636 case SNDCTL_DSP_SETSYNCRO:
637 DPF(2, "SNDCTL_DSP_SETSYNCRO: not implemented\n");
638 break;
640 case SNDCTL_DSP_GETTRIGGER:
641 DPF(2, "SNDCTL_DSP_GETTRIGGER:\n");
643 if (file->f_mode & FMODE_WRITE && (wave_dev->enablebits & PCM_ENABLE_OUTPUT))
644 val |= PCM_ENABLE_OUTPUT;
646 if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
647 val |= PCM_ENABLE_INPUT;
649 return put_user(val, p);
651 case SNDCTL_DSP_SETTRIGGER:
652 DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
654 if (get_user(val, p))
655 return -EFAULT;
657 if (file->f_mode & FMODE_WRITE) {
658 spin_lock_irqsave(&woinst->lock, flags);
660 if (val & PCM_ENABLE_OUTPUT) {
661 wave_dev->enablebits |= PCM_ENABLE_OUTPUT;
662 if (woinst->state & WAVE_STATE_OPEN)
663 emu10k1_waveout_start(wave_dev);
664 } else {
665 wave_dev->enablebits &= ~PCM_ENABLE_OUTPUT;
666 if (woinst->state & WAVE_STATE_STARTED)
667 emu10k1_waveout_stop(wave_dev);
670 spin_unlock_irqrestore(&woinst->lock, flags);
673 if (file->f_mode & FMODE_READ) {
674 spin_lock_irqsave(&wiinst->lock, flags);
676 if (val & PCM_ENABLE_INPUT) {
677 wave_dev->enablebits |= PCM_ENABLE_INPUT;
678 if (wiinst->state & WAVE_STATE_OPEN)
679 emu10k1_wavein_start(wave_dev);
680 } else {
681 wave_dev->enablebits &= ~PCM_ENABLE_INPUT;
682 if (wiinst->state & WAVE_STATE_STARTED)
683 emu10k1_wavein_stop(wave_dev);
686 spin_unlock_irqrestore(&wiinst->lock, flags);
688 break;
690 case SNDCTL_DSP_GETOSPACE:
692 audio_buf_info info;
694 DPF(4, "SNDCTL_DSP_GETOSPACE:\n");
696 if (!(file->f_mode & FMODE_WRITE))
697 return -EINVAL;
699 spin_lock_irqsave(&woinst->lock, flags);
701 if (woinst->state & WAVE_STATE_OPEN) {
702 emu10k1_waveout_update(woinst);
703 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
704 info.bytes = bytestocopy;
705 } else {
706 calculate_ofrag(woinst);
707 info.bytes = woinst->buffer.size;
709 spin_unlock_irqrestore(&woinst->lock, flags);
711 info.bytes *= woinst->num_voices;
712 info.fragsize = woinst->buffer.fragment_size * woinst->num_voices;
713 info.fragstotal = woinst->buffer.numfrags * woinst->num_voices;
714 info.fragments = info.bytes / info.fragsize;
716 if (copy_to_user(p, &info, sizeof(info)))
717 return -EFAULT;
719 break;
721 case SNDCTL_DSP_GETISPACE:
723 audio_buf_info info;
725 DPF(4, "SNDCTL_DSP_GETISPACE:\n");
727 if (!(file->f_mode & FMODE_READ))
728 return -EINVAL;
730 spin_lock_irqsave(&wiinst->lock, flags);
731 if (wiinst->state & WAVE_STATE_OPEN) {
732 emu10k1_wavein_update(wave_dev->card, wiinst);
733 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
734 info.bytes = bytestocopy;
735 } else {
736 calculate_ifrag(wiinst);
737 info.bytes = 0;
739 spin_unlock_irqrestore(&wiinst->lock, flags);
741 info.fragstotal = wiinst->buffer.numfrags;
742 info.fragments = info.bytes / wiinst->buffer.fragment_size;
743 info.fragsize = wiinst->buffer.fragment_size;
745 if (copy_to_user(p, &info, sizeof(info)))
746 return -EFAULT;
748 break;
750 case SNDCTL_DSP_NONBLOCK:
751 DPF(2, "SNDCTL_DSP_NONBLOCK:\n");
753 file->f_flags |= O_NONBLOCK;
754 break;
756 case SNDCTL_DSP_GETODELAY:
757 DPF(4, "SNDCTL_DSP_GETODELAY:\n");
759 if (!(file->f_mode & FMODE_WRITE))
760 return -EINVAL;
762 spin_lock_irqsave(&woinst->lock, flags);
763 if (woinst->state & WAVE_STATE_OPEN) {
764 emu10k1_waveout_update(woinst);
765 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
766 val = woinst->buffer.size - bytestocopy;
767 } else
768 val = 0;
770 val *= woinst->num_voices;
771 spin_unlock_irqrestore(&woinst->lock, flags);
773 return put_user(val, p);
775 case SNDCTL_DSP_GETIPTR:
777 count_info cinfo;
779 DPF(4, "SNDCTL_DSP_GETIPTR: \n");
781 if (!(file->f_mode & FMODE_READ))
782 return -EINVAL;
784 spin_lock_irqsave(&wiinst->lock, flags);
786 if (wiinst->state & WAVE_STATE_OPEN) {
787 emu10k1_wavein_update(wave_dev->card, wiinst);
788 cinfo.ptr = wiinst->buffer.hw_pos;
789 cinfo.bytes = cinfo.ptr + wiinst->total_recorded - wiinst->total_recorded % wiinst->buffer.size;
790 cinfo.blocks = cinfo.bytes / wiinst->buffer.fragment_size - wiinst->blocks;
791 wiinst->blocks = cinfo.bytes / wiinst->buffer.fragment_size;
792 } else {
793 cinfo.ptr = 0;
794 cinfo.bytes = 0;
795 cinfo.blocks = 0;
798 if (wiinst->mmapped)
799 wiinst->buffer.bytestocopy %= wiinst->buffer.fragment_size;
801 spin_unlock_irqrestore(&wiinst->lock, flags);
803 if (copy_to_user(p, &cinfo, sizeof(cinfo)))
804 return -EFAULT;
806 break;
808 case SNDCTL_DSP_GETOPTR:
810 count_info cinfo;
812 DPF(4, "SNDCTL_DSP_GETOPTR:\n");
814 if (!(file->f_mode & FMODE_WRITE))
815 return -EINVAL;
817 spin_lock_irqsave(&woinst->lock, flags);
819 if (woinst->state & WAVE_STATE_OPEN ||
820 ((woinst->format.passthrough == 1) && wave_dev->card->pt.state)) {
821 int num_fragments;
823 if (woinst->format.passthrough == 1) {
824 emu10k1_pt_waveout_update(wave_dev);
825 cinfo.bytes = woinst->total_played;
826 } else {
827 emu10k1_waveout_update(woinst);
828 cinfo.bytes = woinst->total_played;
831 cinfo.ptr = woinst->buffer.hw_pos;
832 num_fragments = cinfo.bytes / woinst->buffer.fragment_size;
833 cinfo.blocks = num_fragments - woinst->blocks;
834 woinst->blocks = num_fragments;
836 cinfo.bytes *= woinst->num_voices;
837 cinfo.ptr *= woinst->num_voices;
838 } else {
839 cinfo.ptr = 0;
840 cinfo.bytes = 0;
841 cinfo.blocks = 0;
844 if (woinst->mmapped)
845 woinst->buffer.free_bytes %= woinst->buffer.fragment_size;
847 spin_unlock_irqrestore(&woinst->lock, flags);
849 if (copy_to_user(p, &cinfo, sizeof(cinfo)))
850 return -EFAULT;
852 break;
854 case SNDCTL_DSP_GETBLKSIZE:
855 DPF(2, "SNDCTL_DSP_GETBLKSIZE:\n");
857 if (file->f_mode & FMODE_WRITE) {
858 spin_lock_irqsave(&woinst->lock, flags);
860 calculate_ofrag(woinst);
861 val = woinst->buffer.fragment_size * woinst->num_voices;
863 spin_unlock_irqrestore(&woinst->lock, flags);
866 if (file->f_mode & FMODE_READ) {
867 spin_lock_irqsave(&wiinst->lock, flags);
869 calculate_ifrag(wiinst);
870 val = wiinst->buffer.fragment_size;
872 spin_unlock_irqrestore(&wiinst->lock, flags);
875 return put_user(val, p);
877 break;
879 case SNDCTL_DSP_POST:
880 if (file->f_mode & FMODE_WRITE) {
881 spin_lock_irqsave(&woinst->lock, flags);
883 if (!(woinst->state & WAVE_STATE_STARTED)
884 && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
885 && (woinst->total_copied > 0))
886 emu10k1_waveout_start(wave_dev);
888 spin_unlock_irqrestore(&woinst->lock, flags);
891 break;
893 case SNDCTL_DSP_SUBDIVIDE:
894 DPF(2, "SNDCTL_DSP_SUBDIVIDE: not implemented\n");
895 break;
897 case SNDCTL_DSP_SETFRAGMENT:
898 DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
900 if (get_user(val, p))
901 return -EFAULT;
903 DPD(2, "val is %#x\n", val);
905 if (val == 0)
906 return -EIO;
908 if (file->f_mode & FMODE_WRITE) {
909 /* digital pass-through fragment count and size are fixed values */
910 if (woinst->state & WAVE_STATE_OPEN || (woinst->format.passthrough == 1))
911 return -EINVAL; /* too late to change */
913 woinst->buffer.ossfragshift = val & 0xffff;
914 woinst->buffer.numfrags = (val >> 16) & 0xffff;
917 if (file->f_mode & FMODE_READ) {
918 if (wiinst->state & WAVE_STATE_OPEN)
919 return -EINVAL; /* too late to change */
921 wiinst->buffer.ossfragshift = val & 0xffff;
922 wiinst->buffer.numfrags = (val >> 16) & 0xffff;
925 break;
927 case SNDCTL_COPR_LOAD:
929 copr_buffer *buf;
930 u32 i;
932 DPF(4, "SNDCTL_COPR_LOAD:\n");
934 buf = kmalloc(sizeof(copr_buffer), GFP_KERNEL);
935 if (!buf)
936 return -ENOMEM;
938 if (copy_from_user(buf, p, sizeof(copr_buffer))) {
939 kfree (buf);
940 return -EFAULT;
943 if ((buf->command != CMD_READ) && (buf->command != CMD_WRITE)) {
944 kfree (buf);
945 return -EINVAL;
948 if (buf->command == CMD_WRITE) {
950 #ifdef DBGEMU
951 if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
952 #else
953 if (((buf->offs < 0x100) || (buf->offs + buf->len > (wave_dev->card->is_audigy ? 0xe00 : 0x800)) || (buf->len > 1000)
954 ) && !(
955 //any register allowed raw access to users goes here:
956 (buf->offs == DBG ||
957 buf->offs == A_DBG)
958 && (buf->len == 1))) {
959 #endif
960 kfree(buf);
961 return -EINVAL;
963 } else {
964 if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
965 kfree(buf);
966 return -EINVAL;
970 if (((unsigned)buf->flags) > 0x3f)
971 buf->flags = 0;
973 if (buf->command == CMD_READ) {
974 for (i = 0; i < buf->len; i++)
975 ((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags);
977 if (copy_to_user(p, buf, sizeof(copr_buffer))) {
978 kfree(buf);
979 return -EFAULT;
981 } else {
982 for (i = 0; i < buf->len; i++)
983 sblive_writeptr(wave_dev->card, buf->offs + i, buf->flags, ((u32 *) buf->data)[i]);
986 kfree (buf);
987 break;
990 default: /* Default is unrecognized command */
991 DPD(2, "default: %#x\n", cmd);
992 return -EINVAL;
994 return 0;
997 static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int *type)
999 struct emu10k1_wavedevice *wave_dev = vma->vm_private_data;
1000 struct woinst *woinst = wave_dev->woinst;
1001 struct wiinst *wiinst = wave_dev->wiinst;
1002 struct page *dmapage;
1003 unsigned long pgoff;
1004 int rd, wr;
1006 DPF(3, "emu10k1_mm_nopage()\n");
1007 DPD(3, "addr: %#lx\n", address);
1009 if (address > vma->vm_end) {
1010 DPF(1, "EXIT, returning NOPAGE_SIGBUS\n");
1011 return NOPAGE_SIGBUS; /* Disallow mremap */
1014 pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
1015 if (woinst != NULL)
1016 wr = woinst->mmapped;
1017 else
1018 wr = 0;
1020 if (wiinst != NULL)
1021 rd = wiinst->mmapped;
1022 else
1023 rd = 0;
1025 /* if full-duplex (read+write) and we have two sets of bufs,
1026 * then the playback buffers come first, sez soundcard.c */
1027 if (wr) {
1028 if (pgoff >= woinst->buffer.pages) {
1029 pgoff -= woinst->buffer.pages;
1030 dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1031 } else
1032 dmapage = virt_to_page (woinst->voice[0].mem.addr[pgoff]);
1033 } else {
1034 dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1037 get_page (dmapage);
1039 DPD(3, "page: %#lx\n", (unsigned long) dmapage);
1040 if (type)
1041 *type = VM_FAULT_MINOR;
1042 return dmapage;
1045 static struct vm_operations_struct emu10k1_mm_ops = {
1046 .nopage = emu10k1_mm_nopage,
1049 static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
1051 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1052 unsigned long max_pages, n_pages, pgoffset;
1053 struct woinst *woinst = NULL;
1054 struct wiinst *wiinst = NULL;
1055 unsigned long flags;
1057 DPF(2, "emu10k1_audio_mmap()\n");
1059 max_pages = 0;
1060 if (vma->vm_flags & VM_WRITE) {
1061 woinst = wave_dev->woinst;
1063 spin_lock_irqsave(&woinst->lock, flags);
1065 /* No m'mapping possible for multichannel */
1066 if (woinst->num_voices > 1) {
1067 spin_unlock_irqrestore(&woinst->lock, flags);
1068 return -EINVAL;
1071 if (woinst->state == WAVE_STATE_CLOSED) {
1072 calculate_ofrag(woinst);
1074 if (emu10k1_waveout_open(wave_dev) < 0) {
1075 spin_unlock_irqrestore(&woinst->lock, flags);
1076 ERROR();
1077 return -EINVAL;
1081 woinst->mmapped = 1;
1082 max_pages += woinst->buffer.pages;
1083 spin_unlock_irqrestore(&woinst->lock, flags);
1086 if (vma->vm_flags & VM_READ) {
1087 wiinst = wave_dev->wiinst;
1089 spin_lock_irqsave(&wiinst->lock, flags);
1090 if (wiinst->state == WAVE_STATE_CLOSED) {
1091 calculate_ifrag(wiinst);
1093 if (emu10k1_wavein_open(wave_dev) < 0) {
1094 spin_unlock_irqrestore(&wiinst->lock, flags);
1095 ERROR();
1096 return -EINVAL;
1100 wiinst->mmapped = 1;
1101 max_pages += wiinst->buffer.pages;
1102 spin_unlock_irqrestore(&wiinst->lock, flags);
1105 n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
1106 pgoffset = vma->vm_pgoff;
1108 DPD(2, "vma_start: %#lx, vma_end: %#lx, vma_offset: %ld\n", vma->vm_start, vma->vm_end, pgoffset);
1109 DPD(2, "n_pages: %ld, max_pages: %ld\n", n_pages, max_pages);
1111 if (pgoffset + n_pages > max_pages)
1112 return -EINVAL;
1114 vma->vm_flags |= VM_RESERVED;
1115 vma->vm_ops = &emu10k1_mm_ops;
1116 vma->vm_private_data = wave_dev;
1117 return 0;
1120 static int emu10k1_audio_open(struct inode *inode, struct file *file)
1122 int minor = iminor(inode);
1123 struct emu10k1_card *card = NULL;
1124 struct list_head *entry;
1125 struct emu10k1_wavedevice *wave_dev;
1127 DPF(2, "emu10k1_audio_open()\n");
1129 /* Check for correct device to open */
1131 list_for_each(entry, &emu10k1_devs) {
1132 card = list_entry(entry, struct emu10k1_card, list);
1134 if (!((card->audio_dev ^ minor) & ~0xf) || !((card->audio_dev1 ^ minor) & ~0xf))
1135 goto match;
1138 return -ENODEV;
1140 match:
1142 wave_dev = kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
1144 if (wave_dev == NULL) {
1145 ERROR();
1146 return -ENOMEM;
1149 wave_dev->card = card;
1150 wave_dev->wiinst = NULL;
1151 wave_dev->woinst = NULL;
1152 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT; /* Default */
1154 if (file->f_mode & FMODE_READ) {
1155 /* Recording */
1156 struct wiinst *wiinst;
1158 if ((wiinst = kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
1159 ERROR();
1160 kfree(wave_dev);
1161 return -ENOMEM;
1164 wiinst->recsrc = card->wavein.recsrc;
1165 wiinst->fxwc = card->wavein.fxwc;
1167 switch (wiinst->recsrc) {
1168 case WAVERECORD_AC97:
1169 wiinst->format.id = AFMT_S16_LE;
1170 wiinst->format.samplingrate = 8000;
1171 wiinst->format.bitsperchannel = 16;
1172 wiinst->format.channels = 1;
1173 break;
1174 case WAVERECORD_MIC:
1175 wiinst->format.id = AFMT_S16_LE;
1176 wiinst->format.samplingrate = 8000;
1177 wiinst->format.bitsperchannel = 16;
1178 wiinst->format.channels = 1;
1179 break;
1180 case WAVERECORD_FX:
1181 wiinst->format.id = AFMT_S16_LE;
1182 wiinst->format.samplingrate = 48000;
1183 wiinst->format.bitsperchannel = 16;
1184 wiinst->format.channels = hweight32(wiinst->fxwc);
1185 break;
1186 default:
1187 kfree(wave_dev);
1188 kfree(wiinst);
1189 BUG();
1190 break;
1193 wiinst->state = WAVE_STATE_CLOSED;
1195 wiinst->buffer.ossfragshift = 0;
1196 wiinst->buffer.fragment_size = 0;
1197 wiinst->buffer.numfrags = 0;
1199 init_waitqueue_head(&wiinst->wait_queue);
1201 wiinst->mmapped = 0;
1202 wiinst->total_recorded = 0;
1203 wiinst->blocks = 0;
1204 spin_lock_init(&wiinst->lock);
1205 tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev);
1206 wave_dev->wiinst = wiinst;
1207 emu10k1_wavein_setformat(wave_dev, &wiinst->format);
1210 if (file->f_mode & FMODE_WRITE) {
1211 struct woinst *woinst;
1212 int i;
1214 if ((woinst = kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
1215 ERROR();
1216 kfree(wave_dev);
1217 return -ENOMEM;
1220 if (wave_dev->wiinst != NULL) {
1221 woinst->format = wave_dev->wiinst->format;
1222 } else {
1223 woinst->format.id = AFMT_U8;
1224 woinst->format.samplingrate = 8000;
1225 woinst->format.bitsperchannel = 8;
1226 woinst->format.channels = 1;
1229 woinst->state = WAVE_STATE_CLOSED;
1231 woinst->buffer.fragment_size = 0;
1232 woinst->buffer.ossfragshift = 0;
1233 woinst->buffer.numfrags = 0;
1234 woinst->device = (card->audio_dev1 == minor);
1235 woinst->timer.state = TIMER_STATE_UNINSTALLED;
1236 woinst->num_voices = 1;
1237 for (i = 0; i < WAVEOUT_MAXVOICES; i++) {
1238 woinst->voice[i].usage = VOICE_USAGE_FREE;
1239 woinst->voice[i].mem.emupageindex = -1;
1242 init_waitqueue_head(&woinst->wait_queue);
1244 woinst->mmapped = 0;
1245 woinst->total_copied = 0;
1246 woinst->total_played = 0;
1247 woinst->blocks = 0;
1248 spin_lock_init(&woinst->lock);
1249 tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev);
1250 wave_dev->woinst = woinst;
1251 emu10k1_waveout_setformat(wave_dev, &woinst->format);
1254 file->private_data = (void *) wave_dev;
1256 return nonseekable_open(inode, file);
1259 static int emu10k1_audio_release(struct inode *inode, struct file *file)
1261 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1262 struct emu10k1_card *card;
1263 unsigned long flags;
1265 card = wave_dev->card;
1267 DPF(2, "emu10k1_audio_release()\n");
1269 if (file->f_mode & FMODE_WRITE) {
1270 struct woinst *woinst = wave_dev->woinst;
1272 spin_lock_irqsave(&woinst->lock, flags);
1273 if(woinst->format.passthrough==2)
1274 card->pt.state=PT_STATE_PLAYING;
1275 if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE){
1276 spin_lock(&card->pt.lock);
1277 emu10k1_pt_stop(card);
1278 spin_unlock(&card->pt.lock);
1280 if (woinst->state & WAVE_STATE_OPEN) {
1281 if (woinst->state & WAVE_STATE_STARTED) {
1282 if (!(file->f_flags & O_NONBLOCK)) {
1283 while (!signal_pending(current)
1284 && (woinst->total_played < woinst->total_copied)) {
1285 DPF(4, "Buffer hasn't been totally played, sleep....\n");
1286 spin_unlock_irqrestore(&woinst->lock, flags);
1287 interruptible_sleep_on(&woinst->wait_queue);
1288 spin_lock_irqsave(&woinst->lock, flags);
1292 emu10k1_waveout_close(wave_dev);
1295 spin_unlock_irqrestore(&woinst->lock, flags);
1296 /* remove the tasklet */
1297 tasklet_kill(&woinst->timer.tasklet);
1298 kfree(wave_dev->woinst);
1301 if (file->f_mode & FMODE_READ) {
1302 struct wiinst *wiinst = wave_dev->wiinst;
1304 spin_lock_irqsave(&wiinst->lock, flags);
1306 if (wiinst->state & WAVE_STATE_OPEN) {
1307 emu10k1_wavein_close(wave_dev);
1310 spin_unlock_irqrestore(&wiinst->lock, flags);
1311 tasklet_kill(&wiinst->timer.tasklet);
1312 kfree(wave_dev->wiinst);
1315 kfree(wave_dev);
1317 if (waitqueue_active(&card->open_wait))
1318 wake_up_interruptible(&card->open_wait);
1320 return 0;
1323 /* FIXME sort out poll() + mmap() */
1324 static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_struct *wait)
1326 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1327 struct woinst *woinst = wave_dev->woinst;
1328 struct wiinst *wiinst = wave_dev->wiinst;
1329 unsigned int mask = 0;
1330 u32 bytestocopy;
1331 unsigned long flags;
1333 DPF(4, "emu10k1_audio_poll()\n");
1335 if (file->f_mode & FMODE_WRITE)
1336 poll_wait(file, &woinst->wait_queue, wait);
1338 if (file->f_mode & FMODE_READ)
1339 poll_wait(file, &wiinst->wait_queue, wait);
1341 if (file->f_mode & FMODE_WRITE) {
1342 spin_lock_irqsave(&woinst->lock, flags);
1344 if (woinst->state & WAVE_STATE_OPEN) {
1345 emu10k1_waveout_update(woinst);
1346 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1348 if (bytestocopy >= woinst->buffer.fragment_size)
1349 mask |= POLLOUT | POLLWRNORM;
1350 } else
1351 mask |= POLLOUT | POLLWRNORM;
1353 spin_unlock_irqrestore(&woinst->lock, flags);
1356 if (file->f_mode & FMODE_READ) {
1357 spin_lock_irqsave(&wiinst->lock, flags);
1359 if (wiinst->state & WAVE_STATE_OPEN) {
1360 emu10k1_wavein_update(wave_dev->card, wiinst);
1361 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1363 if (bytestocopy >= wiinst->buffer.fragment_size)
1364 mask |= POLLIN | POLLRDNORM;
1367 spin_unlock_irqrestore(&wiinst->lock, flags);
1370 return mask;
1373 static void calculate_ofrag(struct woinst *woinst)
1375 struct waveout_buffer *buffer = &woinst->buffer;
1376 u32 fragsize;
1378 if (buffer->fragment_size)
1379 return;
1381 if (!buffer->ossfragshift) {
1382 fragsize = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTFRAGLEN) / 1000 - 1;
1384 while (fragsize) {
1385 fragsize >>= 1;
1386 buffer->ossfragshift++;
1390 if (buffer->ossfragshift < WAVEOUT_MINFRAGSHIFT)
1391 buffer->ossfragshift = WAVEOUT_MINFRAGSHIFT;
1393 buffer->fragment_size = 1 << buffer->ossfragshift;
1395 while (buffer->fragment_size * WAVEOUT_MINFRAGS > WAVEOUT_MAXBUFSIZE)
1396 buffer->fragment_size >>= 1;
1398 /* now we are sure that:
1399 (2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
1402 if (!buffer->numfrags) {
1403 u32 numfrags;
1405 numfrags = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTBUFLEN) /
1406 (buffer->fragment_size * 1000) - 1;
1408 buffer->numfrags = 1;
1410 while (numfrags) {
1411 numfrags >>= 1;
1412 buffer->numfrags <<= 1;
1416 if (buffer->numfrags < WAVEOUT_MINFRAGS)
1417 buffer->numfrags = WAVEOUT_MINFRAGS;
1419 if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE)
1420 buffer->numfrags = WAVEOUT_MAXBUFSIZE / buffer->fragment_size;
1422 if (buffer->numfrags < WAVEOUT_MINFRAGS)
1423 BUG();
1425 buffer->size = buffer->fragment_size * buffer->numfrags;
1426 buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1428 DPD(2, " calculated playback fragment_size -> %d\n", buffer->fragment_size);
1429 DPD(2, " calculated playback numfrags -> %d\n", buffer->numfrags);
1431 return;
1434 static void calculate_ifrag(struct wiinst *wiinst)
1436 struct wavein_buffer *buffer = &wiinst->buffer;
1437 u32 fragsize, bufsize, size[4];
1438 int i, j;
1440 if (buffer->fragment_size)
1441 return;
1443 if (!buffer->ossfragshift) {
1444 fragsize = (wiinst->format.bytespersec * WAVEIN_DEFAULTFRAGLEN) / 1000 - 1;
1446 while (fragsize) {
1447 fragsize >>= 1;
1448 buffer->ossfragshift++;
1452 if (buffer->ossfragshift < WAVEIN_MINFRAGSHIFT)
1453 buffer->ossfragshift = WAVEIN_MINFRAGSHIFT;
1455 buffer->fragment_size = 1 << buffer->ossfragshift;
1457 while (buffer->fragment_size * WAVEIN_MINFRAGS > WAVEIN_MAXBUFSIZE)
1458 buffer->fragment_size >>= 1;
1460 /* now we are sure that:
1461 (2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
1465 if (!buffer->numfrags)
1466 buffer->numfrags = (wiinst->format.bytespersec * WAVEIN_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
1468 if (buffer->numfrags < WAVEIN_MINFRAGS)
1469 buffer->numfrags = WAVEIN_MINFRAGS;
1471 if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE)
1472 buffer->numfrags = WAVEIN_MAXBUFSIZE / buffer->fragment_size;
1474 if (buffer->numfrags < WAVEIN_MINFRAGS)
1475 BUG();
1477 bufsize = buffer->fragment_size * buffer->numfrags;
1479 /* the buffer size for recording is restricted to certain values, adjust it now */
1480 if (bufsize >= 0x10000) {
1481 buffer->size = 0x10000;
1482 buffer->sizeregval = 0x1f;
1483 } else {
1484 buffer->size = 0;
1485 size[0] = 384;
1486 size[1] = 448;
1487 size[2] = 512;
1488 size[3] = 640;
1490 for (i = 0; i < 8; i++)
1491 for (j = 0; j < 4; j++)
1492 if (bufsize >= size[j]) {
1493 buffer->size = size[j];
1494 size[j] *= 2;
1495 buffer->sizeregval = i * 4 + j + 1;
1496 } else
1497 goto exitloop;
1498 exitloop:
1499 if (buffer->size == 0) {
1500 buffer->size = 384;
1501 buffer->sizeregval = 0x01;
1505 /* adjust the fragment size so that buffer size is an integer multiple */
1506 while (buffer->size % buffer->fragment_size)
1507 buffer->fragment_size >>= 1;
1509 buffer->numfrags = buffer->size / buffer->fragment_size;
1510 buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1512 DPD(2, " calculated recording fragment_size -> %d\n", buffer->fragment_size);
1513 DPD(2, " calculated recording numfrags -> %d\n", buffer->numfrags);
1514 DPD(2, " buffer size register -> %#04x\n", buffer->sizeregval);
1516 return;
1519 static void emu10k1_wavein_bh(unsigned long refdata)
1521 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1522 struct wiinst *wiinst = wave_dev->wiinst;
1523 u32 bytestocopy;
1524 unsigned long flags;
1526 if (!wiinst)
1527 return;
1529 spin_lock_irqsave(&wiinst->lock, flags);
1531 if (!(wiinst->state & WAVE_STATE_STARTED)) {
1532 spin_unlock_irqrestore(&wiinst->lock, flags);
1533 return;
1536 emu10k1_wavein_update(wave_dev->card, wiinst);
1537 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1539 spin_unlock_irqrestore(&wiinst->lock, flags);
1541 if (bytestocopy >= wiinst->buffer.fragment_size) {
1542 if (waitqueue_active(&wiinst->wait_queue))
1543 wake_up_interruptible(&wiinst->wait_queue);
1544 } else
1545 DPD(3, "Not enough transfer size, %d\n", bytestocopy);
1547 return;
1550 static void emu10k1_waveout_bh(unsigned long refdata)
1552 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1553 struct woinst *woinst = wave_dev->woinst;
1554 u32 bytestocopy;
1555 unsigned long flags;
1557 if (!woinst)
1558 return;
1560 spin_lock_irqsave(&woinst->lock, flags);
1562 if (!(woinst->state & WAVE_STATE_STARTED)) {
1563 spin_unlock_irqrestore(&woinst->lock, flags);
1564 return;
1567 emu10k1_waveout_update(woinst);
1568 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1570 if (woinst->buffer.fill_silence) {
1571 spin_unlock_irqrestore(&woinst->lock, flags);
1572 emu10k1_waveout_fillsilence(woinst);
1573 } else
1574 spin_unlock_irqrestore(&woinst->lock, flags);
1576 if (bytestocopy >= woinst->buffer.fragment_size) {
1577 if (waitqueue_active(&woinst->wait_queue))
1578 wake_up_interruptible(&woinst->wait_queue);
1579 } else
1580 DPD(3, "Not enough transfer size -> %d\n", bytestocopy);
1582 return;
1585 const struct file_operations emu10k1_audio_fops = {
1586 .owner = THIS_MODULE,
1587 .llseek = no_llseek,
1588 .read = emu10k1_audio_read,
1589 .write = emu10k1_audio_write,
1590 .poll = emu10k1_audio_poll,
1591 .ioctl = emu10k1_audio_ioctl,
1592 .mmap = emu10k1_audio_mmap,
1593 .open = emu10k1_audio_open,
1594 .release = emu10k1_audio_release,