2 * pas2_pcm.c Audio routines for PAS16
5 * Copyright (C) by Hannu Savolainen 1993-1997
7 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
8 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
13 * Alan Cox : Swatted a double allocation of device bug. Made a few
14 * more things module options.
17 #include "sound_config.h"
23 #define PAS_PCM_INTRBITS (0x08)
25 * Sample buffer timer interrupt enable
32 static unsigned long pcm_speed
= 0; /* sampling rate */
33 static unsigned char pcm_channels
= 1; /* channels (1 or 2) */
34 static unsigned char pcm_bits
= 8; /* bits/sample (8 or 16) */
35 static unsigned char pcm_filter
= 0; /* filter FLAG */
36 static unsigned char pcm_mode
= PCM_NON
;
37 static unsigned long pcm_count
= 0;
38 static unsigned short pcm_bitsok
= 8; /* mask of OK bits */
39 static int pcm_busy
= 0;
40 int pas_audiodev
= -1;
41 static int open_mode
= 0;
43 static int pcm_set_speed(int arg
)
58 foo
= (596590 + (arg
/ 2)) / arg
;
59 arg
= (596590 + (foo
/ 2)) / foo
;
63 foo
= (1193180 + (arg
/ 2)) / arg
;
64 arg
= (1193180 + (foo
/ 2)) / foo
;
69 tmp
= pas_read(0x0B8A);
72 * Set anti-aliasing filters according to sample rate. You really *NEED*
73 * to enable this feature for all normal recording unless you want to
74 * experiment with aliasing effects.
75 * These filters apply to the selected "recording" source.
76 * I (pfw) don't know the encoding of these 5 bits. The values shown
77 * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
79 * I cleared bit 5 of these values, since that bit controls the master
80 * mute flag. (Olav Wölfelschneider)
83 #if !defined NO_AUTO_FILTER_SET
85 if (pcm_speed
>= 2 * 17897)
87 else if (pcm_speed
>= 2 * 15909)
89 else if (pcm_speed
>= 2 * 11931)
91 else if (pcm_speed
>= 2 * 8948)
93 else if (pcm_speed
>= 2 * 5965)
95 else if (pcm_speed
>= 2 * 2982)
103 pas_write(tmp
& ~(0x40 | 0x80), 0x0B8A);
104 pas_write(0x00 | 0x30 | 0x04, 0x138B);
105 pas_write(foo
& 0xff, 0x1388);
106 pas_write((foo
>> 8) & 0xff, 0x1388);
107 pas_write(tmp
, 0x0B8A);
109 restore_flags(flags
);
114 static int pcm_set_channels(int arg
)
117 if ((arg
!= 1) && (arg
!= 2))
120 if (arg
!= pcm_channels
)
122 pas_write(pas_read(0xF8A) ^ 0x20, 0xF8A);
125 pcm_set_speed(pcm_speed
); /* The speed must be reinitialized */
130 static int pcm_set_bits(int arg
)
135 if ((arg
& pcm_bitsok
) != arg
)
140 pas_write(pas_read(0x8389) ^ 0x04, 0x8389);
147 static int pas_audio_ioctl(int dev
, unsigned int cmd
, caddr_t arg
)
151 DEB(printk("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd
, arg
));
155 case SOUND_PCM_WRITE_RATE
:
156 if (get_user(val
, (int *)arg
))
158 ret
= pcm_set_speed(val
);
161 case SOUND_PCM_READ_RATE
:
165 case SNDCTL_DSP_STEREO
:
166 if (get_user(val
, (int *)arg
))
168 ret
= pcm_set_channels(val
+ 1) - 1;
171 case SOUND_PCM_WRITE_CHANNELS
:
172 if (get_user(val
, (int *)arg
))
174 ret
= pcm_set_channels(val
);
177 case SOUND_PCM_READ_CHANNELS
:
181 case SNDCTL_DSP_SETFMT
:
182 if (get_user(val
, (int *)arg
))
184 ret
= pcm_set_bits(val
);
187 case SOUND_PCM_READ_BITS
:
194 return put_user(ret
, (int *)arg
);
197 static void pas_audio_reset(int dev
)
199 DEB(printk("pas2_pcm.c: static void pas_audio_reset(void)\n"));
201 pas_write(pas_read(0xF8A) & ~0x40, 0xF8A); /* Disable PCM */
204 static int pas_audio_open(int dev
, int mode
)
209 DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode
));
215 restore_flags(flags
);
219 restore_flags(flags
);
221 if ((err
= pas_set_intr(PAS_PCM_INTRBITS
)) < 0)
231 static void pas_audio_close(int dev
)
235 DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
240 pas_audio_reset(dev
);
241 pas_remove_intr(PAS_PCM_INTRBITS
);
245 restore_flags(flags
);
248 static void pas_audio_output_block(int dev
, unsigned long buf
, int count
,
251 unsigned long flags
, cnt
;
253 DEB(printk("pas2_pcm.c: static void pas_audio_output_block(char *buf = %P, int count = %X)\n", buf
, count
));
256 if (audio_devs
[dev
]->dmap_out
->dma
> 3)
259 if (audio_devs
[dev
]->flags
& DMA_AUTOMODE
&&
267 pas_write(pas_read(0xF8A) & ~0x40,
270 /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
272 if (audio_devs
[dev
]->dmap_out
->dma
> 3)
275 if (count
!= pcm_count
)
277 pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
278 pas_write(0x40 | 0x30 | 0x04, 0x138B);
279 pas_write(count
& 0xff, 0x1389);
280 pas_write((count
>> 8) & 0xff, 0x1389);
281 pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
285 pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
287 pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
292 restore_flags(flags
);
295 static void pas_audio_start_input(int dev
, unsigned long buf
, int count
,
301 DEB(printk("pas2_pcm.c: static void pas_audio_start_input(char *buf = %P, int count = %X)\n", buf
, count
));
304 if (audio_devs
[dev
]->dmap_out
->dma
> 3)
307 if (audio_devs
[pas_audiodev
]->flags
& DMA_AUTOMODE
&&
315 /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
317 if (audio_devs
[dev
]->dmap_out
->dma
> 3)
320 if (count
!= pcm_count
)
322 pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
323 pas_write(0x40 | 0x30 | 0x04, 0x138B);
324 pas_write(count
& 0xff, 0x1389);
325 pas_write((count
>> 8) & 0xff, 0x1389);
326 pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
330 pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
332 pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
337 restore_flags(flags
);
341 static void pas_audio_trigger(int dev
, int state
)
349 if (state
& PCM_ENABLE_OUTPUT
)
350 pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
351 else if (state
& PCM_ENABLE_INPUT
)
352 pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
354 pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
356 restore_flags(flags
);
360 static int pas_audio_prepare_for_input(int dev
, int bsize
, int bcount
)
362 pas_audio_reset(dev
);
366 static int pas_audio_prepare_for_output(int dev
, int bsize
, int bcount
)
368 pas_audio_reset(dev
);
372 static struct audio_driver pas_audio_driver
=
376 pas_audio_output_block
,
377 pas_audio_start_input
,
379 pas_audio_prepare_for_input
,
380 pas_audio_prepare_for_output
,
389 void pas_pcm_init(struct address_info
*hw_config
)
391 DEB(printk("pas2_pcm.c: long pas_pcm_init()\n"));
394 if (pas_read(0xEF8B) & 0x08)
397 pcm_set_speed(DSP_DEFAULT_SPEED
);
399 if ((pas_audiodev
= sound_install_audiodrv(AUDIO_DRIVER_VERSION
,
400 "Pro Audio Spectrum",
402 sizeof(struct audio_driver
),
404 AFMT_U8
| AFMT_S16_LE
,
407 hw_config
->dma
)) < 0)
408 printk(KERN_WARNING
"PAS16: Too many PCM devices available\n");
411 void pas_pcm_interrupt(unsigned char status
, int cause
)
416 * Halt the PCM first. Otherwise we don't have time to start a new
417 * block before the PCM chip proceeds to the next sample
420 if (!(audio_devs
[pas_audiodev
]->flags
& DMA_AUTOMODE
))
421 pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
426 DMAbuf_outputintr(pas_audiodev
, 1);
430 DMAbuf_inputintr(pas_audiodev
);
434 printk(KERN_WARNING
"PAS: Unexpected PCM interrupt\n");