patch-2.1.67 linux/drivers/sound/pas2_pcm.c
Next file: linux/drivers/sound/pnp.c
Previous file: linux/drivers/sound/pas2_mixer.c
Back to the patch index
Back to the overall index
- Lines: 739
- Date:
Sat Nov 29 10:33:21 1997
- Orig file:
v2.1.66/linux/drivers/sound/pas2_pcm.c
- Orig date:
Wed Nov 12 13:34:27 1997
diff -u --recursive --new-file v2.1.66/linux/drivers/sound/pas2_pcm.c linux/drivers/sound/pas2_pcm.c
@@ -12,8 +12,7 @@
#include "sound_config.h"
-#ifdef CONFIG_PAS
-#ifdef CONFIG_AUDIO
+#if defined(MODULE) || ( defined(CONFIG_PAS) && defined(CONFIG_AUDIO) )
#ifndef DEB
#define DEB(WHAT)
@@ -40,425 +39,418 @@
static int open_mode = 0;
static int
-pcm_set_speed (int arg)
+pcm_set_speed(int arg)
{
- int foo, tmp;
- unsigned long flags;
+ int foo, tmp;
+ unsigned long flags;
- if (arg == 0)
- return pcm_speed;
+ if (arg == 0)
+ return pcm_speed;
- if (arg > 44100)
- arg = 44100;
- if (arg < 5000)
- arg = 5000;
-
- if (pcm_channels & 2)
- {
- foo = (596590 + (arg / 2)) / arg;
- arg = (596590 + (foo / 2)) / foo;
- }
- else
- {
- foo = (1193180 + (arg / 2)) / arg;
- arg = (1193180 + (foo / 2)) / foo;
- }
-
- pcm_speed = arg;
-
- tmp = pas_read (0x0B8A);
-
- /*
- * Set anti-aliasing filters according to sample rate. You really *NEED*
- * to enable this feature for all normal recording unless you want to
- * experiment with aliasing effects.
- * These filters apply to the selected "recording" source.
- * I (pfw) don't know the encoding of these 5 bits. The values shown
- * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
- *
- * I cleared bit 5 of these values, since that bit controls the master
- * mute flag. (Olav Wölfelschneider)
- *
- */
+ if (arg > 44100)
+ arg = 44100;
+ if (arg < 5000)
+ arg = 5000;
+
+ if (pcm_channels & 2)
+ {
+ foo = (596590 + (arg / 2)) / arg;
+ arg = (596590 + (foo / 2)) / foo;
+ } else
+ {
+ foo = (1193180 + (arg / 2)) / arg;
+ arg = (1193180 + (foo / 2)) / foo;
+ }
+
+ pcm_speed = arg;
+
+ tmp = pas_read(0x0B8A);
+
+ /*
+ * Set anti-aliasing filters according to sample rate. You really *NEED*
+ * to enable this feature for all normal recording unless you want to
+ * experiment with aliasing effects.
+ * These filters apply to the selected "recording" source.
+ * I (pfw) don't know the encoding of these 5 bits. The values shown
+ * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
+ *
+ * I cleared bit 5 of these values, since that bit controls the master
+ * mute flag. (Olav Wölfelschneider)
+ *
+ */
#if !defined NO_AUTO_FILTER_SET
- tmp &= 0xe0;
- if (pcm_speed >= 2 * 17897)
- tmp |= 0x01;
- else if (pcm_speed >= 2 * 15909)
- tmp |= 0x02;
- else if (pcm_speed >= 2 * 11931)
- tmp |= 0x09;
- else if (pcm_speed >= 2 * 8948)
- tmp |= 0x11;
- else if (pcm_speed >= 2 * 5965)
- tmp |= 0x19;
- else if (pcm_speed >= 2 * 2982)
- tmp |= 0x04;
- pcm_filter = tmp;
+ tmp &= 0xe0;
+ if (pcm_speed >= 2 * 17897)
+ tmp |= 0x01;
+ else if (pcm_speed >= 2 * 15909)
+ tmp |= 0x02;
+ else if (pcm_speed >= 2 * 11931)
+ tmp |= 0x09;
+ else if (pcm_speed >= 2 * 8948)
+ tmp |= 0x11;
+ else if (pcm_speed >= 2 * 5965)
+ tmp |= 0x19;
+ else if (pcm_speed >= 2 * 2982)
+ tmp |= 0x04;
+ pcm_filter = tmp;
#endif
- save_flags (flags);
- cli ();
+ save_flags(flags);
+ cli();
- pas_write (tmp & ~(0x40 | 0x80), 0x0B8A);
- pas_write (0x00 | 0x30 | 0x04, 0x138B);
- pas_write (foo & 0xff, 0x1388);
- pas_write ((foo >> 8) & 0xff, 0x1388);
- pas_write (tmp, 0x0B8A);
+ pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
+ pas_write(0x00 | 0x30 | 0x04, 0x138B);
+ pas_write(foo & 0xff, 0x1388);
+ pas_write((foo >> 8) & 0xff, 0x1388);
+ pas_write(tmp, 0x0B8A);
- restore_flags (flags);
+ restore_flags(flags);
- return pcm_speed;
+ return pcm_speed;
}
static int
-pcm_set_channels (int arg)
+pcm_set_channels(int arg)
{
- if ((arg != 1) && (arg != 2))
- return pcm_channels;
+ if ((arg != 1) && (arg != 2))
+ return pcm_channels;
- if (arg != pcm_channels)
- {
- pas_write (pas_read (0xF8A) ^ 0x20, 0xF8A);
+ if (arg != pcm_channels)
+ {
+ pas_write(pas_read(0xF8A) ^ 0x20, 0xF8A);
- pcm_channels = arg;
- pcm_set_speed (pcm_speed); /* The speed must be reinitialized */
- }
-
- return pcm_channels;
+ pcm_channels = arg;
+ pcm_set_speed(pcm_speed); /* The speed must be reinitialized */
+ }
+ return pcm_channels;
}
static int
-pcm_set_bits (int arg)
+pcm_set_bits(int arg)
{
- if (arg == 0)
- return pcm_bits;
-
- if ((arg & pcm_bitsok) != arg)
- return pcm_bits;
+ if (arg == 0)
+ return pcm_bits;
- if (arg != pcm_bits)
- {
- pas_write (pas_read (0x8389) ^ 0x04, 0x8389);
+ if ((arg & pcm_bitsok) != arg)
+ return pcm_bits;
- pcm_bits = arg;
- }
+ if (arg != pcm_bits)
+ {
+ pas_write(pas_read(0x8389) ^ 0x04, 0x8389);
- return pcm_bits;
+ pcm_bits = arg;
+ }
+ return pcm_bits;
}
static int
-pas_audio_ioctl (int dev, unsigned int cmd, caddr_t arg)
+pas_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- int val;
+ int val;
- DEB (printk ("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
+ DEB(printk("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_speed (val));
- break;
-
- case SOUND_PCM_READ_RATE:
- return (*(int *) arg = pcm_speed);
- break;
-
- case SNDCTL_DSP_STEREO:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_channels (val + 1) - 1);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_channels (val));
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- return (*(int *) arg = pcm_channels);
- break;
-
- case SNDCTL_DSP_SETFMT:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_bits (val));
- break;
-
- case SOUND_PCM_READ_BITS:
- return (*(int *) arg = pcm_bits);
-
- default:
- return -EINVAL;
- }
+ switch (cmd)
+ {
+ case SOUND_PCM_WRITE_RATE:
+ val = *(int *) arg;
+ return (*(int *) arg = pcm_set_speed(val));
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ return (*(int *) arg = pcm_speed);
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ val = *(int *) arg;
+ return (*(int *) arg = pcm_set_channels(val + 1) - 1);
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ val = *(int *) arg;
+ return (*(int *) arg = pcm_set_channels(val));
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ return (*(int *) arg = pcm_channels);
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ val = *(int *) arg;
+ return (*(int *) arg = pcm_set_bits(val));
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ return (*(int *) arg = pcm_bits);
+
+ default:
+ return -EINVAL;
+ }
- return -EINVAL;
+ return -EINVAL;
}
static void
-pas_audio_reset (int dev)
+pas_audio_reset(int dev)
{
- DEB (printk ("pas2_pcm.c: static void pas_audio_reset(void)\n"));
+ DEB(printk("pas2_pcm.c: static void pas_audio_reset(void)\n"));
- pas_write (pas_read (0xF8A) & ~0x40, 0xF8A); /* Disable PCM */
+ pas_write(pas_read(0xF8A) & ~0x40, 0xF8A); /* Disable PCM */
}
static int
-pas_audio_open (int dev, int mode)
+pas_audio_open(int dev, int mode)
{
- int err;
- unsigned long flags;
-
- DEB (printk ("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));
+ int err;
+ unsigned long flags;
- save_flags (flags);
- cli ();
- if (pcm_busy)
- {
- restore_flags (flags);
- return -EBUSY;
- }
+ DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));
- pcm_busy = 1;
- restore_flags (flags);
+ save_flags(flags);
+ cli();
+ if (pcm_busy)
+ {
+ restore_flags(flags);
+ return -EBUSY;
+ }
+ pcm_busy = 1;
+ restore_flags(flags);
- if ((err = pas_set_intr (PAS_PCM_INTRBITS)) < 0)
- return err;
+ if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
+ return err;
- pcm_count = 0;
- open_mode = mode;
+ pcm_count = 0;
+ open_mode = mode;
- return 0;
+ return 0;
}
static void
-pas_audio_close (int dev)
+pas_audio_close(int dev)
{
- unsigned long flags;
+ unsigned long flags;
- DEB (printk ("pas2_pcm.c: static void pas_audio_close(void)\n"));
+ DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
- save_flags (flags);
- cli ();
+ save_flags(flags);
+ cli();
- pas_audio_reset (dev);
- pas_remove_intr (PAS_PCM_INTRBITS);
- pcm_mode = PCM_NON;
+ pas_audio_reset(dev);
+ pas_remove_intr(PAS_PCM_INTRBITS);
+ pcm_mode = PCM_NON;
- pcm_busy = 0;
- restore_flags (flags);
+ pcm_busy = 0;
+ restore_flags(flags);
}
static void
-pas_audio_output_block (int dev, unsigned long buf, int count,
- int intrflag)
+pas_audio_output_block(int dev, unsigned long buf, int count,
+ int intrflag)
{
- unsigned long flags, cnt;
+ unsigned long flags, cnt;
- DEB (printk ("pas2_pcm.c: static void pas_audio_output_block(char *buf = %P, int count = %X)\n", buf, count));
+ DEB(printk("pas2_pcm.c: static void pas_audio_output_block(char *buf = %P, int count = %X)\n", buf, count));
- cnt = count;
- if (audio_devs[dev]->dmap_out->dma > 3)
- cnt >>= 1;
+ cnt = count;
+ if (audio_devs[dev]->dmap_out->dma > 3)
+ cnt >>= 1;
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return;
+ if (audio_devs[dev]->flags & DMA_AUTOMODE &&
+ intrflag &&
+ cnt == pcm_count)
+ return;
- save_flags (flags);
- cli ();
+ save_flags(flags);
+ cli();
- pas_write (pas_read (0xF8A) & ~0x40,
- 0xF8A);
+ pas_write(pas_read(0xF8A) & ~0x40,
+ 0xF8A);
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
+ /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
+ if (audio_devs[dev]->dmap_out->dma > 3)
+ count >>= 1;
- if (count != pcm_count)
- {
- pas_write (pas_read (0x0B8A) & ~0x80, 0x0B8A);
- pas_write (0x40 | 0x30 | 0x04, 0x138B);
- pas_write (count & 0xff, 0x1389);
- pas_write ((count >> 8) & 0xff, 0x1389);
- pas_write (pas_read (0x0B8A) | 0x80, 0x0B8A);
+ if (count != pcm_count)
+ {
+ pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
+ pas_write(0x40 | 0x30 | 0x04, 0x138B);
+ pas_write(count & 0xff, 0x1389);
+ pas_write((count >> 8) & 0xff, 0x1389);
+ pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
- pcm_count = count;
- }
- pas_write (pas_read (0x0B8A) | 0x80 | 0x40, 0x0B8A);
+ pcm_count = count;
+ }
+ pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
#ifdef NO_TRIGGER
- pas_write (pas_read (0xF8A) | 0x40 | 0x10, 0xF8A);
+ pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
#endif
- pcm_mode = PCM_DAC;
+ pcm_mode = PCM_DAC;
- restore_flags (flags);
+ restore_flags(flags);
}
static void
-pas_audio_start_input (int dev, unsigned long buf, int count,
- int intrflag)
+pas_audio_start_input(int dev, unsigned long buf, int count,
+ int intrflag)
{
- unsigned long flags;
- int cnt;
+ unsigned long flags;
+ int cnt;
- DEB (printk ("pas2_pcm.c: static void pas_audio_start_input(char *buf = %P, int count = %X)\n", buf, count));
+ DEB(printk("pas2_pcm.c: static void pas_audio_start_input(char *buf = %P, int count = %X)\n", buf, count));
- cnt = count;
- if (audio_devs[dev]->dmap_out->dma > 3)
- cnt >>= 1;
-
- if (audio_devs[pas_audiodev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return;
-
- save_flags (flags);
- cli ();
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
-
- if (count != pcm_count)
- {
- pas_write (pas_read (0x0B8A) & ~0x80, 0x0B8A);
- pas_write (0x40 | 0x30 | 0x04, 0x138B);
- pas_write (count & 0xff, 0x1389);
- pas_write ((count >> 8) & 0xff, 0x1389);
- pas_write (pas_read (0x0B8A) | 0x80, 0x0B8A);
-
- pcm_count = count;
- }
- pas_write (pas_read (0x0B8A) | 0x80 | 0x40, 0x0B8A);
+ cnt = count;
+ if (audio_devs[dev]->dmap_out->dma > 3)
+ cnt >>= 1;
+
+ if (audio_devs[pas_audiodev]->flags & DMA_AUTOMODE &&
+ intrflag &&
+ cnt == pcm_count)
+ return;
+
+ save_flags(flags);
+ cli();
+
+ /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
+
+ if (audio_devs[dev]->dmap_out->dma > 3)
+ count >>= 1;
+
+ if (count != pcm_count)
+ {
+ pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
+ pas_write(0x40 | 0x30 | 0x04, 0x138B);
+ pas_write(count & 0xff, 0x1389);
+ pas_write((count >> 8) & 0xff, 0x1389);
+ pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
+
+ pcm_count = count;
+ }
+ pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
#ifdef NO_TRIGGER
- pas_write ((pas_read (0xF8A) | 0x40) & ~0x10, 0xF8A);
+ pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
#endif
- pcm_mode = PCM_ADC;
+ pcm_mode = PCM_ADC;
- restore_flags (flags);
+ restore_flags(flags);
}
#ifndef NO_TRIGGER
static void
-pas_audio_trigger (int dev, int state)
+pas_audio_trigger(int dev, int state)
{
- unsigned long flags;
+ unsigned long flags;
- save_flags (flags);
- cli ();
- state &= open_mode;
-
- if (state & PCM_ENABLE_OUTPUT)
- pas_write (pas_read (0xF8A) | 0x40 | 0x10, 0xF8A);
- else if (state & PCM_ENABLE_INPUT)
- pas_write ((pas_read (0xF8A) | 0x40) & ~0x10, 0xF8A);
- else
- pas_write (pas_read (0xF8A) & ~0x40, 0xF8A);
+ save_flags(flags);
+ cli();
+ state &= open_mode;
+
+ if (state & PCM_ENABLE_OUTPUT)
+ pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
+ else if (state & PCM_ENABLE_INPUT)
+ pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
+ else
+ pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
- restore_flags (flags);
+ restore_flags(flags);
}
#endif
static int
-pas_audio_prepare_for_input (int dev, int bsize, int bcount)
+pas_audio_prepare_for_input(int dev, int bsize, int bcount)
{
- pas_audio_reset (dev);
- return 0;
+ pas_audio_reset(dev);
+ return 0;
}
static int
-pas_audio_prepare_for_output (int dev, int bsize, int bcount)
+pas_audio_prepare_for_output(int dev, int bsize, int bcount)
{
- pas_audio_reset (dev);
- return 0;
+ pas_audio_reset(dev);
+ return 0;
}
static struct audio_driver pas_audio_driver =
{
- pas_audio_open,
- pas_audio_close,
- pas_audio_output_block,
- pas_audio_start_input,
- pas_audio_ioctl,
- pas_audio_prepare_for_input,
- pas_audio_prepare_for_output,
- pas_audio_reset,
- NULL,
- NULL,
- NULL,
- NULL,
- pas_audio_trigger
+ pas_audio_open,
+ pas_audio_close,
+ pas_audio_output_block,
+ pas_audio_start_input,
+ pas_audio_ioctl,
+ pas_audio_prepare_for_input,
+ pas_audio_prepare_for_output,
+ pas_audio_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pas_audio_trigger
};
void
-pas_pcm_init (struct address_info *hw_config)
+pas_pcm_init(struct address_info *hw_config)
{
- DEB (printk ("pas2_pcm.c: long pas_pcm_init()\n"));
+ DEB(printk("pas2_pcm.c: long pas_pcm_init()\n"));
- pcm_bitsok = 8;
- if (pas_read (0xEF8B) & 0x08)
- pcm_bitsok |= 16;
-
- pcm_set_speed (DSP_DEFAULT_SPEED);
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
-
- if ((pas_audiodev = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
- "Pro Audio Spectrum",
- &pas_audio_driver,
- sizeof (struct audio_driver),
- DMA_AUTOMODE,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- hw_config->dma,
- hw_config->dma)) < 0)
- {
- return;
- }
- }
- else
- printk ("PAS16: Too many PCM devices available\n");
+ pcm_bitsok = 8;
+ if (pas_read(0xEF8B) & 0x08)
+ pcm_bitsok |= 16;
+
+ pcm_set_speed(DSP_DEFAULT_SPEED);
+
+ if ((pas_audiodev = sound_alloc_audiodev()) != -1)
+ {
+
+ if ((pas_audiodev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
+ "Pro Audio Spectrum",
+ &pas_audio_driver,
+ sizeof(struct audio_driver),
+ DMA_AUTOMODE,
+ AFMT_U8 | AFMT_S16_LE,
+ NULL,
+ hw_config->dma,
+ hw_config->dma)) < 0)
+ {
+ return;
+ }
+ } else
+ printk(KERN_WARNING "PAS16: Too many PCM devices available\n");
}
void
-pas_pcm_interrupt (unsigned char status, int cause)
+pas_pcm_interrupt(unsigned char status, int cause)
{
- if (cause == 1)
- {
- /*
- * Halt the PCM first. Otherwise we don't have time to start a new
- * block before the PCM chip proceeds to the next sample
- */
-
- if (!(audio_devs[pas_audiodev]->flags & DMA_AUTOMODE))
- {
- pas_write (pas_read (0xF8A) & ~0x40,
- 0xF8A);
- }
-
- switch (pcm_mode)
- {
-
- case PCM_DAC:
- DMAbuf_outputintr (pas_audiodev, 1);
- break;
-
- case PCM_ADC:
- DMAbuf_inputintr (pas_audiodev);
- break;
-
- default:
- printk ("PAS: Unexpected PCM interrupt\n");
- }
- }
+ if (cause == 1)
+ {
+ /*
+ * Halt the PCM first. Otherwise we don't have time to start a new
+ * block before the PCM chip proceeds to the next sample
+ */
+
+ if (!(audio_devs[pas_audiodev]->flags & DMA_AUTOMODE))
+ {
+ pas_write(pas_read(0xF8A) & ~0x40,
+ 0xF8A);
+ }
+ switch (pcm_mode)
+ {
+
+ case PCM_DAC:
+ DMAbuf_outputintr(pas_audiodev, 1);
+ break;
+
+ case PCM_ADC:
+ DMAbuf_inputintr(pas_audiodev);
+ break;
+
+ default:
+ printk("PAS: Unexpected PCM interrupt\n");
+ }
+ }
}
-#endif
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov