diff options
Diffstat (limited to 'sound/isa/sb/sb8_main.c')
| -rw-r--r-- | sound/isa/sb/sb8_main.c | 264 |
1 files changed, 99 insertions, 165 deletions
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 24d4121ab0e0..a4b5725255cf 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Uros Bizjak <uros@kss-loka.si> @@ -5,21 +6,6 @@ * Routines for control of 8-bit SoundBlaster cards and clones * Please note: I don't have access to old SB8 soundcards. * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * -- * * Thu Apr 29 20:36:17 BST 1999 George David Morrison <gdm@gedamo.demon.co.uk> @@ -30,7 +16,7 @@ * Cleaned up and rewrote lowlevel routines. */ -#include <asm/io.h> +#include <linux/io.h> #include <asm/dma.h> #include <linux/init.h> #include <linux/time.h> @@ -46,19 +32,19 @@ MODULE_LICENSE("GPL"); #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v)) #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v)) -static struct snd_ratnum clock = { +static const struct snd_ratnum clock = { .num = SB8_CLOCK, .den_min = 1, .den_max = 256, .den_step = 1, }; -static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { +static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { .nrats = 1, .rats = &clock, }; -static struct snd_ratnum stereo_clocks[] = { +static const struct snd_ratnum stereo_clocks[] = { { .num = SB8_CLOCK, .den_min = SB8_DEN(22050), @@ -103,7 +89,6 @@ static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params, static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) { - unsigned long flags; struct snd_sb *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; @@ -130,13 +115,13 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } - /* fallthru */ + fallthrough; case SB_HW_201: if (rate > 23000) { chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } - /* fallthru */ + fallthrough; case SB_HW_20: chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; break; @@ -156,48 +141,48 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) } size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); - if (chip->hardware == SB_HW_JAZZ16) - snd_sbdsp_command(chip, format); - else if (stereo) { - /* set playback stereo mode */ - spin_lock(&chip->mixer_lock); - mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); - snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02); - spin_unlock(&chip->mixer_lock); - - /* Soundblaster hardware programming reference guide, 3-23 */ - snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); - runtime->dma_area[0] = 0x80; - snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); - /* force interrupt */ - snd_sbdsp_command(chip, SB_DSP_OUTPUT); - snd_sbdsp_command(chip, 0); - snd_sbdsp_command(chip, 0); - } - snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (stereo) { - snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); - spin_lock(&chip->mixer_lock); - /* save output filter status and turn it off */ - mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT); - snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20); - spin_unlock(&chip->mixer_lock); - /* just use force_mode16 for temporary storate... */ - chip->force_mode16 = mixreg; - } else { - snd_sbdsp_command(chip, 256 - runtime->rate_den); - } - if (chip->playback_format != SB_DSP_OUTPUT) { - if (chip->mode & SB_MODE_PLAYBACK_16) - count /= 2; - count--; - snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); - snd_sbdsp_command(chip, count & 0xff); - snd_sbdsp_command(chip, count >> 8); + scoped_guard(spinlock_irqsave, &chip->reg_lock) { + snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) { + /* set playback stereo mode */ + scoped_guard(spinlock, &chip->mixer_lock) { + mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); + snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02); + } + + /* Soundblaster hardware programming reference guide, 3-23 */ + snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); + runtime->dma_area[0] = 0x80; + snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); + /* force interrupt */ + snd_sbdsp_command(chip, SB_DSP_OUTPUT); + snd_sbdsp_command(chip, 0); + snd_sbdsp_command(chip, 0); + } + snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); + if (stereo) { + snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); + scoped_guard(spinlock, &chip->mixer_lock) { + /* save output filter status and turn it off */ + mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT); + snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20); + } + /* just use force_mode16 for temporary storate... */ + chip->force_mode16 = mixreg; + } else { + snd_sbdsp_command(chip, 256 - runtime->rate_den); + } + if (chip->playback_format != SB_DSP_OUTPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; + count--; + snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); + snd_sbdsp_command(chip, count & 0xff); + snd_sbdsp_command(chip, count >> 8); + } } - spin_unlock_irqrestore(&chip->reg_lock, flags); snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); return 0; @@ -206,11 +191,10 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - unsigned long flags; struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int count; - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_sbdsp_command(chip, chip->playback_format); @@ -225,35 +209,20 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; snd_sbdsp_reset(chip); if (runtime->channels > 1) { - spin_lock(&chip->mixer_lock); + guard(spinlock)(&chip->mixer_lock); /* restore output filter and set hardware to mono mode */ snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02); - spin_unlock(&chip->mixer_lock); } } else { snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); } snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } - spin_unlock_irqrestore(&chip->reg_lock, flags); - return 0; -} - -static int snd_sb8_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_sb8_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_lib_free_pages(substream); return 0; } static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) { - unsigned long flags; struct snd_sb *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; @@ -287,7 +256,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) chip->capture_format = SB_DSP_HI_INPUT_AUTO; break; } - /* fallthru */ + fallthrough; case SB_HW_20: chip->capture_format = SB_DSP_LO_INPUT_AUTO; break; @@ -307,34 +276,34 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) } size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); - spin_lock_irqsave(&chip->reg_lock, flags); - snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); - if (chip->hardware == SB_HW_JAZZ16) - snd_sbdsp_command(chip, format); - else if (stereo) - snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); - snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (stereo) { - snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); - spin_lock(&chip->mixer_lock); - /* save input filter status and turn it off */ - mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT); - snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20); - spin_unlock(&chip->mixer_lock); - /* just use force_mode16 for temporary storate... */ - chip->force_mode16 = mixreg; - } else { - snd_sbdsp_command(chip, 256 - runtime->rate_den); - } - if (chip->capture_format != SB_DSP_INPUT) { - if (chip->mode & SB_MODE_PLAYBACK_16) - count /= 2; - count--; - snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); - snd_sbdsp_command(chip, count & 0xff); - snd_sbdsp_command(chip, count >> 8); + scoped_guard(spinlock_irqsave, &chip->reg_lock) { + snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) + snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); + snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); + if (stereo) { + snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); + scoped_guard(spinlock, &chip->mixer_lock) { + /* save input filter status and turn it off */ + mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT); + snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20); + } + /* just use force_mode16 for temporary storate... */ + chip->force_mode16 = mixreg; + } else { + snd_sbdsp_command(chip, 256 - runtime->rate_den); + } + if (chip->capture_format != SB_DSP_INPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; + count--; + snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); + snd_sbdsp_command(chip, count & 0xff); + snd_sbdsp_command(chip, count >> 8); + } } - spin_unlock_irqrestore(&chip->reg_lock, flags); snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); return 0; @@ -343,11 +312,10 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - unsigned long flags; struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int count; - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_sbdsp_command(chip, chip->capture_format); @@ -363,9 +331,9 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, snd_sbdsp_reset(chip); if (runtime->channels > 1) { /* restore input filter status */ - spin_lock(&chip->mixer_lock); - snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16); - spin_unlock(&chip->mixer_lock); + scoped_guard(spinlock, &chip->mixer_lock) { + snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16); + } /* set hardware to mono mode */ snd_sbdsp_command(chip, SB_DSP_MONO_8BIT); } @@ -374,24 +342,21 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, } snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } - spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) { struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; snd_sb_ack_8bit(chip); switch (chip->mode) { case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ if (chip->hardware != SB_HW_JAZZ16) break; - /* fallthru */ + fallthrough; case SB_MODE_PLAYBACK_8: substream = chip->playback_substream; - runtime = substream->runtime; if (chip->playback_format == SB_DSP_OUTPUT) snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); snd_pcm_period_elapsed(substream); @@ -399,10 +364,9 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) case SB_MODE_CAPTURE_16: if (chip->hardware != SB_HW_JAZZ16) break; - /* fallthru */ + fallthrough; case SB_MODE_CAPTURE_8: substream = chip->capture_substream; - runtime = substream->runtime; if (chip->capture_format == SB_DSP_INPUT) snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START); snd_pcm_period_elapsed(substream); @@ -447,7 +411,7 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst */ -static struct snd_pcm_hardware snd_sb8_playback = +static const struct snd_pcm_hardware snd_sb8_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -466,7 +430,7 @@ static struct snd_pcm_hardware snd_sb8_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sb8_capture = +static const struct snd_pcm_hardware snd_sb8_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -493,15 +457,12 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) { struct snd_sb *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long flags; - spin_lock_irqsave(&chip->open_lock, flags); - if (chip->open) { - spin_unlock_irqrestore(&chip->open_lock, flags); - return -EAGAIN; + scoped_guard(spinlock_irqsave, &chip->open_lock) { + if (chip->open) + return -EAGAIN; + chip->open |= SB_OPEN_PCM; } - chip->open |= SB_OPEN_PCM; - spin_unlock_irqrestore(&chip->open_lock, flags); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { chip->playback_substream = substream; runtime->hw = snd_sb8_playback; @@ -535,6 +496,7 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) } else { runtime->hw.rate_max = 15000; } + break; default: break; } @@ -553,18 +515,16 @@ static int snd_sb8_open(struct snd_pcm_substream *substream) static int snd_sb8_close(struct snd_pcm_substream *substream) { - unsigned long flags; struct snd_sb *chip = snd_pcm_substream_chip(substream); chip->playback_substream = NULL; chip->capture_substream = NULL; - spin_lock_irqsave(&chip->open_lock, flags); + guard(spinlock_irqsave)(&chip->open_lock); chip->open &= ~SB_OPEN_PCM; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) chip->mode &= ~SB_MODE_PLAYBACK; else chip->mode &= ~SB_MODE_CAPTURE; - spin_unlock_irqrestore(&chip->open_lock, flags); return 0; } @@ -572,38 +532,31 @@ static int snd_sb8_close(struct snd_pcm_substream *substream) * Initialization part */ -static struct snd_pcm_ops snd_sb8_playback_ops = { +static const struct snd_pcm_ops snd_sb8_playback_ops = { .open = snd_sb8_open, .close = snd_sb8_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_sb8_hw_params, - .hw_free = snd_sb8_hw_free, .prepare = snd_sb8_playback_prepare, .trigger = snd_sb8_playback_trigger, .pointer = snd_sb8_playback_pointer, }; -static struct snd_pcm_ops snd_sb8_capture_ops = { +static const struct snd_pcm_ops snd_sb8_capture_ops = { .open = snd_sb8_open, .close = snd_sb8_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_sb8_hw_params, - .hw_free = snd_sb8_hw_free, .prepare = snd_sb8_capture_prepare, .trigger = snd_sb8_capture_trigger, .pointer = snd_sb8_capture_pointer, }; -int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) +int snd_sb8dsp_pcm(struct snd_sb *chip, int device) { struct snd_card *card = chip->card; struct snd_pcm *pcm; int err; size_t max_prealloc = 64 * 1024; - if (rpcm) - *rpcm = NULL; - if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0) + err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm); + if (err < 0) return err; sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; @@ -614,12 +567,9 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) if (chip->dma8 > 3 || chip->dma16 >= 0) max_prealloc = 128 * 1024; - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_isa_data(), - 64*1024, max_prealloc); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, + card->dev, 64*1024, max_prealloc); - if (rpcm) - *rpcm = pcm; return 0; } @@ -628,19 +578,3 @@ EXPORT_SYMBOL(snd_sb8dsp_interrupt); /* sb8_midi.c */ EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt); EXPORT_SYMBOL(snd_sb8dsp_midi); - -/* - * INIT part - */ - -static int __init alsa_sb8_init(void) -{ - return 0; -} - -static void __exit alsa_sb8_exit(void) -{ -} - -module_init(alsa_sb8_init) -module_exit(alsa_sb8_exit) |
