mirror of https://github.com/torvalds/linux.git
ALSA: sb: Use guard() for spin locks
Clean up the code using guard() for spin locks. Merely code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250829145300.5460-14-tiwai@suse.de
This commit is contained in:
parent
d994b2ba8f
commit
5487fb09fa
|
|
@ -310,7 +310,6 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
|
||||||
#ifdef CONFIG_SND_SB16_CSP
|
#ifdef CONFIG_SND_SB16_CSP
|
||||||
struct snd_hwdep *xcsp = NULL;
|
struct snd_hwdep *xcsp = NULL;
|
||||||
#endif
|
#endif
|
||||||
unsigned long flags;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
xirq = irq[dev];
|
xirq = irq[dev];
|
||||||
|
|
@ -421,11 +420,11 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* setup Mic AGC */
|
/* setup Mic AGC */
|
||||||
spin_lock_irqsave(&chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
|
||||||
snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
|
snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
|
||||||
(snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
|
(snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
|
||||||
(mic_agc[dev] ? 0x00 : 0x01));
|
(mic_agc[dev] ? 0x00 : 0x01));
|
||||||
spin_unlock_irqrestore(&chip->mixer_lock, flags);
|
}
|
||||||
|
|
||||||
err = snd_card_register(card);
|
err = snd_card_register(card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,6 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||||
__le32 item_type;
|
__le32 item_type;
|
||||||
struct desc_header funcdesc_h;
|
struct desc_header funcdesc_h;
|
||||||
|
|
||||||
unsigned long flags;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (copy_from_user(&info, mcode, sizeof(info)))
|
if (copy_from_user(&info, mcode, sizeof(info)))
|
||||||
|
|
@ -429,10 +428,9 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||||
p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
|
p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
|
||||||
|
|
||||||
/* Decouple CSP from IRQ and DMAREQ lines */
|
/* Decouple CSP from IRQ and DMAREQ lines */
|
||||||
spin_lock_irqsave(&p->chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&p->chip->reg_lock);
|
||||||
set_mode_register(p->chip, 0xfc);
|
set_mode_register(p->chip, 0xfc);
|
||||||
set_mode_register(p->chip, 0x00);
|
set_mode_register(p->chip, 0x00);
|
||||||
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
|
|
||||||
|
|
||||||
/* finished loading successfully */
|
/* finished loading successfully */
|
||||||
p->running = SNDRV_SB_CSP_ST_LOADED; /* set LOADED flag */
|
p->running = SNDRV_SB_CSP_ST_LOADED; /* set LOADED flag */
|
||||||
|
|
@ -542,10 +540,8 @@ static int set_mode_register(struct snd_sb *chip, unsigned char mode)
|
||||||
static int csp_detect(struct snd_sb *chip, int *version)
|
static int csp_detect(struct snd_sb *chip, int *version)
|
||||||
{
|
{
|
||||||
unsigned char csp_test1, csp_test2;
|
unsigned char csp_test1, csp_test2;
|
||||||
unsigned long flags;
|
|
||||||
int result = -ENODEV;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
|
|
||||||
set_codec_parameter(chip, 0x00, 0x00);
|
set_codec_parameter(chip, 0x00, 0x00);
|
||||||
set_mode_register(chip, 0xfc); /* 0xfc = ?? */
|
set_mode_register(chip, 0xfc); /* 0xfc = ?? */
|
||||||
|
|
@ -554,23 +550,21 @@ static int csp_detect(struct snd_sb *chip, int *version)
|
||||||
set_register(chip, 0x83, ~csp_test1);
|
set_register(chip, 0x83, ~csp_test1);
|
||||||
csp_test2 = read_register(chip, 0x83);
|
csp_test2 = read_register(chip, 0x83);
|
||||||
if (csp_test2 != (csp_test1 ^ 0xff))
|
if (csp_test2 != (csp_test1 ^ 0xff))
|
||||||
goto __fail;
|
return -ENODEV;
|
||||||
|
|
||||||
set_register(chip, 0x83, csp_test1);
|
set_register(chip, 0x83, csp_test1);
|
||||||
csp_test2 = read_register(chip, 0x83);
|
csp_test2 = read_register(chip, 0x83);
|
||||||
if (csp_test2 != csp_test1)
|
if (csp_test2 != csp_test1)
|
||||||
goto __fail;
|
return -ENODEV;
|
||||||
|
|
||||||
set_mode_register(chip, 0x00); /* 0x00 = ? */
|
set_mode_register(chip, 0x00); /* 0x00 = ? */
|
||||||
|
|
||||||
*version = get_version(chip);
|
*version = get_version(chip);
|
||||||
snd_sbdsp_reset(chip); /* reset DSP after getversion! */
|
snd_sbdsp_reset(chip); /* reset DSP after getversion! */
|
||||||
if (*version >= 0x10 && *version <= 0x1f)
|
if (*version >= 0x10 && *version <= 0x1f)
|
||||||
result = 0; /* valid version id */
|
return 0; /* valid version id */
|
||||||
|
|
||||||
__fail:
|
return -ENODEV;
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -608,14 +602,12 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
|
||||||
{
|
{
|
||||||
int status, i;
|
int status, i;
|
||||||
int err;
|
int err;
|
||||||
int result = -EIO;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&p->chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&p->chip->reg_lock);
|
||||||
snd_sbdsp_command(p->chip, 0x01); /* CSP download command */
|
snd_sbdsp_command(p->chip, 0x01); /* CSP download command */
|
||||||
if (snd_sbdsp_get_byte(p->chip)) {
|
if (snd_sbdsp_get_byte(p->chip)) {
|
||||||
dev_dbg(p->chip->card->dev, "%s: Download command failed\n", __func__);
|
dev_dbg(p->chip->card->dev, "%s: Download command failed\n", __func__);
|
||||||
goto __fail;
|
return -EIO;
|
||||||
}
|
}
|
||||||
/* Send CSP low byte (size - 1) */
|
/* Send CSP low byte (size - 1) */
|
||||||
snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
|
snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
|
||||||
|
|
@ -625,10 +617,10 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
|
||||||
/* load from kernel space */
|
/* load from kernel space */
|
||||||
while (size--) {
|
while (size--) {
|
||||||
if (!snd_sbdsp_command(p->chip, *buf++))
|
if (!snd_sbdsp_command(p->chip, *buf++))
|
||||||
goto __fail;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (snd_sbdsp_get_byte(p->chip))
|
if (snd_sbdsp_get_byte(p->chip))
|
||||||
goto __fail;
|
return -EIO;
|
||||||
|
|
||||||
if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
|
if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
@ -644,7 +636,7 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
|
||||||
dev_dbg(p->chip->card->dev,
|
dev_dbg(p->chip->card->dev,
|
||||||
"%s: Microcode initialization failed\n",
|
"%s: Microcode initialization failed\n",
|
||||||
__func__);
|
__func__);
|
||||||
goto __fail;
|
return -EIO;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|
@ -652,24 +644,21 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
|
||||||
* Start CSP chip if no 16bit DMA channel is set - some kind
|
* Start CSP chip if no 16bit DMA channel is set - some kind
|
||||||
* of autorun or perhaps a bugfix?
|
* of autorun or perhaps a bugfix?
|
||||||
*/
|
*/
|
||||||
spin_lock(&p->chip->mixer_lock);
|
scoped_guard(spinlock, &p->chip->mixer_lock) {
|
||||||
status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
|
status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
|
||||||
spin_unlock(&p->chip->mixer_lock);
|
}
|
||||||
if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
|
if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
|
||||||
err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
|
err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
|
||||||
set_codec_parameter(p->chip, 0xff, 0x00));
|
set_codec_parameter(p->chip, 0xff, 0x00));
|
||||||
snd_sbdsp_reset(p->chip); /* really! */
|
snd_sbdsp_reset(p->chip); /* really! */
|
||||||
if (err)
|
if (err)
|
||||||
goto __fail;
|
return -EIO;
|
||||||
set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
||||||
set_mode_register(p->chip, 0x70); /* 70 = RUN */
|
set_mode_register(p->chip, 0x70); /* 70 = RUN */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = 0;
|
|
||||||
|
|
||||||
__fail:
|
return 0;
|
||||||
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
|
static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
|
||||||
|
|
@ -716,7 +705,6 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
|
||||||
*/
|
*/
|
||||||
static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode)
|
static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* if CSP is running or manually loaded then exit */
|
/* if CSP is running or manually loaded then exit */
|
||||||
|
|
@ -757,10 +745,9 @@ static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt,
|
||||||
default:
|
default:
|
||||||
/* Decouple CSP from IRQ and DMAREQ lines */
|
/* Decouple CSP from IRQ and DMAREQ lines */
|
||||||
if (p->running & SNDRV_SB_CSP_ST_AUTO) {
|
if (p->running & SNDRV_SB_CSP_ST_AUTO) {
|
||||||
spin_lock_irqsave(&p->chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&p->chip->reg_lock);
|
||||||
set_mode_register(p->chip, 0xfc);
|
set_mode_register(p->chip, 0xfc);
|
||||||
set_mode_register(p->chip, 0x00);
|
set_mode_register(p->chip, 0x00);
|
||||||
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
|
|
||||||
p->running = 0; /* clear autoloaded flag */
|
p->running = 0; /* clear autoloaded flag */
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -792,7 +779,6 @@ static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channel
|
||||||
unsigned char s_type; /* sample type */
|
unsigned char s_type; /* sample type */
|
||||||
unsigned char mixL, mixR;
|
unsigned char mixL, mixR;
|
||||||
int result = -EIO;
|
int result = -EIO;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
|
if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
|
||||||
dev_dbg(dev, "%s: Microcode not loaded\n", __func__);
|
dev_dbg(dev, "%s: Microcode not loaded\n", __func__);
|
||||||
|
|
@ -812,55 +798,54 @@ static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channel
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mute PCM volume */
|
/* Mute PCM volume */
|
||||||
spin_lock_irqsave(&p->chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &p->chip->mixer_lock) {
|
||||||
mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
|
mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
|
||||||
mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
|
mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
|
||||||
spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
|
|
||||||
|
|
||||||
spin_lock(&p->chip->reg_lock);
|
|
||||||
set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
|
||||||
set_mode_register(p->chip, 0x70); /* 70 = RUN */
|
|
||||||
|
|
||||||
s_type = 0x00;
|
|
||||||
if (channels == SNDRV_SB_CSP_MONO)
|
|
||||||
s_type = 0x11; /* 000n 000n (n = 1 if mono) */
|
|
||||||
if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT)
|
|
||||||
s_type |= 0x22; /* 00dX 00dX (d = 1 if 8 bit samples) */
|
|
||||||
|
|
||||||
if (set_codec_parameter(p->chip, 0x81, s_type)) {
|
|
||||||
dev_dbg(dev, "%s: Set sample type command failed\n", __func__);
|
|
||||||
goto __fail;
|
|
||||||
}
|
}
|
||||||
if (set_codec_parameter(p->chip, 0x80, 0x00)) {
|
|
||||||
dev_dbg(dev, "%s: Codec start command failed\n", __func__);
|
scoped_guard(spinlock, &p->chip->reg_lock) {
|
||||||
goto __fail;
|
set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
||||||
|
set_mode_register(p->chip, 0x70); /* 70 = RUN */
|
||||||
|
|
||||||
|
s_type = 0x00;
|
||||||
|
if (channels == SNDRV_SB_CSP_MONO)
|
||||||
|
s_type = 0x11; /* 000n 000n (n = 1 if mono) */
|
||||||
|
if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT)
|
||||||
|
s_type |= 0x22; /* 00dX 00dX (d = 1 if 8 bit samples) */
|
||||||
|
|
||||||
|
if (set_codec_parameter(p->chip, 0x81, s_type)) {
|
||||||
|
dev_dbg(dev, "%s: Set sample type command failed\n", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (set_codec_parameter(p->chip, 0x80, 0x00)) {
|
||||||
|
dev_dbg(dev, "%s: Codec start command failed\n", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p->run_width = sample_width;
|
||||||
|
p->run_channels = channels;
|
||||||
|
|
||||||
|
p->running |= SNDRV_SB_CSP_ST_RUNNING;
|
||||||
|
|
||||||
|
if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) {
|
||||||
|
set_codec_parameter(p->chip, 0xe0, 0x01);
|
||||||
|
/* enable QSound decoder */
|
||||||
|
set_codec_parameter(p->chip, 0x00, 0xff);
|
||||||
|
set_codec_parameter(p->chip, 0x01, 0xff);
|
||||||
|
p->running |= SNDRV_SB_CSP_ST_QSOUND;
|
||||||
|
/* set QSound startup value */
|
||||||
|
snd_sb_csp_qsound_transfer(p);
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
p->run_width = sample_width;
|
|
||||||
p->run_channels = channels;
|
|
||||||
|
|
||||||
p->running |= SNDRV_SB_CSP_ST_RUNNING;
|
|
||||||
|
|
||||||
if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) {
|
|
||||||
set_codec_parameter(p->chip, 0xe0, 0x01);
|
|
||||||
/* enable QSound decoder */
|
|
||||||
set_codec_parameter(p->chip, 0x00, 0xff);
|
|
||||||
set_codec_parameter(p->chip, 0x01, 0xff);
|
|
||||||
p->running |= SNDRV_SB_CSP_ST_QSOUND;
|
|
||||||
/* set QSound startup value */
|
|
||||||
snd_sb_csp_qsound_transfer(p);
|
|
||||||
}
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
__fail:
|
|
||||||
spin_unlock(&p->chip->reg_lock);
|
|
||||||
|
|
||||||
/* restore PCM volume */
|
/* restore PCM volume */
|
||||||
spin_lock_irqsave(&p->chip->mixer_lock, flags);
|
if (result < 0) {
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
|
guard(spinlock_irqsave)(&p->chip->mixer_lock);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
|
||||||
spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -872,36 +857,35 @@ static int snd_sb_csp_stop(struct snd_sb_csp * p)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
unsigned char mixL, mixR;
|
unsigned char mixL, mixR;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
|
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Mute PCM volume */
|
/* Mute PCM volume */
|
||||||
spin_lock_irqsave(&p->chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &p->chip->mixer_lock) {
|
||||||
mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
|
mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
|
||||||
mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
|
mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
|
||||||
spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
|
}
|
||||||
|
|
||||||
spin_lock(&p->chip->reg_lock);
|
scoped_guard(spinlock, &p->chip->reg_lock) {
|
||||||
if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
|
if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
|
||||||
set_codec_parameter(p->chip, 0xe0, 0x01);
|
set_codec_parameter(p->chip, 0xe0, 0x01);
|
||||||
/* disable QSound decoder */
|
/* disable QSound decoder */
|
||||||
set_codec_parameter(p->chip, 0x00, 0x00);
|
set_codec_parameter(p->chip, 0x00, 0x00);
|
||||||
set_codec_parameter(p->chip, 0x01, 0x00);
|
set_codec_parameter(p->chip, 0x01, 0x00);
|
||||||
|
|
||||||
p->running &= ~SNDRV_SB_CSP_ST_QSOUND;
|
p->running &= ~SNDRV_SB_CSP_ST_QSOUND;
|
||||||
|
}
|
||||||
|
result = set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
||||||
}
|
}
|
||||||
result = set_mode_register(p->chip, 0xc0); /* c0 = STOP */
|
|
||||||
spin_unlock(&p->chip->reg_lock);
|
|
||||||
|
|
||||||
/* restore PCM volume */
|
/* restore PCM volume */
|
||||||
spin_lock_irqsave(&p->chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &p->chip->mixer_lock) {
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
|
||||||
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
|
snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
|
||||||
spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
|
}
|
||||||
|
|
||||||
if (!(result))
|
if (!(result))
|
||||||
p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
|
p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
|
||||||
|
|
@ -914,14 +898,13 @@ static int snd_sb_csp_stop(struct snd_sb_csp * p)
|
||||||
static int snd_sb_csp_pause(struct snd_sb_csp * p)
|
static int snd_sb_csp_pause(struct snd_sb_csp * p)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
|
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
spin_lock_irqsave(&p->chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &p->chip->reg_lock) {
|
||||||
result = set_codec_parameter(p->chip, 0x80, 0xff);
|
result = set_codec_parameter(p->chip, 0x80, 0xff);
|
||||||
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
|
}
|
||||||
if (!(result))
|
if (!(result))
|
||||||
p->running |= SNDRV_SB_CSP_ST_PAUSED;
|
p->running |= SNDRV_SB_CSP_ST_PAUSED;
|
||||||
|
|
||||||
|
|
@ -934,14 +917,13 @@ static int snd_sb_csp_pause(struct snd_sb_csp * p)
|
||||||
static int snd_sb_csp_restart(struct snd_sb_csp * p)
|
static int snd_sb_csp_restart(struct snd_sb_csp * p)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
|
if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
spin_lock_irqsave(&p->chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &p->chip->reg_lock) {
|
||||||
result = set_codec_parameter(p->chip, 0x80, 0x00);
|
result = set_codec_parameter(p->chip, 0x80, 0x00);
|
||||||
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
|
}
|
||||||
if (!(result))
|
if (!(result))
|
||||||
p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
|
p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
|
||||||
|
|
||||||
|
|
@ -967,15 +949,13 @@ static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||||
static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int change;
|
int change;
|
||||||
unsigned char nval;
|
unsigned char nval;
|
||||||
|
|
||||||
nval = ucontrol->value.integer.value[0] & 0x01;
|
nval = ucontrol->value.integer.value[0] & 0x01;
|
||||||
spin_lock_irqsave(&p->q_lock, flags);
|
guard(spinlock_irqsave)(&p->q_lock);
|
||||||
change = p->q_enabled != nval;
|
change = p->q_enabled != nval;
|
||||||
p->q_enabled = nval;
|
p->q_enabled = nval;
|
||||||
spin_unlock_irqrestore(&p->q_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -991,19 +971,16 @@ static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||||
static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&p->q_lock, flags);
|
guard(spinlock_irqsave)(&p->q_lock);
|
||||||
ucontrol->value.integer.value[0] = p->qpos_left;
|
ucontrol->value.integer.value[0] = p->qpos_left;
|
||||||
ucontrol->value.integer.value[1] = p->qpos_right;
|
ucontrol->value.integer.value[1] = p->qpos_right;
|
||||||
spin_unlock_irqrestore(&p->q_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int change;
|
int change;
|
||||||
unsigned char nval1, nval2;
|
unsigned char nval1, nval2;
|
||||||
|
|
||||||
|
|
@ -1013,12 +990,11 @@ static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl
|
||||||
nval2 = ucontrol->value.integer.value[1];
|
nval2 = ucontrol->value.integer.value[1];
|
||||||
if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
|
if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
|
||||||
nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
|
nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
|
||||||
spin_lock_irqsave(&p->q_lock, flags);
|
guard(spinlock_irqsave)(&p->q_lock);
|
||||||
change = p->qpos_left != nval1 || p->qpos_right != nval2;
|
change = p->qpos_left != nval1 || p->qpos_right != nval2;
|
||||||
p->qpos_left = nval1;
|
p->qpos_left = nval1;
|
||||||
p->qpos_right = nval2;
|
p->qpos_right = nval2;
|
||||||
p->qpos_changed = change;
|
p->qpos_changed = change;
|
||||||
spin_unlock_irqrestore(&p->q_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1074,7 +1050,6 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p)
|
||||||
static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
|
static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
|
||||||
{
|
{
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (snd_BUG_ON(!p))
|
if (snd_BUG_ON(!p))
|
||||||
return;
|
return;
|
||||||
|
|
@ -1087,9 +1062,8 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
|
||||||
p->qsound_space = NULL;
|
p->qsound_space = NULL;
|
||||||
|
|
||||||
/* cancel pending transfer of QSound parameters */
|
/* cancel pending transfer of QSound parameters */
|
||||||
spin_lock_irqsave (&p->q_lock, flags);
|
guard(spinlock_irqsave)(&p->q_lock);
|
||||||
p->qpos_changed = 0;
|
p->qpos_changed = 0;
|
||||||
spin_unlock_irqrestore (&p->q_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1100,7 +1074,7 @@ static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
|
||||||
{
|
{
|
||||||
int err = -ENXIO;
|
int err = -ENXIO;
|
||||||
|
|
||||||
spin_lock(&p->q_lock);
|
guard(spinlock)(&p->q_lock);
|
||||||
if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
|
if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
|
||||||
set_codec_parameter(p->chip, 0xe0, 0x01);
|
set_codec_parameter(p->chip, 0xe0, 0x01);
|
||||||
/* left channel */
|
/* left channel */
|
||||||
|
|
@ -1112,7 +1086,6 @@ static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
p->qpos_changed = 0;
|
p->qpos_changed = 0;
|
||||||
spin_unlock(&p->q_lock);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,8 @@ static void snd_sb16_csp_update(struct snd_sb *chip)
|
||||||
struct snd_sb_csp *csp = chip->csp;
|
struct snd_sb_csp *csp = chip->csp;
|
||||||
|
|
||||||
if (csp->qpos_changed) {
|
if (csp->qpos_changed) {
|
||||||
spin_lock(&chip->reg_lock);
|
guard(spinlock)(&chip->reg_lock);
|
||||||
csp->ops.csp_qsound_transfer (csp);
|
csp->ops.csp_qsound_transfer (csp);
|
||||||
spin_unlock(&chip->reg_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,9 +212,7 @@ static void snd_sb16_setup_rate(struct snd_sb *chip,
|
||||||
unsigned short rate,
|
unsigned short rate,
|
||||||
int channel)
|
int channel)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
|
||||||
if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
|
if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
|
||||||
snd_sb_ack_16bit(chip);
|
snd_sb_ack_16bit(chip);
|
||||||
else
|
else
|
||||||
|
|
@ -229,12 +226,10 @@ static void snd_sb16_setup_rate(struct snd_sb *chip,
|
||||||
snd_sbdsp_command(chip, rate >> 8);
|
snd_sbdsp_command(chip, rate >> 8);
|
||||||
snd_sbdsp_command(chip, rate & 0xff);
|
snd_sbdsp_command(chip, rate & 0xff);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
|
static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned char format;
|
unsigned char format;
|
||||||
|
|
@ -253,7 +248,7 @@ static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
|
||||||
snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
|
snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
|
||||||
|
|
||||||
count = snd_pcm_lib_period_bytes(substream);
|
count = snd_pcm_lib_period_bytes(substream);
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
if (chip->mode & SB_MODE_PLAYBACK_16) {
|
if (chip->mode & SB_MODE_PLAYBACK_16) {
|
||||||
count >>= 1;
|
count >>= 1;
|
||||||
count--;
|
count--;
|
||||||
|
|
@ -270,7 +265,6 @@ static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
|
||||||
snd_sbdsp_command(chip, count >> 8);
|
snd_sbdsp_command(chip, count >> 8);
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,9 +272,8 @@ static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
|
||||||
int cmd)
|
int cmd)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
spin_lock(&chip->reg_lock);
|
guard(spinlock)(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
case SNDRV_PCM_TRIGGER_RESUME:
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
|
|
@ -296,15 +289,13 @@ static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
|
||||||
chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
|
chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
spin_unlock(&chip->reg_lock);
|
return 0;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
|
static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned char format;
|
unsigned char format;
|
||||||
|
|
@ -322,7 +313,7 @@ static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
|
||||||
snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
|
snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
|
||||||
|
|
||||||
count = snd_pcm_lib_period_bytes(substream);
|
count = snd_pcm_lib_period_bytes(substream);
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
if (chip->mode & SB_MODE_CAPTURE_16) {
|
if (chip->mode & SB_MODE_CAPTURE_16) {
|
||||||
count >>= 1;
|
count >>= 1;
|
||||||
count--;
|
count--;
|
||||||
|
|
@ -339,7 +330,6 @@ static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
|
||||||
snd_sbdsp_command(chip, count >> 8);
|
snd_sbdsp_command(chip, count >> 8);
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,9 +337,8 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
int cmd)
|
int cmd)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
spin_lock(&chip->reg_lock);
|
guard(spinlock)(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
case SNDRV_PCM_TRIGGER_RESUME:
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
|
|
@ -365,10 +354,9 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
chip->mode &= ~SB_RATE_LOCK_CAPTURE;
|
chip->mode &= ~SB_RATE_LOCK_CAPTURE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
spin_unlock(&chip->reg_lock);
|
return 0;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
|
irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
|
||||||
|
|
@ -377,9 +365,9 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
|
||||||
unsigned char status;
|
unsigned char status;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
spin_lock(&chip->mixer_lock);
|
scoped_guard(spinlock, &chip->mixer_lock) {
|
||||||
status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
|
status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
|
||||||
spin_unlock(&chip->mixer_lock);
|
}
|
||||||
if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
|
if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
|
||||||
chip->rmidi_callback(irq, chip->rmidi->private_data);
|
chip->rmidi_callback(irq, chip->rmidi->private_data);
|
||||||
if (status & SB_IRQTYPE_8BIT) {
|
if (status & SB_IRQTYPE_8BIT) {
|
||||||
|
|
@ -393,11 +381,11 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
|
||||||
snd_pcm_period_elapsed(chip->capture_substream);
|
snd_pcm_period_elapsed(chip->capture_substream);
|
||||||
ok++;
|
ok++;
|
||||||
}
|
}
|
||||||
spin_lock(&chip->reg_lock);
|
scoped_guard(spinlock, &chip->reg_lock) {
|
||||||
if (!ok)
|
if (!ok)
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
||||||
snd_sb_ack_8bit(chip);
|
snd_sb_ack_8bit(chip);
|
||||||
spin_unlock(&chip->reg_lock);
|
}
|
||||||
}
|
}
|
||||||
if (status & SB_IRQTYPE_16BIT) {
|
if (status & SB_IRQTYPE_16BIT) {
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
|
@ -410,11 +398,11 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
|
||||||
snd_pcm_period_elapsed(chip->capture_substream);
|
snd_pcm_period_elapsed(chip->capture_substream);
|
||||||
ok++;
|
ok++;
|
||||||
}
|
}
|
||||||
spin_lock(&chip->reg_lock);
|
scoped_guard(spinlock, &chip->reg_lock) {
|
||||||
if (!ok)
|
if (!ok)
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
|
snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
|
||||||
snd_sb_ack_16bit(chip);
|
snd_sb_ack_16bit(chip);
|
||||||
spin_unlock(&chip->reg_lock);
|
}
|
||||||
}
|
}
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
@ -491,15 +479,12 @@ static const struct snd_pcm_hardware snd_sb16_capture =
|
||||||
|
|
||||||
static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
|
static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
if (chip->mode & SB_MODE_PLAYBACK) {
|
if (chip->mode & SB_MODE_PLAYBACK)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
|
||||||
runtime->hw = snd_sb16_playback;
|
runtime->hw = snd_sb16_playback;
|
||||||
|
|
||||||
/* skip if 16 bit DMA was reserved for capture */
|
/* skip if 16 bit DMA was reserved for capture */
|
||||||
|
|
@ -533,7 +518,6 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
|
||||||
runtime->hw.period_bytes_max = 64 * 1024;
|
runtime->hw.period_bytes_max = 64 * 1024;
|
||||||
goto __open_ok;
|
goto __open_ok;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
__open_ok:
|
__open_ok:
|
||||||
|
|
@ -547,34 +531,28 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
|
||||||
if (chip->mode & SB_RATE_LOCK)
|
if (chip->mode & SB_RATE_LOCK)
|
||||||
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
|
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
|
||||||
chip->playback_substream = substream;
|
chip->playback_substream = substream;
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
|
static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
|
|
||||||
snd_sb16_csp_playback_close(chip);
|
snd_sb16_csp_playback_close(chip);
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
chip->playback_substream = NULL;
|
chip->playback_substream = NULL;
|
||||||
chip->mode &= ~SB_MODE_PLAYBACK;
|
chip->mode &= ~SB_MODE_PLAYBACK;
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
|
static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
if (chip->mode & SB_MODE_CAPTURE) {
|
if (chip->mode & SB_MODE_CAPTURE)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
|
||||||
runtime->hw = snd_sb16_capture;
|
runtime->hw = snd_sb16_capture;
|
||||||
|
|
||||||
/* skip if 16 bit DMA was reserved for playback */
|
/* skip if 16 bit DMA was reserved for playback */
|
||||||
|
|
@ -608,7 +586,6 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
|
||||||
runtime->hw.period_bytes_max = 64 * 1024;
|
runtime->hw.period_bytes_max = 64 * 1024;
|
||||||
goto __open_ok;
|
goto __open_ok;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
__open_ok:
|
__open_ok:
|
||||||
|
|
@ -622,20 +599,17 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
|
||||||
if (chip->mode & SB_RATE_LOCK)
|
if (chip->mode & SB_RATE_LOCK)
|
||||||
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
|
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
|
||||||
chip->capture_substream = substream;
|
chip->capture_substream = substream;
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
|
static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
|
|
||||||
snd_sb16_csp_capture_close(chip);
|
snd_sb16_csp_capture_close(chip);
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
chip->capture_substream = NULL;
|
chip->capture_substream = NULL;
|
||||||
chip->mode &= ~SB_MODE_CAPTURE;
|
chip->mode &= ~SB_MODE_CAPTURE;
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,18 +662,15 @@ static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_c
|
||||||
static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip);
|
ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip);
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
unsigned char nval, oval;
|
unsigned char nval, oval;
|
||||||
int change;
|
int change;
|
||||||
|
|
||||||
|
|
@ -709,11 +680,11 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||||
nval = ucontrol->value.enumerated.item[0];
|
nval = ucontrol->value.enumerated.item[0];
|
||||||
if (nval > 2)
|
if (nval > 2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->reg_lock) {
|
||||||
oval = snd_sb16_get_dma_mode(chip);
|
oval = snd_sb16_get_dma_mode(chip);
|
||||||
change = nval != oval;
|
change = nval != oval;
|
||||||
snd_sb16_set_dma_mode(chip, nval);
|
snd_sb16_set_dma_mode(chip, nval);
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
}
|
||||||
if (change) {
|
if (change) {
|
||||||
snd_dma_disable(chip->dma8);
|
snd_dma_disable(chip->dma8);
|
||||||
snd_dma_disable(chip->dma16);
|
snd_dma_disable(chip->dma16);
|
||||||
|
|
@ -735,14 +706,13 @@ static const struct snd_kcontrol_new snd_sb16_dma_control = {
|
||||||
|
|
||||||
int snd_sb16dsp_configure(struct snd_sb * chip)
|
int snd_sb16dsp_configure(struct snd_sb * chip)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
unsigned char irqreg = 0, dmareg = 0, mpureg;
|
unsigned char irqreg = 0, dmareg = 0, mpureg;
|
||||||
unsigned char realirq, realdma, realmpureg;
|
unsigned char realirq, realdma, realmpureg;
|
||||||
/* note: mpu register should be present only on SB16 Vibra soundcards */
|
/* note: mpu register should be present only on SB16 Vibra soundcards */
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
|
||||||
mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
|
mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
|
||||||
spin_unlock_irqrestore(&chip->mixer_lock, flags);
|
}
|
||||||
switch (chip->irq) {
|
switch (chip->irq) {
|
||||||
case 2:
|
case 2:
|
||||||
case 9:
|
case 9:
|
||||||
|
|
@ -800,18 +770,17 @@ int snd_sb16dsp_configure(struct snd_sb * chip)
|
||||||
default:
|
default:
|
||||||
mpureg |= 0x02; /* disable MPU */
|
mpureg |= 0x02; /* disable MPU */
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&chip->mixer_lock, flags);
|
|
||||||
|
|
||||||
snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
|
scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
|
||||||
realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
|
snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
|
||||||
|
realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
|
||||||
|
|
||||||
snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
|
snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
|
||||||
realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
|
realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
|
||||||
|
|
||||||
snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
|
snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
|
||||||
realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
|
realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&chip->mixer_lock, flags);
|
|
||||||
if ((~realirq) & irqreg || (~realdma) & dmareg) {
|
if ((~realirq) & irqreg || (~realdma) & dmareg) {
|
||||||
dev_err(chip->card->dev,
|
dev_err(chip->card->dev,
|
||||||
"SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n",
|
"SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n",
|
||||||
|
|
|
||||||
|
|
@ -89,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)
|
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_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned int mixreg, rate, size, count;
|
unsigned int mixreg, rate, size, count;
|
||||||
|
|
@ -142,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);
|
size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
|
||||||
count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
|
count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->reg_lock) {
|
||||||
snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
|
snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
|
||||||
if (chip->hardware == SB_HW_JAZZ16)
|
if (chip->hardware == SB_HW_JAZZ16)
|
||||||
snd_sbdsp_command(chip, format);
|
snd_sbdsp_command(chip, format);
|
||||||
else if (stereo) {
|
else if (stereo) {
|
||||||
/* set playback stereo mode */
|
/* set playback stereo mode */
|
||||||
spin_lock(&chip->mixer_lock);
|
scoped_guard(spinlock, &chip->mixer_lock) {
|
||||||
mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
|
mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
|
||||||
snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
|
snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
|
||||||
spin_unlock(&chip->mixer_lock);
|
}
|
||||||
|
|
||||||
/* Soundblaster hardware programming reference guide, 3-23 */
|
/* Soundblaster hardware programming reference guide, 3-23 */
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
|
snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
|
||||||
runtime->dma_area[0] = 0x80;
|
runtime->dma_area[0] = 0x80;
|
||||||
snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
|
snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
|
||||||
/* force interrupt */
|
/* force interrupt */
|
||||||
snd_sbdsp_command(chip, SB_DSP_OUTPUT);
|
snd_sbdsp_command(chip, SB_DSP_OUTPUT);
|
||||||
snd_sbdsp_command(chip, 0);
|
snd_sbdsp_command(chip, 0);
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
snd_dma_program(dma, runtime->dma_addr,
|
snd_dma_program(dma, runtime->dma_addr,
|
||||||
size, DMA_MODE_WRITE | DMA_AUTOINIT);
|
size, DMA_MODE_WRITE | DMA_AUTOINIT);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -192,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,
|
static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
|
||||||
int cmd)
|
int cmd)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
snd_sbdsp_command(chip, chip->playback_format);
|
snd_sbdsp_command(chip, chip->playback_format);
|
||||||
|
|
@ -211,23 +209,20 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
snd_sbdsp_reset(chip);
|
snd_sbdsp_reset(chip);
|
||||||
if (runtime->channels > 1) {
|
if (runtime->channels > 1) {
|
||||||
spin_lock(&chip->mixer_lock);
|
guard(spinlock)(&chip->mixer_lock);
|
||||||
/* restore output filter and set hardware to mono mode */
|
/* restore output filter and set hardware to mono mode */
|
||||||
snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02);
|
snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02);
|
||||||
spin_unlock(&chip->mixer_lock);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
|
||||||
}
|
}
|
||||||
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
|
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_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned int mixreg, rate, size, count;
|
unsigned int mixreg, rate, size, count;
|
||||||
|
|
@ -281,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);
|
size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
|
||||||
count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
|
count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->reg_lock) {
|
||||||
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
||||||
if (chip->hardware == SB_HW_JAZZ16)
|
if (chip->hardware == SB_HW_JAZZ16)
|
||||||
snd_sbdsp_command(chip, format);
|
snd_sbdsp_command(chip, format);
|
||||||
else if (stereo)
|
else if (stereo)
|
||||||
snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
|
snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
|
||||||
snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
|
snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
|
||||||
if (stereo) {
|
if (stereo) {
|
||||||
snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
|
snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
|
||||||
spin_lock(&chip->mixer_lock);
|
scoped_guard(spinlock, &chip->mixer_lock) {
|
||||||
/* save input filter status and turn it off */
|
/* save input filter status and turn it off */
|
||||||
mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
|
mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
|
||||||
snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
|
snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
|
||||||
spin_unlock(&chip->mixer_lock);
|
}
|
||||||
/* just use force_mode16 for temporary storate... */
|
/* just use force_mode16 for temporary storate... */
|
||||||
chip->force_mode16 = mixreg;
|
chip->force_mode16 = mixreg;
|
||||||
} else {
|
} else {
|
||||||
snd_sbdsp_command(chip, 256 - runtime->rate_den);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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,
|
snd_dma_program(dma, runtime->dma_addr,
|
||||||
size, DMA_MODE_READ | DMA_AUTOINIT);
|
size, DMA_MODE_READ | DMA_AUTOINIT);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -317,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,
|
static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
int cmd)
|
int cmd)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
guard(spinlock_irqsave)(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
snd_sbdsp_command(chip, chip->capture_format);
|
snd_sbdsp_command(chip, chip->capture_format);
|
||||||
|
|
@ -337,9 +331,9 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
snd_sbdsp_reset(chip);
|
snd_sbdsp_reset(chip);
|
||||||
if (runtime->channels > 1) {
|
if (runtime->channels > 1) {
|
||||||
/* restore input filter status */
|
/* restore input filter status */
|
||||||
spin_lock(&chip->mixer_lock);
|
scoped_guard(spinlock, &chip->mixer_lock) {
|
||||||
snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
|
snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
|
||||||
spin_unlock(&chip->mixer_lock);
|
}
|
||||||
/* set hardware to mono mode */
|
/* set hardware to mono mode */
|
||||||
snd_sbdsp_command(chip, SB_DSP_MONO_8BIT);
|
snd_sbdsp_command(chip, SB_DSP_MONO_8BIT);
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +342,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,15 +457,12 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
if (chip->open) {
|
if (chip->open)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
return -EAGAIN;
|
||||||
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) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
chip->playback_substream = substream;
|
chip->playback_substream = substream;
|
||||||
runtime->hw = snd_sb8_playback;
|
runtime->hw = snd_sb8_playback;
|
||||||
|
|
@ -525,18 +515,16 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
|
||||||
|
|
||||||
static int snd_sb8_close(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);
|
struct snd_sb *chip = snd_pcm_substream_chip(substream);
|
||||||
|
|
||||||
chip->playback_substream = NULL;
|
chip->playback_substream = NULL;
|
||||||
chip->capture_substream = NULL;
|
chip->capture_substream = NULL;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
chip->open &= ~SB_OPEN_PCM;
|
chip->open &= ~SB_OPEN_PCM;
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||||
chip->mode &= ~SB_MODE_PLAYBACK;
|
chip->mode &= ~SB_MODE_PLAYBACK;
|
||||||
else
|
else
|
||||||
chip->mode &= ~SB_MODE_CAPTURE;
|
chip->mode &= ~SB_MODE_CAPTURE;
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&chip->midi_input_lock);
|
guard(spinlock)(&chip->midi_input_lock);
|
||||||
while (max-- > 0) {
|
while (max-- > 0) {
|
||||||
if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
|
if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
|
||||||
byte = inb(SBP(chip, READ));
|
byte = inb(SBP(chip, READ));
|
||||||
|
|
@ -44,108 +44,90 @@ irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&chip->midi_input_lock);
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
|
static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
unsigned int valid_open_flags;
|
unsigned int valid_open_flags;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
valid_open_flags = chip->hardware >= SB_HW_20
|
valid_open_flags = chip->hardware >= SB_HW_20
|
||||||
? SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER : 0;
|
? SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER : 0;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
if (chip->open & ~valid_open_flags) {
|
if (chip->open & ~valid_open_flags)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
chip->open |= SB_OPEN_MIDI_INPUT;
|
||||||
}
|
chip->midi_substream_input = substream;
|
||||||
chip->open |= SB_OPEN_MIDI_INPUT;
|
if (chip->open & SB_OPEN_MIDI_OUTPUT)
|
||||||
chip->midi_substream_input = substream;
|
return 0;
|
||||||
if (!(chip->open & SB_OPEN_MIDI_OUTPUT)) {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
snd_sbdsp_reset(chip); /* reset DSP */
|
|
||||||
if (chip->hardware >= SB_HW_20)
|
|
||||||
snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
|
|
||||||
} else {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
snd_sbdsp_reset(chip); /* reset DSP */
|
||||||
|
if (chip->hardware >= SB_HW_20)
|
||||||
|
snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream)
|
static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
unsigned int valid_open_flags;
|
unsigned int valid_open_flags;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
valid_open_flags = chip->hardware >= SB_HW_20
|
valid_open_flags = chip->hardware >= SB_HW_20
|
||||||
? SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER : 0;
|
? SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER : 0;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
if (chip->open & ~valid_open_flags) {
|
if (chip->open & ~valid_open_flags)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
chip->open |= SB_OPEN_MIDI_OUTPUT;
|
||||||
}
|
chip->midi_substream_output = substream;
|
||||||
chip->open |= SB_OPEN_MIDI_OUTPUT;
|
if (chip->open & SB_OPEN_MIDI_INPUT)
|
||||||
chip->midi_substream_output = substream;
|
return 0;
|
||||||
if (!(chip->open & SB_OPEN_MIDI_INPUT)) {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
snd_sbdsp_reset(chip); /* reset DSP */
|
|
||||||
if (chip->hardware >= SB_HW_20)
|
|
||||||
snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
|
|
||||||
} else {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
snd_sbdsp_reset(chip); /* reset DSP */
|
||||||
|
if (chip->hardware >= SB_HW_20)
|
||||||
|
snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream)
|
static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
chip->open &= ~(SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER);
|
chip->open &= ~(SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER);
|
||||||
chip->midi_substream_input = NULL;
|
chip->midi_substream_input = NULL;
|
||||||
if (!(chip->open & SB_OPEN_MIDI_OUTPUT)) {
|
if (chip->open & SB_OPEN_MIDI_OUTPUT)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
return 0;
|
||||||
snd_sbdsp_reset(chip); /* reset DSP */
|
|
||||||
} else {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
snd_sbdsp_reset(chip); /* reset DSP */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
|
static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
timer_delete_sync(&chip->midi_timer);
|
timer_delete_sync(&chip->midi_timer);
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
|
chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
|
||||||
chip->midi_substream_output = NULL;
|
chip->midi_substream_output = NULL;
|
||||||
if (!(chip->open & SB_OPEN_MIDI_INPUT)) {
|
if (chip->open & SB_OPEN_MIDI_INPUT)
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
return 0;
|
||||||
snd_sbdsp_reset(chip); /* reset DSP */
|
|
||||||
} else {
|
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
snd_sbdsp_reset(chip); /* reset DSP */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
|
static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
if (up) {
|
if (up) {
|
||||||
if (!(chip->open & SB_OPEN_MIDI_INPUT_TRIGGER)) {
|
if (!(chip->open & SB_OPEN_MIDI_INPUT_TRIGGER)) {
|
||||||
if (chip->hardware < SB_HW_20)
|
if (chip->hardware < SB_HW_20)
|
||||||
|
|
@ -159,12 +141,10 @@ static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substrea
|
||||||
chip->open &= ~SB_OPEN_MIDI_INPUT_TRIGGER;
|
chip->open &= ~SB_OPEN_MIDI_INPUT_TRIGGER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream)
|
static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
char byte;
|
char byte;
|
||||||
int max = 32;
|
int max = 32;
|
||||||
|
|
@ -172,11 +152,10 @@ static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream
|
||||||
/* how big is Tx FIFO? */
|
/* how big is Tx FIFO? */
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
while (max-- > 0) {
|
while (max-- > 0) {
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
guard(spinlock_irqsave)(&chip->open_lock);
|
||||||
if (snd_rawmidi_transmit_peek(substream, &byte, 1) != 1) {
|
if (snd_rawmidi_transmit_peek(substream, &byte, 1) != 1) {
|
||||||
chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
||||||
timer_delete(&chip->midi_timer);
|
timer_delete(&chip->midi_timer);
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (chip->hardware >= SB_HW_20) {
|
if (chip->hardware >= SB_HW_20) {
|
||||||
|
|
@ -185,7 +164,6 @@ static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream
|
||||||
;
|
;
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
/* Tx FIFO full - try again later */
|
/* Tx FIFO full - try again later */
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
outb(byte, SBP(chip, WRITE));
|
outb(byte, SBP(chip, WRITE));
|
||||||
|
|
@ -194,7 +172,6 @@ static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream
|
||||||
snd_sbdsp_command(chip, byte);
|
snd_sbdsp_command(chip, byte);
|
||||||
}
|
}
|
||||||
snd_rawmidi_transmit_ack(substream, 1);
|
snd_rawmidi_transmit_ack(substream, 1);
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,32 +179,30 @@ static void snd_sb8dsp_midi_output_timer(struct timer_list *t)
|
||||||
{
|
{
|
||||||
struct snd_sb *chip = timer_container_of(chip, t, midi_timer);
|
struct snd_sb *chip = timer_container_of(chip, t, midi_timer);
|
||||||
struct snd_rawmidi_substream *substream = chip->midi_substream_output;
|
struct snd_rawmidi_substream *substream = chip->midi_substream_output;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
mod_timer(&chip->midi_timer, 1 + jiffies);
|
mod_timer(&chip->midi_timer, 1 + jiffies);
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
}
|
||||||
snd_sb8dsp_midi_output_write(substream);
|
snd_sb8dsp_midi_output_write(substream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
|
static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_sb *chip;
|
struct snd_sb *chip;
|
||||||
|
|
||||||
chip = substream->rmidi->private_data;
|
chip = substream->rmidi->private_data;
|
||||||
spin_lock_irqsave(&chip->open_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->open_lock) {
|
||||||
if (up) {
|
if (up) {
|
||||||
if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
|
if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
|
||||||
mod_timer(&chip->midi_timer, 1 + jiffies);
|
mod_timer(&chip->midi_timer, 1 + jiffies);
|
||||||
chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER) {
|
if (chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER) {
|
||||||
chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&chip->open_lock, flags);
|
|
||||||
|
|
||||||
if (up)
|
if (up)
|
||||||
snd_sb8dsp_midi_output_write(substream);
|
snd_sb8dsp_midi_output_write(substream);
|
||||||
|
|
|
||||||
|
|
@ -94,23 +94,18 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
|
||||||
int version;
|
int version;
|
||||||
int major, minor;
|
int major, minor;
|
||||||
char *str;
|
char *str;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialization sequence
|
* initialization sequence
|
||||||
*/
|
*/
|
||||||
|
|
||||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->reg_lock) {
|
||||||
if (snd_sbdsp_reset(chip) < 0) {
|
if (snd_sbdsp_reset(chip) < 0)
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
return -ENODEV;
|
||||||
return -ENODEV;
|
version = snd_sbdsp_version(chip);
|
||||||
|
if (version < 0)
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
version = snd_sbdsp_version(chip);
|
|
||||||
if (version < 0) {
|
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
|
||||||
major = version >> 8;
|
major = version >> 8;
|
||||||
minor = version & 0xff;
|
minor = version & 0xff;
|
||||||
dev_dbg(chip->card->dev, "SB [0x%lx]: DSP chip found, version = %i.%i\n",
|
dev_dbg(chip->card->dev, "SB [0x%lx]: DSP chip found, version = %i.%i\n",
|
||||||
|
|
|
||||||
|
|
@ -57,15 +57,13 @@ static int snd_sbmixer_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl
|
||||||
static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int reg = kcontrol->private_value & 0xff;
|
int reg = kcontrol->private_value & 0xff;
|
||||||
int shift = (kcontrol->private_value >> 16) & 0xff;
|
int shift = (kcontrol->private_value >> 16) & 0xff;
|
||||||
int mask = (kcontrol->private_value >> 24) & 0xff;
|
int mask = (kcontrol->private_value >> 24) & 0xff;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
val = (snd_sbmixer_read(sb, reg) >> shift) & mask;
|
val = (snd_sbmixer_read(sb, reg) >> shift) & mask;
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
ucontrol->value.integer.value[0] = val;
|
ucontrol->value.integer.value[0] = val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +71,6 @@ static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int reg = kcontrol->private_value & 0xff;
|
int reg = kcontrol->private_value & 0xff;
|
||||||
int shift = (kcontrol->private_value >> 16) & 0x07;
|
int shift = (kcontrol->private_value >> 16) & 0x07;
|
||||||
int mask = (kcontrol->private_value >> 24) & 0xff;
|
int mask = (kcontrol->private_value >> 24) & 0xff;
|
||||||
|
|
@ -81,13 +78,12 @@ static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
unsigned char val, oval;
|
unsigned char val, oval;
|
||||||
|
|
||||||
val = (ucontrol->value.integer.value[0] & mask) << shift;
|
val = (ucontrol->value.integer.value[0] & mask) << shift;
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, reg);
|
oval = snd_sbmixer_read(sb, reg);
|
||||||
val = (oval & ~(mask << shift)) | val;
|
val = (oval & ~(mask << shift)) | val;
|
||||||
change = val != oval;
|
change = val != oval;
|
||||||
if (change)
|
if (change)
|
||||||
snd_sbmixer_write(sb, reg, val);
|
snd_sbmixer_write(sb, reg, val);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,7 +105,6 @@ static int snd_sbmixer_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl
|
||||||
static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int left_reg = kcontrol->private_value & 0xff;
|
int left_reg = kcontrol->private_value & 0xff;
|
||||||
int right_reg = (kcontrol->private_value >> 8) & 0xff;
|
int right_reg = (kcontrol->private_value >> 8) & 0xff;
|
||||||
int left_shift = (kcontrol->private_value >> 16) & 0x07;
|
int left_shift = (kcontrol->private_value >> 16) & 0x07;
|
||||||
|
|
@ -117,10 +112,9 @@ static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
int mask = (kcontrol->private_value >> 24) & 0xff;
|
int mask = (kcontrol->private_value >> 24) & 0xff;
|
||||||
unsigned char left, right;
|
unsigned char left, right;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
left = (snd_sbmixer_read(sb, left_reg) >> left_shift) & mask;
|
left = (snd_sbmixer_read(sb, left_reg) >> left_shift) & mask;
|
||||||
right = (snd_sbmixer_read(sb, right_reg) >> right_shift) & mask;
|
right = (snd_sbmixer_read(sb, right_reg) >> right_shift) & mask;
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
ucontrol->value.integer.value[0] = left;
|
ucontrol->value.integer.value[0] = left;
|
||||||
ucontrol->value.integer.value[1] = right;
|
ucontrol->value.integer.value[1] = right;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -129,7 +123,6 @@ static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int left_reg = kcontrol->private_value & 0xff;
|
int left_reg = kcontrol->private_value & 0xff;
|
||||||
int right_reg = (kcontrol->private_value >> 8) & 0xff;
|
int right_reg = (kcontrol->private_value >> 8) & 0xff;
|
||||||
int left_shift = (kcontrol->private_value >> 16) & 0x07;
|
int left_shift = (kcontrol->private_value >> 16) & 0x07;
|
||||||
|
|
@ -140,7 +133,7 @@ static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
|
|
||||||
left = (ucontrol->value.integer.value[0] & mask) << left_shift;
|
left = (ucontrol->value.integer.value[0] & mask) << left_shift;
|
||||||
right = (ucontrol->value.integer.value[1] & mask) << right_shift;
|
right = (ucontrol->value.integer.value[1] & mask) << right_shift;
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
if (left_reg == right_reg) {
|
if (left_reg == right_reg) {
|
||||||
oleft = snd_sbmixer_read(sb, left_reg);
|
oleft = snd_sbmixer_read(sb, left_reg);
|
||||||
left = (oleft & ~((mask << left_shift) | (mask << right_shift))) | left | right;
|
left = (oleft & ~((mask << left_shift) | (mask << right_shift))) | left | right;
|
||||||
|
|
@ -158,7 +151,6 @@ static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||||
snd_sbmixer_write(sb, right_reg, right);
|
snd_sbmixer_write(sb, right_reg, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,12 +170,11 @@ static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ct
|
||||||
static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
unsigned char oval;
|
unsigned char oval;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &sb->mixer_lock) {
|
||||||
oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
|
oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
}
|
||||||
switch (oval & 0x07) {
|
switch (oval & 0x07) {
|
||||||
case SB_DT019X_CAP_CD:
|
case SB_DT019X_CAP_CD:
|
||||||
ucontrol->value.enumerated.item[0] = 0;
|
ucontrol->value.enumerated.item[0] = 0;
|
||||||
|
|
@ -214,7 +205,6 @@ static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl
|
||||||
static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int change;
|
int change;
|
||||||
unsigned char nval, oval;
|
unsigned char nval, oval;
|
||||||
|
|
||||||
|
|
@ -239,12 +229,11 @@ static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl
|
||||||
default:
|
default:
|
||||||
nval = SB_DT019X_CAP_MAIN;
|
nval = SB_DT019X_CAP_MAIN;
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
|
oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
|
||||||
change = nval != oval;
|
change = nval != oval;
|
||||||
if (change)
|
if (change)
|
||||||
snd_sbmixer_write(sb, SB_DT019X_CAPTURE_SW, nval);
|
snd_sbmixer_write(sb, SB_DT019X_CAPTURE_SW, nval);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,12 +255,10 @@ static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
unsigned char oval;
|
unsigned char oval;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
|
oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
oval >>= 6;
|
oval >>= 6;
|
||||||
if (oval > 2)
|
if (oval > 2)
|
||||||
oval = 2;
|
oval = 2;
|
||||||
|
|
@ -284,13 +271,12 @@ static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int change;
|
int change;
|
||||||
unsigned char nval, oval;
|
unsigned char nval, oval;
|
||||||
|
|
||||||
if (ucontrol->value.enumerated.item[0] > 2)
|
if (ucontrol->value.enumerated.item[0] > 2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
|
oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
|
||||||
|
|
||||||
nval = (oval & ~(3 << 6))
|
nval = (oval & ~(3 << 6))
|
||||||
|
|
@ -298,7 +284,6 @@ static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol,
|
||||||
change = nval != oval;
|
change = nval != oval;
|
||||||
if (change)
|
if (change)
|
||||||
snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval);
|
snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,12 +304,10 @@ static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
||||||
static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
unsigned char oval;
|
unsigned char oval;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
|
oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
switch ((oval >> 0x01) & 0x03) {
|
switch ((oval >> 0x01) & 0x03) {
|
||||||
case SB_DSP_MIXS_CD:
|
case SB_DSP_MIXS_CD:
|
||||||
ucontrol->value.enumerated.item[0] = 1;
|
ucontrol->value.enumerated.item[0] = 1;
|
||||||
|
|
@ -342,7 +325,6 @@ static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_el
|
||||||
static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int change;
|
int change;
|
||||||
unsigned char nval, oval;
|
unsigned char nval, oval;
|
||||||
|
|
||||||
|
|
@ -359,13 +341,12 @@ static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_el
|
||||||
nval = SB_DSP_MIXS_MIC;
|
nval = SB_DSP_MIXS_MIC;
|
||||||
}
|
}
|
||||||
nval <<= 1;
|
nval <<= 1;
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
|
oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
|
||||||
nval |= oval & ~0x06;
|
nval |= oval & ~0x06;
|
||||||
change = nval != oval;
|
change = nval != oval;
|
||||||
if (change)
|
if (change)
|
||||||
snd_sbmixer_write(sb, SB_DSP_CAPTURE_SOURCE, nval);
|
snd_sbmixer_write(sb, SB_DSP_CAPTURE_SOURCE, nval);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,17 +366,15 @@ static int snd_sb16mixer_info_input_sw(struct snd_kcontrol *kcontrol, struct snd
|
||||||
static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int reg1 = kcontrol->private_value & 0xff;
|
int reg1 = kcontrol->private_value & 0xff;
|
||||||
int reg2 = (kcontrol->private_value >> 8) & 0xff;
|
int reg2 = (kcontrol->private_value >> 8) & 0xff;
|
||||||
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
|
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
|
||||||
int right_shift = (kcontrol->private_value >> 24) & 0x0f;
|
int right_shift = (kcontrol->private_value >> 24) & 0x0f;
|
||||||
unsigned char val1, val2;
|
unsigned char val1, val2;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
val1 = snd_sbmixer_read(sb, reg1);
|
val1 = snd_sbmixer_read(sb, reg1);
|
||||||
val2 = snd_sbmixer_read(sb, reg2);
|
val2 = snd_sbmixer_read(sb, reg2);
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
ucontrol->value.integer.value[0] = (val1 >> left_shift) & 0x01;
|
ucontrol->value.integer.value[0] = (val1 >> left_shift) & 0x01;
|
||||||
ucontrol->value.integer.value[1] = (val2 >> left_shift) & 0x01;
|
ucontrol->value.integer.value[1] = (val2 >> left_shift) & 0x01;
|
||||||
ucontrol->value.integer.value[2] = (val1 >> right_shift) & 0x01;
|
ucontrol->value.integer.value[2] = (val1 >> right_shift) & 0x01;
|
||||||
|
|
@ -406,7 +385,6 @@ static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_
|
||||||
static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned long flags;
|
|
||||||
int reg1 = kcontrol->private_value & 0xff;
|
int reg1 = kcontrol->private_value & 0xff;
|
||||||
int reg2 = (kcontrol->private_value >> 8) & 0xff;
|
int reg2 = (kcontrol->private_value >> 8) & 0xff;
|
||||||
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
|
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
|
||||||
|
|
@ -414,7 +392,7 @@ static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_
|
||||||
int change;
|
int change;
|
||||||
unsigned char val1, val2, oval1, oval2;
|
unsigned char val1, val2, oval1, oval2;
|
||||||
|
|
||||||
spin_lock_irqsave(&sb->mixer_lock, flags);
|
guard(spinlock_irqsave)(&sb->mixer_lock);
|
||||||
oval1 = snd_sbmixer_read(sb, reg1);
|
oval1 = snd_sbmixer_read(sb, reg1);
|
||||||
oval2 = snd_sbmixer_read(sb, reg2);
|
oval2 = snd_sbmixer_read(sb, reg2);
|
||||||
val1 = oval1 & ~((1 << left_shift) | (1 << right_shift));
|
val1 = oval1 & ~((1 << left_shift) | (1 << right_shift));
|
||||||
|
|
@ -428,7 +406,6 @@ static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_
|
||||||
snd_sbmixer_write(sb, reg1, val1);
|
snd_sbmixer_write(sb, reg1, val1);
|
||||||
snd_sbmixer_write(sb, reg2, val2);
|
snd_sbmixer_write(sb, reg2, val2);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&sb->mixer_lock, flags);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,20 +674,18 @@ static int snd_sbmixer_init(struct snd_sb *chip,
|
||||||
int map_count,
|
int map_count,
|
||||||
char *name)
|
char *name)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct snd_card *card = chip->card;
|
struct snd_card *card = chip->card;
|
||||||
int idx, err;
|
int idx, err;
|
||||||
|
|
||||||
/* mixer reset */
|
/* mixer reset */
|
||||||
spin_lock_irqsave(&chip->mixer_lock, flags);
|
scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
|
||||||
snd_sbmixer_write(chip, 0x00, 0x00);
|
snd_sbmixer_write(chip, 0x00, 0x00);
|
||||||
spin_unlock_irqrestore(&chip->mixer_lock, flags);
|
}
|
||||||
|
|
||||||
/* mute and zero volume channels */
|
/* mute and zero volume channels */
|
||||||
for (idx = 0; idx < map_count; idx++) {
|
for (idx = 0; idx < map_count; idx++) {
|
||||||
spin_lock_irqsave(&chip->mixer_lock, flags);
|
guard(spinlock_irqsave)(&chip->mixer_lock);
|
||||||
snd_sbmixer_write(chip, map[idx][0], map[idx][1]);
|
snd_sbmixer_write(chip, map[idx][0], map[idx][1]);
|
||||||
spin_unlock_irqrestore(&chip->mixer_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0; idx < controls_count; idx++) {
|
for (idx = 0; idx < controls_count; idx++) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue