4 * Device file manager for /dev/audio
8 * Copyright (C) by Hannu Savolainen 1993-1997
10 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11 * Version 2 (June 1991). See the "COPYING" file distributed with this software
15 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
16 * Thomas Sailer : moved several static variables into struct audio_operations
17 * (which is grossly misnamed btw.) because they have the same
18 * lifetime as the rest in there and dynamic allocation saves
20 * Thomas Sailer : use more logical O_NONBLOCK semantics
21 * Daniel Rodriksson: reworked the use of the device specific copy_user
23 * Horst von Brand: Add missing #include <linux/string.h>
26 #include <linux/stddef.h>
27 #include <linux/string.h>
28 #include <linux/kmod.h>
30 #include "sound_config.h"
35 #define NEUTRAL16 0x00
38 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
);
40 static int set_format(int dev
, int fmt
)
42 if (fmt
!= AFMT_QUERY
)
44 audio_devs
[dev
]->local_conversion
= 0;
46 if (!(audio_devs
[dev
]->format_mask
& fmt
)) /* Not supported */
48 if (fmt
== AFMT_MU_LAW
)
51 audio_devs
[dev
]->local_conversion
= CNV_MU_LAW
;
54 fmt
= AFMT_U8
; /* This is always supported */
56 audio_devs
[dev
]->audio_format
= audio_devs
[dev
]->d
->set_bits(dev
, fmt
);
57 audio_devs
[dev
]->local_format
= fmt
;
60 return audio_devs
[dev
]->local_format
;
62 if (audio_devs
[dev
]->local_conversion
)
63 return audio_devs
[dev
]->local_conversion
;
65 return audio_devs
[dev
]->local_format
;
68 int audio_open(int dev
, struct file
*file
)
72 int dev_type
= dev
& 0x0f;
73 int mode
= translate_mode(file
);
77 if (dev_type
== SND_DEV_DSP16
)
82 if (dev
< 0 || dev
>= num_audiodevs
)
85 if ((ret
= DMAbuf_open(dev
, mode
)) < 0)
88 if (audio_devs
[dev
]->coproc
)
90 if ((ret
= audio_devs
[dev
]->coproc
->
91 open(audio_devs
[dev
]->coproc
->devc
, COPR_PCM
)) < 0)
93 audio_release(dev
, file
);
94 printk(KERN_WARNING
"Sound: Can't access coprocessor device\n");
99 audio_devs
[dev
]->local_conversion
= 0;
101 if (dev_type
== SND_DEV_AUDIO
)
102 set_format(dev
, AFMT_MU_LAW
);
104 set_format(dev
, bits
);
106 audio_devs
[dev
]->audio_mode
= AM_NONE
;
112 static void sync_output(int dev
)
116 struct dma_buffparms
*dmap
= audio_devs
[dev
]->dmap_out
;
118 if (dmap
->fragment_size
<= 0)
120 dmap
->flags
|= DMA_POST
;
122 /* Align the write pointer with fragment boundaries */
124 if ((l
= dmap
->user_counter
% dmap
->fragment_size
) > 0)
127 unsigned long offs
= dmap
->user_counter
% dmap
->bytes_in_use
;
129 len
= dmap
->fragment_size
- l
;
130 memset(dmap
->raw_buf
+ offs
, dmap
->neutral_byte
, len
);
131 DMAbuf_move_wrpointer(dev
, len
);
135 * Clean all unused buffer fragments.
139 dmap
->flags
|= DMA_POST
;
141 for (i
= dmap
->qlen
+ 1; i
< dmap
->nbufs
; i
++)
143 p
= (p
+ 1) % dmap
->nbufs
;
144 if (((dmap
->raw_buf
+ p
* dmap
->fragment_size
) + dmap
->fragment_size
) >
145 (dmap
->raw_buf
+ dmap
->buffsize
))
146 printk(KERN_ERR
"audio: Buffer error 2\n");
148 memset(dmap
->raw_buf
+ p
* dmap
->fragment_size
,
150 dmap
->fragment_size
);
153 dmap
->flags
|= DMA_DIRTY
;
156 void audio_release(int dev
, struct file
*file
)
158 int mode
= translate_mode(file
);
163 * We do this in DMAbuf_release(). Why are we doing it
164 * here? Why don't we test the file mode before setting
165 * both flags? DMAbuf_release() does.
166 * ...pester...pester...pester...
168 audio_devs
[dev
]->dmap_out
->closing
= 1;
169 audio_devs
[dev
]->dmap_in
->closing
= 1;
172 * We need to make sure we allocated the dmap_out buffer
173 * before we go mucking around with it in sync_output().
175 if (mode
& OPEN_WRITE
)
178 if (audio_devs
[dev
]->coproc
)
179 audio_devs
[dev
]->coproc
->close(audio_devs
[dev
]->coproc
->devc
, COPR_PCM
);
180 DMAbuf_release(dev
, mode
);
183 static void translate_bytes(const unsigned char *table
, unsigned char *buff
, int n
)
190 for (i
= 0; i
< n
; ++i
)
191 buff
[i
] = table
[buff
[i
]];
194 int audio_write(int dev
, struct file
*file
, const char *buf
, int count
)
196 int c
, p
, l
, buf_size
, used
, returned
;
208 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
211 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
212 audio_devs
[dev
]->audio_mode
|= AM_WRITE
;
214 audio_devs
[dev
]->audio_mode
= AM_WRITE
;
216 if (!count
) /* Flush output */
224 if ((err
= DMAbuf_getwrbuffer(dev
, &dma_buf
, &buf_size
, !!(file
->f_flags
& O_NONBLOCK
))) < 0)
226 /* Handle nonblocking mode */
227 if ((file
->f_flags
& O_NONBLOCK
) && err
== -EAGAIN
)
228 return p
? p
: -EAGAIN
; /* No more space. Return # of accepted bytes */
238 if (!audio_devs
[dev
]->d
->copy_user
)
241 (audio_devs
[dev
]->dmap_out
->raw_buf
+ audio_devs
[dev
]->dmap_out
->buffsize
))
243 printk(KERN_ERR
"audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf
, l
, (long) audio_devs
[dev
]->dmap_out
->raw_buf
, (int) audio_devs
[dev
]->dmap_out
->buffsize
);
246 if (dma_buf
< audio_devs
[dev
]->dmap_out
->raw_buf
)
248 printk(KERN_ERR
"audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf
, (long) audio_devs
[dev
]->dmap_out
->raw_buf
);
251 if(copy_from_user(dma_buf
, &(buf
)[p
], l
))
254 else audio_devs
[dev
]->d
->copy_user (dev
,
262 if (audio_devs
[dev
]->local_conversion
& CNV_MU_LAW
)
265 * This just allows interrupts while the conversion is running
268 translate_bytes(ulaw_dsp
, (unsigned char *) dma_buf
, l
);
272 DMAbuf_move_wrpointer(dev
, l
);
279 int audio_read(int dev
, struct file
*file
, char *buf
, int count
)
289 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
292 if ((audio_devs
[dev
]->audio_mode
& AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
295 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
296 audio_devs
[dev
]->audio_mode
|= AM_READ
;
298 audio_devs
[dev
]->audio_mode
= AM_READ
;
302 if ((buf_no
= DMAbuf_getrdbuffer(dev
, &dmabuf
, &l
, !!(file
->f_flags
& O_NONBLOCK
))) < 0)
305 * Nonblocking mode handling. Return current # of bytes
308 if (p
> 0) /* Avoid throwing away data */
309 return p
; /* Return it instead */
311 if ((file
->f_flags
& O_NONBLOCK
) && buf_no
== -EAGAIN
)
320 * Insert any local processing here.
323 if (audio_devs
[dev
]->local_conversion
& CNV_MU_LAW
)
326 * This just allows interrupts while the conversion is running
330 translate_bytes(dsp_ulaw
, (unsigned char *) dmabuf
, l
);
334 char *fixit
= dmabuf
;
336 if(copy_to_user(&(buf
)[p
], fixit
, l
))
340 DMAbuf_rmchars(dev
, buf_no
, l
);
349 int audio_ioctl(int dev
, struct file
*file
, unsigned int cmd
, caddr_t arg
)
353 struct dma_buffparms
*dmap
;
357 if (_IOC_TYPE(cmd
) == 'C') {
358 if (audio_devs
[dev
]->coproc
) /* Coprocessor ioctl */
359 return audio_devs
[dev
]->coproc
->ioctl(audio_devs
[dev
]->coproc
->devc
, cmd
, arg
, 0);
361 printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
366 case SNDCTL_DSP_SYNC
:
367 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
369 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
376 case SNDCTL_DSP_POST
:
377 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
379 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
381 audio_devs
[dev
]->dmap_out
->flags
|= DMA_POST
| DMA_DIRTY
;
383 dma_ioctl(dev
, SNDCTL_DSP_POST
, (caddr_t
) 0);
386 case SNDCTL_DSP_RESET
:
387 audio_devs
[dev
]->audio_mode
= AM_NONE
;
391 case SNDCTL_DSP_GETFMTS
:
392 val
= audio_devs
[dev
]->format_mask
| AFMT_MU_LAW
;
395 case SNDCTL_DSP_SETFMT
:
396 if (get_user(val
, (int *)arg
))
398 val
= set_format(dev
, val
);
401 case SNDCTL_DSP_GETISPACE
:
402 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
404 if ((audio_devs
[dev
]->audio_mode
& AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
406 return dma_ioctl(dev
, cmd
, arg
);
408 case SNDCTL_DSP_GETOSPACE
:
409 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
411 if ((audio_devs
[dev
]->audio_mode
& AM_READ
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
413 return dma_ioctl(dev
, cmd
, arg
);
415 case SNDCTL_DSP_NONBLOCK
:
416 file
->f_flags
|= O_NONBLOCK
;
419 case SNDCTL_DSP_GETCAPS
:
420 val
= 1 | DSP_CAP_MMAP
; /* Revision level of this ioctl() */
421 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
422 audio_devs
[dev
]->open_mode
== OPEN_READWRITE
)
423 val
|= DSP_CAP_DUPLEX
;
424 if (audio_devs
[dev
]->coproc
)
425 val
|= DSP_CAP_COPROC
;
426 if (audio_devs
[dev
]->d
->local_qlen
) /* Device has hidden buffers */
427 val
|= DSP_CAP_BATCH
;
428 if (audio_devs
[dev
]->d
->trigger
) /* Supports SETTRIGGER */
429 val
|= DSP_CAP_TRIGGER
;
432 case SOUND_PCM_WRITE_RATE
:
433 if (get_user(val
, (int *)arg
))
435 val
= audio_devs
[dev
]->d
->set_speed(dev
, val
);
438 case SOUND_PCM_READ_RATE
:
439 val
= audio_devs
[dev
]->d
->set_speed(dev
, 0);
442 case SNDCTL_DSP_STEREO
:
443 if (get_user(val
, (int *)arg
))
445 if (val
> 1 || val
< 0)
447 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
+ 1) - 1;
450 case SOUND_PCM_WRITE_CHANNELS
:
451 if (get_user(val
, (int *)arg
))
453 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
);
456 case SOUND_PCM_READ_CHANNELS
:
457 val
= audio_devs
[dev
]->d
->set_channels(dev
, 0);
460 case SOUND_PCM_READ_BITS
:
461 val
= audio_devs
[dev
]->d
->set_bits(dev
, 0);
464 case SNDCTL_DSP_SETDUPLEX
:
465 if (audio_devs
[dev
]->open_mode
!= OPEN_READWRITE
)
467 return (audio_devs
[dev
]->flags
& DMA_DUPLEX
) ? 0 : -EIO
;
469 case SNDCTL_DSP_PROFILE
:
470 if (get_user(val
, (int *)arg
))
472 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
473 audio_devs
[dev
]->dmap_out
->applic_profile
= val
;
474 if (audio_devs
[dev
]->open_mode
& OPEN_READ
)
475 audio_devs
[dev
]->dmap_in
->applic_profile
= val
;
478 case SNDCTL_DSP_GETODELAY
:
479 dmap
= audio_devs
[dev
]->dmap_out
;
480 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
482 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
490 /* Compute number of bytes that have been played */
491 count
= DMAbuf_get_buffer_pointer (dev
, dmap
, DMODE_OUTPUT
);
492 if (count
< dmap
->fragment_size
&& dmap
->qhead
!= 0)
493 count
+= dmap
->bytes_in_use
; /* Pointer wrap not handled yet */
494 count
+= dmap
->byte_counter
;
496 /* Substract current count from the number of bytes written by app */
497 count
= dmap
->user_counter
- count
;
500 restore_flags (flags
);
505 return dma_ioctl(dev
, cmd
, arg
);
507 return put_user(val
, (int *)arg
);
510 void audio_init_devices(void)
513 * NOTE! This routine could be called several times during boot.
517 void reorganize_buffers(int dev
, struct dma_buffparms
*dmap
, int recording
)
520 * This routine breaks the physical device buffers to logical ones.
523 struct audio_operations
*dsp_dev
= audio_devs
[dev
];
526 unsigned sr
, nc
, sz
, bsz
;
528 sr
= dsp_dev
->d
->set_speed(dev
, 0);
529 nc
= dsp_dev
->d
->set_channels(dev
, 0);
530 sz
= dsp_dev
->d
->set_bits(dev
, 0);
533 dmap
->neutral_byte
= NEUTRAL8
;
535 dmap
->neutral_byte
= NEUTRAL16
;
537 if (sr
< 1 || nc
< 1 || sz
< 1)
539 /* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
540 sr
= DSP_DEFAULT_SPEED
;
547 sz
/= 8; /* #bits -> #bytes */
548 dmap
->data_rate
= sz
;
550 if (!dmap
->needs_reorg
)
552 dmap
->needs_reorg
= 0;
554 if (dmap
->fragment_size
== 0)
556 /* Compute the fragment size using the default algorithm */
559 * Compute a buffer size for time not exceeding 1 second.
560 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
561 * of sound (using the current speed, sample size and #channels).
564 bsz
= dmap
->buffsize
;
568 if (bsz
== dmap
->buffsize
)
569 bsz
/= 2; /* Needs at least 2 buffers */
572 * Split the computed fragment to smaller parts. After 3.5a9
573 * the default subdivision is 4 which should give better
574 * results when recording.
577 if (dmap
->subdivision
== 0) /* Not already set */
579 dmap
->subdivision
= 4; /* Init to the default value */
581 if ((bsz
/ dmap
->subdivision
) > 4096)
582 dmap
->subdivision
*= 2;
583 if ((bsz
/ dmap
->subdivision
) < 4096)
584 dmap
->subdivision
= 1;
586 bsz
/= dmap
->subdivision
;
589 bsz
= 16; /* Just a sanity check */
591 dmap
->fragment_size
= bsz
;
596 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
597 * the buffer size computation has already been done.
599 if (dmap
->fragment_size
> (dmap
->buffsize
/ 2))
600 dmap
->fragment_size
= (dmap
->buffsize
/ 2);
601 bsz
= dmap
->fragment_size
;
604 if (audio_devs
[dev
]->min_fragment
)
605 if (bsz
< (1 << audio_devs
[dev
]->min_fragment
))
606 bsz
= 1 << audio_devs
[dev
]->min_fragment
;
607 if (audio_devs
[dev
]->max_fragment
)
608 if (bsz
> (1 << audio_devs
[dev
]->max_fragment
))
609 bsz
= 1 << audio_devs
[dev
]->max_fragment
;
610 bsz
&= ~0x07; /* Force size which is multiple of 8 bytes */
611 #ifdef OS_DMA_ALIGN_CHECK
612 OS_DMA_ALIGN_CHECK(bsz
);
615 n
= dmap
->buffsize
/ bsz
;
616 if (n
> MAX_SUB_BUFFERS
)
618 if (n
> dmap
->max_fragments
)
619 n
= dmap
->max_fragments
;
627 dmap
->bytes_in_use
= n
* bsz
;
628 dmap
->fragment_size
= bsz
;
629 dmap
->max_byte_counter
= (dmap
->data_rate
* 60 * 60) +
630 dmap
->bytes_in_use
; /* Approximately one hour */
634 memset(dmap
->raw_buf
, dmap
->neutral_byte
, dmap
->bytes_in_use
);
637 for (i
= 0; i
< dmap
->nbufs
; i
++)
642 dmap
->flags
|= DMA_ALLOC_DONE
| DMA_EMPTY
;
645 static int dma_subdivide(int dev
, struct dma_buffparms
*dmap
, int fact
)
649 fact
= dmap
->subdivision
;
654 if (dmap
->subdivision
!= 0 || dmap
->fragment_size
) /* Too late to change */
657 if (fact
> MAX_REALTIME_FACTOR
)
660 if (fact
!= 1 && fact
!= 2 && fact
!= 4 && fact
!= 8 && fact
!= 16)
663 dmap
->subdivision
= fact
;
667 static int dma_set_fragment(int dev
, struct dma_buffparms
*dmap
, int fact
)
674 if (dmap
->subdivision
!= 0 ||
675 dmap
->fragment_size
) /* Too late to change */
678 bytes
= fact
& 0xffff;
679 count
= (fact
>> 16) & 0x7fff;
682 count
= MAX_SUB_BUFFERS
;
683 else if (count
< MAX_SUB_BUFFERS
)
686 if (bytes
< 4 || bytes
> 17) /* <16 || > 512k */
692 if (audio_devs
[dev
]->min_fragment
> 0)
693 if (bytes
< audio_devs
[dev
]->min_fragment
)
694 bytes
= audio_devs
[dev
]->min_fragment
;
696 if (audio_devs
[dev
]->max_fragment
> 0)
697 if (bytes
> audio_devs
[dev
]->max_fragment
)
698 bytes
= audio_devs
[dev
]->max_fragment
;
700 #ifdef OS_DMA_MINBITS
701 if (bytes
< OS_DMA_MINBITS
)
702 bytes
= OS_DMA_MINBITS
;
705 dmap
->fragment_size
= (1 << bytes
);
706 dmap
->max_fragments
= count
;
708 if (dmap
->fragment_size
> dmap
->buffsize
)
709 dmap
->fragment_size
= dmap
->buffsize
;
711 if (dmap
->fragment_size
== dmap
->buffsize
&&
712 audio_devs
[dev
]->flags
& DMA_AUTOMODE
)
713 dmap
->fragment_size
/= 2; /* Needs at least 2 buffers */
715 dmap
->subdivision
= 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
716 return bytes
| ((count
- 1) << 16);
719 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
)
721 struct dma_buffparms
*dmap_out
= audio_devs
[dev
]->dmap_out
;
722 struct dma_buffparms
*dmap_in
= audio_devs
[dev
]->dmap_in
;
723 struct dma_buffparms
*dmap
;
726 int fact
, ret
, changed
, bits
, count
, err
;
731 case SNDCTL_DSP_SUBDIVIDE
:
733 if (get_user(fact
, (int *)arg
))
735 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
736 ret
= dma_subdivide(dev
, dmap_out
, fact
);
739 if (audio_devs
[dev
]->open_mode
!= OPEN_WRITE
||
740 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
741 audio_devs
[dev
]->open_mode
& OPEN_READ
))
742 ret
= dma_subdivide(dev
, dmap_in
, fact
);
747 case SNDCTL_DSP_GETISPACE
:
748 case SNDCTL_DSP_GETOSPACE
:
750 if (cmd
== SNDCTL_DSP_GETISPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_READ
))
752 if (cmd
== SNDCTL_DSP_GETOSPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
754 if (cmd
== SNDCTL_DSP_GETISPACE
&& audio_devs
[dev
]->flags
& DMA_DUPLEX
)
756 if (dmap
->mapping_flags
& DMA_MAP_MAPPED
)
758 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
759 reorganize_buffers(dev
, dmap
, (cmd
== SNDCTL_DSP_GETISPACE
));
760 info
.fragstotal
= dmap
->nbufs
;
761 if (cmd
== SNDCTL_DSP_GETISPACE
)
762 info
.fragments
= dmap
->qlen
;
765 if (!DMAbuf_space_in_queue(dev
))
769 info
.fragments
= DMAbuf_space_in_queue(dev
);
770 if (audio_devs
[dev
]->d
->local_qlen
)
772 int tmp
= audio_devs
[dev
]->d
->local_qlen(dev
);
773 if (tmp
&& info
.fragments
)
775 * This buffer has been counted twice
777 info
.fragments
-= tmp
;
781 if (info
.fragments
< 0)
783 else if (info
.fragments
> dmap
->nbufs
)
784 info
.fragments
= dmap
->nbufs
;
786 info
.fragsize
= dmap
->fragment_size
;
787 info
.bytes
= info
.fragments
* dmap
->fragment_size
;
789 if (cmd
== SNDCTL_DSP_GETISPACE
&& dmap
->qlen
)
790 info
.bytes
-= dmap
->counts
[dmap
->qhead
];
793 info
.fragments
= info
.bytes
/ dmap
->fragment_size
;
794 info
.bytes
-= dmap
->user_counter
% dmap
->fragment_size
;
796 if (copy_to_user(arg
, &info
, sizeof(info
)))
800 case SNDCTL_DSP_SETTRIGGER
:
801 if (get_user(bits
, (int *)arg
))
803 bits
&= audio_devs
[dev
]->open_mode
;
804 if (audio_devs
[dev
]->d
->trigger
== NULL
)
806 if (!(audio_devs
[dev
]->flags
& DMA_DUPLEX
) && (bits
& PCM_ENABLE_INPUT
) &&
807 (bits
& PCM_ENABLE_OUTPUT
))
811 changed
= audio_devs
[dev
]->enable_bits
^ bits
;
812 if ((changed
& bits
) & PCM_ENABLE_INPUT
&& audio_devs
[dev
]->go
)
814 reorganize_buffers(dev
, dmap_in
, 1);
815 if ((err
= audio_devs
[dev
]->d
->prepare_for_input(dev
,
816 dmap_in
->fragment_size
, dmap_in
->nbufs
)) < 0) {
817 restore_flags(flags
);
820 dmap_in
->dma_mode
= DMODE_INPUT
;
821 audio_devs
[dev
]->enable_bits
= bits
;
822 DMAbuf_activate_recording(dev
, dmap_in
);
824 if ((changed
& bits
) & PCM_ENABLE_OUTPUT
&&
825 (dmap_out
->mapping_flags
& DMA_MAP_MAPPED
|| dmap_out
->qlen
> 0) &&
828 if (!(dmap_out
->flags
& DMA_ALLOC_DONE
))
829 reorganize_buffers(dev
, dmap_out
, 0);
830 dmap_out
->dma_mode
= DMODE_OUTPUT
;
831 audio_devs
[dev
]->enable_bits
= bits
;
832 dmap_out
->counts
[dmap_out
->qhead
] = dmap_out
->fragment_size
;
833 DMAbuf_launch_output(dev
, dmap_out
);
835 audio_devs
[dev
]->enable_bits
= bits
;
837 if (changed
&& audio_devs
[dev
]->d
->trigger
)
838 audio_devs
[dev
]->d
->trigger(dev
, bits
* audio_devs
[dev
]->go
);
840 restore_flags(flags
);
841 /* Falls through... */
843 case SNDCTL_DSP_GETTRIGGER
:
844 ret
= audio_devs
[dev
]->enable_bits
;
847 case SNDCTL_DSP_SETSYNCRO
:
848 if (!audio_devs
[dev
]->d
->trigger
)
850 audio_devs
[dev
]->d
->trigger(dev
, 0);
851 audio_devs
[dev
]->go
= 0;
854 case SNDCTL_DSP_GETIPTR
:
855 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
859 cinfo
.bytes
= dmap_in
->byte_counter
;
860 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_in
, DMODE_INPUT
) & ~3;
861 if (cinfo
.ptr
< dmap_in
->fragment_size
&& dmap_in
->qtail
!= 0)
862 cinfo
.bytes
+= dmap_in
->bytes_in_use
; /* Pointer wrap not handled yet */
863 cinfo
.blocks
= dmap_in
->qlen
;
864 cinfo
.bytes
+= cinfo
.ptr
;
865 if (dmap_in
->mapping_flags
& DMA_MAP_MAPPED
)
866 dmap_in
->qlen
= 0; /* Reset interrupt counter */
867 restore_flags(flags
);
868 if (copy_to_user(arg
, &cinfo
, sizeof(cinfo
)))
872 case SNDCTL_DSP_GETOPTR
:
873 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
878 cinfo
.bytes
= dmap_out
->byte_counter
;
879 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_out
, DMODE_OUTPUT
) & ~3;
880 if (cinfo
.ptr
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
881 cinfo
.bytes
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
882 cinfo
.blocks
= dmap_out
->qlen
;
883 cinfo
.bytes
+= cinfo
.ptr
;
884 if (dmap_out
->mapping_flags
& DMA_MAP_MAPPED
)
885 dmap_out
->qlen
= 0; /* Reset interrupt counter */
886 restore_flags(flags
);
887 if (copy_to_user(arg
, &cinfo
, sizeof(cinfo
)))
891 case SNDCTL_DSP_GETODELAY
:
892 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
894 if (!(dmap_out
->flags
& DMA_ALLOC_DONE
))
901 /* Compute number of bytes that have been played */
902 count
= DMAbuf_get_buffer_pointer (dev
, dmap_out
, DMODE_OUTPUT
);
903 if (count
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
904 count
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
905 count
+= dmap_out
->byte_counter
;
906 /* Substract current count from the number of bytes written by app */
907 count
= dmap_out
->user_counter
- count
;
910 restore_flags (flags
);
914 case SNDCTL_DSP_POST
:
915 if (audio_devs
[dev
]->dmap_out
->qlen
> 0)
916 if (!(audio_devs
[dev
]->dmap_out
->flags
& DMA_ACTIVE
))
917 DMAbuf_launch_output(dev
, audio_devs
[dev
]->dmap_out
);
920 case SNDCTL_DSP_GETBLKSIZE
:
922 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
923 reorganize_buffers(dev
, dmap_out
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
924 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
925 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
926 audio_devs
[dev
]->open_mode
& OPEN_READ
))
927 reorganize_buffers(dev
, dmap_in
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
928 if (audio_devs
[dev
]->open_mode
== OPEN_READ
)
930 ret
= dmap
->fragment_size
;
933 case SNDCTL_DSP_SETFRAGMENT
:
935 if (get_user(fact
, (int *)arg
))
937 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
938 ret
= dma_set_fragment(dev
, dmap_out
, fact
);
941 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
942 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
943 audio_devs
[dev
]->open_mode
& OPEN_READ
))
944 ret
= dma_set_fragment(dev
, dmap_in
, fact
);
947 if (!arg
) /* don't know what this is good for, but preserve old semantics */
952 if (!audio_devs
[dev
]->d
->ioctl
)
954 return audio_devs
[dev
]->d
->ioctl(dev
, cmd
, arg
);
956 return put_user(ret
, (int *)arg
);