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)
18 #include <linux/config.h>
20 #include "sound_config.h"
22 #if defined(CONFIG_AUDIO) || defined(MODULE)
27 #define NEUTRAL16 0x00
29 static int audio_mode
[MAX_AUDIO_DEV
];
30 static int dev_nblock
[MAX_AUDIO_DEV
]; /* 1 if in nonblocking mode */
33 #define AM_WRITE OPEN_WRITE
34 #define AM_READ OPEN_READ
35 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
);
38 static int local_format
[MAX_AUDIO_DEV
], audio_format
[MAX_AUDIO_DEV
];
39 static int local_conversion
[MAX_AUDIO_DEV
];
41 #define CNV_MU_LAW 0x00000001
43 static int set_format(int dev
, int fmt
)
45 if (fmt
!= AFMT_QUERY
)
47 local_conversion
[dev
] = 0;
49 if (!(audio_devs
[dev
]->format_mask
& fmt
)) /* Not supported */
51 if (fmt
== AFMT_MU_LAW
)
54 local_conversion
[dev
] = CNV_MU_LAW
;
57 fmt
= AFMT_U8
; /* This is always supported */
59 audio_format
[dev
] = audio_devs
[dev
]->d
->set_bits(dev
, fmt
);
60 local_format
[dev
] = fmt
;
63 return local_format
[dev
];
65 return local_format
[dev
];
68 int audio_open(int dev
, struct fileinfo
*file
)
72 int dev_type
= dev
& 0x0f;
73 int mode
= file
->mode
& O_ACCMODE
;
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 local_conversion
[dev
] = 0;
101 if (dev_type
== SND_DEV_AUDIO
)
102 set_format(dev
, AFMT_MU_LAW
);
104 set_format(dev
, bits
);
106 audio_mode
[dev
] = AM_NONE
;
113 static void sync_output(int dev
)
117 struct dma_buffparms
*dmap
= audio_devs
[dev
]->dmap_out
;
119 if (dmap
->fragment_size
<= 0)
121 dmap
->flags
|= DMA_POST
;
123 /* Align the write pointer with fragment boundaries */
125 if ((l
= dmap
->user_counter
% dmap
->fragment_size
) > 0)
128 unsigned long offs
= dmap
->user_counter
% dmap
->bytes_in_use
;
130 len
= dmap
->fragment_size
- l
;
131 memset(dmap
->raw_buf
+ offs
, dmap
->neutral_byte
, len
);
132 DMAbuf_move_wrpointer(dev
, len
);
136 * Clean all unused buffer fragments.
140 dmap
->flags
|= DMA_POST
;
142 for (i
= dmap
->qlen
+ 1; i
< dmap
->nbufs
; i
++)
144 p
= (p
+ 1) % dmap
->nbufs
;
145 if (((dmap
->raw_buf
+ p
* dmap
->fragment_size
) + dmap
->fragment_size
) >
146 (dmap
->raw_buf
+ dmap
->buffsize
))
147 printk(KERN_ERR
"audio: Buffer error 2\n");
149 memset(dmap
->raw_buf
+ p
* dmap
->fragment_size
,
151 dmap
->fragment_size
);
154 dmap
->flags
|= DMA_DIRTY
;
157 void audio_release(int dev
, struct fileinfo
*file
)
162 mode
= file
->mode
& O_ACCMODE
;
164 audio_devs
[dev
]->dmap_out
->closing
= 1;
165 audio_devs
[dev
]->dmap_in
->closing
= 1;
169 if (audio_devs
[dev
]->coproc
)
170 audio_devs
[dev
]->coproc
->close(audio_devs
[dev
]->coproc
->devc
, COPR_PCM
);
171 DMAbuf_release(dev
, mode
);
174 #if defined(NO_INLINE_ASM) || !defined(i386)
176 static void translate_bytes(const unsigned char *table
, unsigned char *buff
, int n
)
183 for (i
= 0; i
< n
; ++i
)
184 buff
[i
] = table
[buff
[i
]];
189 translate_bytes(const void *table
, void *buff
, int n
)
198 : "b"((long) table
), "c"(n
), "D"((long) buff
), "S"((long) buff
)
199 : "bx", "cx", "di", "si", "ax");
205 int audio_write(int dev
, struct fileinfo
*file
, const char *buf
, int count
)
207 int c
, p
, l
, buf_size
;
216 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
219 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
220 audio_mode
[dev
] |= AM_WRITE
;
222 audio_mode
[dev
] = AM_WRITE
;
224 if (!count
) /* Flush output */
232 if ((err
= DMAbuf_getwrbuffer(dev
, &dma_buf
, &buf_size
, dev_nblock
[dev
])) < 0)
234 /* Handle nonblocking mode */
235 if (dev_nblock
[dev
] && err
== -EAGAIN
)
236 return p
; /* No more space. Return # of accepted bytes */
244 if (!audio_devs
[dev
]->d
->copy_user
)
247 (audio_devs
[dev
]->dmap_out
->raw_buf
+ audio_devs
[dev
]->dmap_out
->buffsize
))
249 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
);
252 if (dma_buf
< audio_devs
[dev
]->dmap_out
->raw_buf
)
254 printk(KERN_ERR
"audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf
, (long) audio_devs
[dev
]->dmap_out
->raw_buf
);
257 if(copy_from_user(dma_buf
, &(buf
)[p
], l
))
260 else audio_devs
[dev
]->d
->copy_user(dev
, dma_buf
, 0, buf
, p
, l
);
262 if (local_conversion
[dev
] & 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 fileinfo
*file
, char *buf
, int count
)
289 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
292 if ((audio_mode
[dev
] & AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
295 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
)
296 audio_mode
[dev
] |= AM_READ
;
298 audio_mode
[dev
] = AM_READ
;
302 if ((buf_no
= DMAbuf_getrdbuffer(dev
, &dmabuf
, &l
,
303 dev_nblock
[dev
])) < 0)
306 * Nonblocking mode handling. Return current # of bytes
309 if (dev_nblock
[dev
] && buf_no
== -EAGAIN
)
312 if (p
> 0) /* Avoid throwing away data */
313 return p
; /* Return it instead */
321 * Insert any local processing here.
324 if (local_conversion
[dev
] & CNV_MU_LAW
)
327 * This just allows interrupts while the conversion is running
331 translate_bytes(dsp_ulaw
, (unsigned char *) dmabuf
, l
);
335 char *fixit
= dmabuf
;
337 if(copy_to_user(&(buf
)[p
], fixit
, l
))
341 DMAbuf_rmchars(dev
, buf_no
, l
);
350 int audio_ioctl(int dev
, struct fileinfo
*file_must_not_be_used
,
351 unsigned int cmd
, caddr_t arg
)
353 int val
= 0, info
, count
;
355 struct dma_buffparms
*dmap
;
359 if (((cmd
>> 8) & 0xff) == 'C') {
360 if (audio_devs
[dev
]->coproc
) /* Coprocessor ioctl */
361 return audio_devs
[dev
]->coproc
->ioctl(audio_devs
[dev
]->coproc
->devc
, cmd
, arg
, 0);
363 printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
368 case SNDCTL_DSP_SYNC
:
369 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
371 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
378 case SNDCTL_DSP_POST
:
379 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
381 if (audio_devs
[dev
]->dmap_out
->fragment_size
== 0)
383 audio_devs
[dev
]->dmap_out
->flags
|= DMA_POST
| DMA_DIRTY
;
385 dma_ioctl(dev
, SNDCTL_DSP_POST
, (caddr_t
) 0);
388 case SNDCTL_DSP_RESET
:
389 audio_mode
[dev
] = AM_NONE
;
393 case SNDCTL_DSP_GETFMTS
:
394 val
= audio_devs
[dev
]->format_mask
;
397 case SNDCTL_DSP_SETFMT
:
398 if (get_user(val
, (int *)arg
))
400 val
= set_format(dev
, val
);
403 case SNDCTL_DSP_GETISPACE
:
404 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
406 if ((audio_mode
[dev
] & AM_WRITE
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
408 return dma_ioctl(dev
, cmd
, arg
);
410 case SNDCTL_DSP_GETOSPACE
:
411 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
413 if ((audio_mode
[dev
] & AM_READ
) && !(audio_devs
[dev
]->flags
& DMA_DUPLEX
))
415 return dma_ioctl(dev
, cmd
, arg
);
417 case SNDCTL_DSP_NONBLOCK
:
421 case SNDCTL_DSP_GETCAPS
:
422 info
= 1 | DSP_CAP_MMAP
; /* Revision level of this ioctl() */
423 if (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
424 audio_devs
[dev
]->open_mode
== OPEN_READWRITE
)
425 info
|= DSP_CAP_DUPLEX
;
426 if (audio_devs
[dev
]->coproc
)
427 info
|= DSP_CAP_COPROC
;
428 if (audio_devs
[dev
]->d
->local_qlen
) /* Device has hidden buffers */
429 info
|= DSP_CAP_BATCH
;
430 if (audio_devs
[dev
]->d
->trigger
) /* Supports SETTRIGGER */
431 info
|= DSP_CAP_TRIGGER
;
434 case SOUND_PCM_WRITE_RATE
:
435 if (get_user(val
, (int *)arg
))
437 val
= audio_devs
[dev
]->d
->set_speed(dev
, val
);
440 case SOUND_PCM_READ_RATE
:
441 val
= audio_devs
[dev
]->d
->set_speed(dev
, 0);
444 case SNDCTL_DSP_STEREO
:
445 if (get_user(val
, (int *)arg
))
447 if (val
> 1 || val
< 0)
449 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
+ 1) - 1;
452 case SOUND_PCM_WRITE_CHANNELS
:
453 if (get_user(val
, (int *)arg
))
455 val
= audio_devs
[dev
]->d
->set_channels(dev
, val
);
458 case SOUND_PCM_READ_CHANNELS
:
459 val
= audio_devs
[dev
]->d
->set_channels(dev
, 0);
462 case SOUND_PCM_READ_BITS
:
463 val
= audio_devs
[dev
]->d
->set_bits(dev
, 0);
466 case SNDCTL_DSP_SETDUPLEX
:
467 if (audio_devs
[dev
]->open_mode
!= OPEN_READWRITE
)
469 return (audio_devs
[dev
]->flags
& DMA_DUPLEX
) ? 0 : -EIO
;
471 case SNDCTL_DSP_PROFILE
:
472 if (get_user(val
, (int *)arg
))
474 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
475 audio_devs
[dev
]->dmap_out
->applic_profile
= val
;
476 if (audio_devs
[dev
]->open_mode
& OPEN_READ
)
477 audio_devs
[dev
]->dmap_in
->applic_profile
= val
;
480 case SNDCTL_DSP_GETODELAY
:
481 dmap
= audio_devs
[dev
]->dmap_out
;
482 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
484 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
492 /* Compute number of bytes that have been played */
493 count
= DMAbuf_get_buffer_pointer (dev
, dmap
, DMODE_OUTPUT
);
494 if (count
< dmap
->fragment_size
&& dmap
->qhead
!= 0)
495 count
+= dmap
->bytes_in_use
; /* Pointer wrap not handled yet */
496 count
+= dmap
->byte_counter
;
498 /* Substract current count from the number of bytes written by app */
499 count
= dmap
->user_counter
- count
;
502 restore_flags (flags
);
507 return dma_ioctl(dev
, cmd
, arg
);
509 return put_user(val
, (int *)arg
);
512 void audio_init_devices(void)
515 * NOTE! This routine could be called several times during boot.
521 void reorganize_buffers(int dev
, struct dma_buffparms
*dmap
, int recording
)
524 * This routine breaks the physical device buffers to logical ones.
527 struct audio_operations
*dsp_dev
= audio_devs
[dev
];
530 unsigned sr
, nc
, sz
, bsz
;
532 sr
= dsp_dev
->d
->set_speed(dev
, 0);
533 nc
= dsp_dev
->d
->set_channels(dev
, 0);
534 sz
= dsp_dev
->d
->set_bits(dev
, 0);
537 dmap
->neutral_byte
= NEUTRAL8
;
539 dmap
->neutral_byte
= NEUTRAL16
;
541 if (sr
< 1 || nc
< 1 || sz
< 1)
543 /* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
544 sr
= DSP_DEFAULT_SPEED
;
551 sz
/= 8; /* #bits -> #bytes */
552 dmap
->data_rate
= sz
;
554 if (!dmap
->needs_reorg
)
556 dmap
->needs_reorg
= 0;
558 if (dmap
->fragment_size
== 0)
560 /* Compute the fragment size using the default algorithm */
563 * Compute a buffer size for time not exceeding 1 second.
564 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
565 * of sound (using the current speed, sample size and #channels).
568 bsz
= dmap
->buffsize
;
572 if (bsz
== dmap
->buffsize
)
573 bsz
/= 2; /* Needs at least 2 buffers */
576 * Split the computed fragment to smaller parts. After 3.5a9
577 * the default subdivision is 4 which should give better
578 * results when recording.
581 if (dmap
->subdivision
== 0) /* Not already set */
583 dmap
->subdivision
= 4; /* Init to the default value */
585 if ((bsz
/ dmap
->subdivision
) > 4096)
586 dmap
->subdivision
*= 2;
587 if ((bsz
/ dmap
->subdivision
) < 4096)
588 dmap
->subdivision
= 1;
590 bsz
/= dmap
->subdivision
;
593 bsz
= 16; /* Just a sanity check */
595 dmap
->fragment_size
= bsz
;
600 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
601 * the buffer size computation has already been done.
603 if (dmap
->fragment_size
> (dmap
->buffsize
/ 2))
604 dmap
->fragment_size
= (dmap
->buffsize
/ 2);
605 bsz
= dmap
->fragment_size
;
608 if (audio_devs
[dev
]->min_fragment
)
609 if (bsz
< (1 << audio_devs
[dev
]->min_fragment
))
610 bsz
= 1 << audio_devs
[dev
]->min_fragment
;
611 if (audio_devs
[dev
]->max_fragment
)
612 if (bsz
> (1 << audio_devs
[dev
]->max_fragment
))
613 bsz
= 1 << audio_devs
[dev
]->max_fragment
;
614 bsz
&= ~0x07; /* Force size which is multiple of 8 bytes */
615 #ifdef OS_DMA_ALIGN_CHECK
616 OS_DMA_ALIGN_CHECK(bsz
);
619 n
= dmap
->buffsize
/ bsz
;
620 if (n
> MAX_SUB_BUFFERS
)
622 if (n
> dmap
->max_fragments
)
623 n
= dmap
->max_fragments
;
631 dmap
->bytes_in_use
= n
* bsz
;
632 dmap
->fragment_size
= bsz
;
633 dmap
->max_byte_counter
= (dmap
->data_rate
* 60 * 60) +
634 dmap
->bytes_in_use
; /* Approximately one hour */
638 memset(dmap
->raw_buf
, dmap
->neutral_byte
, dmap
->bytes_in_use
);
641 for (i
= 0; i
< dmap
->nbufs
; i
++)
646 dmap
->flags
|= DMA_ALLOC_DONE
| DMA_EMPTY
;
649 static int dma_subdivide(int dev
, struct dma_buffparms
*dmap
, int fact
)
653 fact
= dmap
->subdivision
;
658 if (dmap
->subdivision
!= 0 || dmap
->fragment_size
) /* Too late to change */
661 if (fact
> MAX_REALTIME_FACTOR
)
664 if (fact
!= 1 && fact
!= 2 && fact
!= 4 && fact
!= 8 && fact
!= 16)
667 dmap
->subdivision
= fact
;
671 static int dma_set_fragment(int dev
, struct dma_buffparms
*dmap
, int fact
)
678 if (dmap
->subdivision
!= 0 ||
679 dmap
->fragment_size
) /* Too late to change */
682 bytes
= fact
& 0xffff;
683 count
= (fact
>> 16) & 0x7fff;
686 count
= MAX_SUB_BUFFERS
;
687 else if (count
< MAX_SUB_BUFFERS
)
690 if (bytes
< 4 || bytes
> 17) /* <16 || > 512k */
696 if (audio_devs
[dev
]->min_fragment
> 0)
697 if (bytes
< audio_devs
[dev
]->min_fragment
)
698 bytes
= audio_devs
[dev
]->min_fragment
;
700 if (audio_devs
[dev
]->max_fragment
> 0)
701 if (bytes
> audio_devs
[dev
]->max_fragment
)
702 bytes
= audio_devs
[dev
]->max_fragment
;
704 #ifdef OS_DMA_MINBITS
705 if (bytes
< OS_DMA_MINBITS
)
706 bytes
= OS_DMA_MINBITS
;
709 dmap
->fragment_size
= (1 << bytes
);
710 dmap
->max_fragments
= count
;
712 if (dmap
->fragment_size
> dmap
->buffsize
)
713 dmap
->fragment_size
= dmap
->buffsize
;
715 if (dmap
->fragment_size
== dmap
->buffsize
&&
716 audio_devs
[dev
]->flags
& DMA_AUTOMODE
)
717 dmap
->fragment_size
/= 2; /* Needs at least 2 buffers */
719 dmap
->subdivision
= 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
720 return bytes
| ((count
- 1) << 16);
723 int dma_ioctl(int dev
, unsigned int cmd
, caddr_t arg
)
725 struct dma_buffparms
*dmap_out
= audio_devs
[dev
]->dmap_out
;
726 struct dma_buffparms
*dmap_in
= audio_devs
[dev
]->dmap_in
;
727 struct dma_buffparms
*dmap
;
730 int fact
, ret
, changed
, bits
, count
, err
;
735 case SNDCTL_DSP_SUBDIVIDE
:
737 if (get_user(fact
, (int *)arg
))
739 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
740 ret
= dma_subdivide(dev
, dmap_out
, fact
);
743 if (audio_devs
[dev
]->open_mode
!= OPEN_WRITE
||
744 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
745 audio_devs
[dev
]->open_mode
& OPEN_READ
))
746 ret
= dma_subdivide(dev
, dmap_in
, fact
);
751 case SNDCTL_DSP_GETISPACE
:
752 case SNDCTL_DSP_GETOSPACE
:
754 if (cmd
== SNDCTL_DSP_GETISPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_READ
))
756 if (cmd
== SNDCTL_DSP_GETOSPACE
&& !(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
758 if (cmd
== SNDCTL_DSP_GETISPACE
&& audio_devs
[dev
]->flags
& DMA_DUPLEX
)
760 if (dmap
->mapping_flags
& DMA_MAP_MAPPED
)
762 if (!(dmap
->flags
& DMA_ALLOC_DONE
))
763 reorganize_buffers(dev
, dmap
, (cmd
== SNDCTL_DSP_GETISPACE
));
764 info
.fragstotal
= dmap
->nbufs
;
765 if (cmd
== SNDCTL_DSP_GETISPACE
)
766 info
.fragments
= dmap
->qlen
;
769 if (!DMAbuf_space_in_queue(dev
))
773 info
.fragments
= DMAbuf_space_in_queue(dev
);
774 if (audio_devs
[dev
]->d
->local_qlen
)
776 int tmp
= audio_devs
[dev
]->d
->local_qlen(dev
);
777 if (tmp
&& info
.fragments
)
779 * This buffer has been counted twice
781 info
.fragments
-= tmp
;
785 if (info
.fragments
< 0)
787 else if (info
.fragments
> dmap
->nbufs
)
788 info
.fragments
= dmap
->nbufs
;
790 info
.fragsize
= dmap
->fragment_size
;
791 info
.bytes
= info
.fragments
* dmap
->fragment_size
;
793 if (cmd
== SNDCTL_DSP_GETISPACE
&& dmap
->qlen
)
794 info
.bytes
-= dmap
->counts
[dmap
->qhead
];
797 info
.fragments
= info
.bytes
/ dmap
->fragment_size
;
798 info
.bytes
-= dmap
->user_counter
% dmap
->fragment_size
;
800 return copy_to_user(arg
, &info
, sizeof(info
));
802 case SNDCTL_DSP_SETTRIGGER
:
803 if (get_user(bits
, (int *)arg
))
805 bits
&= audio_devs
[dev
]->open_mode
;
806 if (audio_devs
[dev
]->d
->trigger
== NULL
)
808 if (!(audio_devs
[dev
]->flags
& DMA_DUPLEX
) && (bits
& PCM_ENABLE_INPUT
) &&
809 (bits
& PCM_ENABLE_OUTPUT
))
813 changed
= audio_devs
[dev
]->enable_bits
^ bits
;
814 if ((changed
& bits
) & PCM_ENABLE_INPUT
&& audio_devs
[dev
]->go
)
816 reorganize_buffers(dev
, dmap_in
, 1);
817 if ((err
= audio_devs
[dev
]->d
->prepare_for_input(dev
,
818 dmap_in
->fragment_size
, dmap_in
->nbufs
)) < 0)
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
;
836 if (changed
&& audio_devs
[dev
]->d
->trigger
)
837 audio_devs
[dev
]->d
->trigger(dev
, bits
* audio_devs
[dev
]->go
);
838 restore_flags(flags
);
839 /* Falls through... */
841 case SNDCTL_DSP_GETTRIGGER
:
842 ret
= audio_devs
[dev
]->enable_bits
;
845 case SNDCTL_DSP_SETSYNCRO
:
846 if (!audio_devs
[dev
]->d
->trigger
)
848 audio_devs
[dev
]->d
->trigger(dev
, 0);
849 audio_devs
[dev
]->go
= 0;
852 case SNDCTL_DSP_GETIPTR
:
853 if (!(audio_devs
[dev
]->open_mode
& OPEN_READ
))
857 cinfo
.bytes
= dmap_in
->byte_counter
;
858 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_in
, DMODE_INPUT
) & ~3;
859 if (cinfo
.ptr
< dmap_in
->fragment_size
&& dmap_in
->qtail
!= 0)
860 cinfo
.bytes
+= dmap_in
->bytes_in_use
; /* Pointer wrap not handled yet */
861 cinfo
.blocks
= dmap_in
->qlen
;
862 cinfo
.bytes
+= cinfo
.ptr
;
863 if (dmap_in
->mapping_flags
& DMA_MAP_MAPPED
)
864 dmap_in
->qlen
= 0; /* Reset interrupt counter */
865 restore_flags(flags
);
866 return copy_to_user(arg
, &cinfo
, sizeof(cinfo
));
868 case SNDCTL_DSP_GETOPTR
:
869 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
874 cinfo
.bytes
= dmap_out
->byte_counter
;
875 cinfo
.ptr
= DMAbuf_get_buffer_pointer(dev
, dmap_out
, DMODE_OUTPUT
) & ~3;
876 if (cinfo
.ptr
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
877 cinfo
.bytes
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
878 cinfo
.blocks
= dmap_out
->qlen
;
879 cinfo
.bytes
+= cinfo
.ptr
;
880 if (dmap_out
->mapping_flags
& DMA_MAP_MAPPED
)
881 dmap_out
->qlen
= 0; /* Reset interrupt counter */
882 restore_flags(flags
);
883 return copy_to_user(arg
, &cinfo
, sizeof(cinfo
));
885 case SNDCTL_DSP_GETODELAY
:
886 if (!(audio_devs
[dev
]->open_mode
& OPEN_WRITE
))
888 if (!(dmap_out
->flags
& DMA_ALLOC_DONE
))
895 /* Compute number of bytes that have been played */
896 count
= DMAbuf_get_buffer_pointer (dev
, dmap_out
, DMODE_OUTPUT
);
897 if (count
< dmap_out
->fragment_size
&& dmap_out
->qhead
!= 0)
898 count
+= dmap_out
->bytes_in_use
; /* Pointer wrap not handled yet */
899 count
+= dmap_out
->byte_counter
;
900 /* Substract current count from the number of bytes written by app */
901 count
= dmap_out
->user_counter
- count
;
904 restore_flags (flags
);
908 case SNDCTL_DSP_POST
:
909 if (audio_devs
[dev
]->dmap_out
->qlen
> 0)
910 if (!(audio_devs
[dev
]->dmap_out
->flags
& DMA_ACTIVE
))
911 DMAbuf_launch_output(dev
, audio_devs
[dev
]->dmap_out
);
914 case SNDCTL_DSP_GETBLKSIZE
:
916 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
917 reorganize_buffers(dev
, dmap_out
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
918 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
919 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
920 audio_devs
[dev
]->open_mode
& OPEN_READ
))
921 reorganize_buffers(dev
, dmap_in
, (audio_devs
[dev
]->open_mode
== OPEN_READ
));
922 if (audio_devs
[dev
]->open_mode
== OPEN_READ
)
924 ret
= dmap
->fragment_size
;
927 case SNDCTL_DSP_SETFRAGMENT
:
929 if (get_user(fact
, (int *)arg
))
931 if (audio_devs
[dev
]->open_mode
& OPEN_WRITE
)
932 ret
= dma_set_fragment(dev
, dmap_out
, fact
);
935 if (audio_devs
[dev
]->open_mode
== OPEN_READ
||
936 (audio_devs
[dev
]->flags
& DMA_DUPLEX
&&
937 audio_devs
[dev
]->open_mode
& OPEN_READ
))
938 ret
= dma_set_fragment(dev
, dmap_in
, fact
);
941 if (!arg
) /* don't know what this is good for, but preserve old semantics */
946 if (!audio_devs
[dev
]->d
->ioctl
)
948 return audio_devs
[dev
]->d
->ioctl(dev
, cmd
, arg
);
950 return put_user(ret
, (int *)arg
);