diff options
Diffstat (limited to 'sound/pci/trident')
-rw-r--r-- | sound/pci/trident/trident_main.c | 324 | ||||
-rw-r--r-- | sound/pci/trident/trident_memory.c | 19 |
2 files changed, 145 insertions, 198 deletions
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 39ed52bf8631..55515c58b8aa 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -107,10 +107,9 @@ static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned sho { unsigned int data = 0, treg; unsigned short count = 0xffff; - unsigned long flags; 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) { data = (DX_AC97_BUSY_READ | (reg & 0x000000ff)); 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; } - spin_unlock_irqrestore(&trident->reg_lock, flags); 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 short count = 0xffff; - unsigned long flags; struct snd_trident *trident = ac97->private_data; 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) { 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 */ } - if (count == 0) { - spin_unlock_irqrestore(&trident->reg_lock, flags); + if (count == 0) return; - } 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_pcm_mixer *mix = &trident->pcm_mixer[substream->number]; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); /* set delta (rate) value */ 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; } - spin_unlock_irq(&trident->reg_lock); - 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; unsigned int val, ESO_bytes; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); // Initialize the channel and set channel Mode 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); - spin_unlock_irq(&trident->reg_lock); 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 *evoice = voice->extra; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); voice->LBA = runtime->dma_addr; 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; } - spin_unlock_irq(&trident->reg_lock); 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 *evoice = voice->extra; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); /* Set channel buffer Address */ 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; } - spin_unlock_irq(&trident->reg_lock); return 0; } @@ -1307,35 +1296,33 @@ static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream, } /* prepare SPDIF channel */ - spin_lock_irq(&trident->reg_lock); - old_bits = trident->spdif_pcm_bits; - if (old_bits & IEC958_AES0_PROFESSIONAL) - trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS; - else - trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24); - if (params_rate(hw_params) >= 48000) { - trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz - trident->spdif_pcm_bits |= - trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? + scoped_guard(spinlock_irq, &trident->reg_lock) { + old_bits = trident->spdif_pcm_bits; + if (old_bits & IEC958_AES0_PROFESSIONAL) + trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS; + else + trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24); + if (params_rate(hw_params) >= 48000) { + trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz + trident->spdif_pcm_bits |= + trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? IEC958_AES0_PRO_FS_48000 : (IEC958_AES3_CON_FS_48000 << 24); - } - else if (params_rate(hw_params) >= 44100) { - trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz - trident->spdif_pcm_bits |= - trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? + } else if (params_rate(hw_params) >= 44100) { + trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz + trident->spdif_pcm_bits |= + trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? IEC958_AES0_PRO_FS_44100 : (IEC958_AES3_CON_FS_44100 << 24); - } - else { - trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz - trident->spdif_pcm_bits |= - trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? + } else { + trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz + trident->spdif_pcm_bits |= + trident->spdif_bits & IEC958_AES0_PROFESSIONAL ? IEC958_AES0_PRO_FS_32000 : (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) 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 temp; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); 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)); } - spin_unlock_irq(&trident->reg_lock); - return 0; } @@ -1518,7 +1503,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, return -EINVAL; } 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; snd_pcm_group_for_each_entry(s, substream) { 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) outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD)); } - spin_unlock(&trident->reg_lock); return 0; } @@ -1602,7 +1586,7 @@ static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream * if (!voice->running) return 0; - spin_lock(&trident->reg_lock); + guard(spinlock)(&trident->reg_lock); 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; } - spin_unlock(&trident->reg_lock); - if (cso >= runtime->buffer_size) cso = 0; @@ -1866,9 +1848,9 @@ static int snd_trident_spdif_open(struct snd_pcm_substream *substream) return -EAGAIN; voice->spdif = 1; voice->substream = substream; - spin_lock_irq(&trident->reg_lock); - trident->spdif_pcm_bits = trident->spdif_bits; - spin_unlock_irq(&trident->reg_lock); + scoped_guard(spinlock_irq, &trident->reg_lock) { + trident->spdif_pcm_bits = trident->spdif_bits; + } runtime->private_data = voice; 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); unsigned int temp; - spin_lock_irq(&trident->reg_lock); - // restore default SPDIF setting - if (trident->device != TRIDENT_DEVICE_ID_SI7018) { - outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); - 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; + scoped_guard(spinlock_irq, &trident->reg_lock) { + // restore default SPDIF setting + if (trident->device != TRIDENT_DEVICE_ID_SI7018) { + outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); + outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); } 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; snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | 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; /* 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)); - spin_unlock_irq(&trident->reg_lock); 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); unsigned char val; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); val = trident->spdif_ctrl; ucontrol->value.integer.value[0] = val == kcontrol->private_value; - spin_unlock_irq(&trident->reg_lock); return 0; } @@ -2284,7 +2264,7 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol, int change; 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 */ change = 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)); } } - spin_unlock_irq(&trident->reg_lock); 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); - 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[1] = (trident->spdif_bits >> 8) & 0xff; ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff; ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff; - spin_unlock_irq(&trident->reg_lock); 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[2] << 16) | (ucontrol->value.iec958.status[3] << 24); - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); change = trident->spdif_bits != val; trident->spdif_bits = val; 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) outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); } - spin_unlock_irq(&trident->reg_lock); 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); - 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[1] = (trident->spdif_pcm_bits >> 8) & 0xff; ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff; ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff; - spin_unlock_irq(&trident->reg_lock); 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[2] << 16) | (ucontrol->value.iec958.status[3] << 24); - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); change = trident->spdif_pcm_bits != val; trident->spdif_pcm_bits = val; 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)); } } - spin_unlock_irq(&trident->reg_lock); 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); 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)); ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0; - spin_unlock_irq(&trident->reg_lock); return 0; } @@ -2503,7 +2477,7 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol, unsigned char val; 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 &= ~(1 << kcontrol->private_value); 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; trident->ac97_ctrl = val; outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); - spin_unlock_irq(&trident->reg_lock); return change; } @@ -2562,14 +2535,13 @@ static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, unsigned int val; int change = 0; - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); val = trident->musicvol_wavevol; val &= ~(0xffff << kcontrol->private_value); val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) | ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value; change = val != trident->musicvol_wavevol; outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); - spin_unlock_irq(&trident->reg_lock); return change; } @@ -2642,12 +2614,11 @@ static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol, } else { 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; mix->vol = val; if (mix->voice != NULL) snd_trident_write_vol_reg(trident, mix->voice, val); - spin_unlock_irq(&trident->reg_lock); 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; else 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; mix->pan = val; if (mix->voice != NULL) snd_trident_write_pan_reg(trident, mix->voice, val); - spin_unlock_irq(&trident->reg_lock); return change; } @@ -2761,12 +2731,11 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol, int change = 0; val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); change = val != mix->rvol; mix->rvol = val; if (mix->voice != NULL) snd_trident_write_rvol_reg(trident, mix->voice, val); - spin_unlock_irq(&trident->reg_lock); return change; } @@ -2819,12 +2788,11 @@ static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol, int change = 0; val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f); - spin_lock_irq(&trident->reg_lock); + guard(spinlock_irq)(&trident->reg_lock); change = val != mix->cvol; mix->cvol = val; if (mix->voice != NULL) snd_trident_write_cvol_reg(trident, mix->voice, val); - spin_unlock_irq(&trident->reg_lock); return change; } @@ -3659,79 +3627,76 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id) return IRQ_NONE; if (audio_int & ADDRESS_IRQ) { // get interrupt status for all channels - spin_lock(&trident->reg_lock); - stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; - chn_int = inl(TRID_REG(trident, T4D_AINT_A)); - if (chn_int == 0) - goto __skip1; - outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */ - __skip1: - chn_int = inl(TRID_REG(trident, T4D_AINT_B)); - if (chn_int == 0) - goto __skip2; - for (channel = 63; channel >= 32; channel--) { - mask = 1 << (channel&0x1f); - if ((chn_int & mask) == 0) - continue; - voice = &trident->synth.voices[channel]; - if (!voice->pcm || voice->substream == NULL) { - 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; + scoped_guard(spinlock, &trident->reg_lock) { + stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; + chn_int = inl(TRID_REG(trident, T4D_AINT_A)); + if (chn_int) + outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */ + chn_int = inl(TRID_REG(trident, T4D_AINT_B)); + if (chn_int == 0) + break; + for (channel = 63; channel >= 32; channel--) { + mask = 1 << (channel&0x1f); + if ((chn_int & mask) == 0) + continue; + voice = &trident->synth.voices[channel]; + if (!voice->pcm || voice->substream == NULL) { + 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; } - 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 */ + 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_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); } - } 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 (voice->extra) { - /* update CSO for extra voice to preserve sync */ - snd_trident_stop_voice(trident, voice->extra->number); - snd_trident_write_cso_reg(trident, voice->extra, 0); - snd_trident_start_voice(trident, voice->extra->number); - } + if (voice->extra) { + /* update CSO for extra voice to preserve sync */ + snd_trident_stop_voice(trident, voice->extra->number); + snd_trident_write_cso_reg(trident, voice->extra, 0); + snd_trident_start_voice(trident, voice->extra->number); + } #endif - spin_unlock(&trident->reg_lock); - snd_pcm_period_elapsed(voice->substream); - spin_lock(&trident->reg_lock); + spin_unlock(&trident->reg_lock); + snd_pcm_period_elapsed(voice->substream); + 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 (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 *pvoice; - unsigned long flags; int idx; - spin_lock_irqsave(&trident->voice_alloc, flags); + guard(spinlock_irqsave)(&trident->voice_alloc); if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) { idx = snd_trident_allocate_pcm_channel(trident); - if(idx < 0) { - spin_unlock_irqrestore(&trident->voice_alloc, flags); + if (idx < 0) return NULL; - } pvoice = &trident->synth.voices[idx]; pvoice->use = 1; pvoice->pcm = 1; @@ -3764,27 +3726,22 @@ struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, pvoice->spdif = 0; pvoice->memblk = NULL; pvoice->substream = NULL; - spin_unlock_irqrestore(&trident->voice_alloc, flags); return pvoice; } if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) { idx = snd_trident_allocate_synth_channel(trident); - if(idx < 0) { - spin_unlock_irqrestore(&trident->voice_alloc, flags); + if (idx < 0) return NULL; - } pvoice = &trident->synth.voices[idx]; pvoice->use = 1; pvoice->synth = 1; pvoice->client = client; pvoice->port = port; pvoice->memblk = NULL; - spin_unlock_irqrestore(&trident->voice_alloc, flags); return pvoice; } if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) { } - spin_unlock_irqrestore(&trident->voice_alloc, flags); 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) { - unsigned long flags; void (*private_free)(struct snd_trident_voice *); if (voice == NULL || !voice->use) return; snd_trident_clear_voices(trident, voice->number, voice->number); - spin_lock_irqsave(&trident->voice_alloc, flags); - private_free = voice->private_free; - voice->private_free = NULL; - voice->private_data = NULL; - if (voice->pcm) - snd_trident_free_pcm_channel(trident, voice->number); - if (voice->synth) - snd_trident_free_synth_channel(trident, voice->number); - voice->use = voice->pcm = voice->synth = voice->midi = 0; - voice->capture = voice->spdif = 0; - voice->sample_ops = NULL; - voice->substream = NULL; - voice->extra = NULL; - spin_unlock_irqrestore(&trident->voice_alloc, flags); + scoped_guard(spinlock_irqsave, &trident->voice_alloc) { + private_free = voice->private_free; + voice->private_free = NULL; + voice->private_data = NULL; + if (voice->pcm) + snd_trident_free_pcm_channel(trident, voice->number); + if (voice->synth) + snd_trident_free_synth_channel(trident, voice->number); + voice->use = voice->pcm = voice->synth = voice->midi = 0; + voice->capture = voice->spdif = 0; + voice->sample_ops = NULL; + voice->substream = NULL; + voice->extra = NULL; + } if (private_free) private_free(voice); } diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index 4a36f194c7f8..81f6348191dc 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -172,12 +172,10 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, - mutex_lock(&hdr->block_mutex); + guard(mutex)(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); - if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + if (blk == NULL) return NULL; - } /* set TLB entries */ idx = 0; @@ -186,12 +184,10 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs); if (!is_valid_page(trident, addr)) { __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); return NULL; } set_tlb_bus(trident, page, addr); } - mutex_unlock(&hdr->block_mutex); return blk; } @@ -216,12 +212,10 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, if (snd_BUG_ON(!hdr)) return NULL; - mutex_lock(&hdr->block_mutex); + guard(mutex)(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); - if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); + if (blk == NULL) return NULL; - } /* set TLB entries */ addr = runtime->dma_addr; @@ -229,12 +223,10 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, addr += SNDRV_TRIDENT_PAGE_SIZE) { if (!is_valid_page(trident, addr)) { __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); return NULL; } set_tlb_bus(trident, page, addr); } - mutex_unlock(&hdr->block_mutex); return blk; } @@ -267,12 +259,11 @@ int snd_trident_free_pages(struct snd_trident *trident, return -EINVAL; hdr = trident->tlb.memhdr; - mutex_lock(&hdr->block_mutex); + guard(mutex)(&hdr->block_mutex); /* reset TLB entries */ for (page = firstpg(blk); page <= lastpg(blk); page++) set_silent_tlb(trident, page); /* free memory block */ __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); return 0; } |