diff options
Diffstat (limited to 'sound/pci/emu10k1/emumixer.c')
| -rw-r--r-- | sound/pci/emu10k1/emumixer.c | 82 |
1 files changed, 38 insertions, 44 deletions
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 0a32ea53d8c6..f4906ab30c02 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -12,6 +12,7 @@ #include <linux/time.h> #include <linux/init.h> +#include <linux/string.h> #include <sound/core.h> #include <sound/emu10k1.h> #include <linux/delay.h> @@ -661,6 +662,7 @@ static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol, change = (emu->emu1010.output_source[channel] != val); if (change) { emu->emu1010.output_source[channel] = val; + guard(snd_emu1010_fpga_lock)(emu); snd_emu1010_output_source_apply(emu, channel, val); } return change; @@ -705,6 +707,7 @@ static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol, change = (emu->emu1010.input_source[channel] != val); if (change) { emu->emu1010.input_source[channel] = val; + guard(snd_emu1010_fpga_lock)(emu); snd_emu1010_input_source_apply(emu, channel, val); } return change; @@ -774,7 +777,7 @@ static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ct cache = cache & ~mask; change = (cache != emu->emu1010.adc_pads); if (change) { - snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache ); + snd_emu1010_fpga_write_lock(emu, EMU_HANA_ADC_PADS, cache ); emu->emu1010.adc_pads = cache; } @@ -832,7 +835,7 @@ static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ct cache = cache & ~mask; change = (cache != emu->emu1010.dac_pads); if (change) { - snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache ); + snd_emu1010_fpga_write_lock(emu, EMU_HANA_DAC_PADS, cache ); emu->emu1010.dac_pads = cache; } @@ -975,28 +978,25 @@ static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol, const struct snd_emu1010_clock_info *emu_ci = &emu1010_clock_info[emu1010_idx(emu)]; unsigned int val; - int change = 0; val = ucontrol->value.enumerated.item[0] ; if (val >= emu_ci->num) return -EINVAL; - spin_lock_irq(&emu->reg_lock); - change = (emu->emu1010.clock_source != val); - if (change) { + guard(snd_emu1010_fpga_lock)(emu); + scoped_guard(spinlock_irq, &emu->reg_lock) { + if (emu->emu1010.clock_source == val) + return 0; emu->emu1010.clock_source = val; emu->emu1010.wclock = emu_ci->vals[val]; snd_emu1010_update_clock(emu); snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE); snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, emu->emu1010.wclock); - spin_unlock_irq(&emu->reg_lock); - - msleep(10); // Allow DLL to settle - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); - } else { - spin_unlock_irq(&emu->reg_lock); } - return change; + + msleep(10); // Allow DLL to settle + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); + return 1; } static const struct snd_kcontrol_new snd_emu1010_clock_source = @@ -1041,7 +1041,7 @@ static int snd_emu1010_clock_fallback_put(struct snd_kcontrol *kcontrol, change = (emu->emu1010.clock_fallback != val); if (change) { emu->emu1010.clock_fallback = val; - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 1 - val); + snd_emu1010_fpga_write_lock(emu, EMU_HANA_DEFCLOCK, 1 - val); } return change; } @@ -1093,7 +1093,7 @@ static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol, emu->emu1010.optical_out = val; tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF); - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); + snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp); } return change; } @@ -1144,7 +1144,7 @@ static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol, emu->emu1010.optical_in = val; tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF); - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); + snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp); } return change; } @@ -1204,13 +1204,13 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, change = (emu->i2c_capture_source != source_id); if (change) { snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */ - spin_lock_irq(&emu->emu_lock); - gpio = inw(emu->port + A_IOCFG); - if (source_id==0) - outw(gpio | 0x4, emu->port + A_IOCFG); - else - outw(gpio & ~0x4, emu->port + A_IOCFG); - spin_unlock_irq(&emu->emu_lock); + scoped_guard(spinlock_irq, &emu->emu_lock) { + gpio = inw(emu->port + A_IOCFG); + if (source_id == 0) + outw(gpio | 0x4, emu->port + A_IOCFG); + else + outw(gpio & ~0x4, emu->port + A_IOCFG); + } ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ @@ -1371,14 +1371,13 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol, } - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); tmp = reg & ~A_SPDIF_RATE_MASK; tmp |= val; change = (tmp != reg); if (change) snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1502,7 +1501,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, int num_efx = emu->audigy ? 8 : 4; int mask = emu->audigy ? 0x3f : 0x0f; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); for (voice = 0; voice < 3; voice++) for (idx = 0; idx < num_efx; idx++) { val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask; @@ -1522,7 +1521,6 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, &mix->send_routing[0][0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1570,7 +1568,7 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, int change = 0, idx, val; int num_efx = emu->audigy ? 8 : 4; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); for (idx = 0; idx < 3*num_efx; idx++) { val = ucontrol->value.integer.value[idx] & 255; if (mix->send_volume[idx/num_efx][idx%num_efx] != val) { @@ -1589,7 +1587,6 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, &mix->send_volume[0][0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1634,7 +1631,7 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)]; int change = 0, idx, val; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); for (idx = 0; idx < 3; idx++) { unsigned uval = ucontrol->value.integer.value[idx] & 0x1ffff; val = uval * 0x8000U / 0xffffU; @@ -1651,7 +1648,6 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1704,7 +1700,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, int num_efx = emu->audigy ? 8 : 4; int mask = emu->audigy ? 0x3f : 0x0f; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); for (idx = 0; idx < num_efx; idx++) { val = ucontrol->value.integer.value[idx] & mask; if (mix->send_routing[0][idx] != val) { @@ -1719,7 +1715,6 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, &mix->send_routing[0][0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1767,7 +1762,7 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol, int change = 0, idx, val; int num_efx = emu->audigy ? 8 : 4; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); for (idx = 0; idx < num_efx; idx++) { val = ucontrol->value.integer.value[idx] & 255; if (mix->send_volume[0][idx] != val) { @@ -1781,7 +1776,6 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol, &mix->send_volume[0][0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1826,7 +1820,7 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol, int change = 0, val; unsigned uval; - spin_lock_irq(&emu->reg_lock); + guard(spinlock_irq)(&emu->reg_lock); uval = ucontrol->value.integer.value[0] & 0x1ffff; val = uval * 0x8000U / 0xffffU; if (mix->attn[0] != val) { @@ -1838,7 +1832,6 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol, snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]); } } - spin_unlock_irq(&emu->reg_lock); return change; } @@ -1881,7 +1874,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, sw = ucontrol->value.integer.value[0]; if (emu->card_capabilities->invert_shared_spdif) sw = !sw; - spin_lock_irq(&emu->emu_lock); + guard(spinlock_irq)(&emu->emu_lock); if ( emu->card_capabilities->i2c_adc) { /* Do nothing for Audigy 2 ZS Notebook */ } else if (emu->audigy) { @@ -1902,7 +1895,6 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, reg |= val; outl(reg | val, emu->port + HCFG); } - spin_unlock_irq(&emu->emu_lock); return change; } @@ -1977,7 +1969,7 @@ static int remove_ctl(struct snd_card *card, const char *name) { struct snd_ctl_elem_id id; memset(&id, 0, sizeof(id)); - strcpy(id.name, name); + strscpy(id.name, name); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; return snd_ctl_remove_id(card, &id); } @@ -2182,11 +2174,11 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu, } else { no_ac97: if (emu->card_capabilities->ecard) - strcpy(emu->card->mixername, "EMU APS"); + strscpy(emu->card->mixername, "EMU APS"); else if (emu->audigy) - strcpy(emu->card->mixername, "SB Audigy"); + strscpy(emu->card->mixername, "SB Audigy"); else - strcpy(emu->card->mixername, "Emu10k1"); + strscpy(emu->card->mixername, "Emu10k1"); } if (emu->audigy) @@ -2323,7 +2315,9 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu, for (i = 0; i < emu_ri->n_outs; i++) emu->emu1010.output_source[i] = emu1010_map_source(emu_ri, emu_ri->out_dflts[i]); - snd_emu1010_apply_sources(emu); + scoped_guard(snd_emu1010_fpga_lock, emu) { + snd_emu1010_apply_sources(emu); + } kctl = emu->ctl_clock_source = snd_ctl_new1(&snd_emu1010_clock_source, emu); err = snd_ctl_add(card, kctl); |
