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/config.h>
27 #include <linux/stddef.h>
28 #include <linux/string.h>
29 #include <linux/kmod.h>
31 #include "sound_config.h"
38 #define NEUTRAL16 0x00
41 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
);
43 static int set_format(int dev
, int fmt
)
45 if (fmt
!= AFMT_QUERY
)
47 audio_devs
[dev
]->local_conversion
= 0;
49 if (!(audio_devs
[dev
]->format_mask
& fmt
)) /* Not supported */
51 if (fmt
== AFMT_MU_LAW
)
54 audio_devs
[dev
]->local_conversion
= CNV_MU_LAW
;
57 fmt
= AFMT_U8
; /* This is always supported */
59 audio_devs
[dev
]->audio_format
= audio_devs
[dev
]->d
->set_bits(dev
, fmt
);
60 audio_devs
[dev
]->local_format
= fmt
;
63 return audio_devs
[dev
]->local_format
;
65 if (audio_devs
[dev
]->local_conversion
)
66 return audio_devs
[dev
]->local_conversion
;
68 return audio_devs
[dev
]->local_format
;
71 int audio_open(int dev
, struct file
*file
)
75 int dev_type
= dev
& 0x0f;
76 int mode
= translate_mode(file
);
80 if (dev_type
== SND_DEV_DSP16
)
85 if (dev
< 0 || dev
>= num_audiodevs
)
88 if ((ret
= DMAbuf_open(dev
, mode
)) < 0)
91 if (audio_devs
[dev
]->coproc
)
93 if ((ret
= audio_devs
[dev
]->coproc
->
94 open(audio_devs
[dev
]->coproc
->devc
, COPR_PCM
)) < 0)
96 audio_release(dev
, file
);
97 printk(KERN_WARNING
"Sound: Can't access coprocessor device\n");
102 audio_devs
[dev
]->local_conversion
= 0;
104 if (dev_type
== SND_DEV_AUDIO
)
105 set_format(dev
, AFMT_MU_LAW
);
107 set_format(dev
, bits
);
109 audio_devs
[dev
]->audio_mode
= AM_NONE
;
115 static void sync_output(int dev
)
119 struct dma_buffparms
*dmap
= audio_devs
[dev
]->dmap_out
;
121 if (dmap
->fragment_size
<= 0)
123 dmap
->flags
|= DMA_POST
;
125 /* Align the write pointer with fragment boundaries */
127 if ((l
= dmap
->user_counter
% dmap
->fragment_size
) > 0)
130 unsigned long offs
= dmap
->user_counter
% dmap
->bytes_in_use
;
132 len
= dmap
->fragment_size
- l
;
133 memset(dmap
->raw_buf
+ offs
, dmap
->neutral_byte
, len
);
134 DMAbuf_move_wrpointer(dev
, len
);
138 * Clean all unused buffer fragments.
142 dmap
->flags
|= DMA_POST
;
144 for (i
= dmap
->qlen
+ 1; i
< dmap
->nbufs
; i
++)
146 p
= (p
+ 1) % dmap
->nbufs
;
147 if (((dmap
->raw_buf
+ p
* dmap
->fragment_size
) + dmap
->fragment_size
) >
148 (dmap
->raw_buf
+ dmap
->buffsize
))
149 printk(KERN_ERR
"audio: Buffer error 2\n");
151 memset(dmap
->raw_buf
+ p
* dmap
->fragment_size
,
153 dmap
->fragment_size
);
156 dmap
->flags
|= DMA_DIRTY
;
159 void audio_release(int dev
, struct file
*file
)
161 int mode
= translate_mode(file
);
166 * We do this in DMAbuf_release(). Why are we doing it
167 * here? Why don't we test the file mode before setting
168 * both flags? DMAbuf_release() does.
169 * ...pester...pester...pester...
171 audio_devs
[dev
]->dmap_out
->closing
= 1;
172 audio_devs
[dev
]->dmap_in
->closing
= 1;
175 * We need to make sure we allocated the dmap_out buffer
176 * before we go mucking around with it in sync_output().
178 if (mode
& OPEN_WRITE
)
181 if (audio_devs
[dev
]->coproc
)
182 audio_devs
[dev
]->coproc
->close(audio_devs
[dev
]->coproc
->devc
, COPR_PCM
);
183 DMAbuf_release(dev
, mode
);
186 static void translate_bytes(const unsigned char *table
, unsigned char *buff
, int n
)
193 for (i
= 0; i
< n
; ++i
)
194 buff
[i
] = table
[buff
[i
]];
197 int audio_write(int dev
, struct file
*file
, const char *buf
, int count
)
199 int c
, p
, l
, buf_size
, used
, returned
;
211 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
214 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
215 audio_devs
[dev
]->audio_mode
|= AM_WRITE
;
217 audio_devs
[dev
]->audio_mode
= AM_WRITE
;
219 if (!count
) /* Flush output */
227 if ((err
= DMAbuf_getwrbuffer(dev
, &dma_buf
, &buf_size
, !!(file
->f_flags
& O_NONBLOCK
))) < 0)
229 /* Handle nonblocking mode */
230 if ((file
->f_flags
& O_NONBLOCK
) && err
== -EAGAIN
)
231 return p
; /* No more space. Return # of accepted bytes */
241 if (!audio_devs
[dev
]->d
->copy_user
)
244 (audio_devs
[dev
]->dmap_out
->raw_buf
+ audio_devs
[dev
]->dmap_out
->buffsize
))
246 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
);
249 if (dma_buf
< audio_devs
[dev
]->dmap_out
->raw_buf
)
251 printk(KERN_ERR
"audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf
, (long) audio_devs
[dev
]->dmap_out
->raw_buf
);
254 if(copy_from_user(dma_buf
, &(buf
)[p
], l
))
257 else audio_devs
[dev
]->d
->copy_user (dev
,
265 if (audio_devs
[dev
]->local_conversion
& CNV_MU_LAW
)
268 * This just allows interrupts while the conversion is running
271 translate_bytes(ulaw_dsp
, (unsigned char *) dma_buf
, l
);
275 DMAbuf_move_wrpointer(dev
, l
);
282 int audio_read(int dev
, struct file
*file
, char *buf
, int count
)
292 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
295 if ((audio_devs
[dev
]->audio_mode
& AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
298 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
299 audio_devs
[dev
]->audio_mode
|= AM_READ
;
301 audio_devs
[dev
]->audio_mode
= AM_READ
;
305 if ((buf_no
= DMAbuf_getrdbuffer(dev
, &dmabuf
, &l
, !!(file
->f_flags
& O_NONBLOCK
))) < 0)
308 * Nonblocking mode handling. Return current # of bytes
311 if ((file
->f_flags
& O_NONBLOCK
) && buf_no
== -EAGAIN
)
314 if (p
> 0) /* Avoid throwing away data */
315 return p
; /* Return it instead */
323 * Insert any local processing here.
326 if (audio_devs
[dev
]->local_conversion
& CNV_MU_LAW
)
329 * This just allows interrupts while the conversion is running
333 translate_bytes(dsp_ulaw
, (unsigned char *) dmabuf
, l
);
337 char *fixit
= dmabuf
;
339 if(copy_to_user(&(buf
)[p
], fixit
, l
))
343 DMAbuf_rmchars(dev
, buf_no
, l
);
352 int audio_ioctl(int dev
, struct file
*file
, unsigned int cmd
, caddr_t arg
)
356 struct dma_buffparms
*dmap
;
360 if (_IOC_TYPE(cmd
) == 'C') {
361 if (audio_devs
[dev
]->coproc
) /* Coprocessor ioctl */
362 return audio_devs
[dev
]->coproc
->ioctl(audio_devs
[dev
]->coproc
->devc
, cmd
, arg
, 0);
364 printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
369 case SNDCTL_DSP_SYNC
:
370 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
372 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
379 case SNDCTL_DSP_POST
:
380 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
382 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
384 audio_devs
[dev
]->dmap_out
->flags
|= DMA_POST
| DMA_DIRTY
;
386 dma_ioctl(dev
, SNDCTL_DSP_POST
, (caddr_t
) 0);
389 case SNDCTL_DSP_RESET
:
390 audio_devs
[dev
]->audio_mode
= AM_NONE
;
394 case SNDCTL_DSP_GETFMTS
:
395 val
= audio_devs
[dev
]->format_mask
| AFMT_MU_LAW
;
398 case SNDCTL_DSP_SETFMT
:
399 if (get_user(val
, (int *)arg
))
401 val
= set_format(dev
, val
);
404 case SNDCTL_DSP_GETISPACE
:
405 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
407 if ((audio_devs
[dev
]->audio_mode
& AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
409 return dma_ioctl(dev
, cmd
, arg
);
411 case SNDCTL_DSP_GETOSPACE
:
412 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
414 if ((audio_devs
[dev
]->audio_mode
& AM_READ
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
416 return dma_ioctl(dev
, cmd
, arg
);
418 case SNDCTL_DSP_NONBLOCK
:
419 file
->f_flags
|= O_NONBLOCK
;
422 case SNDCTL_DSP_GETCAPS
:
423 val
= 1 | DSP_CAP_MMAP
; /* Revision level of this ioctl() */
424 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
425 audio_devs
[dev
]->open_mode
== OPEN_READWRITE
)
426 val
|= DSP_CAP_DUPLEX
;
427 if (audio_devs
[dev
]->coproc
)
428 val
|= DSP_CAP_COPROC
;
429 if (audio_devs
[dev
]->d
->local_qlen
) /* Device has hidden buffers */
430 val
|= DSP_CAP_BATCH
;
431 if (audio_devs
[dev
]->d
->trigger
) /* Supports SETTRIGGER */
432 val
|= DSP_CAP_TRIGGER
;
435 case SOUND_PCM_WRITE_RATE
:
436 if (get_user(val
, (int *)arg
))
438 val
= audio_devs
[dev
]->d
->set_speed(dev
, val
);
441 case SOUND_PCM_READ_RATE
:
442 val
= audio_devs
[dev
]->d
->set_speed(dev
, 0);
445 case SNDCTL_DSP_STEREO
:
446 if (get_user(val
, (int *)arg
))
448 if (val
> 1 || val
< 0)
450 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
+ 1) - 1;
453 case SOUND_PCM_WRITE_CHANNELS
:
454 if (get_user(val
, (int *)arg
))
456 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
);
459 case SOUND_PCM_READ_CHANNELS
:
460 val
= audio_devs
[dev
]->d
->set_channels(dev
, 0);
463 case SOUND_PCM_READ_BITS
:
464 val
= audio_devs
[dev
]->d
->set_bits(dev
, 0);
467 case SNDCTL_DSP_SETDUPLEX
:
468 if (audio_devs
[dev
]->open_mode
!= OPEN_READWRITE
)
470 return (audio_devs
[dev
]->flags
& DMA_DUPLEX
) ? 0 : -EIO
;
472 case SNDCTL_DSP_PROFILE
:
473 if (get_user(val
, (int *)arg
))
475 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
476 audio_devs
[dev
]->dmap_out
->applic_profile
= val
;
477 if (audio_devs
[dev
]->open_mode
& OPEN_READ
)
478 audio_devs
[dev
]->dmap_in
->applic_profile
= val
;
481 case SNDCTL_DSP_GETODELAY
:
482 dmap
= audio_devs
[dev
]->dmap_out
;
483 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
485 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
493 /* Compute number of bytes that have been played */
494 count
= DMAbuf_get_buffer_pointer (dev
, dmap
, DMODE_OUTPUT
);
495 if (count
< dmap
->fragment_size
&& dmap
->qhead
!= 0)
496 count
+= dmap
->bytes_in_use
; /* Pointer wrap not handled yet */
497 count
+= dmap
->byte_counter
;
499 /* Substract current count from the number of bytes written by app */
500 count
= dmap
->user_counter
- count
;
503 restore_flags (flags
);
508 return dma_ioctl(dev
, cmd
, arg
);
510 return put_user(val
, (int *)arg
);
513 void audio_init_devices(void)
516 * NOTE! This routine could be called several times during boot.
522 void reorganize_buffers(int dev
, struct dma_buffparms
*dmap
, int recording
)
525 * This routine breaks the physical device buffers to logical ones.
528 struct audio_operations
*dsp_dev
= audio_devs
[dev
];
531 unsigned sr
, nc
, sz
, bsz
;
533 sr
= dsp_dev
->d
->set_speed(dev
, 0);
534 nc
= dsp_dev
->d
->set_channels(dev
, 0);
535 sz
= dsp_dev
->d
->set_bits(dev
, 0);
538 dmap
->neutral_byte
= NEUTRAL8
;
540 dmap
->neutral_byte
= NEUTRAL16
;
542 if (sr
< 1 || nc
< 1 || sz
< 1)
544 /* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
545 sr
= DSP_DEFAULT_SPEED
;
552 sz
/= 8; /* #bits -> #bytes */
553 dmap
->data_rate
= sz
;
555 if (!dmap
->needs_reorg
)
557 dmap
->needs_reorg
= 0;
559 if (dmap
->fragment_size
== 0)
561 /* Compute the fragment size using the default algorithm */
564 * Compute a buffer size for time not exceeding 1 second.
565 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
566 * of sound (using the current speed, sample size and #channels).
569 bsz
= dmap
->buffsize
;
573 if (bsz
== dmap
->buffsize
)
574 bsz
/= 2; /* Needs at least 2 buffers */
577 * Split the computed fragment to smaller parts. After 3.5a9
578 * the default subdivision is 4 which should give better
579 * results when recording.
582 if (dmap
->subdivision
== 0) /* Not already set */
584 dmap
->subdivision
= 4; /* Init to the default value */
586 if ((bsz
/ dmap
->subdivision
) > 4096)
587 dmap
->subdivision
*= 2;
588 if ((bsz
/ dmap
->subdivision
) < 4096)
589 dmap
->subdivision
= 1;
591 bsz
/= dmap
->subdivision
;
594 bsz
= 16; /* Just a sanity check */
596 dmap
->fragment_size
= bsz
;
601 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
602 * the buffer size computation has already been done.
604 if (dmap
->fragment_size
> (dmap
->buffsize
/ 2))
605 dmap
->fragment_size
= (dmap
->buffsize
/ 2);
606 bsz
= dmap
->fragment_size
;
609 if (audio_devs
[dev
]->min_fragment
)
610 if (bsz
< (1 << audio_devs
[dev
]->min_fragment
))
611 bsz
= 1 << audio_devs
[dev
]->min_fragment
;
612 if (audio_devs
[dev
]->max_fragment
)
613 if (bsz
> (1 << audio_devs
[dev
]->max_fragment
))
614 bsz
= 1 << audio_devs
[dev
]->max_fragment
;
615 bsz
&= ~0x07; /* Force size which is multiple of 8 bytes */
616 #ifdef OS_DMA_ALIGN_CHECK
617 OS_DMA_ALIGN_CHECK(bsz
);
620 n
= dmap
->buffsize
/ bsz
;
621 if (n
> MAX_SUB_BUFFERS
)
623 if (n
> dmap
->max_fragments
)
624 n
= dmap
->max_fragments
;
632 dmap
->bytes_in_use
= n
* bsz
;
633 dmap
->fragment_size
= bsz
;
634 dmap
->max_byte_counter
= (dmap
->data_rate
* 60 * 60) +
635 dmap
->bytes_in_use
; /* Approximately one hour */
639 memset(dmap
->raw_buf
, dmap
->neutral_byte
, dmap
->bytes_in_use
);
642 for (i
= 0; i
< dmap
->nbufs
; i
++)
647 dmap
->flags
|= DMA_ALLOC_DONE
| DMA_EMPTY
;
650 static int dma_subdivide(int dev
, struct dma_buffparms
*dmap
, int fact
)
654 fact
= dmap
->subdivision
;
659 if (dmap
->subdivision
!= 0 || dmap
->fragment_size
) /* Too late to change */
662 if (fact
> MAX_REALTIME_FACTOR
)
665 if (fact
!= 1 && fact
!= 2 && fact
!= 4 && fact
!= 8 && fact
!= 16)
668 dmap
->subdivision
= fact
;
672 static int dma_set_fragment(int dev
, struct dma_buffparms
*dmap
, int fact
)
679 if (dmap
->subdivision
!= 0 ||
680 dmap
->fragment_size
) /* Too late to change */
683 bytes
= fact
& 0xffff;
684 count
= (fact
>> 16) & 0x7fff;
687 count
= MAX_SUB_BUFFERS
;
688 else if (count
< MAX_SUB_BUFFERS
)
691 if (bytes
< 4 || bytes
> 17) /* <16 || > 512k */
697 if (audio_devs
[dev
]->min_fragment
> 0)
698 if (bytes
< audio_devs
[dev
]->min_fragment
)
699 bytes
= audio_devs
[dev
]->min_fragment
;
701 if (audio_devs
[dev
]->max_fragment
> 0)
702 if (bytes
> audio_devs
[dev
]->max_fragment
)
703 bytes
= audio_devs
[dev
]->max_fragment
;
705 #ifdef OS_DMA_MINBITS
706 if (bytes
< OS_DMA_MINBITS
)
707 bytes
= OS_DMA_MINBITS
;
710 dmap
->fragment_size
= (1 << bytes
);
711 dmap
->max_fragments
= count
;
713 if (dmap
->fragment_size
> dmap
->buffsize
)
714 dmap
->fragment_size
= dmap
->buffsize
;
716 if (dmap
->fragment_size
== dmap
->buffsize
&&
717 audio_devs
[dev
]->flags
& DMA_AUTOMODE
)
718 dmap
->fragment_size
/= 2; /* Needs at least 2 buffers */
720 dmap
->subdivision
= 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
721 return bytes
| ((count
- 1) << 16);
724 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
)
726 struct dma_buffparms
*dmap_out
= audio_devs
[dev
]->dmap_out
;
727 struct dma_buffparms
*dmap_in
= audio_devs
[dev
]->dmap_in
;
728 struct dma_buffparms
*dmap
;
731 int fact
, ret
, changed
, bits
, count
, err
;
736 case SNDCTL_DSP_SUBDIVIDE
:
738 if (get_user(fact
, (int *)arg
))
740 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
741 ret
= dma_subdivide(dev
, dmap_out
, fact
);
744 if (audio_devs
[dev
]->open_mode
!= OPEN_WRITE
||
745 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
746 audio_devs
[dev
]->open_mode
& OPEN_READ
))
747 ret
= dma_subdivide(dev
, dmap_in
, fact
);
752 case SNDCTL_DSP_GETISPACE
:
753 case SNDCTL_DSP_GETOSPACE
:
755 if (cmd
== SNDCTL_DSP_GETISPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_READ
))
757 if (cmd
== SNDCTL_DSP_GETOSPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
759 if (cmd
== SNDCTL_DSP_GETISPACE
&& audio_devs
[dev
]->flags
& DMA_DUPLEX
)
761 if (dmap
->mapping_flags
& DMA_MAP_MAPPED
)
763 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
764 reorganize_buffers(dev
, dmap
, (cmd
== SNDCTL_DSP_GETISPACE
));
765 info
.fragstotal
= dmap
->nbufs
;
766 if (cmd
== SNDCTL_DSP_GETISPACE
)
767 info
.fragments
= dmap
->qlen
;
770 if (!DMAbuf_space_in_queue(dev
))
774 info
.fragments
= DMAbuf_space_in_queue(dev
);
775 if (audio_devs
[dev
]->d
->local_qlen
)
777 int tmp
= audio_devs
[dev
]->d
->local_qlen(dev
);
778 if (tmp
&& info
.fragments
)
780 * This buffer has been counted twice
782 info
.fragments
-= tmp
;
786 if (info
.fragments
< 0)
788 else if (info
.fragments
> dmap
->nbufs
)
789 info
.fragments
= dmap
->nbufs
;
791 info
.fragsize
= dmap
->fragment_size
;
792 info
.bytes
= info
.fragments
* dmap
->fragment_size
;
794 if (cmd
== SNDCTL_DSP_GETISPACE
&& dmap
->qlen
)
795 info
.bytes
-= dmap
->counts
[dmap
->qhead
];
798 info
.fragments
= info
.bytes
/ dmap
->fragment_size
;
799 info
.bytes
-= dmap
->user_counter
% dmap
->fragment_size
;
801 if (copy_to_user(arg
, &info
, sizeof(info
)))
805 case SNDCTL_DSP_SETTRIGGER
:
806 if (get_user(bits
, (int *)arg
))
808 bits
&= audio_devs
[dev
]->open_mode
;
809 if (audio_devs
[dev
]->d
->trigger
== NULL
)
811 if (!(audio_devs
[dev
]->flags
& DMA_DUPLEX
) && (bits
& PCM_ENABLE_INPUT
) &&
812 (bits
& PCM_ENABLE_OUTPUT
))
816 changed
= audio_devs
[dev
]->enable_bits
^ bits
;
817 if ((changed
& bits
) & PCM_ENABLE_INPUT
&& audio_devs
[dev
]->go
)
819 reorganize_buffers(dev
, dmap_in
, 1);
820 if ((err
= audio_devs
[dev
]->d
->prepare_for_input(dev
,
821 dmap_in
->fragment_size
, dmap_in
->nbufs
)) < 0) {
822 restore_flags(flags
);
825 dmap_in
->dma_mode
= DMODE_INPUT
;
826 audio_devs
[dev
]->enable_bits
= bits
;
827 DMAbuf_activate_recording(dev
, dmap_in
);
829 if ((changed
& bits
) & PCM_ENABLE_OUTPUT
&&
830 (dmap_out
->mapping_flags
& DMA_MAP_MAPPED
|| dmap_out
->qlen
> 0) &&
833 if (!(dmap_out
->flags
& DMA_ALLOC_DONE
))
834 reorganize_buffers(dev
, dmap_out
, 0);
835 dmap_out
->dma_mode
= DMODE_OUTPUT
;
836 audio_devs
[dev
]->enable_bits
= bits
;
837 dmap_out
->counts
[dmap_out
->qhead
] = dmap_out
->fragment_size
;
838 DMAbuf_launch_output(dev
, dmap_out
);
840 audio_devs
[dev
]->enable_bits
= bits
;
842 if (changed
&& audio_devs
[dev
]->d
->trigger
)
843 audio_devs
[dev
]->d
->trigger(dev
, bits
* audio_devs
[dev
]->go
);
845 restore_flags(flags
);
846 /* Falls through... */
848 case SNDCTL_DSP_GETTRIGGER
:
849 ret
= audio_devs
[dev
]->enable_bits
;
852 case SNDCTL_DSP_SETSYNCRO
:
853 if (!audio_devs
[dev
]->d
->trigger
)
855 audio_devs
[dev
]->d
->trigger(dev
, 0);
856 audio_devs
[dev
]->go
= 0;
859 case SNDCTL_DSP_GETIPTR
:
860 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
864 cinfo
.bytes
= dmap_in
->byte_counter
;
865 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_in
, DMODE_INPUT
) & ~3;
866 if (cinfo
.ptr
< dmap_in
->fragment_size
&& dmap_in
->qtail
!= 0)
867 cinfo
.bytes
+= dmap_in
->bytes_in_use
; /* Pointer wrap not handled yet */
868 cinfo
.blocks
= dmap_in
->qlen
;
869 cinfo
.bytes
+= cinfo
.ptr
;
870 if (dmap_in
->mapping_flags
& DMA_MAP_MAPPED
)
871 dmap_in
->qlen
= 0; /* Reset interrupt counter */
872 restore_flags(flags
);
873 if (copy_to_user(arg
, &cinfo
, sizeof(cinfo
)))
877 case SNDCTL_DSP_GETOPTR
:
878 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
883 cinfo
.bytes
= dmap_out
->byte_counter
;
884 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_out
, DMODE_OUTPUT
) & ~3;
885 if (cinfo
.ptr
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
886 cinfo
.bytes
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
887 cinfo
.blocks
= dmap_out
->qlen
;
888 cinfo
.bytes
+= cinfo
.ptr
;
889 if (dmap_out
->mapping_flags
& DMA_MAP_MAPPED
)
890 dmap_out
->qlen
= 0; /* Reset interrupt counter */
891 restore_flags(flags
);
892 if (copy_to_user(arg
, &cinfo
, sizeof(cinfo
)))
896 case SNDCTL_DSP_GETODELAY
:
897 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
899 if (!(dmap_out
->flags
& DMA_ALLOC_DONE
))
906 /* Compute number of bytes that have been played */
907 count
= DMAbuf_get_buffer_pointer (dev
, dmap_out
, DMODE_OUTPUT
);
908 if (count
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
909 count
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
910 count
+= dmap_out
->byte_counter
;
911 /* Substract current count from the number of bytes written by app */
912 count
= dmap_out
->user_counter
- count
;
915 restore_flags (flags
);
919 case SNDCTL_DSP_POST
:
920 if (audio_devs
[dev
]->dmap_out
->qlen
> 0)
921 if (!(audio_devs
[dev
]->dmap_out
->flags
& DMA_ACTIVE
))
922 DMAbuf_launch_output(dev
, audio_devs
[dev
]->dmap_out
);
925 case SNDCTL_DSP_GETBLKSIZE
:
927 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
928 reorganize_buffers(dev
, dmap_out
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
929 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
930 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
931 audio_devs
[dev
]->open_mode
& OPEN_READ
))
932 reorganize_buffers(dev
, dmap_in
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
933 if (audio_devs
[dev
]->open_mode
== OPEN_READ
)
935 ret
= dmap
->fragment_size
;
938 case SNDCTL_DSP_SETFRAGMENT
:
940 if (get_user(fact
, (int *)arg
))
942 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
943 ret
= dma_set_fragment(dev
, dmap_out
, fact
);
946 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
947 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
948 audio_devs
[dev
]->open_mode
& OPEN_READ
))
949 ret
= dma_set_fragment(dev
, dmap_in
, fact
);
952 if (!arg
) /* don't know what this is good for, but preserve old semantics */
957 if (!audio_devs
[dev
]->d
->ioctl
)
959 return audio_devs
[dev
]->d
->ioctl(dev
, cmd
, arg
);
961 return put_user(ret
, (int *)arg
);