ALSA: trident: 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/20250829144342.4290-59-tiwai@suse.de
This commit is contained in:
Takashi Iwai 2025-08-29 16:43:33 +02:00
parent 4f83e1da6e
commit 62d8070db6
1 changed files with 140 additions and 184 deletions

View File

@ -107,10 +107,9 @@ static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned sho
{ {
unsigned int data = 0, treg; unsigned int data = 0, treg;
unsigned short count = 0xffff; unsigned short count = 0xffff;
unsigned long flags;
struct snd_trident *trident = ac97->private_data; struct snd_trident *trident = ac97->private_data;
spin_lock_irqsave(&trident->reg_lock, flags); guard(spinlock_irqsave)(&trident->reg_lock);
if (trident->device == TRIDENT_DEVICE_ID_DX) { if (trident->device == TRIDENT_DEVICE_ID_DX) {
data = (DX_AC97_BUSY_READ | (reg & 0x000000ff)); data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
outl(data, TRID_REG(trident, DX_ACR1_AC97_R)); outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
@ -147,7 +146,6 @@ static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned sho
data = 0; data = 0;
} }
spin_unlock_irqrestore(&trident->reg_lock, flags);
return ((unsigned short) (data >> 16)); return ((unsigned short) (data >> 16));
} }
@ -170,12 +168,11 @@ static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
{ {
unsigned int address, data; unsigned int address, data;
unsigned short count = 0xffff; unsigned short count = 0xffff;
unsigned long flags;
struct snd_trident *trident = ac97->private_data; struct snd_trident *trident = ac97->private_data;
data = ((unsigned long) wdata) << 16; data = ((unsigned long) wdata) << 16;
spin_lock_irqsave(&trident->reg_lock, flags); guard(spinlock_irqsave)(&trident->reg_lock);
if (trident->device == TRIDENT_DEVICE_ID_DX) { if (trident->device == TRIDENT_DEVICE_ID_DX) {
address = DX_ACR0_AC97_W; address = DX_ACR0_AC97_W;
@ -213,12 +210,9 @@ static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
count = 0; /* return */ count = 0; /* return */
} }
if (count == 0) { if (count == 0)
spin_unlock_irqrestore(&trident->reg_lock, flags);
return; return;
}
outl(data, TRID_REG(trident, address)); outl(data, TRID_REG(trident, address));
spin_unlock_irqrestore(&trident->reg_lock, flags);
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
@ -911,7 +905,7 @@ static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
struct snd_trident_voice *evoice = voice->extra; struct snd_trident_voice *evoice = voice->extra;
struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number]; struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
/* set delta (rate) value */ /* set delta (rate) value */
voice->Delta = snd_trident_convert_rate(runtime->rate); voice->Delta = snd_trident_convert_rate(runtime->rate);
@ -972,8 +966,6 @@ static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
evoice->ESO = (runtime->period_size * 2) - 1; evoice->ESO = (runtime->period_size * 2) - 1;
} }
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -1013,7 +1005,7 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
struct snd_trident_voice *voice = runtime->private_data; struct snd_trident_voice *voice = runtime->private_data;
unsigned int val, ESO_bytes; unsigned int val, ESO_bytes;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
// Initialize the channel and set channel Mode // Initialize the channel and set channel Mode
outb(0, TRID_REG(trident, LEGACY_DMAR15)); outb(0, TRID_REG(trident, LEGACY_DMAR15));
@ -1082,7 +1074,6 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
snd_trident_write_voice_regs(trident, voice); snd_trident_write_voice_regs(trident, voice);
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -1147,7 +1138,7 @@ static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substrea
struct snd_trident_voice *voice = runtime->private_data; struct snd_trident_voice *voice = runtime->private_data;
struct snd_trident_voice *evoice = voice->extra; struct snd_trident_voice *evoice = voice->extra;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
voice->LBA = runtime->dma_addr; voice->LBA = runtime->dma_addr;
voice->Delta = snd_trident_convert_adc_rate(runtime->rate); voice->Delta = snd_trident_convert_adc_rate(runtime->rate);
@ -1196,7 +1187,6 @@ static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substrea
evoice->ESO = (runtime->period_size * 2) - 1; evoice->ESO = (runtime->period_size * 2) - 1;
} }
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -1218,7 +1208,7 @@ static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
struct snd_trident_voice *voice = runtime->private_data; struct snd_trident_voice *voice = runtime->private_data;
struct snd_trident_voice *evoice = voice->extra; struct snd_trident_voice *evoice = voice->extra;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
/* Set channel buffer Address */ /* Set channel buffer Address */
if (voice->memblk) if (voice->memblk)
@ -1273,7 +1263,6 @@ static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
evoice->ESO = (runtime->period_size * 2) - 1; evoice->ESO = (runtime->period_size * 2) - 1;
} }
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -1307,35 +1296,33 @@ static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream,
} }
/* prepare SPDIF channel */ /* prepare SPDIF channel */
spin_lock_irq(&trident->reg_lock); scoped_guard(spinlock_irq, &trident->reg_lock) {
old_bits = trident->spdif_pcm_bits; old_bits = trident->spdif_pcm_bits;
if (old_bits & IEC958_AES0_PROFESSIONAL) if (old_bits & IEC958_AES0_PROFESSIONAL)
trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS; trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;
else else
trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24); trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);
if (params_rate(hw_params) >= 48000) { if (params_rate(hw_params) >= 48000) {
trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz
trident->spdif_pcm_bits |= trident->spdif_pcm_bits |=
trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
IEC958_AES0_PRO_FS_48000 : IEC958_AES0_PRO_FS_48000 :
(IEC958_AES3_CON_FS_48000 << 24); (IEC958_AES3_CON_FS_48000 << 24);
} } else if (params_rate(hw_params) >= 44100) {
else if (params_rate(hw_params) >= 44100) { trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz
trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz trident->spdif_pcm_bits |=
trident->spdif_pcm_bits |= trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
IEC958_AES0_PRO_FS_44100 : IEC958_AES0_PRO_FS_44100 :
(IEC958_AES3_CON_FS_44100 << 24); (IEC958_AES3_CON_FS_44100 << 24);
} } else {
else { trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz
trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz trident->spdif_pcm_bits |=
trident->spdif_pcm_bits |= trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
IEC958_AES0_PRO_FS_32000 : IEC958_AES0_PRO_FS_32000 :
(IEC958_AES3_CON_FS_32000 << 24); (IEC958_AES3_CON_FS_32000 << 24);
}
change = old_bits != trident->spdif_pcm_bits;
} }
change = old_bits != trident->spdif_pcm_bits;
spin_unlock_irq(&trident->reg_lock);
if (change) if (change)
snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id); snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);
@ -1364,7 +1351,7 @@ static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
unsigned int RESO, LBAO; unsigned int RESO, LBAO;
unsigned int temp; unsigned int temp;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
if (trident->device != TRIDENT_DEVICE_ID_SI7018) { if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
@ -1476,8 +1463,6 @@ static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
} }
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -1518,7 +1503,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
what = whati = capture_flag = spdif_flag = 0; what = whati = capture_flag = spdif_flag = 0;
spin_lock(&trident->reg_lock); guard(spinlock)(&trident->reg_lock);
val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
snd_pcm_group_for_each_entry(s, substream) { snd_pcm_group_for_each_entry(s, substream) {
if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
@ -1577,7 +1562,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018) if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
} }
spin_unlock(&trident->reg_lock);
return 0; return 0;
} }
@ -1602,7 +1586,7 @@ static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *
if (!voice->running) if (!voice->running)
return 0; return 0;
spin_lock(&trident->reg_lock); guard(spinlock)(&trident->reg_lock);
outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
@ -1612,8 +1596,6 @@ static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *
cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff; cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
} }
spin_unlock(&trident->reg_lock);
if (cso >= runtime->buffer_size) if (cso >= runtime->buffer_size)
cso = 0; cso = 0;
@ -1866,9 +1848,9 @@ static int snd_trident_spdif_open(struct snd_pcm_substream *substream)
return -EAGAIN; return -EAGAIN;
voice->spdif = 1; voice->spdif = 1;
voice->substream = substream; voice->substream = substream;
spin_lock_irq(&trident->reg_lock); scoped_guard(spinlock_irq, &trident->reg_lock) {
trident->spdif_pcm_bits = trident->spdif_bits; trident->spdif_pcm_bits = trident->spdif_bits;
spin_unlock_irq(&trident->reg_lock); }
runtime->private_data = voice; runtime->private_data = voice;
runtime->private_free = snd_trident_pcm_free_substream; runtime->private_free = snd_trident_pcm_free_substream;
@ -1901,22 +1883,22 @@ static int snd_trident_spdif_close(struct snd_pcm_substream *substream)
struct snd_trident *trident = snd_pcm_substream_chip(substream); struct snd_trident *trident = snd_pcm_substream_chip(substream);
unsigned int temp; unsigned int temp;
spin_lock_irq(&trident->reg_lock); scoped_guard(spinlock_irq, &trident->reg_lock) {
// restore default SPDIF setting // restore default SPDIF setting
if (trident->device != TRIDENT_DEVICE_ID_SI7018) { if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
} else {
outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
if (trident->spdif_ctrl) {
temp |= SPDIF_EN;
} else { } else {
temp &= ~SPDIF_EN; outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
if (trident->spdif_ctrl) {
temp |= SPDIF_EN;
} else {
temp &= ~SPDIF_EN;
}
outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
} }
outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
} }
spin_unlock_irq(&trident->reg_lock);
trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
@ -2013,9 +1995,8 @@ static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
voice = runtime->private_data; voice = runtime->private_data;
/* stop capture channel */ /* stop capture channel */
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan)); outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan));
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -2269,10 +2250,9 @@ static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
struct snd_trident *trident = snd_kcontrol_chip(kcontrol); struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val; unsigned char val;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
val = trident->spdif_ctrl; val = trident->spdif_ctrl;
ucontrol->value.integer.value[0] = val == kcontrol->private_value; ucontrol->value.integer.value[0] = val == kcontrol->private_value;
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -2284,7 +2264,7 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
int change; int change;
val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00; val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
/* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */ /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
change = trident->spdif_ctrl != val; change = trident->spdif_ctrl != val;
trident->spdif_ctrl = val; trident->spdif_ctrl = val;
@ -2303,7 +2283,6 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
} }
} }
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2336,12 +2315,11 @@ static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
{ {
struct snd_trident *trident = snd_kcontrol_chip(kcontrol); struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff; ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff; ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff; ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff; ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -2356,7 +2334,7 @@ static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
(ucontrol->value.iec958.status[1] << 8) | (ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) | (ucontrol->value.iec958.status[2] << 16) |
(ucontrol->value.iec958.status[3] << 24); (ucontrol->value.iec958.status[3] << 24);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = trident->spdif_bits != val; change = trident->spdif_bits != val;
trident->spdif_bits = val; trident->spdif_bits = val;
if (trident->device != TRIDENT_DEVICE_ID_SI7018) { if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
@ -2366,7 +2344,6 @@ static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
if (trident->spdif == NULL) if (trident->spdif == NULL)
outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
} }
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2431,12 +2408,11 @@ static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
{ {
struct snd_trident *trident = snd_kcontrol_chip(kcontrol); struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff; ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff; ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff; ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff; ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -2451,7 +2427,7 @@ static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
(ucontrol->value.iec958.status[1] << 8) | (ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) | (ucontrol->value.iec958.status[2] << 16) |
(ucontrol->value.iec958.status[3] << 24); (ucontrol->value.iec958.status[3] << 24);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = trident->spdif_pcm_bits != val; change = trident->spdif_pcm_bits != val;
trident->spdif_pcm_bits = val; trident->spdif_pcm_bits = val;
if (trident->spdif != NULL) { if (trident->spdif != NULL) {
@ -2461,7 +2437,6 @@ static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
} }
} }
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2489,10 +2464,9 @@ static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
struct snd_trident *trident = snd_kcontrol_chip(kcontrol); struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
unsigned char val; unsigned char val;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0; ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
spin_unlock_irq(&trident->reg_lock);
return 0; return 0;
} }
@ -2503,7 +2477,7 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
unsigned char val; unsigned char val;
int change = 0; int change = 0;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
val &= ~(1 << kcontrol->private_value); val &= ~(1 << kcontrol->private_value);
if (ucontrol->value.integer.value[0]) if (ucontrol->value.integer.value[0])
@ -2511,7 +2485,6 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
change = val != trident->ac97_ctrl; change = val != trident->ac97_ctrl;
trident->ac97_ctrl = val; trident->ac97_ctrl = val;
outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2562,14 +2535,13 @@ static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
unsigned int val; unsigned int val;
int change = 0; int change = 0;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
val = trident->musicvol_wavevol; val = trident->musicvol_wavevol;
val &= ~(0xffff << kcontrol->private_value); val &= ~(0xffff << kcontrol->private_value);
val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) | val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value; ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
change = val != trident->musicvol_wavevol; change = val != trident->musicvol_wavevol;
outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2642,12 +2614,11 @@ static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
} else { } else {
val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2; val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
} }
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = val != mix->vol; change = val != mix->vol;
mix->vol = val; mix->vol = val;
if (mix->voice != NULL) if (mix->voice != NULL)
snd_trident_write_vol_reg(trident, mix->voice, val); snd_trident_write_vol_reg(trident, mix->voice, val);
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2706,12 +2677,11 @@ static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
val = ucontrol->value.integer.value[0] & 0x3f; val = ucontrol->value.integer.value[0] & 0x3f;
else else
val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40; val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = val != mix->pan; change = val != mix->pan;
mix->pan = val; mix->pan = val;
if (mix->voice != NULL) if (mix->voice != NULL)
snd_trident_write_pan_reg(trident, mix->voice, val); snd_trident_write_pan_reg(trident, mix->voice, val);
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2761,12 +2731,11 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
int change = 0; int change = 0;
val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = val != mix->rvol; change = val != mix->rvol;
mix->rvol = val; mix->rvol = val;
if (mix->voice != NULL) if (mix->voice != NULL)
snd_trident_write_rvol_reg(trident, mix->voice, val); snd_trident_write_rvol_reg(trident, mix->voice, val);
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -2819,12 +2788,11 @@ static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
int change = 0; int change = 0;
val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
spin_lock_irq(&trident->reg_lock); guard(spinlock_irq)(&trident->reg_lock);
change = val != mix->cvol; change = val != mix->cvol;
mix->cvol = val; mix->cvol = val;
if (mix->voice != NULL) if (mix->voice != NULL)
snd_trident_write_cvol_reg(trident, mix->voice, val); snd_trident_write_cvol_reg(trident, mix->voice, val);
spin_unlock_irq(&trident->reg_lock);
return change; return change;
} }
@ -3659,79 +3627,76 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
if (audio_int & ADDRESS_IRQ) { if (audio_int & ADDRESS_IRQ) {
// get interrupt status for all channels // get interrupt status for all channels
spin_lock(&trident->reg_lock); scoped_guard(spinlock, &trident->reg_lock) {
stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
chn_int = inl(TRID_REG(trident, T4D_AINT_A)); chn_int = inl(TRID_REG(trident, T4D_AINT_A));
if (chn_int == 0) if (chn_int)
goto __skip1; outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */
outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */ chn_int = inl(TRID_REG(trident, T4D_AINT_B));
__skip1: if (chn_int == 0)
chn_int = inl(TRID_REG(trident, T4D_AINT_B)); break;
if (chn_int == 0) for (channel = 63; channel >= 32; channel--) {
goto __skip2; mask = 1 << (channel&0x1f);
for (channel = 63; channel >= 32; channel--) { if ((chn_int & mask) == 0)
mask = 1 << (channel&0x1f); continue;
if ((chn_int & mask) == 0) voice = &trident->synth.voices[channel];
continue; if (!voice->pcm || voice->substream == NULL) {
voice = &trident->synth.voices[channel]; outl(mask, TRID_REG(trident, T4D_STOP_B));
if (!voice->pcm || voice->substream == NULL) { continue;
outl(mask, TRID_REG(trident, T4D_STOP_B));
continue;
}
delta = (int)stimer - (int)voice->stimer;
if (delta < 0)
delta = -delta;
if ((unsigned int)delta < voice->spurious_threshold) {
/* do some statistics here */
trident->spurious_irq_count++;
if (trident->spurious_irq_max_delta < (unsigned int)delta)
trident->spurious_irq_max_delta = delta;
continue;
}
voice->stimer = stimer;
if (voice->isync) {
if (!voice->isync3) {
tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
if (trident->bDMAStart & 0x40)
tmp >>= 1;
if (tmp > 0)
tmp = voice->isync_max - tmp;
} else {
tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
} }
if (tmp < voice->isync_mark) { delta = (int)stimer - (int)voice->stimer;
if (tmp > 0x10) if (delta < 0)
tmp = voice->isync_ESO - 7; delta = -delta;
else if ((unsigned int)delta < voice->spurious_threshold) {
tmp = voice->isync_ESO + 2; /* do some statistics here */
/* update ESO for IRQ voice to preserve sync */ trident->spurious_irq_count++;
if (trident->spurious_irq_max_delta < (unsigned int)delta)
trident->spurious_irq_max_delta = delta;
continue;
}
voice->stimer = stimer;
if (voice->isync) {
if (!voice->isync3) {
tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
if (trident->bDMAStart & 0x40)
tmp >>= 1;
if (tmp > 0)
tmp = voice->isync_max - tmp;
} else {
tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
}
if (tmp < voice->isync_mark) {
if (tmp > 0x10)
tmp = voice->isync_ESO - 7;
else
tmp = voice->isync_ESO + 2;
/* update ESO for IRQ voice to preserve sync */
snd_trident_stop_voice(trident, voice->number);
snd_trident_write_eso_reg(trident, voice, tmp);
snd_trident_start_voice(trident, voice->number);
}
} else if (voice->isync2) {
voice->isync2 = 0;
/* write original ESO and update CSO for IRQ voice to preserve sync */
snd_trident_stop_voice(trident, voice->number); snd_trident_stop_voice(trident, voice->number);
snd_trident_write_eso_reg(trident, voice, tmp); snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
snd_trident_write_eso_reg(trident, voice, voice->ESO);
snd_trident_start_voice(trident, voice->number); snd_trident_start_voice(trident, voice->number);
} }
} else if (voice->isync2) {
voice->isync2 = 0;
/* write original ESO and update CSO for IRQ voice to preserve sync */
snd_trident_stop_voice(trident, voice->number);
snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
snd_trident_write_eso_reg(trident, voice, voice->ESO);
snd_trident_start_voice(trident, voice->number);
}
#if 0 #if 0
if (voice->extra) { if (voice->extra) {
/* update CSO for extra voice to preserve sync */ /* update CSO for extra voice to preserve sync */
snd_trident_stop_voice(trident, voice->extra->number); snd_trident_stop_voice(trident, voice->extra->number);
snd_trident_write_cso_reg(trident, voice->extra, 0); snd_trident_write_cso_reg(trident, voice->extra, 0);
snd_trident_start_voice(trident, voice->extra->number); snd_trident_start_voice(trident, voice->extra->number);
} }
#endif #endif
spin_unlock(&trident->reg_lock); spin_unlock(&trident->reg_lock);
snd_pcm_period_elapsed(voice->substream); snd_pcm_period_elapsed(voice->substream);
spin_lock(&trident->reg_lock); spin_lock(&trident->reg_lock);
}
outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
} }
outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
__skip2:
spin_unlock(&trident->reg_lock);
} }
if (audio_int & MPU401_IRQ) { if (audio_int & MPU401_IRQ) {
if (trident->rmidi) { if (trident->rmidi) {
@ -3747,16 +3712,13 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port) struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
{ {
struct snd_trident_voice *pvoice; struct snd_trident_voice *pvoice;
unsigned long flags;
int idx; int idx;
spin_lock_irqsave(&trident->voice_alloc, flags); guard(spinlock_irqsave)(&trident->voice_alloc);
if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) { if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
idx = snd_trident_allocate_pcm_channel(trident); idx = snd_trident_allocate_pcm_channel(trident);
if(idx < 0) { if (idx < 0)
spin_unlock_irqrestore(&trident->voice_alloc, flags);
return NULL; return NULL;
}
pvoice = &trident->synth.voices[idx]; pvoice = &trident->synth.voices[idx];
pvoice->use = 1; pvoice->use = 1;
pvoice->pcm = 1; pvoice->pcm = 1;
@ -3764,27 +3726,22 @@ struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident,
pvoice->spdif = 0; pvoice->spdif = 0;
pvoice->memblk = NULL; pvoice->memblk = NULL;
pvoice->substream = NULL; pvoice->substream = NULL;
spin_unlock_irqrestore(&trident->voice_alloc, flags);
return pvoice; return pvoice;
} }
if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) { if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
idx = snd_trident_allocate_synth_channel(trident); idx = snd_trident_allocate_synth_channel(trident);
if(idx < 0) { if (idx < 0)
spin_unlock_irqrestore(&trident->voice_alloc, flags);
return NULL; return NULL;
}
pvoice = &trident->synth.voices[idx]; pvoice = &trident->synth.voices[idx];
pvoice->use = 1; pvoice->use = 1;
pvoice->synth = 1; pvoice->synth = 1;
pvoice->client = client; pvoice->client = client;
pvoice->port = port; pvoice->port = port;
pvoice->memblk = NULL; pvoice->memblk = NULL;
spin_unlock_irqrestore(&trident->voice_alloc, flags);
return pvoice; return pvoice;
} }
if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) { if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
} }
spin_unlock_irqrestore(&trident->voice_alloc, flags);
return NULL; return NULL;
} }
@ -3792,26 +3749,25 @@ EXPORT_SYMBOL(snd_trident_alloc_voice);
void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice) void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
{ {
unsigned long flags;
void (*private_free)(struct snd_trident_voice *); void (*private_free)(struct snd_trident_voice *);
if (voice == NULL || !voice->use) if (voice == NULL || !voice->use)
return; return;
snd_trident_clear_voices(trident, voice->number, voice->number); snd_trident_clear_voices(trident, voice->number, voice->number);
spin_lock_irqsave(&trident->voice_alloc, flags); scoped_guard(spinlock_irqsave, &trident->voice_alloc) {
private_free = voice->private_free; private_free = voice->private_free;
voice->private_free = NULL; voice->private_free = NULL;
voice->private_data = NULL; voice->private_data = NULL;
if (voice->pcm) if (voice->pcm)
snd_trident_free_pcm_channel(trident, voice->number); snd_trident_free_pcm_channel(trident, voice->number);
if (voice->synth) if (voice->synth)
snd_trident_free_synth_channel(trident, voice->number); snd_trident_free_synth_channel(trident, voice->number);
voice->use = voice->pcm = voice->synth = voice->midi = 0; voice->use = voice->pcm = voice->synth = voice->midi = 0;
voice->capture = voice->spdif = 0; voice->capture = voice->spdif = 0;
voice->sample_ops = NULL; voice->sample_ops = NULL;
voice->substream = NULL; voice->substream = NULL;
voice->extra = NULL; voice->extra = NULL;
spin_unlock_irqrestore(&trident->voice_alloc, flags); }
if (private_free) if (private_free)
private_free(voice); private_free(voice);
} }