source: cmedia/trunk/Sblive/audio.c@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 37.3 KB
Line 
1/* $Id: audio.c,v 1.3 2000/07/23 16:21:57 sandervl Exp $ */
2
3
4/*
5 **********************************************************************
6 * audio.c -- /dev/dsp interface for emu10k1 driver
7 * Copyright 1999, 2000 Creative Labs, Inc.
8 *
9 **********************************************************************
10 *
11 * Date Author Summary of changes
12 * ---- ------ ------------------
13 * October 20, 1999 Bertrand Lee base code release
14 * November 2, 1999 Alan Cox cleaned up types/leaks
15 *
16 **********************************************************************
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public
29 * License along with this program; if not, write to the Free
30 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
31 * USA.
32 *
33 **********************************************************************
34 */
35
36#include "hwaccess.h"
37#include "cardwo.h"
38#include "cardwi.h"
39#include "recmgr.h"
40#include "audio.h"
41
42static void calculate_ofrag(struct woinst *);
43static void calculate_ifrag(struct wiinst *);
44
45#ifdef TARGET_OS2
46extern int OSS32_ProcessIRQ(int fWaveOut, unsigned long streamid);
47#endif
48
49/* Audio file operations */
50static loff_t emu10k1_audio_llseek(struct file *file, loff_t offset, int nOrigin)
51{
52 return -ESPIPE;
53}
54
55static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
56{
57 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
58 struct wiinst *wiinst = wave_dev->wiinst;
59 struct wave_in *wave_in;
60 ssize_t ret = 0;
61 unsigned long flags;
62
63 GET_INODE_STRUCT();
64
65 DPD(4, "emu10k1_audio_read(), buffer=%p, count=%x\n", buffer, (u32) count);
66
67 if (ppos != &file->f_pos)
68 return -ESPIPE;
69
70 if (!access_ok(VERIFY_WRITE, buffer, count))
71 return -EFAULT;
72
73 spin_lock_irqsave(&wiinst->lock, flags);
74
75 if (wiinst->mapped) {
76 spin_unlock_irqrestore(&wiinst->lock, flags);
77 return -ENXIO;
78 }
79
80 if (!wiinst->wave_in) {
81 calculate_ifrag(wiinst);
82
83 while (emu10k1_wavein_open(wave_dev) != CTSTATUS_SUCCESS) {
84 spin_unlock_irqrestore(&wiinst->lock, flags);
85
86 if (file->f_flags & O_NONBLOCK)
87 return -EAGAIN;
88
89 UP_INODE_SEM(&inode->i_sem);
90 interruptible_sleep_on(&wave_dev->card->open_wait);
91 DOWN_INODE_SEM(&inode->i_sem);
92
93 if (signal_pending(current))
94 return -ERESTARTSYS;
95
96 spin_lock_irqsave(&wiinst->lock, flags);
97 }
98 }
99
100 wave_in = wiinst->wave_in;
101
102 spin_unlock_irqrestore(&wiinst->lock, flags);
103
104 while (count > 0) {
105 u32 bytestocopy;
106
107 spin_lock_irqsave(&wiinst->lock, flags);
108
109 if ((wave_in->state != CARDWAVE_STATE_STARTED)
110 && (wave_dev->enablebits & PCM_ENABLE_INPUT))
111 emu10k1_wavein_start(wave_dev);
112
113 emu10k1_wavein_update(wiinst);
114 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
115
116 spin_unlock_irqrestore(&wiinst->lock, flags);
117
118 DPD(4, "bytestocopy --> %x\n", bytestocopy);
119
120 if ((bytestocopy >= wiinst->fragment_size)
121 || (bytestocopy >= count)) {
122 bytestocopy = min(bytestocopy, count);
123
124 emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy);
125
126 count -= bytestocopy;
127 buffer += bytestocopy;
128 ret += bytestocopy;
129 }
130
131 if (count > 0) {
132 if ((file->f_flags & O_NONBLOCK)
133 || (!(wave_dev->enablebits & PCM_ENABLE_INPUT)))
134 return (ret ? ret : -EAGAIN);
135
136 UP_INODE_SEM(&inode->i_sem);
137 interruptible_sleep_on(&wiinst->wait_queue);
138 DOWN_INODE_SEM(&inode->i_sem);
139
140 if (signal_pending(current))
141 return (ret ? ret : -ERESTARTSYS);
142
143 }
144 }
145
146 DPD(4, "bytes copied -> %x\n", (u32) ret);
147
148 return ret;
149}
150
151static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
152{
153 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
154 struct woinst *woinst = wave_dev->woinst;
155 struct wave_out *wave_out;
156 ssize_t ret;
157 unsigned long flags;
158
159 GET_INODE_STRUCT();
160
161 DPD(4, "emu10k1_audio_write(), buffer=%p, count=%x\n", buffer, (u32) count);
162
163 if (ppos != &file->f_pos)
164 return -ESPIPE;
165
166 if (!access_ok(VERIFY_READ, buffer, count))
167 return -EFAULT;
168
169 spin_lock_irqsave(&woinst->lock, flags);
170
171 if (woinst->mapped) {
172 spin_unlock_irqrestore(&woinst->lock, flags);
173 return -ENXIO;
174 }
175
176 if (!woinst->wave_out) {
177 calculate_ofrag(woinst);
178
179 while (emu10k1_waveout_open(wave_dev) != CTSTATUS_SUCCESS) {
180 spin_unlock_irqrestore(&woinst->lock, flags);
181
182 if (file->f_flags & O_NONBLOCK)
183 return -EAGAIN;
184
185 UP_INODE_SEM(&inode->i_sem);
186 interruptible_sleep_on(&wave_dev->card->open_wait);
187 DOWN_INODE_SEM(&inode->i_sem);
188
189 if (signal_pending(current))
190 return -ERESTARTSYS;
191
192 spin_lock_irqsave(&woinst->lock, flags);
193 }
194 }
195
196 wave_out = woinst->wave_out;
197
198 spin_unlock_irqrestore(&woinst->lock, flags);
199
200 ret = 0;
201 while (count > 0) {
202 u32 bytestocopy;
203
204 spin_lock_irqsave(&woinst->lock, flags);
205 emu10k1_waveout_update(woinst);
206 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
207 spin_unlock_irqrestore(&woinst->lock, flags);
208
209 DPD(4, "bytestocopy --> %x\n", bytestocopy);
210
211 if ((bytestocopy >= woinst->fragment_size)
212 || (bytestocopy >= count)) {
213
214 bytestocopy = min(bytestocopy, count);
215
216 emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy);
217
218 count -= bytestocopy;
219 buffer += bytestocopy;
220 ret += bytestocopy;
221
222 spin_lock_irqsave(&woinst->lock, flags);
223 woinst->total_copied += bytestocopy;
224
225 if ((wave_out->state != CARDWAVE_STATE_STARTED)
226 && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
227 && (woinst->total_copied >= woinst->fragment_size)) {
228
229 if (emu10k1_waveout_start(wave_dev) != CTSTATUS_SUCCESS) {
230 spin_unlock_irqrestore(&woinst->lock, flags);
231 ERROR();
232 return -EFAULT;
233 }
234 }
235 spin_unlock_irqrestore(&woinst->lock, flags);
236 }
237
238 if (count > 0) {
239 if ((file->f_flags & O_NONBLOCK)
240 || (!(wave_dev->enablebits & PCM_ENABLE_OUTPUT)))
241 return (ret ? ret : -EAGAIN);
242
243 UP_INODE_SEM(&inode->i_sem);
244 interruptible_sleep_on(&woinst->wait_queue);
245 DOWN_INODE_SEM(&inode->i_sem);
246
247 if (signal_pending(current))
248 return (ret ? ret : -ERESTARTSYS);
249 }
250 }
251
252 DPD(4, "bytes copied -> %x\n", (u32) ret);
253
254 return ret;
255}
256
257static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
258{
259 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
260 int val = 0;
261 struct woinst *woinst = NULL;
262 struct wave_out *wave_out = NULL;
263 struct wiinst *wiinst = NULL;
264 struct wave_in *wave_in = NULL;
265 u32 bytestocopy;
266 unsigned long flags;
267
268 DPF(4, "emu10k1_audio_ioctl()\n");
269
270 if (file->f_mode & FMODE_WRITE) {
271 woinst = wave_dev->woinst;
272 spin_lock_irqsave(&woinst->lock, flags);
273 wave_out = woinst->wave_out;
274 spin_unlock_irqrestore(&woinst->lock, flags);
275 }
276
277 if (file->f_mode & FMODE_READ) {
278 wiinst = wave_dev->wiinst;
279 spin_lock_irqsave(&wiinst->lock, flags);
280 wave_in = wiinst->wave_in;
281 spin_unlock_irqrestore(&wiinst->lock, flags);
282 }
283
284 switch (cmd) {
285 case OSS_GETVERSION:
286 DPF(2, "OSS_GETVERSION:\n");
287 return put_user(SOUND_VERSION, (int *) arg);
288
289 case SNDCTL_DSP_RESET:
290 DPF(2, "SNDCTL_DSP_RESET:\n");
291 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
292
293 if (file->f_mode & FMODE_WRITE) {
294 spin_lock_irqsave(&woinst->lock, flags);
295
296 if (wave_out)
297 emu10k1_waveout_close(wave_dev);
298
299#ifdef TARGET_OS2
300 woinst->fragment_size = 0;
301#endif
302 woinst->total_copied = 0;
303 woinst->total_played = 0;
304 woinst->silence_bytes = 0;
305 woinst->blocks = 0;
306 woinst->curpos = 0;
307
308 spin_unlock_irqrestore(&woinst->lock, flags);
309 }
310
311 if (file->f_mode & FMODE_READ) {
312 spin_lock_irqsave(&wiinst->lock, flags);
313
314 if (wave_in)
315 emu10k1_wavein_close(wave_dev);
316
317#ifdef TARGET_OS2
318 wiinst->fragment_size = 0;
319#endif
320 wiinst->total_recorded = 0;
321 wiinst->blocks = 0;
322 wiinst->curpos = 0;
323 spin_unlock_irqrestore(&wiinst->lock, flags);
324 }
325
326 break;
327
328 case SNDCTL_DSP_SYNC:
329 DPF(2, "SNDCTL_DSP_SYNC:\n");
330
331 if (file->f_mode & FMODE_WRITE) {
332
333 if (wave_out) {
334 spin_lock_irqsave(&woinst->lock, flags);
335
336 if (wave_out->state == CARDWAVE_STATE_STARTED)
337 while ((woinst->total_played < woinst->total_copied)
338 && !signal_pending(current)) {
339 spin_unlock_irqrestore(&woinst->lock, flags);
340 interruptible_sleep_on(&woinst->wait_queue);
341 spin_lock_irqsave(&woinst->lock, flags);
342 }
343
344 emu10k1_waveout_close(wave_dev);
345 woinst->total_copied = 0;
346 woinst->total_played = 0;
347 woinst->silence_bytes = 0;
348 woinst->blocks = 0;
349 woinst->curpos = 0;
350
351 spin_unlock_irqrestore(&woinst->lock, flags);
352 }
353 }
354
355 if (file->f_mode & FMODE_READ) {
356 spin_lock_irqsave(&wiinst->lock, flags);
357
358 if (wave_in)
359 emu10k1_wavein_close(wave_dev);
360
361 wiinst->total_recorded = 0;
362 wiinst->blocks = 0;
363 wiinst->curpos = 0;
364 spin_unlock_irqrestore(&wiinst->lock, flags);
365 }
366
367 break;
368
369 case SNDCTL_DSP_SETDUPLEX:
370 DPF(2, "SNDCTL_DSP_SETDUPLEX:\n");
371 break;
372
373 case SNDCTL_DSP_GETCAPS:
374 DPF(2, "SNDCTL_DSP_GETCAPS:\n");
375 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_COPROC, (int *) arg);
376
377 case SNDCTL_DSP_SPEED:
378 DPF(2, "SNDCTL_DSP_SPEED:\n");
379
380 get_user_ret(val, (int *) arg, -EFAULT);
381 DPD(2, "val is %d\n", val);
382
383 if (val >= 0) {
384 if (file->f_mode & FMODE_WRITE) {
385 spin_lock_irqsave(&woinst->lock, flags);
386
387 woinst->wave_fmt.samplingrate = val;
388
389 if (emu10k1_waveout_setformat(wave_dev) != CTSTATUS_SUCCESS)
390 return -EINVAL;
391
392 val = woinst->wave_fmt.samplingrate;
393
394 spin_unlock_irqrestore(&woinst->lock, flags);
395
396 DPD(2, "set playback sampling rate -> %d\n", val);
397 }
398
399 if (file->f_mode & FMODE_READ) {
400 spin_lock_irqsave(&wiinst->lock, flags);
401
402 wiinst->wave_fmt.samplingrate = val;
403
404 if (emu10k1_wavein_setformat(wave_dev) != CTSTATUS_SUCCESS)
405 return -EINVAL;
406
407 val = wiinst->wave_fmt.samplingrate;
408
409 spin_unlock_irqrestore(&wiinst->lock, flags);
410
411 DPD(2, "set recording sampling rate -> %d\n", val);
412 }
413
414 return put_user(val, (int *) arg);
415 } else {
416 if (file->f_mode & FMODE_READ)
417 val = wiinst->wave_fmt.samplingrate;
418 else if (file->f_mode & FMODE_WRITE)
419 val = woinst->wave_fmt.samplingrate;
420
421 return put_user(val, (int *) arg);
422 }
423 break;
424
425 case SNDCTL_DSP_STEREO:
426 DPF(2, "SNDCTL_DSP_STEREO:\n");
427
428 get_user_ret(val, (int *) arg, -EFAULT);
429 DPD(2, " val is %d\n", val);
430
431 if (file->f_mode & FMODE_WRITE) {
432 spin_lock_irqsave(&woinst->lock, flags);
433
434 woinst->wave_fmt.channels = val ? 2 : 1;
435
436 if (emu10k1_waveout_setformat(wave_dev) != CTSTATUS_SUCCESS)
437 return -EINVAL;
438
439 val = woinst->wave_fmt.channels - 1;
440
441 spin_unlock_irqrestore(&woinst->lock, flags);
442
443 DPD(2, "set playback stereo -> %d\n", val);
444 }
445
446 if (file->f_mode & FMODE_READ) {
447 spin_lock_irqsave(&wiinst->lock, flags);
448
449 wiinst->wave_fmt.channels = val ? 2 : 1;
450
451 if (emu10k1_wavein_setformat(wave_dev) != CTSTATUS_SUCCESS)
452 return -EINVAL;
453
454 val = wiinst->wave_fmt.channels - 1;
455
456 spin_unlock_irqrestore(&wiinst->lock, flags);
457 DPD(2, "set recording stereo -> %d\n", val);
458 }
459
460 return put_user(val, (int *) arg);
461
462 break;
463
464 case SNDCTL_DSP_CHANNELS:
465 DPF(2, "SNDCTL_DSP_CHANNELS:\n");
466
467 get_user_ret(val, (int *) arg, -EFAULT);
468 DPD(2, " val is %d\n", val);
469
470 if (val != 0) {
471 if (file->f_mode & FMODE_WRITE) {
472 spin_lock_irqsave(&woinst->lock, flags);
473
474 woinst->wave_fmt.channels = val;
475
476 if (emu10k1_waveout_setformat(wave_dev) != CTSTATUS_SUCCESS)
477 return -EINVAL;
478
479 val = woinst->wave_fmt.channels;
480
481 spin_unlock_irqrestore(&woinst->lock, flags);
482 DPD(2, "set playback number of channels -> %d\n", val);
483 }
484
485 if (file->f_mode & FMODE_READ) {
486 spin_lock_irqsave(&wiinst->lock, flags);
487
488 wiinst->wave_fmt.channels = val;
489
490 if (emu10k1_wavein_setformat(wave_dev) != CTSTATUS_SUCCESS)
491 return -EINVAL;
492
493 val = wiinst->wave_fmt.channels;
494
495 spin_unlock_irqrestore(&wiinst->lock, flags);
496 DPD(2, "set recording number of channels -> %d\n", val);
497 }
498
499 return put_user(val, (int *) arg);
500 } else {
501 if (file->f_mode & FMODE_READ)
502 val = wiinst->wave_fmt.channels;
503 else if (file->f_mode & FMODE_WRITE)
504 val = woinst->wave_fmt.channels;
505
506 return put_user(val, (int *) arg);
507 }
508 break;
509
510 case SNDCTL_DSP_GETFMTS:
511 DPF(2, "SNDCTL_DSP_GETFMTS:\n");
512
513 if (file->f_mode & FMODE_READ)
514 val = AFMT_S16_LE;
515 else if (file->f_mode & FMODE_WRITE)
516 val = AFMT_S16_LE | AFMT_U8;
517
518 return put_user(val, (int *) arg);
519
520 case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
521 DPF(2, "SNDCTL_DSP_SETFMT:\n");
522
523 get_user_ret(val, (int *) arg, -EFAULT);
524 DPD(2, " val is %d\n", val);
525
526 if (val != AFMT_QUERY) {
527 if (file->f_mode & FMODE_WRITE) {
528 spin_lock_irqsave(&woinst->lock, flags);
529
530 woinst->wave_fmt.bitsperchannel = val;
531
532 if (emu10k1_waveout_setformat(wave_dev) != CTSTATUS_SUCCESS)
533 return -EINVAL;
534
535 val = woinst->wave_fmt.bitsperchannel;
536
537 spin_unlock_irqrestore(&woinst->lock, flags);
538 DPD(2, "set playback sample size -> %d\n", val);
539 }
540
541 if (file->f_mode & FMODE_READ) {
542 spin_lock_irqsave(&wiinst->lock, flags);
543
544 wiinst->wave_fmt.bitsperchannel = val;
545
546 if (emu10k1_wavein_setformat(wave_dev) != CTSTATUS_SUCCESS)
547 return -EINVAL;
548
549 val = wiinst->wave_fmt.bitsperchannel;
550
551 spin_unlock_irqrestore(&wiinst->lock, flags);
552 DPD(2, "set recording sample size -> %d\n", val);
553 }
554
555 return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
556 } else {
557 if (file->f_mode & FMODE_READ)
558 val = wiinst->wave_fmt.bitsperchannel;
559 else if (file->f_mode & FMODE_WRITE)
560 val = woinst->wave_fmt.bitsperchannel;
561
562 return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
563 }
564 break;
565
566 case SOUND_PCM_READ_BITS:
567
568 if (file->f_mode & FMODE_READ)
569 val = wiinst->wave_fmt.bitsperchannel;
570 else if (file->f_mode & FMODE_WRITE)
571 val = woinst->wave_fmt.bitsperchannel;
572
573 return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
574
575 case SOUND_PCM_READ_RATE:
576
577 if (file->f_mode & FMODE_READ)
578 val = wiinst->wave_fmt.samplingrate;
579 else if (file->f_mode & FMODE_WRITE)
580 val = woinst->wave_fmt.samplingrate;
581
582 return put_user(val, (int *) arg);
583
584 case SOUND_PCM_READ_CHANNELS:
585
586 if (file->f_mode & FMODE_READ)
587 val = wiinst->wave_fmt.channels;
588 else if (file->f_mode & FMODE_WRITE)
589 val = woinst->wave_fmt.channels;
590
591 return put_user(val, (int *) arg);
592
593 case SOUND_PCM_WRITE_FILTER:
594 DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
595 break;
596
597 case SOUND_PCM_READ_FILTER:
598 DPF(2, "SOUND_PCM_READ_FILTER: not implemented\n");
599 break;
600
601 case SNDCTL_DSP_SETSYNCRO:
602 DPF(2, "SNDCTL_DSP_SETSYNCRO: not implemented\n");
603 break;
604
605 case SNDCTL_DSP_GETTRIGGER:
606 DPF(2, "SNDCTL_DSP_GETTRIGGER:\n");
607
608 if (file->f_mode & FMODE_WRITE && (wave_dev->enablebits & PCM_ENABLE_OUTPUT))
609 val |= PCM_ENABLE_OUTPUT;
610 if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
611 val |= PCM_ENABLE_INPUT;
612
613 return put_user(val, (int *) arg);
614
615 case SNDCTL_DSP_SETTRIGGER:
616 DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
617
618 get_user_ret(val, (int *) arg, -EFAULT);
619
620 if (file->f_mode & FMODE_WRITE) {
621 spin_lock_irqsave(&woinst->lock, flags);
622
623 if (val & PCM_ENABLE_OUTPUT) {
624 wave_dev->enablebits |= PCM_ENABLE_OUTPUT;
625 if (wave_out)
626 emu10k1_waveout_start(wave_dev);
627 } else {
628 wave_dev->enablebits &= ~PCM_ENABLE_OUTPUT;
629 if (wave_out)
630 emu10k1_waveout_stop(wave_dev);
631 }
632
633 spin_unlock_irqrestore(&woinst->lock, flags);
634 }
635
636 if (file->f_mode & FMODE_READ) {
637 spin_lock_irqsave(&wiinst->lock, flags);
638
639 if (val & PCM_ENABLE_INPUT) {
640 wave_dev->enablebits |= PCM_ENABLE_INPUT;
641 if (wave_in)
642 emu10k1_wavein_start(wave_dev);
643 } else {
644 wave_dev->enablebits &= ~PCM_ENABLE_INPUT;
645 if (wave_in)
646 emu10k1_wavein_stop(wave_dev);
647 }
648
649 spin_unlock_irqrestore(&wiinst->lock, flags);
650 }
651 break;
652
653 case SNDCTL_DSP_GETOSPACE:
654 {
655 audio_buf_info info;
656
657 DPF(4, "SNDCTL_DSP_GETOSPACE:\n");
658
659 if (!(file->f_mode & FMODE_WRITE))
660 return -EINVAL;
661
662 if (wave_out) {
663 spin_lock_irqsave(&woinst->lock, flags);
664 emu10k1_waveout_update(woinst);
665 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
666 spin_unlock_irqrestore(&woinst->lock, flags);
667
668 info.bytes = bytestocopy;
669 } else {
670 spin_lock_irqsave(&woinst->lock, flags);
671 calculate_ofrag(woinst);
672 spin_unlock_irqrestore(&woinst->lock, flags);
673
674 info.bytes = woinst->numfrags * woinst->fragment_size;
675 }
676
677 info.fragstotal = woinst->numfrags;
678 info.fragments = info.bytes / woinst->fragment_size;
679 info.fragsize = woinst->fragment_size;
680
681 if (copy_to_user((int *) arg, &info, sizeof(info)))
682 return -EFAULT;
683 }
684 break;
685
686 case SNDCTL_DSP_GETISPACE:
687 {
688 audio_buf_info info;
689
690 DPF(4, "SNDCTL_DSP_GETISPACE:\n");
691
692 if (!(file->f_mode & FMODE_READ))
693 return -EINVAL;
694
695 if (wave_in) {
696 spin_lock_irqsave(&wiinst->lock, flags);
697 emu10k1_wavein_update(wiinst);
698 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
699 spin_unlock_irqrestore(&wiinst->lock, flags);
700
701 info.bytes = bytestocopy;
702 } else {
703 spin_lock_irqsave(&wiinst->lock, flags);
704 calculate_ifrag(wiinst);
705 spin_unlock_irqrestore(&wiinst->lock, flags);
706
707 info.bytes = 0;
708 }
709
710 info.fragstotal = wiinst->numfrags;
711 info.fragments = info.bytes / wiinst->fragment_size;
712 info.fragsize = wiinst->fragment_size;
713
714 if (copy_to_user((int *) arg, &info, sizeof(info)))
715 return -EFAULT;
716 }
717 break;
718
719 case SNDCTL_DSP_NONBLOCK:
720 DPF(2, "SNDCTL_DSP_NONBLOCK:\n");
721
722 file->f_flags |= O_NONBLOCK;
723 break;
724
725 case SNDCTL_DSP_GETODELAY:
726 DPF(4, "SNDCTL_DSP_GETODELAY:\n");
727
728 if (!(file->f_mode & FMODE_WRITE))
729 return -EINVAL;
730
731 if (wave_out) {
732 spin_lock_irqsave(&woinst->lock, flags);
733 emu10k1_waveout_update(woinst);
734 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
735 spin_unlock_irqrestore(&woinst->lock, flags);
736
737 val = woinst->numfrags * woinst->fragment_size - bytestocopy;
738 } else
739 val = 0;
740
741 return put_user(val, (int *) arg);
742
743 case SNDCTL_DSP_GETIPTR:
744 {
745 count_info cinfo;
746
747 DPF(4, "SNDCTL_DSP_GETIPTR: \n");
748
749 if (!(file->f_mode & FMODE_READ))
750 return -EINVAL;
751
752 spin_lock_irqsave(&wiinst->lock, flags);
753
754 if (wave_in) {
755 emu10k1_wavein_update(wiinst);
756 cinfo.ptr = wiinst->curpos;
757 cinfo.bytes =
758 cinfo.ptr + wiinst->total_recorded - wiinst->total_recorded % (wiinst->fragment_size * wiinst->numfrags);
759 cinfo.blocks = cinfo.bytes / wiinst->fragment_size - wiinst->blocks;
760 wiinst->blocks = cinfo.bytes / wiinst->fragment_size;
761 } else {
762 cinfo.ptr = 0;
763 cinfo.bytes = 0;
764 cinfo.blocks = 0;
765 wiinst->blocks = 0;
766 }
767
768 spin_unlock_irqrestore(&wiinst->lock, flags);
769
770 if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
771 return -EFAULT;
772 }
773 break;
774
775 case SNDCTL_DSP_GETOPTR:
776 {
777 count_info cinfo;
778
779 DPF(4, "SNDCTL_DSP_GETOPTR:\n");
780
781 if (!(file->f_mode & FMODE_WRITE))
782 return -EINVAL;
783
784 spin_lock_irqsave(&woinst->lock, flags);
785
786 if (wave_out) {
787 emu10k1_waveout_update(woinst);
788 cinfo.ptr = woinst->curpos;
789 cinfo.bytes = cinfo.ptr + woinst->total_played - woinst->total_played % (woinst->fragment_size * woinst->numfrags);
790
791 cinfo.blocks = cinfo.bytes / woinst->fragment_size - woinst->blocks;
792 woinst->blocks = cinfo.bytes / woinst->fragment_size;
793 } else {
794 cinfo.ptr = 0;
795 cinfo.bytes = 0;
796 cinfo.blocks = 0;
797 woinst->blocks = 0;
798 }
799
800 spin_unlock_irqrestore(&woinst->lock, flags);
801
802 if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
803 return -EFAULT;
804 }
805 break;
806
807 case SNDCTL_DSP_GETBLKSIZE:
808 DPF(2, "SNDCTL_DSP_GETBLKSIZE:\n");
809
810 if (file->f_mode & FMODE_WRITE) {
811 spin_lock_irqsave(&woinst->lock, flags);
812
813 calculate_ofrag(woinst);
814 val = woinst->fragment_size;
815
816 spin_unlock_irqrestore(&woinst->lock, flags);
817 }
818
819 if (file->f_mode & FMODE_READ) {
820 spin_lock_irqsave(&wiinst->lock, flags);
821
822 calculate_ifrag(wiinst);
823 val = wiinst->fragment_size;
824
825 spin_unlock_irqrestore(&wiinst->lock, flags);
826 }
827
828 return put_user(val, (int *) arg);
829
830 break;
831
832 case SNDCTL_DSP_POST:
833 DPF(2, "SNDCTL_DSP_POST: not implemented\n");
834 break;
835
836 case SNDCTL_DSP_SUBDIVIDE:
837 DPF(2, "SNDCTL_DSP_SUBDIVIDE: not implemented\n");
838 break;
839
840 case SNDCTL_DSP_SETFRAGMENT:
841 DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
842
843 get_user_ret(val, (int *) arg, -EFAULT);
844
845 DPD(2, "val is %x\n", val);
846
847 if (val == 0)
848 return -EIO;
849
850 if (file->f_mode & FMODE_WRITE) {
851 if (wave_out)
852 return -EINVAL; /* too late to change */
853
854 woinst->ossfragshift = val & 0xffff;
855 woinst->numfrags = (val >> 16) & 0xffff;
856 }
857
858 if (file->f_mode & FMODE_READ) {
859 if (wave_in)
860 return -EINVAL; /* too late to change */
861
862 wiinst->ossfragshift = val & 0xffff;
863 wiinst->numfrags = (val >> 16) & 0xffff;
864 }
865
866 break;
867
868//SvL: Uses WAY too much stack
869#ifndef TARGET_OS2
870 case SNDCTL_COPR_LOAD:
871 {
872 copr_buffer buf;
873 u32 i;
874
875 DPF(2, "SNDCTL_COPR_LOAD:\n");
876
877 if (copy_from_user(&buf, (copr_buffer *) arg, sizeof(buf)))
878 return -EFAULT;
879
880 if ((buf.command != 1) && (buf.command != 2))
881 return -EINVAL;
882
883 if (((buf.offs < 0x100) && (buf.command == 2))
884 || (buf.offs < 0x000)
885 || (buf.offs + buf.len > 0x800) || (buf.len > 1000))
886 return -EINVAL;
887
888 if (buf.command == 1) {
889 for (i = 0; i < buf.len; i++)
890
891 ((u32 *) buf.data)[i] = sblive_readptr(wave_dev->card, buf.offs + i, 0);
892 if (copy_to_user((copr_buffer *) arg, &buf, sizeof(buf)))
893 return -EFAULT;
894 } else {
895 for (i = 0; i < buf.len; i++)
896 sblive_writeptr(wave_dev->card, buf.offs + i, 0, ((u32 *) buf.data)[i]);
897 }
898 break;
899 }
900#endif
901 default: /* Default is unrecognized command */
902 DPD(2, "default: %x\n", cmd);
903 return -EINVAL;
904 }
905 return 0;
906}
907
908static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
909{
910 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
911
912 DPF(2, "emu10k1_audio_mmap()\n");
913
914 if (vma_get_pgoff(vma) != 0)
915 return -ENXIO;
916
917 if (vma->vm_flags & VM_WRITE) {
918 struct woinst *woinst = wave_dev->woinst;
919 struct wave_out *wave_out;
920 u32 size;
921 unsigned long flags;
922 int i;
923
924 spin_lock_irqsave(&woinst->lock, flags);
925
926 wave_out = woinst->wave_out;
927
928 if (!wave_out) {
929 calculate_ofrag(woinst);
930
931 if (emu10k1_waveout_open(wave_dev) != CTSTATUS_SUCCESS) {
932 spin_unlock_irqrestore(&woinst->lock, flags);
933 ERROR();
934 return -EINVAL;
935 }
936
937 wave_out = woinst->wave_out;
938
939 /* Now mark the pages as reserved, otherwise remap_page_range doesn't do what we want */
940 for (i = 0; i < wave_out->wavexferbuf->numpages; i++)
941 set_bit(PG_reserved, &mem_map[MAP_NR(wave_out->pagetable[i])].flags);
942 }
943
944 size = vma->vm_end - vma->vm_start;
945
946 if (size > (PAGE_SIZE * wave_out->wavexferbuf->numpages)) {
947 spin_unlock_irqrestore(&woinst->lock, flags);
948 return -EINVAL;
949 }
950
951 for (i = 0; i < wave_out->wavexferbuf->numpages; i++) {
952 if (remap_page_range(vma->vm_start + (i * PAGE_SIZE), virt_to_phys(wave_out->pagetable[i]), PAGE_SIZE, vma->vm_page_prot)) {
953 spin_unlock_irqrestore(&woinst->lock, flags);
954 return -EAGAIN;
955 }
956 }
957
958 woinst->mapped = 1;
959
960 spin_unlock_irqrestore(&woinst->lock, flags);
961 }
962
963 if (vma->vm_flags & VM_READ) {
964 struct wiinst *wiinst = wave_dev->wiinst;
965 unsigned long flags;
966
967 spin_lock_irqsave(&wiinst->lock, flags);
968 wiinst->mapped = 1;
969 spin_unlock_irqrestore(&wiinst->lock, flags);
970 }
971
972 return 0;
973}
974
975static int emu10k1_audio_open(struct inode *inode, struct file *file)
976{
977 int minor = MINOR(inode->i_rdev);
978 struct emu10k1_card *card;
979 struct list_head *entry;
980 struct emu10k1_wavedevice *wave_dev;
981
982 DPF(2, "emu10k1_audio_open()\n");
983
984 /* Check for correct device to open */
985
986 list_for_each(entry, &emu10k1_devs) {
987 card = list_entry(entry, struct emu10k1_card, list);
988
989 if (card->audio1_num == minor || card->audio2_num == minor)
990 break;
991 }
992
993 if (entry == &emu10k1_devs)
994 return -ENODEV;
995
996 MOD_INC_USE_COUNT;
997
998 if ((wave_dev = (struct emu10k1_wavedevice *)
999 kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL)) == NULL) {
1000 ERROR();
1001 MOD_DEC_USE_COUNT;
1002 return -EINVAL;
1003 }
1004
1005 wave_dev->card = card;
1006 wave_dev->wiinst = NULL;
1007 wave_dev->woinst = NULL;
1008 wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT; /* Default */
1009
1010 if (file->f_mode & FMODE_WRITE) {
1011 struct woinst *woinst;
1012
1013 if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
1014 ERROR();
1015 MOD_DEC_USE_COUNT;
1016 return -ENODEV;
1017 }
1018
1019 woinst->wave_fmt.samplingrate = 8000;
1020 woinst->wave_fmt.bitsperchannel = 8;
1021 woinst->wave_fmt.channels = 1;
1022 woinst->ossfragshift = 0;
1023 woinst->fragment_size = 0;
1024 woinst->numfrags = 0;
1025 woinst->device = (card->audio2_num == minor);
1026 woinst->wave_out = NULL;
1027
1028 init_waitqueue_head(&woinst->wait_queue);
1029
1030 woinst->mapped = 0;
1031 woinst->total_copied = 0;
1032 woinst->total_played = 0;
1033 woinst->silence_bytes = 0;
1034 woinst->blocks = 0;
1035 woinst->curpos = 0;
1036 woinst->lock = SPIN_LOCK_UNLOCKED;
1037 wave_dev->woinst = woinst;
1038
1039#ifdef PRIVATE_PCM_VOLUME
1040 {
1041 int i;
1042 int j = -1;
1043
1044 /*
1045 * find out if we've already been in this table
1046 * xmms reopens dsp on every move of slider
1047 * this way we keep the same local pcm for such
1048 * process
1049 */
1050 for (i = 0; i < MAX_PCM_CHANNELS; i++) {
1051 if (sblive_pcm_volume[i].files == current->files)
1052 break;
1053 // here we should select last used memeber
1054 // improve me in case its not sufficient
1055 if (j < 0 && !sblive_pcm_volume[i].opened)
1056 j = i;
1057 }
1058 // current task not found
1059 if (i == MAX_PCM_CHANNELS) {
1060 // add new entry
1061 if (j < 0)
1062 printk("TOO MANY WRITTERS!!!\n");
1063 i = (j >= 0) ? j : 0;
1064 DPD(2, "new pcm private %p\n", current->files);
1065 sblive_pcm_volume[i].files = current->files;
1066 sblive_pcm_volume[i].mixer = 0x6464; // max
1067 sblive_pcm_volume[i].attn_l = 0;
1068 sblive_pcm_volume[i].attn_r = 0;
1069 sblive_pcm_volume[i].channel_l = NUM_G;
1070 sblive_pcm_volume[i].channel_r = NUM_G;
1071 }
1072 sblive_pcm_volume[i].opened++;
1073 }
1074#endif
1075 }
1076
1077 if (file->f_mode & FMODE_READ) {
1078 /* Recording */
1079 struct wiinst *wiinst;
1080
1081 if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
1082 ERROR();
1083 MOD_DEC_USE_COUNT;
1084 return -ENODEV;
1085 }
1086
1087 switch (card->wavein->recsrc) {
1088 case WAVERECORD_AC97:
1089 wiinst->wave_fmt.samplingrate = 8000;
1090 wiinst->wave_fmt.bitsperchannel = 8;
1091 wiinst->wave_fmt.channels = 1;
1092 break;
1093 case WAVERECORD_MIC:
1094 wiinst->wave_fmt.samplingrate = 8000;
1095 wiinst->wave_fmt.bitsperchannel = 8;
1096 wiinst->wave_fmt.channels = 1;
1097 break;
1098 case WAVERECORD_FX:
1099 wiinst->wave_fmt.samplingrate = 48000;
1100 wiinst->wave_fmt.bitsperchannel = 16;
1101 wiinst->wave_fmt.channels = 2;
1102 break;
1103 default:
1104 break;
1105 }
1106
1107 wiinst->recsrc = card->wavein->recsrc;
1108 wiinst->ossfragshift = 0;
1109 wiinst->fragment_size = 0;
1110 wiinst->numfrags = 0;
1111 wiinst->wave_in = NULL;
1112
1113 init_waitqueue_head(&wiinst->wait_queue);
1114
1115 wiinst->mapped = 0;
1116 wiinst->total_recorded = 0;
1117 wiinst->blocks = 0;
1118 wiinst->curpos = 0;
1119 wiinst->lock = SPIN_LOCK_UNLOCKED;
1120 wave_dev->wiinst = wiinst;
1121 }
1122
1123 file->private_data = (void *) wave_dev;
1124
1125 return 0; /* Success? */
1126}
1127
1128static int emu10k1_audio_release(struct inode *inode, struct file *file)
1129{
1130 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1131 struct emu10k1_card *card = wave_dev->card;
1132 unsigned long flags;
1133
1134 DPF(2, "emu10k1_audio_release()\n");
1135
1136 if (file->f_mode & FMODE_WRITE) {
1137 struct woinst *woinst = wave_dev->woinst;
1138 struct wave_out *wave_out;
1139
1140 spin_lock_irqsave(&woinst->lock, flags);
1141
1142 wave_out = woinst->wave_out;
1143
1144 if (wave_out) {
1145 if ((wave_out->state == CARDWAVE_STATE_STARTED)
1146 && !(file->f_flags & O_NONBLOCK)) {
1147 while (!signal_pending(current)
1148 && (woinst->total_played < woinst->total_copied)) {
1149 DPF(4, "Buffer hasn't been totally played, sleep....\n");
1150 spin_unlock_irqrestore(&woinst->lock, flags);
1151 interruptible_sleep_on(&woinst->wait_queue);
1152 spin_lock_irqsave(&woinst->lock, flags);
1153 }
1154 }
1155
1156 if (woinst->mapped && wave_out->pagetable) {
1157 int i;
1158
1159 /* Undo marking the pages as reserved */
1160 for (i = 0; i < woinst->wave_out->wavexferbuf->numpages; i++)
1161 set_bit(PG_reserved, &mem_map[MAP_NR(woinst->wave_out->pagetable[i])].flags);
1162 }
1163
1164 woinst->mapped = 0;
1165 emu10k1_waveout_close(wave_dev);
1166 }
1167#ifdef PRIVATE_PCM_VOLUME
1168 {
1169 int i;
1170
1171 /* mark as closed
1172 * NOTE: structure remains unchanged for next reopen */
1173 for (i = 0; i < MAX_PCM_CHANNELS; i++) {
1174 if (sblive_pcm_volume[i].files == current->files) {
1175 sblive_pcm_volume[i].opened--;
1176 break;
1177 }
1178 }
1179 }
1180#endif
1181 spin_unlock_irqrestore(&woinst->lock, flags);
1182 kfree(wave_dev->woinst);
1183 }
1184
1185 if (file->f_mode & FMODE_READ) {
1186 struct wiinst *wiinst = wave_dev->wiinst;
1187
1188 spin_lock_irqsave(&wiinst->lock, flags);
1189
1190 if (wiinst->wave_in) {
1191 wiinst->mapped = 0;
1192 emu10k1_wavein_close(wave_dev);
1193 }
1194 spin_unlock_irqrestore(&wiinst->lock, flags);
1195 kfree(wave_dev->wiinst);
1196 }
1197
1198 kfree(wave_dev);
1199
1200 wake_up_interruptible(&card->open_wait);
1201 MOD_DEC_USE_COUNT;
1202
1203 return 0;
1204}
1205
1206static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_struct *wait)
1207{
1208 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1209 struct woinst *woinst = wave_dev->woinst;
1210 struct wiinst *wiinst = wave_dev->wiinst;
1211 unsigned int mask = 0;
1212 u32 bytestocopy;
1213 unsigned long flags;
1214
1215 DPF(4, "emu10k1_audio_poll()\n");
1216
1217 if (file->f_mode & FMODE_WRITE)
1218 poll_wait(file, &woinst->wait_queue, wait);
1219
1220 if (file->f_mode & FMODE_READ)
1221 poll_wait(file, &wiinst->wait_queue, wait);
1222
1223 if (file->f_mode & FMODE_WRITE) {
1224 spin_lock_irqsave(&woinst->lock, flags);
1225
1226 if (woinst->wave_out) {
1227 emu10k1_waveout_update(woinst);
1228 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1229
1230 if (bytestocopy >= woinst->fragment_size)
1231 mask |= POLLOUT | POLLWRNORM;
1232 } else
1233 mask |= POLLOUT | POLLWRNORM;
1234
1235 spin_unlock_irqrestore(&woinst->lock, flags);
1236 }
1237
1238 if (file->f_mode & FMODE_READ) {
1239 spin_lock_irqsave(&wiinst->lock, flags);
1240
1241 if (!wiinst->wave_in) {
1242 calculate_ifrag(wiinst);
1243 if (emu10k1_wavein_open(wave_dev) != CTSTATUS_SUCCESS) {
1244 spin_unlock_irqrestore(&wiinst->lock, flags);
1245 return (mask |= POLLERR);
1246 }
1247 }
1248
1249 if (wiinst->wave_in->state != CARDWAVE_STATE_STARTED) {
1250 wave_dev->enablebits |= PCM_ENABLE_INPUT;
1251 emu10k1_wavein_start(wave_dev);
1252 }
1253
1254 emu10k1_wavein_update(wiinst);
1255 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1256
1257 if (bytestocopy >= wiinst->fragment_size)
1258 mask |= POLLIN | POLLRDNORM;
1259
1260 spin_unlock_irqrestore(&wiinst->lock, flags);
1261 }
1262
1263 return mask;
1264}
1265
1266static void calculate_ofrag(struct woinst *woinst)
1267{
1268 u32 fragsize, bytespersec;
1269
1270 if (woinst->fragment_size)
1271 return;
1272
1273 bytespersec = woinst->wave_fmt.channels * (woinst->wave_fmt.bitsperchannel >> 3) * woinst->wave_fmt.samplingrate;
1274
1275 if (!woinst->ossfragshift) {
1276 fragsize = (bytespersec * WAVEOUT_DEFAULTFRAGLEN) / 1000 - 1;
1277
1278 while (fragsize) {
1279 fragsize >>= 1;
1280 woinst->ossfragshift++;
1281 }
1282 }
1283
1284 if (woinst->ossfragshift < WAVEOUT_MINFRAGSHIFT)
1285 woinst->ossfragshift = WAVEOUT_MINFRAGSHIFT;
1286
1287 woinst->fragment_size = 1 << woinst->ossfragshift;
1288
1289 if (!woinst->numfrags) {
1290 u32 numfrags;
1291
1292 numfrags = (bytespersec * WAVEOUT_DEFAULTBUFLEN) / (woinst->fragment_size * 1000) - 1;
1293
1294 woinst->numfrags = 1;
1295
1296 while (numfrags) {
1297 numfrags >>= 1;
1298 woinst->numfrags <<= 1;
1299 }
1300 }
1301
1302 if (woinst->numfrags < MINFRAGS)
1303 woinst->numfrags = MINFRAGS;
1304
1305 if (woinst->numfrags * woinst->fragment_size > WAVEOUT_MAXBUFSIZE) {
1306 woinst->numfrags = WAVEOUT_MAXBUFSIZE / woinst->fragment_size;
1307
1308 if (woinst->numfrags < MINFRAGS) {
1309 woinst->numfrags = MINFRAGS;
1310 woinst->fragment_size = WAVEOUT_MAXBUFSIZE / MINFRAGS;
1311 }
1312
1313 } else if (woinst->numfrags * woinst->fragment_size < WAVEOUT_MINBUFSIZE)
1314 woinst->numfrags = WAVEOUT_MINBUFSIZE / woinst->fragment_size;
1315
1316 DPD(2, " calculated playback fragment_size -> %d\n", woinst->fragment_size);
1317 DPD(2, " calculated playback numfrags -> %d\n", woinst->numfrags);
1318}
1319
1320static void calculate_ifrag(struct wiinst *wiinst)
1321{
1322 u32 fragsize, bytespersec;
1323
1324 if (wiinst->fragment_size)
1325 return;
1326
1327 bytespersec = wiinst->wave_fmt.channels * (wiinst->wave_fmt.bitsperchannel >> 3) * wiinst->wave_fmt.samplingrate;
1328
1329 if (!wiinst->ossfragshift) {
1330 fragsize = (bytespersec * WAVEIN_DEFAULTFRAGLEN) / 1000 - 1;
1331
1332 while (fragsize) {
1333 fragsize >>= 1;
1334 wiinst->ossfragshift++;
1335 }
1336 }
1337
1338 if (wiinst->ossfragshift < WAVEIN_MINFRAGSHIFT)
1339 wiinst->ossfragshift = WAVEIN_MINFRAGSHIFT;
1340
1341 wiinst->fragment_size = 1 << wiinst->ossfragshift;
1342
1343 if (!wiinst->numfrags)
1344 wiinst->numfrags = (bytespersec * WAVEIN_DEFAULTBUFLEN) / (wiinst->fragment_size * 1000) - 1;
1345
1346 if (wiinst->numfrags < MINFRAGS)
1347 wiinst->numfrags = MINFRAGS;
1348
1349 if (wiinst->numfrags * wiinst->fragment_size > WAVEIN_MAXBUFSIZE) {
1350 wiinst->numfrags = WAVEIN_MAXBUFSIZE / wiinst->fragment_size;
1351
1352 if (wiinst->numfrags < MINFRAGS) {
1353 wiinst->numfrags = MINFRAGS;
1354 wiinst->fragment_size = WAVEIN_MAXBUFSIZE / MINFRAGS;
1355 }
1356 } else if (wiinst->numfrags * wiinst->fragment_size < WAVEIN_MINBUFSIZE)
1357 wiinst->numfrags = WAVEIN_MINBUFSIZE / wiinst->fragment_size;
1358
1359 DPD(2, " calculated recording fragment_size -> %d\n", wiinst->fragment_size);
1360 DPD(2, " calculated recording numfrags -> %d\n", wiinst->numfrags);
1361}
1362
1363void emu10k1_wavein_bh(unsigned long refdata)
1364{
1365 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1366 struct wiinst *wiinst = wave_dev->wiinst;
1367 u32 bytestocopy;
1368 unsigned long flags;
1369
1370 spin_lock_irqsave(&wiinst->lock, flags);
1371
1372 if (wiinst->wave_in->state == CARDWAVE_STATE_STOPPED) {
1373 spin_unlock_irqrestore(&wiinst->lock, flags);
1374 return;
1375 }
1376 emu10k1_wavein_update(wiinst);
1377
1378#ifdef TARGET_OS2
1379 OSS32_ProcessIRQ(FALSE, (unsigned long)wave_dev);
1380#endif
1381
1382 if (wiinst->mapped) {
1383 spin_unlock_irqrestore(&wiinst->lock, flags);
1384 return;
1385 }
1386
1387 emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1388
1389 spin_unlock_irqrestore(&wiinst->lock, flags);
1390
1391 if (bytestocopy >= wiinst->fragment_size)
1392 wake_up_interruptible(&wiinst->wait_queue);
1393 else
1394 DPD(4, "Not enough transfer size, %d\n", bytestocopy);
1395
1396 return;
1397}
1398
1399void emu10k1_waveout_bh(unsigned long refdata)
1400{
1401 struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1402 struct woinst *woinst = wave_dev->woinst;
1403 u32 bytestocopy;
1404 unsigned long flags;
1405
1406 spin_lock_irqsave(&woinst->lock, flags);
1407
1408 if (woinst->wave_out->state == CARDWAVE_STATE_STOPPED) {
1409 spin_unlock_irqrestore(&woinst->lock, flags);
1410 return;
1411 }
1412
1413 emu10k1_waveout_update(woinst);
1414
1415 if (woinst->mapped) {
1416 spin_unlock_irqrestore(&woinst->lock, flags);
1417 return;
1418 }
1419
1420 emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1421
1422 if (woinst->wave_out->fill_silence) {
1423 spin_unlock_irqrestore(&woinst->lock, flags);
1424 emu10k1_waveout_fillsilence(woinst);
1425 } else
1426 spin_unlock_irqrestore(&woinst->lock, flags);
1427
1428 if (bytestocopy >= woinst->fragment_size)
1429#ifdef TARGET_OS2
1430 OSS32_ProcessIRQ(TRUE, (unsigned long)wave_dev);
1431#else
1432 wake_up_interruptible(&woinst->wait_queue);
1433#endif
1434 else
1435 DPD(4, "Not enough transfer size -> %x\n", bytestocopy);
1436
1437 return;
1438}
1439
1440#ifdef TARGET_OS2
1441//Hello!?! Use standard C!
1442struct file_operations emu10k1_audio_fops =
1443{
1444 &emu10k1_audio_llseek,
1445 &emu10k1_audio_read, /* read */
1446 &emu10k1_audio_write, /* write */
1447 NULL, /* readdir */
1448 &emu10k1_audio_poll, /* select/poll */
1449 &emu10k1_audio_ioctl,
1450 &emu10k1_audio_mmap, /* mmap */
1451 &emu10k1_audio_open,
1452#if LINUX_VERSION_CODE >= 0x020100
1453 NULL, /* flush */
1454#endif
1455 &emu10k1_audio_release,
1456 NULL, /* fsync */
1457 NULL, /* fasync */
1458 NULL /* check_media_change */
1459};
1460#else
1461struct file_operations emu10k1_audio_fops = {
1462 llseek:emu10k1_audio_llseek,
1463 read:emu10k1_audio_read,
1464 write:emu10k1_audio_write,
1465 poll:emu10k1_audio_poll,
1466 ioctl:emu10k1_audio_ioctl,
1467 mmap:emu10k1_audio_mmap,
1468 open:emu10k1_audio_open,
1469 release:emu10k1_audio_release,
1470};
1471#endif
Note: See TracBrowser for help on using the repository browser.