source: sbliveos2/trunk/sblive/audio.c@ 777

Last change on this file since 777 was 153, checked in by sandervl, 25 years ago

update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.8 KB
Line 
1/* $Id: audio.c 153 2000-07-23 16:21:57Z sandervl $ */
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.