summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97/bus.c22
-rw-r--r--sound/aoa/codecs/onyx.c106
-rw-r--r--sound/aoa/codecs/tas.c115
-rw-r--r--sound/aoa/codecs/toonie.c2
-rw-r--r--sound/aoa/core/alsa.c8
-rw-r--r--sound/aoa/core/gpio-feature.c20
-rw-r--r--sound/aoa/core/gpio-pmf.c26
-rw-r--r--sound/aoa/fabrics/layout.c9
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c4
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c202
-rw-r--r--sound/arm/aaci.c192
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c12
-rw-r--r--sound/atmel/ac97c.c18
-rw-r--r--sound/core/compress_offload.c98
-rw-r--r--sound/core/misc.c25
-rw-r--r--sound/core/oss/pcm_oss.c3
-rw-r--r--sound/core/pcm_dmaengine.c2
-rw-r--r--sound/core/pcm_native.c25
-rw-r--r--sound/core/seq/oss/seq_oss.c24
-rw-r--r--sound/core/seq/oss/seq_oss_device.h7
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c116
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c10
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c125
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c5
-rw-r--r--sound/core/seq/seq_clientmgr.c743
-rw-r--r--sound/core/seq/seq_clientmgr.h17
-rw-r--r--sound/core/seq/seq_fifo.c16
-rw-r--r--sound/core/seq/seq_fifo.h1
-rw-r--r--sound/core/seq/seq_ports.c19
-rw-r--r--sound/core/seq/seq_ports.h2
-rw-r--r--sound/core/seq/seq_queue.c76
-rw-r--r--sound/core/seq/seq_queue.h2
-rw-r--r--sound/core/seq/seq_timer.c5
-rw-r--r--sound/drivers/aloop.c262
-rw-r--r--sound/drivers/dummy.c40
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c41
-rw-r--r--sound/drivers/mtpav.c61
-rw-r--r--sound/drivers/mts64.c57
-rw-r--r--sound/drivers/opl3/opl3_lib.c26
-rw-r--r--sound/drivers/opl3/opl3_midi.c51
-rw-r--r--sound/drivers/opl3/opl3_seq.c27
-rw-r--r--sound/drivers/opl4/opl4_lib.c10
-rw-r--r--sound/drivers/opl4/opl4_mixer.c8
-rw-r--r--sound/drivers/opl4/opl4_proc.c10
-rw-r--r--sound/drivers/opl4/opl4_seq.c30
-rw-r--r--sound/drivers/opl4/opl4_synth.c81
-rw-r--r--sound/drivers/portman2x4.c12
-rw-r--r--sound/drivers/serial-generic.c12
-rw-r--r--sound/drivers/serial-u16550.c48
-rw-r--r--sound/drivers/vx/vx_core.c19
-rw-r--r--sound/drivers/vx/vx_mixer.c57
-rw-r--r--sound/drivers/vx/vx_pcm.c3
-rw-r--r--sound/drivers/vx/vx_uer.c17
-rw-r--r--sound/firewire/amdtp-stream.c28
-rw-r--r--sound/firewire/bebob/bebob.c36
-rw-r--r--sound/firewire/bebob/bebob_hwdep.c37
-rw-r--r--sound/firewire/bebob/bebob_maudio.c42
-rw-r--r--sound/firewire/bebob/bebob_midi.c34
-rw-r--r--sound/firewire/bebob/bebob_pcm.c70
-rw-r--r--sound/firewire/bebob/bebob_stream.c21
-rw-r--r--sound/firewire/cmp.c37
-rw-r--r--sound/firewire/dice/dice-hwdep.c37
-rw-r--r--sound/firewire/dice/dice-midi.c38
-rw-r--r--sound/firewire/dice/dice-pcm.c93
-rw-r--r--sound/firewire/dice/dice-stream.c21
-rw-r--r--sound/firewire/dice/dice-transaction.c7
-rw-r--r--sound/firewire/dice/dice.c3
-rw-r--r--sound/firewire/digi00x/digi00x-hwdep.c37
-rw-r--r--sound/firewire/digi00x/digi00x-midi.c34
-rw-r--r--sound/firewire/digi00x/digi00x-pcm.c77
-rw-r--r--sound/firewire/digi00x/digi00x-stream.c21
-rw-r--r--sound/firewire/digi00x/digi00x-transaction.c8
-rw-r--r--sound/firewire/digi00x/digi00x.c3
-rw-r--r--sound/firewire/fcp.c19
-rw-r--r--sound/firewire/fireface/ff-hwdep.c37
-rw-r--r--sound/firewire/fireface/ff-midi.c10
-rw-r--r--sound/firewire/fireface/ff-pcm.c92
-rw-r--r--sound/firewire/fireface/ff-stream.c21
-rw-r--r--sound/firewire/fireface/ff-transaction.c4
-rw-r--r--sound/firewire/fireworks/fireworks.c41
-rw-r--r--sound/firewire/fireworks/fireworks_command.c16
-rw-r--r--sound/firewire/fireworks/fireworks_hwdep.c41
-rw-r--r--sound/firewire/fireworks/fireworks_midi.c39
-rw-r--r--sound/firewire/fireworks/fireworks_pcm.c69
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c21
-rw-r--r--sound/firewire/fireworks/fireworks_transaction.c39
-rw-r--r--sound/firewire/isight.c20
-rw-r--r--sound/firewire/iso-resources.c66
-rw-r--r--sound/firewire/motu/motu-command-dsp-message-parser.c9
-rw-r--r--sound/firewire/motu/motu-hwdep.c37
-rw-r--r--sound/firewire/motu/motu-midi.c38
-rw-r--r--sound/firewire/motu/motu-pcm.c92
-rw-r--r--sound/firewire/motu/motu-register-dsp-message-parser.c18
-rw-r--r--sound/firewire/motu/motu-stream.c21
-rw-r--r--sound/firewire/motu/motu-transaction.c7
-rw-r--r--sound/firewire/oxfw/oxfw-hwdep.c37
-rw-r--r--sound/firewire/oxfw/oxfw-midi.c62
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c92
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c21
-rw-r--r--sound/firewire/oxfw/oxfw.c3
-rw-r--r--sound/firewire/tascam/amdtp-tascam.c17
-rw-r--r--sound/firewire/tascam/tascam-hwdep.c37
-rw-r--r--sound/firewire/tascam/tascam-midi.c10
-rw-r--r--sound/firewire/tascam/tascam-pcm.c75
-rw-r--r--sound/firewire/tascam/tascam-stream.c21
-rw-r--r--sound/firewire/tascam/tascam.c3
-rw-r--r--sound/hda/codecs/analog.c3
-rw-r--r--sound/hda/codecs/ca0132.c295
-rw-r--r--sound/hda/codecs/cirrus/cs8409.c22
-rw-r--r--sound/hda/codecs/conexant.c4
-rw-r--r--sound/hda/codecs/generic.c76
-rw-r--r--sound/hda/codecs/hdmi/hdmi.c199
-rw-r--r--sound/hda/codecs/hdmi/nvhdmi-mcp.c3
-rw-r--r--sound/hda/codecs/realtek/alc268.c3
-rw-r--r--sound/hda/codecs/realtek/alc269.c7
-rw-r--r--sound/hda/codecs/realtek/realtek.c40
-rw-r--r--sound/hda/codecs/realtek/realtek.h21
-rw-r--r--sound/hda/codecs/side-codecs/cirrus_scodec_test.c2
-rw-r--r--sound/hda/codecs/side-codecs/cs35l41_hda.c110
-rw-r--r--sound/hda/codecs/side-codecs/cs35l56_hda.c1
-rw-r--r--sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c2
-rw-r--r--sound/hda/codecs/side-codecs/cs35l56_hda_spi.c2
-rw-r--r--sound/hda/codecs/side-codecs/hda_component.c15
-rw-r--r--sound/hda/codecs/side-codecs/hda_component.h3
-rw-r--r--sound/hda/codecs/side-codecs/tas2781_hda_i2c.c83
-rw-r--r--sound/hda/common/codec.c142
-rw-r--r--sound/hda/common/controller.c124
-rw-r--r--sound/hda/common/proc.c13
-rw-r--r--sound/hda/common/sysfs.c110
-rw-r--r--sound/hda/controllers/intel.c14
-rw-r--r--sound/hda/core/bus.c8
-rw-r--r--sound/hda/core/component.c6
-rw-r--r--sound/hda/core/controller.c58
-rw-r--r--sound/hda/core/device.c23
-rw-r--r--sound/hda/core/ext/controller.c6
-rw-r--r--sound/hda/core/ext/stream.c38
-rw-r--r--sound/hda/core/regmap.c35
-rw-r--r--sound/hda/core/stream.c34
-rw-r--r--sound/i2c/other/ak4113.c54
-rw-r--r--sound/i2c/other/ak4114.c39
-rw-r--r--sound/i2c/other/ak4117.c40
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c117
-rw-r--r--sound/isa/cmi8330.c15
-rw-r--r--sound/isa/cs423x/cs4236_lib.c131
-rw-r--r--sound/isa/es1688/es1688_lib.c280
-rw-r--r--sound/isa/es18xx.c58
-rw-r--r--sound/isa/gus/gus_dma.c88
-rw-r--r--sound/isa/gus/gus_dram.c8
-rw-r--r--sound/isa/gus/gus_io.c65
-rw-r--r--sound/isa/gus/gus_main.c65
-rw-r--r--sound/isa/gus/gus_mem.c33
-rw-r--r--sound/isa/gus/gus_mixer.c12
-rw-r--r--sound/isa/gus/gus_pcm.c175
-rw-r--r--sound/isa/gus/gus_reset.c66
-rw-r--r--sound/isa/gus/gus_timer.c16
-rw-r--r--sound/isa/gus/gus_uart.c24
-rw-r--r--sound/isa/gus/gusextreme.c23
-rw-r--r--sound/isa/gus/interwave.c33
-rw-r--r--sound/isa/msnd/msnd.c29
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c11
-rw-r--r--sound/isa/msnd/msnd_pinnacle_mixer.c8
-rw-r--r--sound/isa/opl3sa2.c29
-rw-r--r--sound/isa/opti9xx/miro.c17
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c21
-rw-r--r--sound/isa/sb/emu8000.c94
-rw-r--r--sound/isa/sb/emu8000_pcm.c48
-rw-r--r--sound/isa/sb/sb16.c11
-rw-r--r--sound/isa/sb/sb16_csp.c219
-rw-r--r--sound/isa/sb/sb16_main.c123
-rw-r--r--sound/isa/sb/sb8_main.c170
-rw-r--r--sound/isa/sb/sb8_midi.c121
-rw-r--r--sound/isa/sb/sb_common.c17
-rw-r--r--sound/isa/sb/sb_mixer.c61
-rw-r--r--sound/isa/sscape.c190
-rw-r--r--sound/isa/wavefront/wavefront_midi.c131
-rw-r--r--sound/isa/wavefront/wavefront_synth.c18
-rw-r--r--sound/isa/wss/wss_lib.c285
-rw-r--r--sound/mips/sgio2audio.c20
-rw-r--r--sound/mips/snd-n64.c17
-rw-r--r--sound/parisc/harmony.c103
-rw-r--r--sound/pci/ac97/ac97_codec.c32
-rw-r--r--sound/pci/ac97/ac97_patch.c9
-rw-r--r--sound/pci/ac97/ac97_pcm.c50
-rw-r--r--sound/pci/ac97/ac97_proc.c10
-rw-r--r--sound/pci/ad1889.c12
-rw-r--r--sound/pci/ak4531_codec.c18
-rw-r--r--sound/pci/ali5451/ali5451.c92
-rw-r--r--sound/pci/als300.c21
-rw-r--r--sound/pci/als4000.c68
-rw-r--r--sound/pci/asihpi/asihpi.c16
-rw-r--r--sound/pci/atiixp.c69
-rw-r--r--sound/pci/atiixp_modem.c49
-rw-r--r--sound/pci/aw2/aw2-alsa.c26
-rw-r--r--sound/pci/azt3328.c145
-rw-r--r--sound/pci/bt87x.c26
-rw-r--r--sound/pci/ca0106/ca0106_main.c33
-rw-r--r--sound/pci/ca0106/ca0106_proc.c28
-rw-r--r--sound/pci/ca0106/ca_midi.c171
-rw-r--r--sound/pci/cmipci.c185
-rw-r--r--sound/pci/cs4281.c54
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c202
-rw-r--r--sound/pci/cs46xx/dsp_spos.c70
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c63
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c14
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c12
-rw-r--r--sound/pci/ctxfi/ctamixer.c67
-rw-r--r--sound/pci/ctxfi/ctatc.c28
-rw-r--r--sound/pci/ctxfi/ctdaio.c42
-rw-r--r--sound/pci/ctxfi/cthw20k1.c39
-rw-r--r--sound/pci/ctxfi/ctsrc.c101
-rw-r--r--sound/pci/ctxfi/cttimer.c63
-rw-r--r--sound/pci/ctxfi/ctvmem.c16
-rw-r--r--sound/pci/echoaudio/echoaudio.c128
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c6
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c3
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c6
-rw-r--r--sound/pci/echoaudio/midi.c41
-rw-r--r--sound/pci/echoaudio/mona_dsp.c3
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c27
-rw-r--r--sound/pci/emu10k1/emu10k1_synth.c11
-rw-r--r--sound/pci/emu10k1/emu10k1x.c223
-rw-r--r--sound/pci/emu10k1/emufx.c81
-rw-r--r--sound/pci/emu10k1/emumixer.c71
-rw-r--r--sound/pci/emu10k1/emumpu401.c175
-rw-r--r--sound/pci/emu10k1/emupcm.c58
-rw-r--r--sound/pci/emu10k1/emuproc.c19
-rw-r--r--sound/pci/emu10k1/io.c123
-rw-r--r--sound/pci/emu10k1/memory.c34
-rw-r--r--sound/pci/emu10k1/p16v.c8
-rw-r--r--sound/pci/emu10k1/voice.c8
-rw-r--r--sound/pci/ens1370.c316
-rw-r--r--sound/pci/es1938.c28
-rw-r--r--sound/pci/es1968.c160
-rw-r--r--sound/pci/fm801.c71
-rw-r--r--sound/pci/ice1712/aureon.c27
-rw-r--r--sound/pci/ice1712/delta.c83
-rw-r--r--sound/pci/ice1712/ews.c53
-rw-r--r--sound/pci/ice1712/hoontech.c24
-rw-r--r--sound/pci/ice1712/ice1712.c184
-rw-r--r--sound/pci/ice1712/ice1724.c310
-rw-r--r--sound/pci/ice1712/maya44.c18
-rw-r--r--sound/pci/ice1712/phase.c6
-rw-r--r--sound/pci/ice1712/pontis.c70
-rw-r--r--sound/pci/ice1712/prodigy192.c11
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c56
-rw-r--r--sound/pci/ice1712/quartet.c3
-rw-r--r--sound/pci/ice1712/wtm.c6
-rw-r--r--sound/pci/intel8x0.c178
-rw-r--r--sound/pci/intel8x0m.c8
-rw-r--r--sound/pci/korg1212/korg1212.c182
-rw-r--r--sound/pci/lola/lola.c4
-rw-r--r--sound/pci/lola/lola_pcm.c36
-rw-r--r--sound/pci/lx6464es/lx6464es.c49
-rw-r--r--sound/pci/lx6464es/lx_core.c111
-rw-r--r--sound/pci/maestro3.c23
-rw-r--r--sound/pci/mixart/mixart.c48
-rw-r--r--sound/pci/mixart/mixart_core.c71
-rw-r--r--sound/pci/mixart/mixart_mixer.c46
-rw-r--r--sound/pci/nm256/nm256.c37
-rw-r--r--sound/pci/oxygen/oxygen.c12
-rw-r--r--sound/pci/oxygen/oxygen_lib.c134
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c66
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c167
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c6
-rw-r--r--sound/pci/oxygen/xonar_dg_mixer.c33
-rw-r--r--sound/pci/oxygen/xonar_lib.c3
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c21
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c31
-rw-r--r--sound/pci/pcxhr/pcxhr.c35
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c15
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c23
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c58
-rw-r--r--sound/pci/rme32.c152
-rw-r--r--sound/pci/rme96.c211
-rw-r--r--sound/pci/rme9652/hdsp.c311
-rw-r--r--sound/pci/rme9652/hdspm.c301
-rw-r--r--sound/pci/rme9652/rme9652.c199
-rw-r--r--sound/pci/sis7019.c43
-rw-r--r--sound/pci/sonicvibes.c113
-rw-r--r--sound/pci/trident/trident_main.c324
-rw-r--r--sound/pci/trident/trident_memory.c19
-rw-r--r--sound/pci/via82xx.c80
-rw-r--r--sound/pci/via82xx_modem.c6
-rw-r--r--sound/pci/vx222/vx222_ops.c12
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c248
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c3
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c25
-rw-r--r--sound/pcmcia/vx/vxp_mixer.c9
-rw-r--r--sound/pcmcia/vx/vxp_ops.c6
-rw-r--r--sound/ppc/awacs.c24
-rw-r--r--sound/ppc/beep.c17
-rw-r--r--sound/ppc/burgundy.c10
-rw-r--r--sound/ppc/pmac.c88
-rw-r--r--sound/ppc/snd_ps3.c21
-rw-r--r--sound/soc/amd/acp/acp-rembrandt.c2
-rw-r--r--sound/soc/amd/acp/amd-sdw-acpi.c2
-rw-r--r--sound/soc/amd/raven/acp3x-i2s.c3
-rw-r--r--sound/soc/amd/vangogh/acp5x-i2s.c3
-rw-r--r--sound/soc/apple/mca.c1
-rw-r--r--sound/soc/codecs/Kconfig67
-rw-r--r--sound/soc/codecs/Makefile20
-rw-r--r--sound/soc/codecs/adau1977.c2
-rw-r--r--sound/soc/codecs/cs-amp-lib-test.c252
-rw-r--r--sound/soc/codecs/cs-amp-lib.c139
-rw-r--r--sound/soc/codecs/cs35l41.c77
-rw-r--r--sound/soc/codecs/cs35l56-i2c.c4
-rw-r--r--sound/soc/codecs/cs35l56-sdw.c4
-rw-r--r--sound/soc/codecs/cs35l56-shared.c109
-rw-r--r--sound/soc/codecs/cs35l56-spi.c2
-rw-r--r--sound/soc/codecs/cs42l43-jack.c8
-rw-r--r--sound/soc/codecs/cs42l43.c109
-rw-r--r--sound/soc/codecs/cs42l43.h3
-rw-r--r--sound/soc/codecs/cs48l32-tables.c4
-rw-r--r--sound/soc/codecs/da7213.c6
-rw-r--r--sound/soc/codecs/es8323.c17
-rw-r--r--sound/soc/codecs/fs-amp-lib.c265
-rw-r--r--sound/soc/codecs/fs-amp-lib.h150
-rw-r--r--sound/soc/codecs/fs210x.c1586
-rw-r--r--sound/soc/codecs/fs210x.h75
-rw-r--r--sound/soc/codecs/lpass-macro-common.h1
-rw-r--r--sound/soc/codecs/lpass-va-macro.c2
-rw-r--r--sound/soc/codecs/lpass-wsa-macro.c2
-rw-r--r--sound/soc/codecs/pcm1754.c185
-rw-r--r--sound/soc/codecs/pcm6240.c4
-rw-r--r--sound/soc/codecs/pm4125-sdw.c545
-rw-r--r--sound/soc/codecs/pm4125.c1780
-rw-r--r--sound/soc/codecs/pm4125.h307
-rw-r--r--sound/soc/codecs/rt1320-sdw.c380
-rw-r--r--sound/soc/codecs/rt1320-sdw.h10
-rw-r--r--sound/soc/codecs/rt721-sdca-sdw.c10
-rw-r--r--sound/soc/codecs/tas2781-comlib-i2c.c2
-rw-r--r--sound/soc/codecs/tas2781-fmwlib.c79
-rw-r--r--sound/soc/codecs/tas2781-i2c.c190
-rw-r--r--sound/soc/codecs/tas2783-sdw.c1331
-rw-r--r--sound/soc/codecs/tas2783.h110
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c18
-rw-r--r--sound/soc/codecs/tlv320aic3x.c32
-rw-r--r--sound/soc/codecs/tlv320dac33.c69
-rw-r--r--sound/soc/codecs/wcd-common.c144
-rw-r--r--sound/soc/codecs/wcd-common.h46
-rw-r--r--sound/soc/codecs/wcd934x.c99
-rw-r--r--sound/soc/codecs/wcd937x-sdw.c67
-rw-r--r--sound/soc/codecs/wcd937x.c93
-rw-r--r--sound/soc/codecs/wcd937x.h24
-rw-r--r--sound/soc/codecs/wcd938x-sdw.c83
-rw-r--r--sound/soc/codecs/wcd938x.c99
-rw-r--r--sound/soc/codecs/wcd938x.h26
-rw-r--r--sound/soc/codecs/wcd939x-sdw.c98
-rw-r--r--sound/soc/codecs/wcd939x.c104
-rw-r--r--sound/soc/codecs/wcd939x.h32
-rw-r--r--sound/soc/codecs/wl1273.c500
-rw-r--r--sound/soc/codecs/wl1273.h16
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c6
-rw-r--r--sound/soc/codecs/wm8994.h12
-rw-r--r--sound/soc/codecs/wm8996.c2
-rw-r--r--sound/soc/codecs/wm_adsp.c6
-rw-r--r--sound/soc/codecs/wm_adsp.h2
-rw-r--r--sound/soc/codecs/wsa883x.c57
-rw-r--r--sound/soc/fsl/fsl_qmc_audio.c125
-rw-r--r--sound/soc/fsl/fsl_sai.c3
-rw-r--r--sound/soc/fsl/imx-audmux.c2
-rw-r--r--sound/soc/fsl/imx-hdmi.c13
-rw-r--r--sound/soc/generic/test-component.c4
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-compress.c12
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform.h2
-rw-r--r--sound/soc/intel/atom/sst/sst.c2
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c9
-rw-r--r--sound/soc/intel/avs/apl.c1
-rw-r--r--sound/soc/intel/avs/avs.h90
-rw-r--r--sound/soc/intel/avs/board_selection.c309
-rw-r--r--sound/soc/intel/avs/boards/da7219.c15
-rw-r--r--sound/soc/intel/avs/boards/dmic.c80
-rw-r--r--sound/soc/intel/avs/boards/es8336.c18
-rw-r--r--sound/soc/intel/avs/boards/hdaudio.c13
-rw-r--r--sound/soc/intel/avs/boards/i2s_test.c15
-rw-r--r--sound/soc/intel/avs/boards/max98357a.c15
-rw-r--r--sound/soc/intel/avs/boards/max98373.c15
-rw-r--r--sound/soc/intel/avs/boards/max98927.c15
-rw-r--r--sound/soc/intel/avs/boards/nau8825.c15
-rw-r--r--sound/soc/intel/avs/boards/probe.c49
-rw-r--r--sound/soc/intel/avs/boards/rt274.c17
-rw-r--r--sound/soc/intel/avs/boards/rt286.c15
-rw-r--r--sound/soc/intel/avs/boards/rt298.c15
-rw-r--r--sound/soc/intel/avs/boards/rt5514.c15
-rw-r--r--sound/soc/intel/avs/boards/rt5640.c2
-rw-r--r--sound/soc/intel/avs/boards/rt5663.c15
-rw-r--r--sound/soc/intel/avs/boards/rt5682.c15
-rw-r--r--sound/soc/intel/avs/boards/ssm4567.c15
-rw-r--r--sound/soc/intel/avs/cnl.c1
-rw-r--r--sound/soc/intel/avs/core.c1
-rw-r--r--sound/soc/intel/avs/debug.h91
-rw-r--r--sound/soc/intel/avs/debugfs.c1
-rw-r--r--sound/soc/intel/avs/icl.c1
-rw-r--r--sound/soc/intel/avs/ipc.c1
-rw-r--r--sound/soc/intel/avs/lnl.c1
-rw-r--r--sound/soc/intel/avs/mtl.c1
-rw-r--r--sound/soc/intel/avs/path.c267
-rw-r--r--sound/soc/intel/avs/path.h13
-rw-r--r--sound/soc/intel/avs/pcm.c35
-rw-r--r--sound/soc/intel/avs/probes.c25
-rw-r--r--sound/soc/intel/avs/ptl.c1
-rw-r--r--sound/soc/intel/avs/skl.c1
-rw-r--r--sound/soc/intel/avs/tgl.c1
-rw-r--r--sound/soc/intel/avs/topology.c110
-rw-r--r--sound/soc/intel/avs/topology.h8
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c2
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c22
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c9
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c28
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c2
-rw-r--r--sound/soc/intel/boards/sof_es8336.c2
-rw-r--r--sound/soc/intel/boards/sof_sdw.c2
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-mtl-match.c30
-rw-r--r--sound/soc/mediatek/common/mtk-soundcard-driver.c19
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c2
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c2
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c2
-rw-r--r--sound/soc/mediatek/mt8186/mt8186-mt6366.c2
-rw-r--r--sound/soc/mediatek/mt8188/mt8188-mt6359.c8
-rw-r--r--sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c2
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-mt6359.c4
-rw-r--r--sound/soc/pxa/Kconfig4
-rw-r--r--sound/soc/qcom/lpass-cdc-dma.c3
-rw-r--r--sound/soc/qcom/lpass-hdmi.c2
-rw-r--r--sound/soc/qcom/qdsp6/audioreach.c54
-rw-r--r--sound/soc/qcom/qdsp6/audioreach.h35
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-dai.c29
-rw-r--r--sound/soc/qcom/qdsp6/q6apm.c3
-rw-r--r--sound/soc/qcom/qdsp6/q6asm-dai.c26
-rw-r--r--sound/soc/qcom/qdsp6/topology.c45
-rw-r--r--sound/soc/qcom/sc8280xp.c7
-rw-r--r--sound/soc/qcom/x1e80100.c5
-rw-r--r--sound/soc/renesas/fsi.c30
-rw-r--r--sound/soc/renesas/rcar/core.c18
-rw-r--r--sound/soc/renesas/rcar/msiof.c219
-rw-r--r--sound/soc/renesas/rcar/src.c19
-rw-r--r--sound/soc/renesas/rcar/ssi.c35
-rw-r--r--sound/soc/renesas/rz-ssi.c14
-rw-r--r--sound/soc/rockchip/rockchip_i2s_tdm.h4
-rw-r--r--sound/soc/sdw_utils/Makefile3
-rw-r--r--sound/soc/sdw_utils/soc_sdw_ti_amp.c92
-rw-r--r--sound/soc/sdw_utils/soc_sdw_utils.c38
-rw-r--r--sound/soc/soc-component.c2
-rw-r--r--sound/soc/soc-compress.c2
-rw-r--r--sound/soc/soc-core.c4
-rw-r--r--sound/soc/soc-dai.c2
-rw-r--r--sound/soc/soc-dapm.c121
-rw-r--r--sound/soc/soc-ops.c1
-rw-r--r--sound/soc/sof/amd/acp-probes.c2
-rw-r--r--sound/soc/sof/compress.c2
-rw-r--r--sound/soc/sof/imx/imx-common.c6
-rw-r--r--sound/soc/sof/imx/imx8.c3
-rw-r--r--sound/soc/sof/intel/hda-codec.c3
-rw-r--r--sound/soc/sof/intel/hda-ctrl.c8
-rw-r--r--sound/soc/sof/intel/hda-dsp.c2
-rw-r--r--sound/soc/sof/intel/hda-probes.c2
-rw-r--r--sound/soc/sof/intel/hda-sdw-bpt.c2
-rw-r--r--sound/soc/sof/intel/hda.c2
-rw-r--r--sound/soc/sof/intel/hda.h2
-rw-r--r--sound/soc/sof/ipc3-dtrace.c2
-rw-r--r--sound/soc/sof/ipc4-pcm.c60
-rw-r--r--sound/soc/sof/ipc4-topology.c187
-rw-r--r--sound/soc/sof/ipc4-topology.h16
-rw-r--r--sound/soc/sof/sof-audio.h3
-rw-r--r--sound/soc/sof/sof-client-probes-ipc3.c25
-rw-r--r--sound/soc/sof/sof-client-probes-ipc4.c134
-rw-r--r--sound/soc/sof/sof-client-probes.c62
-rw-r--r--sound/soc/sof/sof-client-probes.h13
-rw-r--r--sound/soc/sof/sof-client.c118
-rw-r--r--sound/soc/sof/sof-client.h8
-rw-r--r--sound/soc/sof/sof-priv.h9
-rw-r--r--sound/soc/sprd/sprd-pcm-compress.c6
-rw-r--r--sound/soc/sprd/sprd-pcm-dma.h4
-rw-r--r--sound/soc/stm/stm32_sai_sub.c8
-rw-r--r--sound/soc/uniphier/aio-compress.c2
-rw-r--r--sound/sparc/amd7930.c114
-rw-r--r--sound/sparc/cs4231.c225
-rw-r--r--sound/sparc/dbri.c232
-rw-r--r--sound/spi/at73c213.c91
-rw-r--r--sound/synth/emux/emux_effect.c29
-rw-r--r--sound/synth/emux/emux_proc.c6
-rw-r--r--sound/synth/emux/emux_seq.c17
-rw-r--r--sound/synth/emux/emux_synth.c54
-rw-r--r--sound/synth/emux/soundfont.c115
-rw-r--r--sound/synth/util_mem.c17
-rw-r--r--sound/usb/6fire/chip.c40
-rw-r--r--sound/usb/6fire/midi.c21
-rw-r--r--sound/usb/6fire/pcm.c83
-rw-r--r--sound/usb/Kconfig12
-rw-r--r--sound/usb/bcd2000/bcd2000.c16
-rw-r--r--sound/usb/caiaq/audio.c39
-rw-r--r--sound/usb/card.c94
-rw-r--r--sound/usb/endpoint.c124
-rw-r--r--sound/usb/fcp.c17
-rw-r--r--sound/usb/hiface/chip.c11
-rw-r--r--sound/usb/hiface/pcm.c60
-rw-r--r--sound/usb/line6/capture.c6
-rw-r--r--sound/usb/line6/driver.c39
-rw-r--r--sound/usb/line6/midi.c10
-rw-r--r--sound/usb/line6/pcm.c85
-rw-r--r--sound/usb/media.c6
-rw-r--r--sound/usb/midi.c77
-rw-r--r--sound/usb/midi2.c16
-rw-r--r--sound/usb/misc/ua101.c256
-rw-r--r--sound/usb/mixer.c66
-rw-r--r--sound/usb/mixer_quirks.c354
-rw-r--r--sound/usb/mixer_s1810c.c295
-rw-r--r--sound/usb/mixer_scarlett2.c1414
-rw-r--r--sound/usb/mixer_us16x08.c3
-rw-r--r--sound/usb/pcm.c301
-rw-r--r--sound/usb/proc.c3
-rw-r--r--sound/usb/qcom/qc_audio_offload.c84
-rw-r--r--sound/usb/quirks.c200
-rw-r--r--sound/usb/quirks.h11
-rw-r--r--sound/usb/usbaudio.h110
-rw-r--r--sound/usb/usx2y/Makefile2
-rw-r--r--sound/usb/usx2y/us122l.c50
-rw-r--r--sound/usb/usx2y/us144mkii.c620
-rw-r--r--sound/usb/usx2y/us144mkii.h367
-rw-r--r--sound/usb/usx2y/us144mkii_capture.c319
-rw-r--r--sound/usb/usx2y/us144mkii_controls.c444
-rw-r--r--sound/usb/usx2y/us144mkii_midi.c403
-rw-r--r--sound/usb/usx2y/us144mkii_pcm.c370
-rw-r--r--sound/usb/usx2y/us144mkii_pcm.h165
-rw-r--r--sound/usb/usx2y/us144mkii_playback.c456
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c23
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c33
-rw-r--r--sound/usb/validate.c9
-rw-r--r--sound/virtio/virtio_card.c8
-rw-r--r--sound/virtio/virtio_ctl_msg.c23
-rw-r--r--sound/virtio/virtio_pcm.c8
-rw-r--r--sound/virtio/virtio_pcm_msg.c17
-rw-r--r--sound/virtio/virtio_pcm_ops.c56
-rw-r--r--sound/x86/intel_hdmi_audio.c109
-rw-r--r--sound/xen/xen_snd_front.c82
-rw-r--r--sound/xen/xen_snd_front_evtchnl.c33
537 files changed, 22518 insertions, 15689 deletions
diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
index 47c6787158a7..f4254703d29f 100644
--- a/sound/ac97/bus.c
+++ b/sound/ac97/bus.c
@@ -241,10 +241,9 @@ static ssize_t cold_reset_store(struct device *dev,
{
struct ac97_controller *ac97_ctrl;
- mutex_lock(&ac97_controllers_mutex);
+ guard(mutex)(&ac97_controllers_mutex);
ac97_ctrl = to_ac97_controller(dev);
ac97_ctrl->ops->reset(ac97_ctrl);
- mutex_unlock(&ac97_controllers_mutex);
return len;
}
static DEVICE_ATTR_WO(cold_reset);
@@ -258,10 +257,9 @@ static ssize_t warm_reset_store(struct device *dev,
if (!dev)
return -ENODEV;
- mutex_lock(&ac97_controllers_mutex);
+ guard(mutex)(&ac97_controllers_mutex);
ac97_ctrl = to_ac97_controller(dev);
ac97_ctrl->ops->warm_reset(ac97_ctrl);
- mutex_unlock(&ac97_controllers_mutex);
return len;
}
static DEVICE_ATTR_WO(warm_reset);
@@ -284,10 +282,10 @@ static const struct attribute_group *ac97_adapter_groups[] = {
static void ac97_del_adapter(struct ac97_controller *ac97_ctrl)
{
- mutex_lock(&ac97_controllers_mutex);
- ac97_ctrl_codecs_unregister(ac97_ctrl);
- list_del(&ac97_ctrl->controllers);
- mutex_unlock(&ac97_controllers_mutex);
+ scoped_guard(mutex, &ac97_controllers_mutex) {
+ ac97_ctrl_codecs_unregister(ac97_ctrl);
+ list_del(&ac97_ctrl->controllers);
+ }
device_unregister(&ac97_ctrl->adap);
}
@@ -311,7 +309,7 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl)
{
int ret;
- mutex_lock(&ac97_controllers_mutex);
+ guard(mutex)(&ac97_controllers_mutex);
ret = idr_alloc(&ac97_adapter_idr, ac97_ctrl, 0, 0, GFP_KERNEL);
ac97_ctrl->nr = ret;
if (ret >= 0) {
@@ -322,13 +320,11 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl)
if (ret)
put_device(&ac97_ctrl->adap);
}
- if (!ret)
+ if (!ret) {
list_add(&ac97_ctrl->controllers, &ac97_controllers);
- mutex_unlock(&ac97_controllers_mutex);
-
- if (!ret)
dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n",
dev_name(ac97_ctrl->parent));
+ }
return ret;
}
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index ac347a14f282..4cf959017c9d 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -122,10 +122,9 @@ static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
s8 l, r;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
- mutex_unlock(&onyx->mutex);
ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
@@ -146,15 +145,13 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[1] > -1 + VOLUME_RANGE_SHIFT)
return -EINVAL;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
- r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
- mutex_unlock(&onyx->mutex);
+ r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1])
return 0;
- }
onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
ucontrol->value.integer.value[0]
@@ -162,7 +159,6 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
ucontrol->value.integer.value[1]
- VOLUME_RANGE_SHIFT);
- mutex_unlock(&onyx->mutex);
return 1;
}
@@ -198,9 +194,8 @@ static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
u8 ig;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
- mutex_unlock(&onyx->mutex);
ucontrol->value.integer.value[0] =
(ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
@@ -217,14 +212,13 @@ static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.integer.value[0] < 3 + INPUTGAIN_RANGE_SHIFT ||
ucontrol->value.integer.value[0] > 28 + INPUTGAIN_RANGE_SHIFT)
return -EINVAL;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
n = v;
n &= ~ONYX_ADC_PGA_GAIN_MASK;
n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
& ONYX_ADC_PGA_GAIN_MASK;
onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
- mutex_unlock(&onyx->mutex);
return n != v;
}
@@ -252,9 +246,8 @@ static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
s8 v;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
- mutex_unlock(&onyx->mutex);
ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
@@ -265,13 +258,12 @@ static void onyx_set_capture_source(struct onyx *onyx, int mic)
{
s8 v;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
v &= ~ONYX_ADC_INPUT_MIC;
if (mic)
v |= ONYX_ADC_INPUT_MIC;
onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
- mutex_unlock(&onyx->mutex);
}
static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
@@ -312,9 +304,8 @@ static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
u8 c;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
- mutex_unlock(&onyx->mutex);
ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
@@ -329,9 +320,9 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
u8 v = 0, c = 0;
int err = -EBUSY;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
if (onyx->analog_locked)
- goto out_unlock;
+ return -EBUSY;
onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
c = v;
@@ -342,9 +333,6 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
c |= ONYX_MUTE_RIGHT;
err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
return !err ? (v != c) : err;
}
@@ -373,9 +361,8 @@ static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
u8 address = (pv >> 8) & 0xff;
u8 mask = pv & 0xff;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, address, &c);
- mutex_unlock(&onyx->mutex);
ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
@@ -394,11 +381,10 @@ static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
u8 address = (pv >> 8) & 0xff;
u8 mask = pv & 0xff;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
if (spdiflock && onyx->spdif_locked) {
/* even if alsamixer doesn't care.. */
- err = -EBUSY;
- goto out_unlock;
+ return -EBUSY;
}
onyx_read_register(onyx, address, &v);
c = v;
@@ -407,9 +393,6 @@ static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
c |= mask;
err = onyx_write_register(onyx, address, c);
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
return !err ? (v != c) : err;
}
@@ -490,7 +473,7 @@ static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
u8 v;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
ucontrol->value.iec958.status[0] = v & 0x3e;
@@ -502,7 +485,6 @@ static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
ucontrol->value.iec958.status[4] = v & 0x0f;
- mutex_unlock(&onyx->mutex);
return 0;
}
@@ -513,7 +495,7 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
struct onyx *onyx = snd_kcontrol_chip(kcontrol);
u8 v;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
@@ -528,7 +510,6 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
- mutex_unlock(&onyx->mutex);
return 1;
}
@@ -673,14 +654,13 @@ static int onyx_usable(struct codec_info_item *cii,
struct onyx *onyx = cii->codec_data;
int spdif_enabled, analog_enabled;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
analog_enabled =
(v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
!= (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
- mutex_unlock(&onyx->mutex);
switch (ti->tag) {
case 0: return 1;
@@ -696,9 +676,8 @@ static int onyx_prepare(struct codec_info_item *cii,
{
u8 v;
struct onyx *onyx = cii->codec_data;
- int err = -EBUSY;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
@@ -707,10 +686,9 @@ static int onyx_prepare(struct codec_info_item *cii,
if (onyx_write_register(onyx,
ONYX_REG_DAC_CONTROL,
v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
- goto out_unlock;
+ return -EBUSY;
onyx->analog_locked = 1;
- err = 0;
- goto out_unlock;
+ return 0;
}
#endif
switch (substream->runtime->rate) {
@@ -720,8 +698,7 @@ static int onyx_prepare(struct codec_info_item *cii,
/* these rates are ok for all outputs */
/* FIXME: program spdif channel control bits here so that
* userspace doesn't have to if it only plays pcm! */
- err = 0;
- goto out_unlock;
+ return 0;
default:
/* got some rate that the digital output can't do,
* so disable and lock it */
@@ -729,16 +706,12 @@ static int onyx_prepare(struct codec_info_item *cii,
if (onyx_write_register(onyx,
ONYX_REG_DIG_INFO4,
v & ~ONYX_SPDIF_ENABLE))
- goto out_unlock;
+ return -EBUSY;
onyx->spdif_locked = 1;
- err = 0;
- goto out_unlock;
+ return 0;
}
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
+ return -EBUSY;
}
static int onyx_open(struct codec_info_item *cii,
@@ -746,9 +719,8 @@ static int onyx_open(struct codec_info_item *cii,
{
struct onyx *onyx = cii->codec_data;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx->open_count++;
- mutex_unlock(&onyx->mutex);
return 0;
}
@@ -758,11 +730,10 @@ static int onyx_close(struct codec_info_item *cii,
{
struct onyx *onyx = cii->codec_data;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
onyx->open_count--;
if (!onyx->open_count)
onyx->spdif_locked = onyx->analog_locked = 0;
- mutex_unlock(&onyx->mutex);
return 0;
}
@@ -772,7 +743,7 @@ static int onyx_switch_clock(struct codec_info_item *cii,
{
struct onyx *onyx = cii->codec_data;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
/* this *MUST* be more elaborate later... */
switch (what) {
case CLOCK_SWITCH_PREPARE_SLAVE:
@@ -784,7 +755,6 @@ static int onyx_switch_clock(struct codec_info_item *cii,
default: /* silence warning */
break;
}
- mutex_unlock(&onyx->mutex);
return 0;
}
@@ -795,27 +765,21 @@ static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
{
struct onyx *onyx = cii->codec_data;
u8 v;
- int err = -ENXIO;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
- goto out_unlock;
+ return -ENXIO;
onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
/* Apple does a sleep here but the datasheet says to do it on resume */
- err = 0;
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
+ return 0;
}
static int onyx_resume(struct codec_info_item *cii)
{
struct onyx *onyx = cii->codec_data;
u8 v;
- int err = -ENXIO;
- mutex_lock(&onyx->mutex);
+ guard(mutex)(&onyx->mutex);
/* reset codec */
onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
@@ -827,17 +791,13 @@ static int onyx_resume(struct codec_info_item *cii)
/* take codec out of suspend (if it still is after reset) */
if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
- goto out_unlock;
+ return -ENXIO;
onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
/* FIXME: should divide by sample rate, but 8k is the lowest we go */
msleep(2205000/8000);
/* reset all values */
onyx_register_init(onyx);
- err = 0;
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
+ return 0;
}
#endif /* CONFIG_PM */
@@ -1013,7 +973,7 @@ static int onyx_i2c_probe(struct i2c_client *client)
goto fail;
}
- strscpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
+ strscpy(onyx->codec.name, "onyx");
onyx->codec.owner = THIS_MODULE;
onyx->codec.init = onyx_init_codec;
onyx->codec.exit = onyx_exit_codec;
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 804b2ebbe28f..7085e0b93e29 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -235,10 +235,9 @@ static int tas_snd_vol_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->cached_volume_l;
ucontrol->value.integer.value[1] = tas->cached_volume_r;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -254,18 +253,15 @@ static int tas_snd_vol_put(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[1] > 177)
return -EINVAL;
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
if (tas->cached_volume_l == ucontrol->value.integer.value[0]
- && tas->cached_volume_r == ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
+ && tas->cached_volume_r == ucontrol->value.integer.value[1])
return 0;
- }
tas->cached_volume_l = ucontrol->value.integer.value[0];
tas->cached_volume_r = ucontrol->value.integer.value[1];
if (tas->hw_enabled)
tas_set_volume(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -285,10 +281,9 @@ static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = !tas->mute_l;
ucontrol->value.integer.value[1] = !tas->mute_r;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -297,18 +292,15 @@ static int tas_snd_mute_put(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
if (tas->mute_l == !ucontrol->value.integer.value[0]
- && tas->mute_r == !ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
+ && tas->mute_r == !ucontrol->value.integer.value[1])
return 0;
- }
tas->mute_l = !ucontrol->value.integer.value[0];
tas->mute_r = !ucontrol->value.integer.value[1];
if (tas->hw_enabled)
tas_set_volume(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -337,10 +329,9 @@ static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol,
struct tas *tas = snd_kcontrol_chip(kcontrol);
int idx = kcontrol->private_value;
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->mixer_l[idx];
ucontrol->value.integer.value[1] = tas->mixer_r[idx];
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -351,19 +342,16 @@ static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol,
struct tas *tas = snd_kcontrol_chip(kcontrol);
int idx = kcontrol->private_value;
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
if (tas->mixer_l[idx] == ucontrol->value.integer.value[0]
- && tas->mixer_r[idx] == ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
+ && tas->mixer_r[idx] == ucontrol->value.integer.value[1])
return 0;
- }
tas->mixer_l[idx] = ucontrol->value.integer.value[0];
tas->mixer_r[idx] = ucontrol->value.integer.value[1];
if (tas->hw_enabled)
tas_set_mixer(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -396,9 +384,8 @@ static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->drc_range;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -411,16 +398,13 @@ static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] > TAS3004_DRC_MAX)
return -EINVAL;
- mutex_lock(&tas->mtx);
- if (tas->drc_range == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
+ if (tas->drc_range == ucontrol->value.integer.value[0])
return 0;
- }
tas->drc_range = ucontrol->value.integer.value[0];
if (tas->hw_enabled)
tas3004_set_drc(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -440,9 +424,8 @@ static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->drc_enabled;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -451,16 +434,13 @@ static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
- if (tas->drc_enabled == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
+ if (tas->drc_enabled == ucontrol->value.integer.value[0])
return 0;
- }
tas->drc_enabled = !!ucontrol->value.integer.value[0];
if (tas->hw_enabled)
tas3004_set_drc(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -486,9 +466,8 @@ static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B);
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -500,7 +479,7 @@ static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.enumerated.item[0] > 1)
return -EINVAL;
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
oldacr = tas->acr;
/*
@@ -512,13 +491,10 @@ static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.enumerated.item[0])
tas->acr |= TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL |
TAS_ACR_B_MON_SEL_RIGHT;
- if (oldacr == tas->acr) {
- mutex_unlock(&tas->mtx);
+ if (oldacr == tas->acr)
return 0;
- }
if (tas->hw_enabled)
tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -557,9 +533,8 @@ static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->treble;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -571,16 +546,13 @@ static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.integer.value[0] < TAS3004_TREBLE_MIN ||
ucontrol->value.integer.value[0] > TAS3004_TREBLE_MAX)
return -EINVAL;
- mutex_lock(&tas->mtx);
- if (tas->treble == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
+ if (tas->treble == ucontrol->value.integer.value[0])
return 0;
- }
tas->treble = ucontrol->value.integer.value[0];
if (tas->hw_enabled)
tas_set_treble(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -608,9 +580,8 @@ static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
ucontrol->value.integer.value[0] = tas->bass;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -622,16 +593,13 @@ static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.integer.value[0] < TAS3004_BASS_MIN ||
ucontrol->value.integer.value[0] > TAS3004_BASS_MAX)
return -EINVAL;
- mutex_lock(&tas->mtx);
- if (tas->bass == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
+ if (tas->bass == ucontrol->value.integer.value[0])
return 0;
- }
tas->bass = ucontrol->value.integer.value[0];
if (tas->hw_enabled)
tas_set_bass(tas);
- mutex_unlock(&tas->mtx);
return 1;
}
@@ -722,13 +690,13 @@ static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock
break;
case CLOCK_SWITCH_SLAVE:
/* Clocks are back, re-init the codec */
- mutex_lock(&tas->mtx);
- tas_reset_init(tas);
- tas_set_volume(tas);
- tas_set_mixer(tas);
- tas->hw_enabled = 1;
- tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
- mutex_unlock(&tas->mtx);
+ scoped_guard(mutex, &tas->mtx) {
+ tas_reset_init(tas);
+ tas_set_volume(tas);
+ tas_set_mixer(tas);
+ tas->hw_enabled = 1;
+ tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
+ }
break;
default:
/* doesn't happen as of now */
@@ -743,23 +711,21 @@ static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock
* our i2c device is suspended, and then take note of that! */
static int tas_suspend(struct tas *tas)
{
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
tas->hw_enabled = 0;
tas->acr |= TAS_ACR_ANALOG_PDOWN;
tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
- mutex_unlock(&tas->mtx);
return 0;
}
static int tas_resume(struct tas *tas)
{
/* reset codec */
- mutex_lock(&tas->mtx);
+ guard(mutex)(&tas->mtx);
tas_reset_init(tas);
tas_set_volume(tas);
tas_set_mixer(tas);
tas->hw_enabled = 1;
- mutex_unlock(&tas->mtx);
return 0;
}
@@ -802,14 +768,13 @@ static int tas_init_codec(struct aoa_codec *codec)
return -EINVAL;
}
- mutex_lock(&tas->mtx);
- if (tas_reset_init(tas)) {
- printk(KERN_ERR PFX "tas failed to initialise\n");
- mutex_unlock(&tas->mtx);
- return -ENXIO;
+ scoped_guard(mutex, &tas->mtx) {
+ if (tas_reset_init(tas)) {
+ printk(KERN_ERR PFX "tas failed to initialise\n");
+ return -ENXIO;
+ }
+ tas->hw_enabled = 1;
}
- tas->hw_enabled = 1;
- mutex_unlock(&tas->mtx);
if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
aoa_get_card(),
@@ -892,7 +857,7 @@ static int tas_i2c_probe(struct i2c_client *client)
/* seems that half is a saner default */
tas->drc_range = TAS3004_DRC_MAX / 2;
- strscpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
+ strscpy(tas->codec.name, "tas");
tas->codec.owner = THIS_MODULE;
tas->codec.init = tas_init_codec;
tas->codec.exit = tas_exit_codec;
diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c
index 0da5af129492..b59967c49e0a 100644
--- a/sound/aoa/codecs/toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -126,7 +126,7 @@ static int __init toonie_init(void)
if (!toonie)
return -ENOMEM;
- strscpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
+ strscpy(toonie->codec.name, "toonie");
toonie->codec.owner = THIS_MODULE;
toonie->codec.init = toonie_init_codec;
toonie->codec.exit = toonie_exit_codec;
diff --git a/sound/aoa/core/alsa.c b/sound/aoa/core/alsa.c
index 7fce8581ddbd..aad7dfe089c7 100644
--- a/sound/aoa/core/alsa.c
+++ b/sound/aoa/core/alsa.c
@@ -28,10 +28,10 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev)
return err;
aoa_card = alsa_card->private_data;
aoa_card->alsa_card = alsa_card;
- strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
- strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
- strscpy(alsa_card->longname, name, sizeof(alsa_card->longname));
- strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
+ strscpy(alsa_card->driver, "AppleOnbdAudio");
+ strscpy(alsa_card->shortname, name);
+ strscpy(alsa_card->longname, name);
+ strscpy(alsa_card->mixername, name);
err = snd_card_register(aoa_card->alsa_card);
if (err < 0) {
printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c
index 39bb409b27f6..19ed0e6907da 100644
--- a/sound/aoa/core/gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -212,10 +212,9 @@ static void ftr_handle_notify(struct work_struct *work)
struct gpio_notification *notif =
container_of(work, struct gpio_notification, work.work);
- mutex_lock(&notif->mutex);
+ guard(mutex)(&notif->mutex);
if (notif->notify)
notif->notify(notif->data);
- mutex_unlock(&notif->mutex);
}
static void gpio_enable_dual_edge(int gpio)
@@ -341,19 +340,17 @@ static int ftr_set_notify(struct gpio_runtime *rt,
if (!irq)
return -ENODEV;
- mutex_lock(&notif->mutex);
+ guard(mutex)(&notif->mutex);
old = notif->notify;
- if (!old && !notify) {
- err = 0;
- goto out_unlock;
- }
+ if (!old && !notify)
+ return 0;
if (old && notify) {
if (old == notify && notif->data == data)
err = 0;
- goto out_unlock;
+ return err;
}
if (old && !notify)
@@ -362,16 +359,13 @@ static int ftr_set_notify(struct gpio_runtime *rt,
if (!old && notify) {
err = request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
if (err)
- goto out_unlock;
+ return err;
}
notif->notify = notify;
notif->data = data;
- err = 0;
- out_unlock:
- mutex_unlock(&notif->mutex);
- return err;
+ return 0;
}
static int ftr_get_detect(struct gpio_runtime *rt,
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 37866039d1ea..e76bde25e41a 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -74,10 +74,9 @@ static void pmf_handle_notify(struct work_struct *work)
struct gpio_notification *notif =
container_of(work, struct gpio_notification, work.work);
- mutex_lock(&notif->mutex);
+ guard(mutex)(&notif->mutex);
if (notif->notify)
notif->notify(notif->data);
- mutex_unlock(&notif->mutex);
}
static void pmf_gpio_init(struct gpio_runtime *rt)
@@ -154,19 +153,17 @@ static int pmf_set_notify(struct gpio_runtime *rt,
return -EINVAL;
}
- mutex_lock(&notif->mutex);
+ guard(mutex)(&notif->mutex);
old = notif->notify;
- if (!old && !notify) {
- err = 0;
- goto out_unlock;
- }
+ if (!old && !notify)
+ return 0;
if (old && notify) {
if (old == notify && notif->data == data)
err = 0;
- goto out_unlock;
+ return err;
}
if (old && !notify) {
@@ -178,10 +175,8 @@ static int pmf_set_notify(struct gpio_runtime *rt,
if (!old && notify) {
irq_client = kzalloc(sizeof(struct pmf_irq_client),
GFP_KERNEL);
- if (!irq_client) {
- err = -ENOMEM;
- goto out_unlock;
- }
+ if (!irq_client)
+ return -ENOMEM;
irq_client->data = notif;
irq_client->handler = pmf_handle_notify_irq;
irq_client->owner = THIS_MODULE;
@@ -192,17 +187,14 @@ static int pmf_set_notify(struct gpio_runtime *rt,
printk(KERN_ERR "snd-aoa: gpio layer failed to"
" register %s irq (%d)\n", name, err);
kfree(irq_client);
- goto out_unlock;
+ return err;
}
notif->gpio_private = irq_client;
}
notif->notify = notify;
notif->data = data;
- err = 0;
- out_unlock:
- mutex_unlock(&notif->mutex);
- return err;
+ return 0;
}
static int pmf_get_detect(struct gpio_runtime *rt,
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index e68b4cb4df29..bb2a0ef3004b 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -949,8 +949,7 @@ static void layout_attached_codec(struct aoa_codec *codec)
ldev->gpio.methods->set_lineout(codec->gpio, 1);
ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
- strscpy(ctl->id.name,
- "Headphone Switch", sizeof(ctl->id.name));
+ strscpy(ctl->id.name, "Headphone Switch");
ldev->lineout_ctrl = ctl;
aoa_snd_ctl_add(ctl);
ldev->have_lineout_detect =
@@ -964,15 +963,13 @@ static void layout_attached_codec(struct aoa_codec *codec)
ldev);
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
strscpy(ctl->id.name,
- "Headphone Detect Autoswitch",
- sizeof(ctl->id.name));
+ "Headphone Detect Autoswitch");
aoa_snd_ctl_add(ctl);
ctl = snd_ctl_new1(&lineout_detected,
ldev);
if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
strscpy(ctl->id.name,
- "Headphone Detected",
- sizeof(ctl->id.name));
+ "Headphone Detected");
ldev->lineout_detected_ctrl = ctl;
aoa_snd_ctl_add(ctl);
}
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index ce84288168e4..f4d43c854bbd 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -93,14 +93,12 @@ static irqreturn_t i2sbus_bus_intr(int irq, void *devid)
struct i2sbus_dev *dev = devid;
u32 intreg;
- spin_lock(&dev->low_lock);
+ guard(spinlock)(&dev->low_lock);
intreg = in_le32(&dev->intfregs->intr_ctl);
/* acknowledge interrupt reasons */
out_le32(&dev->intfregs->intr_ctl, intreg);
- spin_unlock(&dev->low_lock);
-
return IRQ_HANDLED;
}
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 98b812ffbde6..4c480ad2c05d 100644
--- a/sound/aoa/soundbus/i2sbus/pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
@@ -79,11 +79,10 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
u64 formats = 0;
unsigned int rates = 0;
struct transfer_info v;
- int result = 0;
int bus_factor = 0, sysclock_factor = 0;
int found_this;
- mutex_lock(&i2sdev->lock);
+ guard(mutex)(&i2sdev->lock);
get_pcm_info(i2sdev, in, &pi, &other);
@@ -92,8 +91,7 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
if (pi->active) {
/* alsa messed up */
- result = -EBUSY;
- goto out_unlock;
+ return -EBUSY;
}
/* we now need to assign the hw */
@@ -117,10 +115,8 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
ti++;
}
}
- if (!masks_inited || !bus_factor || !sysclock_factor) {
- result = -ENODEV;
- goto out_unlock;
- }
+ if (!masks_inited || !bus_factor || !sysclock_factor)
+ return -ENODEV;
/* bus dependent stuff */
hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME |
@@ -194,15 +190,12 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
hw->periods_max = MAX_DBDMA_COMMANDS;
err = snd_pcm_hw_constraint_integer(pi->substream->runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- result = err;
- goto out_unlock;
- }
+ if (err < 0)
+ return err;
list_for_each_entry(cii, &sdev->codec_list, list) {
if (cii->codec->open) {
err = cii->codec->open(cii, pi->substream);
if (err) {
- result = err;
/* unwind */
found_this = 0;
list_for_each_entry_reverse(rev,
@@ -214,14 +207,12 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
if (rev == cii)
found_this = 1;
}
- goto out_unlock;
+ return err;
}
}
}
- out_unlock:
- mutex_unlock(&i2sdev->lock);
- return result;
+ return 0;
}
#undef CHECK_RATE
@@ -232,7 +223,7 @@ static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
struct pcm_info *pi;
int err = 0, tmp;
- mutex_lock(&i2sdev->lock);
+ guard(mutex)(&i2sdev->lock);
get_pcm_info(i2sdev, in, &pi, NULL);
@@ -246,7 +237,6 @@ static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
pi->substream = NULL;
pi->active = 0;
- mutex_unlock(&i2sdev->lock);
return err;
}
@@ -330,33 +320,26 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
int input_16bit;
struct pcm_info *pi, *other;
int cnt;
- int result = 0;
unsigned int cmd, stopaddr;
- mutex_lock(&i2sdev->lock);
+ guard(mutex)(&i2sdev->lock);
get_pcm_info(i2sdev, in, &pi, &other);
- if (pi->dbdma_ring.running) {
- result = -EBUSY;
- goto out_unlock;
- }
+ if (pi->dbdma_ring.running)
+ return -EBUSY;
if (pi->dbdma_ring.stopping)
i2sbus_wait_for_stop(i2sdev, pi);
- if (!pi->substream || !pi->substream->runtime) {
- result = -EINVAL;
- goto out_unlock;
- }
+ if (!pi->substream || !pi->substream->runtime)
+ return -EINVAL;
runtime = pi->substream->runtime;
pi->active = 1;
if (other->active &&
((i2sdev->format != runtime->format)
- || (i2sdev->rate != runtime->rate))) {
- result = -EINVAL;
- goto out_unlock;
- }
+ || (i2sdev->rate != runtime->rate)))
+ return -EINVAL;
i2sdev->format = runtime->format;
i2sdev->rate = runtime->rate;
@@ -412,10 +395,8 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
bi.bus_factor = cii->codec->bus_factor;
break;
}
- if (!bi.bus_factor) {
- result = -ENODEV;
- goto out_unlock;
- }
+ if (!bi.bus_factor)
+ return -ENODEV;
input_16bit = 1;
break;
case SNDRV_PCM_FORMAT_S32_BE:
@@ -426,8 +407,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
input_16bit = 0;
break;
default:
- result = -EINVAL;
- goto out_unlock;
+ return -EINVAL;
}
/* we assume all sysclocks are the same! */
list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
@@ -438,10 +418,8 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
if (clock_and_divisors(bi.sysclock_factor,
bi.bus_factor,
runtime->rate,
- &sfr) < 0) {
- result = -EINVAL;
- goto out_unlock;
- }
+ &sfr) < 0)
+ return -EINVAL;
switch (bi.bus_factor) {
case 32:
sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
@@ -457,10 +435,8 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
int err = 0;
if (cii->codec->prepare)
err = cii->codec->prepare(cii, &bi, pi->substream);
- if (err) {
- result = err;
- goto out_unlock;
- }
+ if (err)
+ return err;
}
/* codecs are fine with it, so set our clocks */
if (input_16bit)
@@ -476,7 +452,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
/* not locking these is fine since we touch them only in this function */
if (in_le32(&i2sdev->intfregs->serial_format) == sfr
&& in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
- goto out_unlock;
+ return 0;
/* let's notify the codecs about clocks going away.
* For now we only do mastering on the i2s cell... */
@@ -514,9 +490,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
if (cii->codec->switch_clock)
cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
- out_unlock:
- mutex_unlock(&i2sdev->lock);
- return result;
+ return 0;
}
#ifdef CONFIG_PM
@@ -531,20 +505,16 @@ static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
{
struct codec_info_item *cii;
struct pcm_info *pi;
- int result = 0;
- unsigned long flags;
- spin_lock_irqsave(&i2sdev->low_lock, flags);
+ guard(spinlock_irqsave)(&i2sdev->low_lock);
get_pcm_info(i2sdev, in, &pi, NULL);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
- if (pi->dbdma_ring.running) {
- result = -EALREADY;
- goto out_unlock;
- }
+ if (pi->dbdma_ring.running)
+ return -EALREADY;
list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
if (cii->codec->start)
cii->codec->start(cii, pi->substream);
@@ -558,7 +528,7 @@ static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
udelay(10);
if (in_le32(&pi->dbdma->status) & ACTIVE) {
pi->dbdma_ring.stopping = 0;
- goto out_unlock; /* keep running */
+ return 0; /* keep running */
}
}
}
@@ -584,10 +554,8 @@ static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
- if (!pi->dbdma_ring.running) {
- result = -EALREADY;
- goto out_unlock;
- }
+ if (!pi->dbdma_ring.running)
+ return -EALREADY;
pi->dbdma_ring.running = 0;
/* Set the S0 bit to make the DMA branch to the stop cmd */
@@ -599,13 +567,10 @@ static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
cii->codec->stop(cii, pi->substream);
break;
default:
- result = -EINVAL;
- goto out_unlock;
+ return -EINVAL;
}
- out_unlock:
- spin_unlock_irqrestore(&i2sdev->low_lock, flags);
- return result;
+ return 0;
}
static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
@@ -632,70 +597,67 @@ static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
int dma_stopped = 0;
struct snd_pcm_runtime *runtime;
- spin_lock(&i2sdev->low_lock);
- get_pcm_info(i2sdev, in, &pi, NULL);
- if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
- goto out_unlock;
+ scoped_guard(spinlock, &i2sdev->low_lock) {
+ get_pcm_info(i2sdev, in, &pi, NULL);
+ if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
+ return;
+
+ i = pi->current_period;
+ runtime = pi->substream->runtime;
+ while (pi->dbdma_ring.cmds[i].xfer_status) {
+ if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
+ /*
+ * BT is the branch taken bit. If it took a branch
+ * it is because we set the S0 bit to make it
+ * branch to the stop command.
+ */
+ dma_stopped = 1;
+ pi->dbdma_ring.cmds[i].xfer_status = 0;
+
+ if (++i >= runtime->periods) {
+ i = 0;
+ pi->frame_count += runtime->buffer_size;
+ }
+ pi->current_period = i;
- i = pi->current_period;
- runtime = pi->substream->runtime;
- while (pi->dbdma_ring.cmds[i].xfer_status) {
- if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
/*
- * BT is the branch taken bit. If it took a branch
- * it is because we set the S0 bit to make it
- * branch to the stop command.
+ * Check the frame count. The DMA tends to get a bit
+ * ahead of the frame counter, which confuses the core.
*/
- dma_stopped = 1;
- pi->dbdma_ring.cmds[i].xfer_status = 0;
-
- if (++i >= runtime->periods) {
- i = 0;
- pi->frame_count += runtime->buffer_size;
+ fc = in_le32(&i2sdev->intfregs->frame_count);
+ nframes = i * runtime->period_size;
+ if (fc < pi->frame_count + nframes)
+ pi->frame_count = fc - nframes;
}
- pi->current_period = i;
-
- /*
- * Check the frame count. The DMA tends to get a bit
- * ahead of the frame counter, which confuses the core.
- */
- fc = in_le32(&i2sdev->intfregs->frame_count);
- nframes = i * runtime->period_size;
- if (fc < pi->frame_count + nframes)
- pi->frame_count = fc - nframes;
- }
- if (dma_stopped) {
- timeout = 1000;
- for (;;) {
- status = in_le32(&pi->dbdma->status);
- if (!(status & ACTIVE) && (!in || (status & 0x80)))
- break;
- if (--timeout <= 0) {
- printk(KERN_ERR "i2sbus: timed out "
- "waiting for DMA to stop!\n");
- break;
+ if (dma_stopped) {
+ timeout = 1000;
+ for (;;) {
+ status = in_le32(&pi->dbdma->status);
+ if (!(status & ACTIVE) && (!in || (status & 0x80)))
+ break;
+ if (--timeout <= 0) {
+ printk(KERN_ERR
+ "i2sbus: timed out waiting for DMA to stop!\n");
+ break;
+ }
+ udelay(1);
}
- udelay(1);
- }
- /* Turn off DMA controller, clear S0 bit */
- out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
+ /* Turn off DMA controller, clear S0 bit */
+ out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
- pi->dbdma_ring.stopping = 0;
- if (pi->stop_completion)
- complete(pi->stop_completion);
+ pi->dbdma_ring.stopping = 0;
+ if (pi->stop_completion)
+ complete(pi->stop_completion);
+ }
+
+ if (!pi->dbdma_ring.running)
+ return;
}
- if (!pi->dbdma_ring.running)
- goto out_unlock;
- spin_unlock(&i2sdev->low_lock);
/* may call _trigger again, hence needs to be unlocked */
snd_pcm_period_elapsed(pi->substream);
- return;
-
- out_unlock:
- spin_unlock(&i2sdev->low_lock);
}
irqreturn_t i2sbus_tx_intr(int irq, void *devid)
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 243965615ef2..5548ed8e6b1c 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -73,7 +73,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
if (ac97->num >= 4)
return;
- mutex_lock(&aaci->ac97_sem);
+ guard(mutex)(&aaci->ac97_sem);
aaci_ac97_select_codec(aaci, ac97);
@@ -97,8 +97,6 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
if (v & (SLFR_1TXB|SLFR_2TXB))
dev_err(&aaci->dev->dev,
"timeout waiting for write to complete\n");
-
- mutex_unlock(&aaci->ac97_sem);
}
/*
@@ -113,7 +111,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
if (ac97->num >= 4)
return ~0;
- mutex_lock(&aaci->ac97_sem);
+ guard(mutex)(&aaci->ac97_sem);
aaci_ac97_select_codec(aaci, ac97);
@@ -134,8 +132,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
if (v & SLFR_1TXB) {
dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
- v = ~0;
- goto out;
+ return ~0;
}
/* Now wait for the response frame */
@@ -151,8 +148,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
if (v != (SLFR_1RXV|SLFR_2RXV)) {
dev_err(&aaci->dev->dev, "timeout on RX valid\n");
- v = ~0;
- goto out;
+ return ~0;
}
do {
@@ -171,8 +167,6 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
v = ~0;
}
} while (retries);
- out:
- mutex_unlock(&aaci->ac97_sem);
return v;
}
@@ -216,45 +210,43 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
return;
}
- spin_lock(&aacirun->lock);
-
- ptr = aacirun->ptr;
- do {
- unsigned int len = aacirun->fifo_bytes;
- u32 val;
-
- if (aacirun->bytes <= 0) {
- aacirun->bytes += aacirun->period;
- period_elapsed = true;
- }
- if (!(aacirun->cr & CR_EN))
- break;
-
- val = readl(aacirun->base + AACI_SR);
- if (!(val & SR_RXHF))
- break;
- if (!(val & SR_RXFF))
- len >>= 1;
-
- aacirun->bytes -= len;
-
- /* reading 16 bytes at a time */
- for( ; len > 0; len -= 16) {
- asm(
- "ldmia %1, {r0, r1, r2, r3}\n\t"
- "stmia %0!, {r0, r1, r2, r3}"
- : "+r" (ptr)
- : "r" (aacirun->fifo)
- : "r0", "r1", "r2", "r3", "cc");
-
- if (ptr >= aacirun->end)
- ptr = aacirun->start;
- }
- } while(1);
-
- aacirun->ptr = ptr;
-
- spin_unlock(&aacirun->lock);
+ scoped_guard(spinlock, &aacirun->lock) {
+ ptr = aacirun->ptr;
+ do {
+ unsigned int len = aacirun->fifo_bytes;
+ u32 val;
+
+ if (aacirun->bytes <= 0) {
+ aacirun->bytes += aacirun->period;
+ period_elapsed = true;
+ }
+ if (!(aacirun->cr & CR_EN))
+ break;
+
+ val = readl(aacirun->base + AACI_SR);
+ if (!(val & SR_RXHF))
+ break;
+ if (!(val & SR_RXFF))
+ len >>= 1;
+
+ aacirun->bytes -= len;
+
+ /* reading 16 bytes at a time */
+ for( ; len > 0; len -= 16) {
+ asm(
+ "ldmia %1, {r0, r1, r2, r3}\n\t"
+ "stmia %0!, {r0, r1, r2, r3}"
+ : "+r" (ptr)
+ : "r" (aacirun->fifo)
+ : "r0", "r1", "r2", "r3", "cc");
+
+ if (ptr >= aacirun->end)
+ ptr = aacirun->start;
+ }
+ } while(1);
+
+ aacirun->ptr = ptr;
+ }
if (period_elapsed)
snd_pcm_period_elapsed(aacirun->substream);
@@ -276,45 +268,43 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
return;
}
- spin_lock(&aacirun->lock);
-
- ptr = aacirun->ptr;
- do {
- unsigned int len = aacirun->fifo_bytes;
- u32 val;
-
- if (aacirun->bytes <= 0) {
- aacirun->bytes += aacirun->period;
- period_elapsed = true;
- }
- if (!(aacirun->cr & CR_EN))
- break;
-
- val = readl(aacirun->base + AACI_SR);
- if (!(val & SR_TXHE))
- break;
- if (!(val & SR_TXFE))
- len >>= 1;
-
- aacirun->bytes -= len;
-
- /* writing 16 bytes at a time */
- for ( ; len > 0; len -= 16) {
- asm(
- "ldmia %0!, {r0, r1, r2, r3}\n\t"
- "stmia %1, {r0, r1, r2, r3}"
- : "+r" (ptr)
- : "r" (aacirun->fifo)
- : "r0", "r1", "r2", "r3", "cc");
-
- if (ptr >= aacirun->end)
- ptr = aacirun->start;
- }
- } while (1);
-
- aacirun->ptr = ptr;
-
- spin_unlock(&aacirun->lock);
+ scoped_guard(spinlock, &aacirun->lock) {
+ ptr = aacirun->ptr;
+ do {
+ unsigned int len = aacirun->fifo_bytes;
+ u32 val;
+
+ if (aacirun->bytes <= 0) {
+ aacirun->bytes += aacirun->period;
+ period_elapsed = true;
+ }
+ if (!(aacirun->cr & CR_EN))
+ break;
+
+ val = readl(aacirun->base + AACI_SR);
+ if (!(val & SR_TXHE))
+ break;
+ if (!(val & SR_TXFE))
+ len >>= 1;
+
+ aacirun->bytes -= len;
+
+ /* writing 16 bytes at a time */
+ for ( ; len > 0; len -= 16) {
+ asm(
+ "ldmia %0!, {r0, r1, r2, r3}\n\t"
+ "stmia %1, {r0, r1, r2, r3}"
+ : "+r" (ptr)
+ : "r" (aacirun->fifo)
+ : "r0", "r1", "r2", "r3", "cc");
+
+ if (ptr >= aacirun->end)
+ ptr = aacirun->start;
+ }
+ } while (1);
+
+ aacirun->ptr = ptr;
+ }
if (period_elapsed)
snd_pcm_period_elapsed(aacirun->substream);
@@ -437,14 +427,13 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream)
*/
runtime->hw.fifo_size = aaci->fifo_depth * 2;
- mutex_lock(&aaci->irq_lock);
+ guard(mutex)(&aaci->irq_lock);
if (!aaci->users++) {
ret = request_irq(aaci->dev->irq[0], aaci_irq,
IRQF_SHARED, DRIVER_NAME, aaci);
if (ret != 0)
aaci->users--;
}
- mutex_unlock(&aaci->irq_lock);
return ret;
}
@@ -462,10 +451,9 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream)
aacirun->substream = NULL;
- mutex_lock(&aaci->irq_lock);
+ guard(mutex)(&aaci->irq_lock);
if (!--aaci->users)
free_irq(aaci->dev->irq[0], aaci);
- mutex_unlock(&aaci->irq_lock);
return 0;
}
@@ -585,10 +573,8 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct aaci_runtime *aacirun = substream->runtime->private_data;
- unsigned long flags;
- int ret = 0;
- spin_lock_irqsave(&aacirun->lock, flags);
+ guard(spinlock_irqsave)(&aacirun->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -614,12 +600,10 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
break;
default:
- ret = -EINVAL;
+ return -EINVAL;
}
- spin_unlock_irqrestore(&aacirun->lock, flags);
-
- return ret;
+ return 0;
}
static const struct snd_pcm_ops aaci_playback_ops = {
@@ -669,10 +653,8 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct aaci_runtime *aacirun = substream->runtime->private_data;
- unsigned long flags;
- int ret = 0;
- spin_lock_irqsave(&aacirun->lock, flags);
+ guard(spinlock_irqsave)(&aacirun->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -698,12 +680,10 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd
break;
default:
- ret = -EINVAL;
+ return -EINVAL;
}
- spin_unlock_irqrestore(&aacirun->lock, flags);
-
- return ret;
+ return 0;
}
static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream)
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index a03a3291de84..64510318091f 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -51,7 +51,7 @@ int pxa2xx_ac97_read(int slot, unsigned short reg)
if (slot > 0)
return -ENODEV;
- mutex_lock(&car_mutex);
+ guard(mutex)(&car_mutex);
/* set up primary or secondary codec space */
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
@@ -67,13 +67,12 @@ int pxa2xx_ac97_read(int slot, unsigned short reg)
gsr_bits = 0;
val = (readl(reg_addr) & 0xffff);
if (reg == AC97_GPIO_STATUS)
- goto out;
+ return val;
if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 &&
!((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) {
printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
__func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
- val = -ETIMEDOUT;
- goto out;
+ return -ETIMEDOUT;
}
/* valid data now */
@@ -82,8 +81,6 @@ int pxa2xx_ac97_read(int slot, unsigned short reg)
val = (readl(reg_addr) & 0xffff);
/* but we've just started another cycle... */
wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1);
-
-out: mutex_unlock(&car_mutex);
return val;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
@@ -93,7 +90,7 @@ int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
u32 __iomem *reg_addr;
int ret = 0;
- mutex_lock(&car_mutex);
+ guard(mutex)(&car_mutex);
/* set up primary or secondary codec space */
if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
@@ -114,7 +111,6 @@ int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
ret = -EIO;
}
- mutex_unlock(&car_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 693d48f08b88..df0a049192de 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -88,7 +88,7 @@ static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->opened++;
runtime->hw = atmel_ac97c_hw;
if (chip->cur_rate) {
@@ -97,7 +97,6 @@ static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
}
if (chip->cur_format)
runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
- mutex_unlock(&opened_mutex);
chip->playback_substream = substream;
return 0;
}
@@ -107,7 +106,7 @@ static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->opened++;
runtime->hw = atmel_ac97c_hw;
if (chip->cur_rate) {
@@ -116,7 +115,6 @@ static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
}
if (chip->cur_format)
runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
- mutex_unlock(&opened_mutex);
chip->capture_substream = substream;
return 0;
}
@@ -125,13 +123,12 @@ static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->opened--;
if (!chip->opened) {
chip->cur_rate = 0;
chip->cur_format = 0;
}
- mutex_unlock(&opened_mutex);
chip->playback_substream = NULL;
@@ -142,13 +139,12 @@ static int atmel_ac97c_capture_close(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->opened--;
if (!chip->opened) {
chip->cur_rate = 0;
chip->cur_format = 0;
}
- mutex_unlock(&opened_mutex);
chip->capture_substream = NULL;
@@ -161,10 +157,9 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
/* Set restrictions to params. */
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->cur_rate = params_rate(hw_params);
chip->cur_format = params_format(hw_params);
- mutex_unlock(&opened_mutex);
return 0;
}
@@ -175,10 +170,9 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
/* Set restrictions to params. */
- mutex_lock(&opened_mutex);
+ guard(mutex)(&opened_mutex);
chip->cur_rate = params_rate(hw_params);
chip->cur_format = params_format(hw_params);
- mutex_unlock(&opened_mutex);
return 0;
}
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index a66f258cafaa..da514fef45bc 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -176,14 +176,25 @@ static int snd_compr_free(struct inode *inode, struct file *f)
return 0;
}
+static void
+snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tstamp32,
+ const struct snd_compr_tstamp64 *tstamp64)
+{
+ tstamp32->byte_offset = tstamp64->byte_offset;
+ tstamp32->copied_total = (u32)tstamp64->copied_total;
+ tstamp32->pcm_frames = (u32)tstamp64->pcm_frames;
+ tstamp32->pcm_io_frames = (u32)tstamp64->pcm_io_frames;
+ tstamp32->sampling_rate = tstamp64->sampling_rate;
+}
+
static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
if (!stream->ops->pointer)
return -ENOTSUPP;
stream->ops->pointer(stream, tstamp);
- pr_debug("dsp consumed till %d total %d bytes\n",
- tstamp->byte_offset, tstamp->copied_total);
+ pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset,
+ tstamp->copied_total);
if (stream->direction == SND_COMPRESS_PLAYBACK)
stream->runtime->total_bytes_transferred = tstamp->copied_total;
else
@@ -192,7 +203,7 @@ static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
}
static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
- struct snd_compr_avail *avail)
+ struct snd_compr_avail64 *avail)
{
memset(avail, 0, sizeof(*avail));
snd_compr_update_tstamp(stream, &avail->tstamp);
@@ -204,9 +215,9 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
pr_debug("detected init and someone forgot to do a write\n");
return stream->runtime->buffer_size;
}
- pr_debug("app wrote %lld, DSP consumed %lld\n",
- stream->runtime->total_bytes_available,
- stream->runtime->total_bytes_transferred);
+ pr_debug("app wrote %llu, DSP consumed %llu\n",
+ stream->runtime->total_bytes_available,
+ stream->runtime->total_bytes_transferred);
if (stream->runtime->total_bytes_available ==
stream->runtime->total_bytes_transferred) {
if (stream->direction == SND_COMPRESS_PLAYBACK) {
@@ -223,28 +234,43 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
if (stream->direction == SND_COMPRESS_PLAYBACK)
avail->avail = stream->runtime->buffer_size - avail->avail;
- pr_debug("ret avail as %lld\n", avail->avail);
+ pr_debug("ret avail as %zu\n", (size_t)avail->avail);
return avail->avail;
}
static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
{
- struct snd_compr_avail avail;
+ struct snd_compr_avail64 avail;
return snd_compr_calc_avail(stream, &avail);
}
-static int
-snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
+static void snd_compr_avail32_from_64(struct snd_compr_avail *avail32,
+ const struct snd_compr_avail64 *avail64)
{
- struct snd_compr_avail ioctl_avail;
+ avail32->avail = avail64->avail;
+ snd_compr_tstamp32_from_64(&avail32->tstamp, &avail64->tstamp);
+}
+
+static int snd_compr_ioctl_avail(struct snd_compr_stream *stream,
+ unsigned long arg, bool is_32bit)
+{
+ struct snd_compr_avail64 ioctl_avail64;
+ struct snd_compr_avail ioctl_avail32;
size_t avail;
+ const void *copy_from = &ioctl_avail64;
+ size_t copy_size = sizeof(ioctl_avail64);
if (stream->direction == SND_COMPRESS_ACCEL)
return -EBADFD;
- avail = snd_compr_calc_avail(stream, &ioctl_avail);
- ioctl_avail.avail = avail;
+ avail = snd_compr_calc_avail(stream, &ioctl_avail64);
+ ioctl_avail64.avail = avail;
+ if (is_32bit) {
+ snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64);
+ copy_from = &ioctl_avail32;
+ copy_size = sizeof(ioctl_avail32);
+ }
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN:
@@ -255,8 +281,7 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
break;
}
- if (copy_to_user((__u64 __user *)arg,
- &ioctl_avail, sizeof(ioctl_avail)))
+ if (copy_to_user((__u64 __user *)arg, copy_from, copy_size))
return -EFAULT;
return 0;
}
@@ -274,8 +299,7 @@ static int snd_compr_write_data(struct snd_compr_stream *stream,
(app_pointer * runtime->buffer_size);
dstn = runtime->buffer + app_pointer;
- pr_debug("copying %ld at %lld\n",
- (unsigned long)count, app_pointer);
+ pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer);
if (count < runtime->buffer_size - app_pointer) {
if (copy_from_user(dstn, buf, count))
return -EFAULT;
@@ -318,7 +342,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
}
avail = snd_compr_get_avail(stream);
- pr_debug("avail returned %ld\n", (unsigned long)avail);
+ pr_debug("avail returned %lu\n", (unsigned long)avail);
/* calculate how much we can write to buffer */
if (avail > count)
avail = count;
@@ -374,7 +398,7 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
}
avail = snd_compr_get_avail(stream);
- pr_debug("avail returned %ld\n", (unsigned long)avail);
+ pr_debug("avail returned %lu\n", (unsigned long)avail);
/* calculate how much we can read from buffer */
if (avail > count)
avail = count;
@@ -443,7 +467,7 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
#endif
avail = snd_compr_get_avail(stream);
- pr_debug("avail is %ld\n", (unsigned long)avail);
+ pr_debug("avail is %lu\n", (unsigned long)avail);
/* check if we have at least one fragment to fill */
switch (runtime->state) {
case SNDRV_PCM_STATE_DRAINING:
@@ -723,16 +747,26 @@ snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg)
return retval;
}
-static inline int
-snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
+static inline int snd_compr_tstamp(struct snd_compr_stream *stream,
+ unsigned long arg, bool is_32bit)
{
- struct snd_compr_tstamp tstamp = {0};
+ struct snd_compr_tstamp64 tstamp64 = { 0 };
+ struct snd_compr_tstamp tstamp32 = { 0 };
+ const void *copy_from = &tstamp64;
+ size_t copy_size = sizeof(tstamp64);
int ret;
- ret = snd_compr_update_tstamp(stream, &tstamp);
- if (ret == 0)
- ret = copy_to_user((struct snd_compr_tstamp __user *)arg,
- &tstamp, sizeof(tstamp)) ? -EFAULT : 0;
+ ret = snd_compr_update_tstamp(stream, &tstamp64);
+ if (ret == 0) {
+ if (is_32bit) {
+ snd_compr_tstamp32_from_64(&tstamp32, &tstamp64);
+ copy_from = &tstamp32;
+ copy_size = sizeof(tstamp32);
+ }
+ ret = copy_to_user((void __user *)arg, copy_from, copy_size) ?
+ -EFAULT :
+ 0;
+ }
return ret;
}
@@ -1309,9 +1343,13 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
switch (cmd) {
case SNDRV_COMPRESS_TSTAMP:
- return snd_compr_tstamp(stream, arg);
+ return snd_compr_tstamp(stream, arg, true);
+ case SNDRV_COMPRESS_TSTAMP64:
+ return snd_compr_tstamp(stream, arg, false);
case SNDRV_COMPRESS_AVAIL:
- return snd_compr_ioctl_avail(stream, arg);
+ return snd_compr_ioctl_avail(stream, arg, true);
+ case SNDRV_COMPRESS_AVAIL64:
+ return snd_compr_ioctl_avail(stream, arg, false);
case SNDRV_COMPRESS_PAUSE:
return snd_compr_pause(stream);
case SNDRV_COMPRESS_RESUME:
diff --git a/sound/core/misc.c b/sound/core/misc.c
index c2fda3bd90a0..88d9e1f9a6e9 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -127,35 +127,30 @@ int snd_fasync_helper(int fd, struct file *file, int on,
INIT_LIST_HEAD(&fasync->list);
}
- spin_lock_irq(&snd_fasync_lock);
- if (*fasyncp) {
- kfree(fasync);
- fasync = *fasyncp;
- } else {
- if (!fasync) {
- spin_unlock_irq(&snd_fasync_lock);
- return 0;
+ scoped_guard(spinlock_irq, &snd_fasync_lock) {
+ if (*fasyncp) {
+ kfree(fasync);
+ fasync = *fasyncp;
+ } else {
+ if (!fasync)
+ return 0;
+ *fasyncp = fasync;
}
- *fasyncp = fasync;
+ fasync->on = on;
}
- fasync->on = on;
- spin_unlock_irq(&snd_fasync_lock);
return fasync_helper(fd, file, on, &fasync->fasync);
}
EXPORT_SYMBOL_GPL(snd_fasync_helper);
void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
{
- unsigned long flags;
-
if (!fasync || !fasync->on)
return;
- spin_lock_irqsave(&snd_fasync_lock, flags);
+ guard(spinlock_irqsave)(&snd_fasync_lock);
fasync->signal = signal;
fasync->poll = poll;
list_move(&fasync->list, &snd_fasync_list);
schedule_work(&snd_fasync_work);
- spin_unlock_irqrestore(&snd_fasync_lock, flags);
}
EXPORT_SYMBOL_GPL(snd_kill_fasync);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 4ecb17bd5436..a82dd155e1d3 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2002,9 +2002,8 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig
static int snd_pcm_oss_nonblock(struct file * file)
{
- spin_lock(&file->f_lock);
+ guard(spinlock)(&file->f_lock);
file->f_flags |= O_NONBLOCK;
- spin_unlock(&file->f_lock);
return 0;
}
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 72040964b6fd..f0c17503df42 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -111,6 +111,7 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
slave_config->dst_addr = dma_data->addr;
slave_config->dst_maxburst = dma_data->maxburst;
+ slave_config->dst_port_window_size = dma_data->port_window_size;
if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
slave_config->dst_addr_width =
DMA_SLAVE_BUSWIDTH_UNDEFINED;
@@ -119,6 +120,7 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
} else {
slave_config->src_addr = dma_data->addr;
slave_config->src_maxburst = dma_data->maxburst;
+ slave_config->src_port_window_size = dma_data->port_window_size;
if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
slave_config->src_addr_width =
DMA_SLAVE_BUSWIDTH_UNDEFINED;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1eab940fa2e5..68bee40c9ada 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -84,19 +84,24 @@ void snd_pcm_group_init(struct snd_pcm_group *group)
}
/* define group lock helpers */
-#define DEFINE_PCM_GROUP_LOCK(action, mutex_action) \
+#define DEFINE_PCM_GROUP_LOCK(action, bh_lock, bh_unlock, mutex_action) \
static void snd_pcm_group_ ## action(struct snd_pcm_group *group, bool nonatomic) \
{ \
- if (nonatomic) \
+ if (nonatomic) { \
mutex_ ## mutex_action(&group->mutex); \
- else \
- spin_ ## action(&group->lock); \
-}
-
-DEFINE_PCM_GROUP_LOCK(lock, lock);
-DEFINE_PCM_GROUP_LOCK(unlock, unlock);
-DEFINE_PCM_GROUP_LOCK(lock_irq, lock);
-DEFINE_PCM_GROUP_LOCK(unlock_irq, unlock);
+ } else { \
+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && bh_lock) \
+ local_bh_disable(); \
+ spin_ ## action(&group->lock); \
+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && bh_unlock) \
+ local_bh_enable(); \
+ } \
+}
+
+DEFINE_PCM_GROUP_LOCK(lock, false, false, lock);
+DEFINE_PCM_GROUP_LOCK(unlock, false, false, unlock);
+DEFINE_PCM_GROUP_LOCK(lock_irq, true, false, lock);
+DEFINE_PCM_GROUP_LOCK(unlock_irq, false, true, unlock);
/**
* snd_pcm_stream_lock - Lock the PCM stream
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 77c1214acd90..02d30d8b6c3a 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -117,18 +117,15 @@ static DEFINE_MUTEX(register_mutex);
static int
odev_open(struct inode *inode, struct file *file)
{
- int level, rc;
+ int level;
if (iminor(inode) == SNDRV_MINOR_OSS_MUSIC)
level = SNDRV_SEQ_OSS_MODE_MUSIC;
else
level = SNDRV_SEQ_OSS_MODE_SYNTH;
- mutex_lock(&register_mutex);
- rc = snd_seq_oss_open(file, level);
- mutex_unlock(&register_mutex);
-
- return rc;
+ guard(mutex)(&register_mutex);
+ return snd_seq_oss_open(file, level);
}
static int
@@ -140,10 +137,8 @@ odev_release(struct inode *inode, struct file *file)
if (!dp)
return 0;
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
snd_seq_oss_release(dp);
- mutex_unlock(&register_mutex);
-
return 0;
}
@@ -229,13 +224,12 @@ register_device(void)
{
int rc;
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
NULL, 0,
&seq_oss_f_ops, NULL);
if (rc < 0) {
pr_err("ALSA: seq_oss: can't register device seq\n");
- mutex_unlock(&register_mutex);
return rc;
}
rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
@@ -244,22 +238,19 @@ register_device(void)
if (rc < 0) {
pr_err("ALSA: seq_oss: can't register device music\n");
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
- mutex_unlock(&register_mutex);
return rc;
}
- mutex_unlock(&register_mutex);
return 0;
}
static void
unregister_device(void)
{
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)
pr_err("ALSA: seq_oss: error unregister device music\n");
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
pr_err("ALSA: seq_oss: error unregister device seq\n");
- mutex_unlock(&register_mutex);
}
/*
@@ -273,12 +264,11 @@ static struct snd_info_entry *info_entry;
static void
info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
{
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
snd_seq_oss_system_info_read(buf);
snd_seq_oss_synth_info_read(buf);
snd_seq_oss_midi_info_read(buf);
- mutex_unlock(&register_mutex);
}
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index 6163a00bc8de..935cf3df0b30 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -137,12 +137,7 @@ snd_seq_oss_dispatch(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int a
static inline int
snd_seq_oss_control(struct seq_oss_devinfo *dp, unsigned int type, void *arg)
{
- int err;
-
- snd_seq_client_ioctl_lock(dp->cseq);
- err = snd_seq_kernel_client_ctl(dp->cseq, type, arg);
- snd_seq_client_ioctl_unlock(dp->cseq);
- return err;
+ return snd_seq_kernel_client_ioctl(dp->cseq, type, arg);
}
/* fill the addresses in header */
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index f8e247d9e5c9..023e5d0a4351 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -40,6 +40,7 @@ struct seq_oss_midi {
struct mutex open_mutex;
};
+DEFINE_FREE(seq_oss_midi, struct seq_oss_midi *, if (!IS_ERR_OR_NULL(_T)) snd_use_lock_free(&(_T)->use_lock))
/*
* midi device table
@@ -90,13 +91,11 @@ static struct seq_oss_midi *
get_mdev(int dev)
{
struct seq_oss_midi *mdev;
- unsigned long flags;
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
mdev = midi_devs[dev];
if (mdev)
snd_use_lock_use(&mdev->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
return mdev;
}
@@ -108,19 +107,16 @@ find_slot(int client, int port)
{
int i;
struct seq_oss_midi *mdev;
- unsigned long flags;
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
for (i = 0; i < max_midi_devs; i++) {
mdev = midi_devs[i];
if (mdev && mdev->client == client && mdev->port == port) {
/* found! */
snd_use_lock_use(&mdev->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
return mdev;
}
}
- spin_unlock_irqrestore(&register_lock, flags);
return NULL;
}
@@ -135,7 +131,6 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
{
int i;
struct seq_oss_midi *mdev;
- unsigned long flags;
/* the port must include generic midi */
if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
@@ -185,14 +180,13 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
/*
* look for en empty slot
*/
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
for (i = 0; i < max_midi_devs; i++) {
if (midi_devs[i] == NULL)
break;
}
if (i >= max_midi_devs) {
if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
- spin_unlock_irqrestore(&register_lock, flags);
snd_midi_event_free(mdev->coder);
kfree(mdev);
return -ENOMEM;
@@ -201,7 +195,6 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
}
mdev->seq_device = i;
midi_devs[mdev->seq_device] = mdev;
- spin_unlock_irqrestore(&register_lock, flags);
return 0;
}
@@ -213,26 +206,24 @@ int
snd_seq_oss_midi_check_exit_port(int client, int port)
{
struct seq_oss_midi *mdev;
- unsigned long flags;
int index;
mdev = find_slot(client, port);
if (mdev) {
- spin_lock_irqsave(&register_lock, flags);
- midi_devs[mdev->seq_device] = NULL;
- spin_unlock_irqrestore(&register_lock, flags);
+ scoped_guard(spinlock_irqsave, &register_lock) {
+ midi_devs[mdev->seq_device] = NULL;
+ }
snd_use_lock_free(&mdev->use_lock);
snd_use_lock_sync(&mdev->use_lock);
snd_midi_event_free(mdev->coder);
kfree(mdev);
}
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
for (index = max_midi_devs - 1; index >= 0; index--) {
if (midi_devs[index])
break;
}
max_midi_devs = index + 1;
- spin_unlock_irqrestore(&register_lock, flags);
return 0;
}
@@ -245,9 +236,8 @@ snd_seq_oss_midi_clear_all(void)
{
int i;
struct seq_oss_midi *mdev;
- unsigned long flags;
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
for (i = 0; i < max_midi_devs; i++) {
mdev = midi_devs[i];
if (mdev) {
@@ -257,7 +247,6 @@ snd_seq_oss_midi_clear_all(void)
}
}
max_midi_devs = 0;
- spin_unlock_irqrestore(&register_lock, flags);
}
@@ -267,9 +256,8 @@ snd_seq_oss_midi_clear_all(void)
void
snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp)
{
- spin_lock_irq(&register_lock);
+ guard(spinlock_irq)(&register_lock);
dp->max_mididev = max_midi_devs;
- spin_unlock_irq(&register_lock);
}
/*
@@ -317,20 +305,17 @@ int
snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
{
int perm;
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
struct snd_seq_port_subscribe subs;
- int err;
mdev = get_mididev(dp, dev);
if (!mdev)
return -ENODEV;
- mutex_lock(&mdev->open_mutex);
+ guard(mutex)(&mdev->open_mutex);
/* already used? */
- if (mdev->opened && mdev->devinfo != dp) {
- err = -EBUSY;
- goto unlock;
- }
+ if (mdev->opened && mdev->devinfo != dp)
+ return -EBUSY;
perm = 0;
if (is_write_mode(fmode))
@@ -338,16 +323,12 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
if (is_read_mode(fmode))
perm |= PERM_READ;
perm &= mdev->flags;
- if (perm == 0) {
- err = -ENXIO;
- goto unlock;
- }
+ if (perm == 0)
+ return -ENXIO;
/* already opened? */
- if ((mdev->opened & perm) == perm) {
- err = 0;
- goto unlock;
- }
+ if ((mdev->opened & perm) == perm)
+ return 0;
perm &= ~mdev->opened;
@@ -370,18 +351,11 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
mdev->opened |= PERM_READ;
}
- if (! mdev->opened) {
- err = -ENXIO;
- goto unlock;
- }
+ if (!mdev->opened)
+ return -ENXIO;
mdev->devinfo = dp;
- err = 0;
-
- unlock:
- mutex_unlock(&mdev->open_mutex);
- snd_use_lock_free(&mdev->use_lock);
- return err;
+ return 0;
}
/*
@@ -390,15 +364,15 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
int
snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
struct snd_seq_port_subscribe subs;
mdev = get_mididev(dp, dev);
if (!mdev)
return -ENODEV;
- mutex_lock(&mdev->open_mutex);
+ guard(mutex)(&mdev->open_mutex);
if (!mdev->opened || mdev->devinfo != dp)
- goto unlock;
+ return 0;
memset(&subs, 0, sizeof(subs));
if (mdev->opened & PERM_WRITE) {
@@ -416,10 +390,6 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
mdev->opened = 0;
mdev->devinfo = NULL;
-
- unlock:
- mutex_unlock(&mdev->open_mutex);
- snd_use_lock_free(&mdev->use_lock);
return 0;
}
@@ -429,7 +399,7 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
int
snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
int mode;
mdev = get_mididev(dp, dev);
@@ -442,7 +412,6 @@ snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
if (mdev->opened & PERM_READ)
mode |= SNDRV_SEQ_OSS_FILE_READ;
- snd_use_lock_free(&mdev->use_lock);
return mode;
}
@@ -453,15 +422,13 @@ snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
void
snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
mdev = get_mididev(dp, dev);
if (!mdev)
return;
- if (! mdev->opened) {
- snd_use_lock_free(&mdev->use_lock);
+ if (!mdev->opened)
return;
- }
if (mdev->opened & PERM_WRITE) {
struct snd_seq_event ev;
@@ -492,7 +459,6 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
}
}
// snd_seq_oss_midi_close(dp, dev);
- snd_use_lock_free(&mdev->use_lock);
}
@@ -502,14 +468,13 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
void
snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
mdev = get_mididev(dp, dev);
if (!mdev)
return;
addr->client = mdev->client;
addr->port = mdev->port;
- snd_use_lock_free(&mdev->use_lock);
}
@@ -520,26 +485,20 @@ int
snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
{
struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
- struct seq_oss_midi *mdev;
- int rc;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
if (dp->readq == NULL)
return 0;
mdev = find_slot(ev->source.client, ev->source.port);
if (!mdev)
return 0;
- if (! (mdev->opened & PERM_READ)) {
- snd_use_lock_free(&mdev->use_lock);
+ if (!(mdev->opened & PERM_READ))
return 0;
- }
if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- rc = send_synth_event(dp, ev, mdev->seq_device);
+ return send_synth_event(dp, ev, mdev->seq_device);
else
- rc = send_midi_event(dp, ev, mdev);
-
- snd_use_lock_free(&mdev->use_lock);
- return rc;
+ return send_midi_event(dp, ev, mdev);
}
/*
@@ -636,17 +595,15 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq
int
snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
mdev = get_mididev(dp, dev);
if (!mdev)
return -ENODEV;
if (snd_midi_event_encode_byte(mdev->coder, c, ev)) {
snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);
- snd_use_lock_free(&mdev->use_lock);
return 0;
}
- snd_use_lock_free(&mdev->use_lock);
return -EINVAL;
}
@@ -656,7 +613,7 @@ snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, stru
int
snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf)
{
- struct seq_oss_midi *mdev;
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
mdev = get_mididev(dp, dev);
if (!mdev)
@@ -665,7 +622,6 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info
inf->dev_type = 0; /* FIXME: ?? */
inf->capabilities = 0; /* FIXME: ?? */
strscpy(inf->name, mdev->name, sizeof(inf->name));
- snd_use_lock_free(&mdev->use_lock);
return 0;
}
@@ -692,10 +648,11 @@ void
snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
{
int i;
- struct seq_oss_midi *mdev;
snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);
for (i = 0; i < max_midi_devs; i++) {
+ struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL;
+
snd_iprintf(buf, "\nmidi %d: ", i);
mdev = get_mdev(i);
if (mdev == NULL) {
@@ -707,7 +664,6 @@ snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
snd_iprintf(buf, " capability %s / opened %s\n",
capmode_str(mdev->flags),
capmode_str(mdev->opened));
- snd_use_lock_free(&mdev->use_lock);
}
}
#endif /* CONFIG_SND_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index f0db5d3dcba4..bbaf72e70b35 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -140,13 +140,9 @@ int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
int
snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
{
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
- if (q->qlen >= q->maxlen - 1) {
- spin_unlock_irqrestore(&q->lock, flags);
+ guard(spinlock_irqsave)(&q->lock);
+ if (q->qlen >= q->maxlen - 1)
return -ENOMEM;
- }
memcpy(&q->q[q->tail], ev, sizeof(*ev));
q->tail = (q->tail + 1) % q->maxlen;
@@ -155,8 +151,6 @@ snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
/* wake up sleeper */
wake_up(&q->midi_sleep);
- spin_unlock_irqrestore(&q->lock, flags);
-
return 0;
}
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 9de47e098b29..8c4e5913c7e6 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -44,6 +44,7 @@ struct seq_oss_synth {
snd_use_lock_t use_lock;
};
+DEFINE_FREE(seq_oss_synth, struct seq_oss_synth *, if (!IS_ERR_OR_NULL(_T)) snd_use_lock_free(&(_T)->use_lock))
/*
* device table
@@ -85,7 +86,6 @@ snd_seq_oss_synth_probe(struct device *_dev)
int i;
struct seq_oss_synth *rec;
struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- unsigned long flags;
rec = kzalloc(sizeof(*rec), GFP_KERNEL);
if (!rec)
@@ -103,23 +103,22 @@ snd_seq_oss_synth_probe(struct device *_dev)
strscpy(rec->name, dev->name, sizeof(rec->name));
/* registration */
- spin_lock_irqsave(&register_lock, flags);
- for (i = 0; i < max_synth_devs; i++) {
- if (synth_devs[i] == NULL)
- break;
- }
- if (i >= max_synth_devs) {
- if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
- spin_unlock_irqrestore(&register_lock, flags);
- pr_err("ALSA: seq_oss: no more synth slot\n");
- kfree(rec);
- return -ENOMEM;
+ scoped_guard(spinlock_irqsave, &register_lock) {
+ for (i = 0; i < max_synth_devs; i++) {
+ if (synth_devs[i] == NULL)
+ break;
}
- max_synth_devs++;
+ if (i >= max_synth_devs) {
+ if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
+ pr_err("ALSA: seq_oss: no more synth slot\n");
+ kfree(rec);
+ return -ENOMEM;
+ }
+ max_synth_devs++;
+ }
+ rec->seq_device = i;
+ synth_devs[i] = rec;
}
- rec->seq_device = i;
- synth_devs[i] = rec;
- spin_unlock_irqrestore(&register_lock, flags);
dev->driver_data = rec;
#ifdef SNDRV_OSS_INFO_DEV_SYNTH
if (i < SNDRV_CARDS)
@@ -135,27 +134,25 @@ snd_seq_oss_synth_remove(struct device *_dev)
struct snd_seq_device *dev = to_seq_dev(_dev);
int index;
struct seq_oss_synth *rec = dev->driver_data;
- unsigned long flags;
- spin_lock_irqsave(&register_lock, flags);
- for (index = 0; index < max_synth_devs; index++) {
- if (synth_devs[index] == rec)
- break;
- }
- if (index >= max_synth_devs) {
- spin_unlock_irqrestore(&register_lock, flags);
- pr_err("ALSA: seq_oss: can't unregister synth\n");
- return -EINVAL;
- }
- synth_devs[index] = NULL;
- if (index == max_synth_devs - 1) {
- for (index--; index >= 0; index--) {
- if (synth_devs[index])
+ scoped_guard(spinlock_irqsave, &register_lock) {
+ for (index = 0; index < max_synth_devs; index++) {
+ if (synth_devs[index] == rec)
break;
}
- max_synth_devs = index + 1;
+ if (index >= max_synth_devs) {
+ pr_err("ALSA: seq_oss: can't unregister synth\n");
+ return -EINVAL;
+ }
+ synth_devs[index] = NULL;
+ if (index == max_synth_devs - 1) {
+ for (index--; index >= 0; index--) {
+ if (synth_devs[index])
+ break;
+ }
+ max_synth_devs = index + 1;
+ }
}
- spin_unlock_irqrestore(&register_lock, flags);
#ifdef SNDRV_OSS_INFO_DEV_SYNTH
if (rec->seq_device < SNDRV_CARDS)
snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device);
@@ -174,13 +171,11 @@ static struct seq_oss_synth *
get_sdev(int dev)
{
struct seq_oss_synth *rec;
- unsigned long flags;
- spin_lock_irqsave(&register_lock, flags);
+ guard(spinlock_irqsave)(&register_lock);
rec = synth_devs[dev];
if (rec)
snd_use_lock_use(&rec->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
return rec;
}
@@ -193,20 +188,18 @@ void
snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
{
int i;
- struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info;
dp->max_synthdev = max_synth_devs;
dp->synth_opened = 0;
memset(dp->synths, 0, sizeof(dp->synths));
for (i = 0; i < dp->max_synthdev; i++) {
- rec = get_sdev(i);
+ struct seq_oss_synth *rec __free(seq_oss_synth) = get_sdev(i);
+
if (rec == NULL)
continue;
- if (rec->oper.open == NULL || rec->oper.close == NULL) {
- snd_use_lock_free(&rec->use_lock);
+ if (rec->oper.open == NULL || rec->oper.close == NULL)
continue;
- }
info = &dp->synths[i];
info->arg.app_index = dp->port;
info->arg.file_mode = dp->file_mode;
@@ -216,13 +209,10 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
else
info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
info->opened = 0;
- if (!try_module_get(rec->oper.owner)) {
- snd_use_lock_free(&rec->use_lock);
+ if (!try_module_get(rec->oper.owner))
continue;
- }
if (rec->oper.open(&info->arg, rec->private_data) < 0) {
module_put(rec->oper.owner);
- snd_use_lock_free(&rec->use_lock);
continue;
}
info->nr_voices = rec->nr_voices;
@@ -231,7 +221,6 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
if (!info->ch) {
rec->oper.close(&info->arg);
module_put(rec->oper.owner);
- snd_use_lock_free(&rec->use_lock);
continue;
}
reset_channels(info);
@@ -239,7 +228,6 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
info->opened++;
rec->opened++;
dp->synth_opened++;
- snd_use_lock_free(&rec->use_lock);
}
}
@@ -286,7 +274,6 @@ void
snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
{
int i;
- struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info;
if (snd_BUG_ON(dp->max_synthdev > SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
@@ -301,7 +288,9 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
midi_synth_dev.opened--;
}
} else {
- rec = get_sdev(i);
+ struct seq_oss_synth *rec __free(seq_oss_synth) =
+ get_sdev(i);
+
if (rec == NULL)
continue;
if (rec->opened > 0) {
@@ -309,7 +298,6 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
module_put(rec->oper.owner);
rec->opened = 0;
}
- snd_use_lock_free(&rec->use_lock);
}
kfree(info->ch);
info->ch = NULL;
@@ -380,7 +368,7 @@ reset_channels(struct seq_oss_synthinfo *info)
void
snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
{
- struct seq_oss_synth *rec;
+ struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;
struct seq_oss_synthinfo *info;
info = get_synthinfo_nospec(dp, dev);
@@ -416,7 +404,6 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
ev.type = SNDRV_SEQ_EVENT_RESET;
snd_seq_oss_dispatch(dp, &ev, 0, 0);
}
- snd_use_lock_free(&rec->use_lock);
}
@@ -428,9 +415,8 @@ int
snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
const char __user *buf, int p, int c)
{
- struct seq_oss_synth *rec;
+ struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;
struct seq_oss_synthinfo *info;
- int rc;
info = get_synthinfo_nospec(dp, dev);
if (!info)
@@ -443,11 +429,9 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
return -ENXIO;
if (rec->oper.load_patch == NULL)
- rc = -ENXIO;
+ return -ENXIO;
else
- rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
- snd_use_lock_free(&rec->use_lock);
- return rc;
+ return rec->oper.load_patch(&info->arg, fmt, buf, p, c);
}
/*
@@ -456,13 +440,11 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
struct seq_oss_synthinfo *
snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
{
- struct seq_oss_synth *rec;
+ struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;
rec = get_synthdev(dp, dev);
- if (rec) {
- snd_use_lock_free(&rec->use_lock);
+ if (rec)
return get_synthinfo_nospec(dp, dev);
- }
return NULL;
}
@@ -513,9 +495,8 @@ snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event
int
snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
{
- struct seq_oss_synth *rec;
+ struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;
struct seq_oss_synthinfo *info;
- int rc;
info = get_synthinfo_nospec(dp, dev);
if (!info || info->is_midi)
@@ -524,11 +505,9 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
if (!rec)
return -ENXIO;
if (rec->oper.ioctl == NULL)
- rc = -ENXIO;
+ return -ENXIO;
else
- rc = rec->oper.ioctl(&info->arg, cmd, addr);
- snd_use_lock_free(&rec->use_lock);
- return rc;
+ return rec->oper.ioctl(&info->arg, cmd, addr);
}
@@ -555,7 +534,6 @@ snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *
int
snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf)
{
- struct seq_oss_synth *rec;
struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
if (!info)
@@ -571,7 +549,9 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
inf->device = dev;
strscpy(inf->name, minf.name, sizeof(inf->name));
} else {
- rec = get_synthdev(dp, dev);
+ struct seq_oss_synth *rec __free(seq_oss_synth) =
+ get_synthdev(dp, dev);
+
if (!rec)
return -ENXIO;
inf->synth_type = rec->synth_type;
@@ -579,7 +559,6 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
inf->nr_voices = rec->nr_voices;
inf->device = dev;
strscpy(inf->name, rec->name, sizeof(inf->name));
- snd_use_lock_free(&rec->use_lock);
}
return 0;
}
@@ -593,10 +572,11 @@ void
snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)
{
int i;
- struct seq_oss_synth *rec;
snd_iprintf(buf, "\nNumber of synth devices: %d\n", max_synth_devs);
for (i = 0; i < max_synth_devs; i++) {
+ struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;
+
snd_iprintf(buf, "\nsynth %d: ", i);
rec = get_sdev(i);
if (rec == NULL) {
@@ -610,7 +590,6 @@ snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)
snd_iprintf(buf, " capabilities : ioctl %s / load_patch %s\n",
str_enabled_disabled((long)rec->oper.ioctl),
str_enabled_disabled((long)rec->oper.load_patch));
- snd_use_lock_free(&rec->use_lock);
}
}
#endif /* CONFIG_SND_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 3e3209ce53b1..a93ff8315b8e 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -122,13 +122,10 @@ snd_seq_oss_writeq_sync(struct seq_oss_writeq *q)
void
snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time)
{
- unsigned long flags;
-
- spin_lock_irqsave(&q->sync_lock, flags);
+ guard(spinlock_irqsave)(&q->sync_lock);
q->sync_time = time;
q->sync_event_put = 0;
wake_up(&q->sync_sleep);
- spin_unlock_irqrestore(&q->sync_lock, flags);
}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index aa9c956d2581..f9a6e497f997 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -108,7 +108,6 @@ static struct snd_seq_client *clientptr(int clientid)
static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
{
- unsigned long flags;
struct snd_seq_client *client;
if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
@@ -116,15 +115,13 @@ static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
clientid);
return NULL;
}
- spin_lock_irqsave(&clients_lock, flags);
- client = clientptr(clientid);
- if (client)
- goto __lock;
- if (clienttablock[clientid]) {
- spin_unlock_irqrestore(&clients_lock, flags);
- return NULL;
+ scoped_guard(spinlock_irqsave, &clients_lock) {
+ client = clientptr(clientid);
+ if (client)
+ return snd_seq_client_ref(client);
+ if (clienttablock[clientid])
+ return NULL;
}
- spin_unlock_irqrestore(&clients_lock, flags);
#ifdef CONFIG_MODULES
if (load_module) {
static DECLARE_BITMAP(client_requested, SNDRV_SEQ_GLOBAL_CLIENTS);
@@ -153,19 +150,14 @@ static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
snd_seq_device_load_drivers();
}
}
- spin_lock_irqsave(&clients_lock, flags);
- client = clientptr(clientid);
- if (client)
- goto __lock;
- spin_unlock_irqrestore(&clients_lock, flags);
+ scoped_guard(spinlock_irqsave, &clients_lock) {
+ client = clientptr(clientid);
+ if (client)
+ return snd_seq_client_ref(client);
+ }
}
#endif
return NULL;
-
- __lock:
- snd_use_lock_use(&client->use_lock);
- spin_unlock_irqrestore(&clients_lock, flags);
- return client;
}
/* get snd_seq_client object for the given id quickly */
@@ -182,41 +174,6 @@ static struct snd_seq_client *client_load_and_use_ptr(int clientid)
return client_use_ptr(clientid, IS_ENABLED(CONFIG_MODULES));
}
-/* Take refcount and perform ioctl_mutex lock on the given client;
- * used only for OSS sequencer
- * Unlock via snd_seq_client_ioctl_unlock() below
- */
-bool snd_seq_client_ioctl_lock(int clientid)
-{
- struct snd_seq_client *client;
-
- client = client_load_and_use_ptr(clientid);
- if (!client)
- return false;
- mutex_lock(&client->ioctl_mutex);
- /* The client isn't unrefed here; see snd_seq_client_ioctl_unlock() */
- return true;
-}
-EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_lock);
-
-/* Unlock and unref the given client; for OSS sequencer use only */
-void snd_seq_client_ioctl_unlock(int clientid)
-{
- struct snd_seq_client *client;
-
- client = snd_seq_client_use_ptr(clientid);
- if (WARN_ON(!client))
- return;
- mutex_unlock(&client->ioctl_mutex);
- /* The doubly unrefs below are intentional; the first one releases the
- * leftover from snd_seq_client_ioctl_lock() above, and the second one
- * is for releasing snd_seq_client_use_ptr() in this function
- */
- snd_seq_client_unlock(client);
- snd_seq_client_unlock(client);
-}
-EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_unlock);
-
static void usage_alloc(struct snd_seq_usage *res, int num)
{
res->cur += num;
@@ -262,25 +219,24 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
client->ump_endpoint_port = -1;
/* find free slot in the client table */
- spin_lock_irq(&clients_lock);
- if (client_index < 0) {
- for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
- c < SNDRV_SEQ_MAX_CLIENTS;
- c++) {
- if (clienttab[c] || clienttablock[c])
- continue;
- clienttab[client->number = c] = client;
- spin_unlock_irq(&clients_lock);
- return client;
- }
- } else {
- if (clienttab[client_index] == NULL && !clienttablock[client_index]) {
- clienttab[client->number = client_index] = client;
- spin_unlock_irq(&clients_lock);
- return client;
+ scoped_guard(spinlock_irq, &clients_lock) {
+ if (client_index < 0) {
+ for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
+ c < SNDRV_SEQ_MAX_CLIENTS;
+ c++) {
+ if (clienttab[c] || clienttablock[c])
+ continue;
+ clienttab[client->number = c] = client;
+ return client;
+ }
+ } else {
+ if (clienttab[client_index] == NULL && !clienttablock[client_index]) {
+ clienttab[client->number = client_index] = client;
+ return client;
+ }
}
}
- spin_unlock_irq(&clients_lock);
+
snd_seq_pool_delete(&client->pool);
kfree(client);
return NULL; /* no free slot found or busy, return failure code */
@@ -291,41 +247,41 @@ static int seq_free_client1(struct snd_seq_client *client)
{
if (!client)
return 0;
- spin_lock_irq(&clients_lock);
- clienttablock[client->number] = 1;
- clienttab[client->number] = NULL;
- spin_unlock_irq(&clients_lock);
+ scoped_guard(spinlock_irq, &clients_lock) {
+ clienttablock[client->number] = 1;
+ clienttab[client->number] = NULL;
+ }
snd_seq_delete_all_ports(client);
snd_seq_queue_client_leave(client->number);
snd_use_lock_sync(&client->use_lock);
if (client->pool)
snd_seq_pool_delete(&client->pool);
- spin_lock_irq(&clients_lock);
- clienttablock[client->number] = 0;
- spin_unlock_irq(&clients_lock);
+ scoped_guard(spinlock_irq, &clients_lock) {
+ clienttablock[client->number] = 0;
+ }
return 0;
}
static void seq_free_client(struct snd_seq_client * client)
{
- mutex_lock(&register_mutex);
- switch (client->type) {
- case NO_CLIENT:
- pr_warn("ALSA: seq: Trying to free unused client %d\n",
- client->number);
- break;
- case USER_CLIENT:
- case KERNEL_CLIENT:
- seq_free_client1(client);
- usage_free(&client_usage, 1);
- break;
+ scoped_guard(mutex, &register_mutex) {
+ switch (client->type) {
+ case NO_CLIENT:
+ pr_warn("ALSA: seq: Trying to free unused client %d\n",
+ client->number);
+ break;
+ case USER_CLIENT:
+ case KERNEL_CLIENT:
+ seq_free_client1(client);
+ usage_free(&client_usage, 1);
+ break;
- default:
- pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n",
- client->number, client->type);
+ default:
+ pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n",
+ client->number, client->type);
+ }
}
- mutex_unlock(&register_mutex);
snd_seq_system_client_ev_client_exit(client->number);
}
@@ -346,37 +302,34 @@ static int snd_seq_open(struct inode *inode, struct file *file)
if (err < 0)
return err;
- mutex_lock(&register_mutex);
- client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
- if (!client) {
- mutex_unlock(&register_mutex);
- return -ENOMEM; /* failure code */
- }
-
- mode = snd_seq_file_flags(file);
- if (mode & SNDRV_SEQ_LFLG_INPUT)
- client->accept_input = 1;
- if (mode & SNDRV_SEQ_LFLG_OUTPUT)
- client->accept_output = 1;
-
- user = &client->data.user;
- user->fifo = NULL;
- user->fifo_pool_size = 0;
-
- if (mode & SNDRV_SEQ_LFLG_INPUT) {
- user->fifo_pool_size = SNDRV_SEQ_DEFAULT_CLIENT_EVENTS;
- user->fifo = snd_seq_fifo_new(user->fifo_pool_size);
- if (user->fifo == NULL) {
- seq_free_client1(client);
- kfree(client);
- mutex_unlock(&register_mutex);
- return -ENOMEM;
+ scoped_guard(mutex, &register_mutex) {
+ client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
+ if (!client)
+ return -ENOMEM; /* failure code */
+
+ mode = snd_seq_file_flags(file);
+ if (mode & SNDRV_SEQ_LFLG_INPUT)
+ client->accept_input = 1;
+ if (mode & SNDRV_SEQ_LFLG_OUTPUT)
+ client->accept_output = 1;
+
+ user = &client->data.user;
+ user->fifo = NULL;
+ user->fifo_pool_size = 0;
+
+ if (mode & SNDRV_SEQ_LFLG_INPUT) {
+ user->fifo_pool_size = SNDRV_SEQ_DEFAULT_CLIENT_EVENTS;
+ user->fifo = snd_seq_fifo_new(user->fifo_pool_size);
+ if (user->fifo == NULL) {
+ seq_free_client1(client);
+ kfree(client);
+ return -ENOMEM;
+ }
}
- }
- usage_alloc(&client_usage, 1);
- client->type = USER_CLIENT;
- mutex_unlock(&register_mutex);
+ usage_alloc(&client_usage, 1);
+ client->type = USER_CLIENT;
+ }
c = client->number;
file->private_data = client;
@@ -463,7 +416,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
cell = NULL;
err = 0;
- snd_seq_fifo_lock(fifo);
+ guard(snd_seq_fifo)(fifo);
if (IS_ENABLED(CONFIG_SND_SEQ_UMP) && client->midi_version > 0)
aligned_size = sizeof(struct snd_seq_ump_event);
@@ -521,7 +474,6 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
if (err == -EAGAIN && result > 0)
err = 0;
}
- snd_seq_fifo_unlock(fifo);
return (err < 0) ? err : result;
}
@@ -542,24 +494,21 @@ static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)
*/
static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event)
{
- struct snd_seq_client *dest;
+ struct snd_seq_client *dest __free(snd_seq_client) = NULL;
dest = snd_seq_client_use_ptr(event->dest.client);
if (dest == NULL)
return NULL;
if (! dest->accept_input)
- goto __not_avail;
+ return NULL;
if (snd_seq_ev_is_ump(event))
- return dest; /* ok - no filter checks */
+ return no_free_ptr(dest); /* ok - no filter checks */
if ((dest->filter & SNDRV_SEQ_FILTER_USE_EVENT) &&
! test_bit(event->type, dest->event_filter))
- goto __not_avail;
+ return NULL;
- return dest; /* ok - accessible */
-__not_avail:
- snd_seq_client_unlock(dest);
- return NULL;
+ return no_free_ptr(dest); /* ok - accessible */
}
@@ -616,7 +565,7 @@ static int bounce_error_event(struct snd_seq_client *client,
static int update_timestamp_of_queue(struct snd_seq_event *event,
int queue, int real_time)
{
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = queueptr(queue);
if (! q)
@@ -630,7 +579,6 @@ static int update_timestamp_of_queue(struct snd_seq_event *event,
event->time.tick = snd_seq_timer_get_cur_tick(q->timer);
event->flags |= SNDRV_SEQ_TIME_STAMP_TICK;
}
- queuefree(q);
return 1;
}
@@ -656,73 +604,63 @@ int __snd_seq_deliver_single_event(struct snd_seq_client *dest,
return 0;
}
-/*
- * deliver an event to the specified destination.
- * if filter is non-zero, client filter bitmap is tested.
- *
- * RETURN VALUE: 0 : if succeeded
- * <0 : error
- */
-static int snd_seq_deliver_single_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int atomic, int hop)
+/* deliver a single event; called from snd_seq_deliver_single_event() */
+static int _snd_seq_deliver_single_event(struct snd_seq_client *client,
+ struct snd_seq_event *event,
+ int atomic, int hop)
{
- struct snd_seq_client *dest = NULL;
- struct snd_seq_client_port *dest_port = NULL;
- int result = -ENOENT;
- int direct;
-
- direct = snd_seq_ev_is_direct(event);
+ struct snd_seq_client *dest __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *dest_port __free(snd_seq_port) = NULL;
dest = get_event_dest_client(event);
if (dest == NULL)
- goto __skip;
+ return -ENOENT;
dest_port = snd_seq_port_use_ptr(dest, event->dest.port);
if (dest_port == NULL)
- goto __skip;
+ return -ENOENT;
/* check permission */
- if (! check_port_perm(dest_port, SNDRV_SEQ_PORT_CAP_WRITE)) {
- result = -EPERM;
- goto __skip;
- }
-
+ if (!check_port_perm(dest_port, SNDRV_SEQ_PORT_CAP_WRITE))
+ return -EPERM;
+
if (dest_port->timestamping)
update_timestamp_of_queue(event, dest_port->time_queue,
dest_port->time_real);
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
if (snd_seq_ev_is_ump(event)) {
- if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) {
- result = snd_seq_deliver_from_ump(client, dest, dest_port,
- event, atomic, hop);
- goto __skip;
- } else if (dest->type == USER_CLIENT &&
- !snd_seq_client_is_ump(dest)) {
- result = 0; // drop the event
- goto __skip;
- }
- } else if (snd_seq_client_is_ump(dest)) {
- if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) {
- result = snd_seq_deliver_to_ump(client, dest, dest_port,
+ if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT))
+ return snd_seq_deliver_from_ump(client, dest, dest_port,
event, atomic, hop);
- goto __skip;
- }
+ else if (dest->type == USER_CLIENT &&
+ !snd_seq_client_is_ump(dest))
+ return 0; // drop the event
+ } else if (snd_seq_client_is_ump(dest)) {
+ if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT))
+ return snd_seq_deliver_to_ump(client, dest, dest_port,
+ event, atomic, hop);
}
#endif /* CONFIG_SND_SEQ_UMP */
- result = __snd_seq_deliver_single_event(dest, dest_port, event,
- atomic, hop);
+ return __snd_seq_deliver_single_event(dest, dest_port, event,
+ atomic, hop);
+}
- __skip:
- if (dest_port)
- snd_seq_port_unlock(dest_port);
- if (dest)
- snd_seq_client_unlock(dest);
+/*
+ * deliver an event to the specified destination.
+ * if filter is non-zero, client filter bitmap is tested.
+ *
+ * RETURN VALUE: 0 : if succeeded
+ * <0 : error
+ */
+static int snd_seq_deliver_single_event(struct snd_seq_client *client,
+ struct snd_seq_event *event,
+ int atomic, int hop)
+{
+ int result = _snd_seq_deliver_single_event(client, event, atomic, hop);
- if (result < 0 && !direct) {
- result = bounce_error_event(client, event, result, atomic, hop);
- }
+ if (result < 0 && !snd_seq_ev_is_direct(event))
+ return bounce_error_event(client, event, result, atomic, hop);
return result;
}
@@ -734,7 +672,7 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,
struct snd_seq_event *event,
int port, int atomic, int hop)
{
- struct snd_seq_client_port *src_port;
+ struct snd_seq_client_port *src_port __free(snd_seq_port) = NULL;
struct snd_seq_subscribers *subs;
int err, result = 0, num_ev = 0;
union __snd_seq_event event_saved;
@@ -781,7 +719,6 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,
read_unlock(&grp->list_lock);
else
up_read(&grp->list_mutex);
- snd_seq_port_unlock(src_port);
memcpy(event, &event_saved, saved_size);
return (result < 0) ? result : num_ev;
}
@@ -864,7 +801,7 @@ static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_e
*/
int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
{
- struct snd_seq_client *client;
+ struct snd_seq_client *client __free(snd_seq_client) = NULL;
int result;
if (snd_BUG_ON(!cell))
@@ -926,7 +863,6 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
snd_seq_cell_free(cell);
}
- snd_seq_client_unlock(client);
return result;
}
@@ -950,10 +886,10 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
event->queue = SNDRV_SEQ_QUEUE_DIRECT;
} else if (event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
/* check presence of source port */
- struct snd_seq_client_port *src_port = snd_seq_port_use_ptr(client, event->source.port);
- if (src_port == NULL)
+ struct snd_seq_client_port *src_port __free(snd_seq_port) =
+ snd_seq_port_use_ptr(client, event->source.port);
+ if (!src_port)
return -EINVAL;
- snd_seq_port_unlock(src_port);
}
/* direct event processing without enqueued */
@@ -1218,8 +1154,7 @@ static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg)
static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg)
{
struct snd_seq_running_info *info = arg;
- struct snd_seq_client *cptr;
- int err = 0;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
/* requested client number */
cptr = client_load_and_use_ptr(info->client);
@@ -1227,25 +1162,16 @@ static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg)
return -ENOENT; /* don't change !!! */
#ifdef SNDRV_BIG_ENDIAN
- if (!info->big_endian) {
- err = -EINVAL;
- goto __err;
- }
+ if (!info->big_endian)
+ return -EINVAL;
#else
- if (info->big_endian) {
- err = -EINVAL;
- goto __err;
- }
-
+ if (info->big_endian)
+ return -EINVAL;
#endif
- if (info->cpu_mode > sizeof(long)) {
- err = -EINVAL;
- goto __err;
- }
+ if (info->cpu_mode > sizeof(long))
+ return -EINVAL;
cptr->convert32 = (info->cpu_mode < sizeof(long));
- __err:
- snd_seq_client_unlock(cptr);
- return err;
+ return 0;
}
/* CLIENT_INFO ioctl() */
@@ -1281,7 +1207,7 @@ static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_client_info *client_info = arg;
- struct snd_seq_client *cptr;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
/* requested client number */
cptr = client_load_and_use_ptr(client_info->client);
@@ -1289,8 +1215,6 @@ static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
return -ENOENT; /* don't change !!! */
get_client_info(cptr, client_info);
- snd_seq_client_unlock(cptr);
-
return 0;
}
@@ -1420,24 +1344,19 @@ static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg)
static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)
{
struct snd_seq_port_info *info = arg;
- struct snd_seq_client *cptr;
- struct snd_seq_client_port *port;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
cptr = client_load_and_use_ptr(info->addr.client);
if (cptr == NULL)
return -ENXIO;
port = snd_seq_port_use_ptr(cptr, info->addr.port);
- if (port == NULL) {
- snd_seq_client_unlock(cptr);
+ if (port == NULL)
return -ENOENT; /* don't change */
- }
/* get port info */
snd_seq_get_port_info(port, info);
- snd_seq_port_unlock(port);
- snd_seq_client_unlock(cptr);
-
return 0;
}
@@ -1448,14 +1367,13 @@ static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)
static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, void *arg)
{
struct snd_seq_port_info *info = arg;
- struct snd_seq_client_port *port;
+ struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
if (info->addr.client != client->number) /* only set our own ports ! */
return -EPERM;
port = snd_seq_port_use_ptr(client, info->addr.port);
if (port) {
snd_seq_set_port_info(port, info);
- snd_seq_port_unlock(port);
/* notify the change */
snd_seq_system_client_ev_port_change(info->addr.client,
info->addr.port);
@@ -1526,41 +1444,34 @@ static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_port_subscribe *subs = arg;
- int result = -EINVAL;
- struct snd_seq_client *receiver = NULL, *sender = NULL;
- struct snd_seq_client_port *sport = NULL, *dport = NULL;
+ struct snd_seq_client *receiver __free(snd_seq_client) = NULL;
+ struct snd_seq_client *sender __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
+ struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;
+ int result;
receiver = client_load_and_use_ptr(subs->dest.client);
if (!receiver)
- goto __end;
+ return -EINVAL;
sender = client_load_and_use_ptr(subs->sender.client);
if (!sender)
- goto __end;
+ return -EINVAL;
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
if (!sport)
- goto __end;
+ return -EINVAL;
dport = snd_seq_port_use_ptr(receiver, subs->dest.port);
if (!dport)
- goto __end;
+ return -EINVAL;
result = check_subscription_permission(client, sport, dport, subs);
if (result < 0)
- goto __end;
+ return result;
/* connect them */
result = snd_seq_port_connect(client, sender, sport, receiver, dport, subs);
if (! result) /* broadcast announce */
snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (dport)
- snd_seq_port_unlock(dport);
- if (sender)
- snd_seq_client_unlock(sender);
- if (receiver)
- snd_seq_client_unlock(receiver);
return result;
}
@@ -1572,40 +1483,33 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_port_subscribe *subs = arg;
- int result = -ENXIO;
- struct snd_seq_client *receiver = NULL, *sender = NULL;
- struct snd_seq_client_port *sport = NULL, *dport = NULL;
+ struct snd_seq_client *receiver __free(snd_seq_client) = NULL;
+ struct snd_seq_client *sender __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
+ struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;
+ int result;
receiver = snd_seq_client_use_ptr(subs->dest.client);
if (!receiver)
- goto __end;
+ return -ENXIO;
sender = snd_seq_client_use_ptr(subs->sender.client);
if (!sender)
- goto __end;
+ return -ENXIO;
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
if (!sport)
- goto __end;
+ return -ENXIO;
dport = snd_seq_port_use_ptr(receiver, subs->dest.port);
if (!dport)
- goto __end;
+ return -ENXIO;
result = check_subscription_permission(client, sport, dport, subs);
if (result < 0)
- goto __end;
+ return result;
result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, subs);
if (! result) /* broadcast announce */
snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (dport)
- snd_seq_port_unlock(dport);
- if (sender)
- snd_seq_client_unlock(sender);
- if (receiver)
- snd_seq_client_unlock(receiver);
return result;
}
@@ -1614,7 +1518,7 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
{
struct snd_seq_queue_info *info = arg;
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = snd_seq_queue_alloc(client->number, info->locked, info->flags);
if (IS_ERR(q))
@@ -1628,7 +1532,6 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
if (!info->name[0])
snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue);
strscpy(q->name, info->name, sizeof(q->name));
- snd_use_lock_free(&q->use_lock);
return 0;
}
@@ -1646,7 +1549,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_info *info = arg;
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = queueptr(info->queue);
if (q == NULL)
@@ -1657,7 +1560,6 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
info->owner = q->owner;
info->locked = q->locked;
strscpy(info->name, q->name, sizeof(info->name));
- queuefree(q);
return 0;
}
@@ -1667,7 +1569,7 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_info *info = arg;
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
if (info->owner != client->number)
return -EINVAL;
@@ -1685,12 +1587,9 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
q = queueptr(info->queue);
if (! q)
return -EINVAL;
- if (q->owner != client->number) {
- queuefree(q);
+ if (q->owner != client->number)
return -EPERM;
- }
strscpy(q->name, info->name, sizeof(q->name));
- queuefree(q);
return 0;
}
@@ -1700,7 +1599,7 @@ static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_info *info = arg;
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = snd_seq_queue_find_name(info->name);
if (q == NULL)
@@ -1708,7 +1607,6 @@ static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client,
info->queue = q->queue;
info->owner = q->owner;
info->locked = q->locked;
- queuefree(q);
return 0;
}
@@ -1718,7 +1616,7 @@ static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_status *status = arg;
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
struct snd_seq_timer *tmr;
queue = queueptr(status->queue);
@@ -1736,7 +1634,6 @@ static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
status->running = tmr->running;
status->flags = queue->flags;
- queuefree(queue);
return 0;
}
@@ -1747,7 +1644,7 @@ static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_tempo *tempo = arg;
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
struct snd_seq_timer *tmr;
queue = queueptr(tempo->queue);
@@ -1764,7 +1661,6 @@ static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
tempo->skew_base = tmr->skew_base;
if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 4))
tempo->tempo_base = tmr->tempo_base;
- queuefree(queue);
return 0;
}
@@ -1797,14 +1693,14 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_queue_timer *timer = arg;
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
struct snd_seq_timer *tmr;
queue = queueptr(timer->queue);
if (queue == NULL)
return -EINVAL;
- mutex_lock(&queue->timer_mutex);
+ guard(mutex)(&queue->timer_mutex);
tmr = queue->timer;
memset(timer, 0, sizeof(*timer));
timer->queue = queue->queue;
@@ -1814,8 +1710,6 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
timer->u.alsa.id = tmr->alsa_id;
timer->u.alsa.resolution = tmr->preferred_resolution;
}
- mutex_unlock(&queue->timer_mutex);
- queuefree(queue);
return 0;
}
@@ -1832,13 +1726,13 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
return -EINVAL;
if (snd_seq_queue_check_access(timer->queue, client->number)) {
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
struct snd_seq_timer *tmr;
q = queueptr(timer->queue);
if (q == NULL)
return -ENXIO;
- mutex_lock(&q->timer_mutex);
+ guard(mutex)(&q->timer_mutex);
tmr = q->timer;
snd_seq_queue_timer_close(timer->queue);
tmr->type = timer->type;
@@ -1847,8 +1741,6 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
tmr->preferred_resolution = timer->u.alsa.resolution;
}
result = snd_seq_queue_timer_open(timer->queue);
- mutex_unlock(&q->timer_mutex);
- queuefree(q);
} else {
return -EPERM;
}
@@ -1896,7 +1788,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_client_pool *info = arg;
- struct snd_seq_client *cptr;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
cptr = client_load_and_use_ptr(info->client);
if (cptr == NULL)
@@ -1915,7 +1807,6 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
info->input_pool = 0;
info->input_free = 0;
}
- snd_seq_client_unlock(cptr);
return 0;
}
@@ -1997,26 +1888,16 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_port_subscribe *subs = arg;
- int result;
- struct snd_seq_client *sender = NULL;
- struct snd_seq_client_port *sport = NULL;
+ struct snd_seq_client *sender __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
- result = -EINVAL;
sender = client_load_and_use_ptr(subs->sender.client);
if (!sender)
- goto __end;
+ return -EINVAL;
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
if (!sport)
- goto __end;
- result = snd_seq_port_get_subscription(&sport->c_src, &subs->dest,
- subs);
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (sender)
- snd_seq_client_unlock(sender);
-
- return result;
+ return -EINVAL;
+ return snd_seq_port_get_subscription(&sport->c_src, &subs->dest, subs);
}
@@ -2026,19 +1907,18 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
{
struct snd_seq_query_subs *subs = arg;
- int result = -ENXIO;
- struct snd_seq_client *cptr = NULL;
- struct snd_seq_client_port *port = NULL;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
struct snd_seq_port_subs_info *group;
struct list_head *p;
int i;
cptr = client_load_and_use_ptr(subs->root.client);
if (!cptr)
- goto __end;
+ return -ENXIO;
port = snd_seq_port_use_ptr(cptr, subs->root.port);
if (!port)
- goto __end;
+ return -ENXIO;
switch (subs->type) {
case SNDRV_SEQ_QUERY_SUBS_READ:
@@ -2048,14 +1928,13 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
group = &port->c_dest;
break;
default:
- goto __end;
+ return -ENXIO;
}
- down_read(&group->list_mutex);
+ guard(rwsem_read)(&group->list_mutex);
/* search for the subscriber */
subs->num_subs = group->count;
i = 0;
- result = -ENOENT;
list_for_each(p, &group->list_head) {
if (i++ == subs->index) {
/* found! */
@@ -2069,19 +1948,11 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
}
subs->flags = s->info.flags;
subs->queue = s->info.queue;
- result = 0;
- break;
+ return 0;
}
}
- up_read(&group->list_mutex);
-
- __end:
- if (port)
- snd_seq_port_unlock(port);
- if (cptr)
- snd_seq_client_unlock(cptr);
- return result;
+ return -ENOENT;
}
@@ -2092,7 +1963,7 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_client_info *info = arg;
- struct snd_seq_client *cptr = NULL;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
/* search for next client */
if (info->client < INT_MAX)
@@ -2101,16 +1972,12 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
info->client = 0;
for (; info->client < SNDRV_SEQ_MAX_CLIENTS; info->client++) {
cptr = client_load_and_use_ptr(info->client);
- if (cptr)
- break; /* found */
+ if (cptr) {
+ get_client_info(cptr, info);
+ return 0; /* found */
+ }
}
- if (cptr == NULL)
- return -ENOENT;
-
- get_client_info(cptr, info);
- snd_seq_client_unlock(cptr);
-
- return 0;
+ return -ENOENT;
}
/*
@@ -2120,8 +1987,8 @@ static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
void *arg)
{
struct snd_seq_port_info *info = arg;
- struct snd_seq_client *cptr;
- struct snd_seq_client_port *port = NULL;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
cptr = client_load_and_use_ptr(info->addr.client);
if (cptr == NULL)
@@ -2130,16 +1997,12 @@ static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
/* search for next port */
info->addr.port++;
port = snd_seq_port_query_nearest(cptr, info);
- if (port == NULL) {
- snd_seq_client_unlock(cptr);
+ if (port == NULL)
return -ENOENT;
- }
/* get port info */
info->addr = port->addr;
snd_seq_get_port_info(port, info);
- snd_seq_port_unlock(port);
- snd_seq_client_unlock(cptr);
return 0;
}
@@ -2204,7 +2067,7 @@ static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller,
{
struct snd_seq_client_ump_info __user *argp =
(struct snd_seq_client_ump_info __user *)arg;
- struct snd_seq_client *cptr;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
int client, type, err = 0;
size_t size;
void *p;
@@ -2224,51 +2087,49 @@ static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller,
if (!cptr)
return -ENOENT;
- mutex_lock(&cptr->ioctl_mutex);
- if (!cptr->midi_version) {
- err = -EBADFD;
- goto error;
- }
-
- if (cmd == SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO) {
- if (!cptr->ump_info)
- p = NULL;
- else
- p = cptr->ump_info[type];
- if (!p) {
- err = -ENODEV;
- goto error;
- }
- if (copy_to_user(argp->info, p, size)) {
- err = -EFAULT;
- goto error;
- }
- } else {
- if (cptr->type != USER_CLIENT) {
+ scoped_guard(mutex, &cptr->ioctl_mutex) {
+ if (!cptr->midi_version) {
err = -EBADFD;
- goto error;
+ break;
}
- if (!cptr->ump_info) {
- cptr->ump_info = kcalloc(NUM_UMP_INFOS,
- sizeof(void *), GFP_KERNEL);
+
+ if (cmd == SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO) {
+ if (!cptr->ump_info)
+ p = NULL;
+ else
+ p = cptr->ump_info[type];
+ if (!p) {
+ err = -ENODEV;
+ break;
+ }
+ if (copy_to_user(argp->info, p, size)) {
+ err = -EFAULT;
+ break;
+ }
+ } else {
+ if (cptr->type != USER_CLIENT) {
+ err = -EBADFD;
+ break;
+ }
if (!cptr->ump_info) {
- err = -ENOMEM;
- goto error;
+ cptr->ump_info = kcalloc(NUM_UMP_INFOS,
+ sizeof(void *), GFP_KERNEL);
+ if (!cptr->ump_info) {
+ err = -ENOMEM;
+ break;
+ }
}
+ p = memdup_user(argp->info, size);
+ if (IS_ERR(p)) {
+ err = PTR_ERR(p);
+ break;
+ }
+ kfree(cptr->ump_info[type]);
+ terminate_ump_info_strings(p, type);
+ cptr->ump_info[type] = p;
}
- p = memdup_user(argp->info, size);
- if (IS_ERR(p)) {
- err = PTR_ERR(p);
- goto error;
- }
- kfree(cptr->ump_info[type]);
- terminate_ump_info_strings(p, type);
- cptr->ump_info[type] = p;
- }
- error:
- mutex_unlock(&cptr->ioctl_mutex);
- snd_seq_client_unlock(cptr);
+ }
if (!err && cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO) {
if (type == SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT)
snd_seq_system_ump_notify(client, 0,
@@ -2381,9 +2242,9 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
}
- mutex_lock(&client->ioctl_mutex);
- err = handler->func(client, &buf);
- mutex_unlock(&client->ioctl_mutex);
+ scoped_guard(mutex, &client->ioctl_mutex) {
+ err = handler->func(client, &buf);
+ }
if (err >= 0) {
/* Some commands includes a bug in 'dir' field. */
if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT ||
@@ -2420,34 +2281,32 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
return -EINVAL;
- mutex_lock(&register_mutex);
+ scoped_guard(mutex, &register_mutex) {
- if (card) {
- client_index += SNDRV_SEQ_GLOBAL_CLIENTS
- + card->number * SNDRV_SEQ_CLIENTS_PER_CARD;
- if (client_index >= SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN)
- client_index = -1;
- }
+ if (card) {
+ client_index += SNDRV_SEQ_GLOBAL_CLIENTS
+ + card->number * SNDRV_SEQ_CLIENTS_PER_CARD;
+ if (client_index >= SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN)
+ client_index = -1;
+ }
- /* empty write queue as default */
- client = seq_create_client1(client_index, 0);
- if (client == NULL) {
- mutex_unlock(&register_mutex);
- return -EBUSY; /* failure code */
- }
- usage_alloc(&client_usage, 1);
+ /* empty write queue as default */
+ client = seq_create_client1(client_index, 0);
+ if (client == NULL)
+ return -EBUSY; /* failure code */
+ usage_alloc(&client_usage, 1);
- client->accept_input = 1;
- client->accept_output = 1;
- client->data.kernel.card = card;
- client->user_pversion = SNDRV_SEQ_VERSION;
+ client->accept_input = 1;
+ client->accept_output = 1;
+ client->data.kernel.card = card;
+ client->user_pversion = SNDRV_SEQ_VERSION;
- va_start(args, name_fmt);
- vsnprintf(client->name, sizeof(client->name), name_fmt, args);
- va_end(args);
+ va_start(args, name_fmt);
+ vsnprintf(client->name, sizeof(client->name), name_fmt, args);
+ va_end(args);
- client->type = KERNEL_CLIENT;
- mutex_unlock(&register_mutex);
+ client->type = KERNEL_CLIENT;
+ }
/* make others aware this new client */
snd_seq_system_client_ev_client_start(client->number);
@@ -2483,8 +2342,7 @@ EXPORT_SYMBOL(snd_seq_delete_kernel_client);
int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev,
struct file *file, bool blocking)
{
- struct snd_seq_client *cptr;
- int result;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
if (snd_BUG_ON(!ev))
return -EINVAL;
@@ -2507,17 +2365,13 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev,
return -EINVAL;
if (!cptr->accept_output) {
- result = -EPERM;
+ return -EPERM;
} else { /* send it */
- mutex_lock(&cptr->ioctl_mutex);
- result = snd_seq_client_enqueue_event(cptr, ev, file, blocking,
- false, 0,
- &cptr->ioctl_mutex);
- mutex_unlock(&cptr->ioctl_mutex);
+ guard(mutex)(&cptr->ioctl_mutex);
+ return snd_seq_client_enqueue_event(cptr, ev, file, blocking,
+ false, 0,
+ &cptr->ioctl_mutex);
}
-
- snd_seq_client_unlock(cptr);
- return result;
}
EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
@@ -2531,8 +2385,7 @@ EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
int atomic, int hop)
{
- struct snd_seq_client *cptr;
- int result;
+ struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
if (snd_BUG_ON(!ev))
return -EINVAL;
@@ -2549,15 +2402,27 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
return -EINVAL;
if (!cptr->accept_output)
- result = -EPERM;
+ return -EPERM;
else
- result = snd_seq_deliver_event(cptr, ev, atomic, hop);
-
- snd_seq_client_unlock(cptr);
- return result;
+ return snd_seq_deliver_event(cptr, ev, atomic, hop);
}
EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
+static int call_seq_client_ctl(struct snd_seq_client *client,
+ unsigned int cmd, void *arg)
+{
+ const struct ioctl_handler *handler;
+
+ for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
+ if (handler->cmd == cmd)
+ return handler->func(client, arg);
+ }
+
+ pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
+ return -ENOTTY;
+}
+
/**
* snd_seq_kernel_client_ctl - operate a command for a client with data in
* kernel space.
@@ -2572,24 +2437,29 @@ EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
*/
int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
{
- const struct ioctl_handler *handler;
struct snd_seq_client *client;
client = clientptr(clientid);
if (client == NULL)
return -ENXIO;
- for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
- if (handler->cmd == cmd)
- return handler->func(client, arg);
- }
-
- pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
- cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
- return -ENOTTY;
+ return call_seq_client_ctl(client, cmd, arg);
}
EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
+/* a similar like above but taking locks; used only from OSS sequencer layer */
+int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg)
+{
+ struct snd_seq_client *client __free(snd_seq_client) = NULL;
+
+ client = client_load_and_use_ptr(clientid);
+ if (!client)
+ return -ENXIO;
+ guard(mutex)(&client->ioctl_mutex);
+ return call_seq_client_ctl(client, cmd, arg);
+}
+EXPORT_SYMBOL_GPL(snd_seq_kernel_client_ioctl);
+
/* exported (for OSS emulator) */
int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
{
@@ -2616,7 +2486,7 @@ EXPORT_SYMBOL_GPL(snd_seq_kernel_client_get);
void snd_seq_kernel_client_put(struct snd_seq_client *cptr)
{
if (cptr)
- snd_seq_client_unlock(cptr);
+ snd_seq_client_unref(cptr);
}
EXPORT_SYMBOL_GPL(snd_seq_kernel_client_put);
@@ -2634,11 +2504,9 @@ static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
struct snd_seq_subscribers *s;
int count = 0;
- down_read(&group->list_mutex);
- if (list_empty(&group->list_head)) {
- up_read(&group->list_mutex);
+ guard(rwsem_read)(&group->list_mutex);
+ if (list_empty(&group->list_head))
return;
- }
snd_iprintf(buffer, msg);
list_for_each(p, &group->list_head) {
if (is_src)
@@ -2655,7 +2523,6 @@ static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
if (group->exclusive)
snd_iprintf(buffer, "[ex]");
}
- up_read(&group->list_mutex);
snd_iprintf(buffer, "\n");
}
@@ -2681,7 +2548,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
{
struct snd_seq_client_port *p;
- mutex_lock(&client->ports_mutex);
+ guard(mutex)(&client->ports_mutex);
list_for_each_entry(p, &client->ports_list_head, list) {
if (p->capability & SNDRV_SEQ_PORT_CAP_INACTIVE)
continue;
@@ -2700,7 +2567,6 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: ");
snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
}
- mutex_unlock(&client->ports_mutex);
}
static const char *midi_version_string(unsigned int version)
@@ -2722,7 +2588,6 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
int c;
- struct snd_seq_client *client;
snd_iprintf(buffer, "Client info\n");
snd_iprintf(buffer, " cur clients : %d\n", client_usage.cur);
@@ -2732,15 +2597,15 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,
/* list the client table */
for (c = 0; c < SNDRV_SEQ_MAX_CLIENTS; c++) {
+ struct snd_seq_client *client __free(snd_seq_client) = NULL;
+
client = client_load_and_use_ptr(c);
if (client == NULL)
continue;
- if (client->type == NO_CLIENT) {
- snd_seq_client_unlock(client);
+ if (client->type == NO_CLIENT)
continue;
- }
- mutex_lock(&client->ioctl_mutex);
+ guard(mutex)(&client->ioctl_mutex);
snd_iprintf(buffer, "Client %3d : \"%s\" [%s %s]\n",
c, client->name,
client->type == USER_CLIENT ? "User" : "Kernel",
@@ -2758,8 +2623,6 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,
snd_iprintf(buffer, " Input pool :\n");
snd_seq_info_pool(buffer, client->data.user.fifo->pool, " ");
}
- mutex_unlock(&client->ioctl_mutex);
- snd_seq_client_unlock(client);
}
}
#endif /* CONFIG_SND_PROC_FS */
@@ -2797,10 +2660,10 @@ int __init snd_sequencer_device_init(void)
return err;
dev_set_name(seq_dev, "seq");
- mutex_lock(&register_mutex);
- err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
- &snd_seq_f_ops, NULL, seq_dev);
- mutex_unlock(&register_mutex);
+ scoped_guard(mutex, &register_mutex) {
+ err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
+ &snd_seq_f_ops, NULL, seq_dev);
+ }
if (err < 0) {
put_device(seq_dev);
return err;
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
index 915b1017286e..ece02c58db70 100644
--- a/sound/core/seq/seq_clientmgr.h
+++ b/sound/core/seq/seq_clientmgr.h
@@ -78,8 +78,20 @@ void snd_sequencer_device_done(void);
/* get locked pointer to client */
struct snd_seq_client *snd_seq_client_use_ptr(int clientid);
+static inline struct snd_seq_client *
+snd_seq_client_ref(struct snd_seq_client *client)
+{
+ snd_use_lock_use(&client->use_lock);
+ return client;
+}
+
/* unlock pointer to client */
-#define snd_seq_client_unlock(client) snd_use_lock_free(&(client)->use_lock)
+static inline void snd_seq_client_unref(struct snd_seq_client *client)
+{
+ snd_use_lock_free(&client->use_lock);
+}
+
+DEFINE_FREE(snd_seq_client, struct snd_seq_client *, if (!IS_ERR_OR_NULL(_T)) snd_seq_client_unref(_T))
/* dispatch event to client(s) */
int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop);
@@ -94,8 +106,7 @@ int __snd_seq_deliver_single_event(struct snd_seq_client *dest,
int atomic, int hop);
/* only for OSS sequencer */
-bool snd_seq_client_ioctl_lock(int clientid);
-void snd_seq_client_ioctl_unlock(int clientid);
+int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg);
extern int seq_client_load[15];
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 3a10b081f129..91cce1890111 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -106,12 +106,11 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
if (snd_BUG_ON(!f))
return -EINVAL;
- snd_use_lock_use(&f->use_lock);
+ guard(snd_seq_fifo)(f);
err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL, NULL); /* always non-blocking */
if (err < 0) {
if ((err == -ENOMEM) || (err == -EAGAIN))
atomic_inc(&f->overflow);
- snd_use_lock_free(&f->use_lock);
return err;
}
@@ -130,8 +129,6 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
if (waitqueue_active(&f->input_sleep))
wake_up(&f->input_sleep);
- snd_use_lock_free(&f->use_lock);
-
return 0; /* success */
}
@@ -213,6 +210,7 @@ int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file,
poll_table *wait)
{
poll_wait(file, &f->input_sleep, wait);
+ guard(spinlock_irq)(&f->lock);
return (f->cells > 0);
}
@@ -263,14 +261,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
/* get the number of unused cells safely */
int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f)
{
- int cells;
-
if (!f)
return 0;
- snd_use_lock_use(&f->use_lock);
- scoped_guard(spinlock_irqsave, &f->lock)
- cells = snd_seq_unused_cells(f->pool);
- snd_use_lock_free(&f->use_lock);
- return cells;
+ guard(snd_seq_fifo)(f);
+ guard(spinlock_irqsave)(&f->lock);
+ return snd_seq_unused_cells(f->pool);
}
diff --git a/sound/core/seq/seq_fifo.h b/sound/core/seq/seq_fifo.h
index b56a7b897c9c..4c9c49127746 100644
--- a/sound/core/seq/seq_fifo.h
+++ b/sound/core/seq/seq_fifo.h
@@ -37,6 +37,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, struct snd_seq_event *event);
/* lock fifo from release */
#define snd_seq_fifo_lock(fifo) snd_use_lock_use(&(fifo)->use_lock)
#define snd_seq_fifo_unlock(fifo) snd_use_lock_free(&(fifo)->use_lock)
+DEFINE_GUARD(snd_seq_fifo, struct snd_seq_fifo *, snd_seq_fifo_lock(_T), snd_seq_fifo_unlock(_T))
/* get a cell from fifo - fifo should be locked */
int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, struct snd_seq_event_cell **cellp, int nonblock);
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index cc2f8e846584..40fa379847e5 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -178,17 +178,10 @@ static int unsubscribe_port(struct snd_seq_client *client,
static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
struct snd_seq_client **cp)
{
- struct snd_seq_client_port *p;
*cp = snd_seq_client_use_ptr(addr->client);
- if (*cp) {
- p = snd_seq_port_use_ptr(*cp, addr->port);
- if (! p) {
- snd_seq_client_unlock(*cp);
- *cp = NULL;
- }
- return p;
- }
- return NULL;
+ if (!*cp)
+ return NULL;
+ return snd_seq_port_use_ptr(*cp, addr->port);
}
static void delete_and_unsubscribe_port(struct snd_seq_client *client,
@@ -218,8 +211,8 @@ static void clear_subscriber_list(struct snd_seq_client *client,
list_for_each_safe(p, n, &grp->list_head) {
struct snd_seq_subscribers *subs;
- struct snd_seq_client *c;
- struct snd_seq_client_port *aport;
+ struct snd_seq_client *c __free(snd_seq_client) = NULL;
+ struct snd_seq_client_port *aport __free(snd_seq_port) = NULL;
subs = get_subscriber(p, is_src);
if (is_src)
@@ -241,8 +234,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
/* ok we got the connected port */
delete_and_unsubscribe_port(c, aport, subs, !is_src, true);
kfree(subs);
- snd_seq_port_unlock(aport);
- snd_seq_client_unlock(c);
}
}
diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h
index b3b35018cb82..40ed6cf7cb90 100644
--- a/sound/core/seq/seq_ports.h
+++ b/sound/core/seq/seq_ports.h
@@ -96,6 +96,8 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl
/* unlock the port */
#define snd_seq_port_unlock(port) snd_use_lock_free(&(port)->use_lock)
+DEFINE_FREE(snd_seq_port, struct snd_seq_client_port *, if (!IS_ERR_OR_NULL(_T)) snd_seq_port_unlock(_T))
+
/* create a port, port number or a negative error code is returned */
int snd_seq_create_port(struct snd_seq_client *client, int port_index,
struct snd_seq_client_port **port_ret);
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 10add922323d..f5c0e401c8ae 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -209,14 +209,13 @@ struct snd_seq_queue *queueptr(int queueid)
struct snd_seq_queue *snd_seq_queue_find_name(char *name)
{
int i;
- struct snd_seq_queue *q;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = queueptr(i);
if (q) {
if (strncmp(q->name, name, sizeof(q->name)) == 0)
- return q;
- queuefree(q);
+ return no_free_ptr(q);
}
}
return NULL;
@@ -286,7 +285,7 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
{
int dest, err;
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
if (snd_BUG_ON(!cell))
return -EINVAL;
@@ -321,16 +320,12 @@ int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
break;
}
- if (err < 0) {
- queuefree(q); /* unlock */
+ if (err < 0)
return err;
- }
/* trigger dispatching */
snd_seq_check_queue(q, atomic, hop);
- queuefree(q); /* unlock */
-
return 0;
}
@@ -366,15 +361,12 @@ static inline void queue_access_unlock(struct snd_seq_queue *q)
/* exported - only checking permission */
int snd_seq_queue_check_access(int queueid, int client)
{
- struct snd_seq_queue *q = queueptr(queueid);
- int access_ok;
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(queueid);
if (! q)
return 0;
- scoped_guard(spinlock_irqsave, &q->owner_lock)
- access_ok = check_access(q, client);
- queuefree(q);
- return access_ok;
+ guard(spinlock_irqsave)(&q->owner_lock);
+ return check_access(q, client);
}
/*----------------------------------------------------------------*/
@@ -384,22 +376,19 @@ int snd_seq_queue_check_access(int queueid, int client)
*/
int snd_seq_queue_set_owner(int queueid, int client, int locked)
{
- struct snd_seq_queue *q = queueptr(queueid);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(queueid);
if (q == NULL)
return -EINVAL;
- if (! queue_access_lock(q, client)) {
- queuefree(q);
+ if (!queue_access_lock(q, client))
return -EPERM;
- }
scoped_guard(spinlock_irqsave, &q->owner_lock) {
q->locked = locked ? 1 : 0;
q->owner = client;
}
queue_access_unlock(q);
- queuefree(q);
return 0;
}
@@ -414,7 +403,7 @@ int snd_seq_queue_set_owner(int queueid, int client, int locked)
int snd_seq_queue_timer_open(int queueid)
{
int result = 0;
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
struct snd_seq_timer *tmr;
queue = queueptr(queueid);
@@ -426,7 +415,6 @@ int snd_seq_queue_timer_open(int queueid)
snd_seq_timer_defaults(tmr);
result = snd_seq_timer_open(queue);
}
- queuefree(queue);
return result;
}
@@ -435,14 +423,13 @@ int snd_seq_queue_timer_open(int queueid)
*/
int snd_seq_queue_timer_close(int queueid)
{
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
int result = 0;
queue = queueptr(queueid);
if (queue == NULL)
return -EINVAL;
snd_seq_timer_close(queue);
- queuefree(queue);
return result;
}
@@ -450,15 +437,13 @@ int snd_seq_queue_timer_close(int queueid)
int snd_seq_queue_timer_set_tempo(int queueid, int client,
struct snd_seq_queue_tempo *info)
{
- struct snd_seq_queue *q = queueptr(queueid);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(queueid);
int result;
if (q == NULL)
return -EINVAL;
- if (! queue_access_lock(q, client)) {
- queuefree(q);
+ if (!queue_access_lock(q, client))
return -EPERM;
- }
result = snd_seq_timer_set_tempo_ppq(q->timer, info->tempo, info->ppq,
info->tempo_base);
@@ -466,7 +451,6 @@ int snd_seq_queue_timer_set_tempo(int queueid, int client,
result = snd_seq_timer_set_skew(q->timer, info->skew_value,
info->skew_base);
queue_access_unlock(q);
- queuefree(q);
return result;
}
@@ -495,15 +479,13 @@ static void queue_use(struct snd_seq_queue *queue, int client, int use)
*/
int snd_seq_queue_use(int queueid, int client, int use)
{
- struct snd_seq_queue *queue;
+ struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
queue = queueptr(queueid);
if (queue == NULL)
return -EINVAL;
- mutex_lock(&queue->timer_mutex);
+ guard(mutex)(&queue->timer_mutex);
queue_use(queue, client, use);
- mutex_unlock(&queue->timer_mutex);
- queuefree(queue);
return 0;
}
@@ -514,15 +496,12 @@ int snd_seq_queue_use(int queueid, int client, int use)
*/
int snd_seq_queue_is_used(int queueid, int client)
{
- struct snd_seq_queue *q;
- int result;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
q = queueptr(queueid);
if (q == NULL)
return -EINVAL; /* invalid queue */
- result = test_bit(client, q->clients_bitmap) ? 1 : 0;
- queuefree(q);
- return result;
+ return test_bit(client, q->clients_bitmap) ? 1 : 0;
}
@@ -535,11 +514,10 @@ int snd_seq_queue_is_used(int queueid, int client)
void snd_seq_queue_client_leave(int client)
{
int i;
- struct snd_seq_queue *q;
/* delete own queues from queue list */
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- q = queue_list_remove(i, client);
+ struct snd_seq_queue *q = queue_list_remove(i, client);
if (q)
queue_delete(q);
}
@@ -548,7 +526,7 @@ void snd_seq_queue_client_leave(int client)
* they are not owned by this client
*/
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- q = queueptr(i);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(i);
if (!q)
continue;
if (test_bit(client, q->clients_bitmap)) {
@@ -556,7 +534,6 @@ void snd_seq_queue_client_leave(int client)
snd_seq_prioq_leave(q->timeq, client, 0);
snd_seq_queue_use(q->queue, client, 0);
}
- queuefree(q);
}
}
@@ -568,10 +545,9 @@ void snd_seq_queue_client_leave(int client)
void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info)
{
int i;
- struct snd_seq_queue *q;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- q = queueptr(i);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(i);
if (!q)
continue;
if (test_bit(client, q->clients_bitmap) &&
@@ -580,7 +556,6 @@ void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info)
snd_seq_prioq_remove_events(q->tickq, client, info);
snd_seq_prioq_remove_events(q->timeq, client, info);
}
- queuefree(q);
}
}
@@ -667,7 +642,7 @@ static void snd_seq_queue_process_event(struct snd_seq_queue *q,
*/
int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
{
- struct snd_seq_queue *q;
+ struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
if (snd_BUG_ON(!ev))
return -EINVAL;
@@ -676,15 +651,12 @@ int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
if (q == NULL)
return -EINVAL;
- if (! queue_access_lock(q, ev->source.client)) {
- queuefree(q);
+ if (!queue_access_lock(q, ev->source.client))
return -EPERM;
- }
snd_seq_queue_process_event(q, ev, atomic, hop);
queue_access_unlock(q);
- queuefree(q);
return 0;
}
@@ -697,13 +669,12 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
int i, bpm;
- struct snd_seq_queue *q;
struct snd_seq_timer *tmr;
bool locked;
int owner;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- q = queueptr(i);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(i);
if (!q)
continue;
@@ -731,7 +702,6 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "current time : %d.%09d s\n", tmr->cur_time.tv_sec, tmr->cur_time.tv_nsec);
snd_iprintf(buffer, "current tick : %d\n", tmr->tick.cur_tick);
snd_iprintf(buffer, "\n");
- queuefree(q);
}
}
#endif /* CONFIG_SND_PROC_FS */
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
index b81379c9af43..afcd3c5484a6 100644
--- a/sound/core/seq/seq_queue.h
+++ b/sound/core/seq/seq_queue.h
@@ -73,6 +73,8 @@ struct snd_seq_queue *queueptr(int queueid);
/* unlock */
#define queuefree(q) snd_use_lock_free(&(q)->use_lock)
+DEFINE_FREE(snd_seq_queue, struct snd_seq_queue *, if (!IS_ERR_OR_NULL(_T)) queuefree(_T))
+
/* return the (first) queue matching with the specified name */
struct snd_seq_queue *snd_seq_queue_find_name(char *name);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index c9f0392ac7f1..29b018a212fc 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -440,13 +440,13 @@ void snd_seq_info_timer_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
int idx;
- struct snd_seq_queue *q;
struct snd_seq_timer *tmr;
struct snd_timer_instance *ti;
unsigned long resolution;
for (idx = 0; idx < SNDRV_SEQ_MAX_QUEUES; idx++) {
- q = queueptr(idx);
+ struct snd_seq_queue *q __free(snd_seq_queue) = queueptr(idx);
+
if (q == NULL)
continue;
scoped_guard(mutex, &q->timer_mutex) {
@@ -461,7 +461,6 @@ void snd_seq_info_timer_read(struct snd_info_entry *entry,
snd_iprintf(buffer, " Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000);
snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base);
}
- queuefree(q);
}
}
#endif /* CONFIG_SND_PROC_FS */
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index a8902dc45dc1..64ef03b2d579 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -414,39 +414,39 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
dpcm->last_jiffies = jiffies;
dpcm->pcm_rate_shift = 0;
dpcm->last_drift = 0;
- spin_lock(&cable->lock);
- cable->running |= stream;
- cable->pause &= ~stream;
- err = cable->ops->start(dpcm);
- spin_unlock(&cable->lock);
+ scoped_guard(spinlock, &cable->lock) {
+ cable->running |= stream;
+ cable->pause &= ~stream;
+ err = cable->ops->start(dpcm);
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
loopback_active_notify(dpcm);
break;
case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&cable->lock);
- cable->running &= ~stream;
- cable->pause &= ~stream;
- err = cable->ops->stop(dpcm);
- spin_unlock(&cable->lock);
+ scoped_guard(spinlock, &cable->lock) {
+ cable->running &= ~stream;
+ cable->pause &= ~stream;
+ err = cable->ops->stop(dpcm);
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
loopback_active_notify(dpcm);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
- spin_lock(&cable->lock);
- cable->pause |= stream;
- err = cable->ops->stop(dpcm);
- spin_unlock(&cable->lock);
+ scoped_guard(spinlock, &cable->lock) {
+ cable->pause |= stream;
+ err = cable->ops->stop(dpcm);
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
loopback_active_notify(dpcm);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- spin_lock(&cable->lock);
- dpcm->last_jiffies = jiffies;
- cable->pause &= ~stream;
- err = cable->ops->start(dpcm);
- spin_unlock(&cable->lock);
+ scoped_guard(spinlock, &cable->lock) {
+ dpcm->last_jiffies = jiffies;
+ cable->pause &= ~stream;
+ err = cable->ops->start(dpcm);
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
loopback_active_notify(dpcm);
break;
@@ -511,13 +511,12 @@ static int loopback_prepare(struct snd_pcm_substream *substream)
dpcm->pcm_salign = salign;
dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
- mutex_lock(&dpcm->loopback->cable_lock);
+ guard(mutex)(&dpcm->loopback->cable_lock);
if (!(cable->valid & ~(1 << substream->stream)) ||
(get_setup(dpcm)->notify &&
substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
params_change(substream);
cable->valid |= 1 << substream->stream;
- mutex_unlock(&dpcm->loopback->cable_lock);
return 0;
}
@@ -701,21 +700,22 @@ static unsigned int loopback_jiffies_timer_pos_update
static void loopback_jiffies_timer_function(struct timer_list *t)
{
struct loopback_pcm *dpcm = timer_container_of(dpcm, t, timer);
- unsigned long flags;
-
- spin_lock_irqsave(&dpcm->cable->lock, flags);
- if (loopback_jiffies_timer_pos_update(dpcm->cable) &
- (1 << dpcm->substream->stream)) {
- loopback_jiffies_timer_start(dpcm);
- if (dpcm->period_update_pending) {
- dpcm->period_update_pending = 0;
- spin_unlock_irqrestore(&dpcm->cable->lock, flags);
- /* need to unlock before calling below */
- snd_pcm_period_elapsed(dpcm->substream);
- return;
+ bool period_elapsed = false;
+
+ scoped_guard(spinlock_irqsave, &dpcm->cable->lock) {
+ if (loopback_jiffies_timer_pos_update(dpcm->cable) &
+ (1 << dpcm->substream->stream)) {
+ loopback_jiffies_timer_start(dpcm);
+ if (dpcm->period_update_pending) {
+ dpcm->period_update_pending = 0;
+ period_elapsed = true;
+ break;
+ }
}
}
- spin_unlock_irqrestore(&dpcm->cable->lock, flags);
+
+ if (period_elapsed)
+ snd_pcm_period_elapsed(dpcm->substream);
}
/* call in cable->lock */
@@ -760,68 +760,68 @@ static void loopback_snd_timer_period_elapsed(struct loopback_cable *cable,
struct snd_pcm_substream *substream_play, *substream_capt;
struct snd_pcm_runtime *valid_runtime;
unsigned int running, elapsed_bytes;
- unsigned long flags;
+ bool xrun = false;
- spin_lock_irqsave(&cable->lock, flags);
- running = cable->running ^ cable->pause;
- /* no need to do anything if no stream is running */
- if (!running) {
- spin_unlock_irqrestore(&cable->lock, flags);
- return;
- }
+ scoped_guard(spinlock_irqsave, &cable->lock) {
+ running = cable->running ^ cable->pause;
+ /* no need to do anything if no stream is running */
+ if (!running)
+ return;
- dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
- dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
+ dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
+ dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (event == SNDRV_TIMER_EVENT_MSTOP) {
- if (!dpcm_play ||
- dpcm_play->substream->runtime->state !=
- SNDRV_PCM_STATE_DRAINING) {
- spin_unlock_irqrestore(&cable->lock, flags);
- return;
+ if (event == SNDRV_TIMER_EVENT_MSTOP) {
+ if (!dpcm_play ||
+ dpcm_play->substream->runtime->state !=
+ SNDRV_PCM_STATE_DRAINING)
+ return;
}
- }
- substream_play = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
+ substream_play = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
dpcm_play->substream : NULL;
- substream_capt = (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) ?
+ substream_capt = (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) ?
dpcm_capt->substream : NULL;
- valid_runtime = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
- dpcm_play->substream->runtime :
- dpcm_capt->substream->runtime;
-
- /* resolution is only valid for SNDRV_TIMER_EVENT_TICK events */
- if (event == SNDRV_TIMER_EVENT_TICK) {
- /* The hardware rules guarantee that playback and capture period
- * are the same. Therefore only one device has to be checked
- * here.
- */
- if (loopback_snd_timer_check_resolution(valid_runtime,
- resolution) < 0) {
- spin_unlock_irqrestore(&cable->lock, flags);
- if (substream_play)
- snd_pcm_stop_xrun(substream_play);
- if (substream_capt)
- snd_pcm_stop_xrun(substream_capt);
- return;
+ valid_runtime = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
+ dpcm_play->substream->runtime :
+ dpcm_capt->substream->runtime;
+
+ /* resolution is only valid for SNDRV_TIMER_EVENT_TICK events */
+ if (event == SNDRV_TIMER_EVENT_TICK) {
+ /* The hardware rules guarantee that playback and capture period
+ * are the same. Therefore only one device has to be checked
+ * here.
+ */
+ if (loopback_snd_timer_check_resolution(valid_runtime,
+ resolution) < 0) {
+ xrun = true;
+ break;
+ }
+ }
+
+ elapsed_bytes = frames_to_bytes(valid_runtime,
+ valid_runtime->period_size);
+ /* The same timer interrupt is used for playback and capture device */
+ if ((running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
+ (running & (1 << SNDRV_PCM_STREAM_CAPTURE))) {
+ copy_play_buf(dpcm_play, dpcm_capt, elapsed_bytes);
+ bytepos_finish(dpcm_play, elapsed_bytes);
+ bytepos_finish(dpcm_capt, elapsed_bytes);
+ } else if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
+ bytepos_finish(dpcm_play, elapsed_bytes);
+ } else if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
+ clear_capture_buf(dpcm_capt, elapsed_bytes);
+ bytepos_finish(dpcm_capt, elapsed_bytes);
}
}
- elapsed_bytes = frames_to_bytes(valid_runtime,
- valid_runtime->period_size);
- /* The same timer interrupt is used for playback and capture device */
- if ((running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
- (running & (1 << SNDRV_PCM_STREAM_CAPTURE))) {
- copy_play_buf(dpcm_play, dpcm_capt, elapsed_bytes);
- bytepos_finish(dpcm_play, elapsed_bytes);
- bytepos_finish(dpcm_capt, elapsed_bytes);
- } else if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
- bytepos_finish(dpcm_play, elapsed_bytes);
- } else if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
- clear_capture_buf(dpcm_capt, elapsed_bytes);
- bytepos_finish(dpcm_capt, elapsed_bytes);
+ if (xrun) {
+ if (substream_play)
+ snd_pcm_stop_xrun(substream_play);
+ if (substream_capt)
+ snd_pcm_stop_xrun(substream_capt);
+ return;
}
- spin_unlock_irqrestore(&cable->lock, flags);
if (substream_play)
snd_pcm_period_elapsed(substream_play);
@@ -910,11 +910,10 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
struct loopback_pcm *dpcm = runtime->private_data;
snd_pcm_uframes_t pos;
- spin_lock(&dpcm->cable->lock);
+ guard(spinlock)(&dpcm->cable->lock);
if (dpcm->cable->ops->pos_update)
dpcm->cable->ops->pos_update(dpcm->cable);
pos = dpcm->buf_pos;
- spin_unlock(&dpcm->cable->lock);
return bytes_to_frames(runtime, pos);
}
@@ -958,9 +957,8 @@ static int loopback_hw_free(struct snd_pcm_substream *substream)
struct loopback_pcm *dpcm = runtime->private_data;
struct loopback_cable *cable = dpcm->cable;
- mutex_lock(&dpcm->loopback->cable_lock);
+ guard(mutex)(&dpcm->loopback->cable_lock);
cable->valid &= ~(1 << substream->stream);
- mutex_unlock(&dpcm->loopback->cable_lock);
return 0;
}
@@ -980,10 +978,10 @@ static int rule_format(struct snd_pcm_hw_params *params,
struct snd_mask m;
snd_mask_none(&m);
- mutex_lock(&dpcm->loopback->cable_lock);
- m.bits[0] = (u_int32_t)cable->hw.formats;
- m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
- mutex_unlock(&dpcm->loopback->cable_lock);
+ scoped_guard(mutex, &dpcm->loopback->cable_lock) {
+ m.bits[0] = (u_int32_t)cable->hw.formats;
+ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
+ }
return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
@@ -994,10 +992,10 @@ static int rule_rate(struct snd_pcm_hw_params *params,
struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- mutex_lock(&dpcm->loopback->cable_lock);
- t.min = cable->hw.rate_min;
- t.max = cable->hw.rate_max;
- mutex_unlock(&dpcm->loopback->cable_lock);
+ scoped_guard(mutex, &dpcm->loopback->cable_lock) {
+ t.min = cable->hw.rate_min;
+ t.max = cable->hw.rate_max;
+ }
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -1010,10 +1008,10 @@ static int rule_channels(struct snd_pcm_hw_params *params,
struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- mutex_lock(&dpcm->loopback->cable_lock);
- t.min = cable->hw.channels_min;
- t.max = cable->hw.channels_max;
- mutex_unlock(&dpcm->loopback->cable_lock);
+ scoped_guard(mutex, &dpcm->loopback->cable_lock) {
+ t.min = cable->hw.channels_min;
+ t.max = cable->hw.channels_max;
+ }
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -1026,10 +1024,10 @@ static int rule_period_bytes(struct snd_pcm_hw_params *params,
struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- mutex_lock(&dpcm->loopback->cable_lock);
- t.min = cable->hw.period_bytes_min;
- t.max = cable->hw.period_bytes_max;
- mutex_unlock(&dpcm->loopback->cable_lock);
+ scoped_guard(mutex, &dpcm->loopback->cable_lock) {
+ t.min = cable->hw.period_bytes_min;
+ t.max = cable->hw.period_bytes_max;
+ }
t.openmin = 0;
t.openmax = 0;
t.integer = 0;
@@ -1047,9 +1045,8 @@ static void free_cable(struct snd_pcm_substream *substream)
return;
if (cable->streams[!substream->stream]) {
/* other stream is still alive */
- spin_lock_irq(&cable->lock);
+ guard(spinlock_irq)(&cable->lock);
cable->streams[substream->stream] = NULL;
- spin_unlock_irq(&cable->lock);
} else {
struct loopback_pcm *dpcm = substream->runtime->private_data;
@@ -1238,12 +1235,10 @@ static int loopback_open(struct snd_pcm_substream *substream)
int err = 0;
int dev = get_cable_index(substream);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm) {
- err = -ENOMEM;
- goto unlock;
- }
+ if (!dpcm)
+ return -ENOMEM;
dpcm->loopback = loopback;
dpcm->substream = substream;
@@ -1317,16 +1312,15 @@ static int loopback_open(struct snd_pcm_substream *substream)
else
runtime->hw = cable->hw;
- spin_lock_irq(&cable->lock);
- cable->streams[substream->stream] = dpcm;
- spin_unlock_irq(&cable->lock);
+ scoped_guard(spinlock_irq, &cable->lock) {
+ cable->streams[substream->stream] = dpcm;
+ }
unlock:
if (err < 0) {
free_cable(substream);
kfree(dpcm);
}
- mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -1338,9 +1332,8 @@ static int loopback_close(struct snd_pcm_substream *substream)
if (dpcm->cable->ops->close_substream)
err = dpcm->cable->ops->close_substream(dpcm);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
free_cable(substream);
- mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -1391,11 +1384,10 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate_shift;
- mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -1411,14 +1403,13 @@ static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
val = 80000;
if (val > 120000)
val = 120000;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
if (val != loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate_shift) {
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate_shift = val;
change = 1;
}
- mutex_unlock(&loopback->cable_lock);
return change;
}
@@ -1427,11 +1418,10 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol,
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify;
- mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -1443,14 +1433,13 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol,
int change = 0;
val = ucontrol->value.integer.value[0] ? 1 : 0;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
if (val != loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify) {
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify = val;
change = 1;
}
- mutex_unlock(&loopback->cable_lock);
return change;
}
@@ -1462,14 +1451,13 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol,
unsigned int val = 0;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
if (cable != NULL) {
unsigned int running = cable->running ^ cable->pause;
val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
}
- mutex_unlock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = val;
return 0;
}
@@ -1512,11 +1500,10 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol,
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate;
- mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -1536,11 +1523,10 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol,
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].channels;
- mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -1558,12 +1544,11 @@ static int loopback_access_get(struct snd_kcontrol *kcontrol,
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
snd_pcm_access_t access;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
access = loopback->setup[kcontrol->id.subdevice][kcontrol->id.device].access;
ucontrol->value.enumerated.item[0] = !is_access_interleaved(access);
- mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -1731,12 +1716,11 @@ static void print_cable_info(struct snd_info_entry *entry,
struct loopback *loopback = entry->private_data;
int sub, num;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
num = entry->name[strlen(entry->name)-1];
num = num == '0' ? 0 : 1;
for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
print_substream_info(buffer, loopback, sub, num);
- mutex_unlock(&loopback->cable_lock);
}
static int loopback_cable_proc_new(struct loopback *loopback, int cidx)
@@ -1765,10 +1749,9 @@ static void print_timer_source_info(struct snd_info_entry *entry,
{
struct loopback *loopback = entry->private_data;
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
snd_iprintf(buffer, "%s\n",
loopback->timer_source ? loopback->timer_source : "");
- mutex_unlock(&loopback->cable_lock);
}
static void change_timer_source_info(struct snd_info_entry *entry,
@@ -1777,10 +1760,9 @@ static void change_timer_source_info(struct snd_info_entry *entry,
struct loopback *loopback = entry->private_data;
char line[64];
- mutex_lock(&loopback->cable_lock);
+ guard(mutex)(&loopback->cable_lock);
if (!snd_info_get_line(buffer, line, sizeof(line)))
loopback_set_timer_source(loopback, strim(line));
- mutex_unlock(&loopback->cable_lock);
}
static int loopback_timer_source_proc_new(struct loopback *loopback)
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 6dac0b2523c1..1860ff75fe15 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -269,19 +269,19 @@ static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
static int dummy_systimer_start(struct snd_pcm_substream *substream)
{
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
+
+ guard(spinlock)(&dpcm->lock);
dpcm->base_time = jiffies;
dummy_systimer_rearm(dpcm);
- spin_unlock(&dpcm->lock);
return 0;
}
static int dummy_systimer_stop(struct snd_pcm_substream *substream)
{
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
+
+ guard(spinlock)(&dpcm->lock);
timer_delete(&dpcm->timer);
- spin_unlock(&dpcm->lock);
return 0;
}
@@ -303,15 +303,14 @@ static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
static void dummy_systimer_callback(struct timer_list *t)
{
struct dummy_systimer_pcm *dpcm = timer_container_of(dpcm, t, timer);
- unsigned long flags;
int elapsed = 0;
- spin_lock_irqsave(&dpcm->lock, flags);
- dummy_systimer_update(dpcm);
- dummy_systimer_rearm(dpcm);
- elapsed = dpcm->elapsed;
- dpcm->elapsed = 0;
- spin_unlock_irqrestore(&dpcm->lock, flags);
+ scoped_guard(spinlock_irqsave, &dpcm->lock) {
+ dummy_systimer_update(dpcm);
+ dummy_systimer_rearm(dpcm);
+ elapsed = dpcm->elapsed;
+ dpcm->elapsed = 0;
+ }
if (elapsed)
snd_pcm_period_elapsed(dpcm->substream);
}
@@ -320,13 +319,10 @@ static snd_pcm_uframes_t
dummy_systimer_pointer(struct snd_pcm_substream *substream)
{
struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- snd_pcm_uframes_t pos;
- spin_lock(&dpcm->lock);
+ guard(spinlock)(&dpcm->lock);
dummy_systimer_update(dpcm);
- pos = dpcm->frac_pos / HZ;
- spin_unlock(&dpcm->lock);
- return pos;
+ return dpcm->frac_pos / HZ;
}
static int dummy_systimer_create(struct snd_pcm_substream *substream)
@@ -724,10 +720,9 @@ static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
- spin_lock_irq(&dummy->mixer_lock);
+ guard(spinlock_irq)(&dummy->mixer_lock);
ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
return 0;
}
@@ -748,12 +743,11 @@ static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
right = mixer_volume_level_min;
if (right > mixer_volume_level_max)
right = mixer_volume_level_max;
- spin_lock_irq(&dummy->mixer_lock);
+ guard(spinlock_irq)(&dummy->mixer_lock);
change = dummy->mixer_volume[addr][0] != left ||
dummy->mixer_volume[addr][1] != right;
dummy->mixer_volume[addr][0] = left;
dummy->mixer_volume[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
return change;
}
@@ -773,10 +767,9 @@ static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
- spin_lock_irq(&dummy->mixer_lock);
+ guard(spinlock_irq)(&dummy->mixer_lock);
ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
return 0;
}
@@ -788,12 +781,11 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
left = ucontrol->value.integer.value[0] & 1;
right = ucontrol->value.integer.value[1] & 1;
- spin_lock_irq(&dummy->mixer_lock);
+ guard(spinlock_irq)(&dummy->mixer_lock);
change = dummy->capture_source[addr][0] != left &&
dummy->capture_source[addr][1] != right;
dummy->capture_source[addr][0] = left;
dummy->capture_source[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
return change;
}
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 670f8ba92c08..4af89822bf32 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -81,27 +81,21 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
static void uart_interrupt_tx(struct snd_mpu401 *mpu)
{
- unsigned long flags;
-
if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
- spin_lock_irqsave(&mpu->output_lock, flags);
+ guard(spinlock_irqsave)(&mpu->output_lock);
snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
}
}
static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
{
- unsigned long flags;
-
if (mpu->info_flags & MPU401_INFO_INPUT) {
- spin_lock_irqsave(&mpu->input_lock, flags);
+ guard(spinlock_irqsave)(&mpu->input_lock);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
snd_mpu401_uart_input_read(mpu);
else
snd_mpu401_uart_clear_rx(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
}
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
/* ok. for better Tx performance try do some output
@@ -158,12 +152,11 @@ EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
static void snd_mpu401_uart_timer(struct timer_list *t)
{
struct snd_mpu401 *mpu = timer_container_of(mpu, t, timer);
- unsigned long flags;
- spin_lock_irqsave(&mpu->timer_lock, flags);
- /*mpu->mode |= MPU401_MODE_TIMER;*/
- mod_timer(&mpu->timer, 1 + jiffies);
- spin_unlock_irqrestore(&mpu->timer_lock, flags);
+ scoped_guard(spinlock_irqsave, &mpu->timer_lock) {
+ /*mpu->mode |= MPU401_MODE_TIMER;*/
+ mod_timer(&mpu->timer, 1 + jiffies);
+ }
if (mpu->rmidi)
_snd_mpu401_uart_interrupt(mpu);
}
@@ -173,16 +166,13 @@ static void snd_mpu401_uart_timer(struct timer_list *t)
*/
static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
+ guard(spinlock_irqsave)(&mpu->timer_lock);
if (mpu->timer_invoked == 0) {
timer_setup(&mpu->timer, snd_mpu401_uart_timer, 0);
mod_timer(&mpu->timer, 1 + jiffies);
}
mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
MPU401_MODE_OUTPUT_TIMER;
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
}
/*
@@ -190,16 +180,13 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
*/
static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
+ guard(spinlock_irqsave)(&mpu->timer_lock);
if (mpu->timer_invoked) {
mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
~MPU401_MODE_OUTPUT_TIMER;
if (! mpu->timer_invoked)
timer_delete(&mpu->timer);
}
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
}
/*
@@ -210,10 +197,9 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
int ack)
{
- unsigned long flags;
int timeout, ok;
- spin_lock_irqsave(&mpu->input_lock, flags);
+ guard(spinlock_irqsave)(&mpu->input_lock);
if (mpu->hardware != MPU401_HW_TRID4DWAVE) {
mpu->write(mpu, 0x00, MPU401D(mpu));
/*snd_mpu401_uart_clear_rx(mpu);*/
@@ -244,7 +230,6 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
ok = 1;
} else
ok = 1;
- spin_unlock_irqrestore(&mpu->input_lock, flags);
if (!ok) {
dev_err(mpu->rmidi->dev,
"cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n",
@@ -358,7 +343,6 @@ static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
static void
snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_mpu401 *mpu;
int max = 64;
@@ -374,9 +358,8 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
}
/* read data in advance */
- spin_lock_irqsave(&mpu->input_lock, flags);
+ guard(spinlock_irqsave)(&mpu->input_lock);
snd_mpu401_uart_input_read(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
} else {
if (mpu->info_flags & MPU401_INFO_USE_TIMER)
snd_mpu401_uart_remove_timer(mpu, 1);
@@ -445,7 +428,6 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
static void
snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_mpu401 *mpu;
mpu = substream->rmidi->private_data;
@@ -460,9 +442,8 @@ snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
snd_mpu401_uart_add_timer(mpu, 0);
/* output pending data */
- spin_lock_irqsave(&mpu->output_lock, flags);
+ guard(spinlock_irqsave)(&mpu->output_lock);
snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
} else {
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
snd_mpu401_uart_remove_timer(mpu, 0);
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 91828f496738..d31eadf4be5f 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -304,11 +304,9 @@ static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
snd_mtpav_output_port_write(mtp_card, portp, substream);
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
}
@@ -334,14 +332,12 @@ static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
portp->mode |= MTPAV_MODE_INPUT_OPENED;
portp->input = substream;
if (mtp_card->share_irq++ == 0)
snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0;
}
@@ -352,14 +348,12 @@ static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
portp->input = NULL;
if (--mtp_card->share_irq == 0)
snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0;
}
@@ -370,15 +364,12 @@ static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
if (up)
portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
else
portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-
}
@@ -388,11 +379,10 @@ static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int
static void snd_mtpav_output_timer(struct timer_list *t)
{
- unsigned long flags;
struct mtpav *chip = timer_container_of(chip, t, timer);
int p;
- spin_lock_irqsave(&chip->spinlock, flags);
+ guard(spinlock_irqsave)(&chip->spinlock);
/* reprogram timer */
mod_timer(&chip->timer, 1 + jiffies);
/* process each port */
@@ -401,7 +391,6 @@ static void snd_mtpav_output_timer(struct timer_list *t)
if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
snd_mtpav_output_port_write(chip, portp, portp->output);
}
- spin_unlock_irqrestore(&chip->spinlock, flags);
}
/* spinlock held! */
@@ -423,12 +412,10 @@ static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
portp->output = substream;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0;
};
@@ -439,12 +426,10 @@ static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
- spin_lock_irqsave(&mtp_card->spinlock, flags);
+ guard(spinlock_irqsave)(&mtp_card->spinlock);
portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
portp->output = NULL;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
return 0;
};
@@ -455,21 +440,20 @@ static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, in
{
struct mtpav *mtp_card = substream->rmidi->private_data;
struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- if (up) {
- if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
- if (mtp_card->istimer++ == 0)
- snd_mtpav_add_output_timer(mtp_card);
- portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
+
+ scoped_guard(spinlock_irqsave, &mtp_card->spinlock) {
+ if (up) {
+ if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
+ if (mtp_card->istimer++ == 0)
+ snd_mtpav_add_output_timer(mtp_card);
+ portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
+ }
+ } else {
+ portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
+ if (--mtp_card->istimer == 0)
+ snd_mtpav_remove_output_timer(mtp_card);
}
- } else {
- portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
- if (--mtp_card->istimer == 0)
- snd_mtpav_remove_output_timer(mtp_card);
}
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
if (up)
snd_mtpav_output_write(substream);
@@ -550,9 +534,8 @@ static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
{
struct mtpav *mcard = dev_id;
- spin_lock(&mcard->spinlock);
+ guard(spinlock)(&mcard->spinlock);
snd_mtpav_read_bytes(mcard);
- spin_unlock(&mcard->spinlock);
return IRQ_HANDLED;
}
@@ -658,12 +641,10 @@ static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
static void snd_mtpav_free(struct snd_card *card)
{
struct mtpav *crd = card->private_data;
- unsigned long flags;
- spin_lock_irqsave(&crd->spinlock, flags);
+ guard(spinlock_irqsave)(&crd->spinlock);
if (crd->istimer > 0)
snd_mtpav_remove_output_timer(crd);
- spin_unlock_irqrestore(&crd->spinlock, flags);
}
/*
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index bbeebbe467ea..fe50b48c10e7 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -432,9 +432,8 @@ static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
{
struct mts64 *mts = snd_kcontrol_chip(kctl);
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
uctl->value.integer.value[0] = mts->smpte_switch;
- spin_unlock_irq(&mts->lock);
return 0;
}
@@ -445,14 +444,12 @@ static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
struct snd_ctl_elem_value *uctl)
{
struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
int val = !!uctl->value.integer.value[0];
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
if (mts->smpte_switch == val)
- goto __out;
+ return 0;
- changed = 1;
mts->smpte_switch = val;
if (mts->smpte_switch) {
mts64_smpte_start(mts->pardev->port,
@@ -462,9 +459,7 @@ static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
} else {
mts64_smpte_stop(mts->pardev->port);
}
-__out:
- spin_unlock_irq(&mts->lock);
- return changed;
+ return 1;
}
static const struct snd_kcontrol_new mts64_ctl_smpte_switch = {
@@ -515,9 +510,8 @@ static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,
struct mts64 *mts = snd_kcontrol_chip(kctl);
int idx = kctl->private_value;
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
uctl->value.integer.value[0] = mts->time[idx];
- spin_unlock_irq(&mts->lock);
return 0;
}
@@ -528,16 +522,14 @@ static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,
struct mts64 *mts = snd_kcontrol_chip(kctl);
int idx = kctl->private_value;
unsigned int time = uctl->value.integer.value[0] % 60;
- int changed = 0;
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
if (mts->time[idx] != time) {
- changed = 1;
mts->time[idx] = time;
+ return 1;
}
- spin_unlock_irq(&mts->lock);
- return changed;
+ return 0;
}
static const struct snd_kcontrol_new mts64_ctl_smpte_time_hours = {
@@ -600,9 +592,8 @@ static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,
{
struct mts64 *mts = snd_kcontrol_chip(kctl);
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
uctl->value.enumerated.item[0] = mts->fps;
- spin_unlock_irq(&mts->lock);
return 0;
}
@@ -611,18 +602,16 @@ static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *uctl)
{
struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
if (uctl->value.enumerated.item[0] >= 5)
return -EINVAL;
- spin_lock_irq(&mts->lock);
+ guard(spinlock_irq)(&mts->lock);
if (mts->fps != uctl->value.enumerated.item[0]) {
- changed = 1;
mts->fps = uctl->value.enumerated.item[0];
+ return 1;
}
- spin_unlock_irq(&mts->lock);
- return changed;
+ return 0;
}
static const struct snd_kcontrol_new mts64_ctl_smpte_fps = {
@@ -687,15 +676,14 @@ static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)
static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)
{
struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
--(mts->open_count);
if (mts->open_count == 0) {
/* We need the spinlock_irqsave here because we can still
have IRQs at this point */
- spin_lock_irqsave(&mts->lock, flags);
- mts64_device_close(mts);
- spin_unlock_irqrestore(&mts->lock, flags);
+ scoped_guard(spinlock_irqsave, &mts->lock) {
+ mts64_device_close(mts);
+ }
msleep(500);
@@ -710,29 +698,24 @@ static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *subst
{
struct mts64 *mts = substream->rmidi->private_data;
u8 data;
- unsigned long flags;
- spin_lock_irqsave(&mts->lock, flags);
+ guard(spinlock_irqsave)(&mts->lock);
while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
mts64_write_midi(mts, data, substream->number+1);
snd_rawmidi_transmit_ack(substream, 1);
}
- spin_unlock_irqrestore(&mts->lock, flags);
}
static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&mts->lock, flags);
+ guard(spinlock_irqsave)(&mts->lock);
if (up)
mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;
else
mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;
-
- spin_unlock_irqrestore(&mts->lock, flags);
}
static const struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
@@ -819,7 +802,7 @@ static void snd_mts64_interrupt(void *private)
if (!mts)
return;
- spin_lock(&mts->lock);
+ guard(spinlock)(&mts->lock);
ret = mts64_read(mts->pardev->port);
data = ret & 0x00ff;
status = ret >> 8;
@@ -828,13 +811,11 @@ static void snd_mts64_interrupt(void *private)
mts->current_midi_input_port = mts64_map_midi_input(data);
} else {
if (mts->current_midi_input_port == -1)
- goto __out;
+ return;
substream = mts->midi_input_substream[mts->current_midi_input_port];
if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
snd_rawmidi_receive(substream, &data, 1);
}
-__out:
- spin_unlock(&mts->lock);
}
static void snd_mts64_attach(struct parport *p)
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index cd9642a6689b..fa8a2ccbbd51 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -25,7 +25,6 @@ MODULE_LICENSE("GPL");
static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
{
- unsigned long flags;
unsigned long port;
/*
@@ -35,20 +34,17 @@ static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigne
port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
- spin_lock_irqsave(&opl3->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl3->reg_lock);
outb((unsigned char) cmd, port);
udelay(10);
outb((unsigned char) val, port + 1);
udelay(30);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
}
static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
{
- unsigned long flags;
unsigned long port;
/*
@@ -58,7 +54,7 @@ static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigne
port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
- spin_lock_irqsave(&opl3->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl3->reg_lock);
outb((unsigned char) cmd, port);
inb(opl3->l_port);
@@ -67,8 +63,6 @@ static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigne
outb((unsigned char) val, port + 1);
inb(opl3->l_port);
inb(opl3->l_port);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
}
static int snd_opl3_detect(struct snd_opl3 * opl3)
@@ -142,34 +136,30 @@ static int snd_opl3_detect(struct snd_opl3 * opl3)
static int snd_opl3_timer1_start(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
unsigned int ticks;
struct snd_opl3 *opl3;
opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->timer_lock);
ticks = timer->sticks;
tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
opl3->timer_enable = tmp;
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks); /* timer 1 count */
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
return 0;
}
static int snd_opl3_timer1_stop(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
struct snd_opl3 *opl3;
opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->timer_lock);
tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
opl3->timer_enable = tmp;
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
return 0;
}
@@ -179,34 +169,30 @@ static int snd_opl3_timer1_stop(struct snd_timer * timer)
static int snd_opl3_timer2_start(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
unsigned int ticks;
struct snd_opl3 *opl3;
opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->timer_lock);
ticks = timer->sticks;
tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
opl3->timer_enable = tmp;
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks); /* timer 1 count */
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
return 0;
}
static int snd_opl3_timer2_stop(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
struct snd_opl3 *opl3;
opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->timer_lock);
tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
opl3->timer_enable = tmp;
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
return 0;
}
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index de7449cb6515..6d3c5b5a35ff 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -234,29 +234,27 @@ void snd_opl3_timer_func(struct timer_list *t)
{
struct snd_opl3 *opl3 = timer_container_of(opl3, t, tlist);
- unsigned long flags;
int again = 0;
int i;
- spin_lock_irqsave(&opl3->voice_lock, flags);
- for (i = 0; i < opl3->max_voices; i++) {
- struct snd_opl3_voice *vp = &opl3->voices[i];
- if (vp->state > 0 && vp->note_off_check) {
- if (vp->note_off == jiffies)
- snd_opl3_note_off_unsafe(opl3, vp->note, 0,
- vp->chan);
- else
- again++;
+ scoped_guard(spinlock_irqsave, &opl3->voice_lock) {
+ for (i = 0; i < opl3->max_voices; i++) {
+ struct snd_opl3_voice *vp = &opl3->voices[i];
+ if (vp->state > 0 && vp->note_off_check) {
+ if (vp->note_off == jiffies)
+ snd_opl3_note_off_unsafe(opl3, vp->note, 0,
+ vp->chan);
+ else
+ again++;
+ }
}
}
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->sys_timer_lock);
if (again)
mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */
else
opl3->sys_timer_status = 0;
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
}
/*
@@ -264,13 +262,11 @@ void snd_opl3_timer_func(struct timer_list *t)
*/
static void snd_opl3_start_timer(struct snd_opl3 *opl3)
{
- unsigned long flags;
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
+ guard(spinlock_irqsave)(&opl3->sys_timer_lock);
if (! opl3->sys_timer_status) {
mod_timer(&opl3->tlist, jiffies + 1);
opl3->sys_timer_status = 1;
}
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
}
/* ------------------------------ */
@@ -309,7 +305,6 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
struct fm_patch *patch;
struct fm_instrument *fm;
- unsigned long flags;
opl3 = p;
@@ -337,20 +332,17 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
prg = chan->midi_program;
}
- spin_lock_irqsave(&opl3->voice_lock, flags);
+ guard(spinlock_irqsave)(&opl3->voice_lock);
if (use_internal_drums) {
snd_opl3_drum_switch(opl3, note, vel, 1, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
return;
}
__extra_prg:
patch = snd_opl3_find_patch(opl3, prg, bank, 0);
- if (!patch) {
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
+ if (!patch)
return;
- }
fm = &patch->inst;
switch (patch->type) {
@@ -364,7 +356,6 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
}
fallthrough;
default:
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
return;
}
opl3_dbg(opl3, " --> OPL%i instrument: %s\n",
@@ -378,10 +369,8 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
voice = snd_opl3_oss_map[chan->number];
}
- if (voice < 0) {
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
+ if (voice < 0)
return;
- }
if (voice < MAX_OPL2_VOICES) {
/* Left register block for voices 0 .. 8 */
@@ -597,7 +586,6 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
opl3_dbg(opl3, " *** allocating extra program\n");
goto __extra_prg;
}
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
}
static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
@@ -686,11 +674,9 @@ void snd_opl3_note_off(void *p, int note, int vel,
struct snd_midi_channel *chan)
{
struct snd_opl3 *opl3 = p;
- unsigned long flags;
- spin_lock_irqsave(&opl3->voice_lock, flags);
+ guard(spinlock_irqsave)(&opl3->voice_lock);
snd_opl3_note_off_unsafe(p, note, vel, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
}
/*
@@ -764,9 +750,7 @@ static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *
int voice;
struct snd_opl3_voice *vp;
- unsigned long flags;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
+ guard(spinlock_irqsave)(&opl3->voice_lock);
if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
for (voice = 0; voice < opl3->max_voices; voice++) {
@@ -782,7 +766,6 @@ static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *
snd_opl3_update_pitch(opl3, voice);
}
}
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
}
/*
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index 9fc78b7fb780..d3278428d360 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -40,13 +40,11 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3)
int idx;
struct snd_hwdep *hwdep = opl3->hwdep;
- mutex_lock(&hwdep->open_mutex);
- if (hwdep->used) {
- mutex_unlock(&hwdep->open_mutex);
- return -EBUSY;
+ scoped_guard(mutex, &hwdep->open_mutex) {
+ if (hwdep->used)
+ return -EBUSY;
+ hwdep->used++;
}
- hwdep->used++;
- mutex_unlock(&hwdep->open_mutex);
snd_opl3_reset(opl3);
@@ -68,22 +66,21 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3)
void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
{
- unsigned long flags;
struct snd_hwdep *hwdep;
/* Stop system timer */
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (opl3->sys_timer_status) {
- timer_delete(&opl3->tlist);
- opl3->sys_timer_status = 0;
+ scoped_guard(spinlock_irq, &opl3->sys_timer_lock) {
+ if (opl3->sys_timer_status) {
+ timer_delete(&opl3->tlist);
+ opl3->sys_timer_status = 0;
+ }
}
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
snd_opl3_reset(opl3);
hwdep = opl3->hwdep;
- mutex_lock(&hwdep->open_mutex);
- hwdep->used--;
- mutex_unlock(&hwdep->open_mutex);
+ scoped_guard(mutex, &hwdep->open_mutex) {
+ hwdep->used--;
+ }
wake_up(&hwdep->open_wait);
}
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index ef6b2d533958..44fbc6bf0654 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -47,10 +47,9 @@ EXPORT_SYMBOL(snd_opl4_read);
void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
{
- unsigned long flags;
u8 memcfg;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
@@ -65,18 +64,15 @@ void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size
insb(opl4->pcm_port + 1, buf, size);
snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
EXPORT_SYMBOL(snd_opl4_read_memory);
void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
{
- unsigned long flags;
u8 memcfg;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
@@ -91,8 +87,6 @@ void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, i
outsb(opl4->pcm_port + 1, buf, size);
snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
EXPORT_SYMBOL(snd_opl4_write_memory);
diff --git a/sound/drivers/opl4/opl4_mixer.c b/sound/drivers/opl4/opl4_mixer.c
index fa1e6eff43ab..deebb8636437 100644
--- a/sound/drivers/opl4/opl4_mixer.c
+++ b/sound/drivers/opl4/opl4_mixer.c
@@ -19,13 +19,11 @@ static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
u8 reg = kcontrol->private_value;
u8 value;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
value = snd_opl4_read(opl4, reg);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
ucontrol->value.integer.value[0] = 7 - (value & 7);
ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
return 0;
@@ -34,16 +32,14 @@ static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
u8 reg = kcontrol->private_value;
u8 value, old_value;
value = (7 - (ucontrol->value.integer.value[0] & 7)) |
((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
old_value = snd_opl4_read(opl4, reg);
snd_opl4_write(opl4, reg, value);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
return value != old_value;
}
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index f2149091e10a..fd0ba4704d9f 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -14,13 +14,10 @@ static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
{
struct snd_opl4 *opl4 = entry->private_data;
- mutex_lock(&opl4->access_mutex);
- if (opl4->memory_access) {
- mutex_unlock(&opl4->access_mutex);
+ guard(mutex)(&opl4->access_mutex);
+ if (opl4->memory_access)
return -EBUSY;
- }
opl4->memory_access++;
- mutex_unlock(&opl4->access_mutex);
return 0;
}
@@ -29,9 +26,8 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
{
struct snd_opl4 *opl4 = entry->private_data;
- mutex_lock(&opl4->access_mutex);
+ guard(mutex)(&opl4->access_mutex);
opl4->memory_access--;
- mutex_unlock(&opl4->access_mutex);
return 0;
}
diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c
index f59ca660c616..7bb22089a093 100644
--- a/sound/drivers/opl4/opl4_seq.c
+++ b/sound/drivers/opl4/opl4_seq.c
@@ -63,24 +63,18 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i
struct snd_opl4 *opl4 = private_data;
int err;
- mutex_lock(&opl4->access_mutex);
-
- if (opl4->used) {
- mutex_unlock(&opl4->access_mutex);
- return -EBUSY;
- }
- opl4->used++;
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- err = snd_opl4_seq_use_inc(opl4);
- if (err < 0) {
- mutex_unlock(&opl4->access_mutex);
- return err;
+ scoped_guard(mutex, &opl4->access_mutex) {
+ if (opl4->used)
+ return -EBUSY;
+ opl4->used++;
+
+ if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
+ err = snd_opl4_seq_use_inc(opl4);
+ if (err < 0)
+ return err;
}
}
- mutex_unlock(&opl4->access_mutex);
-
snd_opl4_synth_reset(opl4);
return 0;
}
@@ -91,9 +85,9 @@ static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe
snd_opl4_synth_shutdown(opl4);
- mutex_lock(&opl4->access_mutex);
- opl4->used--;
- mutex_unlock(&opl4->access_mutex);
+ scoped_guard(mutex, &opl4->access_mutex) {
+ opl4->used--;
+ }
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
snd_opl4_seq_use_dec(opl4);
diff --git a/sound/drivers/opl4/opl4_synth.c b/sound/drivers/opl4/opl4_synth.c
index 34e2bd52bba1..82dbb8519ab1 100644
--- a/sound/drivers/opl4/opl4_synth.c
+++ b/sound/drivers/opl4/opl4_synth.c
@@ -272,13 +272,12 @@ static const unsigned char snd_opl4_volume_table[128] = {
*/
void snd_opl4_synth_reset(struct snd_opl4 *opl4)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++)
- snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &opl4->reg_lock) {
+ for (i = 0; i < OPL4_MAX_VOICES; i++)
+ snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
+ }
INIT_LIST_HEAD(&opl4->off_voices);
INIT_LIST_HEAD(&opl4->on_voices);
@@ -296,14 +295,12 @@ void snd_opl4_synth_reset(struct snd_opl4 *opl4)
*/
void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
for (i = 0; i < OPL4_MAX_VOICES; i++)
snd_opl4_write(opl4, OPL4_REG_MISC + i,
opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
/*
@@ -313,17 +310,15 @@ static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_mid
void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
{
int i;
- unsigned long flags;
struct opl4_voice *voice;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
for (i = 0; i < OPL4_MAX_VOICES; i++) {
voice = &opl4->voices[i];
if (voice->chan == chan && voice->note == note) {
func(opl4, voice);
}
}
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
/*
@@ -334,17 +329,15 @@ static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
{
int i;
- unsigned long flags;
struct opl4_voice *voice;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
for (i = 0; i < OPL4_MAX_VOICES; i++) {
voice = &opl4->voices[i];
if (voice->chan == chan) {
func(opl4, voice);
}
}
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
/*
@@ -354,16 +347,14 @@ static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
{
int i;
- unsigned long flags;
struct opl4_voice *voice;
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
for (i = 0; i < OPL4_MAX_VOICES; i++) {
voice = &opl4->voices[i];
if (voice->chan)
func(opl4, voice);
}
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
@@ -486,7 +477,6 @@ void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_cha
struct opl4_voice *voice[2];
const struct opl4_sound *sound[2];
int voices = 0, i;
- unsigned long flags;
/* determine the number of voices and voice parameters */
i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
@@ -501,41 +491,41 @@ void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_cha
}
/* allocate and initialize the needed voices */
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < voices; i++) {
- voice[i] = snd_opl4_get_voice(opl4);
- list_move_tail(&voice[i]->list, &opl4->on_voices);
- voice[i]->chan = chan;
- voice[i]->note = note;
- voice[i]->velocity = vel & 0x7f;
- voice[i]->sound = sound[i];
- }
+ scoped_guard(spinlock_irqsave, &opl4->reg_lock) {
+ for (i = 0; i < voices; i++) {
+ voice[i] = snd_opl4_get_voice(opl4);
+ list_move_tail(&voice[i]->list, &opl4->on_voices);
+ voice[i]->chan = chan;
+ voice[i]->note = note;
+ voice[i]->velocity = vel & 0x7f;
+ voice[i]->sound = sound[i];
+ }
- /* set tone number (triggers header loading) */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_f_number =
- (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
- snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
- voice[i]->reg_f_number);
- snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
- sound[i]->tone & 0xff);
- }
+ /* set tone number (triggers header loading) */
+ for (i = 0; i < voices; i++) {
+ voice[i]->reg_f_number =
+ (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
+ snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
+ voice[i]->reg_f_number);
+ snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
+ sound[i]->tone & 0xff);
+ }
- /* set parameters which can be set while loading */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
- snd_opl4_update_pan(opl4, voice[i]);
- snd_opl4_update_pitch(opl4, voice[i]);
- voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
- snd_opl4_update_volume(opl4, voice[i]);
+ /* set parameters which can be set while loading */
+ for (i = 0; i < voices; i++) {
+ voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
+ snd_opl4_update_pan(opl4, voice[i]);
+ snd_opl4_update_pitch(opl4, voice[i]);
+ voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
+ snd_opl4_update_volume(opl4, voice[i]);
+ }
}
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
/* wait for completion of loading */
snd_opl4_wait_for_wave_headers(opl4);
/* set remaining parameters */
- spin_lock_irqsave(&opl4->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl4->reg_lock);
for (i = 0; i < voices; i++) {
snd_opl4_update_tone_parameters(opl4, voice[i]);
voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
@@ -549,7 +539,6 @@ void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_cha
snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
voice[i]->reg_misc);
}
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index b4fa6625a3d6..b903a138fc2a 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -496,29 +496,25 @@ static void snd_portman_midi_input_trigger(struct snd_rawmidi_substream *substre
int up)
{
struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&pm->reg_lock, flags);
+ guard(spinlock_irqsave)(&pm->reg_lock);
if (up)
pm->mode[substream->number] |= PORTMAN2X4_MODE_INPUT_TRIGGERED;
else
pm->mode[substream->number] &= ~PORTMAN2X4_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&pm->reg_lock, flags);
}
static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
unsigned char byte;
- spin_lock_irqsave(&pm->reg_lock, flags);
+ guard(spinlock_irqsave)(&pm->reg_lock);
if (up) {
while ((snd_rawmidi_transmit(substream, &byte, 1) == 1))
portman_write_midi(pm, substream->number, byte);
}
- spin_unlock_irqrestore(&pm->reg_lock, flags);
}
static const struct snd_rawmidi_ops snd_portman_midi_output = {
@@ -590,7 +586,7 @@ static void snd_portman_interrupt(void *userdata)
unsigned char midivalue = 0;
struct portman *pm = ((struct snd_card*)userdata)->private_data;
- spin_lock(&pm->reg_lock);
+ guard(spinlock)(&pm->reg_lock);
/* While any input data is waiting */
while ((portman_read_status(pm) & INT_REQ) == INT_REQ) {
@@ -617,8 +613,6 @@ static void snd_portman_interrupt(void *userdata)
}
}
-
- spin_unlock(&pm->reg_lock);
}
static void snd_portman_attach(struct parport *p)
diff --git a/sound/drivers/serial-generic.c b/sound/drivers/serial-generic.c
index 21ae053c0576..766206c6ca75 100644
--- a/sound/drivers/serial-generic.c
+++ b/sound/drivers/serial-generic.c
@@ -37,6 +37,8 @@ MODULE_LICENSE("GPL");
#define SERIAL_TX_STATE_ACTIVE 1
#define SERIAL_TX_STATE_WAKEUP 2
+#define INTERNAL_BUF_SIZE 256
+
struct snd_serial_generic {
struct serdev_device *serdev;
@@ -51,6 +53,7 @@ struct snd_serial_generic {
struct work_struct tx_work;
unsigned long tx_state;
+ char tx_buf[INTERNAL_BUF_SIZE];
};
static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
@@ -61,11 +64,8 @@ static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
schedule_work(&drvdata->tx_work);
}
-#define INTERNAL_BUF_SIZE 256
-
static void snd_serial_generic_tx_work(struct work_struct *work)
{
- static char buf[INTERNAL_BUF_SIZE];
int num_bytes;
struct snd_serial_generic *drvdata = container_of(work, struct snd_serial_generic,
tx_work);
@@ -78,8 +78,10 @@ static void snd_serial_generic_tx_work(struct work_struct *work)
if (!test_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode))
break;
- num_bytes = snd_rawmidi_transmit_peek(substream, buf, INTERNAL_BUF_SIZE);
- num_bytes = serdev_device_write_buf(drvdata->serdev, buf, num_bytes);
+ num_bytes = snd_rawmidi_transmit_peek(substream, drvdata->tx_buf,
+ INTERNAL_BUF_SIZE);
+ num_bytes = serdev_device_write_buf(drvdata->serdev, drvdata->tx_buf,
+ num_bytes);
if (!num_bytes)
break;
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 52772ccfc377..3c28961091b1 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -281,29 +281,24 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
struct snd_uart16550 *uart;
uart = dev_id;
- spin_lock(&uart->open_lock);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
- spin_unlock(&uart->open_lock);
+ guard(spinlock)(&uart->open_lock);
+ if (uart->filemode == SERIAL_MODE_NOT_OPENED)
return IRQ_NONE;
- }
/* indicate to the UART that the interrupt has been serviced */
inb(uart->base + UART_IIR);
snd_uart16550_io_loop(uart);
- spin_unlock(&uart->open_lock);
return IRQ_HANDLED;
}
/* When the polling mode, this function calls snd_uart16550_io_loop. */
static void snd_uart16550_buffer_timer(struct timer_list *t)
{
- unsigned long flags;
struct snd_uart16550 *uart;
uart = timer_container_of(uart, t, buffer_timer);
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
snd_uart16550_del_timer(uart);
snd_uart16550_io_loop(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
}
/*
@@ -499,71 +494,61 @@ static void snd_uart16550_do_close(struct snd_uart16550 * uart)
static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
snd_uart16550_do_open(uart);
uart->filemode |= SERIAL_MODE_INPUT_OPEN;
uart->midi_input[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
return 0;
}
static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
uart->filemode &= ~SERIAL_MODE_INPUT_OPEN;
uart->midi_input[substream->number] = NULL;
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
return 0;
}
static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream,
int up)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
if (up)
uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED;
else
uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
}
static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
snd_uart16550_do_open(uart);
uart->filemode |= SERIAL_MODE_OUTPUT_OPEN;
uart->midi_output[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
return 0;
};
static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN;
uart->midi_output[substream->number] = NULL;
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
return 0;
};
@@ -632,7 +617,6 @@ static int snd_uart16550_output_byte(struct snd_uart16550 *uart,
static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
unsigned char midi_byte, addr_byte;
struct snd_uart16550 *uart = substream->rmidi->private_data;
char first;
@@ -643,7 +627,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
* variables (ie buff_in & buff_out)
*/
- spin_lock_irqsave(&uart->open_lock, flags);
+ guard(spinlock_irqsave)(&uart->open_lock);
if (uart->irq < 0) /* polling */
snd_uart16550_io_loop(uart);
@@ -718,21 +702,19 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
}
lasttime = jiffies;
}
- spin_unlock_irqrestore(&uart->open_lock, flags);
}
static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream,
int up)
{
- unsigned long flags;
struct snd_uart16550 *uart = substream->rmidi->private_data;
- spin_lock_irqsave(&uart->open_lock, flags);
- if (up)
- uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
- else
- uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &uart->open_lock) {
+ if (up)
+ uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
+ else
+ uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
+ }
if (up)
snd_uart16550_output_write(substream);
}
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 7f25fa7c0404..52b93407bfe3 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -344,12 +344,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
*/
int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
{
- int err;
-
- mutex_lock(&chip->lock);
- err = vx_send_msg_nolock(chip, rmh);
- mutex_unlock(&chip->lock);
- return err;
+ guard(mutex)(&chip->lock);
+ return vx_send_msg_nolock(chip, rmh);
}
@@ -404,12 +400,8 @@ int vx_send_rih_nolock(struct vx_core *chip, int cmd)
*/
int vx_send_rih(struct vx_core *chip, int cmd)
{
- int err;
-
- mutex_lock(&chip->lock);
- err = vx_send_rih_nolock(chip, cmd);
- mutex_unlock(&chip->lock);
- return err;
+ guard(mutex)(&chip->lock);
+ return vx_send_rih_nolock(chip, cmd);
}
#define END_OF_RESET_WAIT_TIME 500 /* us */
@@ -481,13 +473,12 @@ static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)
int err;
vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT);
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
err = vx_send_msg_nolock(chip, &chip->irq_rmh);
if (err < 0)
*ret = 0;
else
*ret = chip->irq_rmh.Stat[0];
- mutex_unlock(&chip->lock);
return err;
}
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index 0a51ecdc084a..9dc5cecaa86a 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -25,9 +25,8 @@ static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int dat
if (chip->chip_status & VX_STAT_IS_STALE)
return;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
chip->ops->write_codec(chip, codec, data);
- mutex_unlock(&chip->lock);
}
/*
@@ -166,9 +165,8 @@ static void vx_change_audio_source(struct vx_core *chip, int src)
if (chip->chip_status & VX_STAT_IS_STALE)
return;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
chip->ops->change_audio_source(chip, src);
- mutex_unlock(&chip->lock);
}
@@ -411,10 +409,10 @@ static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int codec = kcontrol->id.index;
- mutex_lock(&chip->mixer_mutex);
+
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->output_level[codec][0];
ucontrol->value.integer.value[1] = chip->output_level[codec][1];
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -429,16 +427,14 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
val[1] = ucontrol->value.integer.value[1];
if (val[0] > vmax || val[1] > vmax)
return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (val[0] != chip->output_level[codec][0] ||
val[1] != chip->output_level[codec][1]) {
vx_set_analog_output_level(chip, codec, val[0], val[1]);
chip->output_level[codec][0] = val[0];
chip->output_level[codec][1] = val[1];
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -490,14 +486,12 @@ static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
if (ucontrol->value.enumerated.item[0] > 1)
return -EINVAL;
}
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
chip->audio_source_target = ucontrol->value.enumerated.item[0];
vx_sync_audio_source(chip);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -534,14 +528,12 @@ static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
if (ucontrol->value.enumerated.item[0] > 2)
return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
chip->clock_mode = ucontrol->value.enumerated.item[0];
vx_set_clock(chip, chip->freq);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -571,10 +563,9 @@ static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
int audio = kcontrol->private_value & 0xff;
int capture = (kcontrol->private_value >> 8) & 1;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -589,15 +580,13 @@ static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
val[1] = ucontrol->value.integer.value[1];
if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (val[0] != chip->audio_gain[capture][audio] ||
val[1] != chip->audio_gain[capture][audio+1]) {
vx_set_audio_gain(chip, audio, capture, val[0]);
vx_set_audio_gain(chip, audio+1, capture, val[1]);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -606,10 +595,9 @@ static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -624,17 +612,15 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (val[0] != chip->audio_monitor[audio] ||
val[1] != chip->audio_monitor[audio+1]) {
vx_set_monitor_level(chip, audio, val[0],
chip->audio_monitor_active[audio]);
vx_set_monitor_level(chip, audio+1, val[1],
chip->audio_monitor_active[audio+1]);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -645,10 +631,9 @@ static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_active[audio];
ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -657,17 +642,15 @@ static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
vx_set_audio_switch(chip, audio,
!!ucontrol->value.integer.value[0]);
vx_set_audio_switch(chip, audio+1,
!!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -676,10 +659,9 @@ static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -688,17 +670,15 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
!!ucontrol->value.integer.value[0]);
vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
!!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -754,12 +734,11 @@ static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
@@ -781,14 +760,12 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
(ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) |
(ucontrol->value.iec958.status[3] << 24);
- mutex_lock(&chip->mixer_mutex);
+ guard(mutex)(&chip->mixer_mutex);
if (chip->uer_bits != val) {
chip->uer_bits = val;
vx_set_iec958_status(chip, val);
- mutex_unlock(&chip->mixer_mutex);
return 1;
}
- mutex_unlock(&chip->mixer_mutex);
return 0;
}
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index defc489494af..7fd8f413d6cf 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -630,12 +630,11 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
/* we don't need irqsave here, because this function
* is called from either trigger callback or irq handler
*/
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
vx_pseudo_dma_write(chip, runtime, pipe, size);
err = vx_notify_end_of_buffer(chip, pipe);
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- mutex_unlock(&chip->lock);
return err;
}
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
index 3eca22151225..1d90db3b0abd 100644
--- a/sound/drivers/vx/vx_uer.c
+++ b/sound/drivers/vx/vx_uer.c
@@ -49,7 +49,7 @@ static int vx_read_one_cbit(struct vx_core *chip, int index)
{
int val;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
if (chip->type >= VX_TYPE_VXPOCKET) {
vx_outb(chip, CSUER, 1); /* read */
vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
@@ -59,7 +59,6 @@ static int vx_read_one_cbit(struct vx_core *chip, int index)
vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
val = (vx_inl(chip, RUER) >> 7) & 0x01;
}
- mutex_unlock(&chip->lock);
return val;
}
@@ -71,7 +70,7 @@ static int vx_read_one_cbit(struct vx_core *chip, int index)
static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
{
val = !!val; /* 0 or 1 */
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
if (vx_is_pcmcia(chip)) {
vx_outb(chip, CSUER, 0); /* write */
vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
@@ -79,7 +78,6 @@ static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
vx_outl(chip, CSUER, 0); /* write */
vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
}
- mutex_unlock(&chip->lock);
}
/*
@@ -178,10 +176,10 @@ static void vx_change_clock_source(struct vx_core *chip, int source)
{
/* we mute DAC to prevent clicks */
vx_toggle_dac_mute(chip, 1);
- mutex_lock(&chip->lock);
- chip->ops->set_clock_source(chip, source);
- chip->clock_source = source;
- mutex_unlock(&chip->lock);
+ scoped_guard(mutex, &chip->lock) {
+ chip->ops->set_clock_source(chip, source);
+ chip->clock_source = source;
+ }
/* unmute */
vx_toggle_dac_mute(chip, 0);
}
@@ -198,7 +196,7 @@ void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
clock = vx_calc_clock_from_freq(chip, freq);
dev_dbg(chip->card->dev,
"set internal clock to 0x%x from freq %d\n", clock, freq);
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
if (vx_is_pcmcia(chip)) {
vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
vx_outb(chip, LOFREQ, clock & 0xff);
@@ -206,7 +204,6 @@ void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
vx_outl(chip, LOFREQ, clock & 0xff);
}
- mutex_unlock(&chip->lock);
}
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 7fc51f829ecc..5cdc34877fc1 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -1688,20 +1688,16 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
struct pkt_desc *descs;
int i, type, tag, err;
- mutex_lock(&s->mutex);
+ guard(mutex)(&s->mutex);
if (WARN_ON(amdtp_stream_running(s) ||
- (s->data_block_quadlets < 1))) {
- err = -EBADFD;
- goto err_unlock;
- }
+ (s->data_block_quadlets < 1)))
+ return -EBADFD;
if (s->direction == AMDTP_IN_STREAM) {
// NOTE: IT context should be used for constant IRQ.
- if (is_irq_target) {
- err = -EINVAL;
- goto err_unlock;
- }
+ if (is_irq_target)
+ return -EINVAL;
s->data_block_counter = UINT_MAX;
} else {
@@ -1725,7 +1721,7 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
err = iso_packets_buffer_init(&s->buffer, s->unit, queue_size, max_ctx_payload_size, dir);
if (err < 0)
- goto err_unlock;
+ return err;
s->queue_size = queue_size;
s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
@@ -1846,8 +1842,6 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
if (err < 0)
goto err_pkt_descs;
- mutex_unlock(&s->mutex);
-
return 0;
err_pkt_descs:
kfree(s->packet_descs);
@@ -1863,8 +1857,6 @@ err_context:
s->context = ERR_PTR(-1);
err_buffer:
iso_packets_buffer_destroy(&s->buffer, s->unit);
-err_unlock:
- mutex_unlock(&s->mutex);
return err;
}
@@ -1934,12 +1926,10 @@ EXPORT_SYMBOL(amdtp_stream_update);
*/
static void amdtp_stream_stop(struct amdtp_stream *s)
{
- mutex_lock(&s->mutex);
+ guard(mutex)(&s->mutex);
- if (!amdtp_stream_running(s)) {
- mutex_unlock(&s->mutex);
+ if (!amdtp_stream_running(s))
return;
- }
cancel_work_sync(&s->period_work);
fw_iso_context_stop(s->context);
@@ -1955,8 +1945,6 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
if (s->domain->replay.enable)
kfree(s->ctx_data.tx.cache.descs);
}
-
- mutex_unlock(&s->mutex);
}
/**
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index 4ebaeff16455..01e2c4cc03d4 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -122,9 +122,9 @@ bebob_card_free(struct snd_card *card)
{
struct snd_bebob *bebob = card->private_data;
- mutex_lock(&devices_mutex);
- clear_bit(bebob->card_index, devices_used);
- mutex_unlock(&devices_mutex);
+ scoped_guard(mutex, &devices_mutex) {
+ clear_bit(bebob->card_index, devices_used);
+ }
snd_bebob_stream_destroy_duplex(bebob);
@@ -207,25 +207,21 @@ static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *en
return -ENODEV;
}
- mutex_lock(&devices_mutex);
- for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
- if (!test_bit(card_index, devices_used) && enable[card_index])
- break;
- }
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
- return -ENOENT;
- }
+ scoped_guard(mutex, &devices_mutex) {
+ for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
+ if (!test_bit(card_index, devices_used) && enable[card_index])
+ break;
+ }
+ if (card_index >= SNDRV_CARDS)
+ return -ENOENT;
- err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE,
- sizeof(*bebob), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
- return err;
+ err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE,
+ sizeof(*bebob), &card);
+ if (err < 0)
+ return err;
+ card->private_free = bebob_card_free;
+ set_bit(card_index, devices_used);
}
- card->private_free = bebob_card_free;
- set_bit(card_index, devices_used);
- mutex_unlock(&devices_mutex);
bebob = card->private_data;
bebob->unit = fw_unit_get(unit);
diff --git a/sound/firewire/bebob/bebob_hwdep.c b/sound/firewire/bebob/bebob_hwdep.c
index 5779e99a6bb2..216d1fceb6e7 100644
--- a/sound/firewire/bebob/bebob_hwdep.c
+++ b/sound/firewire/bebob/bebob_hwdep.c
@@ -53,18 +53,14 @@ static __poll_t
hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
{
struct snd_bebob *bebob = hwdep->private_data;
- __poll_t events;
poll_wait(file, &bebob->hwdep_wait, wait);
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
if (bebob->dev_lock_changed)
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&bebob->lock);
-
- return events;
+ return 0;
}
static int
@@ -90,39 +86,27 @@ hwdep_get_info(struct snd_bebob *bebob, void __user *arg)
static int
hwdep_lock(struct snd_bebob *bebob)
{
- int err;
-
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
if (bebob->dev_lock_count == 0) {
bebob->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&bebob->lock);
-
- return err;
}
static int
hwdep_unlock(struct snd_bebob *bebob)
{
- int err;
-
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
if (bebob->dev_lock_count == -1) {
bebob->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&bebob->lock);
-
- return err;
}
static int
@@ -130,10 +114,9 @@ hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_bebob *bebob = hwdep->private_data;
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
if (bebob->dev_lock_count == -1)
bebob->dev_lock_count = 0;
- spin_unlock_irq(&bebob->lock);
return 0;
}
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c
index 177699e1be11..376a9a175479 100644
--- a/sound/firewire/bebob/bebob_maudio.c
+++ b/sound/firewire/bebob/bebob_maudio.c
@@ -265,7 +265,7 @@ snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
if (!params)
return -ENOMEM;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
bebob->maudio_special_quirk = (void *)params;
params->is1814 = is1814;
@@ -277,12 +277,12 @@ snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
if (err < 0) {
dev_err(&bebob->unit->device,
"fail to initialize clock params: %d\n", err);
- goto end;
+ return err;
}
err = add_special_controls(bebob);
if (err < 0)
- goto end;
+ return err;
special_stream_formation_set(bebob);
@@ -293,8 +293,6 @@ snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
bebob->midi_input_ports = 2;
bebob->midi_output_ports = 2;
}
-end:
- mutex_unlock(&bebob->mutex);
return err;
}
@@ -383,14 +381,12 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
if (id >= ARRAY_SIZE(special_clk_types))
return -EINVAL;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
err = avc_maudio_set_special_clk(bebob, id,
params->dig_in_fmt,
params->dig_out_fmt,
params->clk_lock);
- mutex_unlock(&bebob->mutex);
-
if (err >= 0)
err = 1;
@@ -456,14 +452,14 @@ static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl,
unsigned int dig_in_iface;
int err, val;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
err = avc_audio_get_selector(bebob->unit, 0x00, 0x04,
&dig_in_iface);
if (err < 0) {
dev_err(&bebob->unit->device,
"fail to get digital input interface: %d\n", err);
- goto end;
+ return err;
}
/* encoded id for user value */
@@ -474,9 +470,7 @@ static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl,
val = 2;
uval->value.enumerated.item[0] = val;
-end:
- mutex_unlock(&bebob->mutex);
- return err;
+ return 0;
}
static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *uval)
@@ -494,7 +488,7 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
dig_in_fmt = (id >> 1) & 0x01;
dig_in_iface = id & 0x01;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
err = avc_maudio_set_special_clk(bebob,
params->clk_src,
@@ -502,24 +496,19 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
params->dig_out_fmt,
params->clk_lock);
if (err < 0)
- goto end;
+ return err;
/* For ADAT, optical interface is only available. */
- if (params->dig_in_fmt > 0) {
- err = 1;
- goto end;
- }
+ if (params->dig_in_fmt > 0)
+ return 1;
/* For S/PDIF, optical/coaxial interfaces are selectable. */
err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
if (err < 0)
dev_err(&bebob->unit->device,
"fail to set digital input interface: %d\n", err);
- err = 1;
-end:
special_stream_formation_set(bebob);
- mutex_unlock(&bebob->mutex);
- return err;
+ return 1;
}
static const struct snd_kcontrol_new special_dig_in_iface_ctl = {
.name = "Digital Input Interface",
@@ -546,9 +535,9 @@ static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl,
{
struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
struct special_params *params = bebob->maudio_special_quirk;
- mutex_lock(&bebob->mutex);
+
+ guard(mutex)(&bebob->mutex);
uval->value.enumerated.item[0] = params->dig_out_fmt;
- mutex_unlock(&bebob->mutex);
return 0;
}
static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
@@ -563,7 +552,7 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
if (id >= ARRAY_SIZE(special_dig_out_iface_labels))
return -EINVAL;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
err = avc_maudio_set_special_clk(bebob,
params->clk_src,
@@ -574,7 +563,6 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
err = 1;
}
- mutex_unlock(&bebob->mutex);
return err;
}
static const struct snd_kcontrol_new special_dig_out_iface_ctl = {
diff --git a/sound/firewire/bebob/bebob_midi.c b/sound/firewire/bebob/bebob_midi.c
index b1425bf98c3b..678631f31d3c 100644
--- a/sound/firewire/bebob/bebob_midi.c
+++ b/sound/firewire/bebob/bebob_midi.c
@@ -16,15 +16,15 @@ static int midi_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&bebob->mutex);
- err = snd_bebob_stream_reserve_duplex(bebob, 0, 0, 0);
- if (err >= 0) {
- ++bebob->substreams_counter;
- err = snd_bebob_stream_start_duplex(bebob);
- if (err < 0)
- --bebob->substreams_counter;
+ scoped_guard(mutex, &bebob->mutex) {
+ err = snd_bebob_stream_reserve_duplex(bebob, 0, 0, 0);
+ if (err >= 0) {
+ ++bebob->substreams_counter;
+ err = snd_bebob_stream_start_duplex(bebob);
+ if (err < 0)
+ --bebob->substreams_counter;
+ }
}
- mutex_unlock(&bebob->mutex);
if (err < 0)
snd_bebob_stream_lock_release(bebob);
@@ -35,10 +35,10 @@ static int midi_close(struct snd_rawmidi_substream *substream)
{
struct snd_bebob *bebob = substream->rmidi->private_data;
- mutex_lock(&bebob->mutex);
- bebob->substreams_counter--;
- snd_bebob_stream_stop_duplex(bebob);
- mutex_unlock(&bebob->mutex);
+ scoped_guard(mutex, &bebob->mutex) {
+ bebob->substreams_counter--;
+ snd_bebob_stream_stop_duplex(bebob);
+ }
snd_bebob_stream_lock_release(bebob);
return 0;
@@ -47,9 +47,8 @@ static int midi_close(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_bebob *bebob = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&bebob->lock, flags);
+ guard(spinlock_irqsave)(&bebob->lock);
if (up)
amdtp_am824_midi_trigger(&bebob->tx_stream,
@@ -57,16 +56,13 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&bebob->tx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&bebob->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_bebob *bebob = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&bebob->lock, flags);
+ guard(spinlock_irqsave)(&bebob->lock);
if (up)
amdtp_am824_midi_trigger(&bebob->rx_stream,
@@ -74,8 +70,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&bebob->rx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&bebob->lock, flags);
}
static void set_midi_substream_names(struct snd_bebob *bebob,
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c
index 360ebf3c4ca2..692d33bac2d2 100644
--- a/sound/firewire/bebob/bebob_pcm.c
+++ b/sound/firewire/bebob/bebob_pcm.c
@@ -149,49 +149,42 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
goto err_locked;
- mutex_lock(&bebob->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if (src == SND_BEBOB_CLOCK_TYPE_EXTERNAL ||
- (bebob->substreams_counter > 0 && d->events_per_period > 0)) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int sampling_rate;
-
- err = spec->get(bebob, &sampling_rate);
- if (err < 0) {
- mutex_unlock(&bebob->mutex);
- dev_err(&bebob->unit->device,
- "fail to get sampling rate: %d\n", err);
- goto err_locked;
- }
-
- substream->runtime->hw.rate_min = sampling_rate;
- substream->runtime->hw.rate_max = sampling_rate;
-
- if (frames_per_period > 0) {
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
+ scoped_guard(mutex, &bebob->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if (src == SND_BEBOB_CLOCK_TYPE_EXTERNAL ||
+ (bebob->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int sampling_rate;
+
+ err = spec->get(bebob, &sampling_rate);
if (err < 0) {
- mutex_unlock(&bebob->mutex);
+ dev_err(&bebob->unit->device,
+ "fail to get sampling rate: %d\n", err);
goto err_locked;
}
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&bebob->mutex);
- goto err_locked;
+ substream->runtime->hw.rate_min = sampling_rate;
+ substream->runtime->hw.rate_max = sampling_rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
}
- mutex_unlock(&bebob->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -219,12 +212,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
err = snd_bebob_stream_reserve_duplex(bebob, rate,
frames_per_period, frames_per_buffer);
if (err >= 0)
++bebob->substreams_counter;
- mutex_unlock(&bebob->mutex);
}
return err;
@@ -234,15 +226,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_bebob *bebob = substream->private_data;
- mutex_lock(&bebob->mutex);
+ guard(mutex)(&bebob->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
bebob->substreams_counter--;
snd_bebob_stream_stop_duplex(bebob);
- mutex_unlock(&bebob->mutex);
-
return 0;
}
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index 8629b14ded76..449cb17717f0 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -964,33 +964,24 @@ void snd_bebob_stream_lock_changed(struct snd_bebob *bebob)
int snd_bebob_stream_lock_try(struct snd_bebob *bebob)
{
- int err;
-
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
/* user land lock this */
- if (bebob->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (bebob->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (bebob->dev_lock_count++ == 0)
snd_bebob_stream_lock_changed(bebob);
- err = 0;
-end:
- spin_unlock_irq(&bebob->lock);
- return err;
+ return 0;
}
void snd_bebob_stream_lock_release(struct snd_bebob *bebob)
{
- spin_lock_irq(&bebob->lock);
+ guard(spinlock_irq)(&bebob->lock);
if (WARN_ON(bebob->dev_lock_count <= 0))
- goto end;
+ return;
if (--bebob->dev_lock_count == 0)
snd_bebob_stream_lock_changed(bebob);
-end:
- spin_unlock_irq(&bebob->lock);
}
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c
index f5028a061a91..b2b76c7c71b3 100644
--- a/sound/firewire/cmp.c
+++ b/sound/firewire/cmp.c
@@ -188,32 +188,23 @@ EXPORT_SYMBOL(cmp_connection_destroy);
int cmp_connection_reserve(struct cmp_connection *c,
unsigned int max_payload_bytes)
{
- int err;
-
- mutex_lock(&c->mutex);
+ guard(mutex)(&c->mutex);
- if (WARN_ON(c->resources.allocated)) {
- err = -EBUSY;
- goto end;
- }
+ if (WARN_ON(c->resources.allocated))
+ return -EBUSY;
c->speed = min(c->max_speed,
fw_parent_device(c->resources.unit)->max_speed);
- err = fw_iso_resources_allocate(&c->resources, max_payload_bytes,
- c->speed);
-end:
- mutex_unlock(&c->mutex);
-
- return err;
+ return fw_iso_resources_allocate(&c->resources, max_payload_bytes,
+ c->speed);
}
EXPORT_SYMBOL(cmp_connection_reserve);
void cmp_connection_release(struct cmp_connection *c)
{
- mutex_lock(&c->mutex);
+ guard(mutex)(&c->mutex);
fw_iso_resources_free(&c->resources);
- mutex_unlock(&c->mutex);
}
EXPORT_SYMBOL(cmp_connection_release);
@@ -304,12 +295,10 @@ int cmp_connection_establish(struct cmp_connection *c)
{
int err;
- mutex_lock(&c->mutex);
+ guard(mutex)(&c->mutex);
- if (WARN_ON(c->connected)) {
- mutex_unlock(&c->mutex);
+ if (WARN_ON(c->connected))
return -EISCONN;
- }
retry_after_bus_reset:
if (c->direction == CMP_OUTPUT)
@@ -327,8 +316,6 @@ retry_after_bus_reset:
if (err >= 0)
c->connected = true;
- mutex_unlock(&c->mutex);
-
return err;
}
EXPORT_SYMBOL(cmp_connection_establish);
@@ -350,19 +337,15 @@ void cmp_connection_break(struct cmp_connection *c)
{
int err;
- mutex_lock(&c->mutex);
+ guard(mutex)(&c->mutex);
- if (!c->connected) {
- mutex_unlock(&c->mutex);
+ if (!c->connected)
return;
- }
err = pcr_modify(c, pcr_break_modify, NULL, SUCCEED_ON_BUS_RESET);
if (err < 0)
cmp_error(c, "plug is still connected\n");
c->connected = false;
-
- mutex_unlock(&c->mutex);
}
EXPORT_SYMBOL(cmp_connection_break);
diff --git a/sound/firewire/dice/dice-hwdep.c b/sound/firewire/dice/dice-hwdep.c
index d165dd427bd3..747ff0952483 100644
--- a/sound/firewire/dice/dice-hwdep.c
+++ b/sound/firewire/dice/dice-hwdep.c
@@ -55,18 +55,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_dice *dice = hwdep->private_data;
- __poll_t events;
poll_wait(file, &dice->hwdep_wait, wait);
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
if (dice->dev_lock_changed || dice->notification_bits != 0)
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&dice->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_dice *dice, void __user *arg)
@@ -90,48 +86,35 @@ static int hwdep_get_info(struct snd_dice *dice, void __user *arg)
static int hwdep_lock(struct snd_dice *dice)
{
- int err;
-
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
if (dice->dev_lock_count == 0) {
dice->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&dice->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_dice *dice)
{
- int err;
-
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
if (dice->dev_lock_count == -1) {
dice->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&dice->lock);
-
- return err;
}
static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_dice *dice = hwdep->private_data;
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
if (dice->dev_lock_count == -1)
dice->dev_lock_count = 0;
- spin_unlock_irq(&dice->lock);
return 0;
}
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c
index 78988e44b8bc..722bce379345 100644
--- a/sound/firewire/dice/dice-midi.c
+++ b/sound/firewire/dice/dice-midi.c
@@ -15,18 +15,16 @@ static int midi_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&dice->mutex);
-
- err = snd_dice_stream_reserve_duplex(dice, 0, 0, 0);
- if (err >= 0) {
- ++dice->substreams_counter;
- err = snd_dice_stream_start_duplex(dice);
- if (err < 0)
- --dice->substreams_counter;
+ scoped_guard(mutex, &dice->mutex) {
+ err = snd_dice_stream_reserve_duplex(dice, 0, 0, 0);
+ if (err >= 0) {
+ ++dice->substreams_counter;
+ err = snd_dice_stream_start_duplex(dice);
+ if (err < 0)
+ --dice->substreams_counter;
+ }
}
- mutex_unlock(&dice->mutex);
-
if (err < 0)
snd_dice_stream_lock_release(dice);
@@ -37,12 +35,10 @@ static int midi_close(struct snd_rawmidi_substream *substream)
{
struct snd_dice *dice = substream->rmidi->private_data;
- mutex_lock(&dice->mutex);
-
- --dice->substreams_counter;
- snd_dice_stream_stop_duplex(dice);
-
- mutex_unlock(&dice->mutex);
+ scoped_guard(mutex, &dice->mutex) {
+ --dice->substreams_counter;
+ snd_dice_stream_stop_duplex(dice);
+ }
snd_dice_stream_lock_release(dice);
return 0;
@@ -51,9 +47,8 @@ static int midi_close(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_dice *dice = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&dice->lock, flags);
+ guard(spinlock_irqsave)(&dice->lock);
if (up)
amdtp_am824_midi_trigger(&dice->tx_stream[0],
@@ -61,16 +56,13 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&dice->tx_stream[0],
substrm->number, NULL);
-
- spin_unlock_irqrestore(&dice->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_dice *dice = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&dice->lock, flags);
+ guard(spinlock_irqsave)(&dice->lock);
if (up)
amdtp_am824_midi_trigger(&dice->rx_stream[0],
@@ -78,8 +70,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&dice->rx_stream[0],
substrm->number, NULL);
-
- spin_unlock_irqrestore(&dice->lock, flags);
}
static void set_midi_substream_names(struct snd_dice *dice,
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index cfc19bd0d5dd..d5319cd2cc6f 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -196,53 +196,45 @@ static int pcm_open(struct snd_pcm_substream *substream)
break;
}
- mutex_lock(&dice->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if (!internal ||
- (dice->substreams_counter > 0 && d->events_per_period > 0)) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int rate;
-
- err = snd_dice_transaction_get_rate(dice, &rate);
- if (err < 0) {
- mutex_unlock(&dice->mutex);
- goto err_locked;
- }
-
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
-
- if (frames_per_period > 0) {
- // For double_pcm_frame quirk.
- if (rate > 96000 && !dice->disable_double_pcm_frames) {
- frames_per_period *= 2;
- frames_per_buffer *= 2;
- }
-
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&dice->mutex);
+ scoped_guard(mutex, &dice->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if (!internal ||
+ (dice->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int rate;
+
+ err = snd_dice_transaction_get_rate(dice, &rate);
+ if (err < 0)
goto err_locked;
- }
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&dice->mutex);
- goto err_locked;
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+
+ if (frames_per_period > 0) {
+ // For double_pcm_frame quirk.
+ if (rate > 96000 && !dice->disable_double_pcm_frames) {
+ frames_per_period *= 2;
+ frames_per_buffer *= 2;
+ }
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
}
- mutex_unlock(&dice->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -271,7 +263,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int events_per_period = params_period_size(hw_params);
unsigned int events_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&dice->mutex);
+ guard(mutex)(&dice->mutex);
// For double_pcm_frame quirk.
if (rate > 96000 && !dice->disable_double_pcm_frames) {
events_per_period /= 2;
@@ -281,7 +273,6 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
events_per_period, events_per_buffer);
if (err >= 0)
++dice->substreams_counter;
- mutex_unlock(&dice->mutex);
}
return err;
@@ -291,15 +282,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
- mutex_lock(&dice->mutex);
+ guard(mutex)(&dice->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--dice->substreams_counter;
snd_dice_stream_stop_duplex(dice);
- mutex_unlock(&dice->mutex);
-
return 0;
}
@@ -309,9 +298,9 @@ static int capture_prepare(struct snd_pcm_substream *substream)
struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
int err;
- mutex_lock(&dice->mutex);
- err = snd_dice_stream_start_duplex(dice);
- mutex_unlock(&dice->mutex);
+ scoped_guard(mutex, &dice->mutex) {
+ err = snd_dice_stream_start_duplex(dice);
+ }
if (err >= 0)
amdtp_stream_pcm_prepare(stream);
@@ -323,9 +312,9 @@ static int playback_prepare(struct snd_pcm_substream *substream)
struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
int err;
- mutex_lock(&dice->mutex);
- err = snd_dice_stream_start_duplex(dice);
- mutex_unlock(&dice->mutex);
+ scoped_guard(mutex, &dice->mutex) {
+ err = snd_dice_stream_start_duplex(dice);
+ }
if (err >= 0)
amdtp_stream_pcm_prepare(stream);
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 4c677c8546c7..d5ffe7c82993 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -677,32 +677,23 @@ static void dice_lock_changed(struct snd_dice *dice)
int snd_dice_stream_lock_try(struct snd_dice *dice)
{
- int err;
-
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
- if (dice->dev_lock_count < 0) {
- err = -EBUSY;
- goto out;
- }
+ if (dice->dev_lock_count < 0)
+ return -EBUSY;
if (dice->dev_lock_count++ == 0)
dice_lock_changed(dice);
- err = 0;
-out:
- spin_unlock_irq(&dice->lock);
- return err;
+ return 0;
}
void snd_dice_stream_lock_release(struct snd_dice *dice)
{
- spin_lock_irq(&dice->lock);
+ guard(spinlock_irq)(&dice->lock);
if (WARN_ON(dice->dev_lock_count <= 0))
- goto out;
+ return;
if (--dice->dev_lock_count == 0)
dice_lock_changed(dice);
-out:
- spin_unlock_irq(&dice->lock);
}
diff --git a/sound/firewire/dice/dice-transaction.c b/sound/firewire/dice/dice-transaction.c
index 92941ef83cd5..a3f7dfa990a4 100644
--- a/sound/firewire/dice/dice-transaction.c
+++ b/sound/firewire/dice/dice-transaction.c
@@ -136,7 +136,6 @@ static void dice_notification(struct fw_card *card, struct fw_request *request,
{
struct snd_dice *dice = callback_data;
u32 bits;
- unsigned long flags;
if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
fw_send_response(card, request, RCODE_TYPE_ERROR);
@@ -149,9 +148,9 @@ static void dice_notification(struct fw_card *card, struct fw_request *request,
bits = be32_to_cpup(data);
- spin_lock_irqsave(&dice->lock, flags);
- dice->notification_bits |= bits;
- spin_unlock_irqrestore(&dice->lock, flags);
+ scoped_guard(spinlock_irqsave, &dice->lock) {
+ dice->notification_bits |= bits;
+ }
fw_send_response(card, request, RCODE_COMPLETE);
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 9675ec14271d..bcbe80344328 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -238,9 +238,8 @@ static void dice_bus_reset(struct fw_unit *unit)
/* The handler address register becomes initialized. */
snd_dice_transaction_reinit(dice);
- mutex_lock(&dice->mutex);
+ guard(mutex)(&dice->mutex);
snd_dice_stream_update_duplex(dice);
- mutex_unlock(&dice->mutex);
}
#define DICE_INTERFACE 0x000001
diff --git a/sound/firewire/digi00x/digi00x-hwdep.c b/sound/firewire/digi00x/digi00x-hwdep.c
index b150607c0a0d..435d18417cf0 100644
--- a/sound/firewire/digi00x/digi00x-hwdep.c
+++ b/sound/firewire/digi00x/digi00x-hwdep.c
@@ -63,18 +63,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_dg00x *dg00x = hwdep->private_data;
- __poll_t events;
poll_wait(file, &dg00x->hwdep_wait, wait);
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
if (dg00x->dev_lock_changed || dg00x->msg)
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&dg00x->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg)
@@ -98,48 +94,35 @@ static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg)
static int hwdep_lock(struct snd_dg00x *dg00x)
{
- int err;
-
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
if (dg00x->dev_lock_count == 0) {
dg00x->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&dg00x->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_dg00x *dg00x)
{
- int err;
-
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
if (dg00x->dev_lock_count == -1) {
dg00x->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&dg00x->lock);
-
- return err;
}
static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_dg00x *dg00x = hwdep->private_data;
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
if (dg00x->dev_lock_count == -1)
dg00x->dev_lock_count = 0;
- spin_unlock_irq(&dg00x->lock);
return 0;
}
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c
index 8f4bace16050..bcdaf003514b 100644
--- a/sound/firewire/digi00x/digi00x-midi.c
+++ b/sound/firewire/digi00x/digi00x-midi.c
@@ -16,15 +16,15 @@ static int midi_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&dg00x->mutex);
- err = snd_dg00x_stream_reserve_duplex(dg00x, 0, 0, 0);
- if (err >= 0) {
- ++dg00x->substreams_counter;
- err = snd_dg00x_stream_start_duplex(dg00x);
- if (err < 0)
- --dg00x->substreams_counter;
+ scoped_guard(mutex, &dg00x->mutex) {
+ err = snd_dg00x_stream_reserve_duplex(dg00x, 0, 0, 0);
+ if (err >= 0) {
+ ++dg00x->substreams_counter;
+ err = snd_dg00x_stream_start_duplex(dg00x);
+ if (err < 0)
+ --dg00x->substreams_counter;
+ }
}
- mutex_unlock(&dg00x->mutex);
if (err < 0)
snd_dg00x_stream_lock_release(dg00x);
@@ -35,10 +35,10 @@ static int midi_close(struct snd_rawmidi_substream *substream)
{
struct snd_dg00x *dg00x = substream->rmidi->private_data;
- mutex_lock(&dg00x->mutex);
- --dg00x->substreams_counter;
- snd_dg00x_stream_stop_duplex(dg00x);
- mutex_unlock(&dg00x->mutex);
+ scoped_guard(mutex, &dg00x->mutex) {
+ --dg00x->substreams_counter;
+ snd_dg00x_stream_stop_duplex(dg00x);
+ }
snd_dg00x_stream_lock_release(dg00x);
return 0;
@@ -49,21 +49,18 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
{
struct snd_dg00x *dg00x = substream->rmidi->private_data;
unsigned int port;
- unsigned long flags;
if (substream->rmidi->device == 0)
port = substream->number;
else
port = 2;
- spin_lock_irqsave(&dg00x->lock, flags);
+ guard(spinlock_irqsave)(&dg00x->lock);
if (up)
amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
else
amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
-
- spin_unlock_irqrestore(&dg00x->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
@@ -71,21 +68,18 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
{
struct snd_dg00x *dg00x = substream->rmidi->private_data;
unsigned int port;
- unsigned long flags;
if (substream->rmidi->device == 0)
port = substream->number;
else
port = 2;
- spin_lock_irqsave(&dg00x->lock, flags);
+ guard(spinlock_irqsave)(&dg00x->lock);
if (up)
amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
else
amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
-
- spin_unlock_irqrestore(&dg00x->lock, flags);
}
static void set_substream_names(struct snd_dg00x *dg00x,
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c
index 85e65cbc00c4..75f81545d50c 100644
--- a/sound/firewire/digi00x/digi00x-pcm.c
+++ b/sound/firewire/digi00x/digi00x-pcm.c
@@ -127,46 +127,38 @@ static int pcm_open(struct snd_pcm_substream *substream)
}
}
- mutex_lock(&dg00x->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if ((clock != SND_DG00X_CLOCK_INTERNAL) ||
- (dg00x->substreams_counter > 0 && d->events_per_period > 0)) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int rate;
-
- err = snd_dg00x_stream_get_external_rate(dg00x, &rate);
- if (err < 0) {
- mutex_unlock(&dg00x->mutex);
- goto err_locked;
- }
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
-
- if (frames_per_period > 0) {
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&dg00x->mutex);
- goto err_locked;
- }
-
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&dg00x->mutex);
+ scoped_guard(mutex, &dg00x->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if ((clock != SND_DG00X_CLOCK_INTERNAL) ||
+ (dg00x->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int rate;
+
+ err = snd_dg00x_stream_get_external_rate(dg00x, &rate);
+ if (err < 0)
goto err_locked;
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
}
- mutex_unlock(&dg00x->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -195,12 +187,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&dg00x->mutex);
+ guard(mutex)(&dg00x->mutex);
err = snd_dg00x_stream_reserve_duplex(dg00x, rate,
frames_per_period, frames_per_buffer);
if (err >= 0)
++dg00x->substreams_counter;
- mutex_unlock(&dg00x->mutex);
}
return err;
@@ -210,15 +201,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_dg00x *dg00x = substream->private_data;
- mutex_lock(&dg00x->mutex);
+ guard(mutex)(&dg00x->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--dg00x->substreams_counter;
snd_dg00x_stream_stop_duplex(dg00x);
- mutex_unlock(&dg00x->mutex);
-
return 0;
}
@@ -227,14 +216,12 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
struct snd_dg00x *dg00x = substream->private_data;
int err;
- mutex_lock(&dg00x->mutex);
+ guard(mutex)(&dg00x->mutex);
err = snd_dg00x_stream_start_duplex(dg00x);
if (err >= 0)
amdtp_stream_pcm_prepare(&dg00x->tx_stream);
- mutex_unlock(&dg00x->mutex);
-
return err;
}
@@ -243,7 +230,7 @@ static int pcm_playback_prepare(struct snd_pcm_substream *substream)
struct snd_dg00x *dg00x = substream->private_data;
int err;
- mutex_lock(&dg00x->mutex);
+ guard(mutex)(&dg00x->mutex);
err = snd_dg00x_stream_start_duplex(dg00x);
if (err >= 0) {
@@ -251,8 +238,6 @@ static int pcm_playback_prepare(struct snd_pcm_substream *substream)
amdtp_dot_reset(&dg00x->rx_stream);
}
- mutex_unlock(&dg00x->mutex);
-
return err;
}
diff --git a/sound/firewire/digi00x/digi00x-stream.c b/sound/firewire/digi00x/digi00x-stream.c
index 295163bb8abb..250ffdb26ebd 100644
--- a/sound/firewire/digi00x/digi00x-stream.c
+++ b/sound/firewire/digi00x/digi00x-stream.c
@@ -427,33 +427,24 @@ void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x)
int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x)
{
- int err;
-
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
/* user land lock this */
- if (dg00x->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (dg00x->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (dg00x->dev_lock_count++ == 0)
snd_dg00x_stream_lock_changed(dg00x);
- err = 0;
-end:
- spin_unlock_irq(&dg00x->lock);
- return err;
+ return 0;
}
void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x)
{
- spin_lock_irq(&dg00x->lock);
+ guard(spinlock_irq)(&dg00x->lock);
if (WARN_ON(dg00x->dev_lock_count <= 0))
- goto end;
+ return;
if (--dg00x->dev_lock_count == 0)
snd_dg00x_stream_lock_changed(dg00x);
-end:
- spin_unlock_irq(&dg00x->lock);
}
diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
index cf0bcf1c5956..8a1667159930 100644
--- a/sound/firewire/digi00x/digi00x-transaction.c
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -11,11 +11,9 @@
static void handle_unknown_message(struct snd_dg00x *dg00x,
unsigned long long offset, __be32 *buf)
{
- unsigned long flags;
-
- spin_lock_irqsave(&dg00x->lock, flags);
- dg00x->msg = be32_to_cpu(*buf);
- spin_unlock_irqrestore(&dg00x->lock, flags);
+ scoped_guard(spinlock_irqsave, &dg00x->lock) {
+ dg00x->msg = be32_to_cpu(*buf);
+ }
wake_up(&dg00x->hwdep_wait);
}
diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
index cebc35dcf8cd..f73a9fc8adb1 100644
--- a/sound/firewire/digi00x/digi00x.c
+++ b/sound/firewire/digi00x/digi00x.c
@@ -116,9 +116,8 @@ static void snd_dg00x_update(struct fw_unit *unit)
snd_dg00x_transaction_reregister(dg00x);
- mutex_lock(&dg00x->mutex);
+ guard(mutex)(&dg00x->mutex);
snd_dg00x_stream_update_duplex(dg00x);
- mutex_unlock(&dg00x->mutex);
}
static void snd_dg00x_remove(struct fw_unit *unit)
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
index df44dd5dc4b2..e60bfd0ee4ac 100644
--- a/sound/firewire/fcp.c
+++ b/sound/firewire/fcp.c
@@ -242,9 +242,9 @@ int fcp_avc_transaction(struct fw_unit *unit,
init_waitqueue_head(&t.wait);
t.deferrable = (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03);
- spin_lock_irq(&transactions_lock);
- list_add_tail(&t.list, &transactions);
- spin_unlock_irq(&transactions_lock);
+ scoped_guard(spinlock_irq, &transactions_lock) {
+ list_add_tail(&t.list, &transactions);
+ }
for (;;) {
tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
@@ -280,9 +280,9 @@ deferred:
}
}
- spin_lock_irq(&transactions_lock);
- list_del(&t.list);
- spin_unlock_irq(&transactions_lock);
+ scoped_guard(spinlock_irq, &transactions_lock) {
+ list_del(&t.list);
+ }
return ret;
}
@@ -300,7 +300,7 @@ void fcp_bus_reset(struct fw_unit *unit)
{
struct fcp_transaction *t;
- spin_lock_irq(&transactions_lock);
+ guard(spinlock_irq)(&transactions_lock);
list_for_each_entry(t, &transactions, list) {
if (t->unit == unit &&
(t->state == STATE_PENDING ||
@@ -309,7 +309,6 @@ void fcp_bus_reset(struct fw_unit *unit)
wake_up(&t->wait);
}
}
- spin_unlock_irq(&transactions_lock);
}
EXPORT_SYMBOL(fcp_bus_reset);
@@ -341,12 +340,11 @@ static void fcp_response(struct fw_card *card, struct fw_request *request,
void *data, size_t length, void *callback_data)
{
struct fcp_transaction *t;
- unsigned long flags;
if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
return;
- spin_lock_irqsave(&transactions_lock, flags);
+ guard(spinlock_irqsave)(&transactions_lock);
list_for_each_entry(t, &transactions, list) {
struct fw_device *device = fw_parent_device(t->unit);
if (device->card != card ||
@@ -370,7 +368,6 @@ static void fcp_response(struct fw_card *card, struct fw_request *request,
wake_up(&t->wait);
}
}
- spin_unlock_irqrestore(&transactions_lock, flags);
}
static struct fw_address_handler response_register_handler = {
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c
index ca5c5dee71f2..5976abf2e1ab 100644
--- a/sound/firewire/fireface/ff-hwdep.c
+++ b/sound/firewire/fireface/ff-hwdep.c
@@ -72,18 +72,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_ff *ff = hwdep->private_data;
- __poll_t events;
poll_wait(file, &ff->hwdep_wait, wait);
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
if (ff->dev_lock_changed || has_msg(ff))
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&ff->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_ff *ff, void __user *arg)
@@ -107,48 +103,35 @@ static int hwdep_get_info(struct snd_ff *ff, void __user *arg)
static int hwdep_lock(struct snd_ff *ff)
{
- int err;
-
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
if (ff->dev_lock_count == 0) {
ff->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&ff->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_ff *ff)
{
- int err;
-
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
if (ff->dev_lock_count == -1) {
ff->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&ff->lock);
-
- return err;
}
static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_ff *ff = hwdep->private_data;
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
if (ff->dev_lock_count == -1)
ff->dev_lock_count = 0;
- spin_unlock_irq(&ff->lock);
return 0;
}
diff --git a/sound/firewire/fireface/ff-midi.c b/sound/firewire/fireface/ff-midi.c
index da3054fdcc7d..9f6aa490e5bf 100644
--- a/sound/firewire/fireface/ff-midi.c
+++ b/sound/firewire/fireface/ff-midi.c
@@ -46,31 +46,25 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct snd_ff *ff = substream->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&ff->lock, flags);
+ guard(spinlock_irqsave)(&ff->lock);
if (up)
WRITE_ONCE(ff->tx_midi_substreams[substream->number],
substream);
else
WRITE_ONCE(ff->tx_midi_substreams[substream->number], NULL);
-
- spin_unlock_irqrestore(&ff->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct snd_ff *ff = substream->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&ff->lock, flags);
+ guard(spinlock_irqsave)(&ff->lock);
if (up || !ff->rx_midi_error[substream->number])
schedule_work(&ff->rx_midi_work[substream->number]);
-
- spin_unlock_irqrestore(&ff->lock, flags);
}
static void set_midi_substream_names(struct snd_rawmidi_str *stream,
diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c
index 63457d24a288..7ad8204fbfe8 100644
--- a/sound/firewire/fireface/ff-pcm.c
+++ b/sound/firewire/fireface/ff-pcm.c
@@ -156,56 +156,49 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
goto release_lock;
- mutex_lock(&ff->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if (src != SND_FF_CLOCK_SRC_INTERNAL) {
- for (i = 0; i < CIP_SFC_COUNT; ++i) {
- if (amdtp_rate_table[i] == rate)
- break;
- }
-
- // The unit is configured at sampling frequency which packet
- // streaming engine can't support.
- if (i >= CIP_SFC_COUNT) {
- mutex_unlock(&ff->mutex);
- err = -EIO;
- goto release_lock;
- }
-
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
- } else {
- if (ff->substreams_counter > 0) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
-
- rate = amdtp_rate_table[ff->rx_stream.sfc];
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
+ scoped_guard(mutex, &ff->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if (src != SND_FF_CLOCK_SRC_INTERNAL) {
+ for (i = 0; i < CIP_SFC_COUNT; ++i) {
+ if (amdtp_rate_table[i] == rate)
+ break;
+ }
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&ff->mutex);
+ // The unit is configured at sampling frequency which packet
+ // streaming engine can't support.
+ if (i >= CIP_SFC_COUNT) {
+ err = -EIO;
goto release_lock;
}
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&ff->mutex);
- goto release_lock;
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+ } else {
+ if (ff->substreams_counter > 0) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+
+ rate = amdtp_rate_table[ff->rx_stream.sfc];
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto release_lock;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto release_lock;
}
}
}
- mutex_unlock(&ff->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -235,12 +228,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&ff->mutex);
+ guard(mutex)(&ff->mutex);
err = snd_ff_stream_reserve_duplex(ff, rate, frames_per_period,
frames_per_buffer);
if (err >= 0)
++ff->substreams_counter;
- mutex_unlock(&ff->mutex);
}
return err;
@@ -250,15 +242,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_ff *ff = substream->private_data;
- mutex_lock(&ff->mutex);
+ guard(mutex)(&ff->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--ff->substreams_counter;
snd_ff_stream_stop_duplex(ff);
- mutex_unlock(&ff->mutex);
-
return 0;
}
@@ -268,14 +258,12 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- mutex_lock(&ff->mutex);
+ guard(mutex)(&ff->mutex);
err = snd_ff_stream_start_duplex(ff, runtime->rate);
if (err >= 0)
amdtp_stream_pcm_prepare(&ff->tx_stream);
- mutex_unlock(&ff->mutex);
-
return err;
}
@@ -285,14 +273,12 @@ static int pcm_playback_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- mutex_lock(&ff->mutex);
+ guard(mutex)(&ff->mutex);
err = snd_ff_stream_start_duplex(ff, runtime->rate);
if (err >= 0)
amdtp_stream_pcm_prepare(&ff->rx_stream);
- mutex_unlock(&ff->mutex);
-
return err;
}
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 95bf405adb3d..ba42490f2b0e 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -253,33 +253,24 @@ void snd_ff_stream_lock_changed(struct snd_ff *ff)
int snd_ff_stream_lock_try(struct snd_ff *ff)
{
- int err;
-
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
/* user land lock this */
- if (ff->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (ff->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (ff->dev_lock_count++ == 0)
snd_ff_stream_lock_changed(ff);
- err = 0;
-end:
- spin_unlock_irq(&ff->lock);
- return err;
+ return 0;
}
void snd_ff_stream_lock_release(struct snd_ff *ff)
{
- spin_lock_irq(&ff->lock);
+ guard(spinlock_irq)(&ff->lock);
if (WARN_ON(ff->dev_lock_count <= 0))
- goto end;
+ return;
if (--ff->dev_lock_count == 0)
snd_ff_stream_lock_changed(ff);
-end:
- spin_unlock_irq(&ff->lock);
}
diff --git a/sound/firewire/fireface/ff-transaction.c b/sound/firewire/fireface/ff-transaction.c
index 6b89e39f4a43..436da0a3bdcc 100644
--- a/sound/firewire/fireface/ff-transaction.c
+++ b/sound/firewire/fireface/ff-transaction.c
@@ -132,15 +132,13 @@ static void handle_msg(struct fw_card *card, struct fw_request *request, int tco
struct snd_ff *ff = callback_data;
__le32 *buf = data;
u32 tstamp = fw_request_get_timestamp(request);
- unsigned long flag;
fw_send_response(card, request, RCODE_COMPLETE);
offset -= ff->async_handler.offset;
- spin_lock_irqsave(&ff->lock, flag);
+ guard(spinlock_irqsave)(&ff->lock);
ff->spec->protocol->handle_msg(ff, (unsigned int)offset, buf, length, tstamp);
- spin_unlock_irqrestore(&ff->lock, flag);
}
static int allocate_own_address(struct snd_ff *ff, int i)
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index 69f722244362..3378c7dce88a 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -188,9 +188,9 @@ efw_card_free(struct snd_card *card)
{
struct snd_efw *efw = card->private_data;
- mutex_lock(&devices_mutex);
- clear_bit(efw->card_index, devices_used);
- mutex_unlock(&devices_mutex);
+ scoped_guard(mutex, &devices_mutex) {
+ clear_bit(efw->card_index, devices_used);
+ }
snd_efw_stream_destroy_duplex(efw);
snd_efw_transaction_remove_instance(efw);
@@ -207,25 +207,21 @@ static int efw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entr
int err;
// check registered cards.
- mutex_lock(&devices_mutex);
- for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) {
- if (!test_bit(card_index, devices_used) && enable[card_index])
- break;
- }
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
- return -ENOENT;
- }
-
- err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE,
- sizeof(*efw), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
- return err;
+ scoped_guard(mutex, &devices_mutex) {
+ for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) {
+ if (!test_bit(card_index, devices_used) && enable[card_index])
+ break;
+ }
+ if (card_index >= SNDRV_CARDS)
+ return -ENOENT;
+
+ err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE,
+ sizeof(*efw), &card);
+ if (err < 0)
+ return err;
+ card->private_free = efw_card_free;
+ set_bit(card_index, devices_used);
}
- card->private_free = efw_card_free;
- set_bit(card_index, devices_used);
- mutex_unlock(&devices_mutex);
efw = card->private_data;
efw->unit = fw_unit_get(unit);
@@ -287,9 +283,8 @@ static void efw_update(struct fw_unit *unit)
snd_efw_transaction_bus_reset(efw->unit);
- mutex_lock(&efw->mutex);
+ guard(mutex)(&efw->mutex);
snd_efw_stream_update_duplex(efw);
- mutex_unlock(&efw->mutex);
}
static void efw_remove(struct fw_unit *unit)
diff --git a/sound/firewire/fireworks/fireworks_command.c b/sound/firewire/fireworks/fireworks_command.c
index 7e255fc2c6e4..2b595ee0bc35 100644
--- a/sound/firewire/fireworks/fireworks_command.c
+++ b/sound/firewire/fireworks/fireworks_command.c
@@ -119,14 +119,14 @@ efw_transaction(struct snd_efw *efw, unsigned int category,
return -ENOMEM;
/* to keep consistency of sequence number */
- spin_lock(&efw->lock);
- if ((efw->seqnum < KERNEL_SEQNUM_MIN) ||
- (efw->seqnum >= KERNEL_SEQNUM_MAX - 2))
- efw->seqnum = KERNEL_SEQNUM_MIN;
- else
- efw->seqnum += 2;
- seqnum = efw->seqnum;
- spin_unlock(&efw->lock);
+ scoped_guard(spinlock, &efw->lock) {
+ if ((efw->seqnum < KERNEL_SEQNUM_MIN) ||
+ (efw->seqnum >= KERNEL_SEQNUM_MAX - 2))
+ efw->seqnum = KERNEL_SEQNUM_MIN;
+ else
+ efw->seqnum += 2;
+ seqnum = efw->seqnum;
+ }
/* fill transaction header fields */
cmd_bytes = sizeof(struct snd_efw_transaction) + param_bytes;
diff --git a/sound/firewire/fireworks/fireworks_hwdep.c b/sound/firewire/fireworks/fireworks_hwdep.c
index 037833cd066e..7d6bd8ceeab3 100644
--- a/sound/firewire/fireworks/fireworks_hwdep.c
+++ b/sound/firewire/fireworks/fireworks_hwdep.c
@@ -103,12 +103,10 @@ hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
};
- spin_lock_irq(&efw->lock);
-
- event.lock_status.status = (efw->dev_lock_count > 0);
- efw->dev_lock_changed = false;
-
- spin_unlock_irq(&efw->lock);
+ scoped_guard(spinlock_irq, &efw->lock) {
+ event.lock_status.status = (efw->dev_lock_count > 0);
+ efw->dev_lock_changed = false;
+ }
count = min_t(long, count, sizeof(event.lock_status));
@@ -192,13 +190,11 @@ hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
poll_wait(file, &efw->hwdep_wait, wait);
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr)
events = EPOLLIN | EPOLLRDNORM;
else
events = 0;
- spin_unlock_irq(&efw->lock);
-
return events | EPOLLOUT;
}
@@ -225,39 +221,27 @@ hwdep_get_info(struct snd_efw *efw, void __user *arg)
static int
hwdep_lock(struct snd_efw *efw)
{
- int err;
-
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
if (efw->dev_lock_count == 0) {
efw->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&efw->lock);
-
- return err;
}
static int
hwdep_unlock(struct snd_efw *efw)
{
- int err;
-
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
if (efw->dev_lock_count == -1) {
efw->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&efw->lock);
-
- return err;
}
static int
@@ -265,10 +249,9 @@ hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_efw *efw = hwdep->private_data;
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
if (efw->dev_lock_count == -1)
efw->dev_lock_count = 0;
- spin_unlock_irq(&efw->lock);
return 0;
}
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c
index 350bf4d299c2..405106a6aef9 100644
--- a/sound/firewire/fireworks/fireworks_midi.c
+++ b/sound/firewire/fireworks/fireworks_midi.c
@@ -14,20 +14,19 @@ static int midi_open(struct snd_rawmidi_substream *substream)
err = snd_efw_stream_lock_try(efw);
if (err < 0)
- goto end;
-
- mutex_lock(&efw->mutex);
- err = snd_efw_stream_reserve_duplex(efw, 0, 0, 0);
- if (err >= 0) {
- ++efw->substreams_counter;
- err = snd_efw_stream_start_duplex(efw);
- if (err < 0)
- --efw->substreams_counter;
+ return err;
+
+ scoped_guard(mutex, &efw->mutex) {
+ err = snd_efw_stream_reserve_duplex(efw, 0, 0, 0);
+ if (err >= 0) {
+ ++efw->substreams_counter;
+ err = snd_efw_stream_start_duplex(efw);
+ if (err < 0)
+ --efw->substreams_counter;
+ }
}
- mutex_unlock(&efw->mutex);
if (err < 0)
snd_efw_stream_lock_release(efw);
-end:
return err;
}
@@ -35,10 +34,10 @@ static int midi_close(struct snd_rawmidi_substream *substream)
{
struct snd_efw *efw = substream->rmidi->private_data;
- mutex_lock(&efw->mutex);
- --efw->substreams_counter;
- snd_efw_stream_stop_duplex(efw);
- mutex_unlock(&efw->mutex);
+ scoped_guard(mutex, &efw->mutex) {
+ --efw->substreams_counter;
+ snd_efw_stream_stop_duplex(efw);
+ }
snd_efw_stream_lock_release(efw);
return 0;
@@ -47,9 +46,8 @@ static int midi_close(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_efw *efw = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&efw->lock, flags);
+ guard(spinlock_irqsave)(&efw->lock);
if (up)
amdtp_am824_midi_trigger(&efw->tx_stream,
@@ -57,16 +55,13 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&efw->tx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&efw->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_efw *efw = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&efw->lock, flags);
+ guard(spinlock_irqsave)(&efw->lock);
if (up)
amdtp_am824_midi_trigger(&efw->rx_stream,
@@ -74,8 +69,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&efw->rx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&efw->lock, flags);
}
static void set_midi_substream_names(struct snd_efw *efw,
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
index eaf7778211de..9399293a9fe9 100644
--- a/sound/firewire/fireworks/fireworks_pcm.c
+++ b/sound/firewire/fireworks/fireworks_pcm.c
@@ -189,46 +189,38 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
goto err_locked;
- mutex_lock(&efw->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
- (efw->substreams_counter > 0 && d->events_per_period > 0)) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int sampling_rate;
-
- err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
- if (err < 0) {
- mutex_unlock(&efw->mutex);
- goto err_locked;
- }
- substream->runtime->hw.rate_min = sampling_rate;
- substream->runtime->hw.rate_max = sampling_rate;
-
- if (frames_per_period > 0) {
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&efw->mutex);
- goto err_locked;
- }
-
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&efw->mutex);
+ scoped_guard(mutex, &efw->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
+ (efw->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int sampling_rate;
+
+ err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
+ if (err < 0)
goto err_locked;
+ substream->runtime->hw.rate_min = sampling_rate;
+ substream->runtime->hw.rate_max = sampling_rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
}
- mutex_unlock(&efw->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -255,12 +247,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&efw->mutex);
+ guard(mutex)(&efw->mutex);
err = snd_efw_stream_reserve_duplex(efw, rate,
frames_per_period, frames_per_buffer);
if (err >= 0)
++efw->substreams_counter;
- mutex_unlock(&efw->mutex);
}
return err;
@@ -270,15 +261,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- mutex_lock(&efw->mutex);
+ guard(mutex)(&efw->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--efw->substreams_counter;
snd_efw_stream_stop_duplex(efw);
- mutex_unlock(&efw->mutex);
-
return 0;
}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 53dbd4d4b0d0..974084e1c083 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -345,33 +345,24 @@ void snd_efw_stream_lock_changed(struct snd_efw *efw)
int snd_efw_stream_lock_try(struct snd_efw *efw)
{
- int err;
-
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
/* user land lock this */
- if (efw->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (efw->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (efw->dev_lock_count++ == 0)
snd_efw_stream_lock_changed(efw);
- err = 0;
-end:
- spin_unlock_irq(&efw->lock);
- return err;
+ return 0;
}
void snd_efw_stream_lock_release(struct snd_efw *efw)
{
- spin_lock_irq(&efw->lock);
+ guard(spinlock_irq)(&efw->lock);
if (WARN_ON(efw->dev_lock_count <= 0))
- goto end;
+ return;
if (--efw->dev_lock_count == 0)
snd_efw_stream_lock_changed(efw);
-end:
- spin_unlock_irq(&efw->lock);
}
diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c
index 9f8c53b39f95..5c859773fe06 100644
--- a/sound/firewire/fireworks/fireworks_transaction.c
+++ b/sound/firewire/fireworks/fireworks_transaction.c
@@ -82,9 +82,9 @@ int snd_efw_transaction_run(struct fw_unit *unit,
t.state = STATE_PENDING;
init_waitqueue_head(&t.wait);
- spin_lock_irq(&transaction_queues_lock);
- list_add_tail(&t.list, &transaction_queues);
- spin_unlock_irq(&transaction_queues_lock);
+ scoped_guard(spinlock_irq, &transaction_queues_lock) {
+ list_add_tail(&t.list, &transaction_queues);
+ }
tries = 0;
do {
@@ -107,9 +107,9 @@ int snd_efw_transaction_run(struct fw_unit *unit,
}
} while (1);
- spin_lock_irq(&transaction_queues_lock);
- list_del(&t.list);
- spin_unlock_irq(&transaction_queues_lock);
+ scoped_guard(spinlock_irq, &transaction_queues_lock) {
+ list_del(&t.list);
+ }
return ret;
}
@@ -123,7 +123,7 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
t = (struct snd_efw_transaction *)data;
length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length);
- spin_lock(&efw->lock);
+ guard(spinlock)(&efw->lock);
if (efw->push_ptr < efw->pull_ptr)
capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
@@ -134,7 +134,7 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
/* confirm enough space for this response */
if (capacity < length) {
*rcode = RCODE_CONFLICT_ERROR;
- goto end;
+ return;
}
/* copy to ring buffer */
@@ -157,8 +157,6 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
wake_up(&efw->hwdep_wait);
*rcode = RCODE_COMPLETE;
-end:
- spin_unlock_irq(&efw->lock);
}
static void
@@ -169,7 +167,7 @@ handle_resp_for_user(struct fw_card *card, int generation, int source,
struct snd_efw *efw;
unsigned int i;
- spin_lock_irq(&instances_lock);
+ guard(spinlock_irq)(&instances_lock);
for (i = 0; i < SNDRV_CARDS; i++) {
efw = instances[i];
@@ -186,11 +184,9 @@ handle_resp_for_user(struct fw_card *card, int generation, int source,
break;
}
if (i == SNDRV_CARDS)
- goto end;
+ return;
copy_resp_to_buf(efw, data, length, rcode);
-end:
- spin_unlock(&instances_lock);
}
static void
@@ -199,9 +195,8 @@ handle_resp_for_kernel(struct fw_card *card, int generation, int source,
{
struct fw_device *device;
struct transaction_queue *t;
- unsigned long flags;
- spin_lock_irqsave(&transaction_queues_lock, flags);
+ guard(spinlock_irqsave)(&transaction_queues_lock);
list_for_each_entry(t, &transaction_queues, list) {
device = fw_parent_device(t->unit);
if ((device->card != card) ||
@@ -219,7 +214,6 @@ handle_resp_for_kernel(struct fw_card *card, int generation, int source,
*rcode = RCODE_COMPLETE;
}
}
- spin_unlock_irqrestore(&transaction_queues_lock, flags);
}
static void
@@ -259,7 +253,7 @@ void snd_efw_transaction_add_instance(struct snd_efw *efw)
{
unsigned int i;
- spin_lock_irq(&instances_lock);
+ guard(spinlock_irq)(&instances_lock);
for (i = 0; i < SNDRV_CARDS; i++) {
if (instances[i] != NULL)
@@ -267,30 +261,26 @@ void snd_efw_transaction_add_instance(struct snd_efw *efw)
instances[i] = efw;
break;
}
-
- spin_unlock_irq(&instances_lock);
}
void snd_efw_transaction_remove_instance(struct snd_efw *efw)
{
unsigned int i;
- spin_lock_irq(&instances_lock);
+ guard(spinlock_irq)(&instances_lock);
for (i = 0; i < SNDRV_CARDS; i++) {
if (instances[i] != efw)
continue;
instances[i] = NULL;
}
-
- spin_unlock_irq(&instances_lock);
}
void snd_efw_transaction_bus_reset(struct fw_unit *unit)
{
struct transaction_queue *t;
- spin_lock_irq(&transaction_queues_lock);
+ guard(spinlock_irq)(&transaction_queues_lock);
list_for_each_entry(t, &transaction_queues, list) {
if ((t->unit == unit) &&
(t->state == STATE_PENDING)) {
@@ -298,7 +288,6 @@ void snd_efw_transaction_bus_reset(struct fw_unit *unit)
wake_up(&t->wait);
}
}
- spin_unlock_irq(&transaction_queues_lock);
}
static struct fw_address_handler resp_register_handler = {
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index ee574b5d7406..2b7f071d593b 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -327,9 +327,8 @@ static int isight_hw_free(struct snd_pcm_substream *substream)
WRITE_ONCE(isight->pcm_active, false);
- mutex_lock(&isight->mutex);
+ guard(mutex)(&isight->mutex);
isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
return 0;
}
@@ -400,16 +399,12 @@ error:
static int isight_prepare(struct snd_pcm_substream *substream)
{
struct isight *isight = substream->private_data;
- int err;
isight->buffer_pointer = 0;
isight->period_counter = 0;
- mutex_lock(&isight->mutex);
- err = isight_start_streaming(isight);
- mutex_unlock(&isight->mutex);
-
- return err;
+ guard(mutex)(&isight->mutex);
+ return isight_start_streaming(isight);
}
static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -677,9 +672,8 @@ static void isight_bus_reset(struct fw_unit *unit)
if (fw_iso_resources_update(&isight->resources) < 0) {
isight_pcm_abort(isight);
- mutex_lock(&isight->mutex);
+ guard(mutex)(&isight->mutex);
isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
}
}
@@ -691,9 +685,9 @@ static void isight_remove(struct fw_unit *unit)
snd_card_disconnect(isight->card);
- mutex_lock(&isight->mutex);
- isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
+ scoped_guard(mutex, &isight->mutex) {
+ isight_stop_streaming(isight);
+ }
// Block till all of ALSA character devices are released.
snd_card_free(isight->card);
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
index 84f71b2eaa82..4f63279225c5 100644
--- a/sound/firewire/iso-resources.c
+++ b/sound/firewire/iso-resources.c
@@ -114,38 +114,34 @@ int fw_iso_resources_allocate(struct fw_iso_resources *r,
r->bandwidth = packet_bandwidth(max_payload_bytes, speed);
retry_after_bus_reset:
- spin_lock_irq(&card->lock);
- r->generation = card->generation;
- r->bandwidth_overhead = current_bandwidth_overhead(card);
- spin_unlock_irq(&card->lock);
+ scoped_guard(spinlock_irq, &card->lock) {
+ r->generation = card->generation;
+ r->bandwidth_overhead = current_bandwidth_overhead(card);
+ }
err = wait_isoch_resource_delay_after_bus_reset(card);
if (err < 0)
return err;
- mutex_lock(&r->mutex);
-
- bandwidth = r->bandwidth + r->bandwidth_overhead;
- fw_iso_resource_manage(card, r->generation, r->channels_mask,
- &channel, &bandwidth, true);
- if (channel == -EAGAIN) {
- mutex_unlock(&r->mutex);
- goto retry_after_bus_reset;
- }
- if (channel >= 0) {
- r->channel = channel;
- r->allocated = true;
- } else {
- if (channel == -EBUSY)
- dev_err(&r->unit->device,
- "isochronous resources exhausted\n");
- else
- dev_err(&r->unit->device,
- "isochronous resource allocation failed\n");
+ scoped_guard(mutex, &r->mutex) {
+ bandwidth = r->bandwidth + r->bandwidth_overhead;
+ fw_iso_resource_manage(card, r->generation, r->channels_mask,
+ &channel, &bandwidth, true);
+ if (channel == -EAGAIN)
+ goto retry_after_bus_reset;
+ if (channel >= 0) {
+ r->channel = channel;
+ r->allocated = true;
+ } else {
+ if (channel == -EBUSY)
+ dev_err(&r->unit->device,
+ "isochronous resources exhausted\n");
+ else
+ dev_err(&r->unit->device,
+ "isochronous resource allocation failed\n");
+ }
}
- mutex_unlock(&r->mutex);
-
return channel;
}
EXPORT_SYMBOL(fw_iso_resources_allocate);
@@ -166,17 +162,15 @@ int fw_iso_resources_update(struct fw_iso_resources *r)
struct fw_card *card = fw_parent_device(r->unit)->card;
int bandwidth, channel;
- mutex_lock(&r->mutex);
+ guard(mutex)(&r->mutex);
- if (!r->allocated) {
- mutex_unlock(&r->mutex);
+ if (!r->allocated)
return 0;
- }
- spin_lock_irq(&card->lock);
- r->generation = card->generation;
- r->bandwidth_overhead = current_bandwidth_overhead(card);
- spin_unlock_irq(&card->lock);
+ scoped_guard(spinlock_irq, &card->lock) {
+ r->generation = card->generation;
+ r->bandwidth_overhead = current_bandwidth_overhead(card);
+ }
bandwidth = r->bandwidth + r->bandwidth_overhead;
@@ -196,8 +190,6 @@ int fw_iso_resources_update(struct fw_iso_resources *r)
"isochronous resource allocation failed\n");
}
- mutex_unlock(&r->mutex);
-
return channel;
}
EXPORT_SYMBOL(fw_iso_resources_update);
@@ -218,7 +210,7 @@ void fw_iso_resources_free(struct fw_iso_resources *r)
return;
card = fw_parent_device(r->unit)->card;
- mutex_lock(&r->mutex);
+ guard(mutex)(&r->mutex);
if (r->allocated) {
bandwidth = r->bandwidth + r->bandwidth_overhead;
@@ -230,7 +222,5 @@ void fw_iso_resources_free(struct fw_iso_resources *r)
r->allocated = false;
}
-
- mutex_unlock(&r->mutex);
}
EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/sound/firewire/motu/motu-command-dsp-message-parser.c b/sound/firewire/motu/motu-command-dsp-message-parser.c
index 5d8a86a12f1f..c6440e6e360b 100644
--- a/sound/firewire/motu/motu-command-dsp-message-parser.c
+++ b/sound/firewire/motu/motu-command-dsp-message-parser.c
@@ -87,10 +87,9 @@ void snd_motu_command_dsp_message_parser_parse(const struct amdtp_stream *s,
unsigned int data_block_quadlets = s->data_block_quadlets;
struct msg_parser *parser = motu->message_parser;
unsigned int interval = parser->interval;
- unsigned long flags;
int i;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
for (i = 0; i < count; ++i) {
__be32 *buffer = desc->ctx_payload;
@@ -168,17 +167,13 @@ void snd_motu_command_dsp_message_parser_parse(const struct amdtp_stream *s,
}
}
}
-
- spin_unlock_irqrestore(&parser->lock, flags);
}
void snd_motu_command_dsp_message_parser_copy_meter(struct snd_motu *motu,
struct snd_firewire_motu_command_dsp_meter *meter)
{
struct msg_parser *parser = motu->message_parser;
- unsigned long flags;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
memcpy(meter, &parser->meter, sizeof(*meter));
- spin_unlock_irqrestore(&parser->lock, flags);
}
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
index fa2685665db3..981c19430cb0 100644
--- a/sound/firewire/motu/motu-hwdep.c
+++ b/sound/firewire/motu/motu-hwdep.c
@@ -100,18 +100,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_motu *motu = hwdep->private_data;
- __poll_t events;
poll_wait(file, &motu->hwdep_wait, wait);
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
if (motu->dev_lock_changed || motu->msg || has_dsp_event(motu))
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&motu->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
@@ -135,48 +131,35 @@ static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
static int hwdep_lock(struct snd_motu *motu)
{
- int err;
-
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
if (motu->dev_lock_count == 0) {
motu->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&motu->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_motu *motu)
{
- int err;
-
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
if (motu->dev_lock_count == -1) {
motu->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&motu->lock);
-
- return err;
}
static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_motu *motu = hwdep->private_data;
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
if (motu->dev_lock_count == -1)
motu->dev_lock_count = 0;
- spin_unlock_irq(&motu->lock);
return 0;
}
diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c
index eebc7e790ee2..85e3260f9349 100644
--- a/sound/firewire/motu/motu-midi.c
+++ b/sound/firewire/motu/motu-midi.c
@@ -15,18 +15,16 @@ static int midi_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&motu->mutex);
-
- err = snd_motu_stream_reserve_duplex(motu, 0, 0, 0);
- if (err >= 0) {
- ++motu->substreams_counter;
- err = snd_motu_stream_start_duplex(motu);
- if (err < 0)
- --motu->substreams_counter;
+ scoped_guard(mutex, &motu->mutex) {
+ err = snd_motu_stream_reserve_duplex(motu, 0, 0, 0);
+ if (err >= 0) {
+ ++motu->substreams_counter;
+ err = snd_motu_stream_start_duplex(motu);
+ if (err < 0)
+ --motu->substreams_counter;
+ }
}
- mutex_unlock(&motu->mutex);
-
if (err < 0)
snd_motu_stream_lock_release(motu);
@@ -37,12 +35,10 @@ static int midi_close(struct snd_rawmidi_substream *substream)
{
struct snd_motu *motu = substream->rmidi->private_data;
- mutex_lock(&motu->mutex);
-
- --motu->substreams_counter;
- snd_motu_stream_stop_duplex(motu);
-
- mutex_unlock(&motu->mutex);
+ scoped_guard(mutex, &motu->mutex) {
+ --motu->substreams_counter;
+ snd_motu_stream_stop_duplex(motu);
+ }
snd_motu_stream_lock_release(motu);
return 0;
@@ -51,9 +47,8 @@ static int midi_close(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_motu *motu = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&motu->lock, flags);
+ guard(spinlock_irqsave)(&motu->lock);
if (up)
amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
@@ -61,16 +56,13 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
NULL);
-
- spin_unlock_irqrestore(&motu->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_motu *motu = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&motu->lock, flags);
+ guard(spinlock_irqsave)(&motu->lock);
if (up)
amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
@@ -78,8 +70,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
NULL);
-
- spin_unlock_irqrestore(&motu->lock, flags);
}
static void set_midi_substream_names(struct snd_motu *motu,
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c
index 7b4d476af348..600c571edf02 100644
--- a/sound/firewire/motu/motu-pcm.c
+++ b/sound/firewire/motu/motu-pcm.c
@@ -138,59 +138,56 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
return err;
- mutex_lock(&motu->mutex);
-
- err = snd_motu_stream_cache_packet_formats(motu);
- if (err < 0)
- goto err_locked;
-
- err = init_hw_info(motu, substream);
- if (err < 0)
- goto err_locked;
+ scoped_guard(mutex, &motu->mutex) {
+ err = snd_motu_stream_cache_packet_formats(motu);
+ if (err < 0)
+ goto err_locked;
- err = snd_motu_protocol_get_clock_source(motu, &src);
- if (err < 0)
- goto err_locked;
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if ((src != SND_MOTU_CLOCK_SOURCE_INTERNAL &&
- src != SND_MOTU_CLOCK_SOURCE_SPH) ||
- (motu->substreams_counter > 0 && d->events_per_period > 0)) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int rate;
-
- err = snd_motu_protocol_get_clock_rate(motu, &rate);
+ err = init_hw_info(motu, substream);
if (err < 0)
goto err_locked;
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
+ err = snd_motu_protocol_get_clock_source(motu, &src);
+ if (err < 0)
+ goto err_locked;
- if (frames_per_period > 0) {
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if ((src != SND_MOTU_CLOCK_SOURCE_INTERNAL &&
+ src != SND_MOTU_CLOCK_SOURCE_SPH) ||
+ (motu->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int rate;
+
+ err = snd_motu_protocol_get_clock_rate(motu, &rate);
if (err < 0)
goto err_locked;
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0)
- goto err_locked;
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
+ }
}
}
snd_pcm_set_sync(substream);
- mutex_unlock(&motu->mutex);
-
return 0;
err_locked:
- mutex_unlock(&motu->mutex);
snd_motu_stream_lock_release(motu);
return err;
}
@@ -215,12 +212,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&motu->mutex);
+ guard(mutex)(&motu->mutex);
err = snd_motu_stream_reserve_duplex(motu, rate,
frames_per_period, frames_per_buffer);
if (err >= 0)
++motu->substreams_counter;
- mutex_unlock(&motu->mutex);
}
return err;
@@ -230,15 +226,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_motu *motu = substream->private_data;
- mutex_lock(&motu->mutex);
+ guard(mutex)(&motu->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--motu->substreams_counter;
snd_motu_stream_stop_duplex(motu);
- mutex_unlock(&motu->mutex);
-
return 0;
}
@@ -247,9 +241,9 @@ static int capture_prepare(struct snd_pcm_substream *substream)
struct snd_motu *motu = substream->private_data;
int err;
- mutex_lock(&motu->mutex);
- err = snd_motu_stream_start_duplex(motu);
- mutex_unlock(&motu->mutex);
+ scoped_guard(mutex, &motu->mutex) {
+ err = snd_motu_stream_start_duplex(motu);
+ }
if (err >= 0)
amdtp_stream_pcm_prepare(&motu->tx_stream);
@@ -260,9 +254,9 @@ static int playback_prepare(struct snd_pcm_substream *substream)
struct snd_motu *motu = substream->private_data;
int err;
- mutex_lock(&motu->mutex);
- err = snd_motu_stream_start_duplex(motu);
- mutex_unlock(&motu->mutex);
+ scoped_guard(mutex, &motu->mutex) {
+ err = snd_motu_stream_start_duplex(motu);
+ }
if (err >= 0)
amdtp_stream_pcm_prepare(&motu->rx_stream);
diff --git a/sound/firewire/motu/motu-register-dsp-message-parser.c b/sound/firewire/motu/motu-register-dsp-message-parser.c
index ef3b0b0f0dab..a8053e3ef065 100644
--- a/sound/firewire/motu/motu-register-dsp-message-parser.c
+++ b/sound/firewire/motu/motu-register-dsp-message-parser.c
@@ -150,10 +150,9 @@ void snd_motu_register_dsp_message_parser_parse(const struct amdtp_stream *s,
struct msg_parser *parser = motu->message_parser;
bool meter_pos_quirk = parser->meter_pos_quirk;
unsigned int pos = parser->push_pos;
- unsigned long flags;
int i;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
for (i = 0; i < count; ++i) {
__be32 *buffer = desc->ctx_payload;
@@ -363,30 +362,24 @@ void snd_motu_register_dsp_message_parser_parse(const struct amdtp_stream *s,
if (pos != parser->push_pos)
wake_up(&motu->hwdep_wait);
-
- spin_unlock_irqrestore(&parser->lock, flags);
}
void snd_motu_register_dsp_message_parser_copy_meter(struct snd_motu *motu,
struct snd_firewire_motu_register_dsp_meter *meter)
{
struct msg_parser *parser = motu->message_parser;
- unsigned long flags;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
memcpy(meter, &parser->meter, sizeof(*meter));
- spin_unlock_irqrestore(&parser->lock, flags);
}
void snd_motu_register_dsp_message_parser_copy_parameter(struct snd_motu *motu,
struct snd_firewire_motu_register_dsp_parameter *param)
{
struct msg_parser *parser = motu->message_parser;
- unsigned long flags;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
memcpy(param, &parser->param, sizeof(*param));
- spin_unlock_irqrestore(&parser->lock, flags);
}
unsigned int snd_motu_register_dsp_message_parser_count_event(struct snd_motu *motu)
@@ -403,12 +396,11 @@ bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32
{
struct msg_parser *parser = motu->message_parser;
unsigned int pos = parser->pull_pos;
- unsigned long flags;
if (pos == parser->push_pos)
return false;
- spin_lock_irqsave(&parser->lock, flags);
+ guard(spinlock_irqsave)(&parser->lock);
*event = parser->event_queue[pos];
@@ -417,7 +409,5 @@ bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32
pos = 0;
parser->pull_pos = pos;
- spin_unlock_irqrestore(&parser->lock, flags);
-
return true;
}
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
index 64aec9c3eefd..e5f21360cfb7 100644
--- a/sound/firewire/motu/motu-stream.c
+++ b/sound/firewire/motu/motu-stream.c
@@ -407,32 +407,23 @@ static void motu_lock_changed(struct snd_motu *motu)
int snd_motu_stream_lock_try(struct snd_motu *motu)
{
- int err;
-
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
- if (motu->dev_lock_count < 0) {
- err = -EBUSY;
- goto out;
- }
+ if (motu->dev_lock_count < 0)
+ return -EBUSY;
if (motu->dev_lock_count++ == 0)
motu_lock_changed(motu);
- err = 0;
-out:
- spin_unlock_irq(&motu->lock);
- return err;
+ return 0;
}
void snd_motu_stream_lock_release(struct snd_motu *motu)
{
- spin_lock_irq(&motu->lock);
+ guard(spinlock_irq)(&motu->lock);
if (WARN_ON(motu->dev_lock_count <= 0))
- goto out;
+ return;
if (--motu->dev_lock_count == 0)
motu_lock_changed(motu);
-out:
- spin_unlock_irq(&motu->lock);
}
diff --git a/sound/firewire/motu/motu-transaction.c b/sound/firewire/motu/motu-transaction.c
index 2dc1d6e59144..804f4208cf81 100644
--- a/sound/firewire/motu/motu-transaction.c
+++ b/sound/firewire/motu/motu-transaction.c
@@ -51,7 +51,6 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
{
struct snd_motu *motu = callback_data;
__be32 *buf = (__be32 *)data;
- unsigned long flags;
if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
fw_send_response(card, request, RCODE_COMPLETE);
@@ -63,9 +62,9 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
return;
}
- spin_lock_irqsave(&motu->lock, flags);
- motu->msg = be32_to_cpu(*buf);
- spin_unlock_irqrestore(&motu->lock, flags);
+ scoped_guard(spinlock_irqsave, &motu->lock) {
+ motu->msg = be32_to_cpu(*buf);
+ }
fw_send_response(card, request, RCODE_COMPLETE);
diff --git a/sound/firewire/oxfw/oxfw-hwdep.c b/sound/firewire/oxfw/oxfw-hwdep.c
index 3be214d8a922..f8ac362fc73a 100644
--- a/sound/firewire/oxfw/oxfw-hwdep.c
+++ b/sound/firewire/oxfw/oxfw-hwdep.c
@@ -53,18 +53,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_oxfw *oxfw = hwdep->private_data;
- __poll_t events;
poll_wait(file, &oxfw->hwdep_wait, wait);
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
if (oxfw->dev_lock_changed)
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&oxfw->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_oxfw *oxfw, void __user *arg)
@@ -88,48 +84,35 @@ static int hwdep_get_info(struct snd_oxfw *oxfw, void __user *arg)
static int hwdep_lock(struct snd_oxfw *oxfw)
{
- int err;
-
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
if (oxfw->dev_lock_count == 0) {
oxfw->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&oxfw->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_oxfw *oxfw)
{
- int err;
-
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
if (oxfw->dev_lock_count == -1) {
oxfw->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&oxfw->lock);
-
- return err;
}
static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_oxfw *oxfw = hwdep->private_data;
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
if (oxfw->dev_lock_count == -1)
oxfw->dev_lock_count = 0;
- spin_unlock_irq(&oxfw->lock);
return 0;
}
diff --git a/sound/firewire/oxfw/oxfw-midi.c b/sound/firewire/oxfw/oxfw-midi.c
index c215fa6f7a03..a16bf885f918 100644
--- a/sound/firewire/oxfw/oxfw-midi.c
+++ b/sound/firewire/oxfw/oxfw-midi.c
@@ -16,18 +16,16 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&oxfw->mutex);
-
- err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0, 0, 0);
- if (err >= 0) {
- ++oxfw->substreams_count;
- err = snd_oxfw_stream_start_duplex(oxfw);
- if (err < 0)
- --oxfw->substreams_count;
+ scoped_guard(mutex, &oxfw->mutex) {
+ err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0, 0, 0);
+ if (err >= 0) {
+ ++oxfw->substreams_count;
+ err = snd_oxfw_stream_start_duplex(oxfw);
+ if (err < 0)
+ --oxfw->substreams_count;
+ }
}
- mutex_unlock(&oxfw->mutex);
-
if (err < 0)
snd_oxfw_stream_lock_release(oxfw);
@@ -43,16 +41,14 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)
if (err < 0)
return err;
- mutex_lock(&oxfw->mutex);
-
- err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0, 0, 0);
- if (err >= 0) {
- ++oxfw->substreams_count;
- err = snd_oxfw_stream_start_duplex(oxfw);
+ scoped_guard(mutex, &oxfw->mutex) {
+ err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0, 0, 0);
+ if (err >= 0) {
+ ++oxfw->substreams_count;
+ err = snd_oxfw_stream_start_duplex(oxfw);
+ }
}
- mutex_unlock(&oxfw->mutex);
-
if (err < 0)
snd_oxfw_stream_lock_release(oxfw);
@@ -63,12 +59,10 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream)
{
struct snd_oxfw *oxfw = substream->rmidi->private_data;
- mutex_lock(&oxfw->mutex);
-
- --oxfw->substreams_count;
- snd_oxfw_stream_stop_duplex(oxfw);
-
- mutex_unlock(&oxfw->mutex);
+ scoped_guard(mutex, &oxfw->mutex) {
+ --oxfw->substreams_count;
+ snd_oxfw_stream_stop_duplex(oxfw);
+ }
snd_oxfw_stream_lock_release(oxfw);
return 0;
@@ -78,12 +72,10 @@ static int midi_playback_close(struct snd_rawmidi_substream *substream)
{
struct snd_oxfw *oxfw = substream->rmidi->private_data;
- mutex_lock(&oxfw->mutex);
-
- --oxfw->substreams_count;
- snd_oxfw_stream_stop_duplex(oxfw);
-
- mutex_unlock(&oxfw->mutex);
+ scoped_guard(mutex, &oxfw->mutex) {
+ --oxfw->substreams_count;
+ snd_oxfw_stream_stop_duplex(oxfw);
+ }
snd_oxfw_stream_lock_release(oxfw);
return 0;
@@ -92,9 +84,8 @@ static int midi_playback_close(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_oxfw *oxfw = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&oxfw->lock, flags);
+ guard(spinlock_irqsave)(&oxfw->lock);
if (up)
amdtp_am824_midi_trigger(&oxfw->tx_stream,
@@ -102,16 +93,13 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&oxfw->tx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&oxfw->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_oxfw *oxfw = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&oxfw->lock, flags);
+ guard(spinlock_irqsave)(&oxfw->lock);
if (up)
amdtp_am824_midi_trigger(&oxfw->rx_stream,
@@ -119,8 +107,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
else
amdtp_am824_midi_trigger(&oxfw->rx_stream,
substrm->number, NULL);
-
- spin_unlock_irqrestore(&oxfw->lock, flags);
}
static void set_midi_substream_names(struct snd_oxfw *oxfw,
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index e13dc817fc28..774b8a763795 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -181,42 +181,34 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
goto err_locked;
- mutex_lock(&oxfw->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if (oxfw->substreams_count > 0 && d->events_per_period > 0) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
-
- err = limit_to_current_params(substream);
- if (err < 0) {
- mutex_unlock(&oxfw->mutex);
- goto err_locked;
- }
-
- if (frames_per_period > 0) {
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&oxfw->mutex);
+ scoped_guard(mutex, &oxfw->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if (oxfw->substreams_count > 0 && d->events_per_period > 0) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+
+ err = limit_to_current_params(substream);
+ if (err < 0)
goto err_locked;
- }
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&oxfw->mutex);
- goto err_locked;
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
}
- mutex_unlock(&oxfw->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -245,13 +237,12 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&oxfw->mutex);
+ guard(mutex)(&oxfw->mutex);
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
rate, channels, frames_per_period,
frames_per_buffer);
if (err >= 0)
++oxfw->substreams_count;
- mutex_unlock(&oxfw->mutex);
}
return err;
@@ -268,13 +259,12 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&oxfw->mutex);
+ guard(mutex)(&oxfw->mutex);
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream,
rate, channels, frames_per_period,
frames_per_buffer);
if (err >= 0)
++oxfw->substreams_count;
- mutex_unlock(&oxfw->mutex);
}
return err;
@@ -284,30 +274,26 @@ static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
{
struct snd_oxfw *oxfw = substream->private_data;
- mutex_lock(&oxfw->mutex);
+ guard(mutex)(&oxfw->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--oxfw->substreams_count;
snd_oxfw_stream_stop_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
-
return 0;
}
static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
{
struct snd_oxfw *oxfw = substream->private_data;
- mutex_lock(&oxfw->mutex);
+ guard(mutex)(&oxfw->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--oxfw->substreams_count;
snd_oxfw_stream_stop_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
-
return 0;
}
@@ -316,30 +302,28 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
struct snd_oxfw *oxfw = substream->private_data;
int err;
- mutex_lock(&oxfw->mutex);
- err = snd_oxfw_stream_start_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
- if (err < 0)
- goto end;
+ scoped_guard(mutex, &oxfw->mutex) {
+ err = snd_oxfw_stream_start_duplex(oxfw);
+ if (err < 0)
+ return err;
+ }
amdtp_stream_pcm_prepare(&oxfw->tx_stream);
-end:
- return err;
+ return 0;
}
static int pcm_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_oxfw *oxfw = substream->private_data;
int err;
- mutex_lock(&oxfw->mutex);
- err = snd_oxfw_stream_start_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
- if (err < 0)
- goto end;
+ scoped_guard(mutex, &oxfw->mutex) {
+ err = snd_oxfw_stream_start_duplex(oxfw);
+ if (err < 0)
+ return err;
+ }
amdtp_stream_pcm_prepare(&oxfw->rx_stream);
-end:
- return err;
+ return 0;
}
static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 00f7feb91f92..5e36d7153a7b 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -866,33 +866,24 @@ void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
{
- int err;
-
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
/* user land lock this */
- if (oxfw->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (oxfw->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (oxfw->dev_lock_count++ == 0)
snd_oxfw_stream_lock_changed(oxfw);
- err = 0;
-end:
- spin_unlock_irq(&oxfw->lock);
- return err;
+ return 0;
}
void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
{
- spin_lock_irq(&oxfw->lock);
+ guard(spinlock_irq)(&oxfw->lock);
if (WARN_ON(oxfw->dev_lock_count <= 0))
- goto end;
+ return;
if (--oxfw->dev_lock_count == 0)
snd_oxfw_stream_lock_changed(oxfw);
-end:
- spin_unlock_irq(&oxfw->lock);
}
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 7a985f3cb8f6..5039bd79b18e 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -283,9 +283,8 @@ static void oxfw_bus_reset(struct fw_unit *unit)
fcp_bus_reset(oxfw->unit);
if (oxfw->has_output || oxfw->has_input) {
- mutex_lock(&oxfw->mutex);
+ guard(mutex)(&oxfw->mutex);
snd_oxfw_stream_update_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
}
if (oxfw->quirks & SND_OXFW_QUIRK_SCS_TRANSACTION)
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
index 079afa4bd381..59c339d9b5fb 100644
--- a/sound/firewire/tascam/amdtp-tascam.c
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -157,15 +157,14 @@ static void read_status_messages(struct amdtp_stream *s,
if ((before ^ after) & mask) {
struct snd_firewire_tascam_change *entry =
&tscm->queue[tscm->push_pos];
- unsigned long flag;
-
- spin_lock_irqsave(&tscm->lock, flag);
- entry->index = index;
- entry->before = before;
- entry->after = after;
- if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
- tscm->push_pos = 0;
- spin_unlock_irqrestore(&tscm->lock, flag);
+
+ scoped_guard(spinlock_irqsave, &tscm->lock) {
+ entry->index = index;
+ entry->before = before;
+ entry->after = after;
+ if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
+ tscm->push_pos = 0;
+ }
wake_up(&tscm->hwdep_wait);
}
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index 8fc30cba29d5..867b4ea1096e 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -130,18 +130,14 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_table *wait)
{
struct snd_tscm *tscm = hwdep->private_data;
- __poll_t events;
poll_wait(file, &tscm->hwdep_wait, wait);
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
if (tscm->dev_lock_changed || tscm->push_pos != tscm->pull_pos)
- events = EPOLLIN | EPOLLRDNORM;
+ return EPOLLIN | EPOLLRDNORM;
else
- events = 0;
- spin_unlock_irq(&tscm->lock);
-
- return events;
+ return 0;
}
static int hwdep_get_info(struct snd_tscm *tscm, void __user *arg)
@@ -165,38 +161,26 @@ static int hwdep_get_info(struct snd_tscm *tscm, void __user *arg)
static int hwdep_lock(struct snd_tscm *tscm)
{
- int err;
-
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
if (tscm->dev_lock_count == 0) {
tscm->dev_lock_count = -1;
- err = 0;
+ return 0;
} else {
- err = -EBUSY;
+ return -EBUSY;
}
-
- spin_unlock_irq(&tscm->lock);
-
- return err;
}
static int hwdep_unlock(struct snd_tscm *tscm)
{
- int err;
-
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
if (tscm->dev_lock_count == -1) {
tscm->dev_lock_count = 0;
- err = 0;
+ return 0;
} else {
- err = -EBADFD;
+ return -EBADFD;
}
-
- spin_unlock_irq(&tscm->lock);
-
- return err;
}
static int tscm_hwdep_state(struct snd_tscm *tscm, void __user *arg)
@@ -211,10 +195,9 @@ static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
struct snd_tscm *tscm = hwdep->private_data;
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
if (tscm->dev_lock_count == -1)
tscm->dev_lock_count = 0;
- spin_unlock_irq(&tscm->lock);
return 0;
}
diff --git a/sound/firewire/tascam/tascam-midi.c b/sound/firewire/tascam/tascam-midi.c
index c57fac4f1968..1bf9d7b3da33 100644
--- a/sound/firewire/tascam/tascam-midi.c
+++ b/sound/firewire/tascam/tascam-midi.c
@@ -43,30 +43,24 @@ static void midi_playback_drain(struct snd_rawmidi_substream *substream)
static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_tscm *tscm = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&tscm->lock, flags);
+ guard(spinlock_irqsave)(&tscm->lock);
if (up)
tscm->tx_midi_substreams[substrm->number] = substrm;
else
tscm->tx_midi_substreams[substrm->number] = NULL;
-
- spin_unlock_irqrestore(&tscm->lock, flags);
}
static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
struct snd_tscm *tscm = substrm->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&tscm->lock, flags);
+ guard(spinlock_irqsave)(&tscm->lock);
if (up)
snd_fw_async_midi_port_run(&tscm->out_ports[substrm->number],
substrm);
-
- spin_unlock_irqrestore(&tscm->lock, flags);
}
int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
diff --git a/sound/firewire/tascam/tascam-pcm.c b/sound/firewire/tascam/tascam-pcm.c
index a73003ac11e6..d885fef0c8ca 100644
--- a/sound/firewire/tascam/tascam-pcm.c
+++ b/sound/firewire/tascam/tascam-pcm.c
@@ -59,43 +59,35 @@ static int pcm_open(struct snd_pcm_substream *substream)
if (err < 0)
goto err_locked;
- mutex_lock(&tscm->mutex);
-
- // When source of clock is not internal or any stream is reserved for
- // transmission of PCM frames, the available sampling rate is limited
- // at current one.
- if (clock != SND_TSCM_CLOCK_INTERNAL || tscm->substreams_counter > 0) {
- unsigned int frames_per_period = d->events_per_period;
- unsigned int frames_per_buffer = d->events_per_buffer;
- unsigned int rate;
-
- err = snd_tscm_stream_get_rate(tscm, &rate);
- if (err < 0) {
- mutex_unlock(&tscm->mutex);
- goto err_locked;
- }
- substream->runtime->hw.rate_min = rate;
- substream->runtime->hw.rate_max = rate;
-
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- frames_per_period, frames_per_period);
- if (err < 0) {
- mutex_unlock(&tscm->mutex);
- goto err_locked;
- }
-
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- frames_per_buffer, frames_per_buffer);
- if (err < 0) {
- mutex_unlock(&tscm->mutex);
- goto err_locked;
+ scoped_guard(mutex, &tscm->mutex) {
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
+ if (clock != SND_TSCM_CLOCK_INTERNAL || tscm->substreams_counter > 0) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int rate;
+
+ err = snd_tscm_stream_get_rate(tscm, &rate);
+ if (err < 0)
+ goto err_locked;
+ substream->runtime->hw.rate_min = rate;
+ substream->runtime->hw.rate_max = rate;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0)
+ goto err_locked;
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0)
+ goto err_locked;
}
}
- mutex_unlock(&tscm->mutex);
-
snd_pcm_set_sync(substream);
return 0;
@@ -124,12 +116,11 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int frames_per_period = params_period_size(hw_params);
unsigned int frames_per_buffer = params_buffer_size(hw_params);
- mutex_lock(&tscm->mutex);
+ guard(mutex)(&tscm->mutex);
err = snd_tscm_stream_reserve_duplex(tscm, rate,
frames_per_period, frames_per_buffer);
if (err >= 0)
++tscm->substreams_counter;
- mutex_unlock(&tscm->mutex);
}
return err;
@@ -139,15 +130,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_tscm *tscm = substream->private_data;
- mutex_lock(&tscm->mutex);
+ guard(mutex)(&tscm->mutex);
if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
--tscm->substreams_counter;
snd_tscm_stream_stop_duplex(tscm);
- mutex_unlock(&tscm->mutex);
-
return 0;
}
@@ -157,14 +146,12 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- mutex_lock(&tscm->mutex);
+ guard(mutex)(&tscm->mutex);
err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
if (err >= 0)
amdtp_stream_pcm_prepare(&tscm->tx_stream);
- mutex_unlock(&tscm->mutex);
-
return err;
}
@@ -174,14 +161,12 @@ static int pcm_playback_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- mutex_lock(&tscm->mutex);
+ guard(mutex)(&tscm->mutex);
err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
if (err >= 0)
amdtp_stream_pcm_prepare(&tscm->rx_stream);
- mutex_unlock(&tscm->mutex);
-
return err;
}
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index dfe783d01d7d..9c8fddd7dee1 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -527,33 +527,24 @@ void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
{
- int err;
-
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
/* user land lock this */
- if (tscm->dev_lock_count < 0) {
- err = -EBUSY;
- goto end;
- }
+ if (tscm->dev_lock_count < 0)
+ return -EBUSY;
/* this is the first time */
if (tscm->dev_lock_count++ == 0)
snd_tscm_stream_lock_changed(tscm);
- err = 0;
-end:
- spin_unlock_irq(&tscm->lock);
- return err;
+ return 0;
}
void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
{
- spin_lock_irq(&tscm->lock);
+ guard(spinlock_irq)(&tscm->lock);
if (WARN_ON(tscm->dev_lock_count <= 0))
- goto end;
+ return;
if (--tscm->dev_lock_count == 0)
snd_tscm_stream_lock_changed(tscm);
-end:
- spin_unlock_irq(&tscm->lock);
}
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
index 4f68bb4c58bc..f4092df8650c 100644
--- a/sound/firewire/tascam/tascam.c
+++ b/sound/firewire/tascam/tascam.c
@@ -158,9 +158,8 @@ static void snd_tscm_update(struct fw_unit *unit)
snd_tscm_transaction_reregister(tscm);
- mutex_lock(&tscm->mutex);
+ guard(mutex)(&tscm->mutex);
snd_tscm_stream_update_duplex(tscm);
- mutex_unlock(&tscm->mutex);
}
static void snd_tscm_remove(struct fw_unit *unit)
diff --git a/sound/hda/codecs/analog.c b/sound/hda/codecs/analog.c
index 33aaeb44c4dc..357ad5a6c0db 100644
--- a/sound/hda/codecs/analog.c
+++ b/sound/hda/codecs/analog.c
@@ -727,7 +727,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
if (spec->cur_smux == val)
return 0;
- mutex_lock(&codec->control_mutex);
+ guard(mutex)(&codec->control_mutex);
path = snd_hda_get_path_from_idx(codec,
spec->smux_paths[spec->cur_smux]);
if (path)
@@ -736,7 +736,6 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
if (path)
snd_hda_activate_path(codec, path, true, true);
spec->cur_smux = val;
- mutex_unlock(&codec->control_mutex);
return 1;
}
diff --git a/sound/hda/codecs/ca0132.c b/sound/hda/codecs/ca0132.c
index b7d456e16c93..dd054aedd501 100644
--- a/sound/hda/codecs/ca0132.c
+++ b/sound/hda/codecs/ca0132.c
@@ -1684,20 +1684,14 @@ static int chipio_write(struct hda_codec *codec,
struct ca0132_spec *spec = codec->spec;
int err;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
/* write the address, and if successful proceed to write data */
err = chipio_write_address(codec, chip_addx);
if (err < 0)
- goto exit;
-
- err = chipio_write_data(codec, data);
- if (err < 0)
- goto exit;
+ return err;
-exit:
- mutex_unlock(&spec->chipio_mutex);
- return err;
+ return chipio_write_data(codec, data);
}
/*
@@ -1735,16 +1729,12 @@ static int chipio_write_multiple(struct hda_codec *codec,
struct ca0132_spec *spec = codec->spec;
int status;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
status = chipio_write_address(codec, chip_addx);
if (status < 0)
- goto error;
-
- status = chipio_write_data_multiple(codec, data, count);
-error:
- mutex_unlock(&spec->chipio_mutex);
+ return status;
- return status;
+ return chipio_write_data_multiple(codec, data, count);
}
/*
@@ -1757,20 +1747,14 @@ static int chipio_read(struct hda_codec *codec,
struct ca0132_spec *spec = codec->spec;
int err;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
/* write the address, and if successful proceed to write data */
err = chipio_write_address(codec, chip_addx);
if (err < 0)
- goto exit;
-
- err = chipio_read_data(codec, data);
- if (err < 0)
- goto exit;
+ return err;
-exit:
- mutex_unlock(&spec->chipio_mutex);
- return err;
+ return chipio_read_data(codec, data);
}
/*
@@ -1803,7 +1787,7 @@ static void chipio_set_control_param(struct hda_codec *codec,
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
VENDOR_CHIPIO_PARAM_SET, val);
} else {
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) {
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
VENDOR_CHIPIO_PARAM_EX_ID_SET,
@@ -1812,7 +1796,6 @@ static void chipio_set_control_param(struct hda_codec *codec,
VENDOR_CHIPIO_PARAM_EX_VALUE_SET,
param_val);
}
- mutex_unlock(&spec->chipio_mutex);
}
}
@@ -1977,12 +1960,10 @@ static void chipio_8051_write_exram(struct hda_codec *codec,
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_8051_set_address(codec, addr);
chipio_8051_set_data(codec, data);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void chipio_8051_write_exram_no_mutex(struct hda_codec *codec,
@@ -2005,12 +1986,10 @@ static void chipio_8051_write_pll_pmu(struct hda_codec *codec,
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_8051_set_address(codec, addr & 0xff);
chipio_8051_set_data_pll(codec, data);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void chipio_8051_write_pll_pmu_no_mutex(struct hda_codec *codec,
@@ -2027,13 +2006,11 @@ static void chipio_enable_clocks(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_8051_write_pll_pmu_no_mutex(codec, 0x00, 0xff);
chipio_8051_write_pll_pmu_no_mutex(codec, 0x05, 0x0b);
chipio_8051_write_pll_pmu_no_mutex(codec, 0x06, 0xff);
-
- mutex_unlock(&spec->chipio_mutex);
}
/*
@@ -2084,22 +2061,20 @@ static int dspio_write(struct hda_codec *codec, unsigned int scp_data)
dspio_write_wait(codec);
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
status = dspio_send(codec, VENDOR_DSPIO_SCP_WRITE_DATA_LOW,
scp_data & 0xffff);
if (status < 0)
- goto error;
+ return status;
status = dspio_send(codec, VENDOR_DSPIO_SCP_WRITE_DATA_HIGH,
scp_data >> 16);
if (status < 0)
- goto error;
+ return status;
/* OK, now check if the write itself has executed*/
status = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0,
VENDOR_DSPIO_STATUS, 0);
-error:
- mutex_unlock(&spec->chipio_mutex);
return (status == VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL) ?
-EIO : 0;
@@ -4236,21 +4211,19 @@ static const unsigned int equalizer_vals_lookup[] = {
static int tuning_ctl_set(struct hda_codec *codec, hda_nid_t nid,
const unsigned int *lookup, int idx)
{
- int i = 0;
+ int i;
- for (i = 0; i < TUNING_CTLS_COUNT; i++)
- if (nid == ca0132_tuning_ctls[i].nid)
- goto found;
+ for (i = 0; i < TUNING_CTLS_COUNT; i++) {
+ if (nid == ca0132_tuning_ctls[i].nid) {
+ CLASS(snd_hda_power, pm)(codec);
+ dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
+ ca0132_tuning_ctls[i].req,
+ &(lookup[idx]), sizeof(unsigned int));
+ return 1;
+ }
+ }
return -EINVAL;
-found:
- snd_hda_power_up(codec);
- dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
- ca0132_tuning_ctls[i].req,
- &(lookup[idx]), sizeof(unsigned int));
- snd_hda_power_down(codec);
-
- return 1;
}
static int tuning_ctl_get(struct snd_kcontrol *kcontrol,
@@ -4465,7 +4438,7 @@ static int ca0132_select_out(struct hda_codec *codec)
codec_dbg(codec, "ca0132_select_out\n");
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
@@ -4486,12 +4459,12 @@ static int ca0132_select_out(struct hda_codec *codec)
tmp = FLOAT_ONE;
err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
if (err < 0)
- goto exit;
+ return err;
/*enable speaker EQ*/
tmp = FLOAT_ONE;
err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp);
if (err < 0)
- goto exit;
+ return err;
/* Setup EAPD */
snd_hda_codec_write(codec, spec->out_pins[1], 0,
@@ -4519,12 +4492,12 @@ static int ca0132_select_out(struct hda_codec *codec)
tmp = FLOAT_ZERO;
err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
if (err < 0)
- goto exit;
+ return err;
/*disable speaker EQ*/
tmp = FLOAT_ZERO;
err = dspio_set_uint_param(codec, 0x8f, 0x00, tmp);
if (err < 0)
- goto exit;
+ return err;
/* Setup EAPD */
snd_hda_codec_write(codec, spec->out_pins[0], 0,
@@ -4548,10 +4521,7 @@ static int ca0132_select_out(struct hda_codec *codec)
pin_ctl | PIN_HP);
}
-exit:
- snd_hda_power_down_pm(codec);
-
- return err < 0 ? err : 0;
+ return 0;
}
static int ae5_headphone_gain_set(struct hda_codec *codec, long val);
@@ -4775,7 +4745,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
codec_dbg(codec, "%s\n", __func__);
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
@@ -4800,11 +4770,11 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
/* Begin DSP output switch, mute DSP volume. */
err = dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_MUTE, FLOAT_ONE);
if (err < 0)
- goto exit;
+ return err;
err = ca0132_alt_select_out_quirk_set(codec);
if (err < 0)
- goto exit;
+ return err;
switch (spec->cur_out_type) {
case SPEAKER_OUT:
@@ -4835,7 +4805,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
err = dspio_set_uint_param(codec, 0x80, 0x04, tmp);
if (err < 0)
- goto exit;
+ return err;
break;
case HEADPHONE_OUT:
@@ -4862,7 +4832,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
err = dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO);
if (err < 0)
- goto exit;
+ return err;
break;
}
/*
@@ -4877,7 +4847,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
/* Set speaker EQ bypass attenuation to 0. */
err = dspio_set_uint_param(codec, 0x8f, 0x01, FLOAT_ZERO);
if (err < 0)
- goto exit;
+ return err;
/*
* Although unused on all cards but the AE series, this is always set
@@ -4886,7 +4856,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
err = dspio_set_uint_param(codec, 0x96,
SPEAKER_TUNING_USE_SPEAKER_EQ, FLOAT_ZERO);
if (err < 0)
- goto exit;
+ return err;
if (spec->cur_out_type == SPEAKER_OUT)
err = ca0132_alt_surround_set_bass_redirection(codec,
@@ -4894,24 +4864,21 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
else
err = ca0132_alt_surround_set_bass_redirection(codec, 0);
if (err < 0)
- goto exit;
+ return err;
/* Unmute DSP now that we're done with output selection. */
err = dspio_set_uint_param(codec, 0x96,
SPEAKER_TUNING_MUTE, FLOAT_ZERO);
if (err < 0)
- goto exit;
+ return err;
if (spec->cur_out_type == SPEAKER_OUT) {
err = ca0132_alt_set_full_range_speaker(codec);
if (err < 0)
- goto exit;
+ return err;
}
-exit:
- snd_hda_power_down_pm(codec);
-
- return err < 0 ? err : 0;
+ return 0;
}
static void ca0132_unsol_hp_delayed(struct work_struct *work)
@@ -5059,7 +5026,7 @@ static int ca0132_select_mic(struct hda_codec *codec)
codec_dbg(codec, "ca0132_select_mic\n");
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
auto_jack = spec->vnode_lswitch[VNID_AMIC1_ASEL - VNODE_START_NID];
@@ -5092,8 +5059,6 @@ static int ca0132_select_mic(struct hda_codec *codec)
ca0132_effects_set(codec, VOICE_FOCUS, 0);
}
- snd_hda_power_down_pm(codec);
-
return 0;
}
@@ -5110,7 +5075,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
codec_dbg(codec, "%s\n", __func__);
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
chipio_set_stream_control(codec, 0x03, 0);
chipio_set_stream_control(codec, 0x04, 0);
@@ -5273,7 +5238,6 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
}
ca0132_cvoice_switch_set(codec);
- snd_hda_power_down_pm(codec);
return 0;
}
@@ -5595,13 +5559,12 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
int ch = get_amp_channels(kcontrol);
unsigned long pval;
- mutex_lock(&codec->control_mutex);
+ guard(mutex)(&codec->control_mutex);
pval = kcontrol->private_value;
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(shared_nid, ch,
0, dir);
ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
}
return ret;
@@ -5611,12 +5574,10 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
static void ca0132_alt_bass_redirection_xover_set(struct hda_codec *codec,
long idx)
{
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
dspio_set_param(codec, 0x96, 0x20, SPEAKER_BASS_REDIRECT_XOVER_FREQ,
&(float_xbass_xover_lookup[idx]), sizeof(unsigned int));
-
- snd_hda_power_down(codec);
}
/*
@@ -5642,7 +5603,7 @@ static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
else
y = 1;
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
if (nid == XBASS_XOVER) {
for (i = 0; i < OUT_EFFECTS_COUNT; i++)
if (ca0132_effects[i].nid == X_BASS)
@@ -5662,8 +5623,6 @@ static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
&(lookup[idx]), sizeof(unsigned int));
}
- snd_hda_power_down(codec);
-
return 0;
}
@@ -6342,12 +6301,11 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
hda_nid_t nid = get_amp_nid(kcontrol);
int ch = get_amp_channels(kcontrol);
long *valp = ucontrol->value.integer.value;
- int changed = 1;
codec_dbg(codec, "ca0132_switch_put: nid=0x%x, val=%ld\n",
nid, *valp);
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
/* vnode */
if ((nid >= VNODE_START_NID) && (nid < VNODE_END_NID)) {
if (ch & 1) {
@@ -6358,30 +6316,26 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
spec->vnode_rswitch[nid - VNODE_START_NID] = *valp;
valp++;
}
- changed = ca0132_vnode_switch_set(kcontrol, ucontrol);
- goto exit;
+ return ca0132_vnode_switch_set(kcontrol, ucontrol);
}
/* PE */
if (nid == PLAY_ENHANCEMENT) {
spec->effects_switch[nid - EFFECT_START_NID] = *valp;
- changed = ca0132_pe_switch_set(codec);
- goto exit;
+ return ca0132_pe_switch_set(codec);
}
/* CrystalVoice */
if (nid == CRYSTAL_VOICE) {
spec->effects_switch[nid - EFFECT_START_NID] = *valp;
- changed = ca0132_cvoice_switch_set(codec);
- goto exit;
+ return ca0132_cvoice_switch_set(codec);
}
/* out and in effects */
if (((nid >= OUT_EFFECT_START_NID) && (nid < OUT_EFFECT_END_NID)) ||
((nid >= IN_EFFECT_START_NID) && (nid < IN_EFFECT_END_NID))) {
spec->effects_switch[nid - EFFECT_START_NID] = *valp;
- changed = ca0132_effects_set(codec, nid, *valp);
- goto exit;
+ return ca0132_effects_set(codec, nid, *valp);
}
/* mic boost */
@@ -6389,24 +6343,22 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
spec->cur_mic_boost = *valp;
if (ca0132_use_alt_functions(spec)) {
if (spec->in_enum_val != REAR_LINE_IN)
- changed = ca0132_mic_boost_set(codec, *valp);
+ return ca0132_mic_boost_set(codec, *valp);
} else {
/* Mic boost does not apply to Digital Mic */
if (spec->cur_mic_type != DIGITAL_MIC)
- changed = ca0132_mic_boost_set(codec, *valp);
+ return ca0132_mic_boost_set(codec, *valp);
}
- goto exit;
+ return 1;
}
if (nid == ZXR_HEADPHONE_GAIN) {
spec->zxr_gain_set = *valp;
if (spec->cur_out_type == HEADPHONE_OUT)
- changed = zxr_headphone_gain_set(codec, *valp);
+ return zxr_headphone_gain_set(codec, *valp);
else
- changed = 0;
-
- goto exit;
+ return 0;
}
if (nid == SPEAKER_FULL_RANGE_FRONT || nid == SPEAKER_FULL_RANGE_REAR) {
@@ -6414,7 +6366,7 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
if (spec->cur_out_type == SPEAKER_OUT)
ca0132_alt_set_full_range_speaker(codec);
- changed = 0;
+ return 0;
}
if (nid == BASS_REDIRECTION) {
@@ -6422,12 +6374,10 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
if (spec->cur_out_type == SPEAKER_OUT)
ca0132_alt_surround_set_bass_redirection(codec, *valp);
- changed = 0;
+ return 0;
}
-exit:
- snd_hda_power_down(codec);
- return changed;
+ return 1;
}
/*
@@ -6483,22 +6433,22 @@ static int ca0132_volume_info(struct snd_kcontrol *kcontrol,
case VNID_SPK:
/* follow shared_out info */
nid = spec->shared_out_nid;
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
- err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
+ scoped_guard(mutex, &codec->control_mutex) {
+ pval = kcontrol->private_value;
+ kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
+ err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
+ kcontrol->private_value = pval;
+ }
break;
case VNID_MIC:
/* follow shared_mic info */
nid = spec->shared_mic_nid;
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
- err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
+ scoped_guard(mutex, &codec->control_mutex) {
+ pval = kcontrol->private_value;
+ kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
+ err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
+ kcontrol->private_value = pval;
+ }
break;
default:
err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
@@ -6555,15 +6505,13 @@ static int ca0132_volume_put(struct snd_kcontrol *kcontrol,
int dir = get_amp_direction(kcontrol);
unsigned long pval;
- snd_hda_power_up(codec);
- mutex_lock(&codec->control_mutex);
+ CLASS(snd_hda_power, pm)(codec);
+ guard(mutex)(&codec->control_mutex);
pval = kcontrol->private_value;
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(shared_nid, ch,
0, dir);
changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
- snd_hda_power_down(codec);
}
return changed;
@@ -6583,7 +6531,6 @@ static int ca0132_alt_volume_put(struct snd_kcontrol *kcontrol,
int ch = get_amp_channels(kcontrol);
long *valp = ucontrol->value.integer.value;
hda_nid_t vnid = 0;
- int changed;
switch (nid) {
case 0x02:
@@ -6604,14 +6551,10 @@ static int ca0132_alt_volume_put(struct snd_kcontrol *kcontrol,
valp++;
}
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
ca0132_alt_dsp_volume_put(codec, vnid);
- mutex_lock(&codec->control_mutex);
- changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
- mutex_unlock(&codec->control_mutex);
- snd_hda_power_down(codec);
-
- return changed;
+ guard(mutex)(&codec->control_mutex);
+ return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
}
static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag,
@@ -6629,22 +6572,22 @@ static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag,
case VNID_SPK:
/* follow shared_out tlv */
nid = spec->shared_out_nid;
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
- err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
+ scoped_guard(mutex, &codec->control_mutex) {
+ pval = kcontrol->private_value;
+ kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
+ err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
+ kcontrol->private_value = pval;
+ }
break;
case VNID_MIC:
/* follow shared_mic tlv */
nid = spec->shared_mic_nid;
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
- err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
+ scoped_guard(mutex, &codec->control_mutex) {
+ pval = kcontrol->private_value;
+ kcontrol->private_value = HDA_COMPOSE_AMP_VAL(nid, ch, 0, dir);
+ err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
+ kcontrol->private_value = pval;
+ }
break;
default:
err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
@@ -7526,12 +7469,10 @@ static void ca0132_init_analog_mic2(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_8051_write_exram_no_mutex(codec, 0x1920, 0x00);
chipio_8051_write_exram_no_mutex(codec, 0x192d, 0x00);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void ca0132_refresh_widget_caps(struct hda_codec *codec)
@@ -7621,19 +7562,17 @@ static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
* Check if any of the default streams are active, and if they are,
* stop them.
*/
- mutex_lock(&spec->chipio_mutex);
-
- for (i = 0; i < ARRAY_SIZE(dsp_dma_stream_ids); i++) {
- chipio_get_stream_control(codec, dsp_dma_stream_ids[i], &tmp);
+ scoped_guard(mutex, &spec->chipio_mutex) {
+ for (i = 0; i < ARRAY_SIZE(dsp_dma_stream_ids); i++) {
+ chipio_get_stream_control(codec, dsp_dma_stream_ids[i], &tmp);
- if (tmp) {
- chipio_set_stream_control(codec,
- dsp_dma_stream_ids[i], 0);
+ if (tmp) {
+ chipio_set_stream_control(codec,
+ dsp_dma_stream_ids[i], 0);
+ }
}
}
- mutex_unlock(&spec->chipio_mutex);
-
/*
* If all DSP streams are inactive, there should be no active DSP DMA
* channels. Check and make sure this is the case, and if it isn't,
@@ -7641,7 +7580,7 @@ static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
*/
ca0132_alt_free_active_dma_channels(codec);
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
/* Make sure stream 0x0c is six channels. */
chipio_set_stream_channels(codec, 0x0c, 6);
@@ -7653,8 +7592,6 @@ static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
/* Give the DSP some time to setup the DMA channel. */
msleep(75);
}
-
- mutex_unlock(&spec->chipio_mutex);
}
/*
@@ -7846,7 +7783,7 @@ static void sbz_connect_streams(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n");
@@ -7861,8 +7798,6 @@ static void sbz_connect_streams(struct hda_codec *codec)
chipio_set_stream_control(codec, 0x14, 1);
codec_dbg(codec, "Connect Streams exited, mutex released.\n");
-
- mutex_unlock(&spec->chipio_mutex);
}
/*
@@ -7876,7 +7811,7 @@ static void sbz_chipio_startup_data(struct hda_codec *codec)
const struct chipio_stream_remap_data *dsp_out_remap_data;
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
codec_dbg(codec, "Startup Data entered, mutex locked and loaded.\n");
/* Remap DAC0's output ports. */
@@ -7901,7 +7836,6 @@ static void sbz_chipio_startup_data(struct hda_codec *codec)
chipio_remap_stream(codec, dsp_out_remap_data);
codec_dbg(codec, "Startup Data exited, mutex released.\n");
- mutex_unlock(&spec->chipio_mutex);
}
static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
@@ -7993,7 +7927,7 @@ static void ae5_post_dsp_stream_setup(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
@@ -8011,15 +7945,13 @@ static void ae5_post_dsp_stream_setup(struct hda_codec *codec)
chipio_8051_write_pll_pmu_no_mutex(codec, 0x43, 0xc7);
ca0113_mmio_command_set(codec, 0x48, 0x01, 0x80);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void ae5_post_dsp_startup_data(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_write_no_mutex(codec, 0x189000, 0x0001f101);
chipio_write_no_mutex(codec, 0x189004, 0x0001f101);
@@ -8043,15 +7975,13 @@ static void ae5_post_dsp_startup_data(struct hda_codec *codec)
ca0113_mmio_command_set(codec, 0x48, 0x0f, 0x00);
ca0113_mmio_command_set(codec, 0x48, 0x10, 0x00);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void ae7_post_dsp_setup_ports(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
/* Seems to share the same port remapping as the SBZ. */
chipio_remap_stream(codec, &stream_remap_data[1]);
@@ -8064,15 +7994,13 @@ static void ae7_post_dsp_setup_ports(struct hda_codec *codec)
ca0113_mmio_command_set(codec, 0x48, 0x12, 0xff);
ca0113_mmio_command_set(codec, 0x48, 0x13, 0xff);
ca0113_mmio_command_set(codec, 0x48, 0x14, 0x7f);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void ae7_post_dsp_asi_stream_setup(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
@@ -8087,8 +8015,6 @@ static void ae7_post_dsp_asi_stream_setup(struct hda_codec *codec)
chipio_set_stream_control(codec, 0x18, 1);
chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 4);
-
- mutex_unlock(&spec->chipio_mutex);
}
static void ae7_post_dsp_pll_setup(struct hda_codec *codec)
@@ -8116,7 +8042,7 @@ static void ae7_post_dsp_asi_setup_ports(struct hda_codec *codec)
};
unsigned int i;
- mutex_lock(&spec->chipio_mutex);
+ guard(mutex)(&spec->chipio_mutex);
chipio_8051_write_pll_pmu_no_mutex(codec, 0x43, 0xc7);
@@ -8178,8 +8104,6 @@ static void ae7_post_dsp_asi_setup_ports(struct hda_codec *codec)
*/
ae7_post_dsp_pll_setup(codec);
chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 7);
-
- mutex_unlock(&spec->chipio_mutex);
}
/*
@@ -8664,14 +8588,13 @@ static void ca0132_process_dsp_response(struct hda_codec *codec,
struct ca0132_spec *spec = codec->spec;
codec_dbg(codec, "ca0132_process_dsp_response\n");
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
if (spec->wait_scp) {
if (dspio_get_response_data(codec) >= 0)
spec->wait_scp = 0;
}
dspio_clear_response_queue(codec);
- snd_hda_power_down_pm(codec);
}
static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
@@ -9546,7 +9469,7 @@ static int ca0132_init(struct hda_codec *codec)
if (ca0132_use_pci_mmio(spec))
ca0132_mmio_init(codec);
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
if (ca0132_quirk(spec) == QUIRK_AE5 || ca0132_quirk(spec) == QUIRK_AE7)
ae5_register_set(codec);
@@ -9626,8 +9549,6 @@ static int ca0132_init(struct hda_codec *codec)
ca0132_pe_switch_set(codec);
}
- snd_hda_power_down_pm(codec);
-
return 0;
}
diff --git a/sound/hda/codecs/cirrus/cs8409.c b/sound/hda/codecs/cirrus/cs8409.c
index e32b462cdc5e..2c02d3be89ee 100644
--- a/sound/hda/codecs/cirrus/cs8409.c
+++ b/sound/hda/codecs/cirrus/cs8409.c
@@ -92,13 +92,12 @@ static void cs8409_disable_i2c_clock(struct hda_codec *codec)
{
struct cs8409_spec *spec = codec->spec;
- mutex_lock(&spec->i2c_mux);
+ guard(mutex)(&spec->i2c_mux);
if (spec->i2c_clck_enabled) {
cs8409_vendor_coef_set(spec->codec, 0x0,
cs8409_vendor_coef_get(spec->codec, 0x0) & 0xfffffff7);
spec->i2c_clck_enabled = 0;
}
- mutex_unlock(&spec->i2c_mux);
}
/*
@@ -204,7 +203,7 @@ static int cs8409_i2c_read(struct sub_codec *scodec, unsigned int addr)
if (scodec->suspended)
return -EPERM;
- mutex_lock(&spec->i2c_mux);
+ guard(mutex)(&spec->i2c_mux);
cs8409_enable_i2c_clock(codec);
cs8409_set_i2c_dev_addr(codec, scodec->addr);
@@ -219,12 +218,9 @@ static int cs8409_i2c_read(struct sub_codec *scodec, unsigned int addr)
/* Register in bits 15-8 and the data in 7-0 */
read_data = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD);
- mutex_unlock(&spec->i2c_mux);
-
return read_data & 0x0ff;
error:
- mutex_unlock(&spec->i2c_mux);
codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, scodec->addr, addr);
return -EIO;
}
@@ -247,7 +243,7 @@ static int cs8409_i2c_bulk_read(struct sub_codec *scodec, struct cs8409_i2c_para
if (scodec->suspended)
return -EPERM;
- mutex_lock(&spec->i2c_mux);
+ guard(mutex)(&spec->i2c_mux);
cs8409_set_i2c_dev_addr(codec, scodec->addr);
for (i = 0; i < count; i++) {
@@ -264,12 +260,9 @@ static int cs8409_i2c_bulk_read(struct sub_codec *scodec, struct cs8409_i2c_para
seq[i].value = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD) & 0xff;
}
- mutex_unlock(&spec->i2c_mux);
-
return 0;
error:
- mutex_unlock(&spec->i2c_mux);
codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", scodec->addr);
return -EIO;
}
@@ -291,7 +284,7 @@ static int cs8409_i2c_write(struct sub_codec *scodec, unsigned int addr, unsigne
if (scodec->suspended)
return -EPERM;
- mutex_lock(&spec->i2c_mux);
+ guard(mutex)(&spec->i2c_mux);
cs8409_enable_i2c_clock(codec);
cs8409_set_i2c_dev_addr(codec, scodec->addr);
@@ -305,11 +298,9 @@ static int cs8409_i2c_write(struct sub_codec *scodec, unsigned int addr, unsigne
if (cs8409_i2c_wait_complete(codec) < 0)
goto error;
- mutex_unlock(&spec->i2c_mux);
return 0;
error:
- mutex_unlock(&spec->i2c_mux);
codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, scodec->addr, addr);
return -EIO;
}
@@ -333,7 +324,7 @@ static int cs8409_i2c_bulk_write(struct sub_codec *scodec, const struct cs8409_i
if (scodec->suspended)
return -EPERM;
- mutex_lock(&spec->i2c_mux);
+ guard(mutex)(&spec->i2c_mux);
cs8409_set_i2c_dev_addr(codec, scodec->addr);
for (i = 0; i < count; i++) {
@@ -353,12 +344,9 @@ static int cs8409_i2c_bulk_write(struct sub_codec *scodec, const struct cs8409_i
fsleep(seq[i].delay);
}
- mutex_unlock(&spec->i2c_mux);
-
return 0;
error:
- mutex_unlock(&spec->i2c_mux);
codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", scodec->addr);
return -EIO;
}
diff --git a/sound/hda/codecs/conexant.c b/sound/hda/codecs/conexant.c
index c881bf213ebe..5fcbc1312c69 100644
--- a/sound/hda/codecs/conexant.c
+++ b/sound/hda/codecs/conexant.c
@@ -32,7 +32,7 @@ struct conexant_spec {
unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
- /* OPLC XO specific */
+ /* OLPC XO specific */
bool recording;
bool dc_enable;
unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */
@@ -407,7 +407,7 @@ static void cxt_fixup_headset_mic(struct hda_codec *codec,
}
}
-/* OPLC XO 1.5 fixup */
+/* OLPC XO 1.5 fixup */
/* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
* through the microphone jack.
diff --git a/sound/hda/codecs/generic.c b/sound/hda/codecs/generic.c
index a44beefe3e97..7bcf9aef8275 100644
--- a/sound/hda/codecs/generic.c
+++ b/sound/hda/codecs/generic.c
@@ -1118,12 +1118,11 @@ static int hda_gen_bind_mute_get(struct snd_kcontrol *kcontrol,
unsigned long pval;
int err;
- mutex_lock(&codec->control_mutex);
+ guard(mutex)(&codec->control_mutex);
pval = kcontrol->private_value;
kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
return err;
}
@@ -1136,7 +1135,7 @@ static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
sync_auto_mute_bits(kcontrol, ucontrol);
- mutex_lock(&codec->control_mutex);
+ guard(mutex)(&codec->control_mutex);
pval = kcontrol->private_value;
indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
for (i = 0; i < indices; i++) {
@@ -1148,7 +1147,6 @@ static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
change |= err;
}
kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
return err < 0 ? err : change;
}
@@ -1986,7 +1984,7 @@ static int parse_output_paths(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
- struct auto_pin_cfg *best_cfg;
+ struct auto_pin_cfg *best_cfg __free(kfree) = NULL;
unsigned int val;
int best_badness = INT_MAX;
int badness;
@@ -2002,10 +2000,8 @@ static int parse_output_paths(struct hda_codec *codec)
for (;;) {
badness = fill_and_eval_dacs(codec, fill_hardwired,
fill_mio_first);
- if (badness < 0) {
- kfree(best_cfg);
+ if (badness < 0)
return badness;
- }
debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
cfg->line_out_type, fill_hardwired, fill_mio_first,
badness);
@@ -2098,7 +2094,6 @@ static int parse_output_paths(struct hda_codec *codec)
if (spec->indep_hp && !indep_hp_possible(codec))
spec->indep_hp = 0;
- kfree(best_cfg);
return 0;
}
@@ -2249,11 +2244,9 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol,
unsigned int select = ucontrol->value.enumerated.item[0];
int ret = 0;
- mutex_lock(&spec->pcm_mutex);
- if (spec->active_streams) {
- ret = -EBUSY;
- goto unlock;
- }
+ guard(mutex)(&spec->pcm_mutex);
+ if (spec->active_streams)
+ return -EBUSY;
if (spec->indep_hp_enabled != select) {
hda_nid_t *dacp;
@@ -2285,8 +2278,6 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol,
call_hp_automute(codec, NULL);
ret = 1;
}
- unlock:
- mutex_unlock(&spec->pcm_mutex);
return ret;
}
@@ -3475,22 +3466,20 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
imux = &spec->input_mux;
adc_idx = kcontrol->id.index;
- mutex_lock(&codec->control_mutex);
- for (i = 0; i < imux->num_items; i++) {
- path = get_input_path(codec, adc_idx, i);
- if (!path || !path->ctls[type])
- continue;
- kcontrol->private_value = path->ctls[type];
- ret = func(kcontrol, ucontrol);
- if (ret < 0) {
- err = ret;
- break;
+ scoped_guard(mutex, &codec->control_mutex) {
+ for (i = 0; i < imux->num_items; i++) {
+ path = get_input_path(codec, adc_idx, i);
+ if (!path || !path->ctls[type])
+ continue;
+ kcontrol->private_value = path->ctls[type];
+ ret = func(kcontrol, ucontrol);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ err = 1;
}
- if (ret > 0)
- err = 1;
}
- mutex_unlock(&codec->control_mutex);
- if (err >= 0 && spec->cap_sync_hook)
+ if (spec->cap_sync_hook)
spec->cap_sync_hook(codec, kcontrol, ucontrol);
return err;
}
@@ -5332,17 +5321,17 @@ static int playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_gen_spec *spec = codec->spec;
int err;
- mutex_lock(&spec->pcm_mutex);
+ guard(mutex)(&spec->pcm_mutex);
err = snd_hda_multi_out_analog_open(codec,
&spec->multiout, substream,
hinfo);
- if (!err) {
- spec->active_streams |= 1 << STREAM_MULTI_OUT;
- call_pcm_playback_hook(hinfo, codec, substream,
- HDA_GEN_PCM_ACT_OPEN);
- }
- mutex_unlock(&spec->pcm_mutex);
- return err;
+ if (err < 0)
+ return err;
+
+ spec->active_streams |= 1 << STREAM_MULTI_OUT;
+ call_pcm_playback_hook(hinfo, codec, substream,
+ HDA_GEN_PCM_ACT_OPEN);
+ return 0;
}
static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -5381,11 +5370,11 @@ static int playback_pcm_close(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
- mutex_lock(&spec->pcm_mutex);
+
+ guard(mutex)(&spec->pcm_mutex);
spec->active_streams &= ~(1 << STREAM_MULTI_OUT);
call_pcm_playback_hook(hinfo, codec, substream,
HDA_GEN_PCM_ACT_CLOSE);
- mutex_unlock(&spec->pcm_mutex);
return 0;
}
@@ -5434,14 +5423,13 @@ static int alt_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_gen_spec *spec = codec->spec;
int err = 0;
- mutex_lock(&spec->pcm_mutex);
+ guard(mutex)(&spec->pcm_mutex);
if (spec->indep_hp && !spec->indep_hp_enabled)
err = -EBUSY;
else
spec->active_streams |= 1 << STREAM_INDEP_HP;
call_pcm_playback_hook(hinfo, codec, substream,
HDA_GEN_PCM_ACT_OPEN);
- mutex_unlock(&spec->pcm_mutex);
return err;
}
@@ -5450,11 +5438,11 @@ static int alt_playback_pcm_close(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
- mutex_lock(&spec->pcm_mutex);
+
+ guard(mutex)(&spec->pcm_mutex);
spec->active_streams &= ~(1 << STREAM_INDEP_HP);
call_pcm_playback_hook(hinfo, codec, substream,
HDA_GEN_PCM_ACT_CLOSE);
- mutex_unlock(&spec->pcm_mutex);
return 0;
}
diff --git a/sound/hda/codecs/hdmi/hdmi.c b/sound/hda/codecs/hdmi/hdmi.c
index 44576b30f699..dc38bfd9dba5 100644
--- a/sound/hda/codecs/hdmi/hdmi.c
+++ b/sound/hda/codecs/hdmi/hdmi.c
@@ -145,18 +145,15 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
pcm_idx = kcontrol->private_value;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
per_pin = pcm_idx_to_pin(spec, pcm_idx);
if (!per_pin) {
/* no pin is bound to the pcm */
uinfo->count = 0;
- goto unlock;
+ return 0;
}
eld = &per_pin->sink_eld;
uinfo->count = eld->eld_valid ? eld->eld_size : 0;
-
- unlock:
- mutex_unlock(&spec->pcm_lock);
return 0;
}
@@ -168,24 +165,22 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
struct hdmi_spec_per_pin *per_pin;
struct hdmi_eld *eld;
int pcm_idx;
- int err = 0;
pcm_idx = kcontrol->private_value;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
per_pin = pcm_idx_to_pin(spec, pcm_idx);
if (!per_pin) {
/* no pin is bound to the pcm */
memset(ucontrol->value.bytes.data, 0,
ARRAY_SIZE(ucontrol->value.bytes.data));
- goto unlock;
+ return 0;
}
eld = &per_pin->sink_eld;
if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
eld->eld_size > ELD_MAX_SIZE) {
snd_BUG();
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
memset(ucontrol->value.bytes.data, 0,
@@ -193,10 +188,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
if (eld->eld_valid)
memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
eld->eld_size);
-
- unlock:
- mutex_unlock(&spec->pcm_lock);
- return err;
+ return 0;
}
static const struct snd_kcontrol_new eld_bytes_ctl = {
@@ -295,10 +287,9 @@ static void print_eld_info(struct snd_info_entry *entry,
{
struct hdmi_spec_per_pin *per_pin = entry->private_data;
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
snd_hdmi_print_eld_info(&per_pin->sink_eld, buffer, per_pin->pin_nid,
per_pin->dev_id, per_pin->cvt_nid);
- mutex_unlock(&per_pin->lock);
}
static void write_eld_info(struct snd_info_entry *entry,
@@ -306,9 +297,8 @@ static void write_eld_info(struct snd_info_entry *entry,
{
struct hdmi_spec_per_pin *per_pin = entry->private_data;
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
snd_hdmi_write_eld_info(&per_pin->sink_eld, buffer);
- mutex_unlock(&per_pin->lock);
}
static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
@@ -599,9 +589,8 @@ void snd_hda_hdmi_check_presence_and_report(struct hda_codec *codec,
if (pin_idx < 0)
return;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
hdmi_present_sense(get_pin(spec, pin_idx), 1);
- mutex_unlock(&spec->pcm_lock);
}
EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_check_presence_and_report,
"SND_HDA_CODEC_HDMI");
@@ -907,19 +896,17 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
if (pcm_idx < 0)
return -EINVAL;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
pin_idx = hinfo_to_pin_index(codec, hinfo);
/* no pin is assigned to the PCM
* PA need pcm open successfully when probe
*/
- if (pin_idx < 0) {
- err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
- goto unlock;
- }
+ if (pin_idx < 0)
+ return hdmi_pcm_open_no_pin(hinfo, codec, substream);
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false);
if (err < 0)
- goto unlock;
+ return err;
per_cvt = get_cvt(spec, cvt_idx);
/* Claim converter */
@@ -960,8 +947,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
per_cvt->assigned = false;
hinfo->nid = 0;
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
- err = -ENODEV;
- goto unlock;
+ return -ENODEV;
}
}
@@ -973,9 +959,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- unlock:
- mutex_unlock(&spec->pcm_lock);
- return err;
+ return 0;
}
/*
@@ -1270,20 +1254,19 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
* the unsolicited response to avoid custom WARs.
*/
int present;
- int ret;
#ifdef CONFIG_PM
if (dev->power.runtime_status == RPM_SUSPENDING)
return;
#endif
- ret = snd_hda_power_up_pm(codec);
- if (ret < 0 && pm_runtime_suspended(dev))
- goto out;
+ CLASS(snd_hda_power_pm, pm)(codec);
+ if (pm.err < 0 && pm_runtime_suspended(dev))
+ return;
present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
if (eld->monitor_present)
eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
@@ -1301,9 +1284,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
}
update_eld(codec, per_pin, eld, repoll);
- mutex_unlock(&per_pin->lock);
- out:
- snd_hda_power_down_pm(codec);
}
static void silent_stream_enable(struct hda_codec *codec,
@@ -1318,27 +1298,25 @@ static void silent_stream_enable(struct hda_codec *codec,
* have to be done without mutex held.
*/
- err = snd_hda_power_up_pm(codec);
- if (err < 0 && err != -EACCES) {
+ CLASS(snd_hda_power_pm, pm)(codec);
+ if (pm.err < 0 && pm.err != -EACCES) {
codec_err(codec,
- "Failed to power up codec for silent stream enable ret=[%d]\n", err);
- snd_hda_power_down_pm(codec);
+ "Failed to power up codec for silent stream enable ret=[%d]\n", pm.err);
return;
}
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
if (per_pin->setup) {
codec_dbg(codec, "hdmi: PCM already open, no silent stream\n");
- err = -EBUSY;
- goto unlock_out;
+ return;
}
pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id);
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, true);
if (err) {
codec_err(codec, "hdmi: no free converter to enable silent mode\n");
- goto unlock_out;
+ return;
}
per_cvt = get_cvt(spec, cvt_idx);
@@ -1358,11 +1336,6 @@ static void silent_stream_enable(struct hda_codec *codec,
pin_cvt_fixup(codec, per_pin, 0);
spec->ops.silent_stream(codec, per_pin, true);
-
- unlock_out:
- mutex_unlock(&per_pin->lock);
-
- snd_hda_power_down_pm(codec);
}
static void silent_stream_disable(struct hda_codec *codec,
@@ -1370,20 +1343,19 @@ static void silent_stream_disable(struct hda_codec *codec,
{
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_cvt *per_cvt;
- int cvt_idx, err;
+ int cvt_idx;
- err = snd_hda_power_up_pm(codec);
- if (err < 0 && err != -EACCES) {
+ CLASS(snd_hda_power_pm, pm)(codec);
+ if (pm.err < 0 && pm.err != -EACCES) {
codec_err(codec,
"Failed to power up codec for silent stream disable ret=[%d]\n",
- err);
- snd_hda_power_down_pm(codec);
+ pm.err);
return;
}
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
if (!per_pin->silent_stream)
- goto unlock_out;
+ return;
codec_dbg(codec, "HDMI: disable silent stream on pin-NID=0x%x cvt-NID=0x%x\n",
per_pin->pin_nid, per_pin->cvt_nid);
@@ -1398,11 +1370,6 @@ static void silent_stream_disable(struct hda_codec *codec,
per_pin->cvt_nid = 0;
per_pin->silent_stream = false;
-
- unlock_out:
- mutex_unlock(&per_pin->lock);
-
- snd_hda_power_down_pm(codec);
}
/* update ELD and jack state via audio component */
@@ -1413,16 +1380,16 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
struct hdmi_eld *eld = &spec->temp_eld;
bool monitor_prev, monitor_next;
- mutex_lock(&per_pin->lock);
- eld->monitor_present = false;
- monitor_prev = per_pin->sink_eld.monitor_present;
- eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
- per_pin->dev_id, &eld->monitor_present,
- eld->eld_buffer, ELD_MAX_SIZE);
- eld->eld_valid = (eld->eld_size > 0);
- update_eld(codec, per_pin, eld, 0);
- monitor_next = per_pin->sink_eld.monitor_present;
- mutex_unlock(&per_pin->lock);
+ scoped_guard(mutex, &per_pin->lock) {
+ eld->monitor_present = false;
+ monitor_prev = per_pin->sink_eld.monitor_present;
+ eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
+ per_pin->dev_id, &eld->monitor_present,
+ eld->eld_buffer, ELD_MAX_SIZE);
+ eld->eld_valid = (eld->eld_size > 0);
+ update_eld(codec, per_pin, eld, 0);
+ monitor_next = per_pin->sink_eld.monitor_present;
+ }
if (spec->silent_stream_type) {
if (!monitor_prev && monitor_next)
@@ -1458,9 +1425,8 @@ static void hdmi_repoll_eld(struct work_struct *work)
if (per_pin->repoll_count++ > 6)
per_pin->repoll_count = 0;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
hdmi_present_sense(per_pin, per_pin->repoll_count);
- mutex_unlock(&spec->pcm_lock);
}
static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
@@ -1655,20 +1621,15 @@ EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_parse_codec, "SND_HDA_CODEC_HDMI");
static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
{
struct hda_spdif_out *spdif;
- bool non_pcm;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
- if (WARN_ON(spdif == NULL)) {
- mutex_unlock(&codec->spdif_mutex);
+ if (WARN_ON(spdif == NULL))
return true;
- }
- non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
- mutex_unlock(&codec->spdif_mutex);
- return non_pcm;
+ return !!(spdif->status & IEC958_AES0_NONAUDIO);
}
/*
@@ -1688,9 +1649,8 @@ int snd_hda_hdmi_generic_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_runtime *runtime = substream->runtime;
bool non_pcm;
int pinctl, stripe;
- int err = 0;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
pin_idx = hinfo_to_pin_index(codec, hinfo);
if (pin_idx < 0) {
/* when pcm is not bound to a pin skip pin setup and return 0
@@ -1699,7 +1659,7 @@ int snd_hda_hdmi_generic_pcm_prepare(struct hda_pcm_stream *hinfo,
pin_cvt_fixup(codec, NULL, cvt_nid);
snd_hda_codec_setup_stream(codec, cvt_nid,
stream_tag, 0, format);
- goto unlock;
+ return 0;
}
per_pin = get_pin(spec, pin_idx);
@@ -1721,20 +1681,20 @@ int snd_hda_hdmi_generic_pcm_prepare(struct hda_pcm_stream *hinfo,
per_pin->dev_id, runtime->rate);
non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
- mutex_lock(&per_pin->lock);
- per_pin->channels = substream->runtime->channels;
- per_pin->setup = true;
+ scoped_guard(mutex, &per_pin->lock) {
+ per_pin->channels = substream->runtime->channels;
+ per_pin->setup = true;
+
+ if (get_wcaps(codec, cvt_nid) & AC_WCAP_STRIPE) {
+ stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core,
+ substream);
+ snd_hda_codec_write(codec, cvt_nid, 0,
+ AC_VERB_SET_STRIPE_CONTROL,
+ stripe);
+ }
- if (get_wcaps(codec, cvt_nid) & AC_WCAP_STRIPE) {
- stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core,
- substream);
- snd_hda_codec_write(codec, cvt_nid, 0,
- AC_VERB_SET_STRIPE_CONTROL,
- stripe);
+ snd_hda_hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
}
-
- snd_hda_hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
- mutex_unlock(&per_pin->lock);
if (spec->dyn_pin_out) {
snd_hda_set_dev_select(codec, per_pin->pin_nid,
per_pin->dev_id);
@@ -1746,11 +1706,8 @@ int snd_hda_hdmi_generic_pcm_prepare(struct hda_pcm_stream *hinfo,
}
/* snd_hda_set_dev_select() has been called before */
- err = spec->ops.setup_stream(codec, cvt_nid, per_pin->pin_nid,
- per_pin->dev_id, stream_tag, format);
- unlock:
- mutex_unlock(&spec->pcm_lock);
- return err;
+ return spec->ops.setup_stream(codec, cvt_nid, per_pin->pin_nid,
+ per_pin->dev_id, stream_tag, format);
}
EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_pcm_prepare, "SND_HDA_CODEC_HDMI");
@@ -1772,20 +1729,15 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
struct hdmi_spec_per_cvt *per_cvt;
struct hdmi_spec_per_pin *per_pin;
int pinctl;
- int err = 0;
- mutex_lock(&spec->pcm_lock);
+ guard(mutex)(&spec->pcm_lock);
if (hinfo->nid) {
pcm_idx = hinfo_to_pcm_index(codec, hinfo);
- if (snd_BUG_ON(pcm_idx < 0)) {
- err = -EINVAL;
- goto unlock;
- }
+ if (snd_BUG_ON(pcm_idx < 0))
+ return -EINVAL;
cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);
- if (snd_BUG_ON(cvt_idx < 0)) {
- err = -EINVAL;
- goto unlock;
- }
+ if (snd_BUG_ON(cvt_idx < 0))
+ return -EINVAL;
per_cvt = get_cvt(spec, cvt_idx);
per_cvt->assigned = false;
hinfo->nid = 0;
@@ -1800,7 +1752,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
* hdmi_pcm_open()
*/
if (pin_idx < 0)
- goto unlock;
+ return 0;
per_pin = get_pin(spec, pin_idx);
@@ -1814,19 +1766,15 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
pinctl & ~PIN_OUT);
}
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
per_pin->chmap_set = false;
memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
per_pin->setup = false;
per_pin->channels = 0;
- mutex_unlock(&per_pin->lock);
}
-unlock:
- mutex_unlock(&spec->pcm_lock);
-
- return err;
+ return 0;
}
static const struct hda_pcm_ops generic_ops = {
@@ -1871,12 +1819,11 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
if (!per_pin)
return;
- mutex_lock(&per_pin->lock);
+ guard(mutex)(&per_pin->lock);
per_pin->chmap_set = true;
memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
if (prepared)
snd_hda_hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
- mutex_unlock(&per_pin->lock);
}
static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
@@ -2045,7 +1992,7 @@ int snd_hda_hdmi_generic_init(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec;
int pin_idx;
- mutex_lock(&spec->bind_lock);
+ guard(mutex)(&spec->bind_lock);
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
hda_nid_t pin_nid = per_pin->pin_nid;
@@ -2058,7 +2005,6 @@ int snd_hda_hdmi_generic_init(struct hda_codec *codec)
snd_hda_jack_detect_enable_callback_mst(codec, pin_nid, dev_id,
jack_callback);
}
- mutex_unlock(&spec->bind_lock);
return 0;
}
EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_init, "SND_HDA_CODEC_HDMI");
@@ -2229,7 +2175,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp,
int i;
spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops);
- mutex_lock(&spec->bind_lock);
+ guard(mutex)(&spec->bind_lock);
spec->use_acomp_notifier = use_acomp;
spec->codec->relaxed_resume = use_acomp;
spec->codec->bus->keep_power = 0;
@@ -2239,7 +2185,6 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp,
get_pin(spec, i)->pin_nid,
get_pin(spec, i)->dev_id,
use_acomp);
- mutex_unlock(&spec->bind_lock);
}
/* enable / disable the notifier via master bind / unbind */
diff --git a/sound/hda/codecs/hdmi/nvhdmi-mcp.c b/sound/hda/codecs/hdmi/nvhdmi-mcp.c
index fbcea6d1850e..8fd8d76fa72f 100644
--- a/sound/hda/codecs/hdmi/nvhdmi-mcp.c
+++ b/sound/hda/codecs/hdmi/nvhdmi-mcp.c
@@ -131,7 +131,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_spdif_out *spdif;
struct hdmi_spec_per_cvt *per_cvt;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
per_cvt = get_cvt(spec, 0);
spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid);
@@ -215,7 +215,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs);
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
diff --git a/sound/hda/codecs/realtek/alc268.c b/sound/hda/codecs/realtek/alc268.c
index e489cdc98eb8..4b565fb7bd1c 100644
--- a/sound/hda/codecs/realtek/alc268.c
+++ b/sound/hda/codecs/realtek/alc268.c
@@ -12,7 +12,7 @@ static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
unsigned long pval;
int err;
- mutex_lock(&codec->control_mutex);
+ guard(mutex)(&codec->control_mutex);
pval = kcontrol->private_value;
kcontrol->private_value = (pval & ~0xff) | 0x0f;
err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
@@ -21,7 +21,6 @@ static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
}
kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
return err;
}
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index f267437c9698..3c42f66fe000 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -872,8 +872,7 @@ static void alc294_init(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
/* required only at boot or S4 resume time */
- if (!spec->done_hp_init ||
- codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
+ if (!spec->done_hp_init || is_s4_resume(codec)) {
alc294_hp_init(codec);
spec->done_hp_init = true;
}
@@ -1224,9 +1223,8 @@ static void alc_update_vref_led(struct hda_codec *codec, hda_nid_t pin,
pinval &= ~AC_PINCTL_VREFEN;
pinval |= on ? AC_PINCTL_VREF_80 : AC_PINCTL_VREF_HIZ;
/* temporarily power up/down for setting VREF */
- snd_hda_power_up_pm(codec);
+ CLASS(snd_hda_power_pm, pm)(codec);
snd_hda_set_pin_ctl_cache(codec, pin, pinval);
- snd_hda_power_down_pm(codec);
}
/* update mute-LED according to the speaker mute state via mic VREF pin */
@@ -6487,6 +6485,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
diff --git a/sound/hda/codecs/realtek/realtek.c b/sound/hda/codecs/realtek/realtek.c
index b6feccfd45a9..ca377a5adadb 100644
--- a/sound/hda/codecs/realtek/realtek.c
+++ b/sound/hda/codecs/realtek/realtek.c
@@ -7,26 +7,6 @@
#include <linux/module.h>
#include "realtek.h"
-/*
- * COEF access helper functions
- */
-
-static void coef_mutex_lock(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- snd_hda_power_up_pm(codec);
- mutex_lock(&spec->coef_mutex);
-}
-
-static void coef_mutex_unlock(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- mutex_unlock(&spec->coef_mutex);
- snd_hda_power_down_pm(codec);
-}
-
static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
unsigned int coef_idx)
{
@@ -40,12 +20,8 @@ static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
unsigned int coef_idx)
{
- unsigned int val;
-
- coef_mutex_lock(codec);
- val = __alc_read_coefex_idx(codec, nid, coef_idx);
- coef_mutex_unlock(codec);
- return val;
+ guard(coef_mutex)(codec);
+ return __alc_read_coefex_idx(codec, nid, coef_idx);
}
EXPORT_SYMBOL_NS_GPL(alc_read_coefex_idx, "SND_HDA_CODEC_REALTEK");
@@ -59,9 +35,8 @@ static void __alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
unsigned int coef_idx, unsigned int coef_val)
{
- coef_mutex_lock(codec);
+ guard(coef_mutex)(codec);
__alc_write_coefex_idx(codec, nid, coef_idx, coef_val);
- coef_mutex_unlock(codec);
}
EXPORT_SYMBOL_NS_GPL(alc_write_coefex_idx, "SND_HDA_CODEC_REALTEK");
@@ -80,9 +55,8 @@ void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
unsigned int coef_idx, unsigned int mask,
unsigned int bits_set)
{
- coef_mutex_lock(codec);
+ guard(coef_mutex)(codec);
__alc_update_coefex_idx(codec, nid, coef_idx, mask, bits_set);
- coef_mutex_unlock(codec);
}
EXPORT_SYMBOL_NS_GPL(alc_update_coefex_idx, "SND_HDA_CODEC_REALTEK");
@@ -99,7 +73,7 @@ EXPORT_SYMBOL_NS_GPL(alc_get_coef0, "SND_HDA_CODEC_REALTEK");
void alc_process_coef_fw(struct hda_codec *codec, const struct coef_fw *fw)
{
- coef_mutex_lock(codec);
+ guard(coef_mutex)(codec);
for (; fw->nid; fw++) {
if (fw->mask == (unsigned short)-1)
__alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
@@ -107,7 +81,6 @@ void alc_process_coef_fw(struct hda_codec *codec, const struct coef_fw *fw)
__alc_update_coefex_idx(codec, fw->nid, fw->idx,
fw->mask, fw->val);
}
- coef_mutex_unlock(codec);
}
EXPORT_SYMBOL_NS_GPL(alc_process_coef_fw, "SND_HDA_CODEC_REALTEK");
@@ -242,7 +215,7 @@ void alc_update_knob_master(struct hda_codec *codec,
{
unsigned int val;
struct snd_kcontrol *kctl;
- struct snd_ctl_elem_value *uctl;
+ struct snd_ctl_elem_value *uctl __free(kfree) = NULL;
kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
if (!kctl)
@@ -256,7 +229,6 @@ void alc_update_knob_master(struct hda_codec *codec,
uctl->value.integer.value[0] = val;
uctl->value.integer.value[1] = val;
kctl->put(kctl, uctl);
- kfree(uctl);
}
EXPORT_SYMBOL_NS_GPL(alc_update_knob_master, "SND_HDA_CODEC_REALTEK");
diff --git a/sound/hda/codecs/realtek/realtek.h b/sound/hda/codecs/realtek/realtek.h
index ee893da0c486..b2a919904c4c 100644
--- a/sound/hda/codecs/realtek/realtek.h
+++ b/sound/hda/codecs/realtek/realtek.h
@@ -295,4 +295,25 @@ void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
void alc_fixup_dell_xps13(struct hda_codec *codec,
const struct hda_fixup *fix, int action);
+/*
+ * COEF access helper functions
+ */
+static inline void coef_mutex_lock(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ snd_hda_power_up_pm(codec);
+ mutex_lock(&spec->coef_mutex);
+}
+
+static inline void coef_mutex_unlock(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ mutex_unlock(&spec->coef_mutex);
+ snd_hda_power_down_pm(codec);
+}
+
+DEFINE_GUARD(coef_mutex, struct hda_codec *, coef_mutex_lock(_T), coef_mutex_unlock(_T))
+
#endif /* __HDA_REALTEK_H */
diff --git a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c
index 9ba14c09c07f..3cca750857b6 100644
--- a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c
+++ b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c
@@ -69,7 +69,7 @@ static int cirrus_scodec_test_gpio_set_config(struct gpio_chip *gc,
unsigned long config)
{
switch (pinconf_to_config_param(config)) {
- case PIN_CONFIG_OUTPUT:
+ case PIN_CONFIG_LEVEL:
case PIN_CONFIG_OUTPUT_ENABLE:
return -EOPNOTSUPP;
default:
diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda.c b/sound/hda/codecs/side-codecs/cs35l41_hda.c
index 37f2cdc8ce82..c04208e685a0 100644
--- a/sound/hda/codecs/side-codecs/cs35l41_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l41_hda.c
@@ -624,11 +624,10 @@ static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41)
cancel_work_sync(&cs35l41->fw_load_work);
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
cs35l41_shutdown_dsp(cs35l41);
cs_dsp_remove(dsp);
cs35l41->halo_initialized = false;
- mutex_unlock(&cs35l41->fw_mutex);
}
/* Protection release cycle to get the speaker out of Safe-Mode */
@@ -790,9 +789,9 @@ static void cs35l41_hda_pre_playback_hook(struct device *dev, int action)
switch (action) {
case HDA_GEN_PCM_ACT_CLEANUP:
- mutex_lock(&cs35l41->fw_mutex);
- cs35l41_hda_pause_start(dev);
- mutex_unlock(&cs35l41->fw_mutex);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ cs35l41_hda_pause_start(dev);
+ }
break;
default:
break;
@@ -813,24 +812,24 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
pm_runtime_get_sync(dev);
break;
case HDA_GEN_PCM_ACT_PREPARE:
- mutex_lock(&cs35l41->fw_mutex);
- cs35l41_hda_play_start(dev);
- mutex_unlock(&cs35l41->fw_mutex);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ cs35l41_hda_play_start(dev);
+ }
break;
case HDA_GEN_PCM_ACT_CLEANUP:
- mutex_lock(&cs35l41->fw_mutex);
- cs35l41_hda_pause_done(dev);
- mutex_unlock(&cs35l41->fw_mutex);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ cs35l41_hda_pause_done(dev);
+ }
break;
case HDA_GEN_PCM_ACT_CLOSE:
- mutex_lock(&cs35l41->fw_mutex);
- if (!cs35l41->cs_dsp.running && cs35l41->request_fw_load &&
- !cs35l41->fw_request_ongoing) {
- dev_info(dev, "Requesting Firmware Load after HDA_GEN_PCM_ACT_CLOSE\n");
- cs35l41->fw_request_ongoing = true;
- schedule_work(&cs35l41->fw_load_work);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ if (!cs35l41->cs_dsp.running && cs35l41->request_fw_load &&
+ !cs35l41->fw_request_ongoing) {
+ dev_info(dev, "Requesting Firmware Load after HDA_GEN_PCM_ACT_CLOSE\n");
+ cs35l41->fw_request_ongoing = true;
+ schedule_work(&cs35l41->fw_load_work);
+ }
}
- mutex_unlock(&cs35l41->fw_mutex);
/*
* Playback must be finished for all amps before we start runtime suspend.
@@ -849,9 +848,9 @@ static void cs35l41_hda_post_playback_hook(struct device *dev, int action)
switch (action) {
case HDA_GEN_PCM_ACT_PREPARE:
- mutex_lock(&cs35l41->fw_mutex);
- cs35l41_hda_play_done(dev);
- mutex_unlock(&cs35l41->fw_mutex);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ cs35l41_hda_play_done(dev);
+ }
break;
default:
break;
@@ -917,13 +916,12 @@ static int cs35l41_verify_id(struct cs35l41_hda *cs35l41, unsigned int *regid, u
static int cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41)
{
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
if (cs35l41->cs_dsp.running) {
cs35l41->cs_dsp.running = false;
cs35l41->cs_dsp.booted = false;
}
regcache_mark_dirty(cs35l41->regmap);
- mutex_unlock(&cs35l41->fw_mutex);
return 0;
}
@@ -939,10 +937,9 @@ static int cs35l41_system_suspend_prep(struct device *dev)
return 0; /* don't block the whole system suspend */
}
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
if (cs35l41->playback_started)
cs35l41_hda_pause_start(dev);
- mutex_unlock(&cs35l41->fw_mutex);
return 0;
}
@@ -959,10 +956,10 @@ static int cs35l41_system_suspend(struct device *dev)
return 0; /* don't block the whole system suspend */
}
- mutex_lock(&cs35l41->fw_mutex);
- if (cs35l41->playback_started)
- cs35l41_hda_pause_done(dev);
- mutex_unlock(&cs35l41->fw_mutex);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ if (cs35l41->playback_started)
+ cs35l41_hda_pause_done(dev);
+ }
ret = pm_runtime_force_suspend(dev);
if (ret) {
@@ -1047,13 +1044,12 @@ static int cs35l41_system_resume(struct device *dev)
return ret;
}
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
if (cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) {
cs35l41->fw_request_ongoing = true;
schedule_work(&cs35l41->fw_load_work);
}
- mutex_unlock(&cs35l41->fw_mutex);
return ret;
}
@@ -1070,7 +1066,7 @@ static int cs35l41_runtime_idle(struct device *dev)
static int cs35l41_runtime_suspend(struct device *dev)
{
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
- int ret = 0;
+ int ret;
dev_dbg(cs35l41->dev, "Runtime Suspend\n");
@@ -1079,13 +1075,13 @@ static int cs35l41_runtime_suspend(struct device *dev)
return 0;
}
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
if (cs35l41->cs_dsp.running) {
ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap,
cs35l41->hw_cfg.bst_type);
if (ret)
- goto err;
+ return ret;
} else {
cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
}
@@ -1093,17 +1089,14 @@ static int cs35l41_runtime_suspend(struct device *dev)
regcache_cache_only(cs35l41->regmap, true);
regcache_mark_dirty(cs35l41->regmap);
-err:
- mutex_unlock(&cs35l41->fw_mutex);
-
- return ret;
+ return 0;
}
static int cs35l41_runtime_resume(struct device *dev)
{
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
unsigned int regid, reg_revid;
- int ret = 0;
+ int ret;
dev_dbg(cs35l41->dev, "Runtime Resume\n");
@@ -1112,7 +1105,7 @@ static int cs35l41_runtime_resume(struct device *dev)
return 0;
}
- mutex_lock(&cs35l41->fw_mutex);
+ guard(mutex)(&cs35l41->fw_mutex);
regcache_cache_only(cs35l41->regmap, false);
@@ -1120,13 +1113,13 @@ static int cs35l41_runtime_resume(struct device *dev)
ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap);
if (ret) {
dev_warn(cs35l41->dev, "Unable to exit Hibernate.");
- goto err;
+ return ret;
}
}
ret = cs35l41_verify_id(cs35l41, &regid, &reg_revid);
if (ret)
- goto err;
+ return ret;
/* Test key needs to be unlocked to allow the OTP settings to re-apply */
cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
@@ -1134,7 +1127,7 @@ static int cs35l41_runtime_resume(struct device *dev)
cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
if (ret) {
dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
- goto err;
+ return ret;
}
if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
@@ -1142,22 +1135,14 @@ static int cs35l41_runtime_resume(struct device *dev)
dev_dbg(cs35l41->dev, "CS35L41 Resumed (%x), Revision: %02X\n", regid, reg_revid);
-err:
- mutex_unlock(&cs35l41->fw_mutex);
-
- return ret;
+ return 0;
}
static int cs35l41_hda_read_ctl(struct cs_dsp *dsp, const char *name, int type,
unsigned int alg, void *buf, size_t len)
{
- int ret;
-
- mutex_lock(&dsp->pwr_lock);
- ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len);
- mutex_unlock(&dsp->pwr_lock);
-
- return ret;
+ guard(mutex)(&dsp->pwr_lock);
+ return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len);
}
static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41)
@@ -1272,16 +1257,15 @@ static void cs35l41_fw_load_work(struct work_struct *work)
pm_runtime_get_sync(cs35l41->dev);
- mutex_lock(&cs35l41->fw_mutex);
-
- /* Recheck if playback is ongoing, mutex will block playback during firmware loading */
- if (cs35l41->playback_started)
- dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n");
- else
- cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load);
+ scoped_guard(mutex, &cs35l41->fw_mutex) {
+ /* Recheck if playback is ongoing, mutex will block playback during firmware loading */
+ if (cs35l41->playback_started)
+ dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n");
+ else
+ cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load);
- cs35l41->fw_request_ongoing = false;
- mutex_unlock(&cs35l41->fw_mutex);
+ cs35l41->fw_request_ongoing = false;
+ }
pm_runtime_put_autosuspend(cs35l41->dev);
}
diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/side-codecs/cs35l56_hda.c
index 36fa62a41984..5bb1c4ebeaf3 100644
--- a/sound/hda/codecs/side-codecs/cs35l56_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c
@@ -1049,6 +1049,7 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
goto err;
}
+ cs35l56->base.type = hid & 0xff;
cs35l56->base.cal_index = -1;
cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp);
diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c b/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c
index d10209e4eddd..1072f17385ac 100644
--- a/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c
+++ b/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c
@@ -27,8 +27,6 @@ static int cs35l56_hda_i2c_probe(struct i2c_client *clt)
cs35l56->base.can_hibernate = true;
#endif
- cs35l56->base.fw_reg = &cs35l56_fw_reg;
-
cs35l56->base.regmap = devm_regmap_init_i2c(clt, &cs35l56_regmap_i2c);
if (IS_ERR(cs35l56->base.regmap)) {
ret = PTR_ERR(cs35l56->base.regmap);
diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c b/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c
index f57533d3d728..f802c83c57b4 100644
--- a/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c
+++ b/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c
@@ -30,8 +30,6 @@ static int cs35l56_hda_spi_probe(struct spi_device *spi)
cs35l56->base.can_hibernate = true;
#endif
- cs35l56->base.fw_reg = &cs35l56_fw_reg;
-
cs35l56->base.regmap = devm_regmap_init_spi(spi, &cs35l56_regmap_spi);
if (IS_ERR(cs35l56->base.regmap)) {
ret = PTR_ERR(cs35l56->base.regmap);
diff --git a/sound/hda/codecs/side-codecs/hda_component.c b/sound/hda/codecs/side-codecs/hda_component.c
index 71860e2d6377..bcf47a301697 100644
--- a/sound/hda/codecs/side-codecs/hda_component.c
+++ b/sound/hda/codecs/side-codecs/hda_component.c
@@ -21,13 +21,12 @@ void hda_component_acpi_device_notify(struct hda_component_parent *parent,
struct hda_component *comp;
int i;
- mutex_lock(&parent->mutex);
+ guard(mutex)(&parent->mutex);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->acpi_notify)
comp->acpi_notify(acpi_device_handle(comp->adev), event, comp->dev);
}
- mutex_unlock(&parent->mutex);
}
EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, "SND_HDA_SCODEC_COMPONENT");
@@ -89,7 +88,7 @@ void hda_component_manager_playback_hook(struct hda_component_parent *parent, in
struct hda_component *comp;
int i;
- mutex_lock(&parent->mutex);
+ guard(mutex)(&parent->mutex);
for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
if (comp->dev && comp->pre_playback_hook)
@@ -105,7 +104,6 @@ void hda_component_manager_playback_hook(struct hda_component_parent *parent, in
if (comp->dev && comp->post_playback_hook)
comp->post_playback_hook(comp->dev, action);
}
- mutex_unlock(&parent->mutex);
}
EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, "SND_HDA_SCODEC_COMPONENT");
@@ -138,16 +136,11 @@ static int hda_comp_match_dev_name(struct device *dev, void *data)
int hda_component_manager_bind(struct hda_codec *cdc,
struct hda_component_parent *parent)
{
- int ret;
-
/* Init shared and component specific data */
memset(parent->comps, 0, sizeof(parent->comps));
- mutex_lock(&parent->mutex);
- ret = component_bind_all(hda_codec_dev(cdc), parent);
- mutex_unlock(&parent->mutex);
-
- return ret;
+ guard(mutex)(&parent->mutex);
+ return component_bind_all(hda_codec_dev(cdc), parent);
}
EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, "SND_HDA_SCODEC_COMPONENT");
diff --git a/sound/hda/codecs/side-codecs/hda_component.h b/sound/hda/codecs/side-codecs/hda_component.h
index 7ee37154749f..075137a73bae 100644
--- a/sound/hda/codecs/side-codecs/hda_component.h
+++ b/sound/hda/codecs/side-codecs/hda_component.h
@@ -95,9 +95,8 @@ static inline struct hda_component *hda_component_from_index(struct hda_componen
static inline void hda_component_manager_unbind(struct hda_codec *cdc,
struct hda_component_parent *parent)
{
- mutex_lock(&parent->mutex);
+ guard(mutex)(&parent->mutex);
component_unbind_all(hda_codec_dev(cdc), parent);
- mutex_unlock(&parent->mutex);
}
#endif /* ifndef __HDA_COMPONENT_H__ */
diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
index b5b7a1e82b75..4dea442d8c30 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
@@ -26,6 +26,7 @@
#include <sound/tlv.h>
#include <sound/tas2770-tlv.h>
#include <sound/tas2781-tlv.h>
+#include <sound/tas5825-tlv.h>
#include "hda_local.h"
#include "hda_auto_parser.h"
@@ -50,6 +51,7 @@ enum device_chip_id {
HDA_TAS2563,
HDA_TAS2770,
HDA_TAS2781,
+ HDA_TAS5825,
HDA_OTHERS
};
@@ -156,16 +158,16 @@ static void tas2781_hda_playback_hook(struct device *dev, int action)
switch (action) {
case HDA_GEN_PCM_ACT_OPEN:
pm_runtime_get_sync(dev);
- mutex_lock(&tas_hda->priv->codec_lock);
- tasdevice_tuning_switch(tas_hda->priv, 0);
- tas_hda->priv->playback_started = true;
- mutex_unlock(&tas_hda->priv->codec_lock);
+ scoped_guard(mutex, &tas_hda->priv->codec_lock) {
+ tasdevice_tuning_switch(tas_hda->priv, 0);
+ tas_hda->priv->playback_started = true;
+ }
break;
case HDA_GEN_PCM_ACT_CLOSE:
- mutex_lock(&tas_hda->priv->codec_lock);
- tasdevice_tuning_switch(tas_hda->priv, 1);
- tas_hda->priv->playback_started = false;
- mutex_unlock(&tas_hda->priv->codec_lock);
+ scoped_guard(mutex, &tas_hda->priv->codec_lock) {
+ tasdevice_tuning_switch(tas_hda->priv, 1);
+ tas_hda->priv->playback_started = false;
+ }
pm_runtime_put_autosuspend(dev);
break;
@@ -182,15 +184,13 @@ static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
(struct soc_mixer_control *)kcontrol->private_value;
int ret;
- mutex_lock(&tas_priv->codec_lock);
+ guard(mutex)(&tas_priv->codec_lock);
ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc);
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %ld\n",
__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);
- mutex_unlock(&tas_priv->codec_lock);
-
return ret;
}
@@ -200,19 +200,14 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- int ret;
- mutex_lock(&tas_priv->codec_lock);
+ guard(mutex)(&tas_priv->codec_lock);
dev_dbg(tas_priv->dev, "%s: kcontrol %s: -> %ld\n",
__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);
/* The check of the given value is in tasdevice_amp_putvol. */
- ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc);
-
- mutex_unlock(&tas_priv->codec_lock);
-
- return ret;
+ return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
}
static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
@@ -220,14 +215,12 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
{
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
- mutex_lock(&tas_priv->codec_lock);
+ guard(mutex)(&tas_priv->codec_lock);
ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
__func__, kcontrol->id.name, tas_priv->force_fwload_status);
- mutex_unlock(&tas_priv->codec_lock);
-
return 0;
}
@@ -237,7 +230,7 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
bool change, val = (bool)ucontrol->value.integer.value[0];
- mutex_lock(&tas_priv->codec_lock);
+ guard(mutex)(&tas_priv->codec_lock);
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
__func__, kcontrol->id.name,
@@ -250,8 +243,6 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
tas_priv->force_fwload_status = val;
}
- mutex_unlock(&tas_priv->codec_lock);
-
return change;
}
@@ -272,6 +263,17 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = {
tas2781_force_fwload_get, tas2781_force_fwload_put),
};
+static const struct snd_kcontrol_new tas5825_snd_controls[] = {
+ ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS5825_AMP_LEVEL,
+ 0, 0, 31, 1, tas2781_amp_getvol,
+ tas2781_amp_putvol, tas5825_amp_tlv),
+ ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS5825_DVC_LEVEL,
+ 0, 0, 254, 1, tas2781_amp_getvol,
+ tas2781_amp_putvol, tas5825_dvc_tlv),
+ ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
+ tas2781_force_fwload_get, tas2781_force_fwload_put),
+};
+
static const struct snd_kcontrol_new tasdevice_prof_ctrl = {
.name = "Speaker Profile Id",
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
@@ -364,7 +366,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
}
if (cd->total_sz != offset) {
- dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) dismatch\n",
+ dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) mismatch\n",
__func__, cd->total_sz, offset);
return -EINVAL;
}
@@ -509,6 +511,12 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
ARRAY_SIZE(tas2781_snd_controls));
tasdevice_dspfw_init(context);
break;
+ case HDA_TAS5825:
+ tasdev_add_kcontrols(tas_priv, hda_priv->snd_ctls, codec,
+ &tas5825_snd_controls[0],
+ ARRAY_SIZE(tas5825_snd_controls));
+ tasdevice_dspfw_init(context);
+ break;
case HDA_TAS2563:
tasdevice_dspfw_init(context);
break;
@@ -636,6 +644,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
} else if (strstarts(dev_name(&clt->dev),
"i2c-TXNW2781:00-tas2781-hda.0")) {
device_name = "TXNW2781";
+ hda_priv->hda_chip_id = HDA_TAS2781;
hda_priv->save_calibration = tas2781_save_calibration;
tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
} else if (strstr(dev_name(&clt->dev), "INT8866")) {
@@ -647,6 +656,13 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
hda_priv->hda_chip_id = HDA_TAS2563;
hda_priv->save_calibration = tas2563_save_calibration;
tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;
+ } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW5825")) {
+ /*
+ * TAS5825, integrated on-chip DSP without
+ * global I2C address and calibration supported.
+ */
+ device_name = "TXNW5825";
+ hda_priv->hda_chip_id = HDA_TAS5825;
} else {
return -ENODEV;
}
@@ -692,7 +708,7 @@ static int tas2781_runtime_suspend(struct device *dev)
dev_dbg(tas_hda->dev, "Runtime Suspend\n");
- mutex_lock(&tas_hda->priv->codec_lock);
+ guard(mutex)(&tas_hda->priv->codec_lock);
/* The driver powers up the amplifiers at module load time.
* Stop the playback if it's unused.
@@ -702,8 +718,6 @@ static int tas2781_runtime_suspend(struct device *dev)
tas_hda->priv->playback_started = false;
}
- mutex_unlock(&tas_hda->priv->codec_lock);
-
return 0;
}
@@ -713,12 +727,10 @@ static int tas2781_runtime_resume(struct device *dev)
dev_dbg(tas_hda->dev, "Runtime Resume\n");
- mutex_lock(&tas_hda->priv->codec_lock);
+ guard(mutex)(&tas_hda->priv->codec_lock);
tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog);
- mutex_unlock(&tas_hda->priv->codec_lock);
-
return 0;
}
@@ -728,14 +740,12 @@ static int tas2781_system_suspend(struct device *dev)
dev_dbg(tas_hda->priv->dev, "System Suspend\n");
- mutex_lock(&tas_hda->priv->codec_lock);
+ guard(mutex)(&tas_hda->priv->codec_lock);
/* Shutdown chip before system suspend */
if (tas_hda->priv->playback_started)
tasdevice_tuning_switch(tas_hda->priv, 1);
- mutex_unlock(&tas_hda->priv->codec_lock);
-
/*
* Reset GPIO may be shared, so cannot reset here.
* However beyond this point, amps may be powered down.
@@ -750,7 +760,7 @@ static int tas2781_system_resume(struct device *dev)
dev_dbg(tas_hda->priv->dev, "System Resume\n");
- mutex_lock(&tas_hda->priv->codec_lock);
+ guard(mutex)(&tas_hda->priv->codec_lock);
for (i = 0; i < tas_hda->priv->ndev; i++) {
tas_hda->priv->tasdevice[i].cur_book = -1;
@@ -763,8 +773,6 @@ static int tas2781_system_resume(struct device *dev)
if (tas_hda->priv->playback_started)
tasdevice_tuning_switch(tas_hda->priv, 0);
- mutex_unlock(&tas_hda->priv->codec_lock);
-
return 0;
}
@@ -783,6 +791,7 @@ static const struct acpi_device_id tas2781_acpi_hda_match[] = {
{"TIAS2781", 0 },
{"TXNW2770", 0 },
{"TXNW2781", 0 },
+ {"TXNW5825", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);
diff --git a/sound/hda/common/codec.c b/sound/hda/common/codec.c
index eb268d442201..c6d44168c7f9 100644
--- a/sound/hda/common/codec.c
+++ b/sound/hda/common/codec.c
@@ -8,6 +8,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/minmax.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/pm.h>
@@ -31,6 +32,22 @@
#define codec_has_clkstop(codec) \
((codec)->core.power_caps & AC_PWRST_CLKSTOP)
+static int call_exec_verb(struct hda_bus *bus, struct hda_codec *codec,
+ unsigned int cmd, unsigned int flags,
+ unsigned int *res)
+{
+ int err;
+
+ CLASS(snd_hda_power_pm, pm)(codec);
+ guard(mutex)(&bus->core.cmd_mutex);
+ if (flags & HDA_RW_NO_RESPONSE_FALLBACK)
+ bus->no_response_fallback = 1;
+ err = snd_hdac_bus_exec_verb_unlocked(&bus->core, codec->core.addr,
+ cmd, res);
+ bus->no_response_fallback = 0;
+ return err;
+}
+
/*
* Send and receive a verb - passed to exec_verb override for hdac_device
*/
@@ -45,15 +62,7 @@ static int codec_exec_verb(struct hdac_device *dev, unsigned int cmd,
return -1;
again:
- snd_hda_power_up_pm(codec);
- mutex_lock(&bus->core.cmd_mutex);
- if (flags & HDA_RW_NO_RESPONSE_FALLBACK)
- bus->no_response_fallback = 1;
- err = snd_hdac_bus_exec_verb_unlocked(&bus->core, codec->core.addr,
- cmd, res);
- bus->no_response_fallback = 0;
- mutex_unlock(&bus->core.cmd_mutex);
- snd_hda_power_down_pm(codec);
+ err = call_exec_verb(bus, codec, cmd, flags, res);
if (!codec_in_pm(codec) && res && err == -EAGAIN) {
if (bus->response_reset) {
codec_dbg(codec,
@@ -300,7 +309,7 @@ EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid)
{
unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int parm;
+ int parm;
if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
get_wcaps_type(wcaps) != AC_WID_PIN)
@@ -323,18 +332,16 @@ EXPORT_SYMBOL_GPL(snd_hda_get_num_devices);
* Copy the device list. This info is dynamic and so not cached.
* Currently called only from hda_proc.c, so not exported.
*/
-int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
- u8 *dev_list, int max_devices)
+unsigned int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
+ u8 *dev_list, unsigned int max_devices)
{
- unsigned int parm;
- int i, dev_len, devices;
+ unsigned int parm, i, dev_len, devices;
parm = snd_hda_get_num_devices(codec, nid);
if (!parm) /* not multi-stream capable */
return 0;
- dev_len = parm + 1;
- dev_len = dev_len < max_devices ? dev_len : max_devices;
+ dev_len = min(parm + 1, max_devices);
devices = 0;
while (devices < dev_len) {
@@ -523,11 +530,11 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
#ifdef CONFIG_SND_HDA_RECONFIG
{
unsigned int cfg = 0;
- mutex_lock(&codec->user_mutex);
- pin = look_up_pincfg(codec, &codec->user_pins, nid);
- if (pin)
- cfg = pin->cfg;
- mutex_unlock(&codec->user_mutex);
+ scoped_guard(mutex, &codec->user_mutex) {
+ pin = look_up_pincfg(codec, &codec->user_pins, nid);
+ if (pin)
+ cfg = pin->cfg;
+ }
if (cfg)
return cfg;
}
@@ -634,12 +641,11 @@ static void hda_jackpoll_work(struct work_struct *work)
return;
/* the power-up/down sequence triggers the runtime resume */
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
/* update jacks manually if polling is required, too */
snd_hda_jack_set_dirty_all(codec);
snd_hda_jack_poll_all(codec);
schedule_delayed_work(&codec->jackpoll_work, codec->jackpoll_interval);
- snd_hda_power_down(codec);
}
/* release all pincfg lists */
@@ -1742,9 +1748,9 @@ int snd_hda_lock_devices(struct hda_bus *bus)
struct snd_card *card = bus->card;
struct hda_codec *codec;
- spin_lock(&card->files_lock);
+ guard(spinlock)(&card->files_lock);
if (card->shutdown)
- goto err_unlock;
+ return -EINVAL;
card->shutdown = 1;
if (!list_empty(&card->ctl_files))
goto err_clear;
@@ -1759,13 +1765,10 @@ int snd_hda_lock_devices(struct hda_bus *bus)
goto err_clear;
}
}
- spin_unlock(&card->files_lock);
return 0;
err_clear:
card->shutdown = 0;
- err_unlock:
- spin_unlock(&card->files_lock);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(snd_hda_lock_devices);
@@ -1778,9 +1781,8 @@ void snd_hda_unlock_devices(struct hda_bus *bus)
{
struct snd_card *card = bus->card;
- spin_lock(&card->files_lock);
+ guard(spinlock)(&card->files_lock);
card->shutdown = 0;
- spin_unlock(&card->files_lock);
}
EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
@@ -1852,14 +1854,14 @@ static int check_follower_present(struct hda_codec *codec,
/* call kctl->put with the given value(s) */
static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
{
- struct snd_ctl_elem_value *ucontrol;
+ struct snd_ctl_elem_value *ucontrol __free(kfree) = NULL;
+
ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
if (!ucontrol)
return -ENOMEM;
ucontrol->value.integer.value[0] = val;
ucontrol->value.integer.value[1] = val;
kctl->put(kctl, ucontrol);
- kfree(ucontrol);
return 0;
}
@@ -2172,13 +2174,12 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
if (WARN_ON(codec->spdif_out.used <= idx))
return -EINVAL;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
ucontrol->value.iec958.status[0] = spdif->status & 0xff;
ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
@@ -2281,7 +2282,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
if (WARN_ON(codec->spdif_out.used <= idx))
return -EINVAL;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
nid = spdif->nid;
spdif->status = ucontrol->value.iec958.status[0] |
@@ -2294,7 +2295,6 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
spdif->ctls = val;
if (change && nid != (u16)-1)
set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
- mutex_unlock(&codec->spdif_mutex);
return change;
}
@@ -2309,10 +2309,9 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
if (WARN_ON(codec->spdif_out.used <= idx))
return -EINVAL;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
@@ -2339,7 +2338,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
if (WARN_ON(codec->spdif_out.used <= idx))
return -EINVAL;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
nid = spdif->nid;
val = spdif->ctls & ~AC_DIG1_ENABLE;
@@ -2349,7 +2348,6 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
spdif->ctls = val;
if (change && nid != (u16)-1)
set_spdif_ctls(codec, nid, val & 0xff, -1);
- mutex_unlock(&codec->spdif_mutex);
return change;
}
@@ -2494,10 +2492,9 @@ void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
if (WARN_ON(codec->spdif_out.used <= idx))
return;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
spdif->nid = (u16)-1;
- mutex_unlock(&codec->spdif_mutex);
}
EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign);
@@ -2516,14 +2513,13 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
if (WARN_ON(codec->spdif_out.used <= idx))
return;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
if (spdif->nid != nid) {
spdif->nid = nid;
val = spdif->ctls;
set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
}
- mutex_unlock(&codec->spdif_mutex);
}
EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_assign);
@@ -2598,14 +2594,13 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
unsigned int val = !!ucontrol->value.integer.value[0];
int change;
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
change = codec->spdif_in_enable != val;
if (change) {
codec->spdif_in_enable = val;
snd_hdac_regmap_write(&codec->core, nid,
AC_VERB_SET_DIGI_CONVERT_1, val);
}
- mutex_unlock(&codec->spdif_mutex);
return change;
}
@@ -3175,7 +3170,8 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
int ret;
- mutex_lock(&codec->bus->prepare_mutex);
+
+ guard(mutex)(&codec->bus->prepare_mutex);
if (hinfo->ops.prepare)
ret = hinfo->ops.prepare(hinfo, codec, stream, format,
substream);
@@ -3183,7 +3179,6 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
ret = -ENODEV;
if (ret >= 0)
purify_inactive_streams(codec);
- mutex_unlock(&codec->bus->prepare_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(snd_hda_codec_prepare);
@@ -3200,10 +3195,9 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
- mutex_lock(&codec->bus->prepare_mutex);
+ guard(mutex)(&codec->bus->prepare_mutex);
if (hinfo->ops.cleanup)
hinfo->ops.cleanup(hinfo, codec, substream);
- mutex_unlock(&codec->bus->prepare_mutex);
}
EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup);
@@ -3633,12 +3627,11 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
int snd_hda_multi_out_dig_open(struct hda_codec *codec,
struct hda_multi_out *mout)
{
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
/* already opened as analog dup; reset it once */
cleanup_dig_out_stream(codec, mout->dig_out_nid);
mout->dig_out_used = HDA_DIG_EXCLUSIVE;
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open);
@@ -3657,9 +3650,8 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
unsigned int format,
struct snd_pcm_substream *substream)
{
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare);
@@ -3672,9 +3664,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare);
int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
struct hda_multi_out *mout)
{
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
cleanup_dig_out_stream(codec, mout->dig_out_nid);
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup);
@@ -3687,9 +3678,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup);
int snd_hda_multi_out_dig_close(struct hda_codec *codec,
struct hda_multi_out *mout)
{
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
mout->dig_out_used = 0;
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close);
@@ -3729,7 +3719,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
NULL,
&mout->spdif_maxbps);
}
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
if (mout->share_spdif) {
if ((runtime->hw.rates & mout->spdif_rates) &&
(runtime->hw.formats & mout->spdif_formats)) {
@@ -3742,7 +3732,6 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
/* FIXME: need notify? */
}
}
- mutex_unlock(&codec->spdif_mutex);
}
return snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
@@ -3771,23 +3760,23 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
struct hda_spdif_out *spdif;
int i;
- mutex_lock(&codec->spdif_mutex);
- spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
- if (mout->dig_out_nid && mout->share_spdif &&
- mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
- if (chs == 2 && spdif != NULL &&
- snd_hda_is_supported_format(codec, mout->dig_out_nid,
- format) &&
- !(spdif->status & IEC958_AES0_NONAUDIO)) {
- mout->dig_out_used = HDA_DIG_ANALOG_DUP;
- setup_dig_out_stream(codec, mout->dig_out_nid,
- stream_tag, format);
- } else {
- mout->dig_out_used = 0;
- cleanup_dig_out_stream(codec, mout->dig_out_nid);
+ scoped_guard(mutex, &codec->spdif_mutex) {
+ spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
+ if (mout->dig_out_nid && mout->share_spdif &&
+ mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
+ if (chs == 2 && spdif != NULL &&
+ snd_hda_is_supported_format(codec, mout->dig_out_nid,
+ format) &&
+ !(spdif->status & IEC958_AES0_NONAUDIO)) {
+ mout->dig_out_used = HDA_DIG_ANALOG_DUP;
+ setup_dig_out_stream(codec, mout->dig_out_nid,
+ stream_tag, format);
+ } else {
+ mout->dig_out_used = 0;
+ cleanup_dig_out_stream(codec, mout->dig_out_nid);
+ }
}
}
- mutex_unlock(&codec->spdif_mutex);
/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
@@ -3854,12 +3843,11 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
if (mout->extra_out_nid[i])
snd_hda_codec_cleanup_stream(codec,
mout->extra_out_nid[i]);
- mutex_lock(&codec->spdif_mutex);
+ guard(mutex)(&codec->spdif_mutex);
if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
cleanup_dig_out_stream(codec, mout->dig_out_nid);
mout->dig_out_used = 0;
}
- mutex_unlock(&codec->spdif_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup);
diff --git a/sound/hda/common/controller.c b/sound/hda/common/controller.c
index 84387ed761be..b1cfd9bd4dcb 100644
--- a/sound/hda/common/controller.c
+++ b/sound/hda/common/controller.c
@@ -32,8 +32,11 @@
#include "controller_trace.h"
/* DSP lock helpers */
-#define dsp_lock(dev) snd_hdac_dsp_lock(azx_stream(dev))
-#define dsp_unlock(dev) snd_hdac_dsp_unlock(azx_stream(dev))
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+#define guard_dsp_lock(dev) guard(snd_hdac_dsp_lock)(azx_stream(dev))
+#else
+#define guard_dsp_lock(dev) do {} while (0)
+#endif
#define dsp_is_locked(dev) snd_hdac_stream_is_locked(azx_stream(dev))
/* assign a stream for the PCM */
@@ -93,12 +96,12 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
struct azx_dev *azx_dev = get_azx_dev(substream);
trace_azx_pcm_close(chip, azx_dev);
- mutex_lock(&chip->open_mutex);
- azx_release_device(azx_dev);
- if (hinfo->ops.close)
- hinfo->ops.close(hinfo, apcm->codec, substream);
- snd_hda_power_down(apcm->codec);
- mutex_unlock(&chip->open_mutex);
+ scoped_guard(mutex, &chip->open_mutex) {
+ azx_release_device(azx_dev);
+ if (hinfo->ops.close)
+ hinfo->ops.close(hinfo, apcm->codec, substream);
+ snd_hda_power_down(apcm->codec);
+ }
snd_hda_codec_pcm_put(apcm->info);
return 0;
}
@@ -110,14 +113,11 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
struct azx *chip = apcm->chip;
struct azx_dev *azx_dev = get_azx_dev(substream);
struct hdac_stream *hdas = azx_stream(azx_dev);
- int ret = 0;
trace_azx_pcm_hw_params(chip, azx_dev);
- dsp_lock(azx_dev);
- if (dsp_is_locked(azx_dev)) {
- ret = -EBUSY;
- goto unlock;
- }
+ guard_dsp_lock(azx_dev);
+ if (dsp_is_locked(azx_dev))
+ return -EBUSY;
/* Set up BDLEs here, return -ENOMEM if too many BDLEs are required */
hdas->bufsize = params_buffer_bytes(hw_params);
@@ -127,11 +127,9 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
(hw_params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
(hw_params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
if (snd_hdac_stream_setup_periods(hdas) < 0)
- ret = -ENOMEM;
+ return -ENOMEM;
-unlock:
- dsp_unlock(azx_dev);
- return ret;
+ return 0;
}
static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
@@ -141,14 +139,13 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
/* reset BDL address */
- dsp_lock(azx_dev);
+ guard_dsp_lock(azx_dev);
if (!dsp_is_locked(azx_dev))
snd_hdac_stream_cleanup(azx_stream(azx_dev));
snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
azx_stream(azx_dev)->prepared = 0;
- dsp_unlock(azx_dev);
return 0;
}
@@ -166,11 +163,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
unsigned short ctls = spdif ? spdif->ctls : 0;
trace_azx_pcm_prepare(chip, azx_dev);
- dsp_lock(azx_dev);
- if (dsp_is_locked(azx_dev)) {
- err = -EBUSY;
- goto unlock;
- }
+ guard_dsp_lock(azx_dev);
+ if (dsp_is_locked(azx_dev))
+ return -EBUSY;
snd_hdac_stream_reset(azx_stream(azx_dev));
bits = snd_hdac_stream_format_bits(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps);
@@ -180,13 +175,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
dev_err(chip->card->dev,
"invalid format_val, rate=%d, ch=%d, format=%d\n",
runtime->rate, runtime->channels, runtime->format);
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
err = snd_hdac_stream_set_params(azx_stream(azx_dev), format_val);
if (err < 0)
- goto unlock;
+ return err;
snd_hdac_stream_setup(azx_stream(azx_dev), false);
@@ -197,12 +191,11 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
stream_tag -= chip->capture_streams;
err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
azx_dev->core.format_val, substream);
+ if (err < 0)
+ return err;
- unlock:
- if (!err)
- azx_stream(azx_dev)->prepared = 1;
- dsp_unlock(azx_dev);
- return err;
+ azx_stream(azx_dev)->prepared = 1;
+ return 0;
}
static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -252,31 +245,29 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_pcm_trigger_done(s, substream);
}
- spin_lock(&bus->reg_lock);
+ scoped_guard(spinlock, &bus->reg_lock) {
+ /* first, set SYNC bits of corresponding streams */
+ snd_hdac_stream_sync_trigger(hstr, true, sbits, sync_reg);
- /* first, set SYNC bits of corresponding streams */
- snd_hdac_stream_sync_trigger(hstr, true, sbits, sync_reg);
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- azx_dev = get_azx_dev(s);
- if (start) {
- azx_dev->insufficient = 1;
- snd_hdac_stream_start(azx_stream(azx_dev));
- } else {
- snd_hdac_stream_stop(azx_stream(azx_dev));
+ snd_pcm_group_for_each_entry(s, substream) {
+ if (s->pcm->card != substream->pcm->card)
+ continue;
+ azx_dev = get_azx_dev(s);
+ if (start) {
+ azx_dev->insufficient = 1;
+ snd_hdac_stream_start(azx_stream(azx_dev));
+ } else {
+ snd_hdac_stream_stop(azx_stream(azx_dev));
+ }
}
}
- spin_unlock(&bus->reg_lock);
snd_hdac_stream_sync(hstr, start, sbits);
- spin_lock(&bus->reg_lock);
+ guard(spinlock)(&bus->reg_lock);
/* reset SYNC bits */
snd_hdac_stream_sync_trigger(hstr, false, sbits, sync_reg);
snd_hdac_stream_timecounter_init(hstr, sbits, start);
- spin_unlock(&bus->reg_lock);
return 0;
}
@@ -971,19 +962,18 @@ int snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
azx_dev = azx_get_dsp_loader_dev(chip);
hstr = azx_stream(azx_dev);
- spin_lock_irq(&bus->reg_lock);
- if (hstr->opened) {
- chip->saved_azx_dev = *azx_dev;
- saved = true;
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ if (hstr->opened) {
+ chip->saved_azx_dev = *azx_dev;
+ saved = true;
+ }
}
- spin_unlock_irq(&bus->reg_lock);
err = snd_hdac_dsp_prepare(hstr, format, byte_size, bufp);
if (err < 0) {
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
if (saved)
*azx_dev = chip->saved_azx_dev;
- spin_unlock_irq(&bus->reg_lock);
return err;
}
@@ -1014,11 +1004,10 @@ void snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
return;
snd_hdac_dsp_cleanup(hstr, dmab);
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
if (hstr->opened)
*azx_dev = chip->saved_azx_dev;
hstr->locked = false;
- spin_unlock_irq(&bus->reg_lock);
}
EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_cleanup);
#endif /* CONFIG_SND_HDA_DSP_LOADER */
@@ -1079,10 +1068,10 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
if (!pm_runtime_active(chip->card->dev))
return IRQ_NONE;
- spin_lock(&bus->reg_lock);
+ guard(spinlock)(&bus->reg_lock);
if (chip->disabled)
- goto unlock;
+ return IRQ_NONE;
do {
status = azx_readl(chip, INTSTS);
@@ -1114,9 +1103,6 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
}
} while (active && ++repeat < 10);
- unlock:
- spin_unlock(&bus->reg_lock);
-
return IRQ_RETVAL(handled);
}
EXPORT_SYMBOL_GPL(azx_interrupt);
@@ -1136,12 +1122,12 @@ static int probe_codec(struct azx *chip, int addr)
int err;
unsigned int res = -1;
- mutex_lock(&bus->cmd_mutex);
- chip->probing = 1;
- azx_send_cmd(bus, cmd);
- err = azx_get_response(bus, addr, &res);
- chip->probing = 0;
- mutex_unlock(&bus->cmd_mutex);
+ scoped_guard(mutex, &bus->cmd_mutex) {
+ chip->probing = 1;
+ azx_send_cmd(bus, cmd);
+ err = azx_get_response(bus, addr, &res);
+ chip->probing = 0;
+ }
if (err < 0 || res == -1)
return -EIO;
dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr);
diff --git a/sound/hda/common/proc.c b/sound/hda/common/proc.c
index 00c2eeb2c472..5f3f61519ba6 100644
--- a/sound/hda/common/proc.c
+++ b/sound/hda/common/proc.c
@@ -716,16 +716,15 @@ static void print_device_list(struct snd_info_buffer *buffer,
{
int i, curr = -1;
u8 dev_list[AC_MAX_DEV_LIST_LEN];
- int devlist_len;
+ unsigned int devlist_len;
devlist_len = snd_hda_get_devices(codec, nid, dev_list,
AC_MAX_DEV_LIST_LEN);
- snd_iprintf(buffer, " Devices: %d\n", devlist_len);
- if (devlist_len <= 0)
+ snd_iprintf(buffer, " Devices: %u\n", devlist_len);
+ if (devlist_len == 0)
return;
- curr = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DEVICE_SEL, 0);
+ curr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0);
for (i = 0; i < devlist_len; i++) {
if (i == curr)
@@ -782,7 +781,7 @@ static void print_codec_info(struct snd_info_entry *entry,
fg = codec->core.afg;
if (!fg)
return;
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
snd_iprintf(buffer, "Default PCM:\n");
print_pcm_caps(buffer, codec, fg);
snd_iprintf(buffer, "Default Amp-In caps: ");
@@ -795,7 +794,6 @@ static void print_codec_info(struct snd_info_entry *entry,
nodes = snd_hda_get_sub_nodes(codec, fg, &nid);
if (! nid || nodes < 0) {
snd_iprintf(buffer, "Invalid AFG subtree\n");
- snd_hda_power_down(codec);
return;
}
@@ -932,7 +930,6 @@ static void print_codec_info(struct snd_info_entry *entry,
kfree(conn);
}
- snd_hda_power_down(codec);
}
/*
diff --git a/sound/hda/common/sysfs.c b/sound/hda/common/sysfs.c
index 140e24bf4d7f..f8c8483fd5e5 100644
--- a/sound/hda/common/sysfs.c
+++ b/sound/hda/common/sysfs.c
@@ -81,12 +81,12 @@ static ssize_t pin_configs_show(struct hda_codec *codec,
{
const struct hda_pincfg *pin;
int i, len = 0;
- mutex_lock(&codec->user_mutex);
+
+ guard(mutex)(&codec->user_mutex);
snd_array_for_each(list, i, pin) {
len += sysfs_emit_at(buf, len, "0x%02x 0x%08x\n",
pin->nid, pin->cfg);
}
- mutex_unlock(&codec->user_mutex);
return len;
}
@@ -129,21 +129,18 @@ static int reconfig_codec(struct hda_codec *codec)
{
int err;
- snd_hda_power_up(codec);
+ CLASS(snd_hda_power, pm)(codec);
codec_info(codec, "hda-codec: reconfiguring\n");
err = snd_hda_codec_reset(codec);
if (err < 0) {
codec_err(codec,
"The codec is being used, can't reconfigure.\n");
- goto error;
+ return err;
}
err = device_reprobe(hda_codec_dev(codec));
if (err < 0)
- goto error;
- err = snd_card_register(codec->card);
- error:
- snd_hda_power_down(codec);
- return err;
+ return err;
+ return snd_card_register(codec->card);
}
/*
@@ -218,12 +215,12 @@ static ssize_t init_verbs_show(struct device *dev,
struct hda_codec *codec = dev_get_drvdata(dev);
const struct hda_verb *v;
int i, len = 0;
- mutex_lock(&codec->user_mutex);
+
+ guard(mutex)(&codec->user_mutex);
snd_array_for_each(&codec->init_verbs, i, v) {
len += sysfs_emit_at(buf, len, "0x%02x 0x%03x 0x%04x\n",
v->nid, v->verb, v->param);
}
- mutex_unlock(&codec->user_mutex);
return len;
}
@@ -236,16 +233,13 @@ static int parse_init_verbs(struct hda_codec *codec, const char *buf)
return -EINVAL;
if (!nid || !verb)
return -EINVAL;
- mutex_lock(&codec->user_mutex);
+ guard(mutex)(&codec->user_mutex);
v = snd_array_new(&codec->init_verbs);
- if (!v) {
- mutex_unlock(&codec->user_mutex);
+ if (!v)
return -ENOMEM;
- }
v->nid = nid;
v->verb = verb;
v->param = param;
- mutex_unlock(&codec->user_mutex);
return 0;
}
@@ -267,12 +261,12 @@ static ssize_t hints_show(struct device *dev,
struct hda_codec *codec = dev_get_drvdata(dev);
const struct hda_hint *hint;
int i, len = 0;
- mutex_lock(&codec->user_mutex);
+
+ guard(mutex)(&codec->user_mutex);
snd_array_for_each(&codec->hints, i, hint) {
len += sysfs_emit_at(buf, len, "%s = %s\n",
hint->key, hint->val);
}
- mutex_unlock(&codec->user_mutex);
return len;
}
@@ -305,9 +299,9 @@ static void remove_trail_spaces(char *str)
static int parse_hints(struct hda_codec *codec, const char *buf)
{
- char *key, *val;
+ char *key __free(kfree) = NULL;
+ char *val;
struct hda_hint *hint;
- int err = 0;
buf = skip_spaces(buf);
if (!*buf || *buf == '#' || *buf == '\n')
@@ -319,39 +313,29 @@ static int parse_hints(struct hda_codec *codec, const char *buf)
return -ENOMEM;
/* extract key and val */
val = strchr(key, '=');
- if (!val) {
- kfree(key);
+ if (!val)
return -EINVAL;
- }
*val++ = 0;
val = skip_spaces(val);
remove_trail_spaces(key);
remove_trail_spaces(val);
- mutex_lock(&codec->user_mutex);
+ guard(mutex)(&codec->user_mutex);
hint = get_hint(codec, key);
if (hint) {
/* replace */
kfree(hint->key);
- hint->key = key;
- hint->val = val;
- goto unlock;
+ goto replace;
}
/* allocate a new hint entry */
if (codec->hints.used >= MAX_HINTS)
- hint = NULL;
- else
- hint = snd_array_new(&codec->hints);
- if (hint) {
- hint->key = key;
- hint->val = val;
- } else {
- err = -ENOMEM;
- }
- unlock:
- mutex_unlock(&codec->user_mutex);
- if (err)
- kfree(key);
- return err;
+ return -ENOMEM;
+ hint = snd_array_new(&codec->hints);
+ if (!hint)
+ return -ENOMEM;
+ replace:
+ hint->key = no_free_ptr(key);
+ hint->val = val;
+ return 0;
}
static ssize_t hints_store(struct device *dev,
@@ -375,16 +359,14 @@ static ssize_t user_pin_configs_show(struct device *dev,
static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
{
- int nid, cfg, err;
+ int nid, cfg;
if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
return -EINVAL;
if (!nid)
return -EINVAL;
- mutex_lock(&codec->user_mutex);
- err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
- mutex_unlock(&codec->user_mutex);
- return err;
+ guard(mutex)(&codec->user_mutex);
+ return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
}
static ssize_t user_pin_configs_store(struct device *dev,
@@ -432,26 +414,19 @@ EXPORT_SYMBOL_GPL(snd_hda_get_hint);
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
{
const char *p;
- int ret;
- mutex_lock(&codec->user_mutex);
+ guard(mutex)(&codec->user_mutex);
p = snd_hda_get_hint(codec, key);
if (!p || !*p)
- ret = -ENOENT;
- else {
- switch (toupper(*p)) {
- case 'T': /* true */
- case 'Y': /* yes */
- case '1':
- ret = 1;
- break;
- default:
- ret = 0;
- break;
- }
+ return -ENOENT;
+ switch (toupper(*p)) {
+ case 'T': /* true */
+ case 'Y': /* yes */
+ case '1':
+ return 1;
+ default:
+ return 0;
}
- mutex_unlock(&codec->user_mutex);
- return ret;
}
EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint);
@@ -469,20 +444,17 @@ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
{
const char *p;
unsigned long val;
- int ret;
- mutex_lock(&codec->user_mutex);
+ guard(mutex)(&codec->user_mutex);
p = snd_hda_get_hint(codec, key);
if (!p)
- ret = -ENOENT;
+ return -ENOENT;
else if (kstrtoul(p, 0, &val))
- ret = -EINVAL;
+ return -EINVAL;
else {
*valp = val;
- ret = 0;
+ return 0;
}
- mutex_unlock(&codec->user_mutex);
- return ret;
}
EXPORT_SYMBOL_GPL(snd_hda_get_int_hint);
#endif /* CONFIG_SND_HDA_RECONFIG */
diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c
index 1bb3ff55b115..48c52a207024 100644
--- a/sound/hda/controllers/intel.c
+++ b/sound/hda/controllers/intel.c
@@ -764,12 +764,11 @@ static void azx_clear_irq_pending(struct azx *chip)
struct hdac_bus *bus = azx_bus(chip);
struct hdac_stream *s;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
list_for_each_entry(s, &bus->stream_list, list) {
struct azx_dev *azx_dev = stream_to_azx_dev(s);
azx_dev->irq_pending = 0;
}
- spin_unlock_irq(&bus->reg_lock);
}
static int azx_acquire_irq(struct azx *chip, int do_disconnect)
@@ -915,17 +914,17 @@ static void azx_shutdown_chip(struct azx *chip)
static void azx_add_card_list(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
- mutex_lock(&card_list_lock);
+
+ guard(mutex)(&card_list_lock);
list_add(&hda->list, &card_list);
- mutex_unlock(&card_list_lock);
}
static void azx_del_card_list(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
- mutex_lock(&card_list_lock);
+
+ guard(mutex)(&card_list_lock);
list_del_init(&hda->list);
- mutex_unlock(&card_list_lock);
}
/* trigger power-save check at writing parameter */
@@ -942,7 +941,7 @@ static int __maybe_unused param_set_xint(const char *val, const struct kernel_pa
if (pm_blacklist > 0)
return 0;
- mutex_lock(&card_list_lock);
+ guard(mutex)(&card_list_lock);
list_for_each_entry(hda, &card_list, list) {
chip = &hda->chip;
if (!hda->probe_continued || chip->disabled ||
@@ -950,7 +949,6 @@ static int __maybe_unused param_set_xint(const char *val, const struct kernel_pa
continue;
snd_hda_set_power_save(&chip->bus, power_save * 1000);
}
- mutex_unlock(&card_list_lock);
return 0;
}
diff --git a/sound/hda/core/bus.c b/sound/hda/core/bus.c
index d497414a5538..9b196c915f37 100644
--- a/sound/hda/core/bus.c
+++ b/sound/hda/core/bus.c
@@ -87,12 +87,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_exit);
int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
unsigned int cmd, unsigned int *res)
{
- int err;
-
- mutex_lock(&bus->cmd_mutex);
- err = snd_hdac_bus_exec_verb_unlocked(bus, addr, cmd, res);
- mutex_unlock(&bus->cmd_mutex);
- return err;
+ guard(mutex)(&bus->cmd_mutex);
+ return snd_hdac_bus_exec_verb_unlocked(bus, addr, cmd, res);
}
/**
diff --git a/sound/hda/core/component.c b/sound/hda/core/component.c
index 9c82a2864a2f..04755903880e 100644
--- a/sound/hda/core/component.c
+++ b/sound/hda/core/component.c
@@ -69,14 +69,14 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable)
dev_dbg(bus->dev, "display power %s\n", str_enable_disable(enable));
- mutex_lock(&bus->lock);
+ guard(mutex)(&bus->lock);
if (enable)
set_bit(idx, &bus->display_power_status);
else
clear_bit(idx, &bus->display_power_status);
if (!acomp || !acomp->ops)
- goto unlock;
+ return;
if (bus->display_power_status) {
if (!bus->display_power_active) {
@@ -99,8 +99,6 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable)
bus->display_power_active = 0;
}
}
- unlock:
- mutex_unlock(&bus->lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_display_power);
diff --git a/sound/hda/core/controller.c b/sound/hda/core/controller.c
index b5c833b9f8b9..a7c00ad80117 100644
--- a/sound/hda/core/controller.c
+++ b/sound/hda/core/controller.c
@@ -44,7 +44,7 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
{
WARN_ON_ONCE(!bus->rb.area);
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
/* CORB set up */
bus->corb.addr = bus->rb.addr;
bus->corb.buf = (__le32 *)bus->rb.area;
@@ -86,7 +86,6 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
/* Accept unsolicited responses */
snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
- spin_unlock_irq(&bus->reg_lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
@@ -112,18 +111,17 @@ static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus)
*/
void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus)
{
- spin_lock_irq(&bus->reg_lock);
- /* disable ringbuffer DMAs */
- snd_hdac_chip_writeb(bus, RIRBCTL, 0);
- snd_hdac_chip_writeb(bus, CORBCTL, 0);
- spin_unlock_irq(&bus->reg_lock);
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ /* disable ringbuffer DMAs */
+ snd_hdac_chip_writeb(bus, RIRBCTL, 0);
+ snd_hdac_chip_writeb(bus, CORBCTL, 0);
+ }
hdac_wait_for_cmd_dmas(bus);
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
/* disable unsolicited responses */
snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0);
- spin_unlock_irq(&bus->reg_lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_cmd_io);
@@ -171,9 +169,8 @@ static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val)
{
unsigned int addr = azx_command_addr(val);
int timeout = 50;
- int ret = -EIO;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
while (timeout--) {
/* check ICB bit */
@@ -184,8 +181,7 @@ static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val)
/* Set ICB bit */
snd_hdac_chip_updatew(bus, IRS, AZX_IRS_BUSY, AZX_IRS_BUSY);
- ret = snd_hdac_bus_wait_for_pio_response(bus, addr);
- goto out;
+ return snd_hdac_bus_wait_for_pio_response(bus, addr);
}
udelay(1);
}
@@ -193,10 +189,7 @@ static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val)
dev_dbg_ratelimited(bus->dev, "send_cmd_pio timeout: IRS=%#x, val=%#x\n",
snd_hdac_chip_readw(bus, IRS), val);
-out:
- spin_unlock_irq(&bus->reg_lock);
-
- return ret;
+ return -EIO;
}
/**
@@ -228,7 +221,7 @@ static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
unsigned int addr = azx_command_addr(val);
unsigned int wp, rp;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
bus->last_cmd[azx_command_addr(val)] = val;
@@ -236,7 +229,6 @@ static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
wp = snd_hdac_chip_readw(bus, CORBWP);
if (wp == 0xffff) {
/* something wrong, controller likely turned to D3 */
- spin_unlock_irq(&bus->reg_lock);
return -EIO;
}
wp++;
@@ -245,7 +237,6 @@ static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
rp = snd_hdac_chip_readw(bus, CORBRP);
if (wp == rp) {
/* oops, it's full */
- spin_unlock_irq(&bus->reg_lock);
return -EAGAIN;
}
@@ -253,8 +244,6 @@ static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
bus->corb.buf[wp] = cpu_to_le32(val);
snd_hdac_chip_writew(bus, CORBWP, wp);
- spin_unlock_irq(&bus->reg_lock);
-
return 0;
}
@@ -333,21 +322,20 @@ static int snd_hdac_bus_get_response_rirb(struct hdac_bus *bus,
timeout = jiffies + msecs_to_jiffies(1000);
for (loopcounter = 0;; loopcounter++) {
- spin_lock_irq(&bus->reg_lock);
- if (!bus->polling_mode)
- prepare_to_wait(&bus->rirb_wq, &wait,
- TASK_UNINTERRUPTIBLE);
- if (bus->polling_mode)
- snd_hdac_bus_update_rirb(bus);
- if (!bus->rirb.cmds[addr]) {
- if (res)
- *res = bus->rirb.res[addr]; /* the last value */
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
if (!bus->polling_mode)
- finish_wait(&bus->rirb_wq, &wait);
- spin_unlock_irq(&bus->reg_lock);
- return 0;
+ prepare_to_wait(&bus->rirb_wq, &wait,
+ TASK_UNINTERRUPTIBLE);
+ if (bus->polling_mode)
+ snd_hdac_bus_update_rirb(bus);
+ if (!bus->rirb.cmds[addr]) {
+ if (res)
+ *res = bus->rirb.res[addr]; /* the last value */
+ if (!bus->polling_mode)
+ finish_wait(&bus->rirb_wq, &wait);
+ return 0;
+ }
}
- spin_unlock_irq(&bus->reg_lock);
if (time_after(jiffies, timeout))
break;
#define LOOP_COUNT_MAX 3000
diff --git a/sound/hda/core/device.c b/sound/hda/core/device.c
index 018f9e176b1b..160c8d0453b0 100644
--- a/sound/hda/core/device.c
+++ b/sound/hda/core/device.c
@@ -147,9 +147,9 @@ int snd_hdac_device_register(struct hdac_device *codec)
err = device_add(&codec->dev);
if (err < 0)
return err;
- mutex_lock(&codec->widget_lock);
- err = hda_widget_sysfs_init(codec);
- mutex_unlock(&codec->widget_lock);
+ scoped_guard(mutex, &codec->widget_lock) {
+ err = hda_widget_sysfs_init(codec);
+ }
if (err < 0) {
device_del(&codec->dev);
return err;
@@ -166,9 +166,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_device_register);
void snd_hdac_device_unregister(struct hdac_device *codec)
{
if (device_is_registered(&codec->dev)) {
- mutex_lock(&codec->widget_lock);
- hda_widget_sysfs_exit(codec);
- mutex_unlock(&codec->widget_lock);
+ scoped_guard(mutex, &codec->widget_lock) {
+ hda_widget_sysfs_exit(codec);
+ }
device_del(&codec->dev);
snd_hdac_bus_remove_device(codec->bus, codec);
}
@@ -411,25 +411,22 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec)
* Serialize against multiple threads trying to update the sysfs
* widgets array.
*/
- mutex_lock(&codec->widget_lock);
+ guard(mutex)(&codec->widget_lock);
nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid);
if (!start_nid || nums <= 0 || nums >= 0xff) {
dev_err(&codec->dev, "cannot read sub nodes for FG 0x%02x\n",
codec->afg);
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
err = hda_widget_sysfs_reinit(codec, start_nid, nums);
if (err < 0)
- goto unlock;
+ return err;
codec->num_nodes = nums;
codec->start_nid = start_nid;
codec->end_nid = start_nid + nums;
-unlock:
- mutex_unlock(&codec->widget_lock);
- return err;
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets);
diff --git a/sound/hda/core/ext/controller.c b/sound/hda/core/ext/controller.c
index c84754434d16..9eea3ea2dae0 100644
--- a/sound/hda/core/ext/controller.c
+++ b/sound/hda/core/ext/controller.c
@@ -300,7 +300,7 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus,
unsigned long codec_mask;
int ret = 0;
- mutex_lock(&bus->lock);
+ guard(mutex)(&bus->lock);
/*
* if we move from 0 to 1, count will be 1 so power up this link
@@ -331,7 +331,6 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus,
bus->codec_mask = codec_mask;
}
- mutex_unlock(&bus->lock);
return ret;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get);
@@ -343,7 +342,7 @@ int snd_hdac_ext_bus_link_put(struct hdac_bus *bus,
struct hdac_ext_link *hlink_tmp;
bool link_up = false;
- mutex_lock(&bus->lock);
+ guard(mutex)(&bus->lock);
/*
* if we move from 1 to 0, count will be 0
@@ -369,7 +368,6 @@ int snd_hdac_ext_bus_link_put(struct hdac_bus *bus,
}
}
- mutex_unlock(&bus->lock);
return ret;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put);
diff --git a/sound/hda/core/ext/stream.c b/sound/hda/core/ext/stream.c
index a3ac738f1130..b4759198e51d 100644
--- a/sound/hda/core/ext/stream.c
+++ b/sound/hda/core/ext/stream.c
@@ -163,9 +163,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple_locked);
void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
struct hdac_ext_stream *hext_stream, bool decouple)
{
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
snd_hdac_ext_stream_decouple_locked(bus, hext_stream, decouple);
- spin_unlock_irq(&bus->reg_lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple);
@@ -265,7 +264,7 @@ hdac_ext_link_dma_stream_assign(struct hdac_bus *bus,
return NULL;
}
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
list_for_each_entry(hstream, &bus->stream_list, list) {
struct hdac_ext_stream *hext_stream = container_of(hstream,
struct hdac_ext_stream,
@@ -285,7 +284,6 @@ hdac_ext_link_dma_stream_assign(struct hdac_bus *bus,
res->link_locked = 1;
res->link_substream = substream;
}
- spin_unlock_irq(&bus->reg_lock);
return res;
}
@@ -301,7 +299,7 @@ hdac_ext_host_dma_stream_assign(struct hdac_bus *bus,
return NULL;
}
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
list_for_each_entry(hstream, &bus->stream_list, list) {
struct hdac_ext_stream *hext_stream = container_of(hstream,
struct hdac_ext_stream,
@@ -320,7 +318,6 @@ hdac_ext_host_dma_stream_assign(struct hdac_bus *bus,
res->hstream.running = 0;
res->hstream.substream = substream;
}
- spin_unlock_irq(&bus->reg_lock);
return res;
}
@@ -387,22 +384,22 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
break;
case HDAC_EXT_STREAM_TYPE_HOST:
- spin_lock_irq(&bus->reg_lock);
- /* couple link only if not in use */
- if (!hext_stream->link_locked)
- snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
- snd_hdac_stream_release_locked(&hext_stream->hstream);
- spin_unlock_irq(&bus->reg_lock);
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ /* couple link only if not in use */
+ if (!hext_stream->link_locked)
+ snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
+ snd_hdac_stream_release_locked(&hext_stream->hstream);
+ }
break;
case HDAC_EXT_STREAM_TYPE_LINK:
- spin_lock_irq(&bus->reg_lock);
- /* couple host only if not in use */
- if (!hext_stream->hstream.opened)
- snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
- hext_stream->link_locked = 0;
- hext_stream->link_substream = NULL;
- spin_unlock_irq(&bus->reg_lock);
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ /* couple host only if not in use */
+ if (!hext_stream->hstream.opened)
+ snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
+ hext_stream->link_locked = 0;
+ hext_stream->link_substream = NULL;
+ }
break;
default:
@@ -427,7 +424,7 @@ struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus,
struct hdac_ext_stream *res = NULL;
struct hdac_stream *hstream;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
list_for_each_entry(hstream, &bus->stream_list, list) {
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
@@ -446,7 +443,6 @@ struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus,
res->hstream.running = 0;
res->hstream.cstream = cstream;
}
- spin_unlock_irq(&bus->reg_lock);
return res;
}
diff --git a/sound/hda/core/regmap.c b/sound/hda/core/regmap.c
index 97cee096a286..e7b866fc52c1 100644
--- a/sound/hda/core/regmap.c
+++ b/sound/hda/core/regmap.c
@@ -425,15 +425,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb);
static int reg_raw_write(struct hdac_device *codec, unsigned int reg,
unsigned int val)
{
- int err;
-
- mutex_lock(&codec->regmap_lock);
+ guard(mutex)(&codec->regmap_lock);
if (!codec->regmap)
- err = hda_reg_write(codec, reg, val);
+ return hda_reg_write(codec, reg, val);
else
- err = regmap_write(codec->regmap, reg, val);
- mutex_unlock(&codec->regmap_lock);
- return err;
+ return regmap_write(codec->regmap, reg, val);
}
/* a helper macro to call @func_call; retry with power-up if failed */
@@ -466,15 +462,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);
static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
unsigned int *val, bool uncached)
{
- int err;
-
- mutex_lock(&codec->regmap_lock);
+ guard(mutex)(&codec->regmap_lock);
if (uncached || !codec->regmap)
- err = hda_reg_read(codec, reg, val);
+ return hda_reg_read(codec, reg, val);
else
- err = regmap_read(codec->regmap, reg, val);
- mutex_unlock(&codec->regmap_lock);
- return err;
+ return regmap_read(codec->regmap, reg, val);
}
static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
@@ -515,7 +507,7 @@ static int reg_raw_update(struct hdac_device *codec, unsigned int reg,
bool change;
int err;
- mutex_lock(&codec->regmap_lock);
+ guard(mutex)(&codec->regmap_lock);
if (codec->regmap) {
err = regmap_update_bits_check(codec->regmap, reg, mask, val,
&change);
@@ -533,7 +525,6 @@ static int reg_raw_update(struct hdac_device *codec, unsigned int reg,
}
}
}
- mutex_unlock(&codec->regmap_lock);
return err;
}
@@ -556,17 +547,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw);
static int reg_raw_update_once(struct hdac_device *codec, unsigned int reg,
unsigned int mask, unsigned int val)
{
- int err = 0;
-
if (!codec->regmap)
return reg_raw_update(codec, reg, mask, val);
- mutex_lock(&codec->regmap_lock);
+ guard(mutex)(&codec->regmap_lock);
/* Discard any updates to already initialised registers. */
if (!regcache_reg_cached(codec->regmap, reg))
- err = regmap_update_bits(codec->regmap, reg, mask, val);
- mutex_unlock(&codec->regmap_lock);
- return err;
+ return regmap_update_bits(codec->regmap, reg, mask, val);
+ return 0;
}
/**
@@ -593,9 +581,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw_once);
*/
void snd_hdac_regmap_sync(struct hdac_device *codec)
{
- mutex_lock(&codec->regmap_lock);
+ guard(mutex)(&codec->regmap_lock);
if (codec->regmap)
regcache_sync(codec->regmap);
- mutex_unlock(&codec->regmap_lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_sync);
diff --git a/sound/hda/core/stream.c b/sound/hda/core/stream.c
index 4a87bef8834f..579ec544ef4a 100644
--- a/sound/hda/core/stream.c
+++ b/sound/hda/core/stream.c
@@ -370,7 +370,7 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
if (substream->pcm)
key |= (substream->pcm->device << 16);
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
list_for_each_entry(azx_dev, &bus->stream_list, list) {
if (azx_dev->direction != substream->stream)
continue;
@@ -389,7 +389,6 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
res->assigned_key = key;
res->substream = substream;
}
- spin_unlock_irq(&bus->reg_lock);
return res;
}
EXPORT_SYMBOL_GPL(snd_hdac_stream_assign);
@@ -419,9 +418,8 @@ void snd_hdac_stream_release(struct hdac_stream *azx_dev)
{
struct hdac_bus *bus = azx_dev->bus;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
snd_hdac_stream_release_locked(azx_dev);
- spin_unlock_irq(&bus->reg_lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_stream_release);
@@ -922,15 +920,12 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
struct hdac_bus *bus = azx_dev->bus;
int err;
- snd_hdac_dsp_lock(azx_dev);
- spin_lock_irq(&bus->reg_lock);
- if (azx_dev->running || azx_dev->locked) {
- spin_unlock_irq(&bus->reg_lock);
- err = -EBUSY;
- goto unlock;
+ guard(snd_hdac_dsp_lock)(azx_dev);
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ if (azx_dev->running || azx_dev->locked)
+ return -EBUSY;
+ azx_dev->locked = true;
}
- azx_dev->locked = true;
- spin_unlock_irq(&bus->reg_lock);
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev,
byte_size, bufp);
@@ -951,17 +946,14 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
goto error;
snd_hdac_stream_setup(azx_dev, true);
- snd_hdac_dsp_unlock(azx_dev);
return azx_dev->stream_tag;
error:
snd_dma_free_pages(bufp);
err_alloc:
- spin_lock_irq(&bus->reg_lock);
- azx_dev->locked = false;
- spin_unlock_irq(&bus->reg_lock);
- unlock:
- snd_hdac_dsp_unlock(azx_dev);
+ scoped_guard(spinlock_irq, &bus->reg_lock) {
+ azx_dev->locked = false;
+ }
return err;
}
EXPORT_SYMBOL_GPL(snd_hdac_dsp_prepare);
@@ -993,7 +985,7 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
if (!dmab->area || !azx_dev->locked)
return;
- snd_hdac_dsp_lock(azx_dev);
+ guard(snd_hdac_dsp_lock)(azx_dev);
/* reset BDL address */
snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
@@ -1005,10 +997,8 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
snd_dma_free_pages(dmab);
dmab->area = NULL;
- spin_lock_irq(&bus->reg_lock);
+ guard(spinlock_irq)(&bus->reg_lock);
azx_dev->locked = false;
- spin_unlock_irq(&bus->reg_lock);
- snd_hdac_dsp_unlock(azx_dev);
}
EXPORT_SYMBOL_GPL(snd_hdac_dsp_cleanup);
#endif /* CONFIG_SND_HDA_DSP_LOADER */
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index c1f7447a4d11..70b3f7e17f9e 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -127,9 +127,9 @@ void snd_ak4113_reinit(struct ak4113 *chip)
{
if (atomic_inc_return(&chip->wq_processing) == 1)
cancel_delayed_work_sync(&chip->work);
- mutex_lock(&chip->reinit_mutex);
- ak4113_init_regs(chip);
- mutex_unlock(&chip->reinit_mutex);
+ scoped_guard(mutex, &chip->reinit_mutex) {
+ ak4113_init_regs(chip);
+ }
/* bring up statistics / event queing */
if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
@@ -185,11 +185,10 @@ static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol,
{
struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
ucontrol->value.integer.value[0] =
chip->errors[kcontrol->private_value];
chip->errors[kcontrol->private_value] = 0;
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -235,14 +234,13 @@ static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol,
int change;
u8 old_val;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
old_val = chip->regmap[AK4113_REG_IO1];
change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val);
if (change)
reg_write(chip, AK4113_REG_IO1,
(old_val & (~AK4113_IPS(0xff))) |
(AK4113_IPS(ucontrol->value.integer.value[0])));
- spin_unlock_irq(&chip->lock);
return change;
}
@@ -532,27 +530,27 @@ int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags)
goto __rate;
rcs0 = reg_read(ak4113, AK4113_REG_RCS0);
rcs2 = reg_read(ak4113, AK4113_REG_RCS2);
- spin_lock_irqsave(&ak4113->lock, _flags);
- if (rcs0 & AK4113_PAR)
- ak4113->errors[AK4113_PARITY_ERRORS]++;
- if (rcs0 & AK4113_V)
- ak4113->errors[AK4113_V_BIT_ERRORS]++;
- if (rcs2 & AK4113_CCRC)
- ak4113->errors[AK4113_CCRC_ERRORS]++;
- if (rcs2 & AK4113_QCRC)
- ak4113->errors[AK4113_QCRC_ERRORS]++;
- c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
- AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^
- (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
- AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));
- c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
- AK4113_DAT | 0xf0)) ^
- (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
- AK4113_DAT | 0xf0));
- ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);
- ak4113->rcs1 = rcs1;
- ak4113->rcs2 = rcs2;
- spin_unlock_irqrestore(&ak4113->lock, _flags);
+ scoped_guard(spinlock_irqsave, &ak4113->lock) {
+ if (rcs0 & AK4113_PAR)
+ ak4113->errors[AK4113_PARITY_ERRORS]++;
+ if (rcs0 & AK4113_V)
+ ak4113->errors[AK4113_V_BIT_ERRORS]++;
+ if (rcs2 & AK4113_CCRC)
+ ak4113->errors[AK4113_CCRC_ERRORS]++;
+ if (rcs2 & AK4113_QCRC)
+ ak4113->errors[AK4113_QCRC_ERRORS]++;
+ c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
+ AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^
+ (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
+ AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));
+ c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
+ AK4113_DAT | 0xf0)) ^
+ (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
+ AK4113_DAT | 0xf0));
+ ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);
+ ak4113->rcs1 = rcs1;
+ ak4113->rcs2 = rcs2;
+ }
if (rcs0 & AK4113_PAR)
snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 7c493681f3cb..0e3a272c1490 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -132,9 +132,9 @@ void snd_ak4114_reinit(struct ak4114 *chip)
{
if (atomic_inc_return(&chip->wq_processing) == 1)
cancel_delayed_work_sync(&chip->work);
- mutex_lock(&chip->reinit_mutex);
- ak4114_init_regs(chip);
- mutex_unlock(&chip->reinit_mutex);
+ scoped_guard(mutex, &chip->reinit_mutex) {
+ ak4114_init_regs(chip);
+ }
/* bring up statistics / event queing */
if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
@@ -170,11 +170,10 @@ static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol,
{
struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
ucontrol->value.integer.value[0] =
chip->errors[kcontrol->private_value];
chip->errors[kcontrol->private_value] = 0;
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -552,21 +551,21 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
if (flags & AK4114_CHECK_NO_STAT)
goto __rate;
rcs0 = reg_read(ak4114, AK4114_REG_RCS0);
- spin_lock_irqsave(&ak4114->lock, _flags);
- if (rcs0 & AK4114_PAR)
- ak4114->errors[AK4114_PARITY_ERRORS]++;
- if (rcs1 & AK4114_V)
- ak4114->errors[AK4114_V_BIT_ERRORS]++;
- if (rcs1 & AK4114_CCRC)
- ak4114->errors[AK4114_CCRC_ERRORS]++;
- if (rcs1 & AK4114_QCRC)
- ak4114->errors[AK4114_QCRC_ERRORS]++;
- c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^
- (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK));
- c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0);
- ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT);
- ak4114->rcs1 = rcs1;
- spin_unlock_irqrestore(&ak4114->lock, _flags);
+ scoped_guard(spinlock_irqsave, &ak4114->lock) {
+ if (rcs0 & AK4114_PAR)
+ ak4114->errors[AK4114_PARITY_ERRORS]++;
+ if (rcs1 & AK4114_V)
+ ak4114->errors[AK4114_V_BIT_ERRORS]++;
+ if (rcs1 & AK4114_CCRC)
+ ak4114->errors[AK4114_CCRC_ERRORS]++;
+ if (rcs1 & AK4114_QCRC)
+ ak4114->errors[AK4114_QCRC_ERRORS]++;
+ c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^
+ (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK));
+ c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0);
+ ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT);
+ ak4114->rcs1 = rcs1;
+ }
ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
if (ak4114->change_callback && (c0 | c1) != 0)
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index cd380db195ef..d2ec20f885f0 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -144,11 +144,10 @@ static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol,
{
struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
ucontrol->value.integer.value[0] =
chip->errors[kcontrol->private_value];
chip->errors[kcontrol->private_value] = 0;
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -192,12 +191,11 @@ static int snd_ak4117_rx_put(struct snd_kcontrol *kcontrol,
int change;
u8 old_val;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
old_val = chip->regmap[AK4117_REG_IO];
change = !!ucontrol->value.integer.value[0] != ((old_val & AK4117_IPS) ? 1 : 0);
if (change)
reg_write(chip, AK4117_REG_IO, (old_val & ~AK4117_IPS) | (ucontrol->value.integer.value[0] ? AK4117_IPS : 0));
- spin_unlock_irq(&chip->lock);
return change;
}
@@ -441,23 +439,23 @@ int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
goto __rate;
rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
- spin_lock_irqsave(&ak4117->lock, _flags);
- if (rcs0 & AK4117_PAR)
- ak4117->errors[AK4117_PARITY_ERRORS]++;
- if (rcs0 & AK4117_V)
- ak4117->errors[AK4117_V_BIT_ERRORS]++;
- if (rcs2 & AK4117_CCRC)
- ak4117->errors[AK4117_CCRC_ERRORS]++;
- if (rcs2 & AK4117_QCRC)
- ak4117->errors[AK4117_QCRC_ERRORS]++;
- c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^
- (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));
- c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^
- (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));
- ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
- ak4117->rcs1 = rcs1;
- ak4117->rcs2 = rcs2;
- spin_unlock_irqrestore(&ak4117->lock, _flags);
+ scoped_guard(spinlock_irqsave, &ak4117->lock) {
+ if (rcs0 & AK4117_PAR)
+ ak4117->errors[AK4117_PARITY_ERRORS]++;
+ if (rcs0 & AK4117_V)
+ ak4117->errors[AK4117_V_BIT_ERRORS]++;
+ if (rcs2 & AK4117_CCRC)
+ ak4117->errors[AK4117_CCRC_ERRORS]++;
+ if (rcs2 & AK4117_QCRC)
+ ak4117->errors[AK4117_QCRC_ERRORS]++;
+ c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^
+ (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));
+ c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^
+ (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));
+ ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
+ ak4117->rcs1 = rcs1;
+ ak4117->rcs2 = rcs2;
+ }
if (rcs0 & AK4117_PAR)
snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id);
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 400ae547bcba..50f62304de61 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -96,14 +96,10 @@ static unsigned char snd_ad1816a_get_format(struct snd_ad1816a *chip,
static int snd_ad1816a_open(struct snd_ad1816a *chip, unsigned int mode)
{
- unsigned long flags;
+ guard(spinlock_irqsave)(&chip->lock);
- spin_lock_irqsave(&chip->lock, flags);
-
- if (chip->mode & mode) {
- spin_unlock_irqrestore(&chip->lock, flags);
+ if (chip->mode & mode)
return -EAGAIN;
- }
switch ((mode &= AD1816A_MODE_OPEN)) {
case AD1816A_MODE_PLAYBACK:
@@ -126,15 +122,12 @@ static int snd_ad1816a_open(struct snd_ad1816a *chip, unsigned int mode)
}
chip->mode |= mode;
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
switch ((mode &= AD1816A_MODE_OPEN)) {
case AD1816A_MODE_PLAYBACK:
@@ -158,8 +151,6 @@ static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
chip->mode &= ~mode;
if (!(chip->mode & AD1816A_MODE_OPEN))
chip->mode = 0;
-
- spin_unlock_irqrestore(&chip->lock, flags);
}
@@ -171,19 +162,19 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&chip->lock);
- cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
- /* if (what & AD1816A_PLAYBACK_ENABLE) */
- /* That is not valid, because playback and capture enable
- * are the same bit pattern, just to different addresses
- */
- if (! iscapture)
- snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
- AD1816A_PLAYBACK_ENABLE, cmd);
- else
- snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
- AD1816A_CAPTURE_ENABLE, cmd);
- spin_unlock(&chip->lock);
+ scoped_guard(spinlock, &chip->lock) {
+ cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
+ /* if (what & AD1816A_PLAYBACK_ENABLE) */
+ /* That is not valid, because playback and capture enable
+ * are the same bit pattern, just to different addresses
+ */
+ if (!iscapture)
+ snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
+ AD1816A_PLAYBACK_ENABLE, cmd);
+ else
+ snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
+ AD1816A_CAPTURE_ENABLE, cmd);
+ }
break;
default:
dev_warn(chip->card->dev, "invalid trigger mode 0x%x.\n", what);
@@ -210,11 +201,10 @@ static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int
static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size, rate;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->p_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
@@ -234,19 +224,16 @@ static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
snd_ad1816a_write(chip, AD1816A_PLAYBACK_BASE_COUNT,
snd_pcm_lib_period_bytes(substream) / 4 - 1);
-
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size, rate;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->c_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
@@ -266,8 +253,6 @@ static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
snd_ad1816a_write(chip, AD1816A_CAPTURE_BASE_COUNT,
snd_pcm_lib_period_bytes(substream) / 4 - 1);
-
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -298,9 +283,9 @@ static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
struct snd_ad1816a *chip = dev_id;
unsigned char status;
- spin_lock(&chip->lock);
- status = snd_ad1816a_in(chip, AD1816A_INTERRUPT_STATUS);
- spin_unlock(&chip->lock);
+ scoped_guard(spinlock, &chip->lock) {
+ status = snd_ad1816a_in(chip, AD1816A_INTERRUPT_STATUS);
+ }
if ((status & AD1816A_PLAYBACK_IRQ_PENDING) && chip->playback_substream)
snd_pcm_period_elapsed(chip->playback_substream);
@@ -311,9 +296,9 @@ static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
if ((status & AD1816A_TIMER_IRQ_PENDING) && chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
- spin_lock(&chip->lock);
- snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
- spin_unlock(&chip->lock);
+ scoped_guard(spinlock, &chip->lock) {
+ snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
+ }
return IRQ_HANDLED;
}
@@ -381,9 +366,9 @@ static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer)
static int snd_ad1816a_timer_start(struct snd_timer *timer)
{
unsigned short bits;
- unsigned long flags;
struct snd_ad1816a *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
+
+ guard(spinlock_irqsave)(&chip->lock);
bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE);
if (!(bits & AD1816A_TIMER_ENABLE)) {
@@ -393,20 +378,16 @@ static int snd_ad1816a_timer_start(struct snd_timer *timer)
snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
AD1816A_TIMER_ENABLE, 0xffff);
}
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static int snd_ad1816a_timer_stop(struct snd_timer *timer)
{
- unsigned long flags;
struct snd_ad1816a *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
AD1816A_TIMER_ENABLE, 0x0000);
-
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -474,9 +455,7 @@ static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream)
static void snd_ad1816a_init(struct snd_ad1816a *chip)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
@@ -488,40 +467,32 @@ static void snd_ad1816a_init(struct snd_ad1816a *chip)
AD1816A_CAPTURE_NOT_EQUAL | AD1816A_WSS_ENABLE, 0xffff);
snd_ad1816a_write(chip, AD1816A_DSP_CONFIG, 0x0000);
snd_ad1816a_write(chip, AD1816A_POWERDOWN_CTRL, 0x0000);
-
- spin_unlock_irqrestore(&chip->lock, flags);
}
#ifdef CONFIG_PM
void snd_ad1816a_suspend(struct snd_ad1816a *chip)
{
int reg;
- unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
for (reg = 0; reg < 48; reg++)
chip->image[reg] = snd_ad1816a_read(chip, reg);
- spin_unlock_irqrestore(&chip->lock, flags);
}
void snd_ad1816a_resume(struct snd_ad1816a *chip)
{
int reg;
- unsigned long flags;
snd_ad1816a_init(chip);
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
for (reg = 0; reg < 48; reg++)
snd_ad1816a_write(chip, reg, chip->image[reg]);
- spin_unlock_irqrestore(&chip->lock, flags);
}
#endif
static int snd_ad1816a_probe(struct snd_ad1816a *chip)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
switch (chip->version = snd_ad1816a_read(chip, AD1816A_VERSION_ID)) {
case 0:
@@ -536,8 +507,6 @@ static int snd_ad1816a_probe(struct snd_ad1816a *chip)
default:
chip->hardware = AD1816A_HW_AUTO;
}
-
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -679,12 +648,10 @@ static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_el
static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned short val;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
val = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL);
- spin_unlock_irqrestore(&chip->lock, flags);
ucontrol->value.enumerated.item[0] = (val >> 12) & 7;
ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
return 0;
@@ -693,7 +660,6 @@ static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned short val;
int change;
@@ -702,10 +668,9 @@ static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
return -EINVAL;
val = (ucontrol->value.enumerated.item[0] << 12) |
(ucontrol->value.enumerated.item[1] << 4);
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
change = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL) != val;
snd_ad1816a_write(chip, AD1816A_ADC_SOURCE_SEL, val);
- spin_unlock_irqrestore(&chip->lock, flags);
return change;
}
@@ -735,15 +700,13 @@ static int snd_ad1816a_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl
static int snd_ad1816a_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
ucontrol->value.integer.value[0] = (snd_ad1816a_read(chip, reg) >> shift) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -752,7 +715,6 @@ static int snd_ad1816a_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -764,12 +726,11 @@ static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
old_val = snd_ad1816a_read(chip, reg);
val = (old_val & ~(mask << shift)) | val;
change = val != old_val;
snd_ad1816a_write(chip, reg, val);
- spin_unlock_irqrestore(&chip->lock, flags);
return change;
}
@@ -800,7 +761,6 @@ static int snd_ad1816a_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl
static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift_left = (kcontrol->private_value >> 8) & 0x0f;
int shift_right = (kcontrol->private_value >> 12) & 0x0f;
@@ -808,11 +768,10 @@ static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
int invert = (kcontrol->private_value >> 24) & 0xff;
unsigned short val;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
val = snd_ad1816a_read(chip, reg);
ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -823,7 +782,6 @@ static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift_left = (kcontrol->private_value >> 8) & 0x0f;
int shift_right = (kcontrol->private_value >> 12) & 0x0f;
@@ -840,12 +798,11 @@ static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
old_val = snd_ad1816a_read(chip, reg);
val1 = (old_val & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
change = val1 != old_val;
snd_ad1816a_write(chip, reg, val1);
- spin_unlock_irqrestore(&chip->lock, flags);
return change;
}
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index e681c2c82474..3d1f19321b9e 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -269,18 +269,17 @@ static const unsigned char cmi8330_sb_init_values[][2] = {
static int cmi8330_add_sb_mixers(struct snd_sb *chip)
{
int idx, err;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, 0x00, 0x00); /* mixer reset */
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, 0x00, 0x00); /* mixer reset */
+ }
/* mute and zero volume channels */
for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_init_values); idx++) {
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0],
- cmi8330_sb_init_values[idx][1]);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0],
+ cmi8330_sb_init_values[idx][1]);
+ }
}
for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) {
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index eaaf39aae526..e2c29e831020 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -169,10 +169,9 @@ static void snd_cs4236_playback_format(struct snd_wss *chip,
struct snd_pcm_hw_params *params,
unsigned char pdfr)
{
- unsigned long flags;
unsigned char rate = divisor_to_rate_register(params->rate_den);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
/* set fast playback format change and clean playback FIFO */
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1] | 0x10);
@@ -180,17 +179,15 @@ static void snd_cs4236_playback_format(struct snd_wss *chip,
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1] & ~0x10);
snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_cs4236_capture_format(struct snd_wss *chip,
struct snd_pcm_hw_params *params,
unsigned char cdfr)
{
- unsigned long flags;
unsigned char rate = divisor_to_rate_register(params->rate_den);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
/* set fast capture format change and clean capture FIFO */
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1] | 0x20);
@@ -198,7 +195,6 @@ static void snd_cs4236_capture_format(struct snd_wss *chip,
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1] & ~0x20);
snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
#ifdef CONFIG_PM
@@ -206,48 +202,45 @@ static void snd_cs4236_capture_format(struct snd_wss *chip,
static void snd_cs4236_suspend(struct snd_wss *chip)
{
int reg;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
for (reg = 0; reg < 32; reg++)
chip->image[reg] = snd_wss_in(chip, reg);
for (reg = 0; reg < 18; reg++)
chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg));
for (reg = 2; reg < 9; reg++)
chip->cimage[reg] = snd_cs4236_ctrl_in(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_cs4236_resume(struct snd_wss *chip)
{
int reg;
- unsigned long flags;
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++) {
- switch (reg) {
- case CS4236_EXT_REG:
- case CS4231_VERSION:
- case 27: /* why? CS4235 - master left */
- case 29: /* why? CS4235 - master right */
- break;
- default:
- snd_wss_out(chip, reg, chip->image[reg]);
- break;
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ for (reg = 0; reg < 32; reg++) {
+ switch (reg) {
+ case CS4236_EXT_REG:
+ case CS4231_VERSION:
+ case 27: /* why? CS4235 - master left */
+ case 29: /* why? CS4235 - master right */
+ break;
+ default:
+ snd_wss_out(chip, reg, chip->image[reg]);
+ break;
+ }
}
- }
- for (reg = 0; reg < 18; reg++)
- snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), chip->eimage[reg]);
- for (reg = 2; reg < 9; reg++) {
- switch (reg) {
- case 7:
- break;
- default:
- snd_cs4236_ctrl_out(chip, reg, chip->cimage[reg]);
+ for (reg = 0; reg < 18; reg++)
+ snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), chip->eimage[reg]);
+ for (reg = 2; reg < 9; reg++) {
+ switch (reg) {
+ case 7:
+ break;
+ default:
+ snd_cs4236_ctrl_out(chip, reg, chip->cimage[reg]);
+ }
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_wss_mce_down(chip);
}
@@ -403,15 +396,13 @@ static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->eimage[CS4236_REG(reg)] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -420,7 +411,6 @@ static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -432,11 +422,10 @@ static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = (chip->eimage[CS4236_REG(reg)] & ~(mask << shift)) | val;
change = val != chip->eimage[CS4236_REG(reg)];
snd_cs4236_ext_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -449,15 +438,13 @@ static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->cimage[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -466,7 +453,6 @@ static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -478,11 +464,10 @@ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = (chip->cimage[reg] & ~(mask << shift)) | val;
change = val != chip->cimage[reg];
snd_cs4236_ctrl_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -516,7 +501,6 @@ static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -524,10 +508,9 @@ static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->eimage[CS4236_REG(left_reg)] >> shift_left) & mask;
ucontrol->value.integer.value[1] = (chip->eimage[CS4236_REG(right_reg)] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -538,7 +521,6 @@ static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -556,7 +538,7 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (left_reg != right_reg) {
val1 = (chip->eimage[CS4236_REG(left_reg)] & ~(mask << shift_left)) | val1;
val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
@@ -568,7 +550,6 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
change = val1 != chip->eimage[CS4236_REG(left_reg)];
snd_cs4236_ext_out(chip, left_reg, val1);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -592,7 +573,6 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -600,10 +580,9 @@ static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
ucontrol->value.integer.value[1] = (chip->eimage[CS4236_REG(right_reg)] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -614,7 +593,6 @@ static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -632,13 +610,12 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)];
snd_wss_out(chip, left_reg, val1);
snd_cs4236_ext_out(chip, right_reg, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -658,31 +635,27 @@ static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = snd_cs4236_mixer_master_digital_invert_volume(chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] & 0x7f);
ucontrol->value.integer.value[1] = snd_cs4236_mixer_master_digital_invert_volume(chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & 0x7f);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short val1, val2;
val1 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[0] & 0x7f);
val2 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[1] & 0x7f);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val1 = (chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] & ~0x7f) | val1;
val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2;
change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)];
snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1);
snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -719,31 +692,27 @@ static inline int snd_cs4235_mixer_output_accu_set_volume(int vol)
static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = snd_cs4235_mixer_output_accu_get_volume(chip->image[CS4235_LEFT_MASTER]);
ucontrol->value.integer.value[1] = snd_cs4235_mixer_output_accu_get_volume(chip->image[CS4235_RIGHT_MASTER]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short val1, val2;
val1 = snd_cs4235_mixer_output_accu_set_volume(ucontrol->value.integer.value[0]);
val2 = snd_cs4235_mixer_output_accu_set_volume(ucontrol->value.integer.value[1]);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val1 = (chip->image[CS4235_LEFT_MASTER] & ~(3 << 5)) | val1;
val2 = (chip->image[CS4235_RIGHT_MASTER] & ~(3 << 5)) | val2;
change = val1 != chip->image[CS4235_LEFT_MASTER] || val2 != chip->image[CS4235_RIGHT_MASTER];
snd_wss_out(chip, CS4235_LEFT_MASTER, val1);
snd_wss_out(chip, CS4235_RIGHT_MASTER, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -929,9 +898,8 @@ WSS_DOUBLE("Analog Loopback Switch", 0,
static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0;
#if 0
dev_dbg(chip->card->dev,
@@ -943,33 +911,30 @@ static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
snd_cs4236_ctrl_in(chip, 6),
snd_cs4236_ctrl_in(chip, 8));
#endif
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short enable, val;
enable = ucontrol->value.integer.value[0] & 1;
- mutex_lock(&chip->mce_mutex);
+ guard(mutex)(&chip->mce_mutex);
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
- change = val != chip->image[CS4231_ALT_FEATURE_1];
- snd_wss_out(chip, CS4231_ALT_FEATURE_1, val);
- val = snd_cs4236_ctrl_in(chip, 4) | 0xc0;
- snd_cs4236_ctrl_out(chip, 4, val);
- udelay(100);
- val &= ~0x40;
- snd_cs4236_ctrl_out(chip, 4, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
+ change = val != chip->image[CS4231_ALT_FEATURE_1];
+ snd_wss_out(chip, CS4231_ALT_FEATURE_1, val);
+ val = snd_cs4236_ctrl_in(chip, 4) | 0xc0;
+ snd_cs4236_ctrl_out(chip, 4, val);
+ udelay(100);
+ val &= ~0x40;
+ snd_cs4236_ctrl_out(chip, 4, val);
+ }
snd_wss_mce_down(chip);
- mutex_unlock(&chip->mce_mutex);
#if 0
dev_dbg(chip->card->dev,
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 2ef183f197ad..59987dbc9ae9 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -105,7 +105,6 @@ EXPORT_SYMBOL(snd_es1688_reset);
static int snd_es1688_probe(struct snd_es1688 *chip)
{
- unsigned long flags;
unsigned short major, minor;
int i;
@@ -113,39 +112,36 @@ static int snd_es1688_probe(struct snd_es1688 *chip)
* initialization sequence
*/
- spin_lock_irqsave(&chip->reg_lock, flags); /* Some ESS1688 cards need this */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE0)); /* ENABLE0 */
-
- if (snd_es1688_reset(chip) < 0) {
- dev_dbg(chip->card->dev, "ESS: [0x%lx] reset failed... 0x%x\n",
- chip->port, inb(ES1688P(chip, READ)));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
- }
- snd_es1688_dsp_command(chip, 0xe7); /* return identification */
-
- for (i = 1000, major = minor = 0; i; i--) {
- if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) {
- if (major == 0) {
- major = inb(ES1688P(chip, READ));
- } else {
- minor = inb(ES1688P(chip, READ));
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) { /* Some ESS1688 cards need this */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
+ inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
+ inb(ES1688P(chip, ENABLE0)); /* ENABLE0 */
+
+ if (snd_es1688_reset(chip) < 0) {
+ dev_dbg(chip->card->dev, "ESS: [0x%lx] reset failed... 0x%x\n",
+ chip->port, inb(ES1688P(chip, READ)));
+ return -ENODEV;
+ }
+ snd_es1688_dsp_command(chip, 0xe7); /* return identification */
+
+ for (i = 1000, major = minor = 0; i; i--) {
+ if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) {
+ if (major == 0)
+ major = inb(ES1688P(chip, READ));
+ else
+ minor = inb(ES1688P(chip, READ));
}
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
dev_dbg(chip->card->dev,
"ESS: [0x%lx] found.. major = 0x%x, minor = 0x%x\n",
chip->port, major, minor);
@@ -169,15 +165,15 @@ static int snd_es1688_probe(struct snd_es1688 *chip)
return -ENODEV;
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
- snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
+ snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
+ }
/* enable joystick, but disable OPL3 */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_es1688_mixer_write(chip, 0x40, 0x01);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_es1688_mixer_write(chip, 0x40, 0x01);
+ }
return 0;
}
@@ -185,7 +181,6 @@ static int snd_es1688_probe(struct snd_es1688 *chip)
static int snd_es1688_init(struct snd_es1688 * chip, int enable)
{
static const int irqs[16] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, 0, 3, -1, -1, -1, -1, -1};
- unsigned long flags;
int cfg, irq_bits, dma, dma_bits, tmp, tmp1;
/* ok.. setup MPU-401 port and joystick and OPL3 */
@@ -214,14 +209,14 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable)
}
}
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_mixer_write(chip, 0x40, cfg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_mixer_write(chip, 0x40, cfg);
+ }
/* --- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_read(chip, 0xb1);
- snd_es1688_read(chip, 0xb2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_read(chip, 0xb1);
+ snd_es1688_read(chip, 0xb2);
+ }
if (enable) {
cfg = 0xf0; /* enable only DMA counter interrupt */
irq_bits = irqs[chip->irq & 0x0f];
@@ -235,9 +230,9 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable)
#endif
return -EINVAL;
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, cfg | (irq_bits << 2));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xb1, cfg | (irq_bits << 2));
+ }
cfg = 0xf0; /* extended mode DMA enable */
dma = chip->dma8;
if (dma > 3 || dma == 2) {
@@ -254,20 +249,20 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable)
if (dma != 3)
dma_bits++;
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb2, cfg | (dma_bits << 2));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xb2, cfg | (dma_bits << 2));
+ }
} else {
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
- snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
+ snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
+ }
+ }
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_read(chip, 0xb1);
+ snd_es1688_read(chip, 0xb2);
+ snd_es1688_reset(chip);
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_read(chip, 0xb1);
- snd_es1688_read(chip, 0xb2);
- snd_es1688_reset(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -320,74 +315,70 @@ static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char va
} else if (cmd != SNDRV_PCM_TRIGGER_START) {
return -EINVAL;
}
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
chip->trigger_value = value;
val = snd_es1688_read(chip, 0xb8);
- if ((val < 0) || (val & 0x0f) == value) {
- spin_unlock(&chip->reg_lock);
+ if ((val < 0) || (val & 0x0f) == value)
return -EINVAL; /* something is wrong */
- }
#if 0
dev_dbg(chip->card->dev, "trigger: val = 0x%x, value = 0x%x\n", val, value);
dev_dbg(chip->card->dev, "trigger: pointer = 0x%x\n",
snd_dma_pointer(chip->dma8, chip->dma_size));
#endif
snd_es1688_write(chip, 0xb8, (val & 0xf0) | value);
- spin_unlock(&chip->reg_lock);
return 0;
}
static int snd_es1688_playback_prepare(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
unsigned int count = snd_pcm_lib_period_bytes(substream);
chip->dma_size = size;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_reset(chip);
- snd_es1688_set_rate(chip, substream);
- snd_es1688_write(chip, 0xb8, 4); /* auto init DMA mode */
- snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
- snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
- if (runtime->channels == 1) {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit mono */
- snd_es1688_write(chip, 0xb6, 0x80);
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0xd0);
- } else {
- /* 16. bit mono */
- snd_es1688_write(chip, 0xb6, 0x00);
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xf4);
- }
- } else {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit stereo */
- snd_es1688_write(chip, 0xb6, 0x80);
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0x98);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_reset(chip);
+ snd_es1688_set_rate(chip, substream);
+ snd_es1688_write(chip, 0xb8, 4); /* auto init DMA mode */
+ snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
+ snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
+ if (runtime->channels == 1) {
+ if (snd_pcm_format_width(runtime->format) == 8) {
+ /* 8. bit mono */
+ snd_es1688_write(chip, 0xb6, 0x80);
+ snd_es1688_write(chip, 0xb7, 0x51);
+ snd_es1688_write(chip, 0xb7, 0xd0);
+ } else {
+ /* 16. bit mono */
+ snd_es1688_write(chip, 0xb6, 0x00);
+ snd_es1688_write(chip, 0xb7, 0x71);
+ snd_es1688_write(chip, 0xb7, 0xf4);
+ }
} else {
- /* 16. bit stereo */
- snd_es1688_write(chip, 0xb6, 0x00);
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xbc);
+ if (snd_pcm_format_width(runtime->format) == 8) {
+ /* 8. bit stereo */
+ snd_es1688_write(chip, 0xb6, 0x80);
+ snd_es1688_write(chip, 0xb7, 0x51);
+ snd_es1688_write(chip, 0xb7, 0x98);
+ } else {
+ /* 16. bit stereo */
+ snd_es1688_write(chip, 0xb6, 0x00);
+ snd_es1688_write(chip, 0xb7, 0x71);
+ snd_es1688_write(chip, 0xb7, 0xbc);
+ }
}
+ snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
+ snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
+ snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON);
}
- snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
- snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
- snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
/* --- */
count = -count;
snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xa4, (unsigned char) count);
- snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xa4, (unsigned char) count);
+ snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
+ }
return 0;
}
@@ -400,51 +391,50 @@ static int snd_es1688_playback_trigger(struct snd_pcm_substream *substream,
static int snd_es1688_capture_prepare(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
unsigned int count = snd_pcm_lib_period_bytes(substream);
chip->dma_size = size;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_reset(chip);
- snd_es1688_set_rate(chip, substream);
- snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF);
- snd_es1688_write(chip, 0xb8, 0x0e); /* auto init DMA mode */
- snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
- snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
- if (runtime->channels == 1) {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit mono */
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0xd0);
- } else {
- /* 16. bit mono */
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xf4);
- }
- } else {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit stereo */
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0x98);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_reset(chip);
+ snd_es1688_set_rate(chip, substream);
+ snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF);
+ snd_es1688_write(chip, 0xb8, 0x0e); /* auto init DMA mode */
+ snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
+ snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
+ if (runtime->channels == 1) {
+ if (snd_pcm_format_width(runtime->format) == 8) {
+ /* 8. bit mono */
+ snd_es1688_write(chip, 0xb7, 0x51);
+ snd_es1688_write(chip, 0xb7, 0xd0);
+ } else {
+ /* 16. bit mono */
+ snd_es1688_write(chip, 0xb7, 0x71);
+ snd_es1688_write(chip, 0xb7, 0xf4);
+ }
} else {
- /* 16. bit stereo */
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xbc);
+ if (snd_pcm_format_width(runtime->format) == 8) {
+ /* 8. bit stereo */
+ snd_es1688_write(chip, 0xb7, 0x51);
+ snd_es1688_write(chip, 0xb7, 0x98);
+ } else {
+ /* 16. bit stereo */
+ snd_es1688_write(chip, 0xb7, 0x71);
+ snd_es1688_write(chip, 0xb7, 0xbc);
+ }
}
+ snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
+ snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
}
- snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
- snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
/* --- */
count = -count;
snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xa4, (unsigned char) count);
- snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_es1688_write(chip, 0xa4, (unsigned char) count);
+ snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
+ }
return 0;
}
@@ -738,19 +728,17 @@ static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
static int snd_es1688_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned char oval, nval;
int change;
if (ucontrol->value.enumerated.item[0] > 8)
return -EINVAL;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
oval = snd_es1688_mixer_read(chip, ES1688_REC_DEV);
nval = (ucontrol->value.enumerated.item[0] & 7) | (oval & ~15);
change = nval != oval;
if (change)
snd_es1688_mixer_write(chip, ES1688_REC_DEV, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -774,15 +762,13 @@ static int snd_es1688_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (snd_es1688_mixer_read(chip, reg) >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -791,7 +777,6 @@ static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -803,13 +788,12 @@ static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
if (invert)
nval = mask - nval;
nval <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
oval = snd_es1688_mixer_read(chip, reg);
nval = (oval & ~(mask << shift)) | nval;
change = nval != oval;
if (change)
snd_es1688_mixer_write(chip, reg, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -833,7 +817,6 @@ static int snd_es1688_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -842,7 +825,7 @@ static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
int invert = (kcontrol->private_value >> 22) & 1;
unsigned char left, right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (left_reg < 0xa0)
left = snd_es1688_mixer_read(chip, left_reg);
else
@@ -854,7 +837,6 @@ static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
right = snd_es1688_read(chip, right_reg);
} else
right = left;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
if (invert) {
@@ -867,7 +849,6 @@ static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -885,7 +866,7 @@ static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (left_reg != right_reg) {
if (left_reg < 0xa0)
oval1 = snd_es1688_mixer_read(chip, left_reg);
@@ -923,7 +904,6 @@ static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 3e89a84c6244..1da7b400a17b 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -185,16 +185,13 @@ static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip)
static int snd_es18xx_write(struct snd_es18xx *chip,
unsigned char reg, unsigned char data)
{
- unsigned long flags;
int ret;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ret = snd_es18xx_dsp_command(chip, reg);
if (ret < 0)
- goto end;
+ return ret;
ret = snd_es18xx_dsp_command(chip, data);
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Reg %02x set to %02x\n", reg, data);
#endif
@@ -203,22 +200,20 @@ static int snd_es18xx_write(struct snd_es18xx *chip,
static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg)
{
- unsigned long flags;
int ret, data;
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
ret = snd_es18xx_dsp_command(chip, 0xC0);
if (ret < 0)
- goto end;
+ return ret;
ret = snd_es18xx_dsp_command(chip, reg);
if (ret < 0)
- goto end;
+ return ret;
data = snd_es18xx_dsp_get_byte(chip);
ret = data;
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Reg %02x now is %02x (%d)\n", reg, data, ret);
#endif
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return ret;
}
@@ -228,47 +223,41 @@ static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg,
{
int ret;
unsigned char old, new, oval;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
ret = snd_es18xx_dsp_command(chip, 0xC0);
if (ret < 0)
- goto end;
+ return ret;
ret = snd_es18xx_dsp_command(chip, reg);
if (ret < 0)
- goto end;
+ return ret;
ret = snd_es18xx_dsp_get_byte(chip);
- if (ret < 0) {
- goto end;
- }
+ if (ret < 0)
+ return ret;
old = ret;
oval = old & mask;
if (val != oval) {
ret = snd_es18xx_dsp_command(chip, reg);
if (ret < 0)
- goto end;
+ return ret;
new = (old & ~mask) | (val & mask);
ret = snd_es18xx_dsp_command(chip, new);
if (ret < 0)
- goto end;
+ return ret;
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Reg %02x was %02x, set to %02x (%d)\n",
reg, old, new, ret);
#endif
}
- ret = oval;
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return ret;
+ return oval;
}
static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip,
unsigned char reg, unsigned char data)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, chip->port + 0x04);
outb(data, chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Mixer reg %02x set to %02x\n", reg, data);
#endif
@@ -276,12 +265,11 @@ static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip,
static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg)
{
- unsigned long flags;
int data;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, chip->port + 0x04);
data = inb(chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Mixer reg %02x now is %02x\n", reg, data);
#endif
@@ -293,8 +281,8 @@ static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char r
unsigned char mask, unsigned char val)
{
unsigned char old, new, oval;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, chip->port + 0x04);
old = inb(chip->port + 0x05);
oval = old & mask;
@@ -306,7 +294,6 @@ static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char r
reg, old, new);
#endif
}
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
return oval;
}
@@ -314,14 +301,13 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch
unsigned char mask)
{
int old, expected, new;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, chip->port + 0x04);
old = inb(chip->port + 0x05);
expected = old ^ mask;
outb(expected, chip->port + 0x05);
new = inb(chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
dev_dbg(chip->card->dev, "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
reg, old, expected, new);
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index bb5a4e2fbfb3..ffc69e26227e 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -11,12 +11,9 @@
static void snd_gf1_dma_ack(struct snd_gus_card * gus)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, 0x00);
snd_gf1_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
static void snd_gf1_dma_program(struct snd_gus_card * gus,
@@ -25,7 +22,6 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus,
unsigned int count,
unsigned int cmd)
{
- unsigned long flags;
unsigned int address;
unsigned char dma_cmd;
unsigned int address_high;
@@ -70,7 +66,7 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus,
"address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n",
address << 1, count, dma_cmd);
#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
if (gus->gf1.enh_mode) {
address_high = ((address >> 16) & 0x000000f0) | (address & 0x0000000f);
snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
@@ -78,7 +74,6 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus,
} else
snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, dma_cmd);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
static struct snd_gf1_dma_block *snd_gf1_dma_next_block(struct snd_gus_card * gus)
@@ -120,16 +115,15 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
snd_gf1_dma_ack(gus);
if (gus->gf1.dma_ack)
gus->gf1.dma_ack(gus, gus->gf1.dma_private_data);
- spin_lock(&gus->dma_lock);
- if (gus->gf1.dma_data_pcm == NULL &&
- gus->gf1.dma_data_synth == NULL) {
- gus->gf1.dma_ack = NULL;
- gus->gf1.dma_flags &= ~SNDRV_GF1_DMA_TRIGGER;
- spin_unlock(&gus->dma_lock);
- return;
+ scoped_guard(spinlock, &gus->dma_lock) {
+ if (gus->gf1.dma_data_pcm == NULL &&
+ gus->gf1.dma_data_synth == NULL) {
+ gus->gf1.dma_ack = NULL;
+ gus->gf1.dma_flags &= ~SNDRV_GF1_DMA_TRIGGER;
+ return;
+ }
+ block = snd_gf1_dma_next_block(gus);
}
- block = snd_gf1_dma_next_block(gus);
- spin_unlock(&gus->dma_lock);
if (!block)
return;
snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
@@ -143,18 +137,15 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
int snd_gf1_dma_init(struct snd_gus_card * gus)
{
- mutex_lock(&gus->dma_mutex);
+ guard(mutex)(&gus->dma_mutex);
gus->gf1.dma_shared++;
- if (gus->gf1.dma_shared > 1) {
- mutex_unlock(&gus->dma_mutex);
+ if (gus->gf1.dma_shared > 1)
return 0;
- }
gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt;
gus->gf1.dma_data_pcm =
gus->gf1.dma_data_pcm_last =
gus->gf1.dma_data_synth =
gus->gf1.dma_data_synth_last = NULL;
- mutex_unlock(&gus->dma_mutex);
return 0;
}
@@ -162,7 +153,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
{
struct snd_gf1_dma_block *block;
- mutex_lock(&gus->dma_mutex);
+ guard(mutex)(&gus->dma_mutex);
gus->gf1.dma_shared--;
if (!gus->gf1.dma_shared) {
snd_dma_disable(gus->gf1.dma1);
@@ -179,7 +170,6 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
gus->gf1.dma_data_pcm_last =
gus->gf1.dma_data_synth_last = NULL;
}
- mutex_unlock(&gus->dma_mutex);
return 0;
}
@@ -188,8 +178,8 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
int atomic,
int synth)
{
- unsigned long flags;
struct snd_gf1_dma_block *block;
+ struct snd_gf1_dma_block *free_block = NULL;
block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
if (!block)
@@ -210,34 +200,36 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
"gus->gf1.dma_data_pcm = 0x%lx\n",
(long)gus->gf1.dma_data_pcm);
- spin_lock_irqsave(&gus->dma_lock, flags);
- if (synth) {
- if (gus->gf1.dma_data_synth_last) {
- gus->gf1.dma_data_synth_last->next = block;
- gus->gf1.dma_data_synth_last = block;
+ scoped_guard(spinlock_irqsave, &gus->dma_lock) {
+ if (synth) {
+ if (gus->gf1.dma_data_synth_last) {
+ gus->gf1.dma_data_synth_last->next = block;
+ gus->gf1.dma_data_synth_last = block;
+ } else {
+ gus->gf1.dma_data_synth =
+ gus->gf1.dma_data_synth_last = block;
+ }
} else {
- gus->gf1.dma_data_synth =
- gus->gf1.dma_data_synth_last = block;
+ if (gus->gf1.dma_data_pcm_last) {
+ gus->gf1.dma_data_pcm_last->next = block;
+ gus->gf1.dma_data_pcm_last = block;
+ } else {
+ gus->gf1.dma_data_pcm =
+ gus->gf1.dma_data_pcm_last = block;
+ }
}
- } else {
- if (gus->gf1.dma_data_pcm_last) {
- gus->gf1.dma_data_pcm_last->next = block;
- gus->gf1.dma_data_pcm_last = block;
- } else {
- gus->gf1.dma_data_pcm =
- gus->gf1.dma_data_pcm_last = block;
+ if (!(gus->gf1.dma_flags & SNDRV_GF1_DMA_TRIGGER)) {
+ gus->gf1.dma_flags |= SNDRV_GF1_DMA_TRIGGER;
+ free_block = snd_gf1_dma_next_block(gus);
}
}
- if (!(gus->gf1.dma_flags & SNDRV_GF1_DMA_TRIGGER)) {
- gus->gf1.dma_flags |= SNDRV_GF1_DMA_TRIGGER;
- block = snd_gf1_dma_next_block(gus);
- spin_unlock_irqrestore(&gus->dma_lock, flags);
- if (block == NULL)
- return 0;
- snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
- kfree(block);
- return 0;
+
+ if (free_block) {
+ snd_gf1_dma_program(gus, free_block->addr, free_block->buf_addr,
+ free_block->count,
+ (unsigned short)free_block->cmd);
+ kfree(free_block);
}
- spin_unlock_irqrestore(&gus->dma_lock, flags);
+
return 0;
}
diff --git a/sound/isa/gus/gus_dram.c b/sound/isa/gus/gus_dram.c
index 5cebc0119d0a..50fe738ee3ea 100644
--- a/sound/isa/gus/gus_dram.c
+++ b/sound/isa/gus/gus_dram.c
@@ -13,7 +13,6 @@
static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer,
unsigned int address, unsigned int size)
{
- unsigned long flags;
unsigned int size1, size2;
char buffer[256], *pbuffer;
@@ -22,11 +21,10 @@ static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer,
if (copy_from_user(buffer, _buffer, size1))
return -EFAULT;
if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
snd_gf1_dram_addr(gus, address);
outsb(GUSP(gus, DRAM), buffer, size1);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
address += size1;
} else {
pbuffer = buffer;
@@ -51,19 +49,17 @@ static int snd_gus_dram_peek(struct snd_gus_card *gus, char __user *_buffer,
unsigned int address, unsigned int size,
int rom)
{
- unsigned long flags;
unsigned int size1, size2;
char buffer[256], *pbuffer;
while (size > 0) {
size1 = size > sizeof(buffer) ? sizeof(buffer) : size;
if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, rom ? 0x03 : 0x01);
snd_gf1_dram_addr(gus, address);
insb(GUSP(gus, DRAM), buffer, size1);
snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
address += size1;
} else {
pbuffer = buffer;
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index f167eb8d516b..3e6f35084f26 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -177,55 +177,36 @@ unsigned int snd_gf1_read_addr(struct snd_gus_card * gus,
void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
__snd_gf1_ctrl_stop(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
void snd_gf1_i_write8(struct snd_gus_card * gus,
unsigned char reg,
unsigned char data)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
__snd_gf1_write8(gus, reg, data);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg)
{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- res = __snd_gf1_look8(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
+ guard(spinlock_irqsave)(&gus->reg_lock);
+ return __snd_gf1_look8(gus, reg);
}
void snd_gf1_i_write16(struct snd_gus_card * gus,
unsigned char reg,
unsigned int data)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
__snd_gf1_write16(gus, reg, data);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg)
{
- unsigned long flags;
- unsigned short res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- res = __snd_gf1_look16(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
+ guard(spinlock_irqsave)(&gus->reg_lock);
+ return __snd_gf1_look16(gus, reg);
}
void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
@@ -242,9 +223,7 @@ void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
mb();
outw((unsigned short) addr, gus->gf1.reg_data16);
@@ -254,15 +233,11 @@ void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char da
outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
mb();
outb(data, gus->gf1.reg_dram);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
mb();
outw((unsigned short) addr, gus->gf1.reg_data16);
@@ -271,20 +246,16 @@ unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
mb();
outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
mb();
- res = inb(gus->gf1.reg_dram);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
+ return inb(gus->gf1.reg_dram);
}
#if 0
void snd_gf1_pokew(struct snd_gus_card * gus, unsigned int addr, unsigned short data)
{
- unsigned long flags;
-
if (!gus->interwave)
dev_dbg(gus->card->dev, "%s - GF1!!!\n", __func__);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
mb();
outw((unsigned short) addr, gus->gf1.reg_data16);
@@ -296,17 +267,13 @@ void snd_gf1_pokew(struct snd_gus_card * gus, unsigned int addr, unsigned short
outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
mb();
outw(data, gus->gf1.reg_data16);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
unsigned short snd_gf1_peekw(struct snd_gus_card * gus, unsigned int addr)
{
- unsigned long flags;
- unsigned short res;
-
if (!gus->interwave)
dev_dbg(gus->card->dev, "%s - GF1!!!\n", __func__);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
mb();
outw((unsigned short) addr, gus->gf1.reg_data16);
@@ -317,23 +284,20 @@ unsigned short snd_gf1_peekw(struct snd_gus_card * gus, unsigned int addr)
mb();
outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
mb();
- res = inw(gus->gf1.reg_data16);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
+ return inw(gus->gf1.reg_data16);
}
void snd_gf1_dram_setmem(struct snd_gus_card * gus, unsigned int addr,
unsigned short value, unsigned int count)
{
unsigned long port;
- unsigned long flags;
if (!gus->interwave)
dev_dbg(gus->card->dev, "%s - GF1!!!\n", __func__);
addr &= ~1;
count >>= 1;
port = GUSP(gus, GF1DATALOW);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
mb();
outw((unsigned short) addr, gus->gf1.reg_data16);
@@ -345,7 +309,6 @@ void snd_gf1_dram_setmem(struct snd_gus_card * gus, unsigned int addr,
outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
while (count--)
outw(value, port);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
#endif /* 0 */
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 873ef4046cd6..5f50a39c6f16 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -42,16 +42,14 @@ static int snd_gus_joystick_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
static int snd_gus_joystick_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned char nval;
nval = ucontrol->value.integer.value[0] & 31;
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
change = gus->joystick_dac != nval;
gus->joystick_dac = nval;
snd_gf1_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return change;
}
@@ -249,7 +247,6 @@ static int snd_gus_detect_memory(struct snd_gus_card * gus)
static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
{
struct snd_card *card;
- unsigned long flags;
int irq, dma1, dma2;
static const unsigned char irqs[16] =
{0, 0, 1, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
@@ -292,34 +289,34 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
card->mixer.mix_ctrl_reg |= 0x10;
#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(5, GUSP(gus, REGCNTRLS));
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(0x00, GUSP(gus, IRQDMACNTRLREG));
- outb(0, GUSP(gus, REGCNTRLS));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(5, GUSP(gus, REGCNTRLS));
+ outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(0x00, GUSP(gus, IRQDMACNTRLREG));
+ outb(0, GUSP(gus, REGCNTRLS));
+ }
udelay(100);
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(dma1, GUSP(gus, IRQDMACNTRLREG));
- if (latches) {
- outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(irq, GUSP(gus, IRQDMACNTRLREG));
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(dma1, GUSP(gus, IRQDMACNTRLREG));
+ if (latches) {
+ outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(irq, GUSP(gus, IRQDMACNTRLREG));
+ }
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
udelay(100);
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(dma1, GUSP(gus, IRQDMACNTRLREG));
- if (latches) {
- outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(irq, GUSP(gus, IRQDMACNTRLREG));
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(dma1, GUSP(gus, IRQDMACNTRLREG));
+ if (latches) {
+ outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(irq, GUSP(gus, IRQDMACNTRLREG));
+ }
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
snd_gf1_delay(gus);
@@ -327,26 +324,25 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
gus->mix_cntrl_reg |= 0x08; /* enable latches */
else
gus->mix_cntrl_reg &= ~0x08; /* disable latches */
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(0, GUSP(gus, GF1PAGE));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ outb(0, GUSP(gus, GF1PAGE));
+ }
return 0;
}
static int snd_gus_check_version(struct snd_gus_card * gus)
{
- unsigned long flags;
unsigned char val, rev;
struct snd_card *card;
card = gus->card;
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x20, GUSP(gus, REGCNTRLS));
- val = inb(GUSP(gus, REGCNTRLS));
- rev = inb(GUSP(gus, BOARDVERSION));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(0x20, GUSP(gus, REGCNTRLS));
+ val = inb(GUSP(gus, REGCNTRLS));
+ rev = inb(GUSP(gus, BOARDVERSION));
+ }
dev_dbg(card->dev, "GF1 [0x%lx] init - val = 0x%x, rev = 0x%x\n", gus->gf1.port, val, rev);
strscpy(card->driver, "GUS");
strscpy(card->longname, "Gravis UltraSound Classic (2.4)");
@@ -447,4 +443,3 @@ EXPORT_SYMBOL(snd_gf1_translate_freq);
EXPORT_SYMBOL(snd_gf1_mem_alloc);
EXPORT_SYMBOL(snd_gf1_mem_xfree);
EXPORT_SYMBOL(snd_gf1_mem_free);
-EXPORT_SYMBOL(snd_gf1_mem_lock);
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 054058779db6..8d95d8d5abdf 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -15,15 +15,6 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer);
#endif
-void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
-{
- if (!xup) {
- mutex_lock(&alloc->memory_mutex);
- } else {
- mutex_unlock(&alloc->memory_mutex);
- }
-}
-
static struct snd_gf1_mem_block *
snd_gf1_mem_xalloc(struct snd_gf1_mem *alloc, struct snd_gf1_mem_block *block,
const char *name)
@@ -50,7 +41,6 @@ snd_gf1_mem_xalloc(struct snd_gf1_mem *alloc, struct snd_gf1_mem_block *block,
alloc->first = nblock;
else
nblock->prev->next = nblock;
- mutex_unlock(&alloc->memory_mutex);
return nblock;
}
pblock = pblock->next;
@@ -71,7 +61,6 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo
{
if (block->share) { /* ok.. shared block */
block->share--;
- mutex_unlock(&alloc->memory_mutex);
return 0;
}
if (alloc->first == block) {
@@ -183,7 +172,7 @@ struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owne
{
struct snd_gf1_mem_block block, *nblock;
- snd_gf1_mem_lock(alloc, 0);
+ guard(mutex)(&alloc->memory_mutex);
if (share_id != NULL) {
nblock = snd_gf1_mem_share(alloc, share_id);
if (nblock != NULL) {
@@ -193,36 +182,27 @@ struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owne
goto __std;
}
nblock->share++;
- snd_gf1_mem_lock(alloc, 1);
return NULL;
}
}
__std:
- if (snd_gf1_mem_find(alloc, &block, size, w_16, align) < 0) {
- snd_gf1_mem_lock(alloc, 1);
+ if (snd_gf1_mem_find(alloc, &block, size, w_16, align) < 0)
return NULL;
- }
if (share_id != NULL)
memcpy(&block.share_id, share_id, sizeof(block.share_id));
block.owner = owner;
nblock = snd_gf1_mem_xalloc(alloc, &block, name);
- snd_gf1_mem_lock(alloc, 1);
return nblock;
}
int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address)
{
- int result;
struct snd_gf1_mem_block *block;
- snd_gf1_mem_lock(alloc, 0);
+ guard(mutex)(&alloc->memory_mutex);
block = snd_gf1_mem_look(alloc, address);
- if (block) {
- result = snd_gf1_mem_xfree(alloc, block);
- snd_gf1_mem_lock(alloc, 1);
- return result;
- }
- snd_gf1_mem_lock(alloc, 1);
+ if (block)
+ return snd_gf1_mem_xfree(alloc, block);
return -EINVAL;
}
@@ -282,7 +262,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
gus = entry->private_data;
alloc = &gus->gf1.mem_alloc;
- mutex_lock(&alloc->memory_mutex);
+ guard(mutex)(&alloc->memory_mutex);
snd_iprintf(buffer, "8-bit banks : \n ");
for (i = 0; i < 4; i++)
snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : "");
@@ -326,7 +306,6 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
}
snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n",
total, used, total - used);
- mutex_unlock(&alloc->memory_mutex);
#if 0
ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n",
ultra_memory_free_size(card, &card->gf1.mem_alloc),
diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
index 60c3a8219770..9bfdb4e45a5d 100644
--- a/sound/isa/gus/gus_mixer.c
+++ b/sound/isa/gus/gus_mixer.c
@@ -37,7 +37,6 @@ static int snd_gf1_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
static int snd_gf1_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int shift = kcontrol->private_value & 0xff;
int invert = (kcontrol->private_value >> 8) & 1;
int change;
@@ -47,13 +46,12 @@ static int snd_gf1_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
if (invert)
nval ^= 1;
nval <<= shift;
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
oval = gus->mix_cntrl_reg;
nval = (oval & ~(1 << shift)) | nval;
change = nval != oval;
outb(gus->mix_cntrl_reg = nval, GUSP(gus, MIXCNTRLREG));
outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return change;
}
@@ -75,14 +73,12 @@ static int snd_ics_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
static int snd_ics_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int addr = kcontrol->private_value & 0xff;
unsigned char left, right;
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
left = gus->gf1.ics_regs[addr][0];
right = gus->gf1.ics_regs[addr][1];
- spin_unlock_irqrestore(&gus->reg_lock, flags);
ucontrol->value.integer.value[0] = left & 127;
ucontrol->value.integer.value[1] = right & 127;
return 0;
@@ -91,14 +87,13 @@ static int snd_ics_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
static int snd_ics_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int addr = kcontrol->private_value & 0xff;
int change;
unsigned char val1, val2, oval1, oval2;
val1 = ucontrol->value.integer.value[0] & 127;
val2 = ucontrol->value.integer.value[1] & 127;
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
oval1 = gus->gf1.ics_regs[addr][0];
oval2 = gus->gf1.ics_regs[addr][1];
change = val1 != oval1 || val2 != oval2;
@@ -116,7 +111,6 @@ static int snd_ics_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
outb(2, GUSP(gus, MIXDATAPORT));
outb(addr | 3, GUSP(gus, MIXCNTRLPORT));
outb((unsigned char) val2, GUSP(gus, MIXDATAPORT));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return change;
}
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 8b9b7b8d92b2..9249cbff30f3 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -89,7 +89,6 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct gus_pcm_private *pcmp = runtime->private_data;
struct snd_gus_card * gus = pcmp->gus;
- unsigned long flags;
unsigned char voice_ctrl, ramp_ctrl;
unsigned short rate;
unsigned int curr, begin, end;
@@ -97,14 +96,12 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
unsigned char pan;
unsigned int voice;
- spin_lock_irqsave(&pcmp->lock, flags);
- if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) {
- spin_unlock_irqrestore(&pcmp->lock, flags);
- return;
+ scoped_guard(spinlock_irqsave, &pcmp->lock) {
+ if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE)
+ return;
+ pcmp->flags |= SNDRV_GF1_PCM_PFLG_ACTIVE;
+ pcmp->final_volume = 0;
}
- pcmp->flags |= SNDRV_GF1_PCM_PFLG_ACTIVE;
- pcmp->final_volume = 0;
- spin_unlock_irqrestore(&pcmp->lock, flags);
rate = snd_gf1_translate_freq(gus, runtime->rate << 4);
/* enable WAVE IRQ */
voice_ctrl = snd_pcm_format_width(runtime->format) == 16 ? 0x24 : 0x20;
@@ -121,7 +118,7 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1;
pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8;
vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, pan);
snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, rate);
@@ -137,9 +134,9 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
snd_gf1_delay(gus);
snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
- spin_lock_irqsave(&gus->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&gus->reg_lock);
for (voice = 0; voice < pcmp->voices; voice++) {
snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
if (gus->gf1.enh_mode)
@@ -156,7 +153,6 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
voice_ctrl &= ~0x20; /* disable IRQ for next voice */
}
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,
@@ -182,52 +178,52 @@ static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,
gus = pcmp->gus;
runtime = pcmp->substream->runtime;
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & ~0x8b;
- ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03;
+ scoped_guard(spinlock, &gus->reg_lock) {
+ snd_gf1_select_voice(gus, pvoice->number);
+ voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & ~0x8b;
+ ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03;
#if 0
- snd_gf1_select_voice(gus, pvoice->number);
- dev_dbg(gus->card->dev, "position = 0x%x\n",
- (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
- snd_gf1_select_voice(gus, pcmp->pvoices[1]->number);
- dev_dbg(gus->card->dev, "position = 0x%x\n",
- (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
- snd_gf1_select_voice(gus, pvoice->number);
+ snd_gf1_select_voice(gus, pvoice->number);
+ dev_dbg(gus->card->dev, "position = 0x%x\n",
+ (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
+ snd_gf1_select_voice(gus, pcmp->pvoices[1]->number);
+ dev_dbg(gus->card->dev, "position = 0x%x\n",
+ (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
+ snd_gf1_select_voice(gus, pvoice->number);
#endif
- pcmp->bpos++;
- pcmp->bpos %= pcmp->blocks;
- if (pcmp->bpos + 1 >= pcmp->blocks) { /* last block? */
- voice_ctrl |= 0x08; /* enable loop */
- } else {
- ramp_ctrl |= 0x04; /* enable rollover */
- }
- end = pcmp->memory + (((pcmp->bpos + 1) * pcmp->block_size) / runtime->channels);
- end -= voice_ctrl & 4 ? 2 : 1;
- step = pcmp->dma_size / runtime->channels;
- voice_ctrl |= 0x20;
- if (!pcmp->final_volume) {
- ramp_ctrl |= 0x20;
- ramp_ctrl &= ~0x03;
- }
- for (idx = 0; idx < pcmp->voices; idx++, end += step) {
- snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
- snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
- voice_ctrl &= ~0x20;
- }
- if (!gus->gf1.enh_mode) {
- snd_gf1_delay(gus);
+ pcmp->bpos++;
+ pcmp->bpos %= pcmp->blocks;
+ if (pcmp->bpos + 1 >= pcmp->blocks) { /* last block? */
+ voice_ctrl |= 0x08; /* enable loop */
+ } else {
+ ramp_ctrl |= 0x04; /* enable rollover */
+ }
+ end = pcmp->memory + (((pcmp->bpos + 1) * pcmp->block_size) / runtime->channels);
+ end -= voice_ctrl & 4 ? 2 : 1;
+ step = pcmp->dma_size / runtime->channels;
voice_ctrl |= 0x20;
- for (idx = 0; idx < pcmp->voices; idx++) {
+ if (!pcmp->final_volume) {
+ ramp_ctrl |= 0x20;
+ ramp_ctrl &= ~0x03;
+ }
+ for (idx = 0; idx < pcmp->voices; idx++, end += step) {
snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
+ snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
voice_ctrl &= ~0x20;
}
+ if (!gus->gf1.enh_mode) {
+ snd_gf1_delay(gus);
+ voice_ctrl |= 0x20;
+ for (idx = 0; idx < pcmp->voices; idx++) {
+ snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
+ snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
+ snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
+ voice_ctrl &= ~0x20;
+ }
+ }
}
- spin_unlock(&gus->reg_lock);
snd_pcm_period_elapsed(pcmp->substream);
#if 0
@@ -252,10 +248,10 @@ static void snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,
struct gus_pcm_private *pcmp = pvoice->private_data;
/* stop ramp, but leave rollover bit untouched */
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- spin_unlock(&gus->reg_lock);
+ scoped_guard(spinlock, &gus->reg_lock) {
+ snd_gf1_select_voice(gus, pvoice->number);
+ snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
+ }
if (pcmp == NULL)
return;
/* are we active? */
@@ -266,11 +262,10 @@ static void snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,
if (pcmp->substream == NULL)
return;
vol = !cvoice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- spin_lock(&gus->reg_lock);
+ guard(spinlock)(&gus->reg_lock);
snd_gf1_select_voice(gus, pvoice->number);
snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
pcmp->final_volume = 1;
- spin_unlock(&gus->reg_lock);
}
static void snd_gf1_pcm_volume_change(struct snd_gus_card * gus)
@@ -282,7 +277,6 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
int w16, int invert)
{
unsigned int len;
- unsigned long flags;
while (count > 0) {
len = count;
@@ -290,7 +284,7 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
len = 512;
count -= len;
if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01 | (invert ? 0x08 : 0x00));
snd_gf1_dram_addr(gus, pos);
if (w16) {
@@ -299,7 +293,6 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
} else {
outsb(GUSP(gus, DRAM), buf, len);
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
buf += 512;
pos += 512;
} else {
@@ -479,9 +472,9 @@ static int snd_gf1_pcm_playback_trigger(struct snd_pcm_substream *substream,
if (cmd == SNDRV_PCM_TRIGGER_START) {
snd_gf1_pcm_trigger_up(substream);
} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- spin_lock(&pcmp->lock);
- pcmp->flags &= ~SNDRV_GF1_PCM_PFLG_ACTIVE;
- spin_unlock(&pcmp->lock);
+ scoped_guard(spinlock, &pcmp->lock) {
+ pcmp->flags &= ~SNDRV_GF1_PCM_PFLG_ACTIVE;
+ }
voice = pcmp->pvoices[0]->number;
snd_gf1_stop_voices(gus, voice, voice);
if (pcmp->pvoices[1]) {
@@ -503,7 +496,7 @@ static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream *
unsigned char voice_ctrl;
pos = 0;
- spin_lock(&gus->reg_lock);
+ guard(spinlock)(&gus->reg_lock);
if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) {
snd_gf1_select_voice(gus, pcmp->pvoices[0]->number);
voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
@@ -512,7 +505,6 @@ static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream *
pos <<= 1;
pos = bytes_to_frames(runtime, pos);
}
- spin_unlock(&gus->reg_lock);
return pos;
}
@@ -572,10 +564,9 @@ static int snd_gf1_pcm_capture_trigger(struct snd_pcm_substream *substream,
return -EINVAL;
}
- spin_lock(&gus->reg_lock);
+ guard(spinlock)(&gus->reg_lock);
snd_gf1_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, val);
snd_gf1_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL);
- spin_unlock(&gus->reg_lock);
return 0;
}
@@ -724,19 +715,16 @@ static int snd_gf1_pcm_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl
static int snd_gf1_pcm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&gus->pcm_volume_level_lock, flags);
+ guard(spinlock_irqsave)(&gus->pcm_volume_level_lock);
ucontrol->value.integer.value[0] = gus->gf1.pcm_volume_level_left1;
ucontrol->value.integer.value[1] = gus->gf1.pcm_volume_level_right1;
- spin_unlock_irqrestore(&gus->pcm_volume_level_lock, flags);
return 0;
}
static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned int idx;
unsigned short val1, val2, vol;
@@ -745,33 +733,32 @@ static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
val1 = ucontrol->value.integer.value[0] & 127;
val2 = ucontrol->value.integer.value[1] & 127;
- spin_lock_irqsave(&gus->pcm_volume_level_lock, flags);
- change = val1 != gus->gf1.pcm_volume_level_left1 ||
- val2 != gus->gf1.pcm_volume_level_right1;
- gus->gf1.pcm_volume_level_left1 = val1;
- gus->gf1.pcm_volume_level_right1 = val2;
- gus->gf1.pcm_volume_level_left = snd_gf1_lvol_to_gvol_raw(val1 << 9) << 4;
- gus->gf1.pcm_volume_level_right = snd_gf1_lvol_to_gvol_raw(val2 << 9) << 4;
- spin_unlock_irqrestore(&gus->pcm_volume_level_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->pcm_volume_level_lock) {
+ change = val1 != gus->gf1.pcm_volume_level_left1 ||
+ val2 != gus->gf1.pcm_volume_level_right1;
+ gus->gf1.pcm_volume_level_left1 = val1;
+ gus->gf1.pcm_volume_level_right1 = val2;
+ gus->gf1.pcm_volume_level_left = snd_gf1_lvol_to_gvol_raw(val1 << 9) << 4;
+ gus->gf1.pcm_volume_level_right = snd_gf1_lvol_to_gvol_raw(val2 << 9) << 4;
+ }
/* are we active? */
- spin_lock_irqsave(&gus->voice_alloc, flags);
- for (idx = 0; idx < 32; idx++) {
- pvoice = &gus->gf1.voices[idx];
- if (!pvoice->pcm)
- continue;
- pcmp = pvoice->private_data;
- if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
- continue;
- /* load real volume - better precision */
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
- pcmp->final_volume = 1;
- spin_unlock(&gus->reg_lock);
+ scoped_guard(spinlock_irqsave, &gus->voice_alloc) {
+ for (idx = 0; idx < 32; idx++) {
+ pvoice = &gus->gf1.voices[idx];
+ if (!pvoice->pcm)
+ continue;
+ pcmp = pvoice->private_data;
+ if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
+ continue;
+ /* load real volume - better precision */
+ guard(spinlock)(&gus->reg_lock);
+ snd_gf1_select_voice(gus, pvoice->number);
+ snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
+ vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
+ snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
+ pcmp->final_volume = 1;
+ }
}
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
return change;
}
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index 326bc6028885..5cbace8369f8 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -83,26 +83,20 @@ void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what)
static void snd_gf1_clear_regs(struct snd_gus_card * gus)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
inb(GUSP(gus, IRQSTAT));
snd_gf1_write8(gus, 0x41, 0); /* DRAM DMA Control Register */
snd_gf1_write8(gus, 0x45, 0); /* Timer Control */
snd_gf1_write8(gus, 0x49, 0); /* Sampling Control Register */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
static void snd_gf1_look_regs(struct snd_gus_card * gus)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_look8(gus, 0x41); /* DRAM DMA Control Register */
snd_gf1_look8(gus, 0x49); /* Sampling Control Register */
inb(GUSP(gus, IRQSTAT));
snd_gf1_read8(gus, 0x0f); /* IRQ Source Register */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
/*
@@ -111,9 +105,7 @@ static void snd_gf1_look_regs(struct snd_gus_card * gus)
void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_select_voice(gus, voice);
#if 0
dev_dbg(gus->card->dev,
@@ -122,14 +114,11 @@ void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice)
#endif
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice)
{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_select_voice(gus, voice);
#if 0
dev_dbg(gus->card->dev,
@@ -140,13 +129,11 @@ void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice)
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
if (gus->gf1.enh_mode)
snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, 0);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min,
unsigned short v_max)
{
- unsigned long flags;
unsigned int daddr;
unsigned short i, w_16;
@@ -156,7 +143,7 @@ static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min
if (gus->gf1.syn_voices)
gus->gf1.syn_voices[i].flags = ~VFLG_DYNAMIC;
#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_select_voice(gus, i);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); /* Voice Control Register = voice stop */
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); /* Volume Ramp Control Register = ramp off */
@@ -177,19 +164,17 @@ static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min
snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, 0);
snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, 0);
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
}
void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max)
{
- unsigned long flags;
short i, ramp_ok;
unsigned short ramp_end;
if (!in_interrupt()) { /* this can't be done in interrupt */
for (i = v_min, ramp_ok = 0; i <= v_max; i++) {
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
snd_gf1_select_voice(gus, i);
ramp_end = snd_gf1_read16(gus, 9) >> 8;
if (ramp_end > SNDRV_GF1_MIN_OFFSET) {
@@ -203,7 +188,6 @@ void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsign
snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, 0x40);
}
}
- spin_unlock_irqrestore(&gus->reg_lock, flags);
}
msleep_interruptible(50);
}
@@ -236,21 +220,17 @@ static void snd_gf1_alloc_voice_use(struct snd_gus_card * gus,
struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port)
{
struct snd_gus_voice *pvoice;
- unsigned long flags;
int idx;
- spin_lock_irqsave(&gus->voice_alloc, flags);
+ guard(spinlock_irqsave)(&gus->voice_alloc);
if (type == SNDRV_GF1_VOICE_TYPE_PCM) {
- if (gus->gf1.pcm_alloc_voices >= gus->gf1.pcm_channels) {
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
+ if (gus->gf1.pcm_alloc_voices >= gus->gf1.pcm_channels)
return NULL;
- }
}
for (idx = 0; idx < 32; idx++) {
pvoice = &gus->gf1.voices[idx];
if (!pvoice->use) {
snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
return pvoice;
}
}
@@ -259,32 +239,29 @@ struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, i
if (pvoice->midi && !pvoice->client) {
snd_gf1_clear_voices(gus, pvoice->number, pvoice->number);
snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
return pvoice;
}
}
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
return NULL;
}
void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
{
- unsigned long flags;
void (*private_free)(struct snd_gus_voice *voice);
if (voice == NULL || !voice->use)
return;
snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_VOICE | voice->number);
snd_gf1_clear_voices(gus, voice->number, voice->number);
- spin_lock_irqsave(&gus->voice_alloc, flags);
- private_free = voice->private_free;
- voice->private_free = NULL;
- voice->private_data = NULL;
- if (voice->pcm)
- gus->gf1.pcm_alloc_voices--;
- voice->use = voice->pcm = 0;
- voice->sample_ops = NULL;
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
+ scoped_guard(spinlock_irqsave, &gus->voice_alloc) {
+ private_free = voice->private_free;
+ voice->private_free = NULL;
+ voice->private_data = NULL;
+ if (voice->pcm)
+ gus->gf1.pcm_alloc_voices--;
+ voice->use = voice->pcm = 0;
+ voice->sample_ops = NULL;
+ }
if (private_free)
private_free(voice);
}
@@ -295,7 +272,6 @@ void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
int snd_gf1_start(struct snd_gus_card * gus)
{
- unsigned long flags;
unsigned int i;
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
@@ -344,10 +320,10 @@ int snd_gf1_start(struct snd_gus_card * gus)
}
while ((snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ) & 0xc0) != 0xc0);
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
+ outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
+ }
snd_gf1_timers_init(gus);
snd_gf1_look_regs(gus);
diff --git a/sound/isa/gus/gus_timer.c b/sound/isa/gus/gus_timer.c
index 7267fb5bf8e5..e3a8847e02cf 100644
--- a/sound/isa/gus/gus_timer.c
+++ b/sound/isa/gus/gus_timer.c
@@ -16,33 +16,29 @@
static int snd_gf1_timer1_start(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
unsigned int ticks;
struct snd_gus_card *gus;
gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
ticks = timer->sticks;
tmp = (gus->gf1.timer_enabled |= 4);
snd_gf1_write8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1, 256 - ticks); /* timer 1 count */
snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* enable timer 1 IRQ */
snd_gf1_adlib_write(gus, 0x04, tmp >> 2); /* timer 2 start */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return 0;
}
static int snd_gf1_timer1_stop(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
struct snd_gus_card *gus;
gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
tmp = (gus->gf1.timer_enabled &= ~4);
snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return 0;
}
@@ -52,33 +48,29 @@ static int snd_gf1_timer1_stop(struct snd_timer * timer)
static int snd_gf1_timer2_start(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
unsigned int ticks;
struct snd_gus_card *gus;
gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
ticks = timer->sticks;
tmp = (gus->gf1.timer_enabled |= 8);
snd_gf1_write8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2, 256 - ticks); /* timer 2 count */
snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* enable timer 2 IRQ */
snd_gf1_adlib_write(gus, 0x04, tmp >> 2); /* timer 2 start */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return 0;
}
static int snd_gf1_timer2_stop(struct snd_timer * timer)
{
- unsigned long flags;
unsigned char tmp;
struct snd_gus_card *gus;
gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
+ guard(spinlock_irqsave)(&gus->reg_lock);
tmp = (gus->gf1.timer_enabled &= ~8);
snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
return 0;
}
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index e207f274f240..770d8f3e4cff 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -49,13 +49,12 @@ static void snd_gf1_interrupt_midi_in(struct snd_gus_card * gus)
static void snd_gf1_interrupt_midi_out(struct snd_gus_card * gus)
{
char byte;
- unsigned long flags;
/* try unlock output */
if (snd_gf1_uart_stat(gus) & 0x01)
snd_gf1_interrupt_midi_in(gus);
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (snd_gf1_uart_stat(gus) & 0x02) { /* Tx FIFO free? */
if (snd_rawmidi_transmit(gus->midi_substream_output, &byte, 1) != 1) { /* no other bytes or error */
snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x20); /* disable Tx interrupt */
@@ -63,7 +62,6 @@ static void snd_gf1_interrupt_midi_out(struct snd_gus_card * gus)
snd_gf1_uart_put(gus, byte);
}
}
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
}
static void snd_gf1_uart_reset(struct snd_gus_card * gus, int close)
@@ -77,17 +75,15 @@ static void snd_gf1_uart_reset(struct snd_gus_card * gus, int close)
static int snd_gf1_uart_output_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_gus_card *gus;
gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (!(gus->gf1.uart_cmd & 0x80)) { /* input active? */
snd_gf1_uart_reset(gus, 0);
}
gus->gf1.interrupt_handler_midi_out = snd_gf1_interrupt_midi_out;
gus->midi_substream_output = substream;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0
dev_dbg(gus->card->dev,
"write init - cmd = 0x%x, stat = 0x%x\n",
@@ -98,12 +94,11 @@ static int snd_gf1_uart_output_open(struct snd_rawmidi_substream *substream)
static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_gus_card *gus;
int i;
gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (gus->gf1.interrupt_handler_midi_out != snd_gf1_interrupt_midi_out) {
snd_gf1_uart_reset(gus, 0);
}
@@ -115,7 +110,6 @@ static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream)
if (i >= 1000)
dev_err(gus->card->dev, "gus midi uart init read - cleanup error\n");
}
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0
dev_dbg(gus->card->dev,
"read init - enable = %i, cmd = 0x%x, stat = 0x%x\n",
@@ -130,42 +124,37 @@ static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream)
static int snd_gf1_uart_output_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_gus_card *gus;
gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (gus->gf1.interrupt_handler_midi_in != snd_gf1_interrupt_midi_in)
snd_gf1_uart_reset(gus, 1);
snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_MIDI_OUT);
gus->midi_substream_output = NULL;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
return 0;
}
static int snd_gf1_uart_input_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_gus_card *gus;
gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (gus->gf1.interrupt_handler_midi_out != snd_gf1_interrupt_midi_out)
snd_gf1_uart_reset(gus, 1);
snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_MIDI_IN);
gus->midi_substream_input = NULL;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
return 0;
}
static void snd_gf1_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct snd_gus_card *gus;
- unsigned long flags;
gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
+ guard(spinlock_irqsave)(&gus->uart_cmd_lock);
if (up) {
if ((gus->gf1.uart_cmd & 0x80) == 0)
snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd | 0x80); /* enable Rx interrupts */
@@ -173,7 +162,6 @@ static void snd_gf1_uart_input_trigger(struct snd_rawmidi_substream *substream,
if (gus->gf1.uart_cmd & 0x80)
snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x80); /* disable Rx interrupts */
}
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
}
static void snd_gf1_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 28827a2e6cbd..ed921b89b00a 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -145,7 +145,6 @@ static int snd_gusextreme_gus_card_create(struct snd_card *card,
static int snd_gusextreme_detect(struct snd_gus_card *gus,
struct snd_es1688 *es1688)
{
- unsigned long flags;
unsigned char d;
/*
@@ -162,17 +161,17 @@ static int snd_gusextreme_detect(struct snd_gus_card *gus,
* 0x260 = 2,2,1
*/
- spin_lock_irqsave(&es1688->mixer_lock, flags);
- snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */
- spin_unlock_irqrestore(&es1688->mixer_lock, flags);
-
- spin_lock_irqsave(&es1688->reg_lock, flags);
- outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
- outb(0, 0x201);
- outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
- outb(0, 0x201);
- outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
- spin_unlock_irqrestore(&es1688->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &es1688->mixer_lock) {
+ snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */
+ }
+
+ scoped_guard(spinlock_irqsave, &es1688->reg_lock) {
+ outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
+ outb(0, 0x201);
+ outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
+ outb(0, 0x201);
+ outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
+ }
udelay(100);
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 0e0bcd85a648..18adcd35e117 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -239,7 +239,6 @@ static int snd_interwave_detect(struct snd_interwave *iwcard,
#endif
)
{
- unsigned long flags;
unsigned char rev1, rev2;
int d;
@@ -257,12 +256,12 @@ static int snd_interwave_detect(struct snd_interwave *iwcard,
dev_dbg(gus->card->dev, "[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
- spin_lock_irqsave(&gus->reg_lock, flags);
- rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
- rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
+ rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);
+ }
dev_dbg(gus->card->dev,
"[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n",
gus->gf1.port, rev1, rev2);
@@ -457,18 +456,16 @@ static void snd_interwave_detect_memory(struct snd_gus_card *gus)
static void snd_interwave_init(int dev, struct snd_gus_card *gus)
{
- unsigned long flags;
-
/* ok.. some InterWave specific initialization */
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);
- snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);
- snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);
- snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &gus->reg_lock) {
+ snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);
+ snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);
+ }
gus->equal_irq = 1;
gus->codec_flag = 1;
gus->interwave = 1;
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c
index 8c1d2e27854b..5e350234d572 100644
--- a/sound/isa/msnd/msnd.c
+++ b/sound/isa/msnd/msnd.c
@@ -76,15 +76,11 @@ static int snd_msnd_wait_HC0(struct snd_msnd *dev)
int snd_msnd_send_dsp_cmd(struct snd_msnd *dev, u8 cmd)
{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
+ guard(spinlock_irqsave)(&dev->lock);
if (snd_msnd_wait_HC0(dev) == 0) {
outb(cmd, dev->io + HP_CVR);
- spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
- spin_unlock_irqrestore(&dev->lock, flags);
dev_dbg(dev->card->dev, LOGNAME ": Send DSP command timeout\n");
@@ -133,14 +129,12 @@ EXPORT_SYMBOL(snd_msnd_upload_host);
int snd_msnd_enable_irq(struct snd_msnd *dev)
{
- unsigned long flags;
-
if (dev->irq_ref++)
return 0;
dev_dbg(dev->card->dev, LOGNAME ": Enabling IRQ\n");
- spin_lock_irqsave(&dev->lock, flags);
+ guard(spinlock_irqsave)(&dev->lock);
if (snd_msnd_wait_TXDE(dev) == 0) {
outb(inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR);
if (dev->type == msndClassic)
@@ -151,10 +145,8 @@ int snd_msnd_enable_irq(struct snd_msnd *dev)
enable_irq(dev->irq);
snd_msnd_init_queue(dev->DSPQ, dev->dspq_data_buff,
dev->dspq_buff_size);
- spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
- spin_unlock_irqrestore(&dev->lock, flags);
dev_dbg(dev->card->dev, LOGNAME ": Enable IRQ failed\n");
@@ -164,8 +156,6 @@ EXPORT_SYMBOL(snd_msnd_enable_irq);
int snd_msnd_disable_irq(struct snd_msnd *dev)
{
- unsigned long flags;
-
if (--dev->irq_ref > 0)
return 0;
@@ -175,16 +165,14 @@ int snd_msnd_disable_irq(struct snd_msnd *dev)
dev_dbg(dev->card->dev, LOGNAME ": Disabling IRQ\n");
- spin_lock_irqsave(&dev->lock, flags);
+ guard(spinlock_irqsave)(&dev->lock);
if (snd_msnd_wait_TXDE(dev) == 0) {
outb(inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR);
if (dev->type == msndClassic)
outb(HPIRQ_NONE, dev->io + HP_IRQM);
disable_irq(dev->irq);
- spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
- spin_unlock_irqrestore(&dev->lock, flags);
dev_dbg(dev->card->dev, LOGNAME ": Disable IRQ failed\n");
@@ -376,7 +364,6 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
{
int n;
void __iomem *pDAQ;
- /* unsigned long flags; */
/* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */
@@ -388,11 +375,11 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
chip->DARQ + JQS_wTail);
#if 0 /* Critical section: bank 1 access. this is how the OSS driver does it:*/
- spin_lock_irqsave(&chip->lock, flags);
- outb(HPBLKSEL_1, chip->io + HP_BLKS);
- memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3);
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ outb(HPBLKSEL_1, chip->io + HP_BLKS);
+ memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3);
+ outb(HPBLKSEL_0, chip->io + HP_BLKS);
+ }
#endif
chip->capturePeriodBytes = pcm_count;
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 969bbb18657b..c4eec391cd29 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -300,7 +300,6 @@ static int snd_msnd_init_sma(struct snd_msnd *chip)
{
static int initted;
u16 mastVolLeft, mastVolRight;
- unsigned long flags;
#ifdef MSND_CLASSIC
outb(chip->memid, chip->io + HP_MEMM);
@@ -317,11 +316,11 @@ static int snd_msnd_init_sma(struct snd_msnd *chip)
memset_io(chip->mappedbase, 0, 0x8000);
/* Critical section: bank 1 access */
- spin_lock_irqsave(&chip->lock, flags);
- outb(HPBLKSEL_1, chip->io + HP_BLKS);
- memset_io(chip->mappedbase, 0, 0x8000);
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ outb(HPBLKSEL_1, chip->io + HP_BLKS);
+ memset_io(chip->mappedbase, 0, 0x8000);
+ outb(HPBLKSEL_0, chip->io + HP_BLKS);
+ }
/* Digital audio play queue */
chip->DAPQ = chip->mappedbase + DAPQ_OFFSET;
diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c
index 2f1bb5a2b376..ec354483b9f8 100644
--- a/sound/isa/msnd/msnd_pinnacle_mixer.c
+++ b/sound/isa/msnd/msnd_pinnacle_mixer.c
@@ -136,14 +136,12 @@ static int snd_msndmix_volume_get(struct snd_kcontrol *kcontrol,
{
struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
- unsigned long flags;
- spin_lock_irqsave(&msnd->mixer_lock, flags);
+ guard(spinlock_irqsave)(&msnd->mixer_lock);
ucontrol->value.integer.value[0] = msnd->left_levels[addr] * 100;
ucontrol->value.integer.value[0] /= 0xFFFF;
ucontrol->value.integer.value[1] = msnd->right_levels[addr] * 100;
ucontrol->value.integer.value[1] /= 0xFFFF;
- spin_unlock_irqrestore(&msnd->mixer_lock, flags);
return 0;
}
@@ -253,15 +251,13 @@ static int snd_msndmix_volume_put(struct snd_kcontrol *kcontrol,
struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol);
int change, addr = kcontrol->private_value;
int left, right;
- unsigned long flags;
left = ucontrol->value.integer.value[0] % 101;
right = ucontrol->value.integer.value[1] % 101;
- spin_lock_irqsave(&msnd->mixer_lock, flags);
+ guard(spinlock_irqsave)(&msnd->mixer_lock);
change = msnd->left_levels[addr] != left
|| msnd->right_levels[addr] != right;
snd_msndmix_set(msnd, addr, left, right);
- spin_unlock_irqrestore(&msnd->mixer_lock, flags);
return change;
}
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 5e8e1326d5c0..8c1767697b62 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -172,13 +172,8 @@ static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char
/* read control port (with spinlock) */
static unsigned char snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
{
- unsigned long flags;
- unsigned char result;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- result = __snd_opl3sa2_read(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
+ guard(spinlock_irqsave)(&chip->reg_lock);
+ return __snd_opl3sa2_read(chip, reg);
}
/* write control port (w/o spinlock) */
@@ -195,10 +190,8 @@ static void __snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, uns
/* write control port (with spinlock) */
static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
__snd_opl3sa2_write(chip, reg, value);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static int snd_opl3sa2_detect(struct snd_card *card)
@@ -336,15 +329,13 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->ctlregs[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -353,7 +344,6 @@ static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -365,12 +355,11 @@ static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
oval = chip->ctlregs[reg];
val = (oval & ~(mask << shift)) | val;
change = val != oval;
__snd_opl3sa2_write(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -391,7 +380,6 @@ static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -399,10 +387,9 @@ static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->ctlregs[left_reg] >> shift_left) & mask;
ucontrol->value.integer.value[1] = (chip->ctlregs[right_reg] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -413,7 +400,6 @@ static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -431,7 +417,7 @@ static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (left_reg != right_reg) {
oval1 = chip->ctlregs[left_reg];
oval2 = chip->ctlregs[right_reg];
@@ -446,7 +432,6 @@ static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
change = val1 != oval1;
__snd_opl3sa2_write(chip, left_reg, val1);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index ad7180d7c0c2..c320af3e9a05 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -822,10 +822,9 @@ static int snd_miro_init(struct snd_miro *chip,
static unsigned char snd_miro_read(struct snd_miro *chip,
unsigned char reg)
{
- unsigned long flags;
unsigned char retval = 0xff;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
outb(chip->password, chip->mc_base + chip->pwd_reg);
switch (chip->hardware) {
@@ -846,16 +845,13 @@ static unsigned char snd_miro_read(struct snd_miro *chip,
dev_err(chip->card->dev, "sorry, no support for %d\n", chip->hardware);
}
- spin_unlock_irqrestore(&chip->lock, flags);
return retval;
}
static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
unsigned char value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
outb(chip->password, chip->mc_base + chip->pwd_reg);
switch (chip->hardware) {
@@ -875,8 +871,6 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
default:
dev_err(chip->card->dev, "sorry, no support for %d\n", chip->hardware);
}
-
- spin_unlock_irqrestore(&chip->lock, flags);
}
static inline void snd_miro_write_mask(struct snd_miro *chip,
@@ -1013,7 +1007,6 @@ static int snd_miro_configure(struct snd_miro *chip)
unsigned char dma_bits;
unsigned char mpu_port_bits = 0;
unsigned char mpu_irq_bits;
- unsigned long flags;
snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
@@ -1109,9 +1102,9 @@ __skip_base:
}
dma_bits |= 0x04;
- spin_lock_irqsave(&chip->lock, flags);
- outb(irq_bits << 3 | dma_bits, chip->wss_base);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ outb(irq_bits << 3 | dma_bits, chip->wss_base);
+ }
__skip_resources:
if (chip->hardware > OPTi9XX_HW_82C928) {
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 328d043a1619..abaa3ed3ab5c 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -228,10 +228,9 @@ static int snd_opti9xx_init(struct snd_opti9xx *chip,
static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
unsigned char reg)
{
- unsigned long flags;
unsigned char retval = 0xff;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
outb(chip->password, chip->mc_base + chip->pwd_reg);
switch (chip->hardware) {
@@ -265,16 +264,13 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
dev_err(chip->card->dev, "chip %d not supported\n", chip->hardware);
}
- spin_unlock_irqrestore(&chip->lock, flags);
return retval;
}
static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
unsigned char value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
outb(chip->password, chip->mc_base + chip->pwd_reg);
switch (chip->hardware) {
@@ -307,8 +303,6 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
default:
dev_err(chip->card->dev, "chip %d not supported\n", chip->hardware);
}
-
- spin_unlock_irqrestore(&chip->lock, flags);
}
@@ -659,9 +653,6 @@ static int snd_opti9xx_read_check(struct snd_card *card,
struct snd_opti9xx *chip)
{
unsigned char value;
-#ifdef OPTi93X
- unsigned long flags;
-#endif
chip->res_mc_base =
devm_request_region(card->dev, chip->mc_base,
@@ -680,10 +671,10 @@ static int snd_opti9xx_read_check(struct snd_card *card,
if (!chip->res_mc_indir)
return -EBUSY;
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ outb(chip->password, chip->mc_base + chip->pwd_reg);
+ outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
+ }
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 312b217491d4..12c296ee34ec 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -35,60 +35,49 @@
/* Write a word */
void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
{
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
+ guard(spinlock_irqsave)(&emu->reg_lock);
if (reg != emu->last_reg) {
outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
emu->last_reg = reg;
}
outw((unsigned short)val, port); /* Send data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
}
/* Read a word */
unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
{
- unsigned short res;
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
+ guard(spinlock_irqsave)(&emu->reg_lock);
if (reg != emu->last_reg) {
outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
emu->last_reg = reg;
}
- res = inw(port); /* Read data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return res;
+ return inw(port); /* Read data */
}
/* Write a double word */
void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
{
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
+ guard(spinlock_irqsave)(&emu->reg_lock);
if (reg != emu->last_reg) {
outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
emu->last_reg = reg;
}
outw((unsigned short)val, port); /* Send low word of data */
outw((unsigned short)(val>>16), port+2); /* Send high word of data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
}
/* Read a double word */
unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
{
unsigned short low;
- unsigned int res;
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&emu->reg_lock);
if (reg != emu->last_reg) {
outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
emu->last_reg = reg;
}
low = inw(port); /* Read low word of data */
- res = low + (inw(port+2) << 16);
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return res;
+ return low + (inw(port+2) << 16);
}
/*
@@ -456,8 +445,6 @@ skip_detect:
/*exported*/ void
snd_emu8000_init_fm(struct snd_emu8000 *emu)
{
- unsigned long flags;
-
/* Initialize the last two channels for DRAM refresh and producing
the reverb and chorus effects for Yamaha OPL-3 synthesizer */
@@ -479,12 +466,12 @@ snd_emu8000_init_fm(struct snd_emu8000 *emu)
snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);
- spin_lock_irqsave(&emu->reg_lock, flags);
- while (!(inw(EMU8000_PTR(emu)) & 0x1000))
- ;
- while ((inw(EMU8000_PTR(emu)) & 0x1000))
- ;
- spin_unlock_irqrestore(&emu->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &emu->reg_lock) {
+ while (!(inw(EMU8000_PTR(emu)) & 0x1000))
+ ;
+ while ((inw(EMU8000_PTR(emu)) & 0x1000))
+ ;
+ }
snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);
/* this is really odd part.. */
outb(0x3C, EMU8000_PTR(emu));
@@ -838,20 +825,19 @@ static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short val1;
val1 = ucontrol->value.integer.value[0] % 12;
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- change = val1 != emu->treble_level;
- emu->treble_level = val1;
- } else {
- change = val1 != emu->bass_level;
- emu->bass_level = val1;
+ scoped_guard(spinlock_irqsave, &emu->control_lock) {
+ if (kcontrol->private_value) {
+ change = val1 != emu->treble_level;
+ emu->treble_level = val1;
+ } else {
+ change = val1 != emu->bass_level;
+ emu->bass_level = val1;
+ }
}
- spin_unlock_irqrestore(&emu->control_lock, flags);
snd_emu8000_update_equalizer(emu);
return change;
}
@@ -899,21 +885,20 @@ static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl
static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short val1;
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
- change = val1 != emu->chorus_mode;
- emu->chorus_mode = val1;
- } else {
- val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
- change = val1 != emu->reverb_mode;
- emu->reverb_mode = val1;
+ scoped_guard(spinlock_irqsave, &emu->control_lock) {
+ if (kcontrol->private_value) {
+ val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
+ change = val1 != emu->chorus_mode;
+ emu->chorus_mode = val1;
+ } else {
+ val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
+ change = val1 != emu->reverb_mode;
+ emu->reverb_mode = val1;
+ }
}
- spin_unlock_irqrestore(&emu->control_lock, flags);
if (change) {
if (kcontrol->private_value)
snd_emu8000_update_chorus_mode(emu);
@@ -966,20 +951,19 @@ static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned short val1;
val1 = ucontrol->value.integer.value[0] % 256;
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- change = val1 != emu->fm_chorus_depth;
- emu->fm_chorus_depth = val1;
- } else {
- change = val1 != emu->fm_reverb_depth;
- emu->fm_reverb_depth = val1;
+ scoped_guard(spinlock_irqsave, &emu->control_lock) {
+ if (kcontrol->private_value) {
+ change = val1 != emu->fm_chorus_depth;
+ emu->fm_chorus_depth = val1;
+ } else {
+ change = val1 != emu->fm_reverb_depth;
+ emu->fm_reverb_depth = val1;
+ }
}
- spin_unlock_irqrestore(&emu->control_lock, flags);
if (change)
snd_emu8000_init_fm(emu);
return change;
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 215bbcd0360e..656a655d618d 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -184,28 +184,30 @@ static void emu8k_pcm_timer_func(struct timer_list *t)
{
struct snd_emu8k_pcm *rec = timer_container_of(rec, t, timer);
int ptr, delta;
+ bool period_elapsed = false;
+
+ scoped_guard(spinlock, &rec->timer_lock) {
+ /* update the current pointer */
+ ptr = emu8k_get_curpos(rec, 0);
+ if (ptr < rec->last_ptr)
+ delta = ptr + rec->buf_size - rec->last_ptr;
+ else
+ delta = ptr - rec->last_ptr;
+ rec->period_pos += delta;
+ rec->last_ptr = ptr;
+
+ /* reprogram timer */
+ mod_timer(&rec->timer, jiffies + 1);
- spin_lock(&rec->timer_lock);
- /* update the current pointer */
- ptr = emu8k_get_curpos(rec, 0);
- if (ptr < rec->last_ptr)
- delta = ptr + rec->buf_size - rec->last_ptr;
- else
- delta = ptr - rec->last_ptr;
- rec->period_pos += delta;
- rec->last_ptr = ptr;
-
- /* reprogram timer */
- mod_timer(&rec->timer, jiffies + 1);
+ /* update period */
+ if (rec->period_pos >= (int)rec->period_size) {
+ rec->period_pos %= rec->period_size;
+ period_elapsed = true;
+ }
+ }
- /* update period */
- if (rec->period_pos >= (int)rec->period_size) {
- rec->period_pos %= rec->period_size;
- spin_unlock(&rec->timer_lock);
+ if (period_elapsed)
snd_pcm_period_elapsed(rec->substream);
- return;
- }
- spin_unlock(&rec->timer_lock);
}
@@ -321,7 +323,6 @@ static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
*/
static void start_voice(struct snd_emu8k_pcm *rec, int ch)
{
- unsigned long flags;
struct snd_emu8000 *hw = rec->emu;
unsigned int temp, aux;
int pt = calc_pitch_target(rec->pitch);
@@ -343,12 +344,11 @@ static void start_voice(struct snd_emu8k_pcm *rec, int ch)
EMU8000_CPF_WRITE(hw, ch, pt << 16);
/* start timer */
- spin_lock_irqsave(&rec->timer_lock, flags);
+ guard(spinlock_irqsave)(&rec->timer_lock);
if (! rec->timer_running) {
mod_timer(&rec->timer, jiffies + 1);
rec->timer_running = 1;
}
- spin_unlock_irqrestore(&rec->timer_lock, flags);
}
/*
@@ -356,18 +356,16 @@ static void start_voice(struct snd_emu8k_pcm *rec, int ch)
*/
static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
{
- unsigned long flags;
struct snd_emu8000 *hw = rec->emu;
EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
/* stop timer */
- spin_lock_irqsave(&rec->timer_lock, flags);
+ guard(spinlock_irqsave)(&rec->timer_lock);
if (rec->timer_running) {
timer_delete(&rec->timer);
rec->timer_running = 0;
}
- spin_unlock_irqrestore(&rec->timer_lock, flags);
}
static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 752762117338..208d1942a015 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -310,7 +310,6 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
#ifdef CONFIG_SND_SB16_CSP
struct snd_hwdep *xcsp = NULL;
#endif
- unsigned long flags;
int err;
xirq = irq[dev];
@@ -421,11 +420,11 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
#endif
/* setup Mic AGC */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
- (snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
- (mic_agc[dev] ? 0x00 : 0x01));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
+ (snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
+ (mic_agc[dev] ? 0x00 : 0x01));
+ }
err = snd_card_register(card);
if (err < 0)
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 7034072c80d4..9ad71a9fc18d 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -265,14 +265,10 @@ static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file)
*/
static int snd_sb_csp_use(struct snd_sb_csp * p)
{
- mutex_lock(&p->access_mutex);
- if (p->used) {
- mutex_unlock(&p->access_mutex);
+ guard(mutex)(&p->access_mutex);
+ if (p->used)
return -EAGAIN;
- }
p->used++;
- mutex_unlock(&p->access_mutex);
-
return 0;
}
@@ -282,10 +278,8 @@ static int snd_sb_csp_use(struct snd_sb_csp * p)
*/
static int snd_sb_csp_unuse(struct snd_sb_csp * p)
{
- mutex_lock(&p->access_mutex);
+ guard(mutex)(&p->access_mutex);
p->used--;
- mutex_unlock(&p->access_mutex);
-
return 0;
}
@@ -307,7 +301,6 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
__le32 item_type;
struct desc_header funcdesc_h;
- unsigned long flags;
int err;
if (copy_from_user(&info, mcode, sizeof(info)))
@@ -435,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);
/* 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, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
/* finished loading successfully */
p->running = SNDRV_SB_CSP_ST_LOADED; /* set LOADED flag */
@@ -548,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)
{
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_mode_register(chip, 0xfc); /* 0xfc = ?? */
@@ -560,23 +550,21 @@ static int csp_detect(struct snd_sb *chip, int *version)
set_register(chip, 0x83, ~csp_test1);
csp_test2 = read_register(chip, 0x83);
if (csp_test2 != (csp_test1 ^ 0xff))
- goto __fail;
+ return -ENODEV;
set_register(chip, 0x83, csp_test1);
csp_test2 = read_register(chip, 0x83);
if (csp_test2 != csp_test1)
- goto __fail;
+ return -ENODEV;
set_mode_register(chip, 0x00); /* 0x00 = ? */
*version = get_version(chip);
snd_sbdsp_reset(chip); /* reset DSP after getversion! */
if (*version >= 0x10 && *version <= 0x1f)
- result = 0; /* valid version id */
+ return 0; /* valid version id */
- __fail:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
+ return -ENODEV;
}
/*
@@ -614,14 +602,12 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
{
int status, i;
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 */
if (snd_sbdsp_get_byte(p->chip)) {
dev_dbg(p->chip->card->dev, "%s: Download command failed\n", __func__);
- goto __fail;
+ return -EIO;
}
/* Send CSP low byte (size - 1) */
snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
@@ -631,10 +617,10 @@ static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int
/* load from kernel space */
while (size--) {
if (!snd_sbdsp_command(p->chip, *buf++))
- goto __fail;
+ return -EIO;
}
if (snd_sbdsp_get_byte(p->chip))
- goto __fail;
+ return -EIO;
if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
i = 0;
@@ -650,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,
"%s: Microcode initialization failed\n",
__func__);
- goto __fail;
+ return -EIO;
}
} else {
/*
@@ -658,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
* of autorun or perhaps a bugfix?
*/
- spin_lock(&p->chip->mixer_lock);
- status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
- spin_unlock(&p->chip->mixer_lock);
+ scoped_guard(spinlock, &p->chip->mixer_lock) {
+ status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
+ }
if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
set_codec_parameter(p->chip, 0xff, 0x00));
snd_sbdsp_reset(p->chip); /* really! */
if (err)
- goto __fail;
+ return -EIO;
set_mode_register(p->chip, 0xc0); /* c0 = STOP */
set_mode_register(p->chip, 0x70); /* 70 = RUN */
}
}
- result = 0;
- __fail:
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
- return result;
+ return 0;
}
static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
@@ -722,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)
{
- unsigned long flags;
int err = 0;
/* if CSP is running or manually loaded then exit */
@@ -763,10 +745,9 @@ static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt,
default:
/* Decouple CSP from IRQ and DMAREQ lines */
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, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
p->running = 0; /* clear autoloaded flag */
}
return -EINVAL;
@@ -798,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 mixL, mixR;
int result = -EIO;
- unsigned long flags;
if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
dev_dbg(dev, "%s: Microcode not loaded\n", __func__);
@@ -818,55 +798,54 @@ static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channel
}
/* Mute PCM volume */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
- 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 + 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;
+ scoped_guard(spinlock_irqsave, &p->chip->mixer_lock) {
+ mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
+ 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 + 1, mixR & 0x7);
}
- if (set_codec_parameter(p->chip, 0x80, 0x00)) {
- dev_dbg(dev, "%s: Codec start command failed\n", __func__);
- goto __fail;
- }
- p->run_width = sample_width;
- p->run_channels = channels;
- p->running |= SNDRV_SB_CSP_ST_RUNNING;
+ scoped_guard(spinlock, &p->chip->reg_lock) {
+ set_mode_register(p->chip, 0xc0); /* c0 = STOP */
+ set_mode_register(p->chip, 0x70); /* 70 = RUN */
- 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;
+ 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) */
- __fail:
- spin_unlock(&p->chip->reg_lock);
+ 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;
+ }
/* restore PCM volume */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
- spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
+ if (result < 0) {
+ 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 + 1, mixR);
+ }
return result;
}
@@ -878,36 +857,35 @@ static int snd_sb_csp_stop(struct snd_sb_csp * p)
{
int result;
unsigned char mixL, mixR;
- unsigned long flags;
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
return 0;
/* Mute PCM volume */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
- 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 + 1, mixR & 0x7);
- spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
-
- spin_lock(&p->chip->reg_lock);
- if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
- set_codec_parameter(p->chip, 0xe0, 0x01);
- /* disable QSound decoder */
- set_codec_parameter(p->chip, 0x00, 0x00);
- set_codec_parameter(p->chip, 0x01, 0x00);
+ scoped_guard(spinlock_irqsave, &p->chip->mixer_lock) {
+ mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
+ 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 + 1, mixR & 0x7);
+ }
+
+ scoped_guard(spinlock, &p->chip->reg_lock) {
+ if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
+ set_codec_parameter(p->chip, 0xe0, 0x01);
+ /* disable QSound decoder */
+ set_codec_parameter(p->chip, 0x00, 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 */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
- spin_unlock_irqrestore(&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 + 1, mixR);
+ }
if (!(result))
p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
@@ -920,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)
{
int result;
- unsigned long flags;
if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
return -EBUSY;
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- result = set_codec_parameter(p->chip, 0x80, 0xff);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &p->chip->reg_lock) {
+ result = set_codec_parameter(p->chip, 0x80, 0xff);
+ }
if (!(result))
p->running |= SNDRV_SB_CSP_ST_PAUSED;
@@ -940,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)
{
int result;
- unsigned long flags;
if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
return -EBUSY;
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- result = set_codec_parameter(p->chip, 0x80, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &p->chip->reg_lock) {
+ result = set_codec_parameter(p->chip, 0x80, 0x00);
+ }
if (!(result))
p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
@@ -973,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)
{
struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned char nval;
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;
p->q_enabled = nval;
- spin_unlock_irqrestore(&p->q_lock, flags);
return change;
}
@@ -997,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)
{
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[1] = p->qpos_right;
- spin_unlock_irqrestore(&p->q_lock, flags);
return 0;
}
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);
- unsigned long flags;
int change;
unsigned char nval1, nval2;
@@ -1019,12 +990,11 @@ static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl
nval2 = ucontrol->value.integer.value[1];
if (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;
p->qpos_left = nval1;
p->qpos_right = nval2;
p->qpos_changed = change;
- spin_unlock_irqrestore(&p->q_lock, flags);
return change;
}
@@ -1080,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)
{
struct snd_card *card;
- unsigned long flags;
if (snd_BUG_ON(!p))
return;
@@ -1093,9 +1062,8 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
p->qsound_space = NULL;
/* cancel pending transfer of QSound parameters */
- spin_lock_irqsave (&p->q_lock, flags);
+ guard(spinlock_irqsave)(&p->q_lock);
p->qpos_changed = 0;
- spin_unlock_irqrestore (&p->q_lock, flags);
}
/*
@@ -1106,7 +1074,7 @@ static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
{
int err = -ENXIO;
- spin_lock(&p->q_lock);
+ guard(spinlock)(&p->q_lock);
if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
set_codec_parameter(p->chip, 0xe0, 0x01);
/* left channel */
@@ -1118,7 +1086,6 @@ static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
err = 0;
}
p->qpos_changed = 0;
- spin_unlock(&p->q_lock);
return err;
}
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index 5a083eecaa6b..4d64db4f5852 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -130,9 +130,8 @@ static void snd_sb16_csp_update(struct snd_sb *chip)
struct snd_sb_csp *csp = chip->csp;
if (csp->qpos_changed) {
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
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,
int channel)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
snd_sb_ack_16bit(chip);
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 & 0xff);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
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_pcm_runtime *runtime = substream->runtime;
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);
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) {
count >>= 1;
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, SB_DSP_DMA8_OFF);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -278,9 +272,8 @@ static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
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;
break;
default:
- result = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return result;
+ return 0;
}
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_pcm_runtime *runtime = substream->runtime;
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);
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) {
count >>= 1;
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, SB_DSP_DMA8_OFF);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -347,9 +337,8 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
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;
break;
default:
- result = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return result;
+ return 0;
}
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;
int ok;
- spin_lock(&chip->mixer_lock);
- status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
- spin_unlock(&chip->mixer_lock);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
+ }
if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
chip->rmidi_callback(irq, chip->rmidi->private_data);
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);
ok++;
}
- spin_lock(&chip->reg_lock);
- if (!ok)
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- snd_sb_ack_8bit(chip);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ if (!ok)
+ snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
+ snd_sb_ack_8bit(chip);
+ }
}
if (status & SB_IRQTYPE_16BIT) {
ok = 0;
@@ -410,11 +398,11 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
snd_pcm_period_elapsed(chip->capture_substream);
ok++;
}
- spin_lock(&chip->reg_lock);
- if (!ok)
- snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
- snd_sb_ack_16bit(chip);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ if (!ok)
+ snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
+ snd_sb_ack_16bit(chip);
+ }
}
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)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->mode & SB_MODE_PLAYBACK) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
+ if (chip->mode & SB_MODE_PLAYBACK)
return -EAGAIN;
- }
runtime->hw = snd_sb16_playback;
/* 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;
goto __open_ok;
}
- spin_unlock_irqrestore(&chip->open_lock, flags);
return -EAGAIN;
__open_ok:
@@ -547,34 +531,28 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
if (chip->mode & SB_RATE_LOCK)
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
chip->playback_substream = substream;
- spin_unlock_irqrestore(&chip->open_lock, flags);
return 0;
}
static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
snd_sb16_csp_playback_close(chip);
- spin_lock_irqsave(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
chip->playback_substream = NULL;
chip->mode &= ~SB_MODE_PLAYBACK;
- spin_unlock_irqrestore(&chip->open_lock, flags);
return 0;
}
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_pcm_runtime *runtime = substream->runtime;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->mode & SB_MODE_CAPTURE) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
+ if (chip->mode & SB_MODE_CAPTURE)
return -EAGAIN;
- }
runtime->hw = snd_sb16_capture;
/* 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;
goto __open_ok;
}
- spin_unlock_irqrestore(&chip->open_lock, flags);
return -EAGAIN;
__open_ok:
@@ -622,20 +599,17 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
if (chip->mode & SB_RATE_LOCK)
runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
chip->capture_substream = substream;
- spin_unlock_irqrestore(&chip->open_lock, flags);
return 0;
}
static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
snd_sb16_csp_capture_close(chip);
- spin_lock_irqsave(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
chip->capture_substream = NULL;
chip->mode &= ~SB_MODE_CAPTURE;
- spin_unlock_irqrestore(&chip->open_lock, flags);
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)
{
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);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
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);
- unsigned long flags;
unsigned char nval, oval;
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];
if (nval > 2)
return -EINVAL;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oval = snd_sb16_get_dma_mode(chip);
- change = nval != oval;
- snd_sb16_set_dma_mode(chip, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ oval = snd_sb16_get_dma_mode(chip);
+ change = nval != oval;
+ snd_sb16_set_dma_mode(chip, nval);
+ }
if (change) {
snd_dma_disable(chip->dma8);
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)
{
- unsigned long flags;
unsigned char irqreg = 0, dmareg = 0, mpureg;
unsigned char realirq, realdma, realmpureg;
/* note: mpu register should be present only on SB16 Vibra soundcards */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
+ }
switch (chip->irq) {
case 2:
case 9:
@@ -800,18 +770,17 @@ int snd_sb16dsp_configure(struct snd_sb * chip)
default:
mpureg |= 0x02; /* disable MPU */
}
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
- realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
+ realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
- snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
- realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
+ snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
+ realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
- snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
- realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
-
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
+ realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
+ }
if ((~realirq) & irqreg || (~realdma) & dmareg) {
dev_err(chip->card->dev,
"SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n",
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 2ed176a5a574..a4b5725255cf 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -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)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int mixreg, rate, size, count;
@@ -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);
count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
- if (chip->hardware == SB_HW_JAZZ16)
- snd_sbdsp_command(chip, format);
- else if (stereo) {
- /* set playback stereo mode */
- spin_lock(&chip->mixer_lock);
- mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
- snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
- spin_unlock(&chip->mixer_lock);
-
- /* Soundblaster hardware programming reference guide, 3-23 */
- snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
- runtime->dma_area[0] = 0x80;
- snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
- /* force interrupt */
- snd_sbdsp_command(chip, SB_DSP_OUTPUT);
- snd_sbdsp_command(chip, 0);
- snd_sbdsp_command(chip, 0);
- }
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
- if (stereo) {
- snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
- spin_lock(&chip->mixer_lock);
- /* save output filter status and turn it off */
- mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT);
- snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20);
- spin_unlock(&chip->mixer_lock);
- /* just use force_mode16 for temporary storate... */
- chip->force_mode16 = mixreg;
- } else {
- snd_sbdsp_command(chip, 256 - runtime->rate_den);
- }
- if (chip->playback_format != SB_DSP_OUTPUT) {
- if (chip->mode & SB_MODE_PLAYBACK_16)
- count /= 2;
- count--;
- snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
+ if (chip->hardware == SB_HW_JAZZ16)
+ snd_sbdsp_command(chip, format);
+ else if (stereo) {
+ /* set playback stereo mode */
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
+ snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
+ }
+
+ /* Soundblaster hardware programming reference guide, 3-23 */
+ snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
+ runtime->dma_area[0] = 0x80;
+ snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
+ /* force interrupt */
+ snd_sbdsp_command(chip, SB_DSP_OUTPUT);
+ snd_sbdsp_command(chip, 0);
+ snd_sbdsp_command(chip, 0);
+ }
+ snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
+ if (stereo) {
+ snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ /* save output filter status and turn it off */
+ mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT);
+ snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20);
+ }
+ /* just use force_mode16 for temporary storate... */
+ chip->force_mode16 = mixreg;
+ } else {
+ snd_sbdsp_command(chip, 256 - runtime->rate_den);
+ }
+ if (chip->playback_format != SB_DSP_OUTPUT) {
+ if (chip->mode & SB_MODE_PLAYBACK_16)
+ count /= 2;
+ count--;
+ snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
+ snd_sbdsp_command(chip, count & 0xff);
+ snd_sbdsp_command(chip, count >> 8);
+ }
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_WRITE | DMA_AUTOINIT);
return 0;
@@ -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,
int cmd)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned int count;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_sbdsp_command(chip, chip->playback_format);
@@ -211,23 +209,20 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
snd_sbdsp_reset(chip);
if (runtime->channels > 1) {
- spin_lock(&chip->mixer_lock);
+ guard(spinlock)(&chip->mixer_lock);
/* restore output filter and set hardware to mono mode */
snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02);
- spin_unlock(&chip->mixer_lock);
}
} else {
snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
}
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int mixreg, rate, size, count;
@@ -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);
count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
- if (chip->hardware == SB_HW_JAZZ16)
- snd_sbdsp_command(chip, format);
- else if (stereo)
- snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
- if (stereo) {
- snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
- spin_lock(&chip->mixer_lock);
- /* save input filter status and turn it off */
- mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
- snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
- spin_unlock(&chip->mixer_lock);
- /* just use force_mode16 for temporary storate... */
- chip->force_mode16 = mixreg;
- } else {
- snd_sbdsp_command(chip, 256 - runtime->rate_den);
- }
- if (chip->capture_format != SB_DSP_INPUT) {
- if (chip->mode & SB_MODE_PLAYBACK_16)
- count /= 2;
- count--;
- snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
+ if (chip->hardware == SB_HW_JAZZ16)
+ snd_sbdsp_command(chip, format);
+ else if (stereo)
+ snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
+ snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
+ if (stereo) {
+ snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ /* save input filter status and turn it off */
+ mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
+ snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
+ }
+ /* just use force_mode16 for temporary storate... */
+ chip->force_mode16 = mixreg;
+ } else {
+ snd_sbdsp_command(chip, 256 - runtime->rate_den);
+ }
+ if (chip->capture_format != SB_DSP_INPUT) {
+ if (chip->mode & SB_MODE_PLAYBACK_16)
+ count /= 2;
+ count--;
+ snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
+ snd_sbdsp_command(chip, count & 0xff);
+ snd_sbdsp_command(chip, count >> 8);
+ }
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_READ | DMA_AUTOINIT);
return 0;
@@ -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,
int cmd)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned int count;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_sbdsp_command(chip, chip->capture_format);
@@ -337,9 +331,9 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
snd_sbdsp_reset(chip);
if (runtime->channels > 1) {
/* restore input filter status */
- spin_lock(&chip->mixer_lock);
- snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
- spin_unlock(&chip->mixer_lock);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
+ }
/* set hardware to mono mode */
snd_sbdsp_command(chip, SB_DSP_MONO_8BIT);
}
@@ -348,7 +342,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
}
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -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_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ if (chip->open)
+ return -EAGAIN;
+ chip->open |= SB_OPEN_PCM;
}
- chip->open |= SB_OPEN_PCM;
- spin_unlock_irqrestore(&chip->open_lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
chip->playback_substream = substream;
runtime->hw = snd_sb8_playback;
@@ -525,18 +515,16 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
static int snd_sb8_close(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip = snd_pcm_substream_chip(substream);
chip->playback_substream = NULL;
chip->capture_substream = NULL;
- spin_lock_irqsave(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
chip->open &= ~SB_OPEN_PCM;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
chip->mode &= ~SB_MODE_PLAYBACK;
else
chip->mode &= ~SB_MODE_CAPTURE;
- spin_unlock_irqrestore(&chip->open_lock, flags);
return 0;
}
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index 637079a2f02a..1d41f2470697 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -35,7 +35,7 @@ irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
return IRQ_NONE;
}
- spin_lock(&chip->midi_input_lock);
+ guard(spinlock)(&chip->midi_input_lock);
while (max-- > 0) {
if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
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;
}
static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip;
unsigned int valid_open_flags;
chip = substream->rmidi->private_data;
valid_open_flags = chip->hardware >= SB_HW_20
? SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER : 0;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open & ~valid_open_flags) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- chip->open |= SB_OPEN_MIDI_INPUT;
- chip->midi_substream_input = substream;
- 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);
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ if (chip->open & ~valid_open_flags)
+ return -EAGAIN;
+ chip->open |= SB_OPEN_MIDI_INPUT;
+ chip->midi_substream_input = substream;
+ if (chip->open & SB_OPEN_MIDI_OUTPUT)
+ return 0;
}
+ snd_sbdsp_reset(chip); /* reset DSP */
+ if (chip->hardware >= SB_HW_20)
+ snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
return 0;
}
static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip;
unsigned int valid_open_flags;
chip = substream->rmidi->private_data;
valid_open_flags = chip->hardware >= SB_HW_20
? SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER : 0;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open & ~valid_open_flags) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- chip->open |= SB_OPEN_MIDI_OUTPUT;
- chip->midi_substream_output = substream;
- 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);
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ if (chip->open & ~valid_open_flags)
+ return -EAGAIN;
+ chip->open |= SB_OPEN_MIDI_OUTPUT;
+ chip->midi_substream_output = substream;
+ if (chip->open & SB_OPEN_MIDI_INPUT)
+ return 0;
}
+ snd_sbdsp_reset(chip); /* reset DSP */
+ if (chip->hardware >= SB_HW_20)
+ snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
return 0;
}
static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip;
chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->open &= ~(SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER);
- chip->midi_substream_input = NULL;
- if (!(chip->open & SB_OPEN_MIDI_OUTPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ chip->open &= ~(SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER);
+ chip->midi_substream_input = NULL;
+ if (chip->open & SB_OPEN_MIDI_OUTPUT)
+ return 0;
}
+ snd_sbdsp_reset(chip); /* reset DSP */
return 0;
}
static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip;
chip = substream->rmidi->private_data;
timer_delete_sync(&chip->midi_timer);
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
- chip->midi_substream_output = NULL;
- if (!(chip->open & SB_OPEN_MIDI_INPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
+ chip->midi_substream_output = NULL;
+ if (chip->open & SB_OPEN_MIDI_INPUT)
+ return 0;
}
+ snd_sbdsp_reset(chip); /* reset DSP */
return 0;
}
static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_sb *chip;
chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
+ guard(spinlock_irqsave)(&chip->open_lock);
if (up) {
if (!(chip->open & SB_OPEN_MIDI_INPUT_TRIGGER)) {
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;
}
}
- spin_unlock_irqrestore(&chip->open_lock, flags);
}
static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
struct snd_sb *chip;
char byte;
int max = 32;
@@ -172,11 +152,10 @@ static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream
/* how big is Tx FIFO? */
chip = substream->rmidi->private_data;
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) {
chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
timer_delete(&chip->midi_timer);
- spin_unlock_irqrestore(&chip->open_lock, flags);
break;
}
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) {
/* Tx FIFO full - try again later */
- spin_unlock_irqrestore(&chip->open_lock, flags);
break;
}
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_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_rawmidi_substream *substream = chip->midi_substream_output;
- unsigned long flags;
- spin_lock_irqsave(&chip->open_lock, flags);
- mod_timer(&chip->midi_timer, 1 + jiffies);
- spin_unlock_irqrestore(&chip->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ mod_timer(&chip->midi_timer, 1 + jiffies);
+ }
snd_sb8dsp_midi_output_write(substream);
}
static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_sb *chip;
chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (up) {
- if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
- mod_timer(&chip->midi_timer, 1 + jiffies);
- chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
- }
- } else {
- if (chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER) {
- chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
+ scoped_guard(spinlock_irqsave, &chip->open_lock) {
+ if (up) {
+ if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
+ mod_timer(&chip->midi_timer, 1 + jiffies);
+ chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
+ }
+ } else {
+ if (chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER) {
+ chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
+ }
}
}
- spin_unlock_irqrestore(&chip->open_lock, flags);
if (up)
snd_sb8dsp_midi_output_write(substream);
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index a4d5bf3d145f..f2848559e6da 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -94,23 +94,18 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
int version;
int major, minor;
char *str;
- unsigned long flags;
/*
* initialization sequence
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (snd_sbdsp_reset(chip) < 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
- }
- version = snd_sbdsp_version(chip);
- if (version < 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ if (snd_sbdsp_reset(chip) < 0)
+ return -ENODEV;
+ version = snd_sbdsp_version(chip);
+ if (version < 0)
+ return -ENODEV;
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
major = version >> 8;
minor = version & 0xff;
dev_dbg(chip->card->dev, "SB [0x%lx]: DSP chip found, version = %i.%i\n",
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index b2709ed134b4..95173b18cee3 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0xff;
int mask = (kcontrol->private_value >> 24) & 0xff;
unsigned char val;
- spin_lock_irqsave(&sb->mixer_lock, flags);
+ guard(spinlock_irqsave)(&sb->mixer_lock);
val = (snd_sbmixer_read(sb, reg) >> shift) & mask;
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
ucontrol->value.integer.value[0] = val;
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0x07;
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;
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);
val = (oval & ~(mask << shift)) | val;
change = val != oval;
if (change)
snd_sbmixer_write(sb, reg, val);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
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;
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;
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[1] = right;
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
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;
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) {
oleft = snd_sbmixer_read(sb, left_reg);
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);
}
}
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned char oval;
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &sb->mixer_lock) {
+ oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
+ }
switch (oval & 0x07) {
case SB_DT019X_CAP_CD:
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned char nval, oval;
@@ -239,12 +229,11 @@ static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl
default:
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);
change = nval != oval;
if (change)
snd_sbmixer_write(sb, SB_DT019X_CAPTURE_SW, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
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_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
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);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
oval >>= 6;
if (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_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
unsigned char nval, oval;
if (ucontrol->value.enumerated.item[0] > 2)
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);
nval = (oval & ~(3 << 6))
@@ -298,7 +284,6 @@ static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol,
change = nval != oval;
if (change)
snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
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);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
switch ((oval >> 0x01) & 0x03) {
case SB_DSP_MIXS_CD:
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int change;
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 <<= 1;
- spin_lock_irqsave(&sb->mixer_lock, flags);
+ guard(spinlock_irqsave)(&sb->mixer_lock);
oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
nval |= oval & ~0x06;
change = nval != oval;
if (change)
snd_sbmixer_write(sb, SB_DSP_CAPTURE_SOURCE, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
int right_shift = (kcontrol->private_value >> 24) & 0x0f;
unsigned char val1, val2;
- spin_lock_irqsave(&sb->mixer_lock, flags);
+ guard(spinlock_irqsave)(&sb->mixer_lock);
val1 = snd_sbmixer_read(sb, reg1);
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[1] = (val2 >> left_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)
{
struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
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;
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);
oval2 = snd_sbmixer_read(sb, reg2);
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, reg2, val2);
}
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
return change;
}
@@ -697,20 +674,18 @@ static int snd_sbmixer_init(struct snd_sb *chip,
int map_count,
char *name)
{
- unsigned long flags;
struct snd_card *card = chip->card;
int idx, err;
/* mixer reset */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, 0x00, 0x00);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->mixer_lock) {
+ snd_sbmixer_write(chip, 0x00, 0x00);
+ }
/* mute and zero volume channels */
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]);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
}
for (idx = 0; idx < controls_count; idx++) {
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 709a1659d66f..a31ca75774a6 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -200,11 +200,8 @@ static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg,
static void sscape_write(struct soundscape *s, enum GA_REG reg,
unsigned char val)
{
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
+ guard(spinlock_irqsave)(&s->lock);
sscape_write_unsafe(s->io_base, reg, val);
- spin_unlock_irqrestore(&s->lock, flags);
}
/*
@@ -367,12 +364,11 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
do {
- unsigned long flags;
int x;
- spin_lock_irqsave(&s->lock, flags);
- x = host_read_unsafe(s->io_base);
- spin_unlock_irqrestore(&s->lock, flags);
+ scoped_guard(spinlock_irqsave, &s->lock) {
+ x = host_read_unsafe(s->io_base);
+ }
if (x == 0xfe || x == 0xff)
return 1;
@@ -394,12 +390,11 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
do {
- unsigned long flags;
int x;
- spin_lock_irqsave(&s->lock, flags);
- x = host_read_unsafe(s->io_base);
- spin_unlock_irqrestore(&s->lock, flags);
+ scoped_guard(spinlock_irqsave, &s->lock) {
+ x = host_read_unsafe(s->io_base);
+ }
if (x == 0xfe)
return 1;
@@ -415,7 +410,6 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
static int upload_dma_data(struct soundscape *s, const unsigned char *data,
size_t size)
{
- unsigned long flags;
struct snd_dma_buffer dma;
int ret;
unsigned char val;
@@ -423,62 +417,57 @@ static int upload_dma_data(struct soundscape *s, const unsigned char *data,
if (!get_dmabuf(s, &dma, PAGE_ALIGN(32 * 1024)))
return -ENOMEM;
- spin_lock_irqsave(&s->lock, flags);
-
- /*
- * Reset the board ...
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);
-
- /*
- * Enable the DMA channels and configure them ...
- */
- val = (s->chip->dma1 << 4) | DMA_8BIT;
- sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
- sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);
-
- /*
- * Take the board out of reset ...
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);
+ scoped_guard(spinlock_irqsave, &s->lock) {
- /*
- * Upload the firmware to the SoundScape
- * board through the DMA channel ...
- */
- while (size != 0) {
- unsigned long len;
+ /*
+ * Reset the board ...
+ */
+ val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
+ sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);
- len = min(size, dma.bytes);
- memcpy(dma.area, data, len);
- data += len;
- size -= len;
+ /*
+ * Enable the DMA channels and configure them ...
+ */
+ val = (s->chip->dma1 << 4) | DMA_8BIT;
+ sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
+ sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);
- snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
- sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
- if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
- /*
- * Don't forget to release this spinlock we're holding
- */
- spin_unlock_irqrestore(&s->lock, flags);
+ /*
+ * Take the board out of reset ...
+ */
+ val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
+ sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);
- dev_err(s->dev, "sscape: DMA upload has timed out\n");
- ret = -EAGAIN;
- goto _release_dma;
- }
- } /* while */
+ /*
+ * Upload the firmware to the SoundScape
+ * board through the DMA channel ...
+ */
+ while (size != 0) {
+ unsigned long len;
+
+ len = min(size, dma.bytes);
+ memcpy(dma.area, data, len);
+ data += len;
+ size -= len;
+
+ snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
+ sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
+ if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
+ dev_err(s->dev, "sscape: DMA upload has timed out\n");
+ ret = -EAGAIN;
+ goto _release_dma;
+ }
+ } /* while */
- set_host_mode_unsafe(s->io_base);
- outb(0x0, s->io_base);
+ set_host_mode_unsafe(s->io_base);
+ outb(0x0, s->io_base);
- /*
- * Boot the board ... (I think)
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
- spin_unlock_irqrestore(&s->lock, flags);
+ /*
+ * Boot the board ... (I think)
+ */
+ val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
+ sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
+ }
/*
* If all has gone well, then the board should acknowledge
@@ -513,7 +502,6 @@ _release_dma:
static int sscape_upload_bootblock(struct snd_card *card)
{
struct soundscape *sscape = get_card_soundscape(card);
- unsigned long flags;
const struct firmware *init_fw = NULL;
int data = 0;
int ret;
@@ -527,15 +515,13 @@ static int sscape_upload_bootblock(struct snd_card *card)
release_firmware(init_fw);
- spin_lock_irqsave(&sscape->lock, flags);
+ guard(spinlock_irqsave)(&sscape->lock);
if (ret == 0)
data = host_read_ctrl_unsafe(sscape->io_base, 100);
if (data & 0x10)
sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2f);
- spin_unlock_irqrestore(&sscape->lock, flags);
-
data &= 0xf;
if (ret == 0 && data > 7) {
dev_err(card->dev,
@@ -593,11 +579,9 @@ static int sscape_midi_get(struct snd_kcontrol *kctl,
struct snd_wss *chip = snd_kcontrol_chip(kctl);
struct snd_card *card = chip->card;
register struct soundscape *s = get_card_soundscape(card);
- unsigned long flags;
- spin_lock_irqsave(&s->lock, flags);
+ guard(spinlock_irqsave)(&s->lock);
uctl->value.integer.value[0] = s->midi_vol;
- spin_unlock_irqrestore(&s->lock, flags);
return 0;
}
@@ -607,11 +591,10 @@ static int sscape_midi_put(struct snd_kcontrol *kctl,
struct snd_wss *chip = snd_kcontrol_chip(kctl);
struct snd_card *card = chip->card;
struct soundscape *s = get_card_soundscape(card);
- unsigned long flags;
int change;
unsigned char new_val;
- spin_lock_irqsave(&s->lock, flags);
+ guard(spinlock_irqsave)(&s->lock);
new_val = uctl->value.integer.value[0] & 127;
/*
@@ -642,7 +625,6 @@ __skip_change:
*/
set_midi_mode_unsafe(s->io_base);
- spin_unlock_irqrestore(&s->lock, flags);
return change;
}
@@ -852,8 +834,6 @@ static int create_ad1845(struct snd_card *card, unsigned port,
err = snd_wss_create(card, port, -1, irq, dma1, dma2,
codec_type, WSS_HWSHARE_DMA1, &chip);
if (!err) {
- unsigned long flags;
-
if (sscape->type != SSCAPE_VIVO) {
/*
* The input clock frequency on the SoundScape must
@@ -861,9 +841,9 @@ static int create_ad1845(struct snd_card *card, unsigned port,
* to get the playback to sound correct ...
*/
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, AD1845_CLOCK, 0x20);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_wss_out(chip, AD1845_CLOCK, 0x20);
+ }
snd_wss_mce_down(chip);
}
@@ -920,7 +900,6 @@ static int create_sscape(int dev, struct snd_card *card)
unsigned mpu_irq_cfg;
struct resource *io_res;
struct resource *wss_res;
- unsigned long flags;
int err;
int val;
const char *name;
@@ -1006,34 +985,34 @@ static int create_sscape(int dev, struct snd_card *card)
* Tell the on-board devices where their resources are (I think -
* I can't be sure without a datasheet ... So many magic values!)
*/
- spin_lock_irqsave(&sscape->lock, flags);
+ scoped_guard(spinlock_irqsave, &sscape->lock) {
- sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
- sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
+ sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
+ sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
- /*
- * Enable and configure the DMA channels ...
- */
- sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
- dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
- sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
- sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
-
- mpu_irq_cfg |= mpu_irq_cfg << 2;
- val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
- if (joystick[dev])
- val |= 8;
- sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
- sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
- sscape_write_unsafe(sscape->io_base,
- GA_CDCFG_REG, 0x09 | DMA_8BIT
- | (dma[dev] << 4) | (irq_cfg << 1));
- /*
- * Enable the master IRQ ...
- */
- sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);
+ /*
+ * Enable and configure the DMA channels ...
+ */
+ sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
+ dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
+ sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
+ sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
+
+ mpu_irq_cfg |= mpu_irq_cfg << 2;
+ val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
+ if (joystick[dev])
+ val |= 8;
+ sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
+ sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
+ sscape_write_unsafe(sscape->io_base,
+ GA_CDCFG_REG, 0x09 | DMA_8BIT
+ | (dma[dev] << 4) | (irq_cfg << 1));
+ /*
+ * Enable the master IRQ ...
+ */
+ sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);
- spin_unlock_irqrestore(&sscape->lock, flags);
+ }
/*
* We have now enabled the codec chip, and so we should
@@ -1073,7 +1052,7 @@ static int create_sscape(int dev, struct snd_card *card)
/*
* Initialize mixer
*/
- spin_lock_irqsave(&sscape->lock, flags);
+ guard(spinlock_irqsave)(&sscape->lock);
sscape->midi_vol = 0;
host_write_ctrl_unsafe(sscape->io_base,
CMD_SET_MIDI_VOL, 100);
@@ -1090,7 +1069,6 @@ static int create_sscape(int dev, struct snd_card *card)
host_write_ctrl_unsafe(sscape->io_base, CMD_ACK, 100);
set_midi_mode_unsafe(sscape->io_base);
- spin_unlock_irqrestore(&sscape->lock, flags);
}
}
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c
index 494b21be665c..1250ecba659a 100644
--- a/sound/isa/wavefront/wavefront_midi.c
+++ b/sound/isa/wavefront/wavefront_midi.c
@@ -113,7 +113,6 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
{
snd_wavefront_midi_t *midi = &card->wavefront.midi;
snd_wavefront_mpu_id mpu;
- unsigned long flags;
unsigned char midi_byte;
int max = 256, mask = 1;
int timeout;
@@ -142,11 +141,9 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
break;
}
- spin_lock_irqsave (&midi->virtual, flags);
- if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) {
- spin_unlock_irqrestore (&midi->virtual, flags);
+ guard(spinlock_irqsave)(&midi->virtual);
+ if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0)
goto __second;
- }
if (output_ready (midi)) {
if (snd_rawmidi_transmit(midi->substream_output[midi->output_mpu], &midi_byte, 1) == 1) {
if (!midi->isvirtual ||
@@ -160,14 +157,11 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
timer_delete(&midi->timer);
}
midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
- spin_unlock_irqrestore (&midi->virtual, flags);
goto __second;
}
} else {
- spin_unlock_irqrestore (&midi->virtual, flags);
return;
}
- spin_unlock_irqrestore (&midi->virtual, flags);
}
__second:
@@ -185,15 +179,13 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
break;
}
- spin_lock_irqsave (&midi->virtual, flags);
+ guard(spinlock_irqsave)(&midi->virtual);
if (!midi->isvirtual)
mask = 0;
mpu = midi->output_mpu ^ mask;
mask = 0; /* don't invert the value from now */
- if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) {
- spin_unlock_irqrestore (&midi->virtual, flags);
+ if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0)
return;
- }
if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
goto __timer;
if (output_ready (midi)) {
@@ -215,20 +207,16 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
timer_delete(&midi->timer);
}
midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
- spin_unlock_irqrestore (&midi->virtual, flags);
return;
}
} else {
- spin_unlock_irqrestore (&midi->virtual, flags);
return;
}
- spin_unlock_irqrestore (&midi->virtual, flags);
}
}
static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -243,17 +231,15 @@ static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream
if (!midi)
return -EIO;
- spin_lock_irqsave (&midi->open, flags);
+ guard(spinlock_irqsave)(&midi->open);
midi->mode[mpu] |= MPU401_MODE_INPUT;
midi->substream_input[mpu] = substream;
- spin_unlock_irqrestore (&midi->open, flags);
return 0;
}
static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -268,17 +254,15 @@ static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substrea
if (!midi)
return -EIO;
- spin_lock_irqsave (&midi->open, flags);
+ guard(spinlock_irqsave)(&midi->open);
midi->mode[mpu] |= MPU401_MODE_OUTPUT;
midi->substream_output[mpu] = substream;
- spin_unlock_irqrestore (&midi->open, flags);
return 0;
}
static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -293,16 +277,14 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea
if (!midi)
return -EIO;
- spin_lock_irqsave (&midi->open, flags);
+ guard(spinlock_irqsave)(&midi->open);
midi->mode[mpu] &= ~MPU401_MODE_INPUT;
- spin_unlock_irqrestore (&midi->open, flags);
return 0;
}
static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -317,15 +299,13 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre
if (!midi)
return -EIO;
- spin_lock_irqsave (&midi->open, flags);
+ guard(spinlock_irqsave)(&midi->open);
midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
- spin_unlock_irqrestore (&midi->open, flags);
return 0;
}
static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -341,30 +321,27 @@ static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *subst
if (!midi)
return;
- spin_lock_irqsave (&midi->virtual, flags);
+ guard(spinlock_irqsave)(&midi->virtual);
if (up) {
midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
} else {
midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
}
- spin_unlock_irqrestore (&midi->virtual, flags);
}
static void snd_wavefront_midi_output_timer(struct timer_list *t)
{
snd_wavefront_midi_t *midi = timer_container_of(midi, t, timer);
snd_wavefront_card_t *card = midi->timer_card;
- unsigned long flags;
- spin_lock_irqsave (&midi->virtual, flags);
- mod_timer(&midi->timer, 1 + jiffies);
- spin_unlock_irqrestore (&midi->virtual, flags);
+ scoped_guard(spinlock_irqsave, &midi->virtual) {
+ mod_timer(&midi->timer, 1 + jiffies);
+ }
snd_wavefront_midi_output_write(card);
}
static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
snd_wavefront_mpu_id mpu;
@@ -380,22 +357,22 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs
if (!midi)
return;
- spin_lock_irqsave (&midi->virtual, flags);
- if (up) {
- if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
- if (!midi->istimer) {
- timer_setup(&midi->timer,
- snd_wavefront_midi_output_timer,
- 0);
- mod_timer(&midi->timer, 1 + jiffies);
+ scoped_guard(spinlock_irqsave, &midi->virtual) {
+ if (up) {
+ if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
+ if (!midi->istimer) {
+ timer_setup(&midi->timer,
+ snd_wavefront_midi_output_timer,
+ 0);
+ mod_timer(&midi->timer, 1 + jiffies);
+ }
+ midi->istimer++;
+ midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
}
- midi->istimer++;
- midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
+ } else {
+ midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
}
- } else {
- midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
}
- spin_unlock_irqrestore (&midi->virtual, flags);
if (up)
snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
@@ -405,7 +382,6 @@ void
snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
{
- unsigned long flags;
snd_wavefront_midi_t *midi;
static struct snd_rawmidi_substream *substream = NULL;
static int mpu = external_mpu;
@@ -419,37 +395,37 @@ snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
return;
}
- spin_lock_irqsave (&midi->virtual, flags);
- while (--max) {
-
- if (input_avail (midi)) {
- byte = read_data (midi);
-
- if (midi->isvirtual) {
- if (byte == WF_EXTERNAL_SWITCH) {
- substream = midi->substream_input[external_mpu];
- mpu = external_mpu;
- } else if (byte == WF_INTERNAL_SWITCH) {
- substream = midi->substream_output[internal_mpu];
+ scoped_guard(spinlock_irqsave, &midi->virtual) {
+ while (--max) {
+
+ if (input_avail(midi)) {
+ byte = read_data(midi);
+
+ if (midi->isvirtual) {
+ if (byte == WF_EXTERNAL_SWITCH) {
+ substream = midi->substream_input[external_mpu];
+ mpu = external_mpu;
+ } else if (byte == WF_INTERNAL_SWITCH) {
+ substream = midi->substream_output[internal_mpu];
+ mpu = internal_mpu;
+ } /* else just leave it as it is */
+ } else {
+ substream = midi->substream_input[internal_mpu];
mpu = internal_mpu;
- } /* else just leave it as it is */
- } else {
- substream = midi->substream_input[internal_mpu];
- mpu = internal_mpu;
- }
+ }
- if (substream == NULL) {
- continue;
- }
+ if (substream == NULL) {
+ continue;
+ }
- if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
- snd_rawmidi_receive(substream, &byte, 1);
+ if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
+ snd_rawmidi_receive(substream, &byte, 1);
+ }
+ } else {
+ break;
}
- } else {
- break;
}
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
+ }
snd_wavefront_midi_output_write(card);
}
@@ -471,13 +447,10 @@ void
snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
{
- unsigned long flags;
-
- spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
+ guard(spinlock_irqsave)(&card->wavefront.midi.virtual);
// snd_wavefront_midi_input_close (card->ics2115_external_rmidi);
// snd_wavefront_midi_output_close (card->ics2115_external_rmidi);
card->wavefront.midi.isvirtual = 0;
- spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
}
int
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index bd679e2da154..cd5c177943aa 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1741,10 +1741,10 @@ snd_wavefront_internal_interrupt (snd_wavefront_card_t *card)
return;
}
- spin_lock(&dev->irq_lock);
- dev->irq_ok = 1;
- dev->irq_cnt++;
- spin_unlock(&dev->irq_lock);
+ scoped_guard(spinlock, &dev->irq_lock) {
+ dev->irq_ok = 1;
+ dev->irq_cnt++;
+ }
wake_up(&dev->interrupt_sleeper);
}
@@ -1796,11 +1796,11 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev,
wait_queue_entry_t wait;
init_waitqueue_entry(&wait, current);
- spin_lock_irq(&dev->irq_lock);
- add_wait_queue(&dev->interrupt_sleeper, &wait);
- dev->irq_ok = 0;
- outb (val,port);
- spin_unlock_irq(&dev->irq_lock);
+ scoped_guard(spinlock_irq, &dev->irq_lock) {
+ add_wait_queue(&dev->interrupt_sleeper, &wait);
+ dev->irq_ok = 0;
+ outb(val, port);
+ }
while (!dev->irq_ok && time_before(jiffies, timeout)) {
schedule_timeout_uninterruptible(1);
barrier();
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 1b6a80021d18..6cf88625bbc3 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -360,7 +360,6 @@ static void snd_wss_busy_wait(struct snd_wss *chip)
void snd_wss_mce_up(struct snd_wss *chip)
{
- unsigned long flags;
int timeout;
snd_wss_wait(chip);
@@ -369,7 +368,7 @@ void snd_wss_mce_up(struct snd_wss *chip)
dev_dbg(chip->card->dev,
"mce_up - auto calibration time out (0)\n");
#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
chip->mce_bit |= CS4231_MCE;
timeout = wss_inb(chip, CS4231P(REGSEL));
if (timeout == 0x80)
@@ -379,13 +378,11 @@ void snd_wss_mce_up(struct snd_wss *chip)
if (!(timeout & CS4231_MCE))
wss_outb(chip, CS4231P(REGSEL),
chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
EXPORT_SYMBOL(snd_wss_mce_up);
void snd_wss_mce_down(struct snd_wss *chip)
{
- unsigned long flags;
unsigned long end_time;
int timeout;
int hw_mask = WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK | WSS_HW_AD1848;
@@ -398,11 +395,11 @@ void snd_wss_mce_down(struct snd_wss *chip)
"mce_down [0x%lx] - auto calibration time out (0)\n",
(long)CS4231P(REGSEL));
#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->mce_bit &= ~CS4231_MCE;
- timeout = wss_inb(chip, CS4231P(REGSEL));
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ chip->mce_bit &= ~CS4231_MCE;
+ timeout = wss_inb(chip, CS4231P(REGSEL));
+ wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
+ }
if (timeout == 0x80)
dev_dbg(chip->card->dev,
"mce_down [0x%lx]: serious init problem - codec still busy\n",
@@ -496,7 +493,7 @@ static int snd_wss_trigger(struct snd_pcm_substream *substream,
snd_pcm_trigger_done(s, substream);
}
}
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (do_start) {
chip->image[CS4231_IFACE_CTRL] |= what;
if (chip->trigger)
@@ -507,7 +504,6 @@ static int snd_wss_trigger(struct snd_pcm_substream *substream,
chip->trigger(chip, what, 0);
}
snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock(&chip->reg_lock);
#if 0
snd_wss_debug(chip);
#endif
@@ -553,14 +549,11 @@ static unsigned char snd_wss_get_format(struct snd_wss *chip,
static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
{
- unsigned long flags;
mute = mute ? 0x80 : 0;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->calibrate_mute == mute) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
+ if (chip->calibrate_mute == mute)
return;
- }
if (!mute) {
snd_wss_dout(chip, CS4231_LEFT_INPUT,
chip->image[CS4231_LEFT_INPUT]);
@@ -608,20 +601,18 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
mute | chip->image[CS4231_LINE_RIGHT_OUTPUT]);
}
chip->calibrate_mute = mute;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_wss_playback_format(struct snd_wss *chip,
struct snd_pcm_hw_params *params,
unsigned char pdfr)
{
- unsigned long flags;
int full_calib = 1;
- mutex_lock(&chip->mce_mutex);
+ guard(mutex)(&chip->mce_mutex);
if (chip->hardware == WSS_HW_CS4231A ||
(chip->hardware & WSS_HW_CS4232_MASK)) {
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1] | 0x10);
@@ -633,7 +624,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
udelay(100); /* Fixes audible clicks at least on GUS MAX */
full_calib = 0;
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
} else if (chip->hardware == WSS_HW_AD1845) {
unsigned rate = params_rate(params);
@@ -646,30 +636,28 @@ static void snd_wss_playback_format(struct snd_wss *chip,
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0));
snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
full_calib = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
if (full_calib) {
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
- if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
- pdfr = (pdfr & 0xf0) |
- (chip->image[CS4231_REC_FORMAT] & 0x0f);
- } else {
- chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
+ if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
+ pdfr = (pdfr & 0xf0) |
+ (chip->image[CS4231_REC_FORMAT] & 0x0f);
+ } else {
+ chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
+ }
+ snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
}
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (chip->hardware == WSS_HW_OPL3SA2)
udelay(100); /* this seems to help */
snd_wss_mce_down(chip);
}
- mutex_unlock(&chip->mce_mutex);
}
static void snd_wss_capture_format(struct snd_wss *chip,
@@ -679,10 +667,10 @@ static void snd_wss_capture_format(struct snd_wss *chip,
unsigned long flags;
int full_calib = 1;
- mutex_lock(&chip->mce_mutex);
+ guard(mutex)(&chip->mce_mutex);
if (chip->hardware == WSS_HW_CS4231A ||
(chip->hardware & WSS_HW_CS4232_MASK)) {
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */
(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
@@ -693,7 +681,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
full_calib = 0;
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
} else if (chip->hardware == WSS_HW_AD1845) {
unsigned rate = params_rate(params);
@@ -706,12 +693,11 @@ static void snd_wss_capture_format(struct snd_wss *chip,
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0));
snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
full_calib = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
if (full_calib) {
snd_wss_mce_up(chip);
@@ -736,7 +722,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_wss_mce_down(chip);
}
- mutex_unlock(&chip->mce_mutex);
}
/*
@@ -754,10 +739,10 @@ static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
static int snd_wss_timer_start(struct snd_timer *timer)
{
- unsigned long flags;
unsigned int ticks;
struct snd_wss *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
ticks = timer->sticks;
if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
(unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
@@ -772,26 +757,22 @@ static int snd_wss_timer_start(struct snd_timer *timer)
chip->image[CS4231_ALT_FEATURE_1] |
CS4231_TIMER_ENABLE);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_wss_timer_stop(struct snd_timer *timer)
{
- unsigned long flags;
struct snd_wss *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
snd_wss_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static void snd_wss_init(struct snd_wss *chip)
{
- unsigned long flags;
-
snd_wss_calibrate_mute(chip, 1);
snd_wss_mce_down(chip);
@@ -799,15 +780,15 @@ static void snd_wss_init(struct snd_wss *chip)
dev_dbg(chip->card->dev, "init: (1)\n");
#endif
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
- CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE |
- CS4231_RECORD_PIO |
- CS4231_CALIB_MODE);
- chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
- snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
+ CS4231_PLAYBACK_PIO |
+ CS4231_RECORD_ENABLE |
+ CS4231_RECORD_PIO |
+ CS4231_CALIB_MODE);
+ chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
+ snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
+ }
snd_wss_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -815,12 +796,12 @@ static void snd_wss_init(struct snd_wss *chip)
#endif
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~CS4231_AUTOCALIB;
- snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- snd_wss_out(chip,
- CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ chip->image[CS4231_IFACE_CTRL] &= ~CS4231_AUTOCALIB;
+ snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
+ snd_wss_out(chip,
+ CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
+ }
snd_wss_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -828,16 +809,16 @@ static void snd_wss_init(struct snd_wss *chip)
chip->image[CS4231_ALT_FEATURE_1]);
#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_ALT_FEATURE_2,
- chip->image[CS4231_ALT_FEATURE_2]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_wss_out(chip, CS4231_ALT_FEATURE_2,
+ chip->image[CS4231_ALT_FEATURE_2]);
+ }
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
+ chip->image[CS4231_PLAYBK_FORMAT]);
+ }
snd_wss_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -845,11 +826,11 @@ static void snd_wss_init(struct snd_wss *chip)
#endif
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (!(chip->hardware & WSS_HW_AD1848_MASK))
- snd_wss_out(chip, CS4231_REC_FORMAT,
- chip->image[CS4231_REC_FORMAT]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ if (!(chip->hardware & WSS_HW_AD1848_MASK))
+ snd_wss_out(chip, CS4231_REC_FORMAT,
+ chip->image[CS4231_REC_FORMAT]);
+ }
snd_wss_mce_down(chip);
snd_wss_calibrate_mute(chip, 0);
@@ -860,21 +841,16 @@ static void snd_wss_init(struct snd_wss *chip)
static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
if ((chip->mode & mode) ||
- ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) {
- mutex_unlock(&chip->open_mutex);
+ ((chip->mode & WSS_MODE_OPEN) && chip->single_dma))
return -EAGAIN;
- }
if (chip->mode & WSS_MODE_OPEN) {
chip->mode |= mode;
- mutex_unlock(&chip->open_mutex);
return 0;
}
/* ok. now enable and ack CODEC IRQ */
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
snd_wss_out(chip, CS4231_IRQ_STATUS,
CS4231_PLAYBACK_IRQ |
@@ -893,10 +869,8 @@ static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
CS4231_TIMER_IRQ);
snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = mode;
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -904,12 +878,10 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
{
unsigned long flags;
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
chip->mode &= ~mode;
- if (chip->mode & WSS_MODE_OPEN) {
- mutex_unlock(&chip->open_mutex);
+ if (chip->mode & WSS_MODE_OPEN)
return;
- }
/* disable IRQ */
spin_lock_irqsave(&chip->reg_lock, flags);
if (!(chip->hardware & WSS_HW_AD1848_MASK))
@@ -943,7 +915,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = 0;
- mutex_unlock(&chip->open_mutex);
}
/*
@@ -997,18 +968,16 @@ static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_wss *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
unsigned int count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
chip->p_dma_size = size;
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
#if 0
snd_wss_debug(chip);
#endif
@@ -1032,11 +1001,10 @@ static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_wss *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
unsigned int count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
chip->c_dma_size = size;
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
@@ -1056,18 +1024,16 @@ static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
snd_wss_out(chip, CS4231_REC_UPR_CNT,
(unsigned char) (count >> 8));
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
void snd_wss_overrange(struct snd_wss *chip)
{
- unsigned long flags;
unsigned char res;
- spin_lock_irqsave(&chip->reg_lock, flags);
- res = snd_wss_in(chip, CS4231_TEST_INIT);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ res = snd_wss_in(chip, CS4231_TEST_INIT);
+ }
if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */
chip->capture_substream->runtime->overrange++;
}
@@ -1113,13 +1079,12 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
}
}
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
status = ~CS4231_ALL_IRQS | ~status;
if (chip->hardware & WSS_HW_AD1848_MASK)
wss_outb(chip, CS4231P(STATUS), 0);
else
snd_wss_out(chip, CS4231_IRQ_STATUS, status);
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
EXPORT_SYMBOL(snd_wss_interrupt);
@@ -1153,10 +1118,8 @@ static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *subst
static int snd_ad1848_probe(struct snd_wss *chip)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
- unsigned long flags;
unsigned char r;
unsigned short hardware = 0;
- int err = 0;
int i;
while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
@@ -1164,7 +1127,7 @@ static int snd_ad1848_probe(struct snd_wss *chip)
return -ENODEV;
cond_resched();
}
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
/* set CS423x MODE 1 */
snd_wss_dout(chip, CS4231_MISC_INFO, 0);
@@ -1173,19 +1136,15 @@ static int snd_ad1848_probe(struct snd_wss *chip)
r = snd_wss_in(chip, CS4231_RIGHT_INPUT);
if (r != 0x45) {
/* RMGE always high on AD1847 */
- if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) {
- err = -ENODEV;
- goto out;
- }
+ if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45)
+ return -ENODEV;
hardware = WSS_HW_AD1847;
} else {
snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa);
r = snd_wss_in(chip, CS4231_LEFT_INPUT);
/* L/RMGE always low on AT2320 */
- if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) {
- err = -ENODEV;
- goto out;
- }
+ if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa)
+ return -ENODEV;
}
/* clear pending IRQ */
@@ -1194,11 +1153,11 @@ static int snd_ad1848_probe(struct snd_wss *chip)
mb();
if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT)
- goto out;
+ return 0;
if (hardware) {
chip->hardware = hardware;
- goto out;
+ return 0;
}
r = snd_wss_in(chip, CS4231_MISC_INFO);
@@ -1227,14 +1186,11 @@ static int snd_ad1848_probe(struct snd_wss *chip)
chip->hardware = WSS_HW_AD1848;
out_mode:
snd_wss_dout(chip, CS4231_MISC_INFO, 0);
-out:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return err;
+ return 0;
}
static int snd_wss_probe(struct snd_wss *chip)
{
- unsigned long flags;
int i, id, rev, regnum;
unsigned char *ptr;
unsigned int hw;
@@ -1250,11 +1206,10 @@ static int snd_wss_probe(struct snd_wss *chip)
if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
msleep(2);
else {
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_wss_out(chip, CS4231_MISC_INFO,
CS4231_MODE2);
id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (id == 0x0a)
break; /* this is valid value */
}
@@ -1289,11 +1244,11 @@ static int snd_wss_probe(struct snd_wss *chip)
return -ENODEV; /* unknown CS4231 chip? */
}
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
- wss_outb(chip, CS4231P(STATUS), 0);
- mb();
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
+ wss_outb(chip, CS4231P(STATUS), 0);
+ mb();
+ }
if (!(chip->hardware & WSS_HW_AD1848_MASK))
chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
@@ -1328,10 +1283,10 @@ static int snd_wss_probe(struct snd_wss *chip)
ptr = (unsigned char *) &chip->image;
regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
snd_wss_mce_down(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (i = 0; i < regnum; i++) /* ok.. fill all registers */
- snd_wss_out(chip, i, *ptr++);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ for (i = 0; i < regnum; i++) /* ok.. fill all registers */
+ snd_wss_out(chip, i, *ptr++);
+ }
snd_wss_mce_up(chip);
snd_wss_mce_down(chip);
@@ -1596,12 +1551,11 @@ static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
static void snd_wss_suspend(struct snd_wss *chip)
{
int reg;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++)
- chip->image[reg] = snd_wss_in(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ for (reg = 0; reg < 32; reg++)
+ chip->image[reg] = snd_wss_in(chip, reg);
+ }
if (chip->thinkpad_flag)
snd_wss_thinkpad_twiddle(chip, 0);
}
@@ -1610,27 +1564,26 @@ static void snd_wss_suspend(struct snd_wss *chip)
static void snd_wss_resume(struct snd_wss *chip)
{
int reg;
- unsigned long flags;
/* int timeout; */
if (chip->thinkpad_flag)
snd_wss_thinkpad_twiddle(chip, 1);
snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++) {
- switch (reg) {
- case CS4231_VERSION:
- break;
- default:
- snd_wss_out(chip, reg, chip->image[reg]);
- break;
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ for (reg = 0; reg < 32; reg++) {
+ switch (reg) {
+ case CS4231_VERSION:
+ break;
+ default:
+ snd_wss_out(chip, reg, chip->image[reg]);
+ break;
+ }
}
+ /* Yamaha needs this to resume properly */
+ if (chip->hardware == WSS_HW_OPL3SA2)
+ snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
+ chip->image[CS4231_PLAYBK_FORMAT]);
}
- /* Yamaha needs this to resume properly */
- if (chip->hardware == WSS_HW_OPL3SA2)
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
#if 1
snd_wss_mce_down(chip);
#else
@@ -1639,11 +1592,11 @@ static void snd_wss_resume(struct snd_wss *chip)
include rescheduling. -- iwai
*/
snd_wss_busy_wait(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->mce_bit &= ~CS4231_MCE;
- timeout = wss_inb(chip, CS4231P(REGSEL));
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ chip->mce_bit &= ~CS4231_MCE;
+ timeout = wss_inb(chip, CS4231P(REGSEL));
+ wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
+ }
if (timeout == 0x80)
dev_err(chip->card->dev
"down [0x%lx]: serious init problem - codec still busy\n",
@@ -1944,12 +1897,10 @@ static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *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] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -1957,7 +1908,6 @@ static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned short left, right;
int change;
@@ -1966,14 +1916,13 @@ static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
return -EINVAL;
left = ucontrol->value.enumerated.item[0] << 6;
right = ucontrol->value.enumerated.item[1] << 6;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
change = left != chip->image[CS4231_LEFT_INPUT] ||
right != chip->image[CS4231_RIGHT_INPUT];
snd_wss_out(chip, CS4231_LEFT_INPUT, left);
snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -1994,15 +1943,13 @@ int snd_wss_get_single(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -2013,7 +1960,6 @@ int snd_wss_put_single(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -2025,11 +1971,10 @@ int snd_wss_put_single(struct snd_kcontrol *kcontrol,
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = (chip->image[reg] & ~(mask << shift)) | val;
change = val != chip->image[reg];
snd_wss_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
EXPORT_SYMBOL(snd_wss_put_single);
@@ -2051,7 +1996,6 @@ int snd_wss_get_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -2059,10 +2003,9 @@ int snd_wss_get_double(struct snd_kcontrol *kcontrol,
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -2075,7 +2018,6 @@ int snd_wss_put_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -2093,7 +2035,7 @@ int snd_wss_put_double(struct snd_kcontrol *kcontrol,
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (left_reg != right_reg) {
val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
@@ -2107,7 +2049,6 @@ int snd_wss_put_double(struct snd_kcontrol *kcontrol,
change = val1 != chip->image[left_reg];
snd_wss_out(chip, left_reg, val1);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
EXPORT_SYMBOL(snd_wss_put_double);
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 1af177f25c68..077fdf2181c1 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -103,9 +103,8 @@ static int read_ad1843_reg(void *priv, int reg)
{
struct snd_sgio2audio *chip = priv;
int val;
- unsigned long flags;
- spin_lock_irqsave(&chip->ad1843_lock, flags);
+ guard(spinlock_irqsave)(&chip->ad1843_lock);
writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
@@ -115,7 +114,6 @@ static int read_ad1843_reg(void *priv, int reg)
val = readq(&mace->perif.audio.codec_read);
- spin_unlock_irqrestore(&chip->ad1843_lock, flags);
return val;
}
@@ -126,9 +124,8 @@ static int write_ad1843_reg(void *priv, int reg, int word)
{
struct snd_sgio2audio *chip = priv;
int val;
- unsigned long flags;
- spin_lock_irqsave(&chip->ad1843_lock, flags);
+ guard(spinlock_irqsave)(&chip->ad1843_lock);
writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
(word << CODEC_CONTROL_WORD_SHIFT),
@@ -137,7 +134,6 @@ static int write_ad1843_reg(void *priv, int reg, int word)
val = readq(&mace->perif.audio.codec_control); /* flush bus */
udelay(200);
- spin_unlock_irqrestore(&chip->ad1843_lock, flags);
return 0;
}
@@ -351,10 +347,9 @@ static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
u64 *src;
s16 *dst;
u64 x;
- unsigned long flags;
struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
+ guard(spinlock_irqsave)(&chip->channel[ch].lock);
src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
@@ -383,7 +378,6 @@ static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */
chip->channel[ch].pos = dst_pos;
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
return ret;
}
@@ -399,10 +393,9 @@ static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
int src_pos;
u64 *dst;
s16 *src;
- unsigned long flags;
struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
+ guard(spinlock_irqsave)(&chip->channel[ch].lock);
dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
@@ -433,7 +426,6 @@ static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */
chip->channel[ch].pos = src_pos;
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
return ret;
}
@@ -584,9 +576,8 @@ static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
int ch = chan->idx;
- unsigned long flags;
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
+ guard(spinlock_irqsave)(&chip->channel[ch].lock);
/* Setup the pseudo-dma transfer pointers. */
chip->channel[ch].pos = 0;
@@ -610,7 +601,6 @@ static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
runtime->channels);
break;
}
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
return 0;
}
diff --git a/sound/mips/snd-n64.c b/sound/mips/snd-n64.c
index e1b2ff65d850..f17e63f2ff5a 100644
--- a/sound/mips/snd-n64.c
+++ b/sound/mips/snd-n64.c
@@ -81,10 +81,9 @@ static u32 n64mi_read_reg(struct n64audio *priv, const u8 reg)
static void n64audio_push(struct n64audio *priv)
{
struct snd_pcm_runtime *runtime = priv->chan.substream->runtime;
- unsigned long flags;
u32 count;
- spin_lock_irqsave(&priv->chan.lock, flags);
+ guard(spinlock_irqsave)(&priv->chan.lock);
count = priv->chan.writesize;
@@ -104,15 +103,12 @@ static void n64audio_push(struct n64audio *priv)
priv->chan.nextpos %= priv->chan.bufsize;
runtime->delay = runtime->period_size;
-
- spin_unlock_irqrestore(&priv->chan.lock, flags);
}
static irqreturn_t n64audio_isr(int irq, void *dev_id)
{
struct n64audio *priv = dev_id;
const u32 intrs = n64mi_read_reg(priv, MI_INTR_REG);
- unsigned long flags;
// Check it's ours
if (!(intrs & MI_INTR_AI))
@@ -121,11 +117,9 @@ static irqreturn_t n64audio_isr(int irq, void *dev_id)
n64audio_write_reg(priv, AI_STATUS_REG, 1);
if (priv->chan.substream && snd_pcm_running(priv->chan.substream)) {
- spin_lock_irqsave(&priv->chan.lock, flags);
-
- priv->chan.pos = priv->chan.nextpos;
-
- spin_unlock_irqrestore(&priv->chan.lock, flags);
+ scoped_guard(spinlock_irqsave, &priv->chan.lock) {
+ priv->chan.pos = priv->chan.nextpos;
+ }
snd_pcm_period_elapsed(priv->chan.substream);
if (priv->chan.substream && snd_pcm_running(priv->chan.substream))
@@ -221,7 +215,7 @@ static int n64audio_pcm_prepare(struct snd_pcm_substream *substream)
rate = 16;
n64audio_write_reg(priv, AI_BITCLOCK_REG, rate - 1);
- spin_lock_irq(&priv->chan.lock);
+ guard(spinlock_irq)(&priv->chan.lock);
/* Setup the pseudo-dma transfer pointers. */
priv->chan.pos = 0;
@@ -230,7 +224,6 @@ static int n64audio_pcm_prepare(struct snd_pcm_substream *substream)
priv->chan.writesize = snd_pcm_lib_period_bytes(substream);
priv->chan.bufsize = snd_pcm_lib_buffer_bytes(substream);
- spin_unlock_irq(&priv->chan.lock);
return 0;
}
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index 76dd2210f9ea..4b5a54da25fb 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -140,32 +140,25 @@ harmony_enable_interrupts(struct snd_harmony *h)
static void
harmony_mute(struct snd_harmony *h)
{
- unsigned long flags;
-
- spin_lock_irqsave(&h->mixer_lock, flags);
+ guard(spinlock_irqsave)(&h->mixer_lock);
harmony_wait_for_control(h);
harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE);
- spin_unlock_irqrestore(&h->mixer_lock, flags);
}
static void
harmony_unmute(struct snd_harmony *h)
{
- unsigned long flags;
-
- spin_lock_irqsave(&h->mixer_lock, flags);
+ guard(spinlock_irqsave)(&h->mixer_lock);
harmony_wait_for_control(h);
harmony_write(h, HARMONY_GAINCTL, h->st.gain);
- spin_unlock_irqrestore(&h->mixer_lock, flags);
}
static void
harmony_set_control(struct snd_harmony *h)
{
u32 ctrl;
- unsigned long flags;
- spin_lock_irqsave(&h->lock, flags);
+ guard(spinlock_irqsave)(&h->lock);
ctrl = (HARMONY_CNTL_C |
(h->st.format << 6) |
@@ -174,8 +167,6 @@ harmony_set_control(struct snd_harmony *h)
harmony_wait_for_control(h);
harmony_write(h, HARMONY_CNTL, ctrl);
-
- spin_unlock_irqrestore(&h->lock, flags);
}
static irqreturn_t
@@ -184,53 +175,53 @@ snd_harmony_interrupt(int irq, void *dev)
u32 dstatus;
struct snd_harmony *h = dev;
- spin_lock(&h->lock);
- harmony_disable_interrupts(h);
- harmony_wait_for_control(h);
- dstatus = harmony_read(h, HARMONY_DSTATUS);
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ harmony_disable_interrupts(h);
+ harmony_wait_for_control(h);
+ dstatus = harmony_read(h, HARMONY_DSTATUS);
+ }
if (dstatus & HARMONY_DSTATUS_PN) {
if (h->psubs && h->st.playing) {
- spin_lock(&h->lock);
- h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
- h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
-
- harmony_write(h, HARMONY_PNXTADD,
- h->pbuf.addr + h->pbuf.buf);
- h->stats.play_intr++;
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
+ h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
+
+ harmony_write(h, HARMONY_PNXTADD,
+ h->pbuf.addr + h->pbuf.buf);
+ h->stats.play_intr++;
+ }
snd_pcm_period_elapsed(h->psubs);
} else {
- spin_lock(&h->lock);
- harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
- h->stats.silence_intr++;
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
+ h->stats.silence_intr++;
+ }
}
}
if (dstatus & HARMONY_DSTATUS_RN) {
if (h->csubs && h->st.capturing) {
- spin_lock(&h->lock);
- h->cbuf.buf += h->cbuf.count;
- h->cbuf.buf %= h->cbuf.size;
-
- harmony_write(h, HARMONY_RNXTADD,
- h->cbuf.addr + h->cbuf.buf);
- h->stats.rec_intr++;
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ h->cbuf.buf += h->cbuf.count;
+ h->cbuf.buf %= h->cbuf.size;
+
+ harmony_write(h, HARMONY_RNXTADD,
+ h->cbuf.addr + h->cbuf.buf);
+ h->stats.rec_intr++;
+ }
snd_pcm_period_elapsed(h->csubs);
} else {
- spin_lock(&h->lock);
- harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
- h->stats.graveyard_intr++;
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
+ h->stats.graveyard_intr++;
+ }
}
}
- spin_lock(&h->lock);
- harmony_enable_interrupts(h);
- spin_unlock(&h->lock);
+ scoped_guard(spinlock, &h->lock) {
+ harmony_enable_interrupts(h);
+ }
return IRQ_HANDLED;
}
@@ -297,7 +288,7 @@ snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd)
if (h->st.capturing)
return -EBUSY;
- spin_lock(&h->lock);
+ guard(spinlock)(&h->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
h->st.playing = 1;
@@ -316,11 +307,9 @@ snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd)
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_SUSPEND:
default:
- spin_unlock(&h->lock);
snd_BUG();
return -EINVAL;
}
- spin_unlock(&h->lock);
return 0;
}
@@ -333,7 +322,7 @@ snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd)
if (h->st.playing)
return -EBUSY;
- spin_lock(&h->lock);
+ guard(spinlock)(&h->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
h->st.capturing = 1;
@@ -352,11 +341,9 @@ snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd)
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_SUSPEND:
default:
- spin_unlock(&h->lock);
snd_BUG();
return -EINVAL;
}
- spin_unlock(&h->lock);
return 0;
}
@@ -674,7 +661,7 @@ snd_harmony_volume_get(struct snd_kcontrol *kc,
int invert = (kc->private_value >> 24) & 0xff;
int left, right;
- spin_lock_irq(&h->mixer_lock);
+ guard(spinlock_irq)(&h->mixer_lock);
left = (h->st.gain >> shift_left) & mask;
right = (h->st.gain >> shift_right) & mask;
@@ -687,8 +674,6 @@ snd_harmony_volume_get(struct snd_kcontrol *kc,
if (shift_left != shift_right)
ucontrol->value.integer.value[1] = right;
- spin_unlock_irq(&h->mixer_lock);
-
return 0;
}
@@ -704,7 +689,7 @@ snd_harmony_volume_put(struct snd_kcontrol *kc,
int left, right;
int old_gain = h->st.gain;
- spin_lock_irq(&h->mixer_lock);
+ guard(spinlock_irq)(&h->mixer_lock);
left = ucontrol->value.integer.value[0] & mask;
if (invert)
@@ -722,8 +707,6 @@ snd_harmony_volume_put(struct snd_kcontrol *kc,
snd_harmony_set_new_gain(h);
- spin_unlock_irq(&h->mixer_lock);
-
return h->st.gain != old_gain;
}
@@ -743,13 +726,11 @@ snd_harmony_captureroute_get(struct snd_kcontrol *kc,
struct snd_harmony *h = snd_kcontrol_chip(kc);
int value;
- spin_lock_irq(&h->mixer_lock);
+ guard(spinlock_irq)(&h->mixer_lock);
value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
ucontrol->value.enumerated.item[0] = value;
- spin_unlock_irq(&h->mixer_lock);
-
return 0;
}
@@ -761,7 +742,7 @@ snd_harmony_captureroute_put(struct snd_kcontrol *kc,
int value;
int old_gain = h->st.gain;
- spin_lock_irq(&h->mixer_lock);
+ guard(spinlock_irq)(&h->mixer_lock);
value = ucontrol->value.enumerated.item[0] & 1;
h->st.gain &= ~HARMONY_GAIN_IS_MASK;
@@ -769,8 +750,6 @@ snd_harmony_captureroute_put(struct snd_kcontrol *kc,
snd_harmony_set_new_gain(h);
- spin_unlock_irq(&h->mixer_lock);
-
return h->st.gain != old_gain;
}
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index cd60c856a92e..c54bdefa5afe 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -326,11 +326,10 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh
{
if (!snd_ac97_valid_reg(ac97, reg))
return;
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
ac97->regs[reg] = value;
ac97->bus->ops->write(ac97, reg, value);
set_bit(reg, ac97->reg_accessed);
- mutex_unlock(&ac97->reg_mutex);
}
EXPORT_SYMBOL(snd_ac97_write_cache);
@@ -353,14 +352,13 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va
if (!snd_ac97_valid_reg(ac97, reg))
return -EINVAL;
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
change = ac97->regs[reg] != value;
if (change) {
ac97->regs[reg] = value;
ac97->bus->ops->write(ac97, reg, value);
}
set_bit(reg, ac97->reg_accessed);
- mutex_unlock(&ac97->reg_mutex);
return change;
}
@@ -381,14 +379,10 @@ EXPORT_SYMBOL(snd_ac97_update);
*/
int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value)
{
- int change;
-
if (!snd_ac97_valid_reg(ac97, reg))
return -EINVAL;
- mutex_lock(&ac97->reg_mutex);
- change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
- mutex_unlock(&ac97->reg_mutex);
- return change;
+ guard(mutex)(&ac97->reg_mutex);
+ return snd_ac97_update_bits_nolock(ac97, reg, mask, value);
}
EXPORT_SYMBOL(snd_ac97_update_bits);
@@ -416,12 +410,12 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
int change;
unsigned short old, new, cfg;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
old = ac97->spec.ad18xx.pcmreg[codec];
new = (old & ~mask) | (value & mask);
change = old != new;
if (change) {
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
ac97->spec.ad18xx.pcmreg[codec] = new;
/* select single codec */
@@ -433,9 +427,7 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
/* select all codecs */
ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
cfg | 0x7000);
- mutex_unlock(&ac97->reg_mutex);
}
- mutex_unlock(&ac97->page_mutex);
return change;
}
@@ -716,12 +708,11 @@ static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff;
- mutex_unlock(&ac97->reg_mutex);
return 0;
}
@@ -760,7 +751,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_
}
}
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
change = ac97->spdif_status != new;
ac97->spdif_status = new;
@@ -794,7 +785,6 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
}
}
- mutex_unlock(&ac97->reg_mutex);
return change;
}
@@ -811,7 +801,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
value = (ucontrol->value.integer.value[0] & mask);
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
mask <<= shift;
value <<= shift;
old = snd_ac97_read_cache(ac97, reg);
@@ -825,7 +815,6 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
if (extst & AC97_EA_SPDIF)
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
}
- mutex_unlock(&ac97->reg_mutex);
return change;
}
@@ -936,10 +925,9 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
int codec = kcontrol->private_value & 3;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
- mutex_unlock(&ac97->page_mutex);
return 0;
}
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 3002be9d88f3..64cc39dd2008 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -54,12 +54,11 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi
unsigned short page_save;
int ret;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
ret = snd_ac97_update_bits(ac97, reg, mask, value);
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
- mutex_unlock(&ac97->page_mutex); /* unlock paging */
return ret;
}
@@ -976,12 +975,11 @@ static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
int err;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010,
(ucontrol->value.integer.value[0] & 1) << 4);
snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0);
- mutex_unlock(&ac97->page_mutex);
return err;
}
@@ -3699,7 +3697,7 @@ static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
unsigned short datpag, uaj;
struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
- mutex_lock(&pac97->page_mutex);
+ guard(mutex)(&pac97->page_mutex);
datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
@@ -3708,7 +3706,6 @@ static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
vt1618_uaj[kcontrol->private_value].mask;
snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
- mutex_unlock(&pac97->page_mutex);
ucontrol->value.enumerated.item[0] = uaj >>
vt1618_uaj[kcontrol->private_value].shift;
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index 5fee8e89790f..4715d88ff8f4 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -192,7 +192,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate)
mask = AC97_SC_SPSR_MASK;
}
- mutex_lock(&ac97->reg_mutex);
+ guard(mutex)(&ac97->reg_mutex);
old = snd_ac97_read(ac97, reg) & mask;
if (old != bits) {
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
@@ -217,7 +217,6 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate)
ac97->spdif_status = sbits;
}
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
- mutex_unlock(&ac97->reg_mutex);
return 0;
}
@@ -571,33 +570,31 @@ int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
return err;
}
}
- spin_lock_irq(&pcm->bus->bus_lock);
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- ok_flag = 0;
- for (cidx = 0; cidx < 4; cidx++) {
- if (bus->used_slots[pcm->stream][cidx] & (1 << i)) {
- spin_unlock_irq(&pcm->bus->bus_lock);
- err = -EBUSY;
- goto error;
+ scoped_guard(spinlock_irq, &pcm->bus->bus_lock) {
+ for (i = 3; i < 12; i++) {
+ if (!(slots & (1 << i)))
+ continue;
+ ok_flag = 0;
+ for (cidx = 0; cidx < 4; cidx++) {
+ if (bus->used_slots[pcm->stream][cidx] & (1 << i)) {
+ err = -EBUSY;
+ goto error;
+ }
+ if (pcm->r[r].rslots[cidx] & (1 << i)) {
+ bus->used_slots[pcm->stream][cidx] |= (1 << i);
+ ok_flag++;
+ }
}
- if (pcm->r[r].rslots[cidx] & (1 << i)) {
- bus->used_slots[pcm->stream][cidx] |= (1 << i);
- ok_flag++;
+ if (!ok_flag) {
+ dev_err(bus->card->dev,
+ "cannot find configuration for AC97 slot %i\n",
+ i);
+ err = -EAGAIN;
+ goto error;
}
}
- if (!ok_flag) {
- spin_unlock_irq(&pcm->bus->bus_lock);
- dev_err(bus->card->dev,
- "cannot find configuration for AC97 slot %i\n",
- i);
- err = -EAGAIN;
- goto error;
- }
+ pcm->cur_dbl = r;
}
- pcm->cur_dbl = r;
- spin_unlock_irq(&pcm->bus->bus_lock);
for (i = 3; i < 12; i++) {
if (!(slots & (1 << i)))
continue;
@@ -665,7 +662,7 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm)
#endif
bus = pcm->bus;
- spin_lock_irq(&pcm->bus->bus_lock);
+ guard(spinlock_irq)(&pcm->bus->bus_lock);
for (i = 3; i < 12; i++) {
if (!(slots & (1 << i)))
continue;
@@ -674,7 +671,6 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm)
}
pcm->aslots = 0;
pcm->cur_dbl = 0;
- spin_unlock_irq(&pcm->bus->bus_lock);
return 0;
}
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index 2df3ba9a08dc..1c9d76994b3a 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -329,7 +329,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf
{
struct snd_ac97 *ac97 = entry->private_data;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
int idx;
for (idx = 0; idx < 3; idx++)
@@ -355,7 +355,6 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf
} else {
snd_ac97_proc_read_main(ac97, buffer, 0);
}
- mutex_unlock(&ac97->page_mutex);
}
#ifdef CONFIG_SND_DEBUG
@@ -365,7 +364,8 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in
struct snd_ac97 *ac97 = entry->private_data;
char line[64];
unsigned int reg, val;
- mutex_lock(&ac97->page_mutex);
+
+ guard(mutex)(&ac97->page_mutex);
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
@@ -373,7 +373,6 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in
if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
snd_ac97_write_cache(ac97, reg, val);
}
- mutex_unlock(&ac97->page_mutex);
}
#endif
@@ -392,7 +391,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry,
{
struct snd_ac97 *ac97 = entry->private_data;
- mutex_lock(&ac97->page_mutex);
+ guard(mutex)(&ac97->page_mutex);
if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
int idx;
@@ -408,7 +407,6 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry,
} else {
snd_ac97_proc_regs_read_main(ac97, buffer, 0);
}
- mutex_unlock(&ac97->page_mutex);
}
void snd_ac97_proc_init(struct snd_ac97 * ac97)
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 020cbb467e7e..f4ec404c0d15 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -353,7 +353,7 @@ snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
reg |= AD_DS_WSMC_WAST;
/* let's make sure we don't clobber ourselves */
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
chip->wave.size = size;
chip->wave.reg = reg;
@@ -372,8 +372,6 @@ snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
/* writes flush */
ad1889_readw(chip, AD_DS_WSMC);
- spin_unlock_irq(&chip->lock);
-
dev_dbg(chip->card->dev,
"prepare playback: addr = 0x%x, count = %u, size = %u, reg = 0x%x, rate = %u\n",
chip->wave.addr, count, size, reg, rt->rate);
@@ -403,7 +401,7 @@ snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
reg |= AD_DS_RAMC_ADST;
/* let's make sure we don't clobber ourselves */
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
chip->ramc.size = size;
chip->ramc.reg = reg;
@@ -419,8 +417,6 @@ snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
/* writes flush */
ad1889_readw(chip, AD_DS_RAMC);
- spin_unlock_irq(&chip->lock);
-
dev_dbg(chip->card->dev,
"prepare capture: addr = 0x%x, count = %u, size = %u, reg = 0x%x, rate = %u\n",
chip->ramc.addr, count, size, reg, rt->rate);
@@ -775,7 +771,7 @@ snd_ad1889_free(struct snd_card *card)
{
struct snd_ad1889 *chip = card->private_data;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
ad1889_mute(chip);
@@ -785,8 +781,6 @@ snd_ad1889_free(struct snd_card *card)
/* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */
-
- spin_unlock_irq(&chip->lock);
}
static int
diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c
index e54812bfb2c6..cdad47e4098d 100644
--- a/sound/pci/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -77,9 +77,8 @@ static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
int invert = (kcontrol->private_value >> 22) & 1;
int val;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
val = (ak4531->regs[reg] >> shift) & mask;
- mutex_unlock(&ak4531->reg_mutex);
if (invert) {
val = mask - val;
}
@@ -102,11 +101,10 @@ static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
val = mask - val;
}
val <<= shift;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
val = (ak4531->regs[reg] & ~(mask << shift)) | val;
change = val != ak4531->regs[reg];
ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
- mutex_unlock(&ak4531->reg_mutex);
return change;
}
@@ -146,10 +144,9 @@ static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
int invert = (kcontrol->private_value >> 22) & 1;
int left, right;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
left = (ak4531->regs[left_reg] >> left_shift) & mask;
right = (ak4531->regs[right_reg] >> right_shift) & mask;
- mutex_unlock(&ak4531->reg_mutex);
if (invert) {
left = mask - left;
right = mask - right;
@@ -179,7 +176,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
left <<= left_shift;
right <<= right_shift;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
if (left_reg == right_reg) {
left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
change = left != ak4531->regs[left_reg];
@@ -191,7 +188,6 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
}
- mutex_unlock(&ak4531->reg_mutex);
return change;
}
@@ -218,12 +214,11 @@ static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
int right_shift = (kcontrol->private_value >> 24) & 0x0f;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
- mutex_unlock(&ak4531->reg_mutex);
return 0;
}
@@ -237,7 +232,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl
int change;
int val1, val2;
- mutex_lock(&ak4531->reg_mutex);
+ guard(mutex)(&ak4531->reg_mutex);
val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
@@ -247,7 +242,6 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl
change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
- mutex_unlock(&ak4531->reg_mutex);
return change;
}
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index a6e499e0ceda..571d89a6a8da 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -911,13 +911,12 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
dev_dbg(codec->card->dev, "alloc_voice: type=%d rec=%d\n", type, rec);
- spin_lock_irq(&codec->voice_alloc);
+ guard(spinlock_irq)(&codec->voice_alloc);
if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
snd_ali_find_free_channel(codec,rec);
if (idx < 0) {
dev_err(codec->card->dev, "ali_alloc_voice: err.\n");
- spin_unlock_irq(&codec->voice_alloc);
return NULL;
}
pvoice = &(codec->synth.voices[idx]);
@@ -925,10 +924,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
pvoice->use = 1;
pvoice->pcm = 1;
pvoice->mode = rec;
- spin_unlock_irq(&codec->voice_alloc);
return pvoice;
}
- spin_unlock_irq(&codec->voice_alloc);
return NULL;
}
@@ -943,16 +940,16 @@ static void snd_ali_free_voice(struct snd_ali * codec,
if (!pvoice->use)
return;
snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
- spin_lock_irq(&codec->voice_alloc);
- private_free = pvoice->private_free;
- private_data = pvoice->private_data;
- pvoice->private_free = NULL;
- pvoice->private_data = NULL;
- if (pvoice->pcm)
- snd_ali_free_channel_pcm(codec, pvoice->number);
- pvoice->use = pvoice->pcm = pvoice->synth = 0;
- pvoice->substream = NULL;
- spin_unlock_irq(&codec->voice_alloc);
+ scoped_guard(spinlock_irq, &codec->voice_alloc) {
+ private_free = pvoice->private_free;
+ private_data = pvoice->private_data;
+ pvoice->private_free = NULL;
+ pvoice->private_data = NULL;
+ if (pvoice->pcm)
+ snd_ali_free_channel_pcm(codec, pvoice->number);
+ pvoice->use = pvoice->pcm = pvoice->synth = 0;
+ pvoice->substream = NULL;
+ }
if (private_free)
private_free(private_data);
}
@@ -1109,7 +1106,7 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream,
snd_pcm_trigger_done(s, substream);
}
}
- spin_lock(&codec->reg_lock);
+ guard(spinlock)(&codec->reg_lock);
if (!do_start)
outl(what, ALI_REG(codec, ALI_STOP));
val = inl(ALI_REG(codec, ALI_AINTEN));
@@ -1121,7 +1118,6 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream,
if (do_start)
outl(what, ALI_REG(codec, ALI_START));
dev_dbg(codec->card->dev, "trigger: what=%xh whati=%xh\n", what, whati);
- spin_unlock(&codec->reg_lock);
return 0;
}
@@ -1189,8 +1185,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
dev_dbg(codec->card->dev, "playback_prepare ...\n");
- spin_lock_irq(&codec->reg_lock);
-
+ guard(spinlock_irq)(&codec->reg_lock);
+
/* set Delta (rate) value */
Delta = snd_ali_convert_rate(runtime->rate, 0);
@@ -1259,7 +1255,6 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
CTRL,
EC);
}
- spin_unlock_irq(&codec->reg_lock);
return 0;
}
@@ -1360,14 +1355,11 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream)
struct snd_ali_voice *pvoice = runtime->private_data;
unsigned int cso;
- spin_lock(&codec->reg_lock);
- if (!pvoice->running) {
- spin_unlock(&codec->reg_lock);
+ guard(spinlock)(&codec->reg_lock);
+ if (!pvoice->running)
return 0;
- }
outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
- spin_unlock(&codec->reg_lock);
dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso);
cso %= runtime->buffer_size;
@@ -1382,14 +1374,11 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
struct snd_ali_voice *pvoice = runtime->private_data;
unsigned int cso;
- spin_lock(&codec->reg_lock);
- if (!pvoice->running) {
- spin_unlock(&codec->reg_lock);
+ guard(spinlock)(&codec->reg_lock);
+ if (!pvoice->running)
return 0;
- }
outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
- spin_unlock(&codec->reg_lock);
cso %= runtime->buffer_size;
return cso;
@@ -1693,7 +1682,7 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&codec->reg_lock);
+ guard(spinlock_irq)(&codec->reg_lock);
switch (kcontrol->private_value) {
case 0:
spdif_enable = (codec->spdif_mask & 0x02) ? 1 : 0;
@@ -1709,7 +1698,6 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
break;
}
ucontrol->value.integer.value[0] = spdif_enable;
- spin_unlock_irq(&codec->reg_lock);
return 0;
}
@@ -1721,7 +1709,7 @@ static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&codec->reg_lock);
+ guard(spinlock_irq)(&codec->reg_lock);
switch (kcontrol->private_value) {
case 0:
change = (codec->spdif_mask & 0x02) ? 1 : 0;
@@ -1766,7 +1754,6 @@ static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
default:
break;
}
- spin_unlock_irq(&codec->reg_lock);
return change;
}
@@ -1833,7 +1820,7 @@ static int ali_suspend(struct device *dev)
for (i = 0; i < chip->num_of_codecs; i++)
snd_ac97_suspend(chip->ac97[i]);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
/* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */
@@ -1857,7 +1844,6 @@ static int ali_suspend(struct device *dev)
/* stop all HW channel */
outl(0xffffffff, ALI_REG(chip, ALI_STOP));
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1868,27 +1854,25 @@ static int ali_resume(struct device *dev)
struct snd_ali_image *im = &chip->image;
int i, j;
- spin_lock_irq(&chip->reg_lock);
-
- for (i = 0; i < ALI_CHANNELS; i++) {
- outb(i, ALI_REG(chip, ALI_GC_CIR));
- for (j = 0; j < ALI_CHANNEL_REGS; j++)
- outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));
- }
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ for (i = 0; i < ALI_CHANNELS; i++) {
+ outb(i, ALI_REG(chip, ALI_GC_CIR));
+ for (j = 0; j < ALI_CHANNEL_REGS; j++)
+ outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));
+ }
- for (i = 0; i < ALI_GLOBAL_REGS; i++) {
- if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
- (i*4 == ALI_START))
- continue;
- outl(im->regs[i], ALI_REG(chip, i*4));
+ for (i = 0; i < ALI_GLOBAL_REGS; i++) {
+ if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
+ (i*4 == ALI_START))
+ continue;
+ outl(im->regs[i], ALI_REG(chip, i*4));
+ }
+
+ /* start HW channel */
+ outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
+ /* restore IRQ enable bits */
+ outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
}
-
- /* start HW channel */
- outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
- /* restore IRQ enable bits */
- outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
-
- spin_unlock_irq(&chip->reg_lock);
for (i = 0 ; i < chip->num_of_codecs; i++)
snd_ac97_resume(chip->ac97[i]);
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index f9e8424dc77f..733e84def5a7 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -402,7 +402,7 @@ static int snd_als300_playback_prepare(struct snd_pcm_substream *substream)
unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
tmp &= ~TRANSFER_START;
@@ -419,7 +419,6 @@ static int snd_als300_playback_prepare(struct snd_pcm_substream *substream)
runtime->dma_addr);
snd_als300_gcr_write(chip->port, PLAYBACK_END,
runtime->dma_addr + buffer_bytes - 1);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -431,7 +430,7 @@ static int snd_als300_capture_prepare(struct snd_pcm_substream *substream)
unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL);
tmp &= ~TRANSFER_START;
@@ -448,7 +447,6 @@ static int snd_als300_capture_prepare(struct snd_pcm_substream *substream)
runtime->dma_addr);
snd_als300_gcr_write(chip->port, RECORD_END,
runtime->dma_addr + buffer_bytes - 1);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -463,7 +461,7 @@ static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd)
data = substream->runtime->private_data;
reg = data->control_register;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -492,7 +490,6 @@ static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd)
snd_als300_dbgplay("TRIGGER INVALID\n");
ret = -EINVAL;
}
- spin_unlock(&chip->reg_lock);
return ret;
}
@@ -506,10 +503,10 @@ static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream)
data = substream->runtime->private_data;
period_bytes = snd_pcm_lib_period_bytes(substream);
- spin_lock(&chip->reg_lock);
- current_ptr = (u16) snd_als300_gcr_read(chip->port,
- data->block_counter_register) + 4;
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ current_ptr = (u16) snd_als300_gcr_read(chip->port,
+ data->block_counter_register) + 4;
+ }
if (current_ptr > period_bytes)
current_ptr = 0;
else
@@ -563,10 +560,9 @@ static int snd_als300_new_pcm(struct snd_als300 *chip)
static void snd_als300_init(struct snd_als300 *chip)
{
- unsigned long flags;
u32 tmp;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16)
& 0x0000000F;
/* Setup DRAM */
@@ -591,7 +587,6 @@ static void snd_als300_init(struct snd_als300 *chip)
tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL,
tmp & ~TRANSFER_START);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static int snd_als300_create(struct snd_card *card,
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index eb159497c905..33034e07b3d6 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -369,14 +369,14 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
count >>= 1;
count--;
- spin_lock_irq(&chip->reg_lock);
- snd_als4000_set_rate(chip, runtime->rate);
- snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
- spin_unlock_irq(&chip->reg_lock);
- spin_lock_irq(&chip->mixer_lock);
- snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
- snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
- spin_unlock_irq(&chip->mixer_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ snd_als4000_set_rate(chip, runtime->rate);
+ snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
+ }
+ scoped_guard(spinlock_irq, &chip->mixer_lock) {
+ snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
+ snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
+ }
return 0;
}
@@ -402,7 +402,7 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
* reordering, ...). Something seems to get enabled on playback
* that I haven't found out how to disable again, which then causes
* the switching pops to reach the speakers the next time here. */
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_als4000_set_rate(chip, runtime->rate);
snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
@@ -413,7 +413,6 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
snd_sbdsp_command(chip, count & 0xff);
snd_sbdsp_command(chip, count >> 8);
snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -429,7 +428,7 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
Probably need to take reg_lock as outer (or inner??) lock, too.
(or serialize both lock operations? probably not, though... - racy?)
*/
- spin_lock(&chip->mixer_lock);
+ guard(spinlock)(&chip->mixer_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -447,7 +446,6 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
result = -EINVAL;
break;
}
- spin_unlock(&chip->mixer_lock);
return result;
}
@@ -456,7 +454,7 @@ static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int
struct snd_sb *chip = snd_pcm_substream_chip(substream);
int result = 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -472,7 +470,6 @@ static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int
result = -EINVAL;
break;
}
- spin_unlock(&chip->reg_lock);
return result;
}
@@ -481,9 +478,9 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s
struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned int result;
- spin_lock(&chip->reg_lock);
- result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
+ }
result &= 0xffff;
return bytes_to_frames( substream->runtime, result );
}
@@ -493,9 +490,9 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
struct snd_sb *chip = snd_pcm_substream_chip(substream);
unsigned result;
- spin_lock(&chip->reg_lock);
- result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
+ }
result &= 0xffff;
return bytes_to_frames( substream->runtime, result );
}
@@ -536,10 +533,10 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
snd_als4k_iobase_writeb(chip->alt_port,
ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus);
- spin_lock(&chip->mixer_lock);
- /* SPECS_PAGE: 20 */
- sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
- spin_unlock(&chip->mixer_lock);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ /* SPECS_PAGE: 20 */
+ sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
+ }
if (sb_irqstatus & SB_IRQTYPE_8BIT)
snd_sb_ack_8bit(chip);
@@ -709,18 +706,18 @@ static void snd_als4000_configure(struct snd_sb *chip)
int i;
/* do some more configuration */
- spin_lock_irq(&chip->mixer_lock);
- tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
- snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
- tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
- /* always select DMA channel 0, since we do not actually use DMA
- * SPECS_PAGE: 19/20 */
- snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
- snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
- tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
- spin_unlock_irq(&chip->mixer_lock);
+ scoped_guard(spinlock_irq, &chip->mixer_lock) {
+ tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
+ snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
+ tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
+ /* always select DMA channel 0, since we do not actually use DMA
+ * SPECS_PAGE: 19/20 */
+ snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
+ snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
+ tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
+ }
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
/* enable interrupts */
snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
@@ -731,7 +728,6 @@ static void snd_als4000_configure(struct snd_sb *chip)
/* enable burst mode to prevent dropouts during high PCI bus usage */
snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
(snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04);
- spin_unlock_irq(&chip->reg_lock);
}
#ifdef SUPPORT_JOYSTICK
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 8419f2b6e589..fd0a67b772d1 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -982,12 +982,12 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
err = hpi_outstream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream);
hpi_handle_error(err);
- if (err)
+ if (err) {
kfree(dpcm);
- if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
- return -EBUSY;
- if (err)
+ if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
+ return -EBUSY;
return -EIO;
+ }
/*? also check ASI5000 samplerate source
If external, only support external rate.
@@ -1156,12 +1156,12 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
err = hpi_handle_error(
hpi_instream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream));
- if (err)
+ if (err) {
kfree(dpcm);
- if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
- return -EBUSY;
- if (err)
+ if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
+ return -EBUSY;
return -EIO;
+ }
timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
dpcm->substream = substream;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 4f544950ee7b..2a0c59d5afa5 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -345,7 +345,6 @@ static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
{
unsigned int i;
u32 addr, desc_addr;
- unsigned long flags;
if (periods > ATI_MAX_DESCRIPTORS)
return -ENOMEM;
@@ -363,11 +362,11 @@ static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
return 0;
/* reset DMA before changing the descriptor table */
- spin_lock_irqsave(&chip->reg_lock, flags);
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- dma->ops->enable_dma(chip, 0);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ writel(0, chip->remap_addr + dma->ops->llp_offset);
+ dma->ops->enable_dma(chip, 0);
+ dma->ops->enable_dma(chip, 1);
+ }
/* fill the entries */
addr = (u32)substream->runtime->dma_addr;
@@ -711,7 +710,7 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
!dma->ops->flush_dma))
return -EINVAL;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -745,7 +744,6 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_atiixp_check_bus_busy(chip);
}
}
- spin_unlock(&chip->reg_lock);
return err;
}
@@ -859,7 +857,7 @@ static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream)
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
if (chip->spdif_over_aclink) {
unsigned int data;
/* enable slots 10/11 */
@@ -877,7 +875,6 @@ static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream)
atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK, 0);
atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_SPDF, 0);
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -887,7 +884,7 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
struct atiixp *chip = snd_pcm_substream_chip(substream);
unsigned int data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
switch (substream->runtime->channels) {
case 8:
@@ -922,7 +919,6 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
atiixp_update(chip, 6CH_REORDER, ATI_REG_6CH_REORDER_EN,
substream->runtime->channels >= 6 ? ATI_REG_6CH_REORDER_EN: 0);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -931,11 +927,10 @@ static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_IN,
substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
ATI_REG_CMD_INTERLEAVE_IN : 0);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1043,9 +1038,9 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
runtime->private_data = dma;
/* enable DMA bits */
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ dma->ops->enable_dma(chip, 1);
+ }
dma->opened = 1;
return 0;
@@ -1058,9 +1053,9 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
/* disable DMA bits */
if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 0);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ dma->ops->enable_dma(chip, 0);
+ }
dma->substream = NULL;
dma->opened = 0;
return 0;
@@ -1073,9 +1068,8 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
struct atiixp *chip = snd_pcm_substream_chip(substream);
int err;
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
- mutex_unlock(&chip->open_mutex);
if (err < 0)
return err;
substream->runtime->hw.channels_max = chip->max_channels;
@@ -1089,11 +1083,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
- mutex_unlock(&chip->open_mutex);
- return err;
+
+ guard(mutex)(&chip->open_mutex);
+ return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
}
static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
@@ -1111,27 +1103,23 @@ static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream)
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
+
+ guard(mutex)(&chip->open_mutex);
if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2);
+ return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2);
else
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1);
- mutex_unlock(&chip->open_mutex);
- return err;
+ return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1);
}
static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream)
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
+
+ guard(mutex)(&chip->open_mutex);
if (chip->spdif_over_aclink)
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
+ return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
else
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]);
- mutex_unlock(&chip->open_mutex);
- return err;
+ return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]);
}
/* AC97 playback */
@@ -1355,10 +1343,9 @@ static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
if (status & CODEC_CHECK_BITS) {
unsigned int detected;
detected = status & CODEC_CHECK_BITS;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
chip->codec_not_ready_bits |= detected;
atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
- spin_unlock(&chip->reg_lock);
}
/* ack */
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index f7417c2bb477..91f31e2ad3d3 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -314,7 +314,6 @@ static int atiixp_build_dma_packets(struct atiixp_modem *chip,
{
unsigned int i;
u32 addr, desc_addr;
- unsigned long flags;
if (periods > ATI_MAX_DESCRIPTORS)
return -ENOMEM;
@@ -330,11 +329,11 @@ static int atiixp_build_dma_packets(struct atiixp_modem *chip,
return 0;
/* reset DMA before changing the descriptor table */
- spin_lock_irqsave(&chip->reg_lock, flags);
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- dma->ops->enable_dma(chip, 0);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ writel(0, chip->remap_addr + dma->ops->llp_offset);
+ dma->ops->enable_dma(chip, 0);
+ dma->ops->enable_dma(chip, 1);
+ }
/* fill the entries */
addr = (u32)substream->runtime->dma_addr;
@@ -661,7 +660,7 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
!dma->ops->flush_dma))
return -EINVAL;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch(cmd) {
case SNDRV_PCM_TRIGGER_START:
dma->ops->enable_transfer(chip, 1);
@@ -682,7 +681,6 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_atiixp_check_bus_busy(chip);
}
}
- spin_unlock(&chip->reg_lock);
return err;
}
@@ -753,13 +751,12 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
unsigned int data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
/* set output threshold */
data = atiixp_read(chip, MODEM_OUT_FIFO);
data &= ~ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK;
data |= 0x04 << ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT;
atiixp_write(chip, MODEM_OUT_FIFO, data);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -864,9 +861,9 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
runtime->private_data = dma;
/* enable DMA bits */
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ dma->ops->enable_dma(chip, 1);
+ }
dma->opened = 1;
return 0;
@@ -879,9 +876,9 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
/* disable DMA bits */
if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 0);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ dma->ops->enable_dma(chip, 0);
+ }
dma->substream = NULL;
dma->opened = 0;
return 0;
@@ -892,24 +889,17 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
{
struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
- mutex_unlock(&chip->open_mutex);
- if (err < 0)
- return err;
- return 0;
+ guard(mutex)(&chip->open_mutex);
+ return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
}
static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
{
struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
- mutex_unlock(&chip->open_mutex);
- return err;
+
+ guard(mutex)(&chip->open_mutex);
+ return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
}
static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
@@ -1020,10 +1010,9 @@ static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
if (status & CODEC_CHECK_BITS) {
unsigned int detected;
detected = status & CODEC_CHECK_BITS;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
chip->codec_not_ready_bits |= detected;
atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
- spin_unlock(&chip->reg_lock);
}
/* ack */
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 1d7aab14579e..e2c501f4394c 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -347,7 +347,7 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned long period_size, buffer_size;
- mutex_lock(&chip->mtx);
+ guard(mutex)(&chip->mtx);
period_size = snd_pcm_lib_period_bytes(substream);
buffer_size = snd_pcm_lib_buffer_bytes(substream);
@@ -363,8 +363,6 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream)
snd_pcm_period_elapsed,
(void *)substream);
- mutex_unlock(&chip->mtx);
-
return 0;
}
@@ -376,7 +374,7 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned long period_size, buffer_size;
- mutex_lock(&chip->mtx);
+ guard(mutex)(&chip->mtx);
period_size = snd_pcm_lib_period_bytes(substream);
buffer_size = snd_pcm_lib_buffer_bytes(substream);
@@ -392,8 +390,6 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
snd_pcm_period_elapsed,
(void *)substream);
- mutex_unlock(&chip->mtx);
-
return 0;
}
@@ -401,10 +397,10 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
int cmd)
{
- int status = 0;
struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
struct aw2 *chip = pcm_device->chip;
- spin_lock(&chip->reg_lock);
+
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146,
@@ -417,20 +413,19 @@ static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
stream_number);
break;
default:
- status = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return status;
+ return 0;
}
/* capture trigger callback */
static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
int cmd)
{
- int status = 0;
struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
struct aw2 *chip = pcm_device->chip;
- spin_lock(&chip->reg_lock);
+
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146,
@@ -443,10 +438,9 @@ static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
stream_number);
break;
default:
- status = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return status;
+ return 0;
}
/* playback pointer callback */
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index b33344f65b8c..6cdf76e2b7d2 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1201,7 +1201,6 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
unsigned int channels
)
{
- unsigned long flags;
u16 val = 0xff00;
u8 freq = 0;
@@ -1244,7 +1243,7 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
if (format_width == 16)
val |= SOUNDFORMAT_FLAG_16BIT;
- spin_lock_irqsave(codec->lock, flags);
+ guard(spinlock_irqsave)(codec->lock);
/* set bitrate/format */
snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1266,8 +1265,6 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
DMA_EPILOGUE_SOMETHING |
DMA_SOMETHING_ELSE
);
-
- spin_unlock_irqrestore(codec->lock, flags);
}
static inline void
@@ -1373,8 +1370,6 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
if (!codec->running) {
/* AZF3328 uses a two buffer pointer DMA transfer approach */
- unsigned long flags;
-
/* width 32bit (prevent overflow): */
u32 area_length;
struct codec_setup_io {
@@ -1405,11 +1400,10 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
/* build combined I/O buffer length word */
setup_io.dma_lengths = (area_length << 16) | (area_length);
- spin_lock_irqsave(codec->lock, flags);
+ guard(spinlock_irqsave)(codec->lock);
snd_azf3328_codec_outl_multi(
codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
);
- spin_unlock_irqrestore(codec->lock, flags);
}
}
@@ -1464,48 +1458,48 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_pcm_format_width(runtime->format),
runtime->channels);
- spin_lock(codec->lock);
- /* first, remember current value: */
- flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
+ scoped_guard(spinlock, codec->lock) {
+ /* first, remember current value: */
+ flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
- /* stop transfer */
- flags1 &= ~DMA_RESUME;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+ /* stop transfer */
+ flags1 &= ~DMA_RESUME;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- /* FIXME: clear interrupts or what??? */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
- spin_unlock(codec->lock);
+ /* FIXME: clear interrupts or what??? */
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
+ }
snd_azf3328_codec_setdmaa(chip, codec, runtime->dma_addr,
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream)
);
- spin_lock(codec->lock);
+ scoped_guard(spinlock, codec->lock) {
#ifdef WIN9X
- /* FIXME: enable playback/recording??? */
- flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-
- /* start transfer again */
- /* FIXME: what is this value (0x0010)??? */
- flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+ /* FIXME: enable playback/recording??? */
+ flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+
+ /* start transfer again */
+ /* FIXME: what is this value (0x0010)??? */
+ flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
#else /* NT4 */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- 0x0000);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RUN_SOMETHING1);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RUN_SOMETHING1 |
- DMA_RUN_SOMETHING2);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RESUME |
- SOMETHING_ALMOST_ALWAYS_SET |
- DMA_EPILOGUE_SOMETHING |
- DMA_SOMETHING_ELSE);
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
+ 0x0000);
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
+ DMA_RUN_SOMETHING1);
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
+ DMA_RUN_SOMETHING1 |
+ DMA_RUN_SOMETHING2);
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
+ DMA_RESUME |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE);
#endif
- spin_unlock(codec->lock);
+ }
snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
if (is_main_mixer_playback_codec) {
@@ -1521,14 +1515,14 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_RESUME:
dev_dbg(chip->card->dev, "PCM RESUME %s\n", codec->name);
/* resume codec if we were active */
- spin_lock(codec->lock);
- if (codec->running)
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- snd_azf3328_codec_inw(
- codec, IDX_IO_CODEC_DMA_FLAGS
- ) | DMA_RESUME
- );
- spin_unlock(codec->lock);
+ scoped_guard(spinlock, codec->lock) {
+ if (codec->running)
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
+ snd_azf3328_codec_inw(
+ codec, IDX_IO_CODEC_DMA_FLAGS
+ ) | DMA_RESUME
+ );
+ }
break;
case SNDRV_PCM_TRIGGER_STOP:
dev_dbg(chip->card->dev, "PCM STOP %s\n", codec->name);
@@ -1541,22 +1535,22 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
);
}
- spin_lock(codec->lock);
- /* first, remember current value: */
- flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
+ scoped_guard(spinlock, codec->lock) {
+ /* first, remember current value: */
+ flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
- /* stop transfer */
- flags1 &= ~DMA_RESUME;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+ /* stop transfer */
+ flags1 &= ~DMA_RESUME;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- /* hmm, is this really required? we're resetting the same bit
- * immediately thereafter... */
- flags1 |= DMA_RUN_SOMETHING1;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+ /* hmm, is this really required? we're resetting the same bit
+ * immediately thereafter... */
+ flags1 |= DMA_RUN_SOMETHING1;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- flags1 &= ~DMA_RUN_SOMETHING1;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- spin_unlock(codec->lock);
+ flags1 &= ~DMA_RUN_SOMETHING1;
+ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
+ }
snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
if (is_main_mixer_playback_codec) {
@@ -1724,12 +1718,11 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
struct snd_azf3328 *chip = gameport_get_port_data(gameport);
int i;
u8 val;
- unsigned long flags;
if (snd_BUG_ON(!chip))
return 0;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
*buttons = (~(val) >> 4) & 0xf;
@@ -1766,7 +1759,6 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
axes[i] = chip->axes[i];
@@ -1863,11 +1855,11 @@ snd_azf3328_pcm_interrupt(struct snd_azf3328 *chip,
if (!(status & (1 << codec_type)))
continue;
- spin_lock(codec->lock);
- which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
- /* ack all IRQ types immediately */
- snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
- spin_unlock(codec->lock);
+ scoped_guard(spinlock, codec->lock) {
+ which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
+ /* ack all IRQ types immediately */
+ snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
+ }
if (codec->substream) {
snd_pcm_period_elapsed(codec->substream);
@@ -1912,9 +1904,9 @@ snd_azf3328_interrupt(int irq, void *dev_id)
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
/* ACK timer */
- spin_lock(&chip->reg_lock);
- snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
+ }
dev_dbg(chip->card->dev, "timer IRQ\n");
}
@@ -2137,7 +2129,6 @@ static int
snd_azf3328_timer_start(struct snd_timer *timer)
{
struct snd_azf3328 *chip;
- unsigned long flags;
unsigned int delay;
chip = snd_timer_chip(timer);
@@ -2152,9 +2143,8 @@ snd_azf3328_timer_start(struct snd_timer *timer)
}
dev_dbg(chip->card->dev, "setting timer countdown value %d\n", delay);
delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -2162,10 +2152,9 @@ static int
snd_azf3328_timer_stop(struct snd_timer *timer)
{
struct snd_azf3328 *chip;
- unsigned long flags;
chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
/* disable timer countdown and interrupt */
/* Hmm, should we write TIMER_IRQ_ACK here?
YES indeed, otherwise a rogue timer operation - which prompts
@@ -2174,7 +2163,6 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
Simply manually poking 0x04 _once_ immediately successfully stops
the hardware/ALSA interrupt activity. */
snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -2406,10 +2394,9 @@ snd_azf3328_create(struct snd_card *card,
codec->running = true;
snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
- spin_lock_irq(codec->lock);
+ guard(spinlock_irq)(codec->lock);
snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
dma_init);
- spin_unlock_irq(codec->lock);
}
return 0;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index b70f6f4ffe67..383def1f2af7 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -431,10 +431,10 @@ static int snd_bt87x_close(struct snd_pcm_substream *substream)
{
struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
- chip->reg_control |= CTL_A_PWRDN;
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->reg_control |= CTL_A_PWRDN;
+ snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+ }
chip->substream = NULL;
clear_bit(0, &chip->opened);
@@ -466,20 +466,19 @@ static int snd_bt87x_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int decimation;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
decimation = (ANALOG_CLOCK + runtime->rate / 4) / runtime->rate;
chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
if (runtime->format == SNDRV_PCM_FORMAT_S8)
chip->reg_control |= CTL_DA_SBR;
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
static int snd_bt87x_start(struct snd_bt87x *chip)
{
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
chip->current_line = 0;
chip->reg_control |= CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN;
snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
@@ -487,18 +486,16 @@ static int snd_bt87x_start(struct snd_bt87x *chip)
chip->line_bytes | (chip->lines << 16));
snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock(&chip->reg_lock);
return 0;
}
static int snd_bt87x_stop(struct snd_bt87x *chip)
{
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
snd_bt87x_writel(chip, REG_INT_MASK, 0);
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
- spin_unlock(&chip->reg_lock);
return 0;
}
@@ -560,13 +557,12 @@ static int snd_bt87x_capture_volume_put(struct snd_kcontrol *kcontrol,
u32 old_control;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
old_control = chip->reg_control;
chip->reg_control = (chip->reg_control & ~CTL_A_GAIN_MASK)
| (value->value.integer.value[0] << CTL_A_GAIN_SHIFT);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
changed = old_control != chip->reg_control;
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
@@ -596,13 +592,12 @@ static int snd_bt87x_capture_boost_put(struct snd_kcontrol *kcontrol,
u32 old_control;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
old_control = chip->reg_control;
chip->reg_control = (chip->reg_control & ~CTL_A_G2X)
| (value->value.integer.value[0] ? CTL_A_G2X : 0);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
changed = chip->reg_control != old_control;
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
@@ -638,13 +633,12 @@ static int snd_bt87x_capture_source_put(struct snd_kcontrol *kcontrol,
u32 old_control;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
old_control = chip->reg_control;
chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
| (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
changed = chip->reg_control != old_control;
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 242618793181..41774e2ef53f 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -332,16 +332,13 @@ unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu,
unsigned int reg,
unsigned int chn)
{
- unsigned long flags;
- unsigned int regptr, val;
+ unsigned int regptr;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + CA0106_PTR);
- val = inl(emu->port + CA0106_DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inl(emu->port + CA0106_DATA);
}
void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
@@ -350,14 +347,12 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
unsigned int data)
{
unsigned int regptr;
- unsigned long flags;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + CA0106_PTR);
outl(data, emu->port + CA0106_DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
int snd_ca0106_spi_write(struct snd_ca0106 * emu,
@@ -451,24 +446,20 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
static void snd_ca0106_intr_enable(struct snd_ca0106 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int intr_enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
intr_enable = inl(emu->port + CA0106_INTE) | intrenb;
outl(intr_enable, emu->port + CA0106_INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_ca0106_intr_disable(struct snd_ca0106 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int intr_enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
intr_enable = inl(emu->port + CA0106_INTE) & ~intrenb;
outl(intr_enable, emu->port + CA0106_INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
@@ -1138,26 +1129,20 @@ static unsigned short snd_ca0106_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
struct snd_ca0106 *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + CA0106_AC97ADDRESS);
- val = inw(emu->port + CA0106_AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inw(emu->port + CA0106_AC97DATA);
}
static void snd_ca0106_ac97_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val)
{
struct snd_ca0106 *emu = ac97->private_data;
- unsigned long flags;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + CA0106_AC97ADDRESS);
outw(val, emu->port + CA0106_AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static int snd_ca0106_ac97(struct snd_ca0106 *chip)
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index c99603e137e5..c181e4954579 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -281,16 +281,14 @@ static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_ca0106 *emu = entry->private_data;
- unsigned long flags;
char line[64];
u32 reg, val;
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
if (reg < 0x40 && val <= 0xffffffff) {
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(val, emu->port + (reg & 0xfffffffc));
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
}
}
@@ -300,13 +298,13 @@ static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry,
{
struct snd_ca0106 *emu = entry->private_data;
unsigned long value;
- unsigned long flags;
int i;
+
snd_iprintf(buffer, "Registers:\n\n");
for(i = 0; i < 0x20; i+=4) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inl(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
+ scoped_guard(spinlock_irqsave, &emu->emu_lock) {
+ value = inl(emu->port + i);
+ }
snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
}
}
@@ -316,13 +314,13 @@ static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry,
{
struct snd_ca0106 *emu = entry->private_data;
unsigned int value;
- unsigned long flags;
int i;
+
snd_iprintf(buffer, "Registers:\n\n");
for(i = 0; i < 0x20; i+=2) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inw(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
+ scoped_guard(spinlock_irqsave, &emu->emu_lock) {
+ value = inw(emu->port + i);
+ }
snd_iprintf(buffer, "Register %02X: %04X\n", i, value);
}
}
@@ -332,13 +330,13 @@ static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry,
{
struct snd_ca0106 *emu = entry->private_data;
unsigned int value;
- unsigned long flags;
int i;
+
snd_iprintf(buffer, "Registers:\n\n");
for(i = 0; i < 0x20; i+=1) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inb(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
+ scoped_guard(spinlock_irqsave, &emu->emu_lock) {
+ value = inb(emu->port + i);
+ }
snd_iprintf(buffer, "Register %02X: %02X\n", i, value);
}
}
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index f9cec67f31ac..6efd93abddb5 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -45,58 +45,54 @@ static void ca_midi_interrupt(struct snd_ca_midi *midi, unsigned int status)
return;
}
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- ca_midi_clear_rx(midi);
- } else {
- byte = ca_midi_read_data(midi);
- if(midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
-
-
+ scoped_guard(spinlock, &midi->input_lock) {
+ if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ ca_midi_clear_rx(midi);
+ } else {
+ byte = ca_midi_read_data(midi);
+ if (midi->substream_input)
+ snd_rawmidi_receive(midi->substream_input, &byte, 1);
+ }
}
}
- spin_unlock(&midi->input_lock);
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- ca_midi_write_data(midi, byte);
- } else {
- midi->interrupt_disable(midi,midi->tx_enable);
+ scoped_guard(spinlock, &midi->output_lock) {
+ if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
+ if (midi->substream_output &&
+ snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+ ca_midi_write_data(midi, byte);
+ } else {
+ midi->interrupt_disable(midi, midi->tx_enable);
+ }
}
}
- spin_unlock(&midi->output_lock);
-
}
static void ca_midi_cmd(struct snd_ca_midi *midi, unsigned char cmd, int ack)
{
- unsigned long flags;
int timeout, ok;
- spin_lock_irqsave(&midi->input_lock, flags);
- ca_midi_write_data(midi, 0x00);
- /* ca_midi_clear_rx(midi); */
-
- ca_midi_write_cmd(midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (ca_midi_input_avail(midi)) {
- if (ca_midi_read_data(midi) == midi->ack)
- ok = 1;
+ scoped_guard(spinlock_irqsave, &midi->input_lock) {
+ ca_midi_write_data(midi, 0x00);
+ /* ca_midi_clear_rx(midi); */
+
+ ca_midi_write_cmd(midi, cmd);
+ if (ack) {
+ ok = 0;
+ timeout = 10000;
+ while (!ok && timeout-- > 0) {
+ if (ca_midi_input_avail(midi)) {
+ if (ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ }
}
- }
- if (!ok && ca_midi_read_data(midi) == midi->ack)
+ if (!ok && ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ } else {
ok = 1;
- } else {
- ok = 1;
+ }
}
- spin_unlock_irqrestore(&midi->input_lock, flags);
if (!ok)
pr_err("ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
cmd,
@@ -108,83 +104,69 @@ static void ca_midi_cmd(struct snd_ca_midi *midi, unsigned char cmd, int ack)
static int ca_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
if (snd_BUG_ON(!midi->dev_id))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= CA_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 1);
- ca_midi_cmd(midi, midi->enter_uart, 1);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->midi_mode |= CA_MIDI_MODE_INPUT;
+ midi->substream_input = substream;
+ if (midi->midi_mode & CA_MIDI_MODE_OUTPUT)
+ return 0;
}
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
return 0;
}
static int ca_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
if (snd_BUG_ON(!midi->dev_id))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 1);
- ca_midi_cmd(midi, midi->enter_uart, 1);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = substream;
+ if (midi->midi_mode & CA_MIDI_MODE_INPUT)
+ return 0;
}
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
return 0;
}
static int ca_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
if (snd_BUG_ON(!midi->dev_id))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->interrupt_disable(midi,midi->rx_enable);
- midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->interrupt_disable(midi, midi->rx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
+ midi->substream_input = NULL;
+ if (midi->midi_mode & CA_MIDI_MODE_OUTPUT)
+ return 0;
}
+ ca_midi_cmd(midi, midi->reset, 0);
return 0;
}
static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
if (snd_BUG_ON(!midi->dev_id))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
-
- midi->interrupt_disable(midi,midi->tx_enable);
- midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
-
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->interrupt_disable(midi, midi->tx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = NULL;
+ if (midi->midi_mode & CA_MIDI_MODE_INPUT)
+ return 0;
}
+ ca_midi_cmd(midi, midi->reset, 0);
return 0;
}
@@ -205,7 +187,6 @@ static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int u
static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
if (snd_BUG_ON(!midi->dev_id))
return;
@@ -214,25 +195,23 @@ static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int
int max = 4;
unsigned char byte;
- spin_lock_irqsave(&midi->output_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->output_lock) {
- /* try to send some amount of bytes here before interrupts */
- while (max > 0) {
- if (ca_midi_output_ready(midi)) {
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irqrestore(&midi->output_lock, flags);
- return;
+ /* try to send some amount of bytes here before interrupts */
+ while (max > 0) {
+ if (ca_midi_output_ready(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
+ snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+ /* no more data */
+ return;
+ }
+ ca_midi_write_data(midi, byte);
+ max--;
+ } else {
+ break;
}
- ca_midi_write_data(midi, byte);
- max--;
- } else {
- break;
}
}
-
- spin_unlock_irqrestore(&midi->output_lock, flags);
midi->interrupt_enable(midi,midi->tx_enable);
} else {
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index c4ee550d7c96..0666be543474 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -664,14 +664,11 @@ static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream,
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
if (params_channels(hw_params) > 2) {
- mutex_lock(&cm->open_mutex);
- if (cm->opened[CM_CH_PLAY]) {
- mutex_unlock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
+ if (cm->opened[CM_CH_PLAY])
return -EBUSY;
- }
/* reserve the channel A */
cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
- mutex_unlock(&cm->open_mutex);
}
return 0;
}
@@ -715,7 +712,7 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann
}
if (cm->can_multi_ch) {
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (channels > 2) {
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
@@ -738,7 +735,6 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
else
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
- spin_unlock_irq(&cm->reg_lock);
}
return 0;
}
@@ -779,7 +775,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
period_size = (period_size * runtime->channels) / 2;
}
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
/* set buffer address */
reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
@@ -845,7 +841,6 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
}
rec->running = 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -857,14 +852,13 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
int cmd)
{
unsigned int inthld, chen, reset, pause;
- int result = 0;
inthld = CM_CH0_INT_EN << rec->ch;
chen = CM_CHEN0 << rec->ch;
reset = CM_RST_CH0 << rec->ch;
pause = CM_PAUSE0 << rec->ch;
- spin_lock(&cm->reg_lock);
+ guard(spinlock)(&cm->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
rec->running = 1;
@@ -896,11 +890,9 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&cm->reg_lock);
- return result;
+ return 0;
}
/*
@@ -990,10 +982,9 @@ static int snd_cmipci_spdif_default_get(struct snd_kcontrol *kcontrol,
struct cmipci *chip = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
ucontrol->value.iec958.status[i] = (chip->dig_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1005,12 +996,11 @@ static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
unsigned int val;
val = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
change = val != chip->dig_status;
chip->dig_status = val;
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1064,10 +1054,9 @@ static int snd_cmipci_spdif_stream_get(struct snd_kcontrol *kcontrol,
struct cmipci *chip = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
ucontrol->value.iec958.status[i] = (chip->dig_pcm_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1079,12 +1068,11 @@ static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
unsigned int val;
val = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
change = val != chip->dig_pcm_status;
chip->dig_pcm_status = val;
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1228,7 +1216,7 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
return err;
}
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
cm->spdif_playback_avail = up;
if (up) {
/* they are controlled via "IEC958 Output Switch" */
@@ -1254,7 +1242,6 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
setup_ac3(cm, subs, 0, 0);
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -1320,32 +1307,32 @@ static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec)
/* configure for 16 bits, 2 channels, 8 kHz */
if (runtime->channels > 2)
set_dac_channels(cm, rec, 2);
- spin_lock_irq(&cm->reg_lock);
- val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
- val &= ~(CM_ASFC_MASK << (rec->ch * 3));
- val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
- val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
- val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
- val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
- if (cm->can_96k)
- val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
- snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
+ val &= ~(CM_ASFC_MASK << (rec->ch * 3));
+ val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
+ val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
+ val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
+ val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
+ if (cm->can_96k)
+ val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
+ snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
- /* start stream (we don't need interrupts) */
- cm->ctrl |= CM_CHEN0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- spin_unlock_irq(&cm->reg_lock);
+ /* start stream (we don't need interrupts) */
+ cm->ctrl |= CM_CHEN0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
+ }
msleep(1);
/* stop and reset stream */
- spin_lock_irq(&cm->reg_lock);
- cm->ctrl &= ~(CM_CHEN0 << rec->ch);
- val = CM_RST_CH0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
- spin_unlock_irq(&cm->reg_lock);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ cm->ctrl &= ~(CM_CHEN0 << rec->ch);
+ val = CM_RST_CH0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
+ }
rec->needs_silencing = 0;
}
@@ -1379,20 +1366,19 @@ static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
- if (cm->can_96k) {
- if (substream->runtime->rate > 48000)
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
+ if (cm->can_96k) {
+ if (substream->runtime->rate > 48000)
+ snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ else
+ snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ }
+ if (snd_pcm_format_width(substream->runtime->format) > 16)
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
else
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
}
- if (snd_pcm_format_width(substream->runtime->format) > 16)
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- else
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
-
- spin_unlock_irq(&cm->reg_lock);
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
}
@@ -1401,10 +1387,9 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
{
struct cmipci *cm = snd_pcm_substream_chip(subs);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -1424,14 +1409,14 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
return IRQ_NONE;
/* acknowledge interrupt */
- spin_lock(&cm->reg_lock);
- if (status & CM_CHINT0)
- mask |= CM_CH0_INT_EN;
- if (status & CM_CHINT1)
- mask |= CM_CH1_INT_EN;
- snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
- snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
- spin_unlock(&cm->reg_lock);
+ scoped_guard(spinlock, &cm->reg_lock) {
+ if (status & CM_CHINT0)
+ mask |= CM_CH0_INT_EN;
+ if (status & CM_CHINT1)
+ mask |= CM_CH1_INT_EN;
+ snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
+ snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
+ }
if (cm->rmidi && (status & CM_UARTINT))
snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data);
@@ -1582,21 +1567,17 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre
* pcm framework doesn't pass file pointer before actually opened,
* we can't know whether blocking mode or not in open callback..
*/
- mutex_lock(&cm->open_mutex);
- if (cm->opened[ch]) {
- mutex_unlock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
+ if (cm->opened[ch])
return -EBUSY;
- }
cm->opened[ch] = mode;
cm->channel[ch].substream = subs;
if (! (mode & CM_OPEN_DAC)) {
/* disable dual DAC mode */
cm->channel[ch].is_dac = 0;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
}
- mutex_unlock(&cm->open_mutex);
return 0;
}
@@ -1604,7 +1585,7 @@ static void close_device_check(struct cmipci *cm, int mode)
{
int ch = mode & CM_OPEN_CH_MASK;
- mutex_lock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
if (cm->opened[ch] == mode) {
if (cm->channel[ch].substream) {
snd_cmipci_ch_reset(cm, ch);
@@ -1615,12 +1596,10 @@ static void close_device_check(struct cmipci *cm, int mode)
if (! cm->channel[ch].is_dac) {
/* enable dual DAC mode again */
cm->channel[ch].is_dac = 1;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
}
}
- mutex_unlock(&cm->open_mutex);
}
/*
@@ -1685,7 +1664,7 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
if (err < 0)
return err;
runtime->hw = snd_cmipci_playback2;
- mutex_lock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
if (! cm->opened[CM_CH_PLAY]) {
if (cm->can_multi_ch) {
runtime->hw.channels_max = cm->max_channels;
@@ -1697,7 +1676,6 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8);
}
}
- mutex_unlock(&cm->open_mutex);
if (cm->chip_version == 68) {
runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000;
@@ -2010,7 +1988,7 @@ static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
int val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
val = (snd_cmipci_mixer_read(cm, reg.left_reg) >> reg.left_shift) & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -2021,7 +1999,6 @@ static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2045,7 +2022,7 @@ static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
right <<= reg.right_shift;
} else
right = 0;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oleft = snd_cmipci_mixer_read(cm, reg.left_reg);
left |= oleft & ~(reg.mask << reg.left_shift);
change = left != oleft;
@@ -2060,7 +2037,6 @@ static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
snd_cmipci_mixer_write(cm, reg.right_reg, right);
} else
snd_cmipci_mixer_write(cm, reg.left_reg, left);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2092,10 +2068,9 @@ static int snd_cmipci_get_input_sw(struct snd_kcontrol *kcontrol,
int val1, val2;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
val1 = snd_cmipci_mixer_read(cm, reg.left_reg);
val2 = snd_cmipci_mixer_read(cm, reg.right_reg);
- spin_unlock_irq(&cm->reg_lock);
ucontrol->value.integer.value[0] = (val1 >> reg.left_shift) & 1;
ucontrol->value.integer.value[1] = (val2 >> reg.left_shift) & 1;
ucontrol->value.integer.value[2] = (val1 >> reg.right_shift) & 1;
@@ -2112,7 +2087,7 @@ static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
int val1, val2, oval1, oval2;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oval1 = snd_cmipci_mixer_read(cm, reg.left_reg);
oval2 = snd_cmipci_mixer_read(cm, reg.right_reg);
val1 = oval1 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
@@ -2124,7 +2099,6 @@ static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
change = val1 != oval1 || val2 != oval2;
snd_cmipci_mixer_write(cm, reg.left_reg, val1);
snd_cmipci_mixer_write(cm, reg.right_reg, val2);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2182,7 +2156,7 @@ static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
unsigned char oreg, val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oreg = inb(cm->iobase + reg.left_reg);
val = (oreg >> reg.left_shift) & reg.mask;
if (reg.invert)
@@ -2194,7 +2168,6 @@ static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2206,7 +2179,7 @@ static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
unsigned char oreg, nreg, val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oreg = inb(cm->iobase + reg.left_reg);
val = ucontrol->value.integer.value[0] & reg.mask;
if (reg.invert)
@@ -2221,7 +2194,6 @@ static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
nreg |= (val << reg.right_shift);
}
outb(nreg, cm->iobase + reg.left_reg);
- spin_unlock_irq(&cm->reg_lock);
return (nreg != oreg);
}
@@ -2308,10 +2280,9 @@ static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
unsigned int val;
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (args->ac3_sensitive && cm->mixer_insensitive) {
ucontrol->value.integer.value[0] = 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
if (args->is_byte)
@@ -2319,7 +2290,6 @@ static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
else
val = snd_cmipci_read(cm, args->reg);
ucontrol->value.integer.value[0] = ((val & args->mask) == args->mask_on) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2341,10 +2311,9 @@ static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
int change;
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (args->ac3_sensitive && cm->mixer_insensitive) {
/* ignored */
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
if (args->is_byte)
@@ -2364,7 +2333,6 @@ static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
else
snd_cmipci_write(cm, args->reg, val);
}
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2497,9 +2465,8 @@ static int snd_cmipci_line_in_mode_get(struct snd_kcontrol *kcontrol,
{
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
ucontrol->value.enumerated.item[0] = get_line_in_mode(cm);
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2509,7 +2476,7 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
int change;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (ucontrol->value.enumerated.item[0] == 2)
change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
else
@@ -2518,7 +2485,6 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
else
change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2534,11 +2500,11 @@ static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+
/* same bit as spdi_phase */
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
ucontrol->value.enumerated.item[0] =
(snd_cmipci_read_b(cm, CM_REG_MISC) & CM_SPDIF_INVERSE) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2548,12 +2514,11 @@ static int snd_cmipci_mic_in_mode_put(struct snd_kcontrol *kcontrol,
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
int change;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (ucontrol->value.enumerated.item[0])
change = snd_cmipci_set_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
else
change = snd_cmipci_clear_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2635,9 +2600,9 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
strscpy(card->mixername, "CMedia PCI");
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
- spin_unlock_irq(&cm->reg_lock);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
+ }
for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixers); idx++) {
if (cm->chip_version == 68) { // 8768 has no PCM volume
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 31cb9cbe2f03..d00b2c9fb1e3 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -651,7 +651,7 @@ static int snd_cs4281_trigger(struct snd_pcm_substream *substream, int cmd)
struct cs4281_dma *dma = substream->runtime->private_data;
struct cs4281 *chip = snd_pcm_substream_chip(substream);
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dma->valDCR |= BA0_DCR_MSK;
@@ -678,13 +678,11 @@ static int snd_cs4281_trigger(struct snd_pcm_substream *substream, int cmd)
dma->valFCR &= ~BA0_FCR_FEN;
break;
default:
- spin_unlock(&chip->reg_lock);
return -EINVAL;
}
snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR);
snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR);
snd_cs4281_pokeBA0(chip, dma->regDCR, dma->valDCR);
- spin_unlock(&chip->reg_lock);
return 0;
}
@@ -782,9 +780,8 @@ static int snd_cs4281_playback_prepare(struct snd_pcm_substream *substream)
struct cs4281_dma *dma = runtime->private_data;
struct cs4281 *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_cs4281_mode(chip, dma, runtime, 0, 1);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -794,9 +791,8 @@ static int snd_cs4281_capture_prepare(struct snd_pcm_substream *substream)
struct cs4281_dma *dma = runtime->private_data;
struct cs4281 *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_cs4281_mode(chip, dma, runtime, 1, 1);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1580,7 +1576,7 @@ static int snd_cs4281_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct cs4281 *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->midcr |= BA0_MIDCR_RXE;
chip->midi_input = substream;
if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
@@ -1588,7 +1584,6 @@ static int snd_cs4281_midi_input_open(struct snd_rawmidi_substream *substream)
} else {
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1596,7 +1591,7 @@ static int snd_cs4281_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct cs4281 *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->midcr &= ~(BA0_MIDCR_RXE | BA0_MIDCR_RIE);
chip->midi_input = NULL;
if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
@@ -1605,7 +1600,6 @@ static int snd_cs4281_midi_input_close(struct snd_rawmidi_substream *substream)
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
chip->uartm &= ~CS4281_MODE_INPUT;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1613,7 +1607,7 @@ static int snd_cs4281_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct cs4281 *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->uartm |= CS4281_MODE_OUTPUT;
chip->midcr |= BA0_MIDCR_TXE;
chip->midi_output = substream;
@@ -1622,7 +1616,6 @@ static int snd_cs4281_midi_output_open(struct snd_rawmidi_substream *substream)
} else {
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1630,7 +1623,7 @@ static int snd_cs4281_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct cs4281 *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->midcr &= ~(BA0_MIDCR_TXE | BA0_MIDCR_TIE);
chip->midi_output = NULL;
if (!(chip->uartm & CS4281_MODE_INPUT)) {
@@ -1639,16 +1632,14 @@ static int snd_cs4281_midi_output_close(struct snd_rawmidi_substream *substream)
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
chip->uartm &= ~CS4281_MODE_OUTPUT;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
static void snd_cs4281_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct cs4281 *chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (up) {
if ((chip->midcr & BA0_MIDCR_RIE) == 0) {
chip->midcr |= BA0_MIDCR_RIE;
@@ -1660,16 +1651,14 @@ static void snd_cs4281_midi_input_trigger(struct snd_rawmidi_substream *substrea
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_cs4281_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct cs4281 *chip = substream->rmidi->private_data;
unsigned char byte;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (up) {
if ((chip->midcr & BA0_MIDCR_TIE) == 0) {
chip->midcr |= BA0_MIDCR_TIE;
@@ -1690,7 +1679,6 @@ static void snd_cs4281_midi_output_trigger(struct snd_rawmidi_substream *substre
snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static const struct snd_rawmidi_ops snd_cs4281_midi_output =
@@ -1743,10 +1731,12 @@ static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
}
if (status & (BA0_HISR_DMA(0)|BA0_HISR_DMA(1)|BA0_HISR_DMA(2)|BA0_HISR_DMA(3))) {
- for (dma = 0; dma < 4; dma++)
+ for (dma = 0; dma < 4; dma++) {
+ bool period_elapsed = false;
+ cdma = &chip->dma[dma];
+
if (status & BA0_HISR_DMA(dma)) {
- cdma = &chip->dma[dma];
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
/* ack DMA IRQ */
val = snd_cs4281_peekBA0(chip, cdma->regHDSR);
/* workaround, sometimes CS4281 acknowledges */
@@ -1755,24 +1745,24 @@ static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
if ((val & BA0_HDSR_DHTC) && !(cdma->frag & 1)) {
cdma->frag--;
chip->spurious_dhtc_irq++;
- spin_unlock(&chip->reg_lock);
continue;
}
if ((val & BA0_HDSR_DTC) && (cdma->frag & 1)) {
cdma->frag--;
chip->spurious_dtc_irq++;
- spin_unlock(&chip->reg_lock);
continue;
}
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(cdma->substream);
+ period_elapsed = true;
}
+ if (period_elapsed)
+ snd_pcm_period_elapsed(cdma->substream);
+ }
}
if ((status & BA0_HISR_MIDI) && chip->rmidi) {
unsigned char c;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_RBE) == 0) {
c = snd_cs4281_peekBA0(chip, BA0_MIDRP);
if ((chip->midcr & BA0_MIDCR_RIE) == 0)
@@ -1789,7 +1779,6 @@ static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
}
snd_cs4281_pokeBA0(chip, BA0_MIDWP, c);
}
- spin_unlock(&chip->reg_lock);
}
/* EOI to the PCI part... reenables interrupts */
@@ -1805,7 +1794,6 @@ static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
static void snd_cs4281_opl3_command(struct snd_opl3 *opl3, unsigned short cmd,
unsigned char val)
{
- unsigned long flags;
struct cs4281 *chip = opl3->private_data;
void __iomem *port;
@@ -1814,15 +1802,13 @@ static void snd_cs4281_opl3_command(struct snd_opl3 *opl3, unsigned short cmd,
else
port = chip->ba0 + BA0_B0AP; /* left port */
- spin_lock_irqsave(&opl3->reg_lock, flags);
+ guard(spinlock_irqsave)(&opl3->reg_lock);
writel((unsigned int)cmd, port);
udelay(10);
writel((unsigned int)val, port + 4);
udelay(30);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
}
static int __snd_cs4281_probe(struct pci_dev *pci,
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 85a7988cf822..b96ab7fd464c 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -707,7 +707,6 @@ static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
{
- unsigned long flags;
unsigned int tmp1, tmp2;
unsigned int phiIncr;
unsigned int correctionPerGOF, correctionPerSec;
@@ -744,16 +743,14 @@ static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned in
/*
* Fill in the SampleRateConverter control block.
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_cs46xx_poke(chip, BA1_PSRC,
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
{
- unsigned long flags;
unsigned int phiIncr, coeffIncr, tmp1, tmp2;
unsigned int correctionPerGOF, correctionPerSec, initialDelay;
unsigned int frameGroupLength, cnt;
@@ -818,14 +815,14 @@ static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned
/*
* Fill in the VariDecimate control block.
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs46xx_poke(chip, BA1_CSRC,
- ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
- snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
- snd_cs46xx_poke(chip, BA1_CD,
- (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
- snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_cs46xx_poke(chip, BA1_CSRC,
+ ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
+ snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
+ snd_cs46xx_poke(chip, BA1_CD,
+ (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
+ snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
+ }
/*
* Figure out the frame group length for the write back task. Basically,
@@ -848,13 +845,12 @@ static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned
/*
* Fill in the WriteBack control block.
*/
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
/*
@@ -969,15 +965,14 @@ static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
if (substream->runtime->periods != CS46XX_FRAGS)
snd_cs46xx_playback_transfer(substream);
#else
- spin_lock(&chip->reg_lock);
- if (substream->runtime->periods != CS46XX_FRAGS)
- snd_cs46xx_playback_transfer(substream);
- { unsigned int tmp;
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- tmp &= 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ unsigned int tmp;
+ if (substream->runtime->periods != CS46XX_FRAGS)
+ snd_cs46xx_playback_transfer(substream);
+ tmp = snd_cs46xx_peek(chip, BA1_PCTL);
+ tmp &= 0x0000ffff;
+ snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
}
- spin_unlock(&chip->reg_lock);
#endif
break;
case SNDRV_PCM_TRIGGER_STOP:
@@ -990,13 +985,12 @@ static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
if (!cpcm->pcm_channel->unlinked)
cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
#else
- spin_lock(&chip->reg_lock);
- { unsigned int tmp;
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- tmp &= 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_PCTL, tmp);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ unsigned int tmp;
+ tmp = snd_cs46xx_peek(chip, BA1_PCTL);
+ tmp &= 0x0000ffff;
+ snd_cs46xx_poke(chip, BA1_PCTL, tmp);
}
- spin_unlock(&chip->reg_lock);
#endif
break;
default:
@@ -1012,9 +1006,8 @@ static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
{
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
unsigned int tmp;
- int result = 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -1029,12 +1022,9 @@ static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
snd_cs46xx_poke(chip, BA1_CCTL, tmp);
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
-
- return result;
+ return 0;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1093,24 +1083,17 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
if (snd_BUG_ON(!sample_rate))
return -ENXIO;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
- if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
- mutex_unlock(&chip->spos_mutex);
+ if (_cs46xx_adjust_sample_rate(chip, cpcm, sample_rate))
return -ENXIO;
- }
snd_BUG_ON(!cpcm->pcm_channel);
- if (!cpcm->pcm_channel) {
- mutex_unlock(&chip->spos_mutex);
+ if (!cpcm->pcm_channel)
return -ENXIO;
- }
-
- if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
- mutex_unlock(&chip->spos_mutex);
+ if (cs46xx_dsp_pcm_channel_set_period(chip, cpcm->pcm_channel, period_size))
return -EINVAL;
- }
dev_dbg(chip->card->dev,
"period_size (%d), periods (%d) buffer_size(%d)\n",
@@ -1144,12 +1127,8 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
if (runtime->dma_area == cpcm->hw_buf.area)
snd_pcm_set_runtime_buffer(substream, NULL);
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0) {
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_unlock(&chip->spos_mutex);
-#endif
+ if (err < 0)
return err;
- }
#ifdef CONFIG_SND_CS46XX_NEW_DSP
if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
@@ -1169,10 +1148,6 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
}
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_unlock(&chip->spos_mutex);
-#endif
-
return 0;
}
@@ -1386,7 +1361,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
if ((status1 & HISR_MIDI) && chip->rmidi) {
unsigned char c;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
if ((chip->midcr & MIDCR_RIE) == 0)
@@ -1403,7 +1378,6 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
}
snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
}
- spin_unlock(&chip->reg_lock);
}
/*
* EOI to the PCI part....reenables interrupts
@@ -1495,16 +1469,14 @@ static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,in
cpcm->substream = substream;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_lock(&chip->spos_mutex);
- cpcm->pcm_channel = NULL;
- cpcm->pcm_channel_id = pcm_channel_id;
-
+ scoped_guard(mutex, &chip->spos_mutex) {
+ cpcm->pcm_channel = NULL;
+ cpcm->pcm_channel_id = pcm_channel_id;
+ }
snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
&hw_constraints_period_sizes);
-
- mutex_unlock(&chip->spos_mutex);
#else
chip->playback_pcm = cpcm; /* HACK */
#endif
@@ -1541,9 +1513,9 @@ static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
dev_dbg(chip->card->dev, "open raw iec958 channel\n");
- mutex_lock(&chip->spos_mutex);
- cs46xx_iec958_pre_open (chip);
- mutex_unlock(&chip->spos_mutex);
+ scoped_guard(mutex, &chip->spos_mutex) {
+ cs46xx_iec958_pre_open(chip);
+ }
return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
}
@@ -1559,9 +1531,9 @@ static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
err = snd_cs46xx_playback_close(substream);
- mutex_lock(&chip->spos_mutex);
- cs46xx_iec958_post_close (chip);
- mutex_unlock(&chip->spos_mutex);
+ scoped_guard(mutex, &chip->spos_mutex) {
+ cs46xx_iec958_post_close(chip);
+ }
return err;
}
@@ -1602,12 +1574,12 @@ static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
if (!cpcm) return -ENXIO;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_lock(&chip->spos_mutex);
- if (cpcm->pcm_channel) {
- cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
- cpcm->pcm_channel = NULL;
+ scoped_guard(mutex, &chip->spos_mutex) {
+ if (cpcm->pcm_channel) {
+ cs46xx_dsp_destroy_pcm_channel(chip, cpcm->pcm_channel);
+ cpcm->pcm_channel = NULL;
+ }
}
- mutex_unlock(&chip->spos_mutex);
#else
chip->playback_pcm = NULL;
#endif
@@ -1982,15 +1954,15 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol,
switch (kcontrol->private_value) {
case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
- mutex_lock(&chip->spos_mutex);
- change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
- if (ucontrol->value.integer.value[0] && !change)
- cs46xx_dsp_enable_spdif_out(chip);
- else if (change && !ucontrol->value.integer.value[0])
- cs46xx_dsp_disable_spdif_out(chip);
-
- res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
- mutex_unlock(&chip->spos_mutex);
+ scoped_guard(mutex, &chip->spos_mutex) {
+ change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
+ if (ucontrol->value.integer.value[0] && !change)
+ cs46xx_dsp_enable_spdif_out(chip);
+ else if (change && !ucontrol->value.integer.value[0])
+ cs46xx_dsp_disable_spdif_out(chip);
+
+ res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
+ }
break;
case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
change = chip->dsp_spos_instance->spdif_status_in;
@@ -2131,12 +2103,11 @@ static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
ucontrol->value.iec958.status[2] = 0;
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -2149,7 +2120,7 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
unsigned int val;
int change;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
@@ -2163,8 +2134,6 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
- mutex_unlock(&chip->spos_mutex);
-
return change;
}
@@ -2184,12 +2153,11 @@ static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
ucontrol->value.iec958.status[2] = 0;
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -2202,7 +2170,7 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
unsigned int val;
int change;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
@@ -2216,8 +2184,6 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
- mutex_unlock(&chip->spos_mutex);
-
return change;
}
@@ -2532,7 +2498,7 @@ static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
struct snd_cs46xx *chip = substream->rmidi->private_data;
chip->active_ctrl(chip, 1);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->uartm |= CS46XX_MODE_INPUT;
chip->midcr |= MIDCR_RXE;
chip->midi_input = substream;
@@ -2541,7 +2507,6 @@ static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
} else {
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -2549,16 +2514,16 @@ static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct snd_cs46xx *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
- chip->midi_input = NULL;
- if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
+ chip->midi_input = NULL;
+ if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
+ snd_cs46xx_midi_reset(chip);
+ } else {
+ snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
+ }
+ chip->uartm &= ~CS46XX_MODE_INPUT;
}
- chip->uartm &= ~CS46XX_MODE_INPUT;
- spin_unlock_irq(&chip->reg_lock);
chip->active_ctrl(chip, -1);
return 0;
}
@@ -2569,7 +2534,7 @@ static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
chip->active_ctrl(chip, 1);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->uartm |= CS46XX_MODE_OUTPUT;
chip->midcr |= MIDCR_TXE;
chip->midi_output = substream;
@@ -2578,7 +2543,6 @@ static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
} else {
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -2586,26 +2550,25 @@ static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_cs46xx *chip = substream->rmidi->private_data;
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
- chip->midi_output = NULL;
- if (!(chip->uartm & CS46XX_MODE_INPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
+ chip->midi_output = NULL;
+ if (!(chip->uartm & CS46XX_MODE_INPUT)) {
+ snd_cs46xx_midi_reset(chip);
+ } else {
+ snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
+ }
+ chip->uartm &= ~CS46XX_MODE_OUTPUT;
}
- chip->uartm &= ~CS46XX_MODE_OUTPUT;
- spin_unlock_irq(&chip->reg_lock);
chip->active_ctrl(chip, -1);
return 0;
}
static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_cs46xx *chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (up) {
if ((chip->midcr & MIDCR_RIE) == 0) {
chip->midcr |= MIDCR_RIE;
@@ -2617,16 +2580,14 @@ static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substrea
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct snd_cs46xx *chip = substream->rmidi->private_data;
unsigned char byte;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (up) {
if ((chip->midcr & MIDCR_TIE) == 0) {
chip->midcr |= MIDCR_TIE;
@@ -2647,7 +2608,6 @@ static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substre
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static const struct snd_rawmidi_ops snd_cs46xx_midi_output =
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index e07f85322f1c..3d34575a0e8f 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -283,7 +283,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
if (snd_BUG_ON(!ins))
return;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
for (i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) continue;
@@ -297,7 +297,6 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
vfree(ins->symbol_table.symbols);
kfree(ins->modules);
kfree(ins);
- mutex_unlock(&chip->spos_mutex);
}
static int dsp_load_parameter(struct snd_cs46xx *chip,
@@ -525,7 +524,7 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry,
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
int i,j;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
snd_iprintf(buffer, "MODULES:\n");
for ( i = 0; i < ins->nmodules; ++i ) {
snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name);
@@ -538,7 +537,6 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry,
desc->segment_type,desc->offset, desc->size);
}
}
- mutex_unlock(&chip->spos_mutex);
}
static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry,
@@ -549,7 +547,7 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry,
int i, j, col;
void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
snd_iprintf(buffer, "TASK TREES:\n");
for ( i = 0; i < ins->ntask; ++i) {
snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name);
@@ -566,7 +564,6 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry,
}
snd_iprintf(buffer,"\n");
- mutex_unlock(&chip->spos_mutex);
}
static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry,
@@ -576,7 +573,7 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry,
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
int i;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
snd_iprintf(buffer, "SCB's:\n");
for ( i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted)
@@ -599,7 +596,6 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry,
}
snd_iprintf(buffer,"\n");
- mutex_unlock(&chip->spos_mutex);
}
static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry,
@@ -831,14 +827,13 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
snd_info_set_text_ops(entry, chip,
cs46xx_dsp_proc_scb_read);
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
/* register/update SCB's entries on proc */
for (i = 0; i < ins->nscb; ++i) {
if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i));
}
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -851,12 +846,13 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip)
if (!ins)
return 0;
- mutex_lock(&chip->spos_mutex);
- for (i = 0; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted) continue;
- cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
+ scoped_guard(mutex, &chip->spos_mutex) {
+ for (i = 0; i < ins->nscb; ++i) {
+ if (ins->scbs[i].deleted)
+ continue;
+ cs46xx_dsp_proc_free_scb_desc((ins->scbs + i));
+ }
}
- mutex_unlock(&chip->spos_mutex);
snd_info_free_entry(ins->proc_dsp_dir);
ins->proc_dsp_dir = NULL;
@@ -1677,7 +1673,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->spdif_in_src))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) {
/* time countdown enable */
@@ -1700,7 +1696,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
ins->spdif_in_src,
SCB_ON_PARENT_SUBLIST_SCB);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
/* reset SPDIF input sample buffer pointer */
/*snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2,
@@ -1713,15 +1709,12 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
/* unmute SRC volume */
cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,0x7fff,0x7fff);
- spin_unlock_irq(&chip->reg_lock);
-
/* set SPDIF input sample rate and unmute
NOTE: only 48khz support for SPDIF input this time */
/* cs46xx_dsp_set_src_sample_rate(chip,ins->spdif_in_src,48000); */
/* monitor state */
ins->spdif_status_in = 1;
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -1735,17 +1728,16 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->spdif_in_src))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ scoped_guard(mutex, &chip->spos_mutex) {
+ /* Remove the asynchronous receiver SCB */
+ cs46xx_dsp_remove_scb(chip, ins->asynch_rx_scb);
+ ins->asynch_rx_scb = NULL;
- /* Remove the asynchronous receiver SCB */
- cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb);
- ins->asynch_rx_scb = NULL;
+ cs46xx_src_unlink(chip, ins->spdif_in_src);
- cs46xx_src_unlink(chip,ins->spdif_in_src);
-
- /* monitor state */
- ins->spdif_status_in = 0;
- mutex_unlock(&chip->spos_mutex);
+ /* monitor state */
+ ins->spdif_status_in = 0;
+ }
/* restore amplifier */
chip->active_ctrl(chip, -1);
@@ -1763,10 +1755,9 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->ref_snoop_scb))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
"PCMSerialInput_Wave");
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -1778,10 +1769,9 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->pcm_input))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->pcm_input);
ins->pcm_input = NULL;
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -1795,10 +1785,9 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->codec_in_scb))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
"PCMSerialInput_ADC");
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -1810,10 +1799,9 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip)
if (snd_BUG_ON(!ins->adc_input))
return -EINVAL;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->adc_input);
ins->adc_input = NULL;
- mutex_unlock(&chip->spos_mutex);
return 0;
}
@@ -1861,7 +1849,7 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right)
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
struct dsp_scb_descriptor * scb;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
/* main output */
scb = ins->master_mix_scb->sub_list_ptr;
@@ -1880,8 +1868,6 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right)
ins->dac_volume_left = left;
ins->dac_volume_right = right;
- mutex_unlock(&chip->spos_mutex);
-
return 0;
}
@@ -1889,7 +1875,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
if (ins->asynch_rx_scb != NULL)
cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb,
@@ -1898,8 +1884,6 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
ins->spdif_input_volume_left = left;
ins->spdif_input_volume_right = right;
- mutex_unlock(&chip->spos_mutex);
-
return 0;
}
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 28faca268196..32ed415bf427 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -63,7 +63,7 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
int j,col;
void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
- mutex_lock(&chip->spos_mutex);
+ guard(mutex)(&chip->spos_mutex);
snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);
for (col = 0,j = 0;j < 0x10; j++,col++) {
@@ -91,7 +91,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
scb->task_entry->address);
snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count);
- mutex_unlock(&chip->spos_mutex);
}
#endif
@@ -160,7 +159,6 @@ static void _dsp_clear_sample_buffer (struct snd_cs46xx *chip, u32 sample_buffer
void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned long flags;
/* check integrety */
if (snd_BUG_ON(scb->index < 0 ||
@@ -176,9 +174,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
goto _end;
#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- _dsp_unlink_scb (chip,scb);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ _dsp_unlink_scb(chip, scb);
+ }
cs46xx_dsp_proc_free_scb_desc(scb);
if (snd_BUG_ON(!scb->scb_symbol))
@@ -263,8 +261,6 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
struct dsp_scb_descriptor * scb;
- unsigned long flags;
-
if (snd_BUG_ON(!ins->the_null_scb))
return NULL;
@@ -318,12 +314,10 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
snd_BUG();
}
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- /* update entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
-
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ /* update entry in DSP RAM */
+ cs46xx_dsp_spos_update_scb(chip, scb->parent_scb_ptr);
+ }
}
@@ -1220,7 +1214,6 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
/* struct dsp_scb_descriptor * pcm_parent_scb; */
char scb_name[DSP_MAX_SCB_NAME];
int i, pcm_index = -1, insert_point, src_index = -1, pass_through = 0;
- unsigned long flags;
switch (pcm_channel_id) {
case DSP_PCM_MAIN_CHANNEL:
@@ -1357,7 +1350,7 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
return NULL;
}
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
ins->pcm_channels[pcm_index].sample_rate = sample_rate;
ins->pcm_channels[pcm_index].pcm_reader_scb = pcm_scb;
ins->pcm_channels[pcm_index].src_scb = src_scb;
@@ -1368,7 +1361,6 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
ins->pcm_channels[pcm_index].pcm_slot = pcm_index;
ins->pcm_channels[pcm_index].mixer_scb = mixer_scb;
ins->npcm_channels ++;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return (ins->pcm_channels + pcm_index);
}
@@ -1456,20 +1448,19 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
struct dsp_pcm_channel_descriptor * pcm_channel)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned long flags;
if (snd_BUG_ON(!pcm_channel->active ||
ins->npcm_channels <= 0 ||
pcm_channel->src_scb->ref_count <= 0))
return;
- spin_lock_irqsave(&chip->reg_lock, flags);
- pcm_channel->unlinked = 1;
- pcm_channel->active = 0;
- pcm_channel->private_data = NULL;
- pcm_channel->src_scb->ref_count --;
- ins->npcm_channels --;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ pcm_channel->unlinked = 1;
+ pcm_channel->active = 0;
+ pcm_channel->private_data = NULL;
+ pcm_channel->src_scb->ref_count--;
+ ins->npcm_channels--;
+ }
cs46xx_dsp_remove_scb(chip,pcm_channel->pcm_reader_scb);
@@ -1488,22 +1479,17 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
struct dsp_pcm_channel_descriptor * pcm_channel)
{
- unsigned long flags;
-
if (snd_BUG_ON(!pcm_channel->active ||
chip->dsp_spos_instance->npcm_channels <= 0))
return -EIO;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (pcm_channel->unlinked) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
+ if (pcm_channel->unlinked)
return -EIO;
- }
pcm_channel->unlinked = 1;
_dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -1514,14 +1500,11 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
struct dsp_scb_descriptor * parent_scb;
struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
- if (pcm_channel->unlinked == 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ if (pcm_channel->unlinked == 0)
return -EIO;
- }
parent_scb = src_scb;
@@ -1542,7 +1525,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
cs46xx_dsp_spos_update_scb(chip,parent_scb);
pcm_channel->unlinked = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -1575,17 +1557,14 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
{
- unsigned long flags;
-
if (snd_BUG_ON(!src->parent_scb_ptr))
return -EINVAL;
/* mute SCB */
cs46xx_dsp_scb_set_volume (chip,src,0,0);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
_dsp_unlink_scb (chip,src);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 76566e7baea0..0ebf6c02b1ef 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -176,9 +176,10 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
static void process_bm0_irq(struct cs5535audio *cs5535au)
{
u8 bm_stat;
- spin_lock(&cs5535au->reg_lock);
- bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
- spin_unlock(&cs5535au->reg_lock);
+
+ scoped_guard(spinlock, &cs5535au->reg_lock) {
+ bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
+ }
if (bm_stat & EOP) {
snd_pcm_period_elapsed(cs5535au->playback_substream);
} else {
@@ -191,9 +192,10 @@ static void process_bm0_irq(struct cs5535audio *cs5535au)
static void process_bm1_irq(struct cs5535audio *cs5535au)
{
u8 bm_stat;
- spin_lock(&cs5535au->reg_lock);
- bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
- spin_unlock(&cs5535au->reg_lock);
+
+ scoped_guard(spinlock, &cs5535au->reg_lock) {
+ bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
+ }
if (bm_stat & EOP)
snd_pcm_period_elapsed(cs5535au->capture_substream);
}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index f296b2c63026..48b99a07e3bc 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -150,10 +150,9 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
dma->substream = substream;
dma->period_bytes = period_bytes;
dma->periods = periods;
- spin_lock_irq(&cs5535au->reg_lock);
+ guard(spinlock_irq)(&cs5535au->reg_lock);
dma->ops->disable_dma(cs5535au);
dma->ops->setup_prd(cs5535au, jmpprd_addr);
- spin_unlock_irq(&cs5535au->reg_lock);
return 0;
}
@@ -276,9 +275,8 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
struct cs5535audio_dma *dma = substream->runtime->private_data;
- int err = 0;
- spin_lock(&cs5535au->reg_lock);
+ guard(spinlock)(&cs5535au->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dma->ops->pause_dma(cs5535au);
@@ -300,11 +298,9 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
break;
default:
dev_err(cs5535au->card->dev, "unhandled trigger\n");
- err = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&cs5535au->reg_lock);
- return err;
+ return 0;
}
static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(struct snd_pcm_substream
diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c
index 397900929aa6..bb4658592636 100644
--- a/sound/pci/ctxfi/ctamixer.c
+++ b/sound/pci/ctxfi/ctamixer.c
@@ -231,7 +231,6 @@ static int get_amixer_rsc(struct amixer_mgr *mgr,
int err, i;
unsigned int idx;
struct amixer *amixer;
- unsigned long flags;
*ramixer = NULL;
@@ -243,15 +242,15 @@ static int get_amixer_rsc(struct amixer_mgr *mgr,
/* Check whether there are sufficient
* amixer resources to meet request. */
err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < desc->msr; i++) {
+ err = mgr_get_resource(&mgr->mgr, 1, &idx);
+ if (err)
+ break;
- amixer->idx[i] = idx;
+ amixer->idx[i] = idx;
+ }
}
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
if (err) {
dev_err(mgr->card->dev,
"Can't meet AMIXER resource request!\n");
@@ -267,25 +266,23 @@ static int get_amixer_rsc(struct amixer_mgr *mgr,
return 0;
error:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i--; i >= 0; i--)
+ mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
+ }
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
kfree(amixer);
return err;
}
static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < amixer->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < amixer->rsc.msr; i++)
+ mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
+ }
amixer_rsc_uninit(amixer);
kfree(amixer);
@@ -387,7 +384,6 @@ static int get_sum_rsc(struct sum_mgr *mgr,
int err, i;
unsigned int idx;
struct sum *sum;
- unsigned long flags;
*rsum = NULL;
@@ -398,15 +394,15 @@ static int get_sum_rsc(struct sum_mgr *mgr,
/* Check whether there are sufficient sum resources to meet request. */
err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < desc->msr; i++) {
+ err = mgr_get_resource(&mgr->mgr, 1, &idx);
+ if (err)
+ break;
- sum->idx[i] = idx;
+ sum->idx[i] = idx;
+ }
}
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
if (err) {
dev_err(mgr->card->dev,
"Can't meet SUM resource request!\n");
@@ -422,25 +418,22 @@ static int get_sum_rsc(struct sum_mgr *mgr,
return 0;
error:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i--; i >= 0; i--)
+ mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
+ }
kfree(sum);
return err;
}
static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < sum->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < sum->rsc.msr; i++)
+ mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
+ }
sum_rsc_uninit(sum);
kfree(sum);
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 2a3e9d8ba7db..14779b383d9e 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -295,10 +295,10 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
src = apcm->src;
for (i = 0; i < n_amixer; i++) {
amixer = apcm->amixers[i];
- mutex_lock(&atc->atc_mutex);
- amixer->ops->setup(amixer, &src->rsc,
- INIT_VOL, atc->pcm[i+device*2]);
- mutex_unlock(&atc->atc_mutex);
+ scoped_guard(mutex, &atc->atc_mutex) {
+ amixer->ops->setup(amixer, &src->rsc,
+ INIT_VOL, atc->pcm[i+device*2]);
+ }
src = src->ops->next_interleave(src);
if (!src)
src = apcm->src;
@@ -874,7 +874,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
return -ENOENT;
}
- mutex_lock(&atc->atc_mutex);
+ guard(mutex)(&atc->atc_mutex);
dao->ops->get_spos(dao, &status);
if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
status &= ~(IEC958_AES3_CON_FS << 24);
@@ -884,7 +884,6 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
}
if ((rate != atc->pll_rate) && (32000 != rate))
err = atc_pll_init(atc, rate);
- mutex_unlock(&atc->atc_mutex);
return err;
}
@@ -921,13 +920,13 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
src = apcm->src;
}
/* Connect to SPDIFOO */
- mutex_lock(&atc->atc_mutex);
- dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
- amixer = apcm->amixers[0];
- dao->ops->set_left_input(dao, &amixer->rsc);
- amixer = apcm->amixers[1];
- dao->ops->set_right_input(dao, &amixer->rsc);
- mutex_unlock(&atc->atc_mutex);
+ scoped_guard(mutex, &atc->atc_mutex) {
+ dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
+ amixer = apcm->amixers[0];
+ dao->ops->set_left_input(dao, &amixer->rsc);
+ amixer = apcm->amixers[1];
+ dao->ops->set_right_input(dao, &amixer->rsc);
+ }
ct_timer_prepare(apcm->timer);
@@ -1115,7 +1114,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
struct rsc *rscs[2] = {NULL};
unsigned int spos = 0;
- mutex_lock(&atc->atc_mutex);
+ guard(mutex)(&atc->atc_mutex);
dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
da_dsc.msr = state ? 1 : atc->msr;
da_dsc.passthru = state ? 1 : 0;
@@ -1133,7 +1132,6 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
}
dao->ops->set_spos(dao, spos);
dao->ops->commit_write(dao);
- mutex_unlock(&atc->atc_mutex);
return err;
}
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index 806c4d754387..c0c3f8ab8467 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -503,14 +503,13 @@ static int get_daio_rsc(struct daio_mgr *mgr,
struct daio **rdaio)
{
int err;
- unsigned long flags;
*rdaio = NULL;
/* Check whether there are sufficient daio resources to meet request. */
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
+ }
if (err) {
dev_err(mgr->card->dev,
"Can't meet DAIO resource request!\n");
@@ -551,22 +550,20 @@ static int get_daio_rsc(struct daio_mgr *mgr,
return 0;
error:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- daio_mgr_put_rsc(&mgr->mgr, desc->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ daio_mgr_put_rsc(&mgr->mgr, desc->type);
+ }
return err;
}
static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
{
- unsigned long flags;
-
mgr->daio_disable(mgr, daio);
mgr->commit_write(mgr);
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- daio_mgr_put_rsc(&mgr->mgr, daio->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ daio_mgr_put_rsc(&mgr->mgr, daio->type);
+ }
if (daio->type <= DAIO_OUT_MAX) {
dao_rsc_uninit(container_of(daio, struct dao, daio));
@@ -622,34 +619,26 @@ static int daio_map_op(void *data, struct imapper *entry)
static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
+ guard(spinlock_irqsave)(&mgr->imap_lock);
if (!entry->addr && mgr->init_imap_added) {
input_mapper_delete(&mgr->imappers, mgr->init_imap,
daio_map_op, mgr);
mgr->init_imap_added = 0;
}
- err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
+ return input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
}
static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
{
- unsigned long flags;
int err;
- spin_lock_irqsave(&mgr->imap_lock, flags);
+ guard(spinlock_irqsave)(&mgr->imap_lock);
err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
if (list_empty(&mgr->imappers)) {
input_mapper_add(&mgr->imappers, mgr->init_imap,
daio_map_op, mgr);
mgr->init_imap_added = 1;
}
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
return err;
}
@@ -719,12 +708,11 @@ error1:
int daio_mgr_destroy(void *ptr)
{
struct daio_mgr *daio_mgr = ptr;
- unsigned long flags;
/* free daio input mapper list */
- spin_lock_irqsave(&daio_mgr->imap_lock, flags);
- free_input_mapper_list(&daio_mgr->imappers);
- spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
+ scoped_guard(spinlock_irqsave, &daio_mgr->imap_lock) {
+ free_input_mapper_list(&daio_mgr->imappers);
+ }
rsc_mgr_uninit(&daio_mgr->mgr);
kfree(daio_mgr);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 9edbf5d8c3c7..42b90c9b2ee9 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2091,57 +2091,30 @@ static int hw_resume(struct hw *hw, struct card_conf *info)
static u32 hw_read_20kx(struct hw *hw, u32 reg)
{
- u32 value;
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
+ guard(spinlock_irqsave)(&container_of(hw, struct hw20k1, hw)->reg_20k1_lock);
outl(reg, hw->io_base + 0x0);
- value = inl(hw->io_base + 0x4);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
-
- return value;
+ return inl(hw->io_base + 0x4);
}
static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
{
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
+ guard(spinlock_irqsave)(&container_of(hw, struct hw20k1, hw)->reg_20k1_lock);
outl(reg, hw->io_base + 0x0);
outl(data, hw->io_base + 0x4);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
-
}
static u32 hw_read_pci(struct hw *hw, u32 reg)
{
- u32 value;
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
+ guard(spinlock_irqsave)(&container_of(hw, struct hw20k1, hw)->reg_pci_lock);
outl(reg, hw->io_base + 0x10);
- value = inl(hw->io_base + 0x14);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
-
- return value;
+ return inl(hw->io_base + 0x14);
}
static void hw_write_pci(struct hw *hw, u32 reg, u32 data)
{
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
+ guard(spinlock_irqsave)(&container_of(hw, struct hw20k1, hw)->reg_pci_lock);
outl(reg, hw->io_base + 0x10);
outl(data, hw->io_base + 0x14);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
}
static const struct hw ct20k1_preset = {
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
index 159bd4008069..46afc9604c08 100644
--- a/sound/pci/ctxfi/ctsrc.c
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -414,18 +414,16 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
unsigned int idx = SRC_RESOURCE_NUM;
int err;
struct src *src;
- unsigned long flags;
*rsrc = NULL;
/* Check whether there are sufficient src resources to meet request. */
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- if (MEMRD == desc->mode)
- err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
- else
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ if (MEMRD == desc->mode)
+ err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
+ else
+ err = mgr_get_resource(&mgr->mgr, 1, &idx);
+ }
if (err) {
dev_err(mgr->card->dev,
"Can't meet SRC resource request!\n");
@@ -454,29 +452,25 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
error2:
kfree(src);
error1:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- if (MEMRD == desc->mode)
- mgr_put_resource(&mgr->mgr, desc->multi, idx);
- else
- mgr_put_resource(&mgr->mgr, 1, idx);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ if (MEMRD == desc->mode)
+ mgr_put_resource(&mgr->mgr, desc->multi, idx);
+ else
+ mgr_put_resource(&mgr->mgr, 1, idx);
+ }
return err;
}
static int put_src_rsc(struct src_mgr *mgr, struct src *src)
{
- unsigned long flags;
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- src->rsc.ops->master(&src->rsc);
- if (MEMRD == src->mode)
- mgr_put_resource(&mgr->mgr, src->multi,
- src->rsc.ops->index(&src->rsc));
- else
- mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ src->rsc.ops->master(&src->rsc);
+ if (MEMRD == src->mode)
+ mgr_put_resource(&mgr->mgr, src->multi,
+ src->rsc.ops->index(&src->rsc));
+ else
+ mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
+ }
src_rsc_uninit(src, mgr);
kfree(src);
@@ -714,7 +708,6 @@ static int get_srcimp_rsc(struct srcimp_mgr *mgr,
int err, i;
unsigned int idx;
struct srcimp *srcimp;
- unsigned long flags;
*rsrcimp = NULL;
@@ -725,15 +718,15 @@ static int get_srcimp_rsc(struct srcimp_mgr *mgr,
/* Check whether there are sufficient SRCIMP resources. */
err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < desc->msr; i++) {
+ err = mgr_get_resource(&mgr->mgr, 1, &idx);
+ if (err)
+ break;
- srcimp->idx[i] = idx;
+ srcimp->idx[i] = idx;
+ }
}
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
if (err) {
dev_err(mgr->card->dev,
"Can't meet SRCIMP resource request!\n");
@@ -749,25 +742,22 @@ static int get_srcimp_rsc(struct srcimp_mgr *mgr,
return 0;
error1:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i--; i >= 0; i--)
+ mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
+ }
kfree(srcimp);
return err;
}
static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
{
- unsigned long flags;
int i;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < srcimp->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
+ scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
+ for (i = 0; i < srcimp->rsc.msr; i++)
+ mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
+ }
srcimp_rsc_uninit(srcimp);
kfree(srcimp);
@@ -790,34 +780,26 @@ static int srcimp_map_op(void *data, struct imapper *entry)
static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
+ guard(spinlock_irqsave)(&mgr->imap_lock);
if ((0 == entry->addr) && (mgr->init_imap_added)) {
input_mapper_delete(&mgr->imappers,
mgr->init_imap, srcimp_map_op, mgr);
mgr->init_imap_added = 0;
}
- err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
+ return input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
}
static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
{
- unsigned long flags;
int err;
- spin_lock_irqsave(&mgr->imap_lock, flags);
+ guard(spinlock_irqsave)(&mgr->imap_lock);
err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
if (list_empty(&mgr->imappers)) {
input_mapper_add(&mgr->imappers, mgr->init_imap,
srcimp_map_op, mgr);
mgr->init_imap_added = 1;
}
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
return err;
}
@@ -870,12 +852,11 @@ error1:
int srcimp_mgr_destroy(void *ptr)
{
struct srcimp_mgr *srcimp_mgr = ptr;
- unsigned long flags;
/* free src input mapper list */
- spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
- free_input_mapper_list(&srcimp_mgr->imappers);
- spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
+ scoped_guard(spinlock_irqsave, &srcimp_mgr->imap_lock) {
+ free_input_mapper_list(&srcimp_mgr->imappers);
+ }
rsc_mgr_uninit(&srcimp_mgr->mgr);
kfree(srcimp_mgr);
diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c
index fa6867adb42b..609b10320ff7 100644
--- a/sound/pci/ctxfi/cttimer.c
+++ b/sound/pci/ctxfi/cttimer.c
@@ -68,7 +68,6 @@ static void ct_systimer_callback(struct timer_list *t)
struct ct_atc_pcm *apcm = ti->apcm;
unsigned int period_size = runtime->period_size;
unsigned int buffer_size = runtime->buffer_size;
- unsigned long flags;
unsigned int position, dist, interval;
position = substream->ops->pointer(substream);
@@ -82,10 +81,9 @@ static void ct_systimer_callback(struct timer_list *t)
* at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
interval = ((period_size - (position % period_size))
* HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000;
- spin_lock_irqsave(&ti->lock, flags);
+ guard(spinlock_irqsave)(&ti->lock);
if (ti->running)
mod_timer(&ti->timer, jiffies + interval);
- spin_unlock_irqrestore(&ti->lock, flags);
}
static void ct_systimer_init(struct ct_timer_instance *ti)
@@ -96,24 +94,19 @@ static void ct_systimer_init(struct ct_timer_instance *ti)
static void ct_systimer_start(struct ct_timer_instance *ti)
{
struct snd_pcm_runtime *runtime = ti->substream->runtime;
- unsigned long flags;
- spin_lock_irqsave(&ti->lock, flags);
+ guard(spinlock_irqsave)(&ti->lock);
ti->running = 1;
mod_timer(&ti->timer,
jiffies + (runtime->period_size * HZ +
(runtime->rate - 1)) / runtime->rate);
- spin_unlock_irqrestore(&ti->lock, flags);
}
static void ct_systimer_stop(struct ct_timer_instance *ti)
{
- unsigned long flags;
-
- spin_lock_irqsave(&ti->lock, flags);
+ guard(spinlock_irqsave)(&ti->lock);
ti->running = 0;
timer_delete(&ti->timer);
- spin_unlock_irqrestore(&ti->lock, flags);
}
static void ct_systimer_prepare(struct ct_timer_instance *ti)
@@ -229,25 +222,22 @@ static int ct_xfitimer_reprogram(struct ct_timer *atimer, int can_update)
static void ct_xfitimer_check_period(struct ct_timer *atimer)
{
struct ct_timer_instance *ti;
- unsigned long flags;
- spin_lock_irqsave(&atimer->list_lock, flags);
+ guard(spinlock_irqsave)(&atimer->list_lock);
list_for_each_entry(ti, &atimer->instance_head, instance_list) {
if (ti->running && ti->need_update) {
ti->need_update = 0;
ti->apcm->interrupt(ti->apcm);
}
}
- spin_unlock_irqrestore(&atimer->list_lock, flags);
}
/* Handle timer-interrupt */
static void ct_xfitimer_callback(struct ct_timer *atimer)
{
int update;
- unsigned long flags;
- spin_lock_irqsave(&atimer->lock, flags);
+ guard(spinlock_irqsave)(&atimer->lock);
atimer->irq_handling = 1;
do {
update = ct_xfitimer_reprogram(atimer, 1);
@@ -257,7 +247,6 @@ static void ct_xfitimer_callback(struct ct_timer *atimer)
spin_lock(&atimer->lock);
} while (atimer->reprogram);
atimer->irq_handling = 0;
- spin_unlock_irqrestore(&atimer->lock, flags);
}
static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
@@ -271,45 +260,39 @@ static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
/* start/stop the timer */
static void ct_xfitimer_update(struct ct_timer *atimer)
{
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->lock, flags);
+ guard(spinlock_irqsave)(&atimer->lock);
if (atimer->irq_handling) {
/* reached from IRQ handler; let it handle later */
atimer->reprogram = 1;
- spin_unlock_irqrestore(&atimer->lock, flags);
return;
}
ct_xfitimer_irq_stop(atimer);
ct_xfitimer_reprogram(atimer, 0);
- spin_unlock_irqrestore(&atimer->lock, flags);
}
static void ct_xfitimer_start(struct ct_timer_instance *ti)
{
struct ct_timer *atimer = ti->timer_base;
- unsigned long flags;
- spin_lock_irqsave(&atimer->lock, flags);
- if (list_empty(&ti->running_list))
- atimer->wc = ct_xfitimer_get_wc(atimer);
- ti->running = 1;
- ti->need_update = 0;
- list_add(&ti->running_list, &atimer->running_head);
- spin_unlock_irqrestore(&atimer->lock, flags);
+ scoped_guard(spinlock_irqsave, &atimer->lock) {
+ if (list_empty(&ti->running_list))
+ atimer->wc = ct_xfitimer_get_wc(atimer);
+ ti->running = 1;
+ ti->need_update = 0;
+ list_add(&ti->running_list, &atimer->running_head);
+ }
ct_xfitimer_update(atimer);
}
static void ct_xfitimer_stop(struct ct_timer_instance *ti)
{
struct ct_timer *atimer = ti->timer_base;
- unsigned long flags;
- spin_lock_irqsave(&atimer->lock, flags);
- list_del_init(&ti->running_list);
- ti->running = 0;
- spin_unlock_irqrestore(&atimer->lock, flags);
+ scoped_guard(spinlock_irqsave, &atimer->lock) {
+ list_del_init(&ti->running_list);
+ ti->running = 0;
+ }
ct_xfitimer_update(atimer);
}
@@ -347,9 +330,9 @@ ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm)
if (atimer->ops->init)
atimer->ops->init(ti);
- spin_lock_irq(&atimer->list_lock);
- list_add(&ti->instance_list, &atimer->instance_head);
- spin_unlock_irq(&atimer->list_lock);
+ scoped_guard(spinlock_irq, &atimer->list_lock) {
+ list_add(&ti->instance_list, &atimer->instance_head);
+ }
return ti;
}
@@ -382,9 +365,9 @@ void ct_timer_instance_free(struct ct_timer_instance *ti)
if (atimer->ops->free_instance)
atimer->ops->free_instance(ti);
- spin_lock_irq(&atimer->list_lock);
- list_del(&ti->instance_list);
- spin_unlock_irq(&atimer->list_lock);
+ scoped_guard(spinlock_irq, &atimer->list_lock) {
+ list_del(&ti->instance_list);
+ }
kfree(ti);
}
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 7a805c4a58e1..823d6e240a07 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -29,7 +29,7 @@
static struct ct_vm_block *
get_vm_block(struct ct_vm *vm, unsigned int size, struct ct_atc *atc)
{
- struct ct_vm_block *block = NULL, *entry;
+ struct ct_vm_block *block, *entry;
struct list_head *pos;
size = CT_PAGE_ALIGN(size);
@@ -39,26 +39,25 @@ get_vm_block(struct ct_vm *vm, unsigned int size, struct ct_atc *atc)
return NULL;
}
- mutex_lock(&vm->lock);
+ guard(mutex)(&vm->lock);
list_for_each(pos, &vm->unused) {
entry = list_entry(pos, struct ct_vm_block, list);
if (entry->size >= size)
break; /* found a block that is big enough */
}
if (pos == &vm->unused)
- goto out;
+ return NULL;
if (entry->size == size) {
/* Move the vm node from unused list to used list directly */
list_move(&entry->list, &vm->used);
vm->size -= size;
- block = entry;
- goto out;
+ return entry;
}
block = kzalloc(sizeof(*block), GFP_KERNEL);
if (!block)
- goto out;
+ return NULL;
block->addr = entry->addr;
block->size = size;
@@ -67,8 +66,6 @@ get_vm_block(struct ct_vm *vm, unsigned int size, struct ct_atc *atc)
entry->size -= size;
vm->size -= size;
- out:
- mutex_unlock(&vm->lock);
return block;
}
@@ -79,7 +76,7 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
block->size = CT_PAGE_ALIGN(block->size);
- mutex_lock(&vm->lock);
+ guard(mutex)(&vm->lock);
list_del(&block->list);
vm->size += block->size;
@@ -116,7 +113,6 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
pos = pre;
pre = pos->prev;
}
- mutex_unlock(&vm->lock);
}
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 2b33ef588ac3..f2c8602a1ad7 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -237,7 +237,7 @@ static int hw_rule_sample_rate(struct snd_pcm_hw_params *params,
struct snd_interval fixed;
int err;
- mutex_lock(&chip->mode_mutex);
+ guard(mutex)(&chip->mode_mutex);
if (chip->can_set_rate) {
err = 0;
@@ -247,7 +247,6 @@ static int hw_rule_sample_rate(struct snd_pcm_hw_params *params,
err = snd_interval_refine(rate, &fixed);
}
- mutex_unlock(&chip->mode_mutex);
return err;
}
@@ -415,7 +414,7 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream)
int err, max_channels;
max_channels = num_digital_busses_in(chip) - substream->number;
- mutex_lock(&chip->mode_mutex);
+ guard(mutex)(&chip->mode_mutex);
if (chip->digital_mode == DIGITAL_MODE_ADAT)
err = pcm_open(substream, max_channels);
else /* If the card has ADAT, subtract the 6 channels
@@ -424,24 +423,22 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream)
err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
if (err < 0)
- goto din_exit;
+ return err;
err = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
hw_rule_capture_channels_by_format, NULL,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
- goto din_exit;
+ return err;
err = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
hw_rule_capture_format_by_channels, NULL,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (err < 0)
- goto din_exit;
+ return err;
-din_exit:
- mutex_unlock(&chip->mode_mutex);
- return err;
+ return 0;
}
@@ -454,7 +451,7 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream)
int err, max_channels;
max_channels = num_digital_busses_out(chip) - substream->number;
- mutex_lock(&chip->mode_mutex);
+ guard(mutex)(&chip->mode_mutex);
if (chip->digital_mode == DIGITAL_MODE_ADAT)
err = pcm_open(substream, max_channels);
else /* If the card has ADAT, subtract the 6 channels
@@ -463,7 +460,7 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream)
err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
if (err < 0)
- goto dout_exit;
+ return err;
err = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
@@ -471,18 +468,16 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream)
NULL, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
if (err < 0)
- goto dout_exit;
+ return err;
err = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
hw_rule_playback_format_by_channels,
NULL, SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
if (err < 0)
- goto dout_exit;
+ return err;
-dout_exit:
- mutex_unlock(&chip->mode_mutex);
- return err;
+ return 0;
}
#endif /* !ECHOCARD_HAS_VMIXER */
@@ -499,7 +494,7 @@ static int pcm_close(struct snd_pcm_substream *substream)
* freed by its callback
*/
- mutex_lock(&chip->mode_mutex);
+ guard(mutex)(&chip->mode_mutex);
dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d",
chip->opencount, chip->can_set_rate, chip->rate_set);
@@ -516,7 +511,6 @@ static int pcm_close(struct snd_pcm_substream *substream)
break;
}
- mutex_unlock(&chip->mode_mutex);
return 0;
}
@@ -537,22 +531,21 @@ static int init_engine(struct snd_pcm_substream *substream,
/* Sets up che hardware. If it's already initialized, reset and
* redo with the new parameters
*/
- spin_lock_irq(&chip->lock);
- if (pipe->index >= 0) {
- dev_dbg(chip->card->dev, "hwp_ie free(%d)\n", pipe->index);
- err = free_pipes(chip, pipe);
- snd_BUG_ON(err);
- chip->substream[pipe->index] = NULL;
- }
+ scoped_guard(spinlock_irq, &chip->lock) {
+ if (pipe->index >= 0) {
+ dev_dbg(chip->card->dev, "hwp_ie free(%d)\n", pipe->index);
+ err = free_pipes(chip, pipe);
+ snd_BUG_ON(err);
+ chip->substream[pipe->index] = NULL;
+ }
- err = allocate_pipes(chip, pipe, pipe_index, interleave);
- if (err < 0) {
- spin_unlock_irq(&chip->lock);
- dev_err(chip->card->dev, "allocate_pipes(%d) err=%d\n",
- pipe_index, err);
- return err;
+ err = allocate_pipes(chip, pipe, pipe_index, interleave);
+ if (err < 0) {
+ dev_err(chip->card->dev, "allocate_pipes(%d) err=%d\n",
+ pipe_index, err);
+ return err;
+ }
}
- spin_unlock_irq(&chip->lock);
dev_dbg(chip->card->dev, "allocate_pipes()=%d\n", pipe_index);
dev_dbg(chip->card->dev,
@@ -600,9 +593,8 @@ static int init_engine(struct snd_pcm_substream *substream,
smp_wmb();
chip->substream[pipe_index] = substream;
chip->rate_set = 1;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den);
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -664,14 +656,13 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
chip = snd_pcm_substream_chip(substream);
pipe = (struct audiopipe *) substream->runtime->private_data;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
if (pipe->index >= 0) {
dev_dbg(chip->card->dev, "pcm_hw_free(%d)\n", pipe->index);
free_pipes(chip, pipe);
chip->substream[pipe->index] = NULL;
pipe->index = -1;
}
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -721,15 +712,12 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
* exclusive control
*/
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
- if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) {
- spin_unlock_irq(&chip->lock);
+ if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index)))
return -EINVAL;
- }
set_audio_format(chip, pipe_index, &format);
- spin_unlock_irq(&chip->lock);
return 0;
}
@@ -753,7 +741,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
}
- spin_lock(&chip->lock);
+ guard(spinlock)(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START:
@@ -801,7 +789,6 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
default:
err = -EINVAL;
}
- spin_unlock(&chip->lock);
return err;
}
@@ -1018,7 +1005,7 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
changed = 0;
chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
for (c = 0; c < num_busses_out(chip); c++) {
gain = ucontrol->value.integer.value[c];
/* Ignore out of range values */
@@ -1031,7 +1018,6 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
}
if (changed)
update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
return changed;
}
@@ -1099,7 +1085,7 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
changed = 0;
chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
for (c = 0; c < num_analog_busses_in(chip); c++) {
gain = ucontrol->value.integer.value[c];
/* Ignore out of range values */
@@ -1112,7 +1098,6 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
}
if (changed)
update_input_line_level(chip);
- spin_unlock_irq(&chip->lock);
return changed;
}
@@ -1168,7 +1153,7 @@ static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
changed = 0;
chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
for (c = 0; c < num_analog_busses_out(chip); c++) {
if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) {
set_nominal_level(chip, c,
@@ -1178,7 +1163,6 @@ static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
}
if (changed)
update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
return changed;
}
@@ -1231,7 +1215,7 @@ static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
changed = 0;
chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
for (c = 0; c < num_analog_busses_in(chip); c++) {
if (chip->nominal_level[bx_analog_in(chip) + c] !=
ucontrol->value.integer.value[c]) {
@@ -1244,7 +1228,6 @@ static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
update_output_line_level(chip); /* "Output" is not a mistake
* here.
*/
- spin_unlock_irq(&chip->lock);
return changed;
}
@@ -1304,10 +1287,9 @@ static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol,
if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
return -EINVAL;
if (chip->monitor_gain[out][in] != gain) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_monitor_gain(chip, out, in, gain);
update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
changed = 1;
}
return changed;
@@ -1367,10 +1349,9 @@ static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol,
if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
return -EINVAL;
if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]);
update_vmixer_level(chip);
- spin_unlock_irq(&chip->lock);
changed = 1;
}
return changed;
@@ -1440,7 +1421,7 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
if (dmode != chip->digital_mode) {
/* mode_mutex is required to make this operation atomic wrt
pcm_digital_*_open() and set_input_clock() functions. */
- mutex_lock(&chip->mode_mutex);
+ guard(mutex)(&chip->mode_mutex);
/* Do not allow the user to change the digital mode when a pcm
device is open because it also changes the number of channels
@@ -1460,7 +1441,6 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
if (changed >= 0)
changed = 1; /* No errors */
}
- mutex_unlock(&chip->mode_mutex);
}
return changed;
}
@@ -1507,9 +1487,8 @@ static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
chip = snd_kcontrol_chip(kcontrol);
mode = !!ucontrol->value.enumerated.item[0];
if (mode != chip->professional_spdif) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_professional_spdif(chip, mode);
- spin_unlock_irq(&chip->lock);
return 1;
}
return 0;
@@ -1573,13 +1552,11 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
dclock = chip->clock_source_list[eclock];
if (chip->input_clock != dclock) {
- mutex_lock(&chip->mode_mutex);
- spin_lock_irq(&chip->lock);
+ guard(mutex)(&chip->mode_mutex);
+ guard(spinlock_irq)(&chip->lock);
changed = set_input_clock(chip, dclock);
if (!changed)
changed = 1; /* no errors */
- spin_unlock_irq(&chip->lock);
- mutex_unlock(&chip->mode_mutex);
}
if (changed < 0)
@@ -1623,9 +1600,8 @@ static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
power = !!ucontrol->value.integer.value[0];
if (chip->phantom_power != power) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
changed = set_phantom_power(chip, power);
- spin_unlock_irq(&chip->lock);
if (changed == 0)
changed = 1; /* no errors */
}
@@ -1666,9 +1642,8 @@ static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
automute = !!ucontrol->value.integer.value[0];
if (chip->digital_in_automute != automute) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
changed = set_input_auto_mute(chip, automute);
- spin_unlock_irq(&chip->lock);
if (changed == 0)
changed = 1; /* no errors */
}
@@ -1696,9 +1671,8 @@ static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
struct echoaudio *chip;
chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_meters_on(chip, ucontrol->value.integer.value[0]);
- spin_unlock_irq(&chip->lock);
return 1;
}
@@ -2143,17 +2117,13 @@ static int snd_echo_suspend(struct device *dev)
if (chip->midi_out)
snd_echo_midi_output_trigger(chip->midi_out, 0);
#endif
- spin_lock_irq(&chip->lock);
- if (wait_handshake(chip)) {
- spin_unlock_irq(&chip->lock);
- return -EIO;
- }
- clear_handshake(chip);
- if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
- spin_unlock_irq(&chip->lock);
- return -EIO;
+ scoped_guard(spinlock_irq, &chip->lock) {
+ if (wait_handshake(chip))
+ return -EIO;
+ clear_handshake(chip);
+ if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0)
+ return -EIO;
}
- spin_unlock_irq(&chip->lock);
chip->dsp_code = NULL;
free_irq(chip->irq, chip);
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index 18b4d4b4d38d..c9ee98ea3c71 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -119,7 +119,7 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
* updated by the DSP comm object. */
if (err >= 0 && previous_mode != mode &&
(previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
for (o = 0; o < num_busses_out(chip); o++)
for (i = 0; i < num_busses_in(chip); i++)
set_monitor_gain(chip, o, i,
@@ -134,7 +134,6 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
for (o = 0; o < num_busses_out(chip); o++)
set_output_gain(chip, o, chip->output_gain[o]);
update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
}
return err;
@@ -396,7 +395,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
return -EINVAL;
}
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
if (incompatible_clock) {
chip->sample_rate = 48000;
@@ -422,7 +421,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
}
err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
- spin_unlock_irq(&chip->lock);
if (err < 0)
return err;
chip->digital_mode = mode;
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 56e9d1b9b330..78fbac9f3eac 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -305,7 +305,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
return -EINVAL;
}
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
if (incompatible_clock) { /* Switch to 48KHz, internal */
chip->sample_rate = 48000;
@@ -336,7 +336,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
}
err = write_control_reg(chip, control_reg, true);
- spin_unlock_irq(&chip->lock);
if (err < 0)
return err;
chip->digital_mode = mode;
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index ef27805d63f6..decfccb1e803 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -358,16 +358,15 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
if (incompatible_clock) { /* Switch to 48KHz, internal */
chip->sample_rate = 48000;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
- spin_unlock_irq(&chip->lock);
}
/* switch_asic() can sleep */
if (switch_asic(chip, asic) < 0)
return -EIO;
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
/* Tweak the control register */
control_reg = le32_to_cpu(chip->comm_page->control_register);
@@ -387,7 +386,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
}
err = write_control_reg(chip, control_reg, true);
- spin_unlock_irq(&chip->lock);
if (err < 0)
return err;
chip->digital_mode = mode;
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
index 4ee230794b4e..dd5212644844 100644
--- a/sound/pci/echoaudio/midi.c
+++ b/sound/pci/echoaudio/midi.c
@@ -167,9 +167,8 @@ static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream,
struct echoaudio *chip = substream->rmidi->private_data;
if (up != chip->midi_input_enabled) {
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
enable_midi_input(chip, up);
- spin_unlock_irq(&chip->lock);
chip->midi_input_enabled = up;
}
}
@@ -201,14 +200,13 @@ static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream)
static void snd_echo_midi_output_write(struct timer_list *t)
{
struct echoaudio *chip = timer_container_of(chip, t, timer);
- unsigned long flags;
int bytes, sent, time;
unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1];
/* No interrupts are involved: we have to check at regular intervals
if the card's output buffer has room for new data. */
sent = 0;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->midi_full = 0;
if (!snd_rawmidi_transmit_empty(chip->midi_out)) {
bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf,
@@ -242,7 +240,6 @@ static void snd_echo_midi_output_write(struct timer_list *t)
dev_dbg(chip->card->dev,
"Timer armed(%d)\n", ((time * HZ + 999) / 1000));
}
- spin_unlock_irqrestore(&chip->lock, flags);
}
@@ -251,25 +248,29 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream
int up)
{
struct echoaudio *chip = substream->rmidi->private_data;
+ bool remove_timer = false;
dev_dbg(chip->card->dev, "snd_echo_midi_output_trigger(%d)\n", up);
- spin_lock_irq(&chip->lock);
- if (up) {
- if (!chip->tinuse) {
- timer_setup(&chip->timer, snd_echo_midi_output_write,
- 0);
- chip->tinuse = 1;
- }
- } else {
- if (chip->tinuse) {
- chip->tinuse = 0;
- spin_unlock_irq(&chip->lock);
- timer_delete_sync(&chip->timer);
- dev_dbg(chip->card->dev, "Timer removed\n");
- return;
+ scoped_guard(spinlock_irq, &chip->lock) {
+ if (up) {
+ if (!chip->tinuse) {
+ timer_setup(&chip->timer, snd_echo_midi_output_write,
+ 0);
+ chip->tinuse = 1;
+ }
+ } else {
+ if (chip->tinuse) {
+ chip->tinuse = 0;
+ remove_timer = true;
+ }
}
}
- spin_unlock_irq(&chip->lock);
+
+ if (remove_timer) {
+ timer_delete_sync(&chip->timer);
+ dev_dbg(chip->card->dev, "Timer removed\n");
+ return;
+ }
if (up && !chip->midi_full)
snd_echo_midi_output_write(&chip->timer);
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index f8e7bb6ce040..9bb6a174745c 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -381,7 +381,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
return -EINVAL;
}
- spin_lock_irq(&chip->lock);
+ guard(spinlock_irq)(&chip->lock);
if (incompatible_clock) { /* Switch to 48KHz, internal */
chip->sample_rate = 48000;
@@ -413,7 +413,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
}
err = write_control_reg(chip, control_reg, false);
- spin_unlock_irq(&chip->lock);
if (err < 0)
return err;
chip->digital_mode = mode;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index bbe252b8916c..b2fe2d164ba8 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -745,12 +745,12 @@ static void emu1010_clock_event(struct snd_emu10k1 *emu)
{
struct snd_ctl_elem_id id;
- spin_lock_irq(&emu->reg_lock);
- // This is the only thing that can actually happen.
- emu->emu1010.clock_source = emu->emu1010.clock_fallback;
- emu->emu1010.wclock = 1 - emu->emu1010.clock_source;
- snd_emu1010_update_clock(emu);
- spin_unlock_irq(&emu->reg_lock);
+ scoped_guard(spinlock_irq, &emu->reg_lock) {
+ // This is the only thing that can actually happen.
+ emu->emu1010.clock_source = emu->emu1010.clock_fallback;
+ emu->emu1010.wclock = 1 - emu->emu1010.clock_source;
+ snd_emu1010_update_clock(emu);
+ }
snd_ctl_build_ioff(&id, emu->ctl_clock_source, 0);
snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
}
@@ -768,7 +768,7 @@ static void emu1010_work(struct work_struct *work)
return;
#endif
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts);
@@ -779,8 +779,6 @@ static void emu1010_work(struct work_struct *work)
if (sts & EMU_HANA_IRQ_WCLK_CHANGED)
emu1010_clock_event(emu);
-
- snd_emu1010_fpga_unlock(emu);
}
static void emu1010_interrupt(struct snd_emu10k1 *emu)
@@ -814,13 +812,13 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
* Proper init follows in snd_emu10k1_init(). */
outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
dev_info(emu->card->dev, "emu1010: Loading Hana Firmware\n");
err = snd_emu1010_load_firmware(emu, 0, &emu->firmware);
if (err < 0) {
dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n");
- goto fail;
+ return err;
}
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
@@ -830,8 +828,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
dev_info(emu->card->dev,
"emu1010: Loading Hana Firmware file failed, reg = 0x%x\n",
reg);
- err = -ENODEV;
- goto fail;
+ return -ENODEV;
}
dev_info(emu->card->dev, "emu1010: Hana Firmware loaded\n");
@@ -891,9 +888,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
// so it is safe to simply enable the outputs.
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
-fail:
- snd_emu1010_fpga_unlock(emu);
- return err;
+ return 0;
}
/*
* Create the EMU10K1 instance
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
index 68dfcb24b889..662d20eb9689 100644
--- a/sound/pci/emu10k1/emu10k1_synth.c
+++ b/sound/pci/emu10k1/emu10k1_synth.c
@@ -55,10 +55,9 @@ static int snd_emu10k1_synth_probe(struct device *_dev)
return -ENOMEM;
}
- spin_lock_irq(&hw->voice_lock);
+ guard(spinlock_irq)(&hw->voice_lock);
hw->synth = emux;
hw->get_synth_voice = snd_emu10k1_synth_get_voice;
- spin_unlock_irq(&hw->voice_lock);
dev->driver_data = emux;
@@ -77,10 +76,10 @@ static int snd_emu10k1_synth_remove(struct device *_dev)
emux = dev->driver_data;
hw = emux->hw;
- spin_lock_irq(&hw->voice_lock);
- hw->synth = NULL;
- hw->get_synth_voice = NULL;
- spin_unlock_irq(&hw->voice_lock);
+ scoped_guard(spinlock_irq, &hw->voice_lock) {
+ hw->synth = NULL;
+ hw->get_synth_voice = NULL;
+ }
snd_emux_free(emux);
return 0;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 8c18ad987223..9607a0f7174b 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -281,16 +281,13 @@ static unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu,
unsigned int reg,
unsigned int chn)
{
- unsigned long flags;
- unsigned int regptr, val;
+ unsigned int regptr;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inl(emu->port + DATA);
}
static void snd_emu10k1x_ptr_write(struct emu10k1x *emu,
@@ -299,45 +296,36 @@ static void snd_emu10k1x_ptr_write(struct emu10k1x *emu,
unsigned int data)
{
unsigned int regptr;
- unsigned long flags;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + PTR);
outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int intr_enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
intr_enable = inl(emu->port + INTE) | intrenb;
outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int intr_enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
intr_enable = inl(emu->port + INTE) & ~intrenb;
outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(value, emu->port + GPIO);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
@@ -694,26 +682,20 @@ static unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
struct emu10k1x *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + AC97ADDRESS);
- val = inw(emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inw(emu->port + AC97DATA);
}
static void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val)
{
struct emu10k1x *emu = ac97->private_data;
- unsigned long flags;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + AC97ADDRESS);
outw(val, emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static int snd_emu10k1x_ac97(struct emu10k1x *chip)
@@ -966,14 +948,12 @@ static void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry,
{
struct emu10k1x *emu = entry->private_data;
unsigned long value,value1,value2;
- unsigned long flags;
int i;
snd_iprintf(buffer, "Registers:\n\n");
for(i = 0; i < 0x20; i+=4) {
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
value = inl(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
}
snd_iprintf(buffer, "\nRegisters\n\n");
@@ -1206,28 +1186,28 @@ static void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
return;
}
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- mpu401_clear_rx(emu, midi);
- } else {
- byte = mpu401_read_data(emu, midi);
- if (midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
+ scoped_guard(spinlock, &midi->input_lock) {
+ if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
+ if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
+ mpu401_clear_rx(emu, midi);
+ } else {
+ byte = mpu401_read_data(emu, midi);
+ if (midi->substream_input)
+ snd_rawmidi_receive(midi->substream_input, &byte, 1);
+ }
}
}
- spin_unlock(&midi->input_lock);
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- mpu401_write_data(emu, midi, byte);
- } else {
- snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+ scoped_guard(spinlock, &midi->output_lock) {
+ if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
+ if (midi->substream_output &&
+ snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+ mpu401_write_data(emu, midi, byte);
+ } else {
+ snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+ }
}
}
- spin_unlock(&midi->output_lock);
}
static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
@@ -1238,29 +1218,28 @@ static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int statu
static int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
struct emu10k1x_midi *midi, unsigned char cmd, int ack)
{
- unsigned long flags;
int timeout, ok;
- spin_lock_irqsave(&midi->input_lock, flags);
- mpu401_write_data(emu, midi, 0x00);
- /* mpu401_clear_rx(emu, midi); */
-
- mpu401_write_cmd(emu, midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (mpu401_input_avail(emu, midi)) {
- if (mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
+ scoped_guard(spinlock_irqsave, &midi->input_lock) {
+ mpu401_write_data(emu, midi, 0x00);
+ /* mpu401_clear_rx(emu, midi); */
+
+ mpu401_write_cmd(emu, midi, cmd);
+ if (ack) {
+ ok = 0;
+ timeout = 10000;
+ while (!ok && timeout-- > 0) {
+ if (mpu401_input_avail(emu, midi)) {
+ if (mpu401_read_data(emu, midi) == MPU401_ACK)
+ ok = 1;
+ }
}
- }
- if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
+ if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
+ ok = 1;
+ } else {
ok = 1;
- } else {
- ok = 1;
+ }
}
- spin_unlock_irqrestore(&midi->input_lock, flags);
if (!ok) {
dev_err(emu->card->dev,
"midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
@@ -1276,100 +1255,78 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
+ midi->substream_input = substream;
+ if (midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)
+ return 0;
}
+ if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
+ return -EIO;
+ if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ return -EIO;
return 0;
-
-error_out:
- return -EIO;
}
static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
+ midi->substream_output = substream;
+ if (midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)
+ return 0;
}
+ if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
+ return -EIO;
+ if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ return -EIO;
return 0;
-
-error_out:
- return -EIO;
}
static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1x_intr_disable(emu, midi->rx_enable);
- midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ snd_emu10k1x_intr_disable(emu, midi->rx_enable);
+ midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
+ midi->substream_input = NULL;
+ if (midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)
+ return 0;
}
- return err;
+ return snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
}
static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1x_intr_disable(emu, midi->tx_enable);
- midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
+ scoped_guard(spinlock_irqsave, &midi->open_lock) {
+ snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+ midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
+ midi->substream_output = NULL;
+ if (midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)
+ return 0;
}
- return err;
+ return snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
}
static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -1390,7 +1347,6 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst
{
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
@@ -1401,22 +1357,21 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst
unsigned char byte;
/* try to send some amount of bytes here before interrupts */
- spin_lock_irqsave(&midi->output_lock, flags);
- while (max > 0) {
- if (mpu401_output_ready(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irqrestore(&midi->output_lock, flags);
- return;
+ scoped_guard(spinlock_irqsave, &midi->output_lock) {
+ while (max > 0) {
+ if (mpu401_output_ready(emu, midi)) {
+ if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
+ snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+ /* no more data */
+ return;
+ }
+ mpu401_write_data(emu, midi, byte);
+ max--;
+ } else {
+ break;
}
- mpu401_write_data(emu, midi, byte);
- max--;
- } else {
- break;
}
}
- spin_unlock_irqrestore(&midi->output_lock, flags);
snd_emu10k1x_intr_enable(emu, midi->tx_enable);
} else {
snd_emu10k1x_intr_disable(emu, midi->tx_enable);
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7db0660e6b61..37af7bf76347 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -440,13 +440,11 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
void *private_data,
struct snd_emu10k1_fx8010_irq *irq)
{
- unsigned long flags;
-
irq->handler = handler;
irq->gpr_running = gpr_running;
irq->private_data = private_data;
irq->next = NULL;
- spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
+ guard(spinlock_irqsave)(&emu->fx8010.irq_lock);
if (emu->fx8010.irq_handlers == NULL) {
emu->fx8010.irq_handlers = irq;
emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
@@ -455,7 +453,6 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
irq->next = emu->fx8010.irq_handlers;
emu->fx8010.irq_handlers = irq;
}
- spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
return 0;
}
@@ -463,9 +460,8 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_irq *irq)
{
struct snd_emu10k1_fx8010_irq *tmp;
- unsigned long flags;
- spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
+ guard(spinlock_irqsave)(&emu->fx8010.irq_lock);
tmp = emu->fx8010.irq_handlers;
if (tmp == irq) {
emu->fx8010.irq_handlers = tmp->next;
@@ -479,7 +475,6 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
if (tmp)
tmp->next = tmp->next->next;
}
- spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
return 0;
}
@@ -1026,12 +1021,12 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_code *icode,
bool in_kernel)
{
- int err = 0;
+ int err;
- mutex_lock(&emu->fx8010.lock);
+ guard(mutex)(&emu->fx8010.lock);
err = snd_emu10k1_verify_controls(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
strscpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
/* stop FX processor - this may be dangerous, but it's better to miss
some samples than generate wrong ones - [jk] */
@@ -1042,27 +1037,25 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
/* ok, do the main job */
err = snd_emu10k1_del_controls(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
err = snd_emu10k1_gpr_poke(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
err = snd_emu10k1_tram_poke(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
err = snd_emu10k1_code_poke(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
err = snd_emu10k1_add_controls(emu, icode, in_kernel);
if (err < 0)
- goto __error;
+ return err;
/* start FX processor when the DSP code is updated */
if (emu->audigy)
snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
else
snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
- __error:
- mutex_unlock(&emu->fx8010.lock);
- return err;
+ return 0;
}
static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
@@ -1070,7 +1063,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
{
int err;
- mutex_lock(&emu->fx8010.lock);
+ guard(mutex)(&emu->fx8010.lock);
strscpy(icode->name, emu->fx8010.name, sizeof(icode->name));
/* ok, do the main job */
err = snd_emu10k1_gpr_peek(emu, icode);
@@ -1080,7 +1073,6 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
err = snd_emu10k1_code_peek(emu, icode);
if (err >= 0)
err = snd_emu10k1_list_controls(emu, icode);
- mutex_unlock(&emu->fx8010.lock);
return err;
}
@@ -1088,7 +1080,6 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_pcm_rec *ipcm)
{
unsigned int i;
- int err = 0;
struct snd_emu10k1_fx8010_pcm *pcm;
if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
@@ -1098,20 +1089,16 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
if (ipcm->channels > 32)
return -EINVAL;
pcm = &emu->fx8010.pcm[ipcm->substream];
- mutex_lock(&emu->fx8010.lock);
- spin_lock_irq(&emu->reg_lock);
- if (pcm->opened) {
- err = -EBUSY;
- goto __error;
- }
+ guard(mutex)(&emu->fx8010.lock);
+ guard(spinlock_irq)(&emu->reg_lock);
+ if (pcm->opened)
+ return -EBUSY;
if (ipcm->channels == 0) { /* remove */
pcm->valid = 0;
} else {
/* FIXME: we need to add universal code to the PCM transfer routine */
- if (ipcm->channels != 2) {
- err = -EINVAL;
- goto __error;
- }
+ if (ipcm->channels != 2)
+ return -EINVAL;
pcm->valid = 1;
pcm->opened = 0;
pcm->channels = ipcm->channels;
@@ -1126,17 +1113,13 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
for (i = 0; i < pcm->channels; i++)
pcm->etram[i] = ipcm->etram[i];
}
- __error:
- spin_unlock_irq(&emu->reg_lock);
- mutex_unlock(&emu->fx8010.lock);
- return err;
+ return 0;
}
static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_pcm_rec *ipcm)
{
unsigned int i;
- int err = 0;
struct snd_emu10k1_fx8010_pcm *pcm;
if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
@@ -1144,8 +1127,8 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
ipcm->substream = array_index_nospec(ipcm->substream,
EMU10K1_FX8010_PCM_COUNT);
pcm = &emu->fx8010.pcm[ipcm->substream];
- mutex_lock(&emu->fx8010.lock);
- spin_lock_irq(&emu->reg_lock);
+ guard(mutex)(&emu->fx8010.lock);
+ guard(spinlock_irq)(&emu->reg_lock);
ipcm->channels = pcm->channels;
ipcm->tram_start = pcm->tram_start;
ipcm->buffer_size = pcm->buffer_size;
@@ -1159,9 +1142,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
ipcm->etram[i] = pcm->etram[i];
ipcm->res1 = ipcm->res2 = 0;
ipcm->pad = 0;
- spin_unlock_irq(&emu->reg_lock);
- mutex_unlock(&emu->fx8010.lock);
- return err;
+ return 0;
}
#define SND_EMU10K1_GPR_CONTROLS 44
@@ -2415,9 +2396,9 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
}
if ((emu->fx8010.etram_pages.bytes / 2) == size)
return 0;
- spin_lock_irq(&emu->emu_lock);
- outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
- spin_unlock_irq(&emu->emu_lock);
+ scoped_guard(spinlock_irq, &emu->emu_lock) {
+ outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
+ }
snd_emu10k1_ptr_write(emu, TCB, 0, 0);
snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
if (emu->fx8010.etram_pages.area != NULL) {
@@ -2433,9 +2414,9 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
memset(emu->fx8010.etram_pages.area, 0, size * 2);
snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
- spin_lock_irq(&emu->emu_lock);
- outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
- spin_unlock_irq(&emu->emu_lock);
+ scoped_guard(spinlock_irq, &emu->emu_lock) {
+ outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
+ }
}
return 0;
@@ -2547,9 +2528,9 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un
return -EPERM;
if (get_user(addr, (unsigned int __user *)argp))
return -EFAULT;
- mutex_lock(&emu->fx8010.lock);
- res = snd_emu10k1_fx8010_tram_setup(emu, addr);
- mutex_unlock(&emu->fx8010.lock);
+ scoped_guard(mutex, &emu->fx8010.lock) {
+ res = snd_emu10k1_fx8010_tram_setup(emu, addr);
+ }
return res;
case SNDRV_EMU10K1_IOCTL_STOP:
if (!capable(CAP_SYS_ADMIN))
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index d665d5d1ad7c..f4906ab30c02 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -662,9 +662,8 @@ 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;
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
snd_emu1010_output_source_apply(emu, channel, val);
- snd_emu1010_fpga_unlock(emu);
}
return change;
}
@@ -708,9 +707,8 @@ 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;
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
snd_emu1010_input_source_apply(emu, channel, val);
- snd_emu1010_fpga_unlock(emu);
}
return change;
}
@@ -980,30 +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;
- snd_emu1010_fpga_lock(emu);
- 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);
}
- snd_emu1010_fpga_unlock(emu);
- 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 =
@@ -1211,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 */
@@ -1378,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;
}
@@ -1509,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;
@@ -1529,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;
}
@@ -1577,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) {
@@ -1596,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;
}
@@ -1641,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;
@@ -1658,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;
}
@@ -1711,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) {
@@ -1726,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;
}
@@ -1774,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) {
@@ -1788,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;
}
@@ -1833,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) {
@@ -1845,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;
}
@@ -1888,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) {
@@ -1909,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;
}
@@ -2330,9 +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_fpga_lock(emu);
- snd_emu1010_apply_sources(emu);
- snd_emu1010_fpga_unlock(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);
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index efff19bbc0e9..c102a3599225 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -68,28 +68,28 @@ static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k
return;
}
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- mpu401_clear_rx(emu, midi);
- } else {
- byte = mpu401_read_data(emu, midi);
- if (midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
+ scoped_guard(spinlock, &midi->input_lock) {
+ if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
+ if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
+ mpu401_clear_rx(emu, midi);
+ } else {
+ byte = mpu401_read_data(emu, midi);
+ if (midi->substream_input)
+ snd_rawmidi_receive(midi->substream_input, &byte, 1);
+ }
}
}
- spin_unlock(&midi->input_lock);
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- mpu401_write_data(emu, midi, byte);
- } else {
- snd_emu10k1_intr_disable(emu, midi->tx_enable);
+ scoped_guard(spinlock, &midi->output_lock) {
+ if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
+ if (midi->substream_output &&
+ snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+ mpu401_write_data(emu, midi, byte);
+ } else {
+ snd_emu10k1_intr_disable(emu, midi->tx_enable);
+ }
}
}
- spin_unlock(&midi->output_lock);
}
static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status)
@@ -106,26 +106,26 @@ static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mid
{
int timeout, ok;
- spin_lock_irq(&midi->input_lock);
- mpu401_write_data(emu, midi, 0x00);
- /* mpu401_clear_rx(emu, midi); */
-
- mpu401_write_cmd(emu, midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (mpu401_input_avail(emu, midi)) {
- if (mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
+ scoped_guard(spinlock_irq, &midi->input_lock) {
+ mpu401_write_data(emu, midi, 0x00);
+ /* mpu401_clear_rx(emu, midi); */
+
+ mpu401_write_cmd(emu, midi, cmd);
+ if (ack) {
+ ok = 0;
+ timeout = 10000;
+ while (!ok && timeout-- > 0) {
+ if (mpu401_input_avail(emu, midi)) {
+ if (mpu401_read_data(emu, midi) == MPU401_ACK)
+ ok = 1;
+ }
}
- }
- if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
+ if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
+ ok = 1;
+ } else {
ok = 1;
- } else {
- ok = 1;
+ }
}
- spin_unlock_irq(&midi->input_lock);
if (!ok) {
dev_err(emu->card->dev,
"midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
@@ -145,22 +145,17 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irq(&midi->open_lock);
- midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
- spin_unlock_irq(&midi->open_lock);
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irq(&midi->open_lock);
+ scoped_guard(spinlock_irq, &midi->open_lock) {
+ midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
+ midi->substream_input = substream;
+ if (midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)
+ return 0;
}
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
+ return -EIO;
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ return -EIO;
return 0;
-
-error_out:
- return -EIO;
}
static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
@@ -171,66 +166,53 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irq(&midi->open_lock);
- midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- spin_unlock_irq(&midi->open_lock);
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irq(&midi->open_lock);
+ scoped_guard(spinlock_irq, &midi->open_lock) {
+ midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
+ midi->substream_output = substream;
+ if (midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)
+ return 0;
}
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
+ return -EIO;
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ return -EIO;
return 0;
-
-error_out:
- return -EIO;
}
static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irq(&midi->open_lock);
- snd_emu10k1_intr_disable(emu, midi->rx_enable);
- midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
- spin_unlock_irq(&midi->open_lock);
- err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irq(&midi->open_lock);
+ scoped_guard(spinlock_irq, &midi->open_lock) {
+ snd_emu10k1_intr_disable(emu, midi->rx_enable);
+ midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
+ midi->substream_input = NULL;
+ if (midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)
+ return 0;
}
- return err;
+ return snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
}
static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
- spin_lock_irq(&midi->open_lock);
- snd_emu10k1_intr_disable(emu, midi->tx_enable);
- midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- spin_unlock_irq(&midi->open_lock);
- err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irq(&midi->open_lock);
+ scoped_guard(spinlock_irq, &midi->open_lock) {
+ snd_emu10k1_intr_disable(emu, midi->tx_enable);
+ midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
+ midi->substream_output = NULL;
+ if (midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)
+ return 0;
}
- return err;
+ return snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
}
static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -261,22 +243,21 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
unsigned char byte;
/* try to send some amount of bytes here before interrupts */
- spin_lock_irq(&midi->output_lock);
- while (max > 0) {
- if (mpu401_output_ready(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irq(&midi->output_lock);
- return;
+ scoped_guard(spinlock_irq, &midi->output_lock) {
+ while (max > 0) {
+ if (mpu401_output_ready(emu, midi)) {
+ if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
+ snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+ /* no more data */
+ return;
+ }
+ mpu401_write_data(emu, midi, byte);
+ max--;
+ } else {
+ break;
}
- mpu401_write_data(emu, midi, byte);
- max--;
- } else {
- break;
}
}
- spin_unlock_irq(&midi->output_lock);
snd_emu10k1_intr_enable(emu, midi->tx_enable);
} else {
snd_emu10k1_intr_disable(emu, midi->tx_enable);
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 5414148057ea..071c75ba81fd 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -319,7 +319,7 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu,
unsigned int end_addr,
struct snd_emu10k1_pcm_mixer *mix)
{
- spin_lock_irq(&emu->reg_lock);
+ guard(spinlock_irq)(&emu->reg_lock);
snd_emu10k1_pcm_init_voice(emu, evoice, w_16, stereo,
start_addr, end_addr,
&mix->send_routing[stereo][0],
@@ -329,7 +329,6 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu,
start_addr, end_addr,
&mix->send_routing[2][0],
&mix->send_volume[2][0]);
- spin_unlock_irq(&emu->reg_lock);
}
static void snd_emu10k1_pcm_init_extra_voice(struct snd_emu10k1 *emu,
@@ -726,14 +725,13 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
struct snd_emu10k1_pcm_mixer *mix;
bool w_16 = snd_pcm_format_width(runtime->format) == 16;
bool stereo = runtime->channels == 2;
- int result = 0;
/*
dev_dbg(emu->card->dev,
"trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n",
(int)emu, cmd, substream->ops->pointer(substream))
*/
- spin_lock(&emu->reg_lock);
+ guard(spinlock)(&emu->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_emu10k1_playback_prepare_voices(emu, epcm, w_16, stereo, 1);
@@ -755,11 +753,9 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
snd_emu10k1_playback_mute_voices(emu, epcm->voices[0], stereo);
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&emu->reg_lock);
- return result;
+ return 0;
}
static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
@@ -768,9 +764,8 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int result = 0;
- spin_lock(&emu->reg_lock);
+ guard(spinlock)(&emu->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -829,10 +824,9 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
}
break;
default:
- result = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&emu->reg_lock);
- return result;
+ return 0;
}
static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *substream)
@@ -923,7 +917,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
u64 mask;
int result = 0;
- spin_lock(&emu->reg_lock);
+ guard(spinlock)(&emu->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -950,7 +944,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
if (result == 0) {
// The extra voice is allowed to lag a bit
snd_emu10k1_playback_trigger_voice(emu, epcm->extra);
- goto leave;
+ return 0;
}
snd_emu10k1_efx_playback_stop_voices(
@@ -972,11 +966,8 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
epcm->resume_pos = snd_emu10k1_playback_pointer(substream);
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
-leave:
- spin_unlock(&emu->reg_lock);
return result;
}
@@ -1345,7 +1336,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
#endif
runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
} else {
- spin_lock_irq(&emu->reg_lock);
+ guard(spinlock_irq)(&emu->reg_lock);
runtime->hw.channels_min = runtime->hw.channels_max = 0;
for (idx = 0; idx < nefx; idx++) {
if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
@@ -1355,7 +1346,6 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
}
epcm->capture_cr_val = emu->efx_voices_mask[0];
epcm->capture_cr_val2 = emu->efx_voices_mask[1];
- spin_unlock_irq(&emu->reg_lock);
}
err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&hw_constraints_efx_capture_channels);
@@ -1539,12 +1529,11 @@ static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, st
if (bits == 9 || bits == 11 || bits == 13 || bits == 15 || bits > 16)
return -EINVAL;
- spin_lock_irq(&emu->reg_lock);
+ guard(spinlock_irq)(&emu->reg_lock);
change = (nval[0] != emu->efx_voices_mask[0]) ||
(nval[1] != emu->efx_voices_mask[1]);
emu->efx_voices_mask[0] = nval[0];
emu->efx_voices_mask[1] = nval[1];
- spin_unlock_irq(&emu->reg_lock);
return change;
}
@@ -1685,9 +1674,9 @@ static int snd_emu10k1_fx8010_playback_trigger(struct snd_pcm_substream *substre
{
struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- int result = 0;
+ int result;
- spin_lock(&emu->reg_lock);
+ guard(spinlock)(&emu->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* follow thru */
@@ -1707,7 +1696,7 @@ static int snd_emu10k1_fx8010_playback_trigger(struct snd_pcm_substream *substre
#endif
result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
if (result < 0)
- goto __err;
+ return result;
snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */
snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
break;
@@ -1720,12 +1709,9 @@ static int snd_emu10k1_fx8010_playback_trigger(struct snd_pcm_substream *substre
pcm->tram_shift = 0;
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- __err:
- spin_unlock(&emu->reg_lock);
- return result;
+ return 0;
}
static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_substream *substream)
@@ -1769,13 +1755,10 @@ static int snd_emu10k1_fx8010_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_emu10k1_fx8010_playback;
runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
- spin_lock_irq(&emu->reg_lock);
- if (pcm->valid == 0) {
- spin_unlock_irq(&emu->reg_lock);
+ guard(spinlock_irq)(&emu->reg_lock);
+ if (pcm->valid == 0)
return -ENODEV;
- }
pcm->opened = 1;
- spin_unlock_irq(&emu->reg_lock);
return 0;
}
@@ -1784,9 +1767,8 @@ static int snd_emu10k1_fx8010_playback_close(struct snd_pcm_substream *substream
struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- spin_lock_irq(&emu->reg_lock);
+ guard(spinlock_irq)(&emu->reg_lock);
pcm->opened = 0;
- spin_unlock_irq(&emu->reg_lock);
return 0;
}
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index bd4734dc04cd..f6186b5be049 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -166,7 +166,7 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
u32 value2;
if (emu->card_capabilities->emu_model) {
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
// This represents the S/PDIF lock status on 0404b, which is
// kinda weird and unhelpful, because monitoring it via IRQ is
@@ -200,8 +200,6 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "\nS/PDIF mode: %s%s\n",
value & EMU_HANA_SPDIF_MODE_RX_PRO ? "professional" : "consumer",
value & EMU_HANA_SPDIF_MODE_RX_NOCOPY ? ", no copy" : "");
-
- snd_emu1010_fpga_unlock(emu);
} else {
snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
@@ -464,7 +462,7 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
u32 value;
int i;
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
snd_iprintf(buffer, "EMU1010 Registers:\n\n");
@@ -504,8 +502,6 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
snd_emu_proc_emu1010_link_read(emu, buffer, 0x701);
}
}
-
- snd_emu1010_fpga_unlock(emu);
}
static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
@@ -541,15 +537,13 @@ static unsigned int snd_ptr_read(struct snd_emu10k1 * emu,
unsigned int reg,
unsigned int chn)
{
- unsigned int regptr, val;
+ unsigned int regptr;
regptr = (reg << 16) | chn;
- spin_lock_irq(&emu->emu_lock);
+ guard(spinlock_irq)(&emu->emu_lock);
outl(regptr, emu->port + iobase + PTR);
- val = inl(emu->port + iobase + DATA);
- spin_unlock_irq(&emu->emu_lock);
- return val;
+ return inl(emu->port + iobase + DATA);
}
static void snd_ptr_write(struct snd_emu10k1 *emu,
@@ -562,10 +556,9 @@ static void snd_ptr_write(struct snd_emu10k1 *emu,
regptr = (reg << 16) | chn;
- spin_lock_irq(&emu->emu_lock);
+ guard(spinlock_irq)(&emu->emu_lock);
outl(regptr, emu->port + iobase + PTR);
outl(data, emu->port + iobase + DATA);
- spin_unlock_irq(&emu->emu_lock);
}
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index b60ab5671e00..9c897c3e8c28 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -30,7 +30,6 @@ static inline bool check_ptr_reg(struct snd_emu10k1 *emu, unsigned int reg)
unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
{
- unsigned long flags;
unsigned int regptr, val;
unsigned int mask;
@@ -38,10 +37,10 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
if (!check_ptr_reg(emu, regptr))
return 0;
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
+ scoped_guard(spinlock_irqsave, &emu->emu_lock) {
+ outl(regptr, emu->port + PTR);
+ val = inl(emu->port + DATA);
+ }
if (reg & 0xff000000) {
unsigned char size, offset;
@@ -61,13 +60,13 @@ EXPORT_SYMBOL(snd_emu10k1_ptr_read);
void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
{
unsigned int regptr;
- unsigned long flags;
unsigned int mask;
regptr = (reg << 16) | chn;
if (!check_ptr_reg(emu, regptr))
return;
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (reg & 0xff000000) {
unsigned char size, offset;
@@ -79,15 +78,12 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
mask <<= offset;
data <<= offset;
- spin_lock_irqsave(&emu->emu_lock, flags);
outl(regptr, emu->port + PTR);
data |= inl(emu->port + DATA) & ~mask;
} else {
- spin_lock_irqsave(&emu->emu_lock, flags);
outl(regptr, emu->port + PTR);
}
outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
EXPORT_SYMBOL(snd_emu10k1_ptr_write);
@@ -96,7 +92,6 @@ void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, .
{
va_list va;
u32 addr_mask;
- unsigned long flags;
if (snd_BUG_ON(!emu))
return;
@@ -105,7 +100,7 @@ void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, .
addr_mask = ~((emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK) >> 16);
va_start(va, chn);
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
for (;;) {
u32 data;
u32 reg = va_arg(va, u32);
@@ -117,7 +112,6 @@ void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, .
outl((reg << 16) | chn, emu->port + PTR);
outl(data, emu->port + DATA);
}
- spin_unlock_irqrestore(&emu->emu_lock, flags);
va_end(va);
}
@@ -127,16 +121,13 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
unsigned int reg,
unsigned int chn)
{
- unsigned long flags;
- unsigned int regptr, val;
+ unsigned int regptr;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + PTR2);
- val = inl(emu->port + DATA2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inl(emu->port + DATA2);
}
void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
@@ -145,14 +136,12 @@ void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
unsigned int data)
{
unsigned int regptr;
- unsigned long flags;
regptr = (reg << 16) | chn;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(regptr, emu->port + PTR2);
outl(data, emu->port + DATA2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
@@ -161,22 +150,19 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
unsigned int reset, set;
unsigned int reg, tmp;
int n, result;
- int err = 0;
/* This function is not re-entrant, so protect against it. */
- spin_lock(&emu->spi_lock);
+ guard(spinlock)(&emu->spi_lock);
if (emu->card_capabilities->ca0108_chip)
reg = P17V_SPI;
else {
/* For other chip types the SPI register
* is currently unknown. */
- err = 1;
- goto spi_write_exit;
+ return 1;
}
if (data > 0xffff) {
/* Only 16bit values allowed */
- err = 1;
- goto spi_write_exit;
+ return 1;
}
tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
@@ -197,15 +183,11 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
}
if (result) {
/* Timed out */
- err = 1;
- goto spi_write_exit;
+ return 1;
}
snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
- err = 0;
-spi_write_exit:
- spin_unlock(&emu->spi_lock);
- return err;
+ return 0;
}
/* The ADC does not support i2c read, so only write is implemented */
@@ -217,7 +199,6 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
int timeout = 0;
int status;
int retry;
- int err = 0;
if ((reg > 0x7f) || (value > 0x1ff)) {
dev_err(emu->card->dev, "i2c_write: invalid values.\n");
@@ -225,7 +206,7 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
}
/* This function is not re-entrant, so protect against it. */
- spin_lock(&emu->i2c_lock);
+ guard(spinlock)(&emu->i2c_lock);
tmp = reg << 25 | value << 16;
@@ -264,11 +245,10 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
dev_err(emu->card->dev, "status=0x%x, reg=%d, value=%d\n",
status, reg, value);
/* dump_stack(); */
- err = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&emu->i2c_lock);
- return err;
+ return 0;
}
static void snd_emu1010_fpga_write_locked(struct snd_emu10k1 *emu, u32 reg, u32 value)
@@ -297,9 +277,8 @@ void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value)
{
- snd_emu1010_fpga_lock(emu);
+ guard(snd_emu1010_fpga_lock)(emu);
snd_emu1010_fpga_write_locked(emu, reg, value);
- snd_emu1010_fpga_unlock(emu);
}
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
@@ -477,32 +456,27 @@ void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock,
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
enable = inl(emu->port + INTE) | intrenb;
outl(enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
enable = inl(emu->port + INTE) & ~intrenb;
outl(enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(CLIEH << 16, emu->port + PTR);
val = inl(emu->port + DATA);
@@ -513,15 +487,13 @@ void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenu
val |= 1 << voicenum;
}
outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(CLIEH << 16, emu->port + PTR);
val = inl(emu->port + DATA);
@@ -532,14 +504,11 @@ void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicen
val &= ~(1 << voicenum);
}
outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(CLIPH << 16, emu->port + PTR);
voicenum = 1 << (voicenum - 32);
@@ -548,15 +517,13 @@ void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
voicenum = 1 << voicenum;
}
outl(voicenum, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(HLIEH << 16, emu->port + PTR);
val = inl(emu->port + DATA);
@@ -567,15 +534,13 @@ void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned i
val |= 1 << voicenum;
}
outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(HLIEH << 16, emu->port + PTR);
val = inl(emu->port + DATA);
@@ -586,14 +551,11 @@ void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned
val &= ~(1 << voicenum);
}
outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(HLIPH << 16, emu->port + PTR);
voicenum = 1 << (voicenum - 32);
@@ -602,16 +564,14 @@ void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int
voicenum = 1 << voicenum;
}
outl(voicenum, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
#if 0
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int sol;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(SOLEH << 16, emu->port + PTR);
sol = inl(emu->port + DATA);
@@ -622,15 +582,13 @@ void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voice
sol |= 1 << voicenum;
}
outl(sol, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
{
- unsigned long flags;
unsigned int sol;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
if (voicenum >= 32) {
outl(SOLEH << 16, emu->port + PTR);
sol = inl(emu->port + DATA);
@@ -641,32 +599,25 @@ void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voi
sol &= ~(1 << voicenum);
}
outl(sol, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
#endif
void snd_emu10k1_voice_set_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(SOLEL << 16, emu->port + PTR);
outl(inl(emu->port + DATA) | (u32)voices, emu->port + DATA);
outl(SOLEH << 16, emu->port + PTR);
outl(inl(emu->port + DATA) | (u32)(voices >> 32), emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
void snd_emu10k1_voice_clear_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outl(SOLEL << 16, emu->port + PTR);
outl(inl(emu->port + DATA) & (u32)~voices, emu->port + DATA);
outl(SOLEH << 16, emu->port + PTR);
outl(inl(emu->port + DATA) & (u32)(~voices >> 32), emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
int snd_emu10k1_voice_clear_loop_stop_multiple_atomic(struct snd_emu10k1 *emu, u64 voices)
@@ -749,23 +700,17 @@ void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
struct snd_emu10k1 *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + AC97ADDRESS);
- val = inw(emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
+ return inw(emu->port + AC97DATA);
}
void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
{
struct snd_emu10k1 *emu = ac97->private_data;
- unsigned long flags;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
outb(reg, emu->port + AC97ADDRESS);
outw(data, emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index f6982bc6ff0d..be889a4ccf9a 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -261,14 +261,12 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
int size;
struct list_head *p, *nextp;
struct snd_emu10k1_memblk *deleted;
- unsigned long flags;
- spin_lock_irqsave(&emu->memblk_lock, flags);
+ guard(spinlock_irqsave)(&emu->memblk_lock);
if (blk->mapped_page >= 0) {
/* update order link */
list_move_tail(&blk->mapped_order_link,
&emu->mapped_order_link_head);
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
return 0;
}
err = map_memblk(emu, blk);
@@ -289,7 +287,6 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
}
}
}
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
return err;
}
@@ -315,12 +312,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
if (snd_BUG_ON(!hdr))
return NULL;
- mutex_lock(&hdr->block_mutex);
+ guard(mutex)(&hdr->block_mutex);
blk = search_empty(emu, runtime->dma_bytes);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
+ if (blk == NULL)
return NULL;
- }
/* fill buffer addresses but pointers are not stored so that
* snd_free_pci_page() is not called in synth_free()
*/
@@ -335,7 +330,6 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
if (! is_valid_page(emu, addr)) {
dev_err_ratelimited(emu->card->dev,
"emu: failure page = %d\n", idx);
- mutex_unlock(&hdr->block_mutex);
return NULL;
}
emu->page_addr_table[page] = addr;
@@ -347,10 +341,8 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
err = snd_emu10k1_memblk_map(emu, blk);
if (err < 0) {
__snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
- mutex_unlock(&hdr->block_mutex);
return NULL;
}
- mutex_unlock(&hdr->block_mutex);
return (struct snd_util_memblk *)blk;
}
@@ -407,19 +399,15 @@ snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size)
struct snd_emu10k1_memblk *blk;
struct snd_util_memhdr *hdr = hw->memhdr;
- mutex_lock(&hdr->block_mutex);
+ guard(mutex)(&hdr->block_mutex);
blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
+ if (blk == NULL)
return NULL;
- }
if (synth_alloc_pages(hw, blk)) {
__snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
- mutex_unlock(&hdr->block_mutex);
return NULL;
}
snd_emu10k1_memblk_map(hw, blk);
- mutex_unlock(&hdr->block_mutex);
return (struct snd_util_memblk *)blk;
}
@@ -433,16 +421,14 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk)
{
struct snd_util_memhdr *hdr = emu->memhdr;
struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk;
- unsigned long flags;
- mutex_lock(&hdr->block_mutex);
- spin_lock_irqsave(&emu->memblk_lock, flags);
- if (blk->mapped_page >= 0)
- unmap_memblk(emu, blk);
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
+ guard(mutex)(&hdr->block_mutex);
+ scoped_guard(spinlock_irqsave, &emu->memblk_lock) {
+ if (blk->mapped_page >= 0)
+ unmap_memblk(emu, blk);
+ }
synth_free_pages(emu, blk);
__snd_util_mem_free(hdr, memblk);
- mutex_unlock(&hdr->block_mutex);
return 0;
}
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index e774174d10de..b74128e61254 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -342,24 +342,20 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int enable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
enable = inl(emu->port + INTE2) | intrenb;
outl(enable, emu->port + INTE2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
- unsigned long flags;
unsigned int disable;
- spin_lock_irqsave(&emu->emu_lock, flags);
+ guard(spinlock_irqsave)(&emu->emu_lock);
disable = inl(emu->port + INTE2) & (~intrenb);
outl(disable, emu->port + INTE2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
}
static void snd_p16v_interrupt(struct snd_emu10k1 *emu)
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 77fb5427aaed..7fe1d1727768 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -77,7 +77,6 @@ static void voice_free(struct snd_emu10k1 *emu,
int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int channels,
struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice)
{
- unsigned long flags;
int result;
if (snd_BUG_ON(!rvoice))
@@ -87,7 +86,7 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int ch
if (snd_BUG_ON(!channels))
return -EINVAL;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (int got = 0; got < channels; ) {
result = voice_alloc(emu, type, count, epcm, &rvoice[got]);
if (result == 0) {
@@ -113,7 +112,6 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int ch
}
break;
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
return result;
}
@@ -123,17 +121,15 @@ EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
struct snd_emu10k1_voice *pvoice)
{
- unsigned long flags;
int last;
if (snd_BUG_ON(!pvoice))
return -EINVAL;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
do {
last = pvoice->last;
voice_free(emu, pvoice++);
} while (!last);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
return 0;
}
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 82e10ecb9196..657056a59175 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -596,7 +596,7 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97,
unsigned int t, x, flag;
flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
- mutex_lock(&ensoniq->src_mutex);
+ guard(mutex)(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) {
if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
/* save the current state for latter */
@@ -622,11 +622,9 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97,
/* restore SRC reg */
snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
return;
}
}
- mutex_unlock(&ensoniq->src_mutex);
dev_err(ensoniq->card->dev, "codec write timeout at 0x%lx [0x%x]\n",
ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
}
@@ -713,7 +711,7 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int n, truncm, freq;
- mutex_lock(&ensoniq->src_mutex);
+ guard(mutex)(&ensoniq->src_mutex);
n = rate / 3000;
if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
n--;
@@ -737,14 +735,13 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
- mutex_unlock(&ensoniq->src_mutex);
}
static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int freq, r;
- mutex_lock(&ensoniq->src_mutex);
+ guard(mutex)(&ensoniq->src_mutex);
freq = DIV_ROUND_CLOSEST(rate << 15, 3000);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P2 | ES_1371_DIS_R1)) |
@@ -758,14 +755,13 @@ static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P2 | ES_1371_DIS_R1));
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
}
static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
{
unsigned int freq, r;
- mutex_lock(&ensoniq->src_mutex);
+ guard(mutex)(&ensoniq->src_mutex);
freq = DIV_ROUND_CLOSEST(rate << 15, 3000);
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P1 | ES_1371_DIS_R1)) |
@@ -780,7 +776,6 @@ static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
ES_1371_DIS_P1 | ES_1371_DIS_R1));
outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
}
#endif /* CHIP1371 */
@@ -804,13 +799,13 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
} else if (s == ensoniq->capture_substream)
return -EINVAL;
}
- spin_lock(&ensoniq->reg_lock);
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- ensoniq->sctrl |= what;
- else
- ensoniq->sctrl &= ~what;
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- spin_unlock(&ensoniq->reg_lock);
+ scoped_guard(spinlock, &ensoniq->reg_lock) {
+ if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+ ensoniq->sctrl |= what;
+ else
+ ensoniq->sctrl &= ~what;
+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
+ }
break;
}
case SNDRV_PCM_TRIGGER_START:
@@ -830,13 +825,13 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
snd_pcm_trigger_done(s, substream);
}
}
- spin_lock(&ensoniq->reg_lock);
- if (cmd == SNDRV_PCM_TRIGGER_START)
- ensoniq->ctrl |= what;
- else
- ensoniq->ctrl &= ~what;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock(&ensoniq->reg_lock);
+ scoped_guard(spinlock, &ensoniq->reg_lock) {
+ if (cmd == SNDRV_PCM_TRIGGER_START)
+ ensoniq->ctrl |= what;
+ else
+ ensoniq->ctrl &= ~what;
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ }
break;
}
default:
@@ -861,36 +856,36 @@ static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream)
mode |= 0x02;
if (runtime->channels > 1)
mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_DAC1_EN;
+ scoped_guard(spinlock_irq, &ensoniq->reg_lock) {
+ ensoniq->ctrl &= ~ES_DAC1_EN;
#ifdef CHIP1371
- /* 48k doesn't need SRC (it breaks AC3-passthru) */
- if (runtime->rate == 48000)
- ensoniq->ctrl |= ES_1373_BYPASS_P1;
- else
- ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
+ /* 48k doesn't need SRC (it breaks AC3-passthru) */
+ if (runtime->rate == 48000)
+ ensoniq->ctrl |= ES_1373_BYPASS_P1;
+ else
+ ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
- outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));
- ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
- ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, DAC1_COUNT));
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
+ outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
+ outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));
+ ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
+ ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
+ outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+ ES_REG(ensoniq, DAC1_COUNT));
#ifdef CHIP1370
- ensoniq->ctrl &= ~ES_1370_WTSRSELM;
- switch (runtime->rate) {
- case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;
- case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;
- case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;
- case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
- default: snd_BUG();
- }
+ ensoniq->ctrl &= ~ES_1370_WTSRSELM;
+ switch (runtime->rate) {
+ case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;
+ case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;
+ case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;
+ case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
+ default: snd_BUG();
+ }
#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ }
#ifndef CHIP1370
snd_es1371_dac1_rate(ensoniq, runtime->rate);
#endif
@@ -909,28 +904,28 @@ static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream)
mode |= 0x02;
if (runtime->channels > 1)
mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_DAC2_EN;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));
- outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));
- ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |
- ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);
- ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
- ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, DAC2_COUNT));
+ scoped_guard(spinlock_irq, &ensoniq->reg_lock) {
+ ensoniq->ctrl &= ~ES_DAC2_EN;
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
+ outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));
+ outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));
+ ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |
+ ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);
+ ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
+ ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
+ outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+ ES_REG(ensoniq, DAC2_COUNT));
#ifdef CHIP1370
- if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
- ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
- ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
- ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
- }
+ if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
+ ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
+ ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
+ ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
+ }
#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ }
#ifndef CHIP1370
snd_es1371_dac2_rate(ensoniq, runtime->rate);
#endif
@@ -949,26 +944,26 @@ static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream)
mode |= 0x02;
if (runtime->channels > 1)
mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_ADC_EN;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));
- outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));
- ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
- ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, ADC_COUNT));
+ scoped_guard(spinlock_irq, &ensoniq->reg_lock) {
+ ensoniq->ctrl &= ~ES_ADC_EN;
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
+ outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));
+ outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));
+ ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
+ ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
+ outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+ ES_REG(ensoniq, ADC_COUNT));
#ifdef CHIP1370
- if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
- ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
- ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
- ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
- }
+ if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
+ ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
+ ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
+ ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
+ }
#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
+ }
#ifndef CHIP1370
snd_es1371_adc_rate(ensoniq, runtime->rate);
#endif
@@ -980,16 +975,14 @@ static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream
struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
size_t ptr;
- spin_lock(&ensoniq->reg_lock);
+ guard(spinlock)(&ensoniq->reg_lock);
if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {
outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
+ return bytes_to_frames(substream->runtime, ptr);
} else {
- ptr = 0;
+ return 0;
}
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
}
static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream)
@@ -997,16 +990,14 @@ static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream
struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
size_t ptr;
- spin_lock(&ensoniq->reg_lock);
+ guard(spinlock)(&ensoniq->reg_lock);
if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {
outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
+ return bytes_to_frames(substream->runtime, ptr);
} else {
- ptr = 0;
+ return 0;
}
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
}
static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream)
@@ -1014,16 +1005,14 @@ static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *s
struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
size_t ptr;
- spin_lock(&ensoniq->reg_lock);
+ guard(spinlock)(&ensoniq->reg_lock);
if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {
outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
+ return bytes_to_frames(substream->runtime, ptr);
} else {
- ptr = 0;
+ return 0;
}
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
}
static const struct snd_pcm_hardware snd_ensoniq_playback1 =
@@ -1101,10 +1090,10 @@ static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream)
ensoniq->playback1_substream = substream;
runtime->hw = snd_ensoniq_playback1;
snd_pcm_set_sync(substream);
- spin_lock_irq(&ensoniq->reg_lock);
- if (ensoniq->spdif && ensoniq->playback2_substream == NULL)
- ensoniq->spdif_stream = ensoniq->spdif_default;
- spin_unlock_irq(&ensoniq->reg_lock);
+ scoped_guard(spinlock_irq, &ensoniq->reg_lock) {
+ if (ensoniq->spdif && ensoniq->playback2_substream == NULL)
+ ensoniq->spdif_stream = ensoniq->spdif_default;
+ }
#ifdef CHIP1370
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&snd_es1370_hw_constraints_rates);
@@ -1124,10 +1113,10 @@ static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream)
ensoniq->playback2_substream = substream;
runtime->hw = snd_ensoniq_playback2;
snd_pcm_set_sync(substream);
- spin_lock_irq(&ensoniq->reg_lock);
- if (ensoniq->spdif && ensoniq->playback1_substream == NULL)
- ensoniq->spdif_stream = ensoniq->spdif_default;
- spin_unlock_irq(&ensoniq->reg_lock);
+ scoped_guard(spinlock_irq, &ensoniq->reg_lock) {
+ if (ensoniq->spdif && ensoniq->playback1_substream == NULL)
+ ensoniq->spdif_stream = ensoniq->spdif_default;
+ }
#ifdef CHIP1370
snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&snd_es1370_hw_constraints_clock);
@@ -1171,12 +1160,11 @@ static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream)
struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
ensoniq->playback2_substream = NULL;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
#ifdef CHIP1370
ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_PLAY2;
#endif
ensoniq->mode &= ~ES_MODE_PLAY2;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1185,12 +1173,11 @@ static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
ensoniq->capture_substream = NULL;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
#ifdef CHIP1370
ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_CAPTURE;
#endif
ensoniq->mode &= ~ES_MODE_CAPTURE;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1312,12 +1299,12 @@ static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&ensoniq->reg_lock);
+
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1332,13 +1319,12 @@ static int snd_ens1373_spdif_default_put(struct snd_kcontrol *kcontrol,
((u32)ucontrol->value.iec958.status[1] << 8) |
((u32)ucontrol->value.iec958.status[2] << 16) |
((u32)ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
change = ensoniq->spdif_default != val;
ensoniq->spdif_default = val;
if (change && ensoniq->playback1_substream == NULL &&
ensoniq->playback2_substream == NULL)
outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
@@ -1356,12 +1342,12 @@ static int snd_ens1373_spdif_stream_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&ensoniq->reg_lock);
+
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1376,13 +1362,12 @@ static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
((u32)ucontrol->value.iec958.status[1] << 8) |
((u32)ucontrol->value.iec958.status[2] << 16) |
((u32)ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
change = ensoniq->spdif_stream != val;
ensoniq->spdif_stream = val;
if (change && (ensoniq->playback1_substream != NULL ||
ensoniq->playback2_substream != NULL))
outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
@@ -1397,9 +1382,8 @@ static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
{
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1412,7 +1396,7 @@ static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0;
nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1;
ensoniq->ctrl &= ~ES_1373_SPDIF_THRU;
ensoniq->ctrl |= nval1;
@@ -1420,7 +1404,6 @@ static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
ensoniq->cssr |= nval2;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
@@ -1460,12 +1443,11 @@ static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int val = 0;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|
ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
val = 1;
ucontrol->value.integer.value[0] = val;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1478,13 +1460,12 @@ static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
nval1 = ucontrol->value.integer.value[0] ?
ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
change = (ensoniq->cssr & (ES_1373_REAR_BIT27|
ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
ensoniq->cssr |= nval1;
outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
@@ -1505,11 +1486,10 @@ static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int val = 0;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
if (ensoniq->ctrl & ES_1371_GPIO_OUT(4))
val = 1;
ucontrol->value.integer.value[0] = val;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1520,7 +1500,7 @@ static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
int changed;
unsigned int ctrl;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ctrl = ensoniq->ctrl;
if (ucontrol->value.integer.value[0])
ensoniq->ctrl |= ES_1371_GPIO_OUT(4); /* switch line-in -> rear out */
@@ -1529,7 +1509,6 @@ static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
changed = (ctrl != ensoniq->ctrl);
if (changed)
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
return changed;
}
@@ -1665,9 +1644,8 @@ static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
int mask = kcontrol->private_value;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ucontrol->value.integer.value[0] = ensoniq->ctrl & mask ? 1 : 0;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -1680,12 +1658,11 @@ static int snd_ensoniq_control_put(struct snd_kcontrol *kcontrol,
int change;
nval = ucontrol->value.integer.value[0] ? mask : 0;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
change = (ensoniq->ctrl & mask) != nval;
ensoniq->ctrl &= ~mask;
ensoniq->ctrl |= nval;
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
return change;
}
@@ -2079,19 +2056,19 @@ static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
if (rmidi == NULL)
return;
/* do Rx at first */
- spin_lock(&ensoniq->reg_lock);
- mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
- while (mask) {
- status = inb(ES_REG(ensoniq, UART_STATUS));
- if ((status & mask) == 0)
- break;
- byte = inb(ES_REG(ensoniq, UART_DATA));
- snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
+ scoped_guard(spinlock, &ensoniq->reg_lock) {
+ mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
+ while (mask) {
+ status = inb(ES_REG(ensoniq, UART_STATUS));
+ if ((status & mask) == 0)
+ break;
+ byte = inb(ES_REG(ensoniq, UART_DATA));
+ snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
+ }
}
- spin_unlock(&ensoniq->reg_lock);
/* do Tx at second */
- spin_lock(&ensoniq->reg_lock);
+ guard(spinlock)(&ensoniq->reg_lock);
mask = ensoniq->uartm & ES_MODE_OUTPUT ? ES_TXRDY : 0;
while (mask) {
status = inb(ES_REG(ensoniq, UART_STATUS));
@@ -2105,14 +2082,13 @@ static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
outb(byte, ES_REG(ensoniq, UART_DATA));
}
}
- spin_unlock(&ensoniq->reg_lock);
}
static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct ensoniq *ensoniq = substream->rmidi->private_data;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ensoniq->uartm |= ES_MODE_INPUT;
ensoniq->midi_input = substream;
if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
@@ -2120,7 +2096,6 @@ static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
}
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -2128,7 +2103,7 @@ static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct ensoniq *ensoniq = substream->rmidi->private_data;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
@@ -2137,7 +2112,6 @@ static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
}
ensoniq->midi_input = NULL;
ensoniq->uartm &= ~ES_MODE_INPUT;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -2145,7 +2119,7 @@ static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct ensoniq *ensoniq = substream->rmidi->private_data;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
ensoniq->uartm |= ES_MODE_OUTPUT;
ensoniq->midi_output = substream;
if (!(ensoniq->uartm & ES_MODE_INPUT)) {
@@ -2153,7 +2127,6 @@ static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
}
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
@@ -2161,7 +2134,7 @@ static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream
{
struct ensoniq *ensoniq = substream->rmidi->private_data;
- spin_lock_irq(&ensoniq->reg_lock);
+ guard(spinlock_irq)(&ensoniq->reg_lock);
if (!(ensoniq->uartm & ES_MODE_INPUT)) {
outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
@@ -2170,17 +2143,15 @@ static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream
}
ensoniq->midi_output = NULL;
ensoniq->uartm &= ~ES_MODE_OUTPUT;
- spin_unlock_irq(&ensoniq->reg_lock);
return 0;
}
static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct ensoniq *ensoniq = substream->rmidi->private_data;
int idx;
- spin_lock_irqsave(&ensoniq->reg_lock, flags);
+ guard(spinlock_irqsave)(&ensoniq->reg_lock);
if (up) {
if ((ensoniq->uartc & ES_RXINTEN) == 0) {
/* empty input FIFO */
@@ -2195,16 +2166,14 @@ static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substre
outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
}
}
- spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
}
static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
- unsigned long flags;
struct ensoniq *ensoniq = substream->rmidi->private_data;
unsigned char byte;
- spin_lock_irqsave(&ensoniq->reg_lock, flags);
+ guard(spinlock_irqsave)(&ensoniq->reg_lock);
if (up) {
if (ES_TXINTENI(ensoniq->uartc) == 0) {
ensoniq->uartc |= ES_TXINTENO(1);
@@ -2225,7 +2194,6 @@ static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substr
outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
}
}
- spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
}
static const struct snd_rawmidi_ops snd_ensoniq_midi_output =
@@ -2276,17 +2244,17 @@ static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id)
if (!(status & ES_INTR))
return IRQ_NONE;
- spin_lock(&ensoniq->reg_lock);
- sctrl = ensoniq->sctrl;
- if (status & ES_DAC1)
- sctrl &= ~ES_P1_INT_EN;
- if (status & ES_DAC2)
- sctrl &= ~ES_P2_INT_EN;
- if (status & ES_ADC)
- sctrl &= ~ES_R1_INT_EN;
- outl(sctrl, ES_REG(ensoniq, SERIAL));
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- spin_unlock(&ensoniq->reg_lock);
+ scoped_guard(spinlock, &ensoniq->reg_lock) {
+ sctrl = ensoniq->sctrl;
+ if (status & ES_DAC1)
+ sctrl &= ~ES_P1_INT_EN;
+ if (status & ES_DAC2)
+ sctrl &= ~ES_P2_INT_EN;
+ if (status & ES_ADC)
+ sctrl &= ~ES_R1_INT_EN;
+ outl(sctrl, ES_REG(ensoniq, SERIAL));
+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
+ }
if (status & ES_UART)
snd_ensoniq_midi_interrupt(ensoniq);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 0ce7076206f9..280125eff362 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -237,11 +237,9 @@ MODULE_DEVICE_TABLE(pci, snd_es1938_ids);
* -----------------------------------------------------------------*/
static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsigned char val)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, SLSB_REG(chip, MIXERADDR));
outb(val, SLSB_REG(chip, MIXERDATA));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
dev_dbg(chip->card->dev, "Mixer reg %02x set to %02x\n", reg, val);
}
@@ -251,11 +249,10 @@ static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsig
static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)
{
int data;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, SLSB_REG(chip, MIXERADDR));
data = inb(SLSB_REG(chip, MIXERDATA));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
dev_dbg(chip->card->dev, "Mixer reg %02x now is %02x\n", reg, data);
return data;
}
@@ -266,9 +263,9 @@ static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)
static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,
unsigned char mask, unsigned char val)
{
- unsigned long flags;
unsigned char old, new, oval;
- spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->mixer_lock);
outb(reg, SLSB_REG(chip, MIXERADDR));
old = inb(SLSB_REG(chip, MIXERDATA));
oval = old & mask;
@@ -279,7 +276,6 @@ static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,
"Mixer reg %02x was %02x, set to %02x\n",
reg, old, new);
}
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
return oval;
}
@@ -322,11 +318,9 @@ static int snd_es1938_get_byte(struct es1938 *chip)
* -----------------------------------------------------------------*/
static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned char val)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_es1938_write_cmd(chip, reg);
snd_es1938_write_cmd(chip, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
dev_dbg(chip->card->dev, "Reg %02x set to %02x\n", reg, val);
}
@@ -336,12 +330,11 @@ static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned ch
static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)
{
unsigned char val;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_es1938_write_cmd(chip, ESS_CMD_READREG);
snd_es1938_write_cmd(chip, reg);
val = snd_es1938_get_byte(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
dev_dbg(chip->card->dev, "Reg %02x now is %02x\n", reg, val);
return val;
}
@@ -352,9 +345,9 @@ static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)
static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char mask,
unsigned char val)
{
- unsigned long flags;
unsigned char old, new, oval;
- spin_lock_irqsave(&chip->reg_lock, flags);
+
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_es1938_write_cmd(chip, ESS_CMD_READREG);
snd_es1938_write_cmd(chip, reg);
old = snd_es1938_get_byte(chip);
@@ -366,7 +359,6 @@ static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char
dev_dbg(chip->card->dev, "Reg %02x was %02x, set to %02x\n",
reg, old, new);
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return oval;
}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 624ba7d47566..51aee2c4d461 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -574,10 +574,8 @@ static void __maestro_write(struct es1968 *chip, u16 reg, u16 data)
static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
__maestro_write(chip, reg, data);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
/* no spinlock */
@@ -592,12 +590,8 @@ static u16 __maestro_read(struct es1968 *chip, u16 reg)
static inline u16 maestro_read(struct es1968 *chip, u16 reg)
{
- unsigned long flags;
- u16 result;
- spin_lock_irqsave(&chip->reg_lock, flags);
- result = __maestro_read(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
+ guard(spinlock_irqsave)(&chip->reg_lock);
+ return __maestro_read(chip, reg);
}
/* Wait for the codec bus to be free */
@@ -693,10 +687,8 @@ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 dat
static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
__apu_set_register(chip, channel, reg, data);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
@@ -710,62 +702,40 @@ static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
{
- unsigned long flags;
- u16 v;
- spin_lock_irqsave(&chip->reg_lock, flags);
- v = __apu_get_register(chip, channel, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return v;
+ guard(spinlock_irqsave)(&chip->reg_lock);
+ return __apu_get_register(chip, channel, reg);
}
#if 0 /* ASSP is not supported */
static void assp_set_register(struct es1968 *chip, u32 reg, u32 value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave),(&chip->reg_lock);
outl(reg, chip->io_port + ASSP_INDEX);
outl(value, chip->io_port + ASSP_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static u32 assp_get_register(struct es1968 *chip, u32 reg)
{
- unsigned long flags;
- u32 value;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
outl(reg, chip->io_port + ASSP_INDEX);
- value = inl(chip->io_port + ASSP_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return value;
+ return inl(chip->io_port + ASSP_DATA);
}
#endif
static void wave_set_register(struct es1968 *chip, u16 reg, u16 value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
outw(reg, chip->io_port + WC_INDEX);
outw(value, chip->io_port + WC_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static u16 wave_get_register(struct es1968 *chip, u16 reg)
{
- unsigned long flags;
- u16 value;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
outw(reg, chip->io_port + WC_INDEX);
- value = inw(chip->io_port + WC_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return value;
+ return inw(chip->io_port + WC_DATA);
}
/* *******************
@@ -924,7 +894,7 @@ static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode)
static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
{
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
__apu_set_register(chip, es->apu[0], 5, es->base[0]);
snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]);
if (es->mode == ESM_MODE_CAPTURE) {
@@ -939,19 +909,17 @@ static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]);
}
}
- spin_unlock(&chip->reg_lock);
}
static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es)
{
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
snd_es1968_trigger_apu(chip, es->apu[0], 0);
snd_es1968_trigger_apu(chip, es->apu[1], 0);
if (es->mode == ESM_MODE_CAPTURE) {
snd_es1968_trigger_apu(chip, es->apu[2], 0);
snd_es1968_trigger_apu(chip, es->apu[3], 0);
}
- spin_unlock(&chip->reg_lock);
}
/* set the wavecache control reg */
@@ -981,7 +949,6 @@ static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
int high_apu = 0;
int channel, apu;
int i, size;
- unsigned long flags;
u32 freq;
size = es->dma_size >> es->wav_shift;
@@ -1051,12 +1018,12 @@ static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
apu_set_register(chip, apu, 10, 0x8F08);
}
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* clear WP interrupts */
- outw(1, chip->io_port + 0x04);
- /* enable WP ints */
- outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ /* clear WP interrupts */
+ outw(1, chip->io_port + 0x04);
+ /* enable WP ints */
+ outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
+ }
freq = runtime->rate;
/* set frequency */
@@ -1127,7 +1094,6 @@ static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
{
int size;
u32 freq;
- unsigned long flags;
size = es->dma_size >> es->wav_shift;
@@ -1179,12 +1145,11 @@ static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
snd_es1968_apu_set_freq(chip, es->apu[2], freq);
snd_es1968_apu_set_freq(chip, es->apu[3], freq);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
/* clear WP interrupts */
outw(1, chip->io_port + 0x04);
/* enable WP ints */
outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
/*******************
@@ -1228,7 +1193,7 @@ static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct es1968 *chip = snd_pcm_substream_chip(substream);
struct esschan *es = substream->runtime->private_data;
- spin_lock(&chip->substream_lock);
+ guard(spinlock)(&chip->substream_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -1249,7 +1214,6 @@ static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_es1968_bob_dec(chip);
break;
}
- spin_unlock(&chip->substream_lock);
return 0;
}
@@ -1318,12 +1282,11 @@ static int calc_available_memory_size(struct es1968 *chip)
int max_size = 0;
struct esm_memory *buf;
- mutex_lock(&chip->memory_mutex);
+ guard(mutex)(&chip->memory_mutex);
list_for_each_entry(buf, &chip->buf_list, list) {
if (buf->empty && buf->buf.bytes > max_size)
max_size = buf->buf.bytes;
}
- mutex_unlock(&chip->memory_mutex);
if (max_size >= 128*1024)
max_size = 127*1024;
return max_size;
@@ -1335,21 +1298,18 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
struct esm_memory *buf;
size = ALIGN(size, ESM_MEM_ALIGN);
- mutex_lock(&chip->memory_mutex);
+ guard(mutex)(&chip->memory_mutex);
list_for_each_entry(buf, &chip->buf_list, list) {
if (buf->empty && buf->buf.bytes >= size)
goto __found;
}
- mutex_unlock(&chip->memory_mutex);
return NULL;
__found:
if (buf->buf.bytes > size) {
struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
- if (chunk == NULL) {
- mutex_unlock(&chip->memory_mutex);
+ if (chunk == NULL)
return NULL;
- }
chunk->buf = buf->buf;
chunk->buf.bytes -= size;
chunk->buf.area += size;
@@ -1359,7 +1319,6 @@ __found:
list_add(&chunk->list, &buf->list);
}
buf->empty = 0;
- mutex_unlock(&chip->memory_mutex);
return buf;
}
@@ -1368,7 +1327,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
{
struct esm_memory *chunk;
- mutex_lock(&chip->memory_mutex);
+ guard(mutex)(&chip->memory_mutex);
buf->empty = 1;
if (buf->list.prev != &chip->buf_list) {
chunk = list_entry(buf->list.prev, struct esm_memory, list);
@@ -1387,7 +1346,6 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
kfree(chunk);
}
}
- mutex_unlock(&chip->memory_mutex);
}
static void snd_es1968_free_dmabuf(struct es1968 *chip)
@@ -1549,9 +1507,8 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
calc_available_memory_size(chip);
- spin_lock_irq(&chip->substream_lock);
+ guard(spinlock_irq)(&chip->substream_lock);
list_add(&es->list, &chip->substream_list);
- spin_unlock_irq(&chip->substream_lock);
return 0;
}
@@ -1609,9 +1566,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
if (err < 0)
return err;
- spin_lock_irq(&chip->substream_lock);
+ guard(spinlock_irq)(&chip->substream_lock);
list_add(&es->list, &chip->substream_list);
- spin_unlock_irq(&chip->substream_lock);
return 0;
}
@@ -1624,9 +1580,9 @@ static int snd_es1968_playback_close(struct snd_pcm_substream *substream)
if (substream->runtime->private_data == NULL)
return 0;
es = substream->runtime->private_data;
- spin_lock_irq(&chip->substream_lock);
- list_del(&es->list);
- spin_unlock_irq(&chip->substream_lock);
+ scoped_guard(spinlock_irq, &chip->substream_lock) {
+ list_del(&es->list);
+ }
snd_es1968_free_apu_pair(chip, es->apu[0]);
kfree(es);
@@ -1641,9 +1597,9 @@ static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
if (substream->runtime->private_data == NULL)
return 0;
es = substream->runtime->private_data;
- spin_lock_irq(&chip->substream_lock);
- list_del(&es->list);
- spin_unlock_irq(&chip->substream_lock);
+ scoped_guard(spinlock_irq, &chip->substream_lock) {
+ list_del(&es->list);
+ }
snd_es1968_free_memory(chip, es->mixbuf);
snd_es1968_free_apu_pair(chip, es->apu[0]);
snd_es1968_free_apu_pair(chip, es->apu[2]);
@@ -1724,29 +1680,29 @@ static void es1968_measure_clock(struct es1968 *chip)
apu_set_register(chip, apu, 9, 0xD000);
apu_set_register(chip, apu, 10, 0x8F08);
apu_set_register(chip, apu, 11, 0x0000);
- spin_lock_irq(&chip->reg_lock);
- outw(1, chip->io_port + 0x04); /* clear WP interrupts */
- outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ outw(1, chip->io_port + 0x04); /* clear WP interrupts */
+ outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
+ }
snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
chip->in_measurement = 1;
chip->measure_apu = apu;
- spin_lock_irq(&chip->reg_lock);
- snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
- __apu_set_register(chip, apu, 5, pa & 0xffff);
- snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
- start_time = ktime_get();
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
+ __apu_set_register(chip, apu, 5, pa & 0xffff);
+ snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
+ start_time = ktime_get();
+ }
msleep(50);
- spin_lock_irq(&chip->reg_lock);
- offset = __apu_get_register(chip, apu, 5);
- stop_time = ktime_get();
- snd_es1968_trigger_apu(chip, apu, 0); /* stop */
- snd_es1968_bob_dec(chip);
- chip->in_measurement = 0;
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ offset = __apu_get_register(chip, apu, 5);
+ stop_time = ktime_get();
+ snd_es1968_trigger_apu(chip, apu, 0); /* stop */
+ snd_es1968_bob_dec(chip);
+ chip->in_measurement = 0;
+ }
/* check the current position */
offset -= (pa & 0xffff);
@@ -1970,15 +1926,15 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
if (event & ESM_SOUND_IRQ) {
struct esschan *es;
- spin_lock(&chip->substream_lock);
- list_for_each_entry(es, &chip->substream_list, list) {
- if (es->running) {
- snd_es1968_update_pcm(chip, es);
- if (es->fmt & ESS_FMT_STEREO)
- snd_es1968_suppress_jitter(chip, es);
+ scoped_guard(spinlock, &chip->substream_lock) {
+ list_for_each_entry(es, &chip->substream_list, list) {
+ if (es->running) {
+ snd_es1968_update_pcm(chip, es);
+ if (es->fmt & ESS_FMT_STEREO)
+ snd_es1968_suppress_jitter(chip, es);
+ }
}
}
- spin_unlock(&chip->substream_lock);
if (chip->in_measurement) {
unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5);
if (curp < chip->measure_lastpos)
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index cf40bd06b734..4ca992449ea3 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -279,16 +279,14 @@ static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg,
unsigned short mask, unsigned short value)
{
int change;
- unsigned long flags;
unsigned short old, new;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
old = fm801_ioread16(chip, reg);
new = (old & ~mask) | value;
change = old != new;
if (change)
fm801_iowrite16(chip, reg, new);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@@ -393,7 +391,7 @@ static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream,
{
struct fm801 *chip = snd_pcm_substream_chip(substream);
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
chip->ply_ctrl &= ~(FM801_BUF1_LAST |
@@ -414,12 +412,10 @@ static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream,
chip->ply_ctrl &= ~FM801_PAUSE;
break;
default:
- spin_unlock(&chip->reg_lock);
snd_BUG();
return -EINVAL;
}
fm801_writew(chip, PLY_CTRL, chip->ply_ctrl);
- spin_unlock(&chip->reg_lock);
return 0;
}
@@ -428,7 +424,7 @@ static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream,
{
struct fm801 *chip = snd_pcm_substream_chip(substream);
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
chip->cap_ctrl &= ~(FM801_BUF1_LAST |
@@ -449,12 +445,10 @@ static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream,
chip->cap_ctrl &= ~FM801_PAUSE;
break;
default:
- spin_unlock(&chip->reg_lock);
snd_BUG();
return -EINVAL;
}
fm801_writew(chip, CAP_CTRL, chip->cap_ctrl);
- spin_unlock(&chip->reg_lock);
return 0;
}
@@ -465,7 +459,7 @@ static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream)
chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
chip->ply_count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->ply_ctrl &= ~(FM801_START | FM801_16BIT |
FM801_STEREO | FM801_RATE_MASK |
FM801_CHANNELS_MASK);
@@ -487,7 +481,6 @@ static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream)
fm801_writel(chip, PLY_BUF1, chip->ply_buffer);
fm801_writel(chip, PLY_BUF2,
chip->ply_buffer + (chip->ply_count % chip->ply_size));
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -498,7 +491,7 @@ static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream)
chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
chip->cap_count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->cap_ctrl &= ~(FM801_START | FM801_16BIT |
FM801_STEREO | FM801_RATE_MASK);
if (snd_pcm_format_width(runtime->format) == 16)
@@ -514,7 +507,6 @@ static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream)
fm801_writel(chip, CAP_BUF1, chip->cap_buffer);
fm801_writel(chip, CAP_BUF2,
chip->cap_buffer + (chip->cap_count % chip->cap_size));
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -525,13 +517,12 @@ static snd_pcm_uframes_t snd_fm801_playback_pointer(struct snd_pcm_substream *su
if (!(chip->ply_ctrl & FM801_START))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
ptr = chip->ply_pos + (chip->ply_count - 1) - fm801_readw(chip, PLY_COUNT);
if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_PLAYBACK) {
ptr += chip->ply_count;
ptr %= chip->ply_size;
}
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -542,13 +533,12 @@ static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *sub
if (!(chip->cap_ctrl & FM801_START))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
ptr = chip->cap_pos + (chip->cap_count - 1) - fm801_readw(chip, CAP_COUNT);
if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_CAPTURE) {
ptr += chip->cap_count;
ptr %= chip->cap_size;
}
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -565,31 +555,31 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
/* ack first */
fm801_writew(chip, IRQ_STATUS, status);
if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
- spin_lock(&chip->reg_lock);
- chip->ply_buf++;
- chip->ply_pos += chip->ply_count;
- chip->ply_pos %= chip->ply_size;
- tmp = chip->ply_pos + chip->ply_count;
- tmp %= chip->ply_size;
- if (chip->ply_buf & 1)
- fm801_writel(chip, PLY_BUF1, chip->ply_buffer + tmp);
- else
- fm801_writel(chip, PLY_BUF2, chip->ply_buffer + tmp);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ chip->ply_buf++;
+ chip->ply_pos += chip->ply_count;
+ chip->ply_pos %= chip->ply_size;
+ tmp = chip->ply_pos + chip->ply_count;
+ tmp %= chip->ply_size;
+ if (chip->ply_buf & 1)
+ fm801_writel(chip, PLY_BUF1, chip->ply_buffer + tmp);
+ else
+ fm801_writel(chip, PLY_BUF2, chip->ply_buffer + tmp);
+ }
snd_pcm_period_elapsed(chip->playback_substream);
}
if (chip->pcm && (status & FM801_IRQ_CAPTURE) && chip->capture_substream) {
- spin_lock(&chip->reg_lock);
- chip->cap_buf++;
- chip->cap_pos += chip->cap_count;
- chip->cap_pos %= chip->cap_size;
- tmp = chip->cap_pos + chip->cap_count;
- tmp %= chip->cap_size;
- if (chip->cap_buf & 1)
- fm801_writel(chip, CAP_BUF1, chip->cap_buffer + tmp);
- else
- fm801_writel(chip, CAP_BUF2, chip->cap_buffer + tmp);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ chip->cap_buf++;
+ chip->cap_pos += chip->cap_count;
+ chip->cap_pos %= chip->cap_size;
+ tmp = chip->cap_pos + chip->cap_count;
+ tmp %= chip->cap_size;
+ if (chip->cap_buf & 1)
+ fm801_writel(chip, CAP_BUF1, chip->cap_buffer + tmp);
+ else
+ fm801_writel(chip, CAP_BUF2, chip->cap_buffer + tmp);
+ }
snd_pcm_period_elapsed(chip->capture_substream);
}
if (chip->rmidi && (status & FM801_IRQ_MPU))
@@ -924,10 +914,9 @@ static int snd_fm801_get_double(struct snd_kcontrol *kcontrol,
int invert = (kcontrol->private_value >> 24) & 0xff;
long *value = ucontrol->value.integer.value;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
value[0] = (fm801_ioread16(chip, reg) >> shift_left) & mask;
value[1] = (fm801_ioread16(chip, reg) >> shift_right) & mask;
- spin_unlock_irq(&chip->reg_lock);
if (invert) {
value[0] = mask - value[0];
value[1] = mask - value[1];
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 027849329c1b..b4c9e7d11609 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -358,14 +358,13 @@ static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short vol;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
if (kcontrol->private_value & AUREON_AC97_STEREO)
ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -401,12 +400,11 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -439,11 +437,10 @@ static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ct
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -642,11 +639,10 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -704,9 +700,8 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -944,11 +939,10 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
val = val > PCM_MIN ? (val - PCM_MIN) : 0;
ucontrol->value.integer.value[0] = val;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -984,12 +978,11 @@ static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
unsigned short val;
int i;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
val = wm_get(ice, WM_ADC_GAIN + i);
ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -1031,13 +1024,12 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
int i, idx;
unsigned short vol;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
idx = WM_ADC_GAIN + i;
vol = wm_get(ice, idx) & 0x1f;
ucontrol->value.integer.value[i] = vol;
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -1097,11 +1089,10 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
val = wm_get(ice, WM_ADC_MUX);
ucontrol->value.enumerated.item[0] = val & 7;
ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 08adf4dd1303..e5a9585cba4c 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -126,13 +126,12 @@ static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *byt
int res = count;
unsigned char tmp;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
tmp = ap_cs8427_codec_select(ice);
ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
while (count-- > 0)
ap_cs8427_write_byte(ice, *bytes++, tmp);
ap_cs8427_codec_deassert(ice, tmp);
- mutex_unlock(&ice->gpio_mutex);
return res;
}
@@ -143,13 +142,12 @@ static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *byt
int res = count;
unsigned char tmp;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
tmp = ap_cs8427_codec_select(ice);
ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
while (count-- > 0)
*bytes++ = ap_cs8427_read_byte(ice, tmp);
ap_cs8427_codec_deassert(ice, tmp);
- mutex_unlock(&ice->gpio_mutex);
return res;
}
@@ -176,7 +174,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign
/* send byte to transmitter */
mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
for (idx = 7; idx >= 0; idx--) {
tmp &= ~(mask1 | mask2);
@@ -190,7 +188,6 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign
}
tmp &= ~mask1;
snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- mutex_unlock(&ice->gpio_mutex);
}
@@ -205,15 +202,13 @@ static int delta_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_
int change;
val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_bits != val;
- ice->spdif.cs8403_bits = val;
- if (change && ice->playback_pro_substream == NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_delta_cs8403_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ change = ice->spdif.cs8403_bits != val;
+ ice->spdif.cs8403_bits = val;
+ if (!change || ice->playback_pro_substream)
+ return change;
}
+ snd_ice1712_delta_cs8403_spdif_write(ice, val);
return change;
}
@@ -228,15 +223,13 @@ static int delta_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_v
int change;
val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_stream_bits != val;
- ice->spdif.cs8403_stream_bits = val;
- if (change && ice->playback_pro_substream != NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_delta_cs8403_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ change = ice->spdif.cs8403_stream_bits != val;
+ ice->spdif.cs8403_stream_bits = val;
+ if (!change || ice->playback_pro_substream)
+ return change;
}
+ snd_ice1712_delta_cs8403_spdif_write(ice, val);
return change;
}
@@ -306,14 +299,13 @@ static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
if (rate == 0) /* no hint - S/PDIF input is master, simply return */
return;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
tmp2 = tmp & ~ICE1712_DELTA_DFS;
if (rate > 48000)
tmp2 |= ICE1712_DELTA_DFS;
if (tmp != tmp2)
snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
- mutex_unlock(&ice->gpio_mutex);
}
/*
@@ -328,9 +320,9 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
return;
/* check before reset ak4524 to avoid unnecessary clicks */
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- mutex_unlock(&ice->gpio_mutex);
+ scoped_guard(mutex, &ice->gpio_mutex) {
+ tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
+ }
tmp2 = tmp & ~ICE1712_DELTA_DFS;
if (rate > 48000)
tmp2 |= ICE1712_DELTA_DFS;
@@ -339,12 +331,12 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
/* do it again */
snd_akm4xxx_reset(ak, 1);
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
- if (rate > 48000)
- tmp |= ICE1712_DELTA_DFS;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- mutex_unlock(&ice->gpio_mutex);
+ scoped_guard(mutex, &ice->gpio_mutex) {
+ tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
+ if (rate > 48000)
+ tmp |= ICE1712_DELTA_DFS;
+ snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
+ }
snd_akm4xxx_reset(ak, 0);
}
@@ -379,23 +371,22 @@ static void delta_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *
/* set up */
static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
{
- unsigned long flags;
unsigned int tmp;
int change;
- spin_lock_irqsave(&ice->reg_lock, flags);
- tmp = ice->spdif.cs8403_stream_bits;
- if (tmp & 0x01) /* consumer */
- tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
- switch (rate) {
- case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
- case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
- case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
- default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
+ scoped_guard(spinlock_irqsave, &ice->reg_lock) {
+ tmp = ice->spdif.cs8403_stream_bits;
+ if (tmp & 0x01) /* consumer */
+ tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
+ switch (rate) {
+ case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
+ case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
+ case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
+ default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
+ }
+ change = ice->spdif.cs8403_stream_bits != tmp;
+ ice->spdif.cs8403_stream_bits = tmp;
}
- change = ice->spdif.cs8403_stream_bits != tmp;
- ice->spdif.cs8403_stream_bits = tmp;
- spin_unlock_irqrestore(&ice->reg_lock, flags);
if (change)
snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 8bb86b3c894e..1dffcb011deb 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -260,15 +260,13 @@ static int ews88_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_
int change;
val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_bits != val;
- ice->spdif.cs8403_bits = val;
- if (change && ice->playback_pro_substream == NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_ews_cs8404_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ change = ice->spdif.cs8403_bits != val;
+ ice->spdif.cs8403_bits = val;
+ if (!change || ice->playback_pro_substream)
+ return change;
}
+ snd_ice1712_ews_cs8404_spdif_write(ice, val);
return change;
}
@@ -283,15 +281,13 @@ static int ews88_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_v
int change;
val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_stream_bits != val;
- ice->spdif.cs8403_stream_bits = val;
- if (change && ice->playback_pro_substream != NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_ews_cs8404_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ change = ice->spdif.cs8403_stream_bits != val;
+ ice->spdif.cs8403_stream_bits = val;
+ if (!change || ice->playback_pro_substream)
+ return change;
}
+ snd_ice1712_ews_cs8404_spdif_write(ice, val);
return change;
}
@@ -305,23 +301,22 @@ static void ews88_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *
/* set up SPDIF for EWS88MT / EWS88D */
static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
{
- unsigned long flags;
unsigned char tmp;
int change;
- spin_lock_irqsave(&ice->reg_lock, flags);
- tmp = ice->spdif.cs8403_stream_bits;
- if (tmp & 0x10) /* consumer */
- tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
- switch (rate) {
- case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
- case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
- case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
- default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
+ scoped_guard(spinlock_irqsave, &ice->reg_lock) {
+ tmp = ice->spdif.cs8403_stream_bits;
+ if (tmp & 0x10) /* consumer */
+ tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
+ switch (rate) {
+ case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
+ case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
+ case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
+ default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
+ }
+ change = ice->spdif.cs8403_stream_bits != tmp;
+ ice->spdif.cs8403_stream_bits = tmp;
}
- change = ice->spdif.cs8403_stream_bits != tmp;
- ice->spdif.cs8403_stream_bits = tmp;
- spin_unlock_irqrestore(&ice->reg_lock, flags);
if (change)
snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index 46daeea8dc66..071f94dc7390 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -41,35 +41,35 @@ static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned cha
static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
- mutex_unlock(&ice->gpio_mutex);
}
static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
}
static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
}
static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
/* select box */
ICE1712_STDSP24_0_BOX(spec->boxbits, box);
@@ -111,15 +111,13 @@ static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, in
ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
-
- mutex_unlock(&ice->gpio_mutex);
}
static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
/* select box */
ICE1712_STDSP24_0_BOX(spec->boxbits, box);
@@ -139,17 +137,15 @@ static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int m
ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
-
- mutex_unlock(&ice->gpio_mutex);
}
static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
{
struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
}
static int hoontech_init(struct snd_ice1712 *ice, bool staudio)
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 1aefd46ebf6b..1e39b985bef2 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -249,13 +249,12 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char val, nval;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
nval = val & ~ICE1712_ROUTE_AC97;
if (ucontrol->value.integer.value[0])
nval |= ICE1712_ROUTE_AC97;
outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
- spin_unlock_irq(&ice->reg_lock);
return val != nval;
}
@@ -484,7 +483,7 @@ static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
int result = 0;
u32 tmp;
- spin_lock(&ice->reg_lock);
+ guard(spinlock)(&ice->reg_lock);
tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
tmp |= 1;
@@ -498,7 +497,6 @@ static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
result = -EINVAL;
}
snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
- spin_unlock(&ice->reg_lock);
return result;
}
@@ -509,7 +507,7 @@ static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
int result = 0;
u32 tmp;
- spin_lock(&ice->reg_lock);
+ guard(spinlock)(&ice->reg_lock);
tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
tmp |= 1;
@@ -523,7 +521,6 @@ static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
result = -EINVAL;
}
snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp);
- spin_unlock(&ice->reg_lock);
return result;
}
@@ -534,7 +531,7 @@ static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
int result = 0;
u8 tmp;
- spin_lock(&ice->reg_lock);
+ guard(spinlock)(&ice->reg_lock);
tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
tmp |= 1;
@@ -544,7 +541,6 @@ static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
result = -EINVAL;
}
snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
- spin_unlock(&ice->reg_lock);
return result;
}
@@ -564,7 +560,7 @@ static int snd_ice1712_playback_prepare(struct snd_pcm_substream *substream)
rate = (runtime->rate * 8192) / 375;
if (rate > 0x000fffff)
rate = 0x000fffff;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
outb(0, ice->ddma_port + 15);
outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b);
outl(runtime->dma_addr, ice->ddma_port + 0);
@@ -577,7 +573,6 @@ static int snd_ice1712_playback_prepare(struct snd_pcm_substream *substream)
snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8);
snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0);
snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0);
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -599,7 +594,7 @@ static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream)
ice->playback_con_active_buf[substream->number] = 0;
ice->playback_con_virt_addr[substream->number] = runtime->dma_addr;
chn = substream->number * 2;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr);
snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size);
snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0));
@@ -611,7 +606,6 @@ static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream)
snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate);
snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0);
}
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -629,13 +623,13 @@ static int snd_ice1712_capture_prepare(struct snd_pcm_substream *substream)
tmp &= ~0x04;
if (runtime->channels == 2)
tmp &= ~0x02;
- spin_lock_irq(&ice->reg_lock);
- outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
- outw(buf_size, ICEREG(ice, CONCAP_COUNT));
- snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
- snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
+ outw(buf_size, ICEREG(ice, CONCAP_COUNT));
+ snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
+ snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
+ snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
+ }
snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
return 0;
}
@@ -763,10 +757,9 @@ static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream)
ice->playback_con_substream_ds[substream->number] = substream;
runtime->hw = snd_ice1712_playback_ds;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
outw(tmp, ICEDS(ice, INTMASK));
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -796,10 +789,9 @@ static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
u32 tmp;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
outw(tmp, ICEDS(ice, INTMASK));
- spin_unlock_irq(&ice->reg_lock);
ice->playback_con_substream_ds[substream->number] = NULL;
return 0;
}
@@ -911,14 +903,13 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
return -EINVAL;
what = ICE1712_PLAYBACK_PAUSE;
snd_pcm_trigger_done(substream, substream);
- spin_lock(&ice->reg_lock);
+ guard(spinlock)(&ice->reg_lock);
old = inl(ICEMT(ice, PLAYBACK_CONTROL));
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
old |= what;
else
old &= ~what;
outl(old, ICEMT(ice, PLAYBACK_CONTROL));
- spin_unlock(&ice->reg_lock);
break;
}
case SNDRV_PCM_TRIGGER_START:
@@ -937,14 +928,13 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
snd_pcm_trigger_done(s, substream);
}
}
- spin_lock(&ice->reg_lock);
+ guard(spinlock)(&ice->reg_lock);
old = inl(ICEMT(ice, PLAYBACK_CONTROL));
if (cmd == SNDRV_PCM_TRIGGER_START)
old |= what;
else
old &= ~what;
outl(old, ICEMT(ice, PLAYBACK_CONTROL));
- spin_unlock(&ice->reg_lock);
break;
}
default:
@@ -957,7 +947,6 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
*/
static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, int force)
{
- unsigned long flags;
unsigned char val, old;
unsigned int i;
@@ -982,24 +971,21 @@ static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
break;
}
- spin_lock_irqsave(&ice->reg_lock, flags);
- if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
- ICE1712_PLAYBACK_PAUSE|
- ICE1712_PLAYBACK_START)) {
-__out:
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return;
- }
- if (!force && is_pro_rate_locked(ice))
- goto __out;
+ scoped_guard(spinlock_irqsave, &ice->reg_lock) {
+ if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
+ ICE1712_PLAYBACK_PAUSE|
+ ICE1712_PLAYBACK_START))
+ return;
+ if (!force && is_pro_rate_locked(ice))
+ return;
- old = inb(ICEMT(ice, RATE));
- if (!force && old == val)
- goto __out;
+ old = inb(ICEMT(ice, RATE));
+ if (!force && old == val)
+ return;
- ice->cur_rate = rate;
- outb(val, ICEMT(ice, RATE));
- spin_unlock_irqrestore(&ice->reg_lock, flags);
+ ice->cur_rate = rate;
+ outb(val, ICEMT(ice, RATE));
+ }
if (ice->gpio.set_pro_rate)
ice->gpio.set_pro_rate(ice, rate);
@@ -1016,11 +1002,10 @@ static int snd_ice1712_playback_pro_prepare(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1039,11 +1024,10 @@ static int snd_ice1712_capture_pro_prepare(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1258,12 +1242,11 @@ static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struc
int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
kcontrol->private_value;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
ucontrol->value.integer.value[0] =
!((ice->pro_volumes[priv_idx] >> 15) & 1);
ucontrol->value.integer.value[1] =
!((ice->pro_volumes[priv_idx] >> 31) & 1);
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1276,12 +1259,11 @@ static int snd_ice1712_pro_mixer_switch_put(struct snd_kcontrol *kcontrol, struc
nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |
(ucontrol->value.integer.value[1] ? 0 : 0x80000000);
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
nval |= ice->pro_volumes[priv_idx] & ~0x80008000;
change = nval != ice->pro_volumes[priv_idx];
ice->pro_volumes[priv_idx] = nval;
snd_ice1712_update_volume(ice, priv_idx);
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -1300,12 +1282,11 @@ static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struc
int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
kcontrol->private_value;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
ucontrol->value.integer.value[0] =
(ice->pro_volumes[priv_idx] >> 0) & 127;
ucontrol->value.integer.value[1] =
(ice->pro_volumes[priv_idx] >> 16) & 127;
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1318,12 +1299,11 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc
nval = (ucontrol->value.integer.value[0] & 127) |
((ucontrol->value.integer.value[1] & 127) << 16);
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
nval |= ice->pro_volumes[priv_idx] & ~0x007f007f;
change = nval != ice->pro_volumes[priv_idx];
ice->pro_volumes[priv_idx] = nval;
snd_ice1712_update_volume(ice, priv_idx);
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -1781,7 +1761,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
};
unsigned char val;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
if (is_spdif_master(ice)) {
ucontrol->value.enumerated.item[0] = 13;
} else {
@@ -1792,7 +1772,6 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
}
ucontrol->value.enumerated.item[0] = val;
}
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1916,10 +1895,9 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
int change = 0, nval;
nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
change = PRO_RATE_LOCKED != nval;
PRO_RATE_LOCKED = nval;
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -1947,10 +1925,9 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
int change = 0, nval;
nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
change = PRO_RATE_RESET != nval;
PRO_RATE_RESET = nval;
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -1986,10 +1963,10 @@ static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol,
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned int val, cval;
- spin_lock_irq(&ice->reg_lock);
- val = inw(ICEMT(ice, ROUTE_PSDOUT03));
- cval = inl(ICEMT(ice, ROUTE_CAPTURE));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ val = inw(ICEMT(ice, ROUTE_PSDOUT03));
+ cval = inl(ICEMT(ice, ROUTE_CAPTURE));
+ }
val >>= ((idx % 2) * 8) + ((idx / 2) * 2);
val &= 3;
@@ -2023,35 +2000,35 @@ static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol,
else
nval = 0; /* pcm */
shift = ((idx % 2) * 8) + ((idx / 2) * 2);
- spin_lock_irq(&ice->reg_lock);
- val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
- val &= ~(0x03 << shift);
- val |= nval << shift;
- change = val != old_val;
- if (change)
- outw(val, ICEMT(ice, ROUTE_PSDOUT03));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
+ val &= ~(0x03 << shift);
+ val |= nval << shift;
+ change = val != old_val;
+ if (change)
+ outw(val, ICEMT(ice, ROUTE_PSDOUT03));
+ }
if (nval < 2) /* dig mixer of pcm */
return change;
/* update CAPTURE */
- spin_lock_irq(&ice->reg_lock);
- val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
- shift = ((idx / 2) * 8) + ((idx % 2) * 4);
- if (nval == 2) { /* analog in */
- nval = ucontrol->value.enumerated.item[0] - 1;
- val &= ~(0x07 << shift);
- val |= nval << shift;
- } else { /* spdif in */
- nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
- val &= ~(0x08 << shift);
- val |= nval << shift;
- }
- if (val != old_val) {
- change = 1;
- outl(val, ICEMT(ice, ROUTE_CAPTURE));
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
+ shift = ((idx / 2) * 8) + ((idx % 2) * 4);
+ if (nval == 2) { /* analog in */
+ nval = ucontrol->value.enumerated.item[0] - 1;
+ val &= ~(0x07 << shift);
+ val |= nval << shift;
+ } else { /* spdif in */
+ nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
+ val &= ~(0x08 << shift);
+ val |= nval << shift;
+ }
+ if (val != old_val) {
+ change = 1;
+ outl(val, ICEMT(ice, ROUTE_CAPTURE));
+ }
}
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -2084,7 +2061,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
unsigned int val, old_val, nval;
/* update SPDOUT */
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
if (ucontrol->value.enumerated.item[0] >= 11)
nval = 1;
@@ -2110,7 +2087,6 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
change = val != old_val;
if (change)
outw(val, ICEMT(ice, ROUTE_SPDOUT));
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -2157,10 +2133,9 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int change;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0];
outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE));
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -2188,12 +2163,11 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
for (idx = 0; idx < 22; idx++) {
outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA));
}
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -2675,11 +2649,11 @@ static int snd_ice1712_suspend(struct device *dev)
snd_ac97_suspend(ice->ac97);
- spin_lock_irq(&ice->reg_lock);
- ice->pm_saved_is_spdif_master = is_spdif_master(ice);
- ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT));
- ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ ice->pm_saved_is_spdif_master = is_spdif_master(ice);
+ ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT));
+ ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03));
+ }
if (ice->pm_suspend)
ice->pm_suspend(ice);
@@ -2712,10 +2686,10 @@ static int snd_ice1712_resume(struct device *dev)
if (ice->pm_saved_is_spdif_master) {
/* switching to external clock via SPDIF */
- spin_lock_irq(&ice->reg_lock);
- outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER,
- ICEMT(ice, RATE));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER,
+ ICEMT(ice, RATE));
+ }
snd_ice1712_set_input_clock_source(ice, 1);
} else {
/* internal on-card clock */
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 0445d2e8e548..e2dbbbfbca9f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -288,9 +288,8 @@ static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
{
struct snd_ice1712 *ice = substream->rmidi->private_data;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
enable_midi_irq(ice, flag, enable);
- spin_unlock_irq(&ice->reg_lock);
}
static int vt1724_midi_output_open(struct snd_rawmidi_substream *s)
@@ -306,9 +305,8 @@ static int vt1724_midi_output_close(struct snd_rawmidi_substream *s)
static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up)
{
struct snd_ice1712 *ice = s->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&ice->reg_lock, flags);
+ guard(spinlock_irqsave)(&ice->reg_lock);
if (up) {
ice->midi_output = 1;
vt1724_midi_write(ice);
@@ -316,7 +314,6 @@ static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up)
ice->midi_output = 0;
enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
}
- spin_unlock_irqrestore(&ice->reg_lock, flags);
}
static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s)
@@ -357,16 +354,14 @@ static int vt1724_midi_input_close(struct snd_rawmidi_substream *s)
static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up)
{
struct snd_ice1712 *ice = s->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&ice->reg_lock, flags);
+ guard(spinlock_irqsave)(&ice->reg_lock);
if (up) {
ice->midi_input = 1;
vt1724_midi_read(ice);
} else {
ice->midi_input = 0;
}
- spin_unlock_irqrestore(&ice->reg_lock, flags);
}
static const struct snd_rawmidi_ops vt1724_midi_input_ops = {
@@ -394,40 +389,39 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
status &= status_mask;
if (status == 0)
break;
- spin_lock(&ice->reg_lock);
- if (++timeout > 10) {
- status = inb(ICEREG1724(ice, IRQSTAT));
- dev_err(ice->card->dev,
- "Too long irq loop, status = 0x%x\n", status);
+ scoped_guard(spinlock, &ice->reg_lock) {
+ if (++timeout > 10) {
+ status = inb(ICEREG1724(ice, IRQSTAT));
+ dev_err(ice->card->dev,
+ "Too long irq loop, status = 0x%x\n", status);
+ if (status & VT1724_IRQ_MPU_TX) {
+ dev_err(ice->card->dev, "Disabling MPU_TX\n");
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
+ }
+ goto out;
+ }
+ handled = 1;
if (status & VT1724_IRQ_MPU_TX) {
- dev_err(ice->card->dev, "Disabling MPU_TX\n");
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
+ if (ice->midi_output)
+ vt1724_midi_write(ice);
+ else
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
+ /* Due to mysterical reasons, MPU_TX is always
+ * generated (and can't be cleared) when a PCM
+ * playback is going. So let's ignore at the
+ * next loop.
+ */
+ status_mask &= ~VT1724_IRQ_MPU_TX;
}
- spin_unlock(&ice->reg_lock);
- break;
- }
- handled = 1;
- if (status & VT1724_IRQ_MPU_TX) {
- if (ice->midi_output)
- vt1724_midi_write(ice);
- else
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
- /* Due to mysterical reasons, MPU_TX is always
- * generated (and can't be cleared) when a PCM
- * playback is going. So let's ignore at the
- * next loop.
- */
- status_mask &= ~VT1724_IRQ_MPU_TX;
- }
- if (status & VT1724_IRQ_MPU_RX) {
- if (ice->midi_input)
- vt1724_midi_read(ice);
- else
- vt1724_midi_clear_rx(ice);
+ if (status & VT1724_IRQ_MPU_RX) {
+ if (ice->midi_input)
+ vt1724_midi_read(ice);
+ else
+ vt1724_midi_clear_rx(ice);
+ }
+ /* ack MPU irq */
+ outb(status, ICEREG1724(ice, IRQSTAT));
}
- /* ack MPU irq */
- outb(status, ICEREG1724(ice, IRQSTAT));
- spin_unlock(&ice->reg_lock);
if (status & VT1724_IRQ_MTPCM) {
/*
* Multi-track PCM
@@ -481,6 +475,7 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
}
}
+ out:
return IRQ_RETVAL(handled);
}
@@ -539,27 +534,27 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
switch (cmd) {
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock(&ice->reg_lock);
- old = inb(ICEMT1724(ice, DMA_PAUSE));
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- old |= what;
- else
- old &= ~what;
- outb(old, ICEMT1724(ice, DMA_PAUSE));
- spin_unlock(&ice->reg_lock);
+ scoped_guard(spinlock, &ice->reg_lock) {
+ old = inb(ICEMT1724(ice, DMA_PAUSE));
+ if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+ old |= what;
+ else
+ old &= ~what;
+ outb(old, ICEMT1724(ice, DMA_PAUSE));
+ }
break;
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
- spin_lock(&ice->reg_lock);
- old = inb(ICEMT1724(ice, DMA_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_START)
- old |= what;
- else
- old &= ~what;
- outb(old, ICEMT1724(ice, DMA_CONTROL));
- spin_unlock(&ice->reg_lock);
+ scoped_guard(spinlock, &ice->reg_lock) {
+ old = inb(ICEMT1724(ice, DMA_CONTROL));
+ if (cmd == SNDRV_PCM_TRIGGER_START)
+ old |= what;
+ else
+ old &= ~what;
+ outb(old, ICEMT1724(ice, DMA_CONTROL));
+ }
break;
case SNDRV_PCM_TRIGGER_RESUME:
@@ -625,7 +620,6 @@ static unsigned char stdclock_set_mclk(struct snd_ice1712 *ice,
static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
int force)
{
- unsigned long flags;
unsigned char mclk_change;
unsigned int i, old_rate;
bool call_set_rate = false;
@@ -633,34 +627,31 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
if (rate > ice->hw_rates->list[ice->hw_rates->count - 1])
return -EINVAL;
- spin_lock_irqsave(&ice->reg_lock, flags);
- if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
- (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
- /* running? we cannot change the rate now... */
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
- }
- if (!force && is_pro_rate_locked(ice)) {
- /* comparing required and current rate - makes sense for
- * internal clock only */
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return (rate == ice->cur_rate) ? 0 : -EBUSY;
- }
+ scoped_guard(spinlock_irqsave, &ice->reg_lock) {
+ if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
+ (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
+ /* running? we cannot change the rate now... */
+ return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
+ }
+ if (!force && is_pro_rate_locked(ice)) {
+ /* comparing required and current rate - makes sense for
+ * internal clock only */
+ return (rate == ice->cur_rate) ? 0 : -EBUSY;
+ }
- if (force || !ice->is_spdif_master(ice)) {
- /* force means the rate was switched by ucontrol, otherwise
- * setting clock rate for internal clock mode */
- old_rate = ice->get_rate(ice);
- if (force || (old_rate != rate))
- call_set_rate = true;
- else if (rate == ice->cur_rate) {
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return 0;
+ if (force || !ice->is_spdif_master(ice)) {
+ /* force means the rate was switched by ucontrol, otherwise
+ * setting clock rate for internal clock mode */
+ old_rate = ice->get_rate(ice);
+ if (force || (old_rate != rate))
+ call_set_rate = true;
+ else if (rate == ice->cur_rate) {
+ return 0;
+ }
}
- }
- ice->cur_rate = rate;
- spin_unlock_irqrestore(&ice->reg_lock, flags);
+ ice->cur_rate = rate;
+ }
if (call_set_rate)
ice->set_rate(ice, rate);
@@ -684,24 +675,21 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
return 0;
}
-static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+static int __snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
int i, chs;
chs = params_channels(hw_params);
- mutex_lock(&ice->open_mutex);
/* mark surround channels */
if (substream == ice->playback_pro_substream) {
/* PDMA0 can be multi-channel up to 8 */
chs = chs / 2 - 1;
for (i = 0; i < chs; i++) {
if (ice->pcm_reserved[i] &&
- ice->pcm_reserved[i] != substream) {
- mutex_unlock(&ice->open_mutex);
+ ice->pcm_reserved[i] != substream)
return -EBUSY;
- }
ice->pcm_reserved[i] = substream;
}
for (; i < 3; i++) {
@@ -713,16 +701,28 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
/* check individual playback stream */
if (ice->playback_con_substream_ds[i] == substream) {
if (ice->pcm_reserved[i] &&
- ice->pcm_reserved[i] != substream) {
- mutex_unlock(&ice->open_mutex);
+ ice->pcm_reserved[i] != substream)
return -EBUSY;
- }
ice->pcm_reserved[i] = substream;
break;
}
}
}
- mutex_unlock(&ice->open_mutex);
+
+ return 0;
+}
+
+static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+ int err;
+
+ scoped_guard(mutex, &ice->open_mutex) {
+ err = __snd_vt1724_pcm_hw_params(substream, hw_params);
+ if (err < 0)
+ return err;
+ }
return snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
}
@@ -732,12 +732,11 @@ static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
int i;
- mutex_lock(&ice->open_mutex);
+ guard(mutex)(&ice->open_mutex);
/* unmark surround channels */
for (i = 0; i < 3; i++)
if (ice->pcm_reserved[i] == substream)
ice->pcm_reserved[i] = NULL;
- mutex_unlock(&ice->open_mutex);
return 0;
}
@@ -747,7 +746,7 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
unsigned char val;
unsigned int size;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
val = (8 - substream->runtime->channels) >> 1;
outb(val, ICEMT1724(ice, BURST));
@@ -762,8 +761,6 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
- spin_unlock_irq(&ice->reg_lock);
-
/*
dev_dbg(ice->card->dev, "pro prepare: ch = %d, addr = 0x%x, "
"buffer = 0x%x, period = 0x%x\n",
@@ -817,13 +814,12 @@ static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1,
ice->profi_port + reg->size);
outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1,
ice->profi_port + reg->count);
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1013,18 +1009,18 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
set_rate_constraints(ice, substream);
- mutex_lock(&ice->open_mutex);
- /* calculate the currently available channels */
- num_indeps = ice->num_total_dacs / 2 - 1;
- for (chs = 0; chs < num_indeps; chs++) {
- if (ice->pcm_reserved[chs])
- break;
+ scoped_guard(mutex, &ice->open_mutex) {
+ /* calculate the currently available channels */
+ num_indeps = ice->num_total_dacs / 2 - 1;
+ for (chs = 0; chs < num_indeps; chs++) {
+ if (ice->pcm_reserved[chs])
+ break;
+ }
+ chs = (chs + 1) * 2;
+ runtime->hw.channels_max = chs;
+ if (chs > 2) /* channels must be even */
+ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
}
- chs = (chs + 1) * 2;
- runtime->hw.channels_max = chs;
- if (chs > 2) /* channels must be even */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- mutex_unlock(&ice->open_mutex);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
VT1724_BUFFER_ALIGN);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
@@ -1152,9 +1148,8 @@ static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val)
static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
{
unsigned int val, nval;
- unsigned long flags;
- spin_lock_irqsave(&ice->reg_lock, flags);
+ guard(spinlock_irqsave)(&ice->reg_lock);
nval = val = inw(ICEMT1724(ice, SPDIF_CTRL));
nval &= ~(7 << 12);
switch (rate) {
@@ -1168,7 +1163,6 @@ static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
}
if (val != nval)
update_spdif_bits(ice, nval);
- spin_unlock_irqrestore(&ice->reg_lock, flags);
}
static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream)
@@ -1354,11 +1348,11 @@ static int snd_vt1724_playback_indep_prepare(struct snd_pcm_substream *substream
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
unsigned char val;
- spin_lock_irq(&ice->reg_lock);
- val = 3 - substream->number;
- if (inb(ICEMT1724(ice, BURST)) < val)
- outb(val, ICEMT1724(ice, BURST));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ val = 3 - substream->number;
+ if (inb(ICEMT1724(ice, BURST)) < val)
+ outb(val, ICEMT1724(ice, BURST));
+ }
return snd_vt1724_pcm_prepare(substream);
}
@@ -1367,13 +1361,11 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- mutex_lock(&ice->open_mutex);
- /* already used by PDMA0? */
- if (ice->pcm_reserved[substream->number]) {
- mutex_unlock(&ice->open_mutex);
- return -EBUSY; /* FIXME: should handle blocking mode properly */
+ scoped_guard(mutex, &ice->open_mutex) {
+ /* already used by PDMA0? */
+ if (ice->pcm_reserved[substream->number])
+ return -EBUSY; /* FIXME: should handle blocking mode properly */
}
- mutex_unlock(&ice->open_mutex);
runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number];
ice->playback_con_substream_ds[substream->number] = substream;
runtime->hw = snd_vt1724_2ch_stereo;
@@ -1658,11 +1650,10 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
unsigned int val, old;
val = encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
old = inw(ICEMT1724(ice, SPDIF_CTRL));
if (val != old)
update_spdif_bits(ice, val);
- spin_unlock_irq(&ice->reg_lock);
return val != old;
}
@@ -1733,14 +1724,13 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char old, val;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
old = val = inb(ICEREG1724(ice, SPDIF_CFG));
val &= ~VT1724_CFG_SPDIF_OUT_EN;
if (ucontrol->value.integer.value[0])
val |= VT1724_CFG_SPDIF_OUT_EN;
if (old != val)
outb(val, ICEREG1724(ice, SPDIF_CFG));
- spin_unlock_irq(&ice->reg_lock);
return old != val;
}
@@ -1836,7 +1826,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned int i, rate;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
if (ice->is_spdif_master(ice)) {
ucontrol->value.enumerated.item[0] = ice->hw_rates->count +
ice->get_spdif_master_type(ice);
@@ -1850,7 +1840,6 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
}
}
}
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -1881,29 +1870,31 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
unsigned int old_rate, new_rate;
unsigned int item = ucontrol->value.enumerated.item[0];
unsigned int first_ext_clock = ice->hw_rates->count;
+ bool set_pro_rate = false;
if (item > first_ext_clock + ice->ext_clock_count - 1)
return -EINVAL;
/* if rate = 0 => external clock */
- spin_lock_irq(&ice->reg_lock);
- if (ice->is_spdif_master(ice))
- old_rate = 0;
- else
- old_rate = ice->get_rate(ice);
- if (item >= first_ext_clock) {
- /* switching to external clock */
- ice->set_spdif_clock(ice, item - first_ext_clock);
- new_rate = 0;
- } else {
- /* internal on-card clock */
- new_rate = ice->hw_rates->list[item];
- ice->pro_rate_default = new_rate;
- spin_unlock_irq(&ice->reg_lock);
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
- spin_lock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ if (ice->is_spdif_master(ice))
+ old_rate = 0;
+ else
+ old_rate = ice->get_rate(ice);
+ if (item >= first_ext_clock) {
+ /* switching to external clock */
+ ice->set_spdif_clock(ice, item - first_ext_clock);
+ new_rate = 0;
+ } else {
+ /* internal on-card clock */
+ new_rate = ice->hw_rates->list[item];
+ ice->pro_rate_default = new_rate;
+ set_pro_rate = true;
+ }
}
- spin_unlock_irq(&ice->reg_lock);
+
+ if (set_pro_rate)
+ snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
/* the first switch to the ext. clock mode? */
if (old_rate != new_rate && !new_rate) {
@@ -1943,10 +1934,9 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
int change = 0, nval;
nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
change = PRO_RATE_LOCKED != nval;
PRO_RATE_LOCKED = nval;
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -1974,10 +1964,9 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
int change = 0, nval;
nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
change = PRO_RATE_RESET != nval;
PRO_RATE_RESET = nval;
- spin_unlock_irq(&ice->reg_lock);
return change;
}
@@ -2132,13 +2121,12 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx;
- spin_lock_irq(&ice->reg_lock);
+ guard(spinlock_irq)(&ice->reg_lock);
for (idx = 0; idx < 22; idx++) {
outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
ucontrol->value.integer.value[idx] =
inb(ICEMT1724(ice, MONITOR_PEAKDATA));
}
- spin_unlock_irq(&ice->reg_lock);
return 0;
}
@@ -2220,13 +2208,12 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
{
unsigned char val;
- mutex_lock(&ice->i2c_mutex);
+ guard(mutex)(&ice->i2c_mutex);
wait_i2c_busy(ice);
outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
wait_i2c_busy(ice);
val = inb(ICEREG1724(ice, I2C_DATA));
- mutex_unlock(&ice->i2c_mutex);
/*
dev_dbg(ice->card->dev, "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
*/
@@ -2236,7 +2223,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
unsigned char dev, unsigned char addr, unsigned char data)
{
- mutex_lock(&ice->i2c_mutex);
+ guard(mutex)(&ice->i2c_mutex);
wait_i2c_busy(ice);
/*
dev_dbg(ice->card->dev, "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
@@ -2245,7 +2232,6 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
outb(data, ICEREG1724(ice, I2C_DATA));
outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
wait_i2c_busy(ice);
- mutex_unlock(&ice->i2c_mutex);
}
static int snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
@@ -2685,12 +2671,12 @@ static int snd_vt1724_suspend(struct device *dev)
snd_ac97_suspend(ice->ac97);
- spin_lock_irq(&ice->reg_lock);
- ice->pm_saved_is_spdif_master = ice->is_spdif_master(ice);
- ice->pm_saved_spdif_ctrl = inw(ICEMT1724(ice, SPDIF_CTRL));
- ice->pm_saved_spdif_cfg = inb(ICEREG1724(ice, SPDIF_CFG));
- ice->pm_saved_route = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
- spin_unlock_irq(&ice->reg_lock);
+ scoped_guard(spinlock_irq, &ice->reg_lock) {
+ ice->pm_saved_is_spdif_master = ice->is_spdif_master(ice);
+ ice->pm_saved_spdif_ctrl = inw(ICEMT1724(ice, SPDIF_CTRL));
+ ice->pm_saved_spdif_cfg = inb(ICEREG1724(ice, SPDIF_CFG));
+ ice->pm_saved_route = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
+ }
if (ice->pm_suspend)
ice->pm_suspend(ice);
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c
index b46df1821251..551f478c59c4 100644
--- a/sound/pci/ice1712/maya44.c
+++ b/sound/pci/ice1712/maya44.c
@@ -175,10 +175,9 @@ static int maya_vol_get(struct snd_kcontrol *kcontrol,
&chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
unsigned int idx = kcontrol->private_value;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
ucontrol->value.integer.value[0] = wm->volumes[idx][0];
ucontrol->value.integer.value[1] = wm->volumes[idx][1];
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -193,7 +192,7 @@ static int maya_vol_put(struct snd_kcontrol *kcontrol,
unsigned int val, data;
int ch, changed = 0;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
for (ch = 0; ch < 2; ch++) {
val = ucontrol->value.integer.value[ch];
if (val > vol->maxval)
@@ -213,7 +212,6 @@ static int maya_vol_put(struct snd_kcontrol *kcontrol,
val ? 0 : vol->mux_bits[ch]);
wm->volumes[idx][ch] = val;
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -250,7 +248,7 @@ static int maya_sw_put(struct snd_kcontrol *kcontrol,
unsigned int mask, val;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
mask = 1 << idx;
wm->switch_bits &= ~mask;
val = ucontrol->value.integer.value[0];
@@ -260,7 +258,6 @@ static int maya_sw_put(struct snd_kcontrol *kcontrol,
changed = wm8776_write_bits(chip->ice, wm,
GET_SW_VAL_REG(kcontrol->private_value),
mask, val ? mask : 0);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -315,14 +312,13 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
unsigned int val, mask;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
mask = 1 << shift;
val = ucontrol->value.integer.value[0];
if (GET_GPIO_VAL_INV(kcontrol->private_value))
val = !val;
val = val ? mask : 0;
changed = maya_set_gpio_bits(chip->ice, mask, val);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -369,11 +365,10 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
int sel = ucontrol->value.enumerated.item[0];
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
sel ? (1 << GPIO_MIC_RELAY) : 0);
wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -635,12 +630,11 @@ static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
val |= 8;
val |= ratio << 4;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
for (i = 0; i < 2; i++)
wm8776_write_bits(ice, &chip->wm[i],
WM8776_REG_MASTER_MODE_CONTROL,
0x180, val);
- mutex_unlock(&chip->mutex);
}
/*
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 1e47e46ab8ac..151b740ce66d 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -287,10 +287,9 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
0 : 1;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -638,11 +637,10 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
val = val > PCM_MIN ? (val - PCM_MIN) : 0;
ucontrol->value.integer.value[0] = val;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 683909ca147c..557473f0d59e 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -112,13 +112,12 @@ static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short val;
int i;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
val = val > DAC_MIN ? (val - DAC_MIN) : 0;
ucontrol->value.integer.value[i] = val;
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -128,7 +127,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short oval, nval;
int i, idx, change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
nval = ucontrol->value.integer.value[i];
nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
@@ -140,7 +139,6 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -167,13 +165,12 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short val;
int i;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
val = val > ADC_MIN ? (val - ADC_MIN) : 0;
ucontrol->value.integer.value[i] = val;
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -183,7 +180,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short ovol, nvol;
int i, idx, change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
nvol = ucontrol->value.integer.value[i];
nvol = nvol ? (nvol + ADC_MIN) : 0;
@@ -194,7 +191,6 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -208,9 +204,8 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int bit = kcontrol->private_value;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -221,7 +216,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short oval, nval;
int change;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
nval = oval = wm_get(ice, WM_ADC_MUX);
if (ucontrol->value.integer.value[0])
nval |= (1 << bit);
@@ -231,7 +226,6 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
if (change) {
wm_put(ice, WM_ADC_MUX, nval);
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -244,9 +238,8 @@ static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -256,7 +249,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
unsigned short val, oval;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
val = oval = wm_get(ice, WM_OUT_MUX);
if (ucontrol->value.integer.value[0])
val |= 0x04;
@@ -266,7 +259,6 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
wm_put(ice, WM_OUT_MUX, val);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -279,9 +271,8 @@ static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -291,7 +282,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
unsigned short val, oval;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
oval = wm_get(ice, WM_DAC_CTRL1);
val = oval & 0x0f;
if (ucontrol->value.integer.value[0])
@@ -303,7 +294,6 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
wm_put_nocache(ice, WM_DAC_CTRL1, val);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -410,9 +400,8 @@ static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -422,14 +411,13 @@ static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
unsigned char val;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
val = 0x80 | (ice->gpio.saved[0] << 3);
spi_write(ice, CS_DEV, 0x04, val);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -449,10 +437,10 @@ static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
/* 4-7 reserved */
ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -461,22 +449,22 @@ static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned int val;
int changed;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
/* 4-7 reserved */
val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
changed = val != ice->gpio.write_mask;
ice->gpio.write_mask = val;
- mutex_unlock(&ice->gpio_mutex);
return changed;
}
static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
/* 4-7 reserved */
ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -485,23 +473,23 @@ static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned int val;
int changed;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
/* 4-7 reserved */
val = ucontrol->value.integer.value[0] & 0xff0f;
changed = (val != ice->gpio.direction);
ice->gpio.direction = val;
- mutex_unlock(&ice->gpio_mutex);
return changed;
}
static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -510,7 +498,8 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned int val, nval;
int changed = 0;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
val = snd_ice1712_gpio_read(ice) & 0xffff;
@@ -519,7 +508,6 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
snd_ice1712_gpio_write(ice, nval);
changed = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return changed;
}
@@ -620,14 +608,14 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf
struct snd_ice1712 *ice = entry->private_data;
char line[64];
unsigned int reg, val;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
if (reg <= 0x17 && val <= 0xffff)
wm_put(ice, reg, val);
}
- mutex_unlock(&ice->gpio_mutex);
}
static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
@@ -635,12 +623,11 @@ static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff
struct snd_ice1712 *ice = entry->private_data;
int reg, val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (reg = 0; reg <= 0x17; reg++) {
val = wm_get(ice, reg);
snd_iprintf(buffer, "%02x = %04x\n", reg, val);
}
- mutex_unlock(&ice->gpio_mutex);
}
static void wm_proc_init(struct snd_ice1712 *ice)
@@ -654,14 +641,13 @@ static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff
struct snd_ice1712 *ice = entry->private_data;
int reg, val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (reg = 0; reg <= 0x26; reg++) {
val = spi_read(ice, CS_DEV, reg);
snd_iprintf(buffer, "%02x = %02x\n", reg, val);
}
val = spi_read(ice, CS_DEV, 0x7f);
snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
- mutex_unlock(&ice->gpio_mutex);
}
static void cs_proc_init(struct snd_ice1712 *ice)
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index a12dafbf53ab..cd7db2b65b51 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -110,21 +110,19 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct prodigy192_spec *spec = ice->spec;
- int idx, change;
+ int idx;
if (kcontrol->private_value)
idx = STAC946X_MASTER_VOLUME;
else
idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
/* due to possible conflicts with stac9460_set_rate_val, mutexing */
- mutex_lock(&spec->mute_mutex);
+ guard(mutex)(&spec->mute_mutex);
/*
dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
ucontrol->value.integer.value[0]);
*/
- change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
- mutex_unlock(&spec->mute_mutex);
- return change;
+ return stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
}
/*
@@ -316,7 +314,7 @@ static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
return;
/* change detected, setting master clock, muting first */
/* due to possible conflicts with mute controls - mutexing */
- mutex_lock(&spec->mute_mutex);
+ guard(mutex)(&spec->mute_mutex);
/* we have to remember current mute status for each DAC */
for (idx = 0; idx < 7 ; ++idx)
changed[idx] = stac9460_dac_mute(ice,
@@ -330,7 +328,6 @@ static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
if (changed[idx])
stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
}
- mutex_unlock(&spec->mute_mutex);
}
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 9aa12a67d370..eac233093865 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -268,7 +268,7 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
int i;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
if (ucontrol->value.integer.value[i] != spec->vol[i]) {
spec->vol[i] = ucontrol->value.integer.value[i];
@@ -277,7 +277,6 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -376,7 +375,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
struct prodigy_hifi_spec *spec = ice->spec;
int i, idx, change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
idx = WM_DAC_ATTEN_L + i;
@@ -386,7 +385,6 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -428,7 +426,7 @@ static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
voices = kcontrol->private_value >> 8;
ofs = kcontrol->private_value & 0xff;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < voices; i++) {
if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
idx = WM8766_LDA1 + ofs + i;
@@ -439,7 +437,6 @@ static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -474,7 +471,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
struct prodigy_hifi_spec *spec = ice->spec;
int ch, change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (ch = 0; ch < 2; ch++) {
if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
spec->master[ch] = ucontrol->value.integer.value[ch];
@@ -494,7 +491,6 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -535,9 +531,8 @@ static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.enumerated.item[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -548,14 +543,13 @@ static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
unsigned short oval, nval;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
oval = wm_get(ice, WM_ADC_MUX);
nval = (oval & 0xe0) | ucontrol->value.enumerated.item[0];
if (nval != oval) {
wm_put(ice, WM_ADC_MUX, nval);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -586,13 +580,12 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
unsigned short val;
int i;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
val = val > ADC_MIN ? (val - ADC_MIN) : 0;
ucontrol->value.integer.value[i] = val;
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -603,7 +596,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
unsigned short ovol, nvol;
int i, idx, change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (i = 0; i < 2; i++) {
nvol = ucontrol->value.integer.value[i];
nvol = nvol ? (nvol + ADC_MIN) : 0;
@@ -614,7 +607,6 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
change = 1;
}
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -629,10 +621,9 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int bit = kcontrol->private_value;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] =
(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -644,7 +635,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
unsigned short oval, nval;
int change;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
nval = oval = wm_get(ice, WM_ADC_MUX);
if (ucontrol->value.integer.value[0])
nval |= (1 << bit);
@@ -654,7 +645,6 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
if (change) {
wm_put(ice, WM_ADC_MUX, nval);
}
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -668,10 +658,9 @@ static int wm_bypass_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] =
(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -682,7 +671,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol,
unsigned short val, oval;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
val = oval = wm_get(ice, WM_OUT_MUX);
if (ucontrol->value.integer.value[0])
val |= 0x04;
@@ -692,7 +681,6 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol,
wm_put(ice, WM_OUT_MUX, val);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -706,10 +694,9 @@ static int wm_chswap_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
ucontrol->value.integer.value[0] =
(wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
@@ -720,7 +707,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol,
unsigned short val, oval;
int change = 0;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
oval = wm_get(ice, WM_DAC_CTRL1);
val = oval & 0x0f;
if (ucontrol->value.integer.value[0])
@@ -732,7 +719,6 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol,
wm_put_nocache(ice, WM_DAC_CTRL1, val);
change = 1;
}
- mutex_unlock(&ice->gpio_mutex);
return change;
}
@@ -864,14 +850,14 @@ static void wm_proc_regs_write(struct snd_info_entry *entry,
struct snd_ice1712 *ice = entry->private_data;
char line[64];
unsigned int reg, val;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
if (reg <= 0x17 && val <= 0xffff)
wm_put(ice, reg, val);
}
- mutex_unlock(&ice->gpio_mutex);
}
static void wm_proc_regs_read(struct snd_info_entry *entry,
@@ -880,12 +866,11 @@ static void wm_proc_regs_read(struct snd_info_entry *entry,
struct snd_ice1712 *ice = entry->private_data;
int reg, val;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
for (reg = 0; reg <= 0x17; reg++) {
val = wm_get(ice, reg);
snd_iprintf(buffer, "%02x = %04x\n", reg, val);
}
- mutex_unlock(&ice->gpio_mutex);
}
static void wm_proc_init(struct snd_ice1712 *ice)
@@ -994,7 +979,7 @@ static int prodigy_hifi_resume(struct snd_ice1712 *ice)
struct prodigy_hifi_spec *spec = ice->spec;
int i, ch;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
/* reinitialize WM8776 and re-apply old register values */
wm8776_init(ice);
@@ -1023,7 +1008,6 @@ static int prodigy_hifi_resume(struct snd_ice1712 *ice)
wm_put(ice, WM_DAC_MUTE, 0x00);
wm_put(ice, WM_DAC_CTRL1, 0x90);
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
#endif
@@ -1134,11 +1118,11 @@ static int prodigy_hd2_resume(struct snd_ice1712 *ice)
/* initialize ak4396 codec and restore previous mixer volumes */
struct prodigy_hifi_spec *spec = ice->spec;
int i;
- mutex_lock(&ice->gpio_mutex);
+
+ guard(mutex)(&ice->gpio_mutex);
ak4396_init(ice);
for (i = 0; i < 2; i++)
ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
- mutex_unlock(&ice->gpio_mutex);
return 0;
}
#endif
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c
index f61ee9f5c754..099601edf1d0 100644
--- a/sound/pci/ice1712/quartet.c
+++ b/sound/pci/ice1712/quartet.c
@@ -396,7 +396,7 @@ static void reg_write(struct snd_ice1712 *ice, unsigned int reg,
{
unsigned int tmp;
- mutex_lock(&ice->gpio_mutex);
+ guard(mutex)(&ice->gpio_mutex);
/* set direction of used GPIOs*/
/* all outputs */
tmp = 0x00ffff;
@@ -429,7 +429,6 @@ static void reg_write(struct snd_ice1712 *ice, unsigned int reg,
ice->gpio.set_mask(ice, 0xffffff);
/* outputs only 8-15 */
ice->gpio.set_dir(ice, 0x00ff00);
- mutex_unlock(&ice->gpio_mutex);
}
static unsigned int get_scr(struct snd_ice1712 *ice)
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index f613f0067d8c..57a79536e7ba 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -118,7 +118,7 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
unsigned char val;
int idx, id;
- mutex_lock(&spec->mute_mutex);
+ guard(mutex)(&spec->mute_mutex);
if (kcontrol->private_value) {
idx = STAC946X_MASTER_VOLUME;
@@ -133,7 +133,6 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
val = stac9460_2_get(ice, idx - 6);
ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
- mutex_unlock(&spec->mute_mutex);
return 0;
}
@@ -455,7 +454,7 @@ static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
return;
/* change detected, setting master clock, muting first */
/* due to possible conflicts with mute controls - mutexing */
- mutex_lock(&spec->mute_mutex);
+ guard(mutex)(&spec->mute_mutex);
/* we have to remember current mute status for each DAC */
changed = 0xFFFF;
stac9460_dac_mute_all(ice, 0, &changed);
@@ -466,7 +465,6 @@ static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
/* unmuting - only originally unmuted dacs -
* i.e. those changed when muting */
stac9460_dac_mute_all(ice, 1, &changed);
- mutex_unlock(&spec->mute_mutex);
}
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 9e6a5065ffbf..3b53c5e63c29 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -690,52 +690,51 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich
static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev)
{
unsigned long port = ichdev->reg_offset;
- unsigned long flags;
int status, civ, i, step;
int ack = 0;
if (!(ichdev->prepared || chip->in_measurement) || ichdev->suspended)
return;
- spin_lock_irqsave(&chip->reg_lock, flags);
- status = igetbyte(chip, port + ichdev->roff_sr);
- civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
- if (!(status & ICH_BCIS)) {
- step = 0;
- } else if (civ == ichdev->civ) {
- step = 1;
- ichdev->civ++;
- ichdev->civ &= ICH_REG_LVI_MASK;
- } else {
- step = civ - ichdev->civ;
- if (step < 0)
- step += ICH_REG_LVI_MASK + 1;
- ichdev->civ = civ;
- }
-
- ichdev->position += step * ichdev->fragsize1;
- if (! chip->in_measurement)
- ichdev->position %= ichdev->size;
- ichdev->lvi += step;
- ichdev->lvi &= ICH_REG_LVI_MASK;
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
- for (i = 0; i < step; i++) {
- ichdev->lvi_frag++;
- ichdev->lvi_frag %= ichdev->frags;
- ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ status = igetbyte(chip, port + ichdev->roff_sr);
+ civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
+ if (!(status & ICH_BCIS)) {
+ step = 0;
+ } else if (civ == ichdev->civ) {
+ step = 1;
+ ichdev->civ++;
+ ichdev->civ &= ICH_REG_LVI_MASK;
+ } else {
+ step = civ - ichdev->civ;
+ if (step < 0)
+ step += ICH_REG_LVI_MASK + 1;
+ ichdev->civ = civ;
+ }
+
+ ichdev->position += step * ichdev->fragsize1;
+ if (! chip->in_measurement)
+ ichdev->position %= ichdev->size;
+ ichdev->lvi += step;
+ ichdev->lvi &= ICH_REG_LVI_MASK;
+ iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
+ for (i = 0; i < step; i++) {
+ ichdev->lvi_frag++;
+ ichdev->lvi_frag %= ichdev->frags;
+ ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
#if 0
- dev_dbg(chip->card->dev,
- "new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
- ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
- ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
- inl(port + 4), inb(port + ICH_REG_OFF_CR));
+ dev_dbg(chip->card->dev,
+ "new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
+ ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
+ ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
+ inl(port + 4), inb(port + ICH_REG_OFF_CR));
#endif
- if (--ichdev->ack == 0) {
- ichdev->ack = ichdev->ack_reload;
- ack = 1;
+ if (--ichdev->ack == 0) {
+ ichdev->ack = ichdev->ack_reload;
+ ack = 1;
+ }
}
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (ack && ichdev->substream) {
snd_pcm_period_elapsed(ichdev->substream);
}
@@ -917,7 +916,7 @@ static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,
unsigned int cnt;
int dbl = runtime->rate > 48000;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
switch (chip->device_type) {
case DEVICE_ALI:
cnt = igetdword(chip, ICHREG(ALI_SCR));
@@ -963,7 +962,6 @@ static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,
iputdword(chip, ICHREG(GLOB_CNT), cnt);
break;
}
- spin_unlock_irq(&chip->reg_lock);
}
static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream)
@@ -993,7 +991,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
int civ, timeout = 10;
unsigned int position;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
do {
civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
@@ -1033,7 +1031,6 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
}
}
ichdev->last_pos = ptr;
- spin_unlock(&chip->reg_lock);
if (ptr >= ichdev->size)
return 0;
return bytes_to_frames(substream->runtime, ptr);
@@ -1235,12 +1232,12 @@ static int snd_intel8x0_ali_ac97spdifout_open(struct snd_pcm_substream *substrea
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
unsigned int val;
- spin_lock_irq(&chip->reg_lock);
- val = igetdword(chip, ICHREG(ALI_INTERFACECR));
- val |= ICH_ALI_IF_AC97SP;
- iputdword(chip, ICHREG(ALI_INTERFACECR), val);
- /* also needs to set ALI_SC_CODEC_SPDF correctly */
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ val = igetdword(chip, ICHREG(ALI_INTERFACECR));
+ val |= ICH_ALI_IF_AC97SP;
+ iputdword(chip, ICHREG(ALI_INTERFACECR), val);
+ /* also needs to set ALI_SC_CODEC_SPDF correctly */
+ }
return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
}
@@ -1251,11 +1248,10 @@ static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substre
unsigned int val;
chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
val = igetdword(chip, ICHREG(ALI_INTERFACECR));
val &= ~ICH_ALI_IF_AC97SP;
iputdword(chip, ICHREG(ALI_INTERFACECR), val);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -2662,53 +2658,53 @@ static void intel8x0_measure_ac97_clock(struct intel8x0 *chip)
}
snd_intel8x0_setup_periods(chip, ichdev);
port = ichdev->reg_offset;
- spin_lock_irq(&chip->reg_lock);
- chip->in_measurement = 1;
- /* trigger */
- if (chip->device_type != DEVICE_ALI)
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
- else {
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
- iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->in_measurement = 1;
+ /* trigger */
+ if (chip->device_type != DEVICE_ALI)
+ iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
+ else {
+ iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
+ iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
+ }
+ start_time = ktime_get();
}
- start_time = ktime_get();
- spin_unlock_irq(&chip->reg_lock);
msleep(50);
- spin_lock_irq(&chip->reg_lock);
- /* check the position */
- do {
- civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
- pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
- if (pos1 == 0) {
- udelay(10);
- continue;
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ /* check the position */
+ do {
+ civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
+ pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
+ if (pos1 == 0) {
+ udelay(10);
+ continue;
+ }
+ if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
+ pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
+ break;
+ } while (timeout--);
+ if (pos1 == 0) { /* oops, this value is not reliable */
+ pos = 0;
+ } else {
+ pos = ichdev->fragsize1;
+ pos -= pos1 << ichdev->pos_shift;
+ pos += ichdev->position;
}
- if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
- pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
- break;
- } while (timeout--);
- if (pos1 == 0) { /* oops, this value is not reliable */
- pos = 0;
- } else {
- pos = ichdev->fragsize1;
- pos -= pos1 << ichdev->pos_shift;
- pos += ichdev->position;
- }
- chip->in_measurement = 0;
- stop_time = ktime_get();
- /* stop */
- if (chip->device_type == DEVICE_ALI) {
- iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
- iputbyte(chip, port + ICH_REG_OFF_CR, 0);
- while (igetbyte(chip, port + ICH_REG_OFF_CR))
- ;
- } else {
- iputbyte(chip, port + ICH_REG_OFF_CR, 0);
- while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
- ;
+ chip->in_measurement = 0;
+ stop_time = ktime_get();
+ /* stop */
+ if (chip->device_type == DEVICE_ALI) {
+ iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
+ iputbyte(chip, port + ICH_REG_OFF_CR, 0);
+ while (igetbyte(chip, port + ICH_REG_OFF_CR))
+ ;
+ } else {
+ iputbyte(chip, port + ICH_REG_OFF_CR, 0);
+ while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
+ ;
+ }
+ iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
}
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
- spin_unlock_irq(&chip->reg_lock);
if (pos == 0) {
dev_err(chip->card->dev,
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e5988583abe..84e1b7ea34e2 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -471,16 +471,13 @@ static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
unsigned int status;
unsigned int i;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
status = igetdword(chip, chip->int_sta_reg);
- if (status == 0xffffffff) { /* we are not yet resumed */
- spin_unlock(&chip->reg_lock);
+ if (status == 0xffffffff) /* we are not yet resumed */
return IRQ_NONE;
- }
if ((status & chip->int_sta_mask) == 0) {
if (status)
iputdword(chip, chip->int_sta_reg, status);
- spin_unlock(&chip->reg_lock);
return IRQ_NONE;
}
@@ -492,7 +489,6 @@ static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
/* ack them */
iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 0a66d5cfc090..d16acf83668a 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -568,25 +568,19 @@ static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
{
- unsigned long flags;
- spin_lock_irqsave(&korg1212->lock, flags);
- snd_korg1212_SendStop(korg1212);
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ scoped_guard(spinlock_irqsave, &korg1212->lock) {
+ snd_korg1212_SendStop(korg1212);
+ }
wait_event_timeout(korg1212->wait, !korg1212->dsp_stop_processing, HZ);
}
static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
{
- unsigned long flags;
- int rc;
-
udelay(INTERCOMMAND_DELAY);
- spin_lock_irqsave(&korg1212->lock, flags);
+ guard(spinlock_irqsave)(&korg1212->lock);
korg1212->idleMonitorOn = 1;
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_MonitorOn, 0, 0, 0);
- spin_unlock_irqrestore(&korg1212->lock, flags);
- return rc;
+ return snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
+ K1212_MODE_MonitorOn, 0, 0, 0);
}
static void snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 *korg1212)
@@ -606,13 +600,12 @@ static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212)
{
K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n",
stateName[korg1212->cardState], korg1212->opencnt);
- mutex_lock(&korg1212->open_mutex);
+ guard(mutex)(&korg1212->open_mutex);
if (korg1212->opencnt++ == 0) {
snd_korg1212_TurnOffIdleMonitor(korg1212);
snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
}
- mutex_unlock(&korg1212->open_mutex);
return 1;
}
@@ -621,11 +614,9 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n",
stateName[korg1212->cardState], korg1212->opencnt);
- mutex_lock(&korg1212->open_mutex);
- if (--(korg1212->opencnt)) {
- mutex_unlock(&korg1212->open_mutex);
+ guard(mutex)(&korg1212->open_mutex);
+ if (--(korg1212->opencnt))
return 0;
- }
if (korg1212->cardState == K1212_STATE_SETUP) {
int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
@@ -633,10 +624,8 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
if (rc)
K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n",
rc, stateName[korg1212->cardState]);
- if (rc != K1212_CMDRET_Success) {
- mutex_unlock(&korg1212->open_mutex);
+ if (rc != K1212_CMDRET_Success)
return 0;
- }
} else if (korg1212->cardState > K1212_STATE_SETUP) {
snd_korg1212_SendStopAndWait(korg1212);
}
@@ -646,7 +635,6 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
}
- mutex_unlock(&korg1212->open_mutex);
return 0;
}
@@ -844,7 +832,6 @@ static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
u16 controlValue; // this keeps the current value to be written to
// the card's eeprom control register.
u16 count;
- unsigned long flags;
K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n",
stateName[korg1212->cardState]);
@@ -865,7 +852,7 @@ static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
} else
monModeSet = 0;
- spin_lock_irqsave(&korg1212->lock, flags);
+ guard(spinlock_irqsave)(&korg1212->lock);
// ----------------------------------------------------------------------------
// we are about to send new values to the card, so clear the new values queued
@@ -974,8 +961,6 @@ static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
rc, stateName[korg1212->cardState]);
}
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
return 1;
}
@@ -1067,7 +1052,7 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
if (!doorbellValue)
return IRQ_NONE;
- spin_lock(&korg1212->lock);
+ guard(spinlock)(&korg1212->lock);
writel(doorbellValue, korg1212->inDoorbellPtr);
@@ -1145,8 +1130,6 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
korg1212->inIRQ--;
- spin_unlock(&korg1212->lock);
-
return IRQ_HANDLED;
}
@@ -1332,7 +1315,6 @@ static void snd_korg1212_free_pcm(struct snd_pcm *pcm)
static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1344,15 +1326,13 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_korg1212_playback_info;
snd_pcm_set_runtime_buffer(substream, korg1212->dma_play);
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->playback_substream = substream;
- korg1212->playback_pid = current->pid;
- korg1212->periodsize = K1212_PERIODS;
- korg1212->channels = K1212_CHANNELS;
- korg1212->errorcnt = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ scoped_guard(spinlock_irqsave, &korg1212->lock) {
+ korg1212->playback_substream = substream;
+ korg1212->playback_pid = current->pid;
+ korg1212->periodsize = K1212_PERIODS;
+ korg1212->channels = K1212_CHANNELS;
+ korg1212->errorcnt = 0;
+ }
snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
kPlayBufferFrames);
@@ -1363,7 +1343,6 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1375,14 +1354,12 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_korg1212_capture_info;
snd_pcm_set_runtime_buffer(substream, korg1212->dma_rec);
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->capture_substream = substream;
- korg1212->capture_pid = current->pid;
- korg1212->periodsize = K1212_PERIODS;
- korg1212->channels = K1212_CHANNELS;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ scoped_guard(spinlock_irqsave, &korg1212->lock) {
+ korg1212->capture_substream = substream;
+ korg1212->capture_pid = current->pid;
+ korg1212->periodsize = K1212_PERIODS;
+ korg1212->channels = K1212_CHANNELS;
+ }
snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
kPlayBufferFrames);
@@ -1391,7 +1368,6 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n",
@@ -1399,13 +1375,11 @@ static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->playback_pid = -1;
- korg1212->playback_substream = NULL;
- korg1212->periodsize = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ scoped_guard(spinlock_irqsave, &korg1212->lock) {
+ korg1212->playback_pid = -1;
+ korg1212->playback_substream = NULL;
+ korg1212->periodsize = 0;
+ }
snd_korg1212_CloseCard(korg1212);
return 0;
@@ -1413,19 +1387,16 @@ static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
static int snd_korg1212_capture_close(struct snd_pcm_substream *substream)
{
- unsigned long flags;
struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n",
stateName[korg1212->cardState]);
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->capture_pid = -1;
- korg1212->capture_substream = NULL;
- korg1212->periodsize = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ scoped_guard(spinlock_irqsave, &korg1212->lock) {
+ korg1212->capture_pid = -1;
+ korg1212->capture_substream = NULL;
+ korg1212->periodsize = 0;
+ }
snd_korg1212_CloseCard(korg1212);
return 0;
@@ -1451,7 +1422,6 @@ static int snd_korg1212_ioctl(struct snd_pcm_substream *substream,
static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- unsigned long flags;
struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
int err;
pid_t this_pid;
@@ -1460,7 +1430,7 @@ static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n",
stateName[korg1212->cardState]);
- spin_lock_irqsave(&korg1212->lock, flags);
+ guard(spinlock_irqsave)(&korg1212->lock);
if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
this_pid = korg1212->playback_pid;
@@ -1478,26 +1448,20 @@ static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
*/
if ((int)params_rate(params) != korg1212->clkRate) {
- spin_unlock_irqrestore(&korg1212->lock, flags);
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
return -EBUSY;
}
- spin_unlock_irqrestore(&korg1212->lock, flags);
return 0;
}
err = snd_korg1212_SetRate(korg1212, params_rate(params));
- if (err < 0) {
- spin_unlock_irqrestore(&korg1212->lock, flags);
+ if (err < 0)
return err;
- }
korg1212->channels = params_channels(params);
korg1212->periodsize = K1212_PERIOD_BYTES;
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
return 0;
}
@@ -1517,15 +1481,13 @@ static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n",
stateName[korg1212->cardState]);
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
korg1212->dsp_stop_processing = 0;
rc = snd_korg1212_SetupForPlay(korg1212);
korg1212->currentBuffer = 0;
- spin_unlock_irq(&korg1212->lock);
-
return rc ? -EINVAL : 0;
}
@@ -1538,7 +1500,7 @@ static int snd_korg1212_trigger(struct snd_pcm_substream *substream,
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n",
stateName[korg1212->cardState], cmd);
- spin_lock(&korg1212->lock);
+ guard(spinlock)(&korg1212->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/*
@@ -1566,7 +1528,6 @@ static int snd_korg1212_trigger(struct snd_pcm_substream *substream,
rc = 1;
break;
}
- spin_unlock(&korg1212->lock);
return rc ? -EINVAL : 0;
}
@@ -1666,15 +1627,13 @@ static int snd_korg1212_control_phase_get(struct snd_kcontrol *kcontrol,
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
int i = kcontrol->private_value;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
u->value.integer.value[0] = korg1212->volumePhase[i];
if (i >= 8)
u->value.integer.value[1] = korg1212->volumePhase[i+1];
- spin_unlock_irq(&korg1212->lock);
-
return 0;
}
@@ -1685,7 +1644,7 @@ static int snd_korg1212_control_phase_put(struct snd_kcontrol *kcontrol,
int change = 0;
int i, val;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
i = kcontrol->private_value;
@@ -1711,8 +1670,6 @@ static int snd_korg1212_control_phase_put(struct snd_kcontrol *kcontrol,
}
}
- spin_unlock_irq(&korg1212->lock);
-
return change;
}
@@ -1732,7 +1689,7 @@ static int snd_korg1212_control_volume_get(struct snd_kcontrol *kcontrol,
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
i = kcontrol->private_value;
u->value.integer.value[0] = abs(korg1212->sharedBufferPtr->volumeData[i]);
@@ -1740,8 +1697,6 @@ static int snd_korg1212_control_volume_get(struct snd_kcontrol *kcontrol,
if (i >= 8)
u->value.integer.value[1] = abs(korg1212->sharedBufferPtr->volumeData[i+1]);
- spin_unlock_irq(&korg1212->lock);
-
return 0;
}
@@ -1753,7 +1708,7 @@ static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol,
int i;
int val;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
i = kcontrol->private_value;
@@ -1779,8 +1734,6 @@ static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol,
}
}
- spin_unlock_irq(&korg1212->lock);
-
return change;
}
@@ -1798,7 +1751,7 @@ static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol,
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
i = kcontrol->private_value;
u->value.enumerated.item[0] = korg1212->sharedBufferPtr->routeData[i];
@@ -1806,8 +1759,6 @@ static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol,
if (i >= 8)
u->value.enumerated.item[1] = korg1212->sharedBufferPtr->routeData[i+1];
- spin_unlock_irq(&korg1212->lock);
-
return 0;
}
@@ -1817,7 +1768,7 @@ static int snd_korg1212_control_route_put(struct snd_kcontrol *kcontrol,
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
int change = 0, i;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
i = kcontrol->private_value;
@@ -1837,8 +1788,6 @@ static int snd_korg1212_control_route_put(struct snd_kcontrol *kcontrol,
}
}
- spin_unlock_irq(&korg1212->lock);
-
return change;
}
@@ -1857,13 +1806,11 @@ static int snd_korg1212_control_get(struct snd_kcontrol *kcontrol,
{
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
u->value.integer.value[0] = korg1212->leftADCInSens;
u->value.integer.value[1] = korg1212->rightADCInSens;
- spin_unlock_irq(&korg1212->lock);
-
return 0;
}
@@ -1873,22 +1820,20 @@ static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol,
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
int change = 0;
- spin_lock_irq(&korg1212->lock);
-
- if (u->value.integer.value[0] >= k1212MinADCSens &&
- u->value.integer.value[0] <= k1212MaxADCSens &&
- u->value.integer.value[0] != korg1212->leftADCInSens) {
- korg1212->leftADCInSens = u->value.integer.value[0];
- change = 1;
- }
- if (u->value.integer.value[1] >= k1212MinADCSens &&
- u->value.integer.value[1] <= k1212MaxADCSens &&
- u->value.integer.value[1] != korg1212->rightADCInSens) {
- korg1212->rightADCInSens = u->value.integer.value[1];
- change = 1;
- }
-
- spin_unlock_irq(&korg1212->lock);
+ scoped_guard(spinlock_irq, &korg1212->lock) {
+ if (u->value.integer.value[0] >= k1212MinADCSens &&
+ u->value.integer.value[0] <= k1212MaxADCSens &&
+ u->value.integer.value[0] != korg1212->leftADCInSens) {
+ korg1212->leftADCInSens = u->value.integer.value[0];
+ change = 1;
+ }
+ if (u->value.integer.value[1] >= k1212MinADCSens &&
+ u->value.integer.value[1] <= k1212MaxADCSens &&
+ u->value.integer.value[1] != korg1212->rightADCInSens) {
+ korg1212->rightADCInSens = u->value.integer.value[1];
+ change = 1;
+ }
+ }
if (change)
snd_korg1212_WriteADCSensitivity(korg1212);
@@ -1907,11 +1852,9 @@ static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol,
{
struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
ucontrol->value.enumerated.item[0] = korg1212->clkSource;
-
- spin_unlock_irq(&korg1212->lock);
return 0;
}
@@ -1923,10 +1866,9 @@ static int snd_korg1212_control_sync_put(struct snd_kcontrol *kcontrol,
int change;
val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&korg1212->lock);
+ guard(spinlock_irq)(&korg1212->lock);
change = val != korg1212->clkSource;
snd_korg1212_SetClockSource(korg1212, val);
- spin_unlock_irq(&korg1212->lock);
return change;
}
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 8d927ecba165..34a3ba17deb4 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -74,7 +74,6 @@ static int corb_send_verb(struct lola *chip, unsigned int nid,
unsigned int verb, unsigned int data,
unsigned int extdata)
{
- unsigned long flags;
int ret = -EIO;
chip->last_cmd_nid = nid;
@@ -83,7 +82,7 @@ static int corb_send_verb(struct lola *chip, unsigned int nid,
chip->last_extdata = extdata;
data |= (nid << 20) | (verb << 8);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
unsigned int wp = chip->corb.wp + 1;
wp %= LOLA_CORB_ENTRIES;
@@ -95,7 +94,6 @@ static int corb_send_verb(struct lola *chip, unsigned int nid,
smp_wmb();
ret = 0;
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return ret;
}
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
index 32193fae978d..6c046ecd6e08 100644
--- a/sound/pci/lola/lola_pcm.c
+++ b/sound/pci/lola/lola_pcm.c
@@ -214,11 +214,9 @@ static int lola_pcm_open(struct snd_pcm_substream *substream)
struct lola_stream *str = lola_get_stream(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- mutex_lock(&chip->open_mutex);
- if (str->opened) {
- mutex_unlock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
+ if (str->opened)
return -EBUSY;
- }
str->substream = substream;
str->master = NULL;
str->opened = 1;
@@ -239,7 +237,6 @@ static int lola_pcm_open(struct snd_pcm_substream *substream)
chip->granularity);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
chip->granularity);
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -261,7 +258,7 @@ static int lola_pcm_close(struct snd_pcm_substream *substream)
struct lola *chip = snd_pcm_substream_chip(substream);
struct lola_stream *str = lola_get_stream(substream);
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
if (str->substream == substream) {
str->substream = NULL;
str->opened = 0;
@@ -270,7 +267,6 @@ static int lola_pcm_close(struct snd_pcm_substream *substream)
/* release sample rate */
chip->sample_rate = 0;
}
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -291,10 +287,9 @@ static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
struct lola_pcm *pcm = lola_get_pcm(substream);
struct lola_stream *str = lola_get_stream(substream);
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
lola_stream_reset(chip, str);
lola_cleanup_slave_streams(pcm, str);
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -457,18 +452,16 @@ static int lola_pcm_prepare(struct snd_pcm_substream *substream)
unsigned int bufsize, period_bytes, format_verb;
int i, err;
- mutex_lock(&chip->open_mutex);
- lola_stream_reset(chip, str);
- lola_cleanup_slave_streams(pcm, str);
- if (str->index + runtime->channels > pcm->num_streams) {
- mutex_unlock(&chip->open_mutex);
- return -EINVAL;
- }
- for (i = 1; i < runtime->channels; i++) {
- str[i].master = str;
- str[i].opened = 1;
+ scoped_guard(mutex, &chip->open_mutex) {
+ lola_stream_reset(chip, str);
+ lola_cleanup_slave_streams(pcm, str);
+ if (str->index + runtime->channels > pcm->num_streams)
+ return -EINVAL;
+ for (i = 1; i < runtime->channels; i++) {
+ str[i].master = str;
+ str[i].opened = 1;
+ }
}
- mutex_unlock(&chip->open_mutex);
bufsize = snd_pcm_lib_buffer_bytes(substream);
period_bytes = snd_pcm_lib_period_bytes(substream);
@@ -530,7 +523,7 @@ static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
*/
sync_streams = (start && snd_pcm_stream_linked(substream));
tstamp = lola_get_tstamp(chip, !sync_streams);
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
snd_pcm_group_for_each_entry(s, substream) {
if (s->pcm->card != substream->pcm->card)
continue;
@@ -543,7 +536,6 @@ static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
str->paused = !start;
snd_pcm_trigger_done(s, substream);
}
- spin_unlock(&chip->reg_lock);
return 0;
}
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 9f12c936bb1f..96df00db51d5 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -207,7 +207,7 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
int board_rate;
dev_dbg(chip->card->dev, "->lx_pcm_open\n");
- mutex_lock(&chip->setup_mutex);
+ guard(mutex)(&chip->setup_mutex);
/* copy the struct snd_pcm_hardware struct */
runtime->hw = lx_caps;
@@ -218,7 +218,7 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_PERIODS);
if (err < 0) {
dev_warn(chip->card->dev, "could not constrain periods\n");
- goto exit;
+ return err;
}
#endif
@@ -229,7 +229,7 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
if (err < 0) {
dev_warn(chip->card->dev, "could not constrain periods\n");
- goto exit;
+ return err;
}
/* constrain period size */
@@ -240,7 +240,7 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
if (err < 0) {
dev_warn(chip->card->dev,
"could not constrain period size\n");
- goto exit;
+ return err;
}
snd_pcm_hw_constraint_step(runtime, 0,
@@ -249,10 +249,8 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
err = 0;
-exit:
runtime->private_data = chip;
- mutex_unlock(&chip->setup_mutex);
dev_dbg(chip->card->dev, "<-lx_pcm_open, %d\n", err);
return err;
}
@@ -275,9 +273,8 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n");
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
pos = lx_stream->frame_pos * substream->runtime->period_size;
- mutex_unlock(&chip->lock);
dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos);
return pos;
@@ -291,21 +288,21 @@ static int lx_pcm_prepare(struct snd_pcm_substream *substream)
dev_dbg(chip->card->dev, "->lx_pcm_prepare\n");
- mutex_lock(&chip->setup_mutex);
+ guard(mutex)(&chip->setup_mutex);
if (chip->hardware_running[is_capture]) {
err = lx_hardware_stop(chip, substream);
if (err < 0) {
dev_err(chip->card->dev, "failed to stop hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
err = lx_hardware_close(chip, substream);
if (err < 0) {
dev_err(chip->card->dev, "failed to close hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
}
@@ -314,14 +311,14 @@ static int lx_pcm_prepare(struct snd_pcm_substream *substream)
if (err < 0) {
dev_err(chip->card->dev, "failed to open hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
err = lx_hardware_start(chip, substream);
if (err < 0) {
dev_err(chip->card->dev, "failed to start hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
chip->hardware_running[is_capture] = 1;
@@ -331,8 +328,6 @@ static int lx_pcm_prepare(struct snd_pcm_substream *substream)
chip->board_sample_rate = substream->runtime->rate;
}
-exit:
- mutex_unlock(&chip->setup_mutex);
return err;
}
@@ -343,14 +338,13 @@ static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
dev_dbg(chip->card->dev, "->lx_pcm_hw_params\n");
- mutex_lock(&chip->setup_mutex);
+ guard(mutex)(&chip->setup_mutex);
if (is_capture)
chip->capture_stream.stream = substream;
else
chip->playback_stream.stream = substream;
- mutex_unlock(&chip->setup_mutex);
return 0;
}
@@ -373,21 +367,21 @@ static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
dev_dbg(chip->card->dev, "->lx_pcm_hw_free\n");
- mutex_lock(&chip->setup_mutex);
+ guard(mutex)(&chip->setup_mutex);
if (chip->hardware_running[is_capture]) {
err = lx_hardware_stop(chip, substream);
if (err < 0) {
dev_err(chip->card->dev, "failed to stop hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
err = lx_hardware_close(chip, substream);
if (err < 0) {
dev_err(chip->card->dev, "failed to close hardware. "
"Error code %d\n", err);
- goto exit;
+ return err;
}
chip->hardware_running[is_capture] = 0;
@@ -398,9 +392,7 @@ static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
else
chip->playback_stream.stream = NULL;
-exit:
- mutex_unlock(&chip->setup_mutex);
- return err;
+ return 0;
}
static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
@@ -486,9 +478,7 @@ static void lx_trigger_dispatch_stream(struct lx6464es *chip,
static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
struct lx_stream *lx_stream, int cmd)
{
- int err = 0;
-
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
@@ -499,16 +489,13 @@ static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
break;
default:
- err = -EINVAL;
- goto exit;
+ return -EINVAL;
}
lx_trigger_dispatch_stream(chip, &chip->capture_stream);
lx_trigger_dispatch_stream(chip, &chip->playback_stream);
-exit:
- mutex_unlock(&chip->lock);
- return err;
+ return 0;
}
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 9d95ecb299ae..6f0843cfb3be 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -316,26 +316,25 @@ polling_successful:
/* low-level dsp access */
int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
{
- u16 ret;
+ int ret;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
ret = lx_message_send_atomic(chip, &chip->rmh);
*rdsp_version = chip->rmh.stat[1];
- mutex_unlock(&chip->msg_lock);
return ret;
}
int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
{
- u16 ret = 0;
u32 freq_raw = 0;
u32 freq = 0;
u32 frequency = 0;
+ int ret;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
ret = lx_message_send_atomic(chip, &chip->rmh);
@@ -353,8 +352,6 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
frequency = 48000;
}
- mutex_unlock(&chip->msg_lock);
-
*rfreq = frequency * chip->freq_ratio;
return ret;
@@ -381,23 +378,19 @@ int lx_dsp_get_mac(struct lx6464es *chip)
int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran)
{
- int ret;
-
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY);
chip->rmh.cmd[0] |= gran;
- ret = lx_message_send_atomic(chip, &chip->rmh);
- mutex_unlock(&chip->msg_lock);
- return ret;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
{
int ret;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_04_GET_EVENT);
chip->rmh.stat_len = 9; /* we don't necessarily need the full length */
@@ -407,7 +400,6 @@ int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
if (!ret)
memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32));
- mutex_unlock(&chip->msg_lock);
return ret;
}
@@ -423,14 +415,13 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE);
chip->rmh.cmd[0] |= pipe_cmd;
chip->rmh.cmd[0] |= channels;
err = lx_message_send_atomic(chip, &chip->rmh);
- mutex_unlock(&chip->msg_lock);
if (err != 0)
dev_err(chip->card->dev, "could not allocate pipe\n");
@@ -440,18 +431,14 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE);
chip->rmh.cmd[0] |= pipe_cmd;
- err = lx_message_send_atomic(chip, &chip->rmh);
- mutex_unlock(&chip->msg_lock);
-
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
@@ -468,7 +455,7 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
*r_needed = 0;
*r_freed = 0;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -501,41 +488,32 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
}
}
- mutex_unlock(&chip->msg_lock);
return err;
}
int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_09_STOP_PIPE);
chip->rmh.cmd[0] |= pipe_cmd;
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- mutex_unlock(&chip->msg_lock);
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE);
chip->rmh.cmd[0] |= pipe_cmd;
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- mutex_unlock(&chip->msg_lock);
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
@@ -572,7 +550,7 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -589,7 +567,6 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
+ chip->rmh.stat[1]; /* lo part */
}
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -598,7 +575,7 @@ int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -610,7 +587,6 @@ int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
else
*rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F;
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -651,29 +627,24 @@ int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture)
int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
int is_capture, enum stream_state_t state)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE);
chip->rmh.cmd[0] |= pipe_cmd;
chip->rmh.cmd[0] |= state;
- err = lx_message_send_atomic(chip, &chip->rmh);
- mutex_unlock(&chip->msg_lock);
-
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
u32 pipe, int is_capture)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
u32 channels = runtime->channels;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -688,10 +659,7 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
chip->rmh.cmd[0] |= channels-1;
- err = lx_message_send_atomic(chip, &chip->rmh);
- mutex_unlock(&chip->msg_lock);
-
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
@@ -700,7 +668,7 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -709,7 +677,6 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
*rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE;
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -719,7 +686,7 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -730,7 +697,6 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
<< 32) /* hi part */
+ chip->rmh.stat[1]; /* lo part */
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -742,7 +708,7 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -763,7 +729,7 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
if (err == 0) {
*r_buffer_index = chip->rmh.stat[0];
- goto done;
+ return err;
}
if (err == EB_RBUFFERS_TABLE_OVERFLOW)
@@ -778,8 +744,6 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
dev_err(chip->card->dev,
"lx_buffer_give EB_CMD_REFUSED\n");
- done:
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -789,7 +753,7 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
chip->rmh.cmd[0] |= pipe_cmd;
@@ -801,26 +765,21 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
if (err == 0)
*r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE;
- mutex_unlock(&chip->msg_lock);
return err;
}
int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
u32 buffer_index)
{
- int err;
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
chip->rmh.cmd[0] |= pipe_cmd;
chip->rmh.cmd[0] |= buffer_index;
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- mutex_unlock(&chip->msg_lock);
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
@@ -831,11 +790,10 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
* */
int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
{
- int err;
/* bit set to 1: channel muted */
u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0D_SET_MUTE);
chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0);
@@ -847,10 +805,7 @@ int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
"mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
chip->rmh.cmd[2]);
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- mutex_unlock(&chip->msg_lock);
- return err;
+ return lx_message_send_atomic(chip, &chip->rmh);
}
static const u32 peak_map[] = {
@@ -878,7 +833,7 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
int err = 0;
int i;
- mutex_lock(&chip->msg_lock);
+ guard(mutex)(&chip->msg_lock);
for (i = 0; i < channels; i += 4) {
u32 s0, s1, s2, s3;
@@ -903,7 +858,6 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
r_levels += 4;
}
- mutex_unlock(&chip->msg_lock);
return err;
}
@@ -1033,7 +987,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
dev_dbg(chip->card->dev, "->lx_interrupt_request_new_buffer\n");
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
dev_dbg(chip->card->dev,
@@ -1047,7 +1001,6 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
buffer_index, (unsigned long)buf, period_bytes);
lx_stream->frame_pos = next_pos;
- mutex_unlock(&chip->lock);
return err;
}
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index e092097599ff..bddf47a1f263 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1096,7 +1096,7 @@ snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
if (snd_BUG_ON(!s))
return -ENXIO;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -1117,7 +1117,6 @@ snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
}
break;
}
- spin_unlock(&chip->reg_lock);
return err;
}
@@ -1412,7 +1411,7 @@ snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
runtime->rate < 8000)
return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_m3_pcm_setup1(chip, s, subs);
@@ -1423,8 +1422,6 @@ snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
snd_m3_pcm_setup2(chip, s, runtime);
- spin_unlock_irq(&chip->reg_lock);
-
return 0;
}
@@ -1466,9 +1463,8 @@ snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
if (snd_BUG_ON(!s))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
ptr = snd_m3_get_pointer(chip, s, subs);
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(subs->runtime, ptr);
}
@@ -1629,13 +1625,12 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
if (ctl & DSP2HOST_REQ_TIMER) {
outb(DSP2HOST_REQ_TIMER, chip->iobase + ASSP_HOST_INT_STATUS);
/* update adc/dac info if it was a timer int */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
for (i = 0; i < chip->num_substreams; i++) {
struct m3_dma *s = &chip->substreams[i];
if (s->running)
snd_m3_update_ptr(chip, s);
}
- spin_unlock(&chip->reg_lock);
}
}
}
@@ -1707,18 +1702,16 @@ snd_m3_substream_open(struct snd_m3 *chip, struct snd_pcm_substream *subs)
int i;
struct m3_dma *s;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < chip->num_substreams; i++) {
s = &chip->substreams[i];
if (! s->opened)
goto __found;
}
- spin_unlock_irq(&chip->reg_lock);
return -ENOMEM;
__found:
s->opened = 1;
s->running = 0;
- spin_unlock_irq(&chip->reg_lock);
subs->runtime->private_data = s;
s->substream = subs;
@@ -1742,7 +1735,7 @@ snd_m3_substream_close(struct snd_m3 *chip, struct snd_pcm_substream *subs)
if (s == NULL)
return; /* not opened properly */
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
if (s->substream && s->running)
snd_m3_pcm_stop(chip, s, s->substream); /* does this happen? */
if (s->in_lists) {
@@ -1753,7 +1746,6 @@ snd_m3_substream_close(struct snd_m3 *chip, struct snd_pcm_substream *subs)
}
s->running = 0;
s->opened = 0;
- spin_unlock_irq(&chip->reg_lock);
}
static int
@@ -2339,14 +2331,13 @@ static void snd_m3_free(struct snd_card *card)
cancel_work_sync(&chip->hwvol_work);
if (chip->substreams) {
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < chip->num_substreams; i++) {
s = &chip->substreams[i];
/* check surviving pcms; this should not happen though.. */
if (s->substream && s->running)
snd_m3_pcm_stop(chip, s, s->substream);
}
- spin_unlock_irq(&chip->reg_lock);
}
if (chip->iobase) {
outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index cdc0ba5dd1ad..c6319e75beab 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -603,7 +603,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
/* set up format for the stream */
format = params_format(hw);
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
/* update the stream levels */
if( stream->pcm_number <= MIXART_PCM_DIGITAL ) {
@@ -618,10 +618,8 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
/* set the format to the board */
err = mixart_set_format(stream, format);
- if(err < 0) {
- mutex_unlock(&mgr->setup_mutex);
+ if (err < 0)
return err;
- }
if (subs->runtime->buffer_changed) {
struct mixart_bufferinfo *bufferinfo;
@@ -641,7 +639,6 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
bufferinfo[i].available_length,
subs->number);
}
- mutex_unlock(&mgr->setup_mutex);
return 0;
}
@@ -712,7 +709,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
int err = 0;
int pcm_number;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
if ( pcm == chip->pcm ) {
pcm_number = MIXART_PCM_ANALOG;
@@ -734,25 +731,21 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
dev_err(chip->card->dev,
"snd_mixart_playback_open C%d/P%d/Sub%d in use\n",
chip->chip_idx, pcm_number, subs->number);
- err = -EBUSY;
- goto _exit_open;
+ return -EBUSY;
}
/* get pipe pointer (out pipe) */
pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 0, 0);
- if (pipe == NULL) {
- err = -EINVAL;
- goto _exit_open;
- }
+ if (pipe == NULL)
+ return -EINVAL;
/* start the pipe if necessary */
err = mixart_set_pipe_state(chip->mgr, pipe, 1);
if( err < 0 ) {
dev_err(chip->card->dev, "error starting pipe!\n");
snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
- err = -EINVAL;
- goto _exit_open;
+ return -EINVAL;
}
stream->pipe = pipe;
@@ -773,10 +766,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
}
}
- _exit_open:
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
+ return 0;
}
@@ -791,7 +781,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
int err = 0;
int pcm_number;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
if ( pcm == chip->pcm ) {
pcm_number = MIXART_PCM_ANALOG;
@@ -815,25 +805,21 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
dev_err(chip->card->dev,
"snd_mixart_capture_open C%d/P%d/Sub%d in use\n",
chip->chip_idx, pcm_number, subs->number);
- err = -EBUSY;
- goto _exit_open;
+ return -EBUSY;
}
/* get pipe pointer (in pipe) */
pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 1, 0);
- if (pipe == NULL) {
- err = -EINVAL;
- goto _exit_open;
- }
+ if (pipe == NULL)
+ return -EINVAL;
/* start the pipe if necessary */
err = mixart_set_pipe_state(chip->mgr, pipe, 1);
if( err < 0 ) {
dev_err(chip->card->dev, "error starting pipe!\n");
snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
- err = -EINVAL;
- goto _exit_open;
+ return -EINVAL;
}
stream->pipe = pipe;
@@ -854,10 +840,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
}
}
- _exit_open:
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
+ return 0;
}
@@ -868,7 +851,7 @@ static int snd_mixart_close(struct snd_pcm_substream *subs)
struct mixart_mgr *mgr = chip->mgr;
struct mixart_stream *stream = subs->runtime->private_data;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
dev_dbg(chip->card->dev, "snd_mixart_close C%d/P%d/Sub%d\n",
chip->chip_idx, stream->pcm_number, subs->number);
@@ -890,7 +873,6 @@ static int snd_mixart_close(struct snd_pcm_substream *subs)
stream->status = MIXART_STREAM_STATUS_FREE;
stream->substream = NULL;
- mutex_unlock(&mgr->setup_mutex);
return 0;
}
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index a047ed0f84e9..f7396ee4f6d7 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -226,17 +226,16 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int
init_waitqueue_entry(&wait, current);
- mutex_lock(&mgr->msg_lock);
- /* send the message */
- err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */
- if (err) {
- mutex_unlock(&mgr->msg_lock);
- return err;
+ scoped_guard(mutex, &mgr->msg_lock) {
+ /* send the message */
+ err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */
+ if (err)
+ return err;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&mgr->msg_sleep, &wait);
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&mgr->msg_sleep, &wait);
- mutex_unlock(&mgr->msg_lock);
timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
remove_wait_queue(&mgr->msg_sleep, &wait);
@@ -253,9 +252,9 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int
resp.data = resp_data;
resp.size = max_resp_size;
- mutex_lock(&mgr->msg_lock);
- err = get_msg(mgr, &resp, msg_frame);
- mutex_unlock(&mgr->msg_lock);
+ scoped_guard(mutex, &mgr->msg_lock) {
+ err = get_msg(mgr, &resp, msg_frame);
+ }
if( request->message_id != resp.message_id )
dev_err(&mgr->pci->dev, "RESPONSE ERROR!\n");
@@ -280,17 +279,16 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
init_waitqueue_entry(&wait, current);
- mutex_lock(&mgr->msg_lock);
- /* send the message */
- err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, &notif_event); /* send and mark the notification event pending */
- if(err) {
- mutex_unlock(&mgr->msg_lock);
- return err;
+ scoped_guard(mutex, &mgr->msg_lock) {
+ /* send the message */
+ err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, &notif_event); /* send and mark the notification event pending */
+ if (err)
+ return err;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&mgr->msg_sleep, &wait);
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&mgr->msg_sleep, &wait);
- mutex_unlock(&mgr->msg_lock);
timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
remove_wait_queue(&mgr->msg_sleep, &wait);
@@ -311,9 +309,8 @@ int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *requ
int err;
/* just send the message (do not mark it as a pending one) */
- mutex_lock(&mgr->msg_lock);
+ guard(mutex)(&mgr->msg_lock);
err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 0, &message_frame);
- mutex_unlock(&mgr->msg_lock);
/* the answer will be handled by snd_struct mixart_msgasklet() */
atomic_inc(&mgr->msg_processed);
@@ -420,7 +417,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
struct mixart_msg resp;
u32 msg;
- mutex_lock(&mgr->lock);
+ guard(mutex)(&mgr->lock);
/* process interrupt */
while (retrieve_msg_frame(mgr, &msg)) {
@@ -530,19 +527,19 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
fallthrough;
case MSG_TYPE_ANSWER:
/* answer or notification to a message we are waiting for*/
- mutex_lock(&mgr->msg_lock);
- if( (msg & ~MSG_TYPE_MASK) == mgr->pending_event ) {
- wake_up(&mgr->msg_sleep);
- mgr->pending_event = 0;
- }
- /* answer to a message we did't want to wait for */
- else {
- mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
- mgr->msg_fifo_writeptr++;
- mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
- snd_mixart_process_msg(mgr);
+ scoped_guard(mutex, &mgr->msg_lock) {
+ if ((msg & ~MSG_TYPE_MASK) == mgr->pending_event) {
+ wake_up(&mgr->msg_sleep);
+ mgr->pending_event = 0;
+ }
+ /* answer to a message we did't want to wait for */
+ else {
+ mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
+ mgr->msg_fifo_writeptr++;
+ mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
+ snd_mixart_process_msg(mgr);
+ }
}
- mutex_unlock(&mgr->msg_lock);
break;
case MSG_TYPE_REQUEST:
default:
@@ -556,8 +553,6 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
/* allow interrupt again */
writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
- mutex_unlock(&mgr->lock);
-
return IRQ_HANDLED;
}
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 2727f3345795..f4081d323340 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -344,7 +344,8 @@ static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if(kcontrol->private_value == 0) { /* playback */
ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
@@ -352,7 +353,6 @@ static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -362,7 +362,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
int changed = 0;
int is_capture, i;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
is_capture = (kcontrol->private_value != 0);
for (i = 0; i < 2; i++) {
int new_volume = ucontrol->value.integer.value[i];
@@ -385,7 +385,6 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
if (changed)
mixart_update_analog_audio_level(chip, is_capture);
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -409,10 +408,9 @@ static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -420,7 +418,8 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int i, changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 2; i++) {
if (chip->analog_playback_active[i] !=
ucontrol->value.integer.value[i]) {
@@ -431,7 +430,6 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
}
if (changed) /* update playback levels */
mixart_update_analog_audio_level(chip, 0);
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -825,7 +823,8 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
int *stored_volume;
int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if(is_capture) {
if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
@@ -836,7 +835,6 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
}
ucontrol->value.integer.value[0] = stored_volume[0];
ucontrol->value.integer.value[1] = stored_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -849,7 +847,8 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
int* stored_volume;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (is_capture) {
if (is_aes) /* AES capture */
stored_volume = chip->digital_capture_volume[1];
@@ -878,7 +877,6 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
else
mixart_update_playback_stream_level(chip, is_aes, idx);
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -903,12 +901,12 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */
idx += MIXART_PLAYBACK_STREAMS;
ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -920,7 +918,8 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
int i, j;
snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
j = idx;
if (is_aes)
j += MIXART_PLAYBACK_STREAMS;
@@ -934,7 +933,6 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
}
if (changed)
mixart_update_playback_stream_level(chip, is_aes, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -985,10 +983,10 @@ static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -997,7 +995,8 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 2; i++) {
if (chip->monitoring_volume[i] !=
ucontrol->value.integer.value[i]) {
@@ -1007,7 +1006,6 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
changed = 1;
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -1029,10 +1027,10 @@ static const struct snd_kcontrol_new mixart_control_monitor_vol = {
static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->monitoring_active[0];
ucontrol->value.integer.value[1] = chip->monitoring_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -1041,7 +1039,8 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 2; i++) {
if (chip->monitoring_active[i] !=
ucontrol->value.integer.value[i]) {
@@ -1074,7 +1073,6 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return (changed != 0);
}
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 39464d171f6b..da74b923bc88 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -446,27 +446,25 @@ snd_nm256_set_format(struct nm256 *chip, struct nm256_stream *s,
/* acquire interrupt */
static int snd_nm256_acquire_irq(struct nm256 *chip)
{
- mutex_lock(&chip->irq_mutex);
+ guard(mutex)(&chip->irq_mutex);
if (chip->irq < 0) {
if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
dev_err(chip->card->dev,
"unable to grab IRQ %d\n", chip->pci->irq);
- mutex_unlock(&chip->irq_mutex);
return -EBUSY;
}
chip->irq = chip->pci->irq;
chip->card->sync_irq = chip->irq;
}
chip->irq_acks++;
- mutex_unlock(&chip->irq_mutex);
return 0;
}
/* release interrupt */
static void snd_nm256_release_irq(struct nm256 *chip)
{
- mutex_lock(&chip->irq_mutex);
+ guard(mutex)(&chip->irq_mutex);
if (chip->irq_acks > 0)
chip->irq_acks--;
if (chip->irq_acks == 0 && chip->irq >= 0) {
@@ -474,7 +472,6 @@ static void snd_nm256_release_irq(struct nm256 *chip)
chip->irq = -1;
chip->card->sync_irq = -1;
}
- mutex_unlock(&chip->irq_mutex);
}
/*
@@ -547,12 +544,11 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct nm256 *chip = snd_pcm_substream_chip(substream);
struct nm256_stream *s = substream->runtime->private_data;
- int err = 0;
if (snd_BUG_ON(!s))
return -ENXIO;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
s->suspended = 0;
@@ -573,11 +569,9 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
}
break;
default:
- err = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return err;
+ return 0;
}
static int
@@ -585,12 +579,11 @@ snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct nm256 *chip = snd_pcm_substream_chip(substream);
struct nm256_stream *s = substream->runtime->private_data;
- int err = 0;
if (snd_BUG_ON(!s))
return -ENXIO;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -607,11 +600,9 @@ snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
}
break;
default:
- err = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&chip->reg_lock);
- return err;
+ return 0;
}
@@ -631,10 +622,9 @@ static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream)
s->periods = substream->runtime->periods;
s->cur_period = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
s->running = 0;
snd_nm256_set_format(chip, s, substream);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -999,7 +989,7 @@ snd_nm256_interrupt(int irq, void *dev_id)
/* Rather boring; check for individual interrupts and process them. */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (status & NM_PLAYBACK_INT) {
status &= ~NM_PLAYBACK_INT;
NM_ACK_INT(chip, NM_PLAYBACK_INT);
@@ -1038,7 +1028,6 @@ snd_nm256_interrupt(int irq, void *dev_id)
NM_ACK_INT(chip, status);
}
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
@@ -1065,7 +1054,7 @@ snd_nm256_interrupt_zx(int irq, void *dev_id)
/* Rather boring; check for individual interrupts and process them. */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (status & NM2_PLAYBACK_INT) {
status &= ~NM2_PLAYBACK_INT;
NM2_ACK_INT(chip, NM2_PLAYBACK_INT);
@@ -1103,7 +1092,6 @@ snd_nm256_interrupt_zx(int irq, void *dev_id)
NM2_ACK_INT(chip, status);
}
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
@@ -1392,9 +1380,8 @@ static int nm256_resume(struct device *dev)
for (i = 0; i < 2; i++) {
struct nm256_stream *s = &chip->streams[i];
if (s->substream && s->suspended) {
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_nm256_set_format(chip, s, s->substream);
- spin_unlock_irq(&chip->reg_lock);
}
}
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index ff7439634d76..e6f869cf8ca2 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -450,7 +450,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
int changed;
u8 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->ak4396_regs[0][AK4396_CONTROL_2];
if (value->value.enumerated.item[0])
reg |= AK4396_SLOW;
@@ -461,7 +461,6 @@ static int rolloff_put(struct snd_kcontrol *ctl,
for (i = 0; i < data->dacs; ++i)
ak4396_write(chip, i, AK4396_CONTROL_2, reg);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -499,14 +498,13 @@ static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
unsigned int reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->wm8785_regs[WM8785_R2] & ~(WM8785_HPFR | WM8785_HPFL);
if (value->value.enumerated.item[0])
reg |= WM8785_HPFR | WM8785_HPFL;
changed = reg != data->wm8785_regs[WM8785_R2];
if (changed)
wm8785_write(chip, WM8785_R2, reg);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -563,7 +561,7 @@ static int meridian_dig_source_put(struct snd_kcontrol *ctl,
u16 old_reg, new_reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK;
if (value->value.enumerated.item[0] == 0)
@@ -573,7 +571,6 @@ static int meridian_dig_source_put(struct snd_kcontrol *ctl,
changed = new_reg != old_reg;
if (changed)
oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -584,7 +581,7 @@ static int claro_dig_source_put(struct snd_kcontrol *ctl,
u16 old_reg, new_reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
if (value->value.enumerated.item[0])
@@ -592,7 +589,6 @@ static int claro_dig_source_put(struct snd_kcontrol *ctl,
changed = new_reg != old_reg;
if (changed)
oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
- mutex_unlock(&chip->mutex);
return changed;
}
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9c7270e4c35e..6b096d654f9f 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -59,36 +59,34 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
if (!status)
return IRQ_NONE;
- spin_lock(&chip->reg_lock);
-
- clear = status & (OXYGEN_CHANNEL_A |
- OXYGEN_CHANNEL_B |
- OXYGEN_CHANNEL_C |
- OXYGEN_CHANNEL_SPDIF |
- OXYGEN_CHANNEL_MULTICH |
- OXYGEN_CHANNEL_AC97 |
- OXYGEN_INT_SPDIF_IN_DETECT |
- OXYGEN_INT_GPIO |
- OXYGEN_INT_AC97);
- if (clear) {
- if (clear & OXYGEN_INT_SPDIF_IN_DETECT)
- chip->interrupt_mask &= ~OXYGEN_INT_SPDIF_IN_DETECT;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask & ~clear);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask);
- }
-
- elapsed_streams = status & chip->pcm_running;
+ scoped_guard(spinlock, &chip->reg_lock) {
+ clear = status & (OXYGEN_CHANNEL_A |
+ OXYGEN_CHANNEL_B |
+ OXYGEN_CHANNEL_C |
+ OXYGEN_CHANNEL_SPDIF |
+ OXYGEN_CHANNEL_MULTICH |
+ OXYGEN_CHANNEL_AC97 |
+ OXYGEN_INT_SPDIF_IN_DETECT |
+ OXYGEN_INT_GPIO |
+ OXYGEN_INT_AC97);
+ if (clear) {
+ if (clear & OXYGEN_INT_SPDIF_IN_DETECT)
+ chip->interrupt_mask &= ~OXYGEN_INT_SPDIF_IN_DETECT;
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
+ chip->interrupt_mask & ~clear);
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
+ chip->interrupt_mask);
+ }
- spin_unlock(&chip->reg_lock);
+ elapsed_streams = status & chip->pcm_running;
+ }
for (i = 0; i < PCM_COUNT; ++i)
if ((elapsed_streams & (1 << i)) && chip->streams[i])
snd_pcm_period_elapsed(chip->streams[i]);
if (status & OXYGEN_INT_SPDIF_IN_DETECT) {
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
i = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
if (i & (OXYGEN_SPDIF_SENSE_INT | OXYGEN_SPDIF_LOCK_INT |
OXYGEN_SPDIF_RATE_INT)) {
@@ -96,7 +94,6 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, i);
schedule_work(&chip->spdif_input_bits_work);
}
- spin_unlock(&chip->reg_lock);
}
if (status & OXYGEN_INT_GPIO)
@@ -127,45 +124,45 @@ static void oxygen_spdif_input_bits_changed(struct work_struct *work)
* changes.
*/
msleep(1);
- spin_lock_irq(&chip->reg_lock);
- reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
- OXYGEN_SPDIF_LOCK_STATUS))
- == OXYGEN_SPDIF_SENSE_STATUS) {
- /*
- * If we detect activity on the SPDIF input but cannot lock to
- * a signal, the clock bit is likely to be wrong.
- */
- reg ^= OXYGEN_SPDIF_IN_CLOCK_MASK;
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
- spin_unlock_irq(&chip->reg_lock);
- msleep(1);
- spin_lock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
OXYGEN_SPDIF_LOCK_STATUS))
== OXYGEN_SPDIF_SENSE_STATUS) {
- /* nothing detected with either clock; give up */
- if ((reg & OXYGEN_SPDIF_IN_CLOCK_MASK)
- == OXYGEN_SPDIF_IN_CLOCK_192) {
- /*
- * Reset clock to <= 96 kHz because this is
- * more likely to be received next time.
- */
- reg &= ~OXYGEN_SPDIF_IN_CLOCK_MASK;
- reg |= OXYGEN_SPDIF_IN_CLOCK_96;
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
+ /*
+ * If we detect activity on the SPDIF input but cannot lock to
+ * a signal, the clock bit is likely to be wrong.
+ */
+ reg ^= OXYGEN_SPDIF_IN_CLOCK_MASK;
+ oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
+ spin_unlock_irq(&chip->reg_lock);
+ msleep(1);
+ spin_lock_irq(&chip->reg_lock);
+ reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
+ if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
+ OXYGEN_SPDIF_LOCK_STATUS))
+ == OXYGEN_SPDIF_SENSE_STATUS) {
+ /* nothing detected with either clock; give up */
+ if ((reg & OXYGEN_SPDIF_IN_CLOCK_MASK)
+ == OXYGEN_SPDIF_IN_CLOCK_192) {
+ /*
+ * Reset clock to <= 96 kHz because this is
+ * more likely to be received next time.
+ */
+ reg &= ~OXYGEN_SPDIF_IN_CLOCK_MASK;
+ reg |= OXYGEN_SPDIF_IN_CLOCK_96;
+ oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
+ }
}
}
}
- spin_unlock_irq(&chip->reg_lock);
if (chip->controls[CONTROL_SPDIF_INPUT_BITS]) {
- spin_lock_irq(&chip->reg_lock);
- chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
+ chip->interrupt_mask);
+ }
/*
* We don't actually know that any channel status bits have
@@ -557,12 +554,11 @@ static void oxygen_init(struct oxygen *chip)
static void oxygen_shutdown(struct oxygen *chip)
{
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->interrupt_mask = 0;
chip->pcm_running = 0;
oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- spin_unlock_irq(&chip->reg_lock);
}
static void oxygen_card_free(struct snd_card *card)
@@ -686,13 +682,13 @@ static int __oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
oxygen_proc_init(chip);
- spin_lock_irq(&chip->reg_lock);
- if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
- chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
- if (chip->has_ac97_0 | chip->has_ac97_1)
- chip->interrupt_mask |= OXYGEN_INT_AC97;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
+ chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
+ if (chip->has_ac97_0 | chip->has_ac97_1)
+ chip->interrupt_mask |= OXYGEN_INT_AC97;
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
+ }
err = snd_card_register(card);
if (err < 0)
@@ -724,12 +720,12 @@ static int oxygen_pci_suspend(struct device *dev)
if (chip->model.suspend)
chip->model.suspend(chip);
- spin_lock_irq(&chip->reg_lock);
- saved_interrupt_mask = chip->interrupt_mask;
- chip->interrupt_mask = 0;
- oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ saved_interrupt_mask = chip->interrupt_mask;
+ chip->interrupt_mask = 0;
+ oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
+ }
flush_work(&chip->spdif_input_bits_work);
flush_work(&chip->gpio_work);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index eb3aca16359c..256a601d7811 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,10 +31,9 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
unsigned int i;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
for (i = 0; i < chip->model.dac_channels_mixer; ++i)
value->value.integer.value[i] = chip->dac_volume[i];
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -46,7 +45,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
int changed;
changed = 0;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
for (i = 0; i < chip->model.dac_channels_mixer; ++i)
if (value->value.integer.value[i] != chip->dac_volume[i]) {
chip->dac_volume[i] = value->value.integer.value[i];
@@ -54,7 +53,6 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
}
if (changed)
chip->model.update_dac_volume(chip);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -63,9 +61,8 @@ static int dac_mute_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.integer.value[0] = !chip->dac_mute;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -75,13 +72,12 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = (!value->value.integer.value[0]) != chip->dac_mute;
if (changed) {
chip->dac_mute = !value->value.integer.value[0];
chip->model.update_dac_mute(chip);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -114,9 +110,8 @@ static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.enumerated.item[0] = chip->dac_routing;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -188,13 +183,12 @@ static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
if (value->value.enumerated.item[0] >= count)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = value->value.enumerated.item[0] != chip->dac_routing;
if (changed) {
chip->dac_routing = value->value.enumerated.item[0];
oxygen_update_dac_routing(chip);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -203,9 +197,8 @@ static int spdif_switch_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.integer.value[0] = chip->spdif_playback_enable;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -279,7 +272,7 @@ static int spdif_switch_put(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = value->value.integer.value[0] != chip->spdif_playback_enable;
if (changed) {
chip->spdif_playback_enable = !!value->value.integer.value[0];
@@ -287,7 +280,6 @@ static int spdif_switch_put(struct snd_kcontrol *ctl,
oxygen_update_spdif_source(chip);
spin_unlock_irq(&chip->reg_lock);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -336,9 +328,8 @@ static int spdif_default_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oxygen_to_iec958(chip->spdif_bits, value);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -350,14 +341,13 @@ static int spdif_default_put(struct snd_kcontrol *ctl,
int changed;
new_bits = iec958_to_oxygen(value);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = new_bits != chip->spdif_bits;
if (changed) {
chip->spdif_bits = new_bits;
if (!(chip->pcm_active & (1 << PCM_SPDIF)))
write_spdif_bits(chip, new_bits);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -376,9 +366,8 @@ static int spdif_pcm_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oxygen_to_iec958(chip->spdif_pcm_bits, value);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -390,14 +379,13 @@ static int spdif_pcm_put(struct snd_kcontrol *ctl,
int changed;
new_bits = iec958_to_oxygen(value);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = new_bits != chip->spdif_pcm_bits;
if (changed) {
chip->spdif_pcm_bits = new_bits;
if (chip->pcm_active & (1 << PCM_SPDIF))
write_spdif_bits(chip, new_bits);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -444,7 +432,7 @@ static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
u32 oldreg, newreg;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
if (value->value.integer.value[0])
newreg = oldreg | bit;
@@ -453,7 +441,6 @@ static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
changed = newreg != oldreg;
if (changed)
oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
@@ -488,7 +475,7 @@ static int monitor_put(struct snd_kcontrol *ctl,
u8 oldreg, newreg;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oldreg = oxygen_read8(chip, OXYGEN_ADC_MONITOR);
if ((!!value->value.integer.value[0] ^ !!invert) != 0)
newreg = oldreg | bit;
@@ -497,7 +484,6 @@ static int monitor_put(struct snd_kcontrol *ctl,
changed = newreg != oldreg;
if (changed)
oxygen_write8(chip, OXYGEN_ADC_MONITOR, newreg);
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
@@ -511,9 +497,8 @@ static int ac97_switch_get(struct snd_kcontrol *ctl,
int invert = ctl->private_value & (1 << 16);
u16 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = oxygen_read_ac97(chip, codec, index);
- mutex_unlock(&chip->mutex);
if (!(reg & (1 << bitnr)) ^ !invert)
value->value.integer.value[0] = 1;
else
@@ -550,7 +535,7 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
u16 oldreg, newreg;
int change;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oldreg = oxygen_read_ac97(chip, codec, index);
newreg = oldreg;
if (!value->value.integer.value[0] ^ !invert)
@@ -579,7 +564,6 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
CM9780_GPO0, CM9780_GPO0);
}
}
- mutex_unlock(&chip->mutex);
return change;
}
@@ -604,9 +588,8 @@ static int ac97_volume_get(struct snd_kcontrol *ctl,
unsigned int index = ctl->private_value & 0xff;
u16 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = oxygen_read_ac97(chip, codec, index);
- mutex_unlock(&chip->mutex);
if (!stereo) {
value->value.integer.value[0] = 31 - (reg & 0x1f);
} else {
@@ -626,7 +609,7 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
u16 oldreg, newreg;
int change;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oldreg = oxygen_read_ac97(chip, codec, index);
if (!stereo) {
newreg = oldreg & ~0x1f;
@@ -639,7 +622,6 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
change = newreg != oldreg;
if (change)
oxygen_write_ac97(chip, codec, index, newreg);
- mutex_unlock(&chip->mutex);
return change;
}
@@ -656,10 +638,9 @@ static int mic_fmic_source_get(struct snd_kcontrol *ctl,
{
struct oxygen *chip = ctl->private_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.enumerated.item[0] =
!!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -670,7 +651,7 @@ static int mic_fmic_source_put(struct snd_kcontrol *ctl,
u16 oldreg, newreg;
int change;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
if (value->value.enumerated.item[0])
newreg = oldreg | CM9780_FMIC2MIC;
@@ -679,7 +660,6 @@ static int mic_fmic_source_put(struct snd_kcontrol *ctl,
change = newreg != oldreg;
if (change)
oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
- mutex_unlock(&chip->mutex);
return change;
}
@@ -699,9 +679,8 @@ static int ac97_fp_rec_volume_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
u16 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
- mutex_unlock(&chip->mutex);
value->value.integer.value[0] = reg & 7;
value->value.integer.value[1] = (reg >> 8) & 7;
return 0;
@@ -714,7 +693,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
u16 oldreg, newreg;
int change;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
newreg = oldreg & ~0x0707;
newreg = newreg | (value->value.integer.value[0] & 7);
@@ -722,7 +701,6 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
change = newreg != oldreg;
if (change)
oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg);
- mutex_unlock(&chip->mutex);
return change;
}
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 643141f345bb..b716356010b8 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -171,7 +171,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
snd_pcm_set_sync(substream);
chip->streams[channel] = substream;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
chip->pcm_active |= 1 << channel;
if (channel == PCM_SPDIF) {
chip->spdif_pcm_bits = chip->spdif_bits;
@@ -181,7 +181,6 @@ static int oxygen_open(struct snd_pcm_substream *substream,
SNDRV_CTL_EVENT_MASK_INFO,
&chip->controls[CONTROL_SPDIF_PCM]->id);
}
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -221,7 +220,7 @@ static int oxygen_close(struct snd_pcm_substream *substream)
struct oxygen *chip = snd_pcm_substream_chip(substream);
unsigned int channel = oxygen_substream_channel(substream);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
chip->pcm_active &= ~(1 << channel);
if (channel == PCM_SPDIF) {
chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
@@ -232,7 +231,6 @@ static int oxygen_close(struct snd_pcm_substream *substream)
}
if (channel == PCM_SPDIF || channel == PCM_MULTICH)
oxygen_update_spdif_source(chip);
- mutex_unlock(&chip->mutex);
chip->streams[channel] = NULL;
return 0;
@@ -351,24 +349,23 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
if (err < 0)
return err;
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
- OXYGEN_REC_FORMAT_A_MASK);
- oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.adc_i2s_format |
- get_mclk(chip, PCM_A, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- spin_unlock_irq(&chip->reg_lock);
-
- mutex_lock(&chip->mutex);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
+ oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
+ OXYGEN_REC_FORMAT_A_MASK);
+ oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
+ oxygen_rate(hw_params) |
+ chip->model.adc_i2s_format |
+ get_mclk(chip, PCM_A, hw_params) |
+ oxygen_i2s_bits(hw_params),
+ OXYGEN_I2S_RATE_MASK |
+ OXYGEN_I2S_FORMAT_MASK |
+ OXYGEN_I2S_MCLK_MASK |
+ OXYGEN_I2S_BITS_MASK);
+ }
+
+ guard(mutex)(&chip->mutex);
chip->model.set_adc_params(chip, hw_params);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -386,26 +383,25 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
is_ac97 = chip->has_ac97_1 &&
(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
- OXYGEN_REC_FORMAT_B_MASK);
- if (!is_ac97)
- oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.adc_i2s_format |
- get_mclk(chip, PCM_B, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
+ oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
+ OXYGEN_REC_FORMAT_B_MASK);
+ if (!is_ac97)
+ oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
+ oxygen_rate(hw_params) |
+ chip->model.adc_i2s_format |
+ get_mclk(chip, PCM_B, hw_params) |
+ oxygen_i2s_bits(hw_params),
+ OXYGEN_I2S_RATE_MASK |
+ OXYGEN_I2S_FORMAT_MASK |
+ OXYGEN_I2S_MCLK_MASK |
+ OXYGEN_I2S_BITS_MASK);
+ }
if (!is_ac97) {
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
chip->model.set_adc_params(chip, hw_params);
- mutex_unlock(&chip->mutex);
}
return 0;
}
@@ -423,26 +419,25 @@ static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
is_spdif = chip->model.device_config & CAPTURE_1_FROM_SPDIF;
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
- OXYGEN_REC_FORMAT_C_MASK);
- if (!is_spdif)
- oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.adc_i2s_format |
- get_mclk(chip, PCM_B, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
+ oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
+ OXYGEN_REC_FORMAT_C_MASK);
+ if (!is_spdif)
+ oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT,
+ oxygen_rate(hw_params) |
+ chip->model.adc_i2s_format |
+ get_mclk(chip, PCM_B, hw_params) |
+ oxygen_i2s_bits(hw_params),
+ OXYGEN_I2S_RATE_MASK |
+ OXYGEN_I2S_FORMAT_MASK |
+ OXYGEN_I2S_MCLK_MASK |
+ OXYGEN_I2S_BITS_MASK);
+ }
if (!is_spdif) {
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
chip->model.set_adc_params(chip, hw_params);
- mutex_unlock(&chip->mutex);
}
return 0;
}
@@ -457,8 +452,8 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
if (err < 0)
return err;
- mutex_lock(&chip->mutex);
- spin_lock_irq(&chip->reg_lock);
+ guard(mutex)(&chip->mutex);
+ guard(spinlock_irq)(&chip->reg_lock);
oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
OXYGEN_SPDIF_OUT_ENABLE);
oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
@@ -468,8 +463,6 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
oxygen_rate(hw_params) << OXYGEN_SPDIF_OUT_RATE_SHIFT,
OXYGEN_SPDIF_OUT_RATE_MASK);
oxygen_update_spdif_source(chip);
- spin_unlock_irq(&chip->reg_lock);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -483,29 +476,28 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
if (err < 0)
return err;
- mutex_lock(&chip->mutex);
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
- oxygen_play_channels(hw_params),
- OXYGEN_PLAY_CHANNELS_MASK);
- oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
- oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
- OXYGEN_MULTICH_FORMAT_MASK);
- oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.dac_i2s_format |
- get_mclk(chip, PCM_MULTICH, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- oxygen_update_spdif_source(chip);
- spin_unlock_irq(&chip->reg_lock);
+ guard(mutex)(&chip->mutex);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
+ oxygen_play_channels(hw_params),
+ OXYGEN_PLAY_CHANNELS_MASK);
+ oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
+ oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
+ OXYGEN_MULTICH_FORMAT_MASK);
+ oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
+ oxygen_rate(hw_params) |
+ chip->model.dac_i2s_format |
+ get_mclk(chip, PCM_MULTICH, hw_params) |
+ oxygen_i2s_bits(hw_params),
+ OXYGEN_I2S_RATE_MASK |
+ OXYGEN_I2S_FORMAT_MASK |
+ OXYGEN_I2S_MCLK_MASK |
+ OXYGEN_I2S_BITS_MASK);
+ oxygen_update_spdif_source(chip);
+ }
chip->model.set_dac_params(chip, hw_params);
oxygen_update_dac_routing(chip);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -515,13 +507,12 @@ static int oxygen_hw_free(struct snd_pcm_substream *substream)
unsigned int channel = oxygen_substream_channel(substream);
unsigned int channel_mask = 1 << channel;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
chip->interrupt_mask &= ~channel_mask;
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -530,10 +521,10 @@ static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream)
{
struct oxygen *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
- oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_OUT_ENABLE);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
+ OXYGEN_SPDIF_OUT_ENABLE);
+ }
return oxygen_hw_free(substream);
}
@@ -543,7 +534,7 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
unsigned int channel = oxygen_substream_channel(substream);
unsigned int channel_mask = 1 << channel;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
@@ -552,7 +543,6 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
else
chip->interrupt_mask |= channel_mask;
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -584,7 +574,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
}
}
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (!pausing) {
if (cmd == SNDRV_PCM_TRIGGER_START)
chip->pcm_running |= mask;
@@ -597,7 +587,6 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
else
oxygen_clear_bits8(chip, OXYGEN_DMA_PAUSE, mask);
}
- spin_unlock(&chip->reg_lock);
return 0;
}
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 664b7759dd62..47b2758653e4 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -309,7 +309,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
int changed;
u8 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->cs4398_regs[7];
if (value->value.enumerated.item[0])
reg |= CS4398_FILT_SEL;
@@ -324,7 +324,6 @@ static int rolloff_put(struct snd_kcontrol *ctl,
reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL;
cs4362a_write(chip, 0x04, reg);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -340,11 +339,10 @@ static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
unsigned int reg, unsigned int mute)
{
if (reg == AC97_LINE) {
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
mute ? GPIO_D1_INPUT_ROUTE : 0,
GPIO_D1_INPUT_ROUTE);
- spin_unlock_irq(&chip->reg_lock);
}
}
diff --git a/sound/pci/oxygen/xonar_dg_mixer.c b/sound/pci/oxygen/xonar_dg_mixer.c
index 198588562880..2179ff8e4d86 100644
--- a/sound/pci/oxygen/xonar_dg_mixer.c
+++ b/sound/pci/oxygen/xonar_dg_mixer.c
@@ -62,9 +62,8 @@ static int output_select_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct dg *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.enumerated.item[0] = data->output_sel;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -77,14 +76,13 @@ static int output_select_put(struct snd_kcontrol *ctl,
int changed = 0;
int ret;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (data->output_sel != new) {
data->output_sel = new;
ret = output_select_apply(chip);
changed = ret >= 0 ? 1 : ret;
oxygen_update_dac_routing(chip);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -108,12 +106,11 @@ static int hp_stereo_volume_get(struct snd_kcontrol *ctl,
struct dg *data = chip->model_data;
unsigned int tmp;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
tmp = (~data->cs4245_shadow[CS4245_DAC_A_CTRL]) & 255;
val->value.integer.value[0] = tmp;
tmp = (~data->cs4245_shadow[CS4245_DAC_B_CTRL]) & 255;
val->value.integer.value[1] = tmp;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -130,7 +127,7 @@ static int hp_stereo_volume_put(struct snd_kcontrol *ctl,
if ((new1 > 255) || (new1 < 0) || (new2 > 255) || (new2 < 0))
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if ((data->cs4245_shadow[CS4245_DAC_A_CTRL] != ~new1) ||
(data->cs4245_shadow[CS4245_DAC_B_CTRL] != ~new2)) {
data->cs4245_shadow[CS4245_DAC_A_CTRL] = ~new1;
@@ -140,7 +137,6 @@ static int hp_stereo_volume_put(struct snd_kcontrol *ctl,
ret = cs4245_write_spi(chip, CS4245_DAC_B_CTRL);
changed = ret >= 0 ? 1 : ret;
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -153,10 +149,9 @@ static int hp_mute_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct dg *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
val->value.integer.value[0] =
!(data->cs4245_shadow[CS4245_DAC_CTRL_1] & CS4245_MUTE_DAC);
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -170,13 +165,12 @@ static int hp_mute_put(struct snd_kcontrol *ctl,
if (val->value.integer.value[0] > 1)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
data->cs4245_shadow[CS4245_DAC_CTRL_1] &= ~CS4245_MUTE_DAC;
data->cs4245_shadow[CS4245_DAC_CTRL_1] |=
(~val->value.integer.value[0] << 2) & CS4245_MUTE_DAC;
ret = cs4245_write_spi(chip, CS4245_DAC_CTRL_1);
changed = ret >= 0 ? 1 : ret;
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -212,10 +206,9 @@ static int input_vol_get(struct snd_kcontrol *ctl,
struct dg *data = chip->model_data;
unsigned int idx = ctl->private_value;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.integer.value[0] = data->input_vol[idx][0];
value->value.integer.value[1] = data->input_vol[idx][1];
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -233,7 +226,7 @@ static int input_vol_put(struct snd_kcontrol *ctl,
value->value.integer.value[1] < 2 * -12 ||
value->value.integer.value[1] > 2 * 12)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
data->input_vol[idx][1] != value->value.integer.value[1];
if (changed) {
@@ -246,7 +239,6 @@ static int input_vol_put(struct snd_kcontrol *ctl,
}
changed = ret >= 0 ? 1 : ret;
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -282,9 +274,8 @@ static int input_sel_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct dg *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.enumerated.item[0] = data->input_sel;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -299,7 +290,7 @@ static int input_sel_put(struct snd_kcontrol *ctl,
if (value->value.enumerated.item[0] > 3)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = value->value.enumerated.item[0] != data->input_sel;
if (changed) {
data->input_sel = value->value.enumerated.item[0];
@@ -311,7 +302,6 @@ static int input_sel_put(struct snd_kcontrol *ctl,
data->input_vol[data->input_sel][1]);
changed = ret >= 0 ? 1 : ret;
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -341,7 +331,7 @@ static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
u8 reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->cs4245_shadow[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
if (value->value.enumerated.item[0])
reg |= CS4245_HPF_FREEZE;
@@ -350,7 +340,6 @@ static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
data->cs4245_shadow[CS4245_ADC_CTRL] = reg;
cs4245_write_spi(chip, CS4245_ADC_CTRL);
}
- mutex_unlock(&chip->mutex);
return changed;
}
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index e951f5478075..0edf67ce37d1 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -109,7 +109,7 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
u16 old_bits, new_bits;
int changed;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
if (!!value->value.integer.value[0] ^ invert)
new_bits = old_bits | bit;
@@ -118,6 +118,5 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
changed = new_bits != old_bits;
if (changed)
oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
- spin_unlock_irq(&chip->reg_lock);
return changed;
}
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index cf801a235df9..837a9505382a 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -762,7 +762,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
int changed;
u8 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->pcm1796_regs[0][19 - PCM1796_REG_BASE];
reg &= ~PCM1796_FLT_MASK;
if (!value->value.enumerated.item[0])
@@ -774,7 +774,6 @@ static int rolloff_put(struct snd_kcontrol *ctl,
for (i = 0; i < data->dacs; ++i)
pcm1796_write(chip, i, 19, reg);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -806,7 +805,7 @@ static int deemph_put(struct snd_kcontrol *ctl,
int changed;
u8 reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE];
if (!value->value.integer.value[0])
reg &= ~PCM1796_DME;
@@ -817,7 +816,6 @@ static int deemph_put(struct snd_kcontrol *ctl,
for (i = 0; i < data->dacs; ++i)
pcm1796_write(chip, i, 18, reg);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -872,7 +870,7 @@ static int st_output_switch_put(struct snd_kcontrol *ctl,
struct xonar_pcm179x *data = chip->model_data;
u16 gpio_old, gpio;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
gpio = gpio_old;
switch (value->value.enumerated.item[0]) {
@@ -889,7 +887,6 @@ static int st_output_switch_put(struct snd_kcontrol *ctl,
oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
data->hp_active = gpio & GPIO_ST_HP;
update_pcm1796_volume(chip);
- mutex_unlock(&chip->mutex);
return gpio != gpio_old;
}
@@ -909,7 +906,7 @@ static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct xonar_pcm179x *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (data->hp_gain_offset < 2*-12)
value->value.enumerated.item[0] = 0;
else if (data->hp_gain_offset < 2*-6)
@@ -918,7 +915,6 @@ static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
value->value.enumerated.item[0] = 2;
else
value->value.enumerated.item[0] = 3;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -935,13 +931,12 @@ static int st_hp_volume_offset_put(struct snd_kcontrol *ctl,
if (value->value.enumerated.item[0] > 3)
return -EINVAL;
offset = offsets[value->value.enumerated.item[0]];
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = offset != data->hp_gain_offset;
if (changed) {
data->hp_gain_offset = offset;
update_pcm1796_volume(chip);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -985,7 +980,7 @@ static int xense_output_switch_put(struct snd_kcontrol *ctl,
struct xonar_pcm179x *data = chip->model_data;
u16 gpio_old, gpio;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
gpio = gpio_old;
switch (value->value.enumerated.item[0]) {
@@ -1002,7 +997,6 @@ static int xense_output_switch_put(struct snd_kcontrol *ctl,
oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
data->hp_active = !(gpio & GPIO_XENSE_SPEAKERS);
update_pcm1796_volume(chip);
- mutex_unlock(&chip->mutex);
return gpio != gpio_old;
}
@@ -1027,11 +1021,10 @@ static void xonar_line_mic_ac97_switch(struct oxygen *chip,
unsigned int reg, unsigned int mute)
{
if (reg == AC97_LINE) {
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
mute ? GPIO_INPUT_ROUTE : 0,
GPIO_INPUT_ROUTE);
- spin_unlock_irq(&chip->reg_lock);
}
}
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 8aa92f3e5ee8..7d92e6e20c39 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -237,7 +237,7 @@ static void xonar_ds_handle_hp_jack(struct oxygen *chip)
bool hp_plugged;
unsigned int reg;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
GPIO_DS_HP_DETECT);
@@ -252,8 +252,6 @@ static void xonar_ds_handle_hp_jack(struct oxygen *chip)
wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
-
- mutex_unlock(&chip->mutex);
}
static void xonar_ds_init(struct oxygen *chip)
@@ -521,14 +519,13 @@ static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
bool invert = (ctl->private_value >> 24) & 1;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg_value = data->wm8776_regs[reg_index] & ~bit;
if (value->value.integer.value[0] ^ invert)
reg_value |= bit;
changed = reg_value != data->wm8776_regs[reg_index];
if (changed)
wm8776_write(chip, reg_index, reg_value);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -648,13 +645,12 @@ static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
max = (ctl->private_value >> 12) & 0xf;
if (value < min || value > max)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = value != (ctl->private_value & 0xf);
if (changed) {
ctl->private_value = (ctl->private_value & ~0xf) | value;
wm8776_field_set_from_ctl(ctl);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -700,12 +696,11 @@ static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct xonar_wm87x6 *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.integer.value[0] =
data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
value->value.integer.value[1] =
data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -716,7 +711,7 @@ static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
struct xonar_wm87x6 *data = chip->model_data;
u8 to_update;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
to_update = (value->value.integer.value[0] !=
(data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
<< 0;
@@ -744,7 +739,6 @@ static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
value->value.integer.value[1] |
WM8776_HPZCEN | WM8776_UPDATE);
}
- mutex_unlock(&chip->mutex);
return to_update != 0;
}
@@ -770,7 +764,7 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
u16 reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->wm8776_regs[WM8776_ADCMUX];
if (value->value.integer.value[0]) {
reg |= mux_bit;
@@ -794,7 +788,6 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
GPIO_DS_INPUT_ROUTE);
wm8776_write(chip, WM8776_ADCMUX, reg);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -814,12 +807,11 @@ static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
struct xonar_wm87x6 *data = chip->model_data;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
value->value.integer.value[0] =
data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
value->value.integer.value[1] =
data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
- mutex_unlock(&chip->mutex);
return 0;
}
@@ -830,7 +822,7 @@ static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
struct xonar_wm87x6 *data = chip->model_data;
int changed = 0;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = (value->value.integer.value[0] !=
(data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
(value->value.integer.value[1] !=
@@ -839,7 +831,6 @@ static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
value->value.integer.value[0] | WM8776_ZCA);
wm8776_write_cached(chip, WM8776_ADCRVOL,
value->value.integer.value[1] | WM8776_ZCA);
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -895,7 +886,7 @@ static int wm8776_level_control_put(struct snd_kcontrol *ctl,
if (value->value.enumerated.item[0] >= 3)
return -EINVAL;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
changed = value->value.enumerated.item[0] != ctl->private_value;
if (changed) {
ctl->private_value = value->value.enumerated.item[0];
@@ -926,7 +917,6 @@ static int wm8776_level_control_put(struct snd_kcontrol *ctl,
for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
activate_control(chip, data->lc_controls[i], mode);
}
- mutex_unlock(&chip->mutex);
return changed;
}
@@ -956,14 +946,13 @@ static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
unsigned int reg;
int changed;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
if (!value->value.enumerated.item[0])
reg |= WM8776_ADCHPD;
changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
if (changed)
wm8776_write(chip, WM8776_ADCIFCTRL, reg);
- mutex_unlock(&chip->mutex);
return changed;
}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index bfd84c50e981..83066d08367e 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -701,7 +701,7 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
start_time = ktime_get();
#endif
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
/* check the pipes concerned and build pipe_array */
for (i = 0; i < mgr->num_cards; i++) {
@@ -720,7 +720,6 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
}
}
if (capture_mask == 0 && playback_mask == 0) {
- mutex_unlock(&mgr->setup_mutex);
dev_err(&mgr->pci->dev, "%s : no pipes\n", __func__);
return;
}
@@ -731,7 +730,6 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
/* synchronous stop of all the pipes concerned */
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
if (err) {
- mutex_unlock(&mgr->setup_mutex);
dev_err(&mgr->pci->dev, "%s : "
"error stop pipes (P%x C%x)\n",
__func__, playback_mask, capture_mask);
@@ -776,7 +774,6 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
/* synchronous start of all the pipes concerned */
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
if (err) {
- mutex_unlock(&mgr->setup_mutex);
dev_err(&mgr->pci->dev, "%s : "
"error start pipes (P%x C%x)\n",
__func__, playback_mask, capture_mask);
@@ -786,7 +783,7 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
/* put the streams into the running state now
* (increment pointer by interrupt)
*/
- mutex_lock(&mgr->lock);
+ guard(mutex)(&mgr->lock);
for ( i =0; i < mgr->num_cards; i++) {
struct pcxhr_stream *stream;
chip = mgr->chip[i];
@@ -804,9 +801,6 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
}
}
}
- mutex_unlock(&mgr->lock);
-
- mutex_unlock(&mgr->setup_mutex);
#ifdef CONFIG_SND_DEBUG_VERBOSE
stop_time = ktime_get();
@@ -907,7 +901,7 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs)
subs->runtime->period_size, subs->runtime->periods,
subs->runtime->buffer_size);
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
do {
/* only the first stream can choose the sample rate */
@@ -923,8 +917,6 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs)
}
} while(0); /* do only once (so we can use break instead of goto) */
- mutex_unlock(&mgr->setup_mutex);
-
return err;
}
@@ -939,15 +931,13 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs,
struct pcxhr_mgr *mgr = chip->mgr;
struct pcxhr_stream *stream = subs->runtime->private_data;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
/* set up channels */
stream->channels = params_channels(hw);
/* set up format for the stream */
stream->format = params_format(hw);
- mutex_unlock(&mgr->setup_mutex);
-
return 0;
}
@@ -990,7 +980,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
struct pcxhr_stream *stream;
int err;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
/* copy the struct snd_pcm_hardware struct */
runtime->hw = pcxhr_caps;
@@ -1012,7 +1002,6 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
/* streams in use */
dev_err(chip->card->dev, "%s chip%d subs%d in use\n",
__func__, chip->chip_idx, subs->number);
- mutex_unlock(&mgr->setup_mutex);
return -EBUSY;
}
@@ -1023,10 +1012,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
/* buffer-size should better be multiple of period-size */
err = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- mutex_unlock(&mgr->setup_mutex);
+ if (err < 0)
return err;
- }
/* if a sample rate is already used or fixed by external clock,
* the stream cannot change
@@ -1040,7 +1027,6 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
&external_rate) ||
external_rate == 0) {
/* cannot detect the external clock rate */
- mutex_unlock(&mgr->setup_mutex);
return -EBUSY;
}
runtime->hw.rate_min = external_rate;
@@ -1063,7 +1049,6 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
mgr->ref_count_rate++;
- mutex_unlock(&mgr->setup_mutex);
return 0;
}
@@ -1074,7 +1059,7 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
struct pcxhr_mgr *mgr = chip->mgr;
struct pcxhr_stream *stream = subs->runtime->private_data;
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
dev_dbg(chip->card->dev, "%s chip%d subs%d\n", __func__,
chip->chip_idx, subs->number);
@@ -1088,8 +1073,6 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
stream->status = PCXHR_STREAM_STATUS_FREE;
stream->substream = NULL;
- mutex_unlock(&mgr->setup_mutex);
-
return 0;
}
@@ -1102,14 +1085,12 @@ static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
struct pcxhr_stream *stream = runtime->private_data;
- mutex_lock(&chip->mgr->lock);
+ guard(mutex)(&chip->mgr->lock);
/* get the period fragment and the nb of periods in the buffer */
timer_period_frag = stream->timer_period_frag;
timer_buf_periods = stream->timer_buf_periods;
- mutex_unlock(&chip->mgr->lock);
-
return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +
timer_period_frag);
}
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 23f253effb4f..b3b9ab4f303e 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -754,12 +754,8 @@ void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture,
*/
int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
{
- int err;
-
- mutex_lock(&mgr->msg_lock);
- err = pcxhr_send_msg_nolock(mgr, rmh);
- mutex_unlock(&mgr->msg_lock);
- return err;
+ guard(mutex)(&mgr->msg_lock);
+ return pcxhr_send_msg_nolock(mgr, rmh);
}
static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
@@ -962,14 +958,13 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
struct pcxhr_rmh rmh;
int err;
- mutex_lock(&mgr->msg_lock);
+ guard(mutex)(&mgr->msg_lock);
if ((mgr->io_num_reg_cont & mask) == value) {
dev_dbg(&mgr->pci->dev,
"IO_NUM_REG_CONT mask %x already is set to %x\n",
mask, value);
if (changed)
*changed = 0;
- mutex_unlock(&mgr->msg_lock);
return 0; /* already programmed */
}
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
@@ -984,7 +979,6 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
if (changed)
*changed = 1;
}
- mutex_unlock(&mgr->msg_lock);
return err;
}
@@ -1269,7 +1263,7 @@ irqreturn_t pcxhr_threaded_irq(int irq, void *dev_id)
int i, j;
struct snd_pcxhr *chip;
- mutex_lock(&mgr->lock);
+ guard(mutex)(&mgr->lock);
if (mgr->src_it_dsp & PCXHR_IRQ_TIMER) {
/* is a 24 bit counter */
int dsp_time_new =
@@ -1328,6 +1322,5 @@ irqreturn_t pcxhr_threaded_irq(int irq, void *dev_id)
}
pcxhr_msg_thread(mgr);
- mutex_unlock(&mgr->lock);
return IRQ_HANDLED;
}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
index e1435afc4907..80d22e22ea30 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.c
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -710,9 +710,9 @@ static int hr222_mic_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->mic_volume;
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -721,13 +721,13 @@ static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (chip->mic_volume != ucontrol->value.integer.value[0]) {
changed = 1;
chip->mic_volume = ucontrol->value.integer.value[0];
hr222_update_analog_audio_level(chip, 1, 0);
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -760,9 +760,9 @@ static int hr222_mic_boost_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->mic_boost;
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -771,13 +771,13 @@ static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (chip->mic_boost != ucontrol->value.integer.value[0]) {
changed = 1;
chip->mic_boost = ucontrol->value.integer.value[0];
hr222_micro_boost(chip->mgr, chip->mic_boost);
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -800,9 +800,9 @@ static int hr222_phantom_power_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->phantom_power;
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -812,14 +812,13 @@ static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
int power, changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
power = !!ucontrol->value.integer.value[0];
if (chip->phantom_power != power) {
hr222_phantom_power(chip->mgr, power);
chip->phantom_power = power;
changed = 1;
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index aec509461dd6..03daa2832b1b 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -110,7 +110,8 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (kcontrol->private_value == 0) { /* playback */
ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
@@ -118,7 +119,6 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -129,7 +129,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
int changed = 0;
int is_capture, i;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
is_capture = (kcontrol->private_value != 0);
for (i = 0; i < 2; i++) {
int new_volume = ucontrol->value.integer.value[i];
@@ -168,7 +168,6 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
is_capture, i);
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -192,10 +191,9 @@ static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -204,7 +202,8 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
int i, changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
for(i = 0; i < 2; i++) {
if (chip->analog_playback_active[i] !=
ucontrol->value.integer.value[i]) {
@@ -218,7 +217,6 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
pcxhr_update_analog_audio_level(chip, 0, i);
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -352,14 +350,13 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
int *stored_volume;
int is_capture = kcontrol->private_value;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (is_capture) /* digital capture */
stored_volume = chip->digital_capture_volume;
else /* digital playback */
stored_volume = chip->digital_playback_volume[idx];
ucontrol->value.integer.value[0] = stored_volume[0];
ucontrol->value.integer.value[1] = stored_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -373,7 +370,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
int *stored_volume;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (is_capture) /* digital capture */
stored_volume = chip->digital_capture_volume;
else /* digital playback */
@@ -392,7 +389,6 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
}
if (!is_capture && changed) /* update playback volume */
pcxhr_update_playback_stream_level(chip, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -416,10 +412,9 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -431,7 +426,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
int i, j;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
j = idx;
for (i = 0; i < 2; i++) {
if (chip->digital_playback_active[j][i] !=
@@ -443,7 +438,6 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
}
if (changed)
pcxhr_update_playback_stream_level(chip, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -465,10 +459,10 @@ static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -479,7 +473,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
int changed = 0;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 2; i++) {
if (chip->monitoring_volume[i] !=
ucontrol->value.integer.value[i]) {
@@ -492,7 +486,6 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
changed = 1;
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
@@ -515,10 +508,10 @@ static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
+
+ guard(mutex)(&chip->mgr->mixer_mutex);
ucontrol->value.integer.value[0] = chip->monitoring_active[0];
ucontrol->value.integer.value[1] = chip->monitoring_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -529,7 +522,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
int changed = 0;
int i;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 2; i++) {
if (chip->monitoring_active[i] !=
ucontrol->value.integer.value[i]) {
@@ -545,7 +538,6 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
/* update right monitoring volume and mute */
pcxhr_update_audio_pipe_level(chip, 0, 1);
- mutex_unlock(&chip->mgr->mixer_mutex);
return (changed != 0);
}
@@ -671,7 +663,7 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
}
if (ucontrol->value.enumerated.item[0] >= i)
return -EINVAL;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
chip->audio_capture_source = ucontrol->value.enumerated.item[0];
if (chip->mgr->is_hr_stereo)
@@ -680,7 +672,6 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
pcxhr_set_audio_source(chip);
ret = 1;
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return ret;
}
@@ -760,9 +751,9 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
}
if (ucontrol->value.enumerated.item[0] >= clock_items)
return -EINVAL;
- mutex_lock(&mgr->mixer_mutex);
+ guard(mutex)(&mgr->mixer_mutex);
if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
- mutex_lock(&mgr->setup_mutex);
+ guard(mutex)(&mgr->setup_mutex);
mgr->use_clock_type = ucontrol->value.enumerated.item[0];
rate = 0;
if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
@@ -778,10 +769,8 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
if (mgr->sample_rate)
mgr->sample_rate = rate;
}
- mutex_unlock(&mgr->setup_mutex);
ret = 1; /* return 1 even if the set was not done. ok ? */
}
- mutex_unlock(&mgr->mixer_mutex);
return ret;
}
@@ -814,7 +803,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
int i, err, rate;
- mutex_lock(&mgr->mixer_mutex);
+ guard(mutex)(&mgr->mixer_mutex);
for(i = 0; i < 3 + mgr->capture_chips; i++) {
if (i == PCXHR_CLOCK_TYPE_INTERNAL)
rate = mgr->sample_rate_real;
@@ -825,7 +814,6 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
}
ucontrol->value.integer.value[i] = rate;
}
- mutex_unlock(&mgr->mixer_mutex);
return 0;
}
@@ -918,7 +906,7 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
unsigned char aes_bits;
int i, err;
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
for(i = 0; i < 5; i++) {
if (kcontrol->private_value == 0) /* playback */
aes_bits = chip->aes_bits[i];
@@ -934,7 +922,6 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
}
ucontrol->value.iec958.status[i] = aes_bits;
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return 0;
}
@@ -988,7 +975,7 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
int i, changed = 0;
/* playback */
- mutex_lock(&chip->mgr->mixer_mutex);
+ guard(mutex)(&chip->mgr->mixer_mutex);
for (i = 0; i < 5; i++) {
if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
if (chip->mgr->is_hr_stereo)
@@ -1000,7 +987,6 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
changed = 1;
}
}
- mutex_unlock(&chip->mgr->mixer_mutex);
return changed;
}
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index f07b6023473a..ca9bbf554650 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -646,35 +646,27 @@ snd_rme32_playback_hw_params(struct snd_pcm_substream *substream,
runtime->dma_bytes = RME32_BUFFER_SIZE;
}
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
rate = 0;
if (rme32->rcreg & RME32_RCR_KMODE)
rate = snd_rme32_capture_getrate(rme32, &dummy);
if (rate > 0) {
/* AutoSync */
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme32->lock);
+ if ((int)params_rate(params) != rate)
return -EIO;
- }
} else {
err = snd_rme32_playback_setrate(rme32, params_rate(params));
- if (err < 0) {
- spin_unlock_irq(&rme32->lock);
+ if (err < 0)
return err;
- }
}
err = snd_rme32_setformat(rme32, params_format(params));
- if (err < 0) {
- spin_unlock_irq(&rme32->lock);
+ if (err < 0)
return err;
- }
snd_rme32_setframelog(rme32, params_channels(params), 1);
if (rme32->capture_periodsize != 0) {
- if (params_period_size(params) << rme32->playback_frlog != rme32->capture_periodsize) {
- spin_unlock_irq(&rme32->lock);
+ if (params_period_size(params) << rme32->playback_frlog != rme32->capture_periodsize)
return -EBUSY;
- }
}
rme32->playback_periodsize = params_period_size(params) << rme32->playback_frlog;
/* S/PDIF setup */
@@ -683,7 +675,6 @@ snd_rme32_playback_hw_params(struct snd_pcm_substream *substream,
rme32->wcreg |= rme32->wcreg_spdif_stream;
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
}
- spin_unlock_irq(&rme32->lock);
return 0;
}
@@ -703,32 +694,24 @@ snd_rme32_capture_hw_params(struct snd_pcm_substream *substream,
runtime->dma_bytes = RME32_BUFFER_SIZE;
}
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
/* enable AutoSync for record-preparing */
rme32->wcreg |= RME32_WCR_AUTOSYNC;
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
err = snd_rme32_setformat(rme32, params_format(params));
- if (err < 0) {
- spin_unlock_irq(&rme32->lock);
+ if (err < 0)
return err;
- }
err = snd_rme32_playback_setrate(rme32, params_rate(params));
- if (err < 0) {
- spin_unlock_irq(&rme32->lock);
+ if (err < 0)
return err;
- }
rate = snd_rme32_capture_getrate(rme32, &isadat);
if (rate > 0) {
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme32->lock);
+ if ((int)params_rate(params) != rate)
return -EIO;
- }
if ((isadat && runtime->hw.channels_min == 2) ||
- (!isadat && runtime->hw.channels_min == 8)) {
- spin_unlock_irq(&rme32->lock);
+ (!isadat && runtime->hw.channels_min == 8))
return -EIO;
- }
}
/* AutoSync off for recording */
rme32->wcreg &= ~RME32_WCR_AUTOSYNC;
@@ -737,14 +720,11 @@ snd_rme32_capture_hw_params(struct snd_pcm_substream *substream,
snd_rme32_setframelog(rme32, params_channels(params), 0);
if (rme32->playback_periodsize != 0) {
if (params_period_size(params) << rme32->capture_frlog !=
- rme32->playback_periodsize) {
- spin_unlock_irq(&rme32->lock);
+ rme32->playback_periodsize)
return -EBUSY;
- }
}
rme32->capture_periodsize =
params_period_size(params) << rme32->capture_frlog;
- spin_unlock_irq(&rme32->lock);
return 0;
}
@@ -824,15 +804,13 @@ static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme32->lock);
- if (rme32->playback_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
+ scoped_guard(spinlock_irq, &rme32->lock) {
+ if (rme32->playback_substream != NULL)
+ return -EBUSY;
+ rme32->wcreg &= ~RME32_WCR_ADAT;
+ writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
+ rme32->playback_substream = substream;
}
- rme32->wcreg &= ~RME32_WCR_ADAT;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- rme32->playback_substream = substream;
- spin_unlock_irq(&rme32->lock);
if (rme32->fullduplex_mode)
runtime->hw = snd_rme32_spdif_fd_info;
@@ -869,13 +847,11 @@ static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme32->lock);
- if (rme32->capture_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->capture_substream = substream;
- spin_unlock_irq(&rme32->lock);
+ scoped_guard(spinlock_irq, &rme32->lock) {
+ if (rme32->capture_substream != NULL)
+ return -EBUSY;
+ rme32->capture_substream = substream;
+ }
if (rme32->fullduplex_mode)
runtime->hw = snd_rme32_spdif_fd_info;
@@ -909,15 +885,13 @@ snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme32->lock);
- if (rme32->playback_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->wcreg |= RME32_WCR_ADAT;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- rme32->playback_substream = substream;
- spin_unlock_irq(&rme32->lock);
+ scoped_guard(spinlock_irq, &rme32->lock) {
+ if (rme32->playback_substream != NULL)
+ return -EBUSY;
+ rme32->wcreg |= RME32_WCR_ADAT;
+ writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
+ rme32->playback_substream = substream;
+ }
if (rme32->fullduplex_mode)
runtime->hw = snd_rme32_adat_fd_info;
@@ -960,13 +934,11 @@ snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme32->lock);
- if (rme32->capture_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->capture_substream = substream;
- spin_unlock_irq(&rme32->lock);
+ scoped_guard(spinlock_irq, &rme32->lock) {
+ if (rme32->capture_substream != NULL)
+ return -EBUSY;
+ rme32->capture_substream = substream;
+ }
snd_rme32_set_buffer_constraint(rme32, runtime);
return 0;
@@ -977,11 +949,11 @@ static int snd_rme32_playback_close(struct snd_pcm_substream *substream)
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
int spdif = 0;
- spin_lock_irq(&rme32->lock);
- rme32->playback_substream = NULL;
- rme32->playback_periodsize = 0;
- spdif = (rme32->wcreg & RME32_WCR_ADAT) == 0;
- spin_unlock_irq(&rme32->lock);
+ scoped_guard(spinlock_irq, &rme32->lock) {
+ rme32->playback_substream = NULL;
+ rme32->playback_periodsize = 0;
+ spdif = (rme32->wcreg & RME32_WCR_ADAT) == 0;
+ }
if (spdif) {
rme32->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(rme32->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -995,10 +967,9 @@ static int snd_rme32_capture_close(struct snd_pcm_substream *substream)
{
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
rme32->capture_substream = NULL;
rme32->capture_periodsize = 0;
- spin_unlock_irq(&rme32->lock);
return 0;
}
@@ -1006,7 +977,7 @@ static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream)
{
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
if (rme32->fullduplex_mode) {
memset(&rme32->playback_pcm, 0, sizeof(rme32->playback_pcm));
rme32->playback_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
@@ -1017,7 +988,6 @@ static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream)
if (rme32->wcreg & RME32_WCR_SEL)
rme32->wcreg &= ~RME32_WCR_MUTE;
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
return 0;
}
@@ -1025,7 +995,7 @@ static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream)
{
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
if (rme32->fullduplex_mode) {
memset(&rme32->capture_pcm, 0, sizeof(rme32->capture_pcm));
rme32->capture_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
@@ -1034,7 +1004,6 @@ static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream)
} else {
writel(0, rme32->iobase + RME32_IO_RESET_POS);
}
- spin_unlock_irq(&rme32->lock);
return 0;
}
@@ -1044,7 +1013,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
struct snd_pcm_substream *s;
- spin_lock(&rme32->lock);
+ guard(spinlock)(&rme32->lock);
snd_pcm_group_for_each_entry(s, substream) {
if (s != rme32->playback_substream &&
s != rme32->capture_substream)
@@ -1088,7 +1057,6 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
snd_rme32_pcm_start(rme32, 1);
break;
}
- spin_unlock(&rme32->lock);
return 0;
}
@@ -1124,11 +1092,11 @@ static int snd_rme32_playback_fd_ack(struct snd_pcm_substream *substream)
rec = &rme32->playback_pcm;
cprec = &rme32->capture_pcm;
- spin_lock(&rme32->lock);
- rec->hw_queue_size = RME32_BUFFER_SIZE;
- if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE))
- rec->hw_queue_size -= cprec->hw_ready;
- spin_unlock(&rme32->lock);
+ scoped_guard(spinlock, &rme32->lock) {
+ rec->hw_queue_size = RME32_BUFFER_SIZE;
+ if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE))
+ rec->hw_queue_size -= cprec->hw_ready;
+ }
return snd_pcm_indirect_playback_transfer(substream, rec,
snd_rme32_pb_trans_copy);
}
@@ -1513,10 +1481,9 @@ snd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol,
{
struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
ucontrol->value.integer.value[0] =
rme32->wcreg & RME32_WCR_SEL ? 0 : 1;
- spin_unlock_irq(&rme32->lock);
return 0;
}
static int
@@ -1528,7 +1495,7 @@ snd_rme32_put_loopback_control(struct snd_kcontrol *kcontrol,
int change;
val = ucontrol->value.integer.value[0] ? 0 : RME32_WCR_SEL;
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
val = (rme32->wcreg & ~RME32_WCR_SEL) | val;
change = val != rme32->wcreg;
if (ucontrol->value.integer.value[0])
@@ -1537,7 +1504,6 @@ snd_rme32_put_loopback_control(struct snd_kcontrol *kcontrol,
val |= RME32_WCR_MUTE;
rme32->wcreg = val;
writel(val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
return change;
}
@@ -1572,7 +1538,7 @@ snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol,
struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
unsigned int items = 3;
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);
switch (rme32->pci->device) {
@@ -1591,7 +1557,6 @@ snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol,
ucontrol->value.enumerated.item[0] = items - 1;
}
- spin_unlock_irq(&rme32->lock);
return 0;
}
static int
@@ -1616,10 +1581,9 @@ snd_rme32_put_inputtype_control(struct snd_kcontrol *kcontrol,
}
val = ucontrol->value.enumerated.item[0] % items;
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
change = val != (unsigned int)snd_rme32_getinputtype(rme32);
snd_rme32_setinputtype(rme32, val);
- spin_unlock_irq(&rme32->lock);
return change;
}
@@ -1640,9 +1604,8 @@ snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol,
{
struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
ucontrol->value.enumerated.item[0] = snd_rme32_getclockmode(rme32);
- spin_unlock_irq(&rme32->lock);
return 0;
}
static int
@@ -1654,10 +1617,9 @@ snd_rme32_put_clockmode_control(struct snd_kcontrol *kcontrol,
int change;
val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
change = val != (unsigned int)snd_rme32_getclockmode(rme32);
snd_rme32_setclockmode(rme32, val);
- spin_unlock_irq(&rme32->lock);
return change;
}
@@ -1707,10 +1669,9 @@ static int snd_rme32_control_spdif_put(struct snd_kcontrol *kcontrol,
u32 val;
val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
change = val != rme32->wcreg_spdif;
rme32->wcreg_spdif = val;
- spin_unlock_irq(&rme32->lock);
return change;
}
@@ -1742,13 +1703,12 @@ static int snd_rme32_control_spdif_stream_put(struct snd_kcontrol *kcontrol,
u32 val;
val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme32->lock);
+ guard(spinlock_irq)(&rme32->lock);
change = val != rme32->wcreg_spdif_stream;
rme32->wcreg_spdif_stream = val;
rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
rme32->wcreg |= val;
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
return change;
}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 5cdbbe9cf994..58b8ebf1a24e 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -964,48 +964,45 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
runtime->dma_bytes = RME96_BUFFER_SIZE;
- spin_lock_irq(&rme96->lock);
- rate = 0;
- if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG)
- rate = snd_rme96_capture_getrate(rme96, &dummy);
- if (rate > 0) {
- /* slave clock */
- if ((int)params_rate(params) != rate) {
- err = -EIO;
- goto error;
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ rate = 0;
+ if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+ snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG)
+ rate = snd_rme96_capture_getrate(rme96, &dummy);
+ if (rate > 0) {
+ /* slave clock */
+ if ((int)params_rate(params) != rate)
+ return -EIO;
+ } else {
+ err = snd_rme96_playback_setrate(rme96, params_rate(params));
+ if (err < 0)
+ return err;
+ apply_dac_volume = err > 0; /* need to restore volume later? */
}
- } else {
- err = snd_rme96_playback_setrate(rme96, params_rate(params));
- if (err < 0)
- goto error;
- apply_dac_volume = err > 0; /* need to restore volume later? */
- }
- err = snd_rme96_playback_setformat(rme96, params_format(params));
- if (err < 0)
- goto error;
- snd_rme96_setframelog(rme96, params_channels(params), 1);
- if (rme96->capture_periodsize != 0) {
- if (params_period_size(params) << rme96->playback_frlog !=
- rme96->capture_periodsize)
- {
- err = -EBUSY;
+ err = snd_rme96_playback_setformat(rme96, params_format(params));
+ if (err < 0)
goto error;
+ snd_rme96_setframelog(rme96, params_channels(params), 1);
+ if (rme96->capture_periodsize != 0) {
+ if (params_period_size(params) << rme96->playback_frlog !=
+ rme96->capture_periodsize) {
+ err = -EBUSY;
+ goto error;
+ }
+ }
+ rme96->playback_periodsize =
+ params_period_size(params) << rme96->playback_frlog;
+ snd_rme96_set_period_properties(rme96, rme96->playback_periodsize);
+ /* S/PDIF setup */
+ if ((rme96->wcreg & RME96_WCR_ADAT) == 0) {
+ rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
+ writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
}
- }
- rme96->playback_periodsize =
- params_period_size(params) << rme96->playback_frlog;
- snd_rme96_set_period_properties(rme96, rme96->playback_periodsize);
- /* S/PDIF setup */
- if ((rme96->wcreg & RME96_WCR_ADAT) == 0) {
- rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
- writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- }
- err = 0;
+ err = 0;
+ }
error:
- spin_unlock_irq(&rme96->lock);
if (apply_dac_volume) {
usleep_range(3000, 10000);
snd_rme96_apply_dac_volume(rme96);
@@ -1027,45 +1024,33 @@ snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
runtime->dma_bytes = RME96_BUFFER_SIZE;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
err = snd_rme96_capture_setformat(rme96, params_format(params));
- if (err < 0) {
- spin_unlock_irq(&rme96->lock);
+ if (err < 0)
return err;
- }
if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
err = snd_rme96_capture_analog_setrate(rme96, params_rate(params));
- if (err < 0) {
- spin_unlock_irq(&rme96->lock);
+ if (err < 0)
return err;
- }
} else {
rate = snd_rme96_capture_getrate(rme96, &isadat);
if (rate > 0) {
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
+ if ((int)params_rate(params) != rate)
return -EIO;
- }
if ((isadat && runtime->hw.channels_min == 2) ||
- (!isadat && runtime->hw.channels_min == 8)) {
- spin_unlock_irq(&rme96->lock);
+ (!isadat && runtime->hw.channels_min == 8))
return -EIO;
- }
}
}
snd_rme96_setframelog(rme96, params_channels(params), 0);
if (rme96->playback_periodsize != 0) {
if (params_period_size(params) << rme96->capture_frlog !=
rme96->playback_periodsize)
- {
- spin_unlock_irq(&rme96->lock);
return -EBUSY;
- }
}
rme96->capture_periodsize =
params_period_size(params) << rme96->capture_frlog;
snd_rme96_set_period_properties(rme96, rme96->capture_periodsize);
- spin_unlock_irq(&rme96->lock);
return 0;
}
@@ -1165,15 +1150,13 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->wcreg &= ~RME96_WCR_ADAT;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- rme96->playback_substream = substream;
- spin_unlock_irq(&rme96->lock);
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ if (rme96->playback_substream)
+ return -EBUSY;
+ rme96->wcreg &= ~RME96_WCR_ADAT;
+ writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+ rme96->playback_substream = substream;
+ }
runtime->hw = snd_rme96_playback_spdif_info;
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
@@ -1215,13 +1198,11 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
}
}
- spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->capture_substream = substream;
- spin_unlock_irq(&rme96->lock);
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ if (rme96->capture_substream)
+ return -EBUSY;
+ rme96->capture_substream = substream;
+ }
rme96_set_buffer_size_constraint(rme96, runtime);
return 0;
@@ -1235,15 +1216,13 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_set_sync(substream);
- spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->wcreg |= RME96_WCR_ADAT;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- rme96->playback_substream = substream;
- spin_unlock_irq(&rme96->lock);
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ if (rme96->playback_substream)
+ return -EBUSY;
+ rme96->wcreg |= RME96_WCR_ADAT;
+ writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+ rme96->playback_substream = substream;
+ }
runtime->hw = snd_rme96_playback_adat_info;
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
@@ -1285,13 +1264,11 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
runtime->hw.rate_max = rate;
}
- spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->capture_substream = substream;
- spin_unlock_irq(&rme96->lock);
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ if (rme96->capture_substream)
+ return -EBUSY;
+ rme96->capture_substream = substream;
+ }
rme96_set_buffer_size_constraint(rme96, runtime);
return 0;
@@ -1303,14 +1280,13 @@ snd_rme96_playback_close(struct snd_pcm_substream *substream)
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
int spdif = 0;
- spin_lock_irq(&rme96->lock);
- if (RME96_ISPLAYING(rme96)) {
- snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
+ scoped_guard(spinlock_irq, &rme96->lock) {
+ if (RME96_ISPLAYING(rme96))
+ snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
+ rme96->playback_substream = NULL;
+ rme96->playback_periodsize = 0;
+ spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
}
- rme96->playback_substream = NULL;
- rme96->playback_periodsize = 0;
- spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
- spin_unlock_irq(&rme96->lock);
if (spdif) {
rme96->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -1324,13 +1300,12 @@ snd_rme96_capture_close(struct snd_pcm_substream *substream)
{
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
if (RME96_ISRECORDING(rme96)) {
snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
}
rme96->capture_substream = NULL;
rme96->capture_periodsize = 0;
- spin_unlock_irq(&rme96->lock);
return 0;
}
@@ -1339,12 +1314,11 @@ snd_rme96_playback_prepare(struct snd_pcm_substream *substream)
{
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
if (RME96_ISPLAYING(rme96)) {
snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
}
writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
- spin_unlock_irq(&rme96->lock);
return 0;
}
@@ -1353,12 +1327,11 @@ snd_rme96_capture_prepare(struct snd_pcm_substream *substream)
{
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
if (RME96_ISRECORDING(rme96)) {
snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
}
writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
- spin_unlock_irq(&rme96->lock);
return 0;
}
@@ -1829,9 +1802,8 @@ snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;
- spin_unlock_irq(&rme96->lock);
return 0;
}
static int
@@ -1842,12 +1814,11 @@ snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
int change;
val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
val = (rme96->wcreg & ~RME96_WCR_SEL) | val;
change = val != rme96->wcreg;
rme96->wcreg = val;
writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -1893,7 +1864,7 @@ snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
unsigned int items = 3;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
switch (rme96->pci->device) {
@@ -1923,7 +1894,6 @@ snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
ucontrol->value.enumerated.item[0] = items - 1;
}
- spin_unlock_irq(&rme96->lock);
return 0;
}
static int
@@ -1961,10 +1931,9 @@ snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
}
}
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = (int)val != snd_rme96_getinputtype(rme96);
snd_rme96_setinputtype(rme96, val);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -1980,9 +1949,8 @@ snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
{
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);
- spin_unlock_irq(&rme96->lock);
return 0;
}
static int
@@ -1993,10 +1961,9 @@ snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
int change;
val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = (int)val != snd_rme96_getclockmode(rme96);
snd_rme96_setclockmode(rme96, val);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -2014,9 +1981,8 @@ snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_
{
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);
- spin_unlock_irq(&rme96->lock);
return 0;
}
static int
@@ -2027,11 +1993,10 @@ snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_
int change;
val = ucontrol->value.enumerated.item[0] % 4;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = (int)val != snd_rme96_getattenuation(rme96);
snd_rme96_setattenuation(rme96, val);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -2047,9 +2012,8 @@ snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
{
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);
- spin_unlock_irq(&rme96->lock);
return 0;
}
static int
@@ -2060,10 +2024,9 @@ snd_rme96_put_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el
int change;
val = ucontrol->value.enumerated.item[0] % 4;
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = (int)val != snd_rme96_getmontracks(rme96);
snd_rme96_setmontracks(rme96, val);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -2111,10 +2074,9 @@ static int snd_rme96_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd
u32 val;
val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = val != rme96->wcreg_spdif;
rme96->wcreg_spdif = val;
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -2140,13 +2102,12 @@ static int snd_rme96_control_spdif_stream_put(struct snd_kcontrol *kcontrol, str
u32 val;
val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
change = val != rme96->wcreg_spdif_stream;
rme96->wcreg_spdif_stream = val;
rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
rme96->wcreg |= val;
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme96->lock);
return change;
}
@@ -2180,10 +2141,9 @@ snd_rme96_dac_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
u->value.integer.value[0] = rme96->vol[0];
u->value.integer.value[1] = rme96->vol[1];
- spin_unlock_irq(&rme96->lock);
return 0;
}
@@ -2199,7 +2159,7 @@ snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
if (!RME96_HAS_ANALOG_OUT(rme96))
return -EINVAL;
maxvol = RME96_185X_MAX_OUT(rme96);
- spin_lock_irq(&rme96->lock);
+ guard(spinlock_irq)(&rme96->lock);
vol = u->value.integer.value[0];
if (vol != rme96->vol[0] && vol <= maxvol) {
rme96->vol[0] = vol;
@@ -2212,7 +2172,6 @@ snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
}
if (change)
snd_rme96_apply_dac_volume(rme96);
- spin_unlock_irq(&rme96->lock);
return change;
}
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7ce73746168a..31cc2d91c8d2 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -691,7 +691,6 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
int i;
- unsigned long flags;
const u32 *cache;
if (hdsp->fw_uploaded)
@@ -746,9 +745,8 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
if (hdsp->state & HDSP_InitializationComplete) {
dev_info(hdsp->card->dev,
"firmware loaded from cache, restoring defaults\n");
- spin_lock_irqsave(&hdsp->lock, flags);
+ guard(spinlock_irqsave)(&hdsp->lock);
snd_hdsp_set_defaults(hdsp);
- spin_unlock_irqrestore(&hdsp->lock, flags);
}
hdsp->state |= HDSP_FirmwareLoaded;
@@ -939,14 +937,12 @@ static int hdsp_write_gain(struct hdsp *hdsp, unsigned int addr, unsigned short
static int snd_hdsp_use_is_exclusive(struct hdsp *hdsp)
{
- unsigned long flags;
int ret = 1;
- spin_lock_irqsave(&hdsp->lock, flags);
+ guard(spinlock_irqsave)(&hdsp->lock);
if ((hdsp->playback_pid != hdsp->capture_pid) &&
(hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
ret = 0;
- spin_unlock_irqrestore(&hdsp->lock, flags);
return ret;
}
@@ -1063,8 +1059,6 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
{
int n;
- spin_lock_irq(&s->lock);
-
frames >>= 7;
n = 0;
while (frames) {
@@ -1079,8 +1073,6 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
hdsp_compute_period_size(s);
- spin_unlock_irq(&s->lock);
-
return 0;
}
@@ -1306,7 +1298,6 @@ static void snd_hdsp_flush_midi_input (struct hdsp *hdsp, int id)
static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
{
- unsigned long flags;
int n_pending;
int to_write;
int i;
@@ -1314,7 +1305,7 @@ static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
/* Output is not interrupt driven */
- spin_lock_irqsave (&hmidi->lock, flags);
+ guard(spinlock_irqsave)(&hmidi->lock);
if (hmidi->output) {
if (!snd_rawmidi_transmit_empty (hmidi->output)) {
n_pending = snd_hdsp_midi_output_possible(hmidi->hdsp, hmidi->id);
@@ -1330,40 +1321,38 @@ static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
}
}
}
- spin_unlock_irqrestore (&hmidi->lock, flags);
return 0;
}
static int snd_hdsp_midi_input_read (struct hdsp_midi *hmidi)
{
unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
- unsigned long flags;
int n_pending;
int i;
- spin_lock_irqsave (&hmidi->lock, flags);
- n_pending = snd_hdsp_midi_input_available(hmidi->hdsp, hmidi->id);
- if (n_pending > 0) {
- if (hmidi->input) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
- for (i = 0; i < n_pending; ++i)
- buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- if (n_pending)
- snd_rawmidi_receive (hmidi->input, buf, n_pending);
- } else {
- /* flush the MIDI input FIFO */
- while (--n_pending)
- snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
+ scoped_guard(spinlock_irqsave, &hmidi->lock) {
+ n_pending = snd_hdsp_midi_input_available(hmidi->hdsp, hmidi->id);
+ if (n_pending > 0) {
+ if (hmidi->input) {
+ if (n_pending > (int)sizeof(buf))
+ n_pending = sizeof(buf);
+ for (i = 0; i < n_pending; ++i)
+ buf[i] = snd_hdsp_midi_read_byte(hmidi->hdsp, hmidi->id);
+ if (n_pending)
+ snd_rawmidi_receive(hmidi->input, buf, n_pending);
+ } else {
+ /* flush the MIDI input FIFO */
+ while (--n_pending)
+ snd_hdsp_midi_read_byte(hmidi->hdsp, hmidi->id);
+ }
}
+ hmidi->pending = 0;
+ if (hmidi->id)
+ hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
+ else
+ hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
+ hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
}
- hmidi->pending = 0;
- if (hmidi->id)
- hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
- else
- hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
- hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
- spin_unlock_irqrestore (&hmidi->lock, flags);
return snd_hdsp_midi_output_write (hmidi);
}
@@ -1371,13 +1360,12 @@ static void snd_hdsp_midi_input_trigger(struct snd_rawmidi_substream *substream,
{
struct hdsp *hdsp;
struct hdsp_midi *hmidi;
- unsigned long flags;
u32 ie;
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
hdsp = hmidi->hdsp;
ie = hmidi->id ? HDSP_Midi1InterruptEnable : HDSP_Midi0InterruptEnable;
- spin_lock_irqsave (&hdsp->lock, flags);
+ guard(spinlock_irqsave)(&hdsp->lock);
if (up) {
if (!(hdsp->control_register & ie)) {
snd_hdsp_flush_midi_input (hdsp, hmidi->id);
@@ -1388,16 +1376,14 @@ static void snd_hdsp_midi_input_trigger(struct snd_rawmidi_substream *substream,
}
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- spin_unlock_irqrestore (&hdsp->lock, flags);
}
static void snd_hdsp_midi_output_timer(struct timer_list *t)
{
struct hdsp_midi *hmidi = timer_container_of(hmidi, t, timer);
- unsigned long flags;
snd_hdsp_midi_output_write(hmidi);
- spin_lock_irqsave (&hmidi->lock, flags);
+ guard(spinlock_irqsave)(&hmidi->lock);
/* this does not bump hmidi->istimer, because the
kernel automatically removed the timer when it
@@ -1407,29 +1393,26 @@ static void snd_hdsp_midi_output_timer(struct timer_list *t)
if (hmidi->istimer)
mod_timer(&hmidi->timer, 1 + jiffies);
-
- spin_unlock_irqrestore (&hmidi->lock, flags);
}
static void snd_hdsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct hdsp_midi *hmidi;
- unsigned long flags;
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irqsave (&hmidi->lock, flags);
- if (up) {
- if (!hmidi->istimer) {
- timer_setup(&hmidi->timer, snd_hdsp_midi_output_timer,
- 0);
- mod_timer(&hmidi->timer, 1 + jiffies);
- hmidi->istimer++;
+ scoped_guard(spinlock_irqsave, &hmidi->lock) {
+ if (up) {
+ if (!hmidi->istimer) {
+ timer_setup(&hmidi->timer, snd_hdsp_midi_output_timer,
+ 0);
+ mod_timer(&hmidi->timer, 1 + jiffies);
+ hmidi->istimer++;
+ }
+ } else {
+ if (hmidi->istimer && --hmidi->istimer <= 0)
+ timer_delete(&hmidi->timer);
}
- } else {
- if (hmidi->istimer && --hmidi->istimer <= 0)
- timer_delete(&hmidi->timer);
}
- spin_unlock_irqrestore (&hmidi->lock, flags);
if (up)
snd_hdsp_midi_output_write(hmidi);
}
@@ -1439,10 +1422,9 @@ static int snd_hdsp_midi_input_open(struct snd_rawmidi_substream *substream)
struct hdsp_midi *hmidi;
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id);
hmidi->input = substream;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -1452,9 +1434,8 @@ static int snd_hdsp_midi_output_open(struct snd_rawmidi_substream *substream)
struct hdsp_midi *hmidi;
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->output = substream;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -1466,9 +1447,8 @@ static int snd_hdsp_midi_input_close(struct snd_rawmidi_substream *substream)
snd_hdsp_midi_input_trigger (substream, 0);
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->input = NULL;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -1480,9 +1460,8 @@ static int snd_hdsp_midi_output_close(struct snd_rawmidi_substream *substream)
snd_hdsp_midi_output_trigger (substream, 0);
hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->output = NULL;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -1579,10 +1558,9 @@ static int snd_hdsp_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_
u32 val;
val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = val != hdsp->creg_spdif;
hdsp->creg_spdif = val;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -1608,12 +1586,11 @@ static int snd_hdsp_control_spdif_stream_put(struct snd_kcontrol *kcontrol, stru
u32 val;
val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = val != hdsp->creg_spdif_stream;
hdsp->creg_spdif_stream = val;
hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -1679,11 +1656,10 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = val != hdsp_spdif_in(hdsp);
if (change)
hdsp_set_spdif_input(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -1720,9 +1696,8 @@ static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol,
struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
u32 regmask = kcontrol->private_value;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask);
- spin_unlock_irq(&hdsp->lock);
return 0;
}
@@ -1737,11 +1712,10 @@ static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol,
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int) val != hdsp_toggle_setting(hdsp, regmask);
if (change)
hdsp_set_toggle_setting(hdsp, regmask, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2047,12 +2021,11 @@ static int snd_hdsp_put_clock_source(struct snd_kcontrol *kcontrol, struct snd_c
if (val > 6)
val = 6;
}
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_clock_source(hdsp))
change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2147,12 +2120,11 @@ static int snd_hdsp_put_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_el
val = ucontrol->value.enumerated.item[0];
if (val < 0) val = 0;
if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_da_gain(hdsp))
change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2226,12 +2198,11 @@ static int snd_hdsp_put_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_el
val = ucontrol->value.enumerated.item[0];
if (val < 0) val = 0;
if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_ad_gain(hdsp))
change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2305,12 +2276,11 @@ static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl
val = ucontrol->value.enumerated.item[0];
if (val < 0) val = 0;
if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_phone_gain(hdsp))
change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2436,10 +2406,9 @@ static int snd_hdsp_put_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_
}
val = ucontrol->value.enumerated.item[0] % max;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int)val != hdsp_pref_sync_ref(hdsp);
hdsp_set_pref_sync_ref(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2519,9 +2488,8 @@ static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct sn
{
struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
ucontrol->value.integer.value[0] = hdsp->precise_ptr;
- spin_unlock_irq(&hdsp->lock);
return 0;
}
@@ -2534,10 +2502,9 @@ static int snd_hdsp_put_precise_pointer(struct snd_kcontrol *kcontrol, struct sn
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int)val != hdsp->precise_ptr;
hdsp_set_precise_pointer(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2565,9 +2532,8 @@ static int snd_hdsp_get_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_
{
struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
ucontrol->value.integer.value[0] = hdsp->use_midi_work;
- spin_unlock_irq(&hdsp->lock);
return 0;
}
@@ -2580,10 +2546,9 @@ static int snd_hdsp_put_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int)val != hdsp->use_midi_work;
hdsp_set_use_midi_work(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2624,9 +2589,8 @@ static int snd_hdsp_get_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
else
addr = hdsp_input_to_output_key(hdsp,source, destination);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
- spin_unlock_irq(&hdsp->lock);
return 0;
}
@@ -2652,11 +2616,10 @@ static int snd_hdsp_put_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
gain = ucontrol->value.integer.value[2];
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = gain != hdsp_read_gain(hdsp, addr);
if (change)
hdsp_write_gain(hdsp, addr, gain);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2869,12 +2832,11 @@ static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0];
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_dds_offset(hdsp))
change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -3018,12 +2980,11 @@ static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ct
val = 0;
if (val > 4)
val = 4;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_rpm_input12(hdsp))
change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -3103,12 +3064,11 @@ static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ct
val = 0;
if (val > 4)
val = 4;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (val != hdsp_rpm_input34(hdsp))
change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -3149,10 +3109,9 @@ static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int)val != hdsp_rpm_bypass(hdsp);
hdsp_set_rpm_bypass(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -3201,10 +3160,9 @@ static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd
if (!snd_hdsp_use_is_exclusive(hdsp))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
change = (int)val != hdsp_rpm_disconnect(hdsp);
hdsp_set_rpm_disconnect(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -4051,7 +4009,7 @@ static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
@@ -4071,39 +4029,31 @@ static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
*/
if (params_rate(params) != hdsp->system_sample_rate) {
- spin_unlock_irq(&hdsp->lock);
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
return -EBUSY;
}
if (params_period_size(params) != hdsp->period_bytes / 4) {
- spin_unlock_irq(&hdsp->lock);
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return -EBUSY;
}
/* We're fine. */
- spin_unlock_irq(&hdsp->lock);
return 0;
- } else {
- spin_unlock_irq(&hdsp->lock);
}
/* how to make sure that the rate matches an externally-set one ?
*/
- spin_lock_irq(&hdsp->lock);
if (! hdsp->clock_source_locked) {
err = hdsp_set_rate(hdsp, params_rate(params), 0);
if (err < 0) {
- spin_unlock_irq(&hdsp->lock);
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
return err;
}
}
- spin_unlock_irq(&hdsp->lock);
err = hdsp_set_interrupt_interval(hdsp, params_period_size(params));
if (err < 0) {
@@ -4160,7 +4110,7 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
if (hdsp_check_for_firmware(hdsp, 0)) /* no auto-loading in trigger */
return -EIO;
- spin_lock(&hdsp->lock);
+ guard(spinlock)(&hdsp->lock);
running = hdsp->running;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -4171,7 +4121,6 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
break;
default:
snd_BUG();
- spin_unlock(&hdsp->lock);
return -EINVAL;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -4211,7 +4160,6 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
else if (hdsp->running && !running)
hdsp_stop_audio(hdsp);
hdsp->running = running;
- spin_unlock(&hdsp->lock);
return 0;
}
@@ -4227,10 +4175,9 @@ static int snd_hdsp_prepare(struct snd_pcm_substream *substream)
if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
if (!hdsp->running)
hdsp_reset_hw_pointer(hdsp);
- spin_unlock_irq(&hdsp->lock);
return result;
}
@@ -4473,17 +4420,15 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- spin_lock_irq(&hdsp->lock);
+ scoped_guard(spinlock_irq, &hdsp->lock) {
+ snd_pcm_set_sync(substream);
- snd_pcm_set_sync(substream);
+ runtime->hw = snd_hdsp_playback_subinfo;
+ snd_pcm_set_runtime_buffer(substream, &hdsp->playback_dma_buf);
- runtime->hw = snd_hdsp_playback_subinfo;
- snd_pcm_set_runtime_buffer(substream, &hdsp->playback_dma_buf);
-
- hdsp->playback_pid = current->pid;
- hdsp->playback_substream = substream;
-
- spin_unlock_irq(&hdsp->lock);
+ hdsp->playback_pid = current->pid;
+ hdsp->playback_substream = substream;
+ }
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
@@ -4523,12 +4468,10 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
{
struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- spin_lock_irq(&hdsp->lock);
-
- hdsp->playback_pid = -1;
- hdsp->playback_substream = NULL;
-
- spin_unlock_irq(&hdsp->lock);
+ scoped_guard(spinlock_irq, &hdsp->lock) {
+ hdsp->playback_pid = -1;
+ hdsp->playback_substream = NULL;
+ }
if (RPM != hdsp->io_type) {
hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
@@ -4550,17 +4493,15 @@ static int snd_hdsp_capture_open(struct snd_pcm_substream *substream)
if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- spin_lock_irq(&hdsp->lock);
-
- snd_pcm_set_sync(substream);
+ scoped_guard(spinlock_irq, &hdsp->lock) {
+ snd_pcm_set_sync(substream);
- runtime->hw = snd_hdsp_capture_subinfo;
- snd_pcm_set_runtime_buffer(substream, &hdsp->capture_dma_buf);
+ runtime->hw = snd_hdsp_capture_subinfo;
+ snd_pcm_set_runtime_buffer(substream, &hdsp->capture_dma_buf);
- hdsp->capture_pid = current->pid;
- hdsp->capture_substream = substream;
-
- spin_unlock_irq(&hdsp->lock);
+ hdsp->capture_pid = current->pid;
+ hdsp->capture_substream = substream;
+ }
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
@@ -4588,12 +4529,11 @@ static int snd_hdsp_capture_release(struct snd_pcm_substream *substream)
{
struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- spin_lock_irq(&hdsp->lock);
+ guard(spinlock_irq)(&hdsp->lock);
hdsp->capture_pid = -1;
hdsp->capture_substream = NULL;
- spin_unlock_irq(&hdsp->lock);
return 0;
}
@@ -4756,7 +4696,6 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
}
case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
struct hdsp_config_info info;
- unsigned long flags;
int i;
err = hdsp_check_for_iobox(hdsp);
@@ -4768,48 +4707,48 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
return err;
memset(&info, 0, sizeof(info));
- spin_lock_irqsave(&hdsp->lock, flags);
- info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
- info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
- if (hdsp->io_type != H9632)
- info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
- info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
- info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
- info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
- info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp,
- HDSP_SPDIFOpticalOut);
- info.spdif_professional = (unsigned char)
- hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional);
- info.spdif_emphasis = (unsigned char)
- hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis);
- info.spdif_nonaudio = (unsigned char)
- hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio);
- info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
- info.system_sample_rate = hdsp->system_sample_rate;
- info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
- info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
- info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
- info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
- info.line_out = (unsigned char)
- hdsp_toggle_setting(hdsp, HDSP_LineOut);
- if (hdsp->io_type == H9632) {
- info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
- info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
- info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
- info.xlr_breakout_cable =
- (unsigned char)hdsp_toggle_setting(hdsp,
- HDSP_XLRBreakoutCable);
-
- } else if (hdsp->io_type == RPM) {
- info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
- info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
+ scoped_guard(spinlock_irqsave, &hdsp->lock) {
+ info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
+ info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
+ if (hdsp->io_type != H9632)
+ info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
+ info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
+ for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
+ info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
+ info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
+ info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp,
+ HDSP_SPDIFOpticalOut);
+ info.spdif_professional = (unsigned char)
+ hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional);
+ info.spdif_emphasis = (unsigned char)
+ hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis);
+ info.spdif_nonaudio = (unsigned char)
+ hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio);
+ info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
+ info.system_sample_rate = hdsp->system_sample_rate;
+ info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
+ info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
+ info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
+ info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
+ info.line_out = (unsigned char)
+ hdsp_toggle_setting(hdsp, HDSP_LineOut);
+ if (hdsp->io_type == H9632) {
+ info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
+ info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
+ info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
+ info.xlr_breakout_cable =
+ (unsigned char)hdsp_toggle_setting(hdsp,
+ HDSP_XLRBreakoutCable);
+
+ } else if (hdsp->io_type == RPM) {
+ info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
+ info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
+ }
+ if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
+ info.analog_extension_board =
+ (unsigned char)hdsp_toggle_setting(hdsp,
+ HDSP_AnalogExtensionBoard);
}
- if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
- info.analog_extension_board =
- (unsigned char)hdsp_toggle_setting(hdsp,
- HDSP_AnalogExtensionBoard);
- spin_unlock_irqrestore(&hdsp->lock, flags);
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
break;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index a0976824beda..3ba5bdc96d9d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1204,16 +1204,11 @@ static inline void snd_hdspm_enable_out(struct hdspm * hdspm, int i, int v)
/* check if same process is writing and reading */
static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&hdspm->lock, flags);
+ guard(spinlock_irqsave)(&hdspm->lock);
if ((hdspm->playback_pid != hdspm->capture_pid) &&
- (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0)) {
- ret = 0;
- }
- spin_unlock_irqrestore(&hdspm->lock, flags);
- return ret;
+ (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0))
+ return 0;
+ return 1;
}
/* round arbitrary sample rates to commonly known rates */
@@ -1527,7 +1522,7 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
{
int n;
- spin_lock_irq(&s->lock);
+ guard(spinlock_irq)(&s->lock);
if (32 == frames) {
/* Special case for new RME cards like RayDAT/AIO which
@@ -1557,8 +1552,6 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
hdspm_compute_period_size(s);
- spin_unlock_irq(&s->lock);
-
return 0;
}
@@ -1846,7 +1839,6 @@ static void snd_hdspm_flush_midi_input(struct hdspm *hdspm, int id)
static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
{
- unsigned long flags;
int n_pending;
int to_write;
int i;
@@ -1854,7 +1846,7 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
/* Output is not interrupt driven */
- spin_lock_irqsave (&hmidi->lock, flags);
+ guard(spinlock_irqsave)(&hmidi->lock);
if (hmidi->output &&
!snd_rawmidi_transmit_empty (hmidi->output)) {
n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm,
@@ -1873,7 +1865,6 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
}
}
}
- spin_unlock_irqrestore (&hmidi->lock, flags);
return 0;
}
@@ -1882,37 +1873,36 @@ static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
unsigned char buf[128]; /* this buffer is designed to match the MIDI
* input FIFO size
*/
- unsigned long flags;
int n_pending;
int i;
- spin_lock_irqsave (&hmidi->lock, flags);
- n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id);
- if (n_pending > 0) {
- if (hmidi->input) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
- for (i = 0; i < n_pending; ++i)
- buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm,
- hmidi->id);
- if (n_pending)
- snd_rawmidi_receive (hmidi->input, buf,
- n_pending);
- } else {
- /* flush the MIDI input FIFO */
- while (n_pending--)
- snd_hdspm_midi_read_byte (hmidi->hdspm,
- hmidi->id);
+ scoped_guard(spinlock_irqsave, &hmidi->lock) {
+ n_pending = snd_hdspm_midi_input_available(hmidi->hdspm, hmidi->id);
+ if (n_pending > 0) {
+ if (hmidi->input) {
+ if (n_pending > (int)sizeof(buf))
+ n_pending = sizeof(buf);
+ for (i = 0; i < n_pending; ++i)
+ buf[i] = snd_hdspm_midi_read_byte(hmidi->hdspm,
+ hmidi->id);
+ if (n_pending)
+ snd_rawmidi_receive(hmidi->input, buf,
+ n_pending);
+ } else {
+ /* flush the MIDI input FIFO */
+ while (n_pending--)
+ snd_hdspm_midi_read_byte(hmidi->hdspm,
+ hmidi->id);
+ }
}
+ hmidi->pending = 0;
}
- hmidi->pending = 0;
- spin_unlock_irqrestore(&hmidi->lock, flags);
- spin_lock_irqsave(&hmidi->hdspm->lock, flags);
- hmidi->hdspm->control_register |= hmidi->ie;
- hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
- hmidi->hdspm->control_register);
- spin_unlock_irqrestore(&hmidi->hdspm->lock, flags);
+ scoped_guard(spinlock_irqsave, &hmidi->hdspm->lock) {
+ hmidi->hdspm->control_register |= hmidi->ie;
+ hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
+ hmidi->hdspm->control_register);
+ }
return snd_hdspm_midi_output_write (hmidi);
}
@@ -1922,12 +1912,11 @@ snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct hdspm *hdspm;
struct hdspm_midi *hmidi;
- unsigned long flags;
hmidi = substream->rmidi->private_data;
hdspm = hmidi->hdspm;
- spin_lock_irqsave (&hdspm->lock, flags);
+ guard(spinlock_irqsave)(&hdspm->lock);
if (up) {
if (!(hdspm->control_register & hmidi->ie)) {
snd_hdspm_flush_midi_input (hdspm, hmidi->id);
@@ -1938,16 +1927,14 @@ snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
}
hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
- spin_unlock_irqrestore (&hdspm->lock, flags);
}
static void snd_hdspm_midi_output_timer(struct timer_list *t)
{
struct hdspm_midi *hmidi = timer_container_of(hmidi, t, timer);
- unsigned long flags;
snd_hdspm_midi_output_write(hmidi);
- spin_lock_irqsave (&hmidi->lock, flags);
+ guard(spinlock_irqsave)(&hmidi->lock);
/* this does not bump hmidi->istimer, because the
kernel automatically removed the timer when it
@@ -1957,30 +1944,27 @@ static void snd_hdspm_midi_output_timer(struct timer_list *t)
if (hmidi->istimer)
mod_timer(&hmidi->timer, 1 + jiffies);
-
- spin_unlock_irqrestore (&hmidi->lock, flags);
}
static void
snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct hdspm_midi *hmidi;
- unsigned long flags;
hmidi = substream->rmidi->private_data;
- spin_lock_irqsave (&hmidi->lock, flags);
- if (up) {
- if (!hmidi->istimer) {
- timer_setup(&hmidi->timer,
- snd_hdspm_midi_output_timer, 0);
- mod_timer(&hmidi->timer, 1 + jiffies);
- hmidi->istimer++;
+ scoped_guard(spinlock_irqsave, &hmidi->lock) {
+ if (up) {
+ if (!hmidi->istimer) {
+ timer_setup(&hmidi->timer,
+ snd_hdspm_midi_output_timer, 0);
+ mod_timer(&hmidi->timer, 1 + jiffies);
+ hmidi->istimer++;
+ }
+ } else {
+ if (hmidi->istimer && --hmidi->istimer <= 0)
+ timer_delete(&hmidi->timer);
}
- } else {
- if (hmidi->istimer && --hmidi->istimer <= 0)
- timer_delete(&hmidi->timer);
}
- spin_unlock_irqrestore (&hmidi->lock, flags);
if (up)
snd_hdspm_midi_output_write(hmidi);
}
@@ -1990,10 +1974,9 @@ static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
struct hdspm_midi *hmidi;
hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
hmidi->input = substream;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -2003,9 +1986,8 @@ static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
struct hdspm_midi *hmidi;
hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->output = substream;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -2017,9 +1999,8 @@ static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
snd_hdspm_midi_input_trigger (substream, 0);
hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->input = NULL;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -2031,9 +2012,8 @@ static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
snd_hdspm_midi_output_trigger (substream, 0);
hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
+ guard(spinlock_irq)(&hmidi->lock);
hmidi->output = NULL;
- spin_unlock_irq (&hmidi->lock);
return 0;
}
@@ -2671,12 +2651,11 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
val = 0;
if (val > 9)
val = 9;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
if (val != hdspm_clock_source(hdspm))
change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
else
change = 0;
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -2999,11 +2978,10 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
else if (val >= hdspm->texts_autosync_items)
val = hdspm->texts_autosync_items-1;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
if (val != hdspm_pref_sync_ref(hdspm))
change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3239,9 +3217,8 @@ static int snd_hdspm_get_toggle_setting(struct snd_kcontrol *kcontrol,
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
u32 regmask = kcontrol->private_value;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.integer.value[0] = hdspm_toggle_setting(hdspm, regmask);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3256,10 +3233,9 @@ static int snd_hdspm_put_toggle_setting(struct snd_kcontrol *kcontrol,
if (!snd_hdspm_use_is_exclusive(hdspm))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = (int) val != hdspm_toggle_setting(hdspm, regmask);
hdspm_set_toggle_setting(hdspm, regmask, val);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3301,9 +3277,8 @@ static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol,
{
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3317,10 +3292,9 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
if (!snd_hdspm_use_is_exclusive(hdspm))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = (int) val != hdspm_input_select(hdspm);
hdspm_set_input_select(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3363,9 +3337,8 @@ static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
{
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3379,10 +3352,9 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
if (!snd_hdspm_use_is_exclusive(hdspm))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = (int) val != hdspm_ds_wire(hdspm);
hdspm_set_ds_wire(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3436,9 +3408,8 @@ static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
{
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3456,10 +3427,9 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
val = 0;
if (val > 2)
val = 2;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = val != hdspm_qs_wire(hdspm);
hdspm_set_qs_wire(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3512,9 +3482,8 @@ static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol,
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
u32 regmask = kcontrol->private_value;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.enumerated.item[0] = hdspm_tristate(hdspm, regmask);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3534,10 +3503,9 @@ static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol,
if (val > 2)
val = 2;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = val != hdspm_tristate(hdspm, regmask);
hdspm_set_tristate(hdspm, val, regmask);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3590,9 +3558,8 @@ static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
{
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3610,10 +3577,9 @@ static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
val = 0;
if (val > 2)
val = 2;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change = val != hdspm_madi_speedmode(hdspm);
hdspm_set_madi_speedmode(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3659,7 +3625,7 @@ static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
else if (destination >= HDSPM_MAX_CHANNELS)
destination = HDSPM_MAX_CHANNELS - 1;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
if (source >= HDSPM_MAX_CHANNELS)
ucontrol->value.integer.value[2] =
hdspm_read_pb_gain(hdspm, destination,
@@ -3668,8 +3634,6 @@ static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[2] =
hdspm_read_in_gain(hdspm, destination, source);
- spin_unlock_irq(&hdspm->lock);
-
return 0;
}
@@ -3695,7 +3659,7 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
gain = ucontrol->value.integer.value[2];
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
if (source >= HDSPM_MAX_CHANNELS)
change = gain != hdspm_read_pb_gain(hdspm, destination,
@@ -3714,7 +3678,6 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
hdspm_write_in_gain(hdspm, destination, source,
gain);
}
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -3755,10 +3718,9 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
return -EINVAL;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
ucontrol->value.integer.value[0] =
(hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN;
- spin_unlock_irq(&hdspm->lock);
return 0;
}
@@ -3781,14 +3743,13 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64;
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
change =
gain != hdspm_read_pb_gain(hdspm, channel,
channel);
if (change)
hdspm_write_pb_gain(hdspm, channel, channel,
gain);
- spin_unlock_irq(&hdspm->lock);
return change;
}
@@ -5496,53 +5457,50 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
pid_t this_pid;
pid_t other_pid;
- spin_lock_irq(&hdspm->lock);
+ scoped_guard(spinlock_irq, &hdspm->lock) {
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- this_pid = hdspm->playback_pid;
- other_pid = hdspm->capture_pid;
- } else {
- this_pid = hdspm->capture_pid;
- other_pid = hdspm->playback_pid;
- }
+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ this_pid = hdspm->playback_pid;
+ other_pid = hdspm->capture_pid;
+ } else {
+ this_pid = hdspm->capture_pid;
+ other_pid = hdspm->playback_pid;
+ }
- if (other_pid > 0 && this_pid != other_pid) {
+ if (other_pid > 0 && this_pid != other_pid) {
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
+ /* The other stream is open, and not by the same
+ task as this one. Make sure that the parameters
+ that matter are the same.
+ */
- if (params_rate(params) != hdspm->system_sample_rate) {
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
- }
+ if (params_rate(params) != hdspm->system_sample_rate) {
+ _snd_pcm_hw_param_setempty(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ return -EBUSY;
+ }
- if (params_period_size(params) != hdspm->period_bytes / 4) {
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return -EBUSY;
- }
+ if (params_period_size(params) != hdspm->period_bytes / 4) {
+ _snd_pcm_hw_param_setempty(params,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+ return -EBUSY;
+ }
+ }
}
/* We're fine. */
- spin_unlock_irq(&hdspm->lock);
/* how to make sure that the rate matches an externally-set one ? */
- spin_lock_irq(&hdspm->lock);
- err = hdspm_set_rate(hdspm, params_rate(params), 0);
- if (err < 0) {
- dev_info(hdspm->card->dev, "err on hdspm_set_rate: %d\n", err);
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_RATE);
- return err;
+ scoped_guard(spinlock_irq, &hdspm->lock) {
+ err = hdspm_set_rate(hdspm, params_rate(params), 0);
+ if (err < 0) {
+ dev_info(hdspm->card->dev, "err on hdspm_set_rate: %d\n", err);
+ _snd_pcm_hw_param_setempty(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ return err;
+ }
}
- spin_unlock_irq(&hdspm->lock);
err = hdspm_set_interrupt_interval(hdspm,
params_period_size(params));
@@ -5750,7 +5708,7 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
struct snd_pcm_substream *other;
int running;
- spin_lock(&hdspm->lock);
+ guard(spinlock)(&hdspm->lock);
running = hdspm->running;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -5761,7 +5719,6 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
break;
default:
snd_BUG();
- spin_unlock(&hdspm->lock);
return -EINVAL;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -5802,7 +5759,6 @@ _ok:
else if (hdspm->running && !running)
hdspm_stop_audio(hdspm);
hdspm->running = running;
- spin_unlock(&hdspm->lock);
return 0;
}
@@ -6035,27 +5991,26 @@ static int snd_hdspm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- spin_lock_irq(&hdspm->lock);
- snd_pcm_set_sync(substream);
- runtime->hw = (playback) ? snd_hdspm_playback_subinfo :
- snd_hdspm_capture_subinfo;
+ scoped_guard(spinlock_irq, &hdspm->lock) {
+ snd_pcm_set_sync(substream);
+ runtime->hw = (playback) ? snd_hdspm_playback_subinfo :
+ snd_hdspm_capture_subinfo;
- if (playback) {
- if (!hdspm->capture_substream)
- hdspm_stop_audio(hdspm);
+ if (playback) {
+ if (!hdspm->capture_substream)
+ hdspm_stop_audio(hdspm);
- hdspm->playback_pid = current->pid;
- hdspm->playback_substream = substream;
- } else {
- if (!hdspm->playback_substream)
- hdspm_stop_audio(hdspm);
+ hdspm->playback_pid = current->pid;
+ hdspm->playback_substream = substream;
+ } else {
+ if (!hdspm->playback_substream)
+ hdspm_stop_audio(hdspm);
- hdspm->capture_pid = current->pid;
- hdspm->capture_substream = substream;
+ hdspm->capture_pid = current->pid;
+ hdspm->capture_substream = substream;
+ }
}
- spin_unlock_irq(&hdspm->lock);
-
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
@@ -6108,7 +6063,7 @@ static int snd_hdspm_release(struct snd_pcm_substream *substream)
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- spin_lock_irq(&hdspm->lock);
+ guard(spinlock_irq)(&hdspm->lock);
if (playback) {
hdspm->playback_pid = -1;
@@ -6118,8 +6073,6 @@ static int snd_hdspm_release(struct snd_pcm_substream *substream)
hdspm->capture_substream = NULL;
}
- spin_unlock_irq(&hdspm->lock);
-
return 0;
}
@@ -6242,19 +6195,19 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
case SNDRV_HDSPM_IOCTL_GET_CONFIG:
memset(&info, 0, sizeof(info));
- spin_lock_irq(&hdspm->lock);
- info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
- info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
-
- info.system_sample_rate = hdspm->system_sample_rate;
- info.autosync_sample_rate =
- hdspm_external_sample_rate(hdspm);
- info.system_clock_mode = hdspm_system_clock_mode(hdspm);
- info.clock_source = hdspm_clock_source(hdspm);
- info.autosync_ref = hdspm_autosync_ref(hdspm);
- info.line_out = hdspm_toggle_setting(hdspm, HDSPM_LineOut);
- info.passthru = 0;
- spin_unlock_irq(&hdspm->lock);
+ scoped_guard(spinlock_irq, &hdspm->lock) {
+ info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
+ info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
+
+ info.system_sample_rate = hdspm->system_sample_rate;
+ info.autosync_sample_rate =
+ hdspm_external_sample_rate(hdspm);
+ info.system_clock_mode = hdspm_system_clock_mode(hdspm);
+ info.clock_source = hdspm_clock_source(hdspm);
+ info.autosync_ref = hdspm_autosync_ref(hdspm);
+ info.line_out = hdspm_toggle_setting(hdspm, HDSPM_LineOut);
+ info.passthru = 0;
+ }
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
break;
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 7dc8e3777c37..3be30cb57a2e 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -308,16 +308,11 @@ static inline unsigned int rme9652_read(struct snd_rme9652 *rme9652, int reg)
static inline int snd_rme9652_use_is_exclusive(struct snd_rme9652 *rme9652)
{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&rme9652->lock, flags);
+ guard(spinlock_irqsave)(&rme9652->lock);
if ((rme9652->playback_pid != rme9652->capture_pid) &&
- (rme9652->playback_pid >= 0) && (rme9652->capture_pid >= 0)) {
- ret = 0;
- }
- spin_unlock_irqrestore(&rme9652->lock, flags);
- return ret;
+ (rme9652->playback_pid >= 0) && (rme9652->capture_pid >= 0))
+ return 0;
+ return 1;
}
static inline int rme9652_adat_sample_rate(struct snd_rme9652 *rme9652)
@@ -428,7 +423,7 @@ static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
int restart = 0;
int n;
- spin_lock_irq(&s->lock);
+ guard(spinlock_irq)(&s->lock);
restart = s->running;
if (restart)
@@ -451,8 +446,6 @@ static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
if (restart)
rme9652_start(s);
- spin_unlock_irq(&s->lock);
-
return 0;
}
@@ -477,7 +470,7 @@ static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
is to flag rate changes in the read/write routines.
*/
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
xrate = rme9652_adat_sample_rate(rme9652);
switch (rate) {
@@ -506,14 +499,11 @@ static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
rate = RME9652_DS | RME9652_freq;
break;
default:
- spin_unlock_irq(&rme9652->lock);
return -EINVAL;
}
- if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) {
- spin_unlock_irq(&rme9652->lock);
+ if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0))
return -EBUSY;
- }
restart = rme9652->running;
if (restart)
@@ -539,7 +529,6 @@ static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
}
}
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -798,10 +787,9 @@ static int snd_rme9652_control_spdif_put(struct snd_kcontrol *kcontrol, struct s
u32 val;
val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = val != rme9652->creg_spdif;
rme9652->creg_spdif = val;
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -827,12 +815,11 @@ static int snd_rme9652_control_spdif_stream_put(struct snd_kcontrol *kcontrol, s
u32 val;
val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = val != rme9652->creg_spdif_stream;
rme9652->creg_spdif_stream = val;
rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -897,9 +884,8 @@ static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ct
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -912,11 +898,10 @@ static int snd_rme9652_put_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ct
if (!snd_rme9652_use_is_exclusive(rme9652))
return -EBUSY;
val = ucontrol->value.enumerated.item[0] % 2;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = val != rme9652_adat1_in(rme9652);
if (change)
rme9652_set_adat1_input(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -961,9 +946,8 @@ static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ct
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -976,11 +960,10 @@ static int snd_rme9652_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ct
if (!snd_rme9652_use_is_exclusive(rme9652))
return -EBUSY;
val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = val != rme9652_spdif_in(rme9652);
if (change)
rme9652_set_spdif_input(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -1022,9 +1005,8 @@ static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_c
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -1037,10 +1019,9 @@ static int snd_rme9652_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_c
if (!snd_rme9652_use_is_exclusive(rme9652))
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = (int)val != rme9652_spdif_out(rme9652);
rme9652_set_spdif_output(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -1104,9 +1085,8 @@ static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_c
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -1117,10 +1097,9 @@ static int snd_rme9652_put_sync_mode(struct snd_kcontrol *kcontrol, struct snd_c
unsigned int val;
val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = (int)val != rme9652_sync_mode(rme9652);
rme9652_set_sync_mode(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -1193,9 +1172,8 @@ static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_c
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -1209,10 +1187,9 @@ static int snd_rme9652_put_sync_pref(struct snd_kcontrol *kcontrol, struct snd_c
return -EBUSY;
max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
val = ucontrol->value.enumerated.item[0] % max;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = (int)val != rme9652_sync_pref(rme9652);
rme9652_set_sync_pref(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return change;
}
@@ -1253,7 +1230,7 @@ static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_el
thru_bits |= 1 << chn;
}
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = thru_bits ^ rme9652->thru_bits;
if (change) {
for (chn = 0; chn < rme9652->ss_channels; ++chn) {
@@ -1262,7 +1239,6 @@ static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_el
rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));
}
}
- spin_unlock_irq(&rme9652->lock);
return !!change;
}
@@ -1278,9 +1254,8 @@ static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ct
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.integer.value[0] = rme9652->passthru;
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -1295,11 +1270,10 @@ static int snd_rme9652_put_passthru(struct snd_kcontrol *kcontrol, struct snd_ct
return -EBUSY;
val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
change = (ucontrol->value.integer.value[0] != rme9652->passthru);
if (change)
err = rme9652_set_passthru(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
return err ? err : change;
}
@@ -1324,9 +1298,8 @@ static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_
{
struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
- spin_unlock_irq(&rme9652->lock);
return 0;
}
@@ -1931,45 +1904,39 @@ static int snd_rme9652_hw_params(struct snd_pcm_substream *substream,
pid_t this_pid;
pid_t other_pid;
- spin_lock_irq(&rme9652->lock);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= rme9652->creg_spdif_stream);
- this_pid = rme9652->playback_pid;
- other_pid = rme9652->capture_pid;
- } else {
- this_pid = rme9652->capture_pid;
- other_pid = rme9652->playback_pid;
- }
-
- if ((other_pid > 0) && (this_pid != other_pid)) {
-
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
+ scoped_guard(spinlock_irq, &rme9652->lock) {
- if ((int)params_rate(params) !=
- rme9652_adat_sample_rate(rme9652)) {
- spin_unlock_irq(&rme9652->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
+ rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= rme9652->creg_spdif_stream);
+ this_pid = rme9652->playback_pid;
+ other_pid = rme9652->capture_pid;
+ } else {
+ this_pid = rme9652->capture_pid;
+ other_pid = rme9652->playback_pid;
}
- if (params_period_size(params) != rme9652->period_bytes / 4) {
- spin_unlock_irq(&rme9652->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return -EBUSY;
- }
+ if ((other_pid > 0) && (this_pid != other_pid)) {
- /* We're fine. */
+ /* The other stream is open, and not by the same
+ task as this one. Make sure that the parameters
+ that matter are the same.
+ */
- spin_unlock_irq(&rme9652->lock);
- return 0;
+ if ((int)params_rate(params) !=
+ rme9652_adat_sample_rate(rme9652)) {
+ _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
+ return -EBUSY;
+ }
- } else {
- spin_unlock_irq(&rme9652->lock);
+ if (params_period_size(params) != rme9652->period_bytes / 4) {
+ _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+ return -EBUSY;
+ }
+
+ /* We're fine. */
+ return 0;
+ }
}
/* how to make sure that the rate matches an externally-set one ?
@@ -2041,7 +2008,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
struct snd_pcm_substream *other;
int running;
- spin_lock(&rme9652->lock);
+
+ guard(spinlock)(&rme9652->lock);
running = rme9652->running;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -2052,7 +2020,6 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
break;
default:
snd_BUG();
- spin_unlock(&rme9652->lock);
return -EINVAL;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -2092,7 +2059,6 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
else if (rme9652->running && !running)
rme9652_stop(rme9652);
rme9652->running = running;
- spin_unlock(&rme9652->lock);
return 0;
}
@@ -2100,12 +2066,10 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
static int snd_rme9652_prepare(struct snd_pcm_substream *substream)
{
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- unsigned long flags;
- spin_lock_irqsave(&rme9652->lock, flags);
+ guard(spinlock_irqsave)(&rme9652->lock);
if (!rme9652->running)
rme9652_reset_hw_pointer(rme9652);
- spin_unlock_irqrestore(&rme9652->lock, flags);
return 0;
}
@@ -2226,23 +2190,21 @@ static int snd_rme9652_playback_open(struct snd_pcm_substream *substream)
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- spin_lock_irq(&rme9652->lock);
+ scoped_guard(spinlock_irq, &rme9652->lock) {
+ snd_pcm_set_sync(substream);
- snd_pcm_set_sync(substream);
+ runtime->hw = snd_rme9652_playback_subinfo;
+ snd_pcm_set_runtime_buffer(substream, &rme9652->playback_dma_buf);
- runtime->hw = snd_rme9652_playback_subinfo;
- snd_pcm_set_runtime_buffer(substream, &rme9652->playback_dma_buf);
+ if (rme9652->capture_substream == NULL) {
+ rme9652_stop(rme9652);
+ rme9652_set_thru(rme9652, -1, 0);
+ }
- if (rme9652->capture_substream == NULL) {
- rme9652_stop(rme9652);
- rme9652_set_thru(rme9652, -1, 0);
+ rme9652->playback_pid = current->pid;
+ rme9652->playback_substream = substream;
}
- rme9652->playback_pid = current->pid;
- rme9652->playback_substream = substream;
-
- spin_unlock_irq(&rme9652->lock);
-
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
@@ -2266,12 +2228,10 @@ static int snd_rme9652_playback_release(struct snd_pcm_substream *substream)
{
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme9652->lock);
-
- rme9652->playback_pid = -1;
- rme9652->playback_substream = NULL;
-
- spin_unlock_irq(&rme9652->lock);
+ scoped_guard(spinlock_irq, &rme9652->lock) {
+ rme9652->playback_pid = -1;
+ rme9652->playback_substream = NULL;
+ }
rme9652->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -2285,23 +2245,21 @@ static int snd_rme9652_capture_open(struct snd_pcm_substream *substream)
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- spin_lock_irq(&rme9652->lock);
+ scoped_guard(spinlock_irq, &rme9652->lock) {
+ snd_pcm_set_sync(substream);
- snd_pcm_set_sync(substream);
+ runtime->hw = snd_rme9652_capture_subinfo;
+ snd_pcm_set_runtime_buffer(substream, &rme9652->capture_dma_buf);
- runtime->hw = snd_rme9652_capture_subinfo;
- snd_pcm_set_runtime_buffer(substream, &rme9652->capture_dma_buf);
+ if (rme9652->playback_substream == NULL) {
+ rme9652_stop(rme9652);
+ rme9652_set_thru(rme9652, -1, 0);
+ }
- if (rme9652->playback_substream == NULL) {
- rme9652_stop(rme9652);
- rme9652_set_thru(rme9652, -1, 0);
+ rme9652->capture_pid = current->pid;
+ rme9652->capture_substream = substream;
}
- rme9652->capture_pid = current->pid;
- rme9652->capture_substream = substream;
-
- spin_unlock_irq(&rme9652->lock);
-
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
@@ -2320,12 +2278,11 @@ static int snd_rme9652_capture_release(struct snd_pcm_substream *substream)
{
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- spin_lock_irq(&rme9652->lock);
+ guard(spinlock_irq)(&rme9652->lock);
rme9652->capture_pid = -1;
rme9652->capture_substream = NULL;
- spin_unlock_irq(&rme9652->lock);
return 0;
}
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 3d7abcb31679..4be085d27712 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -383,9 +383,7 @@ static void __sis_unmap_silence(struct sis7019 *sis)
static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sis->voice_lock, flags);
+ guard(spinlock_irqsave)(&sis->voice_lock);
if (voice->timing) {
__sis_unmap_silence(sis);
voice->timing->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING |
@@ -393,7 +391,6 @@ static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
voice->timing = NULL;
}
voice->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING | VOICE_SYNC_TIMING);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
}
static struct voice *__sis_alloc_playback_voice(struct sis7019 *sis)
@@ -417,14 +414,8 @@ found_one:
static struct voice *sis_alloc_playback_voice(struct sis7019 *sis)
{
- struct voice *voice;
- unsigned long flags;
-
- spin_lock_irqsave(&sis->voice_lock, flags);
- voice = __sis_alloc_playback_voice(sis);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
-
- return voice;
+ guard(spinlock_irqsave)(&sis->voice_lock);
+ return __sis_alloc_playback_voice(sis);
}
static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
@@ -434,7 +425,6 @@ static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct voice *voice = runtime->private_data;
unsigned int period_size, buffer_size;
- unsigned long flags;
int needed;
/* If there are one or two periods per buffer, we don't need a
@@ -447,11 +437,11 @@ static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
period_size != (buffer_size / 2));
if (needed && !voice->timing) {
- spin_lock_irqsave(&sis->voice_lock, flags);
- voice->timing = __sis_alloc_playback_voice(sis);
- if (voice->timing)
- __sis_map_silence(sis);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
+ scoped_guard(spinlock_irqsave, &sis->voice_lock) {
+ voice->timing = __sis_alloc_playback_voice(sis);
+ if (voice->timing)
+ __sis_map_silence(sis);
+ }
if (!voice->timing)
return -ENOMEM;
voice->timing->substream = substream;
@@ -645,17 +635,16 @@ static int sis_capture_open(struct snd_pcm_substream *substream)
struct sis7019 *sis = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct voice *voice = &sis->capture_voice;
- unsigned long flags;
/* FIXME: The driver only supports recording from one channel
* at the moment, but it could support more.
*/
- spin_lock_irqsave(&sis->voice_lock, flags);
- if (voice->flags & VOICE_IN_USE)
- voice = NULL;
- else
- voice->flags |= VOICE_IN_USE;
- spin_unlock_irqrestore(&sis->voice_lock, flags);
+ scoped_guard(spinlock_irqsave, &sis->voice_lock) {
+ if (voice->flags & VOICE_IN_USE)
+ voice = NULL;
+ else
+ voice->flags |= VOICE_IN_USE;
+ }
if (!voice)
return -EAGAIN;
@@ -902,7 +891,7 @@ static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
/* Get the AC97 semaphore -- software first, so we don't spin
* pounding out IO reads on the hardware semaphore...
*/
- mutex_lock(&sis->ac97_mutex);
+ guard(mutex)(&sis->ac97_mutex);
count = 0xffff;
while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
@@ -941,8 +930,6 @@ static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
timeout_sema:
outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
timeout:
- mutex_unlock(&sis->ac97_mutex);
-
if (!count) {
dev_err(&sis->pci->dev, "ac97 codec %d timeout cmd 0x%08x\n",
codec, cmd);
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index f85a9556dacb..a4c72799d034 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -303,14 +303,11 @@ static void snd_sonicvibes_out(struct sonicvibes * sonic,
unsigned char reg,
unsigned char value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
outb(reg, SV_REG(sonic, INDEX));
udelay(10);
outb(value, SV_REG(sonic, DATA));
udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
}
static unsigned char snd_sonicvibes_in1(struct sonicvibes * sonic, unsigned char reg)
@@ -326,15 +323,13 @@ static unsigned char snd_sonicvibes_in1(struct sonicvibes * sonic, unsigned char
static unsigned char snd_sonicvibes_in(struct sonicvibes * sonic, unsigned char reg)
{
- unsigned long flags;
unsigned char value;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
outb(reg, SV_REG(sonic, INDEX));
udelay(10);
value = inb(SV_REG(sonic, DATA));
udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
return value;
}
@@ -448,9 +443,7 @@ static void snd_sonicvibes_setfmt(struct sonicvibes * sonic,
unsigned char mask,
unsigned char value)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
outb(SV_MCE | SV_IREG_DMA_DATA_FMT, SV_REG(sonic, INDEX));
if (mask) {
sonic->format = inb(SV_REG(sonic, DATA));
@@ -461,7 +454,6 @@ static void snd_sonicvibes_setfmt(struct sonicvibes * sonic,
udelay(10);
outb(0, SV_REG(sonic, INDEX));
udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
}
static void snd_sonicvibes_pll(unsigned int rate,
@@ -506,21 +498,18 @@ static void snd_sonicvibes_setpll(struct sonicvibes * sonic,
unsigned char reg,
unsigned int rate)
{
- unsigned long flags;
unsigned int r, m, n;
snd_sonicvibes_pll(rate, &r, &m, &n);
if (sonic != NULL) {
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
snd_sonicvibes_out1(sonic, reg, m);
snd_sonicvibes_out1(sonic, reg + 1, r | n);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
}
}
static void snd_sonicvibes_set_adc_rate(struct sonicvibes * sonic, unsigned int rate)
{
- unsigned long flags;
unsigned int div;
unsigned char clock;
@@ -533,10 +522,9 @@ static void snd_sonicvibes_set_adc_rate(struct sonicvibes * sonic, unsigned int
clock = 0x00;
snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, rate);
}
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4);
snd_sonicvibes_out1(sonic, SV_IREG_ADC_CLOCK, clock);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
}
static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params,
@@ -567,22 +555,18 @@ static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *param
static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate)
{
unsigned int div;
- unsigned long flags;
div = DIV_ROUND_CLOSEST(rate * 65536, SV_FULLRATE);
if (div > 65535)
div = 65535;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ guard(spinlock_irqsave)(&sonic->reg_lock);
snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
}
static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd)
{
- int result = 0;
-
- spin_lock(&sonic->reg_lock);
+ guard(spinlock)(&sonic->reg_lock);
if (cmd == SNDRV_PCM_TRIGGER_START) {
if (!(sonic->enable & what)) {
sonic->enable |= what;
@@ -594,10 +578,9 @@ static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd)
snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable);
}
} else {
- result = -EINVAL;
+ return -EINVAL;
}
- spin_unlock(&sonic->reg_lock);
- return result;
+ return 0;
}
static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id)
@@ -628,34 +611,34 @@ static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id)
unsigned char udreg;
int vol, oleft, oright, mleft, mright;
- spin_lock(&sonic->reg_lock);
- udreg = snd_sonicvibes_in1(sonic, SV_IREG_UD_BUTTON);
- vol = udreg & 0x3f;
- if (!(udreg & 0x40))
- vol = -vol;
- oleft = mleft = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ANALOG);
- oright = mright = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ANALOG);
- oleft &= 0x1f;
- oright &= 0x1f;
- oleft += vol;
- if (oleft < 0)
- oleft = 0;
- if (oleft > 0x1f)
- oleft = 0x1f;
- oright += vol;
- if (oright < 0)
- oright = 0;
- if (oright > 0x1f)
- oright = 0x1f;
- if (udreg & 0x80) {
- mleft ^= 0x80;
- mright ^= 0x80;
+ scoped_guard(spinlock, &sonic->reg_lock) {
+ udreg = snd_sonicvibes_in1(sonic, SV_IREG_UD_BUTTON);
+ vol = udreg & 0x3f;
+ if (!(udreg & 0x40))
+ vol = -vol;
+ oleft = mleft = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ANALOG);
+ oright = mright = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ANALOG);
+ oleft &= 0x1f;
+ oright &= 0x1f;
+ oleft += vol;
+ if (oleft < 0)
+ oleft = 0;
+ if (oleft > 0x1f)
+ oleft = 0x1f;
+ oright += vol;
+ if (oright < 0)
+ oright = 0;
+ if (oright > 0x1f)
+ oright = 0x1f;
+ if (udreg & 0x80) {
+ mleft ^= 0x80;
+ mright ^= 0x80;
+ }
+ oleft |= mleft & 0x80;
+ oright |= mright & 0x80;
+ snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ANALOG, oleft);
+ snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ANALOG, oright);
}
- oleft |= mleft & 0x80;
- oright |= mright & 0x80;
- snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ANALOG, oleft);
- snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ANALOG, oright);
- spin_unlock(&sonic->reg_lock);
snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id);
snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id);
}
@@ -696,11 +679,10 @@ static int snd_sonicvibes_playback_prepare(struct snd_pcm_substream *substream)
fmt |= 2;
snd_sonicvibes_setfmt(sonic, ~3, fmt);
snd_sonicvibes_set_dac_rate(sonic, runtime->rate);
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count);
- spin_unlock_irq(&sonic->reg_lock);
return 0;
}
@@ -721,11 +703,10 @@ static int snd_sonicvibes_capture_prepare(struct snd_pcm_substream *substream)
fmt |= 0x20;
snd_sonicvibes_setfmt(sonic, ~0x30, fmt);
snd_sonicvibes_set_adc_rate(sonic, runtime->rate);
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count);
- spin_unlock_irq(&sonic->reg_lock);
return 0;
}
@@ -894,10 +875,9 @@ static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_
{
struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
- spin_unlock_irq(&sonic->reg_lock);
return 0;
}
@@ -912,7 +892,7 @@ static int snd_sonicvibes_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_
return -EINVAL;
left = (ucontrol->value.enumerated.item[0] + 1) << 5;
right = (ucontrol->value.enumerated.item[1] + 1) << 5;
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC);
oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC);
left = (oval1 & ~SV_RECSRC_OUT) | left;
@@ -920,7 +900,6 @@ static int snd_sonicvibes_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_
change = left != oval1 || right != oval2;
snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left);
snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right);
- spin_unlock_irq(&sonic->reg_lock);
return change;
}
@@ -949,9 +928,8 @@ static int snd_sonicvibes_get_single(struct snd_kcontrol *kcontrol, struct snd_c
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask;
- spin_unlock_irq(&sonic->reg_lock);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
@@ -971,12 +949,11 @@ static int snd_sonicvibes_put_single(struct snd_kcontrol *kcontrol, struct snd_c
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
oval = snd_sonicvibes_in1(sonic, reg);
val = (oval & ~(mask << shift)) | val;
change = val != oval;
snd_sonicvibes_out1(sonic, reg, val);
- spin_unlock_irq(&sonic->reg_lock);
return change;
}
@@ -1007,10 +984,9 @@ static int snd_sonicvibes_get_double(struct snd_kcontrol *kcontrol, struct snd_c
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask;
ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask;
- spin_unlock_irq(&sonic->reg_lock);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
@@ -1038,7 +1014,7 @@ static int snd_sonicvibes_put_double(struct snd_kcontrol *kcontrol, struct snd_c
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irq(&sonic->reg_lock);
+ guard(spinlock_irq)(&sonic->reg_lock);
oval1 = snd_sonicvibes_in1(sonic, left_reg);
oval2 = snd_sonicvibes_in1(sonic, right_reg);
val1 = (oval1 & ~(mask << shift_left)) | val1;
@@ -1046,7 +1022,6 @@ static int snd_sonicvibes_put_double(struct snd_kcontrol *kcontrol, struct snd_c
change = val1 != oval1 || val2 != oval2;
snd_sonicvibes_out1(sonic, left_reg, val1);
snd_sonicvibes_out1(sonic, right_reg, val2);
- spin_unlock_irq(&sonic->reg_lock);
return change;
}
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;
}
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 0753c0c73f51..2b0f9e38863e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -628,7 +628,7 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id)
}
/* check status for each stream */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
for (i = 0; i < chip->num_devs; i++) {
struct viadev *viadev = &chip->devs[i];
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
@@ -652,7 +652,6 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id)
}
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
}
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
@@ -667,7 +666,7 @@ static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id)
int irqreturn = 0;
/* check status for each stream */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
status = inl(VIAREG(chip, SGD_SHADOW));
for (i = 0; i < chip->num_devs; i++) {
@@ -706,7 +705,6 @@ static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id)
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
irqreturn = 1;
}
- spin_unlock(&chip->reg_lock);
return IRQ_RETVAL(irqreturn);
}
@@ -833,7 +831,7 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
/* The via686a does not have the current index register,
* so we need to calculate the index from CURR_PTR.
@@ -845,7 +843,6 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
res = calc_linear_pos(chip, viadev, idx, count);
viadev->lastpos = res; /* remember the last position */
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
}
@@ -863,7 +860,7 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst
if (snd_BUG_ON(!viadev->tbl_entries))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
status = viadev->in_interrupt;
if (!status)
@@ -904,7 +901,6 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst
}
unlock:
viadev->lastpos = res;
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
}
@@ -997,7 +993,7 @@ static int via_lock_rate(struct via_rate_lock *rec, int rate)
{
int changed = 0;
- spin_lock_irq(&rec->lock);
+ guard(spinlock_irq)(&rec->lock);
if (rec->rate != rate) {
if (rec->rate && rec->used > 1) /* already set */
changed = -EINVAL;
@@ -1006,7 +1002,6 @@ static int via_lock_rate(struct via_rate_lock *rec, int rate)
changed = 1;
}
}
- spin_unlock_irq(&rec->lock);
return changed;
}
@@ -1167,33 +1162,33 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/* set the hw rate condition */
ratep = &chip->rates[viadev->direction];
- spin_lock_irq(&ratep->lock);
- ratep->used++;
- if (chip->spdif_on && viadev->reg_offset == 0x30) {
- /* DXS#3 and spdif is on */
- runtime->hw.rates = chip->ac97->rates[AC97_RATES_SPDIF];
- snd_pcm_limit_hw_rates(runtime);
- } else if (chip->dxs_fixed && viadev->reg_offset < 0x40) {
- /* fixed DXS playback rate */
- runtime->hw.rates = SNDRV_PCM_RATE_48000;
- runtime->hw.rate_min = runtime->hw.rate_max = 48000;
- } else if (chip->dxs_src && viadev->reg_offset < 0x40) {
- /* use full SRC capabilities of DXS */
- runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000);
- runtime->hw.rate_min = 8000;
- runtime->hw.rate_max = 48000;
- use_src = true;
- } else if (! ratep->rate) {
- int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
- runtime->hw.rates = chip->ac97->rates[idx];
- snd_pcm_limit_hw_rates(runtime);
- } else {
- /* a fixed rate */
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
+ scoped_guard(spinlock_irq, &ratep->lock) {
+ ratep->used++;
+ if (chip->spdif_on && viadev->reg_offset == 0x30) {
+ /* DXS#3 and spdif is on */
+ runtime->hw.rates = chip->ac97->rates[AC97_RATES_SPDIF];
+ snd_pcm_limit_hw_rates(runtime);
+ } else if (chip->dxs_fixed && viadev->reg_offset < 0x40) {
+ /* fixed DXS playback rate */
+ runtime->hw.rates = SNDRV_PCM_RATE_48000;
+ runtime->hw.rate_min = runtime->hw.rate_max = 48000;
+ } else if (chip->dxs_src && viadev->reg_offset < 0x40) {
+ /* use full SRC capabilities of DXS */
+ runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS |
+ SNDRV_PCM_RATE_8000_48000);
+ runtime->hw.rate_min = 8000;
+ runtime->hw.rate_max = 48000;
+ use_src = true;
+ } else if (!ratep->rate) {
+ int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
+ runtime->hw.rates = chip->ac97->rates[idx];
+ snd_pcm_limit_hw_rates(runtime);
+ } else {
+ /* a fixed rate */
+ runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
+ runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
+ }
}
- spin_unlock_irq(&ratep->lock);
/* we may remove following constaint when we modify table entries
in interrupt */
@@ -1311,11 +1306,11 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
/* release the rate lock */
ratep = &chip->rates[viadev->direction];
- spin_lock_irq(&ratep->lock);
- ratep->used--;
- if (! ratep->used)
- ratep->rate = 0;
- spin_unlock_irq(&ratep->lock);
+ scoped_guard(spinlock_irq, &ratep->lock) {
+ ratep->used--;
+ if (!ratep->used)
+ ratep->rate = 0;
+ }
if (! ratep->rate) {
if (! viadev->direction) {
snd_ac97_update_power(chip->ac97,
@@ -1606,14 +1601,13 @@ static int snd_via8233_capture_source_put(struct snd_kcontrol *kcontrol,
unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
u8 val, oval;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oval = inb(port);
val = oval & ~VIA_REG_CAPTURE_CHANNEL_MIC;
if (ucontrol->value.enumerated.item[0])
val |= VIA_REG_CAPTURE_CHANNEL_MIC;
if (val != oval)
outb(val, port);
- spin_unlock_irq(&chip->reg_lock);
return val != oval;
}
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 12a8c620724d..6ce2cd88cda6 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -483,7 +483,7 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id)
// _skip_sgd:
/* check status for each stream */
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
for (i = 0; i < chip->num_devs; i++) {
struct viadev *viadev = &chip->devs[i];
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
@@ -497,7 +497,6 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id)
}
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
}
- spin_unlock(&chip->reg_lock);
return IRQ_HANDLED;
}
@@ -616,7 +615,7 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
return 0;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
/* The via686a does not have the current index register,
* so we need to calculate the index from CURR_PTR.
@@ -628,7 +627,6 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) %
viadev->tbl_entries;
res = calc_linear_pos(chip, viadev, idx, count);
- spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
}
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 3e7e928b24f8..b6459dbdb1b0 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -868,10 +868,10 @@ static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
{
struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vx222 *chip = to_vx222(_chip);
- mutex_lock(&_chip->mixer_mutex);
+
+ guard(mutex)(&_chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->input_level[0];
ucontrol->value.integer.value[1] = chip->input_level[1];
- mutex_unlock(&_chip->mixer_mutex);
return 0;
}
@@ -885,16 +885,14 @@ static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
if (ucontrol->value.integer.value[1] < 0 ||
ucontrol->value.integer.value[1] > MIC_LEVEL_MAX)
return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
+ guard(mutex)(&_chip->mixer_mutex);
if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
chip->input_level[1] != ucontrol->value.integer.value[1]) {
chip->input_level[0] = ucontrol->value.integer.value[0];
chip->input_level[1] = ucontrol->value.integer.value[1];
vx2_set_input_level(chip);
- mutex_unlock(&_chip->mixer_mutex);
return 1;
}
- mutex_unlock(&_chip->mixer_mutex);
return 0;
}
@@ -923,14 +921,12 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
if (ucontrol->value.integer.value[0] < 0 ||
ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
+ guard(mutex)(&_chip->mixer_mutex);
if (chip->mic_level != ucontrol->value.integer.value[0]) {
chip->mic_level = ucontrol->value.integer.value[0];
vx2_set_input_level(chip);
- mutex_unlock(&_chip->mixer_mutex);
return 1;
}
- mutex_unlock(&_chip->mixer_mutex);
return 0;
}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 75e013b66c5b..eb373d9395e3 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -159,26 +159,21 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate)
static void snd_ymfpci_hw_start(struct snd_ymfpci *chip)
{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (chip->start_count++ > 0)
- goto __end;
+ return;
snd_ymfpci_writel(chip, YDSXGR_MODE,
snd_ymfpci_readl(chip, YDSXGR_MODE) | 3);
chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
- __end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip)
{
- unsigned long flags;
long timeout = 1000;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (--chip->start_count > 0)
- goto __end;
+ return;
snd_ymfpci_writel(chip, YDSXGR_MODE,
snd_ymfpci_readl(chip, YDSXGR_MODE) & ~3);
while (timeout-- > 0) {
@@ -189,8 +184,6 @@ static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip)
atomic_set(&chip->interrupt_sleep_count, 0);
wake_up(&chip->interrupt_sleep);
}
- __end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
/*
@@ -239,7 +232,6 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
enum snd_ymfpci_voice_type type, int pair,
struct snd_ymfpci_voice **rvoice)
{
- unsigned long flags;
int result;
if (snd_BUG_ON(!rvoice))
@@ -247,7 +239,7 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
if (snd_BUG_ON(pair && type != YMFPCI_PCM))
return -EINVAL;
- spin_lock_irqsave(&chip->voice_lock, flags);
+ guard(spinlock_irqsave)(&chip->voice_lock);
for (;;) {
result = voice_alloc(chip, type, pair, rvoice);
if (result == 0 || type != YMFPCI_PCM)
@@ -255,18 +247,15 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
/* TODO: synth/midi voice deallocation */
break;
}
- spin_unlock_irqrestore(&chip->voice_lock, flags);
return result;
}
static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voice *pvoice)
{
- unsigned long flags;
-
if (snd_BUG_ON(!pvoice))
return -EINVAL;
snd_ymfpci_hw_stop(chip);
- spin_lock_irqsave(&chip->voice_lock, flags);
+ guard(spinlock_irqsave)(&chip->voice_lock);
if (pvoice->number == chip->src441_used) {
chip->src441_used = -1;
pvoice->ypcm->use_441_slot = 0;
@@ -274,7 +263,6 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic
pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
pvoice->ypcm = NULL;
pvoice->interrupt = NULL;
- spin_unlock_irqrestore(&chip->voice_lock, flags);
return 0;
}
@@ -292,7 +280,7 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_
return;
if (ypcm->substream == NULL)
return;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (ypcm->running) {
pos = le32_to_cpu(voice->bank[chip->active_bank].start);
if (pos < ypcm->last_pos)
@@ -334,7 +322,6 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_
ypcm->update_pcm_vol--;
}
}
- spin_unlock(&chip->reg_lock);
}
static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream)
@@ -344,7 +331,7 @@ static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream
struct snd_ymfpci *chip = ypcm->chip;
u32 pos, delta;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
if (ypcm->running) {
pos = le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
if (pos < ypcm->last_pos)
@@ -366,7 +353,6 @@ static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream
spin_lock(&chip->reg_lock);
}
}
- spin_unlock(&chip->reg_lock);
}
static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
@@ -377,11 +363,9 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
struct snd_kcontrol *kctl = NULL;
int result = 0;
- spin_lock(&chip->reg_lock);
- if (ypcm->voices[0] == NULL) {
- result = -EINVAL;
- goto __unlock;
- }
+ guard(spinlock)(&chip->reg_lock);
+ if (ypcm->voices[0] == NULL)
+ return -EINVAL;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -405,11 +389,8 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
ypcm->running = 0;
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- __unlock:
- spin_unlock(&chip->reg_lock);
if (kctl)
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
return result;
@@ -422,7 +403,7 @@ static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
int result = 0;
u32 tmp;
- spin_lock(&chip->reg_lock);
+ guard(spinlock)(&chip->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -442,7 +423,6 @@ static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
result = -EINVAL;
break;
}
- spin_unlock(&chip->reg_lock);
return result;
}
@@ -489,7 +469,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
unsigned int nbank;
__le32 vol_left, vol_right;
u8 use_left, use_right;
- unsigned long flags;
if (snd_BUG_ON(!voice))
return;
@@ -509,26 +488,26 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
vol_left = cpu_to_le32(0x40000000);
vol_right = cpu_to_le32(0x40000000);
}
- spin_lock_irqsave(&ypcm->chip->voice_lock, flags);
- format = runtime->channels == 2 ? 0x00010000 : 0;
- if (snd_pcm_format_width(runtime->format) == 8)
- format |= 0x80000000;
- else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
- runtime->rate == 44100 && runtime->channels == 2 &&
- voiceidx == 0 && (ypcm->chip->src441_used == -1 ||
- ypcm->chip->src441_used == voice->number)) {
- ypcm->chip->src441_used = voice->number;
- ypcm->use_441_slot = 1;
- format |= 0x10000000;
- }
- if (ypcm->chip->src441_used == voice->number &&
- (format & 0x10000000) == 0) {
- ypcm->chip->src441_used = -1;
- ypcm->use_441_slot = 0;
+ scoped_guard(spinlock_irqsave, &ypcm->chip->voice_lock) {
+ format = runtime->channels == 2 ? 0x00010000 : 0;
+ if (snd_pcm_format_width(runtime->format) == 8)
+ format |= 0x80000000;
+ else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
+ runtime->rate == 44100 && runtime->channels == 2 &&
+ voiceidx == 0 && (ypcm->chip->src441_used == -1 ||
+ ypcm->chip->src441_used == voice->number)) {
+ ypcm->chip->src441_used = voice->number;
+ ypcm->use_441_slot = 1;
+ format |= 0x10000000;
+ }
+ if (ypcm->chip->src441_used == voice->number &&
+ (format & 0x10000000) == 0) {
+ ypcm->chip->src441_used = -1;
+ ypcm->use_441_slot = 0;
+ }
+ if (runtime->channels == 2 && (voiceidx & 1) != 0)
+ format |= 1;
}
- if (runtime->channels == 2 && (voiceidx & 1) != 0)
- format |= 1;
- spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags);
for (nbank = 0; nbank < 2; nbank++) {
bank = &voice->bank[nbank];
memset(bank, 0, sizeof(*bank));
@@ -596,19 +575,18 @@ static int snd_ymfpci_ac3_init(struct snd_ymfpci *chip)
chip->bank_effect[4][0]->loop_end =
chip->bank_effect[4][1]->loop_end = cpu_to_le32(1024);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) | 3 << 3);
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
static int snd_ymfpci_ac3_done(struct snd_ymfpci *chip)
{
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
- snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) & ~(3 << 3));
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
+ snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) & ~(3 << 3));
+ }
// snd_ymfpci_irq_wait(chip);
if (chip->ac3_tmp_base.area) {
snd_dma_free_pages(&chip->ac3_tmp_base);
@@ -778,28 +756,28 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id)
status = snd_ymfpci_readl(chip, YDSXGR_STATUS);
if (status & 0x80000000) {
chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
- spin_lock(&chip->voice_lock);
- for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
- voice = &chip->voices[nvoice];
- if (voice->interrupt)
- voice->interrupt(chip, voice);
- }
- for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
- if (chip->capture_substream[nvoice])
- snd_ymfpci_pcm_capture_interrupt(chip->capture_substream[nvoice]);
- }
+ scoped_guard(spinlock, &chip->voice_lock) {
+ for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
+ voice = &chip->voices[nvoice];
+ if (voice->interrupt)
+ voice->interrupt(chip, voice);
+ }
+ for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
+ if (chip->capture_substream[nvoice])
+ snd_ymfpci_pcm_capture_interrupt(chip->capture_substream[nvoice]);
+ }
#if 0
- for (nvoice = 0; nvoice < YDSXG_EFFECT_VOICES; nvoice++) {
- if (chip->effect_substream[nvoice])
- snd_ymfpci_pcm_effect_interrupt(chip->effect_substream[nvoice]);
- }
+ for (nvoice = 0; nvoice < YDSXG_EFFECT_VOICES; nvoice++) {
+ if (chip->effect_substream[nvoice])
+ snd_ymfpci_pcm_effect_interrupt(chip->effect_substream[nvoice]);
+ }
#endif
- spin_unlock(&chip->voice_lock);
- spin_lock(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_STATUS, 0x80000000);
- mode = snd_ymfpci_readl(chip, YDSXGR_MODE) | 2;
- snd_ymfpci_writel(chip, YDSXGR_MODE, mode);
- spin_unlock(&chip->reg_lock);
+ }
+ scoped_guard(spinlock, &chip->reg_lock) {
+ snd_ymfpci_writel(chip, YDSXGR_STATUS, 0x80000000);
+ mode = snd_ymfpci_readl(chip, YDSXGR_MODE) | 2;
+ snd_ymfpci_writel(chip, YDSXGR_MODE, mode);
+ }
if (atomic_read(&chip->interrupt_sleep_count)) {
atomic_set(&chip->interrupt_sleep_count, 0);
@@ -936,12 +914,11 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
ypcm->output_front = 1;
ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
ypcm->swap_rear = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
if (ypcm->output_rear) {
ymfpci_open_extension(chip);
chip->rear_opened++;
}
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -959,14 +936,14 @@ static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream)
ypcm->output_front = 0;
ypcm->output_rear = 1;
ypcm->swap_rear = 1;
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
- snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
- ymfpci_open_extension(chip);
- chip->spdif_pcm_bits = chip->spdif_bits;
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
- chip->spdif_opened++;
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
+ snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
+ ymfpci_open_extension(chip);
+ chip->spdif_pcm_bits = chip->spdif_bits;
+ snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
+ chip->spdif_opened++;
+ }
chip->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
@@ -988,10 +965,9 @@ static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream)
ypcm->output_front = 0;
ypcm->output_rear = 1;
ypcm->swap_rear = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
ymfpci_open_extension(chip);
chip->rear_opened++;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1048,12 +1024,12 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
- spin_lock_irq(&chip->reg_lock);
- if (ypcm->output_rear && chip->rear_opened > 0) {
- chip->rear_opened--;
- ymfpci_close_extension(chip);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ if (ypcm->output_rear && chip->rear_opened > 0) {
+ chip->rear_opened--;
+ ymfpci_close_extension(chip);
+ }
}
- spin_unlock_irq(&chip->reg_lock);
return snd_ymfpci_playback_close_1(substream);
}
@@ -1061,13 +1037,13 @@ static int snd_ymfpci_playback_spdif_close(struct snd_pcm_substream *substream)
{
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
- chip->spdif_opened = 0;
- ymfpci_close_extension(chip);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
- snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & ~2);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
- spin_unlock_irq(&chip->reg_lock);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ chip->spdif_opened = 0;
+ ymfpci_close_extension(chip);
+ snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
+ snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & ~2);
+ snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
+ }
chip->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id);
@@ -1078,12 +1054,12 @@ static int snd_ymfpci_playback_4ch_close(struct snd_pcm_substream *substream)
{
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- spin_lock_irq(&chip->reg_lock);
- if (chip->rear_opened > 0) {
- chip->rear_opened--;
- ymfpci_close_extension(chip);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ if (chip->rear_opened > 0) {
+ chip->rear_opened--;
+ ymfpci_close_extension(chip);
+ }
}
- spin_unlock_irq(&chip->reg_lock);
return snd_ymfpci_playback_close_1(substream);
}
@@ -1264,11 +1240,10 @@ static int snd_ymfpci_spdif_default_get(struct snd_kcontrol *kcontrol,
{
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff;
ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1281,12 +1256,11 @@ static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,
val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
(ucontrol->value.iec958.status[1] << 8);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
change = chip->spdif_bits != val;
chip->spdif_bits = val;
if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 1) && chip->pcm_spdif == NULL)
snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1311,10 +1285,9 @@ static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,
{
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
ucontrol->value.iec958.status[0] = 0x3e;
ucontrol->value.iec958.status[1] = 0xff;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1339,11 +1312,10 @@ static int snd_ymfpci_spdif_stream_get(struct snd_kcontrol *kcontrol,
{
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff;
ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1356,12 +1328,11 @@ static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,
val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
(ucontrol->value.iec958.status[1] << 8);
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
change = chip->spdif_pcm_bits != val;
chip->spdif_pcm_bits = val;
if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 2))
snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1387,9 +1358,8 @@ static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
u16 reg;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
- spin_unlock_irq(&chip->reg_lock);
if (!(reg & 0x100))
value->value.enumerated.item[0] = 0;
else
@@ -1402,14 +1372,13 @@ static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
u16 reg, old_reg;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
old_reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
if (value->value.enumerated.item[0] == 0)
reg = old_reg & ~0x100;
else
reg = (old_reg & ~0x300) | 0x100 | ((value->value.enumerated.item[0] == 2) << 9);
snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, reg);
- spin_unlock_irq(&chip->reg_lock);
return reg != old_reg;
}
@@ -1469,12 +1438,11 @@ static int snd_ymfpci_put_single(struct snd_kcontrol *kcontrol,
}
val = (ucontrol->value.integer.value[0] & mask);
val <<= shift;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oval = snd_ymfpci_readl(chip, reg);
val = (oval & ~(mask << shift)) | val;
change = val != oval;
snd_ymfpci_writel(chip, reg, val);
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1510,9 +1478,8 @@ static int snd_ymfpci_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
if (reg < 0x80 || reg >= 0xc0)
return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
val = snd_ymfpci_readl(chip, reg);
- spin_unlock_irq(&chip->reg_lock);
ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
return 0;
@@ -1532,12 +1499,11 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
val2 = ucontrol->value.integer.value[1] & mask;
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oval = snd_ymfpci_readl(chip, reg);
val1 = (oval & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
change = val1 != oval;
snd_ymfpci_writel(chip, reg, val1);
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1552,12 +1518,11 @@ static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol,
value = ucontrol->value.integer.value[0] & 0x3fff;
value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
oval = snd_ymfpci_readl(chip, reg);
change = value != oval;
snd_ymfpci_writel(chip, reg, value);
snd_ymfpci_writel(chip, reg2, value);
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1629,9 +1594,8 @@ YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4)
static int snd_ymfpci_get_gpio_out(struct snd_ymfpci *chip, int pin)
{
u16 reg, mode;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
reg &= ~(1 << (pin + 8));
reg |= (1 << pin);
@@ -1642,23 +1606,20 @@ static int snd_ymfpci_get_gpio_out(struct snd_ymfpci *chip, int pin)
snd_ymfpci_writew(chip, YDSXGR_GPIOTYPECONFIG, mode);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
mode = snd_ymfpci_readw(chip, YDSXGR_GPIOINSTATUS);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return (mode >> pin) & 1;
}
static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable)
{
u16 reg;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
reg &= ~(1 << pin);
reg &= ~(1 << (pin + 8));
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
snd_ymfpci_writew(chip, YDSXGR_GPIOOUTCTRL, enable << pin);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -1726,7 +1687,6 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
unsigned int subs = kcontrol->id.subdevice;
struct snd_pcm_substream *substream;
- unsigned long flags;
if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left ||
ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) {
@@ -1738,13 +1698,12 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
chip->pcm_mixer[subs].right = 0x8000;
substream = (struct snd_pcm_substream *)kcontrol->private_value;
- spin_lock_irqsave(&chip->voice_lock, flags);
+ guard(spinlock_irqsave)(&chip->voice_lock);
if (substream->runtime && substream->runtime->private_data) {
struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
if (!ypcm->use_441_slot)
ypcm->update_pcm_vol = 2;
}
- spin_unlock_irqrestore(&chip->voice_lock, flags);
return 1;
}
return 0;
@@ -1884,11 +1843,10 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
static int snd_ymfpci_timer_start(struct snd_timer *timer)
{
struct snd_ymfpci *chip;
- unsigned long flags;
unsigned int count;
chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (timer->sticks > 1) {
chip->timer_ticks = timer->sticks;
count = timer->sticks - 1;
@@ -1902,19 +1860,16 @@ static int snd_ymfpci_timer_start(struct snd_timer *timer)
}
snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_ymfpci_timer_stop(struct snd_timer *timer)
{
struct snd_ymfpci *chip;
- unsigned long flags;
chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x00);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -2273,10 +2228,9 @@ static int snd_ymfpci_resume(struct device *dev)
/* start hw again */
if (chip->start_count > 0) {
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
snd_ymfpci_writel(chip, YDSXGR_MODE, chip->saved_ydsxgr_mode);
chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);
- spin_unlock_irq(&chip->reg_lock);
}
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 11aacc7e3f0b..a104baac3a94 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -161,14 +161,13 @@ static void snd_pdacf_ak4117_change(struct ak4117 *ak4117, unsigned char c0, uns
if (!(c0 & AK4117_UNLCK))
return;
- mutex_lock(&chip->reg_lock);
+ guard(mutex)(&chip->reg_lock);
val = chip->regmap[PDAUDIOCF_REG_SCR>>1];
if (ak4117->rcs0 & AK4117_UNLCK)
val |= PDAUDIOCF_BLUE_LED_OFF;
else
val &= ~PDAUDIOCF_BLUE_LED_OFF;
pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- mutex_unlock(&chip->reg_lock);
}
int snd_pdacf_ak4117_create(struct snd_pdacf *chip)
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 20aba745f1dc..228822996ef7 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -64,21 +64,20 @@ static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
default:
return -EINVAL;
}
- mutex_lock(&chip->reg_lock);
- chip->pcm_running += inc;
- tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- if (chip->pcm_running) {
- if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) {
- chip->pcm_running -= inc;
- ret = -EIO;
- goto __end;
+ scoped_guard(mutex, &chip->reg_lock) {
+ chip->pcm_running += inc;
+ tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
+ if (chip->pcm_running) {
+ if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) {
+ chip->pcm_running -= inc;
+ ret = -EIO;
+ break;
+ }
}
+ tmp &= ~mask;
+ tmp |= val;
+ pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp);
}
- tmp &= ~mask;
- tmp |= val;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp);
- __end:
- mutex_unlock(&chip->reg_lock);
snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_RATE);
return ret;
}
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c
index bc2114475810..998cea2d0318 100644
--- a/sound/pcmcia/vx/vxp_mixer.c
+++ b/sound/pcmcia/vx/vxp_mixer.c
@@ -43,14 +43,12 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
if (val > MIC_LEVEL_MAX)
return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
+ guard(mutex)(&_chip->mixer_mutex);
if (chip->mic_level != ucontrol->value.integer.value[0]) {
vx_set_mic_level(_chip, ucontrol->value.integer.value[0]);
chip->mic_level = ucontrol->value.integer.value[0];
- mutex_unlock(&_chip->mixer_mutex);
return 1;
}
- mutex_unlock(&_chip->mixer_mutex);
return 0;
}
@@ -85,14 +83,13 @@ static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vxpocket *chip = to_vxpocket(_chip);
int val = !!ucontrol->value.integer.value[0];
- mutex_lock(&_chip->mixer_mutex);
+
+ guard(mutex)(&_chip->mixer_mutex);
if (chip->mic_level != val) {
vx_set_mic_boost(_chip, val);
chip->mic_level = val;
- mutex_unlock(&_chip->mixer_mutex);
return 1;
}
- mutex_unlock(&_chip->mixer_mutex);
return 0;
}
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 0bc5c5d9d157..4211e7239138 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -463,7 +463,7 @@ void vx_set_mic_boost(struct vx_core *chip, int boost)
if (chip->chip_status & VX_STAT_IS_STALE)
return;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
if (pchip->regCDSP & P24_CDSP_MICS_SEL_MASK) {
if (boost) {
/* boost: 38 dB */
@@ -476,7 +476,6 @@ void vx_set_mic_boost(struct vx_core *chip, int boost)
}
vx_outb(chip, CDSP, pchip->regCDSP);
}
- mutex_unlock(&chip->lock);
}
/*
@@ -505,12 +504,11 @@ void vx_set_mic_level(struct vx_core *chip, int level)
if (chip->chip_status & VX_STAT_IS_STALE)
return;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
if (pchip->regCDSP & VXP_CDSP_MIC_SEL_MASK) {
level = vx_compute_mic_level(level);
vx_outb(chip, MICRO, level);
}
- mutex_unlock(&chip->lock);
}
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 13a6f3af13ef..c231a9d6d1de 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -137,13 +137,11 @@ static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
int reg = kcontrol->private_value & 0xff;
int lshift = (kcontrol->private_value >> 8) & 0xff;
int inverted = (kcontrol->private_value >> 16) & 1;
- unsigned long flags;
int vol[2];
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
vol[1] = chip->awacs_reg[reg] & 0xf;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (inverted) {
vol[0] = 0x0f - vol[0];
vol[1] = 0x0f - vol[1];
@@ -161,7 +159,6 @@ static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
int lshift = (kcontrol->private_value >> 8) & 0xff;
int inverted = (kcontrol->private_value >> 16) & 1;
int val, oldval;
- unsigned long flags;
unsigned int vol[2];
vol[0] = ucontrol->value.integer.value[0];
@@ -174,14 +171,13 @@ static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
}
vol[0] &= 0x0f;
vol[1] &= 0x0f;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
oldval = chip->awacs_reg[reg];
val = oldval & ~(0xf | (0xf << lshift));
val |= vol[0] << lshift;
val |= vol[1];
if (oldval != val)
snd_pmac_awacs_write_reg(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return oldval != reg;
}
@@ -204,11 +200,9 @@ static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
int shift = (kcontrol->private_value >> 8) & 0xff;
int invert = (kcontrol->private_value >> 16) & 1;
int val;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = (chip->awacs_reg[reg] >> shift) & 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (invert)
val = 1 - val;
ucontrol->value.integer.value[0] = val;
@@ -224,16 +218,14 @@ static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
int invert = (kcontrol->private_value >> 16) & 1;
int mask = 1 << shift;
int val, changed;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val = chip->awacs_reg[reg] & ~mask;
if (ucontrol->value.integer.value[0] != invert)
val |= mask;
changed = chip->awacs_reg[reg] != val;
if (changed)
snd_pmac_awacs_write_reg(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return changed;
}
@@ -541,14 +533,12 @@ static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
int val = 0;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (chip->awacs_reg[6] & MASK_MIC_BOOST)
val |= 2;
if (chip->awacs_reg[0] & MASK_GAINLINE)
val |= 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
ucontrol->value.integer.value[0] = val;
return 0;
}
@@ -559,9 +549,8 @@ static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
int val0, val6;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
if (ucontrol->value.integer.value[0] & 1)
@@ -576,7 +565,6 @@ static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
snd_pmac_awacs_write_reg(chip, 6, val6);
changed = 1;
}
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return changed;
}
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index bf289783eafd..ab2468790b0c 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -88,7 +88,6 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
{
struct snd_pmac *chip;
struct pmac_beep *beep;
- unsigned long flags;
int beep_speed = 0;
int srate;
int period, ncycles, nsamples;
@@ -112,10 +111,9 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
return -1;
if (! hz) {
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
if (beep->running)
snd_pmac_beep_stop(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
@@ -125,13 +123,11 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
if (hz <= srate / BEEP_BUFLEN || hz > srate / 2)
hz = 1000;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->playback.running || chip->capture.running || beep->running) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ if (chip->playback.running || chip->capture.running || beep->running)
+ return 0;
+ beep->running = 1;
}
- beep->running = 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
if (hz == beep->hz && beep->volume == beep->volume_play) {
nsamples = beep->nsamples;
@@ -151,9 +147,8 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
beep->nsamples = nsamples;
}
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, beep_speed);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index ba15bc34c9ec..5d6accce3a72 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -59,9 +59,8 @@ static unsigned
snd_pmac_burgundy_rcw(struct snd_pmac *chip, unsigned addr)
{
unsigned val = 0;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
out_le32(&chip->awacs->codec_ctrl, addr + 0x100000);
snd_pmac_burgundy_busy_wait(chip);
@@ -83,8 +82,6 @@ snd_pmac_burgundy_rcw(struct snd_pmac *chip, unsigned addr)
snd_pmac_burgundy_extend_wait(chip);
val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<24;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
return val;
}
@@ -100,17 +97,14 @@ static unsigned
snd_pmac_burgundy_rcb(struct snd_pmac *chip, unsigned int addr)
{
unsigned val = 0;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
+ guard(spinlock_irqsave)(&chip->reg_lock);
out_le32(&chip->awacs->codec_ctrl, addr + 0x100000);
snd_pmac_burgundy_busy_wait(chip);
snd_pmac_burgundy_extend_wait(chip);
val += (in_le32(&chip->awacs->codec_stat) >> 4) & 0xff;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
return val;
}
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a3d346f1cc05..6d7dab26ddf2 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -206,32 +206,32 @@ static int snd_pmac_pcm_prepare(struct snd_pmac *chip, struct pmac_stream *rec,
* common to many PowerBook G3 systems and random noise otherwise
* captured on iBook2's about every third time. -ReneR
*/
- spin_lock_irq(&chip->reg_lock);
- snd_pmac_dma_stop(rec);
- chip->extra_dma.cmds->command = cpu_to_le16(DBDMA_STOP);
- snd_pmac_dma_set_command(rec, &chip->extra_dma);
- snd_pmac_dma_run(rec, RUN);
- spin_unlock_irq(&chip->reg_lock);
- mdelay(5);
- spin_lock_irq(&chip->reg_lock);
- /* continuous DMA memory type doesn't provide the physical address,
- * so we need to resolve the address here...
- */
- offset = runtime->dma_addr;
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++) {
- cp->phy_addr = cpu_to_le32(offset);
- cp->req_count = cpu_to_le16(rec->period_size);
- /*cp->res_count = cpu_to_le16(0);*/
- cp->xfer_status = cpu_to_le16(0);
- offset += rec->period_size;
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ snd_pmac_dma_stop(rec);
+ chip->extra_dma.cmds->command = cpu_to_le16(DBDMA_STOP);
+ snd_pmac_dma_set_command(rec, &chip->extra_dma);
+ snd_pmac_dma_run(rec, RUN);
}
- /* make loop */
- cp->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
- cp->cmd_dep = cpu_to_le32(rec->cmd.addr);
+ mdelay(5);
+ scoped_guard(spinlock_irq, &chip->reg_lock) {
+ /* continuous DMA memory type doesn't provide the physical address,
+ * so we need to resolve the address here...
+ */
+ offset = runtime->dma_addr;
+ for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++) {
+ cp->phy_addr = cpu_to_le32(offset);
+ cp->req_count = cpu_to_le16(rec->period_size);
+ /*cp->res_count = cpu_to_le16(0);*/
+ cp->xfer_status = cpu_to_le16(0);
+ offset += rec->period_size;
+ }
+ /* make loop */
+ cp->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
+ cp->cmd_dep = cpu_to_le32(rec->cmd.addr);
- snd_pmac_dma_stop(rec);
- snd_pmac_dma_set_command(rec, &rec->cmd);
- spin_unlock_irq(&chip->reg_lock);
+ snd_pmac_dma_stop(rec);
+ snd_pmac_dma_set_command(rec, &rec->cmd);
+ }
return 0;
}
@@ -253,26 +253,26 @@ static int snd_pmac_pcm_trigger(struct snd_pmac *chip, struct pmac_stream *rec,
return -EBUSY;
command = (subs->stream == SNDRV_PCM_STREAM_PLAYBACK ?
OUTPUT_MORE : INPUT_MORE) + INTR_ALWAYS;
- spin_lock(&chip->reg_lock);
- snd_pmac_beep_stop(chip);
- snd_pmac_pcm_set_format(chip);
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
- out_le16(&cp->command, command);
- snd_pmac_dma_set_command(rec, &rec->cmd);
- (void)in_le32(&rec->dma->status);
- snd_pmac_dma_run(rec, RUN|WAKE);
- rec->running = 1;
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ snd_pmac_beep_stop(chip);
+ snd_pmac_pcm_set_format(chip);
+ for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
+ out_le16(&cp->command, command);
+ snd_pmac_dma_set_command(rec, &rec->cmd);
+ (void)in_le32(&rec->dma->status);
+ snd_pmac_dma_run(rec, RUN|WAKE);
+ rec->running = 1;
+ }
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
- spin_lock(&chip->reg_lock);
- rec->running = 0;
- snd_pmac_dma_stop(rec);
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
- out_le16(&cp->command, DBDMA_STOP);
- spin_unlock(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->reg_lock) {
+ rec->running = 0;
+ snd_pmac_dma_stop(rec);
+ for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
+ out_le16(&cp->command, DBDMA_STOP);
+ }
break;
default:
@@ -1321,14 +1321,12 @@ int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
void snd_pmac_suspend(struct snd_pmac *chip)
{
- unsigned long flags;
-
snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
if (chip->suspend)
chip->suspend(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_pmac_beep_stop(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->reg_lock) {
+ snd_pmac_beep_stop(chip);
+ }
if (chip->irq >= 0)
disable_irq(chip->irq);
if (chip->tx_irq >= 0)
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index ce7ee2713f9d..225b20f0b71a 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -221,7 +221,6 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
int fill_stages, dma_ch, stage;
enum snd_ps3_ch ch;
uint32_t ch0_kick_event = 0; /* initialize to mute gcc */
- unsigned long irqsave;
int silent = 0;
switch (filltype) {
@@ -242,7 +241,7 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
snd_ps3_verify_dma_stop(card, 700, 0);
fill_stages = 4;
- spin_lock_irqsave(&card->dma_lock, irqsave);
+ guard(spinlock_irqsave)(&card->dma_lock);
for (ch = 0; ch < 2; ch++) {
for (stage = 0; stage < fill_stages; stage++) {
dma_ch = stage * 2 + ch;
@@ -289,7 +288,6 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
}
/* ensure the hardware sees the change */
wmb();
- spin_unlock_irqrestore(&card->dma_lock, irqsave);
return 0;
}
@@ -561,7 +559,6 @@ static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- unsigned long irqsave;
if (!snd_ps3_set_avsetting(substream)) {
/* some parameter changed */
@@ -578,8 +575,7 @@ static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream)
}
/* restart ring buffer pointer */
- spin_lock_irqsave(&card->dma_lock, irqsave);
- {
+ scoped_guard(spinlock_irqsave, &card->dma_lock) {
card->dma_buffer_size = runtime->dma_bytes;
card->dma_last_transfer_vaddr[SND_PS3_CH_L] =
@@ -600,7 +596,6 @@ static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream)
card->dma_start_bus_addr[SND_PS3_CH_L]);
}
- spin_unlock_irqrestore(&card->dma_lock, irqsave);
/* ensure the hardware sees the change */
mb();
@@ -618,11 +613,9 @@ static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
/* clear outstanding interrupts */
update_reg(PS3_AUDIO_AX_IS, 0);
- spin_lock(&card->dma_lock);
- {
+ scoped_guard(spinlock, &card->dma_lock) {
card->running = 1;
}
- spin_unlock(&card->dma_lock);
snd_ps3_program_dma(card,
SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
@@ -636,11 +629,9 @@ static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
break;
case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&card->dma_lock);
- {
+ scoped_guard(spinlock, &card->dma_lock) {
card->running = 0;
}
- spin_unlock(&card->dma_lock);
snd_ps3_wait_for_dma_stop(card);
break;
default:
@@ -661,12 +652,10 @@ static snd_pcm_uframes_t snd_ps3_pcm_pointer(
size_t bytes;
snd_pcm_uframes_t ret;
- spin_lock(&card->dma_lock);
- {
+ scoped_guard(spinlock, &card->dma_lock) {
bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] -
card->dma_start_vaddr[SND_PS3_CH_L]);
}
- spin_unlock(&card->dma_lock);
ret = bytes_to_frames(substream->runtime, bytes * 2);
diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c
index aeffd24710e7..7e9c07488dcc 100644
--- a/sound/soc/amd/acp/acp-rembrandt.c
+++ b/sound/soc/amd/acp/acp-rembrandt.c
@@ -147,7 +147,7 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct acp_chip_info *chip;
- u32 ret;
+ int ret;
chip = dev_get_platdata(&pdev->dev);
if (!chip || !chip->base) {
diff --git a/sound/soc/amd/acp/amd-sdw-acpi.c b/sound/soc/amd/acp/amd-sdw-acpi.c
index 238b584887ee..0160b0df26a0 100644
--- a/sound/soc/amd/acp/amd-sdw-acpi.c
+++ b/sound/soc/amd/acp/amd-sdw-acpi.c
@@ -17,8 +17,8 @@
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/export.h>
-#include <linux/fwnode.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/soundwire/sdw_amd.h>
#include <linux/string.h>
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
index e7f2a05e802c..352485dd98b1 100644
--- a/sound/soc/amd/raven/acp3x-i2s.c
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -149,8 +149,9 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct i2s_stream_instance *rtd;
- u32 ret, val, period_bytes, reg_val, ier_val, water_val;
+ u32 val, period_bytes, reg_val, ier_val, water_val;
u32 buf_size, buf_reg;
+ int ret;
rtd = substream->runtime->private_data;
period_bytes = frames_to_bytes(substream->runtime,
diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c
index 7dbe33f4b867..bf719f628617 100644
--- a/sound/soc/amd/vangogh/acp5x-i2s.c
+++ b/sound/soc/amd/vangogh/acp5x-i2s.c
@@ -234,8 +234,9 @@ static int acp5x_i2s_trigger(struct snd_pcm_substream *substream,
{
struct i2s_stream_instance *rtd;
struct i2s_dev_data *adata;
- u32 ret, val, period_bytes, reg_val, ier_val, water_val;
+ u32 val, period_bytes, reg_val, ier_val, water_val;
u32 buf_size, buf_reg;
+ int ret;
adata = snd_soc_dai_get_drvdata(dai);
rtd = substream->runtime->private_data;
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
index 5dd24ab90d0f..c4dcb2b54591 100644
--- a/sound/soc/apple/mca.c
+++ b/sound/soc/apple/mca.c
@@ -1191,6 +1191,7 @@ static void apple_mca_remove(struct platform_device *pdev)
}
static const struct of_device_id apple_mca_of_match[] = {
+ { .compatible = "apple,t8103-mca", },
{ .compatible = "apple,mca", },
{}
};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index dfe907c62604..160c07699a8b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -125,6 +125,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_ES7134
imply SND_SOC_ES7241
imply SND_SOC_FRAMER
+ imply SND_SOC_FS210X
imply SND_SOC_GTM601
imply SND_SOC_HDAC_HDMI
imply SND_SOC_HDAC_HDA
@@ -177,6 +178,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_NAU8825
imply SND_SOC_HDMI_CODEC
imply SND_SOC_PCM1681
+ imply SND_SOC_PCM1754
imply SND_SOC_PCM1789_I2C
imply SND_SOC_PCM179X_I2C
imply SND_SOC_PCM179X_SPI
@@ -192,6 +194,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_PCM512x_SPI
imply SND_SOC_PCM6240
imply SND_SOC_PEB2466
+ imply SND_SOC_PM4125_SDW
imply SND_SOC_RK3308
imply SND_SOC_RK3328
imply SND_SOC_RK817
@@ -265,6 +268,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_TAS2770
imply SND_SOC_TAS2780
imply SND_SOC_TAS2781_I2C
+ imply SND_SOC_TAS2783_SDW
imply SND_SOC_TAS5086
imply SND_SOC_TAS571X
imply SND_SOC_TAS5720
@@ -300,7 +304,6 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_LPASS_MACRO_COMMON
imply SND_SOC_LPASS_RX_MACRO
imply SND_SOC_LPASS_TX_MACRO
- imply SND_SOC_WL1273
imply SND_SOC_WM0010
imply SND_SOC_WM1250_EV1
imply SND_SOC_WM2000
@@ -622,6 +625,7 @@ config SND_SOC_AK4619
config SND_SOC_AK4641
tristate
depends on I2C
+ depends on GPIOLIB_LEGACY
config SND_SOC_AK4642
tristate "AKM AK4642 CODEC"
@@ -1232,6 +1236,21 @@ config SND_SOC_FRAMER
To compile this driver as a module, choose M here: the module
will be called snd-soc-framer.
+config SND_SOC_FS_AMP_LIB
+ select CRC16
+ tristate
+
+config SND_SOC_FS210X
+ tristate 'FourSemi FS2104/5S digital audio amplifier'
+ depends on I2C
+ select GPIOLIB
+ select REGMAP_I2C
+ select SND_SOC_FS_AMP_LIB
+ help
+ Enable support for FourSemi FS2104/5S digital audio amplifier.
+ The FS2104/5S are Inductor-Less, Stereo, Closed-Loop,
+ Digital Input Class-D Power Amplifiers with Enhanced Signal Processing.
+ The amplifiers support I2C and I2S/TDM.
config SND_SOC_GTM601
tristate 'GTM601 UMTS modem audio codec'
@@ -1426,6 +1445,10 @@ config SND_SOC_PCM1681
tristate "Texas Instruments PCM1681 CODEC"
depends on I2C
+config SND_SOC_PCM1754
+ tristate "Texas Instruments PCM1754 CODEC"
+ depends on GPIOLIB
+
config SND_SOC_PCM1789
tristate
@@ -1542,6 +1565,23 @@ config SND_SOC_PEB2466
To compile this driver as a module, choose M here: the module
will be called snd-soc-peb2466.
+config SND_SOC_PM4125
+ depends on SND_SOC_PM4125_SDW
+ tristate
+ depends on SOUNDWIRE || !SOUNDWIRE
+
+config SND_SOC_PM4125_SDW
+ tristate "PM4125 audio codec - SDW"
+ select SND_SOC_PM4125
+ select SND_SOC_WCD_MBHC
+ select REGMAP_IRQ
+ depends on SOUNDWIRE
+ select REGMAP_SOUNDWIRE
+ help
+ The PMIC PM4125 has an in-built audio codec IC used with SoCs
+ like QCM2290, and it is connected via soundwire and SPMI.
+ To compile this codec driver say Y or m.
+
config SND_SOC_RK3308
tristate "Rockchip RK3308 audio CODEC"
depends on ARM64 || COMPILE_TEST
@@ -2059,6 +2099,19 @@ config SND_SOC_TAS2781_I2C
algo coefficient setting, for one, two or even multiple TAS2781
chips.
+config SND_SOC_TAS2783_SDW
+ tristate "Texas Instruments TAS2783 speaker amplifier (sdw)"
+ depends on SOUNDWIRE
+ depends on EFI
+ select REGMAP_SOUNDWIRE
+ select REGMAP_SOUNDWIRE_MBQ
+ select CRC32
+ help
+ Enable support for Texas Instruments TAS2783A Digital input
+ mono Class-D and DSP-inside audio power amplifiers. TAS2783
+ driver implements a flexible and configurable algorithm
+ cofficient setting, for one, two or multiple TAS2783 chips.
+
config SND_SOC_TAS5086
tristate "Texas Instruments TAS5086 speaker amplifier"
depends on I2C
@@ -2176,6 +2229,7 @@ config SND_SOC_TLV320AIC3X_SPI
config SND_SOC_TLV320DAC33
tristate
depends on I2C
+ depends on GPIOLIB_LEGACY
config SND_SOC_TLV320ADCX140
tristate "Texas Instruments TLV320ADCX140 CODEC family"
@@ -2230,10 +2284,14 @@ config SND_SOC_UDA1342
config SND_SOC_UDA1380
tristate
depends on I2C
+ depends on GPIOLIB_LEGACY
config SND_SOC_WCD_CLASSH
tristate
+config SND_SOC_WCD_COMMON
+ tristate
+
config SND_SOC_WCD9335
tristate "WCD9335 Codec"
depends on SLIMBUS
@@ -2255,6 +2313,7 @@ config SND_SOC_WCD934X
select REGMAP_IRQ
select REGMAP_SLIMBUS
select SND_SOC_WCD_CLASSH
+ select SND_SOC_WCD_COMMON
select SND_SOC_WCD_MBHC
depends on MFD_WCD934X || COMPILE_TEST
help
@@ -2266,6 +2325,7 @@ config SND_SOC_WCD937X
tristate
depends on SOUNDWIRE || !SOUNDWIRE
select SND_SOC_WCD_CLASSH
+ select SND_SOC_WCD_COMMON
config SND_SOC_WCD937X_SDW
tristate "WCD9370/WCD9375 Codec - SDW"
@@ -2285,6 +2345,7 @@ config SND_SOC_WCD938X
tristate
depends on SOUNDWIRE || !SOUNDWIRE
select SND_SOC_WCD_CLASSH
+ select SND_SOC_WCD_COMMON
select MULTIPLEXER
config SND_SOC_WCD938X_SDW
@@ -2304,6 +2365,7 @@ config SND_SOC_WCD939X
depends on SOUNDWIRE || !SOUNDWIRE
depends on TYPEC || !TYPEC
select SND_SOC_WCD_CLASSH
+ select SND_SOC_WCD_COMMON
config SND_SOC_WCD939X_SDW
tristate "WCD9390/WCD9395 Codec - SDW"
@@ -2317,9 +2379,6 @@ config SND_SOC_WCD939X_SDW
The WCD9390/9395 is a audio codec IC Integrated in
Qualcomm SoCs like SM8650.
-config SND_SOC_WL1273
- tristate
-
config SND_SOC_WM0010
tristate
depends on SPI_MASTER
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index a68c3d192a1b..bd95a7c911d5 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -137,6 +137,8 @@ snd-soc-es8328-spi-y := es8328-spi.o
snd-soc-es8375-y := es8375.o
snd-soc-es8389-y := es8389.o
snd-soc-framer-y := framer-codec.o
+snd-soc-fs-amp-lib-y := fs-amp-lib.o
+snd-soc-fs210x-y := fs210x.o
snd-soc-gtm601-y := gtm601.o
snd-soc-hdac-hdmi-y := hdac_hdmi.o
snd-soc-hdac-hda-y := hdac_hda.o
@@ -201,6 +203,7 @@ snd-soc-ntp8918-y := ntp8918.o
snd-soc-ntpfw-y := ntpfw.o
snd-soc-hdmi-codec-y := hdmi-codec.o
snd-soc-pcm1681-y := pcm1681.o
+snd-soc-pcm1754-y := pcm1754.o
snd-soc-pcm1789-codec-y := pcm1789.o
snd-soc-pcm1789-i2c-y := pcm1789-i2c.o
snd-soc-pcm179x-codec-y := pcm179x.o
@@ -222,6 +225,8 @@ snd-soc-pcm512x-i2c-y := pcm512x-i2c.o
snd-soc-pcm512x-spi-y := pcm512x-spi.o
snd-soc-pcm6240-y := pcm6240.o
snd-soc-peb2466-y := peb2466.o
+snd-soc-pm4125-y := pm4125.o
+snd-soc-pm4125-sdw-y := pm4125-sdw.o
snd-soc-rk3308-y := rk3308_codec.o
snd-soc-rk3328-y := rk3328_codec.o
snd-soc-rk817-y := rk817_codec.o
@@ -314,6 +319,7 @@ snd-soc-tas2781-comlib-y := tas2781-comlib.o
snd-soc-tas2781-comlib-i2c-y := tas2781-comlib-i2c.o
snd-soc-tas2781-fmwlib-y := tas2781-fmwlib.o
snd-soc-tas2781-i2c-y := tas2781-i2c.o
+snd-soc-tas2783-sdw-y := tas2783-sdw.o
snd-soc-tfa9879-y := tfa9879.o
snd-soc-tfa989x-y := tfa989x.o
snd-soc-tlv320adc3xxx-y := tlv320adc3xxx.o
@@ -339,6 +345,7 @@ snd-soc-uda1334-y := uda1334.o
snd-soc-uda1342-y := uda1342.o
snd-soc-uda1380-y := uda1380.o
snd-soc-wcd-classh-y := wcd-clsh-v2.o
+snd-soc-wcd-common-y := wcd-common.o
snd-soc-wcd-mbhc-y := wcd-mbhc-v2.o
snd-soc-wcd9335-y := wcd9335.o
snd-soc-wcd934x-y := wcd934x.o
@@ -348,7 +355,6 @@ snd-soc-wcd938x-y := wcd938x.o
snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
snd-soc-wcd939x-y := wcd939x.o
snd-soc-wcd939x-sdw-y := wcd939x-sdw.o
-snd-soc-wl1273-y := wl1273.o
snd-soc-wm-adsp-y := wm_adsp.o
snd-soc-wm0010-y := wm0010.o
snd-soc-wm1250-ev1-y := wm1250-ev1.o
@@ -562,6 +568,8 @@ obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
obj-$(CONFIG_SND_SOC_ES8375) += snd-soc-es8375.o
obj-$(CONFIG_SND_SOC_ES8389) += snd-soc-es8389.o
obj-$(CONFIG_SND_SOC_FRAMER) += snd-soc-framer.o
+obj-$(CONFIG_SND_SOC_FS_AMP_LIB)+= snd-soc-fs-amp-lib.o
+obj-$(CONFIG_SND_SOC_FS210X) += snd-soc-fs210x.o
obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o
@@ -621,6 +629,7 @@ obj-$(CONFIG_SND_SOC_NTP8918) += snd-soc-ntp8918.o
obj-$(CONFIG_SND_SOC_NTPFW) += snd-soc-ntpfw.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
+obj-$(CONFIG_SND_SOC_PCM1754) += snd-soc-pcm1754.o
obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o
obj-$(CONFIG_SND_SOC_PCM1789_I2C) += snd-soc-pcm1789-i2c.o
obj-$(CONFIG_SND_SOC_PCM1789) += snd-soc-pcm1789-codec.o
@@ -642,6 +651,12 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_PCM6240) += snd-soc-pcm6240.o
obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o
+obj-$(CONFIG_SND_SOC_PM4125_SDW) += snd-soc-pm4125-sdw.o
+obj-$(CONFIG_SND_SOC_PM4125) += snd-soc-pm4125.o
+ifdef CONFIG_SND_SOC_PM4125_SDW
+# avoid link failure by forcing sdw code built-in when needed
+obj-$(CONFIG_SND_SOC_PM4125) += snd-soc-pm4125-sdw.o
+endif
obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o
@@ -729,6 +744,7 @@ obj-$(CONFIG_SND_SOC_TAS2781_COMLIB) += snd-soc-tas2781-comlib.o
obj-$(CONFIG_SND_SOC_TAS2781_COMLIB_I2C) += snd-soc-tas2781-comlib-i2c.o
obj-$(CONFIG_SND_SOC_TAS2781_FMWLIB) += snd-soc-tas2781-fmwlib.o
obj-$(CONFIG_SND_SOC_TAS2781_I2C) += snd-soc-tas2781-i2c.o
+obj-$(CONFIG_SND_SOC_TAS2783_SDW) += snd-soc-tas2783-sdw.o
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
@@ -761,6 +777,7 @@ obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o
obj-$(CONFIG_SND_SOC_UDA1342) += snd-soc-uda1342.o
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WCD_CLASSH) += snd-soc-wcd-classh.o
+obj-$(CONFIG_SND_SOC_WCD_COMMON) += snd-soc-wcd-common.o
obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o
obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o
obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o
@@ -779,7 +796,6 @@ ifdef CONFIG_SND_SOC_WCD939X_SDW
# avoid link failure by forcing sdw code built-in when needed
obj-$(CONFIG_SND_SOC_WCD939X) += snd-soc-wcd939x-sdw.o
endif
-obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index ae59efb38f26..c193a9f22f59 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -795,7 +795,7 @@ static int adau1977_set_sysclk(struct snd_soc_component *component,
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
unsigned int mask = 0;
unsigned int clk_src;
- unsigned int ret;
+ int ret;
if (dir != SND_SOC_CLOCK_IN)
return -EINVAL;
diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-lib-test.c
index f53650128fc3..2fde84309338 100644
--- a/sound/soc/codecs/cs-amp-lib-test.c
+++ b/sound/soc/codecs/cs-amp-lib-test.c
@@ -19,6 +19,14 @@
#include <linux/random.h>
#include <sound/cs-amp-lib.h>
+#define LENOVO_SPEAKER_ID_EFI_NAME L"SdwSpeaker"
+#define LENOVO_SPEAKER_ID_EFI_GUID \
+ EFI_GUID(0x48df970e, 0xe27f, 0x460a, 0xb5, 0x86, 0x77, 0x19, 0x80, 0x1d, 0x92, 0x82)
+
+#define HP_SPEAKER_ID_EFI_NAME L"HPSpeakerID"
+#define HP_SPEAKER_ID_EFI_GUID \
+ EFI_GUID(0xc49593a4, 0xd099, 0x419b, 0xa2, 0xc3, 0x67, 0xe9, 0x80, 0xe6, 0x1d, 0x1e)
+
KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy,
struct faux_device *)
@@ -196,8 +204,40 @@ static efi_status_t cs_amp_lib_test_get_efi_variable(efi_char16_t *name,
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, guid);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, size);
- KUNIT_EXPECT_MEMEQ(test, name, expected_name, sizeof(expected_name));
- KUNIT_EXPECT_MEMEQ(test, guid, &expected_guid, sizeof(expected_guid));
+ if (memcmp(name, expected_name, sizeof(expected_name)) ||
+ efi_guidcmp(*guid, expected_guid))
+ return -EFI_NOT_FOUND;
+
+ if (!buf) {
+ *size = priv->cal_blob->size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ KUNIT_ASSERT_GE_MSG(test, ksize(buf), priv->cal_blob->size, "Buffer to small");
+
+ memcpy(buf, priv->cal_blob, priv->cal_blob->size);
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t cs_amp_lib_test_get_hp_cal_efi_variable(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ static const efi_char16_t expected_name[] = L"SmartAmpCalibrationData";
+ static const efi_guid_t expected_guid =
+ EFI_GUID(0x53559579, 0x8753, 0x4f5c, 0x91, 0x30, 0xe8, 0x2a, 0xcf, 0xb8, 0xd8, 0x93);
+ struct kunit *test = kunit_get_current_test();
+ struct cs_amp_lib_test_priv *priv = test->priv;
+
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, name);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, guid);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, size);
+
+ if (memcmp(name, expected_name, sizeof(expected_name)) ||
+ efi_guidcmp(*guid, expected_guid))
+ return -EFI_NOT_FOUND;
if (!buf) {
*size = priv->cal_blob->size;
@@ -211,6 +251,25 @@ static efi_status_t cs_amp_lib_test_get_efi_variable(efi_char16_t *name,
return EFI_SUCCESS;
}
+/* Get cal data block from HP variable. */
+static void cs_amp_lib_test_get_hp_efi_cal(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct cirrus_amp_cal_data result_data;
+ int ret;
+
+ cs_amp_lib_test_init_dummy_cal_blob(test, 2);
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_hp_cal_efi_variable);
+
+ ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, 0, &result_data);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ KUNIT_EXPECT_MEMEQ(test, &result_data, &priv->cal_blob->data[0], sizeof(result_data));
+}
+
/* Get cal data block for a given amp, matched by target UID. */
static void cs_amp_lib_test_get_efi_cal_by_uid_test(struct kunit *test)
{
@@ -642,6 +701,185 @@ static void cs_amp_lib_test_write_cal_data_test(struct kunit *test)
KUNIT_EXPECT_EQ(test, entry->value, data.calStatus);
}
+static void cs_amp_lib_test_spkid_lenovo_not_present(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_none);
+
+ KUNIT_EXPECT_EQ(test, -ENOENT, cs_amp_get_vendor_spkid(dev));
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_d0(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ struct kunit *test = kunit_get_current_test();
+
+ if (efi_guidcmp(*guid, LENOVO_SPEAKER_ID_EFI_GUID) ||
+ memcmp(name, LENOVO_SPEAKER_ID_EFI_NAME, sizeof(LENOVO_SPEAKER_ID_EFI_NAME)))
+ return EFI_NOT_FOUND;
+
+ KUNIT_ASSERT_EQ(test, *size, 1);
+ *size = 1;
+ *(u8 *)buf = 0xd0;
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_d1(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ struct kunit *test = kunit_get_current_test();
+
+ if (efi_guidcmp(*guid, LENOVO_SPEAKER_ID_EFI_GUID) ||
+ memcmp(name, LENOVO_SPEAKER_ID_EFI_NAME, sizeof(LENOVO_SPEAKER_ID_EFI_NAME)))
+ return EFI_NOT_FOUND;
+
+ KUNIT_ASSERT_EQ(test, *size, 1);
+ *size = 1;
+ *(u8 *)buf = 0xd1;
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_00(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ struct kunit *test = kunit_get_current_test();
+
+ KUNIT_ASSERT_EQ(test, 0, efi_guidcmp(*guid, LENOVO_SPEAKER_ID_EFI_GUID));
+ KUNIT_ASSERT_EQ(test, *size, 1);
+ *size = 1;
+ *(u8 *)buf = 0;
+
+ return EFI_SUCCESS;
+}
+
+static void cs_amp_lib_test_spkid_lenovo_d0(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_lenovo_d0);
+
+ KUNIT_EXPECT_EQ(test, 0, cs_amp_get_vendor_spkid(dev));
+}
+
+static void cs_amp_lib_test_spkid_lenovo_d1(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_lenovo_d1);
+
+ KUNIT_EXPECT_EQ(test, 1, cs_amp_get_vendor_spkid(dev));
+}
+
+static void cs_amp_lib_test_spkid_lenovo_illegal(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_lenovo_00);
+
+ KUNIT_EXPECT_LT(test, cs_amp_get_vendor_spkid(dev), 0);
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_buf_too_small(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ return EFI_BUFFER_TOO_SMALL;
+}
+
+static void cs_amp_lib_test_spkid_lenovo_oversize(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_buf_too_small);
+
+ KUNIT_EXPECT_LT(test, cs_amp_get_vendor_spkid(dev), 0);
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_hp_30(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ struct kunit *test = kunit_get_current_test();
+
+ if (efi_guidcmp(*guid, HP_SPEAKER_ID_EFI_GUID) ||
+ memcmp(name, HP_SPEAKER_ID_EFI_NAME, sizeof(HP_SPEAKER_ID_EFI_NAME)))
+ return EFI_NOT_FOUND;
+
+ KUNIT_ASSERT_EQ(test, *size, 1);
+ *size = 1;
+ *(u8 *)buf = 0x30;
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t cs_amp_lib_test_get_efi_variable_hp_31(efi_char16_t *name,
+ efi_guid_t *guid,
+ unsigned long *size,
+ void *buf)
+{
+ struct kunit *test = kunit_get_current_test();
+
+ if (efi_guidcmp(*guid, HP_SPEAKER_ID_EFI_GUID) ||
+ memcmp(name, HP_SPEAKER_ID_EFI_NAME, sizeof(HP_SPEAKER_ID_EFI_NAME)))
+ return EFI_NOT_FOUND;
+
+ KUNIT_ASSERT_EQ(test, *size, 1);
+ *size = 1;
+ *(u8 *)buf = 0x31;
+
+ return EFI_SUCCESS;
+}
+
+static void cs_amp_lib_test_spkid_hp_30(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_hp_30);
+
+ KUNIT_EXPECT_EQ(test, 0, cs_amp_get_vendor_spkid(dev));
+}
+
+static void cs_amp_lib_test_spkid_hp_31(struct kunit *test)
+{
+ struct cs_amp_lib_test_priv *priv = test->priv;
+ struct device *dev = &priv->amp_dev->dev;
+
+ kunit_activate_static_stub(test,
+ cs_amp_test_hooks->get_efi_variable,
+ cs_amp_lib_test_get_efi_variable_hp_31);
+
+ KUNIT_EXPECT_EQ(test, 1, cs_amp_get_vendor_spkid(dev));
+}
+
static int cs_amp_lib_test_case_init(struct kunit *test)
{
struct cs_amp_lib_test_priv *priv;
@@ -722,6 +960,7 @@ static struct kunit_case cs_amp_lib_test_cases[] = {
KUNIT_CASE(cs_amp_lib_test_get_efi_cal_no_uid_index_not_found_test),
KUNIT_CASE(cs_amp_lib_test_get_efi_cal_no_uid_no_index_test),
KUNIT_CASE(cs_amp_lib_test_get_efi_cal_zero_not_matched_test),
+ KUNIT_CASE(cs_amp_lib_test_get_hp_efi_cal),
KUNIT_CASE_PARAM(cs_amp_lib_test_get_efi_cal_by_uid_test,
cs_amp_lib_test_get_cal_gen_params),
KUNIT_CASE_PARAM(cs_amp_lib_test_get_efi_cal_by_index_unchecked_test,
@@ -737,6 +976,15 @@ static struct kunit_case cs_amp_lib_test_cases[] = {
/* Tests for writing calibration data */
KUNIT_CASE(cs_amp_lib_test_write_cal_data_test),
+ /* Test cases for speaker ID */
+ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_not_present),
+ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_d0),
+ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_d1),
+ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_illegal),
+ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_oversize),
+ KUNIT_CASE(cs_amp_lib_test_spkid_hp_30),
+ KUNIT_CASE(cs_amp_lib_test_spkid_hp_31),
+
{ } /* terminator */
};
diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c
index 808e67c90f7c..8434d5196107 100644
--- a/sound/soc/codecs/cs-amp-lib.c
+++ b/sound/soc/codecs/cs-amp-lib.c
@@ -16,10 +16,35 @@
#include <linux/types.h>
#include <sound/cs-amp-lib.h>
-#define CS_AMP_CAL_GUID \
+#define CIRRUS_LOGIC_CALIBRATION_EFI_NAME L"CirrusSmartAmpCalibrationData"
+#define CIRRUS_LOGIC_CALIBRATION_EFI_GUID \
EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 0xa3, 0x5d, 0xb3)
-#define CS_AMP_CAL_NAME L"CirrusSmartAmpCalibrationData"
+#define LENOVO_SPEAKER_ID_EFI_NAME L"SdwSpeaker"
+#define LENOVO_SPEAKER_ID_EFI_GUID \
+ EFI_GUID(0x48df970e, 0xe27f, 0x460a, 0xb5, 0x86, 0x77, 0x19, 0x80, 0x1d, 0x92, 0x82)
+
+#define HP_SPEAKER_ID_EFI_NAME L"HPSpeakerID"
+#define HP_SPEAKER_ID_EFI_GUID \
+ EFI_GUID(0xc49593a4, 0xd099, 0x419b, 0xa2, 0xc3, 0x67, 0xe9, 0x80, 0xe6, 0x1d, 0x1e)
+
+#define HP_CALIBRATION_EFI_NAME L"SmartAmpCalibrationData"
+#define HP_CALIBRATION_EFI_GUID \
+ EFI_GUID(0x53559579, 0x8753, 0x4f5c, 0x91, 0x30, 0xe8, 0x2a, 0xcf, 0xb8, 0xd8, 0x93)
+
+static const struct cs_amp_lib_cal_efivar {
+ efi_char16_t *name;
+ efi_guid_t *guid;
+} cs_amp_lib_cal_efivars[] = {
+ {
+ .name = HP_CALIBRATION_EFI_NAME,
+ .guid = &HP_CALIBRATION_EFI_GUID,
+ },
+ {
+ .name = CIRRUS_LOGIC_CALIBRATION_EFI_NAME,
+ .guid = &CIRRUS_LOGIC_CALIBRATION_EFI_GUID,
+ },
+};
static int cs_amp_write_cal_coeff(struct cs_dsp *dsp,
const struct cirrus_amp_cal_controls *controls,
@@ -115,16 +140,41 @@ static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name,
return EFI_NOT_FOUND;
}
+static int cs_amp_convert_efi_status(efi_status_t status)
+{
+ switch (status) {
+ case EFI_SUCCESS:
+ return 0;
+ case EFI_NOT_FOUND:
+ return -ENOENT;
+ case EFI_BUFFER_TOO_SMALL:
+ return -EFBIG;
+ case EFI_UNSUPPORTED:
+ case EFI_ACCESS_DENIED:
+ case EFI_SECURITY_VIOLATION:
+ return -EACCES;
+ default:
+ return -EIO;
+ }
+}
+
static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev)
{
struct cirrus_amp_efi_data *efi_data;
unsigned long data_size = 0;
u8 *data;
efi_status_t status;
- int ret;
+ int i, ret;
+
+ /* Find EFI variable and get size */
+ for (i = 0; i < ARRAY_SIZE(cs_amp_lib_cal_efivars); i++) {
+ status = cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name,
+ cs_amp_lib_cal_efivars[i].guid,
+ &data_size, NULL);
+ if (status == EFI_BUFFER_TOO_SMALL)
+ break;
+ }
- /* Get real size of UEFI variable */
- status = cs_amp_get_efi_variable(CS_AMP_CAL_NAME, &CS_AMP_CAL_GUID, &data_size, NULL);
if (status != EFI_BUFFER_TOO_SMALL)
return ERR_PTR(-ENOENT);
@@ -138,7 +188,9 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev)
if (!data)
return ERR_PTR(-ENOMEM);
- status = cs_amp_get_efi_variable(CS_AMP_CAL_NAME, &CS_AMP_CAL_GUID, &data_size, data);
+ status = cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name,
+ cs_amp_lib_cal_efivars[i].guid,
+ &data_size, data);
if (status != EFI_SUCCESS) {
ret = -EINVAL;
goto err;
@@ -273,6 +325,81 @@ int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_
}
EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibration_data, "SND_SOC_CS_AMP_LIB");
+struct cs_amp_spkid_efi {
+ efi_char16_t *name;
+ efi_guid_t *guid;
+ u8 values[2];
+};
+
+static int cs_amp_get_efi_byte_spkid(struct device *dev, const struct cs_amp_spkid_efi *info)
+{
+ efi_status_t status;
+ unsigned long size;
+ u8 spkid;
+ int i, ret;
+
+ size = sizeof(spkid);
+ status = cs_amp_get_efi_variable(info->name, info->guid, &size, &spkid);
+ ret = cs_amp_convert_efi_status(status);
+ if (ret < 0)
+ return ret;
+
+ if (size == 0)
+ return -ENOENT;
+
+ for (i = 0; i < ARRAY_SIZE(info->values); i++) {
+ if (info->values[i] == spkid)
+ return i;
+ }
+
+ dev_err(dev, "EFI speaker ID bad value %#x\n", spkid);
+
+ return -EINVAL;
+}
+
+static const struct cs_amp_spkid_efi cs_amp_spkid_byte_types[] = {
+ {
+ .name = LENOVO_SPEAKER_ID_EFI_NAME,
+ .guid = &LENOVO_SPEAKER_ID_EFI_GUID,
+ .values = { 0xd0, 0xd1 },
+ },
+ {
+ .name = HP_SPEAKER_ID_EFI_NAME,
+ .guid = &HP_SPEAKER_ID_EFI_GUID,
+ .values = { 0x30, 0x31 },
+ },
+};
+
+/**
+ * cs_amp_get_vendor_spkid - get a speaker ID from vendor-specific storage
+ * @dev: pointer to struct device
+ *
+ * Known vendor-specific methods of speaker ID are checked and if one is
+ * found its speaker ID value is returned.
+ *
+ * Return: >=0 is a valid speaker ID. -ENOENT if a vendor-specific method
+ * was not found. -EACCES if the vendor-specific storage could not
+ * be read. Other error values indicate that the data from the
+ * vendor-specific storage was found but could not be understood.
+ */
+int cs_amp_get_vendor_spkid(struct device *dev)
+{
+ int i, ret;
+
+ if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE) &&
+ !IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST))
+ return -ENOENT;
+
+ for (i = 0; i < ARRAY_SIZE(cs_amp_spkid_byte_types); i++) {
+ ret = cs_amp_get_efi_byte_spkid(dev, &cs_amp_spkid_byte_types[i]);
+ if (ret != -ENOENT)
+ return ret;
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_NS_GPL(cs_amp_get_vendor_spkid, "SND_SOC_CS_AMP_LIB");
+
static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs = {
.get_efi_variable = cs_amp_get_efi_variable,
.write_cal_coeff = cs_amp_write_cal_coeff,
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index 224d65987a8d..173d7c59b725 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -7,6 +7,7 @@
// Author: David Rhodes <david.rhodes@cirrus.com>
#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -1147,45 +1148,55 @@ err_dsp:
return ret;
}
-#ifdef CONFIG_ACPI
-static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
+static int cs35l41_get_system_name(struct cs35l41_private *cs35l41)
{
struct acpi_device *adev = ACPI_COMPANION(cs35l41->dev);
- acpi_handle handle = acpi_device_handle(adev);
- const char *hid;
- const char *sub;
-
- /* If there is no acpi_device, there is no ACPI for this system, return 0 */
- if (!adev)
- return 0;
+ const char *sub = NULL;
+ const char *tmp;
+ int ret = 0;
- sub = acpi_get_subsystem_id(handle);
- if (IS_ERR(sub)) {
- /* If no _SUB, fallback to _HID, otherwise fail */
- if (PTR_ERR(sub) == -ENODATA) {
- hid = acpi_device_hid(adev);
- /* If dummy hid, return 0 and fallback to legacy firmware path */
- if (!strcmp(hid, "device"))
- return 0;
- sub = kstrdup(hid, GFP_KERNEL);
- if (!sub)
- sub = ERR_PTR(-ENOMEM);
-
- } else
- return PTR_ERR(sub);
+ /* If there is no acpi_device, there is no ACPI for this system, skip checking ACPI */
+ if (adev) {
+ acpi_handle handle = acpi_device_handle(adev);
+
+ sub = acpi_get_subsystem_id(handle);
+ ret = PTR_ERR_OR_ZERO(sub);
+ if (ret) {
+ sub = NULL;
+ /* If no _SUB, fallback to _HID, otherwise fail */
+ if (ret == -ENODATA) {
+ tmp = acpi_device_hid(adev);
+ /* If dummy hid, return 0 and fallback to legacy firmware path */
+ if (!strcmp(tmp, "device")) {
+ ret = 0;
+ goto err;
+ }
+ sub = kstrdup(tmp, GFP_KERNEL);
+ if (!sub) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ }
+ }
+ } else {
+ if (!device_property_read_string(cs35l41->dev, "cirrus,subsystem-id", &tmp)) {
+ sub = kstrdup(tmp, GFP_KERNEL);
+ if (!sub) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ }
}
- cs35l41->dsp.system_name = sub;
- dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
+err:
+ if (sub) {
+ cs35l41->dsp.system_name = sub;
+ dev_info(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
+ } else
+ dev_warn(cs35l41->dev, "Subsystem ID not found\n");
- return 0;
-}
-#else
-static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
-{
- return 0;
+ return ret;
}
-#endif /* CONFIG_ACPI */
int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
{
@@ -1317,7 +1328,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
goto err;
}
- ret = cs35l41_acpi_get_name(cs35l41);
+ ret = cs35l41_get_system_name(cs35l41);
if (ret < 0)
goto err;
diff --git a/sound/soc/codecs/cs35l56-i2c.c b/sound/soc/codecs/cs35l56-i2c.c
index 073f1796ae29..0492ddc4102d 100644
--- a/sound/soc/codecs/cs35l56-i2c.c
+++ b/sound/soc/codecs/cs35l56-i2c.c
@@ -35,11 +35,11 @@ static int cs35l56_i2c_probe(struct i2c_client *client)
switch (id) {
case 0x3556:
regmap_config = &cs35l56_regmap_i2c;
- cs35l56->base.fw_reg = &cs35l56_fw_reg;
+ cs35l56->base.type = 0x56;
break;
case 0x3563:
regmap_config = &cs35l63_regmap_i2c;
- cs35l56->base.fw_reg = &cs35l63_fw_reg;
+ cs35l56->base.type = 0x63;
break;
default:
return -ENODEV;
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index 3905c9cb188a..42d24ac2977f 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -527,16 +527,16 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
case 0x3556:
case 0x3557:
regmap_config = &cs35l56_regmap_sdw;
- cs35l56->base.fw_reg = &cs35l56_fw_reg;
break;
case 0x3563:
regmap_config = &cs35l63_regmap_sdw;
- cs35l56->base.fw_reg = &cs35l63_fw_reg;
break;
default:
return -ENODEV;
}
+ cs35l56->base.type = ((unsigned int)id->driver_data) & 0xff;
+
cs35l56->base.regmap = devm_regmap_init(dev, &cs35l56_regmap_bus_sdw,
peripheral, regmap_config);
if (IS_ERR(cs35l56->base.regmap)) {
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 850fcf385996..9e6b9ca2f354 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -309,6 +309,58 @@ static bool cs35l63_volatile_reg(struct device *dev, unsigned int reg)
}
}
+static const struct cs35l56_fw_reg cs35l56_fw_reg = {
+ .fw_ver = CS35L56_DSP1_FW_VER,
+ .halo_state = CS35L56_DSP1_HALO_STATE,
+ .pm_cur_stat = CS35L56_DSP1_PM_CUR_STATE,
+ .prot_sts = CS35L56_PROTECTION_STATUS,
+ .transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
+ .user_mute = CS35L56_MAIN_RENDER_USER_MUTE,
+ .user_volume = CS35L56_MAIN_RENDER_USER_VOLUME,
+ .posture_number = CS35L56_MAIN_POSTURE_NUMBER,
+};
+
+static const struct cs35l56_fw_reg cs35l56_b2_fw_reg = {
+ .fw_ver = CS35L56_DSP1_FW_VER,
+ .halo_state = CS35L56_B2_DSP1_HALO_STATE,
+ .pm_cur_stat = CS35L56_B2_DSP1_PM_CUR_STATE,
+ .prot_sts = CS35L56_PROTECTION_STATUS,
+ .transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
+ .user_mute = CS35L56_MAIN_RENDER_USER_MUTE,
+ .user_volume = CS35L56_MAIN_RENDER_USER_VOLUME,
+ .posture_number = CS35L56_MAIN_POSTURE_NUMBER,
+};
+
+static const struct cs35l56_fw_reg cs35l63_fw_reg = {
+ .fw_ver = CS35L63_DSP1_FW_VER,
+ .halo_state = CS35L63_DSP1_HALO_STATE,
+ .pm_cur_stat = CS35L63_DSP1_PM_CUR_STATE,
+ .prot_sts = CS35L63_PROTECTION_STATUS,
+ .transducer_actual_ps = CS35L63_TRANSDUCER_ACTUAL_PS,
+ .user_mute = CS35L63_MAIN_RENDER_USER_MUTE,
+ .user_volume = CS35L63_MAIN_RENDER_USER_VOLUME,
+ .posture_number = CS35L63_MAIN_POSTURE_NUMBER,
+};
+
+static void cs35l56_set_fw_reg_table(struct cs35l56_base *cs35l56_base)
+{
+ switch (cs35l56_base->type) {
+ default:
+ switch (cs35l56_base->rev) {
+ case 0xb0:
+ cs35l56_base->fw_reg = &cs35l56_fw_reg;
+ break;
+ default:
+ cs35l56_base->fw_reg = &cs35l56_b2_fw_reg;
+ break;
+ }
+ break;
+ case 0x63:
+ cs35l56_base->fw_reg = &cs35l63_fw_reg;
+ break;
+ }
+}
+
int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command)
{
unsigned int val;
@@ -468,6 +520,11 @@ static const struct reg_sequence cs35l56_system_reset_seq[] = {
REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
};
+static const struct reg_sequence cs35l56_b2_system_reset_seq[] = {
+ REG_SEQ0(CS35L56_B2_DSP1_HALO_STATE, 0),
+ REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
+};
+
static const struct reg_sequence cs35l63_system_reset_seq[] = {
REG_SEQ0(CS35L63_DSP1_HALO_STATE, 0),
REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
@@ -490,9 +547,18 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
case 0x54:
case 0x56:
case 0x57:
- regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
- cs35l56_system_reset_seq,
- ARRAY_SIZE(cs35l56_system_reset_seq));
+ switch (cs35l56_base->rev) {
+ case 0xb0:
+ regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
+ cs35l56_system_reset_seq,
+ ARRAY_SIZE(cs35l56_system_reset_seq));
+ break;
+ default:
+ regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
+ cs35l56_b2_system_reset_seq,
+ ARRAY_SIZE(cs35l56_b2_system_reset_seq));
+ break;
+ }
break;
case 0x63:
regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
@@ -979,6 +1045,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
return ret;
}
cs35l56_base->rev = revid & (CS35L56_AREVID_MASK | CS35L56_MTLREVID_MASK);
+ cs35l56_set_fw_reg_table(cs35l56_base);
ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
if (ret)
@@ -1054,7 +1121,17 @@ int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base)
u32 speaker_id;
int i, ret;
- /* Attempt to read the speaker type from a device property first */
+ /* Check for vendor-specific speaker ID method */
+ ret = cs_amp_get_vendor_spkid(cs35l56_base->dev);
+ if (ret >= 0) {
+ dev_dbg(cs35l56_base->dev, "Vendor Speaker ID = %d\n", ret);
+ return ret;
+ } else if (ret != -ENOENT) {
+ dev_err(cs35l56_base->dev, "Error getting vendor Speaker ID: %d\n", ret);
+ return ret;
+ }
+
+ /* Attempt to read the speaker type from a device property */
ret = device_property_read_u32(cs35l56_base->dev, "cirrus,speaker-id", &speaker_id);
if (!ret) {
dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
@@ -1270,30 +1347,6 @@ const struct regmap_config cs35l63_regmap_sdw = {
};
EXPORT_SYMBOL_NS_GPL(cs35l63_regmap_sdw, "SND_SOC_CS35L56_SHARED");
-const struct cs35l56_fw_reg cs35l56_fw_reg = {
- .fw_ver = CS35L56_DSP1_FW_VER,
- .halo_state = CS35L56_DSP1_HALO_STATE,
- .pm_cur_stat = CS35L56_DSP1_PM_CUR_STATE,
- .prot_sts = CS35L56_PROTECTION_STATUS,
- .transducer_actual_ps = CS35L56_TRANSDUCER_ACTUAL_PS,
- .user_mute = CS35L56_MAIN_RENDER_USER_MUTE,
- .user_volume = CS35L56_MAIN_RENDER_USER_VOLUME,
- .posture_number = CS35L56_MAIN_POSTURE_NUMBER,
-};
-EXPORT_SYMBOL_NS_GPL(cs35l56_fw_reg, "SND_SOC_CS35L56_SHARED");
-
-const struct cs35l56_fw_reg cs35l63_fw_reg = {
- .fw_ver = CS35L63_DSP1_FW_VER,
- .halo_state = CS35L63_DSP1_HALO_STATE,
- .pm_cur_stat = CS35L63_DSP1_PM_CUR_STATE,
- .prot_sts = CS35L63_PROTECTION_STATUS,
- .transducer_actual_ps = CS35L63_TRANSDUCER_ACTUAL_PS,
- .user_mute = CS35L63_MAIN_RENDER_USER_MUTE,
- .user_volume = CS35L63_MAIN_RENDER_USER_VOLUME,
- .posture_number = CS35L63_MAIN_POSTURE_NUMBER,
-};
-EXPORT_SYMBOL_NS_GPL(cs35l63_fw_reg, "SND_SOC_CS35L56_SHARED");
-
MODULE_DESCRIPTION("ASoC CS35L56 Shared");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c
index c2ddee22cd23..9bc9b7c98390 100644
--- a/sound/soc/codecs/cs35l56-spi.c
+++ b/sound/soc/codecs/cs35l56-spi.c
@@ -26,7 +26,7 @@ static int cs35l56_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, cs35l56);
- cs35l56->base.fw_reg = &cs35l56_fw_reg;
+ cs35l56->base.type = 0x56;
cs35l56->base.regmap = devm_regmap_init_spi(spi, regmap_config);
if (IS_ERR(cs35l56->base.regmap)) {
diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
index 2a0a4986a9ce..867e23d4fb8d 100644
--- a/sound/soc/codecs/cs42l43-jack.c
+++ b/sound/soc/codecs/cs42l43-jack.c
@@ -684,7 +684,7 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
}
}
-static void cs42l43_clear_jack(struct cs42l43_codec *priv)
+void cs42l43_clear_jack(struct cs42l43_codec *priv)
{
struct cs42l43 *cs42l43 = priv->core;
@@ -703,8 +703,6 @@ static void cs42l43_clear_jack(struct cs42l43_codec *priv)
regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
0x2 << CS42L43_HSDET_MODE_SHIFT);
-
- snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
}
void cs42l43_tip_sense_work(struct work_struct *work)
@@ -753,6 +751,8 @@ void cs42l43_tip_sense_work(struct work_struct *work)
cs42l43_clear_jack(priv);
+ snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
+
if (cs42l43->sdw && priv->jack_present) {
pm_runtime_put(priv->dev);
priv->jack_present = false;
@@ -903,6 +903,8 @@ int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
cs42l43_clear_jack(priv);
+ snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
+
if (!override) {
queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
} else {
diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c
index b0c27d696c58..b61df09f20cf 100644
--- a/sound/soc/codecs/cs42l43.c
+++ b/sound/soc/codecs/cs42l43.c
@@ -2210,13 +2210,12 @@ static const struct cs42l43_irq cs42l43_irqs[] = {
};
static int cs42l43_request_irq(struct cs42l43_codec *priv,
- struct irq_domain *dom, const char * const name,
- unsigned int irq, irq_handler_t handler,
- unsigned long flags)
+ const char * const name, unsigned int irq,
+ irq_handler_t handler, unsigned long flags)
{
int ret;
- ret = irq_create_mapping(dom, irq);
+ ret = irq_create_mapping(priv->dom, irq);
if (ret < 0)
return dev_err_probe(priv->dev, ret, "Failed to map IRQ %s\n", name);
@@ -2230,13 +2229,29 @@ static int cs42l43_request_irq(struct cs42l43_codec *priv,
return 0;
}
-static int cs42l43_shutter_irq(struct cs42l43_codec *priv,
- struct irq_domain *dom, unsigned int shutter,
- const char * const open_name,
- const char * const close_name,
+static void cs42l43_disable_irq(struct cs42l43_codec *priv, unsigned int irq)
+{
+ int ret;
+
+ ret = irq_find_mapping(priv->dom, irq);
+ if (ret > 0)
+ disable_irq(ret);
+}
+
+static void cs42l43_enable_irq(struct cs42l43_codec *priv, unsigned int irq)
+{
+ int ret;
+
+ ret = irq_find_mapping(priv->dom, irq);
+ if (ret > 0)
+ enable_irq(ret);
+}
+
+static int cs42l43_shutter_irq(struct cs42l43_codec *priv, unsigned int shutter,
+ const char * const open_name, unsigned int *open_irq,
+ const char * const close_name, unsigned int *close_irq,
irq_handler_t handler)
{
- unsigned int open_irq, close_irq;
int ret;
switch (shutter) {
@@ -2244,40 +2259,35 @@ static int cs42l43_shutter_irq(struct cs42l43_codec *priv,
dev_warn(priv->dev, "Manual shutters, notifications not available\n");
return 0;
case 0x2:
- open_irq = CS42L43_GPIO1_RISE;
- close_irq = CS42L43_GPIO1_FALL;
+ *open_irq = CS42L43_GPIO1_RISE;
+ *close_irq = CS42L43_GPIO1_FALL;
break;
case 0x4:
- open_irq = CS42L43_GPIO2_RISE;
- close_irq = CS42L43_GPIO2_FALL;
+ *open_irq = CS42L43_GPIO2_RISE;
+ *close_irq = CS42L43_GPIO2_FALL;
break;
case 0x8:
- open_irq = CS42L43_GPIO3_RISE;
- close_irq = CS42L43_GPIO3_FALL;
+ *open_irq = CS42L43_GPIO3_RISE;
+ *close_irq = CS42L43_GPIO3_FALL;
break;
default:
return 0;
}
- ret = cs42l43_request_irq(priv, dom, close_name, close_irq, handler, IRQF_SHARED);
+ ret = cs42l43_request_irq(priv, close_name, *close_irq, handler, IRQF_SHARED);
if (ret)
return ret;
- return cs42l43_request_irq(priv, dom, open_name, open_irq, handler, IRQF_SHARED);
+ return cs42l43_request_irq(priv, open_name, *open_irq, handler, IRQF_SHARED);
}
static int cs42l43_codec_probe(struct platform_device *pdev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
struct cs42l43_codec *priv;
- struct irq_domain *dom;
unsigned int val;
int i, ret;
- dom = irq_find_matching_fwnode(dev_fwnode(cs42l43->dev), DOMAIN_BUS_ANY);
- if (!dom)
- return -EPROBE_DEFER;
-
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -2285,6 +2295,10 @@ static int cs42l43_codec_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
priv->core = cs42l43;
+ priv->dom = irq_find_matching_fwnode(dev_fwnode(cs42l43->dev), DOMAIN_BUS_ANY);
+ if (!priv->dom)
+ return -EPROBE_DEFER;
+
platform_set_drvdata(pdev, priv);
mutex_init(&priv->jack_lock);
@@ -2314,7 +2328,7 @@ static int cs42l43_codec_probe(struct platform_device *pdev)
goto err_pm;
for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) {
- ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name,
+ ret = cs42l43_request_irq(priv, cs42l43_irqs[i].name,
cs42l43_irqs[i].irq,
cs42l43_irqs[i].handler, 0);
if (ret)
@@ -2327,15 +2341,17 @@ static int cs42l43_codec_probe(struct platform_device *pdev)
goto err_pm;
}
- ret = cs42l43_shutter_irq(priv, dom, val & CS42L43_MIC_SHUTTER_CFG_MASK,
- "mic shutter open", "mic shutter close",
+ ret = cs42l43_shutter_irq(priv, val & CS42L43_MIC_SHUTTER_CFG_MASK,
+ "mic shutter open", &priv->shutter_irqs[0],
+ "mic shutter close", &priv->shutter_irqs[1],
cs42l43_mic_shutter);
if (ret)
goto err_pm;
- ret = cs42l43_shutter_irq(priv, dom, (val & CS42L43_SPK_SHUTTER_CFG_MASK) >>
+ ret = cs42l43_shutter_irq(priv, (val & CS42L43_SPK_SHUTTER_CFG_MASK) >>
CS42L43_SPK_SHUTTER_CFG_SHIFT,
- "spk shutter open", "spk shutter close",
+ "spk shutter open", &priv->shutter_irqs[2],
+ "spk shutter close", &priv->shutter_irqs[3],
cs42l43_spk_shutter);
if (ret)
goto err_pm;
@@ -2386,22 +2402,53 @@ static int cs42l43_codec_runtime_resume(struct device *dev)
return 0;
}
-static int cs42l43_codec_runtime_force_suspend(struct device *dev)
+static int cs42l43_codec_suspend(struct device *dev)
{
struct cs42l43_codec *priv = dev_get_drvdata(dev);
+ int i;
- dev_dbg(priv->dev, "Runtime suspend\n");
+ dev_dbg(priv->dev, "System suspend\n");
priv->suspend_jack_debounce = true;
- pm_runtime_force_suspend(dev);
+ for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++)
+ cs42l43_disable_irq(priv, cs42l43_irqs[i].irq);
+
+ for (i = 0; i < ARRAY_SIZE(priv->shutter_irqs); i++)
+ if (priv->shutter_irqs[i])
+ cs42l43_disable_irq(priv, priv->shutter_irqs[i]);
+
+ cancel_delayed_work_sync(&priv->bias_sense_timeout);
+ cancel_delayed_work_sync(&priv->tip_sense_work);
+ cancel_delayed_work_sync(&priv->hp_ilimit_clear_work);
+
+ cs42l43_clear_jack(priv);
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int cs42l43_codec_resume(struct device *dev)
+{
+ struct cs42l43_codec *priv = dev_get_drvdata(dev);
+ int ret, i;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++)
+ cs42l43_enable_irq(priv, cs42l43_irqs[i].irq);
+
+ for (i = 0; i < ARRAY_SIZE(priv->shutter_irqs); i++)
+ if (priv->shutter_irqs[i])
+ cs42l43_enable_irq(priv, priv->shutter_irqs[i]);
return 0;
}
static const struct dev_pm_ops cs42l43_codec_pm_ops = {
RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL)
- SYSTEM_SLEEP_PM_OPS(cs42l43_codec_runtime_force_suspend, pm_runtime_force_resume)
+ SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend, cs42l43_codec_resume)
};
static const struct platform_device_id cs42l43_codec_id_table[] = {
diff --git a/sound/soc/codecs/cs42l43.h b/sound/soc/codecs/cs42l43.h
index 3ea36362b11a..b2fa2cd1d99f 100644
--- a/sound/soc/codecs/cs42l43.h
+++ b/sound/soc/codecs/cs42l43.h
@@ -44,6 +44,8 @@ struct cs42l43_codec {
struct device *dev;
struct cs42l43 *core;
struct snd_soc_component *component;
+ struct irq_domain *dom;
+ unsigned int shutter_irqs[4];
struct clk *mclk;
@@ -130,6 +132,7 @@ static inline int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream
int cs42l43_set_jack(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *d);
void cs42l43_bias_sense_timeout(struct work_struct *work);
+void cs42l43_clear_jack(struct cs42l43_codec *priv);
void cs42l43_tip_sense_work(struct work_struct *work);
irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data);
irqreturn_t cs42l43_button_press(int irq, void *data);
diff --git a/sound/soc/codecs/cs48l32-tables.c b/sound/soc/codecs/cs48l32-tables.c
index 59eaa9a5029f..8ff3652a010e 100644
--- a/sound/soc/codecs/cs48l32-tables.c
+++ b/sound/soc/codecs/cs48l32-tables.c
@@ -533,8 +533,6 @@ static const struct regmap_config cs48l32_regmap = {
int cs48l32_create_regmap(struct spi_device *spi, struct cs48l32 *cs48l32)
{
cs48l32->regmap = devm_regmap_init_spi(spi, &cs48l32_regmap);
- if (IS_ERR(cs48l32->regmap))
- return PTR_ERR(cs48l32->regmap);
- return 0;
+ return PTR_ERR_OR_ZERO(cs48l32->regmap);
}
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index a4496cc26902..ae89260ca215 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -2247,10 +2247,8 @@ static int da7213_runtime_resume(struct device *dev)
return regcache_sync(da7213->regmap);
}
-static const struct dev_pm_ops da7213_pm = {
- RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL)
- SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
-};
+static DEFINE_RUNTIME_DEV_PM_OPS(da7213_pm, da7213_runtime_suspend,
+ da7213_runtime_resume, NULL);
static const struct i2c_device_id da7213_i2c_id[] = {
{ "da7213" },
diff --git a/sound/soc/codecs/es8323.c b/sound/soc/codecs/es8323.c
index a9822998199f..eb85b71e87f3 100644
--- a/sound/soc/codecs/es8323.c
+++ b/sound/soc/codecs/es8323.c
@@ -182,13 +182,13 @@ static const struct snd_kcontrol_new es8323_mono_adc_mux_controls =
/* Left Mixer */
static const struct snd_kcontrol_new es8323_left_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left Playback Switch", SND_SOC_NOPM, 7, 1, 1),
+ SOC_DAPM_SINGLE("Left Playback Switch", ES8323_DACCONTROL17, 7, 1, 0),
SOC_DAPM_SINGLE("Left Bypass Switch", ES8323_DACCONTROL17, 6, 1, 0),
};
/* Right Mixer */
static const struct snd_kcontrol_new es8323_right_mixer_controls[] = {
- SOC_DAPM_SINGLE("Right Playback Switch", SND_SOC_NOPM, 6, 1, 1),
+ SOC_DAPM_SINGLE("Right Playback Switch", ES8323_DACCONTROL20, 7, 1, 0),
SOC_DAPM_SINGLE("Right Bypass Switch", ES8323_DACCONTROL20, 6, 1, 0),
};
@@ -211,8 +211,8 @@ static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = {
SND_SOC_DAPM_ADC("Right ADC", "Right Capture", SND_SOC_NOPM, 4, 1),
SND_SOC_DAPM_ADC("Left ADC", "Left Capture", SND_SOC_NOPM, 5, 1),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", SND_SOC_NOPM, 6, 1),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", SND_SOC_NOPM, 7, 1),
+ SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8323_DACPOWER, 6, 1),
+ SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8323_DACPOWER, 7, 1),
SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
&es8323_left_mixer_controls[0],
@@ -223,10 +223,10 @@ static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = {
SND_SOC_DAPM_PGA("Right ADC Power", SND_SOC_NOPM, 6, 1, NULL, 0),
SND_SOC_DAPM_PGA("Left ADC Power", SND_SOC_NOPM, 7, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 2", SND_SOC_NOPM, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 2", SND_SOC_NOPM, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 1", SND_SOC_NOPM, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 1", SND_SOC_NOPM, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Out 2", ES8323_DACPOWER, 2, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Left Out 2", ES8323_DACPOWER, 3, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Out 1", ES8323_DACPOWER, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Left Out 1", ES8323_DACPOWER, 5, 0, NULL, 0),
SND_SOC_DAPM_PGA("LAMP", ES8323_ADCCONTROL1, 4, 0, NULL, 0),
SND_SOC_DAPM_PGA("RAMP", ES8323_ADCCONTROL1, 0, 0, NULL, 0),
@@ -632,7 +632,6 @@ static int es8323_probe(struct snd_soc_component *component)
snd_soc_component_write(component, ES8323_CONTROL2, 0x60);
snd_soc_component_write(component, ES8323_CHIPPOWER, 0x00);
- snd_soc_component_write(component, ES8323_DACCONTROL17, 0xB8);
return 0;
}
diff --git a/sound/soc/codecs/fs-amp-lib.c b/sound/soc/codecs/fs-amp-lib.c
new file mode 100644
index 000000000000..c8f56617e370
--- /dev/null
+++ b/sound/soc/codecs/fs-amp-lib.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// fs-amp-lib.c --- Common library for FourSemi Audio Amplifiers
+//
+// Copyright (C) 2016-2025 Shanghai FourSemi Semiconductor Co.,Ltd.
+
+#include <linux/crc16.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "fs-amp-lib.h"
+
+static int fs_get_scene_count(struct fs_amp_lib *amp_lib)
+{
+ const struct fs_fwm_table *table;
+ int count;
+
+ if (!amp_lib || !amp_lib->dev)
+ return -EINVAL;
+
+ table = amp_lib->table[FS_INDEX_SCENE];
+ if (!table)
+ return -EFAULT;
+
+ count = table->size / sizeof(struct fs_scene_index);
+ if (count < 1 || count > FS_SCENE_COUNT_MAX) {
+ dev_err(amp_lib->dev, "Invalid scene count: %d\n", count);
+ return -ERANGE;
+ }
+
+ return count;
+}
+
+static void fs_get_fwm_string(struct fs_amp_lib *amp_lib,
+ int offset, const char **pstr)
+{
+ const struct fs_fwm_table *table;
+
+ if (!amp_lib || !amp_lib->dev || !pstr)
+ return;
+
+ table = amp_lib->table[FS_INDEX_STRING];
+ if (table && offset > 0 && offset < table->size + sizeof(*table))
+ *pstr = (char *)table + offset;
+ else
+ *pstr = NULL;
+}
+
+static void fs_get_scene_reg(struct fs_amp_lib *amp_lib,
+ int offset, struct fs_amp_scene *scene)
+{
+ const struct fs_fwm_table *table;
+
+ if (!amp_lib || !amp_lib->dev || !scene)
+ return;
+
+ table = amp_lib->table[FS_INDEX_REG];
+ if (table && offset > 0 && offset < table->size + sizeof(*table))
+ scene->reg = (struct fs_reg_table *)((char *)table + offset);
+ else
+ scene->reg = NULL;
+}
+
+static void fs_get_scene_model(struct fs_amp_lib *amp_lib,
+ int offset, struct fs_amp_scene *scene)
+{
+ const struct fs_fwm_table *table;
+ const char *ptr;
+
+ if (!amp_lib || !amp_lib->dev || !scene)
+ return;
+
+ table = amp_lib->table[FS_INDEX_MODEL];
+ ptr = (char *)table;
+ if (table && offset > 0 && offset < table->size + sizeof(*table))
+ scene->model = (struct fs_file_table *)(ptr + offset);
+ else
+ scene->model = NULL;
+}
+
+static void fs_get_scene_effect(struct fs_amp_lib *amp_lib,
+ int offset, struct fs_amp_scene *scene)
+{
+ const struct fs_fwm_table *table;
+ const char *ptr;
+
+ if (!amp_lib || !amp_lib->dev || !scene)
+ return;
+
+ table = amp_lib->table[FS_INDEX_EFFECT];
+ ptr = (char *)table;
+ if (table && offset > 0 && offset < table->size + sizeof(*table))
+ scene->effect = (struct fs_file_table *)(ptr + offset);
+ else
+ scene->effect = NULL;
+}
+
+static int fs_parse_scene_tables(struct fs_amp_lib *amp_lib)
+{
+ const struct fs_scene_index *scene_index;
+ const struct fs_fwm_table *table;
+ struct fs_amp_scene *scene;
+ int idx, count;
+
+ if (!amp_lib || !amp_lib->dev)
+ return -EINVAL;
+
+ count = fs_get_scene_count(amp_lib);
+ if (count <= 0)
+ return -EFAULT;
+
+ scene = devm_kcalloc(amp_lib->dev, count, sizeof(*scene), GFP_KERNEL);
+ if (!scene)
+ return -ENOMEM;
+
+ amp_lib->scene_count = count;
+ amp_lib->scene = scene;
+
+ table = amp_lib->table[FS_INDEX_SCENE];
+ scene_index = (struct fs_scene_index *)table->buf;
+
+ for (idx = 0; idx < count; idx++) {
+ fs_get_fwm_string(amp_lib, scene_index->name, &scene->name);
+ if (!scene->name)
+ scene->name = devm_kasprintf(amp_lib->dev,
+ GFP_KERNEL, "S%d", idx);
+ dev_dbg(amp_lib->dev, "scene.%d name: %s\n", idx, scene->name);
+ fs_get_scene_reg(amp_lib, scene_index->reg, scene);
+ fs_get_scene_model(amp_lib, scene_index->model, scene);
+ fs_get_scene_effect(amp_lib, scene_index->effect, scene);
+ scene++;
+ scene_index++;
+ }
+
+ return 0;
+}
+
+static int fs_parse_all_tables(struct fs_amp_lib *amp_lib)
+{
+ const struct fs_fwm_table *table;
+ const struct fs_fwm_index *index;
+ const char *ptr;
+ int idx, count;
+ int ret;
+
+ if (!amp_lib || !amp_lib->dev || !amp_lib->hdr)
+ return -EINVAL;
+
+ /* Parse all fwm tables */
+ table = (struct fs_fwm_table *)amp_lib->hdr->params;
+ index = (struct fs_fwm_index *)table->buf;
+ count = table->size / sizeof(*index);
+
+ for (idx = 0; idx < count; idx++, index++) {
+ if (index->type >= FS_INDEX_MAX)
+ return -ERANGE;
+ ptr = (char *)table + (int)index->offset;
+ amp_lib->table[index->type] = (struct fs_fwm_table *)ptr;
+ }
+
+ /* Parse all scene tables */
+ ret = fs_parse_scene_tables(amp_lib);
+ if (ret)
+ dev_err(amp_lib->dev, "Failed to parse scene: %d\n", ret);
+
+ return ret;
+}
+
+static int fs_verify_firmware(struct fs_amp_lib *amp_lib)
+{
+ const struct fs_fwm_header *hdr;
+ int crcsum;
+
+ if (!amp_lib || !amp_lib->dev || !amp_lib->hdr)
+ return -EINVAL;
+
+ hdr = amp_lib->hdr;
+
+ /* Verify the crcsum code */
+ crcsum = crc16(0x0000, (const char *)&hdr->crc_size, hdr->crc_size);
+ if (crcsum != hdr->crc16) {
+ dev_err(amp_lib->dev, "Failed to checksum: %x-%x\n",
+ crcsum, hdr->crc16);
+ return -EFAULT;
+ }
+
+ /* Verify the devid(chip_type) */
+ if (amp_lib->devid != LO_U16(hdr->chip_type)) {
+ dev_err(amp_lib->dev, "DEVID dismatch: %04X#%04X\n",
+ amp_lib->devid, hdr->chip_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void fs_print_firmware_info(struct fs_amp_lib *amp_lib)
+{
+ const struct fs_fwm_header *hdr;
+ const char *pro_name = NULL;
+ const char *dev_name = NULL;
+
+ if (!amp_lib || !amp_lib->dev || !amp_lib->hdr)
+ return;
+
+ hdr = amp_lib->hdr;
+
+ fs_get_fwm_string(amp_lib, hdr->project, &pro_name);
+ fs_get_fwm_string(amp_lib, hdr->device, &dev_name);
+
+ dev_info(amp_lib->dev, "Project: %s Device: %s\n",
+ pro_name ? pro_name : "null",
+ dev_name ? dev_name : "null");
+
+ dev_info(amp_lib->dev, "Date: %04d%02d%02d-%02d%02d\n",
+ hdr->date.year, hdr->date.month, hdr->date.day,
+ hdr->date.hour, hdr->date.minute);
+}
+
+int fs_amp_load_firmware(struct fs_amp_lib *amp_lib, const char *name)
+{
+ const struct firmware *cont;
+ struct fs_fwm_header *hdr;
+ int ret;
+
+ if (!amp_lib || !amp_lib->dev || !name)
+ return -EINVAL;
+
+ ret = request_firmware(&cont, name, amp_lib->dev);
+ if (ret) {
+ dev_err(amp_lib->dev, "Failed to request %s: %d\n", name, ret);
+ return ret;
+ }
+
+ dev_info(amp_lib->dev, "Loading %s - size: %zu\n", name, cont->size);
+
+ hdr = devm_kmemdup(amp_lib->dev, cont->data, cont->size, GFP_KERNEL);
+ release_firmware(cont);
+ if (!hdr)
+ return -ENOMEM;
+
+ amp_lib->hdr = hdr;
+ ret = fs_verify_firmware(amp_lib);
+ if (ret) {
+ amp_lib->hdr = NULL;
+ return ret;
+ }
+
+ ret = fs_parse_all_tables(amp_lib);
+ if (ret) {
+ amp_lib->hdr = NULL;
+ return ret;
+ }
+
+ fs_print_firmware_info(amp_lib);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fs_amp_load_firmware);
+
+MODULE_AUTHOR("Nick Li <nick.li@foursemi.com>");
+MODULE_DESCRIPTION("FourSemi audio amplifier library");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/fs-amp-lib.h b/sound/soc/codecs/fs-amp-lib.h
new file mode 100644
index 000000000000..4a77c7b383cd
--- /dev/null
+++ b/sound/soc/codecs/fs-amp-lib.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * fs-amp-lib.h --- Common library for FourSemi Audio Amplifiers
+ *
+ * Copyright (C) 2016-2025 Shanghai FourSemi Semiconductor Co.,Ltd.
+ */
+
+#ifndef __FS_AMP_LIB_H__
+#define __FS_AMP_LIB_H__
+
+#define HI_U16(a) (((a) >> 8) & 0xFF)
+#define LO_U16(a) ((a) & 0xFF)
+#define FS_TABLE_NAME_LEN (4)
+#define FS_SCENE_COUNT_MAX (16)
+#define FS_CMD_DELAY_MS_MAX (100) /* 100ms */
+
+#define FS_CMD_DELAY (0xFF)
+#define FS_CMD_BURST (0xFE)
+#define FS_CMD_UPDATE (0xFD)
+
+#define FS_SOC_ENUM_EXT(xname, xhandler_info, xhandler_get, xhandler_put) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = xhandler_info, \
+ .get = xhandler_get, .put = xhandler_put \
+}
+
+enum fs_index_type {
+ FS_INDEX_INFO = 0,
+ FS_INDEX_STCOEF,
+ FS_INDEX_SCENE,
+ FS_INDEX_MODEL,
+ FS_INDEX_REG,
+ FS_INDEX_EFFECT,
+ FS_INDEX_STRING,
+ FS_INDEX_WOOFER,
+ FS_INDEX_MAX,
+};
+
+#pragma pack(push, 1)
+
+struct fs_reg_val {
+ u8 reg;
+ u16 val;
+};
+
+struct fs_reg_bits {
+ u8 cmd; /* FS_CMD_UPDATE */
+ u8 reg;
+ u16 val;
+ u16 mask;
+};
+
+struct fs_cmd_pkg {
+ union {
+ u8 cmd;
+ struct fs_reg_val regv;
+ struct fs_reg_bits regb;
+ };
+};
+
+struct fs_fwm_index {
+ /* Index type */
+ u16 type;
+ /* Offset address starting from the end of header */
+ u16 offset;
+};
+
+struct fs_fwm_table {
+ char name[FS_TABLE_NAME_LEN];
+ u16 size; /* size of buf */
+ u8 buf[];
+};
+
+struct fs_scene_index {
+ /* Offset address(scene name) in string table */
+ u16 name;
+ /* Offset address(scene reg) in register table */
+ u16 reg;
+ /* Offset address(scene model) in model table */
+ u16 model;
+ /* Offset address(scene effect) in effect table */
+ u16 effect;
+};
+
+struct fs_reg_table {
+ u16 size; /* size of buf */
+ u8 buf[];
+};
+
+struct fs_file_table {
+ u16 name;
+ u16 size; /* size of buf */
+ u8 buf[];
+};
+
+struct fs_fwm_date {
+ u32 year:12;
+ u32 month:4;
+ u32 day:5;
+ u32 hour:5;
+ u32 minute:6;
+};
+
+struct fs_fwm_header {
+ u16 version;
+ u16 project; /* Offset address(project name) in string table */
+ u16 device; /* Offset address(device name) in string table */
+ struct fs_fwm_date date;
+ u16 crc16;
+ u16 crc_size; /* Starting position for CRC checking */
+ u16 chip_type;
+ u16 addr; /* 7-bit i2c address */
+ u16 spkid;
+ u16 rsvd[6];
+ u8 params[];
+};
+
+#pragma pack(pop)
+
+struct fs_i2s_srate {
+ u32 srate; /* Sample rate */
+ u16 i2ssr; /* Value of Bit field[I2SSR] */
+};
+
+struct fs_pll_div {
+ unsigned int bclk; /* Rate of bit clock */
+ u16 pll1;
+ u16 pll2;
+ u16 pll3;
+};
+
+struct fs_amp_scene {
+ const char *name;
+ const struct fs_reg_table *reg;
+ const struct fs_file_table *model;
+ const struct fs_file_table *effect;
+};
+
+struct fs_amp_lib {
+ const struct fs_fwm_header *hdr;
+ const struct fs_fwm_table *table[FS_INDEX_MAX];
+ struct fs_amp_scene *scene;
+ struct device *dev;
+ int scene_count;
+ u16 devid;
+};
+
+int fs_amp_load_firmware(struct fs_amp_lib *amp_lib, const char *name);
+
+#endif // __FS_AMP_LIB_H__
diff --git a/sound/soc/codecs/fs210x.c b/sound/soc/codecs/fs210x.c
new file mode 100644
index 000000000000..e2f85714972d
--- /dev/null
+++ b/sound/soc/codecs/fs210x.c
@@ -0,0 +1,1586 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// fs210x.c -- Driver for the FS2104/5S Audio Amplifier
+//
+// Copyright (C) 2016-2025 Shanghai FourSemi Semiconductor Co.,Ltd.
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/workqueue.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "fs210x.h"
+#include "fs-amp-lib.h"
+
+#define FS210X_DEFAULT_FWM_NAME "fs210x_fwm.bin"
+#define FS210X_DEFAULT_DAI_NAME "fs210x-aif"
+#define FS2105S_DEVICE_ID 0x20 /* FS2105S */
+#define FS210X_DEVICE_ID 0x45 /* FS2104 */
+#define FS210X_REG_MAX 0xF8
+#define FS210X_INIT_SCENE 0
+#define FS210X_DEFAULT_SCENE 1
+#define FS210X_START_DELAY_MS 5
+#define FS210X_FAULT_CHECK_INTERVAL_MS 2000
+#define FS2105S_RATES (SNDRV_PCM_RATE_32000 | \
+ SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_88200 | \
+ SNDRV_PCM_RATE_96000)
+#define FS210X_RATES (SNDRV_PCM_RATE_16000 | FS2105S_RATES)
+#define FS210X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S24_3LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+#define FS210X_NUM_SUPPLIES ARRAY_SIZE(fs210x_supply_names)
+
+static const char *const fs210x_supply_names[] = {
+ "pvdd",
+ "dvdd",
+};
+
+struct fs210x_platform_data {
+ const char *fwm_name;
+};
+
+struct fs210x_priv {
+ struct i2c_client *i2c;
+ struct device *dev;
+ struct regmap *regmap;
+ struct fs210x_platform_data pdata;
+ struct regulator_bulk_data supplies[FS210X_NUM_SUPPLIES];
+ struct gpio_desc *gpio_sdz;
+ struct delayed_work start_work;
+ struct delayed_work fault_check_work;
+ struct fs_amp_lib amp_lib;
+ const struct fs_amp_scene *cur_scene;
+ struct clk *clk_bclk;
+ /*
+ * @lock: Mutex ensuring exclusive access for critical device operations
+ *
+ * This lock serializes access between the following actions:
+ * - Device initialization procedures(probe)
+ * - Enable/disable device(DAPM event)
+ * - Suspend/resume device(PM)
+ * - Runtime scene switching(control)
+ * - Scheduling/execution of delayed works items(delayed works)
+ */
+ struct mutex lock;
+ unsigned int check_interval_ms;
+ unsigned int bclk;
+ unsigned int srate;
+ int scene_id;
+ u16 devid;
+ bool is_inited;
+ bool is_suspended;
+ bool is_bclk_on;
+ bool is_playing;
+};
+
+static const unsigned int fs2105s_rates[] = {
+ 32000, 44100, 48000, 88200, 96000
+};
+
+static const struct snd_pcm_hw_constraint_list fs2105s_constraints = {
+ .count = ARRAY_SIZE(fs2105s_rates),
+ .list = fs2105s_rates,
+};
+
+static const unsigned int fs210x_rates[] = {
+ 16000, 32000, 44100, 48000, 88200, 96000
+};
+
+static const struct snd_pcm_hw_constraint_list fs210x_constraints = {
+ .count = ARRAY_SIZE(fs210x_rates),
+ .list = fs210x_rates,
+};
+
+static const struct fs_pll_div fs210x_pll_div[] = {
+ /* bclk, pll1, pll2, pll3 */
+ { 512000, 0x006C, 0x0120, 0x0001 },
+ { 768000, 0x016C, 0x00C0, 0x0001 },
+ { 1024000, 0x016C, 0x0090, 0x0001 },
+ { 1536000, 0x016C, 0x0060, 0x0001 },
+ { 2048000, 0x016C, 0x0090, 0x0002 },
+ { 2304000, 0x016C, 0x0080, 0x0002 },
+ { 3072000, 0x016C, 0x0090, 0x0003 },
+ { 4096000, 0x016C, 0x0090, 0x0004 },
+ { 4608000, 0x016C, 0x0080, 0x0004 },
+ { 6144000, 0x016C, 0x0090, 0x0006 },
+ { 8192000, 0x016C, 0x0090, 0x0008 },
+ { 9216000, 0x016C, 0x0090, 0x0009 },
+ { 12288000, 0x016C, 0x0090, 0x000C },
+ { 16384000, 0x016C, 0x0090, 0x0010 },
+ { 18432000, 0x016C, 0x0090, 0x0012 },
+ { 24576000, 0x016C, 0x0090, 0x0018 },
+ { 1411200, 0x016C, 0x0060, 0x0001 },
+ { 2116800, 0x016C, 0x0080, 0x0002 },
+ { 2822400, 0x016C, 0x0090, 0x0003 },
+ { 4233600, 0x016C, 0x0080, 0x0004 },
+ { 5644800, 0x016C, 0x0090, 0x0006 },
+ { 8467200, 0x016C, 0x0090, 0x0009 },
+ { 11289600, 0x016C, 0x0090, 0x000C },
+ { 16934400, 0x016C, 0x0090, 0x0012 },
+ { 22579200, 0x016C, 0x0090, 0x0018 },
+ { 2000000, 0x017C, 0x0093, 0x0002 },
+};
+
+static int fs210x_bclk_set(struct fs210x_priv *fs210x, bool on)
+{
+ int ret = 0;
+
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ if ((fs210x->is_bclk_on ^ on) == 0)
+ return 0;
+
+ if (on) {
+ clk_set_rate(fs210x->clk_bclk, fs210x->bclk);
+ ret = clk_prepare_enable(fs210x->clk_bclk);
+ fs210x->is_bclk_on = true;
+ fsleep(2000); /* >= 2ms */
+ } else {
+ clk_disable_unprepare(fs210x->clk_bclk);
+ fs210x->is_bclk_on = false;
+ }
+
+ return ret;
+}
+
+static int fs210x_reg_write(struct fs210x_priv *fs210x,
+ u8 reg, u16 val)
+{
+ int ret;
+
+ ret = regmap_write(fs210x->regmap, reg, val);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to write %02Xh: %d\n", reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fs210x_reg_read(struct fs210x_priv *fs210x,
+ u8 reg, u16 *pval)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(fs210x->regmap, reg, &val);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to read %02Xh: %d\n", reg, ret);
+ return ret;
+ }
+
+ *pval = (u16)val;
+
+ return 0;
+}
+
+static int fs210x_reg_update_bits(struct fs210x_priv *fs210x,
+ u8 reg, u16 mask, u16 val)
+{
+ int ret;
+
+ ret = regmap_update_bits(fs210x->regmap, reg, mask, val);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to update %02Xh: %d\n", reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fs210x_reg_bulk_write(struct fs210x_priv *fs210x,
+ u8 reg, const void *val, u32 size)
+{
+ int ret;
+
+ ret = regmap_bulk_write(fs210x->regmap, reg, val, size / 2);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to bulk write %02Xh: %d\n",
+ reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline int fs210x_write_reg_val(struct fs210x_priv *fs210x,
+ const struct fs_reg_val *regv)
+{
+ return fs210x_reg_write(fs210x, regv->reg, regv->val);
+}
+
+static inline int fs210x_write_reg_bits(struct fs210x_priv *fs210x,
+ const struct fs_reg_bits *regu)
+{
+ return fs210x_reg_update_bits(fs210x,
+ regu->reg,
+ regu->mask,
+ regu->val);
+}
+
+static inline int fs210x_set_cmd_pkg(struct fs210x_priv *fs210x,
+ const struct fs_cmd_pkg *pkg,
+ unsigned int *offset)
+{
+ int delay_us;
+
+ if (pkg->cmd >= 0x00 && pkg->cmd <= FS210X_REG_MAX) {
+ *offset = sizeof(pkg->regv);
+ return fs210x_write_reg_val(fs210x, &pkg->regv);
+ } else if (pkg->cmd == FS_CMD_UPDATE) {
+ *offset = sizeof(pkg->regb);
+ return fs210x_write_reg_bits(fs210x, &pkg->regb);
+ } else if (pkg->cmd == FS_CMD_DELAY) {
+ if (pkg->regv.val > FS_CMD_DELAY_MS_MAX)
+ return -EOPNOTSUPP;
+ delay_us = pkg->regv.val * 1000; /* ms -> us */
+ fsleep(delay_us);
+ *offset = sizeof(pkg->regv);
+ return 0;
+ }
+
+ dev_err(fs210x->dev, "Invalid pkg cmd: %d\n", pkg->cmd);
+
+ return -EOPNOTSUPP;
+}
+
+static int fs210x_reg_write_table(struct fs210x_priv *fs210x,
+ const struct fs_reg_table *reg)
+{
+ const struct fs_cmd_pkg *pkg;
+ unsigned int index, offset;
+ int ret;
+
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ if (!reg || reg->size == 0)
+ return -EFAULT;
+
+ for (index = 0; index < reg->size; index += offset) {
+ pkg = (struct fs_cmd_pkg *)(reg->buf + index);
+ ret = fs210x_set_cmd_pkg(fs210x, pkg, &offset);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to set cmd pkg: %02X-%d\n",
+ pkg->cmd, ret);
+ return ret;
+ }
+ }
+
+ if (index != reg->size) {
+ dev_err(fs210x->dev, "Invalid reg table size: %d-%d\n",
+ index, reg->size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int fs210x_dev_play(struct fs210x_priv *fs210x)
+{
+ int ret;
+
+ if (!fs210x->is_inited)
+ return -EFAULT;
+
+ if (fs210x->is_playing)
+ return 0;
+
+ ret = fs210x_reg_write(fs210x, FS210X_11H_SYSCTRL,
+ FS210X_11H_DPS_PLAY);
+ if (!ret)
+ fs210x->is_playing = true;
+
+ fsleep(10000); /* >= 10ms */
+
+ return ret;
+}
+
+static int fs210x_dev_stop(struct fs210x_priv *fs210x)
+{
+ int ret;
+
+ if (!fs210x->is_inited)
+ return -EFAULT;
+
+ if (!fs210x->is_playing)
+ return 0;
+
+ ret = fs210x_reg_write(fs210x, FS210X_11H_SYSCTRL,
+ FS210X_11H_DPS_PWDN);
+ fs210x->is_playing = false;
+
+ fsleep(30000); /* >= 30ms */
+
+ return ret;
+}
+
+static int fs210x_set_reg_table(struct fs210x_priv *fs210x,
+ const struct fs_amp_scene *scene)
+{
+ const struct fs_amp_scene *cur_scene;
+ const struct fs_reg_table *reg;
+
+ if (!fs210x || !fs210x->dev || !scene)
+ return -EINVAL;
+
+ cur_scene = fs210x->cur_scene;
+ if (!scene->reg || cur_scene == scene) {
+ dev_dbg(fs210x->dev, "Skip writing reg table\n");
+ return 0;
+ }
+
+ reg = scene->reg;
+ dev_dbg(fs210x->dev, "reg table size: %d\n", reg->size);
+
+ return fs210x_reg_write_table(fs210x, reg);
+}
+
+static int fs210x_set_woofer_table(struct fs210x_priv *fs210x)
+{
+ const struct fs_file_table *woofer;
+ const struct fs_fwm_table *table;
+ int ret;
+
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ /* NOTE: fs2105s has woofer ram only */
+ if (fs210x->devid != FS2105S_DEVICE_ID)
+ return 0;
+
+ table = fs210x->amp_lib.table[FS_INDEX_WOOFER];
+ if (!table) {
+ dev_dbg(fs210x->dev, "Skip writing woofer table\n");
+ return 0;
+ }
+
+ woofer = (struct fs_file_table *)table->buf;
+ dev_dbg(fs210x->dev, "woofer table size: %d\n", woofer->size);
+ /* Unit of woofer data is u32(4 bytes) */
+ if (woofer->size == 0 || (woofer->size & 0x3)) {
+ dev_err(fs210x->dev, "Invalid woofer size: %d\n",
+ woofer->size);
+ return -EINVAL;
+ }
+
+ ret = fs210x_reg_write(fs210x, FS210X_46H_DACEQA,
+ FS2105S_46H_CAM_BURST_W);
+ ret |= fs210x_reg_bulk_write(fs210x, FS210X_42H_DACEQWL,
+ woofer->buf, woofer->size);
+
+ return ret;
+}
+
+static int fs210x_set_effect_table(struct fs210x_priv *fs210x,
+ const struct fs_amp_scene *scene)
+{
+ const struct fs_amp_scene *cur_scene;
+ const struct fs_file_table *effect;
+ int half_size;
+ int ret;
+
+ if (!fs210x || !fs210x->dev || !scene)
+ return -EINVAL;
+
+ cur_scene = fs210x->cur_scene;
+ if (!scene->effect || cur_scene == scene) {
+ dev_dbg(fs210x->dev, "Skip writing effect table\n");
+ return 0;
+ }
+
+ effect = scene->effect;
+ dev_dbg(fs210x->dev, "effect table size: %d\n", effect->size);
+
+ /* Unit of effect data is u32(4 bytes), 2 channels */
+ if (effect->size == 0 || (effect->size & 0x7)) {
+ dev_err(fs210x->dev, "Invalid effect size: %d\n",
+ effect->size);
+ return -EINVAL;
+ }
+
+ half_size = effect->size / 2;
+
+ /* Left channel */
+ ret = fs210x_reg_write(fs210x, FS210X_46H_DACEQA,
+ FS210X_46H_CAM_BURST_L);
+ ret |= fs210x_reg_bulk_write(fs210x, FS210X_42H_DACEQWL,
+ effect->buf, half_size);
+ if (ret)
+ return ret;
+
+ /* Right channel */
+ ret = fs210x_reg_write(fs210x, FS210X_46H_DACEQA,
+ FS210X_46H_CAM_BURST_R);
+ ret |= fs210x_reg_bulk_write(fs210x, FS210X_42H_DACEQWL,
+ effect->buf + half_size, half_size);
+
+ return ret;
+}
+
+static int fs210x_access_dsp_ram(struct fs210x_priv *fs210x, bool enable)
+{
+ int ret;
+
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ if (enable) {
+ ret = fs210x_reg_write(fs210x, FS210X_11H_SYSCTRL,
+ FS210X_11H_DPS_HIZ);
+ ret |= fs210x_reg_write(fs210x, FS210X_0BH_ACCKEY,
+ FS210X_0BH_ACCKEY_ON);
+ } else {
+ ret = fs210x_reg_write(fs210x, FS210X_0BH_ACCKEY,
+ FS210X_0BH_ACCKEY_OFF);
+ ret |= fs210x_reg_write(fs210x, FS210X_11H_SYSCTRL,
+ FS210X_11H_DPS_PWDN);
+ }
+
+ fsleep(10000); /* >= 10ms */
+
+ return ret;
+}
+
+static int fs210x_write_dsp_effect(struct fs210x_priv *fs210x,
+ const struct fs_amp_scene *scene,
+ int scene_id)
+{
+ int ret;
+
+ if (!fs210x || !scene)
+ return -EINVAL;
+
+ ret = fs210x_access_dsp_ram(fs210x, true);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to access dsp: %d\n", ret);
+ goto tag_exit;
+ }
+
+ ret = fs210x_set_effect_table(fs210x, scene);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to set effect: %d\n", ret);
+ goto tag_exit;
+ }
+
+ if (scene_id == FS210X_INIT_SCENE)
+ ret = fs210x_set_woofer_table(fs210x);
+
+tag_exit:
+ fs210x_reg_write(fs210x, FS210X_46H_DACEQA,
+ FS210X_46H_CAM_CLEAR);
+ fs210x_access_dsp_ram(fs210x, false);
+
+ return ret;
+}
+
+static int fs210x_check_scene(struct fs210x_priv *fs210x,
+ int scene_id, bool *skip_set)
+{
+ struct fs_amp_lib *amp_lib;
+
+ if (!fs210x || !skip_set)
+ return -EINVAL;
+
+ amp_lib = &fs210x->amp_lib;
+ if (amp_lib->scene_count == 0 || !amp_lib->scene) {
+ dev_err(fs210x->dev, "There's no scene data\n");
+ return -EINVAL;
+ }
+
+ if (scene_id < 0 || scene_id >= amp_lib->scene_count) {
+ dev_err(fs210x->dev, "Invalid scene_id: %d\n", scene_id);
+ return -EINVAL;
+ }
+
+ if (fs210x->scene_id == scene_id) {
+ dev_dbg(fs210x->dev, "Skip to set same scene\n");
+ return 0;
+ }
+
+ *skip_set = false;
+
+ return 0;
+}
+
+static int fs210x_set_scene(struct fs210x_priv *fs210x, int scene_id)
+{
+ const struct fs_amp_scene *scene;
+ bool skip_set = true;
+ bool is_playing;
+ int ret;
+
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ ret = fs210x_check_scene(fs210x, scene_id, &skip_set);
+ if (ret || skip_set)
+ return ret;
+
+ scene = fs210x->amp_lib.scene + scene_id;
+ dev_info(fs210x->dev, "Switch scene.%d: %s\n",
+ scene_id, scene->name);
+
+ is_playing = fs210x->is_playing;
+ if (is_playing)
+ fs210x_dev_stop(fs210x);
+
+ ret = fs210x_set_reg_table(fs210x, scene);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to set reg: %d\n", ret);
+ return ret;
+ }
+
+ ret = fs210x_write_dsp_effect(fs210x, scene, scene_id);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to write ram: %d\n", ret);
+ return ret;
+ }
+
+ fs210x->cur_scene = scene;
+ fs210x->scene_id = scene_id;
+
+ if (is_playing)
+ fs210x_dev_play(fs210x);
+
+ return 0;
+}
+
+static int fs210x_init_chip(struct fs210x_priv *fs210x)
+{
+ int scene_id;
+ int ret;
+
+ regcache_cache_bypass(fs210x->regmap, true);
+
+ if (!fs210x->gpio_sdz) {
+ /* Gpio is not found, i2c reset */
+ ret = fs210x_reg_write(fs210x, FS210X_10H_PWRCTRL,
+ FS210X_10H_I2C_RESET);
+ if (ret)
+ goto tag_power_down;
+ } else {
+ /* gpio reset, deactivate */
+ gpiod_set_value_cansleep(fs210x->gpio_sdz, 0);
+ }
+
+ fsleep(10000); /* >= 10ms */
+
+ /* Backup scene id */
+ scene_id = fs210x->scene_id;
+ fs210x->scene_id = -1;
+
+ /* Init registers/RAM by init scene */
+ ret = fs210x_set_scene(fs210x, FS210X_INIT_SCENE);
+ if (ret)
+ goto tag_power_down;
+
+ /*
+ * If the firmware has effect scene(s),
+ * we load effect scene by default scene or scene_id
+ */
+ if (fs210x->amp_lib.scene_count > 1) {
+ if (scene_id < FS210X_DEFAULT_SCENE)
+ scene_id = FS210X_DEFAULT_SCENE;
+ ret = fs210x_set_scene(fs210x, scene_id);
+ if (ret)
+ goto tag_power_down;
+ }
+
+tag_power_down:
+ /* Power down the device */
+ ret |= fs210x_reg_write(fs210x, FS210X_11H_SYSCTRL,
+ FS210X_11H_DPS_PWDN);
+ fsleep(10000); /* >= 10ms */
+
+ regcache_cache_bypass(fs210x->regmap, false);
+ if (!ret) {
+ regcache_mark_dirty(fs210x->regmap);
+ regcache_sync(fs210x->regmap);
+ fs210x->is_inited = true;
+ }
+
+ return ret;
+}
+
+static int fs210x_set_i2s_params(struct fs210x_priv *fs210x)
+{
+ const struct fs_i2s_srate params[] = {
+ { 16000, 0x3 },
+ { 32000, 0x7 },
+ { 44100, 0x8 },
+ { 48000, 0x9 },
+ { 88200, 0xA },
+ { 96000, 0xB },
+ };
+ u16 val;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(params); i++) {
+ if (params[i].srate != fs210x->srate)
+ continue;
+ val = params[i].i2ssr << FS210X_17H_I2SSR_SHIFT;
+ ret = fs210x_reg_update_bits(fs210x,
+ FS210X_17H_I2SCTRL,
+ FS210X_17H_I2SSR_MASK,
+ val);
+ return ret;
+ }
+
+ dev_err(fs210x->dev, "Invalid sample rate: %d\n", fs210x->srate);
+
+ return -EINVAL;
+}
+
+static int fs210x_get_pll_div(struct fs210x_priv *fs210x,
+ const struct fs_pll_div **pll_div)
+{
+ int i;
+
+ if (!fs210x || !pll_div)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(fs210x_pll_div); i++) {
+ if (fs210x_pll_div[i].bclk != fs210x->bclk)
+ continue;
+ *pll_div = fs210x_pll_div + i;
+ return 0;
+ }
+
+ dev_err(fs210x->dev, "No PLL table for bclk: %d\n", fs210x->bclk);
+
+ return -EFAULT;
+}
+
+static int fs210x_set_hw_params(struct fs210x_priv *fs210x)
+{
+ const struct fs_pll_div *pll_div;
+ int ret;
+
+ ret = fs210x_set_i2s_params(fs210x);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to set i2s params: %d\n", ret);
+ return ret;
+ }
+
+ /* Set pll params */
+ ret = fs210x_get_pll_div(fs210x, &pll_div);
+ if (ret)
+ return ret;
+
+ ret = fs210x_reg_write(fs210x, FS210X_A1H_PLLCTRL1, pll_div->pll1);
+ ret |= fs210x_reg_write(fs210x, FS210X_A2H_PLLCTRL2, pll_div->pll2);
+ ret |= fs210x_reg_write(fs210x, FS210X_A3H_PLLCTRL3, pll_div->pll3);
+
+ return ret;
+}
+
+static int fs210x_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ const struct snd_pcm_hw_constraint_list *list;
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = snd_soc_component_get_drvdata(dai->component);
+ if (!fs210x) {
+ pr_err("dai_startup: fs210x is null\n");
+ return -EINVAL;
+ }
+
+ if (!substream->runtime)
+ return 0;
+
+ ret = snd_pcm_hw_constraint_mask64(substream->runtime,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ FS210X_FORMATS);
+ if (ret < 0) {
+ dev_err(fs210x->dev,
+ "Failed to set hw param format: %d\n", ret);
+ return ret;
+ }
+
+ if (fs210x->devid == FS2105S_DEVICE_ID)
+ list = &fs2105s_constraints;
+ else
+ list = &fs210x_constraints;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ list);
+ if (ret < 0) {
+ dev_err(fs210x->dev,
+ "Failed to set hw param rate: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fs210x_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct fs210x_priv *fs210x;
+
+ fs210x = snd_soc_component_get_drvdata(dai->component);
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBC_CFC:
+ /* Only supports consumer mode */
+ break;
+ default:
+ dev_err(fs210x->dev, "Only supports consumer mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fs210x_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct fs210x_priv *fs210x;
+ int chn_num;
+ int ret;
+
+ if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
+
+ fs210x = snd_soc_component_get_drvdata(dai->component);
+
+ fs210x->srate = params_rate(params);
+ fs210x->bclk = snd_soc_params_to_bclk(params);
+ chn_num = params_channels(params);
+ if (chn_num == 1) /* mono */
+ fs210x->bclk *= 2; /* I2S bus has 2 channels */
+
+ /* The FS2105S can't support 16kHz sample rate. */
+ if (fs210x->devid == FS2105S_DEVICE_ID && fs210x->srate == 16000)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&fs210x->lock);
+ ret = fs210x_set_hw_params(fs210x);
+ mutex_unlock(&fs210x->lock);
+ if (ret)
+ dev_err(fs210x->dev, "Failed to set hw params: %d\n", ret);
+
+ return ret;
+}
+
+static int fs210x_dai_mute(struct snd_soc_dai *dai, int mute, int stream)
+{
+ struct fs210x_priv *fs210x;
+ unsigned long delay;
+
+ if (stream != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
+
+ fs210x = snd_soc_component_get_drvdata(dai->component);
+
+ mutex_lock(&fs210x->lock);
+
+ if (!fs210x->is_inited || fs210x->is_suspended) {
+ mutex_unlock(&fs210x->lock);
+ return 0;
+ }
+
+ mutex_unlock(&fs210x->lock);
+
+ if (mute) {
+ cancel_delayed_work_sync(&fs210x->fault_check_work);
+ cancel_delayed_work_sync(&fs210x->start_work);
+ } else {
+ delay = msecs_to_jiffies(fs210x->check_interval_ms);
+ schedule_delayed_work(&fs210x->fault_check_work, delay);
+ }
+
+ return 0;
+}
+
+static int fs210x_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct fs210x_priv *fs210x;
+
+ fs210x = snd_soc_component_get_drvdata(dai->component);
+
+ mutex_lock(&fs210x->lock);
+
+ if (!fs210x->is_inited || fs210x->is_suspended || fs210x->is_playing) {
+ mutex_unlock(&fs210x->lock);
+ return 0;
+ }
+
+ mutex_unlock(&fs210x->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ /*
+ * According to the power up/down sequence of FS210x,
+ * it requests the I2S clock has been present
+ * and stable(>= 2ms) before playing.
+ */
+ schedule_delayed_work(&fs210x->start_work,
+ msecs_to_jiffies(FS210X_START_DELAY_MS));
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void fs210x_start_work(struct work_struct *work)
+{
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = container_of(work, struct fs210x_priv, start_work.work);
+
+ mutex_lock(&fs210x->lock);
+
+ ret = fs210x_dev_play(fs210x);
+ if (ret)
+ dev_err(fs210x->dev, "Failed to start playing: %d\n", ret);
+
+ mutex_unlock(&fs210x->lock);
+}
+
+static void fs210x_fault_check_work(struct work_struct *work)
+{
+ struct fs210x_priv *fs210x;
+ u16 status;
+ int ret;
+
+ fs210x = container_of(work, struct fs210x_priv, fault_check_work.work);
+
+ mutex_lock(&fs210x->lock);
+
+ if (!fs210x->is_inited || fs210x->is_suspended || !fs210x->is_playing) {
+ mutex_unlock(&fs210x->lock);
+ return;
+ }
+
+ ret = fs210x_reg_read(fs210x, FS210X_05H_ANASTAT, &status);
+ mutex_unlock(&fs210x->lock);
+ if (ret)
+ return;
+
+ if (!(status & FS210X_05H_PVDD_MASK))
+ dev_err(fs210x->dev, "PVDD fault\n");
+ if (status & FS210X_05H_OCDL_MASK)
+ dev_err(fs210x->dev, "OC detected\n");
+ if (status & FS210X_05H_UVDL_MASK)
+ dev_err(fs210x->dev, "UV detected\n");
+ if (status & FS210X_05H_OVDL_MASK)
+ dev_err(fs210x->dev, "OV detected\n");
+ if (status & FS210X_05H_OTPDL_MASK)
+ dev_err(fs210x->dev, "OT detected\n");
+ if (status & FS210X_05H_OCRDL_MASK)
+ dev_err(fs210x->dev, "OCR detected\n");
+ if (status & FS210X_05H_OCLDL_MASK)
+ dev_err(fs210x->dev, "OCL detected\n");
+ if (status & FS210X_05H_DCRDL_MASK)
+ dev_err(fs210x->dev, "DCR detected\n");
+ if (status & FS210X_05H_DCLDL_MASK)
+ dev_err(fs210x->dev, "DCL detected\n");
+ if (status & FS210X_05H_SRDL_MASK)
+ dev_err(fs210x->dev, "SR detected\n");
+ if (status & FS210X_05H_OTWDL_MASK)
+ dev_err(fs210x->dev, "OTW detected\n");
+ if (!(status & FS210X_05H_AMPS_MASK))
+ dev_dbg(fs210x->dev, "Amplifier unready\n");
+ if (!(status & FS210X_05H_PLLS_MASK))
+ dev_err(fs210x->dev, "PLL unlock\n");
+ if (!(status & FS210X_05H_ANAS_MASK))
+ dev_err(fs210x->dev, "Analog power fault\n");
+
+ schedule_delayed_work(&fs210x->fault_check_work,
+ msecs_to_jiffies(fs210x->check_interval_ms));
+}
+
+static int fs210x_get_drvdata_from_kctrl(struct snd_kcontrol *kctrl,
+ struct fs210x_priv **fs210x)
+{
+ struct snd_soc_component *cmpnt;
+
+ if (!kctrl) {
+ pr_err("fs210x: kcontrol is null\n");
+ return -EINVAL;
+ }
+
+ cmpnt = snd_soc_kcontrol_component(kctrl);
+ if (!cmpnt) {
+ pr_err("fs210x: component is null\n");
+ return -EINVAL;
+ }
+
+ *fs210x = snd_soc_component_get_drvdata(cmpnt);
+
+ return 0;
+}
+
+static int fs210x_effect_scene_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ const struct fs_amp_scene *scene;
+ struct fs210x_priv *fs210x;
+ const char *name = "N/A";
+ int idx, count;
+ int ret;
+
+ ret = fs210x_get_drvdata_from_kctrl(kcontrol, &fs210x);
+ if (ret || !fs210x->dev) {
+ pr_err("scene_effect_info: fs210x is null\n");
+ return -EINVAL;
+ }
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+
+ count = fs210x->amp_lib.scene_count - 1; /* Skip init scene */
+ if (count < 1) {
+ uinfo->value.enumerated.items = 0;
+ return 0;
+ }
+
+ uinfo->value.enumerated.items = count;
+ if (uinfo->value.enumerated.item >= count)
+ uinfo->value.enumerated.item = count - 1;
+
+ idx = uinfo->value.enumerated.item;
+ scene = fs210x->amp_lib.scene + idx + 1;
+ if (scene->name)
+ name = scene->name;
+
+ strscpy(uinfo->value.enumerated.name, name, strlen(name) + 1);
+
+ return 0;
+}
+
+static int fs210x_effect_scene_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct fs210x_priv *fs210x;
+ int index;
+ int ret;
+
+ ret = fs210x_get_drvdata_from_kctrl(kcontrol, &fs210x);
+ if (ret || !fs210x->dev) {
+ pr_err("scene_effect_get: fs210x is null\n");
+ return -EINVAL;
+ }
+
+ /* The id of effect scene is from 1 to N. */
+ if (fs210x->scene_id < 1)
+ return -EINVAL;
+
+ mutex_lock(&fs210x->lock);
+ /*
+ * FS210x has scene(s) as below:
+ * init scene: id = 0
+ * effect scene(s): id = 1~N (optional)
+ * effect_index = scene_id - 1
+ */
+ index = fs210x->scene_id - 1;
+ ucontrol->value.integer.value[0] = index;
+ mutex_unlock(&fs210x->lock);
+
+ return 0;
+}
+
+static int fs210x_effect_scene_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct fs210x_priv *fs210x;
+ int scene_id, scene_count;
+ bool is_changed = false;
+ int ret;
+
+ ret = fs210x_get_drvdata_from_kctrl(kcontrol, &fs210x);
+ if (ret || !fs210x->dev) {
+ pr_err("scene_effect_put: fs210x is null\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&fs210x->lock);
+
+ /*
+ * FS210x has scene(s) as below:
+ * init scene: id = 0 (It's set in fs210x_init_chip() only)
+ * effect scene(s): id = 1~N (optional)
+ * scene_id = effect_index + 1.
+ */
+ scene_id = ucontrol->value.integer.value[0] + 1;
+ scene_count = fs210x->amp_lib.scene_count - 1; /* Skip init scene */
+ if (scene_id < 1 || scene_id > scene_count) {
+ mutex_unlock(&fs210x->lock);
+ return -ERANGE;
+ }
+
+ if (scene_id != fs210x->scene_id)
+ is_changed = true;
+
+ if (fs210x->is_suspended) {
+ fs210x->scene_id = scene_id;
+ mutex_unlock(&fs210x->lock);
+ return is_changed;
+ }
+
+ ret = fs210x_set_scene(fs210x, scene_id);
+ if (ret)
+ dev_err(fs210x->dev, "Failed to set scene: %d\n", ret);
+
+ mutex_unlock(&fs210x->lock);
+
+ if (!ret && is_changed)
+ return 1;
+
+ return ret;
+}
+
+static int fs210x_playback_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kc, int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct fs210x_priv *fs210x = snd_soc_component_get_drvdata(cmpnt);
+ int ret = 0;
+
+ mutex_lock(&fs210x->lock);
+
+ if (fs210x->is_suspended) {
+ mutex_unlock(&fs210x->lock);
+ return 0;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /*
+ * If there is no bclk for us to set the clock output,
+ * we will enable the device(start_work) in dai trigger.
+ */
+ if (!fs210x->clk_bclk)
+ break;
+ fs210x_bclk_set(fs210x, true);
+ ret = fs210x_dev_play(fs210x);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = fs210x_dev_stop(fs210x);
+ fs210x_bclk_set(fs210x, false);
+ break;
+ default:
+ break;
+ }
+
+ mutex_unlock(&fs210x->lock);
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops fs210x_dai_ops = {
+ .startup = fs210x_dai_startup,
+ .set_fmt = fs210x_dai_set_fmt,
+ .hw_params = fs210x_dai_hw_params,
+ .mute_stream = fs210x_dai_mute,
+ .trigger = fs210x_dai_trigger,
+};
+
+static const struct snd_soc_dai_driver fs210x_dai = {
+ .name = FS210X_DEFAULT_DAI_NAME,
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = FS210X_RATES,
+ .formats = FS210X_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = FS210X_RATES,
+ .formats = FS210X_FORMATS,
+ },
+ .ops = &fs210x_dai_ops,
+ .symmetric_rate = 1,
+ .symmetric_sample_bits = 1,
+};
+
+static const DECLARE_TLV_DB_SCALE(fs2105s_vol_tlv, -9709, 19, 1);
+static const DECLARE_TLV_DB_SCALE(fs210x_vol_tlv, -13357, 19, 1);
+
+static const struct snd_kcontrol_new fs2105s_vol_control[] = {
+ SOC_DOUBLE_R_TLV("PCM Playback Volume",
+ FS210X_39H_LVOLCTRL, FS210X_3AH_RVOLCTRL,
+ 7, 0x1FF, 0, fs2105s_vol_tlv),
+};
+
+static const struct snd_kcontrol_new fs210x_vol_control[] = {
+ SOC_DOUBLE_R_TLV("PCM Playback Volume",
+ FS210X_39H_LVOLCTRL, FS210X_3AH_RVOLCTRL,
+ 6, 0x2BF, 0, fs210x_vol_tlv),
+};
+
+static const struct snd_kcontrol_new fs210x_controls[] = {
+ SOC_DOUBLE("DAC Mute Switch", FS210X_30H_DACCTRL, 4, 8, 1, 0),
+ SOC_DOUBLE("DAC Fade Switch", FS210X_30H_DACCTRL, 5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new fs210x_scene_control[] = {
+ FS_SOC_ENUM_EXT("Effect Scene",
+ fs210x_effect_scene_info,
+ fs210x_effect_scene_get,
+ fs210x_effect_scene_put),
+};
+
+static const struct snd_soc_dapm_widget fs210x_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN_E("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0,
+ fs210x_playback_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_OUTPUT("OUTL"),
+ SND_SOC_DAPM_OUTPUT("OUTR"),
+ SND_SOC_DAPM_INPUT("SDO"),
+};
+
+static const struct snd_soc_dapm_route fs210x_dapm_routes[] = {
+ { "OUTL", NULL, "AIF IN" },
+ { "OUTR", NULL, "AIF IN" },
+ { "AIF OUT", NULL, "SDO" },
+};
+
+static int fs210x_add_mixer_controls(struct fs210x_priv *fs210x,
+ struct snd_soc_component *cmpnt)
+{
+ const struct snd_kcontrol_new *kctrl;
+ int count;
+ int ret;
+
+ if (!fs210x || !cmpnt)
+ return -EINVAL;
+
+ if (fs210x->devid == FS2105S_DEVICE_ID) {
+ kctrl = fs2105s_vol_control;
+ count = ARRAY_SIZE(fs2105s_vol_control);
+ } else {
+ kctrl = fs210x_vol_control;
+ count = ARRAY_SIZE(fs210x_vol_control);
+ }
+
+ ret = snd_soc_add_component_controls(cmpnt, kctrl, count);
+ if (ret)
+ return ret;
+
+ /*
+ * If the firmware has no scene or only init scene,
+ * we skip adding this mixer control.
+ */
+ if (fs210x->amp_lib.scene_count < 2)
+ return 0;
+
+ kctrl = fs210x_scene_control;
+ count = ARRAY_SIZE(fs210x_scene_control);
+
+ return snd_soc_add_component_controls(cmpnt, kctrl, count);
+}
+
+static int fs210x_probe(struct snd_soc_component *cmpnt)
+{
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = snd_soc_component_get_drvdata(cmpnt);
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ fs210x->amp_lib.dev = fs210x->dev;
+ fs210x->amp_lib.devid = fs210x->devid;
+
+ ret = fs_amp_load_firmware(&fs210x->amp_lib, fs210x->pdata.fwm_name);
+ if (ret)
+ return ret;
+
+ ret = fs210x_add_mixer_controls(fs210x, cmpnt);
+ if (ret)
+ return ret;
+
+ mutex_lock(&fs210x->lock);
+ ret = fs210x_init_chip(fs210x);
+ mutex_unlock(&fs210x->lock);
+
+ return ret;
+}
+
+static void fs210x_remove(struct snd_soc_component *cmpnt)
+{
+ struct fs210x_priv *fs210x;
+
+ fs210x = snd_soc_component_get_drvdata(cmpnt);
+ if (!fs210x || !fs210x->dev)
+ return;
+
+ cancel_delayed_work_sync(&fs210x->start_work);
+ cancel_delayed_work_sync(&fs210x->fault_check_work);
+}
+
+#ifdef CONFIG_PM
+static int fs210x_suspend(struct snd_soc_component *cmpnt)
+{
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = snd_soc_component_get_drvdata(cmpnt);
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ regcache_cache_only(fs210x->regmap, true);
+
+ mutex_lock(&fs210x->lock);
+ fs210x->cur_scene = NULL;
+ fs210x->is_inited = false;
+ fs210x->is_playing = false;
+ fs210x->is_suspended = true;
+
+ gpiod_set_value_cansleep(fs210x->gpio_sdz, 1); /* Active */
+ fsleep(30000); /* >= 30ms */
+ mutex_unlock(&fs210x->lock);
+
+ cancel_delayed_work_sync(&fs210x->start_work);
+ cancel_delayed_work_sync(&fs210x->fault_check_work);
+
+ ret = regulator_bulk_disable(FS210X_NUM_SUPPLIES, fs210x->supplies);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to suspend: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fs210x_resume(struct snd_soc_component *cmpnt)
+{
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = snd_soc_component_get_drvdata(cmpnt);
+ if (!fs210x || !fs210x->dev)
+ return -EINVAL;
+
+ ret = regulator_bulk_enable(FS210X_NUM_SUPPLIES, fs210x->supplies);
+ if (ret) {
+ dev_err(fs210x->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ mutex_lock(&fs210x->lock);
+
+ fs210x->is_suspended = false;
+ ret = fs210x_init_chip(fs210x);
+
+ mutex_unlock(&fs210x->lock);
+
+ return ret;
+}
+#else
+#define fs210x_suspend NULL
+#define fs210x_resume NULL
+#endif // CONFIG_PM
+
+static bool fs210x_volatile_registers(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case FS210X_00H_STATUS ... FS210X_0FH_I2CADDR:
+ case FS210X_ABH_INTSTAT:
+ case FS210X_ACH_INTSTATR:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct snd_soc_component_driver fs210x_soc_component_dev = {
+ .probe = fs210x_probe,
+ .remove = fs210x_remove,
+ .suspend = fs210x_suspend,
+ .resume = fs210x_resume,
+ .controls = fs210x_controls,
+ .num_controls = ARRAY_SIZE(fs210x_controls),
+ .dapm_widgets = fs210x_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(fs210x_dapm_widgets),
+ .dapm_routes = fs210x_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(fs210x_dapm_routes),
+};
+
+static const struct regmap_config fs210x_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = FS210X_REG_MAX,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ .cache_type = REGCACHE_MAPLE,
+ .volatile_reg = fs210x_volatile_registers,
+};
+
+static int fs210x_detect_device(struct fs210x_priv *fs210x)
+{
+ u16 devid;
+ int ret;
+
+ ret = fs210x_reg_read(fs210x, FS210X_03H_DEVID, &devid);
+ if (ret)
+ return ret;
+
+ fs210x->devid = HI_U16(devid);
+
+ switch (fs210x->devid) {
+ case FS210X_DEVICE_ID:
+ dev_info(fs210x->dev, "FS2104 detected\n");
+ break;
+ case FS2105S_DEVICE_ID:
+ dev_info(fs210x->dev, "FS2105S detected\n");
+ break;
+ default:
+ dev_err(fs210x->dev, "DEVID: 0x%04X dismatch\n", devid);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int fs210x_parse_dts(struct fs210x_priv *fs210x,
+ struct fs210x_platform_data *pdata)
+{
+ struct device_node *node = fs210x->dev->of_node;
+ int i, ret;
+
+ if (!node)
+ return 0;
+
+ ret = of_property_read_string(node, "firmware-name", &pdata->fwm_name);
+ if (ret)
+ pdata->fwm_name = FS210X_DEFAULT_FWM_NAME;
+
+ fs210x->gpio_sdz = devm_gpiod_get_optional(fs210x->dev,
+ "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(fs210x->gpio_sdz))
+ return dev_err_probe(fs210x->dev, PTR_ERR(fs210x->gpio_sdz),
+ "Failed to get reset-gpios\n");
+
+ for (i = 0; i < FS210X_NUM_SUPPLIES; i++)
+ fs210x->supplies[i].supply = fs210x_supply_names[i];
+
+ ret = devm_regulator_bulk_get(fs210x->dev,
+ ARRAY_SIZE(fs210x->supplies),
+ fs210x->supplies);
+ if (ret)
+ return dev_err_probe(fs210x->dev, ret,
+ "Failed to get supplies\n");
+
+ return 0;
+}
+
+static void fs210x_deinit(struct fs210x_priv *fs210x)
+{
+ gpiod_set_value_cansleep(fs210x->gpio_sdz, 1); /* Active */
+ fsleep(10000); /* >= 10ms */
+
+ regulator_bulk_disable(FS210X_NUM_SUPPLIES, fs210x->supplies);
+}
+
+static int fs210x_init(struct fs210x_priv *fs210x)
+{
+ int ret;
+
+ ret = fs210x_parse_dts(fs210x, &fs210x->pdata);
+ if (ret)
+ return ret;
+
+ fs210x->clk_bclk = devm_clk_get_optional(fs210x->dev, "bclk");
+ if (IS_ERR(fs210x->clk_bclk))
+ return dev_err_probe(fs210x->dev, PTR_ERR(fs210x->clk_bclk),
+ "Failed to get bclk\n");
+
+ ret = regulator_bulk_enable(FS210X_NUM_SUPPLIES, fs210x->supplies);
+ if (ret)
+ return dev_err_probe(fs210x->dev, ret,
+ "Failed to enable supplies\n");
+
+ /* Make sure the SDZ pin is pulled down enough time. */
+ fsleep(10000); /* >= 10ms */
+ gpiod_set_value_cansleep(fs210x->gpio_sdz, 0); /* Deactivate */
+ fsleep(10000); /* >= 10ms */
+
+ ret = fs210x_detect_device(fs210x);
+ if (ret) {
+ fs210x_deinit(fs210x);
+ return ret;
+ }
+
+ fs210x->scene_id = -1; /* Invalid scene */
+ fs210x->cur_scene = NULL;
+ fs210x->is_playing = false;
+ fs210x->is_inited = false;
+ fs210x->is_suspended = false;
+ fs210x->check_interval_ms = FS210X_FAULT_CHECK_INTERVAL_MS;
+
+ INIT_DELAYED_WORK(&fs210x->fault_check_work, fs210x_fault_check_work);
+ INIT_DELAYED_WORK(&fs210x->start_work, fs210x_start_work);
+ mutex_init(&fs210x->lock);
+
+ return 0;
+}
+
+static int fs210x_register_snd_component(struct fs210x_priv *fs210x)
+{
+ struct snd_soc_dai_driver *dai_drv;
+ static int instance_id;
+ int ret;
+
+ dai_drv = devm_kmemdup(fs210x->dev, &fs210x_dai,
+ sizeof(fs210x_dai), GFP_KERNEL);
+ if (!dai_drv)
+ return -ENOMEM;
+
+ dai_drv->name = devm_kasprintf(fs210x->dev,
+ GFP_KERNEL, "%s-%d",
+ dai_drv->name, instance_id);
+ if (!dai_drv->name)
+ return -ENOMEM;
+
+ instance_id++;
+
+ if (fs210x->devid == FS2105S_DEVICE_ID) {
+ dai_drv->playback.rates = FS2105S_RATES;
+ dai_drv->capture.rates = FS2105S_RATES;
+ }
+
+ ret = snd_soc_register_component(fs210x->dev,
+ &fs210x_soc_component_dev,
+ dai_drv, 1);
+ return ret;
+}
+
+static ssize_t check_interval_ms_show(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct fs210x_priv *fs210x = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%d\n", fs210x->check_interval_ms);
+}
+
+static ssize_t check_interval_ms_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf,
+ size_t count)
+{
+ struct fs210x_priv *fs210x = dev_get_drvdata(dev);
+ int ret;
+
+ ret = kstrtouint(buf, 10, &fs210x->check_interval_ms);
+ if (ret)
+ return -EINVAL;
+
+ return (ssize_t)count;
+}
+
+static DEVICE_ATTR_RW(check_interval_ms);
+
+static struct attribute *fs210x_attrs[] = {
+ &dev_attr_check_interval_ms.attr,
+ NULL,
+};
+
+static struct attribute_group fs210x_attr_group = {
+ .attrs = fs210x_attrs,
+};
+
+static int fs210x_i2c_probe(struct i2c_client *client)
+{
+ struct fs210x_priv *fs210x;
+ int ret;
+
+ fs210x = devm_kzalloc(&client->dev, sizeof(*fs210x), GFP_KERNEL);
+ if (!fs210x)
+ return -ENOMEM;
+
+ fs210x->i2c = client;
+ fs210x->dev = &client->dev;
+ i2c_set_clientdata(client, fs210x);
+
+ fs210x->regmap = devm_regmap_init_i2c(client, &fs210x_regmap);
+ if (IS_ERR(fs210x->regmap))
+ return dev_err_probe(fs210x->dev, PTR_ERR(fs210x->regmap),
+ "Failed to get regmap\n");
+
+ ret = fs210x_init(fs210x);
+ if (ret)
+ return ret;
+
+ ret = devm_device_add_group(fs210x->dev, &fs210x_attr_group);
+ if (ret) {
+ fs210x_deinit(fs210x);
+ return dev_err_probe(fs210x->dev, ret,
+ "Failed to create sysfs group\n");
+ }
+
+ ret = fs210x_register_snd_component(fs210x);
+ if (ret) {
+ fs210x_deinit(fs210x);
+ return dev_err_probe(fs210x->dev, ret,
+ "Failed to register component\n");
+ }
+
+ return 0;
+}
+
+static void fs210x_i2c_remove(struct i2c_client *client)
+{
+ struct fs210x_priv *fs210x = i2c_get_clientdata(client);
+
+ snd_soc_unregister_component(fs210x->dev);
+ fs210x_deinit(fs210x);
+}
+
+static const struct i2c_device_id fs210x_i2c_id[] = {
+ { "fs2104" },
+ { "fs2105s" },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, fs210x_i2c_id);
+
+static const struct of_device_id fs210x_of_match[] = {
+ { .compatible = "foursemi,fs2105s", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, fs210x_of_match);
+
+static struct i2c_driver fs210x_i2c_driver = {
+ .driver = {
+ .name = "fs210x",
+ .of_match_table = fs210x_of_match,
+ },
+ .id_table = fs210x_i2c_id,
+ .probe = fs210x_i2c_probe,
+ .remove = fs210x_i2c_remove,
+};
+
+module_i2c_driver(fs210x_i2c_driver);
+
+MODULE_AUTHOR("Nick Li <nick.li@foursemi.com>");
+MODULE_DESCRIPTION("FS2104/5S Audio Amplifier Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/fs210x.h b/sound/soc/codecs/fs210x.h
new file mode 100644
index 000000000000..78e1760332ca
--- /dev/null
+++ b/sound/soc/codecs/fs210x.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * fs210x.h -- Driver for the FS2104/5S Audio Amplifier
+ *
+ * Copyright (C) 2016-2025 Shanghai FourSemi Semiconductor Co.,Ltd.
+ */
+
+#ifndef __FS210X_H__
+#define __FS210X_H__
+
+#define FS210X_00H_STATUS 0x00
+#define FS210X_03H_DEVID 0x03
+#define FS210X_05H_ANASTAT 0x05
+#define FS210X_06H_DIGSTAT 0x06
+#define FS210X_0BH_ACCKEY 0x0B
+#define FS210X_0FH_I2CADDR 0x0F
+#define FS210X_10H_PWRCTRL 0x10
+#define FS210X_11H_SYSCTRL 0x11
+#define FS210X_17H_I2SCTRL 0x17
+#define FS210X_30H_DACCTRL 0x30
+#define FS210X_39H_LVOLCTRL 0x39
+#define FS210X_3AH_RVOLCTRL 0x3A
+#define FS210X_42H_DACEQWL 0x42
+#define FS210X_46H_DACEQA 0x46
+#define FS210X_A1H_PLLCTRL1 0xA1
+#define FS210X_A2H_PLLCTRL2 0xA2
+#define FS210X_A3H_PLLCTRL3 0xA3
+#define FS210X_ABH_INTSTAT 0xAB
+#define FS210X_ACH_INTSTATR 0xAC
+
+#define FS210X_05H_PVDD_SHIFT 14
+#define FS210X_05H_PVDD_MASK BIT(14)
+#define FS210X_05H_OCDL_SHIFT 13
+#define FS210X_05H_OCDL_MASK BIT(13)
+#define FS210X_05H_UVDL_SHIFT 12
+#define FS210X_05H_UVDL_MASK BIT(12)
+#define FS210X_05H_OVDL_SHIFT 11
+#define FS210X_05H_OVDL_MASK BIT(11)
+#define FS210X_05H_OTPDL_SHIFT 10
+#define FS210X_05H_OTPDL_MASK BIT(10)
+#define FS210X_05H_OCRDL_SHIFT 9
+#define FS210X_05H_OCRDL_MASK BIT(9)
+#define FS210X_05H_OCLDL_SHIFT 8
+#define FS210X_05H_OCLDL_MASK BIT(8)
+#define FS210X_05H_DCRDL_SHIFT 7
+#define FS210X_05H_DCRDL_MASK BIT(7)
+#define FS210X_05H_DCLDL_SHIFT 6
+#define FS210X_05H_DCLDL_MASK BIT(6)
+#define FS210X_05H_SRDL_SHIFT 5
+#define FS210X_05H_SRDL_MASK BIT(5)
+#define FS210X_05H_OTWDL_SHIFT 4
+#define FS210X_05H_OTWDL_MASK BIT(4)
+#define FS210X_05H_AMPS_SHIFT 3
+#define FS210X_05H_AMPS_MASK BIT(3)
+#define FS210X_05H_PLLS_SHIFT 1
+#define FS210X_05H_PLLS_MASK BIT(1)
+#define FS210X_05H_ANAS_SHIFT 0
+#define FS210X_05H_ANAS_MASK BIT(0)
+#define FS210X_17H_I2SSR_SHIFT 12
+#define FS210X_17H_I2SSR_MASK GENMASK(15, 12)
+#define FS210X_30H_RMUTE_SHIFT 8
+#define FS210X_30H_LMUTE_SHIFT 4
+
+#define FS210X_0BH_ACCKEY_ON 0x0091
+#define FS210X_0BH_ACCKEY_OFF 0x0000
+#define FS210X_10H_I2C_RESET 0x0002
+#define FS210X_11H_DPS_HIZ 0x0100
+#define FS210X_11H_DPS_PWDN 0x0000
+#define FS210X_11H_DPS_PLAY 0x0300
+#define FS210X_46H_CAM_BURST_L 0x8000
+#define FS210X_46H_CAM_BURST_R 0x8200
+#define FS2105S_46H_CAM_BURST_W 0x8400
+#define FS210X_46H_CAM_CLEAR 0x0000
+
+#endif /* __FS210X_H__ */
diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
index fb4b96cb2b23..10ad682019fa 100644
--- a/sound/soc/codecs/lpass-macro-common.h
+++ b/sound/soc/codecs/lpass-macro-common.h
@@ -29,6 +29,7 @@ enum lpass_codec_version {
LPASS_CODEC_VERSION_2_6,
LPASS_CODEC_VERSION_2_7,
LPASS_CODEC_VERSION_2_8,
+ LPASS_CODEC_VERSION_2_9,
};
struct lpass_macro {
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index a49551f3fb29..2e1b77973a3e 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -1485,6 +1485,8 @@ static void va_macro_set_lpass_codec_version(struct va_macro *va)
version = LPASS_CODEC_VERSION_2_7;
if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x80 || core_id_2 == 0x81))
version = LPASS_CODEC_VERSION_2_8;
+ if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x90 || core_id_2 == 0x91))
+ version = LPASS_CODEC_VERSION_2_9;
if (version == LPASS_CODEC_VERSION_UNKNOWN)
dev_warn(va->dev, "Unknown Codec version, ID: %02x / %02x / %02x\n",
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index d7eec9fdaf9c..38faa9074ca3 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -2698,6 +2698,7 @@ static int wsa_macro_component_probe(struct snd_soc_component *comp)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_2_9:
widgets = wsa_macro_dapm_widgets_v2_5;
num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_5);
break;
@@ -2846,6 +2847,7 @@ static int wsa_macro_probe(struct platform_device *pdev)
case LPASS_CODEC_VERSION_2_6:
case LPASS_CODEC_VERSION_2_7:
case LPASS_CODEC_VERSION_2_8:
+ case LPASS_CODEC_VERSION_2_9:
wsa->reg_layout = &wsa_codec_v2_5;
def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_5);
reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults),
diff --git a/sound/soc/codecs/pcm1754.c b/sound/soc/codecs/pcm1754.c
new file mode 100644
index 000000000000..b68a528000be
--- /dev/null
+++ b/sound/soc/codecs/pcm1754.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * PCM1754 DAC ASoC codec driver
+ *
+ * Copyright (c) 2022 Alvin Å ipraga <alsi@bang-olufsen.dk>
+ * Copyright (c) 2025 Stefan Kerkmann <s.kerkmann@pengutronix.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+struct pcm1754_priv {
+ unsigned int format;
+ struct gpio_desc *gpiod_mute;
+ struct gpio_desc *gpiod_format;
+};
+
+static int pcm1754_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int format)
+{
+ struct snd_soc_component *component = codec_dai->component;
+ struct pcm1754_priv *priv = snd_soc_component_get_drvdata(component);
+
+ priv->format = format;
+
+ return 0;
+}
+
+static int pcm1754_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *codec_dai)
+{
+ struct snd_soc_component *component = codec_dai->component;
+ struct pcm1754_priv *priv = snd_soc_component_get_drvdata(component);
+ int format;
+
+ switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_RIGHT_J:
+ switch (params_width(params)) {
+ case 16:
+ format = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ switch (params_width(params)) {
+ case 16:
+ fallthrough;
+ case 24:
+ format = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ dev_err(component->dev, "Invalid DAI format\n");
+ return -EINVAL;
+ }
+
+ gpiod_set_value_cansleep(priv->gpiod_format, format);
+
+ return 0;
+}
+
+static int pcm1754_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
+{
+ struct pcm1754_priv *priv = snd_soc_component_get_drvdata(dai->component);
+
+ gpiod_set_value_cansleep(priv->gpiod_mute, mute);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops pcm1754_dai_ops = {
+ .set_fmt = pcm1754_set_dai_fmt,
+ .hw_params = pcm1754_hw_params,
+ .mute_stream = pcm1754_mute_stream,
+};
+
+static const struct snd_soc_dai_driver pcm1754_dai = {
+ .name = "pcm1754",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 5000,
+ .rate_max = 200000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
+ },
+ .ops = &pcm1754_dai_ops,
+};
+
+static const struct snd_soc_dapm_widget pcm1754_dapm_widgets[] = {
+ SND_SOC_DAPM_REGULATOR_SUPPLY("VCC", 0, 0),
+
+ SND_SOC_DAPM_DAC("DAC1", "Channel 1 Playback", SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC2", "Channel 2 Playback", SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_OUTPUT("VOUTL"),
+ SND_SOC_DAPM_OUTPUT("VOUTR"),
+};
+
+static const struct snd_soc_dapm_route pcm1754_dapm_routes[] = {
+ { "DAC1", NULL, "Playback" },
+ { "DAC2", NULL, "Playback" },
+
+ { "DAC1", NULL, "VCC" },
+ { "DAC2", NULL, "VCC" },
+
+ { "VOUTL", NULL, "DAC1" },
+ { "VOUTR", NULL, "DAC2" },
+};
+
+static const struct snd_soc_component_driver soc_component_dev_pcm1754 = {
+ .dapm_widgets = pcm1754_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(pcm1754_dapm_widgets),
+ .dapm_routes = pcm1754_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(pcm1754_dapm_routes),
+};
+
+static int pcm1754_probe(struct platform_device *pdev)
+{
+ struct pcm1754_priv *priv;
+ struct device *dev = &pdev->dev;
+ struct snd_soc_dai_driver *dai_drv;
+ int ret;
+
+ dai_drv = devm_kmemdup(dev, &pcm1754_dai, sizeof(*dai_drv), GFP_KERNEL);
+ if (!dai_drv)
+ return -ENOMEM;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->gpiod_mute = devm_gpiod_get_optional(dev, "mute", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->gpiod_mute))
+ return dev_err_probe(dev, PTR_ERR(priv->gpiod_mute),
+ "failed to get mute gpio");
+
+ priv->gpiod_format = devm_gpiod_get_optional(dev, "format", GPIOD_OUT_LOW);
+ if (IS_ERR(priv->gpiod_format))
+ return dev_err_probe(dev, PTR_ERR(priv->gpiod_format),
+ "failed to get format gpio");
+
+ dev_set_drvdata(dev, priv);
+
+ ret = devm_snd_soc_register_component(
+ &pdev->dev, &soc_component_dev_pcm1754, dai_drv, 1);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register");
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id pcm1754_of_match[] = {
+ { .compatible = "ti,pcm1754" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pcm1754_of_match);
+#endif
+
+static struct platform_driver pcm1754_codec_driver = {
+ .driver = {
+ .name = "pcm1754-codec",
+ .of_match_table = of_match_ptr(pcm1754_of_match),
+ },
+ .probe = pcm1754_probe,
+};
+
+module_platform_driver(pcm1754_codec_driver);
+
+MODULE_DESCRIPTION("ASoC PCM1754 driver");
+MODULE_AUTHOR("Alvin Å ipraga <alsi@bang-olufsen.dk>");
+MODULE_AUTHOR("Stefan Kerkmann <s.kerkmann@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c
index 75af12231d1d..08cc52b374a9 100644
--- a/sound/soc/codecs/pcm6240.c
+++ b/sound/soc/codecs/pcm6240.c
@@ -1353,8 +1353,8 @@ static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev,
return 0;
}
- pcmdev_controls = devm_kzalloc(pcm_dev->dev,
- nr_chn * sizeof(struct snd_kcontrol_new), GFP_KERNEL);
+ pcmdev_controls = devm_kcalloc(pcm_dev->dev, nr_chn,
+ sizeof(struct snd_kcontrol_new), GFP_KERNEL);
if (!pcmdev_controls)
return -ENOMEM;
diff --git a/sound/soc/codecs/pm4125-sdw.c b/sound/soc/codecs/pm4125-sdw.c
new file mode 100644
index 000000000000..4ed09fbe3f54
--- /dev/null
+++ b/sound/soc/codecs/pm4125-sdw.c
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+// Copyright, 2025 Linaro Ltd
+
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_registers.h>
+#include <linux/soundwire/sdw_type.h>
+#include <sound/soc-dapm.h>
+#include <sound/soc.h>
+#include "pm4125.h"
+
+static struct pm4125_sdw_ch_info pm4125_sdw_rx_ch_info[] = {
+ WCD_SDW_CH(PM4125_HPH_L, PM4125_HPH_PORT, BIT(0)),
+ WCD_SDW_CH(PM4125_HPH_R, PM4125_HPH_PORT, BIT(1)),
+};
+
+static struct pm4125_sdw_ch_info pm4125_sdw_tx_ch_info[] = {
+ WCD_SDW_CH(PM4125_ADC1, PM4125_ADC_1_2_DMIC1L_BCS_PORT, BIT(0)),
+ WCD_SDW_CH(PM4125_ADC2, PM4125_ADC_1_2_DMIC1L_BCS_PORT, BIT(1)),
+};
+
+static struct sdw_dpn_prop pm4125_dpn_prop[PM4125_MAX_SWR_PORTS] = {
+ {
+ .num = 1,
+ .type = SDW_DPN_SIMPLE,
+ .min_ch = 1,
+ .max_ch = 8,
+ .simple_ch_prep_sm = true,
+ }, {
+ .num = 2,
+ .type = SDW_DPN_SIMPLE,
+ .min_ch = 1,
+ .max_ch = 4,
+ .simple_ch_prep_sm = true,
+ }
+};
+
+struct device *pm4125_sdw_device_get(struct device_node *np)
+{
+ return bus_find_device_by_of_node(&sdw_bus_type, np);
+}
+EXPORT_SYMBOL_GPL(pm4125_sdw_device_get);
+
+int pm4125_sdw_hw_params(struct pm4125_sdw_priv *priv, struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct sdw_port_config port_config[PM4125_MAX_SWR_PORTS];
+ unsigned long ch_mask;
+ int i, j;
+
+ priv->sconfig.ch_count = 1;
+ priv->active_ports = 0;
+ for (i = 0; i < PM4125_MAX_SWR_PORTS; i++) {
+ ch_mask = priv->port_config[i].ch_mask;
+ if (!ch_mask)
+ continue;
+
+ for_each_set_bit(j, &ch_mask, 4)
+ priv->sconfig.ch_count++;
+
+ port_config[priv->active_ports] = priv->port_config[i];
+ priv->active_ports++;
+ }
+
+ priv->sconfig.bps = 1;
+ priv->sconfig.frame_rate = params_rate(params);
+ priv->sconfig.direction = priv->is_tx ? SDW_DATA_DIR_TX : SDW_DATA_DIR_RX;
+ priv->sconfig.type = SDW_STREAM_PCM;
+
+ return sdw_stream_add_slave(priv->sdev, &priv->sconfig, &port_config[0], priv->active_ports,
+ priv->sruntime);
+}
+EXPORT_SYMBOL_GPL(pm4125_sdw_hw_params);
+
+static int pm4125_update_status(struct sdw_slave *slave, enum sdw_slave_status status)
+{
+ struct pm4125_sdw_priv *priv = dev_get_drvdata(&slave->dev);
+
+ if (priv->regmap && status == SDW_SLAVE_ATTACHED) {
+ /* Write out any cached changes that happened between probe and attach */
+ regcache_cache_only(priv->regmap, false);
+ return regcache_sync(priv->regmap);
+ }
+
+ return 0;
+}
+
+/*
+ * Handle Soundwire out-of-band interrupt event by triggering the first irq of the slave_irq
+ * irq domain, which then will be handled by the regmap_irq threaded irq.
+ * Looping is to ensure no interrupts were missed in the process.
+ */
+static int pm4125_interrupt_callback(struct sdw_slave *slave, struct sdw_slave_intr_status *status)
+{
+ struct pm4125_sdw_priv *priv = dev_get_drvdata(&slave->dev);
+ struct irq_domain *slave_irq = priv->slave_irq;
+ u32 sts1, sts2, sts3;
+
+ do {
+ handle_nested_irq(irq_find_mapping(slave_irq, 0));
+ regmap_read(priv->regmap, PM4125_DIG_SWR_INTR_STATUS_0, &sts1);
+ regmap_read(priv->regmap, PM4125_DIG_SWR_INTR_STATUS_1, &sts2);
+ regmap_read(priv->regmap, PM4125_DIG_SWR_INTR_STATUS_2, &sts3);
+
+ } while (sts1 || sts2 || sts3);
+
+ return IRQ_HANDLED;
+}
+
+static const struct reg_default pm4125_defaults[] = {
+ { PM4125_ANA_MICBIAS_MICB_1_2_EN, 0x01 },
+ { PM4125_ANA_MICBIAS_MICB_3_EN, 0x00 },
+ { PM4125_ANA_MICBIAS_LDO_1_SETTING, 0x21 },
+ { PM4125_ANA_MICBIAS_LDO_1_CTRL, 0x01 },
+ { PM4125_ANA_TX_AMIC1, 0x00 },
+ { PM4125_ANA_TX_AMIC2, 0x00 },
+ { PM4125_ANA_MBHC_MECH, 0x39 },
+ { PM4125_ANA_MBHC_ELECT, 0x08 },
+ { PM4125_ANA_MBHC_ZDET, 0x10 },
+ { PM4125_ANA_MBHC_RESULT_1, 0x00 },
+ { PM4125_ANA_MBHC_RESULT_2, 0x00 },
+ { PM4125_ANA_MBHC_RESULT_3, 0x00 },
+ { PM4125_ANA_MBHC_BTN0_ZDET_VREF1, 0x00 },
+ { PM4125_ANA_MBHC_BTN1_ZDET_VREF2, 0x10 },
+ { PM4125_ANA_MBHC_BTN2_ZDET_VREF3, 0x20 },
+ { PM4125_ANA_MBHC_BTN3_ZDET_DBG_400, 0x30 },
+ { PM4125_ANA_MBHC_BTN4_ZDET_DBG_1400, 0x40 },
+ { PM4125_ANA_MBHC_MICB2_RAMP, 0x00 },
+ { PM4125_ANA_MBHC_CTL_1, 0x02 },
+ { PM4125_ANA_MBHC_CTL_2, 0x05 },
+ { PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0xE9 },
+ { PM4125_ANA_MBHC_ZDET_ANA_CTL, 0x0F },
+ { PM4125_ANA_MBHC_ZDET_RAMP_CTL, 0x00 },
+ { PM4125_ANA_MBHC_FSM_STATUS, 0x00 },
+ { PM4125_ANA_MBHC_ADC_RESULT, 0x00 },
+ { PM4125_ANA_MBHC_CTL_CLK, 0x30 },
+ { PM4125_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 },
+ { PM4125_ANA_NCP_EN, 0x00 },
+ { PM4125_ANA_NCP_VCTRL, 0xA7 },
+ { PM4125_ANA_HPHPA_CNP_CTL_1, 0x54 },
+ { PM4125_ANA_HPHPA_CNP_CTL_2, 0x2B },
+ { PM4125_ANA_HPHPA_PA_STATUS, 0x00 },
+ { PM4125_ANA_HPHPA_FSM_CLK, 0x12 },
+ { PM4125_ANA_HPHPA_L_GAIN, 0x00 },
+ { PM4125_ANA_HPHPA_R_GAIN, 0x00 },
+ { PM4125_SWR_HPHPA_HD2, 0x1B },
+ { PM4125_ANA_HPHPA_SPARE_CTL, 0x02 },
+ { PM4125_ANA_SURGE_EN, 0x38 },
+ { PM4125_ANA_COMBOPA_CTL, 0x35 },
+ { PM4125_ANA_COMBOPA_CTL_4, 0x84 },
+ { PM4125_ANA_COMBOPA_CTL_5, 0x05 },
+ { PM4125_ANA_RXLDO_CTL, 0x86 },
+ { PM4125_ANA_MBIAS_EN, 0x00 },
+ { PM4125_DIG_SWR_CHIP_ID0, 0x00 },
+ { PM4125_DIG_SWR_CHIP_ID1, 0x00 },
+ { PM4125_DIG_SWR_CHIP_ID2, 0x0C },
+ { PM4125_DIG_SWR_CHIP_ID3, 0x01 },
+ { PM4125_DIG_SWR_SWR_TX_CLK_RATE, 0x00 },
+ { PM4125_DIG_SWR_CDC_RST_CTL, 0x03 },
+ { PM4125_DIG_SWR_TOP_CLK_CFG, 0x00 },
+ { PM4125_DIG_SWR_CDC_RX_CLK_CTL, 0x00 },
+ { PM4125_DIG_SWR_CDC_TX_CLK_CTL, 0x33 },
+ { PM4125_DIG_SWR_SWR_RST_EN, 0x00 },
+ { PM4125_DIG_SWR_CDC_RX_RST, 0x00 },
+ { PM4125_DIG_SWR_CDC_RX0_CTL, 0xFC },
+ { PM4125_DIG_SWR_CDC_RX1_CTL, 0xFC },
+ { PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1, 0x00 },
+ { PM4125_DIG_SWR_CDC_COMP_CTL_0, 0x00 },
+ { PM4125_DIG_SWR_CDC_RX_DELAY_CTL, 0x66 },
+ { PM4125_DIG_SWR_CDC_RX_GAIN_0, 0x55 },
+ { PM4125_DIG_SWR_CDC_RX_GAIN_1, 0xA9 },
+ { PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 0x00 },
+ { PM4125_DIG_SWR_CDC_TX0_CTL, 0x68 },
+ { PM4125_DIG_SWR_CDC_TX1_CTL, 0x68 },
+ { PM4125_DIG_SWR_CDC_TX_RST, 0x00 },
+ { PM4125_DIG_SWR_CDC_REQ0_CTL, 0x01 },
+ { PM4125_DIG_SWR_CDC_REQ1_CTL, 0x01 },
+ { PM4125_DIG_SWR_CDC_RST, 0x00 },
+ { PM4125_DIG_SWR_CDC_AMIC_CTL, 0x02 },
+ { PM4125_DIG_SWR_CDC_DMIC_CTL, 0x00 },
+ { PM4125_DIG_SWR_CDC_DMIC1_CTL, 0x00 },
+ { PM4125_DIG_SWR_CDC_DMIC1_RATE, 0x01 },
+ { PM4125_DIG_SWR_PDM_WD_CTL0, 0x00 },
+ { PM4125_DIG_SWR_PDM_WD_CTL1, 0x00 },
+ { PM4125_DIG_SWR_INTR_MODE, 0x00 },
+ { PM4125_DIG_SWR_INTR_MASK_0, 0xFF },
+ { PM4125_DIG_SWR_INTR_MASK_1, 0x7F },
+ { PM4125_DIG_SWR_INTR_MASK_2, 0x0C },
+ { PM4125_DIG_SWR_INTR_STATUS_0, 0x00 },
+ { PM4125_DIG_SWR_INTR_STATUS_1, 0x00 },
+ { PM4125_DIG_SWR_INTR_STATUS_2, 0x00 },
+ { PM4125_DIG_SWR_INTR_CLEAR_0, 0x00 },
+ { PM4125_DIG_SWR_INTR_CLEAR_1, 0x00 },
+ { PM4125_DIG_SWR_INTR_CLEAR_2, 0x00 },
+ { PM4125_DIG_SWR_INTR_LEVEL_0, 0x00 },
+ { PM4125_DIG_SWR_INTR_LEVEL_1, 0x2A },
+ { PM4125_DIG_SWR_INTR_LEVEL_2, 0x00 },
+ { PM4125_DIG_SWR_CDC_CONN_RX0_CTL, 0x00 },
+ { PM4125_DIG_SWR_CDC_CONN_RX1_CTL, 0x00 },
+ { PM4125_DIG_SWR_LOOP_BACK_MODE, 0x00 },
+ { PM4125_DIG_SWR_DRIVE_STRENGTH_0, 0x00 },
+ { PM4125_DIG_SWR_DIG_DEBUG_CTL, 0x00 },
+ { PM4125_DIG_SWR_DIG_DEBUG_EN, 0x00 },
+ { PM4125_DIG_SWR_DEM_BYPASS_DATA0, 0x55 },
+ { PM4125_DIG_SWR_DEM_BYPASS_DATA1, 0x55 },
+ { PM4125_DIG_SWR_DEM_BYPASS_DATA2, 0x55 },
+ { PM4125_DIG_SWR_DEM_BYPASS_DATA3, 0x01 },
+};
+
+static bool pm4125_rdwr_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case PM4125_ANA_MICBIAS_MICB_1_2_EN:
+ case PM4125_ANA_MICBIAS_MICB_3_EN:
+ case PM4125_ANA_MICBIAS_LDO_1_SETTING:
+ case PM4125_ANA_MICBIAS_LDO_1_CTRL:
+ case PM4125_ANA_TX_AMIC1:
+ case PM4125_ANA_TX_AMIC2:
+ case PM4125_ANA_MBHC_MECH:
+ case PM4125_ANA_MBHC_ELECT:
+ case PM4125_ANA_MBHC_ZDET:
+ case PM4125_ANA_MBHC_BTN0_ZDET_VREF1:
+ case PM4125_ANA_MBHC_BTN1_ZDET_VREF2:
+ case PM4125_ANA_MBHC_BTN2_ZDET_VREF3:
+ case PM4125_ANA_MBHC_BTN3_ZDET_DBG_400:
+ case PM4125_ANA_MBHC_BTN4_ZDET_DBG_1400:
+ case PM4125_ANA_MBHC_MICB2_RAMP:
+ case PM4125_ANA_MBHC_CTL_1:
+ case PM4125_ANA_MBHC_CTL_2:
+ case PM4125_ANA_MBHC_PLUG_DETECT_CTL:
+ case PM4125_ANA_MBHC_ZDET_ANA_CTL:
+ case PM4125_ANA_MBHC_ZDET_RAMP_CTL:
+ case PM4125_ANA_MBHC_CTL_CLK:
+ case PM4125_ANA_NCP_EN:
+ case PM4125_ANA_NCP_VCTRL:
+ case PM4125_ANA_HPHPA_CNP_CTL_1:
+ case PM4125_ANA_HPHPA_CNP_CTL_2:
+ case PM4125_ANA_HPHPA_FSM_CLK:
+ case PM4125_ANA_HPHPA_L_GAIN:
+ case PM4125_ANA_HPHPA_R_GAIN:
+ case PM4125_ANA_HPHPA_SPARE_CTL:
+ case PM4125_SWR_HPHPA_HD2:
+ case PM4125_ANA_SURGE_EN:
+ case PM4125_ANA_COMBOPA_CTL:
+ case PM4125_ANA_COMBOPA_CTL_4:
+ case PM4125_ANA_COMBOPA_CTL_5:
+ case PM4125_ANA_RXLDO_CTL:
+ case PM4125_ANA_MBIAS_EN:
+ case PM4125_DIG_SWR_SWR_TX_CLK_RATE:
+ case PM4125_DIG_SWR_CDC_RST_CTL:
+ case PM4125_DIG_SWR_TOP_CLK_CFG:
+ case PM4125_DIG_SWR_CDC_RX_CLK_CTL:
+ case PM4125_DIG_SWR_CDC_TX_CLK_CTL:
+ case PM4125_DIG_SWR_SWR_RST_EN:
+ case PM4125_DIG_SWR_CDC_RX_RST:
+ case PM4125_DIG_SWR_CDC_RX0_CTL:
+ case PM4125_DIG_SWR_CDC_RX1_CTL:
+ case PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1:
+ case PM4125_DIG_SWR_CDC_COMP_CTL_0:
+ case PM4125_DIG_SWR_CDC_RX_DELAY_CTL:
+ case PM4125_DIG_SWR_CDC_RX_GAIN_0:
+ case PM4125_DIG_SWR_CDC_RX_GAIN_1:
+ case PM4125_DIG_SWR_CDC_RX_GAIN_CTL:
+ case PM4125_DIG_SWR_CDC_TX0_CTL:
+ case PM4125_DIG_SWR_CDC_TX1_CTL:
+ case PM4125_DIG_SWR_CDC_TX_RST:
+ case PM4125_DIG_SWR_CDC_REQ0_CTL:
+ case PM4125_DIG_SWR_CDC_REQ1_CTL:
+ case PM4125_DIG_SWR_CDC_RST:
+ case PM4125_DIG_SWR_CDC_AMIC_CTL:
+ case PM4125_DIG_SWR_CDC_DMIC_CTL:
+ case PM4125_DIG_SWR_CDC_DMIC1_CTL:
+ case PM4125_DIG_SWR_CDC_DMIC1_RATE:
+ case PM4125_DIG_SWR_PDM_WD_CTL0:
+ case PM4125_DIG_SWR_PDM_WD_CTL1:
+ case PM4125_DIG_SWR_INTR_MODE:
+ case PM4125_DIG_SWR_INTR_MASK_0:
+ case PM4125_DIG_SWR_INTR_MASK_1:
+ case PM4125_DIG_SWR_INTR_MASK_2:
+ case PM4125_DIG_SWR_INTR_CLEAR_0:
+ case PM4125_DIG_SWR_INTR_CLEAR_1:
+ case PM4125_DIG_SWR_INTR_CLEAR_2:
+ case PM4125_DIG_SWR_INTR_LEVEL_0:
+ case PM4125_DIG_SWR_INTR_LEVEL_1:
+ case PM4125_DIG_SWR_INTR_LEVEL_2:
+ case PM4125_DIG_SWR_CDC_CONN_RX0_CTL:
+ case PM4125_DIG_SWR_CDC_CONN_RX1_CTL:
+ case PM4125_DIG_SWR_LOOP_BACK_MODE:
+ case PM4125_DIG_SWR_DRIVE_STRENGTH_0:
+ case PM4125_DIG_SWR_DIG_DEBUG_CTL:
+ case PM4125_DIG_SWR_DIG_DEBUG_EN:
+ case PM4125_DIG_SWR_DEM_BYPASS_DATA0:
+ case PM4125_DIG_SWR_DEM_BYPASS_DATA1:
+ case PM4125_DIG_SWR_DEM_BYPASS_DATA2:
+ case PM4125_DIG_SWR_DEM_BYPASS_DATA3:
+ return true;
+ }
+
+ return false;
+}
+
+static bool pm4125_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case PM4125_ANA_MBHC_RESULT_1:
+ case PM4125_ANA_MBHC_RESULT_2:
+ case PM4125_ANA_MBHC_RESULT_3:
+ case PM4125_ANA_MBHC_FSM_STATUS:
+ case PM4125_ANA_MBHC_ADC_RESULT:
+ case PM4125_ANA_MBHC_ZDET_CALIB_RESULT:
+ case PM4125_ANA_HPHPA_PA_STATUS:
+ case PM4125_DIG_SWR_CHIP_ID0:
+ case PM4125_DIG_SWR_CHIP_ID1:
+ case PM4125_DIG_SWR_CHIP_ID2:
+ case PM4125_DIG_SWR_CHIP_ID3:
+ case PM4125_DIG_SWR_INTR_STATUS_0:
+ case PM4125_DIG_SWR_INTR_STATUS_1:
+ case PM4125_DIG_SWR_INTR_STATUS_2:
+ return true;
+ }
+ return pm4125_rdwr_register(dev, reg);
+}
+
+static bool pm4125_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case PM4125_ANA_MBHC_RESULT_1:
+ case PM4125_ANA_MBHC_RESULT_2:
+ case PM4125_ANA_MBHC_RESULT_3:
+ case PM4125_ANA_MBHC_FSM_STATUS:
+ case PM4125_ANA_MBHC_ADC_RESULT:
+ case PM4125_ANA_MBHC_ZDET_CALIB_RESULT:
+ case PM4125_ANA_HPHPA_PA_STATUS:
+ case PM4125_DIG_SWR_CHIP_ID0:
+ case PM4125_DIG_SWR_CHIP_ID1:
+ case PM4125_DIG_SWR_CHIP_ID2:
+ case PM4125_DIG_SWR_CHIP_ID3:
+ case PM4125_DIG_SWR_INTR_STATUS_0:
+ case PM4125_DIG_SWR_INTR_STATUS_1:
+ case PM4125_DIG_SWR_INTR_STATUS_2:
+ return true;
+ }
+
+ return false;
+}
+
+static const struct regmap_config pm4125_regmap_config = {
+ .name = "pm4125_csr",
+ .reg_bits = 32,
+ .val_bits = 8,
+ .cache_type = REGCACHE_MAPLE,
+ .reg_defaults = pm4125_defaults,
+ .num_reg_defaults = ARRAY_SIZE(pm4125_defaults),
+ .max_register = PM4125_MAX_REGISTER,
+ .readable_reg = pm4125_readable_register,
+ .writeable_reg = pm4125_rdwr_register,
+ .volatile_reg = pm4125_volatile_register,
+};
+
+static const struct sdw_slave_ops pm4125_slave_ops = {
+ .update_status = pm4125_update_status,
+ .interrupt_callback = pm4125_interrupt_callback,
+};
+
+static int pm4125_sdw_component_bind(struct device *dev, struct device *master, void *data)
+{
+ pm_runtime_set_autosuspend_delay(dev, 3000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ return 0;
+}
+
+static void pm4125_sdw_component_unbind(struct device *dev, struct device *master, void *data)
+{
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+}
+
+static const struct component_ops pm4125_sdw_component_ops = {
+ .bind = pm4125_sdw_component_bind,
+ .unbind = pm4125_sdw_component_unbind,
+};
+
+static int pm4125_probe(struct sdw_slave *pdev, const struct sdw_device_id *id)
+{
+ struct device *dev = &pdev->dev;
+ struct pm4125_sdw_priv *priv;
+ u8 master_ch_mask[PM4125_MAX_SWR_CH_IDS];
+ int master_ch_mask_size = 0;
+ int ret, i;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* Port map index starts at 0, however the data port for this codec starts at index 1 */
+ if (of_property_present(dev->of_node, "qcom,tx-port-mapping")) {
+ priv->is_tx = true;
+ ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",
+ &pdev->m_port_map[1], PM4125_MAX_TX_SWR_PORTS);
+ } else {
+ ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",
+ &pdev->m_port_map[1], PM4125_MAX_SWR_PORTS);
+ }
+
+ if (ret < 0)
+ dev_info(dev, "Error getting static port mapping for %s (%d)\n",
+ priv->is_tx ? "TX" : "RX", ret);
+
+ priv->sdev = pdev;
+ dev_set_drvdata(dev, priv);
+
+ pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
+ SDW_SCP_INT1_BUS_CLASH |
+ SDW_SCP_INT1_PARITY;
+ pdev->prop.lane_control_support = true;
+ pdev->prop.simple_clk_stop_capable = true;
+
+ memset(master_ch_mask, 0, PM4125_MAX_SWR_CH_IDS);
+
+ if (priv->is_tx) {
+ master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
+ "qcom,tx-channel-mapping");
+
+ if (master_ch_mask_size)
+ ret = of_property_read_u8_array(dev->of_node, "qcom,tx-channel-mapping",
+ master_ch_mask, master_ch_mask_size);
+ } else {
+ master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
+ "qcom,rx-channel-mapping");
+
+ if (master_ch_mask_size)
+ ret = of_property_read_u8_array(dev->of_node, "qcom,rx-channel-mapping",
+ master_ch_mask, master_ch_mask_size);
+ }
+
+ if (ret < 0)
+ dev_info(dev, "Static channel mapping not specified using device channel maps\n");
+
+ if (priv->is_tx) {
+ pdev->prop.source_ports = GENMASK(PM4125_MAX_TX_SWR_PORTS, 0);
+ pdev->prop.src_dpn_prop = pm4125_dpn_prop;
+ priv->ch_info = &pm4125_sdw_tx_ch_info[0];
+
+ for (i = 0; i < master_ch_mask_size; i++)
+ priv->ch_info[i].master_ch_mask = PM4125_SWRM_CH_MASK(master_ch_mask[i]);
+
+ pdev->prop.wake_capable = true;
+
+ priv->regmap = devm_regmap_init_sdw(pdev, &pm4125_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return dev_err_probe(dev, PTR_ERR(priv->regmap), "regmap init failed\n");
+
+ /* Start in cache-only until device is enumerated */
+ regcache_cache_only(priv->regmap, true);
+ } else {
+ pdev->prop.sink_ports = GENMASK(PM4125_MAX_SWR_PORTS - 1, 0);
+ pdev->prop.sink_dpn_prop = pm4125_dpn_prop;
+ priv->ch_info = &pm4125_sdw_rx_ch_info[0];
+
+ for (i = 0; i < master_ch_mask_size; i++)
+ priv->ch_info[i].master_ch_mask = PM4125_SWRM_CH_MASK(master_ch_mask[i]);
+ }
+
+ ret = component_add(dev, &pm4125_sdw_component_ops);
+ if (ret)
+ return ret;
+
+ /* Set suspended until aggregate device is bind */
+ pm_runtime_set_suspended(dev);
+
+ return 0;
+}
+
+static int pm4125_remove(struct sdw_slave *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ component_del(dev, &pm4125_sdw_component_ops);
+
+ return 0;
+}
+
+static const struct sdw_device_id pm4125_slave_id[] = {
+ SDW_SLAVE_ENTRY(0x0217, 0x10c, 0), /* Soundwire pm4125 RX/TX Device ID */
+ { }
+};
+MODULE_DEVICE_TABLE(sdw, pm4125_slave_id);
+
+static int __maybe_unused pm4125_sdw_runtime_suspend(struct device *dev)
+{
+ struct pm4125_sdw_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->regmap) {
+ regcache_cache_only(priv->regmap, true);
+ regcache_mark_dirty(priv->regmap);
+ }
+
+ return 0;
+}
+
+static int __maybe_unused pm4125_sdw_runtime_resume(struct device *dev)
+{
+ struct pm4125_sdw_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->regmap) {
+ regcache_cache_only(priv->regmap, false);
+ regcache_sync(priv->regmap);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops pm4125_sdw_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm4125_sdw_runtime_suspend, pm4125_sdw_runtime_resume, NULL)
+};
+
+static struct sdw_driver pm4125_codec_driver = {
+ .probe = pm4125_probe,
+ .remove = pm4125_remove,
+ .ops = &pm4125_slave_ops,
+ .id_table = pm4125_slave_id,
+ .driver = {
+ .name = "pm4125-codec",
+ .pm = &pm4125_sdw_pm_ops,
+ }
+};
+module_sdw_driver(pm4125_codec_driver);
+
+MODULE_DESCRIPTION("PM4125 SDW codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pm4125.c b/sound/soc/codecs/pm4125.c
new file mode 100644
index 000000000000..706fc668ffe2
--- /dev/null
+++ b/sound/soc/codecs/pm4125.c
@@ -0,0 +1,1780 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+// Copyright (c) 2025, Linaro Ltd
+
+#include <linux/component.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "pm4125.h"
+#include "wcd-mbhc-v2.h"
+
+#define WCD_MBHC_HS_V_MAX 1600
+#define PM4125_MBHC_MAX_BUTTONS 8
+
+#define PM4125_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
+ SNDRV_PCM_RATE_384000)
+
+/* Fractional Rates */
+#define PM4125_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
+
+#define PM4125_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+/* Registers in SPMI addr space */
+#define PM4125_CODEC_RESET_REG 0xF3DB
+#define PM4125_CODEC_OFF 0x1
+#define PM4125_CODEC_ON 0x0
+#define PM4125_CODEC_FOUNDRY_ID_REG 0x7
+
+enum {
+ HPH_COMP_DELAY,
+ HPH_PA_DELAY,
+ AMIC2_BCS_ENABLE,
+};
+
+enum {
+ AIF1_PB = 0,
+ AIF1_CAP,
+ NUM_CODEC_DAIS,
+};
+
+struct pm4125_priv {
+ struct sdw_slave *tx_sdw_dev;
+ struct pm4125_sdw_priv *sdw_priv[NUM_CODEC_DAIS];
+ struct device *txdev;
+ struct device *rxdev;
+ struct device_node *rxnode;
+ struct device_node *txnode;
+ struct regmap *regmap;
+ struct regmap *spmi_regmap;
+ /* mbhc module */
+ struct wcd_mbhc *wcd_mbhc;
+ struct wcd_mbhc_config mbhc_cfg;
+ struct wcd_mbhc_intr intr_ids;
+ struct irq_domain *virq;
+ const struct regmap_irq_chip *pm4125_regmap_irq_chip;
+ struct regmap_irq_chip_data *irq_chip;
+ struct snd_soc_jack *jack;
+ unsigned long status_mask;
+ s32 micb_ref[PM4125_MAX_MICBIAS];
+ s32 pullup_ref[PM4125_MAX_MICBIAS];
+ u32 micb1_mv;
+ u32 micb2_mv;
+ u32 micb3_mv;
+
+ int hphr_pdm_wd_int;
+ int hphl_pdm_wd_int;
+ bool comp1_enable;
+ bool comp2_enable;
+
+ atomic_t gloal_mbias_cnt;
+};
+
+static const char * const pm4125_power_supplies[] = {
+ "vdd-io", "vdd-cp", "vdd-mic-bias", "vdd-pa-vpos",
+};
+
+static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+
+static const struct wcd_mbhc_field pm4125_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
+ WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, PM4125_ANA_MBHC_MECH, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, PM4125_ANA_MBHC_MECH, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, PM4125_ANA_MBHC_MECH, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x30),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, PM4125_ANA_MBHC_ELECT, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x1F),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, PM4125_ANA_MBHC_MECH, 0x04),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, PM4125_ANA_MBHC_MECH, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, PM4125_ANA_MBHC_MECH, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, PM4125_ANA_MBHC_MECH, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, PM4125_ANA_MBHC_ELECT, 0x06),
+ WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, PM4125_ANA_MBHC_ELECT, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x0F),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, PM4125_ANA_MBHC_CTL_1, 0x03),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, PM4125_ANA_MBHC_CTL_2, 0x03),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, PM4125_ANA_MBHC_RESULT_3, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x07),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, PM4125_ANA_MBHC_ELECT, 0x70),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0xFF),
+ WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, PM4125_ANA_MICBIAS_MICB_1_2_EN, 0xC0),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0xC0),
+ WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, PM4125_ANA_MBHC_RESULT_3, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, PM4125_ANA_MBHC_FSM_STATUS, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, PM4125_ANA_MBHC_CTL_2, 0x70),
+ WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, PM4125_ANA_MBHC_FSM_STATUS, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, PM4125_DIG_SWR_INTR_STATUS_0, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, PM4125_DIG_SWR_INTR_STATUS_0, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, PM4125_ANA_MBHC_CTL_1, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, PM4125_ANA_MBHC_FSM_STATUS, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, PM4125_ANA_MBHC_FSM_STATUS, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, PM4125_ANA_MBHC_ADC_RESULT, 0xFF),
+ WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, PM4125_ANA_MICBIAS_LDO_1_SETTING, 0x3F),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, PM4125_ANA_MBHC_CTL_1, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, PM4125_ANA_MBHC_CTL_1, 0x04),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, PM4125_ANA_MBHC_ZDET, 0x02),
+};
+
+static const struct regmap_irq pm4125_irqs[PM4125_NUM_IRQS] = {
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_BUTTON_PRESS_DET, 0, BIT(0)),
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_BUTTON_RELEASE_DET, 0, BIT(1)),
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_ELECT_INS_REM_DET, 0, BIT(2)),
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, BIT(3)),
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_SW_DET, 0, BIT(4)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHR_OCP_INT, 0, BIT(5)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHR_CNP_INT, 0, BIT(6)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHL_OCP_INT, 0, BIT(7)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHL_CNP_INT, 1, BIT(0)),
+ REGMAP_IRQ_REG(PM4125_IRQ_EAR_CNP_INT, 1, BIT(1)),
+ REGMAP_IRQ_REG(PM4125_IRQ_EAR_SCD_INT, 1, BIT(2)),
+ REGMAP_IRQ_REG(PM4125_IRQ_AUX_CNP_INT, 1, BIT(3)),
+ REGMAP_IRQ_REG(PM4125_IRQ_AUX_SCD_INT, 1, BIT(4)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHL_PDM_WD_INT, 1, BIT(5)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHR_PDM_WD_INT, 1, BIT(6)),
+ REGMAP_IRQ_REG(PM4125_IRQ_AUX_PDM_WD_INT, 1, BIT(7)),
+ REGMAP_IRQ_REG(PM4125_IRQ_LDORT_SCD_INT, 2, BIT(0)),
+ REGMAP_IRQ_REG(PM4125_IRQ_MBHC_MOISTURE_INT, 2, BIT(1)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHL_SURGE_DET_INT, 2, BIT(2)),
+ REGMAP_IRQ_REG(PM4125_IRQ_HPHR_SURGE_DET_INT, 2, BIT(3)),
+};
+
+static int pm4125_handle_post_irq(void *data)
+{
+ struct pm4125_priv *pm4125 = (struct pm4125_priv *)data;
+
+ regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_0, 0);
+ regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_1, 0);
+ regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_2, 0);
+
+ return IRQ_HANDLED;
+}
+
+static const u32 pm4125_config_regs[] = {
+ PM4125_DIG_SWR_INTR_LEVEL_0,
+};
+
+static struct regmap_irq_chip pm4125_regmap_irq_chip = {
+ .name = "pm4125",
+ .irqs = pm4125_irqs,
+ .num_irqs = ARRAY_SIZE(pm4125_irqs),
+ .num_regs = 3,
+ .status_base = PM4125_DIG_SWR_INTR_STATUS_0,
+ .mask_base = PM4125_DIG_SWR_INTR_MASK_0,
+ .ack_base = PM4125_DIG_SWR_INTR_CLEAR_0,
+ .use_ack = 1,
+ .clear_ack = 1,
+ .config_base = pm4125_config_regs,
+ .num_config_bases = ARRAY_SIZE(pm4125_config_regs),
+ .num_config_regs = 1,
+ .runtime_pm = true,
+ .handle_post_irq = pm4125_handle_post_irq,
+};
+
+static void pm4125_reset(struct pm4125_priv *pm4125)
+{
+ regmap_write(pm4125->spmi_regmap, PM4125_CODEC_RESET_REG, PM4125_CODEC_OFF);
+ usleep_range(20, 30);
+ regmap_write(pm4125->spmi_regmap, PM4125_CODEC_RESET_REG, PM4125_CODEC_ON);
+ usleep_range(5000, 5010);
+}
+
+static void pm4125_io_init(struct regmap *regmap)
+{
+ /* Disable HPH OCP */
+ regmap_update_bits(regmap, PM4125_ANA_HPHPA_CNP_CTL_2,
+ PM4125_ANA_HPHPA_CNP_OCP_EN_L_MASK | PM4125_ANA_HPHPA_CNP_OCP_EN_R_MASK,
+ PM4125_ANA_HPHPA_CNP_OCP_DISABLE);
+
+ /* Enable surge protection */
+ regmap_update_bits(regmap, PM4125_ANA_SURGE_EN, PM4125_ANA_SURGE_PROTECTION_HPHL_MASK,
+ FIELD_PREP(PM4125_ANA_SURGE_PROTECTION_HPHL_MASK,
+ PM4125_ANA_SURGE_PROTECTION_ENABLE));
+ regmap_update_bits(regmap, PM4125_ANA_SURGE_EN, PM4125_ANA_SURGE_PROTECTION_HPHR_MASK,
+ FIELD_PREP(PM4125_ANA_SURGE_PROTECTION_HPHR_MASK,
+ PM4125_ANA_SURGE_PROTECTION_ENABLE));
+
+ /* Disable mic bias 2 pull down */
+ regmap_update_bits(regmap, PM4125_ANA_MICBIAS_MICB_1_2_EN,
+ PM4125_ANA_MICBIAS_MICB2_PULL_DN_MASK,
+ FIELD_PREP(PM4125_ANA_MICBIAS_MICB2_PULL_DN_MASK,
+ PM4125_ANA_MICBIAS_MICB_PULL_DISABLE));
+}
+
+static int pm4125_global_mbias_disable(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ if (atomic_dec_and_test(&pm4125->gloal_mbias_cnt)) {
+
+ snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN,
+ PM4125_ANA_MBIAS_EN_V2I_MASK,
+ PM4125_ANA_MBIAS_EN_DISABLE);
+ snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN,
+ PM4125_ANA_MBIAS_EN_GLOBAL_MASK,
+ PM4125_ANA_MBIAS_EN_DISABLE);
+ }
+
+ return 0;
+}
+
+static int pm4125_global_mbias_enable(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ if (atomic_inc_return(&pm4125->gloal_mbias_cnt) == 1) {
+ snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN,
+ PM4125_ANA_MBIAS_EN_GLOBAL_MASK,
+ PM4125_ANA_MBIAS_EN_ENABLE);
+ snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN,
+ PM4125_ANA_MBIAS_EN_V2I_MASK,
+ PM4125_ANA_MBIAS_EN_ENABLE);
+ usleep_range(1000, 1100);
+ }
+
+ return 0;
+}
+
+static int pm4125_rx_clk_enable(struct snd_soc_component *component)
+{
+ pm4125_global_mbias_enable(component);
+
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_ANA_RX_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_ENABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_ANA_RX_DIV2_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_ENABLE);
+ usleep_range(5000, 5100);
+
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK,
+ PM4125_ANA_HPHPA_FSM_DIV_RATIO_MASK,
+ PM4125_ANA_HPHPA_FSM_DIV_RATIO_68);
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK,
+ PM4125_ANA_HPHPA_FSM_CLK_DIV_EN_MASK,
+ PM4125_ANA_HPHPA_FSM_CLK_DIV_ENABLE);
+ snd_soc_component_update_bits(component, PM4125_ANA_NCP_VCTRL, 0x07, 0x06);
+ snd_soc_component_write_field(component, PM4125_ANA_NCP_EN,
+ PM4125_ANA_NCP_ENABLE_MASK,
+ PM4125_ANA_NCP_ENABLE);
+ usleep_range(500, 510);
+
+ return 0;
+}
+
+static int pm4125_rx_clk_disable(struct snd_soc_component *component)
+{
+
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK,
+ PM4125_ANA_HPHPA_FSM_CLK_DIV_EN_MASK,
+ PM4125_ANA_HPHPA_FSM_CLK_DIV_DISABLE);
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK,
+ PM4125_ANA_HPHPA_FSM_DIV_RATIO_MASK,
+ 0x00);
+ snd_soc_component_write_field(component, PM4125_ANA_NCP_EN,
+ PM4125_ANA_NCP_ENABLE_MASK,
+ PM4125_ANA_NCP_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_ANA_RX_DIV2_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_ANA_RX_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_DISABLE);
+
+ pm4125_global_mbias_disable(component);
+
+ return 0;
+}
+
+
+static int pm4125_codec_enable_rxclk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pm4125_rx_clk_enable(component);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pm4125_rx_clk_disable(component);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_CNP_CTL_1,
+ PM4125_ANA_HPHPA_CNP_CTL_1_EN_MASK,
+ PM4125_ANA_HPHPA_CNP_CTL_1_EN);
+ snd_soc_component_write_field(component, PM4125_SWR_HPHPA_HD2,
+ PM4125_SWR_HPHPA_HD2_LEFT_MASK,
+ PM4125_SWR_HPHPA_HD2_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if (pm4125->comp1_enable) {
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHL_EN_MASK,
+ PM4125_DIG_SWR_COMP_ENABLE);
+
+ if (pm4125->comp2_enable)
+ snd_soc_component_write_field(component,
+ PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHR_EN_MASK,
+ PM4125_DIG_SWR_COMP_ENABLE);
+ /*
+ * 5ms sleep is required after COMP is enabled as per
+ * HW requirement
+ */
+ usleep_range(5000, 5100);
+ } else {
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHL_EN_MASK,
+ PM4125_DIG_SWR_COMP_DISABLE);
+ }
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX0_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_ENABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX0_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX0_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX0_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_ENABLE);
+ if (pm4125->comp1_enable)
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHL_EN_MASK,
+ PM4125_DIG_SWR_COMP_DISABLE);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_write_field(component, PM4125_ANA_HPHPA_CNP_CTL_1,
+ PM4125_ANA_HPHPA_CNP_CTL_1_EN_MASK,
+ PM4125_ANA_HPHPA_CNP_CTL_1_EN);
+ snd_soc_component_write_field(component, PM4125_SWR_HPHPA_HD2,
+ PM4125_SWR_HPHPA_HD2_RIGHT_MASK,
+ PM4125_SWR_HPHPA_HD2_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if (pm4125->comp2_enable) {
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHR_EN_MASK,
+ PM4125_DIG_SWR_COMP_ENABLE);
+ if (pm4125->comp1_enable)
+ snd_soc_component_write_field(component,
+ PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHL_EN_MASK,
+ PM4125_DIG_SWR_COMP_ENABLE);
+ /*
+ * 5ms sleep is required after COMP is enabled
+ * as per HW requirement
+ */
+ usleep_range(5000, 5100);
+ } else {
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHR_EN_MASK,
+ PM4125_DIG_SWR_COMP_DISABLE);
+ }
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX1_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX1_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_ENABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX1_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX1_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX1_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX1_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_ENABLE);
+ if (pm4125->comp2_enable)
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0,
+ PM4125_DIG_SWR_COMP_HPHR_EN_MASK,
+ PM4125_DIG_SWR_COMP_DISABLE);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX0_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_ENABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX0_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL,
+ PM4125_DIG_SWR_RX0_CLK_EN_MASK,
+ PM4125_DIG_SWR_RX_CLK_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL,
+ PM4125_DIG_SWR_RX0_EN_MASK,
+ PM4125_DIG_SWR_RX_INPUT_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL,
+ PM4125_DIG_SWR_DSM_DITHER_EN_MASK,
+ PM4125_DIG_SWR_DSM_DITHER_ENABLE);
+ break;
+ }
+
+ return 0;
+}
+
+
+static int pm4125_codec_enable_hphl_wdt_irq(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(5000, 5100);
+ enable_irq(pm4125->hphl_pdm_wd_int);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ disable_irq_nosync(pm4125->hphl_pdm_wd_int);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_hphr_wdt_irq(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(5000, 5100);
+ enable_irq(pm4125->hphr_pdm_wd_int);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ disable_irq_nosync(pm4125->hphr_pdm_wd_int);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ usleep_range(200, 210);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL1,
+ PM4125_WDT_ENABLE_MASK,
+ (PM4125_WDT_ENABLE_RX1_M | PM4125_WDT_ENABLE_RX1_L));
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ usleep_range(5000, 5100);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL1,
+ PM4125_WDT_ENABLE_MASK, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ usleep_range(200, 210);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK,
+ (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L));
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ usleep_range(5000, 5100);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_5, 0x04, 0x00);
+ usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x0F);
+ usleep_range(1000, 1010);
+ snd_soc_component_write_field(component, PM4125_ANA_COMBOPA_CTL,
+ PM4125_ANA_COMBO_PA_SELECT_MASK,
+ PM4125_ANA_COMBO_PA_SELECT_LO);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK,
+ (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L));
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(5000, 5010);
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x04);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ usleep_range(2000, 2010);
+ snd_soc_component_write_field(component, PM4125_ANA_COMBOPA_CTL,
+ PM4125_ANA_COMBO_PA_SELECT_MASK,
+ PM4125_ANA_COMBO_PA_SELECT_EAR);
+ usleep_range(5000, 5100);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_5, 0x04, 0x00);
+ usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x0F);
+ usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL,
+ PM4125_ANA_COMBO_PA_SELECT_MASK,
+ PM4125_ANA_COMBO_PA_SELECT_EAR);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK,
+ (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L));
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(5000, 5010);
+ snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x04);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ usleep_range(5000, 5010);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0,
+ PM4125_WDT_ENABLE_MASK, 0x00);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv)
+{
+ if (micb_mv < 1600 || micb_mv > 2850) {
+ dev_err(dev, "%s: unsupported micbias voltage (%u mV)\n", __func__, micb_mv);
+ return -EINVAL;
+ }
+
+ return (micb_mv - 1600) / 50;
+}
+
+static int pm4125_codec_enable_adc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable BCS for Headset mic */
+ if (w->shift == 1 &&
+ !(snd_soc_component_read(component, PM4125_ANA_TX_AMIC2) & 0x10)) {
+ set_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask);
+ }
+ pm4125_global_mbias_enable(component);
+ if (w->shift)
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1,
+ PM4125_DIG_SWR_TX_ANA_TXD1_MODE_MASK,
+ PM4125_DIG_SWR_TXD_MODE_NORMAL);
+ else
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1,
+ PM4125_DIG_SWR_TX_ANA_TXD0_MODE_MASK,
+ PM4125_DIG_SWR_TXD_MODE_NORMAL);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (w->shift == 1 && test_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask))
+ clear_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask);
+
+ if (w->shift)
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1,
+ PM4125_DIG_SWR_TX_ANA_TXD1_MODE_MASK,
+ 0x00);
+ else
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1,
+ PM4125_DIG_SWR_TX_ANA_TXD0_MODE_MASK,
+ 0x00);
+ pm4125_global_mbias_disable(component);
+ break;
+ };
+
+ return 0;
+}
+
+static int pm4125_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ u16 dmic_clk_reg = w->reg;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_AMIC_CTL,
+ PM4125_DIG_SWR_AMIC_SELECT_MASK,
+ PM4125_DIG_SWR_AMIC_SELECT_DMIC1);
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ PM4125_DIG_SWR_DMIC1_CLK_EN_MASK,
+ PM4125_DIG_SWR_DMIC1_CLK_ENABLE);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ PM4125_DIG_SWR_DMIC1_CLK_EN_MASK,
+ PM4125_DIG_SWR_DMIC1_CLK_DISABLE);
+ snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_AMIC_CTL,
+ PM4125_DIG_SWR_AMIC_SELECT_MASK,
+ PM4125_DIG_SWR_AMIC_SELECT_AMIC3);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_micbias_control(struct snd_soc_component *component, int micb_num, int req,
+ bool is_dapm)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+ int micb_index = micb_num - 1;
+ u16 micb_reg;
+ u8 pullup_mask = 0, enable_mask = 0;
+
+ if ((micb_index < 0) || (micb_index > PM4125_MAX_MICBIAS - 1)) {
+ dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
+ __func__, micb_index);
+ return -EINVAL;
+ }
+ switch (micb_num) {
+ case MIC_BIAS_1:
+ micb_reg = PM4125_ANA_MICBIAS_MICB_1_2_EN;
+ pullup_mask = PM4125_ANA_MICBIAS_MICB1_PULL_UP_MASK;
+ enable_mask = 0x40;
+ break;
+ case MIC_BIAS_2:
+ micb_reg = PM4125_ANA_MICBIAS_MICB_1_2_EN;
+ pullup_mask = PM4125_ANA_MICBIAS_MICB2_PULL_UP_MASK;
+ enable_mask = 0x04;
+ break;
+ case MIC_BIAS_3:
+ micb_reg = PM4125_ANA_MICBIAS_MICB_3_EN;
+ pullup_mask = 0x02;
+ break;
+ default:
+ dev_err(component->dev, "%s: Invalid micbias number: %d\n",
+ __func__, micb_num);
+ return -EINVAL;
+ };
+
+ switch (req) {
+ case MICB_PULLUP_ENABLE:
+ pm4125->pullup_ref[micb_index]++;
+ if ((pm4125->pullup_ref[micb_index] == 1) &&
+ (pm4125->micb_ref[micb_index] == 0))
+ snd_soc_component_update_bits(component, micb_reg,
+ pullup_mask, pullup_mask);
+ break;
+ case MICB_PULLUP_DISABLE:
+ if (pm4125->pullup_ref[micb_index] > 0)
+ pm4125->pullup_ref[micb_index]--;
+ if ((pm4125->pullup_ref[micb_index] == 0) &&
+ (pm4125->micb_ref[micb_index] == 0))
+ snd_soc_component_update_bits(component, micb_reg,
+ pullup_mask, 0x00);
+ break;
+ case MICB_ENABLE:
+ pm4125->micb_ref[micb_index]++;
+ if (pm4125->micb_ref[micb_index] == 1) {
+ pm4125_global_mbias_enable(component);
+ snd_soc_component_update_bits(component, micb_reg,
+ enable_mask, enable_mask);
+ }
+ break;
+ case MICB_DISABLE:
+ if (pm4125->micb_ref[micb_index] > 0)
+ pm4125->micb_ref[micb_index]--;
+ if ((pm4125->micb_ref[micb_index] == 0) &&
+ (pm4125->pullup_ref[micb_index] > 0)) {
+ snd_soc_component_update_bits(component, micb_reg,
+ pullup_mask, pullup_mask);
+ snd_soc_component_update_bits(component, micb_reg,
+ enable_mask, 0x00);
+ pm4125_global_mbias_disable(component);
+ } else if ((pm4125->micb_ref[micb_index] == 0) &&
+ (pm4125->pullup_ref[micb_index] == 0)) {
+ snd_soc_component_update_bits(component, micb_reg,
+ enable_mask, 0x00);
+ pm4125_global_mbias_disable(component);
+ }
+ break;
+ };
+
+ return 0;
+}
+
+static int pm4125_codec_enable_micbias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ int micb_num = w->shift;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (micb_num == MIC_BIAS_3)
+ pm4125_micbias_control(component, micb_num, MICB_PULLUP_ENABLE, true);
+ else
+ pm4125_micbias_control(component, micb_num, MICB_ENABLE, true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(1000, 1100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (micb_num == MIC_BIAS_3)
+ pm4125_micbias_control(component, micb_num, MICB_PULLUP_DISABLE, true);
+ else
+ pm4125_micbias_control(component, micb_num, MICB_DISABLE, true);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ int micb_num = w->shift;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pm4125_micbias_control(component, micb_num, MICB_PULLUP_ENABLE, true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(1000, 1100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pm4125_micbias_control(component, micb_num, MICB_PULLUP_DISABLE, true);
+ break;
+ }
+
+ return 0;
+}
+
+static int pm4125_connect_port(struct pm4125_sdw_priv *sdw_priv, u8 port_idx, u8 ch_id, bool enable)
+{
+ struct sdw_port_config *port_config = &sdw_priv->port_config[port_idx - 1];
+ const struct pm4125_sdw_ch_info *ch_info = &sdw_priv->ch_info[ch_id];
+ struct sdw_slave *sdev = sdw_priv->sdev;
+ u8 port_num = ch_info->port_num;
+ u8 ch_mask = ch_info->ch_mask;
+ u8 mstr_port_num, mstr_ch_mask;
+
+ port_config->num = port_num;
+
+ mstr_port_num = sdev->m_port_map[port_num];
+ mstr_ch_mask = ch_info->master_ch_mask;
+
+ if (enable) {
+ port_config->ch_mask |= ch_mask;
+ sdw_priv->master_channel_map[mstr_port_num] |= mstr_ch_mask;
+ } else {
+ port_config->ch_mask &= ~ch_mask;
+ sdw_priv->master_channel_map[mstr_port_num] &= ~mstr_ch_mask;
+ }
+
+ return 0;
+}
+
+static int pm4125_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+ struct soc_mixer_control *mc;
+ bool hphr;
+
+ mc = (struct soc_mixer_control *)(kcontrol->private_value);
+ hphr = mc->shift;
+
+ ucontrol->value.integer.value[0] = hphr ? pm4125->comp2_enable : pm4125->comp1_enable;
+ return 0;
+}
+
+static int pm4125_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+ struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[AIF1_PB];
+ int value = ucontrol->value.integer.value[0];
+ struct soc_mixer_control *mc;
+ int portidx;
+ bool hphr;
+
+ mc = (struct soc_mixer_control *)(kcontrol->private_value);
+ hphr = mc->shift;
+
+ if (hphr) {
+ if (value == pm4125->comp2_enable)
+ return 0;
+
+ pm4125->comp2_enable = value;
+ } else {
+ if (value == pm4125->comp1_enable)
+ return 0;
+
+ pm4125->comp1_enable = value;
+ }
+
+ portidx = sdw_priv->ch_info[mc->reg].port_num;
+
+ pm4125_connect_port(sdw_priv, portidx, mc->reg, value ? true : false);
+
+ return 1;
+}
+
+static int pm4125_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp);
+ struct pm4125_sdw_priv *sdw_priv;
+ int dai_id = mixer->shift;
+ int ch_idx = mixer->reg;
+ int portidx;
+
+ sdw_priv = pm4125->sdw_priv[dai_id];
+ portidx = sdw_priv->ch_info[ch_idx].port_num;
+
+ ucontrol->value.integer.value[0] = sdw_priv->port_enable[portidx];
+
+ return 0;
+}
+
+static int pm4125_set_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp);
+ struct pm4125_sdw_priv *sdw_priv;
+ int dai_id = mixer->shift;
+ int ch_idx = mixer->reg;
+ int portidx;
+ bool enable;
+
+ sdw_priv = pm4125->sdw_priv[dai_id];
+
+ portidx = sdw_priv->ch_info[ch_idx].port_num;
+
+ enable = ucontrol->value.integer.value[0];
+
+ if (enable == sdw_priv->port_enable[portidx]) {
+ pm4125_connect_port(sdw_priv, portidx, ch_idx, enable);
+ return 0;
+ }
+
+ sdw_priv->port_enable[portidx] = enable;
+ pm4125_connect_port(sdw_priv, portidx, ch_idx, enable);
+
+ return 1;
+}
+
+static void pm4125_mbhc_bias_control(struct snd_soc_component *component, bool enable)
+{
+ snd_soc_component_write_field(component, PM4125_ANA_MBHC_ELECT,
+ PM4125_ANA_MBHC_ELECT_BIAS_EN_MASK,
+ enable ? PM4125_ANA_MBHC_ELECT_BIAS_ENABLE :
+ PM4125_ANA_MBHC_ELECT_BIAS_DISABLE);
+}
+
+static void pm4125_mbhc_program_btn_thr(struct snd_soc_component *component,
+ int *btn_low, int *btn_high,
+ int num_btn, bool is_micbias)
+{
+ int i, vth;
+
+ if (num_btn > WCD_MBHC_DEF_BUTTONS) {
+ dev_err(component->dev, "%s: invalid number of buttons: %d\n",
+ __func__, num_btn);
+ return;
+ }
+
+ for (i = 0; i < num_btn; i++) {
+ vth = ((btn_high[i] * 2) / 25) & 0x3F;
+ snd_soc_component_write_field(component, PM4125_ANA_MBHC_BTN0_ZDET_VREF1 + i,
+ PM4125_ANA_MBHC_BTN0_THRESHOLD_MASK, vth << 2);
+ }
+}
+
+static const struct wcd_mbhc_cb mbhc_cb = {
+ .mbhc_bias = pm4125_mbhc_bias_control,
+ .set_btn_thr = pm4125_mbhc_program_btn_thr,
+};
+
+static int pm4125_mbhc_init(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+ struct wcd_mbhc_intr *intr_ids = &pm4125->intr_ids;
+
+ intr_ids->mbhc_sw_intr = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_MBHC_SW_DET);
+
+ intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(pm4125->irq_chip,
+ PM4125_IRQ_MBHC_BUTTON_PRESS_DET);
+
+ intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(pm4125->irq_chip,
+ PM4125_IRQ_MBHC_BUTTON_RELEASE_DET);
+
+ intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(pm4125->irq_chip,
+ PM4125_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
+
+ intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(pm4125->irq_chip,
+ PM4125_IRQ_MBHC_ELECT_INS_REM_DET);
+
+ intr_ids->hph_left_ocp = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHL_OCP_INT);
+
+ intr_ids->hph_right_ocp = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHR_OCP_INT);
+
+ pm4125->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, pm4125_mbhc_fields, false);
+ if (IS_ERR(pm4125->wcd_mbhc))
+ return PTR_ERR(pm4125->wcd_mbhc);
+
+ return 0;
+}
+
+static void pm4125_mbhc_deinit(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ wcd_mbhc_deinit(pm4125->wcd_mbhc);
+}
+
+static const struct snd_kcontrol_new pm4125_snd_controls[] = {
+ SOC_SINGLE_EXT("HPHL_COMP Switch", PM4125_COMP_L, 0, 1, 0,
+ pm4125_get_compander, pm4125_set_compander),
+ SOC_SINGLE_EXT("HPHR_COMP Switch", PM4125_COMP_R, 1, 1, 0,
+ pm4125_get_compander, pm4125_set_compander),
+
+ SOC_SINGLE_TLV("HPHL Volume", PM4125_ANA_HPHPA_L_GAIN, 0, 20, 1,
+ line_gain),
+ SOC_SINGLE_TLV("HPHR Volume", PM4125_ANA_HPHPA_R_GAIN, 0, 20, 1,
+ line_gain),
+ SOC_SINGLE_TLV("ADC1 Volume", PM4125_ANA_TX_AMIC1, 0, 8, 0,
+ analog_gain),
+ SOC_SINGLE_TLV("ADC2 Volume", PM4125_ANA_TX_AMIC2, 0, 8, 0,
+ analog_gain),
+
+ SOC_SINGLE_EXT("HPHL Switch", PM4125_HPH_L, 0, 1, 0,
+ pm4125_get_swr_port, pm4125_set_swr_port),
+ SOC_SINGLE_EXT("HPHR Switch", PM4125_HPH_R, 0, 1, 0,
+ pm4125_get_swr_port, pm4125_set_swr_port),
+
+ SOC_SINGLE_EXT("ADC1 Switch", PM4125_ADC1, 1, 1, 0,
+ pm4125_get_swr_port, pm4125_set_swr_port),
+ SOC_SINGLE_EXT("ADC2 Switch", PM4125_ADC2, 1, 1, 0,
+ pm4125_get_swr_port, pm4125_set_swr_port),
+};
+
+static const struct snd_kcontrol_new adc1_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new adc2_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new dmic1_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new dmic2_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new ear_rdac_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new lo_rdac_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new hphl_rdac_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new hphr_rdac_switch[] = {
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const char * const adc2_mux_text[] = {
+ "INP2", "INP3"
+};
+
+static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE(PM4125_ANA_TX_AMIC2, 4,
+ ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
+
+static const struct snd_kcontrol_new tx_adc2_mux = SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
+
+static const struct snd_soc_dapm_widget pm4125_dapm_widgets[] = {
+ /* Input widgets */
+ SND_SOC_DAPM_INPUT("AMIC1"),
+ SND_SOC_DAPM_INPUT("AMIC2"),
+ SND_SOC_DAPM_INPUT("AMIC3"),
+ SND_SOC_DAPM_INPUT("IN1_HPHL"),
+ SND_SOC_DAPM_INPUT("IN2_HPHR"),
+
+ /* TX widgets */
+ SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_enable_adc,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, pm4125_codec_enable_adc,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
+
+ /* TX mixers */
+ SND_SOC_DAPM_MIXER("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch, ARRAY_SIZE(adc1_switch)),
+ SND_SOC_DAPM_MIXER("ADC2_MIXER", SND_SOC_NOPM, 1, 0, adc2_switch, ARRAY_SIZE(adc2_switch)),
+
+ /* MIC_BIAS widgets */
+ SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0, pm4125_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0, pm4125_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0, pm4125_codec_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("PA_VPOS", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* RX widgets */
+ SND_SOC_DAPM_PGA_E("EAR PGA", PM4125_ANA_COMBOPA_CTL, 7, 0, NULL, 0,
+ pm4125_codec_enable_ear_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("LO PGA", PM4125_ANA_COMBOPA_CTL, 7, 0, NULL, 0,
+ pm4125_codec_enable_lo_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("HPHL PGA", PM4125_ANA_HPHPA_CNP_CTL_2, 7, 0, NULL, 0,
+ pm4125_codec_enable_hphl_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("HPHR PGA", PM4125_ANA_HPHPA_CNP_CTL_2, 6, 0, NULL, 0,
+ pm4125_codec_enable_hphr_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_hphl_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_hphr_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_ear_lo_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+
+ SND_SOC_DAPM_SUPPLY("HPHL_WDT_IRQ", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_hphl_wdt_irq,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("HPHR_WDT_IRQ", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_hphr_wdt_irq,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_rxclk,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
+
+ /* RX mixer widgets */
+ SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, ear_rdac_switch,
+ ARRAY_SIZE(ear_rdac_switch)),
+ SND_SOC_DAPM_MIXER("LO_RDAC", SND_SOC_NOPM, 0, 0, lo_rdac_switch,
+ ARRAY_SIZE(lo_rdac_switch)),
+ SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, hphl_rdac_switch,
+ ARRAY_SIZE(hphl_rdac_switch)),
+ SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, hphr_rdac_switch,
+ ARRAY_SIZE(hphr_rdac_switch)),
+
+ /* TX output widgets */
+ SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
+ SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
+
+ /* RX output widgets */
+ SND_SOC_DAPM_OUTPUT("EAR"),
+ SND_SOC_DAPM_OUTPUT("LO"),
+ SND_SOC_DAPM_OUTPUT("HPHL"),
+ SND_SOC_DAPM_OUTPUT("HPHR"),
+
+ /* MIC_BIAS pull up widgets */
+ SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
+ pm4125_codec_enable_micbias_pullup,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
+ pm4125_codec_enable_micbias_pullup,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
+ pm4125_codec_enable_micbias_pullup,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* TX widgets */
+ SND_SOC_DAPM_ADC_E("DMIC1", NULL, PM4125_DIG_SWR_CDC_DMIC1_CTL, 0, 0,
+ pm4125_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC2", NULL, PM4125_DIG_SWR_CDC_DMIC1_CTL, 1, 0,
+ pm4125_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* TX mixer widgets */
+ SND_SOC_DAPM_MIXER("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, dmic1_switch,
+ ARRAY_SIZE(dmic1_switch)),
+ SND_SOC_DAPM_MIXER("DMIC2_MIXER", SND_SOC_NOPM, 1, 0, dmic2_switch,
+ ARRAY_SIZE(dmic2_switch)),
+
+ /* Output widgets */
+ SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
+ SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route pm4125_audio_map[] = {
+ { "ADC1_OUTPUT", NULL, "ADC1_MIXER" },
+ { "ADC1_MIXER", "Switch", "ADC1" },
+ { "ADC1", NULL, "AMIC1" },
+
+ { "ADC2_OUTPUT", NULL, "ADC2_MIXER" },
+ { "ADC2_MIXER", "Switch", "ADC2" },
+ { "ADC2", NULL, "ADC2 MUX" },
+ { "ADC2 MUX", "INP3", "AMIC3" },
+ { "ADC2 MUX", "INP2", "AMIC2" },
+
+ { "IN1_HPHL", NULL, "PA_VPOS" },
+ { "RX1", NULL, "IN1_HPHL" },
+ { "RX1", NULL, "RXCLK" },
+ { "RX1", NULL, "HPHL_WDT_IRQ" },
+ { "RDAC1", NULL, "RX1" },
+ { "HPHL_RDAC", "Switch", "RDAC1" },
+ { "HPHL PGA", NULL, "HPHL_RDAC" },
+ { "HPHL", NULL, "HPHL PGA" },
+
+ { "IN2_HPHR", NULL, "PA_VPOS" },
+ { "RX2", NULL, "IN2_HPHR" },
+ { "RX2", NULL, "RXCLK" },
+ { "RX2", NULL, "HPHR_WDT_IRQ" },
+ { "RDAC2", NULL, "RX2" },
+ { "HPHR_RDAC", "Switch", "RDAC2" },
+ { "HPHR PGA", NULL, "HPHR_RDAC" },
+ { "HPHR", NULL, "HPHR PGA" },
+
+ { "RDAC3", NULL, "RX1" },
+ { "EAR_RDAC", "Switch", "RDAC3" },
+ { "EAR PGA", NULL, "EAR_RDAC" },
+ { "EAR", NULL, "EAR PGA" },
+
+ { "LO_RDAC", "Switch", "RDAC3" },
+ { "LO PGA", NULL, "LO_RDAC" },
+ { "LO", NULL, "LO PGA" },
+
+ { "DMIC1_OUTPUT", NULL, "DMIC1_MIXER" },
+ { "DMIC1_MIXER", "Switch", "DMIC1" },
+
+ { "DMIC2_OUTPUT", NULL, "DMIC2_MIXER" },
+ { "DMIC2_MIXER", "Switch", "DMIC2" },
+};
+
+static int pm4125_set_micbias_data(struct device *dev, struct pm4125_priv *pm4125)
+{
+ int vout_ctl;
+
+ /* Set micbias voltage */
+ vout_ctl = pm4125_get_micb_vout_ctl_val(dev, pm4125->micb1_mv);
+ if (vout_ctl < 0)
+ return -EINVAL;
+
+ regmap_update_bits(pm4125->regmap, PM4125_ANA_MICBIAS_LDO_1_SETTING,
+ PM4125_ANA_MICBIAS_MICB_OUT_VAL_MASK, vout_ctl << 3);
+ return 0;
+}
+
+static irqreturn_t pm4125_wd_handle_irq(int irq, void *data)
+{
+ /*
+ * HPHR/HPHL Watchdog interrupt threaded handler
+ * Watchdog interrupts are expected to be enabled when switching on the HPHL/R
+ * in order to make sure the interrupts are acked by the regmap_irq handler
+ * io allow PDM sync. We could leave those interrupts masked but we would
+ * not haveany valid way to enable/disable them without violating irq layers.
+ *
+ * The HPHR/HPHL Watchdog interrupts are handled by regmap_irq, so requesting
+ * a threaded handler is the safest way to be able to ack those interrupts
+ * without colliding with the regmap_irq setup.
+ */
+ return IRQ_HANDLED;
+}
+
+static const struct irq_chip pm4125_codec_irq_chip = {
+ .name = "pm4125_codec",
+};
+
+static int pm4125_codec_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(virq, &pm4125_codec_irq_chip, handle_simple_irq);
+ irq_set_nested_thread(virq, 1);
+ irq_set_noprobe(virq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops pm4125_domain_ops = {
+ .map = pm4125_codec_irq_chip_map,
+};
+
+static int pm4125_irq_init(struct pm4125_priv *pm4125, struct device *dev)
+{
+ pm4125->virq = irq_domain_add_linear(NULL, 1, &pm4125_domain_ops, NULL);
+ if (!(pm4125->virq)) {
+ dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
+ return -EINVAL;
+ }
+
+ pm4125_regmap_irq_chip.irq_drv_data = pm4125;
+
+ return devm_regmap_add_irq_chip(dev, pm4125->regmap, irq_create_mapping(pm4125->virq, 0),
+ IRQF_ONESHOT, 0, &pm4125_regmap_irq_chip,
+ &pm4125->irq_chip);
+}
+
+static int pm4125_soc_codec_probe(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+ struct sdw_slave *tx_sdw_dev = pm4125->tx_sdw_dev;
+ struct device *dev = component->dev;
+ unsigned long time_left;
+ int i, ret;
+
+ time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete,
+ msecs_to_jiffies(5000));
+ if (!time_left) {
+ dev_err(dev, "soundwire device init timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ snd_soc_component_init_regmap(component, pm4125->regmap);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ return ret;
+
+ pm4125_io_init(pm4125->regmap);
+
+ /* Set all interrupts as edge triggered */
+ for (i = 0; i < pm4125_regmap_irq_chip.num_regs; i++)
+ regmap_write(pm4125->regmap, (PM4125_DIG_SWR_INTR_LEVEL_0 + i), 0);
+
+ pm_runtime_put(dev);
+
+ pm4125->hphr_pdm_wd_int = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHR_PDM_WD_INT);
+ pm4125->hphl_pdm_wd_int = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHL_PDM_WD_INT);
+
+ /* Request for watchdog interrupts */
+ ret = devm_request_threaded_irq(dev, pm4125->hphr_pdm_wd_int, NULL, pm4125_wd_handle_irq,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ "HPHR PDM WDOG INT", pm4125);
+ if (ret)
+ dev_err(dev, "Failed to request HPHR wdt interrupt: %d\n", ret);
+
+ ret = devm_request_threaded_irq(dev, pm4125->hphl_pdm_wd_int, NULL, pm4125_wd_handle_irq,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ "HPHL PDM WDOG INT", pm4125);
+ if (ret)
+ dev_err(dev, "Failed to request HPHL wdt interrupt: %d\n", ret);
+
+ disable_irq_nosync(pm4125->hphr_pdm_wd_int);
+ disable_irq_nosync(pm4125->hphl_pdm_wd_int);
+
+ ret = pm4125_mbhc_init(component);
+ if (ret)
+ dev_err(component->dev, "mbhc initialization failed\n");
+
+ return ret;
+}
+
+static void pm4125_soc_codec_remove(struct snd_soc_component *component)
+{
+ struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component);
+
+ pm4125_mbhc_deinit(component);
+ free_irq(pm4125->hphl_pdm_wd_int, pm4125);
+ free_irq(pm4125->hphr_pdm_wd_int, pm4125);
+}
+
+static int pm4125_codec_set_jack(struct snd_soc_component *comp, struct snd_soc_jack *jack,
+ void *data)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(comp->dev);
+ int ret = 0;
+
+ if (jack)
+ ret = wcd_mbhc_start(pm4125->wcd_mbhc, &pm4125->mbhc_cfg, jack);
+ else
+ wcd_mbhc_stop(pm4125->wcd_mbhc);
+
+ return ret;
+}
+
+static const struct snd_soc_component_driver soc_codec_dev_pm4125 = {
+ .name = "pm4125_codec",
+ .probe = pm4125_soc_codec_probe,
+ .remove = pm4125_soc_codec_remove,
+ .controls = pm4125_snd_controls,
+ .num_controls = ARRAY_SIZE(pm4125_snd_controls),
+ .dapm_widgets = pm4125_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(pm4125_dapm_widgets),
+ .dapm_routes = pm4125_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(pm4125_audio_map),
+ .set_jack = pm4125_codec_set_jack,
+ .endianness = 1,
+};
+
+static void pm4125_dt_parse_micbias_info(struct device *dev, struct pm4125_priv *priv)
+{
+ struct device_node *np = dev->of_node;
+ u32 prop_val = 0;
+ int ret;
+
+ ret = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
+ if (!ret)
+ priv->micb1_mv = prop_val / 1000;
+ else
+ dev_warn(dev, "Micbias1 DT property not found\n");
+
+ ret = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
+ if (!ret)
+ priv->micb2_mv = prop_val / 1000;
+ else
+ dev_warn(dev, "Micbias2 DT property not found\n");
+
+ ret = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
+ if (!ret)
+ priv->micb3_mv = prop_val / 1000;
+ else
+ dev_warn(dev, "Micbias3 DT property not found\n");
+}
+
+static int pm4125_codec_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev);
+ struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id];
+
+ return pm4125_sdw_hw_params(sdw_priv, substream, params, dai);
+}
+
+static int pm4125_codec_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev);
+ struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id];
+
+ return sdw_stream_remove_slave(sdw_priv->sdev, sdw_priv->sruntime);
+}
+
+static int pm4125_codec_set_sdw_stream(struct snd_soc_dai *dai, void *stream, int direction)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev);
+ struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id];
+
+ sdw_priv->sruntime = stream;
+
+ return 0;
+}
+
+static int pm4125_get_channel_map(const struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev);
+ struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id];
+ int i;
+
+ switch (dai->id) {
+ case AIF1_PB:
+ if (!rx_slot || !rx_num) {
+ dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n", rx_slot, rx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ rx_slot[i] = sdw_priv->master_channel_map[i];
+
+ *rx_num = i;
+ break;
+ case AIF1_CAP:
+ if (!tx_slot || !tx_num) {
+ dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n", tx_slot, tx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ tx_slot[i] = sdw_priv->master_channel_map[i];
+
+ *tx_num = i;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops pm4125_sdw_dai_ops = {
+ .hw_params = pm4125_codec_hw_params,
+ .hw_free = pm4125_codec_free,
+ .set_stream = pm4125_codec_set_sdw_stream,
+ .get_channel_map = pm4125_get_channel_map,
+};
+
+static struct snd_soc_dai_driver pm4125_dais[] = {
+ [0] = {
+ .name = "pm4125-sdw-rx",
+ .playback = {
+ .stream_name = "PM4125 AIF Playback",
+ .rates = PM4125_RATES | PM4125_FRAC_RATES,
+ .formats = PM4125_FORMATS,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &pm4125_sdw_dai_ops,
+ },
+ [1] = {
+ .name = "pm4125-sdw-tx",
+ .capture = {
+ .stream_name = "PM4125 AIF Capture",
+ .rates = PM4125_RATES,
+ .formats = PM4125_FORMATS,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &pm4125_sdw_dai_ops,
+ },
+};
+
+static int pm4125_bind(struct device *dev)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dev);
+ struct device_link *devlink;
+ int ret;
+
+ /* Give the soundwire subdevices some more time to settle */
+ usleep_range(15000, 15010);
+
+ ret = component_bind_all(dev, pm4125);
+ if (ret) {
+ dev_err(dev, "Slave bind failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ pm4125->rxdev = pm4125_sdw_device_get(pm4125->rxnode);
+ if (!pm4125->rxdev) {
+ dev_err(dev, "could not find rxslave with matching of node\n");
+ ret = -EINVAL;
+ goto error_unbind_all;
+ }
+
+ pm4125->sdw_priv[AIF1_PB] = dev_get_drvdata(pm4125->rxdev);
+ pm4125->sdw_priv[AIF1_PB]->pm4125 = pm4125;
+
+ pm4125->txdev = pm4125_sdw_device_get(pm4125->txnode);
+ if (!pm4125->txdev) {
+ dev_err(dev, "could not find txslave with matching of node\n");
+ ret = -EINVAL;
+ goto error_unbind_all;
+ }
+
+ pm4125->sdw_priv[AIF1_CAP] = dev_get_drvdata(pm4125->txdev);
+ pm4125->sdw_priv[AIF1_CAP]->pm4125 = pm4125;
+
+ pm4125->tx_sdw_dev = dev_to_sdw_dev(pm4125->txdev);
+ if (!pm4125->tx_sdw_dev) {
+ dev_err(dev, "could not get txslave with matching of dev\n");
+ ret = -EINVAL;
+ goto error_unbind_all;
+ }
+
+ /*
+ * As TX is the main CSR reg interface, which should not be suspended first.
+ * expicilty add the dependency link
+ */
+ devlink = device_link_add(pm4125->rxdev, pm4125->txdev,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+ if (!devlink) {
+ dev_err(dev, "Could not devlink TX and RX\n");
+ ret = -EINVAL;
+ goto error_unbind_all;
+ }
+
+ devlink = device_link_add(dev, pm4125->txdev,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+ if (!devlink) {
+ dev_err(dev, "Could not devlink PM4125 and TX\n");
+ ret = -EINVAL;
+ goto link_remove_rx_tx;
+ }
+
+ devlink = device_link_add(dev, pm4125->rxdev,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+ if (!devlink) {
+ dev_err(dev, "Could not devlink PM4125 and RX\n");
+ ret = -EINVAL;
+ goto link_remove_dev_tx;
+ }
+
+ pm4125->regmap = dev_get_regmap(&pm4125->tx_sdw_dev->dev, NULL);
+ if (!pm4125->regmap) {
+ dev_err(dev, "could not get TX device regmap\n");
+ ret = -EINVAL;
+ goto link_remove_dev_rx;
+ }
+
+ ret = pm4125_irq_init(pm4125, dev);
+ if (ret) {
+ dev_err(dev, "IRQ init failed: %d\n", ret);
+ goto link_remove_dev_rx;
+ }
+
+ pm4125->sdw_priv[AIF1_PB]->slave_irq = pm4125->virq;
+ pm4125->sdw_priv[AIF1_CAP]->slave_irq = pm4125->virq;
+
+ ret = pm4125_set_micbias_data(dev, pm4125);
+ if (ret < 0) {
+ dev_err(dev, "Bad micbias pdata\n");
+ goto link_remove_dev_rx;
+ }
+
+ ret = snd_soc_register_component(dev, &soc_codec_dev_pm4125,
+ pm4125_dais, ARRAY_SIZE(pm4125_dais));
+ if (!ret)
+ return ret;
+
+ dev_err(dev, "Codec registration failed\n");
+
+link_remove_dev_rx:
+ device_link_remove(dev, pm4125->rxdev);
+link_remove_dev_tx:
+ device_link_remove(dev, pm4125->txdev);
+link_remove_rx_tx:
+ device_link_remove(pm4125->rxdev, pm4125->txdev);
+error_unbind_all:
+ component_unbind_all(dev, pm4125);
+ return ret;
+}
+
+static void pm4125_unbind(struct device *dev)
+{
+ struct pm4125_priv *pm4125 = dev_get_drvdata(dev);
+
+ snd_soc_unregister_component(dev);
+ device_link_remove(dev, pm4125->txdev);
+ device_link_remove(dev, pm4125->rxdev);
+ device_link_remove(pm4125->rxdev, pm4125->txdev);
+ component_unbind_all(dev, pm4125);
+}
+
+static const struct component_master_ops pm4125_comp_ops = {
+ .bind = pm4125_bind,
+ .unbind = pm4125_unbind,
+};
+
+static int pm4125_add_slave_components(struct pm4125_priv *pm4125, struct device *dev,
+ struct component_match **matchptr)
+{
+ struct device_node *np = dev->of_node;
+
+ pm4125->rxnode = of_parse_phandle(np, "qcom,rx-device", 0);
+ if (!pm4125->rxnode)
+ return dev_err_probe(dev, -ENODEV, "Couldn't parse phandle to qcom,rx-device\n");
+ component_match_add_release(dev, matchptr, component_release_of, component_compare_of,
+ pm4125->rxnode);
+
+ pm4125->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
+ if (!pm4125->txnode)
+ return dev_err_probe(dev, -ENODEV, "Couldn't parse phandle to qcom,tx-device\n");
+ component_match_add_release(dev, matchptr, component_release_of, component_compare_of,
+ pm4125->txnode);
+
+ return 0;
+}
+
+static int pm4125_probe(struct platform_device *pdev)
+{
+ struct component_match *match = NULL;
+ struct device *dev = &pdev->dev;
+ struct pm4125_priv *pm4125;
+ struct wcd_mbhc_config *cfg;
+ int ret;
+
+ pm4125 = devm_kzalloc(dev, sizeof(*pm4125), GFP_KERNEL);
+ if (!pm4125)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, pm4125);
+
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(pm4125_power_supplies),
+ pm4125_power_supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
+
+ pm4125->spmi_regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!pm4125->spmi_regmap)
+ return -ENXIO;
+
+ pm4125_reset(pm4125);
+
+ pm4125_dt_parse_micbias_info(dev, pm4125);
+ atomic_set(&pm4125->gloal_mbias_cnt, 0);
+
+ cfg = &pm4125->mbhc_cfg;
+ cfg->mbhc_micbias = MIC_BIAS_2;
+ cfg->anc_micbias = MIC_BIAS_2;
+ cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
+ cfg->num_btn = PM4125_MBHC_MAX_BUTTONS;
+ cfg->micb_mv = pm4125->micb2_mv;
+ cfg->linein_th = 5000;
+ cfg->hs_thr = 1700;
+ cfg->hph_thr = 50;
+
+ wcd_dt_parse_mbhc_data(dev, &pm4125->mbhc_cfg);
+
+ ret = pm4125_add_slave_components(pm4125, dev, &match);
+ if (ret)
+ return ret;
+
+ ret = component_master_add_with_match(dev, &pm4125_comp_ops, match);
+ if (ret)
+ return ret;
+
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+ return 0;
+}
+
+static void pm4125_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ component_master_del(&pdev->dev, &pm4125_comp_ops);
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+}
+
+static const struct of_device_id pm4125_of_match[] = {
+ { .compatible = "qcom,pm4125-codec" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pm4125_of_match);
+
+static struct platform_driver pm4125_codec_driver = {
+ .probe = pm4125_probe,
+ .remove = pm4125_remove,
+ .driver = {
+ .name = "pm4125_codec",
+ .of_match_table = pm4125_of_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+module_platform_driver(pm4125_codec_driver);
+MODULE_DESCRIPTION("PM4125 audio codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pm4125.h b/sound/soc/codecs/pm4125.h
new file mode 100644
index 000000000000..3520c711b744
--- /dev/null
+++ b/sound/soc/codecs/pm4125.h
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _PM4125_REGISTERS_H
+#define _PM4125_REGISTERS_H
+
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+
+#define PM4125_ANA_BASE_ADDR 0x3000
+#define PM4125_DIG_BASE_ADDR 0x3400
+
+#define PM4125_ANA_MICBIAS_MICB_1_2_EN (PM4125_ANA_BASE_ADDR+0x040)
+#define PM4125_ANA_MICBIAS_MICB1_PULL_UP_MASK BIT(5)
+#define PM4125_ANA_MICBIAS_MICB2_PULL_UP_MASK BIT(1)
+#define PM4125_ANA_MICBIAS_MICB2_PULL_DN_MASK BIT(0)
+#define PM4125_ANA_MICBIAS_MICB_PULL_ENABLE 1
+#define PM4125_ANA_MICBIAS_MICB_PULL_DISABLE 0
+#define PM4125_ANA_MICBIAS_MICB_3_EN (PM4125_ANA_BASE_ADDR+0x041)
+#define PM4125_ANA_MICBIAS_LDO_1_SETTING (PM4125_ANA_BASE_ADDR+0x042)
+#define PM4125_ANA_MICBIAS_MICB_OUT_VAL_MASK GENMASK(7, 3)
+#define PM4125_ANA_MICBIAS_LDO_1_CTRL (PM4125_ANA_BASE_ADDR+0x043)
+#define PM4125_ANA_TX_AMIC1 (PM4125_ANA_BASE_ADDR+0x047)
+#define PM4125_ANA_TX_AMIC2 (PM4125_ANA_BASE_ADDR+0x048)
+#define PM4125_ANA_MBHC_MECH (PM4125_ANA_BASE_ADDR+0x05A)
+#define PM4125_ANA_MBHC_ELECT (PM4125_ANA_BASE_ADDR+0x05B)
+#define PM4125_ANA_MBHC_ELECT_BIAS_EN_MASK BIT(0)
+#define PM4125_ANA_MBHC_ELECT_BIAS_ENABLE 1
+#define PM4125_ANA_MBHC_ELECT_BIAS_DISABLE 0
+#define PM4125_ANA_MBHC_ZDET (PM4125_ANA_BASE_ADDR+0x05C)
+#define PM4125_ANA_MBHC_RESULT_1 (PM4125_ANA_BASE_ADDR+0x05D)
+#define PM4125_ANA_MBHC_RESULT_2 (PM4125_ANA_BASE_ADDR+0x05E)
+#define PM4125_ANA_MBHC_RESULT_3 (PM4125_ANA_BASE_ADDR+0x05F)
+#define PM4125_ANA_MBHC_BTN0_ZDET_VREF1 (PM4125_ANA_BASE_ADDR+0x060)
+#define PM4125_ANA_MBHC_BTN0_THRESHOLD_MASK GENMASK(7, 2)
+#define PM4125_ANA_MBHC_BTN1_ZDET_VREF2 (PM4125_ANA_BASE_ADDR+0x061)
+#define PM4125_ANA_MBHC_BTN2_ZDET_VREF3 (PM4125_ANA_BASE_ADDR+0x062)
+#define PM4125_ANA_MBHC_BTN3_ZDET_DBG_400 (PM4125_ANA_BASE_ADDR+0x063)
+#define PM4125_ANA_MBHC_BTN4_ZDET_DBG_1400 (PM4125_ANA_BASE_ADDR+0x064)
+#define PM4125_ANA_MBHC_MICB2_RAMP (PM4125_ANA_BASE_ADDR+0x065)
+#define PM4125_ANA_MBHC_CTL_1 (PM4125_ANA_BASE_ADDR+0x066)
+#define PM4125_ANA_MBHC_CTL_2 (PM4125_ANA_BASE_ADDR+0x067)
+#define PM4125_ANA_MBHC_PLUG_DETECT_CTL (PM4125_ANA_BASE_ADDR+0x068)
+#define PM4125_ANA_MBHC_ZDET_ANA_CTL (PM4125_ANA_BASE_ADDR+0x069)
+#define PM4125_ANA_MBHC_ZDET_RAMP_CTL (PM4125_ANA_BASE_ADDR+0x06A)
+#define PM4125_ANA_MBHC_FSM_STATUS (PM4125_ANA_BASE_ADDR+0x06B)
+#define PM4125_ANA_MBHC_ADC_RESULT (PM4125_ANA_BASE_ADDR+0x06C)
+#define PM4125_ANA_MBHC_CTL_CLK (PM4125_ANA_BASE_ADDR+0x06D)
+#define PM4125_ANA_MBHC_ZDET_CALIB_RESULT (PM4125_ANA_BASE_ADDR+0x072)
+#define PM4125_ANA_NCP_EN (PM4125_ANA_BASE_ADDR+0x077)
+#define PM4125_ANA_NCP_ENABLE_MASK BIT(0)
+#define PM4125_ANA_NCP_ENABLE 1
+#define PM4125_ANA_NCP_DISABLE 0
+#define PM4125_ANA_NCP_VCTRL (PM4125_ANA_BASE_ADDR+0x07C)
+#define PM4125_ANA_HPHPA_CNP_CTL_1 (PM4125_ANA_BASE_ADDR+0x083)
+#define PM4125_ANA_HPHPA_CNP_CTL_1_EN_MASK BIT(1)
+#define PM4125_ANA_HPHPA_CNP_CTL_1_EN 1
+#define PM4125_ANA_HPHPA_CNP_CTL_2 (PM4125_ANA_BASE_ADDR+0x084)
+#define PM4125_ANA_HPHPA_CNP_OCP_EN_L_MASK BIT(1)
+#define PM4125_ANA_HPHPA_CNP_OCP_EN_R_MASK BIT(0)
+#define PM4125_ANA_HPHPA_CNP_OCP_ENABLE 1
+#define PM4125_ANA_HPHPA_CNP_OCP_DISABLE 0
+#define PM4125_ANA_HPHPA_PA_STATUS (PM4125_ANA_BASE_ADDR+0x087)
+#define PM4125_ANA_HPHPA_FSM_CLK (PM4125_ANA_BASE_ADDR+0x088)
+#define PM4125_ANA_HPHPA_FSM_CLK_DIV_EN_MASK BIT(7)
+#define PM4125_ANA_HPHPA_FSM_CLK_DIV_ENABLE 1
+#define PM4125_ANA_HPHPA_FSM_CLK_DIV_DISABLE 0
+#define PM4125_ANA_HPHPA_FSM_DIV_RATIO_MASK GENMASK(6, 0)
+#define PM4125_ANA_HPHPA_FSM_DIV_RATIO_68 (0x11)
+#define PM4125_ANA_HPHPA_L_GAIN (PM4125_ANA_BASE_ADDR+0x08B)
+#define PM4125_ANA_HPHPA_R_GAIN (PM4125_ANA_BASE_ADDR+0x08C)
+#define PM4125_ANA_HPHPA_SPARE_CTL (PM4125_ANA_BASE_ADDR+0x08E)
+#define PM4125_SWR_HPHPA_HD2 (PM4125_ANA_BASE_ADDR+0x090)
+#define PM4125_SWR_HPHPA_HD2_LEFT_MASK GENMASK(5, 3)
+#define PM4125_SWR_HPHPA_HD2_RIGHT_MASK GENMASK(2, 0)
+#define PM4125_SWR_HPHPA_HD2_ENABLE (BIT(2) | BIT(1) | BIT(0))
+#define PM4125_ANA_SURGE_EN (PM4125_ANA_BASE_ADDR+0x097)
+#define PM4125_ANA_SURGE_PROTECTION_HPHL_MASK BIT(7)
+#define PM4125_ANA_SURGE_PROTECTION_HPHR_MASK BIT(6)
+#define PM4125_ANA_SURGE_PROTECTION_ENABLE 1
+#define PM4125_ANA_SURGE_PROTECTION_DISABLE 0
+#define PM4125_ANA_COMBOPA_CTL (PM4125_ANA_BASE_ADDR+0x09B)
+#define PM4125_ANA_COMBO_PA_SELECT_MASK BIT(6)
+#define PM4125_ANA_COMBO_PA_SELECT_EAR 0
+#define PM4125_ANA_COMBO_PA_SELECT_LO 1
+#define PM4125_ANA_COMBOPA_CTL_4 (PM4125_ANA_BASE_ADDR+0x09F)
+#define PM4125_ANA_COMBOPA_CTL_5 (PM4125_ANA_BASE_ADDR+0x0A0)
+#define PM4125_ANA_RXLDO_CTL (PM4125_ANA_BASE_ADDR+0x0B2)
+#define PM4125_ANA_MBIAS_EN (PM4125_ANA_BASE_ADDR+0x0B4)
+#define PM4125_ANA_MBIAS_EN_GLOBAL_MASK BIT(5)
+#define PM4125_ANA_MBIAS_EN_V2I_MASK BIT(4)
+#define PM4125_ANA_MBIAS_EN_ENABLE 1
+#define PM4125_ANA_MBIAS_EN_DISABLE 0
+
+#define PM4125_DIG_SWR_CHIP_ID0 (PM4125_DIG_BASE_ADDR+0x001)
+#define PM4125_DIG_SWR_CHIP_ID1 (PM4125_DIG_BASE_ADDR+0x002)
+#define PM4125_DIG_SWR_CHIP_ID2 (PM4125_DIG_BASE_ADDR+0x003)
+#define PM4125_DIG_SWR_CHIP_ID3 (PM4125_DIG_BASE_ADDR+0x004)
+#define PM4125_DIG_SWR_SWR_TX_CLK_RATE (PM4125_DIG_BASE_ADDR+0x040)
+#define PM4125_DIG_SWR_CDC_RST_CTL (PM4125_DIG_BASE_ADDR+0x041)
+#define PM4125_DIG_SWR_TOP_CLK_CFG (PM4125_DIG_BASE_ADDR+0x042)
+#define PM4125_DIG_SWR_CDC_RX_CLK_CTL (PM4125_DIG_BASE_ADDR+0x043)
+#define PM4125_DIG_SWR_ANA_RX_DIV2_CLK_EN_MASK BIT(5)
+#define PM4125_DIG_SWR_ANA_RX_CLK_EN_MASK BIT(4)
+#define PM4125_DIG_SWR_RX1_CLK_EN_MASK BIT(1)
+#define PM4125_DIG_SWR_RX0_CLK_EN_MASK BIT(0)
+#define PM4125_DIG_SWR_RX_CLK_ENABLE 1
+#define PM4125_DIG_SWR_RX_CLK_DISABLE 0
+#define PM4125_DIG_SWR_CDC_TX_CLK_CTL (PM4125_DIG_BASE_ADDR+0x044)
+#define PM4125_DIG_SWR_SWR_RST_EN (PM4125_DIG_BASE_ADDR+0x045)
+#define PM4125_DIG_SWR_CDC_RX_RST (PM4125_DIG_BASE_ADDR+0x047)
+#define PM4125_DIG_SWR_CDC_RX0_CTL (PM4125_DIG_BASE_ADDR+0x048)
+#define PM4125_DIG_SWR_DSM_DITHER_EN_MASK BIT(7)
+#define PM4125_DIG_SWR_DSM_DITHER_DISABLE 0
+#define PM4125_DIG_SWR_DSM_DITHER_ENABLE 1
+#define PM4125_DIG_SWR_CDC_RX1_CTL (PM4125_DIG_BASE_ADDR+0x049)
+#define PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1 (PM4125_DIG_BASE_ADDR+0x04B)
+#define PM4125_DIG_SWR_TX_ANA_TXD1_MODE_MASK GENMASK(7, 4)
+#define PM4125_DIG_SWR_TX_ANA_TXD0_MODE_MASK GENMASK(3, 0)
+#define PM4125_DIG_SWR_TXD_MODE_ULPI (0x9)
+#define PM4125_DIG_SWR_TXD_MODE_NORMAL (0x3)
+#define PM4125_DIG_SWR_CDC_COMP_CTL_0 (PM4125_DIG_BASE_ADDR+0x04F)
+#define PM4125_DIG_SWR_COMP_HPHL_EN_MASK BIT(1)
+#define PM4125_DIG_SWR_COMP_HPHR_EN_MASK BIT(0)
+#define PM4125_DIG_SWR_COMP_ENABLE 1
+#define PM4125_DIG_SWR_COMP_DISABLE 0
+#define PM4125_DIG_SWR_CDC_RX_DELAY_CTL (PM4125_DIG_BASE_ADDR+0x052)
+#define PM4125_DIG_SWR_CDC_RX_GAIN_0 (PM4125_DIG_BASE_ADDR+0x053)
+#define PM4125_DIG_SWR_CDC_RX_GAIN_1 (PM4125_DIG_BASE_ADDR+0x054)
+#define PM4125_DIG_SWR_CDC_RX_GAIN_CTL (PM4125_DIG_BASE_ADDR+0x057)
+#define PM4125_DIG_SWR_RX1_EN_MASK BIT(3)
+#define PM4125_DIG_SWR_RX0_EN_MASK BIT(2)
+#define PM4125_DIG_SWR_RX_INPUT_DISABLE 0
+#define PM4125_DIG_SWR_RX_INPUT_ENABLE 1
+#define PM4125_DIG_SWR_CDC_TX0_CTL (PM4125_DIG_BASE_ADDR+0x060)
+#define PM4125_DIG_SWR_CDC_TX1_CTL (PM4125_DIG_BASE_ADDR+0x061)
+#define PM4125_DIG_SWR_CDC_TX_RST (PM4125_DIG_BASE_ADDR+0x063)
+#define PM4125_DIG_SWR_CDC_REQ0_CTL (PM4125_DIG_BASE_ADDR+0x064)
+#define PM4125_DIG_SWR_CDC_REQ1_CTL (PM4125_DIG_BASE_ADDR+0x065)
+#define PM4125_DIG_SWR_CDC_RST (PM4125_DIG_BASE_ADDR+0x067)
+#define PM4125_DIG_SWR_CDC_AMIC_CTL (PM4125_DIG_BASE_ADDR+0x06A)
+#define PM4125_DIG_SWR_AMIC_SELECT_MASK BIT(1)
+#define PM4125_DIG_SWR_AMIC_SELECT_DMIC1 0
+#define PM4125_DIG_SWR_AMIC_SELECT_AMIC3 1
+#define PM4125_DIG_SWR_CDC_DMIC_CTL (PM4125_DIG_BASE_ADDR+0x06B)
+#define PM4125_DIG_SWR_CDC_DMIC1_CTL (PM4125_DIG_BASE_ADDR+0x06C)
+#define PM4125_DIG_SWR_DMIC1_CLK_EN_MASK BIT(3)
+#define PM4125_DIG_SWR_DMIC1_CLK_ENABLE 1
+#define PM4125_DIG_SWR_DMIC1_CLK_DISABLE 0
+#define PM4125_DIG_SWR_CDC_DMIC1_RATE (PM4125_DIG_BASE_ADDR+0x06D)
+#define PM4125_DIG_SWR_PDM_WD_CTL0 (PM4125_DIG_BASE_ADDR+0x070)
+#define PM4125_WDT_ENABLE_MASK GENMASK(1, 0)
+#define PM4125_WDT_ENABLE_RX0_L BIT(0)
+#define PM4125_WDT_ENABLE_RX0_M BIT(1)
+#define PM4125_DIG_SWR_PDM_WD_CTL1 (PM4125_DIG_BASE_ADDR+0x071)
+#define PM4125_WDT_ENABLE_RX1_L BIT(0)
+#define PM4125_WDT_ENABLE_RX1_M BIT(1)
+#define PM4125_DIG_SWR_INTR_MODE (PM4125_DIG_BASE_ADDR+0x080)
+#define PM4125_DIG_SWR_INTR_MASK_0 (PM4125_DIG_BASE_ADDR+0x081)
+#define PM4125_DIG_SWR_INTR_MASK_1 (PM4125_DIG_BASE_ADDR+0x082)
+#define PM4125_DIG_SWR_INTR_MASK_2 (PM4125_DIG_BASE_ADDR+0x083)
+#define PM4125_DIG_SWR_INTR_STATUS_0 (PM4125_DIG_BASE_ADDR+0x084)
+#define PM4125_DIG_SWR_INTR_STATUS_1 (PM4125_DIG_BASE_ADDR+0x085)
+#define PM4125_DIG_SWR_INTR_STATUS_2 (PM4125_DIG_BASE_ADDR+0x086)
+#define PM4125_DIG_SWR_INTR_CLEAR_0 (PM4125_DIG_BASE_ADDR+0x087)
+#define PM4125_DIG_SWR_INTR_CLEAR_1 (PM4125_DIG_BASE_ADDR+0x088)
+#define PM4125_DIG_SWR_INTR_CLEAR_2 (PM4125_DIG_BASE_ADDR+0x089)
+#define PM4125_DIG_SWR_INTR_LEVEL_0 (PM4125_DIG_BASE_ADDR+0x08A)
+#define PM4125_DIG_SWR_INTR_LEVEL_1 (PM4125_DIG_BASE_ADDR+0x08B)
+#define PM4125_DIG_SWR_INTR_LEVEL_2 (PM4125_DIG_BASE_ADDR+0x08C)
+#define PM4125_DIG_SWR_CDC_CONN_RX0_CTL (PM4125_DIG_BASE_ADDR+0x093)
+#define PM4125_DIG_SWR_CDC_CONN_RX1_CTL (PM4125_DIG_BASE_ADDR+0x094)
+#define PM4125_DIG_SWR_LOOP_BACK_MODE (PM4125_DIG_BASE_ADDR+0x097)
+#define PM4125_DIG_SWR_DRIVE_STRENGTH_0 (PM4125_DIG_BASE_ADDR+0x0A0)
+#define PM4125_DIG_SWR_DIG_DEBUG_CTL (PM4125_DIG_BASE_ADDR+0x0AB)
+#define PM4125_DIG_SWR_DIG_DEBUG_EN (PM4125_DIG_BASE_ADDR+0x0AC)
+#define PM4125_DIG_SWR_DEM_BYPASS_DATA0 (PM4125_DIG_BASE_ADDR+0x0B0)
+#define PM4125_DIG_SWR_DEM_BYPASS_DATA1 (PM4125_DIG_BASE_ADDR+0x0B1)
+#define PM4125_DIG_SWR_DEM_BYPASS_DATA2 (PM4125_DIG_BASE_ADDR+0x0B2)
+#define PM4125_DIG_SWR_DEM_BYPASS_DATA3 (PM4125_DIG_BASE_ADDR+0x0B3)
+
+#define PM4125_ANALOG_REGISTERS_MAX_SIZE (PM4125_ANA_BASE_ADDR+0x0B5)
+#define PM4125_DIGITAL_REGISTERS_MAX_SIZE (PM4125_DIG_BASE_ADDR+0x0B4)
+#define PM4125_ANALOG_MAX_REGISTER (PM4125_ANALOG_REGISTERS_MAX_SIZE - 1)
+#define PM4125_DIGITAL_MAX_REGISTER (PM4125_DIGITAL_REGISTERS_MAX_SIZE - 1)
+#define PM4125_MAX_REGISTER PM4125_DIGITAL_MAX_REGISTER
+
+#define PM4125_MAX_MICBIAS 3
+#define PM4125_MAX_SWR_CH_IDS 15
+#define PM4125_SWRM_CH_MASK(ch_idx) BIT(ch_idx - 1)
+
+enum pm4125_tx_sdw_ports {
+ PM4125_ADC_1_2_DMIC1L_BCS_PORT = 1,
+ PM4125_DMIC_1L_1R_ADC1_BCS_PORT,
+ PM4125_MAX_TX_SWR_PORTS = PM4125_DMIC_1L_1R_ADC1_BCS_PORT,
+};
+
+enum pm4125_rx_sdw_ports {
+ PM4125_HPH_PORT = 1,
+ PM4125_COMP_PORT,
+ PM4125_MAX_SWR_PORTS = PM4125_COMP_PORT,
+};
+
+struct pm4125_sdw_ch_info {
+ int port_num;
+ unsigned int ch_mask;
+ unsigned int master_ch_mask;
+};
+
+#define WCD_SDW_CH(id, pn, cmask) \
+ [id] = { \
+ .port_num = pn, \
+ .ch_mask = cmask, \
+ .master_ch_mask = cmask, \
+ }
+
+struct pm4125_priv;
+struct pm4125_sdw_priv {
+ struct sdw_slave *sdev;
+ struct sdw_stream_config sconfig;
+ struct sdw_stream_runtime *sruntime;
+ struct sdw_port_config port_config[PM4125_MAX_SWR_PORTS];
+ struct pm4125_sdw_ch_info *ch_info;
+ bool port_enable[PM4125_MAX_SWR_CH_IDS];
+ unsigned int master_channel_map[SDW_MAX_PORTS];
+ int active_ports;
+ int num_ports;
+ bool is_tx;
+ struct pm4125_priv *pm4125;
+ struct irq_domain *slave_irq;
+ struct regmap *regmap;
+};
+
+#if IS_ENABLED(CONFIG_SND_SOC_PM4125_SDW)
+int pm4125_sdw_free(struct pm4125_sdw_priv *pm4125, struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+int pm4125_sdw_set_sdw_stream(struct pm4125_sdw_priv *pm4125, struct snd_soc_dai *dai, void *stream,
+ int direction);
+int pm4125_sdw_hw_params(struct pm4125_sdw_priv *pm4125, struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
+
+struct device *pm4125_sdw_device_get(struct device_node *np);
+
+#else
+static inline int pm4125_sdw_free(struct pm4125_sdw_priv *pm4125,
+ struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int pm4125_sdw_set_sdw_stream(struct pm4125_sdw_priv *pm4125,
+ struct snd_soc_dai *dai, void *stream, int direction)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int pm4125_sdw_hw_params(struct pm4125_sdw_priv *pm4125,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
+enum {
+ /* INTR_CTRL_INT_MASK_0 */
+ PM4125_IRQ_MBHC_BUTTON_PRESS_DET = 0,
+ PM4125_IRQ_MBHC_BUTTON_RELEASE_DET,
+ PM4125_IRQ_MBHC_ELECT_INS_REM_DET,
+ PM4125_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
+ PM4125_IRQ_MBHC_SW_DET,
+ PM4125_IRQ_HPHR_OCP_INT,
+ PM4125_IRQ_HPHR_CNP_INT,
+ PM4125_IRQ_HPHL_OCP_INT,
+
+ /* INTR_CTRL_INT_MASK_1 */
+ PM4125_IRQ_HPHL_CNP_INT,
+ PM4125_IRQ_EAR_CNP_INT,
+ PM4125_IRQ_EAR_SCD_INT,
+ PM4125_IRQ_AUX_CNP_INT,
+ PM4125_IRQ_AUX_SCD_INT,
+ PM4125_IRQ_HPHL_PDM_WD_INT,
+ PM4125_IRQ_HPHR_PDM_WD_INT,
+ PM4125_IRQ_AUX_PDM_WD_INT,
+
+ /* INTR_CTRL_INT_MASK_2 */
+ PM4125_IRQ_LDORT_SCD_INT,
+ PM4125_IRQ_MBHC_MOISTURE_INT,
+ PM4125_IRQ_HPHL_SURGE_DET_INT,
+ PM4125_IRQ_HPHR_SURGE_DET_INT,
+ PM4125_NUM_IRQS,
+};
+
+enum pm4125_tx_sdw_channels {
+ PM4125_ADC1,
+ PM4125_ADC2,
+};
+
+enum pm4125_rx_sdw_channels {
+ PM4125_HPH_L,
+ PM4125_HPH_R,
+ PM4125_COMP_L,
+ PM4125_COMP_R,
+};
+
+#endif /* _PM4125_REGISTERS_H */
diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c
index dcddc28e8856..e3f9b03df3aa 100644
--- a/sound/soc/codecs/rt1320-sdw.c
+++ b/sound/soc/codecs/rt1320-sdw.c
@@ -256,6 +256,161 @@ static const struct reg_sequence rt1320_vc_blind_write[] = {
{ SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 },
};
+static const struct reg_sequence rt1321_blind_write[] = {
+ { 0x0000c003, 0xf0 },
+ { 0x0000c01b, 0xfc },
+ { 0x0000c5c3, 0xf2 },
+ { 0x0000c5c2, 0x00 },
+ { 0x0000c5c1, 0x10 },
+ { 0x0000c5c0, 0x04 },
+ { 0x0000c5c7, 0x03 },
+ { 0x0000c5c6, 0x10 },
+ { 0x0000c526, 0x47 },
+ { 0x0000c5c4, 0x12 },
+ { 0x0000c5c5, 0x60 },
+ { 0x0000c520, 0x10 },
+ { 0x0000c521, 0x32 },
+ { 0x0000c5c7, 0x00 },
+ { 0x0000c5c8, 0x03 },
+ { 0x0000c5d3, 0x08 },
+ { 0x0000c5d2, 0x0a },
+ { 0x0000c5d1, 0x49 },
+ { 0x0000c5d0, 0x0f },
+ { 0x0000c580, 0x10 },
+ { 0x0000c581, 0x32 },
+ { 0x0000c582, 0x01 },
+ { 0x0000cb00, 0x03 },
+ { 0x0000cb02, 0x52 },
+ { 0x0000cb04, 0x80 },
+ { 0x0000cb0b, 0x01 },
+ { 0x0000c682, 0x60 },
+ { 0x0000c019, 0x10 },
+ { 0x0000c5f0, 0x01 },
+ { 0x0000c5f7, 0x22 },
+ { 0x0000c5f6, 0x22 },
+ { 0x0000c057, 0x51 },
+ { 0x0000c054, 0x55 },
+ { 0x0000c053, 0x55 },
+ { 0x0000c052, 0x55 },
+ { 0x0000c051, 0x01 },
+ { 0x0000c050, 0x15 },
+ { 0x0000c060, 0x99 },
+ { 0x0000c030, 0x55 },
+ { 0x0000c061, 0x55 },
+ { 0x0000c063, 0x55 },
+ { 0x0000c065, 0xa5 },
+ { 0x0000c06b, 0x0a },
+ { 0x0000ca05, 0xd6 },
+ { 0x0000ca07, 0x07 },
+ { 0x0000ca25, 0xd6 },
+ { 0x0000ca27, 0x07 },
+ { 0x0000cd00, 0x05 },
+ { 0x0000c604, 0x40 },
+ { 0x0000c609, 0x40 },
+ { 0x0000c046, 0xf7 },
+ { 0x0000c045, 0xff },
+ { 0x0000c044, 0xff },
+ { 0x0000c043, 0xff },
+ { 0x0000c042, 0xff },
+ { 0x0000c041, 0xff },
+ { 0x0000c040, 0xff },
+ { 0x0000c049, 0xff },
+ { 0x0000c028, 0x3f },
+ { 0x0000c020, 0x3f },
+ { 0x0000c032, 0x13 },
+ { 0x0000c033, 0x01 },
+ { 0x0000cc10, 0x01 },
+ { 0x0000dc20, 0x03 },
+ { 0x0000de03, 0x05 },
+ { 0x0000dc00, 0x00 },
+ { 0x0000c700, 0xf0 },
+ { 0x0000c701, 0x13 },
+ { 0x0000c900, 0xc3 },
+ { 0x0000c570, 0x08 },
+ { 0x0000c086, 0x02 },
+ { 0x0000c085, 0x7f },
+ { 0x0000c084, 0x00 },
+ { 0x0000c081, 0xff },
+ { 0x0000f084, 0x0f },
+ { 0x0000f083, 0xff },
+ { 0x0000f082, 0xff },
+ { 0x0000f081, 0xff },
+ { 0x0000f080, 0xff },
+ { 0x20003003, 0x3f },
+ { 0x20005818, 0x81 },
+ { 0x20009018, 0x81 },
+ { 0x2000301c, 0x81 },
+ { 0x0000c003, 0xc0 },
+ { 0x0000c047, 0x80 },
+ { 0x0000d541, 0x80 },
+ { 0x0000d487, 0x0b },
+ { 0x0000d487, 0x3b },
+ { 0x0000d486, 0xc3 },
+ { 0x0000d470, 0x89 },
+ { 0x0000d471, 0x3a },
+ { 0x0000d472, 0x1d },
+ { 0x0000d478, 0xff },
+ { 0x0000d479, 0x20 },
+ { 0x0000d47a, 0x10 },
+ { 0x0000d73c, 0xb7 },
+ { 0x0000d73d, 0xd7 },
+ { 0x0000d73e, 0x00 },
+ { 0x0000d73f, 0x10 },
+ { 0x3fc2dfc3, 0x00 },
+ { 0x3fc2dfc2, 0x00 },
+ { 0x3fc2dfc1, 0x00 },
+ { 0x3fc2dfc0, 0x07 },
+ { 0x3fc2dfc7, 0x00 },
+ { 0x3fc2dfc6, 0x00 },
+ { 0x3fc2dfc5, 0x00 },
+ { 0x3fc2dfc4, 0x01 },
+ { 0x3fc2df83, 0x00 },
+ { 0x3fc2df82, 0x00 },
+ { 0x3fc2df81, 0x00 },
+ { 0x3fc2df80, 0x00 },
+ { 0x0000d541, 0x40 },
+ { 0x0000d486, 0x43 },
+ { 0x1000db00, 0x03 },
+ { 0x1000db01, 0x00 },
+ { 0x1000db02, 0x10 },
+ { 0x1000db03, 0x00 },
+ { 0x1000db04, 0x00 },
+ { 0x1000db05, 0x45 },
+ { 0x1000db06, 0x12 },
+ { 0x1000db07, 0x09 },
+ { 0x1000db08, 0x00 },
+ { 0x1000db09, 0x00 },
+ { 0x1000db0a, 0x00 },
+ { 0x1000db0b, 0x13 },
+ { 0x1000db0c, 0x09 },
+ { 0x1000db0d, 0x00 },
+ { 0x1000db0e, 0x00 },
+ { 0x1000db0f, 0x00 },
+ { 0x0000d540, 0x21 },
+ { 0x41000189, 0x00 },
+ { 0x4100018a, 0x00 },
+ { 0x41001988, 0x00 },
+ { 0x41081400, 0x09 },
+ { 0x40801508, 0x03 },
+ { 0x40801588, 0x03 },
+ { 0x40801809, 0x00 },
+ { 0x4080180a, 0x00 },
+ { 0x4080180b, 0x00 },
+ { 0x4080180c, 0x00 },
+ { 0x40801b09, 0x00 },
+ { 0x40801b0a, 0x00 },
+ { 0x40801b0b, 0x00 },
+ { 0x40801b0c, 0x00 },
+ { 0x0000d714, 0x17 },
+ { 0x20009012, 0x00 },
+ { 0x0000dd0b, 0x0d },
+ { 0x0000dd0a, 0xff },
+ { 0x0000dd09, 0x0d },
+ { 0x0000dd08, 0xff },
+ { 0x0000d172, 0x2a },
+ { 0x41001988, 0x03 },
+};
+
static const struct reg_default rt1320_reg_defaults[] = {
{ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 },
{ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01), 0x01 },
@@ -340,10 +495,19 @@ static bool rt1320_readable_register(struct device *dev, unsigned int reg)
case 0xf717 ... 0xf719:
case 0xf720 ... 0xf723:
case 0x1000cd91 ... 0x1000cd96:
+ case RT1321_PATCH_MAIN_VER ... RT1321_PATCH_BETA_VER:
case 0x1000f008:
case 0x1000f021:
+ case 0x2000300f:
+ case 0x2000301c:
+ case 0x2000900f:
+ case 0x20009018:
+ case 0x3fc29d80 ... 0x3fc29d83:
case 0x3fe2e000 ... 0x3fe2e003:
case 0x3fc2ab80 ... 0x3fc2abd4:
+ case 0x3fc2bfc0 ... 0x3fc2bfc8:
+ case 0x3fc2d300 ... 0x3fc2d354:
+ case 0x3fc2dfc0 ... 0x3fc2dfc8:
/* 0x40801508/0x40801809/0x4080180a/0x40801909/0x4080190a */
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_REQ_POWER_STATE, 0):
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_MUTE, CH_01):
@@ -394,6 +558,7 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xc560:
case 0xc5b5 ... 0xc5b7:
case 0xc5fc ... 0xc5ff:
+ case 0xc680 ... 0xc683:
case 0xc820:
case 0xc900:
case 0xc920:
@@ -412,7 +577,7 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xd4e5 ... 0xd4e6:
case 0xd4e8 ... 0xd4ff:
case 0xd530:
- case 0xd540:
+ case 0xd540 ... 0xd541:
case 0xd543:
case 0xdb58 ... 0xdb5f:
case 0xdb60 ... 0xdb63:
@@ -429,13 +594,20 @@ static bool rt1320_volatile_register(struct device *dev, unsigned int reg)
case 0xf01e:
case 0xf717 ... 0xf719:
case 0xf720 ... 0xf723:
- case 0x10000000 ... 0x10007fff:
+ case 0x10000000 ... 0x10008fff:
case 0x1000c000 ... 0x1000dfff:
case 0x1000f008:
case 0x1000f021:
+ case 0x2000300f:
+ case 0x2000301c:
+ case 0x2000900f:
+ case 0x20009018:
case 0x3fc2ab80 ... 0x3fc2abd4:
+ case 0x3fc2b780:
case 0x3fc2bf80 ... 0x3fc2bf83:
- case 0x3fc2bfc0 ... 0x3fc2bfc7:
+ case 0x3fc2bfc0 ... 0x3fc2bfc8:
+ case 0x3fc2d300 ... 0x3fc2d354:
+ case 0x3fc2dfc0 ... 0x3fc2dfc8:
case 0x3fe2e000 ... 0x3fe2e003:
case SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_PDE11, RT1320_SDCA_CTL_ACTUAL_POWER_STATE, 0):
case SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0):
@@ -560,7 +732,7 @@ static int rt1320_read_prop(struct sdw_slave *slave)
static int rt1320_pde_transition_delay(struct rt1320_sdw_priv *rt1320, unsigned char func,
unsigned char entity, unsigned char ps)
{
- unsigned int delay = 1000, val;
+ unsigned int delay = 2000, val;
pm_runtime_mark_last_busy(&rt1320->sdw_slave->dev);
@@ -591,24 +763,44 @@ static void rt1320_load_mcu_patch(struct rt1320_sdw_priv *rt1320)
struct sdw_slave *slave = rt1320->sdw_slave;
const struct firmware *patch;
const char *filename;
- unsigned int addr, val;
+ unsigned int addr, val, min_addr, max_addr;
const unsigned char *ptr;
int ret, i;
- if (rt1320->version_id <= RT1320_VB)
- filename = RT1320_VAB_MCU_PATCH;
- else
- filename = RT1320_VC_MCU_PATCH;
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (rt1320->version_id <= RT1320_VB)
+ filename = RT1320_VAB_MCU_PATCH;
+ else
+ filename = RT1320_VC_MCU_PATCH;
+ min_addr = 0x10007000;
+ max_addr = 0x10007fff;
+ break;
+ case RT1321_DEV_ID:
+ filename = RT1321_VA_MCU_PATCH;
+ min_addr = 0x10008000;
+ max_addr = 0x10008fff;
+ break;
+ default:
+ dev_err(&slave->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
+ return;
+ }
/* load the patch code here */
ret = request_firmware(&patch, filename, &slave->dev);
if (ret) {
dev_err(&slave->dev, "%s: Failed to load %s firmware", __func__, filename);
regmap_write(rt1320->regmap, 0xc598, 0x00);
- regmap_write(rt1320->regmap, 0x10007000, 0x67);
- regmap_write(rt1320->regmap, 0x10007001, 0x80);
- regmap_write(rt1320->regmap, 0x10007002, 0x00);
- regmap_write(rt1320->regmap, 0x10007003, 0x00);
+ regmap_write(rt1320->regmap, min_addr, 0x67);
+ regmap_write(rt1320->regmap, min_addr + 0x1, 0x80);
+ regmap_write(rt1320->regmap, min_addr + 0x2, 0x00);
+ regmap_write(rt1320->regmap, min_addr + 0x3, 0x00);
+ if (rt1320->dev_id == RT1321_DEV_ID) {
+ regmap_write(rt1320->regmap, 0xd73c, 0x67);
+ regmap_write(rt1320->regmap, 0xd73d, 0x80);
+ regmap_write(rt1320->regmap, 0xd73e, 0x00);
+ regmap_write(rt1320->regmap, 0xd73f, 0x00);
+ }
} else {
ptr = (const unsigned char *)patch->data;
if ((patch->size % 8) == 0) {
@@ -618,7 +810,7 @@ static void rt1320_load_mcu_patch(struct rt1320_sdw_priv *rt1320)
val = (ptr[i + 4] & 0xff) | (ptr[i + 5] & 0xff) << 8 |
(ptr[i + 6] & 0xff) << 16 | (ptr[i + 7] & 0xff) << 24;
- if (addr > 0x10007fff || addr < 0x10007000) {
+ if (addr > max_addr || addr < min_addr) {
dev_err(&slave->dev, "%s: the address 0x%x is wrong", __func__, addr);
goto _exit_;
}
@@ -688,6 +880,28 @@ static void rt1320_vc_preset(struct rt1320_sdw_priv *rt1320)
}
}
+static void rt1321_preset(struct rt1320_sdw_priv *rt1320)
+{
+ unsigned int i, reg, val, delay;
+
+ for (i = 0; i < ARRAY_SIZE(rt1321_blind_write); i++) {
+ reg = rt1321_blind_write[i].reg;
+ val = rt1321_blind_write[i].def;
+ delay = rt1321_blind_write[i].delay_us;
+
+ if (reg == 0x3fc2dfc3)
+ rt1320_load_mcu_patch(rt1320);
+
+ regmap_write(rt1320->regmap, reg, val);
+
+ if (delay)
+ usleep_range(delay, delay + 1000);
+
+ if (reg == SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0))
+ rt1320_pde_transition_delay(rt1320, FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, val);
+ }
+}
+
static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
{
struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(dev);
@@ -714,6 +928,9 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
if (rt1320->version_id < 0) {
regmap_read(rt1320->regmap, RT1320_DEV_VERSION_ID_1, &val);
rt1320->version_id = val;
+ regmap_read(rt1320->regmap, RT1320_DEV_ID_0, &val);
+ regmap_read(rt1320->regmap, RT1320_DEV_ID_1, &tmp);
+ rt1320->dev_id = (val << 8) | tmp;
}
regmap_read(rt1320->regmap,
@@ -722,16 +939,25 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
/* initialization write */
if ((amp_func_status & FUNCTION_NEEDS_INITIALIZATION)) {
- if (rt1320->version_id < RT1320_VC)
- rt1320_vab_preset(rt1320);
- else
- rt1320_vc_preset(rt1320);
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (rt1320->version_id < RT1320_VC)
+ rt1320_vab_preset(rt1320);
+ else
+ rt1320_vc_preset(rt1320);
+ break;
+ case RT1321_DEV_ID:
+ rt1321_preset(rt1320);
+ break;
+ default:
+ dev_err(dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
+ }
regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT0, RT1320_SDCA_CTL_FUNC_STATUS, 0),
FUNCTION_NEEDS_INITIALIZATION);
}
- if (!rt1320->first_hw_init && rt1320->version_id == RT1320_VA) {
+ if (!rt1320->first_hw_init && rt1320->version_id == RT1320_VA && rt1320->dev_id == RT1320_DEV_ID) {
regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23,
RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0);
regmap_read(rt1320->regmap, RT1320_HIFI_VER_0, &val);
@@ -751,7 +977,7 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1320->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23,
RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 3);
}
- dev_dbg(dev, "%s version_id=%d\n", __func__, rt1320->version_id);
+ dev_dbg(dev, "%s version_id=%d, dev_id=0x%x\n", __func__, rt1320->version_id, rt1320->dev_id);
if (rt1320->first_hw_init) {
regcache_cache_bypass(rt1320->regmap, false);
@@ -894,12 +1120,20 @@ _dmic_vol_:
/* check all channels */
for (i = 0; i < p->count; i++) {
- if (i < 2) {
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (i < 2) {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue[i]);
+ } else {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue[i]);
+ }
+ break;
+ case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue[i]);
- } else {
- reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
- regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue[i]);
+ break;
}
gain_val[i] = ucontrol->value.integer.value[i];
@@ -916,12 +1150,20 @@ _dmic_vol_:
return 0;
for (i = 0; i < p->count; i++) {
- if (i < 2) {
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (i < 2) {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ err = regmap_write(rt1320->mbq_regmap, reg_base + i, gain_val[i]);
+ } else {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ err = regmap_write(rt1320->mbq_regmap, reg_base + i - 2, gain_val[i]);
+ }
+ break;
+ case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
err = regmap_write(rt1320->mbq_regmap, reg_base + i, gain_val[i]);
- } else {
- reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
- err = regmap_write(rt1320->mbq_regmap, reg_base + i - 2, gain_val[i]);
+ break;
}
if (err < 0)
@@ -966,12 +1208,20 @@ _dmic_vol_:
/* check all channels */
for (i = 0; i < p->count; i++) {
- if (i < 2) {
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (i < 2) {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue);
+ } else {
+ reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
+ regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue);
+ }
+ break;
+ case RT1321_DEV_ID:
reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
regmap_read(rt1320->mbq_regmap, reg_base + i, &regvalue);
- } else {
- reg_base = SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14, RT1320_SDCA_CTL_FU_VOLUME, CH_01);
- regmap_read(rt1320->mbq_regmap, reg_base + i - 2, &regvalue);
+ break;
}
ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);
@@ -989,14 +1239,26 @@ static int rt1320_set_fu_capture_ctl(struct rt1320_sdw_priv *rt1320)
for (i = 0; i < ARRAY_SIZE(rt1320->fu_mixer_mute); i++) {
ch_mute = (rt1320->fu_dapm_mute || rt1320->fu_mixer_mute[i]) ? 0x01 : 0x00;
- if (i < 2)
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ if (i < 2)
+ err = regmap_write(rt1320->regmap,
+ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113,
+ RT1320_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);
+ else
+ err = regmap_write(rt1320->regmap,
+ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14,
+ RT1320_SDCA_CTL_FU_MUTE, CH_01) + i - 2, ch_mute);
+ break;
+ case RT1321_DEV_ID:
err = regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU113,
RT1320_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);
- else
- err = regmap_write(rt1320->regmap,
- SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_FU14,
- RT1320_SDCA_CTL_FU_MUTE, CH_01) + i - 2, ch_mute);
+ break;
+ default:
+ dev_err(&rt1320->sdw_slave->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
+ return -EINVAL;
+ }
if (err < 0)
return err;
}
@@ -1217,10 +1479,20 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
if (dai->id == RT1320_AIF1)
port_config.num = 4;
else if (dai->id == RT1320_AIF2) {
- dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
- dmic_port_config[0].num = 8;
- dmic_port_config[1].ch_mask = BIT(0) | BIT(1);
- dmic_port_config[1].num = 10;
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
+ dmic_port_config[0].num = 8;
+ dmic_port_config[1].ch_mask = BIT(0) | BIT(1);
+ dmic_port_config[1].num = 10;
+ break;
+ case RT1321_DEV_ID:
+ dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
+ dmic_port_config[0].num = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
} else
return -EINVAL;
}
@@ -1228,10 +1500,21 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
if (dai->id == RT1320_AIF1)
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
&port_config, 1, sdw_stream);
- else if (dai->id == RT1320_AIF2)
- retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
+ else if (dai->id == RT1320_AIF2) {
+ switch (rt1320->dev_id) {
+ case RT1320_DEV_ID:
+ retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
dmic_port_config, 2, sdw_stream);
- else
+ break;
+ case RT1321_DEV_ID:
+ retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
+ dmic_port_config, 1, sdw_stream);
+ break;
+ default:
+ dev_err(dai->dev, "%s: Unknown device ID %d\n", __func__, rt1320->dev_id);
+ return -EINVAL;
+ }
+ } else
return -EINVAL;
if (retval) {
dev_err(dai->dev, "%s: Unable to configure port\n", __func__);
@@ -1273,9 +1556,11 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
regmap_write(rt1320->regmap,
SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS113, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
sampling_rate);
- regmap_write(rt1320->regmap,
- SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS14, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
- sampling_rate);
+
+ if (rt1320->dev_id == RT1320_DEV_ID)
+ regmap_write(rt1320->regmap,
+ SDW_SDCA_CTL(FUNC_NUM_MIC, RT1320_SDCA_ENT_CS14, RT1320_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
+ sampling_rate);
}
return 0;
@@ -1469,6 +1754,7 @@ static int rt1320_sdw_remove(struct sdw_slave *slave)
static const struct sdw_device_id rt1320_id[] = {
SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x0, 0),
SDW_SLAVE_ENTRY_EXT(0x025d, 0x1320, 0x3, 0x1, 0),
+ SDW_SLAVE_ENTRY_EXT(0x025d, 0x1321, 0x3, 0x1, 0),
{},
};
MODULE_DEVICE_TABLE(sdw, rt1320_id);
diff --git a/sound/soc/codecs/rt1320-sdw.h b/sound/soc/codecs/rt1320-sdw.h
index 23b321aee6a9..a6d90e259dc9 100644
--- a/sound/soc/codecs/rt1320-sdw.h
+++ b/sound/soc/codecs/rt1320-sdw.h
@@ -14,8 +14,16 @@
#include <linux/soundwire/sdw_registers.h>
#include <sound/soc.h>
+#define RT1320_DEV_ID 0x6981
+#define RT1321_DEV_ID 0x7045
+
/* imp-defined registers */
#define RT1320_DEV_VERSION_ID_1 0xc404
+#define RT1320_DEV_ID_1 0xc405
+#define RT1320_DEV_ID_0 0xc406
+
+#define RT1321_PATCH_MAIN_VER 0x1000cffe
+#define RT1321_PATCH_BETA_VER 0x1000cfff
#define RT1320_KR0_STATUS_CNT 0x1000f008
#define RT1320_KR0_INT_READY 0x1000f021
@@ -86,6 +94,7 @@ enum rt1320_version_id {
#define RT1320_VER_B_ID 0x07392238
#define RT1320_VAB_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vab.bin"
#define RT1320_VC_MCU_PATCH "realtek/rt1320/rt1320-patch-code-vc.bin"
+#define RT1321_VA_MCU_PATCH "realtek/rt1320/rt1321-patch-code-va.bin"
struct rt1320_sdw_priv {
struct snd_soc_component *component;
@@ -96,6 +105,7 @@ struct rt1320_sdw_priv {
bool hw_init;
bool first_hw_init;
int version_id;
+ unsigned int dev_id;
bool fu_dapm_mute;
bool fu_mixer_mute[4];
};
diff --git a/sound/soc/codecs/rt721-sdca-sdw.c b/sound/soc/codecs/rt721-sdca-sdw.c
index 582b47d69278..4d8a12b13015 100644
--- a/sound/soc/codecs/rt721-sdca-sdw.c
+++ b/sound/soc/codecs/rt721-sdca-sdw.c
@@ -63,15 +63,14 @@ static bool rt721_sdca_volatile_register(struct device *dev, unsigned int reg)
static bool rt721_sdca_mbq_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
- case 0x0900007:
+ case 0x0900004 ... 0x0900009:
case 0x0a00005:
case 0x0c00005:
case 0x0d00014:
case 0x0310100:
- case 0x2000001:
- case 0x2000002:
- case 0x2000003:
+ case 0x2000000 ... 0x2000003:
case 0x2000013:
+ case 0x200002c:
case 0x200003c:
case 0x2000046:
case 0x5810000:
@@ -134,6 +133,8 @@ static bool rt721_sdca_mbq_volatile_register(struct device *dev, unsigned int re
{
switch (reg) {
case 0x0310100:
+ case 0x0900005:
+ case 0x0900009:
case 0x0a00005:
case 0x0c00005:
case 0x0d00014:
@@ -141,6 +142,7 @@ static bool rt721_sdca_mbq_volatile_register(struct device *dev, unsigned int re
case 0x200000d:
case 0x2000019:
case 0x2000020:
+ case 0x200002c:
case 0x2000030:
case 0x2000046:
case 0x2000067:
diff --git a/sound/soc/codecs/tas2781-comlib-i2c.c b/sound/soc/codecs/tas2781-comlib-i2c.c
index c078bb0a8437..b3fd7350143b 100644
--- a/sound/soc/codecs/tas2781-comlib-i2c.c
+++ b/sound/soc/codecs/tas2781-comlib-i2c.c
@@ -320,6 +320,8 @@ void tasdevice_reset(struct tasdevice_priv *tas_dev)
for (i = 0; i < tas_dev->ndev; i++) {
ret = tasdevice_dev_write(tas_dev, i,
TASDEVICE_REG_SWRESET,
+ tas_dev->chip_id >= TAS5825 ?
+ TAS5825_REG_SWRESET_RESET :
TASDEVICE_REG_SWRESET_RESET);
if (ret < 0)
dev_err(tas_dev->dev,
diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
index c9c1e608ddb7..78fd0a5dc6f2 100644
--- a/sound/soc/codecs/tas2781-fmwlib.c
+++ b/sound/soc/codecs/tas2781-fmwlib.c
@@ -91,7 +91,7 @@ struct blktyp_devidx_map {
};
static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = {
- 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4
+ 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4, 1, 2
};
/* fixed m68k compiling issue: mapping table can save code field */
@@ -180,6 +180,16 @@ static struct tasdevice_config_info *tasdevice_add_config(
dev_err(tas_priv->dev, "add conf: Out of boundary\n");
goto out;
}
+ /* If in the RCA bin file are several profiles with the
+ * keyword "init", init_profile_id only store the last
+ * init profile id.
+ */
+ if (strnstr(&config_data[config_offset], "init", 64)) {
+ tas_priv->rcabin.init_profile_id =
+ tas_priv->rcabin.ncfgs - 1;
+ dev_dbg(tas_priv->dev, "%s: init profile id = %d\n",
+ __func__, tas_priv->rcabin.init_profile_id);
+ }
config_offset += 64;
}
@@ -283,6 +293,8 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)
int i;
rca = &(tas_priv->rcabin);
+ /* Initialize to none */
+ rca->init_profile_id = -1;
fw_hdr = &(rca->fw_hdr);
if (!fmw || !fmw->data) {
dev_err(tas_priv->dev, "Failed to read %s\n",
@@ -509,6 +521,56 @@ out:
return offset;
}
+static int fw_parse_tas5825_program_data_kernel(
+ struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
+ const struct firmware *fmw, int offset)
+{
+ struct tasdevice_prog *program;
+ unsigned int i;
+
+ for (i = 0; i < tas_fmw->nr_programs; i++) {
+ program = &(tas_fmw->programs[i]);
+ if (offset + 72 > fmw->size) {
+ dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
+ return -EINVAL;
+ }
+ /* Skip 65 unused byts*/
+ offset += 65;
+ offset = fw_parse_data_kernel(tas_fmw, &(program->dev_data),
+ fmw, offset);
+ if (offset < 0)
+ return offset;
+ }
+
+ return offset;
+}
+
+static int fw_parse_tas5825_configuration_data_kernel(
+ struct tasdevice_priv *tas_priv,
+ struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
+{
+ const unsigned char *data = fmw->data;
+ struct tasdevice_config *config;
+ unsigned int i;
+
+ for (i = 0; i < tas_fmw->nr_configurations; i++) {
+ config = &(tas_fmw->configs[i]);
+ if (offset + 80 > fmw->size) {
+ dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
+ return -EINVAL;
+ }
+ memcpy(config->name, &data[offset], 64);
+ /* Skip extra 8 bytes*/
+ offset += 72;
+ offset = fw_parse_data_kernel(tas_fmw, &(config->dev_data),
+ fmw, offset);
+ if (offset < 0)
+ return offset;
+ }
+
+ return offset;
+}
+
static int fw_parse_program_data_kernel(
struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
const struct firmware *fmw, int offset)
@@ -1826,7 +1888,8 @@ static void dspbin_type_check(struct tasdevice_priv *tas_priv,
else
tas_priv->dspbin_typ = TASDEV_ALPHA;
}
- if (tas_priv->dspbin_typ != TASDEV_BASIC)
+ if ((tas_priv->dspbin_typ != TASDEV_BASIC) &&
+ (ppcver < PPC3_VERSION_TAS5825_BASE))
tas_priv->fw_parse_fct_param_address =
fw_parse_fct_param_address;
}
@@ -1837,7 +1900,17 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
int rc = 0;
if (drv_ver == 0x100) {
- if (ppcver >= PPC3_VERSION_BASE) {
+ if (ppcver >= PPC3_VERSION_TAS5825_BASE) {
+ tas_priv->fw_parse_variable_header =
+ fw_parse_variable_header_kernel;
+ tas_priv->fw_parse_program_data =
+ fw_parse_tas5825_program_data_kernel;
+ tas_priv->fw_parse_configuration_data =
+ fw_parse_tas5825_configuration_data_kernel;
+ tas_priv->tasdevice_load_block =
+ tasdevice_load_block_kernel;
+ dspbin_type_check(tas_priv, ppcver);
+ } else if (ppcver >= PPC3_VERSION_BASE) {
tas_priv->fw_parse_variable_header =
fw_parse_variable_header_kernel;
tas_priv->fw_parse_program_data =
diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c
index 0e09d794516f..1539b70881d1 100644
--- a/sound/soc/codecs/tas2781-i2c.c
+++ b/sound/soc/codecs/tas2781-i2c.c
@@ -30,8 +30,10 @@
#include <sound/tas2781.h>
#include <sound/tas2781-comlib-i2c.h>
#include <sound/tlv.h>
+#include <sound/tas2x20-tlv.h>
#include <sound/tas2563-tlv.h>
#include <sound/tas2781-tlv.h>
+#include <sound/tas5825-tlv.h>
#include <linux/unaligned.h>
#define X2563_CL_STT_VAL(xreg, xval) \
@@ -98,16 +100,32 @@ static const struct bulk_reg_val tas2781_cali_start_reg[] = {
};
static const struct i2c_device_id tasdevice_id[] = {
+ { "tas2020", TAS2020 },
+ { "tas2118", TAS2118 },
+ { "tas2120", TAS2120 },
+ { "tas2320", TAS2320 },
{ "tas2563", TAS2563 },
+ { "tas2570", TAS2570 },
+ { "tas2572", TAS2572 },
{ "tas2781", TAS2781 },
+ { "tas5825", TAS5825 },
+ { "tas5827", TAS5827 },
{}
};
MODULE_DEVICE_TABLE(i2c, tasdevice_id);
#ifdef CONFIG_OF
static const struct of_device_id tasdevice_of_match[] = {
+ { .compatible = "ti,tas2020" },
+ { .compatible = "ti,tas2118" },
+ { .compatible = "ti,tas2120" },
+ { .compatible = "ti,tas2320" },
{ .compatible = "ti,tas2563" },
+ { .compatible = "ti,tas2570" },
+ { .compatible = "ti,tas2572" },
{ .compatible = "ti,tas2781" },
+ { .compatible = "ti,tas5825" },
+ { .compatible = "ti,tas5827" },
{},
};
MODULE_DEVICE_TABLE(of, tasdevice_of_match);
@@ -797,7 +815,7 @@ static int tasdev_nop_get(
return 0;
}
-static int tas2563_digital_gain_get(
+static int tasdevice_digital_gain_get(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -823,15 +841,15 @@ static int tas2563_digital_gain_get(
while (r > 1 + l) {
mid = (l + r) / 2;
- ar_mid = get_unaligned_be32(tas2563_dvc_table[mid]);
+ ar_mid = get_unaligned_be32(tas_dev->dvc_tlv_table[mid]);
if (target < ar_mid)
r = mid;
else
l = mid;
}
- ar_l = get_unaligned_be32(tas2563_dvc_table[l]);
- ar_r = get_unaligned_be32(tas2563_dvc_table[r]);
+ ar_l = get_unaligned_be32(tas_dev->dvc_tlv_table[l]);
+ ar_r = get_unaligned_be32(tas_dev->dvc_tlv_table[r]);
/* find out the member same as or closer to the current volume */
ucontrol->value.integer.value[0] =
@@ -841,7 +859,7 @@ out:
return 0;
}
-static int tas2563_digital_gain_put(
+static int tasdevice_digital_gain_put(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -867,7 +885,7 @@ static int tas2563_digital_gain_put(
}
volrd = get_unaligned_be32(&data[0]);
- volwr = get_unaligned_be32(tas2563_dvc_table[vol]);
+ volwr = get_unaligned_be32(tas_dev->dvc_tlv_table[vol]);
if (volrd == volwr) {
rc = 0;
@@ -876,7 +894,7 @@ static int tas2563_digital_gain_put(
for (i = 0; i < tas_dev->ndev; i++) {
ret = tasdevice_dev_bulk_write(tas_dev, i, reg,
- (unsigned char *)tas2563_dvc_table[vol], 4);
+ (unsigned char *)tas_dev->dvc_tlv_table[vol], 4);
if (ret) {
dev_err(tas_dev->dev,
"%s, set digital vol error in dev %d\n",
@@ -892,11 +910,6 @@ out:
return rc;
}
-static const struct snd_kcontrol_new tasdevice_snd_controls[] = {
- SOC_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
- tasdev_force_fwload_get, tasdev_force_fwload_put),
-};
-
static const struct snd_kcontrol_new tasdevice_cali_controls[] = {
SOC_SINGLE_EXT("Calibration Stop", SND_SOC_NOPM, 0, 1, 0,
tasdev_nop_get, tasdev_calib_stop_put),
@@ -907,6 +920,16 @@ static const struct snd_kcontrol_new tasdevice_cali_controls[] = {
SND_SOC_BYTES_EXT("Amp XMA2 Data", 6, tasdev_XMA2_data_get, NULL),
};
+static const struct snd_kcontrol_new tas2x20_snd_controls[] = {
+ SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2X20_AMP_LEVEL,
+ 0, 0, 42, 1, tas2781_amp_getvol,
+ tas2781_amp_putvol, tas2x20_amp_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2X20_DVC_LEVEL,
+ 0, 0, ARRAY_SIZE(tas2x20_dvc_table) - 1, 0,
+ tasdevice_digital_gain_get, tasdevice_digital_gain_put,
+ tas2x20_dvc_tlv),
+};
+
static const struct snd_kcontrol_new tas2781_snd_controls[] = {
SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL,
1, 0, 20, 0, tas2781_amp_getvol,
@@ -916,6 +939,15 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = {
tas2781_digital_putvol, tas2781_dvc_tlv),
};
+static const struct snd_kcontrol_new tas5825_snd_controls[] = {
+ SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS5825_AMP_LEVEL,
+ 0, 0, 31, 1, tas2781_amp_getvol,
+ tas2781_amp_putvol, tas5825_amp_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS5825_DVC_LEVEL,
+ 0, 0, 254, 1, tas2781_amp_getvol,
+ tas2781_amp_putvol, tas5825_dvc_tlv),
+};
+
static const struct snd_kcontrol_new tas2781_cali_controls[] = {
SND_SOC_BYTES_EXT("Amp Latch Data", 3, tas2781_latch_reg_get, NULL),
};
@@ -923,7 +955,7 @@ static const struct snd_kcontrol_new tas2781_cali_controls[] = {
static const struct snd_kcontrol_new tas2563_snd_controls[] = {
SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2563_DVC_LVL, 0,
0, ARRAY_SIZE(tas2563_dvc_table) - 1, 0,
- tas2563_digital_gain_get, tas2563_digital_gain_put,
+ tasdevice_digital_gain_get, tasdevice_digital_gain_put,
tas2563_dvc_tlv),
};
@@ -968,8 +1000,8 @@ static int tasdevice_info_chip_id(struct snd_kcontrol *kcontrol,
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
- uinfo->value.integer.min = TAS2563;
- uinfo->value.integer.max = TAS2781;
+ uinfo->value.integer.min = TAS2020;
+ uinfo->value.integer.max = TAS_OTHERS;
return 0;
}
@@ -1168,9 +1200,9 @@ static int tasdevice_active_num_put(struct snd_kcontrol *kcontrol,
static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv)
{
struct snd_kcontrol_new *dsp_ctrls;
- char *active_dev_num, *chip_id;
+ char *active_dev_num, *chip_id, *fw_load;
char *conf_name, *prog_name;
- int nr_controls = 4;
+ int nr_controls = 5;
int mix_index = 0;
/* Alloc kcontrol via devm_kzalloc, which don't manually
@@ -1228,6 +1260,19 @@ static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv)
dsp_ctrls[mix_index].get = tasdevice_get_chip_id;
mix_index++;
+ fw_load = devm_kstrdup(tas_priv->dev, "Speaker Force Firmware Load",
+ GFP_KERNEL);
+ if (!fw_load)
+ return -ENOMEM;
+
+ dsp_ctrls[mix_index].name = fw_load;
+ dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ dsp_ctrls[mix_index].info = snd_soc_info_bool_ext;
+ dsp_ctrls[mix_index].put = tasdev_force_fwload_put;
+ dsp_ctrls[mix_index].get = tasdev_force_fwload_get;
+ dsp_ctrls[mix_index].private_value = 0UL;
+ mix_index++;
+
return snd_soc_add_component_controls(tas_priv->codec, dsp_ctrls,
nr_controls < mix_index ? nr_controls : mix_index);
}
@@ -1587,6 +1632,16 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
* failing to load DSP firmware is NOT an error.
*/
tas_priv->fw_state = TASDEVICE_RCA_FW_OK;
+ /* There is no DSP firmware required for TAS2118/2X20/257X. */
+ switch (tas_priv->chip_id) {
+ case TAS2020:
+ case TAS2118:
+ case TAS2120:
+ case TAS2320:
+ case TAS2570:
+ case TAS2572:
+ goto out;
+ }
if (tas_priv->name_prefix)
scnprintf(tas_priv->coef_binaryname, 64, "%s-%s_coef.bin",
tas_priv->name_prefix, tas_priv->dev_name);
@@ -1608,39 +1663,48 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
dev_err(tas_priv->dev, "dsp controls error\n");
goto out;
}
-
- ret = tasdevice_create_cali_ctrls(tas_priv);
- if (ret) {
- dev_err(tas_priv->dev, "cali controls error\n");
- goto out;
- }
-
tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
- /* If calibrated data occurs error, dsp will still works with default
- * calibrated data inside algo.
- */
- for (i = 0; i < tas_priv->ndev; i++) {
- if (tas_priv->name_prefix)
- scnprintf(tas_priv->cal_binaryname[i], 64,
- "%s-%s_cal_0x%02x.bin", tas_priv->name_prefix,
- tas_priv->dev_name,
- tas_priv->tasdevice[i].dev_addr);
- else
- scnprintf(tas_priv->cal_binaryname[i], 64,
- "%s_cal_0x%02x.bin", tas_priv->dev_name,
- tas_priv->tasdevice[i].dev_addr);
- ret = tas2781_load_calibration(tas_priv,
- tas_priv->cal_binaryname[i], i);
- if (ret != 0)
- dev_err(tas_priv->dev,
- "%s: load %s error, default will effect\n",
- __func__, tas_priv->cal_binaryname[i]);
+ /* There is no calibration required for TAS5825/TAS5827. */
+ if (tas_priv->chip_id < TAS5825) {
+ ret = tasdevice_create_cali_ctrls(tas_priv);
+ if (ret) {
+ dev_err(tas_priv->dev, "cali controls error\n");
+ goto out;
+ }
+ /* If calibrated data occurs error, dsp will still works
+ * with default calibrated data inside algo.
+ */
+ for (i = 0; i < tas_priv->ndev; i++) {
+ if (tas_priv->name_prefix)
+ scnprintf(tas_priv->cal_binaryname[i], 64,
+ "%s-%s_cal_0x%02x.bin",
+ tas_priv->name_prefix,
+ tas_priv->dev_name,
+ tas_priv->tasdevice[i].dev_addr);
+ else
+ scnprintf(tas_priv->cal_binaryname[i], 64,
+ "%s_cal_0x%02x.bin",
+ tas_priv->dev_name,
+ tas_priv->tasdevice[i].dev_addr);
+ ret = tas2781_load_calibration(tas_priv,
+ tas_priv->cal_binaryname[i], i);
+ if (ret != 0)
+ dev_err(tas_priv->dev,
+ "%s: load %s error, keep default.\n",
+ __func__, tas_priv->cal_binaryname[i]);
+ }
}
tasdevice_prmg_load(tas_priv, 0);
tas_priv->cur_prog = 0;
+ /* Init common setting for different audio profiles */
+ if (tas_priv->rcabin.init_profile_id >= 0)
+ tasdevice_select_cfg_blk(tas_priv,
+ tas_priv->rcabin.init_profile_id,
+ TASDEVICE_BIN_BLK_PRE_POWER_UP);
+
#ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C
if (tas_priv->name_prefix)
acoustic_debugfs_node = devm_kasprintf(tas_priv->dev,
@@ -1653,8 +1717,14 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
#endif
out:
if (tas_priv->fw_state == TASDEVICE_RCA_FW_OK) {
- /* If DSP FW fail, DSP kcontrol won't be created. */
- tasdevice_dsp_remove(tas_priv);
+ switch (tas_priv->chip_id) {
+ case TAS2563:
+ case TAS2781:
+ case TAS5825:
+ case TAS5827:
+ /* If DSP FW fail, DSP kcontrol won't be created. */
+ tasdevice_dsp_remove(tas_priv);
+ }
}
mutex_unlock(&tas_priv->codec_lock);
release_firmware(fmw);
@@ -1798,13 +1868,30 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec)
int rc;
switch (tas_priv->chip_id) {
+ case TAS2020:
+ case TAS2118:
+ case TAS2120:
+ case TAS2320:
+ case TAS2570:
+ case TAS2572:
+ p = (struct snd_kcontrol_new *)tas2x20_snd_controls;
+ size = ARRAY_SIZE(tas2x20_snd_controls);
+ tas_priv->dvc_tlv_table = tas2x20_dvc_table;
+ break;
case TAS2781:
p = (struct snd_kcontrol_new *)tas2781_snd_controls;
size = ARRAY_SIZE(tas2781_snd_controls);
break;
+ case TAS5825:
+ case TAS5827:
+ p = (struct snd_kcontrol_new *)tas5825_snd_controls;
+ size = ARRAY_SIZE(tas5825_snd_controls);
+ break;
default:
p = (struct snd_kcontrol_new *)tas2563_snd_controls;
size = ARRAY_SIZE(tas2563_snd_controls);
+ tas_priv->dvc_tlv_table = tas2563_dvc_table;
+ break;
}
rc = snd_soc_add_component_controls(codec, p, size);
@@ -1844,8 +1931,6 @@ static const struct snd_soc_component_driver
soc_codec_driver_tasdevice = {
.probe = tasdevice_codec_probe,
.remove = tasdevice_codec_remove,
- .controls = tasdevice_snd_controls,
- .num_controls = ARRAY_SIZE(tasdevice_snd_controls),
.dapm_widgets = tasdevice_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(tasdevice_dapm_widgets),
.dapm_routes = tasdevice_audio_map,
@@ -1961,7 +2046,16 @@ static void tasdevice_i2c_remove(struct i2c_client *client)
#ifdef CONFIG_ACPI
static const struct acpi_device_id tasdevice_acpi_match[] = {
- { "TAS2781", TAS2781 },
+ { "TXNW2020", TAS2020 },
+ { "TXNW2118", TAS2118 },
+ { "TXNW2120", TAS2120 },
+ { "TXNW2320", TAS2320 },
+ { "TXNW2563", TAS2563 },
+ { "TXNW2570", TAS2570 },
+ { "TXNW2572", TAS2572 },
+ { "TXNW2781", TAS2781 },
+ { "TXNW5825", TAS5825 },
+ { "TXNW5827", TAS5827 },
{},
};
diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
new file mode 100644
index 000000000000..1fb4227b711e
--- /dev/null
+++ b/sound/soc/codecs/tas2783-sdw.c
@@ -0,0 +1,1331 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// ALSA SoC Texas Instruments TAS2783 Audio Smart Amplifier
+//
+// Copyright (C) 2025 Texas Instruments Incorporated
+// https://www.ti.com
+//
+// The TAS2783 driver implements a flexible and configurable
+// algo coefficient setting for single TAS2783 chips.
+//
+// Author: Niranjan H Y <niranjanhy@ti.com>
+// Author: Baojun Xu <baojun.xu@ti.com>
+// Author: Kevin Lu <kevin-lu@ti.com>
+
+#include <linux/unaligned.h>
+#include <linux/crc32.h>
+#include <linux/efi.h>
+#include <linux/err.h>
+#include <linux/firmware.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <sound/pcm_params.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/wait.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_registers.h>
+#include <linux/soundwire/sdw_type.h>
+#include <sound/sdw.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/tas2781-tlv.h>
+
+#include "tas2783.h"
+
+#define TIMEOUT_FW_DL_MS (3000)
+#define FW_DL_OFFSET 36
+#define FW_FL_HDR 12
+#define TAS2783_PROBE_TIMEOUT 5000
+#define TAS2783_CALI_GUID EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, \
+ 0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92)
+
+static const u32 tas2783_cali_reg[] = {
+ TAS2783_CAL_R0,
+ TAS2783_CAL_INVR0,
+ TAS2783_CAL_R0LOW,
+ TAS2783_CAL_POWER,
+ TAS2783_CAL_TLIM,
+};
+
+struct bin_header_t {
+ u16 vendor_id;
+ u16 version;
+ u32 file_id;
+ u32 length;
+};
+
+struct calibration_data {
+ u32 is_valid;
+ unsigned long read_sz;
+ u8 data[TAS2783_CALIB_DATA_SZ];
+};
+
+struct tas2783_prv {
+ struct snd_soc_component *component;
+ struct calibration_data cali_data;
+ struct sdw_slave *sdw_peripheral;
+ enum sdw_slave_status status;
+ /* calibration */
+ struct mutex calib_lock;
+ /* pde and firmware download */
+ struct mutex pde_lock;
+ struct regmap *regmap;
+ struct device *dev;
+ struct class *class;
+ struct attribute_group *cal_attr_groups;
+ struct tm tm;
+ u8 rca_binaryname[64];
+ u8 dev_name[32];
+ bool hw_init;
+ /* wq for firmware download */
+ wait_queue_head_t fw_wait;
+ bool fw_dl_task_done;
+ bool fw_dl_success;
+};
+
+static const struct reg_default tas2783_reg_default[] = {
+ {TAS2783_AMP_LEVEL, 0x28},
+ {TASDEV_REG_SDW(0, 0, 0x03), 0x28},
+ {TASDEV_REG_SDW(0, 0, 0x04), 0x21},
+ {TASDEV_REG_SDW(0, 0, 0x05), 0x41},
+ {TASDEV_REG_SDW(0, 0, 0x06), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x07), 0x20},
+ {TASDEV_REG_SDW(0, 0, 0x08), 0x09},
+ {TASDEV_REG_SDW(0, 0, 0x09), 0x02},
+ {TASDEV_REG_SDW(0, 0, 0x0a), 0x0a},
+ {TASDEV_REG_SDW(0, 0, 0x0c), 0x10},
+ {TASDEV_REG_SDW(0, 0, 0x0d), 0x13},
+ {TASDEV_REG_SDW(0, 0, 0x0e), 0xc2},
+ {TASDEV_REG_SDW(0, 0, 0x0f), 0x40},
+ {TASDEV_REG_SDW(0, 0, 0x10), 0x04},
+ {TASDEV_REG_SDW(0, 0, 0x13), 0x13},
+ {TASDEV_REG_SDW(0, 0, 0x14), 0x12},
+ {TASDEV_REG_SDW(0, 0, 0x15), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x16), 0x12},
+ {TASDEV_REG_SDW(0, 0, 0x17), 0x80},
+ {TAS2783_DVC_LVL, 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x1b), 0x61},
+ {TASDEV_REG_SDW(0, 0, 0x1c), 0x36},
+ {TASDEV_REG_SDW(0, 0, 0x1d), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x1f), 0x01},
+ {TASDEV_REG_SDW(0, 0, 0x20), 0x2e},
+ {TASDEV_REG_SDW(0, 0, 0x21), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x34), 0x06},
+ {TASDEV_REG_SDW(0, 0, 0x35), 0xbd},
+ {TASDEV_REG_SDW(0, 0, 0x36), 0xad},
+ {TASDEV_REG_SDW(0, 0, 0x37), 0xa8},
+ {TASDEV_REG_SDW(0, 0, 0x38), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x3b), 0xfc},
+ {TASDEV_REG_SDW(0, 0, 0x3d), 0xdd},
+ {TASDEV_REG_SDW(0, 0, 0x40), 0xf6},
+ {TASDEV_REG_SDW(0, 0, 0x41), 0x14},
+ {TASDEV_REG_SDW(0, 0, 0x5c), 0x19},
+ {TASDEV_REG_SDW(0, 0, 0x5d), 0x80},
+ {TASDEV_REG_SDW(0, 0, 0x63), 0x48},
+ {TASDEV_REG_SDW(0, 0, 0x65), 0x08},
+ {TASDEV_REG_SDW(0, 0, 0x66), 0xb2},
+ {TASDEV_REG_SDW(0, 0, 0x67), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x6a), 0x12},
+ {TASDEV_REG_SDW(0, 0, 0x6b), 0xfb},
+ {TASDEV_REG_SDW(0, 0, 0x6c), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x6d), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x6e), 0x1a},
+ {TASDEV_REG_SDW(0, 0, 0x6f), 0x00},
+ {TASDEV_REG_SDW(0, 0, 0x70), 0x96},
+ {TASDEV_REG_SDW(0, 0, 0x71), 0x02},
+ {TASDEV_REG_SDW(0, 0, 0x73), 0x08},
+ {TASDEV_REG_SDW(0, 0, 0x75), 0xe0},
+ {TASDEV_REG_SDW(0, 0, 0x7a), 0x60},
+ {TASDEV_REG_SDW(0, 0, 0x60), 0x21},
+ {TASDEV_REG_SDW(0, 1, 0x02), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x17), 0xc0},
+ {TASDEV_REG_SDW(0, 1, 0x19), 0x60},
+ {TASDEV_REG_SDW(0, 1, 0x35), 0x75},
+ {TASDEV_REG_SDW(0, 1, 0x3d), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x3e), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x3f), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x40), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x41), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x42), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x43), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x44), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x45), 0x00},
+ {TASDEV_REG_SDW(0, 1, 0x47), 0xab},
+ {TASDEV_REG_SDW(0, 0xfd, 0x0d), 0x0d},
+ {TASDEV_REG_SDW(0, 0xfd, 0x39), 0x00},
+ {TASDEV_REG_SDW(0, 0xfd, 0x3e), 0x00},
+ {TASDEV_REG_SDW(0, 0xfd, 0x45), 0x00},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x02, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x02, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x02, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x02, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x02, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x01, 1), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x02, 1), 0x9c00},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 1), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x0b, 1), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 1), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 1), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 1), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 2), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 1), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 2), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x01, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x05, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x01, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x05, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 1), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 2), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 3), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 4), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 5), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 6), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 7), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x06, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x04, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 1), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 2), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 3), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 4), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 5), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 6), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 7), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 8), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 9), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xa), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xb), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xc), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xd), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xe), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xf), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x1, 0), 0x3},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x10, 0), 0x3},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x06, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x13, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x06, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x13, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x05, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x10, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x11, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_TG23, 0x10, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x01, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x06, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x07, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x08, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x09, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x0a, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x10, 0), 0x1},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x12, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x13, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x14, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x15, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x16, 0), 0x0},
+ {SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_UDMPU23, 0x10, 0), 0x0},
+};
+
+static const struct reg_sequence tas2783_init_seq[] = {
+ REG_SEQ0(SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0x00), 0x04),
+ REG_SEQ0(0x00800418, 0x00),
+ REG_SEQ0(0x00800419, 0x00),
+ REG_SEQ0(0x0080041a, 0x00),
+ REG_SEQ0(0x0080041b, 0x00),
+ REG_SEQ0(0x00800428, 0x40),
+ REG_SEQ0(0x00800429, 0x00),
+ REG_SEQ0(0x0080042a, 0x00),
+ REG_SEQ0(0x0080042b, 0x00),
+ REG_SEQ0(SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x1, 0x00), 0x00),
+ REG_SEQ0(0x0080005c, 0xD9),
+ REG_SEQ0(0x00800082, 0x20),
+ REG_SEQ0(0x008000a1, 0x00),
+ REG_SEQ0(0x00800097, 0xc8),
+ REG_SEQ0(0x00800099, 0x20),
+ REG_SEQ0(0x008000c7, 0xaa),
+ REG_SEQ0(0x008000b5, 0x74),
+ REG_SEQ0(0x00800082, 0x20),
+ REG_SEQ0(0x00807e8d, 0x0d),
+ REG_SEQ0(0x00807eb9, 0x53),
+ REG_SEQ0(0x00807ebe, 0x42),
+ REG_SEQ0(0x00807ec5, 0x37),
+ REG_SEQ0(0x00800066, 0x92),
+ REG_SEQ0(0x00800003, 0x28),
+ REG_SEQ0(0x00800004, 0x21),
+ REG_SEQ0(0x00800005, 0x41),
+ REG_SEQ0(0x00800006, 0x00),
+ REG_SEQ0(0x00800007, 0x20),
+ REG_SEQ0(0x0080000c, 0x10),
+ REG_SEQ0(0x00800013, 0x08),
+ REG_SEQ0(0x00800015, 0x00),
+ REG_SEQ0(0x00800017, 0x80),
+ REG_SEQ0(0x0080001a, 0x00),
+ REG_SEQ0(0x0080001b, 0x22),
+ REG_SEQ0(0x0080001c, 0x36),
+ REG_SEQ0(0x0080001d, 0x01),
+ REG_SEQ0(0x0080001f, 0x00),
+ REG_SEQ0(0x00800020, 0x2e),
+ REG_SEQ0(0x00800034, 0x06),
+ REG_SEQ0(0x00800035, 0xb9),
+ REG_SEQ0(0x00800036, 0xad),
+ REG_SEQ0(0x00800037, 0xa8),
+ REG_SEQ0(0x00800038, 0x00),
+ REG_SEQ0(0x0080003b, 0xfc),
+ REG_SEQ0(0x0080003d, 0xdd),
+ REG_SEQ0(0x00800040, 0xf6),
+ REG_SEQ0(0x00800041, 0x14),
+ REG_SEQ0(0x0080005c, 0x19),
+ REG_SEQ0(0x0080005d, 0x80),
+ REG_SEQ0(0x00800063, 0x48),
+ REG_SEQ0(0x00800065, 0x08),
+ REG_SEQ0(0x00800067, 0x00),
+ REG_SEQ0(0x0080006a, 0x12),
+ REG_SEQ0(0x0080006b, 0x7b),
+ REG_SEQ0(0x0080006c, 0x00),
+ REG_SEQ0(0x0080006d, 0x00),
+ REG_SEQ0(0x0080006e, 0x1a),
+ REG_SEQ0(0x0080006f, 0x00),
+ REG_SEQ0(0x00800070, 0x96),
+ REG_SEQ0(0x00800071, 0x02),
+ REG_SEQ0(0x00800073, 0x08),
+ REG_SEQ0(0x00800075, 0xe0),
+ REG_SEQ0(0x0080007a, 0x60),
+ REG_SEQ0(0x008000bd, 0x00),
+ REG_SEQ0(0x008000be, 0x00),
+ REG_SEQ0(0x008000bf, 0x00),
+ REG_SEQ0(0x008000c0, 0x00),
+ REG_SEQ0(0x008000c1, 0x00),
+ REG_SEQ0(0x008000c2, 0x00),
+ REG_SEQ0(0x008000c3, 0x00),
+ REG_SEQ0(0x008000c4, 0x00),
+ REG_SEQ0(0x008000c5, 0x00),
+ REG_SEQ0(0x00800008, 0x49),
+ REG_SEQ0(0x00800009, 0x02),
+ REG_SEQ0(0x0080000a, 0x1a),
+ REG_SEQ0(0x0080000d, 0x93),
+ REG_SEQ0(0x0080000e, 0x82),
+ REG_SEQ0(0x0080000f, 0x42),
+ REG_SEQ0(0x00800010, 0x84),
+ REG_SEQ0(0x00800014, 0x0a),
+ REG_SEQ0(0x00800016, 0x00),
+ REG_SEQ0(0x00800060, 0x21),
+};
+
+static int tas2783_sdca_mbq_size(struct device *dev, u32 reg)
+{
+ switch (reg) {
+ case 0x000 ... 0x080: /* Data port 0. */
+ case 0x100 ... 0x140: /* Data port 1. */
+ case 0x200 ... 0x240: /* Data port 2. */
+ case 0x300 ... 0x340: /* Data port 3. */
+ case 0x400 ... 0x440: /* Data port 4. */
+ case 0x500 ... 0x540: /* Data port 5. */
+ case 0x800000 ... 0x803fff: /* Page 0 ~ 127. */
+ case 0x807e80 ... 0x807eff: /* Page 253. */
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_UDMPU23,
+ TAS2783_SDCA_CTL_UDMPU_CLUSTER, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, TAS2783_SDCA_CTL_FU_MUTE,
+ TAS2783_DEVICE_CHANNEL_LEFT):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x1, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_TG23, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x0a, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x14, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x15, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x16, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 2):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 3):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 4):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 5):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 6):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 7):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 8):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 9):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xa):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xb):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xc):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xd):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xe):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x12, 0xf):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS21, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS24, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS25, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS25, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS127, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS26, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x02, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_CS28, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x05, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 2):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x04, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x05, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x01, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x04, 0):
+ return 1;
+
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x11, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 2):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 3):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 4):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 5):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 6):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x01, 7):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21, 0x02, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x0b, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 2):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x0b, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x0b, 1):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x07, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x09, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x13, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x13, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x11, 0):
+ return 2;
+
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT21, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT26, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT28, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_IT29, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT23, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT24, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT25, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT28, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_OT127, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MU26, 0x06, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU127, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU26, 0x10, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x06, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x12, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_XU22, 0x13, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU21, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x08, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x05, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x06, 0):
+ case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x06, 0):
+ return 4;
+
+ default:
+ return 0;
+ }
+}
+
+static bool tas2783_readable_register(struct device *dev, unsigned int reg)
+{
+ return tas2783_sdca_mbq_size(dev, reg) > 0;
+}
+
+static bool tas2783_volatile_register(struct device *dev, u32 reg)
+{
+ switch (reg) {
+ case 0x000 ... 0x080: /* Data port 0. */
+ case 0x100 ... 0x140: /* Data port 1. */
+ case 0x200 ... 0x240: /* Data port 2. */
+ case 0x300 ... 0x340: /* Data port 3. */
+ case 0x400 ... 0x440: /* Data port 4. */
+ case 0x500 ... 0x540: /* Data port 5. */
+ case 0x800001:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config tas_regmap = {
+ .reg_bits = 32,
+ .val_bits = 8,
+ .readable_reg = tas2783_readable_register,
+ .volatile_reg = tas2783_volatile_register,
+ .reg_defaults = tas2783_reg_default,
+ .num_reg_defaults = ARRAY_SIZE(tas2783_reg_default),
+ .max_register = 0x41008000 + TASDEV_REG_SDW(0xa1, 0x60, 0x7f),
+ .cache_type = REGCACHE_MAPLE,
+ .use_single_read = true,
+ .use_single_write = true,
+};
+
+static const struct regmap_sdw_mbq_cfg tas2783_mbq_cfg = {
+ .mbq_size = tas2783_sdca_mbq_size,
+};
+
+static s32 tas2783_digital_getvol(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return snd_soc_get_volsw(kcontrol, ucontrol);
+}
+
+static s32 tas2783_digital_putvol(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static s32 tas2783_amp_getvol(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return snd_soc_get_volsw(kcontrol, ucontrol);
+}
+
+static s32 tas2783_amp_putvol(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static const struct snd_kcontrol_new tas2783_snd_controls[] = {
+ SOC_SINGLE_RANGE_EXT_TLV("Amp Volume", TAS2783_AMP_LEVEL,
+ 1, 0, 20, 0, tas2783_amp_getvol,
+ tas2783_amp_putvol, tas2781_amp_tlv),
+ SOC_SINGLE_RANGE_EXT_TLV("Speaker Volume", TAS2783_DVC_LVL,
+ 0, 0, 200, 1, tas2783_digital_getvol,
+ tas2783_digital_putvol, tas2781_dvc_tlv),
+};
+
+static s32 tas2783_validate_calibdata(struct tas2783_prv *tas_dev,
+ u8 *data, u32 size)
+{
+ u32 ts, spk_count, size_calculated;
+ u32 crc_calculated, crc_read, i;
+ u32 *tmp_val;
+ struct tm tm;
+
+ i = 0;
+ tmp_val = (u32 *)data;
+ if (tmp_val[i++] != 2783) {
+ dev_err(tas_dev->dev, "cal data magic number mismatch");
+ return -EINVAL;
+ }
+
+ spk_count = tmp_val[i++];
+ if (spk_count > TAS2783_CALIB_MAX_SPK_COUNT) {
+ dev_err(tas_dev->dev, "cal data spk_count too large");
+ return -EINVAL;
+ }
+
+ ts = tmp_val[i++];
+ time64_to_tm(ts, 0, &tm);
+ dev_dbg(tas_dev->dev, "cal data timestamp: %ld-%d-%d %d:%d:%d",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ size_calculated =
+ (spk_count * TAS2783_CALIB_PARAMS * sizeof(u32)) +
+ TAS2783_CALIB_HDR_SZ + TAS2783_CALIB_CRC_SZ;
+ if (size_calculated > TAS2783_CALIB_DATA_SZ) {
+ dev_err(tas_dev->dev, "cali data sz too large");
+ return -EINVAL;
+ } else if (size < size_calculated) {
+ dev_err(tas_dev->dev, "cali data size mismatch calc=%u vs %d\n",
+ size, size_calculated);
+ return -EINVAL;
+ }
+
+ crc_calculated = crc32(~0, data,
+ size_calculated - TAS2783_CALIB_CRC_SZ) ^ ~0;
+ crc_read = tmp_val[(size_calculated - TAS2783_CALIB_CRC_SZ) / sizeof(u32)];
+ if (crc_calculated != crc_read) {
+ dev_err(tas_dev->dev,
+ "calib data integrity check fail, 0x%08x vs 0x%08x\n",
+ crc_calculated, crc_read);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void tas2783_set_calib_params_to_device(struct tas2783_prv *tas_dev, u32 *cali_data)
+{
+ u32 dev_count, offset, i, device_num;
+ u32 reg_value;
+ u8 buf[4];
+
+ dev_count = cali_data[1];
+ offset = 3;
+
+ for (device_num = 0; device_num < dev_count; device_num++) {
+ if (cali_data[offset] != tas_dev->sdw_peripheral->id.unique_id) {
+ offset += TAS2783_CALIB_PARAMS;
+ continue;
+ }
+ offset++;
+
+ for (i = 0; i < ARRAY_SIZE(tas2783_cali_reg); i++) {
+ reg_value = cali_data[offset + i];
+ buf[0] = reg_value >> 24;
+ buf[1] = reg_value >> 16;
+ buf[2] = reg_value >> 8;
+ buf[3] = reg_value & 0xff;
+ regmap_bulk_write(tas_dev->regmap, tas2783_cali_reg[i],
+ buf, sizeof(u32));
+ }
+ break;
+ }
+
+ if (device_num == dev_count)
+ dev_err(tas_dev->dev, "device not found\n");
+ else
+ dev_dbg(tas_dev->dev, "calib data update done\n");
+}
+
+static s32 tas2783_update_calibdata(struct tas2783_prv *tas_dev)
+{
+ efi_guid_t efi_guid = TAS2783_CALI_GUID;
+ u32 attr, i, *tmp_val;
+ unsigned long size;
+ s32 ret;
+ efi_status_t status;
+ static efi_char16_t efi_names[][32] = {
+ L"SmartAmpCalibrationData", L"CALI_DATA"};
+
+ tmp_val = (u32 *)tas_dev->cali_data.data;
+ attr = 0;
+ i = 0;
+
+ /*
+ * In some cases, the calibration is performed in Windows,
+ * and data was saved in UEFI. Linux can access it.
+ */
+ for (i = 0; i < ARRAY_SIZE(efi_names); i++) {
+ size = 0;
+ status = efi.get_variable(efi_names[i], &efi_guid, &attr,
+ &size, NULL);
+ if (size > TAS2783_CALIB_DATA_SZ) {
+ dev_err(tas_dev->dev, "cali data too large\n");
+ break;
+ }
+
+ tas_dev->cali_data.read_sz = size;
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ status = efi.get_variable(efi_names[i], &efi_guid, &attr,
+ &tas_dev->cali_data.read_sz,
+ tas_dev->cali_data.data);
+ dev_dbg(tas_dev->dev, "cali get %lu bytes result:%ld\n",
+ tas_dev->cali_data.read_sz, status);
+ }
+ if (status == EFI_SUCCESS)
+ break;
+ }
+
+ if (status != EFI_SUCCESS) {
+ /* Failed got calibration data from EFI. */
+ dev_dbg(tas_dev->dev, "No calibration data in UEFI.");
+ return 0;
+ }
+
+ mutex_lock(&tas_dev->calib_lock);
+ ret = tas2783_validate_calibdata(tas_dev, tas_dev->cali_data.data,
+ tas_dev->cali_data.read_sz);
+ if (!ret)
+ tas2783_set_calib_params_to_device(tas_dev, tmp_val);
+ mutex_unlock(&tas_dev->calib_lock);
+
+ return ret;
+}
+
+static s32 read_header(const u8 *data, struct bin_header_t *hdr)
+{
+ hdr->vendor_id = get_unaligned_le16(&data[0]);
+ hdr->file_id = get_unaligned_le32(&data[2]);
+ hdr->version = get_unaligned_le16(&data[6]);
+ hdr->length = get_unaligned_le32(&data[8]);
+ return 12;
+}
+
+static void tas2783_fw_ready(const struct firmware *fmw, void *context)
+{
+ struct tas2783_prv *tas_dev =
+ (struct tas2783_prv *)context;
+ const u8 *buf = NULL;
+ s32 offset = 0, img_sz, file_blk_size, ret;
+ struct bin_header_t hdr;
+
+ if (!fmw || !fmw->data) {
+ /* No firmware binary, devices will work in ROM mode. */
+ dev_err(tas_dev->dev,
+ "Failed to read %s, no side-effect on driver running\n",
+ tas_dev->rca_binaryname);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ mutex_lock(&tas_dev->pde_lock);
+ img_sz = fmw->size;
+ buf = fmw->data;
+ offset += FW_DL_OFFSET;
+ while (offset < (img_sz - FW_FL_HDR)) {
+ memset(&hdr, 0, sizeof(hdr));
+ offset += read_header(&buf[offset], &hdr);
+ dev_dbg(tas_dev->dev,
+ "vndr=%d, file=%d, version=%d, len=%d, off=%d\n",
+ hdr.vendor_id, hdr.file_id, hdr.version,
+ hdr.length, offset);
+ /* size also includes the header */
+ file_blk_size = hdr.length - FW_FL_HDR;
+
+ switch (hdr.file_id) {
+ case 0:
+ ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
+ PRAM_ADDR_START, file_blk_size,
+ &buf[offset]);
+ if (ret < 0)
+ dev_err(tas_dev->dev,
+ "PRAM update failed: %d", ret);
+ break;
+
+ case 1:
+ ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
+ YRAM_ADDR_START, file_blk_size,
+ &buf[offset]);
+ if (ret < 0)
+ dev_err(tas_dev->dev,
+ "YRAM update failed: %d", ret);
+
+ break;
+
+ default:
+ ret = -EINVAL;
+ dev_err(tas_dev->dev, "Unsupported file");
+ break;
+ }
+
+ if (ret == 0)
+ offset += file_blk_size;
+ else
+ break;
+ }
+ mutex_unlock(&tas_dev->pde_lock);
+ tas2783_update_calibdata(tas_dev);
+
+out:
+ if (!ret)
+ tas_dev->fw_dl_success = true;
+ tas_dev->fw_dl_task_done = true;
+ wake_up(&tas_dev->fw_wait);
+ if (fmw)
+ release_firmware(fmw);
+}
+
+static inline s32 tas_clear_latch(struct tas2783_prv *priv)
+{
+ return regmap_update_bits(priv->regmap,
+ TASDEV_REG_SDW(0, 0, 0x5c),
+ 0x04, 0x04);
+}
+
+static s32 tas_fu21_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, s32 event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct tas2783_prv *tas_dev = snd_soc_component_get_drvdata(component);
+ s32 mute;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ mute = 0;
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ mute = 1;
+ break;
+ }
+
+ return sdw_write_no_pm(tas_dev->sdw_peripheral,
+ SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU21,
+ TAS2783_SDCA_CTL_FU_MUTE, 1), mute);
+}
+
+static s32 tas_fu23_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, s32 event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct tas2783_prv *tas_dev = snd_soc_component_get_drvdata(component);
+ s32 mute;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ mute = 0;
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ mute = 1;
+ break;
+ }
+
+ return sdw_write_no_pm(tas_dev->sdw_peripheral,
+ SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_FU23,
+ TAS2783_SDCA_CTL_FU_MUTE, 1), mute);
+}
+
+static const struct snd_soc_dapm_widget tas_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("ASI OUT", "ASI Capture", 0, SND_SOC_NOPM,
+ 0, 0),
+ SND_SOC_DAPM_DAC_E("FU21", NULL, SND_SOC_NOPM, 0, 0, tas_fu21_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_DAC_E("FU23", NULL, SND_SOC_NOPM, 0, 0, tas_fu23_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_OUTPUT("SPK"),
+ SND_SOC_DAPM_INPUT("DMIC"),
+};
+
+static const struct snd_soc_dapm_route tas_audio_map[] = {
+ {"FU21", NULL, "ASI"},
+ {"SPK", NULL, "FU21"},
+ {"FU23", NULL, "ASI"},
+ {"SPK", NULL, "FU23"},
+ {"ASI OUT", NULL, "DMIC"},
+};
+
+static s32 tas_set_sdw_stream(struct snd_soc_dai *dai,
+ void *sdw_stream, s32 direction)
+{
+ if (!sdw_stream)
+ return 0;
+
+ snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
+
+ return 0;
+}
+
+static void tas_sdw_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ snd_soc_dai_set_dma_data(dai, substream, NULL);
+}
+
+static s32 tas_sdw_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+ struct tas2783_prv *tas_dev =
+ snd_soc_component_get_drvdata(component);
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
+ struct sdw_stream_runtime *sdw_stream;
+ struct sdw_slave *sdw_peripheral = tas_dev->sdw_peripheral;
+ s32 ret, retry = 3;
+
+ if (!tas_dev->fw_dl_success) {
+ dev_err(tas_dev->dev, "error playback without fw download");
+ return -EINVAL;
+ }
+
+ sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
+ if (!sdw_stream)
+ return -EINVAL;
+
+ ret = tas_clear_latch(tas_dev);
+ if (ret)
+ dev_err(tas_dev->dev,
+ "clear latch failed, err=%d", ret);
+
+ mutex_lock(&tas_dev->pde_lock);
+ /*
+ * Sometimes, there is error returned during power on.
+ * So added retry logic to ensure power on so that
+ * port prepare succeeds
+ */
+ do {
+ ret = regmap_write(tas_dev->regmap,
+ SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23,
+ TAS2783_SDCA_CTL_REQ_POW_STATE, 0),
+ TAS2783_SDCA_POW_STATE_ON);
+ if (!ret)
+ break;
+ usleep_range(2000, 2200);
+ } while (retry--);
+ mutex_unlock(&tas_dev->pde_lock);
+ if (ret)
+ return ret;
+
+ /* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params,
+ &stream_config, &port_config);
+ /* port 1 for playback */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
+ port_config.num = 2;
+
+ ret = sdw_stream_add_slave(sdw_peripheral,
+ &stream_config, &port_config, 1, sdw_stream);
+ if (ret)
+ dev_err(dai->dev, "Unable to configure port\n");
+
+ return ret;
+}
+
+static s32 tas_sdw_pcm_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ s32 ret;
+ struct snd_soc_component *component = dai->component;
+ struct tas2783_prv *tas_dev =
+ snd_soc_component_get_drvdata(component);
+ struct sdw_stream_runtime *sdw_stream =
+ snd_soc_dai_get_dma_data(dai, substream);
+
+ sdw_stream_remove_slave(tas_dev->sdw_peripheral, sdw_stream);
+
+ mutex_lock(&tas_dev->pde_lock);
+ ret = regmap_write(tas_dev->regmap,
+ SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23,
+ TAS2783_SDCA_CTL_REQ_POW_STATE, 0),
+ TAS2783_SDCA_POW_STATE_OFF);
+ mutex_unlock(&tas_dev->pde_lock);
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops tas_dai_ops = {
+ .hw_params = tas_sdw_hw_params,
+ .hw_free = tas_sdw_pcm_hw_free,
+ .set_stream = tas_set_sdw_stream,
+ .shutdown = tas_sdw_shutdown,
+};
+
+static struct snd_soc_dai_driver tas_dai_driver[] = {
+ {
+ .name = "tas2783-codec",
+ .id = 0,
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = TAS2783_DEVICE_RATES,
+ .formats = TAS2783_DEVICE_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = TAS2783_DEVICE_RATES,
+ .formats = TAS2783_DEVICE_FORMATS,
+ },
+ .ops = &tas_dai_ops,
+ .symmetric_rate = 1,
+ },
+};
+
+static s32 tas_component_probe(struct snd_soc_component *component)
+{
+ struct tas2783_prv *tas_dev =
+ snd_soc_component_get_drvdata(component);
+
+ tas_dev->component = component;
+ tas25xx_register_misc(tas_dev->sdw_peripheral);
+
+ return 0;
+}
+
+static void tas_component_remove(struct snd_soc_component *codec)
+{
+ struct tas2783_prv *tas_dev =
+ snd_soc_component_get_drvdata(codec);
+ tas25xx_deregister_misc();
+ tas_dev->component = NULL;
+}
+
+static const struct snd_soc_component_driver soc_codec_driver_tasdevice = {
+ .probe = tas_component_probe,
+ .remove = tas_component_remove,
+ .controls = tas2783_snd_controls,
+ .num_controls = ARRAY_SIZE(tas2783_snd_controls),
+ .dapm_widgets = tas_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tas_dapm_widgets),
+ .dapm_routes = tas_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(tas_audio_map),
+ .idle_bias_on = 1,
+ .endianness = 1,
+};
+
+static s32 tas_init(struct tas2783_prv *tas_dev)
+{
+ s32 ret;
+
+ dev_set_drvdata(tas_dev->dev, tas_dev);
+ ret = devm_snd_soc_register_component(tas_dev->dev,
+ &soc_codec_driver_tasdevice,
+ tas_dai_driver,
+ ARRAY_SIZE(tas_dai_driver));
+ if (ret) {
+ dev_err(tas_dev->dev, "%s: codec register error:%d.\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* set autosuspend parameters */
+ pm_runtime_set_autosuspend_delay(tas_dev->dev, 3000);
+ pm_runtime_use_autosuspend(tas_dev->dev);
+ /* make sure the device does not suspend immediately */
+ pm_runtime_mark_last_busy(tas_dev->dev);
+ pm_runtime_enable(tas_dev->dev);
+
+ return ret;
+}
+
+static s32 tas_read_prop(struct sdw_slave *slave)
+{
+ struct sdw_slave_prop *prop = &slave->prop;
+ s32 nval;
+ s32 i, j;
+ u32 bit;
+ unsigned long addr;
+ struct sdw_dpn_prop *dpn;
+
+ prop->scp_int1_mask =
+ SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+ prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
+
+ prop->paging_support = true;
+
+ /* first we need to allocate memory for set bits in port lists */
+ prop->source_ports = 0x04; /* BITMAP: 00000100 */
+ prop->sink_ports = 0x2; /* BITMAP: 00000010 */
+
+ nval = hweight32(prop->source_ports);
+ prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
+ sizeof(*prop->src_dpn_prop), GFP_KERNEL);
+ if (!prop->src_dpn_prop)
+ return -ENOMEM;
+
+ i = 0;
+ dpn = prop->src_dpn_prop;
+ addr = prop->source_ports;
+ for_each_set_bit(bit, &addr, 32) {
+ dpn[i].num = bit;
+ dpn[i].type = SDW_DPN_FULL;
+ dpn[i].simple_ch_prep_sm = false;
+ dpn[i].ch_prep_timeout = 10;
+ i++;
+ }
+
+ /* do this again for sink now */
+ nval = hweight32(prop->sink_ports);
+ prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
+ sizeof(*prop->sink_dpn_prop), GFP_KERNEL);
+ if (!prop->sink_dpn_prop)
+ return -ENOMEM;
+
+ j = 0;
+ dpn = prop->sink_dpn_prop;
+ addr = prop->sink_ports;
+ for_each_set_bit(bit, &addr, 32) {
+ dpn[j].num = bit;
+ dpn[j].type = SDW_DPN_FULL;
+ dpn[j].simple_ch_prep_sm = false;
+ dpn[j].ch_prep_timeout = 10;
+ j++;
+ }
+
+ /* set the timeout values */
+ prop->clk_stop_timeout = 200;
+
+ return 0;
+}
+
+static s32 tas2783_sdca_dev_suspend(struct device *dev)
+{
+ struct tas2783_prv *tas_dev = dev_get_drvdata(dev);
+
+ if (!tas_dev->hw_init)
+ return 0;
+
+ regcache_cache_only(tas_dev->regmap, true);
+ return 0;
+}
+
+static s32 tas2783_sdca_dev_system_suspend(struct device *dev)
+{
+ return tas2783_sdca_dev_suspend(dev);
+}
+
+static s32 tas2783_sdca_dev_resume(struct device *dev)
+{
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ struct tas2783_prv *tas_dev = dev_get_drvdata(dev);
+ unsigned long t;
+
+ if (!slave->unattach_request)
+ goto regmap_sync;
+
+ t = wait_for_completion_timeout(&slave->initialization_complete,
+ msecs_to_jiffies(TAS2783_PROBE_TIMEOUT));
+ if (!t) {
+ dev_err(&slave->dev, "resume: initialization timed out\n");
+ sdw_show_ping_status(slave->bus, true);
+ return -ETIMEDOUT;
+ }
+
+ slave->unattach_request = 0;
+
+regmap_sync:
+ regcache_cache_only(tas_dev->regmap, false);
+ regcache_sync(tas_dev->regmap);
+ return 0;
+}
+
+static const struct dev_pm_ops tas2783_sdca_pm = {
+ SYSTEM_SLEEP_PM_OPS(tas2783_sdca_dev_system_suspend, tas2783_sdca_dev_resume)
+ RUNTIME_PM_OPS(tas2783_sdca_dev_suspend, tas2783_sdca_dev_resume, NULL)
+};
+
+static s32 tas_io_init(struct device *dev, struct sdw_slave *slave)
+{
+ struct tas2783_prv *tas_dev = dev_get_drvdata(dev);
+ s32 ret;
+ u8 unique_id = tas_dev->sdw_peripheral->id.unique_id;
+
+ if (tas_dev->hw_init)
+ return 0;
+
+ tas_dev->fw_dl_task_done = false;
+ tas_dev->fw_dl_success = false;
+ scnprintf(tas_dev->rca_binaryname, sizeof(tas_dev->rca_binaryname),
+ "tas2783-%01x.bin", unique_id);
+
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
+ tas_dev->rca_binaryname, tas_dev->dev,
+ GFP_KERNEL, tas_dev, tas2783_fw_ready);
+ if (ret) {
+ dev_err(tas_dev->dev,
+ "firmware request failed for uid=%d, ret=%d\n",
+ unique_id, ret);
+ return ret;
+ }
+
+ ret = wait_event_timeout(tas_dev->fw_wait, tas_dev->fw_dl_task_done,
+ msecs_to_jiffies(TIMEOUT_FW_DL_MS));
+ if (!ret) {
+ dev_err(tas_dev->dev, "fw request, wait_event timeout\n");
+ ret = -EAGAIN;
+ } else {
+ ret = regmap_multi_reg_write(tas_dev->regmap, tas2783_init_seq,
+ ARRAY_SIZE(tas2783_init_seq));
+ tas_dev->hw_init = true;
+ }
+
+ return ret;
+}
+
+static s32 tas_update_status(struct sdw_slave *slave,
+ enum sdw_slave_status status)
+{
+ struct tas2783_prv *tas_dev = dev_get_drvdata(&slave->dev);
+ struct device *dev = &slave->dev;
+
+ dev_dbg(dev, "Peripheral status = %s",
+ status == SDW_SLAVE_UNATTACHED ? "unattached" :
+ status == SDW_SLAVE_ATTACHED ? "attached" : "alert");
+
+ tas_dev->status = status;
+ if (status == SDW_SLAVE_UNATTACHED)
+ tas_dev->hw_init = false;
+
+ /* Perform initialization only if slave status
+ * is present and hw_init flag is false
+ */
+ if (tas_dev->hw_init || tas_dev->status != SDW_SLAVE_ATTACHED)
+ return 0;
+
+ /* updated the cache data to device */
+ regcache_cache_only(tas_dev->regmap, false);
+ regcache_sync(tas_dev->regmap);
+
+ /* perform I/O transfers required for Slave initialization */
+ return tas_io_init(&slave->dev, slave);
+}
+
+static const struct sdw_slave_ops tas_sdw_ops = {
+ .read_prop = tas_read_prop,
+ .update_status = tas_update_status,
+};
+
+static void tas_remove(struct tas2783_prv *tas_dev)
+{
+ snd_soc_unregister_component(tas_dev->dev);
+}
+
+static s32 tas_sdw_probe(struct sdw_slave *peripheral,
+ const struct sdw_device_id *id)
+{
+ struct regmap *regmap;
+ struct device *dev = &peripheral->dev;
+ struct tas2783_prv *tas_dev;
+
+ tas_dev = devm_kzalloc(dev, sizeof(*tas_dev), GFP_KERNEL);
+ if (!tas_dev)
+ return dev_err_probe(dev, -ENOMEM,
+ "Failed devm_kzalloc");
+
+ tas_dev->dev = dev;
+ tas_dev->sdw_peripheral = peripheral;
+ tas_dev->hw_init = false;
+ mutex_init(&tas_dev->calib_lock);
+ mutex_init(&tas_dev->pde_lock);
+
+ init_waitqueue_head(&tas_dev->fw_wait);
+ dev_set_drvdata(dev, tas_dev);
+ regmap = devm_regmap_init_sdw_mbq_cfg(peripheral,
+ &tas_regmap,
+ &tas2783_mbq_cfg);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap),
+ "Failed devm_regmap_init_sdw.");
+
+ /* keep in cache until the device is fully initialized */
+ regcache_cache_only(regmap, true);
+ tas_dev->regmap = regmap;
+ return tas_init(tas_dev);
+}
+
+static s32 tas_sdw_remove(struct sdw_slave *peripheral)
+{
+ struct tas2783_prv *tas_dev = dev_get_drvdata(&peripheral->dev);
+
+ pm_runtime_disable(tas_dev->dev);
+ tas_remove(tas_dev);
+ mutex_destroy(&tas_dev->calib_lock);
+ mutex_destroy(&tas_dev->pde_lock);
+ dev_set_drvdata(&peripheral->dev, NULL);
+
+ return 0;
+}
+
+static const struct sdw_device_id tas_sdw_id[] = {
+ /* chipid for the TAS2783 is 0x0000 */
+ SDW_SLAVE_ENTRY(0x0102, 0x0000, 0),
+ {},
+};
+MODULE_DEVICE_TABLE(sdw, tas_sdw_id);
+
+static struct sdw_driver tas_sdw_driver = {
+ .driver = {
+ .name = "slave-tas2783",
+ .pm = pm_ptr(&tas2783_sdca_pm),
+ },
+ .probe = tas_sdw_probe,
+ .remove = tas_sdw_remove,
+ .ops = &tas_sdw_ops,
+ .id_table = tas_sdw_id,
+};
+module_sdw_driver(tas_sdw_driver);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("ASoC TAS2783 SoundWire Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tas2783.h b/sound/soc/codecs/tas2783.h
new file mode 100644
index 000000000000..794333e0a350
--- /dev/null
+++ b/sound/soc/codecs/tas2783.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * ALSA SoC Texas Instruments TAS2783 Audio Smart Amplifier
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated
+ * https://www.ti.com
+ *
+ * The TAS2783 driver implements a flexible and configurable
+ * algo coefficient setting for single TAS2783 chips.
+ *
+ * Author: Niranjan H Y <niranjanhy@ti.com>
+ * Author: Baojun Xu <baojun.xu@ti.com>
+ */
+#include <linux/workqueue.h>
+
+#ifndef __TAS2783_H__
+#define __TAS2783_H__
+
+#define TAS2783_DEVICE_RATES (SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_88200)
+#define TAS2783_DEVICE_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+/* book, page, register */
+#define TASDEV_REG_SDW(book, page, reg) (((book) * 256 * 128) + \
+ 0x800000 + ((page) * 128) + (reg))
+
+/* Volume control */
+#define TAS2783_DVC_LVL TASDEV_REG_SDW(0x0, 0x00, 0x1A)
+#define TAS2783_AMP_LEVEL TASDEV_REG_SDW(0x0, 0x00, 0x03)
+#define TAS2783_AMP_LEVEL_MASK GENMASK(5, 1)
+
+#define PRAM_ADDR_START TASDEV_REG_SDW(0x8c, 0x01, 0x8)
+#define PRAM_ADDR_END TASDEV_REG_SDW(0x8c, 0xff, 0x7f)
+#define YRAM_ADDR_START TASDEV_REG_SDW(0x00, 0x02, 0x8)
+#define YRAM_ADDR_END TASDEV_REG_SDW(0x00, 0x37, 0x7f)
+
+/* Calibration data */
+#define TAS2783_CAL_R0 TASDEV_REG_SDW(0, 0x16, 0x4C)
+#define TAS2783_CAL_INVR0 TASDEV_REG_SDW(0, 0x16, 0x5C)
+#define TAS2783_CAL_R0LOW TASDEV_REG_SDW(0, 0x16, 0x64)
+#define TAS2783_CAL_POWER TASDEV_REG_SDW(0, 0x15, 0x44)
+#define TAS2783_CAL_TLIM TASDEV_REG_SDW(0, 0x17, 0x58)
+
+/* TAS2783 SDCA Control - function number */
+#define FUNC_NUM_SMART_AMP 0x01
+
+/* TAS2783 SDCA entity */
+
+#define TAS2783_SDCA_ENT_FU21 0x01
+#define TAS2783_SDCA_ENT_FU23 0x02
+#define TAS2783_SDCA_ENT_FU26 0x03
+#define TAS2783_SDCA_ENT_XU22 0x04
+#define TAS2783_SDCA_ENT_CS24 0x05
+#define TAS2783_SDCA_ENT_CS21 0x06
+#define TAS2783_SDCA_ENT_CS25 0x07
+#define TAS2783_SDCA_ENT_CS26 0x08
+#define TAS2783_SDCA_ENT_CS28 0x09
+#define TAS2783_SDCA_ENT_PDE23 0x0C
+#define TAS2783_SDCA_ENT_UDMPU23 0x0E
+#define TAS2783_SDCA_ENT_SAPU29 0x0F
+#define TAS2783_SDCA_ENT_PPU21 0x10
+#define TAS2783_SDCA_ENT_PPU26 0x11
+#define TAS2783_SDCA_ENT_TG23 0x12
+#define TAS2783_SDCA_ENT_IT21 0x13
+#define TAS2783_SDCA_ENT_IT29 0x14
+#define TAS2783_SDCA_ENT_IT26 0x15
+#define TAS2783_SDCA_ENT_IT28 0x16
+#define TAS2783_SDCA_ENT_OT24 0x17
+#define TAS2783_SDCA_ENT_OT23 0x18
+#define TAS2783_SDCA_ENT_OT25 0x19
+#define TAS2783_SDCA_ENT_OT28 0x1A
+#define TAS2783_SDCA_ENT_MU26 0x1b
+#define TAS2783_SDCA_ENT_OT127 0x1E
+#define TAS2783_SDCA_ENT_FU127 0x1F
+#define TAS2783_SDCA_ENT_CS127 0x20
+#define TAS2783_SDCA_ENT_MFPU21 0x22
+#define TAS2783_SDCA_ENT_MFPU26 0x23
+
+/* TAS2783 SDCA control */
+#define TAS2783_SDCA_CTL_REQ_POW_STATE 0x01
+#define TAS2783_SDCA_CTL_FU_MUTE 0x01
+#define TAS2783_SDCA_CTL_UDMPU_CLUSTER 0x10
+
+#define TAS2783_DEVICE_CHANNEL_LEFT 1
+#define TAS2783_DEVICE_CHANNEL_RIGHT 2
+
+#define TAS2783_SDCA_POW_STATE_ON 0
+#define TAS2783_SDCA_POW_STATE_OFF 3
+
+/* calibration data */
+#define TAS2783_CALIB_PARAMS 6 /* 5 + 1 unique id */
+#define TAS2783_CALIB_MAX_SPK_COUNT 8
+#define TAS2783_CALIB_HDR_SZ 12
+#define TAS2783_CALIB_CRC_SZ 4
+#define TAS2783_CALIB_DATA_SZ ((TAS2783_CALIB_HDR_SZ) + TAS2783_CALIB_CRC_SZ + \
+ ((TAS2783_CALIB_PARAMS) * 4 * (TAS2783_CALIB_MAX_SPK_COUNT)))
+
+#if IS_ENABLED(CONFIG_SND_SOC_TAS2783_UTIL)
+int32_t tas25xx_register_misc(struct sdw_slave *peripheral);
+int32_t tas25xx_deregister_misc(void);
+#else
+static void tas25xx_register_misc(struct sdw_slave *peripheral) {}
+static void tas25xx_deregister_misc(void) {}
+#endif
+
+#endif /*__TAS2783_H__ */
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 7399080f8580..715a07ab97b9 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -1277,8 +1277,8 @@ static int aic32x4_setup_regulators(struct device *dev,
/* Check if the regulator requirements are fulfilled */
if (IS_ERR(aic32x4->supply_iov)) {
- dev_err(dev, "Missing supply 'iov'\n");
- return PTR_ERR(aic32x4->supply_iov);
+ return dev_err_probe(dev, PTR_ERR(aic32x4->supply_iov),
+ "Missing supply 'iov'\n");
}
if (IS_ERR(aic32x4->supply_ldo)) {
@@ -1286,12 +1286,12 @@ static int aic32x4_setup_regulators(struct device *dev,
return -EPROBE_DEFER;
if (IS_ERR(aic32x4->supply_dv)) {
- dev_err(dev, "Missing supply 'dv' or 'ldoin'\n");
- return PTR_ERR(aic32x4->supply_dv);
+ return dev_err_probe(dev, PTR_ERR(aic32x4->supply_dv),
+ "Missing supply 'dv' or 'ldoin'\n");
}
if (IS_ERR(aic32x4->supply_av)) {
- dev_err(dev, "Missing supply 'av' or 'ldoin'\n");
- return PTR_ERR(aic32x4->supply_av);
+ return dev_err_probe(dev, PTR_ERR(aic32x4->supply_av),
+ "Missing supply 'av' or 'ldoin'\n");
}
} else {
if (PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER)
@@ -1383,10 +1383,8 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap,
}
ret = aic32x4_setup_regulators(dev, aic32x4);
- if (ret) {
- dev_err(dev, "Failed to setup regulators\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to setup regulators\n");
if (aic32x4->rstn_gpio) {
ndelay(10);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index f1649df19738..eea8ca285f8e 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -121,6 +121,16 @@ static const struct reg_default aic3x_reg[] = {
{ 108, 0x00 }, { 109, 0x00 },
};
+static const struct reg_sequence aic3007_class_d[] = {
+ /* Class-D speaker driver init; datasheet p. 46 */
+ { AIC3X_PAGE_SELECT, 0x0D },
+ { 0xD, 0x0D },
+ { 0x8, 0x5C },
+ { 0x8, 0x5D },
+ { 0x8, 0x5C },
+ { AIC3X_PAGE_SELECT, 0x00 },
+};
+
static bool aic3x_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -1393,6 +1403,10 @@ static int aic3x_set_power(struct snd_soc_component *component, int power)
gpiod_set_value(aic3x->gpio_reset, 0);
}
+ if (aic3x->model == AIC3X_MODEL_3007)
+ regmap_multi_reg_write_bypassed(aic3x->regmap, aic3007_class_d,
+ ARRAY_SIZE(aic3007_class_d));
+
/* Sync reg_cache with the hardware */
regcache_cache_only(aic3x->regmap, false);
regcache_sync(aic3x->regmap);
@@ -1723,17 +1737,6 @@ static void aic3x_configure_ocmv(struct device *dev, struct aic3x_priv *aic3x)
}
}
-
-static const struct reg_sequence aic3007_class_d[] = {
- /* Class-D speaker driver init; datasheet p. 46 */
- { AIC3X_PAGE_SELECT, 0x0D },
- { 0xD, 0x0D },
- { 0x8, 0x5C },
- { 0x8, 0x5D },
- { 0x8, 0x5C },
- { AIC3X_PAGE_SELECT, 0x00 },
-};
-
int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver_data)
{
struct aic3x_priv *aic3x;
@@ -1823,13 +1826,6 @@ int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver
aic3x_configure_ocmv(dev, aic3x);
- if (aic3x->model == AIC3X_MODEL_3007) {
- ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
- ARRAY_SIZE(aic3007_class_d));
- if (ret != 0)
- dev_err(dev, "Failed to init class D: %d\n", ret);
- }
-
ret = devm_snd_soc_register_component(dev, &soc_component_dev_aic3x, &aic3x_dai, 1);
if (ret)
return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 423b9264a205..c495be1cf2ed 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -14,7 +14,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -24,7 +24,6 @@
#include <sound/initval.h>
#include <sound/tlv.h>
-#include <sound/tlv320dac33-plat.h>
#include "tlv320dac33.h"
/*
@@ -80,7 +79,7 @@ struct tlv320dac33_priv {
struct snd_soc_component *component;
struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
struct snd_pcm_substream *substream;
- int power_gpio;
+ struct gpio_desc *reset_gpiod;
int chip_power;
int irq;
unsigned int refclk;
@@ -383,14 +382,26 @@ static int dac33_hard_power(struct snd_soc_component *component, int power)
goto exit;
}
- if (dac33->power_gpio >= 0)
- gpio_set_value(dac33->power_gpio, 1);
+ if (dac33->reset_gpiod) {
+ ret = gpiod_set_value(dac33->reset_gpiod, 1);
+ if (ret < 0) {
+ dev_err(&dac33->i2c->dev,
+ "Failed to set reset GPIO: %d\n", ret);
+ goto exit;
+ }
+ }
dac33->chip_power = 1;
} else {
dac33_soft_power(component, 0);
- if (dac33->power_gpio >= 0)
- gpio_set_value(dac33->power_gpio, 0);
+ if (dac33->reset_gpiod) {
+ ret = gpiod_set_value(dac33->reset_gpiod, 0);
+ if (ret < 0) {
+ dev_err(&dac33->i2c->dev,
+ "Failed to set reset GPIO: %d\n", ret);
+ goto exit;
+ }
+ }
ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
dac33->supplies);
@@ -1462,16 +1473,9 @@ static struct snd_soc_dai_driver dac33_dai = {
static int dac33_i2c_probe(struct i2c_client *client)
{
- struct tlv320dac33_platform_data *pdata;
struct tlv320dac33_priv *dac33;
int ret, i;
- if (client->dev.platform_data == NULL) {
- dev_err(&client->dev, "Platform data not set\n");
- return -ENODEV;
- }
- pdata = client->dev.platform_data;
-
dac33 = devm_kzalloc(&client->dev, sizeof(struct tlv320dac33_priv),
GFP_KERNEL);
if (dac33 == NULL)
@@ -1488,26 +1492,22 @@ static int dac33_i2c_probe(struct i2c_client *client)
i2c_set_clientdata(client, dac33);
- dac33->power_gpio = pdata->power_gpio;
- dac33->burst_bclkdiv = pdata->burst_bclkdiv;
- dac33->keep_bclk = pdata->keep_bclk;
- dac33->mode1_latency = pdata->mode1_latency;
+ if (!dac33->burst_bclkdiv)
+ dac33->burst_bclkdiv = 8;
if (!dac33->mode1_latency)
dac33->mode1_latency = 10000; /* 10ms */
dac33->irq = client->irq;
/* Disable FIFO use by default */
dac33->fifo_mode = DAC33_FIFO_BYPASS;
- /* Check if the reset GPIO number is valid and request it */
- if (dac33->power_gpio >= 0) {
- ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
- if (ret < 0) {
- dev_err(&client->dev,
- "Failed to request reset GPIO (%d)\n",
- dac33->power_gpio);
- goto err_gpio;
- }
- gpio_direction_output(dac33->power_gpio, 0);
+ /* request optional reset GPIO */
+ dac33->reset_gpiod =
+ devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(dac33->reset_gpiod)) {
+ ret = PTR_ERR(dac33->reset_gpiod);
+ dev_err_probe(&client->dev, ret,
+ "Failed to get reset GPIO\n");
+ goto err;
}
for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
@@ -1518,19 +1518,17 @@ static int dac33_i2c_probe(struct i2c_client *client)
if (ret != 0) {
dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
- goto err_get;
+ goto err;
}
ret = devm_snd_soc_register_component(&client->dev,
&soc_component_dev_tlv320dac33, &dac33_dai, 1);
if (ret < 0)
- goto err_get;
+ goto err;
return ret;
-err_get:
- if (dac33->power_gpio >= 0)
- gpio_free(dac33->power_gpio);
-err_gpio:
+
+err:
return ret;
}
@@ -1540,9 +1538,6 @@ static void dac33_i2c_remove(struct i2c_client *client)
if (unlikely(dac33->chip_power))
dac33_hard_power(dac33->component, 0);
-
- if (dac33->power_gpio >= 0)
- gpio_free(dac33->power_gpio);
}
static const struct i2c_device_id tlv320dac33_i2c_id[] = {
diff --git a/sound/soc/codecs/wcd-common.c b/sound/soc/codecs/wcd-common.c
new file mode 100644
index 000000000000..9016e974582f
--- /dev/null
+++ b/sound/soc/codecs/wcd-common.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
+
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/component.h>
+#include <linux/pm_runtime.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <linux/regmap.h>
+
+#include "wcd-common.h"
+
+#define WCD_MIN_MICBIAS_MV 1000
+#define WCD_DEF_MICBIAS_MV 1800
+#define WCD_MAX_MICBIAS_MV 2850
+
+#define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
+
+int wcd_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv)
+{
+ /* min micbias voltage is 1V and maximum is 2.85V */
+ if (micb_mv < WCD_MIN_MICBIAS_MV || micb_mv > WCD_MAX_MICBIAS_MV) {
+ dev_err(dev, "Unsupported micbias voltage (%u mV)\n", micb_mv);
+ return -EINVAL;
+ }
+
+ return (micb_mv - WCD_MIN_MICBIAS_MV) / 50;
+}
+EXPORT_SYMBOL_GPL(wcd_get_micb_vout_ctl_val);
+
+static int wcd_get_micbias_val(struct device *dev, int micb_num, u32 *micb_mv)
+{
+ char micbias[64];
+ int mv;
+
+ sprintf(micbias, "qcom,micbias%d-microvolt", micb_num);
+
+ if (of_property_read_u32(dev->of_node, micbias, &mv)) {
+ dev_err(dev, "%s value not found, using default\n", micbias);
+ mv = WCD_DEF_MICBIAS_MV;
+ } else {
+ /* convert it to milli volts */
+ mv = mv/1000;
+ }
+ if (micb_mv)
+ *micb_mv = mv;
+
+ mv = wcd_get_micb_vout_ctl_val(dev, mv);
+ if (mv < 0) {
+ dev_err(dev, "Unsupported %s voltage (%d mV), falling back to default (%d mV)\n",
+ micbias, mv, WCD_DEF_MICBIAS_MV);
+ return wcd_get_micb_vout_ctl_val(dev, WCD_DEF_MICBIAS_MV);
+ }
+
+ return mv;
+}
+
+int wcd_dt_parse_micbias_info(struct wcd_common *common)
+{
+ int ret, i;
+
+ for (i = 0; i < common->max_bias; i++) {
+ ret = wcd_get_micbias_val(common->dev, i + 1, &common->micb_mv[i]);
+ if (ret < 0)
+ return ret;
+ common->micb_vout[i] = ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wcd_dt_parse_micbias_info);
+
+static int wcd_sdw_component_bind(struct device *dev, struct device *master, void *data)
+{
+ pm_runtime_set_autosuspend_delay(dev, 3000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ return 0;
+}
+
+static void wcd_sdw_component_unbind(struct device *dev, struct device *master, void *data)
+{
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+}
+
+const struct component_ops wcd_sdw_component_ops = {
+ .bind = wcd_sdw_component_bind,
+ .unbind = wcd_sdw_component_unbind,
+};
+EXPORT_SYMBOL_GPL(wcd_sdw_component_ops);
+
+int wcd_update_status(struct sdw_slave *slave, enum sdw_slave_status status)
+{
+ struct regmap *regmap = dev_get_regmap(&slave->dev, NULL);
+
+ if (regmap && status == SDW_SLAVE_ATTACHED) {
+ /* Write out any cached changes that happened between probe and attach */
+ regcache_cache_only(regmap, false);
+ return regcache_sync(regmap);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wcd_update_status);
+
+int wcd_bus_config(struct sdw_slave *slave, struct sdw_bus_params *params)
+{
+ sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank), 0x01);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wcd_bus_config);
+
+int wcd_interrupt_callback(struct sdw_slave *slave, struct irq_domain *slave_irq,
+ unsigned int wcd_intr_status0, unsigned int wcd_intr_status1,
+ unsigned int wcd_intr_status2)
+{
+ struct regmap *regmap = dev_get_regmap(&slave->dev, NULL);
+ u32 sts1, sts2, sts3;
+
+ do {
+ handle_nested_irq(irq_find_mapping(slave_irq, 0));
+ regmap_read(regmap, wcd_intr_status0, &sts1);
+ regmap_read(regmap, wcd_intr_status1, &sts2);
+ regmap_read(regmap, wcd_intr_status2, &sts3);
+
+ } while (sts1 || sts2 || sts3);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(wcd_interrupt_callback);
+
+MODULE_DESCRIPTION("Common Qualcomm WCD Codec helpers driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wcd-common.h b/sound/soc/codecs/wcd-common.h
new file mode 100644
index 000000000000..d5c156e641fc
--- /dev/null
+++ b/sound/soc/codecs/wcd-common.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __WCD_COMMON_H__
+#define __WCD_COMMON_H__
+
+struct device;
+struct sdw_slave;
+struct sdw_bus_params;
+struct irq_domain;
+enum sdw_slave_status;
+
+#define WCD_MAX_MICBIAS 4
+
+struct wcd_sdw_ch_info {
+ int port_num;
+ unsigned int ch_mask;
+ unsigned int master_ch_mask;
+};
+
+#define WCD_SDW_CH(id, pn, cmask) \
+ [id] = { \
+ .port_num = pn, \
+ .ch_mask = cmask, \
+ .master_ch_mask = cmask, \
+ }
+
+struct wcd_common {
+ struct device *dev;
+ int max_bias;
+ u32 micb_mv[WCD_MAX_MICBIAS];
+ u32 micb_vout[WCD_MAX_MICBIAS];
+};
+
+extern const struct component_ops wcd_sdw_component_ops;
+int wcd_get_micb_vout_ctl_val(struct device *dev, u32 micb_mv);
+int wcd_dt_parse_micbias_info(struct wcd_common *common);
+int wcd_update_status(struct sdw_slave *slave, enum sdw_slave_status status);
+int wcd_bus_config(struct sdw_slave *slave, struct sdw_bus_params *params);
+int wcd_interrupt_callback(struct sdw_slave *slave, struct irq_domain *slave_irq,
+ unsigned int wcd_intr_status0, unsigned int wcd_intr_status1,
+ unsigned int wcd_intr_status2);
+
+#endif /* __WCD_COMMON_H__ */
diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 1bb7e1dc7e6b..3c22f7149af8 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -21,6 +21,7 @@
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "wcd-clsh-v2.h"
+#include "wcd-common.h"
#include "wcd-mbhc-v2.h"
#include <dt-bindings/sound/qcom,wcd934x.h>
@@ -116,9 +117,6 @@
#define WCD934X_DEC_PWR_LVL_DF 0x00
#define WCD934X_DEC_PWR_LVL_HYBRID WCD934X_DEC_PWR_LVL_DF
-#define WCD934X_DEF_MICBIAS_MV 1800
-#define WCD934X_MAX_MICBIAS_MV 2850
-
#define WCD_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX)
#define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \
@@ -530,6 +528,7 @@ struct wcd934x_codec {
struct slim_device *sdev;
struct slim_device *sidev;
struct wcd_clsh_ctrl *clsh_ctrl;
+ struct wcd_common common;
struct snd_soc_component *component;
struct wcd934x_slim_ch rx_chs[WCD934X_RX_MAX];
struct wcd934x_slim_ch tx_chs[WCD934X_TX_MAX];
@@ -555,7 +554,6 @@ struct wcd934x_codec {
struct mutex micb_lock;
u32 micb_ref[WCD934X_MAX_MICBIAS];
u32 pullup_ref[WCD934X_MAX_MICBIAS];
- u32 micb2_mv;
};
#define to_wcd934x_codec(_hw) container_of(_hw, struct wcd934x_codec, hw)
@@ -2168,55 +2166,24 @@ static struct clk *wcd934x_register_mclk_output(struct wcd934x_codec *wcd)
return NULL;
}
-static int wcd934x_get_micbias_val(struct device *dev, const char *micbias,
- u32 *micb_mv)
-{
- int mv;
-
- if (of_property_read_u32(dev->parent->of_node, micbias, &mv)) {
- dev_err(dev, "%s value not found, using default\n", micbias);
- mv = WCD934X_DEF_MICBIAS_MV;
- } else {
- /* convert it to milli volts */
- mv = mv/1000;
- }
-
- if (mv < 1000 || mv > 2850) {
- dev_err(dev, "%s value not in valid range, using default\n",
- micbias);
- mv = WCD934X_DEF_MICBIAS_MV;
- }
-
- if (micb_mv)
- *micb_mv = mv;
-
- return (mv - 1000) / 50;
-}
-
static int wcd934x_init_dmic(struct snd_soc_component *comp)
{
- int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
u32 def_dmic_rate, dmic_clk_drv;
+ int ret;
- vout_ctl_1 = wcd934x_get_micbias_val(comp->dev,
- "qcom,micbias1-microvolt", NULL);
- vout_ctl_2 = wcd934x_get_micbias_val(comp->dev,
- "qcom,micbias2-microvolt",
- &wcd->micb2_mv);
- vout_ctl_3 = wcd934x_get_micbias_val(comp->dev,
- "qcom,micbias3-microvolt", NULL);
- vout_ctl_4 = wcd934x_get_micbias_val(comp->dev,
- "qcom,micbias4-microvolt", NULL);
+ ret = wcd_dt_parse_mbhc_data(comp->dev, &wcd->mbhc_cfg);
+ if (ret)
+ return ret;
snd_soc_component_update_bits(comp, WCD934X_ANA_MICB1,
- WCD934X_MICB_VAL_MASK, vout_ctl_1);
+ WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[0]);
snd_soc_component_update_bits(comp, WCD934X_ANA_MICB2,
- WCD934X_MICB_VAL_MASK, vout_ctl_2);
+ WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[1]);
snd_soc_component_update_bits(comp, WCD934X_ANA_MICB3,
- WCD934X_MICB_VAL_MASK, vout_ctl_3);
+ WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[2]);
snd_soc_component_update_bits(comp, WCD934X_ANA_MICB4,
- WCD934X_MICB_VAL_MASK, vout_ctl_4);
+ WCD934X_MICB_VAL_MASK, wcd->common.micb_vout[3]);
if (wcd->rate == WCD934X_MCLK_CLK_9P6MHZ)
def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
@@ -2517,15 +2484,6 @@ static void wcd934x_mbhc_micb_ramp_control(struct snd_soc_component *component,
}
}
-static int wcd934x_get_micb_vout_ctl_val(u32 micb_mv)
-{
- /* min micbias voltage is 1V and maximum is 2.85V */
- if (micb_mv < 1000 || micb_mv > 2850)
- return -EINVAL;
-
- return (micb_mv - 1000) / 50;
-}
-
static int wcd934x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
int req_volt, int micb_num)
{
@@ -2562,7 +2520,7 @@ static int wcd934x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
WCD934X_MICB_VAL_MASK);
- req_vout_ctl = wcd934x_get_micb_vout_ctl_val(req_volt);
+ req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
if (req_vout_ctl < 0) {
ret = -EINVAL;
goto exit;
@@ -2610,10 +2568,10 @@ static int wcd934x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
* voltage needed to detect threshold microphone, then do
* not change the micbias, just return.
*/
- if (wcd934x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ if (wcd934x->common.micb_mv[1] >= WCD_MBHC_THR_HS_MICB_MV)
return 0;
- micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd934x->micb2_mv;
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd934x->common.micb_mv[1];
rc = wcd934x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
@@ -3036,7 +2994,7 @@ static void wcd934x_mbhc_deinit(struct snd_soc_component *component)
static int wcd934x_comp_probe(struct snd_soc_component *component)
{
struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
- int i;
+ int i, ret;
snd_soc_component_init_regmap(component, wcd->regmap);
wcd->component = component;
@@ -3054,7 +3012,12 @@ static int wcd934x_comp_probe(struct snd_soc_component *component)
for (i = 0; i < NUM_CODEC_DAIS; i++)
INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
- wcd934x_init_dmic(component);
+
+ ret = wcd934x_init_dmic(component);
+ if (ret) {
+ dev_err(component->dev, "Failed to Initialize micbias\n");
+ return ret;
+ }
if (wcd934x_mbhc_init(component))
dev_err(component->dev, "Failed to Initialize MBHC\n");
@@ -5831,6 +5794,13 @@ static const struct snd_soc_component_driver wcd934x_component_drv = {
.endianness = 1,
};
+static void wcd934x_put_device_action(void *data)
+{
+ struct device *dev = data;
+
+ put_device(dev);
+}
+
static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
{
struct device *dev = &wcd->sdev->dev;
@@ -5847,11 +5817,13 @@ static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
return dev_err_probe(dev, -EINVAL, "Unable to get SLIM Interface device\n");
slim_get_logical_addr(wcd->sidev);
- wcd->if_regmap = regmap_init_slimbus(wcd->sidev,
+ wcd->if_regmap = devm_regmap_init_slimbus(wcd->sidev,
&wcd934x_ifc_regmap_config);
- if (IS_ERR(wcd->if_regmap))
+ if (IS_ERR(wcd->if_regmap)) {
+ put_device(&wcd->sidev->dev);
return dev_err_probe(dev, PTR_ERR(wcd->if_regmap),
"Failed to allocate ifc register map\n");
+ }
of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate",
&wcd->dmic_sample_rate);
@@ -5860,14 +5832,13 @@ static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
cfg->anc_micbias = MIC_BIAS_2;
cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
cfg->num_btn = WCD934X_MBHC_MAX_BUTTONS;
- cfg->micb_mv = wcd->micb2_mv;
+ cfg->micb_mv = wcd->common.micb_mv[1];
cfg->linein_th = 5000;
cfg->hs_thr = 1700;
cfg->hph_thr = 50;
wcd_dt_parse_mbhc_data(dev, cfg);
-
return 0;
}
@@ -5888,11 +5859,17 @@ static int wcd934x_codec_probe(struct platform_device *pdev)
wcd->sdev = to_slim_device(data->dev);
mutex_init(&wcd->sysclk_mutex);
mutex_init(&wcd->micb_lock);
+ wcd->common.dev = dev->parent;
+ wcd->common.max_bias = 4;
ret = wcd934x_codec_parse_data(wcd);
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, wcd934x_put_device_action, &wcd->sidev->dev);
+ if (ret)
+ return ret;
+
/* set default rate 9P6MHz */
regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
diff --git a/sound/soc/codecs/wcd937x-sdw.c b/sound/soc/codecs/wcd937x-sdw.c
index 1bfe7383b311..1878d67e3fa1 100644
--- a/sound/soc/codecs/wcd937x-sdw.c
+++ b/sound/soc/codecs/wcd937x-sdw.c
@@ -19,7 +19,7 @@
#include <sound/soc.h>
#include "wcd937x.h"
-static struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
+static struct wcd_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD937X_HPH_L, WCD937X_HPH_PORT, BIT(0)),
WCD_SDW_CH(WCD937X_HPH_R, WCD937X_HPH_PORT, BIT(1)),
WCD_SDW_CH(WCD937X_CLSH, WCD937X_CLSH_PORT, BIT(0)),
@@ -30,7 +30,7 @@ static struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD937X_DSD_R, WCD937X_DSD_PORT, BIT(1)),
};
-static struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = {
+static struct wcd_sdw_ch_info wcd937x_sdw_tx_ch_info[] = {
WCD_SDW_CH(WCD937X_ADC1, WCD937X_ADC_1_PORT, BIT(0)),
WCD_SDW_CH(WCD937X_ADC2, WCD937X_ADC_2_3_PORT, BIT(0)),
WCD_SDW_CH(WCD937X_ADC3, WCD937X_ADC_2_3_PORT, BIT(0)),
@@ -78,12 +78,6 @@ static struct sdw_dpn_prop wcd937x_dpn_prop[WCD937X_MAX_SWR_PORTS] = {
}
};
-struct device *wcd937x_sdw_device_get(struct device_node *np)
-{
- return bus_find_device_by_of_node(&sdw_bus_type, np);
-}
-EXPORT_SYMBOL_GPL(wcd937x_sdw_device_get);
-
int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
@@ -118,19 +112,6 @@ int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,
}
EXPORT_SYMBOL_GPL(wcd937x_sdw_hw_params);
-static int wcd9370_update_status(struct sdw_slave *slave, enum sdw_slave_status status)
-{
- struct wcd937x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
-
- if (wcd->regmap && status == SDW_SLAVE_ATTACHED) {
- /* Write out any cached changes that happened between probe and attach */
- regcache_cache_only(wcd->regmap, false);
- return regcache_sync(wcd->regmap);
- }
-
- return 0;
-}
-
/*
* Handle Soundwire out-of-band interrupt event by triggering
* the first irq of the slave_irq irq domain, which then will
@@ -141,18 +122,9 @@ static int wcd9370_interrupt_callback(struct sdw_slave *slave,
struct sdw_slave_intr_status *status)
{
struct wcd937x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
- struct irq_domain *slave_irq = wcd->slave_irq;
- u32 sts1, sts2, sts3;
-
- do {
- handle_nested_irq(irq_find_mapping(slave_irq, 0));
- regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &sts1);
- regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &sts2);
- regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &sts3);
- } while (sts1 || sts2 || sts3);
-
- return IRQ_HANDLED;
+ return wcd_interrupt_callback(slave, wcd->slave_irq, WCD937X_DIGITAL_INTR_STATUS_0,
+ WCD937X_DIGITAL_INTR_STATUS_1, WCD937X_DIGITAL_INTR_STATUS_2);
}
static const struct reg_default wcd937x_defaults[] = {
@@ -985,35 +957,10 @@ static const struct regmap_config wcd937x_regmap_config = {
};
static const struct sdw_slave_ops wcd9370_slave_ops = {
- .update_status = wcd9370_update_status,
+ .update_status = wcd_update_status,
.interrupt_callback = wcd9370_interrupt_callback,
};
-static int wcd937x_sdw_component_bind(struct device *dev,
- struct device *master, void *data)
-{
- pm_runtime_set_autosuspend_delay(dev, 3000);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_mark_last_busy(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-
- return 0;
-}
-
-static void wcd937x_sdw_component_unbind(struct device *dev,
- struct device *master, void *data)
-{
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_dont_use_autosuspend(dev);
-}
-
-static const struct component_ops wcd937x_sdw_component_ops = {
- .bind = wcd937x_sdw_component_bind,
- .unbind = wcd937x_sdw_component_unbind,
-};
-
static int wcd9370_probe(struct sdw_slave *pdev,
const struct sdw_device_id *id)
{
@@ -1099,7 +1046,7 @@ static int wcd9370_probe(struct sdw_slave *pdev,
}
- ret = component_add(dev, &wcd937x_sdw_component_ops);
+ ret = component_add(dev, &wcd_sdw_component_ops);
if (ret)
return ret;
@@ -1113,7 +1060,7 @@ static int wcd9370_remove(struct sdw_slave *pdev)
{
struct device *dev = &pdev->dev;
- component_del(dev, &wcd937x_sdw_component_ops);
+ component_del(dev, &wcd_sdw_component_ops);
return 0;
}
diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
index 3b0a8cc314e0..421ec7a2d6bd 100644
--- a/sound/soc/codecs/wcd937x.c
+++ b/sound/soc/codecs/wcd937x.c
@@ -21,6 +21,7 @@
#include <sound/tlv.h>
#include "wcd-clsh-v2.h"
+#include "wcd-common.h"
#include "wcd-mbhc-v2.h"
#include "wcd937x.h"
@@ -85,6 +86,7 @@ struct wcd937x_priv {
struct wcd_mbhc_config mbhc_cfg;
struct wcd_mbhc_intr intr_ids;
struct wcd_clsh_ctrl *clsh_info;
+ struct wcd_common common;
struct irq_domain *virq;
struct regmap_irq_chip_data *irq_chip;
struct snd_soc_jack *jack;
@@ -93,9 +95,6 @@ struct wcd937x_priv {
s32 pullup_ref[WCD937X_MAX_MICBIAS];
u32 hph_mode;
int ear_rx_path;
- u32 micb1_mv;
- u32 micb2_mv;
- u32 micb3_mv;
int hphr_pdm_wd_int;
int hphl_pdm_wd_int;
int aux_pdm_wd_int;
@@ -872,15 +871,6 @@ static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w,
return 0;
}
-static int wcd937x_get_micb_vout_ctl_val(u32 micb_mv)
-{
- if (micb_mv < 1000 || micb_mv > 2850) {
- pr_err("Unsupported micbias voltage (%u mV)\n", micb_mv);
- return -EINVAL;
- }
-
- return (micb_mv - 1000) / 50;
-}
static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
@@ -1193,7 +1183,7 @@ static int wcd937x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch_id, bool enable)
{
struct sdw_port_config *port_config = &wcd->port_config[port_idx - 1];
- const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
+ const struct wcd_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
u8 port_num = ch_info->port_num;
u8 ch_mask = ch_info->ch_mask;
u8 mstr_port_num, mstr_ch_mask;
@@ -1481,7 +1471,7 @@ static int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
WCD937X_MICB_VOUT_MASK);
- req_vout_ctl = wcd937x_get_micb_vout_ctl_val(req_volt);
+ req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
if (req_vout_ctl < 0) {
ret = -EINVAL;
goto exit;
@@ -1529,10 +1519,10 @@ static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
* voltage needed to detect threshold microphone, then do
* not change the micbias, just return.
*/
- if (wcd937x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ if (wcd937x->common.micb_mv[2] >= WCD_MBHC_THR_HS_MICB_MV)
return 0;
- micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd937x->micb2_mv;
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd937x->common.micb_mv[2];
return wcd937x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
}
@@ -2046,9 +2036,9 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put),
- SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0,
+ SOC_SINGLE_EXT("HPHL_COMP Switch", WCD937X_COMP_L, 0, 1, 0,
wcd937x_get_compander, wcd937x_set_compander),
- SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0,
+ SOC_SINGLE_EXT("HPHR_COMP Switch", WCD937X_COMP_R, 1, 1, 0,
wcd937x_get_compander, wcd937x_set_compander),
SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain),
@@ -2436,22 +2426,14 @@ static const struct snd_soc_dapm_route wcd9375_audio_map[] = {
{ "DMIC6_MIXER", "Switch", "DMIC6" },
};
-static int wcd937x_set_micbias_data(struct wcd937x_priv *wcd937x)
+static void wcd937x_set_micbias_data(struct device *dev, struct wcd937x_priv *wcd937x)
{
- int vout_ctl[3];
-
- /* Set micbias voltage */
- vout_ctl[0] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb1_mv);
- vout_ctl[1] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb2_mv);
- vout_ctl[2] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb3_mv);
- if ((vout_ctl[0] | vout_ctl[1] | vout_ctl[2]) < 0)
- return -EINVAL;
-
- regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, WCD937X_ANA_MICB_VOUT, vout_ctl[0]);
- regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, WCD937X_ANA_MICB_VOUT, vout_ctl[1]);
- regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, WCD937X_ANA_MICB_VOUT, vout_ctl[2]);
-
- return 0;
+ regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, WCD937X_ANA_MICB_VOUT,
+ wcd937x->common.micb_vout[0]);
+ regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, WCD937X_ANA_MICB_VOUT,
+ wcd937x->common.micb_vout[1]);
+ regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, WCD937X_ANA_MICB_VOUT,
+ wcd937x->common.micb_vout[2]);
}
static irqreturn_t wcd937x_wd_handle_irq(int irq, void *data)
@@ -2630,31 +2612,6 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
.endianness = 1,
};
-static void wcd937x_dt_parse_micbias_info(struct device *dev, struct wcd937x_priv *wcd)
-{
- struct device_node *np = dev->of_node;
- u32 prop_val = 0;
- int ret = 0;
-
- ret = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
- if (!ret)
- wcd->micb1_mv = prop_val / 1000;
- else
- dev_warn(dev, "Micbias1 DT property not found\n");
-
- ret = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
- if (!ret)
- wcd->micb2_mv = prop_val / 1000;
- else
- dev_warn(dev, "Micbias2 DT property not found\n");
-
- ret = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
- if (!ret)
- wcd->micb3_mv = prop_val / 1000;
- else
- dev_warn(dev, "Micbias3 DT property not found\n");
-}
-
static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component)
{
int value;
@@ -2788,7 +2745,7 @@ static int wcd937x_bind(struct device *dev)
return ret;
}
- wcd937x->rxdev = wcd937x_sdw_device_get(wcd937x->rxnode);
+ wcd937x->rxdev = of_sdw_find_device_by_node(wcd937x->rxnode);
if (!wcd937x->rxdev) {
dev_err(dev, "could not find slave with matching of node\n");
return -EINVAL;
@@ -2797,7 +2754,7 @@ static int wcd937x_bind(struct device *dev)
wcd937x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd937x->rxdev);
wcd937x->sdw_priv[AIF1_PB]->wcd937x = wcd937x;
- wcd937x->txdev = wcd937x_sdw_device_get(wcd937x->txnode);
+ wcd937x->txdev = of_sdw_find_device_by_node(wcd937x->txnode);
if (!wcd937x->txdev) {
dev_err(dev, "could not find txslave with matching of node\n");
return -EINVAL;
@@ -2833,7 +2790,7 @@ static int wcd937x_bind(struct device *dev)
return -EINVAL;
}
- wcd937x->regmap = dev_get_regmap(&wcd937x->tx_sdw_dev->dev, NULL);
+ wcd937x->regmap = wcd937x->sdw_priv[AIF1_CAP]->regmap;
if (!wcd937x->regmap) {
dev_err(dev, "could not get TX device regmap\n");
return -EINVAL;
@@ -2848,11 +2805,7 @@ static int wcd937x_bind(struct device *dev)
wcd937x->sdw_priv[AIF1_PB]->slave_irq = wcd937x->virq;
wcd937x->sdw_priv[AIF1_CAP]->slave_irq = wcd937x->virq;
- ret = wcd937x_set_micbias_data(wcd937x);
- if (ret < 0) {
- dev_err(dev, "Bad micbias pdata\n");
- return ret;
- }
+ wcd937x_set_micbias_data(dev, wcd937x);
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
wcd937x_dais, ARRAY_SIZE(wcd937x_dais));
@@ -2920,6 +2873,8 @@ static int wcd937x_probe(struct platform_device *pdev)
dev_set_drvdata(dev, wcd937x);
mutex_init(&wcd937x->micb_lock);
+ wcd937x->common.dev = dev;
+ wcd937x->common.max_bias = 3;
wcd937x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(wcd937x->reset_gpio))
@@ -2939,13 +2894,15 @@ static int wcd937x_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
- wcd937x_dt_parse_micbias_info(dev, wcd937x);
+ ret = wcd_dt_parse_micbias_info(&wcd937x->common);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get micbias\n");
cfg->mbhc_micbias = MIC_BIAS_2;
cfg->anc_micbias = MIC_BIAS_2;
cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
cfg->num_btn = WCD937X_MBHC_MAX_BUTTONS;
- cfg->micb_mv = wcd937x->micb2_mv;
+ cfg->micb_mv = wcd937x->common.micb_mv[2];
cfg->linein_th = 5000;
cfg->hs_thr = 1700;
cfg->hph_thr = 50;
diff --git a/sound/soc/codecs/wcd937x.h b/sound/soc/codecs/wcd937x.h
index 3ab21bb5846e..3d0ba3cc0ee6 100644
--- a/sound/soc/codecs/wcd937x.h
+++ b/sound/soc/codecs/wcd937x.h
@@ -7,6 +7,7 @@
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
+#include "wcd-common.h"
#define WCD937X_BASE_ADDRESS 0x3000
#define WCD937X_ANA_BIAS 0x3001
@@ -507,26 +508,13 @@ enum wcd937x_rx_sdw_ports {
WCD937X_MAX_SWR_PORTS = WCD937X_DSD_PORT,
};
-struct wcd937x_sdw_ch_info {
- int port_num;
- unsigned int ch_mask;
- unsigned int master_ch_mask;
-};
-
-#define WCD_SDW_CH(id, pn, cmask) \
- [id] = { \
- .port_num = pn, \
- .ch_mask = cmask, \
- .master_ch_mask = cmask, \
- }
-
struct wcd937x_priv;
struct wcd937x_sdw_priv {
struct sdw_slave *sdev;
struct sdw_stream_config sconfig;
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WCD937X_MAX_SWR_PORTS];
- struct wcd937x_sdw_ch_info *ch_info;
+ struct wcd_sdw_ch_info *ch_info;
bool port_enable[WCD937X_MAX_SWR_CH_IDS];
unsigned int master_channel_map[SDW_MAX_PORTS];
int active_ports;
@@ -549,24 +537,22 @@ int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
-struct device *wcd937x_sdw_device_get(struct device_node *np);
-
#else
-int wcd937x_sdw_free(struct wcd937x_sdw_priv *wcd,
+static inline int wcd937x_sdw_free(struct wcd937x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
return -EOPNOTSUPP;
}
-int wcd937x_sdw_set_sdw_stream(struct wcd937x_sdw_priv *wcd,
+static inline int wcd937x_sdw_set_sdw_stream(struct wcd937x_sdw_priv *wcd,
struct snd_soc_dai *dai,
void *stream, int direction)
{
return -EOPNOTSUPP;
}
-int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,
+static inline int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c
index e822cc145250..add907cb2706 100644
--- a/sound/soc/codecs/wcd938x-sdw.c
+++ b/sound/soc/codecs/wcd938x-sdw.c
@@ -18,10 +18,9 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include "wcd938x.h"
+#include "wcd-common.h"
-#define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
-
-static const struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
+static const struct wcd_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD938X_HPH_L, WCD938X_HPH_PORT, BIT(0)),
WCD_SDW_CH(WCD938X_HPH_R, WCD938X_HPH_PORT, BIT(1)),
WCD_SDW_CH(WCD938X_CLSH, WCD938X_CLSH_PORT, BIT(0)),
@@ -32,7 +31,7 @@ static const struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD938X_DSD_R, WCD938X_DSD_PORT, BIT(1)),
};
-static const struct wcd938x_sdw_ch_info wcd938x_sdw_tx_ch_info[] = {
+static const struct wcd_sdw_ch_info wcd938x_sdw_tx_ch_info[] = {
WCD_SDW_CH(WCD938X_ADC1, WCD938X_ADC_1_2_PORT, BIT(0)),
WCD_SDW_CH(WCD938X_ADC2, WCD938X_ADC_1_2_PORT, BIT(1)),
WCD_SDW_CH(WCD938X_ADC3, WCD938X_ADC_3_4_PORT, BIT(0)),
@@ -82,23 +81,6 @@ static struct sdw_dpn_prop wcd938x_dpn_prop[WCD938X_MAX_SWR_PORTS] = {
}
};
-struct device *wcd938x_sdw_device_get(struct device_node *np)
-{
- return bus_find_device_by_of_node(&sdw_bus_type, np);
-
-}
-EXPORT_SYMBOL_GPL(wcd938x_sdw_device_get);
-
-int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
-{
- int bank;
-
- bank = sdw_read(sdev, SDW_SCP_CTRL);
-
- return ((bank & 0x40) ? 1 : 0);
-}
-EXPORT_SYMBOL_GPL(wcd938x_swr_get_current_bank);
-
int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
@@ -158,44 +140,13 @@ int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
}
EXPORT_SYMBOL_GPL(wcd938x_sdw_set_sdw_stream);
-static int wcd9380_update_status(struct sdw_slave *slave,
- enum sdw_slave_status status)
-{
- struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
-
- if (wcd->regmap && (status == SDW_SLAVE_ATTACHED)) {
- /* Write out any cached changes that happened between probe and attach */
- regcache_cache_only(wcd->regmap, false);
- return regcache_sync(wcd->regmap);
- }
-
- return 0;
-}
-
-static int wcd9380_bus_config(struct sdw_slave *slave,
- struct sdw_bus_params *params)
-{
- sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank), 0x01);
-
- return 0;
-}
-
static int wcd9380_interrupt_callback(struct sdw_slave *slave,
struct sdw_slave_intr_status *status)
{
struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
- struct irq_domain *slave_irq = wcd->slave_irq;
- u32 sts1, sts2, sts3;
-
- do {
- handle_nested_irq(irq_find_mapping(slave_irq, 0));
- regmap_read(wcd->regmap, WCD938X_DIGITAL_INTR_STATUS_0, &sts1);
- regmap_read(wcd->regmap, WCD938X_DIGITAL_INTR_STATUS_1, &sts2);
- regmap_read(wcd->regmap, WCD938X_DIGITAL_INTR_STATUS_2, &sts3);
- } while (sts1 || sts2 || sts3);
-
- return IRQ_HANDLED;
+ return wcd_interrupt_callback(slave, wcd->slave_irq, WCD938X_DIGITAL_INTR_STATUS_0,
+ WCD938X_DIGITAL_INTR_STATUS_1, WCD938X_DIGITAL_INTR_STATUS_2);
}
static const struct reg_default wcd938x_defaults[] = {
@@ -1193,25 +1144,9 @@ static const struct regmap_config wcd938x_regmap_config = {
};
static const struct sdw_slave_ops wcd9380_slave_ops = {
- .update_status = wcd9380_update_status,
+ .update_status = wcd_update_status,
.interrupt_callback = wcd9380_interrupt_callback,
- .bus_config = wcd9380_bus_config,
-};
-
-static int wcd938x_sdw_component_bind(struct device *dev,
- struct device *master, void *data)
-{
- return 0;
-}
-
-static void wcd938x_sdw_component_unbind(struct device *dev,
- struct device *master, void *data)
-{
-}
-
-static const struct component_ops wcd938x_sdw_component_ops = {
- .bind = wcd938x_sdw_component_bind,
- .unbind = wcd938x_sdw_component_unbind,
+ .bus_config = wcd_bus_config,
};
static int wcd9380_probe(struct sdw_slave *pdev,
@@ -1278,7 +1213,7 @@ static int wcd9380_probe(struct sdw_slave *pdev,
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
- ret = component_add(dev, &wcd938x_sdw_component_ops);
+ ret = component_add(dev, &wcd_sdw_component_ops);
if (ret)
goto err_disable_rpm;
@@ -1296,7 +1231,7 @@ static int wcd9380_remove(struct sdw_slave *pdev)
{
struct device *dev = &pdev->dev;
- component_del(dev, &wcd938x_sdw_component_ops);
+ component_del(dev, &wcd_sdw_component_ops);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index 711f373ece24..e1a4783b984c 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -22,6 +22,7 @@
#include <linux/regulator/consumer.h>
#include "wcd-clsh-v2.h"
+#include "wcd-common.h"
#include "wcd-mbhc-v2.h"
#include "wcd938x.h"
@@ -155,6 +156,7 @@ struct wcd938x_priv {
struct wcd_mbhc_config mbhc_cfg;
struct wcd_mbhc_intr intr_ids;
struct wcd_clsh_ctrl *clsh_info;
+ struct wcd_common common;
struct irq_domain *virq;
struct regmap_irq_chip_data *irq_chip;
struct snd_soc_jack *jack;
@@ -169,10 +171,6 @@ struct wcd938x_priv {
struct gpio_desc *us_euro_gpio;
struct mux_control *us_euro_mux;
unsigned int mux_state;
- u32 micb1_mv;
- u32 micb2_mv;
- u32 micb3_mv;
- u32 micb4_mv;
int hphr_pdm_wd_int;
int hphl_pdm_wd_int;
int aux_pdm_wd_int;
@@ -396,7 +394,7 @@ static int wcd938x_io_init(struct wcd938x_priv *wcd938x)
}
-static int wcd938x_sdw_connect_port(const struct wcd938x_sdw_ch_info *ch_info,
+static int wcd938x_sdw_connect_port(const struct wcd_sdw_ch_info *ch_info,
struct sdw_port_config *port_config,
u8 enable)
{
@@ -1094,8 +1092,7 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
int bank;
int rate;
- bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1;
- bank = bank ? 0 : 1;
+ bank = sdw_slave_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1975,15 +1972,6 @@ static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
}
}
-static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv)
-{
- /* min micbias voltage is 1V and maximum is 2.85V */
- if (micb_mv < 1000 || micb_mv > 2850)
- return -EINVAL;
-
- return (micb_mv - 1000) / 50;
-}
-
static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
int req_volt, int micb_num)
{
@@ -2020,7 +2008,7 @@ static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
WCD938X_MICB_VOUT_MASK);
- req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt);
+ req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
if (req_vout_ctl < 0) {
ret = -EINVAL;
goto exit;
@@ -2068,10 +2056,10 @@ static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
* voltage needed to detect threshold microphone, then do
* not change the micbias, just return.
*/
- if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ if (wcd938x->common.micb_mv[2] >= WCD_MBHC_THR_HS_MICB_MV)
return 0;
- micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->common.micb_mv[2];
return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
}
@@ -2976,28 +2964,16 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"EAR", NULL, "EAR PGA"},
};
-static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x)
+static void wcd938x_set_micbias_data(struct device *dev, struct wcd938x_priv *wcd938x)
{
- int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
-
- /* set micbias voltage */
- vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv);
- vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv);
- vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv);
- vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv);
- if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
- return -EINVAL;
-
regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1,
- WCD938X_MICB_VOUT_MASK, vout_ctl_1);
+ WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[0]);
regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2,
- WCD938X_MICB_VOUT_MASK, vout_ctl_2);
+ WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[1]);
regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3,
- WCD938X_MICB_VOUT_MASK, vout_ctl_3);
+ WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[2]);
regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4,
- WCD938X_MICB_VOUT_MASK, vout_ctl_4);
-
- return 0;
+ WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[3]);
}
static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
@@ -3201,37 +3177,6 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
.endianness = 1,
};
-static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
-{
- struct device_node *np = dev->of_node;
- u32 prop_val = 0;
- int rc = 0;
-
- rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
- if (!rc)
- wcd->micb1_mv = prop_val/1000;
- else
- dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
- if (!rc)
- wcd->micb2_mv = prop_val/1000;
- else
- dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
- if (!rc)
- wcd->micb3_mv = prop_val/1000;
- else
- dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val);
- if (!rc)
- wcd->micb4_mv = prop_val/1000;
- else
- dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
-}
-
static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
@@ -3296,13 +3241,15 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
if (ret)
return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
- wcd938x_dt_parse_micbias_info(dev, wcd938x);
+ ret = wcd_dt_parse_micbias_info(&wcd938x->common);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
cfg->mbhc_micbias = MIC_BIAS_2;
cfg->anc_micbias = MIC_BIAS_2;
cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS;
- cfg->micb_mv = wcd938x->micb2_mv;
+ cfg->micb_mv = wcd938x->common.micb_mv[2];
cfg->linein_th = 5000;
cfg->hs_thr = 1700;
cfg->hph_thr = 50;
@@ -3400,7 +3347,7 @@ static int wcd938x_bind(struct device *dev)
return ret;
}
- wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode);
+ wcd938x->rxdev = of_sdw_find_device_by_node(wcd938x->rxnode);
if (!wcd938x->rxdev) {
dev_err(dev, "could not find slave with matching of node\n");
ret = -EINVAL;
@@ -3409,7 +3356,7 @@ static int wcd938x_bind(struct device *dev)
wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev);
wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x;
- wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode);
+ wcd938x->txdev = of_sdw_find_device_by_node(wcd938x->txnode);
if (!wcd938x->txdev) {
dev_err(dev, "could not find txslave with matching of node\n");
ret = -EINVAL;
@@ -3442,7 +3389,7 @@ static int wcd938x_bind(struct device *dev)
goto err_remove_tx_link;
}
- wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL);
+ wcd938x->regmap = wcd938x->sdw_priv[AIF1_CAP]->regmap;
if (!wcd938x->regmap) {
dev_err(dev, "could not get TX device regmap\n");
ret = -EINVAL;
@@ -3458,11 +3405,7 @@ static int wcd938x_bind(struct device *dev)
wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq;
- ret = wcd938x_set_micbias_data(wcd938x);
- if (ret < 0) {
- dev_err(dev, "%s: bad micbias pdata\n", __func__);
- goto err_remove_rx_link;
- }
+ wcd938x_set_micbias_data(dev, wcd938x);
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
@@ -3551,6 +3494,8 @@ static int wcd938x_probe(struct platform_device *pdev)
dev_set_drvdata(dev, wcd938x);
mutex_init(&wcd938x->micb_lock);
+ wcd938x->common.dev = dev;
+ wcd938x->common.max_bias = 4;
ret = wcd938x_populate_dt_data(wcd938x, dev);
if (ret)
diff --git a/sound/soc/codecs/wcd938x.h b/sound/soc/codecs/wcd938x.h
index fb6a0e4ef337..c18610466d7d 100644
--- a/sound/soc/codecs/wcd938x.h
+++ b/sound/soc/codecs/wcd938x.h
@@ -587,17 +587,6 @@
#define WCD938X_MAX_SWR_CH_IDS 15
-struct wcd938x_sdw_ch_info {
- int port_num;
- unsigned int ch_mask;
-};
-
-#define WCD_SDW_CH(id, pn, cmask) \
- [id] = { \
- .port_num = pn, \
- .ch_mask = cmask, \
- }
-
enum wcd938x_tx_sdw_ports {
WCD938X_ADC_1_2_PORT = 1,
WCD938X_ADC_3_4_PORT,
@@ -649,7 +638,7 @@ struct wcd938x_sdw_priv {
struct sdw_stream_config sconfig;
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
- const struct wcd938x_sdw_ch_info *ch_info;
+ const struct wcd_sdw_ch_info *ch_info;
bool port_enable[WCD938X_MAX_SWR_CH_IDS];
int active_ports;
bool is_tx;
@@ -669,10 +658,6 @@ int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
-
-struct device *wcd938x_sdw_device_get(struct device_node *np);
-int wcd938x_swr_get_current_bank(struct sdw_slave *sdev);
-
#else
static inline int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
@@ -697,14 +682,5 @@ static inline int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
return -EOPNOTSUPP;
}
-static inline struct device *wcd938x_sdw_device_get(struct device_node *np)
-{
- return NULL;
-}
-
-static inline int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
-{
- return 0;
-}
#endif /* CONFIG_SND_SOC_WCD938X_SDW */
#endif /* __WCD938X_H__ */
diff --git a/sound/soc/codecs/wcd939x-sdw.c b/sound/soc/codecs/wcd939x-sdw.c
index f7a9323a9fea..d369100a2457 100644
--- a/sound/soc/codecs/wcd939x-sdw.c
+++ b/sound/soc/codecs/wcd939x-sdw.c
@@ -20,10 +20,9 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include "wcd939x.h"
+#include "wcd-common.h"
-#define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
-
-static const struct wcd939x_sdw_ch_info wcd939x_sdw_rx_ch_info[] = {
+static const struct wcd_sdw_ch_info wcd939x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD939X_HPH_L, WCD939X_HPH_PORT, BIT(0)),
WCD_SDW_CH(WCD939X_HPH_R, WCD939X_HPH_PORT, BIT(1)),
WCD_SDW_CH(WCD939X_CLSH, WCD939X_CLSH_PORT, BIT(0)),
@@ -36,7 +35,7 @@ static const struct wcd939x_sdw_ch_info wcd939x_sdw_rx_ch_info[] = {
WCD_SDW_CH(WCD939X_HIFI_PCM_R, WCD939X_HIFI_PCM_PORT, BIT(1)),
};
-static const struct wcd939x_sdw_ch_info wcd939x_sdw_tx_ch_info[] = {
+static const struct wcd_sdw_ch_info wcd939x_sdw_tx_ch_info[] = {
WCD_SDW_CH(WCD939X_ADC1, WCD939X_ADC_1_4_PORT, BIT(0)),
WCD_SDW_CH(WCD939X_ADC2, WCD939X_ADC_1_4_PORT, BIT(1)),
WCD_SDW_CH(WCD939X_ADC3, WCD939X_ADC_1_4_PORT, BIT(2)),
@@ -128,19 +127,6 @@ static struct sdw_dpn_prop wcd939x_tx_dpn_prop[WCD939X_MAX_TX_SWR_PORTS] = {
}
};
-struct device *wcd939x_sdw_device_get(struct device_node *np)
-{
- return bus_find_device_by_of_node(&sdw_bus_type, np);
-}
-EXPORT_SYMBOL_GPL(wcd939x_sdw_device_get);
-
-unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev)
-{
- return FIELD_GET(SDW_SCP_STAT_CURR_BANK,
- sdw_read(sdev, SDW_SCP_CTRL));
-}
-EXPORT_SYMBOL_GPL(wcd939x_swr_get_current_bank);
-
int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
@@ -199,38 +185,6 @@ int wcd939x_sdw_set_sdw_stream(struct wcd939x_sdw_priv *wcd,
}
EXPORT_SYMBOL_GPL(wcd939x_sdw_set_sdw_stream);
-struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd)
-{
- if (wcd->regmap)
- return wcd->regmap;
-
- return ERR_PTR(-EINVAL);
-}
-EXPORT_SYMBOL_GPL(wcd939x_swr_get_regmap);
-
-static int wcd9390_update_status(struct sdw_slave *slave,
- enum sdw_slave_status status)
-{
- struct wcd939x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
-
- if (wcd->regmap && status == SDW_SLAVE_ATTACHED) {
- /* Write out any cached changes that happened between probe and attach */
- regcache_cache_only(wcd->regmap, false);
- return regcache_sync(wcd->regmap);
- }
-
- return 0;
-}
-
-static int wcd9390_bus_config(struct sdw_slave *slave,
- struct sdw_bus_params *params)
-{
- sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank),
- 0x01);
-
- return 0;
-}
-
/*
* Handle Soundwire out-of-band interrupt event by triggering
* the first irq of the slave_irq irq domain, which then will
@@ -241,18 +195,9 @@ static int wcd9390_interrupt_callback(struct sdw_slave *slave,
struct sdw_slave_intr_status *status)
{
struct wcd939x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
- struct irq_domain *slave_irq = wcd->slave_irq;
- u32 sts1, sts2, sts3;
-
- do {
- handle_nested_irq(irq_find_mapping(slave_irq, 0));
- regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_0, &sts1);
- regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_1, &sts2);
- regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_2, &sts3);
-
- } while (sts1 || sts2 || sts3);
- return IRQ_HANDLED;
+ return wcd_interrupt_callback(slave, wcd->slave_irq, WCD939X_DIGITAL_INTR_STATUS_0,
+ WCD939X_DIGITAL_INTR_STATUS_1, WCD939X_DIGITAL_INTR_STATUS_2);
}
static const struct reg_default wcd939x_defaults[] = {
@@ -1385,34 +1330,9 @@ static const struct regmap_config wcd939x_regmap_config = {
};
static const struct sdw_slave_ops wcd9390_slave_ops = {
- .update_status = wcd9390_update_status,
+ .update_status = wcd_update_status,
.interrupt_callback = wcd9390_interrupt_callback,
- .bus_config = wcd9390_bus_config,
-};
-
-static int wcd939x_sdw_component_bind(struct device *dev, struct device *master,
- void *data)
-{
- pm_runtime_set_autosuspend_delay(dev, 3000);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_mark_last_busy(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-
- return 0;
-}
-
-static void wcd939x_sdw_component_unbind(struct device *dev,
- struct device *master, void *data)
-{
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_dont_use_autosuspend(dev);
-}
-
-static const struct component_ops wcd939x_sdw_component_ops = {
- .bind = wcd939x_sdw_component_bind,
- .unbind = wcd939x_sdw_component_unbind,
+ .bus_config = wcd_bus_config,
};
static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id)
@@ -1478,7 +1398,7 @@ static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id)
regcache_cache_only(wcd->regmap, true);
}
- ret = component_add(dev, &wcd939x_sdw_component_ops);
+ ret = component_add(dev, &wcd_sdw_component_ops);
if (ret)
return ret;
@@ -1493,7 +1413,7 @@ static int wcd9390_remove(struct sdw_slave *pdev)
struct device *dev = &pdev->dev;
struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev);
- component_del(dev, &wcd939x_sdw_component_ops);
+ component_del(dev, &wcd_sdw_component_ops);
if (wcd->regmap)
regmap_exit(wcd->regmap);
diff --git a/sound/soc/codecs/wcd939x.c b/sound/soc/codecs/wcd939x.c
index 64f082e474c1..e74e6f013131 100644
--- a/sound/soc/codecs/wcd939x.c
+++ b/sound/soc/codecs/wcd939x.c
@@ -28,6 +28,7 @@
#include <linux/usb/typec_altmode.h>
#include "wcd-clsh-v2.h"
+#include "wcd-common.h"
#include "wcd-mbhc-v2.h"
#include "wcd939x.h"
@@ -191,6 +192,7 @@ struct wcd939x_priv {
struct wcd_mbhc_config mbhc_cfg;
struct wcd_mbhc_intr intr_ids;
struct wcd_clsh_ctrl *clsh_info;
+ struct wcd_common common;
struct irq_domain *virq;
struct regmap_irq_chip_data *irq_chip;
struct snd_soc_jack *jack;
@@ -201,10 +203,6 @@ struct wcd939x_priv {
u32 tx_mode[TX_ADC_MAX];
int variant;
struct gpio_desc *reset_gpio;
- u32 micb1_mv;
- u32 micb2_mv;
- u32 micb3_mv;
- u32 micb4_mv;
int hphr_pdm_wd_int;
int hphl_pdm_wd_int;
int ear_pdm_wd_int;
@@ -415,7 +413,7 @@ static int wcd939x_io_init(struct snd_soc_component *component)
return 0;
}
-static int wcd939x_sdw_connect_port(const struct wcd939x_sdw_ch_info *ch_info,
+static int wcd939x_sdw_connect_port(const struct wcd_sdw_ch_info *ch_info,
struct sdw_port_config *port_config,
u8 enable)
{
@@ -1017,7 +1015,7 @@ static int wcd939x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
int bank;
int rate;
- bank = wcd939x_swr_get_current_bank(wcd939x->sdw_priv[AIF1_CAP]->sdev);
+ bank = sdw_slave_get_current_bank(wcd939x->sdw_priv[AIF1_CAP]->sdev);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1919,17 +1917,6 @@ static void wcd939x_mbhc_micb_ramp_control(struct snd_soc_component *component,
}
}
-static int wcd939x_get_micb_vout_ctl_val(u32 micb_mv)
-{
- /* min micbias voltage is 1V and maximum is 2.85V */
- if (micb_mv < 1000 || micb_mv > 2850) {
- pr_err("%s: unsupported micbias voltage\n", __func__);
- return -EINVAL;
- }
-
- return (micb_mv - 1000) / 50;
-}
-
static int wcd939x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
int req_volt, int micb_num)
{
@@ -1969,7 +1956,7 @@ static int wcd939x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
WCD939X_MICB_VOUT_CTL);
- req_vout_ctl = wcd939x_get_micb_vout_ctl_val(req_volt);
+ req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt);
if (req_vout_ctl < 0) {
ret = req_vout_ctl;
goto exit;
@@ -2021,10 +2008,10 @@ static int wcd939x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon
* voltage needed to detect threshold microphone, then do
* not change the micbias, just return.
*/
- if (wcd939x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ if (wcd939x->common.micb_mv[1] >= WCD_MBHC_THR_HS_MICB_MV)
return 0;
- micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd939x->micb2_mv;
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd939x->common.micb_mv[1];
return wcd939x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
}
@@ -2895,28 +2882,16 @@ static const struct snd_soc_dapm_route wcd939x_audio_map[] = {
{"EAR", NULL, "EAR PGA"},
};
-static int wcd939x_set_micbias_data(struct wcd939x_priv *wcd939x)
+static void wcd939x_set_micbias_data(struct device *dev, struct wcd939x_priv *wcd939x)
{
- int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
-
- /* set micbias voltage */
- vout_ctl_1 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb1_mv);
- vout_ctl_2 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb2_mv);
- vout_ctl_3 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb3_mv);
- vout_ctl_4 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb4_mv);
- if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
- return -EINVAL;
-
regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB1,
- WCD939X_MICB_VOUT_CTL, vout_ctl_1);
+ WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[0]);
regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB2,
- WCD939X_MICB_VOUT_CTL, vout_ctl_2);
+ WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[1]);
regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB3,
- WCD939X_MICB_VOUT_CTL, vout_ctl_3);
+ WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[2]);
regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB4,
- WCD939X_MICB_VOUT_CTL, vout_ctl_4);
-
- return 0;
+ WCD939X_MICB_VOUT_CTL, wcd939x->common.micb_vout[3]);
}
static irqreturn_t wcd939x_wd_handle_irq(int irq, void *data)
@@ -3186,37 +3161,6 @@ static int wcd939x_typec_mux_set(struct typec_mux_dev *mux,
}
#endif /* CONFIG_TYPEC */
-static void wcd939x_dt_parse_micbias_info(struct device *dev, struct wcd939x_priv *wcd)
-{
- struct device_node *np = dev->of_node;
- u32 prop_val = 0;
- int rc = 0;
-
- rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
- if (!rc)
- wcd->micb1_mv = prop_val / 1000;
- else
- dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
- if (!rc)
- wcd->micb2_mv = prop_val / 1000;
- else
- dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
- if (!rc)
- wcd->micb3_mv = prop_val / 1000;
- else
- dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
-
- rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val);
- if (!rc)
- wcd->micb4_mv = prop_val / 1000;
- else
- dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
-}
-
#if IS_ENABLED(CONFIG_TYPEC)
static bool wcd939x_swap_gnd_mic(struct snd_soc_component *component)
{
@@ -3252,13 +3196,15 @@ static int wcd939x_populate_dt_data(struct wcd939x_priv *wcd939x, struct device
if (ret)
return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
- wcd939x_dt_parse_micbias_info(dev, wcd939x);
+ ret = wcd_dt_parse_micbias_info(&wcd939x->common);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get micbias\n");
cfg->mbhc_micbias = MIC_BIAS_2;
cfg->anc_micbias = MIC_BIAS_2;
cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
cfg->num_btn = WCD939X_MBHC_MAX_BUTTONS;
- cfg->micb_mv = wcd939x->micb2_mv;
+ cfg->micb_mv = wcd939x->common.micb_mv[1];
cfg->linein_th = 5000;
cfg->hs_thr = 1700;
cfg->hph_thr = 50;
@@ -3383,7 +3329,7 @@ static int wcd939x_bind(struct device *dev)
goto err_put_typec_switch;
}
- wcd939x->rxdev = wcd939x_sdw_device_get(wcd939x->rxnode);
+ wcd939x->rxdev = of_sdw_find_device_by_node(wcd939x->rxnode);
if (!wcd939x->rxdev) {
dev_err(dev, "could not find slave with matching of node\n");
ret = -EINVAL;
@@ -3392,7 +3338,7 @@ static int wcd939x_bind(struct device *dev)
wcd939x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd939x->rxdev);
wcd939x->sdw_priv[AIF1_PB]->wcd939x = wcd939x;
- wcd939x->txdev = wcd939x_sdw_device_get(wcd939x->txnode);
+ wcd939x->txdev = of_sdw_find_device_by_node(wcd939x->txnode);
if (!wcd939x->txdev) {
dev_err(dev, "could not find txslave with matching of node\n");
ret = -EINVAL;
@@ -3428,10 +3374,10 @@ static int wcd939x_bind(struct device *dev)
}
/* Get regmap from TX SoundWire device */
- wcd939x->regmap = wcd939x_swr_get_regmap(wcd939x->sdw_priv[AIF1_CAP]);
- if (IS_ERR(wcd939x->regmap)) {
+ wcd939x->regmap = wcd939x->sdw_priv[AIF1_CAP]->regmap;
+ if (!wcd939x->regmap) {
dev_err(dev, "could not get TX device regmap\n");
- ret = PTR_ERR(wcd939x->regmap);
+ ret = -ENODEV;
goto err_remove_rx_link;
}
@@ -3444,11 +3390,7 @@ static int wcd939x_bind(struct device *dev)
wcd939x->sdw_priv[AIF1_PB]->slave_irq = wcd939x->virq;
wcd939x->sdw_priv[AIF1_CAP]->slave_irq = wcd939x->virq;
- ret = wcd939x_set_micbias_data(wcd939x);
- if (ret < 0) {
- dev_err(dev, "%s: bad micbias pdata\n", __func__);
- goto err_remove_rx_link;
- }
+ wcd939x_set_micbias_data(dev, wcd939x);
/* Check WCD9395 version */
regmap_read(wcd939x->regmap, WCD939X_DIGITAL_CHIP_ID1, &id1);
@@ -3613,6 +3555,8 @@ static int wcd939x_probe(struct platform_device *pdev)
dev_set_drvdata(dev, wcd939x);
mutex_init(&wcd939x->micb_lock);
+ wcd939x->common.dev = dev;
+ wcd939x->common.max_bias = 4;
ret = wcd939x_populate_dt_data(wcd939x, dev);
if (ret) {
diff --git a/sound/soc/codecs/wcd939x.h b/sound/soc/codecs/wcd939x.h
index 3204fb10b58d..6bd2366587a8 100644
--- a/sound/soc/codecs/wcd939x.h
+++ b/sound/soc/codecs/wcd939x.h
@@ -844,17 +844,6 @@
#define WCD939X_MAX_SWR_CH_IDS (15)
-struct wcd939x_sdw_ch_info {
- int port_num;
- unsigned int ch_mask;
-};
-
-#define WCD_SDW_CH(id, pn, cmask) \
- [id] = { \
- .port_num = pn, \
- .ch_mask = cmask, \
- }
-
enum wcd939x_tx_sdw_ports {
WCD939X_ADC_1_4_PORT = 1,
WCD939X_ADC_DMIC_1_2_PORT,
@@ -909,7 +898,7 @@ struct wcd939x_sdw_priv {
struct sdw_stream_config sconfig;
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WCD939X_MAX_SWR_PORTS];
- const struct wcd939x_sdw_ch_info *ch_info;
+ const struct wcd_sdw_ch_info *ch_info;
bool port_enable[WCD939X_MAX_SWR_CH_IDS];
int active_ports;
bool is_tx;
@@ -929,11 +918,6 @@ int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
-
-struct device *wcd939x_sdw_device_get(struct device_node *np);
-unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev);
-
-struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd);
#else
static inline int wcd939x_sdw_free(struct wcd939x_sdw_priv *wcd,
@@ -958,20 +942,6 @@ static inline int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd,
return -EOPNOTSUPP;
}
-static inline struct device *wcd939x_sdw_device_get(struct device_node *np)
-{
- return NULL;
-}
-
-static inline unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev)
-{
- return 0;
-}
-
-struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd)
-{
- return PTR_ERR(-EINVAL);
-}
#endif /* CONFIG_SND_SOC_WCD939X_SDW */
#endif /* __WCD939X_H__ */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
deleted file mode 100644
index 737ca82cf976..000000000000
--- a/sound/soc/codecs/wl1273.c
+++ /dev/null
@@ -1,500 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * ALSA SoC WL1273 codec driver
- *
- * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>
- *
- * Copyright: (C) 2010, 2011 Nokia Corporation
- */
-
-#include <linux/mfd/wl1273-core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wl1273.h"
-
-enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };
-
-/* codec private data */
-struct wl1273_priv {
- enum wl1273_mode mode;
- struct wl1273_core *core;
- unsigned int channels;
-};
-
-static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
- int rate, int width)
-{
- struct device *dev = &core->client->dev;
- int r = 0;
- u16 mode;
-
- dev_dbg(dev, "rate: %d\n", rate);
- dev_dbg(dev, "width: %d\n", width);
-
- mutex_lock(&core->lock);
-
- mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;
-
- switch (rate) {
- case 48000:
- mode |= WL1273_IS2_RATE_48K;
- break;
- case 44100:
- mode |= WL1273_IS2_RATE_44_1K;
- break;
- case 32000:
- mode |= WL1273_IS2_RATE_32K;
- break;
- case 22050:
- mode |= WL1273_IS2_RATE_22_05K;
- break;
- case 16000:
- mode |= WL1273_IS2_RATE_16K;
- break;
- case 12000:
- mode |= WL1273_IS2_RATE_12K;
- break;
- case 11025:
- mode |= WL1273_IS2_RATE_11_025;
- break;
- case 8000:
- mode |= WL1273_IS2_RATE_8K;
- break;
- default:
- dev_err(dev, "Sampling rate: %d not supported\n", rate);
- r = -EINVAL;
- goto out;
- }
-
- switch (width) {
- case 16:
- mode |= WL1273_IS2_WIDTH_32;
- break;
- case 20:
- mode |= WL1273_IS2_WIDTH_40;
- break;
- case 24:
- mode |= WL1273_IS2_WIDTH_48;
- break;
- case 25:
- mode |= WL1273_IS2_WIDTH_50;
- break;
- case 30:
- mode |= WL1273_IS2_WIDTH_60;
- break;
- case 32:
- mode |= WL1273_IS2_WIDTH_64;
- break;
- case 40:
- mode |= WL1273_IS2_WIDTH_80;
- break;
- case 48:
- mode |= WL1273_IS2_WIDTH_96;
- break;
- case 64:
- mode |= WL1273_IS2_WIDTH_128;
- break;
- default:
- dev_err(dev, "Data width: %d not supported\n", width);
- r = -EINVAL;
- goto out;
- }
-
- dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE);
- dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
- dev_dbg(dev, "mode: 0x%04x\n", mode);
-
- if (core->i2s_mode != mode) {
- r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
- if (r)
- goto out;
-
- core->i2s_mode = mode;
- r = core->write(core, WL1273_AUDIO_ENABLE,
- WL1273_AUDIO_ENABLE_I2S);
- if (r)
- goto out;
- }
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
- int channel_number)
-{
- struct device *dev = &core->client->dev;
- int r = 0;
-
- dev_dbg(dev, "%s\n", __func__);
-
- mutex_lock(&core->lock);
-
- if (core->channel_number == channel_number)
- goto out;
-
- if (channel_number == 1 && core->mode == WL1273_MODE_RX)
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
- else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
- else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
- else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
- else
- r = -EINVAL;
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- ucontrol->value.enumerated.item[0] = wl1273->mode;
-
- return 0;
-}
-
-/*
- * TODO: Implement the audio routing in the driver. Now this control
- * only indicates the setting that has been done elsewhere (in the user
- * space).
- */
-static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
-
-static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- if (wl1273->mode == ucontrol->value.enumerated.item[0])
- return 0;
-
- /* Do not allow changes while stream is running */
- if (snd_soc_component_active(component))
- return -EPERM;
-
- if (ucontrol->value.enumerated.item[0] >= ARRAY_SIZE(wl1273_audio_route))
- return -EINVAL;
-
- wl1273->mode = ucontrol->value.enumerated.item[0];
-
- return 1;
-}
-
-static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);
-
-static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- dev_dbg(component->dev, "%s: enter.\n", __func__);
-
- ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;
-
- return 0;
-}
-
-static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
- int val, r = 0;
-
- dev_dbg(component->dev, "%s: enter.\n", __func__);
-
- val = ucontrol->value.enumerated.item[0];
- if (wl1273->core->audio_mode == val)
- return 0;
-
- r = wl1273->core->set_audio(wl1273->core, val);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
-
-static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);
-
-static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- dev_dbg(component->dev, "%s: enter.\n", __func__);
-
- ucontrol->value.integer.value[0] = wl1273->core->volume;
-
- return 0;
-}
-
-static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
- int r;
-
- dev_dbg(component->dev, "%s: enter.\n", __func__);
-
- r = wl1273->core->set_volume(wl1273->core,
- ucontrol->value.integer.value[0]);
- if (r)
- return r;
-
- return 1;
-}
-
-static const struct snd_kcontrol_new wl1273_controls[] = {
- SOC_ENUM_EXT("Codec Mode", wl1273_enum,
- snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
- SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
- snd_wl1273_fm_audio_get, snd_wl1273_fm_audio_put),
- SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
- snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
-};
-
-static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("RX"),
-
- SND_SOC_DAPM_OUTPUT("TX"),
-};
-
-static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
- { "Capture", NULL, "RX" },
-
- { "TX", NULL, "Playback" },
-};
-
-static int wl1273_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_component *component = dai->component;
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- switch (wl1273->mode) {
- case WL1273_MODE_BT:
- snd_pcm_hw_constraint_single(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE, 8000);
- snd_pcm_hw_constraint_single(substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS, 1);
- break;
- case WL1273_MODE_FM_RX:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pr_err("Cannot play in RX mode.\n");
- return -EINVAL;
- }
- break;
- case WL1273_MODE_FM_TX:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- pr_err("Cannot capture in TX mode.\n");
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wl1273_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);
- struct wl1273_core *core = wl1273->core;
- unsigned int rate, width, r;
-
- if (params_width(params) != 16) {
- dev_err(dai->dev, "%d bits/sample not supported\n",
- params_width(params));
- return -EINVAL;
- }
-
- rate = params_rate(params);
- width = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
-
- if (wl1273->mode == WL1273_MODE_BT) {
- if (rate != 8000) {
- pr_err("Rate %d not supported.\n", params_rate(params));
- return -EINVAL;
- }
-
- if (params_channels(params) != 1) {
- pr_err("Only mono supported.\n");
- return -EINVAL;
- }
-
- return 0;
- }
-
- if (wl1273->mode == WL1273_MODE_FM_TX &&
- substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- pr_err("Only playback supported with TX.\n");
- return -EINVAL;
- }
-
- if (wl1273->mode == WL1273_MODE_FM_RX &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pr_err("Only capture supported with RX.\n");
- return -EINVAL;
- }
-
- if (wl1273->mode != WL1273_MODE_FM_RX &&
- wl1273->mode != WL1273_MODE_FM_TX) {
- pr_err("Unexpected mode: %d.\n", wl1273->mode);
- return -EINVAL;
- }
-
- r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
- if (r)
- return r;
-
- wl1273->channels = params_channels(params);
- r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
- if (r)
- return r;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops wl1273_dai_ops = {
- .startup = wl1273_startup,
- .hw_params = wl1273_hw_params,
-};
-
-static struct snd_soc_dai_driver wl1273_dai = {
- .name = "wl1273-fm",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE},
- .ops = &wl1273_dai_ops,
-};
-
-/* Audio interface format for the soc_card driver */
-int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)
-{
- struct wl1273_priv *wl1273;
-
- if (component == NULL || fmt == NULL)
- return -EINVAL;
-
- wl1273 = snd_soc_component_get_drvdata(component);
-
- switch (wl1273->mode) {
- case WL1273_MODE_FM_RX:
- case WL1273_MODE_FM_TX:
- *fmt = SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBP_CFP;
-
- break;
- case WL1273_MODE_BT:
- *fmt = SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBP_CFP;
-
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wl1273_get_format);
-
-static int wl1273_probe(struct snd_soc_component *component)
-{
- struct wl1273_core **core = component->dev->platform_data;
- struct wl1273_priv *wl1273;
-
- dev_dbg(component->dev, "%s.\n", __func__);
-
- if (!core) {
- dev_err(component->dev, "Platform data is missing.\n");
- return -EINVAL;
- }
-
- wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
- if (!wl1273)
- return -ENOMEM;
-
- wl1273->mode = WL1273_MODE_BT;
- wl1273->core = *core;
-
- snd_soc_component_set_drvdata(component, wl1273);
-
- return 0;
-}
-
-static void wl1273_remove(struct snd_soc_component *component)
-{
- struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
-
- dev_dbg(component->dev, "%s\n", __func__);
- kfree(wl1273);
-}
-
-static const struct snd_soc_component_driver soc_component_dev_wl1273 = {
- .probe = wl1273_probe,
- .remove = wl1273_remove,
- .controls = wl1273_controls,
- .num_controls = ARRAY_SIZE(wl1273_controls),
- .dapm_widgets = wl1273_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),
- .dapm_routes = wl1273_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),
- .idle_bias_on = 1,
- .use_pmdown_time = 1,
- .endianness = 1,
-};
-
-static int wl1273_platform_probe(struct platform_device *pdev)
-{
- return devm_snd_soc_register_component(&pdev->dev,
- &soc_component_dev_wl1273,
- &wl1273_dai, 1);
-}
-
-MODULE_ALIAS("platform:wl1273-codec");
-
-static struct platform_driver wl1273_platform_driver = {
- .driver = {
- .name = "wl1273-codec",
- },
- .probe = wl1273_platform_probe,
-};
-
-module_platform_driver(wl1273_platform_driver);
-
-MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
-MODULE_DESCRIPTION("ASoC WL1273 codec driver");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wl1273.h b/sound/soc/codecs/wl1273.h
deleted file mode 100644
index 66c312fa7eee..000000000000
--- a/sound/soc/codecs/wl1273.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * sound/soc/codec/wl1273.h
- *
- * ALSA SoC WL1273 codec driver
- *
- * Copyright (C) Nokia Corporation
- * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
- */
-
-#ifndef __WL1273_CODEC_H__
-#define __WL1273_CODEC_H__
-
-int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt);
-
-#endif /* End of __WL1273_CODEC_H__ */
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 9be4f6cadba3..75d923c2c9ca 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1536,7 +1536,7 @@ static int wm8993_probe(struct snd_soc_component *component)
* VMID as an output and can disable it.
*/
if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff)
- dapm->idle_bias_off = 1;
+ dapm->idle_bias = false;
return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 240ec1bed234..128c3a59beac 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4182,8 +4182,8 @@ static int wm8994_component_probe(struct snd_soc_component *component)
wm8994->micdet_irq = control->pdata.micdet_irq;
- /* By default use idle_bias_off, will override for WM8994 */
- dapm->idle_bias_off = 1;
+ /* By default use idle_bias false, will override for WM8994 */
+ dapm->idle_bias = false;
/* Set revision-specific configuration */
switch (control->type) {
@@ -4191,7 +4191,7 @@ static int wm8994_component_probe(struct snd_soc_component *component)
/* Single ended line outputs should have VMID on. */
if (!control->pdata.lineout1_diff ||
!control->pdata.lineout2_diff)
- dapm->idle_bias_off = 0;
+ dapm->idle_bias = true;
switch (control->revision) {
case 2:
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index bc584b17bf28..b28398aa9e48 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -106,33 +106,33 @@ struct wm8994_priv {
int vss_ena[3];
int enh_eq_ena[3];
- /* Platform dependant DRC configuration */
+ /* Platform dependent DRC configuration */
const char **drc_texts;
int drc_cfg[WM8994_NUM_DRC];
struct soc_enum drc_enum;
- /* Platform dependant ReTune mobile configuration */
+ /* Platform dependent ReTune mobile configuration */
int num_retune_mobile_texts;
const char **retune_mobile_texts;
int retune_mobile_cfg[WM8994_NUM_EQ];
struct soc_enum retune_mobile_enum;
- /* Platform dependant MBC configuration */
+ /* Platform dependent MBC configuration */
int mbc_cfg;
const char **mbc_texts;
struct soc_enum mbc_enum;
- /* Platform dependant VSS configuration */
+ /* Platform dependent VSS configuration */
int vss_cfg;
const char **vss_texts;
struct soc_enum vss_enum;
- /* Platform dependant VSS HPF configuration */
+ /* Platform dependent VSS HPF configuration */
int vss_hpf_cfg;
const char **vss_hpf_texts;
struct soc_enum vss_hpf_enum;
- /* Platform dependant enhanced EQ configuration */
+ /* Platform dependent enhanced EQ configuration */
int enh_eq_cfg;
const char **enh_eq_texts;
struct soc_enum enh_eq_enum;
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 459b39998307..ee2040782532 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -77,7 +77,7 @@ struct wm8996_priv {
int rx_rate[WM8996_AIFS];
int bclk_rate[WM8996_AIFS];
- /* Platform dependant ReTune mobile configuration */
+ /* Platform dependent ReTune mobile configuration */
int num_retune_mobile_texts;
const char **retune_mobile_texts;
int retune_mobile_cfg[2];
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 8a1d5cc75d6c..8782c331e925 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -173,7 +173,7 @@ struct wm_adsp_compr {
struct snd_compressed_buffer size;
u32 *raw_buf;
- unsigned int copied_total;
+ u64 copied_total;
unsigned int sample_rate;
@@ -1043,7 +1043,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- queue_work(system_unbound_wq, &dsp->boot_work);
+ queue_work(system_dfl_wq, &dsp->boot_work);
break;
case SND_SOC_DAPM_PRE_PMD:
wm_adsp_power_down(dsp);
@@ -1860,7 +1860,7 @@ static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf)
int wm_adsp_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct wm_adsp_compr *compr = stream->runtime->private_data;
struct wm_adsp *dsp = compr->dsp;
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 25210d404bf1..8035fda71f8d 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -131,7 +131,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component,
int wm_adsp_compr_handle_irq(struct wm_adsp *dsp);
int wm_adsp_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp);
+ struct snd_compr_tstamp64 *tstamp);
int wm_adsp_compr_copy(struct snd_soc_component *component,
struct snd_compr_stream *stream,
char __user *buf, size_t count);
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
index 188363b03b93..ca4520ade79a 100644
--- a/sound/soc/codecs/wsa883x.c
+++ b/sound/soc/codecs/wsa883x.c
@@ -14,6 +14,7 @@
#include <linux/printk.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_registers.h>
@@ -468,6 +469,7 @@ struct wsa883x_priv {
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WSA883X_MAX_SWR_PORTS];
struct gpio_desc *sd_n;
+ struct reset_control *sd_reset;
bool port_prepared[WSA883X_MAX_SWR_PORTS];
bool port_enable[WSA883X_MAX_SWR_PORTS];
int active_ports;
@@ -1546,6 +1548,46 @@ static const struct hwmon_chip_info wsa883x_hwmon_chip_info = {
.info = wsa883x_hwmon_info,
};
+static void wsa883x_reset_assert(void *data)
+{
+ struct wsa883x_priv *wsa883x = data;
+
+ if (wsa883x->sd_reset)
+ reset_control_assert(wsa883x->sd_reset);
+ else
+ gpiod_direction_output(wsa883x->sd_n, 1);
+}
+
+static void wsa883x_reset_deassert(struct wsa883x_priv *wsa883x)
+{
+ if (wsa883x->sd_reset)
+ reset_control_deassert(wsa883x->sd_reset);
+ else
+ gpiod_direction_output(wsa883x->sd_n, 0);
+}
+
+static int wsa883x_get_reset(struct device *dev, struct wsa883x_priv *wsa883x)
+{
+ wsa883x->sd_reset = devm_reset_control_get_optional_shared(dev, NULL);
+ if (IS_ERR(wsa883x->sd_reset))
+ return dev_err_probe(dev, PTR_ERR(wsa883x->sd_reset),
+ "Failed to get reset\n");
+ /*
+ * if sd_reset: NULL, so use the backwards compatible way for powerdown-gpios,
+ * which does not handle sharing GPIO properly.
+ */
+ if (!wsa883x->sd_reset) {
+ wsa883x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
+ GPIOD_FLAGS_BIT_NONEXCLUSIVE |
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(wsa883x->sd_n))
+ return dev_err_probe(dev, PTR_ERR(wsa883x->sd_n),
+ "Shutdown Control GPIO not found\n");
+ }
+
+ return 0;
+}
+
static int wsa883x_probe(struct sdw_slave *pdev,
const struct sdw_device_id *id)
{
@@ -1566,13 +1608,9 @@ static int wsa883x_probe(struct sdw_slave *pdev,
if (ret)
return dev_err_probe(dev, ret, "Failed to enable vdd regulator\n");
- wsa883x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
- GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH);
- if (IS_ERR(wsa883x->sd_n)) {
- ret = dev_err_probe(dev, PTR_ERR(wsa883x->sd_n),
- "Shutdown Control GPIO not found\n");
+ ret = wsa883x_get_reset(dev, wsa883x);
+ if (ret)
goto err;
- }
dev_set_drvdata(dev, wsa883x);
wsa883x->slave = pdev;
@@ -1595,11 +1633,14 @@ static int wsa883x_probe(struct sdw_slave *pdev,
pdev->prop.simple_clk_stop_capable = true;
pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
- gpiod_direction_output(wsa883x->sd_n, 0);
+
+ wsa883x_reset_deassert(wsa883x);
+ ret = devm_add_action_or_reset(dev, wsa883x_reset_assert, wsa883x);
+ if (ret)
+ return ret;
wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config);
if (IS_ERR(wsa883x->regmap)) {
- gpiod_direction_output(wsa883x->sd_n, 1);
ret = dev_err_probe(dev, PTR_ERR(wsa883x->regmap),
"regmap_init failed\n");
goto err;
diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index 5614a8b909ed..3de448ef724c 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -17,12 +17,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
-struct qmc_dai_chan {
- struct qmc_dai_prtd *prtd_tx;
- struct qmc_dai_prtd *prtd_rx;
- struct qmc_chan *qmc_chan;
-};
-
struct qmc_dai {
char *name;
int id;
@@ -33,7 +27,7 @@ struct qmc_dai {
unsigned int nb_chans_avail;
unsigned int nb_chans_used_tx;
unsigned int nb_chans_used_rx;
- struct qmc_dai_chan *chans;
+ struct qmc_chan **qmc_chans;
};
struct qmc_audio {
@@ -57,7 +51,6 @@ struct qmc_dai_prtd {
size_t ch_dma_offset;
unsigned int channels;
- DECLARE_BITMAP(chans_pending, 64);
struct snd_pcm_substream *substream;
};
@@ -126,17 +119,14 @@ static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
int ret;
for (i = 0; i < prtd->channels; i++) {
- bitmap_set(prtd->chans_pending, i, 1);
-
- ret = qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan,
+ ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chans[i],
prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
prtd->ch_dma_size,
- qmc_audio_pcm_write_complete,
- &prtd->qmc_dai->chans[i]);
+ i == prtd->channels - 1 ? qmc_audio_pcm_write_complete :
+ NULL, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "write_submit %u failed %d\n",
i, ret);
- bitmap_clear(prtd->chans_pending, i, 1);
return ret;
}
}
@@ -146,20 +136,7 @@ static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
static void qmc_audio_pcm_write_complete(void *context)
{
- struct qmc_dai_chan *chan = context;
- struct qmc_dai_prtd *prtd;
-
- prtd = chan->prtd_tx;
-
- /* Mark the current channel as completed */
- bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1);
-
- /*
- * All QMC channels involved must have completed their transfer before
- * submitting a new one.
- */
- if (!bitmap_empty(prtd->chans_pending, 64))
- return;
+ struct qmc_dai_prtd *prtd = context;
prtd->buffer_ended += prtd->period_size;
if (prtd->buffer_ended >= prtd->buffer_size)
@@ -182,17 +159,14 @@ static int qmc_audio_pcm_read_submit(struct qmc_dai_prtd *prtd)
int ret;
for (i = 0; i < prtd->channels; i++) {
- bitmap_set(prtd->chans_pending, i, 1);
-
- ret = qmc_chan_read_submit(prtd->qmc_dai->chans[i].qmc_chan,
+ ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chans[i],
prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
prtd->ch_dma_size,
- qmc_audio_pcm_read_complete,
- &prtd->qmc_dai->chans[i]);
+ i == prtd->channels - 1 ? qmc_audio_pcm_read_complete :
+ NULL, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "read_submit %u failed %d\n",
i, ret);
- bitmap_clear(prtd->chans_pending, i, 1);
return ret;
}
}
@@ -202,26 +176,13 @@ static int qmc_audio_pcm_read_submit(struct qmc_dai_prtd *prtd)
static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned int flags)
{
- struct qmc_dai_chan *chan = context;
- struct qmc_dai_prtd *prtd;
-
- prtd = chan->prtd_rx;
-
- /* Mark the current channel as completed */
- bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1);
+ struct qmc_dai_prtd *prtd = context;
if (length != prtd->ch_dma_size) {
dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n",
length, prtd->ch_dma_size);
}
- /*
- * All QMC channels involved must have completed their transfer before
- * submitting a new one.
- */
- if (!bitmap_empty(prtd->chans_pending, 64))
- return;
-
prtd->buffer_ended += prtd->period_size;
if (prtd->buffer_ended >= prtd->buffer_size)
prtd->buffer_ended = 0;
@@ -239,7 +200,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int cmd)
{
struct qmc_dai_prtd *prtd = substream->runtime->private_data;
- unsigned int i;
int ret;
if (!prtd->qmc_dai) {
@@ -249,14 +209,10 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- bitmap_zero(prtd->chans_pending, 64);
prtd->buffer_ended = 0;
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- for (i = 0; i < prtd->channels; i++)
- prtd->qmc_dai->chans[i].prtd_tx = prtd;
-
/* Submit first chunk ... */
ret = qmc_audio_pcm_write_submit(prtd);
if (ret)
@@ -272,9 +228,6 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
if (ret)
return ret;
} else {
- for (i = 0; i < prtd->channels; i++)
- prtd->qmc_dai->chans[i].prtd_rx = prtd;
-
/* Submit first chunk ... */
ret = qmc_audio_pcm_read_submit(prtd);
if (ret)
@@ -644,9 +597,9 @@ static int qmc_dai_hw_params(struct snd_pcm_substream *substream,
chan_param.mode = QMC_TRANSPARENT;
chan_param.transp.max_rx_buf_size = params_period_bytes(params) / nb_chans_used;
for (i = 0; i < nb_chans_used; i++) {
- ret = qmc_chan_set_param(qmc_dai->chans[i].qmc_chan, &chan_param);
+ ret = qmc_chan_set_param(qmc_dai->qmc_chans[i], &chan_param);
if (ret) {
- dev_err(dai->dev, "chans[%u], set param failed %d\n",
+ dev_err(dai->dev, "qmc_chans[%u], set param failed %d\n",
i, ret);
return ret;
}
@@ -688,7 +641,7 @@ static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
for (i = 0; i < nb_chans_used; i++) {
- ret = qmc_chan_start(qmc_dai->chans[i].qmc_chan, direction);
+ ret = qmc_chan_start(qmc_dai->qmc_chans[i], direction);
if (ret)
goto err_stop;
}
@@ -697,13 +650,13 @@ static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_STOP:
/* Stop and reset all QMC channels and return the first error encountered */
for (i = 0; i < nb_chans_used; i++) {
- ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
+ ret_tmp = qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
if (!ret)
ret = ret_tmp;
if (ret_tmp)
continue;
- ret_tmp = qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
+ ret_tmp = qmc_chan_reset(qmc_dai->qmc_chans[i], direction);
if (!ret)
ret = ret_tmp;
}
@@ -715,7 +668,7 @@ static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* Stop all QMC channels and return the first error encountered */
for (i = 0; i < nb_chans_used; i++) {
- ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
+ ret_tmp = qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
if (!ret)
ret = ret_tmp;
}
@@ -731,8 +684,8 @@ static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
err_stop:
while (i--) {
- qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
- qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
+ qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
+ qmc_chan_reset(qmc_dai->qmc_chans[i], direction);
}
return ret;
}
@@ -791,12 +744,17 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
struct qmc_dai *qmc_dai,
struct snd_soc_dai_driver *qmc_soc_dai_driver)
{
+ struct qmc_chan_ts_info ts_info;
struct qmc_chan_info info;
unsigned long rx_fs_rate;
unsigned long tx_fs_rate;
+ int prev_last_rx_ts = 0;
+ int prev_last_tx_ts = 0;
unsigned int nb_tx_ts;
unsigned int nb_rx_ts;
unsigned int i;
+ int last_rx_ts;
+ int last_tx_ts;
int count;
u32 val;
int ret;
@@ -823,19 +781,20 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
return dev_err_probe(qmc_audio->dev, -EINVAL,
"dai %d no QMC channel defined\n", qmc_dai->id);
- qmc_dai->chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->chans), GFP_KERNEL);
- if (!qmc_dai->chans)
+ qmc_dai->qmc_chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->qmc_chans),
+ GFP_KERNEL);
+ if (!qmc_dai->qmc_chans)
return -ENOMEM;
for (i = 0; i < count; i++) {
- qmc_dai->chans[i].qmc_chan = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np,
- "fsl,qmc-chan", i);
- if (IS_ERR(qmc_dai->chans[i].qmc_chan)) {
- return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->chans[i].qmc_chan),
+ qmc_dai->qmc_chans[i] = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np,
+ "fsl,qmc-chan", i);
+ if (IS_ERR(qmc_dai->qmc_chans[i])) {
+ return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->qmc_chans[i]),
"dai %d get QMC channel %d failed\n", qmc_dai->id, i);
}
- ret = qmc_chan_get_info(qmc_dai->chans[i].qmc_chan, &info);
+ ret = qmc_chan_get_info(qmc_dai->qmc_chans[i], &info);
if (ret) {
dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n",
qmc_dai->id, i, ret);
@@ -879,6 +838,30 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
return -EINVAL;
}
}
+
+ ret = qmc_chan_get_ts_info(qmc_dai->qmc_chans[i], &ts_info);
+ if (ret) {
+ dev_err(qmc_audio->dev, "dai %d get QMC %d channel TS info failed %d\n",
+ qmc_dai->id, i, ret);
+ return ret;
+ }
+
+ last_rx_ts = fls64(ts_info.rx_ts_mask);
+ last_tx_ts = fls64(ts_info.tx_ts_mask);
+
+ if (prev_last_rx_ts > last_rx_ts) {
+ dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (RX timeslot %d before %d)\n",
+ qmc_dai->id, i, prev_last_rx_ts, last_rx_ts);
+ return -EINVAL;
+ }
+ if (prev_last_tx_ts > last_tx_ts) {
+ dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (TX timeslot %d before %d)\n",
+ qmc_dai->id, i, prev_last_tx_ts, last_tx_ts);
+ return -EINVAL;
+ }
+
+ prev_last_rx_ts = last_rx_ts;
+ prev_last_tx_ts = last_tx_ts;
}
qmc_dai->nb_chans_avail = count;
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d0367b21f775..757e7868e322 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1244,7 +1244,6 @@ static struct regmap_config fsl_sai_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
- .fast_io = true,
.max_register = FSL_SAI_RMR,
.reg_defaults = fsl_sai_reg_defaults_ofs0,
@@ -1346,7 +1345,7 @@ static int fsl_sai_read_dlcfg(struct fsl_sai *sai)
num_cfg = elems / 3;
/* Add one more for default value */
- cfg = devm_kzalloc(&pdev->dev, (num_cfg + 1) * sizeof(*cfg), GFP_KERNEL);
+ cfg = devm_kcalloc(&pdev->dev, num_cfg + 1, sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return -ENOMEM;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index cc2918ee2cf5..f8335a04595a 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -305,7 +305,7 @@ static int imx_audmux_probe(struct platform_device *pdev)
return -EINVAL;
}
- regcache = devm_kzalloc(&pdev->dev, sizeof(u32) * reg_max, GFP_KERNEL);
+ regcache = devm_kcalloc(&pdev->dev, reg_max, sizeof(u32), GFP_KERNEL);
if (!regcache)
return -ENOMEM;
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
index fe47b439a818..1115189cc640 100644
--- a/sound/soc/fsl/imx-hdmi.c
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -101,7 +101,6 @@ static int imx_hdmi_probe(struct platform_device *pdev)
bool hdmi_out = of_property_read_bool(np, "hdmi-out");
bool hdmi_in = of_property_read_bool(np, "hdmi-in");
struct snd_soc_dai_link_component *dlc;
- struct platform_device *cpu_pdev;
struct device_node *cpu_np;
struct imx_hdmi_data *data;
int ret;
@@ -117,17 +116,9 @@ static int imx_hdmi_probe(struct platform_device *pdev)
goto fail;
}
- cpu_pdev = of_find_device_by_node(cpu_np);
- if (!cpu_pdev) {
- dev_err(&pdev->dev, "failed to find SAI platform device\n");
- ret = -EINVAL;
- goto fail;
- }
-
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
- put_device(&cpu_pdev->dev);
goto fail;
}
@@ -140,15 +131,13 @@ static int imx_hdmi_probe(struct platform_device *pdev)
data->dai.name = "i.MX HDMI";
data->dai.stream_name = "i.MX HDMI";
- data->dai.cpus->dai_name = dev_name(&cpu_pdev->dev);
+ data->dai.cpus->of_node = cpu_np;
data->dai.platforms->of_node = cpu_np;
data->dai.ops = &imx_hdmi_ops;
data->dai.playback_only = true;
data->dai.capture_only = false;
data->dai.init = imx_hdmi_init;
- put_device(&cpu_pdev->dev);
-
if (of_node_name_eq(cpu_np, "sai")) {
data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c
index 89b995987e2d..2e49066dedd4 100644
--- a/sound/soc/generic/test-component.c
+++ b/sound/soc/generic/test-component.c
@@ -547,8 +547,8 @@ static int test_driver_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
cdriv = devm_kzalloc(dev, sizeof(*cdriv), GFP_KERNEL);
- ddriv = devm_kzalloc(dev, sizeof(*ddriv) * num, GFP_KERNEL);
- dname = devm_kzalloc(dev, sizeof(*dname) * num, GFP_KERNEL);
+ ddriv = devm_kcalloc(dev, num, sizeof(*ddriv), GFP_KERNEL);
+ dname = devm_kcalloc(dev, num, sizeof(*dname), GFP_KERNEL);
if (!priv || !cdriv || !ddriv || !dname || !adata)
return -EINVAL;
diff --git a/sound/soc/intel/atom/sst-mfld-platform-compress.c b/sound/soc/intel/atom/sst-mfld-platform-compress.c
index 89c9c5ad6b21..9dfb0a814b94 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-compress.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c
@@ -18,6 +18,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/compress_driver.h>
+#include <asm/div64.h>
#include "sst-mfld-platform.h"
/* compress stream operations */
@@ -202,15 +203,16 @@ static int sst_platform_compr_trigger(struct snd_soc_component *component,
static int sst_platform_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct sst_runtime_stream *stream;
+ u64 temp_copied_total = tstamp->copied_total;
- stream = cstream->runtime->private_data;
+ stream = cstream->runtime->private_data;
stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
- tstamp->byte_offset = tstamp->copied_total %
- (u32)cstream->runtime->buffer_size;
- pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
+ tstamp->byte_offset =
+ do_div(temp_copied_total, cstream->runtime->buffer_size);
+ pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset);
return 0;
}
diff --git a/sound/soc/intel/atom/sst-mfld-platform.h b/sound/soc/intel/atom/sst-mfld-platform.h
index 8b5777d3229a..a0e33f7f01c5 100644
--- a/sound/soc/intel/atom/sst-mfld-platform.h
+++ b/sound/soc/intel/atom/sst-mfld-platform.h
@@ -105,7 +105,7 @@ struct compress_sst_ops {
int (*stream_pause_release)(struct device *dev, unsigned int str_id);
int (*tstamp)(struct device *dev, unsigned int str_id,
- struct snd_compr_tstamp *tstamp);
+ struct snd_compr_tstamp64 *tstamp);
int (*ack)(struct device *dev, unsigned int str_id,
unsigned long bytes);
int (*close)(struct device *dev, unsigned int str_id);
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index e0357d257c6c..3c47c8de04b7 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -64,7 +64,7 @@ static irqreturn_t intel_sst_interrupt_mrfld(int irq, void *context)
header.p.header_high.part.done = 0;
sst_shim_write64(drv->shim, drv->ipc_reg.ipcx, header.full);
- /* write 1 to clear status register */;
+ /* write 1 to clear status register */
isr.part.done_interrupt = 1;
sst_shim_write64(drv->shim, SST_ISRX, isr.full);
spin_unlock(&drv->ipc_spin_lock);
diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index 8bb27f86eb65..2646c4632ca1 100644
--- a/sound/soc/intel/atom/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -326,7 +326,7 @@ static int sst_cdev_stream_partial_drain(struct device *dev,
}
static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_sst_tstamp fw_tstamp = {0,};
struct stream_info *stream;
@@ -349,10 +349,11 @@ static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
(u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));
tstamp->sampling_rate = fw_tstamp.sampling_frequency;
- dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames);
- dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n",
+ dev_dbg(dev, "PCM = %llu\n", tstamp->pcm_io_frames);
+ dev_dbg(dev,
+ "Ptr Query on strid = %d copied_total %llu, decodec %llu\n",
str_id, tstamp->copied_total, tstamp->pcm_frames);
- dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames);
+ dev_dbg(dev, "rendered %llu\n", tstamp->pcm_io_frames);
return 0;
}
diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c
index 3dccf0a57a3a..b922eeaba843 100644
--- a/sound/soc/intel/avs/apl.c
+++ b/sound/soc/intel/avs/apl.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
#include "path.h"
#include "registers.h"
diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
index 4c096afc5848..0f8ddd0e9e5f 100644
--- a/sound/soc/intel/avs/avs.h
+++ b/sound/soc/intel/avs/avs.h
@@ -22,7 +22,6 @@
struct avs_dev;
struct avs_tplg;
struct avs_tplg_library;
-struct avs_soc_component;
struct avs_ipc_msg;
#ifdef CONFIG_ACPI
@@ -348,91 +347,18 @@ struct avs_soc_component {
extern const struct snd_soc_dai_ops avs_dai_fe_ops;
-int avs_soc_component_register(struct device *dev, const char *name,
- struct snd_soc_component_driver *drv,
- struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais);
-int avs_dmic_platform_register(struct avs_dev *adev, const char *name);
-int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
- unsigned long *tdms);
-int avs_hda_platform_register(struct avs_dev *adev, const char *name);
+int avs_register_dmic_component(struct avs_dev *adev, const char *name);
+int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
+ unsigned long *tdms);
+int avs_register_hda_component(struct avs_dev *adev, const char *name);
+int avs_register_component(struct device *dev, const char *name,
+ struct snd_soc_component_driver *drv,
+ struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais);
int avs_register_all_boards(struct avs_dev *adev);
void avs_unregister_all_boards(struct avs_dev *adev);
-/* Firmware tracing helpers */
-
-#define avs_log_buffer_size(adev) \
- ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores)
-
-#define avs_log_buffer_addr(adev, core) \
-({ \
- s32 __offset = avs_dsp_op(adev, log_buffer_offset, core); \
- (__offset < 0) ? NULL : \
- (avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \
-})
-
-static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&adev->trace_lock, flags);
- ret = avs_dsp_op(adev, log_buffer_status, msg);
- spin_unlock_irqrestore(&adev->trace_lock, flags);
-
- return ret;
-}
-
-struct avs_apl_log_buffer_layout {
- u32 read_ptr;
- u32 write_ptr;
- u8 buffer[];
-} __packed;
-static_assert(sizeof(struct avs_apl_log_buffer_layout) == 8);
-
-#define avs_apl_log_payload_size(adev) \
- (avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout))
-
-#define avs_apl_log_payload_addr(addr) \
- (addr + sizeof(struct avs_apl_log_buffer_layout))
-
-#ifdef CONFIG_DEBUG_FS
-#define AVS_SET_ENABLE_LOGS_OP(name) \
- .enable_logs = avs_##name##_enable_logs
-
-bool avs_logging_fw(struct avs_dev *adev);
-void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len);
-void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len);
-
-int avs_probe_platform_register(struct avs_dev *adev, const char *name);
-
-void avs_debugfs_init(struct avs_dev *adev);
-void avs_debugfs_exit(struct avs_dev *adev);
-#else
-#define AVS_SET_ENABLE_LOGS_OP(name)
-
-static inline bool avs_logging_fw(struct avs_dev *adev)
-{
- return false;
-}
-
-static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len)
-{
-}
-
-static inline void
-avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len)
-{
-}
-
-static inline int avs_probe_platform_register(struct avs_dev *adev, const char *name)
-{
- return 0;
-}
-
-static inline void avs_debugfs_init(struct avs_dev *adev) { }
-static inline void avs_debugfs_exit(struct avs_dev *adev) { }
-#endif
+int avs_parse_sched_cfg(struct avs_dev *adev, const char *buf, size_t len);
/* Filesystems integration */
diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c
index fb49167f5fc4..52e6266a7cb8 100644
--- a/sound/soc/intel/avs/board_selection.c
+++ b/sound/soc/intel/avs/board_selection.c
@@ -17,6 +17,8 @@
#include <sound/soc-acpi.h>
#include <sound/soc-component.h>
#include "avs.h"
+#include "debug.h"
+#include "pcm.h"
#include "utils.h"
static char *i2s_test;
@@ -56,19 +58,13 @@ static const struct dmi_system_id kblr_dmi_table[] = {
static struct snd_soc_acpi_mach *dmi_match_quirk(void *arg)
{
struct snd_soc_acpi_mach *mach = arg;
- const struct dmi_system_id *dmi_id;
struct dmi_system_id *dmi_table;
- if (mach->quirk_data == NULL)
- return mach;
-
dmi_table = (struct dmi_system_id *)mach->quirk_data;
- dmi_id = dmi_first_match(dmi_table);
- if (!dmi_id)
- return NULL;
-
- return mach;
+ if (!dmi_table || dmi_first_match(dmi_table))
+ return mach;
+ return NULL;
}
#define AVS_SSP(x) (BIT(x))
@@ -368,10 +364,10 @@ struct avs_acpi_boards {
/* supported I2S boards per platform */
static const struct avs_acpi_boards i2s_boards[] = {
- AVS_MACH_ENTRY(HDA_SKL_LP, avs_skl_i2s_machines),
- AVS_MACH_ENTRY(HDA_KBL_LP, avs_kbl_i2s_machines),
- AVS_MACH_ENTRY(HDA_APL, avs_apl_i2s_machines),
- AVS_MACH_ENTRY(HDA_GML, avs_gml_i2s_machines),
+ AVS_MACH_ENTRY(HDA_SKL_LP, avs_skl_i2s_machines),
+ AVS_MACH_ENTRY(HDA_KBL_LP, avs_kbl_i2s_machines),
+ AVS_MACH_ENTRY(HDA_APL, avs_apl_i2s_machines),
+ AVS_MACH_ENTRY(HDA_GML, avs_gml_i2s_machines),
AVS_MACH_ENTRY(HDA_CNL_LP, avs_cnl_i2s_machines),
AVS_MACH_ENTRY(HDA_CNL_H, avs_cnl_i2s_machines),
AVS_MACH_ENTRY(HDA_CML_LP, avs_cnl_i2s_machines),
@@ -386,185 +382,122 @@ static const struct avs_acpi_boards i2s_boards[] = {
{ },
};
-static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev)
+static struct snd_soc_acpi_mach *avs_get_i2s_machines(struct avs_dev *adev)
{
int id, i;
id = adev->base.pci->device;
for (i = 0; i < ARRAY_SIZE(i2s_boards); i++)
if (i2s_boards[i].id == id)
- return &i2s_boards[i];
+ return i2s_boards[i].machs;
return NULL;
}
-/* platform devices owned by AVS audio are removed with this hook */
-static void board_pdev_unregister(void *data)
+/* Platform devices spawned by AVS driver are removed with this hook. */
+static void avs_unregister_board(void *pdev)
{
- platform_device_unregister(data);
+ platform_device_unregister(pdev);
}
-static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
+static struct platform_device *avs_register_board(struct avs_dev *adev, const char *name,
+ const void *data, size_t size)
{
- struct platform_device *board;
- struct snd_soc_acpi_mach mach = {{0}};
+ struct platform_device *pdev;
int ret;
- ret = avs_probe_platform_register(adev, "probe-platform");
- if (ret < 0)
- return ret;
-
- mach.mach_params.platform = "probe-platform";
+ pdev = platform_device_register_data(NULL, name, PLATFORM_DEVID_AUTO, data, size);
+ if (IS_ERR(pdev))
+ return pdev;
- board = platform_device_register_data(NULL, "avs_probe_mb", PLATFORM_DEVID_NONE,
- (const void *)&mach, sizeof(mach));
- if (IS_ERR(board)) {
- dev_err(adev->dev, "probe board register failed\n");
- return PTR_ERR(board);
- }
+ ret = devm_add_action_or_reset(adev->dev, avs_unregister_board, pdev);
+ if (ret)
+ return ERR_PTR(ret);
- ret = devm_add_action(adev->dev, board_pdev_unregister, board);
- if (ret < 0) {
- platform_device_unregister(board);
- return ret;
- }
- return 0;
+ return pdev;
}
-static int avs_register_dmic_board(struct avs_dev *adev)
+static struct platform_device *avs_register_board_pdata(struct avs_dev *adev, const char *name,
+ struct snd_soc_acpi_mach *mach,
+ struct hda_codec *codec,
+ unsigned long *tdms, char *codec_name)
{
- struct platform_device *codec, *board;
- struct snd_soc_acpi_mach mach = {{0}};
struct avs_mach_pdata *pdata;
- int ret;
-
- if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) {
- dev_dbg(adev->dev, "no DMIC endpoints present\n");
- return 0;
- }
-
- codec = platform_device_register_simple("dmic-codec", PLATFORM_DEVID_NONE, NULL, 0);
- if (IS_ERR(codec)) {
- dev_err(adev->dev, "dmic codec register failed\n");
- return PTR_ERR(codec);
- }
-
- ret = devm_add_action(adev->dev, board_pdev_unregister, codec);
- if (ret < 0) {
- platform_device_unregister(codec);
- return ret;
- }
-
- ret = avs_dmic_platform_register(adev, "dmic-platform");
- if (ret < 0)
- return ret;
pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
- return -ENOMEM;
- pdata->obsolete_card_names = obsolete_card_names;
- mach.pdata = pdata;
- mach.tplg_filename = "dmic-tplg.bin";
- mach.mach_params.platform = "dmic-platform";
-
- board = platform_device_register_data(NULL, "avs_dmic", PLATFORM_DEVID_NONE,
- (const void *)&mach, sizeof(mach));
- if (IS_ERR(board)) {
- dev_err(adev->dev, "dmic board register failed\n");
- return PTR_ERR(board);
- }
+ return ERR_PTR(-ENOMEM);
- ret = devm_add_action(adev->dev, board_pdev_unregister, board);
- if (ret < 0) {
- platform_device_unregister(board);
- return ret;
- }
+ pdata->codec = codec;
+ pdata->tdms = tdms;
+ pdata->codec_name = codec_name;
+ pdata->obsolete_card_names = obsolete_card_names;
+ mach->pdata = pdata;
- return 0;
+ return avs_register_board(adev, name, mach, sizeof(*mach));
}
-static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
+static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
{
- struct platform_device *board;
- struct avs_mach_pdata *pdata;
- int num_ssps;
- char *name;
- int ret;
- int uid;
-
- num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
- if (fls(mach->mach_params.i2s_link_mask) > num_ssps) {
- dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n",
- num_ssps, mach->drv_name,
- (unsigned long)__fls(mach->mach_params.i2s_link_mask));
- return -ENODEV;
- }
+ struct platform_device *pdev;
- pdata = mach->pdata;
- if (!pdata)
- pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
- pdata->obsolete_card_names = obsolete_card_names;
- mach->pdata = pdata;
+ pdev = avs_register_board(adev, "avs_probe_mb", NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- uid = mach->mach_params.i2s_link_mask;
- if (avs_mach_singular_ssp(mach))
- uid = (uid << AVS_CHANNELS_MAX) + avs_mach_ssp_tdm(mach, avs_mach_ssp_port(mach));
+ return avs_register_probe_component(adev, dev_name(&pdev->dev));
+}
- name = devm_kasprintf(adev->dev, GFP_KERNEL, "%s.%d-platform", mach->drv_name, uid);
- if (!name)
- return -ENOMEM;
+static int avs_register_dmic_board(struct avs_dev *adev)
+{
+ static struct snd_soc_acpi_mach mach = {
+ .tplg_filename = "dmic-tplg.bin",
+ };
+ struct platform_device *pdev;
+ char *codec_name;
- ret = avs_i2s_platform_register(adev, name, mach->mach_params.i2s_link_mask, pdata->tdms);
- if (ret < 0)
- return ret;
+ if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) {
+ dev_dbg(adev->dev, "no DMIC endpoints present\n");
+ return 0;
+ }
- mach->mach_params.platform = name;
+ /* DMIC present in Intel PCH is enumerated statically. */
+ pdev = avs_register_board(adev, "dmic-codec", NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- board = platform_device_register_data(NULL, mach->drv_name, uid,
- (const void *)mach, sizeof(*mach));
- if (IS_ERR(board)) {
- dev_err(adev->dev, "ssp board register failed\n");
- return PTR_ERR(board);
- }
+ codec_name = devm_kstrdup(adev->dev, dev_name(&pdev->dev), GFP_KERNEL);
+ if (!codec_name)
+ return -ENOMEM;
- ret = devm_add_action(adev->dev, board_pdev_unregister, board);
- if (ret < 0) {
- platform_device_unregister(board);
- return ret;
- }
+ pdev = avs_register_board_pdata(adev, "avs_dmic", &mach, NULL, NULL, codec_name);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- return 0;
+ return avs_register_dmic_component(adev, dev_name(&pdev->dev));
}
static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int tdm_slot)
{
- struct snd_soc_acpi_mach *mach;
- int tdm_mask = BIT(tdm_slot);
- unsigned long *tdm_cfg;
- char *tplg_name;
- int ret;
-
- mach = devm_kzalloc(adev->dev, sizeof(*mach), GFP_KERNEL);
- tdm_cfg = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(unsigned long), GFP_KERNEL);
- tplg_name = devm_kasprintf(adev->dev, GFP_KERNEL, AVS_STRING_FMT("i2s", "-test-tplg.bin",
- ssp_port, tdm_slot));
- if (!mach || !tdm_cfg || !tplg_name)
+ struct snd_soc_acpi_mach mach = {{0}};
+ struct platform_device *pdev;
+ unsigned long *tdms;
+
+ tdms = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(*tdms), GFP_KERNEL);
+ mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
+ AVS_STRING_FMT("i2s", "-test-tplg.bin",
+ ssp_port, tdm_slot));
+ if (!tdms || !mach.tplg_filename)
return -ENOMEM;
- mach->drv_name = "avs_i2s_test";
- mach->mach_params.i2s_link_mask = AVS_SSP(ssp_port);
- tdm_cfg[ssp_port] = tdm_mask;
- mach->pdata = tdm_cfg;
- mach->tplg_filename = tplg_name;
+ tdms[ssp_port] = BIT(tdm_slot);
+ mach.drv_name = "avs_i2s_test";
+ mach.mach_params.i2s_link_mask = AVS_SSP(ssp_port);
- ret = avs_register_i2s_board(adev, mach);
- if (ret < 0) {
- dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret);
- return ret;
- }
+ pdev = avs_register_board_pdata(adev, mach.drv_name, &mach, NULL, tdms, NULL);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- return 0;
+ return avs_register_i2s_component(adev, dev_name(&pdev->dev), AVS_SSP(ssp_port), tdms);
}
static int avs_register_i2s_test_boards(struct avs_dev *adev)
@@ -574,6 +507,9 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
unsigned long tdm_slots;
u32 *array, num_elems;
+ if (!i2s_test)
+ return 0;
+
ret = parse_int_array(i2s_test, strlen(i2s_test), (int **)&array);
if (ret) {
dev_err(adev->dev, "failed to parse i2s_test parameter\n");
@@ -599,9 +535,26 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
return 0;
}
+static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
+{
+ u32 i2s_mask = mach->mach_params.i2s_link_mask;
+ struct platform_device *pdev;
+ unsigned long *tdms = NULL;
+
+ if (mach->pdata)
+ tdms = ((struct avs_mach_pdata *)mach->pdata)->tdms;
+
+ pdev = avs_register_board_pdata(adev, mach->drv_name, mach, NULL, tdms, NULL);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return avs_register_i2s_component(adev, dev_name(&pdev->dev), i2s_mask, tdms);
+}
+
static int avs_register_i2s_boards(struct avs_dev *adev)
{
- const struct avs_acpi_boards *boards;
+ int num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
+ struct snd_soc_acpi_mach *machs;
struct snd_soc_acpi_mach *mach;
int ret;
@@ -610,19 +563,22 @@ static int avs_register_i2s_boards(struct avs_dev *adev)
return 0;
}
- if (i2s_test)
- return avs_register_i2s_test_boards(adev);
-
- boards = avs_get_i2s_boards(adev);
- if (!boards) {
+ machs = avs_get_i2s_machines(adev);
+ if (!machs) {
dev_dbg(adev->dev, "no I2S endpoints supported\n");
return 0;
}
- for (mach = boards->machs; mach->id[0]; mach++) {
+ for (mach = machs; mach->id[0]; mach++) {
if (!acpi_dev_present(mach->id, mach->uid, -1))
continue;
+ if (fls(mach->mach_params.i2s_link_mask) > num_ssps) {
+ dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n",
+ num_ssps, mach->drv_name,
+ (unsigned long)__fls(mach->mach_params.i2s_link_mask));
+ continue;
+ }
if (mach->machine_quirk)
if (!mach->machine_quirk(mach))
continue;
@@ -637,49 +593,20 @@ static int avs_register_i2s_boards(struct avs_dev *adev)
static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec)
{
- struct snd_soc_acpi_mach mach = {{0}};
- struct platform_device *board;
- struct avs_mach_pdata *pdata;
struct hdac_device *hdev = &codec->core;
- char *pname;
- int ret, id;
-
- pname = devm_kasprintf(adev->dev, GFP_KERNEL, "%s-platform", dev_name(&hdev->dev));
- if (!pname)
- return -ENOMEM;
-
- pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
- pdata->obsolete_card_names = obsolete_card_names;
- pdata->codec = codec;
-
- ret = avs_hda_platform_register(adev, pname);
- if (ret < 0)
- return ret;
+ struct snd_soc_acpi_mach mach = {{0}};
+ struct platform_device *pdev;
- mach.pdata = pdata;
- mach.mach_params.platform = pname;
mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin",
hdev->vendor_id);
if (!mach.tplg_filename)
return -ENOMEM;
- id = adev->base.core.idx * HDA_MAX_CODECS + hdev->addr;
- board = platform_device_register_data(NULL, "avs_hdaudio", id, (const void *)&mach,
- sizeof(mach));
- if (IS_ERR(board)) {
- dev_err(adev->dev, "hda board register failed\n");
- return PTR_ERR(board);
- }
-
- ret = devm_add_action(adev->dev, board_pdev_unregister, board);
- if (ret < 0) {
- platform_device_unregister(board);
- return ret;
- }
+ pdev = avs_register_board_pdata(adev, "avs_hdaudio", &mach, codec, NULL, NULL);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
- return 0;
+ return avs_register_hda_component(adev, dev_name(&pdev->dev));
}
static int avs_register_hda_boards(struct avs_dev *adev)
@@ -722,6 +649,10 @@ int avs_register_all_boards(struct avs_dev *adev)
dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n",
ret);
+ ret = avs_register_i2s_test_boards(adev);
+ if (ret)
+ dev_dbg(adev->dev, "enumerate I2S TEST endpoints failed: %d\n", ret);
+
ret = avs_register_i2s_boards(adev);
if (ret < 0)
dev_warn(adev->dev, "enumerate I2S endpoints failed: %d\n",
diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c
index 3ef0db254142..6782dc7efae3 100644
--- a/sound/soc/intel/avs/boards/da7219.c
+++ b/sound/soc/intel/avs/boards/da7219.c
@@ -165,8 +165,8 @@ avs_da7219_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_param
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -176,8 +176,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port);
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
@@ -193,6 +191,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -218,18 +217,16 @@ static int avs_da7219_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -259,10 +256,6 @@ static int avs_da7219_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/dmic.c b/sound/soc/intel/avs/boards/dmic.c
index a1448a98874d..bf6f580a5164 100644
--- a/sound/soc/intel/avs/boards/dmic.c
+++ b/sound/soc/intel/avs/boards/dmic.c
@@ -14,30 +14,6 @@
SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
SND_SOC_DAILINK_DEF(dmic_wov_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC WoV Pin")));
-SND_SOC_DAILINK_DEF(dmic_codec, DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
-/* Name overridden on probe */
-SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("")));
-
-static struct snd_soc_dai_link card_dai_links[] = {
- /* Back ends */
- {
- .name = "DMIC",
- .id = 0,
- .capture_only = 1,
- .nonatomic = 1,
- .no_pcm = 1,
- SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
- },
- {
- .name = "DMIC WoV",
- .id = 1,
- .capture_only = 1,
- .nonatomic = 1,
- .no_pcm = 1,
- .ignore_suspend = 1,
- SND_SOC_DAILINK_REG(dmic_wov_pin, dmic_codec, platform),
- },
-};
static const struct snd_soc_dapm_widget card_widgets[] = {
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
@@ -47,12 +23,56 @@ static const struct snd_soc_dapm_route card_routes[] = {
{"DMic", NULL, "SoC DMIC"},
};
+static int avs_create_dai_links(struct device *dev, const char *codec_name,
+ struct snd_soc_dai_link **links, int *num_links)
+{
+ struct snd_soc_dai_link_component *platform;
+ struct snd_soc_dai_link *dl;
+ const int num_dl = 2;
+
+ dl = devm_kcalloc(dev, num_dl, sizeof(*dl), GFP_KERNEL);
+ platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL);
+ if (!dl || !platform)
+ return -ENOMEM;
+
+ dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL);
+ if (!dl->codecs)
+ return -ENOMEM;
+
+ dl->codecs->name = devm_kstrdup(dev, codec_name, GFP_KERNEL);
+ dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "dmic-hifi");
+ if (!dl->codecs->name || !dl->codecs->dai_name)
+ return -ENOMEM;
+
+ platform->name = dev_name(dev);
+ dl[0].num_cpus = 1;
+ dl[0].num_codecs = 1;
+ dl[0].platforms = platform;
+ dl[0].num_platforms = 1;
+ dl[0].nonatomic = 1;
+ dl[0].no_pcm = 1;
+ dl[0].capture_only = 1;
+ memcpy(&dl[1], &dl[0], sizeof(*dl));
+
+ dl[0].name = "DMIC";
+ dl[0].cpus = dmic_pin;
+ dl[0].id = 0;
+ dl[1].name = "DMIC WoV";
+ dl[1].cpus = dmic_wov_pin;
+ dl[1].id = 1;
+ dl[1].ignore_suspend = 1;
+
+ *links = dl;
+ *num_links = num_dl;
+ return 0;
+}
+
static int avs_dmic_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct snd_soc_acpi_mach *mach;
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
- struct device *dev = &pdev->dev;
int ret;
mach = dev_get_platdata(dev);
@@ -62,6 +82,10 @@ static int avs_dmic_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
+ ret = avs_create_dai_links(dev, pdata->codec_name, &card->dai_link, &card->num_links);
+ if (ret)
+ return ret;
+
if (pdata->obsolete_card_names) {
card->name = "avs_dmic";
} else {
@@ -70,18 +94,12 @@ static int avs_dmic_probe(struct platform_device *pdev)
}
card->dev = dev;
card->owner = THIS_MODULE;
- card->dai_link = card_dai_links;
- card->num_links = ARRAY_SIZE(card_dai_links);
card->dapm_widgets = card_widgets;
card->num_dapm_widgets = ARRAY_SIZE(card_widgets);
card->dapm_routes = card_routes;
card->num_dapm_routes = ARRAY_SIZE(card_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c
index 1955f2d383c5..eb2b40894e3f 100644
--- a/sound/soc/intel/avs/boards/es8336.c
+++ b/sound/soc/intel/avs/boards/es8336.c
@@ -132,7 +132,7 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime)
snd_jack_set_key(data->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
snd_soc_component_set_jack(component, &data->jack, NULL);
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
return 0;
}
@@ -195,8 +195,9 @@ static int avs_es8336_be_fixup(struct snd_soc_pcm_runtime *runtime,
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -206,8 +207,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -222,6 +221,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -263,18 +263,16 @@ static int avs_es8336_probe(struct platform_device *pdev)
struct avs_card_drvdata *data;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -306,10 +304,6 @@ static int avs_es8336_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, data);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c
index 19b2255a8ac3..aec769e2396c 100644
--- a/sound/soc/intel/avs/boards/hdaudio.c
+++ b/sound/soc/intel/avs/boards/hdaudio.c
@@ -16,7 +16,7 @@
#include "../utils.h"
static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count,
- const char *platform_name, struct snd_soc_dai_link **links)
+ struct snd_soc_dai_link **links)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -29,7 +29,7 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
+ platform->name = dev_name(dev);
pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
@@ -142,7 +142,7 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
list_for_each_entry(pcm, &codec->pcm_list_head, list)
pcm_count++;
- ret = avs_create_dai_links(card->dev, codec, pcm_count, mach->mach_params.platform, &links);
+ ret = avs_create_dai_links(card->dev, codec, pcm_count, &links);
if (ret < 0) {
dev_err(card->dev, "create links failed: %d\n", ret);
return ret;
@@ -197,7 +197,7 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
if (!binder->codecs->name)
return -ENOMEM;
- binder->platforms->name = mach->mach_params.platform;
+ binder->platforms->name = dev_name(dev);
binder->num_platforms = 1;
binder->codecs->dai_name = "codec-probing-DAI";
binder->num_codecs = 1;
@@ -207,7 +207,10 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
return -ENOMEM;
if (pdata->obsolete_card_names) {
- card->name = binder->codecs->name;
+ card->name = devm_kasprintf(dev, GFP_KERNEL, "hdaudioB%dD%d", codec->bus->core.idx,
+ codec->core.addr);
+ if (!card->name)
+ return -ENOMEM;
} else {
card->driver_name = "avs_hdaudio";
if (hda_codec_is_display(codec))
diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c
index f7b6d7715738..9a6b89ffdf14 100644
--- a/sound/soc/intel/avs/boards/i2s_test.c
+++ b/sound/soc/intel/avs/boards/i2s_test.c
@@ -14,8 +14,8 @@
#include <sound/soc-dapm.h>
#include "../utils.h"
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -25,8 +25,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -39,6 +37,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -59,11 +58,9 @@ static int avs_i2s_test_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
if (!avs_mach_singular_ssp(mach)) {
@@ -94,7 +91,7 @@ static int avs_i2s_test_probe(struct platform_device *pdev)
if (!card->name)
return -ENOMEM;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d\n", ret);
return ret;
@@ -106,10 +103,6 @@ static int avs_i2s_test_probe(struct platform_device *pdev)
card->num_links = 1;
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c
index 72053f83e98b..e9a87804f918 100644
--- a/sound/soc/intel/avs/boards/max98357a.c
+++ b/sound/soc/intel/avs/boards/max98357a.c
@@ -46,8 +46,8 @@ avs_max98357a_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_pa
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -57,8 +57,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -73,6 +71,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -96,18 +95,16 @@ static int avs_max98357a_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -135,10 +132,6 @@ static int avs_max98357a_probe(struct platform_device *pdev)
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c
index cdba1c3ee20b..8b45b643ca29 100644
--- a/sound/soc/intel/avs/boards/max98373.c
+++ b/sound/soc/intel/avs/boards/max98373.c
@@ -95,8 +95,8 @@ static const struct snd_soc_ops avs_max98373_ops = {
.hw_params = avs_max98373_hw_params,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -106,8 +106,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -125,6 +123,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
!dl->codecs[1].name || !dl->codecs[1].dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 2;
dl->platforms = platform;
@@ -149,18 +148,16 @@ static int avs_max98373_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -190,10 +187,6 @@ static int avs_max98373_probe(struct platform_device *pdev)
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c
index a68e227044c5..db073125fa4d 100644
--- a/sound/soc/intel/avs/boards/max98927.c
+++ b/sound/soc/intel/avs/boards/max98927.c
@@ -92,8 +92,8 @@ static const struct snd_soc_ops avs_max98927_ops = {
.hw_params = avs_max98927_hw_params,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -103,8 +103,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -122,6 +120,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
!dl->codecs[1].name || !dl->codecs[1].dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 2;
dl->platforms = platform;
@@ -146,18 +145,16 @@ static int avs_max98927_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -187,10 +184,6 @@ static int avs_max98927_probe(struct platform_device *pdev)
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c
index 3fb1a5d07ae1..9ca400a6412e 100644
--- a/sound/soc/intel/avs/boards/nau8825.c
+++ b/sound/soc/intel/avs/boards/nau8825.c
@@ -172,8 +172,8 @@ static const struct snd_soc_ops avs_nau8825_ops = {
.trigger = avs_nau8825_trigger,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -183,8 +183,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -199,6 +197,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -250,18 +249,16 @@ static int avs_nau8825_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -293,10 +290,6 @@ static int avs_nau8825_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/probe.c b/sound/soc/intel/avs/boards/probe.c
index 06c1f19f27aa..73884f8a535c 100644
--- a/sound/soc/intel/avs/boards/probe.c
+++ b/sound/soc/intel/avs/boards/probe.c
@@ -9,45 +9,54 @@
#include <linux/device.h>
#include <linux/module.h>
#include <sound/soc.h>
-#include <sound/soc-acpi.h>
-SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));
-SND_SOC_DAILINK_DEF(probe_cp, DAILINK_COMP_ARRAY(COMP_CPU("Probe Extraction CPU DAI")));
-SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("probe-platform")));
+static int avs_create_dai_links(struct device *dev, struct snd_soc_dai_link **links, int *num_links)
+{
+ struct snd_soc_dai_link *dl;
-static struct snd_soc_dai_link probe_mb_dai_links[] = {
- {
- .name = "Compress Probe Capture",
- .nonatomic = 1,
- SND_SOC_DAILINK_REG(probe_cp, dummy, platform),
- },
-};
+ dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL);
+ if (!dl)
+ return -ENOMEM;
+
+ dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
+ dl->platforms = devm_kzalloc(dev, sizeof(*dl->platforms), GFP_KERNEL);
+ if (!dl->cpus || !dl->platforms)
+ return -ENOMEM;
+
+ dl->name = "Compress Probe Capture";
+ dl->cpus->dai_name = "Probe Extraction CPU DAI";
+ dl->num_cpus = 1;
+ dl->codecs = &snd_soc_dummy_dlc;
+ dl->num_codecs = 1;
+ dl->platforms->name = dev_name(dev);
+ dl->num_platforms = 1;
+ dl->nonatomic = 1;
+
+ *links = dl;
+ *num_links = 1;
+ return 0;
+}
static int avs_probe_mb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct snd_soc_acpi_mach *mach;
struct snd_soc_card *card;
int ret;
- mach = dev_get_platdata(dev);
-
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
+ ret = avs_create_dai_links(dev, &card->dai_link, &card->num_links);
+ if (ret)
+ return ret;
+
card->driver_name = "avs_probe_mb";
card->long_name = card->name = "AVS PROBE";
card->dev = dev;
card->owner = THIS_MODULE;
- card->dai_link = probe_mb_dai_links;
- card->num_links = ARRAY_SIZE(probe_mb_dai_links);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c
index ec5382925157..4055ecc60838 100644
--- a/sound/soc/intel/avs/boards/rt274.c
+++ b/sound/soc/intel/avs/boards/rt274.c
@@ -117,7 +117,7 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime)
return ret;
}
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
return 0;
}
@@ -147,8 +147,8 @@ static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pc
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -158,8 +158,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -174,6 +172,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -214,18 +213,16 @@ static int avs_rt274_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -257,10 +254,6 @@ static int avs_rt274_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c
index 2566e971ce1c..4c9ac545555a 100644
--- a/sound/soc/intel/avs/boards/rt286.c
+++ b/sound/soc/intel/avs/boards/rt286.c
@@ -115,8 +115,8 @@ static const struct snd_soc_ops avs_rt286_ops = {
.hw_params = avs_rt286_hw_params,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -126,8 +126,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -142,6 +140,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -183,18 +182,16 @@ static int avs_rt286_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
@@ -227,10 +224,6 @@ static int avs_rt286_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c
index 7be34c8ad167..2d7a7748d577 100644
--- a/sound/soc/intel/avs/boards/rt298.c
+++ b/sound/soc/intel/avs/boards/rt298.c
@@ -132,8 +132,8 @@ static const struct snd_soc_ops avs_rt298_ops = {
.hw_params = avs_rt298_hw_params,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -143,8 +143,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -159,6 +157,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -203,18 +202,16 @@ static int avs_rt298_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -246,10 +243,6 @@ static int avs_rt298_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c
index 45f091f2ce22..00b99e36d23c 100644
--- a/sound/soc/intel/avs/boards/rt5514.c
+++ b/sound/soc/intel/avs/boards/rt5514.c
@@ -84,8 +84,8 @@ static const struct snd_soc_ops avs_rt5514_ops = {
.hw_params = avs_rt5514_hw_params,
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -95,8 +95,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -111,6 +109,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -136,18 +135,16 @@ static int avs_rt5514_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -173,10 +170,6 @@ static int avs_rt5514_probe(struct platform_device *pdev)
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt5640.c b/sound/soc/intel/avs/boards/rt5640.c
index 706b84ffe1ef..97d1fa944188 100644
--- a/sound/soc/intel/avs/boards/rt5640.c
+++ b/sound/soc/intel/avs/boards/rt5640.c
@@ -67,7 +67,7 @@ static int avs_rt5640_codec_init(struct snd_soc_pcm_runtime *runtime)
return ret;
snd_soc_component_set_jack(codec_dai->component, jack, NULL);
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
return 0;
}
diff --git a/sound/soc/intel/avs/boards/rt5663.c b/sound/soc/intel/avs/boards/rt5663.c
index 51648801710a..68fea325376a 100644
--- a/sound/soc/intel/avs/boards/rt5663.c
+++ b/sound/soc/intel/avs/boards/rt5663.c
@@ -134,8 +134,8 @@ static const struct snd_soc_ops avs_rt5663_ops = {
};
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -145,8 +145,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -161,6 +159,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -202,18 +201,16 @@ static int avs_rt5663_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct rt5663_private *priv;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -245,10 +242,6 @@ static int avs_rt5663_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, priv);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c
index 9677b9ebeff1..81863728da1d 100644
--- a/sound/soc/intel/avs/boards/rt5682.c
+++ b/sound/soc/intel/avs/boards/rt5682.c
@@ -204,8 +204,8 @@ avs_rt5682_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_param
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -215,8 +215,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -231,6 +229,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 1;
dl->platforms = platform;
@@ -272,7 +271,6 @@ static int avs_rt5682_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
if (pdev->id_entry && pdev->id_entry->driver_data)
@@ -282,14 +280,13 @@ static int avs_rt5682_probe(struct platform_device *pdev)
dev_dbg(dev, "avs_rt5682_quirk = %lx\n", avs_rt5682_quirk);
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -321,10 +318,6 @@ static int avs_rt5682_probe(struct platform_device *pdev)
card->fully_routed = true;
snd_soc_card_set_drvdata(card, jack);
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c
index 3786eef8c494..ae0e6e27a8b8 100644
--- a/sound/soc/intel/avs/boards/ssm4567.c
+++ b/sound/soc/intel/avs/boards/ssm4567.c
@@ -81,8 +81,8 @@ avs_ssm4567_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_para
return 0;
}
-static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
- int tdm_slot, struct snd_soc_dai_link **dai_link)
+static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot,
+ struct snd_soc_dai_link **dai_link)
{
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dl;
@@ -92,8 +92,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
if (!dl || !platform)
return -ENOMEM;
- platform->name = platform_name;
-
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
@@ -111,6 +109,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
!dl->codecs[1].name || !dl->codecs[1].dai_name)
return -ENOMEM;
+ platform->name = dev_name(dev);
dl->num_cpus = 1;
dl->num_codecs = 2;
dl->platforms = platform;
@@ -135,18 +134,16 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
- const char *pname;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
- pname = mach->mach_params.platform;
pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
return ret;
- ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link);
+ ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link);
if (ret) {
dev_err(dev, "Failed to create dai link: %d", ret);
return ret;
@@ -176,10 +173,6 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- ret = snd_soc_fixup_dai_links_platform_name(card, pname);
- if (ret)
- return ret;
-
return devm_snd_soc_register_deferrable_card(dev, card);
}
diff --git a/sound/soc/intel/avs/cnl.c b/sound/soc/intel/avs/cnl.c
index 03f8fb0dc187..5b5359e9128b 100644
--- a/sound/soc/intel/avs/cnl.c
+++ b/sound/soc/intel/avs/cnl.c
@@ -8,6 +8,7 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
#include "registers.h"
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index 5ebadba07ecc..6e0e65584c7f 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -27,6 +27,7 @@
#include "../../codecs/hda.h"
#include "avs.h"
#include "cldma.h"
+#include "debug.h"
#include "messages.h"
#include "pcm.h"
diff --git a/sound/soc/intel/avs/debug.h b/sound/soc/intel/avs/debug.h
new file mode 100644
index 000000000000..94fe8729a5c1
--- /dev/null
+++ b/sound/soc/intel/avs/debug.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2024-2025 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+ * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#ifndef __SOUND_SOC_INTEL_AVS_DEBUG_H
+#define __SOUND_SOC_INTEL_AVS_DEBUG_H
+
+#include "messages.h"
+#include "registers.h"
+
+struct avs_dev;
+
+#define avs_log_buffer_size(adev) \
+ ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores)
+
+#define avs_log_buffer_addr(adev, core) \
+({ \
+ s32 __offset = avs_dsp_op(adev, log_buffer_offset, core); \
+ (__offset < 0) ? NULL : \
+ (avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \
+})
+
+static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&adev->trace_lock, flags);
+ ret = avs_dsp_op(adev, log_buffer_status, msg);
+ spin_unlock_irqrestore(&adev->trace_lock, flags);
+
+ return ret;
+}
+
+struct avs_apl_log_buffer_layout {
+ u32 read_ptr;
+ u32 write_ptr;
+ u8 buffer[];
+} __packed;
+static_assert(sizeof(struct avs_apl_log_buffer_layout) == 8);
+
+#define avs_apl_log_payload_size(adev) \
+ (avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout))
+
+#define avs_apl_log_payload_addr(addr) \
+ (addr + sizeof(struct avs_apl_log_buffer_layout))
+
+#ifdef CONFIG_DEBUG_FS
+int avs_register_probe_component(struct avs_dev *adev, const char *name);
+
+#define AVS_SET_ENABLE_LOGS_OP(name) \
+ .enable_logs = avs_##name##_enable_logs
+
+bool avs_logging_fw(struct avs_dev *adev);
+void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len);
+void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len);
+
+void avs_debugfs_init(struct avs_dev *adev);
+void avs_debugfs_exit(struct avs_dev *adev);
+
+#else
+static inline int avs_register_probe_component(struct avs_dev *adev, const char *name)
+{
+ return -EOPNOTSUPP;
+}
+
+#define AVS_SET_ENABLE_LOGS_OP(name)
+
+static inline bool avs_logging_fw(struct avs_dev *adev)
+{
+ return false;
+}
+
+static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len)
+{
+}
+
+static inline void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src,
+ unsigned int len)
+{
+}
+
+static inline void avs_debugfs_init(struct avs_dev *adev) { }
+static inline void avs_debugfs_exit(struct avs_dev *adev) { }
+#endif
+
+#endif
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
index f508f215ecd2..3534de46f9e4 100644
--- a/sound/soc/intel/avs/debugfs.c
+++ b/sound/soc/intel/avs/debugfs.c
@@ -13,6 +13,7 @@
#include <linux/string_helpers.h>
#include <sound/soc.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
static unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len)
diff --git a/sound/soc/intel/avs/icl.c b/sound/soc/intel/avs/icl.c
index f8d327ea2656..d655e727bebd 100644
--- a/sound/soc/intel/avs/icl.c
+++ b/sound/soc/intel/avs/icl.c
@@ -10,6 +10,7 @@
#include <sound/hdaudio.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
#define ICL_VS_LTRP_GB_ICCMAX 95
diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
index 6bfb9d1a1ca8..c0feb9edd7f6 100644
--- a/sound/soc/intel/avs/ipc.c
+++ b/sound/soc/intel/avs/ipc.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
#include "registers.h"
#include "trace.h"
diff --git a/sound/soc/intel/avs/lnl.c b/sound/soc/intel/avs/lnl.c
index 03208596dfb1..4fbc62bfd6c5 100644
--- a/sound/soc/intel/avs/lnl.c
+++ b/sound/soc/intel/avs/lnl.c
@@ -8,6 +8,7 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "registers.h"
int avs_lnl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall)
diff --git a/sound/soc/intel/avs/mtl.c b/sound/soc/intel/avs/mtl.c
index e7b7915b2a82..d8bdd03275d7 100644
--- a/sound/soc/intel/avs/mtl.c
+++ b/sound/soc/intel/avs/mtl.c
@@ -8,6 +8,7 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "registers.h"
#include "trace.h"
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index e8e6b1c7fc90..7aa20fcf1a33 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -115,6 +115,55 @@ avs_path_find_variant(struct avs_dev *adev,
return NULL;
}
+static struct avs_tplg_path *avs_condpath_find_variant(struct avs_dev *adev,
+ struct avs_tplg_path_template *template,
+ struct avs_path *source,
+ struct avs_path *sink)
+{
+ struct avs_tplg_path *variant;
+
+ list_for_each_entry(variant, &template->path_list, node) {
+ if (variant->source_path_id == source->template->id &&
+ variant->sink_path_id == sink->template->id)
+ return variant;
+ }
+
+ return NULL;
+}
+
+static bool avs_tplg_path_template_id_equal(struct avs_tplg_path_template_id *id,
+ struct avs_tplg_path_template_id *id2)
+{
+ return id->id == id2->id && !strcmp(id->tplg_name, id2->tplg_name);
+}
+
+static struct avs_path *avs_condpath_find_match(struct avs_dev *adev,
+ struct avs_tplg_path_template *template,
+ struct avs_path *path, int dir)
+{
+ struct avs_tplg_path_template_id *id, *id2;
+
+ if (dir) {
+ id = &template->source;
+ id2 = &template->sink;
+ } else {
+ id = &template->sink;
+ id2 = &template->source;
+ }
+
+ /* Check whether this path is either source or sink of condpath template. */
+ if (id->id != path->template->owner->id ||
+ strcmp(id->tplg_name, path->template->owner->owner->name))
+ return NULL;
+
+ /* Unidirectional condpaths are allowed. */
+ if (avs_tplg_path_template_id_equal(id, id2))
+ return path;
+
+ /* Now find the counterpart. */
+ return avs_path_find_path(adev, id2->tplg_name, id2->id);
+}
+
static struct acpi_nhlt_config *
avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t);
@@ -1051,6 +1100,10 @@ static int avs_path_init(struct avs_dev *adev, struct avs_path *path,
path->dma_id = dma_id;
INIT_LIST_HEAD(&path->ppl_list);
INIT_LIST_HEAD(&path->node);
+ INIT_LIST_HEAD(&path->source_list);
+ INIT_LIST_HEAD(&path->sink_list);
+ INIT_LIST_HEAD(&path->source_node);
+ INIT_LIST_HEAD(&path->sink_node);
/* create all the pipelines */
list_for_each_entry(tppl, &template->ppl_list, node) {
@@ -1134,12 +1187,129 @@ err:
return ERR_PTR(ret);
}
+static void avs_condpath_free(struct avs_dev *adev, struct avs_path *path)
+{
+ int ret;
+
+ list_del(&path->source_node);
+ list_del(&path->sink_node);
+
+ ret = avs_path_reset(path);
+ if (ret < 0)
+ dev_err(adev->dev, "reset condpath failed: %d\n", ret);
+
+ ret = avs_path_unbind(path);
+ if (ret < 0)
+ dev_err(adev->dev, "unbind condpath failed: %d\n", ret);
+
+ avs_path_free_unlocked(path);
+}
+
+static struct avs_path *avs_condpath_create(struct avs_dev *adev,
+ struct avs_tplg_path *template,
+ struct avs_path *source,
+ struct avs_path *sink)
+{
+ struct avs_path *path;
+ int ret;
+
+ path = avs_path_create_unlocked(adev, 0, template);
+ if (IS_ERR(path))
+ return path;
+
+ ret = avs_path_bind(path);
+ if (ret)
+ goto err_bind;
+
+ ret = avs_path_reset(path);
+ if (ret)
+ goto err_reset;
+
+ path->source = source;
+ path->sink = sink;
+ list_add_tail(&path->source_node, &source->source_list);
+ list_add_tail(&path->sink_node, &sink->sink_list);
+
+ return path;
+
+err_reset:
+ avs_path_unbind(path);
+err_bind:
+ avs_path_free_unlocked(path);
+ return ERR_PTR(ret);
+}
+
+static int avs_condpaths_walk(struct avs_dev *adev, struct avs_path *path, int dir)
+{
+ struct avs_soc_component *acomp;
+ struct avs_path *source, *sink;
+ struct avs_path **other;
+
+ if (dir) {
+ source = path;
+ other = &sink;
+ } else {
+ sink = path;
+ other = &source;
+ }
+
+ list_for_each_entry(acomp, &adev->comp_list, node) {
+ for (int i = 0; i < acomp->tplg->num_condpath_tmpls; i++) {
+ struct avs_tplg_path_template *template;
+ struct avs_tplg_path *variant;
+ struct avs_path *cpath;
+
+ template = &acomp->tplg->condpath_tmpls[i];
+
+ /* Do not create unidirectional condpaths twice. */
+ if (avs_tplg_path_template_id_equal(&template->source,
+ &template->sink) && dir)
+ continue;
+
+ *other = avs_condpath_find_match(adev, template, path, dir);
+ if (!*other)
+ continue;
+
+ variant = avs_condpath_find_variant(adev, template, source, sink);
+ if (!variant)
+ continue;
+
+ cpath = avs_condpath_create(adev, variant, source, sink);
+ if (IS_ERR(cpath))
+ return PTR_ERR(cpath);
+ }
+ }
+
+ return 0;
+}
+
+/* Caller responsible for holding adev->path_mutex. */
+static int avs_condpaths_walk_all(struct avs_dev *adev, struct avs_path *path)
+{
+ int ret;
+
+ ret = avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_CAPTURE);
+ if (ret)
+ return ret;
+
+ return avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_PLAYBACK);
+}
+
void avs_path_free(struct avs_path *path)
{
+ struct avs_path *cpath, *csave;
struct avs_dev *adev = path->owner;
mutex_lock(&adev->path_mutex);
+
+ /* Free all condpaths this path spawned. */
+ list_for_each_entry_safe(cpath, csave, &path->source_list, source_node)
+ avs_condpath_free(path->owner, cpath);
+ list_for_each_entry_safe(cpath, csave, &path->sink_list, sink_node)
+ avs_condpath_free(path->owner, cpath);
+
avs_path_free_unlocked(path);
+
mutex_unlock(&adev->path_mutex);
}
@@ -1150,6 +1320,7 @@ struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
{
struct avs_tplg_path *variant;
struct avs_path *path;
+ int ret;
variant = avs_path_find_variant(adev, template, fe_params, be_params);
if (!variant) {
@@ -1163,7 +1334,16 @@ struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
mutex_lock(&adev->comp_list_mutex);
path = avs_path_create_unlocked(adev, dma_id, variant);
+ if (IS_ERR(path))
+ goto exit;
+
+ ret = avs_condpaths_walk_all(adev, path);
+ if (ret) {
+ avs_path_free_unlocked(path);
+ path = ERR_PTR(ret);
+ }
+exit:
mutex_unlock(&adev->comp_list_mutex);
mutex_unlock(&adev->path_mutex);
@@ -1286,6 +1466,42 @@ int avs_path_reset(struct avs_path *path)
return 0;
}
+static int avs_condpath_pause(struct avs_dev *adev, struct avs_path *cpath)
+{
+ struct avs_path_pipeline *ppl;
+ int ret;
+
+ if (cpath->state == AVS_PPL_STATE_PAUSED)
+ return 0;
+
+ list_for_each_entry_reverse(ppl, &cpath->ppl_list, node) {
+ ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_PAUSED);
+ if (ret) {
+ dev_err(adev->dev, "pause cpath failed: %d\n", ret);
+ cpath->state = AVS_PPL_STATE_INVALID;
+ return AVS_IPC_RET(ret);
+ }
+ }
+
+ cpath->state = AVS_PPL_STATE_PAUSED;
+ return 0;
+}
+
+static void avs_condpaths_pause(struct avs_dev *adev, struct avs_path *path)
+{
+ struct avs_path *cpath;
+
+ mutex_lock(&adev->path_mutex);
+
+ /* If either source or sink stops, so do the attached conditional paths. */
+ list_for_each_entry(cpath, &path->source_list, source_node)
+ avs_condpath_pause(adev, cpath);
+ list_for_each_entry(cpath, &path->sink_list, sink_node)
+ avs_condpath_pause(adev, cpath);
+
+ mutex_unlock(&adev->path_mutex);
+}
+
int avs_path_pause(struct avs_path *path)
{
struct avs_path_pipeline *ppl;
@@ -1295,6 +1511,8 @@ int avs_path_pause(struct avs_path *path)
if (path->state == AVS_PPL_STATE_PAUSED)
return 0;
+ avs_condpaths_pause(adev, path);
+
list_for_each_entry_reverse(ppl, &path->ppl_list, node) {
ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
AVS_PPL_STATE_PAUSED);
@@ -1309,6 +1527,50 @@ int avs_path_pause(struct avs_path *path)
return 0;
}
+static int avs_condpath_run(struct avs_dev *adev, struct avs_path *cpath, int trigger)
+{
+ struct avs_path_pipeline *ppl;
+ int ret;
+
+ if (cpath->state == AVS_PPL_STATE_RUNNING)
+ return 0;
+
+ list_for_each_entry(ppl, &cpath->ppl_list, node) {
+ if (ppl->template->cfg->trigger != trigger)
+ continue;
+
+ ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_RUNNING);
+ if (ret) {
+ dev_err(adev->dev, "run cpath failed: %d\n", ret);
+ cpath->state = AVS_PPL_STATE_INVALID;
+ return AVS_IPC_RET(ret);
+ }
+ }
+
+ cpath->state = AVS_PPL_STATE_RUNNING;
+ return 0;
+}
+
+static void avs_condpaths_run(struct avs_dev *adev, struct avs_path *path, int trigger)
+{
+ struct avs_path *cpath;
+
+ mutex_lock(&adev->path_mutex);
+
+ /* Run conditional paths only if source and sink are both running. */
+ list_for_each_entry(cpath, &path->source_list, source_node)
+ if (cpath->source->state == AVS_PPL_STATE_RUNNING &&
+ cpath->sink->state == AVS_PPL_STATE_RUNNING)
+ avs_condpath_run(adev, cpath, trigger);
+
+ list_for_each_entry(cpath, &path->sink_list, sink_node)
+ if (cpath->source->state == AVS_PPL_STATE_RUNNING &&
+ cpath->sink->state == AVS_PPL_STATE_RUNNING)
+ avs_condpath_run(adev, cpath, trigger);
+
+ mutex_unlock(&adev->path_mutex);
+}
+
int avs_path_run(struct avs_path *path, int trigger)
{
struct avs_path_pipeline *ppl;
@@ -1332,5 +1594,10 @@ int avs_path_run(struct avs_path *path, int trigger)
}
path->state = AVS_PPL_STATE_RUNNING;
+
+ /* Granular pipeline triggering not intended for conditional paths. */
+ if (trigger == AVS_TPLG_TRIGGER_AUTO)
+ avs_condpaths_run(adev, path, trigger);
+
return 0;
}
diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h
index c65ed84aa853..ceb89971a902 100644
--- a/sound/soc/intel/avs/path.h
+++ b/sound/soc/intel/avs/path.h
@@ -13,11 +13,24 @@
#include "avs.h"
#include "topology.h"
+#define AVS_COND_TYPE_NONE 0
+#define AVS_COND_TYPE_AECREF 1
+
struct avs_path {
u32 dma_id;
struct list_head ppl_list;
u32 state;
+ /* condpath navigation for standard paths */
+ struct list_head source_list;
+ struct list_head sink_list;
+
+ /* conditional path fields */
+ struct avs_path *source;
+ struct avs_path *sink;
+ struct list_head source_node;
+ struct list_head sink_node;
+
struct avs_tplg_path *template;
struct avs_dev *owner;
/* device path management */
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 67ce6675eea7..d31058e2de5b 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -1379,9 +1379,9 @@ static struct snd_soc_component_driver avs_component_driver = {
.topology_name_prefix = "intel/avs",
};
-int avs_soc_component_register(struct device *dev, const char *name,
- struct snd_soc_component_driver *drv,
- struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
+int avs_register_component(struct device *dev, const char *name,
+ struct snd_soc_component_driver *drv,
+ struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
{
struct avs_soc_component *acomp;
int ret;
@@ -1390,16 +1390,18 @@ int avs_soc_component_register(struct device *dev, const char *name,
if (!acomp)
return -ENOMEM;
- ret = snd_soc_component_initialize(&acomp->base, drv, dev);
- if (ret < 0)
- return ret;
+ acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL);
+ if (!acomp->base.name)
+ return -ENOMEM;
- /* force name change after ASoC is done with its init */
- acomp->base.name = name;
INIT_LIST_HEAD(&acomp->node);
drv->use_dai_pcm_id = !obsolete_card_names;
+ ret = snd_soc_component_initialize(&acomp->base, drv, dev);
+ if (ret < 0)
+ return ret;
+
return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
}
@@ -1426,7 +1428,7 @@ static struct snd_soc_dai_driver dmic_cpu_dais[] = {
},
};
-int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
+int avs_register_dmic_component(struct avs_dev *adev, const char *name)
{
const struct snd_soc_dai_ops *ops;
@@ -1437,8 +1439,8 @@ int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
dmic_cpu_dais[0].ops = ops;
dmic_cpu_dais[1].ops = ops;
- return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
- ARRAY_SIZE(dmic_cpu_dais));
+ return avs_register_component(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
+ ARRAY_SIZE(dmic_cpu_dais));
}
static const struct snd_soc_dai_driver i2s_dai_template = {
@@ -1470,8 +1472,8 @@ static const struct snd_soc_dai_driver i2s_dai_template = {
},
};
-int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
- unsigned long *tdms)
+int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
+ unsigned long *tdms)
{
struct snd_soc_dai_driver *cpus, *dai;
const struct snd_soc_dai_ops *ops;
@@ -1537,7 +1539,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
}
plat_register:
- return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
+ return avs_register_component(adev->dev, name, &avs_component_driver, cpus, cpu_count);
}
/* HD-Audio CPU DAI template */
@@ -1762,8 +1764,7 @@ static struct snd_soc_component_driver avs_hda_component_driver = {
.topology_name_prefix = "intel/avs",
};
-int avs_hda_platform_register(struct avs_dev *adev, const char *name)
+int avs_register_hda_component(struct avs_dev *adev, const char *name)
{
- return avs_soc_component_register(adev->dev, name,
- &avs_hda_component_driver, NULL, 0);
+ return avs_register_component(adev->dev, name, &avs_hda_component_driver, NULL, 0);
}
diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c
index a42736b9aa55..693ecfe68fd0 100644
--- a/sound/soc/intel/avs/probes.c
+++ b/sound/soc/intel/avs/probes.c
@@ -11,6 +11,7 @@
#include <sound/hdaudio.h>
#include <sound/soc.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id,
@@ -213,7 +214,7 @@ static int avs_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
}
static int avs_probe_compr_pointer(struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
+ struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai)
{
struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);
struct snd_soc_pcm_stream *pstream;
@@ -284,14 +285,28 @@ static struct snd_soc_dai_driver probe_cpu_dais[] = {
},
};
-static struct snd_soc_component_driver avs_probe_component_driver = {
+static const struct snd_soc_component_driver avs_probe_component_driver = {
.name = "avs-probe-compr",
.compress_ops = &avs_probe_compress_ops,
.module_get_upon_open = 1, /* increment refcount when a stream is opened */
};
-int avs_probe_platform_register(struct avs_dev *adev, const char *name)
+int avs_register_probe_component(struct avs_dev *adev, const char *name)
{
- return avs_soc_component_register(adev->dev, name, &avs_probe_component_driver,
- probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais));
+ struct snd_soc_component *component;
+ int ret;
+
+ component = devm_kzalloc(adev->dev, sizeof(*component), GFP_KERNEL);
+ if (!component)
+ return -ENOMEM;
+
+ component->name = devm_kstrdup(adev->dev, name, GFP_KERNEL);
+ if (!component->name)
+ return -ENOMEM;
+
+ ret = snd_soc_component_initialize(component, &avs_probe_component_driver, adev->dev);
+ if (ret)
+ return ret;
+
+ return snd_soc_add_component(component, probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais));
}
diff --git a/sound/soc/intel/avs/ptl.c b/sound/soc/intel/avs/ptl.c
index 2be4b545c91d..07da9b0aa2b8 100644
--- a/sound/soc/intel/avs/ptl.c
+++ b/sound/soc/intel/avs/ptl.c
@@ -8,6 +8,7 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "debug.h"
#include "registers.h"
#include "trace.h"
diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c
index d66ef000de9e..8fb86f364ff3 100644
--- a/sound/soc/intel/avs/skl.c
+++ b/sound/soc/intel/avs/skl.c
@@ -11,6 +11,7 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
#include "cldma.h"
+#include "debug.h"
#include "messages.h"
#include "registers.h"
diff --git a/sound/soc/intel/avs/tgl.c b/sound/soc/intel/avs/tgl.c
index 9dbb3ad0954a..afb066516101 100644
--- a/sound/soc/intel/avs/tgl.c
+++ b/sound/soc/intel/avs/tgl.c
@@ -8,6 +8,7 @@
#include <linux/pci.h>
#include "avs.h"
+#include "debug.h"
#include "messages.h"
#define CPUID_TSC_LEAF 0x15
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index f2e4ad8b8e14..dfe8cf505381 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -1387,6 +1387,27 @@ static const struct avs_tplg_token_parser path_parsers[] = {
},
};
+static const struct avs_tplg_token_parser condpath_parsers[] = {
+ {
+ .token = AVS_TKN_CONDPATH_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path, id),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_SOURCE_PATH_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path, source_path_id),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_SINK_PATH_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path, sink_path_id),
+ .parse = avs_parse_word_token,
+ },
+};
+
static struct avs_tplg_path *
avs_tplg_path_create(struct snd_soc_component *comp, struct avs_tplg_path_template *owner,
struct snd_soc_tplg_vendor_array *tuples, u32 block_size,
@@ -1454,6 +1475,39 @@ static const struct avs_tplg_token_parser path_tmpl_parsers[] = {
},
};
+static const struct avs_tplg_token_parser condpath_tmpl_parsers[] = {
+ {
+ .token = AVS_TKN_CONDPATH_TMPL_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path_template, id),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_TMPL_SOURCE_TPLG_NAME_STRING,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
+ .offset = offsetof(struct avs_tplg_path_template, source.tplg_name),
+ .parse = avs_parse_string_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_TMPL_SOURCE_PATH_TMPL_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path_template, source.id),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_TMPL_SINK_TPLG_NAME_STRING,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
+ .offset = offsetof(struct avs_tplg_path_template, sink.tplg_name),
+ .parse = avs_parse_string_token,
+ },
+ {
+ .token = AVS_TKN_CONDPATH_TMPL_SINK_PATH_TMPL_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_path_template, sink.id),
+ .parse = avs_parse_word_token,
+ },
+};
+
static int parse_path_template(struct snd_soc_component *comp,
struct snd_soc_tplg_vendor_array *tuples, u32 block_size,
struct avs_tplg_path_template *template,
@@ -1524,6 +1578,56 @@ avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *o
return template;
}
+static int avs_tplg_parse_condpath_templates(struct snd_soc_component *comp,
+ struct snd_soc_tplg_vendor_array *tuples,
+ u32 block_size)
+{
+ struct avs_soc_component *acomp = to_avs_soc_component(comp);
+ struct avs_tplg *tplg = acomp->tplg;
+ int ret, i;
+
+ ret = parse_dictionary_header(comp, tuples, (void **)&tplg->condpath_tmpls,
+ &tplg->num_condpath_tmpls,
+ sizeof(*tplg->condpath_tmpls),
+ AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32);
+ if (ret)
+ return ret;
+
+ block_size -= le32_to_cpu(tuples->size);
+ /* With header parsed, move on to parsing entries. */
+ tuples = avs_tplg_vendor_array_next(tuples);
+
+ for (i = 0; i < tplg->num_condpath_tmpls; i++) {
+ struct avs_tplg_path_template *template;
+ u32 esize;
+
+ template = &tplg->condpath_tmpls[i];
+ template->owner = tplg; /* Used when building sysfs hierarchy. */
+ INIT_LIST_HEAD(&template->path_list);
+ INIT_LIST_HEAD(&template->node);
+
+ ret = avs_tplg_vendor_entry_size(tuples, block_size,
+ AVS_TKN_CONDPATH_TMPL_ID_U32, &esize);
+ if (ret)
+ return ret;
+
+ ret = parse_path_template(comp, tuples, esize, template,
+ condpath_tmpl_parsers,
+ ARRAY_SIZE(condpath_tmpl_parsers),
+ condpath_parsers,
+ ARRAY_SIZE(condpath_parsers));
+ if (ret < 0) {
+ dev_err(comp->dev, "parse condpath_tmpl: %d failed: %d\n", i, ret);
+ return ret;
+ }
+
+ block_size -= esize;
+ tuples = avs_tplg_vendor_array_at(tuples, esize);
+ }
+
+ return 0;
+}
+
static const struct avs_tplg_token_parser mod_init_config_parsers[] = {
{
.token = AVS_TKN_INIT_CONFIG_ID_U32,
@@ -1891,6 +1995,12 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
return ret;
}
+ /* Condpaths dictionary. */
+ ret = avs_tplg_parse_condpath_templates(comp, tuples,
+ has_init_config ? offset : remaining);
+ if (ret < 0)
+ return ret;
+
if (!has_init_config)
return 0;
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index f5601a4e3ec8..1e83fccf2ea2 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -33,6 +33,7 @@ struct avs_tplg {
u32 num_pplcfgs;
struct avs_tplg_binding *bindings;
u32 num_bindings;
+ struct avs_tplg_path_template *condpath_tmpls;
u32 num_condpath_tmpls;
struct avs_tplg_init_config *init_configs;
u32 num_init_configs;
@@ -155,6 +156,10 @@ struct avs_tplg_path_template {
struct snd_soc_dapm_widget *w;
+ /* Conditional path. */
+ struct avs_tplg_path_template_id source;
+ struct avs_tplg_path_template_id sink;
+
struct list_head path_list;
struct avs_tplg *owner;
@@ -176,6 +181,9 @@ struct avs_tplg_path {
/* Path format requirements. */
struct avs_audio_format *fe_fmt;
struct avs_audio_format *be_fmt;
+ /* Condpath path-variant requirements. */
+ u32 source_path_id;
+ u32 sink_path_id;
struct list_head ppl_list;
diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c
index 68a3d345dc25..27b63a853a48 100644
--- a/sound/soc/intel/boards/bytcht_cx2072x.c
+++ b/sound/soc/intel/boards/bytcht_cx2072x.c
@@ -77,7 +77,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd)
byt_cht_cx2072x_acpi_gpios))
dev_warn(rtd->dev, "Unable to add GPIO mapping table\n");
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
/* set the default PLL rate, the clock is handled by the codec driver */
ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL,
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 62594e7966ab..3b5f63112237 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -47,7 +47,8 @@ enum {
BYT_CHT_ES8316_INTMIC_IN2_MAP,
};
-#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & GENMASK(3, 0))
+#define BYT_CHT_ES8316_MAP_MASK GENMASK(3, 0)
+#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & BYT_CHT_ES8316_MAP_MASK)
#define BYT_CHT_ES8316_SSP0 BIT(16)
#define BYT_CHT_ES8316_MONO_SPEAKER BIT(17)
#define BYT_CHT_ES8316_JD_INVERTED BIT(18)
@@ -60,10 +61,23 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev)
{
- if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP)
+ int map;
+
+ map = BYT_CHT_ES8316_MAP(quirk);
+ switch (map) {
+ case BYT_CHT_ES8316_INTMIC_IN1_MAP:
dev_info(dev, "quirk IN1_MAP enabled");
- if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP)
+ break;
+ case BYT_CHT_ES8316_INTMIC_IN2_MAP:
dev_info(dev, "quirk IN2_MAP enabled");
+ break;
+ default:
+ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to INTMIC_IN1_MAP\n", map);
+ quirk &= ~BYT_CHT_ES8316_MAP_MASK;
+ quirk |= BYT_CHT_ES8316_INTMIC_IN1_MAP;
+ break;
+ }
+
if (quirk & BYT_CHT_ES8316_SSP0)
dev_info(dev, "quirk SSP0 enabled");
if (quirk & BYT_CHT_ES8316_MONO_SPEAKER)
@@ -165,7 +179,7 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
int num_routes;
int ret;
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
switch (BYT_CHT_ES8316_MAP(quirk)) {
case BYT_CHT_ES8316_INTMIC_IN1_MAP:
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 0f3b8f44e701..1e9b1903fae8 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -68,7 +68,8 @@ enum {
BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13),
};
-#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0))
+#define BYT_RT5640_MAP_MASK GENMASK(3, 0)
+#define BYT_RT5640_MAP(quirk) ((quirk) & BYT_RT5640_MAP_MASK)
#define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
#define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
#define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
@@ -140,7 +141,9 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n");
break;
default:
- dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
+ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC1_MAP\n", map);
+ byt_rt5640_quirk &= ~BYT_RT5640_MAP_MASK;
+ byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
break;
}
if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
@@ -1321,7 +1324,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
int num_routes = 0;
int ret;
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
jack_data->use_platform_clock = true;
/* Start with RC clk for jack-detect (we disable MCLK below) */
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 67c62844ca2a..ca540a66f22c 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -58,7 +58,8 @@ enum {
BYT_RT5651_OVCD_SF_1P5 = (RT5651_OVCD_SF_1P5 << 13),
};
-#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(3, 0))
+#define BYT_RT5651_MAP_MASK GENMASK(3, 0)
+#define BYT_RT5651_MAP(quirk) ((quirk) & BYT_RT5651_MAP_MASK)
#define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
#define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
#define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
@@ -100,14 +101,29 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev)
{
- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP)
+ int map;
+
+ map = BYT_RT5651_MAP(byt_rt5651_quirk);
+ switch (map) {
+ case BYT_RT5651_DMIC_MAP:
dev_info(dev, "quirk DMIC_MAP enabled");
- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP)
+ break;
+ case BYT_RT5651_IN1_MAP:
dev_info(dev, "quirk IN1_MAP enabled");
- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
+ break;
+ case BYT_RT5651_IN2_MAP:
dev_info(dev, "quirk IN2_MAP enabled");
- if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_IN2_MAP)
+ break;
+ case BYT_RT5651_IN1_IN2_MAP:
dev_info(dev, "quirk IN1_IN2_MAP enabled");
+ break;
+ default:
+ dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC_MAP\n", map);
+ byt_rt5651_quirk &= ~BYT_RT5651_MAP_MASK;
+ byt_rt5651_quirk |= BYT_RT5651_DMIC_MAP;
+ break;
+ }
+
if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
BYT_RT5651_JDSRC(byt_rt5651_quirk));
@@ -570,7 +586,7 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
int report;
int ret;
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
/* Start with RC clk for jack-detect (we disable MCLK below) */
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c
index a6dfbcfdf74e..72c0e5941ae8 100644
--- a/sound/soc/intel/boards/bytcr_wm5102.c
+++ b/sound/soc/intel/boards/bytcr_wm5102.c
@@ -288,7 +288,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime)
const struct snd_soc_dapm_route *custom_map = NULL;
int ret, jack_type, num_routes = 0;
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
ret = snd_soc_add_card_controls(card, byt_wm5102_controls,
ARRAY_SIZE(byt_wm5102_controls));
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index 1211a2b8a2a2..10b189ea88db 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -276,7 +276,7 @@ static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime)
int num_routes;
int ret;
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
if (quirk & SOC_ES8336_HEADSET_MIC1) {
custom_map = sof_es8316_headset_mic1_map;
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 28f03a5f29f7..c013e31d098e 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -841,7 +841,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
(*codec_conf)++;
}
- if (sof_end->include_sidecar) {
+ if (sof_end->include_sidecar && sof_end->codec_info->add_sidecar) {
ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf);
if (ret)
return ret;
diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
index 75dc8935a794..ec9fd8486c05 100644
--- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
@@ -948,6 +948,30 @@ static const struct snd_soc_acpi_adr_device cs42l42_0_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device tas2783_0_adr[] = {
+ {
+ .adr = 0x0000380102000001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "tas2783-1"
+ },
+ {
+ .adr = 0x0000390102000001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "tas2783-2"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr tas2783_link0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(tas2783_0_adr),
+ .adr_d = tas2783_0_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = {
/* Expected order: jack -> amp */
{
@@ -1081,6 +1105,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg",
},
{
+ .link_mask = BIT(0),
+ .links = tas2783_link0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-tas2783.tplg",
+ },
+ {
.link_mask = GENMASK(3, 0),
.links = mtl_rt713_l0_rt1316_l12_rt1713_l3,
.drv_name = "sof_sdw",
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c
index 95a083939f3e..a2a30a87a359 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.c
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c
@@ -89,40 +89,31 @@ static int set_dailink_daifmt(struct snd_soc_card *card,
int parse_dai_link_info(struct snd_soc_card *card)
{
struct device *dev = card->dev;
- struct device_node *sub_node;
struct snd_soc_dai_link *dai_link;
const char *dai_link_name;
int ret, i;
/* Loop over all the dai link sub nodes */
- for_each_available_child_of_node(dev->of_node, sub_node) {
+ for_each_available_child_of_node_scoped(dev->of_node, sub_node) {
if (of_property_read_string(sub_node, "link-name",
- &dai_link_name)) {
- of_node_put(sub_node);
+ &dai_link_name))
return -EINVAL;
- }
for_each_card_prelinks(card, i, dai_link) {
if (!strcmp(dai_link_name, dai_link->name))
break;
}
- if (i >= card->num_links) {
- of_node_put(sub_node);
+ if (i >= card->num_links)
return -EINVAL;
- }
ret = set_card_codec_info(card, sub_node, dai_link);
- if (ret < 0) {
- of_node_put(sub_node);
+ if (ret < 0)
return ret;
- }
ret = set_dailink_daifmt(card, sub_node, dai_link);
- if (ret < 0) {
- of_node_put(sub_node);
+ if (ret < 0)
return ret;
- }
}
return 0;
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 7d6a3586cdd5..3d6d7bc05b87 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -159,7 +159,7 @@ static int mt8173_rt5650_hdmi_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT,
&mt8173_rt5650_hdmi_jack);
if (ret)
return ret;
diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
index 3388e076ccc9..983f3b91119a 100644
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
@@ -378,7 +378,7 @@ static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_card_get_drvdata(rtd->card);
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT,
&priv->hdmi_jack);
if (ret)
return ret;
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index 497a9043be7b..0bc1f11e17aa 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -383,7 +383,7 @@ mt8183_mt6358_ts3a227_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_card_get_drvdata(rtd->card);
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT,
&priv->hdmi_jack);
if (ret)
return ret;
diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366.c b/sound/soc/mediatek/mt8186/mt8186-mt6366.c
index 43546012cf61..45df69809cba 100644
--- a/sound/soc/mediatek/mt8186/mt8186-mt6366.c
+++ b/sound/soc/mediatek/mt8186/mt8186-mt6366.c
@@ -362,7 +362,7 @@ static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rt
return ret;
}
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack);
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT, jack);
if (ret) {
dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
return ret;
diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
index ea814a0f726d..c6e7461e8f76 100644
--- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c
+++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
@@ -250,14 +250,14 @@ enum mt8188_jacks {
static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {
{
.pin = "HDMI",
- .mask = SND_JACK_LINEOUT,
+ .mask = SND_JACK_AVOUT,
},
};
static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {
{
.pin = "DP",
- .mask = SND_JACK_LINEOUT,
+ .mask = SND_JACK_AVOUT,
},
};
@@ -638,7 +638,7 @@ static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
int ret = 0;
ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack",
- SND_JACK_LINEOUT, jack,
+ SND_JACK_AVOUT, jack,
mt8188_hdmi_jack_pins,
ARRAY_SIZE(mt8188_hdmi_jack_pins));
if (ret) {
@@ -663,7 +663,7 @@ static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
int ret = 0;
- ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,
+ ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_AVOUT,
jack, mt8188_dp_jack_pins,
ARRAY_SIZE(mt8188_dp_jack_pins));
if (ret) {
diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
index bf483a8fb34a..91c57765ab57 100644
--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
+++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
@@ -368,7 +368,7 @@ static int mt8192_mt6359_hdmi_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_rtd_to_codec(rtd, 0)->component;
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack);
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT, jack);
if (ret) {
dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
return ret;
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
index e57391c213e7..7b96c843a14a 100644
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
@@ -360,7 +360,7 @@ static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_rtd_to_codec(rtd, 0)->component;
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT, jack);
+ ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_AVOUT, jack);
if (ret)
return ret;
@@ -375,7 +375,7 @@ static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_rtd_to_codec(rtd, 0)->component;
int ret;
- ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack);
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_AVOUT, jack);
if (ret)
return ret;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index e026f9912a6d..e54abcd39f79 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -3,7 +3,7 @@ menu "PXA"
config SND_PXA2XX_SOC
tristate "SoC Audio for the Intel PXA2xx chip"
- depends on ARCH_PXA || COMPILE_TEST
+ depends on ARCH_PXA || (COMPILE_TEST && GPIOLIB_LEGACY)
select SND_PXA2XX_LIB
help
Say Y or M if you want to add support for codecs attached to
@@ -26,7 +26,7 @@ config SND_PXA2XX_SOC_I2S
config SND_PXA_SOC_SSP
tristate "Soc Audio via PXA2xx/PXA3xx SSP ports"
- depends on PLAT_PXA
+ depends on ARCH_PXA
select PXA_SSP
select SND_PXA2XX_LIB
diff --git a/sound/soc/qcom/lpass-cdc-dma.c b/sound/soc/qcom/lpass-cdc-dma.c
index 8106c586f68a..2dc8c75c4bf0 100644
--- a/sound/soc/qcom/lpass-cdc-dma.c
+++ b/sound/soc/qcom/lpass-cdc-dma.c
@@ -217,8 +217,9 @@ static int lpass_cdc_dma_daiops_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
struct lpaif_dmactl *dmactl = NULL;
- unsigned int ret, regval;
+ unsigned int regval;
unsigned int channels = params_channels(params);
+ int ret;
int id;
switch (channels) {
diff --git a/sound/soc/qcom/lpass-hdmi.c b/sound/soc/qcom/lpass-hdmi.c
index ce753ebc0894..6d9795306cfa 100644
--- a/sound/soc/qcom/lpass-hdmi.c
+++ b/sound/soc/qcom/lpass-hdmi.c
@@ -23,7 +23,6 @@ static int lpass_hdmi_daiops_hw_params(struct snd_pcm_substream *substream,
snd_pcm_format_t format = params_format(params);
unsigned int rate = params_rate(params);
unsigned int channels = params_channels(params);
- unsigned int ret;
int bitwidth;
unsigned int word_length;
unsigned int ch_sts_buf0;
@@ -33,6 +32,7 @@ static int lpass_hdmi_daiops_hw_params(struct snd_pcm_substream *substream,
unsigned int ch = 0;
struct lpass_dp_metadata_ctl *meta_ctl = drvdata->meta_ctl;
struct lpass_sstream_ctl *sstream_ctl = drvdata->sstream_ctl;
+ int ret;
bitwidth = snd_pcm_format_width(format);
if (bitwidth < 0) {
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 3f5eed5afce5..2365424a9b42 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -811,6 +811,30 @@ static int audioreach_gapless_set_media_format(struct q6apm_graph *graph,
EARLY_EOS_DELAY_MS);
}
+static int audioreach_set_module_config(struct q6apm_graph *graph,
+ struct audioreach_module *module,
+ struct audioreach_module_config *cfg)
+{
+ int payload_size = le32_to_cpu(module->data->size);
+ struct gpr_pkt *pkt;
+ int rc;
+ void *p;
+
+ pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ if (IS_ERR(pkt))
+ return PTR_ERR(pkt);
+
+ p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
+
+ memcpy(p, module->data->data, payload_size);
+
+ rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
+
+ kfree(pkt);
+
+ return rc;
+}
+
static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
struct audioreach_module *module,
struct audioreach_module_config *cfg)
@@ -859,6 +883,7 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
struct payload_media_fmt_aac_t *aac_cfg;
struct payload_media_fmt_pcm *mp3_cfg;
struct payload_media_fmt_flac_t *flac_cfg;
+ struct payload_media_fmt_opus_t *opus_cfg;
switch (mcfg->fmt) {
case SND_AUDIOCODEC_MP3:
@@ -901,6 +926,32 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;
flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;
break;
+ case SND_AUDIOCODEC_OPUS_RAW:
+ media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
+ media_fmt_hdr->fmt_id = MEDIA_FMT_ID_OPUS;
+ media_fmt_hdr->payload_size = sizeof(*opus_cfg);
+ p = p + sizeof(*media_fmt_hdr);
+ opus_cfg = p;
+ /* raw opus packets prepended with 4 bytes of length */
+ opus_cfg->bitstream_format = 1;
+ /*
+ * payload_type:
+ * 0 -- read metadata from opus stream;
+ * 1 -- metadata is provided by filling in the struct here.
+ */
+ opus_cfg->payload_type = 1;
+ opus_cfg->version = mcfg->codec.options.opus_d.version;
+ opus_cfg->num_channels = mcfg->codec.options.opus_d.num_channels;
+ opus_cfg->pre_skip = mcfg->codec.options.opus_d.pre_skip;
+ opus_cfg->sample_rate = mcfg->codec.options.opus_d.sample_rate;
+ opus_cfg->output_gain = mcfg->codec.options.opus_d.output_gain;
+ opus_cfg->mapping_family = mcfg->codec.options.opus_d.mapping_family;
+ opus_cfg->stream_count = mcfg->codec.options.opus_d.chan_map.stream_count;
+ opus_cfg->coupled_count = mcfg->codec.options.opus_d.chan_map.coupled_count;
+ memcpy(opus_cfg->channel_mapping, mcfg->codec.options.opus_d.chan_map.channel_map,
+ sizeof(opus_cfg->channel_mapping));
+ opus_cfg->reserved[0] = opus_cfg->reserved[1] = opus_cfg->reserved[2] = 0;
+ break;
default:
return -EINVAL;
}
@@ -1248,6 +1299,9 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod
case MODULE_ID_DISPLAY_PORT_SINK:
rc = audioreach_display_port_set_media_format(graph, module, cfg);
break;
+ case MODULE_ID_SMECNS_V2:
+ rc = audioreach_set_module_config(graph, module, cfg);
+ break;
case MODULE_ID_I2S_SOURCE:
case MODULE_ID_I2S_SINK:
rc = audioreach_i2s_set_media_format(graph, module, cfg);
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 61a69df4f50f..d1b60b36468a 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -4,6 +4,7 @@
#define __AUDIOREACH_H__
#include <linux/types.h>
#include <linux/soc/qcom/apr.h>
+#include <uapi/sound/snd_ar_tokens.h>
#include <sound/soc.h>
struct q6apm;
struct q6apm_graph;
@@ -17,18 +18,20 @@ struct q6apm_graph;
#define MODULE_ID_PCM_DEC 0x07001005
#define MODULE_ID_PLACEHOLDER_ENCODER 0x07001008
#define MODULE_ID_PLACEHOLDER_DECODER 0x07001009
-#define MODULE_ID_SAL 0x07001010
-#define MODULE_ID_MFC 0x07001015
-#define MODULE_ID_CODEC_DMA_SINK 0x07001023
-#define MODULE_ID_CODEC_DMA_SOURCE 0x07001024
#define MODULE_ID_I2S_SINK 0x0700100A
#define MODULE_ID_I2S_SOURCE 0x0700100B
+#define MODULE_ID_SAL 0x07001010
+#define MODULE_ID_MFC 0x07001015
#define MODULE_ID_DATA_LOGGING 0x0700101A
#define MODULE_ID_AAC_DEC 0x0700101F
+#define MODULE_ID_CODEC_DMA_SINK 0x07001023
+#define MODULE_ID_CODEC_DMA_SOURCE 0x07001024
#define MODULE_ID_FLAC_DEC 0x0700102F
+#define MODULE_ID_SMECNS_V2 0x07001031
#define MODULE_ID_MP3_DECODE 0x0700103B
#define MODULE_ID_GAPLESS 0x0700104D
#define MODULE_ID_DISPLAY_PORT_SINK 0x07001069
+#define MODULE_ID_OPUS_DEC 0x07001174
#define APM_CMD_GET_SPF_STATE 0x01001021
#define APM_CMD_RSP_GET_SPF_STATE 0x02001007
@@ -255,6 +258,22 @@ struct payload_media_fmt_aac_t {
uint32_t sample_rate;
} __packed;
+#define MEDIA_FMT_ID_OPUS 0x09001039
+struct payload_media_fmt_opus_t {
+ uint16_t bitstream_format;
+ uint16_t payload_type;
+ uint8_t version;
+ uint8_t num_channels;
+ uint16_t pre_skip;
+ uint32_t sample_rate;
+ uint16_t output_gain;
+ uint8_t mapping_family;
+ uint8_t stream_count;
+ uint8_t coupled_count;
+ uint8_t channel_mapping[8];
+ uint8_t reserved[3];
+} __packed;
+
#define DATA_CMD_WR_SH_MEM_EP_EOS 0x04001002
#define WR_SH_MEM_EP_EOS_POLICY_LAST 1
#define WR_SH_MEM_EP_EOS_POLICY_EACH 2
@@ -461,8 +480,8 @@ struct param_id_i2s_intf_cfg {
} __packed;
#define I2S_INTF_TYPE_PRIMARY 0
-#define I2S_INTF_TYPE_SECOINDARY 1
-#define I2S_INTF_TYPE_TERTINARY 2
+#define I2S_INTF_TYPE_SECONDARY 1
+#define I2S_INTF_TYPE_TERTIARY 2
#define I2S_INTF_TYPE_QUATERNARY 3
#define I2S_INTF_TYPE_QUINARY 4
#define I2S_SD0 1
@@ -707,9 +726,6 @@ struct audioreach_module {
uint32_t max_ip_port;
uint32_t max_op_port;
- uint32_t in_port;
- uint32_t out_port;
-
uint32_t num_connections;
/* Connections */
uint32_t src_mod_inst_id;
@@ -745,6 +761,7 @@ struct audioreach_module {
struct list_head node;
struct audioreach_container *container;
struct snd_soc_dapm_widget *widget;
+ struct audioreach_module_priv_data *data;
};
struct audioreach_module_config {
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 2cd522108221..4ecaff45c518 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -11,6 +11,7 @@
#include <sound/soc-dapm.h>
#include <linux/spinlock.h>
#include <sound/pcm.h>
+#include <asm/div64.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <sound/pcm_params.h>
@@ -65,9 +66,9 @@ struct q6apm_dai_rtd {
unsigned int pcm_size;
unsigned int pcm_count;
unsigned int periods;
- unsigned int bytes_sent;
- unsigned int bytes_received;
- unsigned int copied_total;
+ uint64_t bytes_sent;
+ uint64_t bytes_received;
+ uint64_t copied_total;
uint16_t bits_per_sample;
snd_pcm_uframes_t queue_ptr;
bool next_track;
@@ -550,10 +551,11 @@ static int q6apm_dai_compr_get_caps(struct snd_soc_component *component,
caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
- caps->num_codecs = 3;
+ caps->num_codecs = 4;
caps->codecs[0] = SND_AUDIOCODEC_MP3;
caps->codecs[1] = SND_AUDIOCODEC_AAC;
caps->codecs[2] = SND_AUDIOCODEC_FLAC;
+ caps->codecs[3] = SND_AUDIOCODEC_OPUS_RAW;
return 0;
}
@@ -575,15 +577,17 @@ static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component,
static int q6apm_dai_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_compr_runtime *runtime = stream->runtime;
struct q6apm_dai_rtd *prtd = runtime->private_data;
unsigned long flags;
+ uint64_t temp_copied_total;
spin_lock_irqsave(&prtd->lock, flags);
tstamp->copied_total = prtd->copied_total;
- tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;
+ temp_copied_total = tstamp->copied_total;
+ tstamp->byte_offset = do_div(temp_copied_total, prtd->pcm_size);
spin_unlock_irqrestore(&prtd->lock, flags);
return 0;
@@ -760,21 +764,24 @@ static int q6apm_compr_copy(struct snd_soc_component *component,
size_t copy;
u32 wflags = 0;
u32 app_pointer;
- u32 bytes_received;
+ uint64_t bytes_received;
+ uint64_t temp_bytes_received;
uint32_t bytes_to_write;
- int avail, bytes_in_flight = 0;
+ uint64_t avail, bytes_in_flight = 0;
bytes_received = prtd->bytes_received;
+ temp_bytes_received = bytes_received;
/**
* Make sure that next track data pointer is aligned at 32 bit boundary
* This is a Mandatory requirement from DSP data buffers alignment
*/
- if (prtd->next_track)
+ if (prtd->next_track) {
bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
+ temp_bytes_received = bytes_received;
+ }
- app_pointer = bytes_received/prtd->pcm_size;
- app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
+ app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
dstn = prtd->dma_buffer.area + app_pointer;
if (count < prtd->pcm_size - app_pointer) {
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index b4ffa0f0b188..0e667a7eb546 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -354,6 +354,9 @@ int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph,
case SND_AUDIOCODEC_FLAC:
module_id = MODULE_ID_FLAC_DEC;
break;
+ case SND_AUDIOCODEC_OPUS_RAW:
+ module_id = MODULE_ID_OPUS_DEC;
+ break;
default:
return -EINVAL;
}
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
index a400c9a31fea..b616ce316d2f 100644
--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -14,6 +14,7 @@
#include <sound/pcm.h>
#include <linux/spinlock.h>
#include <sound/compress_driver.h>
+#include <asm/div64.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <sound/pcm_params.h>
@@ -59,9 +60,9 @@ struct q6asm_dai_rtd {
unsigned int pcm_count;
unsigned int pcm_irq_pos; /* IRQ position */
unsigned int periods;
- unsigned int bytes_sent;
- unsigned int bytes_received;
- unsigned int copied_total;
+ uint64_t bytes_sent;
+ uint64_t bytes_received;
+ uint64_t copied_total;
uint16_t bits_per_sample;
uint16_t source; /* Encoding source bit mask */
struct audio_client *audio_client;
@@ -1026,16 +1027,18 @@ static int q6asm_dai_compr_trigger(struct snd_soc_component *component,
static int q6asm_dai_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_compr_runtime *runtime = stream->runtime;
struct q6asm_dai_rtd *prtd = runtime->private_data;
unsigned long flags;
+ uint64_t temp_copied_total;
spin_lock_irqsave(&prtd->lock, flags);
tstamp->copied_total = prtd->copied_total;
- tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;
+ temp_copied_total = tstamp->copied_total;
+ tstamp->byte_offset = do_div(temp_copied_total, prtd->pcm_size);
spin_unlock_irqrestore(&prtd->lock, flags);
@@ -1050,23 +1053,26 @@ static int q6asm_compr_copy(struct snd_soc_component *component,
struct q6asm_dai_rtd *prtd = runtime->private_data;
unsigned long flags;
u32 wflags = 0;
- int avail, bytes_in_flight = 0;
+ uint64_t avail, bytes_in_flight = 0;
void *dstn;
size_t copy;
u32 app_pointer;
- u32 bytes_received;
+ uint64_t bytes_received;
+ uint64_t temp_bytes_received;
bytes_received = prtd->bytes_received;
+ temp_bytes_received = bytes_received;
/**
* Make sure that next track data pointer is aligned at 32 bit boundary
* This is a Mandatory requirement from DSP data buffers alignment
*/
- if (prtd->next_track)
+ if (prtd->next_track) {
bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
+ temp_bytes_received = bytes_received;
+ }
- app_pointer = bytes_received/prtd->pcm_size;
- app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
+ app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
dstn = prtd->dma_buffer.area + app_pointer;
if (count < prtd->pcm_size - app_pointer) {
diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c
index 83319a928f29..f61285e7dcf2 100644
--- a/sound/soc/qcom/qdsp6/topology.c
+++ b/sound/soc/qcom/qdsp6/topology.c
@@ -305,6 +305,34 @@ static struct snd_soc_tplg_vendor_array *audioreach_get_module_array(
return NULL;
}
+static struct audioreach_module_priv_data *audioreach_get_module_priv_data(
+ struct snd_soc_tplg_private *private)
+{
+ int sz;
+
+ for (sz = 0; sz < le32_to_cpu(private->size); ) {
+ struct snd_soc_tplg_vendor_array *mod_array;
+
+ mod_array = (struct snd_soc_tplg_vendor_array *)((u8 *)private->array + sz);
+ if (le32_to_cpu(mod_array->type) == SND_SOC_AR_TPLG_MODULE_CFG_TYPE) {
+ struct audioreach_module_priv_data *pdata;
+
+ pdata = kzalloc(struct_size(pdata, data, le32_to_cpu(mod_array->size)),
+ GFP_KERNEL);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+
+ memcpy(pdata, ((u8 *)private->data + sz), struct_size(pdata, data,
+ le32_to_cpu(mod_array->size)));
+ return pdata;
+ }
+
+ sz = sz + le32_to_cpu(mod_array->size);
+ }
+
+ return NULL;
+}
+
static struct audioreach_sub_graph *audioreach_parse_sg_tokens(struct q6apm *apm,
struct snd_soc_tplg_private *private)
{
@@ -412,7 +440,7 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
struct snd_soc_tplg_private *private,
struct snd_soc_dapm_widget *w)
{
- uint32_t max_ip_port = 0, max_op_port = 0, in_port = 0, out_port = 0;
+ uint32_t max_ip_port = 0, max_op_port = 0;
uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS] = { 0, };
uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS] = { 0, };
uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS] = { 0, };
@@ -455,12 +483,6 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
case AR_TKN_U32_MODULE_MAX_OP_PORTS:
max_op_port = le32_to_cpu(mod_elem->value);
break;
- case AR_TKN_U32_MODULE_IN_PORTS:
- in_port = le32_to_cpu(mod_elem->value);
- break;
- case AR_TKN_U32_MODULE_OUT_PORTS:
- out_port = le32_to_cpu(mod_elem->value);
- break;
case AR_TKN_U32_MODULE_SRC_INSTANCE_ID:
src_mod_inst_id = le32_to_cpu(mod_elem->value);
break;
@@ -550,8 +572,6 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
mod->module_id = module_id;
mod->max_ip_port = max_ip_port;
mod->max_op_port = max_op_port;
- mod->in_port = in_port;
- mod->out_port = out_port;
mod->src_mod_inst_id = src_mod_inst_id;
for (pn = 0; pn < mod->max_op_port; pn++) {
if (src_mod_op_port_id[pn] && dst_mod_inst_id[pn] &&
@@ -587,8 +607,10 @@ static int audioreach_widget_load_module_common(struct snd_soc_component *compon
return PTR_ERR(cont);
mod = audioreach_parse_common_tokens(apm, cont, &tplg_w->priv, w);
- if (IS_ERR(mod))
- return PTR_ERR(mod);
+ if (IS_ERR_OR_NULL(mod))
+ return mod ? PTR_ERR(mod) : -ENODEV;
+
+ mod->data = audioreach_get_module_priv_data(&tplg_w->priv);
dobj = &w->dobj;
dobj->private = mod;
@@ -947,6 +969,7 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,
cont->num_modules--;
list_del(&mod->node);
+ kfree(mod->data);
kfree(mod);
/* Graph Info has N sub-graphs, sub-graph has N containers, Container has N Modules */
if (list_empty(&cont->modules_list)) { /* if no modules in the container then remove it */
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 288ccd7f8866..78e327bc2f07 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -7,6 +7,7 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <linux/soundwire/sdw.h>
#include <sound/jack.h>
#include <linux/input-event-codes.h>
@@ -86,8 +87,10 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
+ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
rate->min = rate->max = 48000;
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
channels->min = 2;
channels->max = 2;
switch (cpu_dai->id) {
@@ -191,8 +194,8 @@ static const struct of_device_id snd_sc8280xp_dt_match[] = {
{.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
{.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
{.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
- {.compatible = "qcom,qcs9075-sndcard", "qcs9075"},
- {.compatible = "qcom,qcs9100-sndcard", "qcs9100"},
+ {.compatible = "qcom,qcs9075-sndcard", "sa8775p"},
+ {.compatible = "qcom,qcs9100-sndcard", "sa8775p"},
{.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},
{.compatible = "qcom,sm8450-sndcard", "sm8450"},
{.compatible = "qcom,sm8550-sndcard", "sm8550"},
diff --git a/sound/soc/qcom/x1e80100.c b/sound/soc/qcom/x1e80100.c
index 8eb57fc12f0d..444f2162889f 100644
--- a/sound/soc/qcom/x1e80100.c
+++ b/sound/soc/qcom/x1e80100.c
@@ -210,14 +210,15 @@ static int x1e80100_platform_probe(struct platform_device *pdev)
if (ret)
return ret;
- card->driver_name = "x1e80100";
+ card->driver_name = of_device_get_match_data(dev);
x1e80100_add_be_ops(card);
return devm_snd_soc_register_card(dev, card);
}
static const struct of_device_id snd_x1e80100_dt_match[] = {
- { .compatible = "qcom,x1e80100-sndcard", },
+ { .compatible = "qcom,x1e80100-sndcard", .data = "x1e80100" },
+ { .compatible = "qcom,glymur-sndcard", .data = "glymur" },
{}
};
MODULE_DEVICE_TABLE(of, snd_x1e80100_dt_match);
diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
index 221ce91f1950..630c2f52e1cf 100644
--- a/sound/soc/renesas/fsi.c
+++ b/sound/soc/renesas/fsi.c
@@ -343,14 +343,9 @@ static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
{
- u32 ret;
- unsigned long flags;
+ guard(spinlock_irqsave)(&master->lock);
- spin_lock_irqsave(&master->lock, flags);
- ret = __fsi_reg_read(master->base + reg);
- spin_unlock_irqrestore(&master->lock, flags);
-
- return ret;
+ return __fsi_reg_read(master->base + reg);
}
#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
@@ -358,11 +353,9 @@ static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
static void _fsi_master_mask_set(struct fsi_master *master,
u32 reg, u32 mask, u32 data)
{
- unsigned long flags;
+ guard(spinlock_irqsave)(&master->lock);
- spin_lock_irqsave(&master->lock, flags);
__fsi_reg_mask_set(master->base + reg, mask, data);
- spin_unlock_irqrestore(&master->lock, flags);
}
/*
@@ -499,14 +492,10 @@ static int fsi_stream_is_working(struct fsi_priv *fsi,
struct fsi_stream *io)
{
struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
- int ret;
- spin_lock_irqsave(&master->lock, flags);
- ret = !!(io->substream && io->substream->runtime);
- spin_unlock_irqrestore(&master->lock, flags);
+ guard(spinlock_irqsave)(&master->lock);
- return ret;
+ return !!(io->substream && io->substream->runtime);
}
static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
@@ -520,9 +509,9 @@ static void fsi_stream_init(struct fsi_priv *fsi,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
- spin_lock_irqsave(&master->lock, flags);
+ guard(spinlock_irqsave)(&master->lock);
+
io->substream = substream;
io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
io->buff_sample_pos = 0;
@@ -533,16 +522,14 @@ static void fsi_stream_init(struct fsi_priv *fsi,
io->oerr_num = -1; /* ignore 1st err */
io->uerr_num = -1; /* ignore 1st err */
fsi_stream_handler_call(io, init, fsi, io);
- spin_unlock_irqrestore(&master->lock, flags);
}
static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
{
struct snd_soc_dai *dai = fsi_get_dai(io->substream);
struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
- spin_lock_irqsave(&master->lock, flags);
+ guard(spinlock_irqsave)(&master->lock);
if (io->oerr_num > 0)
dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
@@ -560,7 +547,6 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
io->bus_option = 0;
io->oerr_num = 0;
io->uerr_num = 0;
- spin_unlock_irqrestore(&master->lock, flags);
}
static int fsi_stream_transfer(struct fsi_stream *io)
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index 9f086906a2e5..69fb19964a71 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -696,25 +696,21 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
int ret;
- unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
+ guard(spinlock_irqsave)(&priv->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
ret = rsnd_dai_call(init, io, priv);
if (ret < 0)
- goto dai_trigger_end;
+ break;
ret = rsnd_dai_call(start, io, priv);
if (ret < 0)
- goto dai_trigger_end;
+ break;
ret = rsnd_dai_call(irq, io, priv, 1);
- if (ret < 0)
- goto dai_trigger_end;
-
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -729,9 +725,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
ret = -EINVAL;
}
-dai_trigger_end:
- spin_unlock_irqrestore(&priv->lock, flags);
-
return ret;
}
@@ -1545,15 +1538,14 @@ static int rsnd_hw_update(struct snd_pcm_substream *substream,
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
struct rsnd_priv *priv = rsnd_io_to_priv(io);
- unsigned long flags;
int ret;
- spin_lock_irqsave(&priv->lock, flags);
+ guard(spinlock_irqsave)(&priv->lock);
+
if (hw_params)
ret = rsnd_dai_call(hw_params, io, substream, hw_params);
else
ret = rsnd_dai_call(hw_free, io, substream);
- spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
diff --git a/sound/soc/renesas/rcar/msiof.c b/sound/soc/renesas/rcar/msiof.c
index 36d31ab8ac6a..f2addfbac923 100644
--- a/sound/soc/renesas/rcar/msiof.c
+++ b/sound/soc/renesas/rcar/msiof.c
@@ -7,7 +7,7 @@
//
/*
- * [NOTE]
+ * [NOTE-CLOCK-MODE]
*
* This driver doesn't support Clock/Frame Provider Mode
*
@@ -24,12 +24,64 @@
* Clock/Frame Consumer Mode.
*/
+/*
+ * [NOTE-RESET]
+ *
+ * MSIOF has TXRST/RXRST to reset FIFO, but it shouldn't be used during SYNC signal was asserted,
+ * because it will be cause of HW issue.
+ *
+ * When MSIOF is used as Sound driver, this driver is assuming it is used as clock consumer mode
+ * (= Codec is clock provider). This means, it can't control SYNC signal by itself.
+ *
+ * We need to use SW reset (= reset_control_xxx()) instead of TXRST/RXRST.
+ */
+
+/*
+ * [NOTE-BOTH-SETTING]
+ *
+ * SITMDRn / SIRMDRn and some other registers should not be updated during working even though it
+ * was not related the target direction (for example, do TX settings during RX is working),
+ * otherwise it cause a FSERR.
+ *
+ * Setup both direction (Playback/Capture) in the same time.
+ */
+
+/*
+ * [NOTE-R/L]
+ *
+ * The data of Captured might be R/L opposite.
+ *
+ * This driver is assuming MSIOF is used as Clock/Frame Consumer Mode, and there is a case that some
+ * Codec (= Clock/Frame Provider) might output Clock/Frame before setup MSIOF. It depends on Codec
+ * driver implementation.
+ *
+ * MSIOF will capture data without checking SYNC signal Hi/Low (= R/L).
+ *
+ * This means, if MSIOF RXE bit was set as 1 in case of SYNC signal was Hi (= R) timing, it will
+ * start capture data since next SYNC low singla (= L). Because Linux assumes sound data is lined
+ * up as R->L->R->L->..., the data R/L will be opposite.
+ *
+ * The only solution in this case is start CLK/SYNC *after* MSIOF settings, but it depends when and
+ * how Codec driver start it.
+ */
+
+/*
+ * [NOTE-FSERR]
+ *
+ * We can't remove all FSERR.
+ *
+ * Renesas have tried to minimize the occurrence of FSERR errors as much as possible, but
+ * unfortunately we cannot remove them completely, because MSIOF might setup its register during
+ * CLK/SYNC are inputed. It can be happen because MSIOF is working as Clock/Frame Consumer.
+ */
+
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/reset.h>
#include <linux/spi/sh_msiof.h>
#include <sound/dmaengine_pcm.h>
#include <sound/soc.h>
@@ -37,7 +89,6 @@
/* SISTR */
#define SISTR_ERR_TX (SISTR_TFSERR | SISTR_TFOVF | SISTR_TFUDF)
#define SISTR_ERR_RX (SISTR_RFSERR | SISTR_RFOVF | SISTR_RFUDF)
-#define SISTR_ERR (SISTR_ERR_TX | SISTR_ERR_RX)
/*
* The data on memory in 24bit case is located at <right> side
@@ -61,10 +112,13 @@
struct msiof_priv {
struct device *dev;
struct snd_pcm_substream *substream[SNDRV_PCM_STREAM_LAST + 1];
+ struct reset_control *reset;
spinlock_t lock;
void __iomem *base;
resource_size_t phy_addr;
+ int count;
+
/* for error */
int err_syc[SNDRV_PCM_STREAM_LAST + 1];
int err_ovf[SNDRV_PCM_STREAM_LAST + 1];
@@ -80,15 +134,19 @@ struct msiof_priv {
#define msiof_is_play(substream) ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK)
#define msiof_read(priv, reg) ioread32((priv)->base + reg)
#define msiof_write(priv, reg, val) iowrite32(val, (priv)->base + reg)
-#define msiof_status_clear(priv) msiof_write(priv, SISTR, SISTR_ERR)
-static void msiof_update(struct msiof_priv *priv, u32 reg, u32 mask, u32 val)
+static int msiof_update(struct msiof_priv *priv, u32 reg, u32 mask, u32 val)
{
u32 old = msiof_read(priv, reg);
u32 new = (old & ~mask) | (val & mask);
+ int updated = false;
- if (old != new)
+ if (old != new) {
msiof_write(priv, reg, new);
+ updated = true;
+ }
+
+ return updated;
}
static void msiof_update_and_wait(struct msiof_priv *priv, u32 reg, u32 mask, u32 val, u32 expect)
@@ -96,7 +154,9 @@ static void msiof_update_and_wait(struct msiof_priv *priv, u32 reg, u32 mask, u3
u32 data;
int ret;
- msiof_update(priv, reg, mask, val);
+ ret = msiof_update(priv, reg, mask, val);
+ if (!ret) /* no update */
+ return;
ret = readl_poll_timeout_atomic(priv->base + reg, data,
(data & mask) == expect, 1, 128);
@@ -116,7 +176,7 @@ static int msiof_hw_start(struct snd_soc_component *component,
/*
* see
- * [NOTE] on top of this driver
+ * [NOTE-CLOCK-MODE] on top of this driver
*/
/*
* see
@@ -126,39 +186,63 @@ static int msiof_hw_start(struct snd_soc_component *component,
* RX: Fig 109.15
*/
- /* reset errors */
- priv->err_syc[substream->stream] =
+ /*
+ * Use reset_control_xx() instead of TXRST/RXRST.
+ * see
+ * [NOTE-RESET]
+ */
+ if (!priv->count)
+ reset_control_deassert(priv->reset);
+
+ priv->count++;
+
+ /*
+ * Reset errors. ignore 1st FSERR
+ *
+ * see
+ * [NOTE-FSERR]
+ */
+ priv->err_syc[substream->stream] = -1;
priv->err_ovf[substream->stream] =
priv->err_udf[substream->stream] = 0;
+ /* Start DMAC */
+ snd_dmaengine_pcm_trigger(substream, cmd);
+
+ /*
+ * setup both direction (Playback/Capture) in the same time.
+ * see
+ * above [NOTE-BOTH-SETTING]
+ */
+
/* SITMDRx */
- if (is_play) {
- val = SITMDR1_PCON |
- FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR) |
- SIMDR1_SYNCAC | SIMDR1_XXSTP;
- if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
- val |= FIELD_PREP(SIMDR1_DTDL, 1);
+ val = SITMDR1_PCON | SIMDR1_SYNCAC | SIMDR1_XXSTP |
+ FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR);
+ if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
+ val |= FIELD_PREP(SIMDR1_DTDL, 1);
- msiof_write(priv, SITMDR1, val);
+ msiof_write(priv, SITMDR1, val);
- val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
- msiof_write(priv, SITMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
- msiof_write(priv, SITMDR3, val);
+ val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
+ msiof_write(priv, SITMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
+ msiof_write(priv, SITMDR3, val);
- }
/* SIRMDRx */
- else {
- val = FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR) |
- SIMDR1_SYNCAC;
- if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
- val |= FIELD_PREP(SIMDR1_DTDL, 1);
+ val = SIMDR1_SYNCAC |
+ FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR);
+ if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
+ val |= FIELD_PREP(SIMDR1_DTDL, 1);
- msiof_write(priv, SIRMDR1, val);
+ msiof_write(priv, SIRMDR1, val);
- val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
- msiof_write(priv, SIRMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
- msiof_write(priv, SIRMDR3, val);
- }
+ val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
+ msiof_write(priv, SIRMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
+ msiof_write(priv, SIRMDR3, val);
+
+ /* SIFCTR */
+ msiof_write(priv, SIFCTR,
+ FIELD_PREP(SIFCTR_TFWM, SIFCTR_TFWM_1) |
+ FIELD_PREP(SIFCTR_RFWM, SIFCTR_RFWM_1));
/* SIIER */
if (is_play)
@@ -167,18 +251,21 @@ static int msiof_hw_start(struct snd_soc_component *component,
val = SIIER_RDREQE | SIIER_RDMAE | SISTR_ERR_RX;
msiof_update(priv, SIIER, val, val);
+ /* clear status */
+ if (is_play)
+ val = SISTR_ERR_TX;
+ else
+ val = SISTR_ERR_RX;
+ msiof_update(priv, SISTR, val, val);
+
/* SICTR */
+ val = SICTR_TEDG | SICTR_REDG;
if (is_play)
- val = SICTR_TXE | SICTR_TEDG;
+ val |= SICTR_TXE;
else
- val = SICTR_RXE | SICTR_REDG;
+ val |= SICTR_RXE;
msiof_update_and_wait(priv, SICTR, val, val, val);
- msiof_status_clear(priv);
-
- /* Start DMAC */
- snd_dmaengine_pcm_trigger(substream, cmd);
-
return 0;
}
@@ -197,9 +284,6 @@ static int msiof_hw_stop(struct snd_soc_component *component,
val = SIIER_RDREQE | SIIER_RDMAE | SISTR_ERR_RX;
msiof_update(priv, SIIER, val, 0);
- /* Stop DMAC */
- snd_dmaengine_pcm_trigger(substream, cmd);
-
/* SICTR */
if (is_play)
val = SICTR_TXE;
@@ -207,16 +291,33 @@ static int msiof_hw_stop(struct snd_soc_component *component,
val = SICTR_RXE;
msiof_update_and_wait(priv, SICTR, val, 0, 0);
+ /* Stop DMAC */
+ snd_dmaengine_pcm_trigger(substream, cmd);
+
+ /*
+ * Ignore 1st FSERR
+ *
+ * see
+ * [NOTE-FSERR]
+ */
+ if (priv->err_syc[substream->stream] < 0)
+ priv->err_syc[substream->stream] = 0;
+
/* indicate error status if exist */
if (priv->err_syc[substream->stream] ||
priv->err_ovf[substream->stream] ||
priv->err_udf[substream->stream])
- dev_warn(dev, "FSERR(%s) = %d, FOVF = %d, FUDF = %d\n",
+ dev_warn(dev, "%s: FSERR = %d, FOVF = %d, FUDF = %d\n",
snd_pcm_direction_name(substream->stream),
priv->err_syc[substream->stream],
priv->err_ovf[substream->stream],
priv->err_udf[substream->stream]);
+ priv->count--;
+
+ if (!priv->count)
+ reset_control_assert(priv->reset);
+
return 0;
}
@@ -292,6 +393,9 @@ static struct snd_soc_dai_driver msiof_dai_driver = {
.channels_max = 2,
},
.ops = &msiof_dai_ops,
+ .symmetric_rate = 1,
+ .symmetric_channels = 1,
+ .symmetric_sample_bits = 1,
};
static struct snd_pcm_hardware msiof_pcm_hardware = {
@@ -362,10 +466,9 @@ static int msiof_trigger(struct snd_soc_component *component,
{
struct device *dev = component->dev;
struct msiof_priv *priv = dev_get_drvdata(dev);
- unsigned long flags;
int ret = -EINVAL;
- spin_lock_irqsave(&priv->lock, flags);
+ guard(spinlock_irqsave)(&priv->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -382,8 +485,6 @@ static int msiof_trigger(struct snd_soc_component *component,
break;
}
- spin_unlock_irqrestore(&priv->lock, flags);
-
return ret;
}
@@ -394,23 +495,18 @@ static int msiof_hw_params(struct snd_soc_component *component,
struct msiof_priv *priv = dev_get_drvdata(component->dev);
struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
struct dma_slave_config cfg = {};
- unsigned long flags;
int ret;
- spin_lock_irqsave(&priv->lock, flags);
+ guard(spinlock_irqsave)(&priv->lock);
ret = snd_hwparams_to_dma_slave_config(substream, params, &cfg);
if (ret < 0)
- goto hw_params_out;
+ return ret;
cfg.dst_addr = priv->phy_addr + SITFDR;
cfg.src_addr = priv->phy_addr + SIRFDR;
- ret = dmaengine_slave_config(chan, &cfg);
-hw_params_out:
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return ret;
+ return dmaengine_slave_config(chan, &cfg);
}
static const struct snd_soc_component_driver msiof_component_driver = {
@@ -429,12 +525,10 @@ static irqreturn_t msiof_interrupt(int irq, void *data)
struct snd_pcm_substream *substream;
u32 sistr;
- spin_lock(&priv->lock);
-
- sistr = msiof_read(priv, SISTR);
- msiof_status_clear(priv);
-
- spin_unlock(&priv->lock);
+ scoped_guard(spinlock, &priv->lock) {
+ sistr = msiof_read(priv, SISTR);
+ msiof_write(priv, SISTR, SISTR_ERR_TX | SISTR_ERR_RX);
+ }
/* overflow/underflow error */
substream = priv->substream[SNDRV_PCM_STREAM_PLAYBACK];
@@ -490,12 +584,19 @@ static int msiof_probe(struct platform_device *pdev)
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
+ priv->reset = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(priv->reset))
+ return PTR_ERR(priv->reset);
+
+ reset_control_assert(priv->reset);
+
ret = devm_request_irq(dev, irq, msiof_interrupt, 0, dev_name(dev), priv);
if (ret)
return ret;
priv->dev = dev;
priv->phy_addr = res->start;
+ priv->count = 0;
spin_lock_init(&priv->lock);
platform_set_drvdata(pdev, priv);
diff --git a/sound/soc/renesas/rcar/src.c b/sound/soc/renesas/rcar/src.c
index f47bf38c2f94..6a3dbc84f474 100644
--- a/sound/soc/renesas/rcar/src.c
+++ b/sound/soc/renesas/rcar/src.c
@@ -558,19 +558,16 @@ static void __rsnd_src_interrupt(struct rsnd_mod *mod,
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
bool stop = false;
- spin_lock(&priv->lock);
-
- /* ignore all cases if not working */
- if (!rsnd_io_is_working(io))
- goto rsnd_src_interrupt_out;
+ scoped_guard(spinlock, &priv->lock) {
+ /* ignore all cases if not working */
+ if (!rsnd_io_is_working(io))
+ break;
- if (rsnd_src_error_occurred(mod))
- stop = true;
+ if (rsnd_src_error_occurred(mod))
+ stop = true;
- rsnd_src_status_clear(mod);
-rsnd_src_interrupt_out:
-
- spin_unlock(&priv->lock);
+ rsnd_src_status_clear(mod);
+ }
if (stop)
snd_pcm_stop_xrun(io->substream);
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index d52056caa3ec..0420041e282c 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -680,31 +680,30 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
bool elapsed = false;
bool stop = false;
- spin_lock(&priv->lock);
+ scoped_guard(spinlock, &priv->lock) {
- /* ignore all cases if not working */
- if (!rsnd_io_is_working(io))
- goto rsnd_ssi_interrupt_out;
+ /* ignore all cases if not working */
+ if (!rsnd_io_is_working(io))
+ break;
- status = rsnd_ssi_status_get(mod);
+ status = rsnd_ssi_status_get(mod);
- /* PIO only */
- if (!is_dma && (status & DIRQ))
- elapsed = rsnd_ssi_pio_interrupt(mod, io);
+ /* PIO only */
+ if (!is_dma && (status & DIRQ))
+ elapsed = rsnd_ssi_pio_interrupt(mod, io);
- /* DMA only */
- if (is_dma && (status & (UIRQ | OIRQ))) {
- rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
- rsnd_mod_name(mod), status);
+ /* DMA only */
+ if (is_dma && (status & (UIRQ | OIRQ))) {
+ rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
+ rsnd_mod_name(mod), status);
- stop = true;
- }
+ stop = true;
+ }
- stop |= rsnd_ssiu_busif_err_status_clear(mod);
+ stop |= rsnd_ssiu_busif_err_status_clear(mod);
- rsnd_ssi_status_clear(mod);
-rsnd_ssi_interrupt_out:
- spin_unlock(&priv->lock);
+ rsnd_ssi_status_clear(mod);
+ }
if (elapsed)
snd_pcm_period_elapsed(io->substream);
diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c
index 0f7458a43901..e00940814157 100644
--- a/sound/soc/renesas/rz-ssi.c
+++ b/sound/soc/renesas/rz-ssi.c
@@ -188,24 +188,18 @@ static void rz_ssi_set_substream(struct rz_ssi_stream *strm,
struct snd_pcm_substream *substream)
{
struct rz_ssi_priv *ssi = strm->priv;
- unsigned long flags;
- spin_lock_irqsave(&ssi->lock, flags);
+ guard(spinlock_irqsave)(&ssi->lock);
+
strm->substream = substream;
- spin_unlock_irqrestore(&ssi->lock, flags);
}
static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
struct rz_ssi_stream *strm)
{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&ssi->lock, flags);
- ret = strm->substream && strm->substream->runtime;
- spin_unlock_irqrestore(&ssi->lock, flags);
+ guard(spinlock_irqsave)(&ssi->lock);
- return ret;
+ return strm->substream && strm->substream->runtime;
}
static inline bool rz_ssi_is_stream_running(struct rz_ssi_stream *strm)
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h
index 0aa1c6da1e2c..0171e05ee886 100644
--- a/sound/soc/rockchip/rockchip_i2s_tdm.h
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -10,6 +10,8 @@
#ifndef _ROCKCHIP_I2S_TDM_H
#define _ROCKCHIP_I2S_TDM_H
+#include <linux/hw_bitfield.h>
+
/*
* TXCR
* transmit operation control register
@@ -285,7 +287,7 @@ enum {
#define I2S_TDM_RXCR (0x0034)
#define I2S_CLKDIV (0x0038)
-#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
+#define HIWORD_UPDATE(v, h, l) (FIELD_PREP_WM16_CONST(GENMASK((h), (l)), (v)))
/* PX30 GRF CONFIGS */
#define PX30_I2S0_CLK_IN_SRC_FROM_TX HIWORD_UPDATE(1, 13, 12)
diff --git a/sound/soc/sdw_utils/Makefile b/sound/soc/sdw_utils/Makefile
index daf019113553..a87c53e1a2c1 100644
--- a/sound/soc/sdw_utils/Makefile
+++ b/sound/soc/sdw_utils/Makefile
@@ -6,5 +6,6 @@ snd-soc-sdw-utils-y := soc_sdw_utils.o soc_sdw_dmic.o soc_sdw_rt_dmic.o \
soc_sdw_bridge_cs35l56.o \
soc_sdw_cs42l42.o soc_sdw_cs42l43.o \
soc_sdw_cs_amp.o \
- soc_sdw_maxim.o
+ soc_sdw_maxim.o \
+ soc_sdw_ti_amp.o
obj-$(CONFIG_SND_SOC_SDW_UTILS) += snd-soc-sdw-utils.o
diff --git a/sound/soc/sdw_utils/soc_sdw_ti_amp.c b/sound/soc/sdw_utils/soc_sdw_ti_amp.c
new file mode 100644
index 000000000000..f0011360ae9b
--- /dev/null
+++ b/sound/soc/sdw_utils/soc_sdw_ti_amp.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Texas Instruments Inc.
+
+/*
+ * soc_sdw_ti_amp - Helpers to handle TI's soundwire based codecs
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-dai.h>
+#include <sound/soc_sdw_utils.h>
+
+#define TIAMP_SPK_VOLUME_0DB 200
+
+int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
+ const char *name_prefix)
+{
+ char *volume_ctl_name;
+ int ret;
+
+ volume_ctl_name = kasprintf(GFP_KERNEL, "%s Speaker Volume",
+ name_prefix);
+ if (!volume_ctl_name)
+ return -ENOMEM;
+
+ ret = snd_soc_limit_volume(card, volume_ctl_name,
+ TIAMP_SPK_VOLUME_0DB);
+ if (ret)
+ dev_err(card->dev,
+ "%s update failed %d\n",
+ volume_ctl_name, ret);
+
+ kfree(volume_ctl_name);
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_ti_amp_initial_settings, "SND_SOC_SDW_UTILS");
+
+int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_card *card = rtd->card;
+ char widget_name[16];
+ char speaker[16];
+ struct snd_soc_dapm_route route = {speaker, NULL, widget_name};
+ struct snd_soc_dai *codec_dai;
+ const char *prefix;
+ int i, ret = 0;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ if (!strstr(codec_dai->name, "tas2783"))
+ continue;
+
+ prefix = codec_dai->component->name_prefix;
+ if (!strncmp(prefix, "tas2783-1", strlen("tas2783-1"))) {
+ strscpy(speaker, "Left Spk", sizeof(speaker));
+ } else if (!strncmp(prefix, "tas2783-2", strlen("tas2783-2"))) {
+ strscpy(speaker, "Right Spk", sizeof(speaker));
+ } else {
+ ret = -EINVAL;
+ dev_err(card->dev, "unhandled prefix %s", prefix);
+ break;
+ }
+
+ snprintf(widget_name, sizeof(widget_name), "%s SPK", prefix);
+ ret = asoc_sdw_ti_amp_initial_settings(card, prefix);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, &route, 1);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_ti_spk_rtd_init, "SND_SOC_SDW_UTILS");
+
+int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
+{
+ if (!playback)
+ return 0;
+
+ info->amp_num++;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_ti_amp_init, "SND_SOC_SDW_UTILS");
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 1580331cd34c..56c72ef27e7b 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -35,12 +35,12 @@ static const struct snd_kcontrol_new generic_spk_controls[] = {
SOC_DAPM_PIN_SWITCH("Speaker"),
};
-static const struct snd_soc_dapm_widget maxim_widgets[] = {
+static const struct snd_soc_dapm_widget lr_spk_widgets[] = {
SND_SOC_DAPM_SPK("Left Spk", NULL),
SND_SOC_DAPM_SPK("Right Spk", NULL),
};
-static const struct snd_kcontrol_new maxim_controls[] = {
+static const struct snd_kcontrol_new lr_spk_controls[] = {
SOC_DAPM_PIN_SWITCH("Left Spk"),
SOC_DAPM_PIN_SWITCH("Right Spk"),
};
@@ -59,6 +59,24 @@ static const struct snd_kcontrol_new rt700_controls[] = {
struct asoc_sdw_codec_info codec_info_list[] = {
{
+ .part_id = 0x0000, /* TAS2783A */
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "tas2783-codec",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_ti_amp_init,
+ .rtd_init = asoc_sdw_ti_spk_rtd_init,
+ .controls = lr_spk_controls,
+ .num_controls = ARRAY_SIZE(lr_spk_controls),
+ .widgets = lr_spk_widgets,
+ .num_widgets = ARRAY_SIZE(lr_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
.part_id = 0x700,
.dais = {
{
@@ -450,10 +468,10 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.init = asoc_sdw_maxim_init,
.rtd_init = asoc_sdw_maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
+ .controls = lr_spk_controls,
+ .num_controls = ARRAY_SIZE(lr_spk_controls),
+ .widgets = lr_spk_widgets,
+ .num_widgets = ARRAY_SIZE(lr_spk_widgets),
},
},
.dai_num = 1,
@@ -469,10 +487,10 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
.init = asoc_sdw_maxim_init,
.rtd_init = asoc_sdw_maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
+ .controls = lr_spk_controls,
+ .num_controls = ARRAY_SIZE(lr_spk_controls),
+ .widgets = lr_spk_widgets,
+ .num_widgets = ARRAY_SIZE(lr_spk_widgets),
},
},
.dai_num = 1,
diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
index 65c495094024..c815fd1b3fd1 100644
--- a/sound/soc/soc-component.c
+++ b/sound/soc/soc-component.c
@@ -637,7 +637,7 @@ int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);
int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 01d1d6bee28c..7b81dffc6a93 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -457,7 +457,7 @@ err:
}
static int soc_compr_pointer(struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
int ret;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index cc9125ffe92a..9dd84d73046b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -717,7 +717,7 @@ int snd_soc_suspend(struct device *dev)
* means it's doing something,
* otherwise fall through.
*/
- if (dapm->idle_bias_off) {
+ if (!dapm->idle_bias) {
dev_dbg(component->dev,
"ASoC: idle_bias_off CODEC on over suspend\n");
break;
@@ -1652,7 +1652,7 @@ static int soc_probe_component(struct snd_soc_card *card,
if (ret < 0)
goto err_probe;
- WARN(dapm->idle_bias_off &&
+ WARN(!dapm->idle_bias &&
dapm->bias_level != SND_SOC_BIAS_OFF,
"codec %s can not start from non-off bias with idle_bias_off==1\n",
component->name);
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 32f46a38682b..f231b4174b5f 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -774,7 +774,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack);
int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
int ret = 0;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a37d44cd04c6..51fb09d56c5a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -165,6 +165,27 @@ static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
kfree(buf);
}
+struct device *snd_soc_dapm_to_dev(struct snd_soc_dapm_context *dapm)
+{
+ if (dapm->component)
+ return dapm->component->dev;
+
+ return dapm->card->dev;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_to_dev);
+
+struct snd_soc_card *snd_soc_dapm_to_card(struct snd_soc_dapm_context *dapm)
+{
+ return dapm->card;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_to_card);
+
+struct snd_soc_component *snd_soc_dapm_to_component(struct snd_soc_dapm_context *dapm)
+{
+ return dapm->component;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_to_component);
+
static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
{
return !list_empty(&w->dirty);
@@ -838,13 +859,13 @@ static struct list_head *dapm_kcontrol_get_path_list(
list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
list_kcontrol)
-unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
+unsigned int snd_soc_dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
return data->value;
}
-EXPORT_SYMBOL_GPL(dapm_kcontrol_get_value);
+EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_get_value);
static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
unsigned int value)
@@ -877,31 +898,42 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
}
/**
- * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
+ * snd_soc_dapm_kcontrol_to_widget() - Returns the widget associated to a
* kcontrol
* @kcontrol: The kcontrol
*/
-struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
- struct snd_kcontrol *kcontrol)
+struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_to_widget(struct snd_kcontrol *kcontrol)
{
return dapm_kcontrol_get_wlist(kcontrol)->widgets[0];
}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_widget);
+EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_to_widget);
/**
- * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
- * kcontrol
+ * snd_soc_dapm_kcontrol_to_dapm() - Returns the dapm context associated to a kcontrol
* @kcontrol: The kcontrol
*
* Note: This function must only be used on kcontrols that are known to have
* been registered for a CODEC. Otherwise the behaviour is undefined.
*/
-struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
- struct snd_kcontrol *kcontrol)
+struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_to_dapm(struct snd_kcontrol *kcontrol)
{
return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm;
}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
+EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_to_dapm);
+
+/**
+ * snd_soc_dapm_kcontrol_to_component() - Returns the component associated to a
+ * kcontrol
+ * @kcontrol: The kcontrol
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined
+ */
+struct snd_soc_component *snd_soc_dapm_kcontrol_to_component(struct snd_kcontrol *kcontrol)
+{
+ return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_to_dapm(kcontrol));
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_to_component);
static void dapm_reset(struct snd_soc_card *card)
{
@@ -1000,6 +1032,25 @@ int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_bias_level);
/**
+ * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
+ * @dapm: The DAPM context to initialize
+ * @level: The DAPM level to initialize to
+ *
+ * This function only sets the driver internal state of the DAPM level and will
+ * not modify the state of the device. Hence it should not be used during normal
+ * operation, but only to synchronize the internal state to the device state.
+ * E.g. during driver probe to set the DAPM level to the one corresponding with
+ * the power-on reset state of the device.
+ *
+ * To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
+ */
+void snd_soc_dapm_init_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
+{
+ dapm->bias_level = level;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_init_bias_level);
+
+/**
* snd_soc_dapm_set_bias_level - set the bias level for the system
* @dapm: DAPM context
* @level: level to configure
@@ -1037,6 +1088,18 @@ out:
return ret;
}
+/**
+ * snd_soc_dapm_get_bias_level() - Get current DAPM bias level
+ * @dapm: The context for which to get the bias level
+ *
+ * Returns: The current bias level of the passed DAPM context.
+ */
+enum snd_soc_bias_level snd_soc_dapm_get_bias_level(struct snd_soc_dapm_context *dapm)
+{
+ return dapm->bias_level;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_get_bias_level);
+
static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *kcontrolw,
const struct snd_kcontrol_new *kcontrol_new,
@@ -2117,21 +2180,26 @@ end:
dapm_seq_insert(w, down_list, false);
}
-static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm)
+bool snd_soc_dapm_get_idle_bias(struct snd_soc_dapm_context *dapm)
{
- if (dapm->idle_bias_off)
- return true;
+ if (dapm->idle_bias) {
+ struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+ unsigned int state = snd_power_get_state(dapm->card->snd_card);
- switch (snd_power_get_state(dapm->card->snd_card)) {
- case SNDRV_CTL_POWER_D3hot:
- case SNDRV_CTL_POWER_D3cold:
- return dapm->suspend_bias_off;
- default:
- break;
+ if ((state == SNDRV_CTL_POWER_D3hot || (state == SNDRV_CTL_POWER_D3cold)) &&
+ component)
+ return !component->driver->suspend_bias_off;
}
- return false;
+ return dapm->idle_bias;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_get_idle_bias);
+
+void snd_soc_dapm_set_idle_bias(struct snd_soc_dapm_context *dapm, bool on)
+{
+ dapm->idle_bias = on;
}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_set_idle_bias);
/*
* Scan each dapm widget for complete audio path.
@@ -2158,10 +2226,10 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event,
trace_snd_soc_dapm_start(card, event);
for_each_card_dapms(card, d) {
- if (dapm_idle_bias_off(d))
- d->target_bias_level = SND_SOC_BIAS_OFF;
- else
+ if (snd_soc_dapm_get_idle_bias(d))
d->target_bias_level = SND_SOC_BIAS_STANDBY;
+ else
+ d->target_bias_level = SND_SOC_BIAS_OFF;
}
dapm_reset(card);
@@ -2225,7 +2293,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event,
if (d->target_bias_level > bias)
bias = d->target_bias_level;
for_each_card_dapms(card, d)
- if (!dapm_idle_bias_off(d))
+ if (snd_soc_dapm_get_idle_bias(d))
d->target_bias_level = bias;
trace_snd_soc_dapm_walk_done(card);
@@ -4759,8 +4827,7 @@ void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
if (component) {
dapm->dev = component->dev;
- dapm->idle_bias_off = !component->driver->idle_bias_on;
- dapm->suspend_bias_off = component->driver->suspend_bias_off;
+ dapm->idle_bias = component->driver->idle_bias_on;
} else {
dapm->dev = card->dev;
}
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index a629e0eacb20..d2b6fb8e0b6c 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -118,6 +118,7 @@ static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_v
if (mc->sign_bit)
val = sign_extend32(val, mc->sign_bit);
+ val = clamp(val, mc->min, mc->max);
val -= mc->min;
if (mc->invert)
diff --git a/sound/soc/sof/amd/acp-probes.c b/sound/soc/sof/amd/acp-probes.c
index 0d0f8ec4aed8..ce51ed108a47 100644
--- a/sound/soc/sof/amd/acp-probes.c
+++ b/sound/soc/sof/amd/acp-probes.c
@@ -108,7 +108,7 @@ static int acp_probes_compr_trigger(struct sof_client_dev *cdev,
static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
+ struct snd_compr_tstamp64 *tstamp,
struct snd_soc_dai *dai)
{
struct acp_dsp_stream *stream = cstream->runtime->private_data;
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c
index d7b044f33d79..90b932ae3bab 100644
--- a/sound/soc/sof/compress.c
+++ b/sound/soc/sof/compress.c
@@ -361,7 +361,7 @@ static int sof_compr_copy(struct snd_soc_component *component,
static int sof_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_sof_pcm *spcm;
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c
index d66c198b861a..e787d3932fbb 100644
--- a/sound/soc/sof/imx/imx-common.c
+++ b/sound/soc/sof/imx/imx-common.c
@@ -354,8 +354,8 @@ static int imx_probe(struct snd_sof_dev *sdev)
common = devm_kzalloc(sdev->dev, sizeof(*common), GFP_KERNEL);
if (!common)
- return dev_err_probe(sdev->dev, -ENOMEM,
- "failed to allocate common data\n");
+ return -ENOMEM;
+
sdev->pdata->hw_pdata = common;
common->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp",
@@ -382,7 +382,7 @@ static int imx_probe(struct snd_sof_dev *sdev)
imx_unregister_action,
sdev);
if (ret)
- return dev_err_probe(sdev->dev, ret, "failed to add devm action\n");
+ return ret;
common->ipc_handle = dev_get_drvdata(&common->ipc_dev->dev);
if (!common->ipc_handle)
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index b73dd91bd529..7e9eab2e3034 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -171,8 +171,7 @@ static int imx8m_probe(struct snd_sof_dev *sdev)
chip = devm_kzalloc(sdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
- return dev_err_probe(sdev->dev, -ENOMEM,
- "failed to allocate chip data\n");
+ return -ENOMEM;
chip->dap = devm_ioremap(sdev->dev, IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
if (!chip->dap)
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index 2f9925830d1d..37674ea452d6 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -260,9 +260,6 @@ void hda_codec_detect_mask(struct snd_sof_dev *sdev)
sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
return;
- /* Accept unsolicited responses */
- snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
-
/* detect codecs */
if (!bus->codec_mask) {
bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c
index 4f34fd919a00..8332d4bda558 100644
--- a/sound/soc/sof/intel/hda-ctrl.c
+++ b/sound/soc/sof/intel/hda-ctrl.c
@@ -183,7 +183,7 @@ int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable)
}
EXPORT_SYMBOL_NS(hda_dsp_ctrl_clock_power_gating, "SND_SOC_SOF_INTEL_HDA_COMMON");
-int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev)
+int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool detect_codec)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *stream;
@@ -220,7 +220,11 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev)
}
usleep_range(1000, 1200);
- hda_codec_detect_mask(sdev);
+ /* Accept unsolicited responses */
+ snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
+
+ if (detect_codec)
+ hda_codec_detect_mask(sdev);
/* clear stream status */
list_for_each_entry(stream, &bus->stream_list, list) {
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index f64e8a6a9a33..3ab6d5ce6329 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -870,7 +870,7 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
/* reset and start hda controller */
- ret = hda_dsp_ctrl_init_chip(sdev);
+ ret = hda_dsp_ctrl_init_chip(sdev, false);
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to start controller after resume\n");
diff --git a/sound/soc/sof/intel/hda-probes.c b/sound/soc/sof/intel/hda-probes.c
index c645346c2c84..b06933cebc45 100644
--- a/sound/soc/sof/intel/hda-probes.c
+++ b/sound/soc/sof/intel/hda-probes.c
@@ -112,7 +112,7 @@ static int hda_probes_compr_trigger(struct sof_client_dev *cdev,
static int hda_probes_compr_pointer(struct sof_client_dev *cdev,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
+ struct snd_compr_tstamp64 *tstamp,
struct snd_soc_dai *dai)
{
struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
diff --git a/sound/soc/sof/intel/hda-sdw-bpt.c b/sound/soc/sof/intel/hda-sdw-bpt.c
index 1327f1cad0bc..ff5abccf0d88 100644
--- a/sound/soc/sof/intel/hda-sdw-bpt.c
+++ b/sound/soc/sof/intel/hda-sdw-bpt.c
@@ -150,7 +150,7 @@ static int hda_sdw_bpt_dma_deprepare(struct device *dev, struct hdac_ext_stream
u32 mask;
int ret;
- ret = hda_cl_cleanup(sdev->dev, dmab_bdl, true, sdw_bpt_stream);
+ ret = hda_cl_cleanup(sdev->dev, dmab_bdl, false, sdw_bpt_stream);
if (ret < 0) {
dev_err(sdev->dev, "%s: SDW BPT DMA cleanup failed\n",
__func__);
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index c387efec41e9..52e86fa60077 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -616,7 +616,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n");
/* Init HDA controller after i915 init */
- ret = hda_dsp_ctrl_init_chip(sdev);
+ ret = hda_dsp_ctrl_init_chip(sdev, true);
if (ret < 0) {
dev_err(bus->dev, "error: init chip failed with ret: %d\n",
ret);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index e14f82c0831f..28daf0a3b984 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -757,7 +757,7 @@ void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable);
int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset);
void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable);
int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable);
-int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev);
+int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool detect_codec);
void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev);
/*
* HDA bus operations.
diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c
index e5c8fec173c4..6ec391fd39a9 100644
--- a/sound/soc/sof/ipc3-dtrace.c
+++ b/sound/soc/sof/ipc3-dtrace.c
@@ -126,7 +126,7 @@ static int trace_filter_parse(struct snd_sof_dev *sdev, char *string,
capacity += TRACE_FILTER_ELEMENTS_PER_ENTRY;
entry = strchr(entry + 1, entry_delimiter[0]);
}
- *out = kmalloc(capacity * sizeof(**out), GFP_KERNEL);
+ *out = kmalloc_array(capacity, sizeof(**out), GFP_KERNEL);
if (!*out)
return -ENOMEM;
diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
index 374dc10d10fd..24f82a6f3610 100644
--- a/sound/soc/sof/ipc4-pcm.c
+++ b/sound/soc/sof/ipc4-pcm.c
@@ -639,14 +639,14 @@ static int ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev,
if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
params_width(params) == le32_to_cpu(hw_config->tdm_slot_width) &&
- params_channels(params) == le32_to_cpu(hw_config->tdm_slots)) {
+ params_channels(params) <= le32_to_cpu(hw_config->tdm_slots)) {
current_config = le32_to_cpu(hw_config->id);
partial_match = false;
/* best match found */
break;
} else if (current_config < 0 &&
params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
- params_channels(params) == le32_to_cpu(hw_config->tdm_slots)) {
+ params_channels(params) <= le32_to_cpu(hw_config->tdm_slots)) {
current_config = le32_to_cpu(hw_config->id);
partial_match = true;
/* keep looking for better match */
@@ -727,6 +727,58 @@ static int sof_ipc4_pcm_dai_link_fixup_rate(struct snd_sof_dev *sdev,
return 0;
}
+static int sof_ipc4_pcm_dai_link_fixup_channels(struct snd_sof_dev *sdev,
+ struct snd_pcm_hw_params *params,
+ struct sof_ipc4_copier *ipc4_copier)
+{
+ struct sof_ipc4_pin_format *pin_fmts = ipc4_copier->available_fmt.input_pin_fmts;
+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ int num_input_formats = ipc4_copier->available_fmt.num_input_formats;
+ unsigned int fe_channels = params_channels(params);
+ bool fe_be_match = false;
+ bool single_be_channels = true;
+ unsigned int be_channels, val;
+ int i;
+
+ if (WARN_ON_ONCE(!num_input_formats))
+ return -EINVAL;
+
+ /*
+ * Copier does not change channels, so we
+ * need to only consider the input pin information.
+ */
+ be_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(pin_fmts[0].audio_fmt.fmt_cfg);
+ for (i = 0; i < num_input_formats; i++) {
+ val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(pin_fmts[i].audio_fmt.fmt_cfg);
+
+ if (val != be_channels)
+ single_be_channels = false;
+
+ if (val == fe_channels) {
+ fe_be_match = true;
+ break;
+ }
+ }
+
+ /*
+ * If channels is different than FE channels, topology must contain a
+ * module which can change the number of channels. But we do require
+ * topology to define a single channels in the DAI copier config in
+ * this case (FE channels may be variable).
+ */
+ if (!fe_be_match) {
+ if (!single_be_channels) {
+ dev_err(sdev->dev, "Unable to select channels for DAI link\n");
+ return -EINVAL;
+ }
+
+ channels->min = be_channels;
+ channels->max = be_channels;
+ }
+
+ return 0;
+}
+
static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -790,6 +842,10 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
if (ret)
return ret;
+ ret = sof_ipc4_pcm_dai_link_fixup_channels(sdev, params, ipc4_copier);
+ if (ret)
+ return ret;
+
if (single_bitdepth) {
snd_mask_none(fmt);
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(ipc4_fmt->fmt_cfg);
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 591ee30551ba..b6a732d0adb4 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -38,6 +38,36 @@ MODULE_PARM_DESC(ipc4_ignore_cpc,
static DEFINE_IDA(alh_group_ida);
static DEFINE_IDA(pipeline_ida);
+struct sof_comp_domains {
+ const char *name;
+ enum sof_comp_domain domain;
+};
+
+static const struct sof_comp_domains sof_domains[] = {
+ { "LL", SOF_COMP_DOMAIN_LL, },
+ { "DP", SOF_COMP_DOMAIN_DP, }
+};
+
+static enum sof_comp_domain find_domain(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sof_domains); i++) {
+ if (strcmp(name, sof_domains[i].name) == 0)
+ return sof_domains[i].domain;
+ }
+ /* No valid value found, fall back to manifest value */
+ return SOF_COMP_DOMAIN_UNSET;
+}
+
+static int get_token_comp_domain(void *elem, void *object, u32 offset)
+{
+ u32 *val = (u32 *)((u8 *)object + offset);
+
+ *val = find_domain((const char *)elem);
+ return 0;
+}
+
static const struct sof_topology_token ipc4_sched_tokens[] = {
{SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_pipeline, lp_mode)},
@@ -127,6 +157,8 @@ static const struct sof_topology_token comp_ext_tokens[] = {
offsetof(struct snd_sof_widget, uuid)},
{SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct snd_sof_widget, core)},
+ {SOF_TKN_COMP_SCHED_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_domain,
+ offsetof(struct snd_sof_widget, comp_domain)},
};
static const struct sof_topology_token gain_tokens[] = {
@@ -497,7 +529,17 @@ static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_
msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core);
- type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0;
+ switch (swidget->comp_domain) {
+ case SOF_COMP_DOMAIN_LL:
+ type = 0;
+ break;
+ case SOF_COMP_DOMAIN_DP:
+ type = 1;
+ break;
+ default:
+ type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0;
+ break;
+ }
msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type);
return 0;
@@ -1292,6 +1334,23 @@ static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev,
return 0;
}
+static u32 sof_ipc4_fmt_cfg_to_type(u32 fmt_cfg)
+{
+ /* Fetch the sample type from the fmt for 8 and 32 bit formats */
+ u32 __bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt_cfg);
+
+ if (__bits == 8 || __bits == 32)
+ return SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE(fmt_cfg);
+
+ /*
+ * Return LSB integer type for 20 and 24 formats as the firmware is
+ * handling the LSB/MSB alignment internally, for the kernel this
+ * should not be taken into account, we treat them as LSB to match with
+ * the format we support on the PCM side.
+ */
+ return SOF_IPC4_TYPE_LSB_INTEGER;
+}
+
/* update hw_params based on the audio stream format */
static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params,
struct sof_ipc4_audio_format *fmt, u32 param_to_update)
@@ -1300,10 +1359,27 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) {
int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
+ int type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
snd_pcm_format_t snd_fmt;
struct snd_mask *m;
switch (valid_bits) {
+ case 8:
+ switch (type) {
+ case SOF_IPC4_TYPE_A_LAW:
+ snd_fmt = SNDRV_PCM_FORMAT_A_LAW;
+ break;
+ case SOF_IPC4_TYPE_MU_LAW:
+ snd_fmt = SNDRV_PCM_FORMAT_MU_LAW;
+ break;
+ case SOF_IPC4_TYPE_UNSIGNED_INTEGER:
+ snd_fmt = SNDRV_PCM_FORMAT_U8;
+ break;
+ default:
+ dev_err(sdev->dev, "Unsupported PCM 8-bit IPC4 type %d\n", type);
+ return -EINVAL;
+ }
+ break;
case 16:
snd_fmt = SNDRV_PCM_FORMAT_S16_LE;
break;
@@ -1311,7 +1387,17 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
snd_fmt = SNDRV_PCM_FORMAT_S24_LE;
break;
case 32:
- snd_fmt = SNDRV_PCM_FORMAT_S32_LE;
+ switch (type) {
+ case SOF_IPC4_TYPE_LSB_INTEGER:
+ snd_fmt = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case SOF_IPC4_TYPE_FLOAT:
+ snd_fmt = SNDRV_PCM_FORMAT_FLOAT_LE;
+ break;
+ default:
+ dev_err(sdev->dev, "Unsupported PCM 32-bit IPC4 type %d\n", type);
+ return -EINVAL;
+ }
break;
default:
dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits);
@@ -1375,7 +1461,7 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
struct sof_ipc4_base_module_cfg *base_config,
struct sof_ipc4_available_audio_format *available_fmt,
u32 out_ref_rate, u32 out_ref_channels,
- u32 out_ref_valid_bits)
+ u32 out_ref_valid_bits, u32 out_ref_type)
{
struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts;
u32 pin_fmts_size = available_fmt->num_output_formats;
@@ -1401,19 +1487,22 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
for (i = 0; i < pin_fmts_size; i++) {
struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt;
- u32 _out_rate, _out_channels, _out_valid_bits;
+ u32 _out_rate, _out_channels, _out_valid_bits, _out_type;
_out_rate = fmt->sampling_frequency;
_out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
_out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
+ _out_type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
if (_out_rate == out_ref_rate && _out_channels == out_ref_channels &&
- _out_valid_bits == out_ref_valid_bits)
+ _out_valid_bits == out_ref_valid_bits && _out_type == out_ref_type)
goto out_fmt;
}
- dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n",
- __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels);
+ dev_err(sdev->dev,
+ "%s: Unsupported audio format: %uHz, %ubit, %u channels, type: %d\n",
+ __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels,
+ out_ref_type);
return -EINVAL;
@@ -1426,18 +1515,46 @@ out_fmt:
static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
{
switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_MU_LAW:
+ case SNDRV_PCM_FORMAT_A_LAW:
+ return 8;
case SNDRV_PCM_FORMAT_S16_LE:
return 16;
case SNDRV_PCM_FORMAT_S24_LE:
return 24;
case SNDRV_PCM_FORMAT_S32_LE:
return 32;
+ case SNDRV_PCM_FORMAT_FLOAT_LE:
+ return 32;
default:
dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params));
return -EINVAL;
}
}
+static int sof_ipc4_get_sample_type(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
+{
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_A_LAW:
+ return SOF_IPC4_TYPE_A_LAW;
+ case SNDRV_PCM_FORMAT_MU_LAW:
+ return SOF_IPC4_TYPE_MU_LAW;
+ case SNDRV_PCM_FORMAT_U8:
+ return SOF_IPC4_TYPE_UNSIGNED_INTEGER;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+ return SOF_IPC4_TYPE_LSB_INTEGER;
+ case SNDRV_PCM_FORMAT_FLOAT_LE:
+ return SOF_IPC4_TYPE_FLOAT;
+ default:
+ dev_err(sdev->dev, "invalid pcm sample type %d\n", params_format(params));
+ return -EINVAL;
+ }
+}
+
static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget,
struct sof_ipc4_base_module_cfg *base_config,
@@ -1449,8 +1566,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
u32 valid_bits;
u32 channels;
u32 rate;
+ u32 type;
bool single_format;
int sample_valid_bits;
+ int sample_type;
int i = 0;
if (!pin_fmts_size) {
@@ -1466,6 +1585,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
if (sample_valid_bits < 0)
return sample_valid_bits;
+ sample_type = sof_ipc4_get_sample_type(sdev, params);
+ if (sample_type < 0)
+ return sample_type;
+
/*
* Search supported input audio formats with pin index 0 to match rate, channels and
* sample_valid_bits from reference params
@@ -1479,14 +1602,17 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
rate = fmt->sampling_frequency;
channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
+ type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
if (params_rate(params) == rate && params_channels(params) == channels &&
- sample_valid_bits == valid_bits)
+ sample_valid_bits == valid_bits && sample_type == type)
break;
}
if (i == pin_fmts_size) {
- dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n",
- __func__, params_rate(params), sample_valid_bits, params_channels(params));
+ dev_err(sdev->dev,
+ "%s: Unsupported audio format: %uHz, %ubit, %u channels, type: %d\n",
+ __func__, params_rate(params), sample_valid_bits,
+ params_channels(params), sample_type);
return -EINVAL;
}
@@ -1882,7 +2008,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
int *ipc_config_size;
u32 **data;
int ipc_size, ret, out_ref_valid_bits;
- u32 out_ref_rate, out_ref_channels;
+ u32 out_ref_rate, out_ref_channels, out_ref_type;
u32 deep_buffer_dma_ms = 0;
bool single_output_bitdepth;
int i;
@@ -1923,10 +2049,13 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
host_dma_id = platform_params->stream_tag - 1;
pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id);
- /* Set SCS bit for S16_LE format only */
if (params_format(fe_params) == SNDRV_PCM_FORMAT_S16_LE)
pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK;
+ /* Set SCS bit for 8 and 16 bit formats */
+ if (params_physical_width(fe_params) <= 16)
+ pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK;
+
/*
* Despite its name the bitfield 'fifo_size' is used to define DMA buffer
* size. The expression calculates 2ms buffer size.
@@ -2051,6 +2180,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
out_ref_rate = in_fmt->sampling_frequency;
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
if (!single_output_bitdepth)
out_ref_valid_bits =
@@ -2061,6 +2191,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
case snd_soc_dapm_dai_in:
out_ref_rate = params_rate(fe_params);
out_ref_channels = params_channels(fe_params);
+ ret = sof_ipc4_get_sample_type(sdev, fe_params);
+ if (ret < 0)
+ return ret;
+ out_ref_type = (u32)ret;
+
if (!single_output_bitdepth) {
out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
if (out_ref_valid_bits < 0)
@@ -2085,12 +2220,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt;
out_ref_valid_bits =
SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(out_fmt->fmt_cfg);
}
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
&copier_data->base_config,
available_fmt, out_ref_rate,
- out_ref_channels, out_ref_valid_bits);
+ out_ref_channels, out_ref_valid_bits,
+ out_ref_type);
if (output_fmt_index < 0)
return output_fmt_index;
@@ -2319,7 +2456,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
struct sof_ipc4_gain *gain = swidget->private;
struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt;
struct sof_ipc4_audio_format *in_fmt;
- u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
+ u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
int input_fmt_index, output_fmt_index;
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
@@ -2333,13 +2470,15 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
out_ref_rate = in_fmt->sampling_frequency;
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
&gain->data.base_config,
available_fmt,
out_ref_rate,
out_ref_channels,
- out_ref_valid_bits);
+ out_ref_valid_bits,
+ out_ref_type);
if (output_fmt_index < 0)
return output_fmt_index;
@@ -2362,7 +2501,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
struct sof_ipc4_mixer *mixer = swidget->private;
struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt;
struct sof_ipc4_audio_format *in_fmt;
- u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
+ u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
int input_fmt_index, output_fmt_index;
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
@@ -2376,13 +2515,15 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
out_ref_rate = in_fmt->sampling_frequency;
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
&mixer->base_config,
available_fmt,
out_ref_rate,
out_ref_channels,
- out_ref_valid_bits);
+ out_ref_valid_bits,
+ out_ref_type);
if (output_fmt_index < 0)
return output_fmt_index;
@@ -2406,7 +2547,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt;
struct sof_ipc4_audio_format *out_audio_fmt;
struct sof_ipc4_audio_format *in_audio_fmt;
- u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
+ u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
int output_fmt_index, input_fmt_index;
input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
@@ -2433,6 +2574,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg);
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(in_audio_fmt->fmt_cfg);
/*
* For capture, the SRC module should convert the rate to match the rate requested by the
@@ -2446,7 +2588,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
available_fmt,
out_ref_rate,
out_ref_channels,
- out_ref_valid_bits);
+ out_ref_valid_bits,
+ out_ref_type);
if (output_fmt_index < 0)
return output_fmt_index;
@@ -2570,20 +2713,22 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
struct sof_ipc4_audio_format *in_fmt;
struct sof_ipc4_pin_format *pin_fmt;
u32 out_ref_rate, out_ref_channels;
- int out_ref_valid_bits;
+ int out_ref_valid_bits, out_ref_type;
in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
out_ref_rate = in_fmt->sampling_frequency;
out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
+ out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
&process->base_config,
available_fmt,
out_ref_rate,
out_ref_channels,
- out_ref_valid_bits);
+ out_ref_valid_bits,
+ out_ref_type);
if (output_fmt_index < 0)
return output_fmt_index;
diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h
index 14ba58d2be03..dfa1a6c2ffa8 100644
--- a/sound/soc/sof/ipc4-topology.h
+++ b/sound/soc/sof/ipc4-topology.h
@@ -41,6 +41,15 @@
#define SOF_IPC4_FW_MAX_PAGE_COUNT 20
#define SOF_IPC4_FW_MAX_QUEUE_COUNT 8
+/* IPC4 sample types */
+#define SOF_IPC4_TYPE_MSB_INTEGER 0
+#define SOF_IPC4_TYPE_LSB_INTEGER 1
+#define SOF_IPC4_TYPE_SIGNED_INTEGER 2
+#define SOF_IPC4_TYPE_UNSIGNED_INTEGER 3
+#define SOF_IPC4_TYPE_FLOAT 4
+#define SOF_IPC4_TYPE_A_LAW 5
+#define SOF_IPC4_TYPE_MU_LAW 6
+
/* Node index and mask applicable for host copier and ALH/HDA type DAI copiers */
#define SOF_IPC4_NODE_INDEX_MASK 0xFF
#define SOF_IPC4_NODE_INDEX(x) ((x) & SOF_IPC4_NODE_INDEX_MASK)
@@ -109,6 +118,13 @@ enum sof_ipc4_copier_module_config_params {
SOF_IPC4_COPIER_MODULE_CFG_ATTENUATION,
};
+/* Scheduling domain, unset, Low Latency, or Data Processing */
+enum sof_comp_domain {
+ SOF_COMP_DOMAIN_UNSET = 0, /* Take domain value from manifest */
+ SOF_COMP_DOMAIN_LL, /* Low Latency scheduling domain */
+ SOF_COMP_DOMAIN_DP, /* Data Processing scheduling domain */
+};
+
struct sof_ipc4_copier_config_set_sink_format {
/* Id of sink */
u32 sink_id;
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 36ab75e11779..db6973c8eac3 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -451,6 +451,9 @@ struct snd_sof_widget {
*/
bool dynamic_pipeline_widget;
+ /* Scheduling domain (enum sof_comp_domain), unset, Low Latency, or Data Processing */
+ u32 comp_domain;
+
struct snd_soc_dapm_widget *widget;
struct list_head list; /* list in sdev widget list */
struct snd_sof_pipeline *spipe;
diff --git a/sound/soc/sof/sof-client-probes-ipc3.c b/sound/soc/sof/sof-client-probes-ipc3.c
index 816df745c9af..a78ec0954a61 100644
--- a/sound/soc/sof/sof-client-probes-ipc3.c
+++ b/sound/soc/sof/sof-client-probes-ipc3.c
@@ -100,9 +100,11 @@ static int ipc3_probes_deinit(struct sof_client_dev *cdev)
}
static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
- void **params, size_t *num_params)
+ void **params, size_t *num_params,
+ enum sof_probe_info_type type)
{
size_t max_msg_size = sof_client_get_ipc_max_payload_size(cdev);
+ struct device *dev = &cdev->auxdev.dev;
struct sof_ipc_probe_info_params msg = {{{0}}};
struct sof_ipc_probe_info_params *reply;
size_t bytes;
@@ -111,6 +113,11 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
*params = NULL;
*num_params = 0;
+ if (type != PROBES_INFO_ACTIVE_PROBES) {
+ dev_err(dev, "%s: info type %u not supported", __func__, type);
+ return -EOPNOTSUPP;
+ }
+
reply = kzalloc(max_msg_size, GFP_KERNEL);
if (!reply)
return -ENOMEM;
@@ -142,21 +149,25 @@ exit:
}
/**
- * ipc3_probes_points_info - retrieve list of active probe points
+ * ipc3_probes_points_info - retrieve list of probe points
* @cdev: SOF client device
* @desc: Returned list of active probes
* @num_desc: Returned count of active probes
+ * @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES
+ *
+ * If type is PROBES_INFO_ACTIVE_PROBES, host sends PROBE_POINT_INFO
+ * request to obtain list of active probe points, valid for
+ * disconnection when given probe is no longer required.
*
- * Host sends PROBE_POINT_INFO request to obtain list of active probe
- * points, valid for disconnection when given probe is no longer
- * required.
+ * Type PROBES_INFO_AVAILABE_PROBES is not yet supported.
*/
static int ipc3_probes_points_info(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
- size_t *num_desc)
+ size_t *num_desc,
+ enum sof_probe_info_type type)
{
return ipc3_probes_info(cdev, SOF_IPC_PROBE_POINT_INFO,
- (void **)desc, num_desc);
+ (void **)desc, num_desc, type);
}
/**
diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c
index 603aed222480..758a56d271d7 100644
--- a/sound/soc/sof/sof-client-probes-ipc4.c
+++ b/sound/soc/sof/sof-client-probes-ipc4.c
@@ -8,7 +8,7 @@
#include <sound/soc.h>
#include <sound/sof/ipc4/header.h>
#include <uapi/sound/sof/header.h>
-#include "sof-priv.h"
+#include "sof-audio.h"
#include "ipc4-priv.h"
#include "sof-client.h"
#include "sof-client-probes.h"
@@ -28,6 +28,7 @@ enum sof_ipc4_probe_runtime_param {
SOF_IPC4_PROBE_INJECTION_DMA_DETACH,
SOF_IPC4_PROBE_POINTS,
SOF_IPC4_PROBE_POINTS_DISCONNECT,
+ SOF_IPC4_PROBE_POINTS_AVAILABLE,
};
struct sof_ipc4_probe_gtw_cfg {
@@ -49,14 +50,42 @@ enum sof_ipc4_probe_type {
SOF_IPC4_PROBE_TYPE_INTERNAL
};
+#define SOF_IPC4_PROBE_TYPE_SHIFT 24
+#define SOF_IPC4_PROBE_TYPE_MASK GENMASK(25, 24)
+#define SOF_IPC4_PROBE_TYPE_GET(x) (((x) & SOF_IPC4_PROBE_TYPE_MASK) \
+ >> SOF_IPC4_PROBE_TYPE_SHIFT)
+#define SOF_IPC4_PROBE_IDX_SHIFT 26
+#define SOF_IPC4_PROBE_IDX_MASK GENMASK(31, 26)
+#define SOF_IPC4_PROBE_IDX_GET(x) (((x) & SOF_IPC4_PROBE_IDX_MASK) \
+ >> SOF_IPC4_PROBE_IDX_SHIFT)
+
struct sof_ipc4_probe_point {
u32 point_id;
u32 purpose;
u32 stream_tag;
} __packed __aligned(4);
+struct sof_ipc4_probe_info {
+ unsigned int num_elems;
+ DECLARE_FLEX_ARRAY(struct sof_ipc4_probe_point, points);
+} __packed;
+
#define INVALID_PIPELINE_ID 0xFF
+static const char *sof_probe_ipc4_type_string(u32 type)
+{
+ switch (type) {
+ case SOF_IPC4_PROBE_TYPE_INPUT:
+ return "input";
+ case SOF_IPC4_PROBE_TYPE_OUTPUT:
+ return "output";
+ case SOF_IPC4_PROBE_TYPE_INTERNAL:
+ return "internal";
+ default:
+ return "UNKNOWN";
+ }
+}
+
/**
* sof_ipc4_probe_get_module_info - Get IPC4 module info for probe module
* @cdev: SOF client device
@@ -164,25 +193,113 @@ static int ipc4_probes_deinit(struct sof_client_dev *cdev)
}
/**
- * ipc4_probes_points_info - retrieve list of active probe points
+ * ipc4_probes_points_info - retrieve list of probe points
* @cdev: SOF client device
* @desc: Returned list of active probes
* @num_desc: Returned count of active probes
+ * @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES
* @return: 0 on success, negative error code on error
*
- * Dummy implementation returning empty list of probes.
+ * Returns list if active probe points if type is
+ * PROBES_INFO_ACTIVE_PROBES, or list of all available probe points if
+ * type is PROBES_INFO_AVAILABE_PROBES.
*/
static int ipc4_probes_points_info(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
- size_t *num_desc)
+ size_t *num_desc,
+ enum sof_probe_info_type type)
{
- /* TODO: Firmware side implementation needed first */
- *desc = NULL;
- *num_desc = 0;
+ struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev);
+ struct device *dev = &cdev->auxdev.dev;
+ struct sof_ipc4_probe_info *info;
+ struct sof_ipc4_msg msg;
+ u32 param_id;
+ int i, ret;
+
+ if (!mentry)
+ return -ENODEV;
+
+ switch (type) {
+ case PROBES_INFO_ACTIVE_PROBES:
+ param_id = SOF_IPC4_PROBE_POINTS;
+ break;
+ case PROBES_INFO_AVAILABE_PROBES:
+ param_id = SOF_IPC4_PROBE_POINTS_AVAILABLE;
+ break;
+ default:
+ dev_err(dev, "%s: info type %u not supported", __func__, type);
+ return -EOPNOTSUPP;
+ }
+
+ msg.primary = mentry->id;
+ msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
+ msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
+
+ msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(param_id);
+
+ msg.data_size = sof_client_get_ipc_max_payload_size(cdev);
+ msg.data_ptr = kzalloc(msg.data_size, GFP_KERNEL);
+ if (!msg.data_ptr)
+ return -ENOMEM;
+
+ ret = sof_client_ipc_set_get_data(cdev, &msg, false);
+ if (ret) {
+ kfree(msg.data_ptr);
+ return ret;
+ }
+ info = msg.data_ptr;
+ *num_desc = info->num_elems;
+ dev_dbg(dev, "%s: got %zu probe points", __func__, *num_desc);
+
+ *desc = kzalloc(*num_desc * sizeof(**desc), GFP_KERNEL);
+ if (!*desc) {
+ kfree(msg.data_ptr);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < *num_desc; i++) {
+ (*desc)[i].buffer_id = info->points[i].point_id;
+ (*desc)[i].purpose = info->points[i].purpose;
+ (*desc)[i].stream_tag = info->points[i].stream_tag;
+ }
+ kfree(msg.data_ptr);
+
return 0;
}
/**
+ * ipc4_probes_point_print - Human readable print of probe point descriptor
+ * @cdev: SOF client device
+ * @buf: Buffer to print to
+ * @size: Available bytes in buffer
+ * @desc: Describes the probe point to print
+ * @return: Number of bytes printed or an error code (snprintf return value)
+ */
+static int ipc4_probes_point_print(struct sof_client_dev *cdev, char *buf, size_t size,
+ struct sof_probe_point_desc *desc)
+{
+ struct device *dev = &cdev->auxdev.dev;
+ struct snd_sof_widget *swidget;
+ int ret;
+
+ swidget = sof_client_ipc4_find_swidget_by_id(cdev, SOF_IPC4_MOD_ID_GET(desc->buffer_id),
+ SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id));
+ if (!swidget)
+ dev_err(dev, "%s: Failed to find widget for module %lu.%lu\n",
+ __func__, SOF_IPC4_MOD_ID_GET(desc->buffer_id),
+ SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id));
+
+ ret = snprintf(buf, size, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n",
+ desc->buffer_id, desc->purpose, desc->stream_tag,
+ swidget ? swidget->widget->name : "<unknown>",
+ sof_probe_ipc4_type_string(SOF_IPC4_PROBE_TYPE_GET(desc->buffer_id)),
+ SOF_IPC4_PROBE_IDX_GET(desc->buffer_id),
+ desc->stream_tag ? "(connected)" : "");
+
+ return ret;
+}
+
+/**
* ipc4_probes_points_add - connect specified probes
* @cdev: SOF client device
* @desc: List of probe points to connect
@@ -202,7 +319,7 @@ static int ipc4_probes_points_add(struct sof_client_dev *cdev,
int i, ret;
if (!mentry)
- return -ENODEV;
+ return -EOPNOTSUPP;
/* The sof_probe_point_desc and sof_ipc4_probe_point structs
* are of same size and even the integers are the same in the
@@ -286,6 +403,7 @@ const struct sof_probes_ipc_ops ipc4_probe_ops = {
.init = ipc4_probes_init,
.deinit = ipc4_probes_deinit,
.points_info = ipc4_probes_points_info,
+ .point_print = ipc4_probes_point_print,
.points_add = ipc4_probes_points_add,
.points_remove = ipc4_probes_points_remove,
};
diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c
index 663c0d3c314c..5dbc0aacb8e3 100644
--- a/sound/soc/sof/sof-client-probes.c
+++ b/sound/soc/sof/sof-client-probes.c
@@ -17,8 +17,14 @@
#include <sound/soc.h>
#include <sound/sof/header.h>
+#include <sound/sof/ipc4/header.h>
#include "sof-client.h"
#include "sof-client-probes.h"
+#include "sof-audio.h"
+
+#ifdef CONFIG_SND_SOC_SOF_IPC4
+#include "ipc4-priv.h"
+#endif
#define SOF_PROBES_SUSPEND_DELAY_MS 3000
/* only extraction supported for now */
@@ -69,7 +75,8 @@ static int sof_probes_compr_shutdown(struct snd_compr_stream *cstream,
int i, ret;
/* disconnect all probe points */
- ret = ipc->points_info(cdev, &desc, &num_desc);
+ ret = ipc->points_info(cdev, &desc, &num_desc,
+ PROBES_INFO_ACTIVE_PROBES);
if (ret < 0) {
dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
goto exit;
@@ -137,7 +144,7 @@ static int sof_probes_compr_trigger(struct snd_compr_stream *cstream, int cmd,
}
static int sof_probes_compr_pointer(struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
+ struct snd_compr_tstamp64 *tstamp,
struct snd_soc_dai *dai)
{
struct snd_soc_card *card = snd_soc_component_get_drvdata(dai->component);
@@ -189,7 +196,8 @@ static const struct snd_compress_ops sof_probes_compressed_ops = {
};
static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos,
+ enum sof_probe_info_type type)
{
struct sof_client_dev *cdev = file->private_data;
struct sof_probes_priv *priv = cdev->data;
@@ -216,16 +224,20 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
goto exit;
}
- ret = ipc->points_info(cdev, &desc, &num_desc);
+ ret = ipc->points_info(cdev, &desc, &num_desc, type);
if (ret < 0)
goto pm_error;
for (i = 0; i < num_desc; i++) {
offset = strlen(buf);
remaining = PAGE_SIZE - offset;
- ret = snprintf(buf + offset, remaining,
- "Id: %#010x Purpose: %u Node id: %#x\n",
- desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag);
+ if (ipc->point_print)
+ ret = ipc->point_print(cdev, buf + offset, remaining, &desc[i]);
+ else
+ ret = snprintf(buf + offset, remaining,
+ "Id: %#010x Purpose: %u Node id: %#x\n",
+ desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag);
+
if (ret < 0 || ret >= remaining) {
/* truncate the output buffer at the last full line */
buf[offset] = '\0';
@@ -247,6 +259,22 @@ exit:
return ret;
}
+static ssize_t sof_probes_dfs_active_points_read(struct file *file,
+ char __user *to,
+ size_t count, loff_t *ppos)
+{
+ return sof_probes_dfs_points_read(file, to, count, ppos,
+ PROBES_INFO_ACTIVE_PROBES);
+}
+
+static ssize_t sof_probes_dfs_available_points_read(struct file *file,
+ char __user *to,
+ size_t count, loff_t *ppos)
+{
+ return sof_probes_dfs_points_read(file, to, count, ppos,
+ PROBES_INFO_AVAILABE_PROBES);
+}
+
static ssize_t
sof_probes_dfs_points_write(struct file *file, const char __user *from,
size_t count, loff_t *ppos)
@@ -296,15 +324,23 @@ exit:
return ret;
}
-static const struct file_operations sof_probes_points_fops = {
+static const struct file_operations sof_probes_active_points_fops = {
.open = simple_open,
- .read = sof_probes_dfs_points_read,
+ .read = sof_probes_dfs_active_points_read,
.write = sof_probes_dfs_points_write,
.llseek = default_llseek,
.owner = THIS_MODULE,
};
+static const struct file_operations sof_probes_available_points_fops = {
+ .open = simple_open,
+ .read = sof_probes_dfs_available_points_read,
+ .llseek = default_llseek,
+
+ .owner = THIS_MODULE,
+};
+
static ssize_t
sof_probes_dfs_points_remove_write(struct file *file, const char __user *from,
size_t count, loff_t *ppos)
@@ -449,13 +485,17 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev,
/* create read-write probes_points debugfs entry */
priv->dfs_points = debugfs_create_file("probe_points", 0644, dfsroot,
- cdev, &sof_probes_points_fops);
+ cdev, &sof_probes_active_points_fops);
/* create read-write probe_points_remove debugfs entry */
priv->dfs_points_remove = debugfs_create_file("probe_points_remove", 0644,
dfsroot, cdev,
&sof_probes_points_remove_fops);
+ /* create read-write probes_points debugfs entry */
+ priv->dfs_points = debugfs_create_file("probe_points_available", 0644, dfsroot,
+ cdev, &sof_probes_available_points_fops);
+
links = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*links), GFP_KERNEL);
cpus = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*cpus), GFP_KERNEL);
if (!links || !cpus) {
@@ -485,7 +525,7 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev,
card->dai_link = links;
/* set idle_bias_off to prevent the core from resuming the card->dev */
- card->dapm.idle_bias_off = true;
+ card->dapm.idle_bias = false;
snd_soc_card_set_drvdata(card, cdev);
diff --git a/sound/soc/sof/sof-client-probes.h b/sound/soc/sof/sof-client-probes.h
index da04d65b8d99..47d0582b8eb8 100644
--- a/sound/soc/sof/sof-client-probes.h
+++ b/sound/soc/sof/sof-client-probes.h
@@ -4,7 +4,7 @@
#define __SOF_CLIENT_PROBES_H
struct snd_compr_stream;
-struct snd_compr_tstamp;
+struct snd_compr_tstamp64;
struct snd_compr_params;
struct sof_client_dev;
struct snd_soc_dai;
@@ -24,7 +24,7 @@ struct sof_probes_host_ops {
int (*trigger)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
int cmd, struct snd_soc_dai *dai);
int (*pointer)(struct sof_client_dev *cdev, struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
+ struct snd_compr_tstamp64 *tstamp,
struct snd_soc_dai *dai);
};
@@ -34,13 +34,20 @@ struct sof_probe_point_desc {
unsigned int stream_tag;
} __packed;
+enum sof_probe_info_type {
+ PROBES_INFO_ACTIVE_PROBES,
+ PROBES_INFO_AVAILABE_PROBES,
+};
+
struct sof_probes_ipc_ops {
int (*init)(struct sof_client_dev *cdev, u32 stream_tag,
size_t buffer_size);
int (*deinit)(struct sof_client_dev *cdev);
int (*points_info)(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
- size_t *num_desc);
+ size_t *num_desc, enum sof_probe_info_type type);
+ int (*point_print)(struct sof_client_dev *cdev, char *buf, size_t size,
+ struct sof_probe_point_desc *desc);
int (*points_add)(struct sof_client_dev *cdev,
struct sof_probe_point_desc *desc,
size_t num_desc);
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c
index 4c7951338c66..2dbfc7699c73 100644
--- a/sound/soc/sof/sof-client.c
+++ b/sound/soc/sof/sof-client.c
@@ -45,13 +45,30 @@ struct sof_state_event_entry {
struct list_head list;
};
+/**
+ * struct sof_client_dev_entry - client device entry for internal management use
+ * @sdev: pointer to SOF core device struct
+ * @list: item in SOF core client dev list
+ * @client_dev: SOF client device
+ */
+struct sof_client_dev_entry {
+ struct snd_sof_dev *sdev;
+ struct list_head list;
+
+ struct sof_client_dev client_dev;
+};
+
+#define cdev_to_centry(cdev) \
+ container_of(cdev, struct sof_client_dev_entry, client_dev)
+
static void sof_client_auxdev_release(struct device *dev)
{
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev);
+ struct sof_client_dev_entry *centry = cdev_to_centry(cdev);
kfree(cdev->auxdev.dev.platform_data);
- kfree(cdev);
+ kfree(centry);
}
static int sof_client_dev_add_data(struct sof_client_dev *cdev, const void *data,
@@ -208,15 +225,18 @@ void sof_unregister_clients(struct snd_sof_dev *sdev)
int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
const void *data, size_t size)
{
+ struct sof_client_dev_entry *centry;
struct auxiliary_device *auxdev;
struct sof_client_dev *cdev;
int ret;
- cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
- if (!cdev)
+ centry = kzalloc(sizeof(*centry), GFP_KERNEL);
+ if (!centry)
return -ENOMEM;
- cdev->sdev = sdev;
+ cdev = &centry->client_dev;
+
+ centry->sdev = sdev;
auxdev = &cdev->auxdev;
auxdev->name = name;
auxdev->dev.parent = sdev->dev;
@@ -246,7 +266,7 @@ int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
/* add to list of SOF client devices */
mutex_lock(&sdev->ipc_client_mutex);
- list_add(&cdev->list, &sdev->ipc_client_list);
+ list_add(&centry->list, &sdev->ipc_client_list);
mutex_unlock(&sdev->ipc_client_mutex);
return 0;
@@ -255,7 +275,7 @@ err_dev_init:
kfree(cdev->auxdev.dev.platform_data);
err_dev_add_data:
- kfree(cdev);
+ kfree(centry);
return ret;
}
@@ -263,7 +283,7 @@ EXPORT_SYMBOL_NS_GPL(sof_client_dev_register, "SND_SOC_SOF_CLIENT");
void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id)
{
- struct sof_client_dev *cdev;
+ struct sof_client_dev_entry *centry;
mutex_lock(&sdev->ipc_client_mutex);
@@ -271,9 +291,11 @@ void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 i
* sof_client_auxdev_release() will be invoked to free up memory
* allocations through put_device()
*/
- list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
+ list_for_each_entry(centry, &sdev->ipc_client_list, list) {
+ struct sof_client_dev *cdev = &centry->client_dev;
+
if (!strcmp(cdev->auxdev.name, name) && cdev->auxdev.id == id) {
- list_del(&cdev->list);
+ list_del(&centry->list);
auxiliary_device_delete(&cdev->auxdev);
auxiliary_device_uninit(&cdev->auxdev);
break;
@@ -287,15 +309,17 @@ EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, "SND_SOC_SOF_CLIENT");
int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg,
void *reply_data, size_t reply_bytes)
{
- if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
- return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, hdr->size,
+ return sof_ipc_tx_message(sdev->ipc, ipc_msg, hdr->size,
reply_data, reply_bytes);
- } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
+ } else if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *msg = ipc_msg;
- return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, msg->data_size,
+ return sof_ipc_tx_message(sdev->ipc, ipc_msg, msg->data_size,
reply_data, reply_bytes);
}
@@ -305,16 +329,18 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, "SND_SOC_SOF_CLIENT");
int sof_client_ipc_rx_message(struct sof_client_dev *cdev, void *ipc_msg, void *msg_buf)
{
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
if (IS_ENABLED(CONFIG_SND_SOC_SOF_IPC3) &&
- cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
+ sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
if (hdr->size < sizeof(hdr)) {
- dev_err(cdev->sdev->dev, "The received message size is invalid\n");
+ dev_err(sdev->dev, "The received message size is invalid\n");
return -EINVAL;
}
- sof_ipc3_do_rx_work(cdev->sdev, ipc_msg, msg_buf);
+ sof_ipc3_do_rx_work(sdev, ipc_msg, msg_buf);
return 0;
}
@@ -325,16 +351,17 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc_rx_message, "SND_SOC_SOF_CLIENT");
int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg,
bool set)
{
- if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
- return sof_ipc_set_get_data(cdev->sdev->ipc, ipc_msg, hdr->size,
- set);
- } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
+ return sof_ipc_set_get_data(sdev->ipc, ipc_msg, hdr->size, set);
+ } else if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *msg = ipc_msg;
- return sof_ipc_set_get_data(cdev->sdev->ipc, ipc_msg,
- msg->data_size, set);
+ return sof_ipc_set_get_data(sdev->ipc, ipc_msg, msg->data_size,
+ set);
}
return -EINVAL;
@@ -344,7 +371,7 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc_set_get_data, "SND_SOC_SOF_CLIENT");
#ifdef CONFIG_SND_SOC_SOF_IPC4
struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, const guid_t *uuid)
{
- struct snd_sof_dev *sdev = c->sdev;
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(c);
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4)
return sof_ipc4_find_module_by_uuid(sdev, uuid);
@@ -353,16 +380,31 @@ struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c,
return NULL;
}
EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_module, "SND_SOC_SOF_CLIENT");
+
+struct snd_sof_widget *sof_client_ipc4_find_swidget_by_id(struct sof_client_dev *cdev,
+ u32 module_id, int instance_id)
+{
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4)
+ return sof_ipc4_find_swidget_by_ids(sdev, module_id, instance_id);
+ dev_err(sdev->dev, "Only supported with IPC4\n");
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_swidget_by_id, "SND_SOC_SOF_CLIENT");
#endif
int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
{
const struct auxiliary_driver *adrv;
- struct sof_client_dev *cdev;
+ struct sof_client_dev_entry *centry;
mutex_lock(&sdev->ipc_client_mutex);
- list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
+ list_for_each_entry(centry, &sdev->ipc_client_list, list) {
+ struct sof_client_dev *cdev = &centry->client_dev;
+
/* Skip devices without loaded driver */
if (!cdev->auxdev.dev.driver)
continue;
@@ -381,11 +423,13 @@ EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, "SND_SOC_SOF_CLIENT");
int sof_resume_clients(struct snd_sof_dev *sdev)
{
const struct auxiliary_driver *adrv;
- struct sof_client_dev *cdev;
+ struct sof_client_dev_entry *centry;
mutex_lock(&sdev->ipc_client_mutex);
- list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
+ list_for_each_entry(centry, &sdev->ipc_client_list, list) {
+ struct sof_client_dev *cdev = &centry->client_dev;
+
/* Skip devices without loaded driver */
if (!cdev->auxdev.dev.driver)
continue;
@@ -403,14 +447,18 @@ EXPORT_SYMBOL_NS_GPL(sof_resume_clients, "SND_SOC_SOF_CLIENT");
struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev)
{
- return cdev->sdev->debugfs_root;
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ return sdev->debugfs_root;
}
EXPORT_SYMBOL_NS_GPL(sof_client_get_debugfs_root, "SND_SOC_SOF_CLIENT");
/* DMA buffer allocation in client drivers must use the core SOF device */
struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev)
{
- return cdev->sdev->dev;
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+
+ return sdev->dev;
}
EXPORT_SYMBOL_NS_GPL(sof_client_get_dma_dev, "SND_SOC_SOF_CLIENT");
@@ -498,10 +546,10 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev,
if (!callback)
return -EINVAL;
- if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
if (!(ipc_msg_type & SOF_GLB_TYPE_MASK))
return -EINVAL;
- } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
+ } else if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
if (!(ipc_msg_type & SOF_IPC4_NOTIFICATION_TYPE_MASK))
return -EINVAL;
} else {
@@ -611,3 +659,11 @@ enum sof_fw_state sof_client_get_fw_state(struct sof_client_dev *cdev)
return sdev->fw_state;
}
EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_state, "SND_SOC_SOF_CLIENT");
+
+struct snd_sof_dev *sof_client_dev_to_sof_dev(struct sof_client_dev *cdev)
+{
+ struct sof_client_dev_entry *centry = cdev_to_centry(cdev);
+
+ return centry->sdev;
+}
+EXPORT_SYMBOL_NS_GPL(sof_client_dev_to_sof_dev, "SND_SOC_SOF_CLIENT");
diff --git a/sound/soc/sof/sof-client.h b/sound/soc/sof/sof-client.h
index b6ccc2cd69e5..1a9015e38474 100644
--- a/sound/soc/sof/sof-client.h
+++ b/sound/soc/sof/sof-client.h
@@ -18,19 +18,13 @@ struct sof_ipc4_fw_module;
/**
* struct sof_client_dev - SOF client device
* @auxdev: auxiliary device
- * @sdev: pointer to SOF core device struct
- * @list: item in SOF core client dev list
* @data: device specific data
*/
struct sof_client_dev {
struct auxiliary_device auxdev;
- struct snd_sof_dev *sdev;
- struct list_head list;
void *data;
};
-#define sof_client_dev_to_sof_dev(cdev) ((cdev)->sdev)
-
#define auxiliary_dev_to_sof_client_dev(auxiliary_dev) \
container_of(auxiliary_dev, struct sof_client_dev, auxdev)
@@ -47,6 +41,8 @@ int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg,
bool set);
struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, const guid_t *u);
+struct snd_sof_widget *sof_client_ipc4_find_swidget_by_id(struct sof_client_dev *cdev,
+ u32 module_id, int instance_id);
struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev);
struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index abbb5ee7e08c..0f624d8cde20 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -838,7 +838,11 @@ int sof_stream_pcm_close(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream);
/* SOF client support */
+struct sof_client_dev;
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT)
+struct snd_sof_dev *sof_client_dev_to_sof_dev(struct sof_client_dev *cdev);
+
int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
const void *data, size_t size);
void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id);
@@ -849,6 +853,11 @@ void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
int sof_resume_clients(struct snd_sof_dev *sdev);
#else /* CONFIG_SND_SOC_SOF_CLIENT */
+static inline struct snd_sof_dev *
+sof_client_dev_to_sof_dev(struct sof_client_dev *cdev) {
+ return NULL;
+}
+
static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
u32 id, const void *data, size_t size)
{
diff --git a/sound/soc/sprd/sprd-pcm-compress.c b/sound/soc/sprd/sprd-pcm-compress.c
index 57bd1a0728ac..4b6ebfa5b033 100644
--- a/sound/soc/sprd/sprd-pcm-compress.c
+++ b/sound/soc/sprd/sprd-pcm-compress.c
@@ -85,9 +85,9 @@ struct sprd_compr_stream {
int info_size;
/* Data size copied to IRAM buffer */
- int copied_total;
+ u64 copied_total;
/* Total received data size from userspace */
- int received_total;
+ u64 received_total;
/* Stage 0 IRAM buffer received data size */
int received_stage0;
/* Stage 1 DDR buffer received data size */
@@ -513,7 +513,7 @@ static int sprd_platform_compr_trigger(struct snd_soc_component *component,
static int sprd_platform_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_compr_runtime *runtime = cstream->runtime;
struct sprd_compr_stream *stream = runtime->private_data;
diff --git a/sound/soc/sprd/sprd-pcm-dma.h b/sound/soc/sprd/sprd-pcm-dma.h
index be5e385f5e42..c5935a1367e6 100644
--- a/sound/soc/sprd/sprd-pcm-dma.h
+++ b/sound/soc/sprd/sprd-pcm-dma.h
@@ -19,7 +19,7 @@ struct sprd_compr_playinfo {
int total_time;
int current_time;
int total_data_length;
- int current_data_offset;
+ u64 current_data_offset;
};
struct sprd_compr_params {
@@ -46,7 +46,7 @@ struct sprd_compr_ops {
int (*stop)(int str_id);
int (*pause)(int str_id);
int (*pause_release)(int str_id);
- int (*drain)(int received_total);
+ int (*drain)(u64 received_total);
int (*set_params)(int str_id, struct sprd_compr_params *params);
};
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 463a2b7d023b..0ae1eae2a59e 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -672,6 +672,14 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
+ /*
+ * The mclk rate is determined at runtime from the audio stream rate.
+ * Skip calls to the set_sysclk callback that are not relevant during the
+ * initialization phase.
+ */
+ if (!snd_soc_card_is_instantiated(cpu_dai->component->card))
+ return 0;
+
if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
SAI_XCR1_NODIV,
diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-compress.c
index 4a19d4908ffd..b18af98a552b 100644
--- a/sound/soc/uniphier/aio-compress.c
+++ b/sound/soc/uniphier/aio-compress.c
@@ -249,7 +249,7 @@ static int uniphier_aio_compr_trigger(struct snd_soc_component *component,
static int uniphier_aio_compr_pointer(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_compr_runtime *runtime = cstream->runtime;
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index e73d3b262f57..da04ed5cbac4 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -346,34 +346,25 @@ static struct snd_amd7930 *amd7930_list;
/* Idle the AMD7930 chip. The amd->lock is not held. */
static __inline__ void amd7930_idle(struct snd_amd7930 *amd)
{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
sbus_writeb(0, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
}
/* Enable chip interrupts. The amd->lock is not held. */
static __inline__ void amd7930_enable_ints(struct snd_amd7930 *amd)
{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
sbus_writeb(AM_INIT_ACTIVE, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
}
/* Disable chip interrupts. The amd->lock is not held. */
static __inline__ void amd7930_disable_ints(struct snd_amd7930 *amd)
{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
sbus_writeb(AM_INIT_ACTIVE | AM_INIT_DISABLE_INTS, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
}
/* Commit amd7930_map settings to the hardware.
@@ -497,34 +488,33 @@ static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id)
unsigned int elapsed;
u8 ir;
- spin_lock(&amd->lock);
-
- elapsed = 0;
-
- ir = sbus_readb(amd->regs + AMD7930_IR);
- if (ir & AMR_IR_BBUF) {
- u8 byte;
-
- if (amd->flags & AMD7930_FLAG_PLAYBACK) {
- if (amd->p_left > 0) {
- byte = *(amd->p_cur++);
- amd->p_left--;
- sbus_writeb(byte, amd->regs + AMD7930_BBTB);
- if (amd->p_left == 0)
- elapsed |= AMD7930_FLAG_PLAYBACK;
- } else
- sbus_writeb(0, amd->regs + AMD7930_BBTB);
- } else if (amd->flags & AMD7930_FLAG_CAPTURE) {
- byte = sbus_readb(amd->regs + AMD7930_BBRB);
- if (amd->c_left > 0) {
- *(amd->c_cur++) = byte;
- amd->c_left--;
- if (amd->c_left == 0)
- elapsed |= AMD7930_FLAG_CAPTURE;
+ scoped_guard(spinlock, &amd->lock) {
+ elapsed = 0;
+
+ ir = sbus_readb(amd->regs + AMD7930_IR);
+ if (ir & AMR_IR_BBUF) {
+ u8 byte;
+
+ if (amd->flags & AMD7930_FLAG_PLAYBACK) {
+ if (amd->p_left > 0) {
+ byte = *(amd->p_cur++);
+ amd->p_left--;
+ sbus_writeb(byte, amd->regs + AMD7930_BBTB);
+ if (amd->p_left == 0)
+ elapsed |= AMD7930_FLAG_PLAYBACK;
+ } else
+ sbus_writeb(0, amd->regs + AMD7930_BBTB);
+ } else if (amd->flags & AMD7930_FLAG_CAPTURE) {
+ byte = sbus_readb(amd->regs + AMD7930_BBRB);
+ if (amd->c_left > 0) {
+ *(amd->c_cur++) = byte;
+ amd->c_left--;
+ if (amd->c_left == 0)
+ elapsed |= AMD7930_FLAG_CAPTURE;
+ }
}
}
}
- spin_unlock(&amd->lock);
if (elapsed & AMD7930_FLAG_PLAYBACK)
snd_pcm_period_elapsed(amd->playback_substream);
@@ -536,10 +526,9 @@ static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id)
static int snd_amd7930_trigger(struct snd_amd7930 *amd, unsigned int flag, int cmd)
{
- unsigned long flags;
int result = 0;
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
if (cmd == SNDRV_PCM_TRIGGER_START) {
if (!(amd->flags & flag)) {
amd->flags |= flag;
@@ -559,7 +548,6 @@ static int snd_amd7930_trigger(struct snd_amd7930 *amd, unsigned int flag, int c
} else {
result = -EINVAL;
}
- spin_unlock_irqrestore(&amd->lock, flags);
return result;
}
@@ -583,10 +571,9 @@ static int snd_amd7930_playback_prepare(struct snd_pcm_substream *substream)
struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned long flags;
u8 new_mmr1;
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
amd->flags |= AMD7930_FLAG_PLAYBACK;
@@ -605,8 +592,6 @@ static int snd_amd7930_playback_prepare(struct snd_pcm_substream *substream)
__amd7930_update_map(amd);
}
- spin_unlock_irqrestore(&amd->lock, flags);
-
return 0;
}
@@ -615,10 +600,9 @@ static int snd_amd7930_capture_prepare(struct snd_pcm_substream *substream)
struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned long flags;
u8 new_mmr1;
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
amd->flags |= AMD7930_FLAG_CAPTURE;
@@ -637,8 +621,6 @@ static int snd_amd7930_capture_prepare(struct snd_pcm_substream *substream)
__amd7930_update_map(amd);
}
- spin_unlock_irqrestore(&amd->lock, flags);
-
return 0;
}
@@ -805,7 +787,6 @@ static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{
struct snd_amd7930 *amd = snd_kcontrol_chip(kctl);
- unsigned long flags;
int type = kctl->private_value;
int *swval, change;
@@ -822,7 +803,7 @@ static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
break;
}
- spin_lock_irqsave(&amd->lock, flags);
+ guard(spinlock_irqsave)(&amd->lock);
if (*swval != ucontrol->value.integer.value[0]) {
*swval = ucontrol->value.integer.value[0] & 0xff;
@@ -831,8 +812,6 @@ static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
} else
change = 0;
- spin_unlock_irqrestore(&amd->lock, flags);
-
return change;
}
@@ -921,7 +900,6 @@ static int snd_amd7930_create(struct snd_card *card,
struct snd_amd7930 **ramd)
{
struct snd_amd7930 *amd;
- unsigned long flags;
int err;
*ramd = NULL;
@@ -955,25 +933,23 @@ static int snd_amd7930_create(struct snd_card *card,
amd7930_enable_ints(amd);
- spin_lock_irqsave(&amd->lock, flags);
-
- amd->rgain = 128;
- amd->pgain = 200;
- amd->mgain = 0;
-
- memset(&amd->map, 0, sizeof(amd->map));
- amd->map.mmr1 = (AM_MAP_MMR1_GX | AM_MAP_MMR1_GER |
- AM_MAP_MMR1_GR | AM_MAP_MMR1_STG);
- amd->map.mmr2 = (AM_MAP_MMR2_LS | AM_MAP_MMR2_AINB);
+ scoped_guard(spinlock_irqsave, &amd->lock) {
+ amd->rgain = 128;
+ amd->pgain = 200;
+ amd->mgain = 0;
- __amd7930_update_map(amd);
+ memset(&amd->map, 0, sizeof(amd->map));
+ amd->map.mmr1 = (AM_MAP_MMR1_GX | AM_MAP_MMR1_GER |
+ AM_MAP_MMR1_GR | AM_MAP_MMR1_STG);
+ amd->map.mmr2 = (AM_MAP_MMR2_LS | AM_MAP_MMR2_AINB);
- /* Always MUX audio (Ba) to channel Bb. */
- sbus_writeb(AMR_MUX_MCR1, amd->regs + AMD7930_CR);
- sbus_writeb(AM_MUX_CHANNEL_Ba | (AM_MUX_CHANNEL_Bb << 4),
- amd->regs + AMD7930_DR);
+ __amd7930_update_map(amd);
- spin_unlock_irqrestore(&amd->lock, flags);
+ /* Always MUX audio (Ba) to channel Bb. */
+ sbus_writeb(AMR_MUX_MCR1, amd->regs + AMD7930_CR);
+ sbus_writeb(AM_MUX_CHANNEL_Ba | (AM_MUX_CHANNEL_Bb << 4),
+ amd->regs + AMD7930_DR);
+ }
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
amd, &snd_amd7930_dev_ops);
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 1a1fe3ceb76c..d9e5cca94c73 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -357,10 +357,9 @@ static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
{
- unsigned long flags;
int timeout;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_cs4231_ready(chip);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
@@ -376,7 +375,6 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
if (!(timeout & CS4231_MCE))
__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
CS4231U(chip, REGSEL));
- spin_unlock_irqrestore(&chip->lock, flags);
}
static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
@@ -486,7 +484,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
{
unsigned int what = 0;
struct snd_pcm_substream *s;
- unsigned long flags;
snd_pcm_group_for_each_entry(s, substream) {
if (s == chip->playback_substream) {
@@ -498,7 +495,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
}
}
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
if (cmd == SNDRV_PCM_TRIGGER_START) {
cs4231_dma_trigger(substream, what, 1);
chip->image[CS4231_IFACE_CTRL] |= what;
@@ -508,7 +505,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
}
snd_cs4231_out(chip, CS4231_IFACE_CTRL,
chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->lock, flags);
break;
}
default:
@@ -564,14 +560,11 @@ static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format,
static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
{
- unsigned long flags;
-
mute = mute ? 1 : 0;
- spin_lock_irqsave(&chip->lock, flags);
- if (chip->calibrate_mute == mute) {
- spin_unlock_irqrestore(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
+ if (chip->calibrate_mute == mute)
return;
- }
+
if (!mute) {
snd_cs4231_dout(chip, CS4231_LEFT_INPUT,
chip->image[CS4231_LEFT_INPUT]);
@@ -599,31 +592,27 @@ static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
snd_cs4231_dout(chip, CS4231_MONO_CTRL,
mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
chip->calibrate_mute = mute;
- spin_unlock_irqrestore(&chip->lock, flags);
}
static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
struct snd_pcm_hw_params *params,
unsigned char pdfr)
{
- unsigned long flags;
-
- mutex_lock(&chip->mce_mutex);
+ guard(mutex)(&chip->mce_mutex);
snd_cs4231_calibrate_mute(chip, 1);
snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
- (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ?
- (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) :
- pdfr);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
+ (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ?
+ (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) :
+ pdfr);
+ }
snd_cs4231_mce_down(chip);
snd_cs4231_calibrate_mute(chip, 0);
- mutex_unlock(&chip->mce_mutex);
}
static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
@@ -632,7 +621,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
{
unsigned long flags;
- mutex_lock(&chip->mce_mutex);
+ guard(mutex)(&chip->mce_mutex);
snd_cs4231_calibrate_mute(chip, 1);
snd_cs4231_mce_up(chip);
@@ -653,7 +642,6 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
snd_cs4231_mce_down(chip);
snd_cs4231_calibrate_mute(chip, 0);
- mutex_unlock(&chip->mce_mutex);
}
/*
@@ -669,11 +657,10 @@ static unsigned long snd_cs4231_timer_resolution(struct snd_timer *timer)
static int snd_cs4231_timer_start(struct snd_timer *timer)
{
- unsigned long flags;
unsigned int ticks;
struct snd_cs4231 *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
ticks = timer->sticks;
if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
(unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
@@ -688,44 +675,39 @@ static int snd_cs4231_timer_start(struct snd_timer *timer)
chip->image[CS4231_ALT_FEATURE_1] |
CS4231_TIMER_ENABLE);
}
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static int snd_cs4231_timer_stop(struct snd_timer *timer)
{
- unsigned long flags;
struct snd_cs4231 *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static void snd_cs4231_init(struct snd_cs4231 *chip)
{
- unsigned long flags;
-
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
pr_debug("init: (1)\n");
#endif
snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
- CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE |
- CS4231_RECORD_PIO |
- CS4231_CALIB_MODE);
- chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
- snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
+ CS4231_PLAYBACK_PIO |
+ CS4231_RECORD_ENABLE |
+ CS4231_RECORD_PIO |
+ CS4231_CALIB_MODE);
+ chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
+ snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
+ }
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -733,10 +715,10 @@ static void snd_cs4231_init(struct snd_cs4231 *chip)
#endif
snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
+ chip->image[CS4231_ALT_FEATURE_1]);
+ }
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -744,16 +726,16 @@ static void snd_cs4231_init(struct snd_cs4231 *chip)
chip->image[CS4231_ALT_FEATURE_1]);
#endif
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_2,
- chip->image[CS4231_ALT_FEATURE_2]);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ snd_cs4231_out(chip, CS4231_ALT_FEATURE_2,
+ chip->image[CS4231_ALT_FEATURE_2]);
+ }
snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
+ chip->image[CS4231_PLAYBK_FORMAT]);
+ }
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -761,9 +743,9 @@ static void snd_cs4231_init(struct snd_cs4231 *chip)
#endif
snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
+ }
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -773,20 +755,15 @@ static void snd_cs4231_init(struct snd_cs4231 *chip)
static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- if ((chip->mode & mode)) {
- mutex_unlock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
+ if ((chip->mode & mode))
return -EAGAIN;
- }
if (chip->mode & CS4231_MODE_OPEN) {
chip->mode |= mode;
- mutex_unlock(&chip->open_mutex);
return 0;
}
/* ok. now enable and ack CODEC IRQ */
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
CS4231_RECORD_IRQ |
CS4231_TIMER_IRQ);
@@ -799,10 +776,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
CS4231_TIMER_IRQ);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- spin_unlock_irqrestore(&chip->lock, flags);
-
chip->mode = mode;
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -810,12 +784,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
{
unsigned long flags;
- mutex_lock(&chip->open_mutex);
+ guard(mutex)(&chip->open_mutex);
chip->mode &= ~mode;
- if (chip->mode & CS4231_MODE_OPEN) {
- mutex_unlock(&chip->open_mutex);
+ if (chip->mode & CS4231_MODE_OPEN)
return;
- }
snd_cs4231_calibrate_mute(chip, 1);
/* disable IRQ */
@@ -851,7 +823,6 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
snd_cs4231_calibrate_mute(chip, 0);
chip->mode = 0;
- mutex_unlock(&chip->open_mutex);
}
/*
@@ -905,25 +876,18 @@ static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- int ret = 0;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
CS4231_PLAYBACK_PIO);
- if (WARN_ON(runtime->period_size > 0xffff + 1)) {
- ret = -EINVAL;
- goto out;
- }
+ if (WARN_ON(runtime->period_size > 0xffff + 1))
+ return -EINVAL;
chip->p_periods_sent = 0;
-out:
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return ret;
+ return 0;
}
static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
@@ -943,27 +907,23 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
CS4231_RECORD_PIO);
chip->c_periods_sent = 0;
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static void snd_cs4231_overrange(struct snd_cs4231 *chip)
{
- unsigned long flags;
unsigned char res;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
res = snd_cs4231_in(chip, CS4231_TEST_INIT);
- spin_unlock_irqrestore(&chip->lock, flags);
/* detect overrange only above 0dB; may be user selectable? */
if (res & (0x08 | 0x02))
@@ -1022,7 +982,6 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(
static int snd_cs4231_probe(struct snd_cs4231 *chip)
{
- unsigned long flags;
int i;
int id = 0;
int vers = 0;
@@ -1033,11 +992,10 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip)
if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
msleep(2);
else {
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f;
vers = snd_cs4231_in(chip, CS4231_VERSION);
- spin_unlock_irqrestore(&chip->lock, flags);
if (id == 0x0a)
break; /* this is valid value */
}
@@ -1047,14 +1005,12 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip)
if (id != 0x0a)
return -ENODEV; /* no valid device found */
- spin_lock_irqsave(&chip->lock, flags);
-
- /* clear any pendings IRQ */
- __cs4231_readb(chip, CS4231U(chip, STATUS));
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS));
- mb();
-
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ /* clear any pendings IRQ */
+ __cs4231_readb(chip, CS4231U(chip, STATUS));
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS));
+ mb();
+ }
chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
chip->image[CS4231_IFACE_CTRL] =
@@ -1068,12 +1024,10 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip)
snd_cs4231_mce_down(chip);
- spin_lock_irqsave(&chip->lock, flags);
-
- for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */
- snd_cs4231_out(chip, i, *ptr++);
-
- spin_unlock_irqrestore(&chip->lock, flags);
+ scoped_guard(spinlock_irqsave, &chip->lock) {
+ for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */
+ snd_cs4231_out(chip, i, *ptr++);
+ }
snd_cs4231_mce_up(chip);
@@ -1282,14 +1236,12 @@ static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
ucontrol->value.enumerated.item[0] =
(chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
ucontrol->value.enumerated.item[1] =
(chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
- spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -1298,7 +1250,6 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned short left, right;
int change;
@@ -1308,7 +1259,7 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
left = ucontrol->value.enumerated.item[0] << 6;
right = ucontrol->value.enumerated.item[1] << 6;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
@@ -1317,8 +1268,6 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
snd_cs4231_out(chip, CS4231_LEFT_INPUT, left);
snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right);
- spin_unlock_irqrestore(&chip->lock, flags);
-
return change;
}
@@ -1340,18 +1289,15 @@ static int snd_cs4231_get_single(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
-
if (invert)
ucontrol->value.integer.value[0] =
(mask - ucontrol->value.integer.value[0]);
@@ -1363,7 +1309,6 @@ static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1376,14 +1321,12 @@ static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol,
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
val = (chip->image[reg] & ~(mask << shift)) | val;
change = val != chip->image[reg];
snd_cs4231_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->lock, flags);
-
return change;
}
@@ -1405,7 +1348,6 @@ static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1413,15 +1355,13 @@ static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol,
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
ucontrol->value.integer.value[0] =
(chip->image[left_reg] >> shift_left) & mask;
ucontrol->value.integer.value[1] =
(chip->image[right_reg] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
-
if (invert) {
ucontrol->value.integer.value[0] =
(mask - ucontrol->value.integer.value[0]);
@@ -1436,7 +1376,6 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1455,7 +1394,7 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
@@ -1464,8 +1403,6 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
snd_cs4231_out(chip, left_reg, val1);
snd_cs4231_out(chip, right_reg, val2);
- spin_unlock_irqrestore(&chip->lock, flags);
-
return change;
}
@@ -1610,7 +1547,6 @@ out_err:
static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
{
- unsigned long flags;
unsigned char status;
u32 csr;
struct snd_cs4231 *chip = dev_id;
@@ -1647,9 +1583,8 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
snd_cs4231_overrange(chip);
/* ACK the CS4231 interrupt. */
- spin_lock_irqsave(&chip->lock, flags);
+ guard(spinlock_irqsave)(&chip->lock);
snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
- spin_unlock_irqrestore(&chip->lock, flags);
return IRQ_HANDLED;
}
@@ -1661,42 +1596,34 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
static int sbus_dma_request(struct cs4231_dma_control *dma_cont,
dma_addr_t bus_addr, size_t len)
{
- unsigned long flags;
u32 test, csr;
- int err;
struct sbus_dma_info *base = &dma_cont->sbus_info;
if (len >= (1 << 24))
return -EINVAL;
- spin_lock_irqsave(&base->lock, flags);
+ guard(spinlock_irqsave)(&base->lock);
csr = sbus_readl(base->regs + APCCSR);
- err = -EINVAL;
test = APC_CDMA_READY;
if (base->dir == APC_PLAY)
test = APC_PDMA_READY;
if (!(csr & test))
- goto out;
- err = -EBUSY;
+ return -EINVAL;
test = APC_XINT_CNVA;
if (base->dir == APC_PLAY)
test = APC_XINT_PNVA;
if (!(csr & test))
- goto out;
- err = 0;
+ return -EBUSY;
sbus_writel(bus_addr, base->regs + base->dir + APCNVA);
sbus_writel(len, base->regs + base->dir + APCNC);
-out:
- spin_unlock_irqrestore(&base->lock, flags);
- return err;
+ return 0;
}
static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
{
- unsigned long flags;
u32 csr, test;
struct sbus_dma_info *base = &dma_cont->sbus_info;
- spin_lock_irqsave(&base->lock, flags);
+ guard(spinlock_irqsave)(&base->lock);
csr = sbus_readl(base->regs + APCCSR);
test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
@@ -1706,16 +1633,14 @@ static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
csr |= test;
sbus_writel(csr, base->regs + APCCSR);
- spin_unlock_irqrestore(&base->lock, flags);
}
static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
{
- unsigned long flags;
u32 csr, shift;
struct sbus_dma_info *base = &dma_cont->sbus_info;
- spin_lock_irqsave(&base->lock, flags);
+ guard(spinlock_irqsave)(&base->lock);
if (!on) {
sbus_writel(0, base->regs + base->dir + APCNC);
sbus_writel(0, base->regs + base->dir + APCNVA);
@@ -1740,8 +1665,6 @@ static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
else
csr &= ~(APC_CDMA_READY << shift);
sbus_writel(csr, base->regs + APCCSR);
-
- spin_unlock_irqrestore(&base->lock, flags);
}
static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 93cbe158009f..75f82a92ff44 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -758,40 +758,38 @@ static void dbri_initialize(struct snd_dbri *dbri)
u32 dvma_addr = (u32)dbri->dma_dvma;
s32 *cmd;
u32 dma_addr;
- unsigned long flags;
int n;
- spin_lock_irqsave(&dbri->lock, flags);
-
- dbri_reset(dbri);
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ dbri_reset(dbri);
- /* Initialize pipes */
- for (n = 0; n < DBRI_NO_PIPES; n++)
- dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
+ /* Initialize pipes */
+ for (n = 0; n < DBRI_NO_PIPES; n++)
+ dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
- spin_lock_init(&dbri->cmdlock);
- /*
- * Initialize the interrupt ring buffer.
- */
- dma_addr = dvma_addr + dbri_dma_off(intr, 0);
- dbri->dma->intr[0] = dma_addr;
- dbri->dbri_irqp = 1;
- /*
- * Set up the interrupt queue
- */
- spin_lock(&dbri->cmdlock);
- cmd = dbri->cmdptr = dbri->dma->cmd;
- *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
- *(cmd++) = dma_addr;
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- dbri->cmdptr = cmd;
- *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
- *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
- dma_addr = dvma_addr + dbri_dma_off(cmd, 0);
- sbus_writel(dma_addr, dbri->regs + REG8);
- spin_unlock(&dbri->cmdlock);
+ spin_lock_init(&dbri->cmdlock);
+ /*
+ * Initialize the interrupt ring buffer.
+ */
+ dma_addr = dvma_addr + dbri_dma_off(intr, 0);
+ dbri->dma->intr[0] = dma_addr;
+ dbri->dbri_irqp = 1;
+ /*
+ * Set up the interrupt queue
+ */
+ scoped_guard(spinlock, &dbri->cmdlock) {
+ cmd = dbri->cmdptr = dbri->dma->cmd;
+ *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
+ *(cmd++) = dma_addr;
+ *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
+ dbri->cmdptr = cmd;
+ *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
+ *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
+ dma_addr = dvma_addr + dbri_dma_off(cmd, 0);
+ sbus_writel(dma_addr, dbri->regs + REG8);
+ }
+ }
- spin_unlock_irqrestore(&dbri->lock, flags);
dbri_cmdwait(dbri);
}
@@ -1002,7 +1000,6 @@ static void unlink_time_slot(struct snd_dbri *dbri, int pipe,
static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
{
s32 *cmd;
- unsigned long flags;
if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
@@ -1037,9 +1034,10 @@ static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
*(cmd++) = data;
*(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- spin_lock_irqsave(&dbri->lock, flags);
- dbri_cmdsend(dbri, cmd, 3);
- spin_unlock_irqrestore(&dbri->lock, flags);
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ dbri_cmdsend(dbri, cmd, 3);
+ }
+
dbri_cmdwait(dbri);
}
@@ -1317,33 +1315,31 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins.
*/
static void cs4215_setup_pipes(struct snd_dbri *dbri)
{
- unsigned long flags;
-
- spin_lock_irqsave(&dbri->lock, flags);
- /*
- * Data mode:
- * Pipe 4: Send timeslots 1-4 (audio data)
- * Pipe 20: Send timeslots 5-8 (part of ctrl data)
- * Pipe 6: Receive timeslots 1-4 (audio data)
- * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
- * interrupt, and the rest of the data (slot 5 and 8) is
- * not relevant for us (only for doublechecking).
- *
- * Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
- * Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
- */
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ /*
+ * Data mode:
+ * Pipe 4: Send timeslots 1-4 (audio data)
+ * Pipe 20: Send timeslots 5-8 (part of ctrl data)
+ * Pipe 6: Receive timeslots 1-4 (audio data)
+ * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
+ * interrupt, and the rest of the data (slot 5 and 8) is
+ * not relevant for us (only for doublechecking).
+ *
+ * Control mode:
+ * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
+ * Pipe 18: Receive timeslot 1 (clb).
+ * Pipe 19: Receive timeslot 7 (version).
+ */
- setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
- setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+ setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
+ setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
+ setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
+ setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
- setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
- setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
- spin_unlock_irqrestore(&dbri->lock, flags);
+ setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
+ setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+ setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+ }
dbri_cmdwait(dbri);
}
@@ -1418,7 +1414,6 @@ static void cs4215_open(struct snd_dbri *dbri)
{
int data_width;
u32 tmp;
- unsigned long flags;
dprintk(D_MM, "cs4215_open: %d channels, %d bits\n",
dbri->mm.channels, dbri->mm.precision);
@@ -1443,35 +1438,35 @@ static void cs4215_open(struct snd_dbri *dbri)
* bits. The CS4215, it seems, observes TSIN (the delayed signal)
* even if it's the CHI master. Don't ask me...
*/
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~(D_C); /* Disable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ tmp = sbus_readl(dbri->regs + REG0);
+ tmp &= ~(D_C); /* Disable CHI */
+ sbus_writel(tmp, dbri->regs + REG0);
- /* Switch CS4215 to data mode - set PIO3 to 1 */
- sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
- (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
+ /* Switch CS4215 to data mode - set PIO3 to 1 */
+ sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
+ (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
- reset_chi(dbri, CHIslave, 128);
+ reset_chi(dbri, CHIslave, 128);
- /* Note: this next doesn't work for 8-bit stereo, because the two
- * channels would be on timeslots 1 and 3, with 2 and 4 idle.
- * (See CS4215 datasheet Fig 15)
- *
- * DBRI non-contiguous mode would be required to make this work.
- */
- data_width = dbri->mm.channels * dbri->mm.precision;
+ /* Note: this next doesn't work for 8-bit stereo, because the two
+ * channels would be on timeslots 1 and 3, with 2 and 4 idle.
+ * (See CS4215 datasheet Fig 15)
+ *
+ * DBRI non-contiguous mode would be required to make this work.
+ */
+ data_width = dbri->mm.channels * dbri->mm.precision;
- link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset);
- link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32);
- link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset);
- link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40);
+ link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset);
+ link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32);
+ link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset);
+ link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40);
- /* FIXME: enable CHI after _setdata? */
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_C; /* Enable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
- spin_unlock_irqrestore(&dbri->lock, flags);
+ /* FIXME: enable CHI after _setdata? */
+ tmp = sbus_readl(dbri->regs + REG0);
+ tmp |= D_C; /* Enable CHI */
+ sbus_writel(tmp, dbri->regs + REG0);
+ }
cs4215_setdata(dbri, 0);
}
@@ -1483,7 +1478,6 @@ static int cs4215_setctrl(struct snd_dbri *dbri)
{
int i, val;
u32 tmp;
- unsigned long flags;
/* FIXME - let the CPU do something useful during these delays */
@@ -1520,34 +1514,34 @@ static int cs4215_setctrl(struct snd_dbri *dbri)
* done in hardware by a TI 248 that delays the DBRI->4215
* frame sync signal by eight clock cycles. Anybody know why?
*/
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~D_C; /* Disable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
-
- reset_chi(dbri, CHImaster, 128);
-
- /*
- * Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
- * Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
- */
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ tmp = sbus_readl(dbri->regs + REG0);
+ tmp &= ~D_C; /* Disable CHI */
+ sbus_writel(tmp, dbri->regs + REG0);
+
+ reset_chi(dbri, CHImaster, 128);
+
+ /*
+ * Control mode:
+ * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
+ * Pipe 18: Receive timeslot 1 (clb).
+ * Pipe 19: Receive timeslot 7 (version).
+ */
- link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
- link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset);
- link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48);
- spin_unlock_irqrestore(&dbri->lock, flags);
+ link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
+ link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset);
+ link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48);
+ }
/* Wait for the chip to echo back CLB (Control Latch Bit) as zero */
dbri->mm.ctrl[0] &= ~CS4215_CLB;
xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_C; /* Enable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
- spin_unlock_irqrestore(&dbri->lock, flags);
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ tmp = sbus_readl(dbri->regs + REG0);
+ tmp |= D_C; /* Enable CHI */
+ sbus_writel(tmp, dbri->regs + REG0);
+ }
for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i)
msleep_interruptible(1);
@@ -1709,7 +1703,6 @@ static void xmit_descs(struct snd_dbri *dbri)
struct dbri_streaminfo *info;
u32 dvma_addr;
s32 *cmd;
- unsigned long flags;
int first_td;
if (dbri == NULL)
@@ -1717,7 +1710,7 @@ static void xmit_descs(struct snd_dbri *dbri)
dvma_addr = (u32)dbri->dma_dvma;
info = &dbri->stream_info[DBRI_REC];
- spin_lock_irqsave(&dbri->lock, flags);
+ guard(spinlock_irqsave)(&dbri->lock);
if (info->pipe >= 0) {
first_td = dbri->pipes[info->pipe].first_desc;
@@ -1760,8 +1753,6 @@ static void xmit_descs(struct snd_dbri *dbri)
dbri->pipes[info->pipe].desc = first_td;
}
}
-
- spin_unlock_irqrestore(&dbri->lock, flags);
}
/* transmission_complete_intr()
@@ -1932,7 +1923,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
if (dbri == NULL)
return IRQ_NONE;
- spin_lock(&dbri->lock);
+ guard(spinlock)(&dbri->lock);
/*
* Read it, so the interrupt goes away.
@@ -1977,8 +1968,6 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
dbri_process_interrupt_buffer(dbri);
- spin_unlock(&dbri->lock);
-
return IRQ_HANDLED;
}
@@ -2046,17 +2035,16 @@ static int snd_dbri_open(struct snd_pcm_substream *substream)
struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- unsigned long flags;
dprintk(D_USR, "open audio output.\n");
runtime->hw = snd_dbri_pcm_hw;
- spin_lock_irqsave(&dbri->lock, flags);
- info->substream = substream;
- info->offset = 0;
- info->dvma_buffer = 0;
- info->pipe = -1;
- spin_unlock_irqrestore(&dbri->lock, flags);
+ scoped_guard(spinlock_irqsave, &dbri->lock) {
+ info->substream = substream;
+ info->offset = 0;
+ info->dvma_buffer = 0;
+ info->pipe = -1;
+ }
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT,
@@ -2160,7 +2148,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
else
info->pipe = 6; /* Receive pipe */
- spin_lock_irq(&dbri->lock);
+ guard(spinlock_irq)(&dbri->lock);
info->offset = 0;
/* Setup the all the transmit/receive descriptors to cover the
@@ -2169,8 +2157,6 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
ret = setup_descs(dbri, DBRI_STREAMNO(substream),
snd_pcm_lib_period_bytes(substream));
- spin_unlock_irq(&dbri->lock);
-
dprintk(D_USR, "prepare audio output. %d bytes\n", info->size);
return ret;
}
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index a0a7f90b6146..0c2394733dc4 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -273,9 +273,8 @@ static int snd_at73c213_pcm_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- int retval = 0;
- spin_lock(&chip->lock);
+ guard(spinlock)(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -288,13 +287,11 @@ static int snd_at73c213_pcm_trigger(struct snd_pcm_substream *substream,
break;
default:
dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd);
- retval = -EINVAL;
+ return -EINVAL;
break;
}
- spin_unlock(&chip->lock);
-
- return retval;
+ return 0;
}
static snd_pcm_uframes_t
@@ -358,30 +355,29 @@ static irqreturn_t snd_at73c213_interrupt(int irq, void *dev_id)
int next_period;
int retval = IRQ_NONE;
- spin_lock(&chip->lock);
+ scoped_guard(spinlock, &chip->lock) {
+ block_size = frames_to_bytes(runtime, runtime->period_size);
+ status = ssc_readl(chip->ssc->regs, IMR);
- block_size = frames_to_bytes(runtime, runtime->period_size);
- status = ssc_readl(chip->ssc->regs, IMR);
-
- if (status & SSC_BIT(IMR_ENDTX)) {
- chip->period++;
- if (chip->period == runtime->periods)
- chip->period = 0;
- next_period = chip->period + 1;
- if (next_period == runtime->periods)
- next_period = 0;
-
- offset = block_size * next_period;
-
- ssc_writel(chip->ssc->regs, PDC_TNPR,
- (long)runtime->dma_addr + offset);
- ssc_writel(chip->ssc->regs, PDC_TNCR,
- runtime->period_size * runtime->channels);
- retval = IRQ_HANDLED;
- }
+ if (status & SSC_BIT(IMR_ENDTX)) {
+ chip->period++;
+ if (chip->period == runtime->periods)
+ chip->period = 0;
+ next_period = chip->period + 1;
+ if (next_period == runtime->periods)
+ next_period = 0;
+
+ offset = block_size * next_period;
- ssc_readl(chip->ssc->regs, IMR);
- spin_unlock(&chip->lock);
+ ssc_writel(chip->ssc->regs, PDC_TNPR,
+ (long)runtime->dma_addr + offset);
+ ssc_writel(chip->ssc->regs, PDC_TNCR,
+ runtime->period_size * runtime->channels);
+ retval = IRQ_HANDLED;
+ }
+
+ ssc_readl(chip->ssc->regs, IMR);
+ }
if (status & SSC_BIT(IMR_ENDTX))
snd_pcm_period_elapsed(chip->substream);
@@ -401,7 +397,7 @@ static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
ucontrol->value.integer.value[0] =
(chip->reg_image[reg] >> shift) & mask;
@@ -410,8 +406,6 @@ static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] =
mask - ucontrol->value.integer.value[0];
- mutex_unlock(&chip->mixer_lock);
-
return 0;
}
@@ -431,14 +425,12 @@ static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol,
val = mask - val;
val <<= shift;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
val = (chip->reg_image[reg] & ~(mask << shift)) | val;
change = val != chip->reg_image[reg];
retval = snd_at73c213_write_reg(chip, reg, val);
- mutex_unlock(&chip->mixer_lock);
-
if (retval)
return retval;
@@ -473,7 +465,7 @@ static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
ucontrol->value.integer.value[0] =
(chip->reg_image[left_reg] >> shift_left) & mask;
@@ -487,8 +479,6 @@ static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
mask - ucontrol->value.integer.value[1];
}
- mutex_unlock(&chip->mixer_lock);
-
return 0;
}
@@ -514,29 +504,20 @@ static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol,
val1 <<= shift_left;
val2 <<= shift_right;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1;
val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2;
change = val1 != chip->reg_image[left_reg]
|| val2 != chip->reg_image[right_reg];
retval = snd_at73c213_write_reg(chip, left_reg, val1);
- if (retval) {
- mutex_unlock(&chip->mixer_lock);
- goto out;
- }
+ if (retval)
+ return retval;
retval = snd_at73c213_write_reg(chip, right_reg, val2);
- if (retval) {
- mutex_unlock(&chip->mixer_lock);
- goto out;
- }
-
- mutex_unlock(&chip->mixer_lock);
+ if (retval)
+ return retval;
return change;
-
-out:
- return retval;
}
#define snd_at73c213_mono_switch_info snd_ctl_boolean_mono_info
@@ -549,7 +530,7 @@ static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
int shift = (kcontrol->private_value >> 8) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
ucontrol->value.integer.value[0] =
(chip->reg_image[reg] >> shift) & 0x01;
@@ -558,8 +539,6 @@ static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] =
0x01 - ucontrol->value.integer.value[0];
- mutex_unlock(&chip->mixer_lock);
-
return 0;
}
@@ -583,15 +562,13 @@ static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol,
val = mask - val;
val <<= shift;
- mutex_lock(&chip->mixer_lock);
+ guard(mutex)(&chip->mixer_lock);
val |= (chip->reg_image[reg] & ~(mask << shift));
change = val != chip->reg_image[reg];
retval = snd_at73c213_write_reg(chip, reg, val);
- mutex_unlock(&chip->mixer_lock);
-
if (retval)
return retval;
diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c
index 3c7314f5fb19..bfe383fa90ba 100644
--- a/sound/synth/emux/emux_effect.c
+++ b/sound/synth/emux/emux_effect.c
@@ -168,7 +168,6 @@ snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
unsigned char *srcp, *origp;
struct snd_emux *emu;
struct snd_emux_effect_table *fx;
- unsigned long flags;
emu = port->emu;
fx = chan->private;
@@ -195,22 +194,22 @@ snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
offset++;
#endif
/* modify the register values */
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- struct snd_emux_voice *vp = &emu->voices[i];
- if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
- continue;
- srcp = (unsigned char*)&vp->reg.parm + offset;
- origp = (unsigned char*)&vp->zone->v.parm + offset;
- if (parm_defs[i].type & PARM_IS_BYTE) {
- *srcp = *origp;
- effect_set_byte(srcp, chan, type);
- } else {
- *(unsigned short*)srcp = *(unsigned short*)origp;
- effect_set_word((unsigned short*)srcp, chan, type);
+ scoped_guard(spinlock_irqsave, &emu->voice_lock) {
+ for (i = 0; i < emu->max_voices; i++) {
+ struct snd_emux_voice *vp = &emu->voices[i];
+ if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
+ continue;
+ srcp = (unsigned char *)&vp->reg.parm + offset;
+ origp = (unsigned char *)&vp->zone->v.parm + offset;
+ if (parm_defs[i].type & PARM_IS_BYTE) {
+ *srcp = *origp;
+ effect_set_byte(srcp, chan, type);
+ } else {
+ *(unsigned short *)srcp = *(unsigned short *)origp;
+ effect_set_word((unsigned short *)srcp, chan, type);
+ }
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
/* activate them */
snd_emux_update_channel(port, chan, parm_defs[type].update);
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 820351f52551..16d6c9a1e24f 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -19,7 +19,7 @@ snd_emux_proc_info_read(struct snd_info_entry *entry,
int i;
emu = entry->private_data;
- mutex_lock(&emu->register_mutex);
+ guard(mutex)(&emu->register_mutex);
if (emu->name)
snd_iprintf(buf, "Device: %s\n", emu->name);
snd_iprintf(buf, "Ports: %d\n", emu->num_ports);
@@ -38,13 +38,12 @@ snd_emux_proc_info_read(struct snd_info_entry *entry,
snd_iprintf(buf, "Memory Size: 0\n");
}
if (emu->sflist) {
- mutex_lock(&emu->sflist->presets_mutex);
+ guard(mutex)(&emu->sflist->presets_mutex);
snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size);
snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter);
snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter);
snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked);
snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked);
- mutex_unlock(&emu->sflist->presets_mutex);
}
#if 0 /* debug */
if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) {
@@ -85,7 +84,6 @@ snd_emux_proc_info_read(struct snd_info_entry *entry,
snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset);
}
#endif
- mutex_unlock(&emu->register_mutex);
}
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 9daced0e6c59..9d63ac006aa5 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -272,12 +272,8 @@ __snd_emux_inc_count(struct snd_emux *emu)
int snd_emux_inc_count(struct snd_emux *emu)
{
- int ret;
-
- mutex_lock(&emu->register_mutex);
- ret = __snd_emux_inc_count(emu);
- mutex_unlock(&emu->register_mutex);
- return ret;
+ guard(mutex)(&emu->register_mutex);
+ return __snd_emux_inc_count(emu);
}
/*
@@ -295,9 +291,8 @@ __snd_emux_dec_count(struct snd_emux *emu)
void snd_emux_dec_count(struct snd_emux *emu)
{
- mutex_lock(&emu->register_mutex);
+ guard(mutex)(&emu->register_mutex);
__snd_emux_dec_count(emu);
- mutex_unlock(&emu->register_mutex);
}
/*
@@ -316,10 +311,9 @@ snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
if (snd_BUG_ON(!emu))
return -EINVAL;
- mutex_lock(&emu->register_mutex);
+ guard(mutex)(&emu->register_mutex);
snd_emux_init_port(p);
__snd_emux_inc_count(emu);
- mutex_unlock(&emu->register_mutex);
return 0;
}
@@ -339,10 +333,9 @@ snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
if (snd_BUG_ON(!emu))
return -EINVAL;
- mutex_lock(&emu->register_mutex);
+ guard(mutex)(&emu->register_mutex);
snd_emux_sounds_off_all(p);
__snd_emux_dec_count(emu);
- mutex_unlock(&emu->register_mutex);
return 0;
}
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index cff6aba9bfc3..6982e1317da5 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -49,7 +49,6 @@ snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
int i, key, nvoices;
struct snd_emux_voice *vp;
struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
- unsigned long flags;
struct snd_emux_port *port;
port = p;
@@ -77,7 +76,7 @@ snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
terminate_note1(emu, key, chan, 0);
#endif
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < nvoices; i++) {
/* set up each voice parameter */
@@ -124,7 +123,6 @@ snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
vp->ontime = jiffies; /* remember the trigger timing */
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
@@ -147,7 +145,6 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
int ch;
struct snd_emux *emu;
struct snd_emux_voice *vp;
- unsigned long flags;
struct snd_emux_port *port;
port = p;
@@ -158,7 +155,7 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
if (snd_BUG_ON(!emu || !emu->ops.release))
return;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (STATE_IS_PLAYING(vp->state) &&
@@ -180,7 +177,6 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
emu->ops.release(vp);
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
/*
@@ -192,10 +188,9 @@ void snd_emux_timer_callback(struct timer_list *t)
{
struct snd_emux *emu = timer_container_of(emu, t, tlist);
struct snd_emux_voice *vp;
- unsigned long flags;
int ch, do_again = 0;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (vp->state == SNDRV_EMUX_ST_PENDING) {
@@ -212,7 +207,6 @@ void snd_emux_timer_callback(struct timer_list *t)
emu->timer_active = 1;
} else
emu->timer_active = 0;
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
/*
@@ -224,7 +218,6 @@ snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
int ch;
struct snd_emux *emu;
struct snd_emux_voice *vp;
- unsigned long flags;
struct snd_emux_port *port;
port = p;
@@ -235,7 +228,7 @@ snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
if (snd_BUG_ON(!emu || !emu->ops.update))
return;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (vp->state == SNDRV_EMUX_ST_ON &&
@@ -244,7 +237,6 @@ snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
@@ -257,7 +249,6 @@ snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *cha
struct snd_emux *emu;
struct snd_emux_voice *vp;
int i;
- unsigned long flags;
if (! update)
return;
@@ -266,13 +257,12 @@ snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *cha
if (snd_BUG_ON(!emu || !emu->ops.update))
return;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (vp->chan == chan)
update_voice(emu, vp, update);
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
/*
@@ -284,7 +274,6 @@ snd_emux_update_port(struct snd_emux_port *port, int update)
struct snd_emux *emu;
struct snd_emux_voice *vp;
int i;
- unsigned long flags;
if (! update)
return;
@@ -293,13 +282,12 @@ snd_emux_update_port(struct snd_emux_port *port, int update)
if (snd_BUG_ON(!emu || !emu->ops.update))
return;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (vp->port == port)
update_voice(emu, vp, update);
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
@@ -365,16 +353,14 @@ terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, i
{
int i;
struct snd_emux_voice *vp;
- unsigned long flags;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
vp->key == note)
terminate_voice(emu, vp, free);
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
@@ -407,9 +393,8 @@ snd_emux_terminate_all(struct snd_emux *emu)
{
int i;
struct snd_emux_voice *vp;
- unsigned long flags;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (STATE_IS_PLAYING(vp->state))
@@ -424,7 +409,6 @@ snd_emux_terminate_all(struct snd_emux *emu)
}
/* initialize allocation time */
emu->use_time = 0;
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
EXPORT_SYMBOL(snd_emux_terminate_all);
@@ -438,7 +422,6 @@ snd_emux_sounds_off_all(struct snd_emux_port *port)
int i;
struct snd_emux *emu;
struct snd_emux_voice *vp;
- unsigned long flags;
if (snd_BUG_ON(!port))
return;
@@ -446,7 +429,7 @@ snd_emux_sounds_off_all(struct snd_emux_port *port)
if (snd_BUG_ON(!emu || !emu->ops.terminate))
return;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (STATE_IS_PLAYING(vp->state) &&
@@ -459,7 +442,6 @@ snd_emux_sounds_off_all(struct snd_emux_port *port)
emu->ops.reset(emu, i);
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
@@ -472,9 +454,8 @@ exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass
{
struct snd_emux_voice *vp;
int i;
- unsigned long flags;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
@@ -482,7 +463,6 @@ exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass
terminate_voice(emu, vp, 0);
}
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
/*
@@ -916,9 +896,8 @@ snd_emux_init_voices(struct snd_emux *emu)
{
struct snd_emux_voice *vp;
int i;
- unsigned long flags;
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
vp->ch = -1; /* not used */
@@ -929,23 +908,19 @@ snd_emux_init_voices(struct snd_emux *emu)
vp->emu = emu;
vp->hw = emu->hw;
}
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
/*
*/
void snd_emux_lock_voice(struct snd_emux *emu, int voice)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
else
dev_warn(emu->card->dev,
"invalid voice for lock %d (state = %x)\n",
voice, emu->voices[voice].state);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
EXPORT_SYMBOL(snd_emux_lock_voice);
@@ -954,16 +929,13 @@ EXPORT_SYMBOL(snd_emux_lock_voice);
*/
void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
+ guard(spinlock_irqsave)(&emu->voice_lock);
if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
else
dev_warn(emu->card->dev,
"invalid voice for unlock %d (state = %x)\n",
voice, emu->voices[voice].state);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
}
EXPORT_SYMBOL(snd_emux_unlock_voice);
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index b38a4e231790..59f3b1b6df4a 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -61,47 +61,16 @@ static void snd_sf_init(struct snd_sf_list *sflist);
static void snd_sf_clear(struct snd_sf_list *sflist);
/*
- * lock access to sflist
- */
-static void
-lock_preset(struct snd_sf_list *sflist)
-{
- unsigned long flags;
- mutex_lock(&sflist->presets_mutex);
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->presets_locked = 1;
- spin_unlock_irqrestore(&sflist->lock, flags);
-}
-
-
-/*
- * remove lock
- */
-static void
-unlock_preset(struct snd_sf_list *sflist)
-{
- unsigned long flags;
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->presets_locked = 0;
- spin_unlock_irqrestore(&sflist->lock, flags);
- mutex_unlock(&sflist->presets_mutex);
-}
-
-
-/*
* close the patch if the patch was opened by this client.
*/
int
snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
{
- unsigned long flags;
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client == client) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return close_patch(sflist);
+ scoped_guard(spinlock_irqsave, &sflist->lock) {
+ if (sflist->open_client != client)
+ return 0;
}
- spin_unlock_irqrestore(&sflist->lock, flags);
- return 0;
+ return close_patch(sflist);
}
@@ -119,7 +88,6 @@ snd_soundfont_load(struct snd_card *card,
long count, int client)
{
struct soundfont_patch_info patch;
- unsigned long flags;
int rc;
if (count < (long)sizeof(patch)) {
@@ -148,21 +116,17 @@ snd_soundfont_load(struct snd_card *card,
if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
/* grab sflist to open */
- lock_preset(sflist);
- rc = open_patch(sflist, data, count, client);
- unlock_preset(sflist);
- return rc;
+ guard(snd_soundfont_lock_preset)(sflist);
+ return open_patch(sflist, data, count, client);
}
/* check if other client already opened patch */
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client != client) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return -EBUSY;
+ scoped_guard(spinlock_irqsave, &sflist->lock) {
+ if (sflist->open_client != client)
+ return -EBUSY;
}
- spin_unlock_irqrestore(&sflist->lock, flags);
- lock_preset(sflist);
+ guard(snd_soundfont_lock_preset)(sflist);
rc = -EINVAL;
switch (patch.type) {
case SNDRV_SFNT_LOAD_INFO:
@@ -200,7 +164,6 @@ snd_soundfont_load(struct snd_card *card,
}
break;
}
- unlock_preset(sflist);
return rc;
}
@@ -223,14 +186,11 @@ open_patch(struct snd_sf_list *sflist, const char __user *data,
{
struct soundfont_open_parm parm;
struct snd_soundfont *sf;
- unsigned long flags;
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client >= 0 || sflist->currsf) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return -EBUSY;
+ scoped_guard(spinlock_irqsave, &sflist->lock) {
+ if (sflist->open_client >= 0 || sflist->currsf)
+ return -EBUSY;
}
- spin_unlock_irqrestore(&sflist->lock, flags);
if (copy_from_user(&parm, data, sizeof(parm)))
return -EFAULT;
@@ -244,10 +204,10 @@ open_patch(struct snd_sf_list *sflist, const char __user *data,
return -ENOMEM;
}
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->open_client = client;
- sflist->currsf = sf;
- spin_unlock_irqrestore(&sflist->lock, flags);
+ scoped_guard(spinlock_irqsave, &sflist->lock) {
+ sflist->open_client = client;
+ sflist->currsf = sf;
+ }
return 0;
}
@@ -305,12 +265,10 @@ is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
static int
close_patch(struct snd_sf_list *sflist)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->currsf = NULL;
- sflist->open_client = -1;
- spin_unlock_irqrestore(&sflist->lock, flags);
+ scoped_guard(spinlock_irqsave, &sflist->lock) {
+ sflist->currsf = NULL;
+ sflist->open_client = -1;
+ }
rebuild_presets(sflist);
@@ -1168,11 +1126,8 @@ snd_soundfont_load_guspatch(struct snd_card *card,
struct snd_sf_list *sflist, const char __user *data,
long count)
{
- int rc;
- lock_preset(sflist);
- rc = load_guspatch(card, sflist, data, count);
- unlock_preset(sflist);
- return rc;
+ guard(snd_soundfont_lock_preset)(sflist);
+ return load_guspatch(card, sflist, data, count);
}
@@ -1278,17 +1233,14 @@ snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
struct snd_sf_zone **table, int max_layers)
{
int nvoices;
- unsigned long flags;
/* this function is supposed to be called atomically,
* so we check the lock. if it's busy, just returns 0 to
* tell the caller the busy state
*/
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->presets_locked) {
- spin_unlock_irqrestore(&sflist->lock, flags);
+ guard(spinlock_irqsave)(&sflist->lock);
+ if (sflist->presets_locked)
return 0;
- }
nvoices = search_zones(sflist, notep, vel, preset, bank,
table, max_layers, 0);
if (! nvoices) {
@@ -1297,7 +1249,6 @@ snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
def_preset, def_bank,
table, max_layers, 0);
}
- spin_unlock_irqrestore(&sflist->lock, flags);
return nvoices;
}
@@ -1465,11 +1416,11 @@ snd_sf_free(struct snd_sf_list *sflist)
if (sflist == NULL)
return;
- lock_preset(sflist);
- if (sflist->callback.sample_reset)
- sflist->callback.sample_reset(sflist->callback.private_data);
- snd_sf_clear(sflist);
- unlock_preset(sflist);
+ scoped_guard(snd_soundfont_lock_preset, sflist) {
+ if (sflist->callback.sample_reset)
+ sflist->callback.sample_reset(sflist->callback.private_data);
+ snd_sf_clear(sflist);
+ }
kfree(sflist);
}
@@ -1481,11 +1432,10 @@ snd_sf_free(struct snd_sf_list *sflist)
int
snd_soundfont_remove_samples(struct snd_sf_list *sflist)
{
- lock_preset(sflist);
+ guard(snd_soundfont_lock_preset)(sflist);
if (sflist->callback.sample_reset)
sflist->callback.sample_reset(sflist->callback.private_data);
snd_sf_clear(sflist);
- unlock_preset(sflist);
return 0;
}
@@ -1501,7 +1451,7 @@ snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
struct snd_sf_zone *zp, *nextzp;
struct snd_sf_sample *sp, *nextsp;
- lock_preset(sflist);
+ guard(snd_soundfont_lock_preset)(sflist);
if (sflist->callback.sample_reset)
sflist->callback.sample_reset(sflist->callback.private_data);
@@ -1535,6 +1485,5 @@ snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
rebuild_presets(sflist);
- unlock_preset(sflist);
return 0;
}
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index 304a8f1740c3..2fd577c2a8eb 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -124,11 +124,8 @@ __snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
struct snd_util_memblk *
snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
{
- struct snd_util_memblk *blk;
- mutex_lock(&hdr->block_mutex);
- blk = __snd_util_mem_alloc(hdr, size);
- mutex_unlock(&hdr->block_mutex);
- return blk;
+ guard(mutex)(&hdr->block_mutex);
+ return __snd_util_mem_alloc(hdr, size);
}
@@ -153,9 +150,8 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
if (snd_BUG_ON(!hdr || !blk))
return -EINVAL;
- mutex_lock(&hdr->block_mutex);
+ guard(mutex)(&hdr->block_mutex);
__snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
return 0;
}
@@ -164,11 +160,8 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
*/
int snd_util_mem_avail(struct snd_util_memhdr *hdr)
{
- unsigned int size;
- mutex_lock(&hdr->block_mutex);
- size = hdr->size - hdr->used;
- mutex_unlock(&hdr->block_mutex);
- return size;
+ guard(mutex)(&hdr->block_mutex);
+ return hdr->size - hdr->used;
}
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 9eb4bf9b138b..5ff78814e687 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -88,24 +88,22 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
struct snd_card *card = NULL;
/* look if we already serve this card and return if so */
- mutex_lock(&register_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (devices[i] == device) {
- if (chips[i])
- chips[i]->intf_count++;
- usb_set_intfdata(intf, chips[i]);
- mutex_unlock(&register_mutex);
- return 0;
- } else if (!devices[i] && regidx < 0)
- regidx = i;
- }
- if (regidx < 0) {
- mutex_unlock(&register_mutex);
- dev_err(&intf->dev, "too many cards registered.\n");
- return -ENODEV;
+ scoped_guard(mutex, &register_mutex) {
+ for (i = 0; i < SNDRV_CARDS; i++) {
+ if (devices[i] == device) {
+ if (chips[i])
+ chips[i]->intf_count++;
+ usb_set_intfdata(intf, chips[i]);
+ return 0;
+ } else if (!devices[i] && regidx < 0)
+ regidx = i;
+ }
+ if (regidx < 0) {
+ dev_err(&intf->dev, "too many cards registered.\n");
+ return -ENODEV;
+ }
+ devices[regidx] = device;
}
- devices[regidx] = device;
- mutex_unlock(&register_mutex);
/* check, if firmware is present on device, upload it if not */
ret = usb6fire_fw_init(intf);
@@ -175,10 +173,10 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
if (chip) { /* if !chip, fw upload has been performed */
chip->intf_count--;
if (!chip->intf_count) {
- mutex_lock(&register_mutex);
- devices[chip->regidx] = NULL;
- chips[chip->regidx] = NULL;
- mutex_unlock(&register_mutex);
+ scoped_guard(mutex, &register_mutex) {
+ devices[chip->regidx] = NULL;
+ chips[chip->regidx] = NULL;
+ }
chip->shutdown = true;
usb6fire_chip_abort(chip);
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index 923f7767e62f..4d1eeb32c5fe 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -23,9 +23,8 @@ static void usb6fire_midi_out_handler(struct urb *urb)
{
struct midi_runtime *rt = urb->context;
int ret;
- unsigned long flags;
- spin_lock_irqsave(&rt->out_lock, flags);
+ guard(spinlock_irqsave)(&rt->out_lock);
if (rt->out) {
ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
@@ -43,18 +42,14 @@ static void usb6fire_midi_out_handler(struct urb *urb)
} else /* no more data to transmit */
rt->out = NULL;
}
- spin_unlock_irqrestore(&rt->out_lock, flags);
}
static void usb6fire_midi_in_received(
struct midi_runtime *rt, u8 *data, int length)
{
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
+ guard(spinlock_irqsave)(&rt->in_lock);
if (rt->in)
snd_rawmidi_receive(rt->in, data, length);
- spin_unlock_irqrestore(&rt->in_lock, flags);
}
static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
@@ -73,14 +68,11 @@ static void usb6fire_midi_out_trigger(
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
struct urb *urb = &rt->out_urb;
__s8 ret;
- unsigned long flags;
- spin_lock_irqsave(&rt->out_lock, flags);
+ guard(spinlock_irqsave)(&rt->out_lock);
if (up) { /* start transfer */
- if (rt->out) { /* we are already transmitting so just return */
- spin_unlock_irqrestore(&rt->out_lock, flags);
+ if (rt->out) /* we are already transmitting so just return */
return;
- }
ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
MIDI_BUFSIZE - 4);
@@ -99,7 +91,6 @@ static void usb6fire_midi_out_trigger(
}
} else if (rt->out == alsa_sub)
rt->out = NULL;
- spin_unlock_irqrestore(&rt->out_lock, flags);
}
static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
@@ -125,14 +116,12 @@ static void usb6fire_midi_in_trigger(
struct snd_rawmidi_substream *alsa_sub, int up)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&rt->in_lock, flags);
+ guard(spinlock_irqsave)(&rt->in_lock);
if (up)
rt->in = alsa_sub;
else
rt->in = NULL;
- spin_unlock_irqrestore(&rt->in_lock, flags);
}
static const struct snd_rawmidi_ops out_ops = {
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index d53cad97889a..08515da5dcc8 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -289,7 +289,7 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
struct pcm_urb *out_urb = in_urb->peer;
struct pcm_runtime *rt = in_urb->chip->pcm;
struct pcm_substream *sub;
- unsigned long flags;
+ bool period_elapsed;
int total_length = 0;
int frame_count;
int frame;
@@ -313,17 +313,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* receive our capture data */
sub = &rt->capture;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_capture(sub, in_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
+ period_elapsed = false;
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ if (sub->active) {
+ usb6fire_pcm_capture(sub, in_urb);
+ if (sub->period_off >= sub->instance->runtime->period_size) {
+ sub->period_off %= sub->instance->runtime->period_size;
+ period_elapsed = true;
+ }
+ }
+ }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(sub->instance);
/* setup out urb structure */
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
@@ -338,17 +339,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* now send our playback data (if a free out urb was found) */
sub = &rt->playback;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_playback(sub, out_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
+ period_elapsed = false;
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ if (sub->active) {
+ usb6fire_pcm_playback(sub, out_urb);
+ if (sub->period_off >= sub->instance->runtime->period_size) {
+ sub->period_off %= sub->instance->runtime->period_size;
+ period_elapsed = true;
+ }
+ }
+ }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(sub->instance);
/* setup the 4th byte of each sample (0x40 for analog channels) */
dest = out_urb->buffer;
@@ -392,7 +394,7 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
if (rt->panic)
return -EPIPE;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
alsa_rt->hw = pcm_hw;
if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -408,14 +410,12 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
}
if (!sub) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev, "invalid stream type.\n");
return -EINVAL;
}
sub->instance = alsa_sub;
sub->active = false;
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -423,18 +423,17 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
{
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- unsigned long flags;
if (rt->panic)
return 0;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
if (sub) {
/* deactivate substream */
- spin_lock_irqsave(&sub->lock, flags);
- sub->instance = NULL;
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ sub->instance = NULL;
+ sub->active = false;
+ }
/* all substreams closed? if so, stop streaming */
if (!rt->playback.instance && !rt->capture.instance) {
@@ -442,7 +441,6 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
rt->rate = ARRAY_SIZE(rates);
}
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -458,7 +456,7 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (!sub)
return -ENODEV;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
sub->dma_off = 0;
sub->period_off = 0;
@@ -467,7 +465,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (alsa_rt->rate == rates[rt->rate])
break;
if (rt->rate == ARRAY_SIZE(rates)) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev,
"invalid rate %d in prepare.\n",
alsa_rt->rate);
@@ -475,19 +472,15 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
}
ret = usb6fire_pcm_set_rate(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
+ if (ret)
return ret;
- }
ret = usb6fire_pcm_stream_start(rt);
if (ret) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev,
"could not start pcm stream.\n");
return ret;
}
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -495,26 +488,22 @@ static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
{
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
if (rt->panic)
return -EPIPE;
if (!sub)
return -ENODEV;
+ guard(spinlock_irqsave)(&sub->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&sub->lock, flags);
sub->active = true;
- spin_unlock_irqrestore(&sub->lock, flags);
return 0;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&sub->lock, flags);
sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
return 0;
default:
@@ -527,15 +516,13 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer(
{
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
snd_pcm_uframes_t ret;
if (rt->panic || !sub)
return SNDRV_PCM_POS_XRUN;
- spin_lock_irqsave(&sub->lock, flags);
+ guard(spinlock_irqsave)(&sub->lock);
ret = sub->dma_off;
- spin_unlock_irqrestore(&sub->lock, flags);
return ret;
}
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 41c47301bc19..9b890abd96d3 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -117,6 +117,18 @@ config SND_USB_US122L
To compile this driver as a module, choose M here: the module
will be called snd-usb-us122l.
+config SND_USB_US144MKII
+ tristate "Tascam US-144MKII USB driver"
+ depends on X86 || COMPILE_TEST
+ select SND_RAWMIDI
+ select SND_PCM
+ help
+ Say Y here to include support for Tascam US-144MKII USB Audio/MIDI
+ interface.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-usb-us144mkii.
+
config SND_USB_6FIRE
tristate "TerraTec DMX 6Fire USB"
select FW_LOADER
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index 392b4d8e9e76..bebb48cb9abc 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -369,23 +369,19 @@ static int bcd2000_probe(struct usb_interface *interface,
char usb_path[32];
int err;
- mutex_lock(&devices_mutex);
+ guard(mutex)(&devices_mutex);
for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
if (!test_bit(card_index, devices_used))
break;
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
+ if (card_index >= SNDRV_CARDS)
return -ENOENT;
- }
err = snd_card_new(&interface->dev, index[card_index], id[card_index],
THIS_MODULE, sizeof(*bcd2k), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
+ if (err < 0)
return err;
- }
bcd2k = card->private_data;
bcd2k->dev = interface_to_usbdev(interface);
@@ -413,14 +409,12 @@ static int bcd2000_probe(struct usb_interface *interface,
usb_set_intfdata(interface, bcd2k);
set_bit(card_index, devices_used);
- mutex_unlock(&devices_mutex);
return 0;
probe_error:
dev_info(&bcd2k->dev->dev, PREFIX "error during probing");
bcd2000_free_usb_related_resources(bcd2k, interface);
snd_card_free(card);
- mutex_unlock(&devices_mutex);
return err;
}
@@ -431,7 +425,7 @@ static void bcd2000_disconnect(struct usb_interface *interface)
if (!bcd2k)
return;
- mutex_lock(&devices_mutex);
+ guard(mutex)(&devices_mutex);
/* make sure that userspace cannot create new requests */
snd_card_disconnect(bcd2k->card);
@@ -441,8 +435,6 @@ static void bcd2000_disconnect(struct usb_interface *interface)
clear_bit(bcd2k->card_index, devices_used);
snd_card_free_when_closed(bcd2k->card);
-
- mutex_unlock(&devices_mutex);
}
static struct usb_driver bcd2000_driver = {
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 05f964347ed6..95d425dd9d70 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -51,29 +51,24 @@ static void
activate_substream(struct snd_usb_caiaqdev *cdev,
struct snd_pcm_substream *sub)
{
- spin_lock(&cdev->spinlock);
+ guard(spinlock)(&cdev->spinlock);
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
cdev->sub_playback[sub->number] = sub;
else
cdev->sub_capture[sub->number] = sub;
-
- spin_unlock(&cdev->spinlock);
}
static void
deactivate_substream(struct snd_usb_caiaqdev *cdev,
struct snd_pcm_substream *sub)
{
- unsigned long flags;
- spin_lock_irqsave(&cdev->spinlock, flags);
+ guard(spinlock_irqsave)(&cdev->spinlock);
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
cdev->sub_playback[sub->number] = NULL;
else
cdev->sub_capture[sub->number] = NULL;
-
- spin_unlock_irqrestore(&cdev->spinlock, flags);
}
static int
@@ -285,25 +280,18 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
int index = sub->number;
struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub);
- snd_pcm_uframes_t ptr;
- spin_lock(&cdev->spinlock);
+ guard(spinlock)(&cdev->spinlock);
- if (cdev->input_panic || cdev->output_panic) {
- ptr = SNDRV_PCM_POS_XRUN;
- goto unlock;
- }
+ if (cdev->input_panic || cdev->output_panic)
+ return SNDRV_PCM_POS_XRUN;
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ptr = bytes_to_frames(sub->runtime,
- cdev->audio_out_buf_pos[index]);
+ return bytes_to_frames(sub->runtime,
+ cdev->audio_out_buf_pos[index]);
else
- ptr = bytes_to_frames(sub->runtime,
- cdev->audio_in_buf_pos[index]);
-
-unlock:
- spin_unlock(&cdev->spinlock);
- return ptr;
+ return bytes_to_frames(sub->runtime,
+ cdev->audio_in_buf_pos[index]);
}
/* operators for both playback and capture */
@@ -601,7 +589,6 @@ static void read_completed(struct urb *urb)
struct device *dev;
struct urb *out = NULL;
int i, frame, len, send_it = 0, outframe = 0;
- unsigned long flags;
size_t offset = 0;
if (urb->status || !info)
@@ -638,10 +625,10 @@ static void read_completed(struct urb *urb)
offset += len;
if (len > 0) {
- spin_lock_irqsave(&cdev->spinlock, flags);
- fill_out_urb(cdev, out, &out->iso_frame_desc[outframe]);
- read_in_urb(cdev, urb, &urb->iso_frame_desc[frame]);
- spin_unlock_irqrestore(&cdev->spinlock, flags);
+ scoped_guard(spinlock_irqsave, &cdev->spinlock) {
+ fill_out_urb(cdev, out, &out->iso_frame_desc[outframe]);
+ read_in_urb(cdev, urb, &urb->iso_frame_desc[frame]);
+ }
check_for_elapsed_periods(cdev, cdev->sub_playback);
check_for_elapsed_periods(cdev, cdev->sub_capture);
send_it = 1;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 10d9b7285597..1d5a65eac933 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -73,7 +73,7 @@ static bool lowlatency = true;
static char *quirk_alias[SNDRV_CARDS];
static char *delayed_register[SNDRV_CARDS];
static bool implicit_fb[SNDRV_CARDS];
-static unsigned int quirk_flags[SNDRV_CARDS];
+static char *quirk_flags[SNDRV_CARDS];
bool snd_usb_use_vmalloc = true;
bool snd_usb_skip_validation;
@@ -103,13 +103,32 @@ module_param_array(delayed_register, charp, NULL, 0444);
MODULE_PARM_DESC(delayed_register, "Quirk for delayed registration, given by id:iface, e.g. 0123abcd:4.");
module_param_array(implicit_fb, bool, NULL, 0444);
MODULE_PARM_DESC(implicit_fb, "Apply generic implicit feedback sync mode.");
-module_param_array(quirk_flags, uint, NULL, 0444);
-MODULE_PARM_DESC(quirk_flags, "Driver quirk bit flags.");
module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444);
MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes).");
module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444);
MODULE_PARM_DESC(skip_validation, "Skip unit descriptor validation (default: no).");
+/* protects quirk_flags */
+static DEFINE_MUTEX(quirk_flags_mutex);
+
+static int param_set_quirkp(const char *val,
+ const struct kernel_param *kp)
+{
+ guard(mutex)(&quirk_flags_mutex);
+ return param_set_charp(val, kp);
+}
+
+static const struct kernel_param_ops param_ops_quirkp = {
+ .set = param_set_quirkp,
+ .get = param_get_charp,
+ .free = param_free_charp,
+};
+
+#define param_check_quirkp param_check_charp
+
+module_param_array(quirk_flags, quirkp, NULL, 0644);
+MODULE_PARM_DESC(quirk_flags, "Add/modify USB audio quirks");
+
/*
* we keep the snd_usb_audio_t instances by ourselves for merging
* the all interfaces on the same card as one sound device.
@@ -692,6 +711,31 @@ static void usb_audio_make_longname(struct usb_device *dev,
}
}
+static void snd_usb_init_quirk_flags(int idx, struct snd_usb_audio *chip)
+{
+ size_t i;
+
+ guard(mutex)(&quirk_flags_mutex);
+
+ /* old style option found: the position-based integer value */
+ if (quirk_flags[idx] &&
+ !kstrtou32(quirk_flags[idx], 0, &chip->quirk_flags)) {
+ snd_usb_apply_flag_dbg("module param", chip, chip->quirk_flags);
+ return;
+ }
+
+ /* take the default quirk from the quirk table */
+ snd_usb_init_quirk_flags_table(chip);
+
+ /* add or correct quirk bits from options */
+ for (i = 0; i < ARRAY_SIZE(quirk_flags); i++) {
+ if (!quirk_flags[i] || !*quirk_flags[i])
+ break;
+
+ snd_usb_init_quirk_flags_parse_string(chip, quirk_flags[i]);
+ }
+}
+
/*
* create a chip instance and set its names.
*/
@@ -750,10 +794,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
INIT_LIST_HEAD(&chip->midi_v2_list);
INIT_LIST_HEAD(&chip->mixer_list);
- if (quirk_flags[idx])
- chip->quirk_flags = quirk_flags[idx];
- else
- snd_usb_init_quirk_flags(chip);
+ snd_usb_init_quirk_flags(idx, chip);
card->private_free = snd_usb_audio_free;
@@ -900,7 +941,7 @@ static int usb_audio_probe(struct usb_interface *intf,
/* check whether it's already registered */
chip = NULL;
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
for (i = 0; i < SNDRV_CARDS; i++) {
if (usb_chip[i] && usb_chip[i]->dev == dev) {
if (atomic_read(&usb_chip[i]->shutdown)) {
@@ -1015,7 +1056,6 @@ static int usb_audio_probe(struct usb_interface *intf,
if (platform_ops && platform_ops->connect_cb)
platform_ops->connect_cb(chip);
- mutex_unlock(&register_mutex);
return 0;
@@ -1033,7 +1073,6 @@ static int usb_audio_probe(struct usb_interface *intf,
if (!chip->num_interfaces)
snd_card_free(chip->card);
}
- mutex_unlock(&register_mutex);
return err;
}
@@ -1041,18 +1080,14 @@ static int usb_audio_probe(struct usb_interface *intf,
* we need to take care of counter, since disconnection can be called also
* many times as well as usb_audio_probe().
*/
-static void usb_audio_disconnect(struct usb_interface *intf)
+static bool __usb_audio_disconnect(struct usb_interface *intf,
+ struct snd_usb_audio *chip,
+ struct snd_card *card)
{
- struct snd_usb_audio *chip = usb_get_intfdata(intf);
- struct snd_card *card;
struct list_head *p;
- if (chip == USB_AUDIO_IFACE_UNUSED)
- return;
-
- card = chip->card;
+ guard(mutex)(&register_mutex);
- mutex_lock(&register_mutex);
if (platform_ops && platform_ops->disconnect_cb)
platform_ops->disconnect_cb(chip);
@@ -1098,13 +1133,24 @@ static void usb_audio_disconnect(struct usb_interface *intf)
usb_enable_autosuspend(interface_to_usbdev(intf));
chip->num_interfaces--;
- if (chip->num_interfaces <= 0) {
- usb_chip[chip->index] = NULL;
- mutex_unlock(&register_mutex);
+ if (chip->num_interfaces > 0)
+ return false;
+
+ usb_chip[chip->index] = NULL;
+ return true;
+}
+
+static void usb_audio_disconnect(struct usb_interface *intf)
+{
+ struct snd_usb_audio *chip = usb_get_intfdata(intf);
+ struct snd_card *card;
+
+ if (chip == USB_AUDIO_IFACE_UNUSED)
+ return;
+
+ card = chip->card;
+ if (__usb_audio_disconnect(intf, chip, card))
snd_card_free_when_closed(card);
- } else {
- mutex_unlock(&register_mutex);
- }
}
/* lock the shutdown (disconnect) task and autoresume */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 7b01e7b4e335..880f5afcce60 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -163,22 +163,19 @@ int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep)
static int slave_next_packet_size(struct snd_usb_endpoint *ep,
unsigned int avail)
{
- unsigned long flags;
unsigned int phase;
int ret;
if (ep->fill_max)
return ep->maxframesize;
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
phase = (ep->phase & 0xffff) + (ep->freqm << ep->datainterval);
ret = min(phase >> 16, ep->maxframesize);
if (avail && ret >= avail)
ret = -EAGAIN;
else
ep->phase = phase;
- spin_unlock_irqrestore(&ep->lock, flags);
-
return ret;
}
@@ -440,11 +437,8 @@ next_packet_fifo_dequeue(struct snd_usb_endpoint *ep)
static void push_back_to_ready_list(struct snd_usb_endpoint *ep,
struct snd_urb_ctx *ctx)
{
- unsigned long flags;
-
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs);
- spin_unlock_irqrestore(&ep->lock, flags);
}
/*
@@ -466,23 +460,21 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
bool implicit_fb = snd_usb_endpoint_implicit_feedback_sink(ep);
while (ep_state_running(ep)) {
-
- unsigned long flags;
struct snd_usb_packet_info *packet;
struct snd_urb_ctx *ctx = NULL;
int err, i;
- spin_lock_irqsave(&ep->lock, flags);
- if ((!implicit_fb || ep->next_packet_queued > 0) &&
- !list_empty(&ep->ready_playback_urbs)) {
- /* take URB out of FIFO */
- ctx = list_first_entry(&ep->ready_playback_urbs,
- struct snd_urb_ctx, ready_list);
- list_del_init(&ctx->ready_list);
- if (implicit_fb)
- packet = next_packet_fifo_dequeue(ep);
+ scoped_guard(spinlock_irqsave, &ep->lock) {
+ if ((!implicit_fb || ep->next_packet_queued > 0) &&
+ !list_empty(&ep->ready_playback_urbs)) {
+ /* take URB out of FIFO */
+ ctx = list_first_entry(&ep->ready_playback_urbs,
+ struct snd_urb_ctx, ready_list);
+ list_del_init(&ctx->ready_list);
+ if (implicit_fb)
+ packet = next_packet_fifo_dequeue(ep);
+ }
}
- spin_unlock_irqrestore(&ep->lock, flags);
if (ctx == NULL)
break;
@@ -768,12 +760,8 @@ bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
const struct audioformat *fp,
const struct snd_pcm_hw_params *params)
{
- bool ret;
-
- mutex_lock(&chip->mutex);
- ret = endpoint_compatible(ep, fp, params);
- mutex_unlock(&chip->mutex);
- return ret;
+ guard(mutex)(&chip->mutex);
+ return endpoint_compatible(ep, fp, params);
}
/*
@@ -799,11 +787,11 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep;
int ep_num = is_sync_ep ? fp->sync_ep : fp->endpoint;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
ep = snd_usb_get_endpoint(chip, ep_num);
if (!ep) {
usb_audio_err(chip, "Cannot find EP 0x%x to open\n", ep_num);
- goto unlock;
+ return NULL;
}
if (!ep->opened) {
@@ -820,17 +808,13 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
ep_num, ep->iface, ep->altsetting, ep->ep_idx);
ep->iface_ref = iface_ref_find(chip, ep->iface);
- if (!ep->iface_ref) {
- ep = NULL;
- goto unlock;
- }
+ if (!ep->iface_ref)
+ return NULL;
if (fp->protocol != UAC_VERSION_1) {
ep->clock_ref = clock_ref_find(chip, fp->clock);
- if (!ep->clock_ref) {
- ep = NULL;
- goto unlock;
- }
+ if (!ep->clock_ref)
+ return NULL;
ep->clock_ref->opened++;
}
@@ -859,16 +843,13 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
ep->implicit_fb_sync);
} else {
- if (WARN_ON(!ep->iface_ref)) {
- ep = NULL;
- goto unlock;
- }
+ if (WARN_ON(!ep->iface_ref))
+ return NULL;
if (!endpoint_compatible(ep, fp, params)) {
usb_audio_err(chip, "Incompatible EP setup for 0x%x\n",
ep_num);
- ep = NULL;
- goto unlock;
+ return NULL;
}
usb_audio_dbg(chip, "Reopened EP 0x%x (count %d)\n",
@@ -879,9 +860,6 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
ep->iface_ref->need_setup = true;
ep->opened++;
-
- unlock:
- mutex_unlock(&chip->mutex);
return ep;
}
@@ -964,7 +942,7 @@ retry:
void snd_usb_endpoint_close(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep)
{
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n",
ep->ep_num, ep->opened);
@@ -985,7 +963,6 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
ep->clock_ref = NULL;
usb_audio_dbg(chip, "EP 0x%x closed\n", ep->ep_num);
}
- mutex_unlock(&chip->mutex);
}
/* Prepare for suspening EP, called from the main suspend handler */
@@ -1047,7 +1024,6 @@ void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep)
static int stop_urbs(struct snd_usb_endpoint *ep, bool force, bool keep_pending)
{
unsigned int i;
- unsigned long flags;
if (!force && atomic_read(&ep->running))
return -EBUSY;
@@ -1055,11 +1031,11 @@ static int stop_urbs(struct snd_usb_endpoint *ep, bool force, bool keep_pending)
if (!ep_state_update(ep, EP_STATE_RUNNING, EP_STATE_STOPPING))
return 0;
- spin_lock_irqsave(&ep->lock, flags);
- INIT_LIST_HEAD(&ep->ready_playback_urbs);
- ep->next_packet_head = 0;
- ep->next_packet_queued = 0;
- spin_unlock_irqrestore(&ep->lock, flags);
+ scoped_guard(spinlock_irqsave, &ep->lock) {
+ INIT_LIST_HEAD(&ep->ready_playback_urbs);
+ ep->next_packet_head = 0;
+ ep->next_packet_queued = 0;
+ }
if (keep_pending)
return 0;
@@ -1360,16 +1336,16 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep)
{
const struct audioformat *fmt = ep->cur_audiofmt;
- int err = 0;
+ int err;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (!ep->need_setup)
- goto unlock;
+ return 0;
/* release old buffers, if any */
err = release_urbs(ep, false);
if (err < 0)
- goto unlock;
+ return err;
ep->datainterval = fmt->datainterval;
ep->maxpacksize = fmt->maxpacksize;
@@ -1407,7 +1383,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
usb_audio_dbg(chip, "Set up %d URBS, ret=%d\n", ep->nurbs, err);
if (err < 0)
- goto unlock;
+ return err;
/* some unit conversions in runtime */
ep->maxframesize = ep->maxpacksize / ep->cur_frame_bytes;
@@ -1419,8 +1395,6 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
err = 0;
}
- unlock:
- mutex_unlock(&chip->mutex);
return err;
}
@@ -1467,11 +1441,11 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
bool iface_first;
int err = 0;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (WARN_ON(!ep->iface_ref))
- goto unlock;
+ return 0;
if (!ep->need_prepare)
- goto unlock;
+ return 0;
/* If the interface has been already set up, just set EP parameters */
if (!ep->iface_ref->need_setup) {
@@ -1481,7 +1455,7 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
if (ep->cur_audiofmt->protocol == UAC_VERSION_1) {
err = init_sample_rate(chip, ep);
if (err < 0)
- goto unlock;
+ return err;
}
goto done;
}
@@ -1499,37 +1473,33 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
if (iface_first) {
err = endpoint_set_interface(chip, ep, true);
if (err < 0)
- goto unlock;
+ return err;
}
err = snd_usb_init_pitch(chip, ep->cur_audiofmt);
if (err < 0)
- goto unlock;
+ return err;
err = init_sample_rate(chip, ep);
if (err < 0)
- goto unlock;
+ return err;
err = snd_usb_select_mode_quirk(chip, ep->cur_audiofmt);
if (err < 0)
- goto unlock;
+ return err;
/* for UAC2/3, enable the interface altset here at last */
if (!iface_first) {
err = endpoint_set_interface(chip, ep, true);
if (err < 0)
- goto unlock;
+ return err;
}
ep->iface_ref->need_setup = false;
done:
ep->need_prepare = false;
- err = 1;
-
-unlock:
- mutex_unlock(&chip->mutex);
- return err;
+ return 1;
}
EXPORT_SYMBOL_GPL(snd_usb_endpoint_prepare);
@@ -1541,14 +1511,13 @@ int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock)
if (!clock)
return 0;
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
list_for_each_entry(ref, &chip->clock_ref_list, list) {
if (ref->clock == clock) {
rate = ref->rate;
break;
}
}
- mutex_unlock(&chip->mutex);
return rate;
}
@@ -1898,9 +1867,8 @@ static void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
* If the frequency looks valid, set it.
* This value is referred to in prepare_playback_urb().
*/
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
ep->freqm = f;
- spin_unlock_irqrestore(&ep->lock, flags);
} else {
/*
* Out of range; maybe the shift value is wrong.
diff --git a/sound/usb/fcp.c b/sound/usb/fcp.c
index 98f9964311a7..5ee8d8b66058 100644
--- a/sound/usb/fcp.c
+++ b/sound/usb/fcp.c
@@ -820,7 +820,6 @@ static long fcp_hwdep_read(struct snd_hwdep *hw, char __user *buf,
{
struct usb_mixer_interface *mixer = hw->private_data;
struct fcp_data *private = mixer->private_data;
- unsigned long flags;
long ret = 0;
u32 event;
@@ -832,10 +831,10 @@ static long fcp_hwdep_read(struct snd_hwdep *hw, char __user *buf,
if (ret)
return ret;
- spin_lock_irqsave(&private->notify.lock, flags);
- event = private->notify.event;
- private->notify.event = 0;
- spin_unlock_irqrestore(&private->notify.lock, flags);
+ scoped_guard(spinlock_irqsave, &private->notify.lock) {
+ event = private->notify.event;
+ private->notify.event = 0;
+ }
if (copy_to_user(buf, &event, sizeof(event)))
return -EFAULT;
@@ -946,11 +945,9 @@ static void fcp_notify(struct urb *urb)
}
if (data) {
- unsigned long flags;
-
- spin_lock_irqsave(&private->notify.lock, flags);
- private->notify.event |= data;
- spin_unlock_irqrestore(&private->notify.lock, flags);
+ scoped_guard(spinlock_irqsave, &private->notify.lock) {
+ private->notify.event |= data;
+ }
wake_up_interruptible(&private->notify.queue);
}
diff --git a/sound/usb/hiface/chip.c b/sound/usb/hiface/chip.c
index 95385e90882c..bce28f683666 100644
--- a/sound/usb/hiface/chip.c
+++ b/sound/usb/hiface/chip.c
@@ -101,7 +101,7 @@ static int hiface_chip_probe(struct usb_interface *intf,
/* check whether the card is already registered */
chip = NULL;
- mutex_lock(&register_mutex);
+ guard(mutex)(&register_mutex);
for (i = 0; i < SNDRV_CARDS; i++)
if (enable[i])
@@ -109,13 +109,12 @@ static int hiface_chip_probe(struct usb_interface *intf,
if (i >= SNDRV_CARDS) {
dev_err(&device->dev, "no available " CARD_NAME " audio device\n");
- ret = -ENODEV;
- goto err;
+ return -ENODEV;
}
ret = hiface_chip_create(intf, device, i, quirk, &chip);
if (ret < 0)
- goto err;
+ return ret;
ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
if (ret < 0)
@@ -127,15 +126,11 @@ static int hiface_chip_probe(struct usb_interface *intf,
goto err_chip_destroy;
}
- mutex_unlock(&register_mutex);
-
usb_set_intfdata(intf, chip);
return 0;
err_chip_destroy:
snd_card_free(chip->card);
-err:
- mutex_unlock(&register_mutex);
return ret;
}
diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c
index cf650fab54d7..27cd427fbaa5 100644
--- a/sound/usb/hiface/pcm.c
+++ b/sound/usb/hiface/pcm.c
@@ -305,7 +305,6 @@ static void hiface_pcm_out_urb_handler(struct urb *usb_urb)
struct pcm_runtime *rt = out_urb->chip->pcm;
struct pcm_substream *sub;
bool do_period_elapsed = false;
- unsigned long flags;
int ret;
if (rt->panic || rt->stream_state == STREAM_STOPPING)
@@ -325,13 +324,12 @@ static void hiface_pcm_out_urb_handler(struct urb *usb_urb)
/* now send our playback data (if a free out urb was found) */
sub = &rt->playback;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active)
- do_period_elapsed = hiface_pcm_playback(sub, out_urb);
- else
- memset(out_urb->buffer, 0, PCM_PACKET_SIZE);
-
- spin_unlock_irqrestore(&sub->lock, flags);
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ if (sub->active)
+ do_period_elapsed = hiface_pcm_playback(sub, out_urb);
+ else
+ memset(out_urb->buffer, 0, PCM_PACKET_SIZE);
+ }
if (do_period_elapsed)
snd_pcm_period_elapsed(sub->instance);
@@ -356,7 +354,7 @@ static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
if (rt->panic)
return -EPIPE;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
alsa_rt->hw = pcm_hw;
if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -364,7 +362,6 @@ static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
if (!sub) {
struct device *device = &rt->chip->dev->dev;
- mutex_unlock(&rt->stream_mutex);
dev_err(device, "Invalid stream type\n");
return -EINVAL;
}
@@ -377,15 +374,12 @@ static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&constraints_extra_rates);
- if (ret < 0) {
- mutex_unlock(&rt->stream_mutex);
+ if (ret < 0)
return ret;
- }
}
sub->instance = alsa_sub;
sub->active = false;
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -393,23 +387,19 @@ static int hiface_pcm_close(struct snd_pcm_substream *alsa_sub)
{
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
- unsigned long flags;
if (rt->panic)
return 0;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
if (sub) {
hiface_pcm_stream_stop(rt);
/* deactivate substream */
- spin_lock_irqsave(&sub->lock, flags);
+ guard(spinlock_irqsave)(&sub->lock);
sub->instance = NULL;
sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
-
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -425,7 +415,7 @@ static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (!sub)
return -ENODEV;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
hiface_pcm_stream_stop(rt);
@@ -435,17 +425,12 @@ static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (rt->stream_state == STREAM_DISABLED) {
ret = hiface_pcm_set_rate(rt, alsa_rt->rate);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
+ if (ret)
return ret;
- }
ret = hiface_pcm_stream_start(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
+ if (ret)
return ret;
- }
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -462,16 +447,16 @@ static int hiface_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irq(&sub->lock);
- sub->active = true;
- spin_unlock_irq(&sub->lock);
+ scoped_guard(spinlock_irq, &sub->lock) {
+ sub->active = true;
+ }
return 0;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irq(&sub->lock);
- sub->active = false;
- spin_unlock_irq(&sub->lock);
+ scoped_guard(spinlock_irq, &sub->lock) {
+ sub->active = false;
+ }
return 0;
default:
@@ -483,15 +468,13 @@ static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub)
{
struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
snd_pcm_uframes_t dma_offset;
if (rt->panic || !sub)
return SNDRV_PCM_POS_XRUN;
- spin_lock_irqsave(&sub->lock, flags);
+ guard(spinlock_irqsave)(&sub->lock);
dma_offset = sub->dma_off;
- spin_unlock_irqrestore(&sub->lock, flags);
return bytes_to_frames(alsa_sub->runtime, dma_offset);
}
@@ -532,9 +515,8 @@ void hiface_pcm_abort(struct hiface_chip *chip)
if (rt) {
rt->panic = true;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
hiface_pcm_stream_stop(rt);
- mutex_unlock(&rt->stream_mutex);
}
}
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 84a9b7b76f43..9ef4faa006a0 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -145,8 +145,6 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
static void audio_in_callback(struct urb *urb)
{
int i, index, length = 0, shutdown = 0;
- unsigned long flags;
-
struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
line6pcm->in.last_frame = urb->start_frame;
@@ -156,7 +154,7 @@ static void audio_in_callback(struct urb *urb)
if (urb == line6pcm->in.urbs[index])
break;
- spin_lock_irqsave(&line6pcm->in.lock, flags);
+ guard(spinlock_irqsave)(&line6pcm->in.lock);
for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
char *fbuf;
@@ -211,8 +209,6 @@ static void audio_in_callback(struct urb *urb)
test_bit(LINE6_STREAM_PCM, &line6pcm->in.running))
line6_capture_check_period(line6pcm, length);
}
-
- spin_unlock_irqrestore(&line6pcm->in.lock, flags);
}
/* open capture callback */
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index f2f9261489a2..e97368c31417 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -286,31 +286,30 @@ static void line6_data_received(struct urb *urb)
{
struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
struct midi_buffer *mb = &line6->line6midi->midibuf_in;
- unsigned long flags;
int done;
if (urb->status == -ESHUTDOWN)
return;
if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
- spin_lock_irqsave(&line6->line6midi->lock, flags);
- done =
- line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
-
- if (done < urb->actual_length) {
- line6_midibuf_ignore(mb, done);
- dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
- done, urb->actual_length);
+ scoped_guard(spinlock_irqsave, &line6->line6midi->lock) {
+ done =
+ line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+
+ if (done < urb->actual_length) {
+ line6_midibuf_ignore(mb, done);
+ dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
+ done, urb->actual_length);
+ }
}
- spin_unlock_irqrestore(&line6->line6midi->lock, flags);
for (;;) {
- spin_lock_irqsave(&line6->line6midi->lock, flags);
- done =
- line6_midibuf_read(mb, line6->buffer_message,
- LINE6_MIDI_MESSAGE_MAXLEN,
- LINE6_MIDIBUF_READ_RX);
- spin_unlock_irqrestore(&line6->line6midi->lock, flags);
+ scoped_guard(spinlock_irqsave, &line6->line6midi->lock) {
+ done =
+ line6_midibuf_read(mb, line6->buffer_message,
+ LINE6_MIDI_MESSAGE_MAXLEN,
+ LINE6_MIDIBUF_READ_RX);
+ }
if (done <= 0)
break;
@@ -628,16 +627,12 @@ line6_hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count,
static __poll_t
line6_hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
{
- __poll_t rv;
struct usb_line6 *line6 = hwdep->private_data;
poll_wait(file, &line6->messages.wait_queue, wait);
- mutex_lock(&line6->messages.read_lock);
- rv = kfifo_len(&line6->messages.fifo) == 0 ? 0 : EPOLLIN | EPOLLRDNORM;
- mutex_unlock(&line6->messages.read_lock);
-
- return rv;
+ guard(mutex)(&line6->messages.read_lock);
+ return kfifo_len(&line6->messages.fifo) == 0 ? 0 : EPOLLIN | EPOLLRDNORM;
}
static const struct snd_hwdep_ops hwdep_ops = {
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index 1d77794b4490..4731293728e6 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -72,7 +72,6 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
*/
static void midi_sent(struct urb *urb)
{
- unsigned long flags;
int status;
int num;
struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
@@ -84,7 +83,7 @@ static void midi_sent(struct urb *urb)
if (status == -ESHUTDOWN)
return;
- spin_lock_irqsave(&line6->line6midi->lock, flags);
+ guard(spinlock_irqsave)(&line6->line6midi->lock);
num = --line6->line6midi->num_active_send_urbs;
if (num == 0) {
@@ -94,8 +93,6 @@ static void midi_sent(struct urb *urb)
if (num == 0)
wake_up(&line6->line6midi->send_wait);
-
- spin_unlock_irqrestore(&line6->line6midi->lock, flags);
}
/*
@@ -158,17 +155,14 @@ static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
int up)
{
- unsigned long flags;
struct usb_line6 *line6 =
line6_rawmidi_substream_midi(substream)->line6;
line6->line6midi->substream_transmit = substream;
- spin_lock_irqsave(&line6->line6midi->lock, flags);
+ guard(spinlock_irqsave)(&line6->line6midi->lock);
if (line6->line6midi->num_active_send_urbs == 0)
line6_midi_transmit(substream);
-
- spin_unlock_irqrestore(&line6->line6midi->lock, flags);
}
static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index c1e2a8ab66fa..f61d9f6cf754 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -182,11 +182,10 @@ static void line6_buffer_release(struct snd_line6_pcm *line6pcm,
static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
int type)
{
- unsigned long flags;
struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
int ret = 0;
- spin_lock_irqsave(&pstr->lock, flags);
+ guard(spinlock_irqsave)(&pstr->lock);
if (!test_and_set_bit(type, &pstr->running) &&
!(pstr->active_urbs || pstr->unlink_urbs)) {
pstr->count = 0;
@@ -199,7 +198,6 @@ static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
if (ret < 0)
clear_bit(type, &pstr->running);
- spin_unlock_irqrestore(&pstr->lock, flags);
return ret;
}
@@ -207,21 +205,20 @@ static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
int type)
{
- unsigned long flags;
struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
- spin_lock_irqsave(&pstr->lock, flags);
- clear_bit(type, &pstr->running);
- if (!pstr->running) {
- spin_unlock_irqrestore(&pstr->lock, flags);
- line6_unlink_audio_urbs(line6pcm, pstr);
- spin_lock_irqsave(&pstr->lock, flags);
- if (direction == SNDRV_PCM_STREAM_CAPTURE) {
- line6pcm->prev_fbuf = NULL;
- line6pcm->prev_fsize = 0;
- }
+ scoped_guard(spinlock_irqsave, &pstr->lock) {
+ clear_bit(type, &pstr->running);
+ if (pstr->running)
+ return;
+ }
+
+ line6_unlink_audio_urbs(line6pcm, pstr);
+ if (direction == SNDRV_PCM_STREAM_CAPTURE) {
+ guard(spinlock_irqsave)(&pstr->lock);
+ line6pcm->prev_fbuf = NULL;
+ line6pcm->prev_fsize = 0;
}
- spin_unlock_irqrestore(&pstr->lock, flags);
}
/* common PCM trigger callback */
@@ -295,6 +292,28 @@ snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream)
return pstr->pos_done;
}
+/* Stop and release duplex streams */
+static void __line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
+{
+ struct line6_pcm_stream *pstr;
+ int dir;
+
+ for (dir = 0; dir < 2; dir++)
+ line6_stream_stop(line6pcm, dir, type);
+ for (dir = 0; dir < 2; dir++) {
+ pstr = get_stream(line6pcm, dir);
+ line6_buffer_release(line6pcm, pstr, type);
+ }
+}
+
+/* Stop and release duplex streams */
+void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
+{
+ guard(mutex)(&line6pcm->state_mutex);
+ __line6_pcm_release(line6pcm, type);
+}
+EXPORT_SYMBOL_GPL(line6_pcm_release);
+
/* Acquire and optionally start duplex streams:
* type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR
*/
@@ -304,7 +323,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, bool start)
int ret = 0, dir;
/* TODO: We should assert SNDRV_PCM_STREAM_PLAYBACK/CAPTURE == 0/1 */
- mutex_lock(&line6pcm->state_mutex);
+ guard(mutex)(&line6pcm->state_mutex);
for (dir = 0; dir < 2; dir++) {
pstr = get_stream(line6pcm, dir);
ret = line6_buffer_acquire(line6pcm, pstr, dir, type);
@@ -321,30 +340,12 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, bool start)
}
}
error:
- mutex_unlock(&line6pcm->state_mutex);
if (ret < 0)
- line6_pcm_release(line6pcm, type);
+ __line6_pcm_release(line6pcm, type);
return ret;
}
EXPORT_SYMBOL_GPL(line6_pcm_acquire);
-/* Stop and release duplex streams */
-void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
-{
- struct line6_pcm_stream *pstr;
- int dir;
-
- mutex_lock(&line6pcm->state_mutex);
- for (dir = 0; dir < 2; dir++)
- line6_stream_stop(line6pcm, dir, type);
- for (dir = 0; dir < 2; dir++) {
- pstr = get_stream(line6pcm, dir);
- line6_buffer_release(line6pcm, pstr, type);
- }
- mutex_unlock(&line6pcm->state_mutex);
-}
-EXPORT_SYMBOL_GPL(line6_pcm_release);
-
/* common PCM hw_params callback */
int snd_line6_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
@@ -353,16 +354,14 @@ int snd_line6_hw_params(struct snd_pcm_substream *substream,
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
- mutex_lock(&line6pcm->state_mutex);
+ guard(mutex)(&line6pcm->state_mutex);
ret = line6_buffer_acquire(line6pcm, pstr, substream->stream,
LINE6_STREAM_PCM);
if (ret < 0)
- goto error;
+ return ret;
pstr->period = params_period_bytes(hw_params);
- error:
- mutex_unlock(&line6pcm->state_mutex);
- return ret;
+ return 0;
}
/* common PCM hw_free callback */
@@ -371,9 +370,8 @@ int snd_line6_hw_free(struct snd_pcm_substream *substream)
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
- mutex_lock(&line6pcm->state_mutex);
+ guard(mutex)(&line6pcm->state_mutex);
line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
- mutex_unlock(&line6pcm->state_mutex);
return 0;
}
@@ -588,7 +586,7 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
- mutex_lock(&line6pcm->state_mutex);
+ guard(mutex)(&line6pcm->state_mutex);
if (!pstr->running)
line6_wait_clear_audio_urbs(line6pcm, pstr);
@@ -602,6 +600,5 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
line6pcm->in.bytes = 0;
}
- mutex_unlock(&line6pcm->state_mutex);
return 0;
}
diff --git a/sound/usb/media.c b/sound/usb/media.c
index d48db6f3ae65..0064f8d12422 100644
--- a/sound/usb/media.c
+++ b/sound/usb/media.c
@@ -140,11 +140,10 @@ int snd_media_start_pipeline(struct snd_usb_substream *subs)
if (!mctl)
return 0;
- mutex_lock(&mctl->media_dev->graph_mutex);
+ guard(mutex)(&mctl->media_dev->graph_mutex);
if (mctl->media_dev->enable_source)
ret = mctl->media_dev->enable_source(&mctl->media_entity,
&mctl->media_pipe);
- mutex_unlock(&mctl->media_dev->graph_mutex);
return ret;
}
@@ -155,10 +154,9 @@ void snd_media_stop_pipeline(struct snd_usb_substream *subs)
if (!mctl)
return;
- mutex_lock(&mctl->media_dev->graph_mutex);
+ guard(mutex)(&mctl->media_dev->graph_mutex);
if (mctl->media_dev->disable_source)
mctl->media_dev->disable_source(&mctl->media_entity);
- mutex_unlock(&mctl->media_dev->graph_mutex);
}
static int snd_media_mixer_init(struct snd_usb_audio *chip)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index acb3bf92857c..dd8249e75970 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -265,16 +265,15 @@ static void snd_usbmidi_out_urb_complete(struct urb *urb)
struct out_urb_context *context = urb->context;
struct snd_usb_midi_out_endpoint *ep = context->ep;
unsigned int urb_index;
- unsigned long flags;
-
- spin_lock_irqsave(&ep->buffer_lock, flags);
- urb_index = context - ep->urbs;
- ep->active_urbs &= ~(1 << urb_index);
- if (unlikely(ep->drain_urbs)) {
- ep->drain_urbs &= ~(1 << urb_index);
- wake_up(&ep->drain_wait);
+
+ scoped_guard(spinlock_irqsave, &ep->buffer_lock) {
+ urb_index = context - ep->urbs;
+ ep->active_urbs &= ~(1 << urb_index);
+ if (unlikely(ep->drain_urbs)) {
+ ep->drain_urbs &= ~(1 << urb_index);
+ wake_up(&ep->drain_wait);
+ }
}
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
if (urb->status < 0) {
int err = snd_usbmidi_urb_error(urb);
if (err < 0) {
@@ -295,13 +294,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
{
unsigned int urb_index;
struct urb *urb;
- unsigned long flags;
- spin_lock_irqsave(&ep->buffer_lock, flags);
- if (ep->umidi->disconnected) {
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
+ guard(spinlock_irqsave)(&ep->buffer_lock);
+ if (ep->umidi->disconnected)
return;
- }
urb_index = ep->next_urb;
for (;;) {
@@ -325,7 +321,6 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
break;
}
ep->next_urb = urb_index;
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
}
static void snd_usbmidi_out_work(struct work_struct *work)
@@ -342,9 +337,8 @@ static void snd_usbmidi_error_timer(struct timer_list *t)
struct snd_usb_midi *umidi = timer_container_of(umidi, t, error_timer);
unsigned int i, j;
- spin_lock(&umidi->disc_lock);
+ guard(spinlock)(&umidi->disc_lock);
if (umidi->disconnected) {
- spin_unlock(&umidi->disc_lock);
return;
}
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
@@ -361,7 +355,6 @@ static void snd_usbmidi_error_timer(struct timer_list *t)
if (umidi->endpoints[i].out)
snd_usbmidi_do_output(umidi->endpoints[i].out);
}
- spin_unlock(&umidi->disc_lock);
}
/* helper function to send static data that may not DMA-able */
@@ -1148,13 +1141,11 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
struct snd_usb_midi *umidi = substream->rmidi->private_data;
struct snd_kcontrol *ctl;
- down_read(&umidi->disc_rwsem);
- if (umidi->disconnected) {
- up_read(&umidi->disc_rwsem);
+ guard(rwsem_read)(&umidi->disc_rwsem);
+ if (umidi->disconnected)
return open ? -ENODEV : 0;
- }
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
if (open) {
if (!umidi->opened[0] && !umidi->opened[1]) {
if (umidi->roland_load_ctl) {
@@ -1183,8 +1174,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
}
}
}
- mutex_unlock(&umidi->mutex);
- up_read(&umidi->disc_rwsem);
return 0;
}
@@ -1522,15 +1511,14 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
{
int i;
+ if (!umidi->disconnected)
+ snd_usbmidi_disconnect(&umidi->list);
+
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
- if (ep->out)
- snd_usbmidi_out_endpoint_delete(ep->out);
- if (ep->in)
- snd_usbmidi_in_endpoint_delete(ep->in);
+ kfree(ep->out);
}
mutex_destroy(&umidi->mutex);
- timer_shutdown_sync(&umidi->error_timer);
kfree(umidi);
}
@@ -1548,11 +1536,10 @@ void snd_usbmidi_disconnect(struct list_head *p)
* a timer may submit an URB. To reliably break the cycle
* a flag under lock must be used
*/
- down_write(&umidi->disc_rwsem);
- spin_lock_irq(&umidi->disc_lock);
- umidi->disconnected = 1;
- spin_unlock_irq(&umidi->disc_lock);
- up_write(&umidi->disc_rwsem);
+ scoped_guard(rwsem_write, &umidi->disc_rwsem) {
+ guard(spinlock_irq)(&umidi->disc_lock);
+ umidi->disconnected = 1;
+ }
timer_shutdown_sync(&umidi->error_timer);
@@ -2094,11 +2081,10 @@ static int roland_load_put(struct snd_kcontrol *kcontrol,
if (value->value.enumerated.item[0] > 1)
return -EINVAL;
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
changed = value->value.enumerated.item[0] != kcontrol->private_value;
if (changed)
kcontrol->private_value = value->value.enumerated.item[0];
- mutex_unlock(&umidi->mutex);
return changed;
}
@@ -2448,18 +2434,17 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi *umidi,
struct snd_usb_midi_in_endpoint *ep)
{
unsigned int i;
- unsigned long flags;
if (!ep)
return;
for (i = 0; i < INPUT_URBS; ++i) {
struct urb *urb = ep->urbs[i];
- spin_lock_irqsave(&umidi->disc_lock, flags);
- if (!atomic_read(&urb->use_count)) {
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+ scoped_guard(spinlock_irqsave, &umidi->disc_lock) {
+ if (!atomic_read(&urb->use_count)) {
+ urb->dev = ep->umidi->dev;
+ snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+ }
}
- spin_unlock_irqrestore(&umidi->disc_lock, flags);
}
}
@@ -2488,9 +2473,8 @@ void snd_usbmidi_suspend(struct list_head *p)
struct snd_usb_midi *umidi;
umidi = list_entry(p, struct snd_usb_midi, list);
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
snd_usbmidi_input_stop(p);
- mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_suspend);
@@ -2502,9 +2486,8 @@ void snd_usbmidi_resume(struct list_head *p)
struct snd_usb_midi *umidi;
umidi = list_entry(p, struct snd_usb_midi, list);
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
snd_usbmidi_input_start(p);
- mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_resume);
diff --git a/sound/usb/midi2.c b/sound/usb/midi2.c
index 030569fda416..e6793f3bdfc3 100644
--- a/sound/usb/midi2.c
+++ b/sound/usb/midi2.c
@@ -160,15 +160,13 @@ static void output_urb_complete(struct urb *urb)
{
struct snd_usb_midi2_urb *ctx = urb->context;
struct snd_usb_midi2_endpoint *ep = ctx->ep;
- unsigned long flags;
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
set_bit(ctx->index, &ep->urb_free);
if (urb->status >= 0 && atomic_read(&ep->running))
submit_output_urbs_locked(ep);
if (ep->urb_free == ep->urb_free_mask)
wake_up(&ep->wait);
- spin_unlock_irqrestore(&ep->lock, flags);
}
/* prepare for input submission: just set the buffer length */
@@ -189,10 +187,9 @@ static void input_urb_complete(struct urb *urb)
{
struct snd_usb_midi2_urb *ctx = urb->context;
struct snd_usb_midi2_endpoint *ep = ctx->ep;
- unsigned long flags;
int len;
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
if (ep->disconnected || urb->status < 0)
goto dequeue;
len = urb->actual_length;
@@ -208,22 +205,18 @@ static void input_urb_complete(struct urb *urb)
submit_input_urbs_locked(ep);
if (ep->urb_free == ep->urb_free_mask)
wake_up(&ep->wait);
- spin_unlock_irqrestore(&ep->lock, flags);
}
/* URB submission helper; for both direction */
static void submit_io_urbs(struct snd_usb_midi2_endpoint *ep)
{
- unsigned long flags;
-
if (!ep)
return;
- spin_lock_irqsave(&ep->lock, flags);
+ guard(spinlock_irqsave)(&ep->lock);
if (ep->direction == STR_IN)
submit_input_urbs_locked(ep);
else
submit_output_urbs_locked(ep);
- spin_unlock_irqrestore(&ep->lock, flags);
}
/* kill URBs for close, suspend and disconnect */
@@ -248,13 +241,12 @@ static void drain_urb_queue(struct snd_usb_midi2_endpoint *ep)
{
if (!ep)
return;
- spin_lock_irq(&ep->lock);
+ guard(spinlock_irq)(&ep->lock);
atomic_set(&ep->running, 0);
wait_event_lock_irq_timeout(ep->wait,
ep->disconnected ||
ep->urb_free == ep->urb_free_mask,
ep->lock, msecs_to_jiffies(500));
- spin_unlock_irq(&ep->lock);
}
/* release URBs for an EP */
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index e200e4af799c..76b6eb55dcc2 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -171,7 +171,6 @@ static void playback_urb_complete(struct urb *usb_urb)
{
struct ua101_urb *urb = (struct ua101_urb *)usb_urb;
struct ua101 *ua = urb->urb.context;
- unsigned long flags;
if (unlikely(urb->urb.status == -ENOENT || /* unlinked */
urb->urb.status == -ENODEV || /* device removed */
@@ -184,14 +183,13 @@ static void playback_urb_complete(struct urb *usb_urb)
if (test_bit(USB_PLAYBACK_RUNNING, &ua->states)) {
/* append URB to FIFO */
- spin_lock_irqsave(&ua->lock, flags);
+ guard(spinlock_irqsave)(&ua->lock);
list_add_tail(&urb->ready_list, &ua->ready_playback_urbs);
if (ua->rate_feedback_count > 0)
queue_work(system_highpri_wq, &ua->playback_work);
ua->playback.substream->runtime->delay -=
urb->urb.iso_frame_desc[0].length /
ua->playback.frame_bytes;
- spin_unlock_irqrestore(&ua->lock, flags);
}
}
@@ -249,7 +247,6 @@ static inline void add_with_wraparound(struct ua101 *ua,
static void playback_work(struct work_struct *work)
{
struct ua101 *ua = container_of(work, struct ua101, playback_work);
- unsigned long flags;
unsigned int frames;
struct ua101_urb *urb;
bool do_period_elapsed = false;
@@ -269,43 +266,43 @@ static void playback_work(struct work_struct *work)
* submitting playback URBs is possible as long as both FIFOs are
* nonempty.
*/
- spin_lock_irqsave(&ua->lock, flags);
- while (ua->rate_feedback_count > 0 &&
- !list_empty(&ua->ready_playback_urbs)) {
- /* take packet size out of FIFO */
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
-
- /* take URB out of FIFO */
- urb = list_first_entry(&ua->ready_playback_urbs,
- struct ua101_urb, ready_list);
- list_del(&urb->ready_list);
-
- /* fill packet with data or silence */
- urb->urb.iso_frame_desc[0].length =
- frames * ua->playback.frame_bytes;
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
- do_period_elapsed |= copy_playback_data(&ua->playback,
- &urb->urb,
- frames);
- else
- memset(urb->urb.transfer_buffer, 0,
- urb->urb.iso_frame_desc[0].length);
-
- /* and off you go ... */
- err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- abort_usb_playback(ua);
- abort_alsa_playback(ua);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- return;
+ scoped_guard(spinlock_irqsave, &ua->lock) {
+ while (ua->rate_feedback_count > 0 &&
+ !list_empty(&ua->ready_playback_urbs)) {
+ /* take packet size out of FIFO */
+ frames = ua->rate_feedback[ua->rate_feedback_start];
+ add_with_wraparound(ua, &ua->rate_feedback_start, 1);
+ ua->rate_feedback_count--;
+
+ /* take URB out of FIFO */
+ urb = list_first_entry(&ua->ready_playback_urbs,
+ struct ua101_urb, ready_list);
+ list_del(&urb->ready_list);
+
+ /* fill packet with data or silence */
+ urb->urb.iso_frame_desc[0].length =
+ frames * ua->playback.frame_bytes;
+ if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
+ do_period_elapsed |= copy_playback_data(&ua->playback,
+ &urb->urb,
+ frames);
+ else
+ memset(urb->urb.transfer_buffer, 0,
+ urb->urb.iso_frame_desc[0].length);
+
+ /* and off you go ... */
+ err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
+ if (unlikely(err < 0)) {
+ abort_usb_playback(ua);
+ abort_alsa_playback(ua);
+ dev_err(&ua->dev->dev, "USB request error %d: %s\n",
+ err, usb_error_string(err));
+ return;
+ }
+ ua->playback.substream->runtime->delay += frames;
}
- ua->playback.substream->runtime->delay += frames;
}
- spin_unlock_irqrestore(&ua->lock, flags);
+
if (do_period_elapsed)
snd_pcm_period_elapsed(ua->playback.substream);
}
@@ -347,7 +344,6 @@ static void capture_urb_complete(struct urb *urb)
{
struct ua101 *ua = urb->context;
struct ua101_stream *stream = &ua->capture;
- unsigned long flags;
unsigned int frames, write_ptr;
bool do_period_elapsed;
int err;
@@ -364,47 +360,45 @@ static void capture_urb_complete(struct urb *urb)
else
frames = 0;
- spin_lock_irqsave(&ua->lock, flags);
-
- if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
- do_period_elapsed = copy_capture_data(stream, urb, frames);
- else
- do_period_elapsed = false;
+ scoped_guard(spinlock_irqsave, &ua->lock) {
- if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- goto stream_stopped;
- }
+ if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
+ do_period_elapsed = copy_capture_data(stream, urb, frames);
+ else
+ do_period_elapsed = false;
+
+ if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err < 0)) {
+ dev_err(&ua->dev->dev, "USB request error %d: %s\n",
+ err, usb_error_string(err));
+ goto stream_stopped;
+ }
- /* append packet size to FIFO */
- write_ptr = ua->rate_feedback_start;
- add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
- ua->rate_feedback[write_ptr] = frames;
- if (ua->rate_feedback_count < ua->playback.queue_length) {
- ua->rate_feedback_count++;
- if (ua->rate_feedback_count ==
- ua->playback.queue_length)
- wake_up(&ua->rate_feedback_wait);
- } else {
- /*
- * Ring buffer overflow; this happens when the playback
- * stream is not running. Throw away the oldest entry,
- * so that the playback stream, when it starts, sees
- * the most recent packet sizes.
- */
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
+ /* append packet size to FIFO */
+ write_ptr = ua->rate_feedback_start;
+ add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
+ ua->rate_feedback[write_ptr] = frames;
+ if (ua->rate_feedback_count < ua->playback.queue_length) {
+ ua->rate_feedback_count++;
+ if (ua->rate_feedback_count ==
+ ua->playback.queue_length)
+ wake_up(&ua->rate_feedback_wait);
+ } else {
+ /*
+ * Ring buffer overflow; this happens when the playback
+ * stream is not running. Throw away the oldest entry,
+ * so that the playback stream, when it starts, sees
+ * the most recent packet sizes.
+ */
+ add_with_wraparound(ua, &ua->rate_feedback_start, 1);
+ }
+ if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
+ !list_empty(&ua->ready_playback_urbs))
+ queue_work(system_highpri_wq, &ua->playback_work);
}
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
- !list_empty(&ua->ready_playback_urbs))
- queue_work(system_highpri_wq, &ua->playback_work);
}
- spin_unlock_irqrestore(&ua->lock, flags);
-
if (do_period_elapsed)
snd_pcm_period_elapsed(stream->substream);
@@ -558,9 +552,9 @@ static int start_usb_playback(struct ua101 *ua)
clear_bit(PLAYBACK_URB_COMPLETED, &ua->states);
ua->playback.urbs[0]->urb.complete =
first_playback_urb_complete;
- spin_lock_irq(&ua->lock);
- INIT_LIST_HEAD(&ua->ready_playback_urbs);
- spin_unlock_irq(&ua->lock);
+ scoped_guard(spinlock_irq, &ua->lock) {
+ INIT_LIST_HEAD(&ua->ready_playback_urbs);
+ }
/*
* We submit the initial URBs all at once, so we have to wait for the
@@ -581,11 +575,11 @@ static int start_usb_playback(struct ua101 *ua)
for (i = 0; i < ua->playback.queue_length; ++i) {
/* all initial URBs contain silence */
- spin_lock_irq(&ua->lock);
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
- spin_unlock_irq(&ua->lock);
+ scoped_guard(spinlock_irq, &ua->lock) {
+ frames = ua->rate_feedback[ua->rate_feedback_start];
+ add_with_wraparound(ua, &ua->rate_feedback_start, 1);
+ ua->rate_feedback_count--;
+ }
urb = &ua->playback.urbs[i]->urb;
urb->iso_frame_desc[0].length =
frames * ua->playback.frame_bytes;
@@ -658,11 +652,10 @@ static int capture_pcm_open(struct snd_pcm_substream *substream)
DIV_ROUND_CLOSEST(ua->rate, ua->packets_per_second);
substream->runtime->delay = substream->runtime->hw.fifo_size;
- mutex_lock(&ua->mutex);
+ guard(mutex)(&ua->mutex);
err = start_usb_capture(ua);
if (err >= 0)
set_bit(ALSA_CAPTURE_OPEN, &ua->states);
- mutex_unlock(&ua->mutex);
return err;
}
@@ -679,31 +672,28 @@ static int playback_pcm_open(struct snd_pcm_substream *substream)
DIV_ROUND_CLOSEST(ua->rate * ua->playback.queue_length,
ua->packets_per_second);
- mutex_lock(&ua->mutex);
+ guard(mutex)(&ua->mutex);
err = start_usb_capture(ua);
if (err < 0)
- goto error;
+ return err;
err = start_usb_playback(ua);
if (err < 0) {
if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
stop_usb_capture(ua);
- goto error;
+ return err;
}
set_bit(ALSA_PLAYBACK_OPEN, &ua->states);
-error:
- mutex_unlock(&ua->mutex);
- return err;
+ return 0;
}
static int capture_pcm_close(struct snd_pcm_substream *substream)
{
struct ua101 *ua = substream->private_data;
- mutex_lock(&ua->mutex);
+ guard(mutex)(&ua->mutex);
clear_bit(ALSA_CAPTURE_OPEN, &ua->states);
if (!test_bit(ALSA_PLAYBACK_OPEN, &ua->states))
stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
return 0;
}
@@ -711,12 +701,11 @@ static int playback_pcm_close(struct snd_pcm_substream *substream)
{
struct ua101 *ua = substream->private_data;
- mutex_lock(&ua->mutex);
+ guard(mutex)(&ua->mutex);
stop_usb_playback(ua);
clear_bit(ALSA_PLAYBACK_OPEN, &ua->states);
if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
return 0;
}
@@ -724,12 +713,9 @@ static int capture_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct ua101 *ua = substream->private_data;
- int err;
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- return err;
+ guard(mutex)(&ua->mutex);
+ return start_usb_capture(ua);
}
static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -738,11 +724,10 @@ static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
struct ua101 *ua = substream->private_data;
int err;
- mutex_lock(&ua->mutex);
+ guard(mutex)(&ua->mutex);
err = start_usb_capture(ua);
if (err >= 0)
err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
return err;
}
@@ -751,9 +736,9 @@ static int capture_pcm_prepare(struct snd_pcm_substream *substream)
struct ua101 *ua = substream->private_data;
int err;
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
+ scoped_guard(mutex, &ua->mutex) {
+ err = start_usb_capture(ua);
+ }
if (err < 0)
return err;
@@ -781,11 +766,11 @@ static int playback_pcm_prepare(struct snd_pcm_substream *substream)
struct ua101 *ua = substream->private_data;
int err;
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
+ scoped_guard(mutex, &ua->mutex) {
+ err = start_usb_capture(ua);
+ if (err >= 0)
+ err = start_usb_playback(ua);
+ }
if (err < 0)
return err;
@@ -843,13 +828,8 @@ static int playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static inline snd_pcm_uframes_t ua101_pcm_pointer(struct ua101 *ua,
struct ua101_stream *stream)
{
- unsigned long flags;
- unsigned int pos;
-
- spin_lock_irqsave(&ua->lock, flags);
- pos = stream->buffer_pos;
- spin_unlock_irqrestore(&ua->lock, flags);
- return pos;
+ guard(spinlock_irqsave)(&ua->lock);
+ return stream->buffer_pos;
}
static snd_pcm_uframes_t capture_pcm_pointer(struct snd_pcm_substream *subs)
@@ -1127,18 +1107,18 @@ static void free_usb_related_resources(struct ua101 *ua,
unsigned int i;
struct usb_interface *intf;
- mutex_lock(&ua->mutex);
- free_stream_urbs(&ua->capture);
- free_stream_urbs(&ua->playback);
- mutex_unlock(&ua->mutex);
+ scoped_guard(mutex, &ua->mutex) {
+ free_stream_urbs(&ua->capture);
+ free_stream_urbs(&ua->playback);
+ }
free_stream_buffers(ua, &ua->capture);
free_stream_buffers(ua, &ua->playback);
for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) {
- mutex_lock(&ua->mutex);
- intf = ua->intf[i];
- ua->intf[i] = NULL;
- mutex_unlock(&ua->mutex);
+ scoped_guard(mutex, &ua->mutex) {
+ intf = ua->intf[i];
+ ua->intf[i] = NULL;
+ }
if (intf) {
usb_set_intfdata(intf, NULL);
if (intf != interface)
@@ -1192,22 +1172,18 @@ static int ua101_probe(struct usb_interface *interface,
intf_numbers[is_ua1000][0])
return -ENODEV;
- mutex_lock(&devices_mutex);
+ guard(mutex)(&devices_mutex);
for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
if (enable[card_index] && !(devices_used & (1 << card_index)))
break;
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
+ if (card_index >= SNDRV_CARDS)
return -ENOENT;
- }
err = snd_card_new(&interface->dev,
index[card_index], id[card_index], THIS_MODULE,
sizeof(*ua), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
+ if (err < 0)
return err;
- }
card->private_free = ua101_card_free;
ua = card->private_data;
ua->dev = interface_to_usbdev(interface);
@@ -1290,13 +1266,11 @@ static int ua101_probe(struct usb_interface *interface,
usb_set_intfdata(interface, ua);
devices_used |= 1 << card_index;
- mutex_unlock(&devices_mutex);
return 0;
probe_error:
free_usb_related_resources(ua, interface);
snd_card_free(card);
- mutex_unlock(&devices_mutex);
return err;
}
@@ -1308,7 +1282,7 @@ static void ua101_disconnect(struct usb_interface *interface)
if (!ua)
return;
- mutex_lock(&devices_mutex);
+ guard(mutex)(&devices_mutex);
set_bit(DISCONNECTED, &ua->states);
wake_up(&ua->rate_feedback_wait);
@@ -1321,18 +1295,16 @@ static void ua101_disconnect(struct usb_interface *interface)
snd_usbmidi_disconnect(midi);
abort_alsa_playback(ua);
abort_alsa_capture(ua);
- mutex_lock(&ua->mutex);
- stop_usb_playback(ua);
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
+ scoped_guard(mutex, &ua->mutex) {
+ stop_usb_playback(ua);
+ stop_usb_capture(ua);
+ }
free_usb_related_resources(ua, interface);
devices_used &= ~(1 << ua->card_index);
snd_card_free_when_closed(ua->card);
-
- mutex_unlock(&devices_mutex);
}
static const struct usb_device_id ua101_ids[] = {
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 63b300bc67ba..34bcbfd8b54e 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -313,8 +313,8 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
int timeout = 10;
int idx = 0, err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
return -EIO;
while (timeout-- > 0) {
@@ -324,20 +324,15 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
validx, idx, buf, val_len);
if (err >= val_len) {
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
- err = 0;
- goto out;
+ return 0;
} else if (err == -ETIMEDOUT) {
- goto out;
+ return err;
}
}
usb_audio_dbg(chip,
"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, idx, cval->val_type);
- err = -EINVAL;
-
- out:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return -EINVAL;
}
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
@@ -362,14 +357,16 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
memset(buf, 0, sizeof(buf));
- if (snd_usb_lock_shutdown(chip))
- return -EIO;
+ {
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err)
+ return -EIO;
- idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx, idx, buf, size);
- snd_usb_unlock_shutdown(chip);
+ idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
+ ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+ validx, idx, buf, size);
+ }
if (ret < 0) {
usb_audio_dbg(chip,
@@ -484,8 +481,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
buf[2] = (value_set >> 16) & 0xff;
buf[3] = (value_set >> 24) & 0xff;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
return -EIO;
while (timeout-- > 0) {
@@ -494,20 +491,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
usb_sndctrlpipe(chip->dev, 0), request,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
validx, idx, buf, val_len);
- if (err >= 0) {
- err = 0;
- goto out;
- } else if (err == -ETIMEDOUT) {
- goto out;
- }
+ if (err >= 0)
+ return 0;
+ else if (err == -ETIMEDOUT)
+ return err;
}
usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
request, validx, idx, cval->val_type, buf[0], buf[1]);
- err = -EINVAL;
-
- out:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return -EINVAL;
}
static int set_cur_ctl_value(struct usb_mixer_elem_info *cval,
@@ -1191,6 +1182,13 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
cval->res = 1;
}
break;
+ case USB_ID(0x3302, 0x12db): /* MOONDROP Quark2 */
+ if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
+ usb_audio_info(chip,
+ "set volume quirk for MOONDROP Quark2\n");
+ cval->min = -14208; /* Mute under it */
+ }
+ break;
}
}
@@ -1494,9 +1492,11 @@ static int get_connector_value(struct usb_mixer_elem_info *cval,
validx = cval->control << 8 | 0;
- ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
- if (ret)
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err) {
+ ret = -EIO;
goto error;
+ }
idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
if (cval->head.mixer->protocol == UAC_VERSION_2) {
@@ -1517,8 +1517,6 @@ static int get_connector_value(struct usb_mixer_elem_info *cval,
*val = !!uac3_conn.bmConInserted;
}
- snd_usb_unlock_shutdown(chip);
-
if (ret < 0) {
if (name && strstr(name, "Speaker")) {
if (val)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 3df537fdb9f1..828af3095b86 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -307,9 +307,9 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
struct snd_usb_audio *chip = mixer->chip;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
if (chip->usb_id == USB_ID(0x041e, 0x3042))
err = snd_usb_ctl_msg(chip->dev,
@@ -327,7 +327,6 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
usb_sndctrlpipe(chip->dev, 0), 0x24,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
value, index + 2, NULL, 0);
- snd_usb_unlock_shutdown(chip);
return err;
}
@@ -438,15 +437,14 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
for (i = 0; jacks[i].name; ++i) {
snd_iprintf(buffer, "%s: ", jacks[i].name);
- err = snd_usb_lock_shutdown(mixer->chip);
- if (err < 0)
+ CLASS(snd_usb_lock, pm)(mixer->chip);
+ if (pm.err < 0)
return;
err = snd_usb_ctl_msg(mixer->chip->dev,
usb_rcvctrlpipe(mixer->chip->dev, 0),
UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE, 0,
jacks[i].unitid << 8, buf, 3);
- snd_usb_unlock_shutdown(mixer->chip);
if (err == 3 && (buf[0] == 3 || buf[0] == 6))
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
else
@@ -474,21 +472,18 @@ static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
int value)
{
struct snd_usb_audio *chip = mixer->chip;
- int err;
unsigned char buf[2];
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
buf[0] = 0x01;
buf[1] = value ? 0x02 : 0x01;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- 0x0400, 0x0e00, buf, 2);
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+ 0x0400, 0x0e00, buf, 2);
}
static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
@@ -804,17 +799,14 @@ static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
unsigned char status)
{
struct snd_usb_audio *chip = mixer->chip;
- int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 50, 0, &status, 1);
- snd_usb_unlock_shutdown(chip);
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0), 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ 50, 0, &status, 1);
}
static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
@@ -945,20 +937,17 @@ static int snd_mbox1_clk_switch_get(struct snd_kcontrol *kctl,
struct snd_usb_audio *chip = list->mixer->chip;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- goto err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
err = snd_mbox1_is_spdif_synced(chip);
if (err < 0)
- goto err;
+ return err;
kctl->private_value = err;
- err = 0;
ucontrol->value.enumerated.item[0] = kctl->private_value;
-err:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return 0;
}
static int snd_mbox1_clk_switch_update(struct usb_mixer_interface *mixer, int is_spdif_sync)
@@ -966,27 +955,24 @@ static int snd_mbox1_clk_switch_update(struct usb_mixer_interface *mixer, int is
struct snd_usb_audio *chip = mixer->chip;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
err = snd_mbox1_is_spdif_input(chip);
if (err < 0)
- goto err;
+ return err;
err = snd_mbox1_is_spdif_synced(chip);
if (err < 0)
- goto err;
+ return err;
/* FIXME: hardcoded sample rate */
err = snd_mbox1_set_clk_source(chip, is_spdif_sync ? 0 : 48000);
if (err < 0)
- goto err;
+ return err;
- err = snd_mbox1_is_spdif_synced(chip);
-err:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_mbox1_is_spdif_synced(chip);
}
static int snd_mbox1_clk_switch_put(struct snd_kcontrol *kctl,
@@ -1037,26 +1023,23 @@ static int snd_mbox1_src_switch_update(struct usb_mixer_interface *mixer, int is
struct snd_usb_audio *chip = mixer->chip;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
err = snd_mbox1_is_spdif_input(chip);
if (err < 0)
- goto err;
+ return err;
err = snd_mbox1_set_input_source(chip, is_spdif_input);
if (err < 0)
- goto err;
+ return err;
err = snd_mbox1_is_spdif_input(chip);
if (err < 0)
- goto err;
+ return err;
- err = snd_mbox1_is_spdif_synced(chip);
-err:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_mbox1_is_spdif_synced(chip);
}
static int snd_mbox1_src_switch_put(struct snd_kcontrol *kctl,
@@ -1167,17 +1150,14 @@ static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
{
struct snd_usb_audio *chip = list->mixer->chip;
unsigned int pval = list->kctl->private_value;
- int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
- (pval >> 16) & 0xff,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- pval >> 24, pval & 0xffff, NULL, 0, 1000);
- snd_usb_unlock_shutdown(chip);
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ return usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
+ (pval >> 16) & 0xff,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ pval >> 24, pval & 0xffff, NULL, 0, 1000);
}
static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
@@ -1329,23 +1309,20 @@ static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
struct snd_usb_audio *chip = list->mixer->chip;
unsigned int pval = list->kctl->private_value;
unsigned char value[2];
- int err;
value[0] = pval >> 24;
value[1] = 0;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0),
- UAC_SET_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- pval & 0xff00,
- snd_usb_ctrl_intf(list->mixer->hostif) | ((pval & 0xff) << 8),
- value, 2);
- snd_usb_unlock_shutdown(chip);
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0),
+ UAC_SET_CUR,
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+ pval & 0xff00,
+ snd_usb_ctrl_intf(list->mixer->hostif) | ((pval & 0xff) << 8),
+ value, 2);
}
static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
@@ -1908,9 +1885,9 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
unsigned char data[3];
int rate;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
@@ -1918,15 +1895,11 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
/* use known values for that card: interface#1 altsetting#1 */
iface = usb_ifnum_to_if(chip->dev, 1);
- if (!iface || iface->num_altsetting < 2) {
- err = -EINVAL;
- goto end;
- }
+ if (!iface || iface->num_altsetting < 2)
+ return -EINVAL;
alts = &iface->altsetting[1];
- if (get_iface_desc(alts)->bNumEndpoints < 1) {
- err = -EINVAL;
- goto end;
- }
+ if (get_iface_desc(alts)->bNumEndpoints < 1)
+ return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
err = snd_usb_ctl_msg(chip->dev,
@@ -1938,16 +1911,13 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
data,
sizeof(data));
if (err < 0)
- goto end;
+ return err;
rate = data[0] | (data[1] << 8) | (data[2] << 16);
ucontrol->value.iec958.status[3] = (rate == 48000) ?
IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
- err = 0;
- end:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return 0;
}
static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
@@ -1957,9 +1927,9 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
u8 reg;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
reg = ((pval >> 4) & 0xf0) | (pval & 0x0f);
err = snd_usb_ctl_msg(chip->dev,
@@ -1971,7 +1941,7 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
NULL,
0);
if (err < 0)
- goto end;
+ return err;
reg = (pval & IEC958_AES0_NONAUDIO) ? 0xa0 : 0x20;
reg |= (pval >> 12) & 0x0f;
@@ -1983,11 +1953,6 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
3,
NULL,
0);
- if (err < 0)
- goto end;
-
- end:
- snd_usb_unlock_shutdown(chip);
return err;
}
@@ -2042,23 +2007,19 @@ static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
{
struct snd_usb_audio *chip = list->mixer->chip;
u8 reg = list->kctl->private_value;
- int err;
-
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0),
- UAC_SET_CUR,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- reg,
- 9,
- NULL,
- 0);
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0),
+ UAC_SET_CUR,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ reg,
+ 9,
+ NULL,
+ 0);
}
static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
@@ -2137,21 +2098,18 @@ static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer,
unsigned char state)
{
struct snd_usb_audio *chip = mixer->chip;
- int err;
unsigned char buff[2];
buff[0] = 0x02;
buff[1] = state ? 0x02 : 0x00;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- 0x0202, 3, buff, 2);
- snd_usb_unlock_shutdown(chip);
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 0x0202, 3, buff, 2);
}
static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol,
@@ -2273,32 +2231,28 @@ static int realtek_ctl_connector_get(struct snd_kcontrol *kcontrol,
bool presence;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
err = realtek_hda_get(chip,
HDA_VERB_CMD(AC_VERB_GET_PIN_SENSE, node_id, 0),
&sense);
if (err < 0)
- goto err;
+ return err;
if (pv & REALTEK_MIC_FLAG) {
err = realtek_hda_set(chip,
HDA_VERB_CMD(AC_VERB_SET_COEF_INDEX,
REALTEK_VENDOR_REGISTERS,
REALTEK_CBJ_CTRL2));
if (err < 0)
- goto err;
+ return err;
err = realtek_hda_get(chip,
HDA_VERB_CMD(AC_VERB_GET_PROC_COEF,
REALTEK_VENDOR_REGISTERS, 0),
&cbj_ctrl2);
if (err < 0)
- goto err;
+ return err;
}
-err:
- snd_usb_unlock_shutdown(chip);
- if (err < 0)
- return err;
presence = sense & AC_PINSENSE_PRESENCE;
if (pv & REALTEK_MIC_FLAG)
@@ -2485,14 +2439,11 @@ static int snd_rme_get_status1(struct snd_kcontrol *kcontrol,
{
struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
struct snd_usb_audio *chip = list->mixer->chip;
- int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
- err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, status1);
- snd_usb_unlock_shutdown(chip);
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ return snd_rme_read_value(chip, SND_RME_GET_STATUS1, status1);
}
static int snd_rme_rate_get(struct snd_kcontrol *kcontrol,
@@ -2609,22 +2560,19 @@ static int snd_rme_current_freq_get(struct snd_kcontrol *kcontrol,
unsigned int freq;
int err;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, &status1);
if (err < 0)
- goto end;
+ return err;
err = snd_rme_read_value(chip, SND_RME_GET_CURRENT_FREQ, &den);
if (err < 0)
- goto end;
+ return err;
freq = (den == 0) ? 0 : div64_u64(num, den);
freq <<= SND_RME_CLK_FREQMUL(status1);
ucontrol->value.integer.value[0] = freq;
-
-end:
- snd_usb_unlock_shutdown(chip);
- return err;
+ return 0;
}
static int snd_rme_rate_info(struct snd_kcontrol *kcontrol,
@@ -2831,13 +2779,12 @@ enum {
static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
u8 index, u8 value)
{
- int err;
u16 usb_req, usb_idx, usb_val;
struct snd_usb_audio *chip = mixer->chip;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
if (reg == SND_BBFPRO_CTL_REG1) {
usb_req = SND_BBFPRO_USBREQ_CTL_REG1;
@@ -2854,13 +2801,10 @@ static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
usb_val = value ? usb_idx : 0;
}
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), usb_req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- usb_val, usb_idx, NULL, 0);
-
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0), usb_req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ usb_val, usb_idx, NULL, 0);
}
static int snd_bbfpro_ctl_get(struct snd_kcontrol *kcontrol,
@@ -2975,7 +2919,6 @@ static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
static int snd_bbfpro_gain_update(struct usb_mixer_interface *mixer,
u8 channel, u8 gain)
{
- int err;
struct snd_usb_audio *chip = mixer->chip;
if (channel < 2) {
@@ -2986,18 +2929,15 @@ static int snd_bbfpro_gain_update(struct usb_mixer_interface *mixer,
gain = ((gain % 6) << 5) | (60 / 3);
}
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
-
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0),
- SND_BBFPRO_USBREQ_GAIN,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- gain, channel, NULL, 0);
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0),
+ SND_BBFPRO_USBREQ_GAIN,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ gain, channel, NULL, 0);
}
static int snd_bbfpro_gain_get(struct snd_kcontrol *kcontrol,
@@ -3084,14 +3024,13 @@ static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
u32 value)
{
struct snd_usb_audio *chip = mixer->chip;
- int err;
u16 idx;
u16 usb_idx, usb_val;
u32 v;
- err = snd_usb_lock_shutdown(chip);
- if (err < 0)
- return err;
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
idx = index & SND_BBFPRO_MIXER_IDX_MASK;
// 18 bit linear volume, split so 2 bits end up in index.
@@ -3099,15 +3038,12 @@ static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
usb_idx = idx | (v & 0x3) << 14;
usb_val = (v >> 2) & 0xffff;
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0),
- SND_BBFPRO_USBREQ_MIXER,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE,
- usb_val, usb_idx, NULL, 0);
-
- snd_usb_unlock_shutdown(chip);
- return err;
+ return snd_usb_ctl_msg(chip->dev,
+ usb_sndctrlpipe(chip->dev, 0),
+ SND_BBFPRO_USBREQ_MIXER,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE,
+ usb_val, usb_idx, NULL, 0);
}
static int snd_bbfpro_vol_get(struct snd_kcontrol *kcontrol,
@@ -4212,26 +4148,22 @@ static int snd_djm_controls_info(struct snd_kcontrol *kctl,
static int snd_djm_controls_update(struct usb_mixer_interface *mixer,
u8 device_idx, u8 group, u16 value)
{
- int err;
const struct snd_djm_device *device = &snd_djm_devices[device_idx];
if (group >= device->ncontrols || value >= device->controls[group].noptions)
return -EINVAL;
- err = snd_usb_lock_shutdown(mixer->chip);
- if (err)
- return err;
-
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0),
- USB_REQ_SET_FEATURE,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- device->controls[group].options[value],
- device->controls[group].wIndex,
- NULL, 0);
+ CLASS(snd_usb_lock, pm)(mixer->chip);
+ if (pm.err)
+ return pm.err;
- snd_usb_unlock_shutdown(mixer->chip);
- return err;
+ return snd_usb_ctl_msg(mixer->chip->dev,
+ usb_sndctrlpipe(mixer->chip->dev, 0),
+ USB_REQ_SET_FEATURE,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ device->controls[group].options[value],
+ device->controls[group].wIndex,
+ NULL, 0);
}
static int snd_djm_controls_get(struct snd_kcontrol *kctl,
@@ -4611,10 +4543,20 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
}
/* lowest playback value is muted on some devices */
- if (mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_MIN_MUTE)
- if (strstr(kctl->id.name, "Playback"))
+ if (mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE)
+ if (strstr(kctl->id.name, "Playback")) {
+ usb_audio_info(mixer->chip,
+ "applying playback min mute quirk\n");
cval->min_mute = 1;
+ }
+ /* lowest capture value is muted on some devices */
+ if (mixer->chip->quirk_flags & QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE)
+ if (strstr(kctl->id.name, "Capture")) {
+ usb_audio_info(mixer->chip,
+ "applying capture min mute quirk\n");
+ cval->min_mute = 1;
+ }
/* ALSA-ify some Plantronics headset control names */
if (USB_ID_VENDOR(mixer->chip->usb_id) == 0x047f &&
(cval->control == UAC_FU_MUTE || cval->control == UAC_FU_VOLUME))
diff --git a/sound/usb/mixer_s1810c.c b/sound/usb/mixer_s1810c.c
index fac4bbc6b275..15960d25e748 100644
--- a/sound/usb/mixer_s1810c.c
+++ b/sound/usb/mixer_s1810c.c
@@ -93,6 +93,7 @@ struct s1810c_ctl_packet {
#define SC1810C_CTL_LINE_SW 0
#define SC1810C_CTL_MUTE_SW 1
+#define SC1824C_CTL_MONO_SW 2
#define SC1810C_CTL_AB_SW 3
#define SC1810C_CTL_48V_SW 4
@@ -123,6 +124,7 @@ struct s1810c_state_packet {
#define SC1810C_STATE_48V_SW 58
#define SC1810C_STATE_LINE_SW 59
#define SC1810C_STATE_MUTE_SW 60
+#define SC1824C_STATE_MONO_SW 61
#define SC1810C_STATE_AB_SW 62
struct s1810_mixer_state {
@@ -145,12 +147,7 @@ snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a,
pkt.b = b;
pkt.c = c;
pkt.d = d;
- /*
- * Value for settings 0/1 for this
- * output channel is always 0 (probably because
- * there is no ADAT output on 1810c)
- */
- pkt.e = (c == 4) ? 0 : e;
+ pkt.e = e;
ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
SC1810C_CMD_REQ,
@@ -213,115 +210,164 @@ snd_sc1810c_get_status_field(struct usb_device *dev,
*/
static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
{
- u32 a, b, c, e, n, off;
+ u32 a, b, c, e, n, off, left, right;
struct usb_device *dev = chip->dev;
- /* Set initial volume levels ? */
- a = 0x64;
- e = 0xbc;
- for (n = 0; n < 2; n++) {
- off = n * 18;
- for (b = off; b < 18 + off; b++) {
- /* This channel to all outputs ? */
- for (c = 0; c <= 8; c++) {
+ switch (chip->usb_id) {
+ case USB_ID(0x194f, 0x010c): /* 1810c */
+ /* Set initial volume levels ? */
+ a = 0x64;
+ e = 0xbc;
+ for (n = 0; n < 2; n++) {
+ off = n * 18;
+ for (b = off; b < 18 + off; b++) {
+ /* This channel to all outputs ? */
+ for (c = 0; c <= 8; c++) {
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+ }
+ /* This channel to main output (again) */
+ snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
+ }
+ /*
+ * I noticed on UC that DAW channels have different
+ * initial volumes, so this makes sense.
+ */
+ e = 0xb53bf0;
+ }
+
+ /* Connect analog outputs ? */
+ a = 0x65;
+ e = 0x01000000;
+ for (b = 1; b < 3; b++) {
+ snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
+ }
+ snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
+
+ /* Set initial volume levels for S/PDIF mappings ? */
+ a = 0x64;
+ e = 0xbc;
+ c = 3;
+ for (n = 0; n < 2; n++) {
+ off = n * 18;
+ for (b = off; b < 18 + off; b++) {
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
}
- /* This channel to main output (again) */
+ e = 0xb53bf0;
+ }
+
+ /* Connect S/PDIF output ? */
+ a = 0x65;
+ e = 0x01000000;
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+
+ /* Connect all outputs (again) ? */
+ a = 0x65;
+ e = 0x01000000;
+ for (b = 0; b < 4; b++) {
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
}
- /*
- * I noticed on UC that DAW channels have different
- * initial volumes, so this makes sense.
- */
- e = 0xb53bf0;
- }
- /* Connect analog outputs ? */
- a = 0x65;
- e = 0x01000000;
- for (b = 1; b < 3; b++) {
- snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
- }
- snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
-
- /* Set initial volume levels for S/PDIF mappings ? */
- a = 0x64;
- e = 0xbc;
- c = 3;
- for (n = 0; n < 2; n++) {
- off = n * 18;
- for (b = off; b < 18 + off; b++) {
- snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+ /* Basic routing to get sound out of the device */
+ a = 0x64;
+ e = 0x01000000;
+ for (c = 0; c < 4; c++) {
+ for (b = 0; b < 36; b++) {
+ if ((c == 0 && b == 18) || /* DAW1/2 -> Main */
+ (c == 1 && b == 20) || /* DAW3/4 -> Line3/4 */
+ (c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */
+ (c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */
+ /* Left */
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
+ b++;
+ /* Right */
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+ } else {
+ /* Leave the rest disconnected */
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
+ }
+ }
}
- e = 0xb53bf0;
- }
- /* Connect S/PDIF output ? */
- a = 0x65;
- e = 0x01000000;
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
-
- /* Connect all outputs (again) ? */
- a = 0x65;
- e = 0x01000000;
- for (b = 0; b < 4; b++) {
- snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
- }
-
- /* Basic routing to get sound out of the device */
- a = 0x64;
- e = 0x01000000;
- for (c = 0; c < 4; c++) {
- for (b = 0; b < 36; b++) {
- if ((c == 0 && b == 18) || /* DAW1/2 -> Main */
- (c == 1 && b == 20) || /* DAW3/4 -> Line3/4 */
- (c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */
- (c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */
- /* Left */
+ /* Set initial volume levels for S/PDIF (again) ? */
+ a = 0x64;
+ e = 0xbc;
+ c = 3;
+ for (n = 0; n < 2; n++) {
+ off = n * 18;
+ for (b = off; b < 18 + off; b++) {
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
- b++;
- /* Right */
- snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
- } else {
- /* Leave the rest disconnected */
- snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
- snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
}
+ e = 0xb53bf0;
}
- }
- /* Set initial volume levels for S/PDIF (again) ? */
- a = 0x64;
- e = 0xbc;
- c = 3;
- for (n = 0; n < 2; n++) {
- off = n * 18;
- for (b = off; b < 18 + off; b++) {
+ /* Connect S/PDIF outputs (again) ? */
+ a = 0x65;
+ e = 0x01000000;
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+
+ /* Again ? */
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+ snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+ break;
+
+ case USB_ID(0x194f, 0x010d): /* 1824c */
+ /* Set all output faders to unity gain */
+ a = 0x65;
+ c = 0x00;
+ e = 0x01000000;
+
+ for (b = 0; b < 9; b++) {
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
}
- e = 0xb53bf0;
- }
-
- /* Connect S/PDIF outputs (again) ? */
- a = 0x65;
- e = 0x01000000;
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
-
- /* Again ? */
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
- snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+ /* Set
+ * Daw 1 -> Line out 1 (left), Daw 2 -> Line out 2 (right)
+ * Daw 3 -> Line out 3, (left) Daw 4 -> Line out 4 (right)
+ * Daw 5 -> Line out 5, (left) Daw 6 -> Line out 6 (right)
+ * Daw 7 -> Line out 7, (left) Daw 8 -> Line out 8 (right)
+ * Daw 9 -> SPDIF out 1, (left) Daw 10 -> SPDIF out 2 (right)
+ * Daw 11 -> ADAT out 1, (left) Daw 12 -> ADAT out 2 (right)
+ * Daw 13 -> ADAT out 3, (left) Daw 14 -> ADAT out 4 (right)
+ * Daw 15 -> ADAT out 5, (left) Daw 16 -> ADAT out 6 (right)
+ * Daw 17 -> ADAT out 7, (left) Daw 18 -> ADAT out 8 (right)
+ * Everything else muted
+ */
+ a = 0x64;
+ /* The first Daw channel is channel 18 */
+ left = 18;
+
+ for (c = 0; c < 9; c++) {
+ right = left + 1;
+
+ for (b = 0; b < 36; b++) {
+ if (b == left) {
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x01000000);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
+ } else if (b == right) {
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x01000000);
+ } else {
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
+ snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
+ }
+ }
+ left += 2;
+ }
+ break;
+ }
return 0;
}
@@ -338,18 +384,16 @@ snd_s1810c_get_switch_state(struct usb_mixer_interface *mixer,
struct s1810_mixer_state *private = mixer->private_data;
u32 field = 0;
u32 ctl_idx = (u32) (kctl->private_value & 0xFF);
- int ret = 0;
+ int ret;
- mutex_lock(&private->usb_mutex);
+ guard(mutex)(&private->usb_mutex);
ret = snd_sc1810c_get_status_field(chip->dev, &field,
ctl_idx, &private->seqnum);
if (ret < 0)
- goto unlock;
+ return ret;
*state = field;
- unlock:
- mutex_unlock(&private->usb_mutex);
- return ret ? ret : 0;
+ return ret;
}
/*
@@ -366,12 +410,9 @@ snd_s1810c_set_switch_state(struct usb_mixer_interface *mixer,
u32 pval = (u32) kctl->private_value;
u32 ctl_id = (pval >> 8) & 0xFF;
u32 ctl_val = (pval >> 16) & 0x1;
- int ret = 0;
- mutex_lock(&private->usb_mutex);
- ret = snd_s1810c_send_ctl_packet(chip->dev, 0, 0, 0, ctl_id, ctl_val);
- mutex_unlock(&private->usb_mutex);
- return ret;
+ guard(mutex)(&private->usb_mutex);
+ return snd_s1810c_send_ctl_packet(chip->dev, 0, 0, 0, ctl_id, ctl_val);
}
/* Generic get/set/init functions for switch controls */
@@ -386,12 +427,12 @@ snd_s1810c_switch_get(struct snd_kcontrol *kctl,
u32 pval = (u32) kctl->private_value;
u32 ctl_idx = pval & 0xFF;
u32 state = 0;
- int ret = 0;
+ int ret;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
ret = snd_s1810c_get_switch_state(mixer, kctl, &state);
if (ret < 0)
- goto unlock;
+ return ret;
switch (ctl_idx) {
case SC1810C_STATE_LINE_SW:
@@ -402,9 +443,7 @@ snd_s1810c_switch_get(struct snd_kcontrol *kctl,
ctl_elem->value.integer.value[0] = (long)state;
}
- unlock:
- mutex_unlock(&private->data_mutex);
- return (ret < 0) ? ret : 0;
+ return 0;
}
static int
@@ -420,10 +459,10 @@ snd_s1810c_switch_set(struct snd_kcontrol *kctl,
u32 newval = 0;
int ret = 0;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
ret = snd_s1810c_get_switch_state(mixer, kctl, &curval);
if (ret < 0)
- goto unlock;
+ return ret;
switch (ctl_idx) {
case SC1810C_STATE_LINE_SW:
@@ -435,14 +474,12 @@ snd_s1810c_switch_set(struct snd_kcontrol *kctl,
}
if (curval == newval)
- goto unlock;
+ return 0;
kctl->private_value &= ~(0x1 << 16);
kctl->private_value |= (unsigned int)(newval & 0x1) << 16;
ret = snd_s1810c_set_switch_state(mixer, kctl);
- unlock:
- mutex_unlock(&private->data_mutex);
return (ret < 0) ? 0 : 1;
}
@@ -502,6 +539,15 @@ static const struct snd_kcontrol_new snd_s1810c_mute_sw = {
.private_value = (SC1810C_STATE_MUTE_SW | SC1810C_CTL_MUTE_SW << 8)
};
+static const struct snd_kcontrol_new snd_s1824c_mono_sw = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mono Main Out Switch",
+ .info = snd_ctl_boolean_mono_info,
+ .get = snd_s1810c_switch_get,
+ .put = snd_s1810c_switch_set,
+ .private_value = (SC1824C_STATE_MONO_SW | SC1824C_CTL_MONO_SW << 8)
+};
+
static const struct snd_kcontrol_new snd_s1810c_48v_sw = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "48V Phantom Power On Mic Inputs Switch",
@@ -588,8 +634,17 @@ int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer)
if (ret < 0)
return ret;
- ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
- if (ret < 0)
- return ret;
+ // The 1824c has a Mono Main switch instead of a
+ // A/B select switch.
+ if (mixer->chip->usb_id == USB_ID(0x194f, 0x010d)) {
+ ret = snd_s1810c_switch_init(mixer, &snd_s1824c_mono_sw);
+ if (ret < 0)
+ return ret;
+ } else if (mixer->chip->usb_id == USB_ID(0x194f, 0x010c)) {
+ ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
+ if (ret < 0)
+ return ret;
+ }
+
return ret;
}
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 1ec203cbbd94..f2446bf3982c 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -10,8 +10,9 @@
* - Solo/2i2/4i4 Gen 4
* - Clarett 2Pre/4Pre/8Pre USB
* - Clarett+ 2Pre/4Pre/8Pre
+ * - Vocaster One/Two
*
- * Copyright (c) 2018-2024 by Geoffrey D. Bennett <g at b4.vu>
+ * Copyright (c) 2018-2025 by Geoffrey D. Bennett <g at b4.vu>
* Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com>
* Copyright (c) 2022 by Christian Colglazier <christian@cacolglazier.com>
*
@@ -75,6 +76,9 @@
* to many LinuxMusicians people and to Focusrite for hardware
* donations).
*
+ * Support for Vocaster One and Two added in Mar 2024 (thanks to many
+ * LinuxMusicians people and to Focusrite for hardware donations).
+ *
* This ALSA mixer gives access to (model-dependent):
* - input, output, mixer-matrix muxes
* - mixer-matrix gain stages
@@ -364,6 +368,21 @@ static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
"Mute Playback Switch", "Dim Playback Switch"
};
+/* Vocaster One speaker/headphone mute names */
+static const char *const vocaster_one_sp_hp_mute_names[] = {
+ "Speaker Mute Playback Switch",
+ "Headphones Mute Playback Switch",
+ NULL
+};
+
+/* Vocaster Two speaker/headphone mute names */
+static const char *const vocaster_two_sp_hp_mute_names[] = {
+ "Speaker Mute Playback Switch",
+ "Headphones 1 Mute Playback Switch",
+ "Headphones 2 Mute Playback Switch",
+ NULL
+};
+
/* The autogain_status is set based on the autogain_switch and
* raw_autogain_status values.
*
@@ -547,6 +566,7 @@ enum {
SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN,
SCARLETT2_CONFIG_BLUETOOTH_VOLUME,
SCARLETT2_CONFIG_SPDIF_MODE,
+ SCARLETT2_CONFIG_SP_HP_MUTE,
SCARLETT2_CONFIG_COUNT
};
@@ -814,6 +834,9 @@ static const struct scarlett2_config_set scarlett2_config_set_vocaster = {
[SCARLETT2_CONFIG_BLUETOOTH_VOLUME] = {
.offset = 0xbf, .size = 8, .activate = 28 },
+
+ [SCARLETT2_CONFIG_SP_HP_MUTE] = {
+ .offset = 0xab, .size = 8, .activate = 10 },
}
};
@@ -1177,6 +1200,9 @@ struct scarlett2_device_info {
/* additional description for the line out volume controls */
const char * const line_out_descrs[SCARLETT2_ANALOGUE_MAX];
+ /* Vocaster speaker/headphone mute control names */
+ const char * const *sp_hp_mute_names;
+
/* number of sources/destinations of each port type */
const int port_count[SCARLETT2_PORT_TYPE_COUNT][SCARLETT2_PORT_DIRNS];
@@ -1249,6 +1275,7 @@ struct scarlett2_data {
u8 level_switch[SCARLETT2_LEVEL_SWITCH_MAX];
u8 pad_switch[SCARLETT2_PAD_SWITCH_MAX];
u8 dim_mute[SCARLETT2_DIM_MUTE_COUNT];
+ u8 sp_hp_mute;
u8 air_switch[SCARLETT2_AIR_SWITCH_MAX];
u8 dsp_switch[SCARLETT2_DSP_SWITCH_MAX];
s32 compressor_values[SCARLETT2_COMPRESSOR_CTLS_MAX];
@@ -1791,6 +1818,7 @@ static const struct scarlett2_device_info vocaster_one_info = {
.peq_flt_total_count = 4,
.mute_input_count = 1,
.gain_input_count = 1,
+ .sp_hp_mute_names = vocaster_one_sp_hp_mute_names,
.port_count = {
[SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
@@ -1835,6 +1863,7 @@ static const struct scarlett2_device_info vocaster_two_info = {
.mute_input_count = 2,
.gain_input_count = 2,
.has_bluetooth = 1,
+ .sp_hp_mute_names = vocaster_two_sp_hp_mute_names,
.port_count = {
[SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
@@ -2348,7 +2377,8 @@ static int scarlett2_usb(
{
struct scarlett2_data *private = mixer->private_data;
struct usb_device *dev = mixer->chip->dev;
- struct scarlett2_usb_packet *req, *resp = NULL;
+ struct scarlett2_usb_packet *req __free(kfree) = NULL;
+ struct scarlett2_usb_packet *resp __free(kfree) = NULL;
size_t req_buf_size = struct_size(req, data, req_size);
size_t resp_buf_size = struct_size(resp, data, resp_size);
int retries = 0;
@@ -2356,18 +2386,14 @@ static int scarlett2_usb(
int err;
req = kmalloc(req_buf_size, GFP_KERNEL);
- if (!req) {
- err = -ENOMEM;
- goto error;
- }
+ if (!req)
+ return -ENOMEM;
resp = kmalloc(resp_buf_size, GFP_KERNEL);
- if (!resp) {
- err = -ENOMEM;
- goto error;
- }
+ if (!resp)
+ return -ENOMEM;
- mutex_lock(&private->usb_mutex);
+ guard(mutex)(&private->usb_mutex);
/* build request message and send it */
@@ -2389,8 +2415,7 @@ retry:
mixer->chip,
"%s USB request result cmd %x was %d\n",
private->series_name, cmd, err);
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
if (!wait_for_completion_timeout(&private->cmd_done,
@@ -2400,8 +2425,7 @@ retry:
"%s USB request timed out, cmd %x\n",
private->series_name, cmd);
- err = -ETIMEDOUT;
- goto unlock;
+ return -ETIMEDOUT;
}
/* send a second message to get the response */
@@ -2418,17 +2442,14 @@ retry:
* reboot request
*/
if (cmd == SCARLETT2_USB_REBOOT &&
- (err == -ESHUTDOWN || err == -EPROTO)) {
- err = 0;
- goto unlock;
- }
+ (err == -ESHUTDOWN || err == -EPROTO))
+ return 0;
usb_audio_err(
mixer->chip,
"%s USB response result cmd %x was %d expected %zu\n",
private->series_name, cmd, err, resp_buf_size);
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
/* cmd/seq/size should match except when initialising
@@ -2451,18 +2472,12 @@ retry:
resp_size, le16_to_cpu(resp->size),
le32_to_cpu(resp->error),
le32_to_cpu(resp->pad));
- err = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
if (resp_data && resp_size > 0)
memcpy(resp_data, resp->data, resp_size);
-unlock:
- mutex_unlock(&private->usb_mutex);
-error:
- kfree(req);
- kfree(resp);
return err;
}
@@ -3321,25 +3336,20 @@ static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->sync_updated) {
err = scarlett2_update_sync(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->sync;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static const struct snd_kcontrol_new scarlett2_sync_ctl = {
@@ -3589,17 +3599,13 @@ static int scarlett2_autogain_switch_ctl_info(
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
err = scarlett2_check_input_phantom_updated(mixer);
if (err < 0)
- goto unlock;
-
- err = snd_ctl_boolean_mono_info(kctl, uinfo);
+ return err;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return snd_ctl_boolean_mono_info(kctl, uinfo);
}
static int scarlett2_autogain_switch_ctl_get(
@@ -3610,23 +3616,18 @@ static int scarlett2_autogain_switch_ctl_get(
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
ucontrol->value.enumerated.item[0] =
private->autogain_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_autogain_status_ctl_get(
@@ -3637,23 +3638,18 @@ static int scarlett2_autogain_status_ctl_get(
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
ucontrol->value.enumerated.item[0] =
private->autogain_status[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_autogain_switch_ctl_put(
@@ -3662,46 +3658,37 @@ static int scarlett2_autogain_switch_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_input_phantom_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
- if (scarlett2_phantom_is_switching(private, index)) {
- err = -EPERM;
- goto unlock;
- }
+ if (scarlett2_phantom_is_switching(private, index))
+ return -EPERM;
oval = private->autogain_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->autogain_switch[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_AUTOGAIN_SWITCH, index, val);
- if (err == 0)
- err = 1;
scarlett2_autogain_update_access(mixer);
scarlett2_autogain_notify_access(mixer);
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_autogain_status_ctl_info(
@@ -3742,16 +3729,14 @@ static int scarlett2_ag_target_ctl_info(
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -3759,9 +3744,7 @@ static int scarlett2_ag_target_ctl_info(
uinfo->value.integer.max = 0;
uinfo->value.integer.step = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_ag_target_ctl_get(
@@ -3770,26 +3753,21 @@ static int scarlett2_ag_target_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->autogain_updated) {
err = scarlett2_update_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->ag_targets[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_ag_target_ctl_put(
@@ -3798,39 +3776,32 @@ static int scarlett2_ag_target_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->ag_targets[index];
val = clamp(ucontrol->value.integer.value[0],
(long)SCARLETT2_AG_TARGET_MIN, 0L);
if (oval == val)
- goto unlock;
+ return 0;
private->ag_targets[index] = val;
/* Send new value to the device */
err = scarlett2_usb_set_config(
mixer, scarlett2_ag_target_configs[index], 1, -val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const DECLARE_TLV_DB_MINMAX(
@@ -3885,25 +3856,20 @@ static int scarlett2_input_select_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_select_updated) {
err = scarlett2_update_input_select(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->input_select_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_input_select_ctl_put(
@@ -3913,19 +3879,16 @@ static int scarlett2_input_select_ctl_put(
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
-
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->input_select_switch;
val = ucontrol->value.integer.value[0];
@@ -3936,7 +3899,7 @@ static int scarlett2_input_select_ctl_put(
val = info->gain_input_count - 1;
if (oval == val)
- goto unlock;
+ return 0;
private->input_select_switch = val;
@@ -3944,12 +3907,8 @@ static int scarlett2_input_select_ctl_put(
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_INPUT_SELECT_SWITCH,
0, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_input_select_ctl_info(
@@ -3958,43 +3917,38 @@ static int scarlett2_input_select_ctl_info(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int inputs = private->info->gain_input_count;
int i, err;
- char **values = kcalloc(inputs, sizeof(char *), GFP_KERNEL);
+ char **values __free(kfree) = NULL;
+ values = kcalloc(inputs, sizeof(char *), GFP_KERNEL);
if (!values)
return -ENOMEM;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
/* Loop through each input */
for (i = 0; i < inputs; i++) {
values[i] = kasprintf(GFP_KERNEL, "Input %d", i + 1);
if (!values[i]) {
err = -ENOMEM;
- goto unlock;
+ goto clear;
}
}
err = snd_ctl_enum_info(uinfo, 1, i,
(const char * const *)values);
-unlock:
- mutex_unlock(&private->data_mutex);
-
+clear:
for (i = 0; i < inputs; i++)
kfree(values[i]);
- kfree(values);
return err;
}
@@ -4020,22 +3974,16 @@ static int scarlett2_autogain_disables_ctl_info(struct snd_kcontrol *kctl,
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
-
- err = snd_ctl_boolean_mono_info(kctl, uinfo);
+ return err;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return snd_ctl_boolean_mono_info(kctl, uinfo);
}
static int scarlett2_input_link_ctl_get(
@@ -4044,26 +3992,21 @@ static int scarlett2_input_link_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_select_updated) {
err = scarlett2_update_input_select(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] =
private->input_link_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_input_link_ctl_put(
@@ -4072,37 +4015,30 @@ static int scarlett2_input_link_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->input_link_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->input_link_switch[index] = val;
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_INPUT_LINK_SWITCH, index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_input_link_ctl = {
@@ -4138,16 +4074,14 @@ static int scarlett2_input_gain_ctl_info(struct snd_kcontrol *kctl,
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = elem->channels;
@@ -4155,9 +4089,7 @@ static int scarlett2_input_gain_ctl_info(struct snd_kcontrol *kctl,
uinfo->value.integer.max = SCARLETT2_MAX_GAIN_VALUE;
uinfo->value.integer.step = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_input_gain_ctl_get(struct snd_kcontrol *kctl,
@@ -4166,26 +4098,21 @@ static int scarlett2_input_gain_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_gain_updated) {
err = scarlett2_update_input_gain(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] =
private->gain[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_input_gain_ctl_put(struct snd_kcontrol *kctl,
@@ -4194,38 +4121,31 @@ static int scarlett2_input_gain_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->gain[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->gain[index] = val;
/* Send gain change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_INPUT_GAIN,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_input_gain_ctl = {
@@ -4262,26 +4182,21 @@ static int scarlett2_safe_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_safe_updated) {
err = scarlett2_update_input_safe(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] =
private->safe_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_safe_ctl_put(struct snd_kcontrol *kctl,
@@ -4290,38 +4205,31 @@ static int scarlett2_safe_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->safe_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->safe_switch[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SAFE_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_safe_ctl = {
@@ -4356,20 +4264,17 @@ static int scarlett2_pcm_input_switch_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = elem->head.mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
if (private->pcm_input_switch_updated) {
err = scarlett2_update_pcm_input_switch(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->pcm_input_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_pcm_input_switch_ctl_put(
@@ -4378,21 +4283,18 @@ static int scarlett2_pcm_input_switch_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ int oval, val, err;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->pcm_input_switch;
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->pcm_input_switch = val;
@@ -4400,12 +4302,8 @@ static int scarlett2_pcm_input_switch_ctl_put(
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_PCM_INPUT_SWITCH,
0, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_pcm_input_switch_ctl_info(
@@ -4492,25 +4390,20 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->vol_updated) {
err = scarlett2_update_volumes(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->master_vol;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_headphone_volume_ctl_get(
@@ -4520,25 +4413,20 @@ static int scarlett2_headphone_volume_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->vol_updated) {
err = scarlett2_update_volumes(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->headphone_vol;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int line_out_remap(struct scarlett2_data *private, int index)
@@ -4561,25 +4449,20 @@ static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->vol_updated) {
err = scarlett2_update_volumes(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->vol[index];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl,
@@ -4589,30 +4472,24 @@ static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->vol[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->vol[index] = val;
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME,
index, val - SCARLETT2_VOLUME_BIAS);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const DECLARE_TLV_DB_MINMAX(
@@ -4691,25 +4568,20 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->dim_mute_updated) {
err = scarlett2_update_dim_mute(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->mute_switch[index];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl,
@@ -4719,32 +4591,26 @@ static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->mute_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->mute_switch[index] = val;
/* Send mute change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_MUTE_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_mute_ctl = {
@@ -4863,28 +4729,22 @@ static int scarlett2_sw_hw_enum_ctl_put(struct snd_kcontrol *kctl,
struct scarlett2_data *private = mixer->private_data;
int ctl_index = elem->control;
int index = line_out_remap(private, ctl_index);
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->vol_sw_hw_switch[index];
val = !!ucontrol->value.enumerated.item[0];
if (oval == val)
- goto unlock;
+ return 0;
err = scarlett2_sw_hw_change(mixer, ctl_index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_sw_hw_enum_ctl = {
@@ -4924,22 +4784,16 @@ static int scarlett2_level_enum_ctl_info(struct snd_kcontrol *kctl,
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
-
- err = snd_ctl_enum_info(uinfo, 1, 2, values);
+ return err;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return snd_ctl_enum_info(uinfo, 1, 2, values);
}
static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl,
@@ -4949,28 +4803,22 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
-
int index = elem->control + info->level_input_first;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_level_updated) {
err = scarlett2_update_input_level(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = scarlett2_decode_muteable(
private->level_switch[index]);
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl,
@@ -4980,26 +4828,23 @@ static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
-
int index = elem->control + info->level_input_first;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->level_switch[index];
val = !!ucontrol->value.enumerated.item[0];
if (oval == val)
- goto unlock;
+ return 0;
private->level_switch[index] = val;
@@ -5010,12 +4855,8 @@ static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl,
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_LEVEL_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_level_enum_ctl = {
@@ -5049,26 +4890,21 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_pad_updated) {
err = scarlett2_update_input_pad(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] =
private->pad_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl,
@@ -5077,34 +4913,27 @@ static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->pad_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->pad_switch[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_PAD_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_pad_ctl = {
@@ -5138,25 +4967,20 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_air_updated) {
err = scarlett2_update_input_air(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->air_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl,
@@ -5165,38 +4989,31 @@ static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->air_switch[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->air_switch[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_AIR_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_air_with_drive_ctl_info(
@@ -5210,22 +5027,16 @@ static int scarlett2_air_with_drive_ctl_info(
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_autogain_updated(mixer);
if (err < 0)
- goto unlock;
-
- err = snd_ctl_enum_info(uinfo, 1, 3, values);
+ return err;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return snd_ctl_enum_info(uinfo, 1, 3, values);
}
static const struct snd_kcontrol_new scarlett2_air_ctl[2] = {
@@ -5268,25 +5079,20 @@ static int scarlett2_dsp_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_dsp_updated) {
err = scarlett2_update_input_dsp(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->dsp_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_dsp_ctl_put(struct snd_kcontrol *kctl,
@@ -5295,38 +5101,31 @@ static int scarlett2_dsp_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->dsp_switch[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->dsp_switch[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_DSP_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_dsp_ctl = {
@@ -5389,30 +5188,26 @@ static int scarlett2_compressor_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int channel = index / SCARLETT2_COMPRESSOR_PARAM_COUNT;
int param_index = index % SCARLETT2_COMPRESSOR_PARAM_COUNT;
const struct compressor_param *param = &compressor_params[param_index];
-
int oval, val, err;
s32 scaled_val;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->compressor_values[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->compressor_values[index] = val;
@@ -5427,19 +5222,12 @@ static int scarlett2_compressor_ctl_put(
err = scarlett2_usb_set_data(
mixer, private->config_set->param_buf_addr + 1, 1, channel);
if (err < 0)
- goto unlock;
+ return err;
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_COMPRESSOR_PARAMS, index, scaled_val);
- if (err < 0)
- goto unlock;
- if (err == 0)
- err = 1;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_compressor_ctl_info(
@@ -5495,20 +5283,18 @@ static int scarlett2_precomp_flt_switch_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->precomp_flt_switch[elem->control];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->precomp_flt_switch[elem->control] = val;
@@ -5516,12 +5302,8 @@ static int scarlett2_precomp_flt_switch_ctl_put(
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_PRECOMP_FLT_SWITCH,
elem->control, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_peq_flt_switch_ctl_put(
@@ -5530,20 +5312,18 @@ static int scarlett2_peq_flt_switch_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->peq_flt_switch[elem->control];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->peq_flt_switch[elem->control] = val;
@@ -5551,12 +5331,8 @@ static int scarlett2_peq_flt_switch_ctl_put(
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_PEQ_FLT_SWITCH,
elem->control, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_precomp_flt_switch_ctl = {
@@ -5677,20 +5453,17 @@ static int scarlett2_precomp_flt_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control * SCARLETT2_BIQUAD_COEFFS;
int i, oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
/* Check if any of the values have changed; if not, return */
for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) {
@@ -5701,7 +5474,7 @@ static int scarlett2_precomp_flt_ctl_put(
}
if (i == SCARLETT2_BIQUAD_COEFFS)
- goto unlock;
+ return 0;
/* Update the values */
for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++)
@@ -5712,19 +5485,14 @@ static int scarlett2_precomp_flt_ctl_put(
err = scarlett2_usb_set_data(
mixer, private->config_set->param_buf_addr, 1, index);
if (err < 0)
- goto unlock;
+ return err;
err = scarlett2_usb_set_config_buf(
mixer, SCARLETT2_CONFIG_PRECOMP_FLT_PARAMS,
index, SCARLETT2_BIQUAD_COEFFS,
&private->precomp_flt_values[index]);
- if (err == 0)
- err = 1;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_peq_flt_ctl_put(
@@ -5734,7 +5502,6 @@ static int scarlett2_peq_flt_ctl_put(
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
-
int src_index = elem->control * SCARLETT2_BIQUAD_COEFFS;
int dst_index = (
elem->control /
@@ -5744,16 +5511,14 @@ static int scarlett2_peq_flt_ctl_put(
) * SCARLETT2_BIQUAD_COEFFS;
int i, oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
/* Check if any of the values have changed; if not, return */
for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) {
@@ -5764,7 +5529,7 @@ static int scarlett2_peq_flt_ctl_put(
}
if (i == SCARLETT2_BIQUAD_COEFFS)
- goto unlock;
+ return 0;
/* Update the values */
for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++)
@@ -5775,19 +5540,14 @@ static int scarlett2_peq_flt_ctl_put(
err = scarlett2_usb_set_data(
mixer, private->config_set->param_buf_addr, 1, dst_index);
if (err < 0)
- goto unlock;
+ return err;
err = scarlett2_usb_set_config_buf(
mixer, SCARLETT2_CONFIG_PEQ_FLT_PARAMS,
dst_index, SCARLETT2_BIQUAD_COEFFS,
&private->peq_flt_values[src_index]);
- if (err == 0)
- err = 1;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_flt_ctl_info(
@@ -5840,26 +5600,21 @@ static int scarlett2_input_mute_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->input_mute_updated) {
err = scarlett2_update_input_mute(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] =
private->input_mute_switch[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl,
@@ -5868,26 +5623,23 @@ static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->input_mute_switch[index];
val = ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->input_mute_switch[index] = val;
@@ -5895,12 +5647,8 @@ static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl,
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_INPUT_MUTE_SWITCH,
index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_input_mute_ctl = {
@@ -6011,23 +5759,18 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl,
struct scarlett2_data *private = mixer->private_data;
int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_input_phantom_updated(mixer);
if (err < 0)
- goto unlock;
+ return err;
ucontrol->value.integer.value[0] = scarlett2_decode_muteable(
private->phantom_switch[elem->control]);
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl,
@@ -6037,26 +5780,23 @@ static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
-
int index = elem->control;
int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_check_put_during_autogain(mixer);
if (err < 0)
- goto unlock;
+ return err;
oval = private->phantom_switch[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->phantom_switch[index] = val;
@@ -6067,15 +5807,10 @@ static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl,
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH,
index + info->phantom_first, val);
- if (err == 0)
- err = 1;
-
scarlett2_phantom_update_access(mixer);
scarlett2_phantom_notify_access(mixer);
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_phantom_ctl = {
@@ -6104,34 +5839,27 @@ static int scarlett2_phantom_persistence_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->phantom_persistence;
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->phantom_persistence = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE, index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_phantom_persistence_ctl = {
@@ -6222,25 +5950,20 @@ static int scarlett2_speaker_switch_enum_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->monitor_other_updated) {
err = scarlett2_update_monitor_other(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->speaker_switching_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
/* when speaker switching gets enabled, switch the main/alt speakers
@@ -6306,21 +6029,18 @@ static int scarlett2_speaker_switch_enum_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ int oval, val, err;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->speaker_switching_switch;
val = min(ucontrol->value.enumerated.item[0], 2U);
if (oval == val)
- goto unlock;
+ return 0;
private->speaker_switching_switch = val;
@@ -6329,14 +6049,14 @@ static int scarlett2_speaker_switch_enum_ctl_put(
mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
0, !!val);
if (err < 0)
- goto unlock;
+ return err;
/* if speaker switching is enabled, select main or alt */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
0, val == 2);
if (err < 0)
- goto unlock;
+ return err;
/* update controls if speaker switching gets enabled or disabled */
if (!oval && val)
@@ -6344,12 +6064,7 @@ static int scarlett2_speaker_switch_enum_ctl_put(
else if (oval && !val)
scarlett2_speaker_switch_disable(mixer);
- if (err == 0)
- err = 1;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_speaker_switch_enum_ctl = {
@@ -6392,25 +6107,20 @@ static int scarlett2_talkback_enum_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->monitor_other_updated) {
err = scarlett2_update_monitor_other(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->talkback_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_talkback_enum_ctl_put(
@@ -6419,21 +6129,18 @@ static int scarlett2_talkback_enum_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ int oval, val, err;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->talkback_switch;
val = min(ucontrol->value.enumerated.item[0], 2U);
if (oval == val)
- goto unlock;
+ return 0;
private->talkback_switch = val;
@@ -6442,18 +6149,14 @@ static int scarlett2_talkback_enum_ctl_put(
mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
1, !!val);
if (err < 0)
- goto unlock;
+ return err;
/* if talkback is enabled, select main or alt */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
1, val == 2);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_talkback_enum_ctl = {
@@ -6484,21 +6187,19 @@ static int scarlett2_talkback_map_ctl_put(
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = elem->control;
- int oval, val, err = 0, i;
+ int oval, val, err, i;
u16 bitmap = 0;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->talkback_map[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->talkback_map[index] = val;
@@ -6508,12 +6209,8 @@ static int scarlett2_talkback_map_ctl_put(
/* Send updated bitmap to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_TALKBACK_MAP,
0, bitmap);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_talkback_map_ctl = {
@@ -6561,25 +6258,20 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->dim_mute_updated) {
err = scarlett2_update_dim_mute(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->dim_mute[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
@@ -6589,29 +6281,24 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = elem->control;
- int oval, val, err = 0, i;
+ int oval, val, err, i;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->dim_mute[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->dim_mute[index] = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_DIM_MUTE,
index, val);
- if (err == 0)
- err = 1;
-
if (index == SCARLETT2_BUTTON_MUTE)
for (i = 0; i < private->num_line_out; i++) {
int line_index = line_out_remap(private, i);
@@ -6624,9 +6311,7 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
}
}
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_dim_mute_ctl = {
@@ -6637,6 +6322,61 @@ static const struct snd_kcontrol_new scarlett2_dim_mute_ctl = {
.put = scarlett2_dim_mute_ctl_put
};
+/*** Vocaster Speaker/Headphone Mute Controls ***/
+
+static int scarlett2_sp_hp_mute_ctl_get(struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kctl->private_data;
+ struct scarlett2_data *private = elem->head.mixer->private_data;
+
+ ucontrol->value.integer.value[0] =
+ !!(private->sp_hp_mute & (1 << elem->control));
+
+ return 0;
+}
+
+static int scarlett2_sp_hp_mute_ctl_put(struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kctl->private_data;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = mixer->private_data;
+ int index = elem->control;
+ int val, err;
+
+ guard(mutex)(&private->data_mutex);
+
+ if (private->hwdep_in_use)
+ return -EBUSY;
+
+ val = private->sp_hp_mute;
+
+ if (ucontrol->value.integer.value[0])
+ val |= (1 << index);
+ else
+ val &= ~(1 << index);
+
+ if (val == private->sp_hp_mute)
+ return 0;
+
+ private->sp_hp_mute = val;
+
+ /* Send change to the device */
+ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SP_HP_MUTE,
+ 0, val);
+
+ return err < 0 ? err : 1;
+}
+
+static const struct snd_kcontrol_new scarlett2_sp_hp_mute_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_sp_hp_mute_ctl_get,
+ .put = scarlett2_sp_hp_mute_ctl_put
+};
+
/*** Create the analogue output controls ***/
static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
@@ -6669,6 +6409,17 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
return err;
}
+ /* Add Vocaster speaker/headphone mute controls */
+ if (private->info->sp_hp_mute_names)
+ for (i = 0; private->info->sp_hp_mute_names[i]; i++) {
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_sp_hp_mute_ctl,
+ i, 1, private->info->sp_hp_mute_names[i],
+ NULL);
+ if (err < 0)
+ return err;
+ }
+
/* Remaining controls are only applicable if the device
* has per-channel line-out volume controls.
*/
@@ -7038,25 +6789,20 @@ static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->mix_updated) {
err = scarlett2_update_mix(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->mix[elem->control];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
@@ -7065,15 +6811,13 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, mix_num, err = 0;
+ int oval, val, mix_num, err;
int index = elem->control;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->mix[index];
val = clamp(ucontrol->value.integer.value[0],
@@ -7081,16 +6825,12 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
mix_num = index / private->num_mix_in;
if (oval == val)
- goto unlock;
+ return 0;
private->mix[index] = val;
err = scarlett2_usb_set_mix(mixer, mix_num);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const DECLARE_TLV_DB_MINMAX(
@@ -7177,25 +6917,20 @@ static int scarlett2_direct_monitor_ctl_get(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->direct_monitor_updated) {
err = scarlett2_update_direct_monitor(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->direct_monitor_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_direct_monitor_ctl_put(
@@ -7204,34 +6939,27 @@ static int scarlett2_direct_monitor_ctl_put(
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
-
int index = elem->control;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->direct_monitor_switch;
val = min(ucontrol->value.enumerated.item[0], 2U);
if (oval == val)
- goto unlock;
+ return 0;
private->direct_monitor_switch = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_DIRECT_MONITOR, index, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_direct_monitor_stereo_enum_ctl_info(
@@ -7281,33 +7009,27 @@ static int scarlett2_monitor_mix_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, err = 0;
+ int oval, val, err;
int index = elem->control;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->monitor_mix[index];
val = clamp(ucontrol->value.integer.value[0],
0L, (long)SCARLETT2_MIXER_MAX_VALUE);
if (oval == val)
- goto unlock;
+ return 0;
private->monitor_mix[index] = val;
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN,
index, scarlett2_mixer_values[val]);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_monitor_mix_ctl = {
@@ -7433,25 +7155,20 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->mux_updated) {
err = scarlett2_usb_get_mux(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.enumerated.item[0] = private->mux[index];
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl,
@@ -7461,30 +7178,24 @@ static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
int index = line_out_remap(private, elem->control);
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->mux[index];
val = min(ucontrol->value.enumerated.item[0],
private->num_mux_srcs - 1U);
if (oval == val)
- goto unlock;
+ return 0;
private->mux[index] = val;
err = scarlett2_usb_set_mux(mixer);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_mux_src_enum_ctl = {
@@ -7561,17 +7272,15 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
u16 meter_levels[SCARLETT2_MAX_METERS];
int i, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
err = scarlett2_usb_get_meter_levels(mixer, elem->channels,
meter_levels);
if (err < 0)
- goto unlock;
+ return err;
/* copy & translate from meter_levels[] using meter_level_map[] */
for (i = 0; i < elem->channels; i++) {
@@ -7586,10 +7295,7 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
ucontrol->value.integer.value[i] = value;
}
-unlock:
- mutex_unlock(&private->data_mutex);
-
- return err;
+ return 0;
}
static const struct snd_kcontrol_new scarlett2_meter_ctl = {
@@ -7631,33 +7337,26 @@ static int scarlett2_msd_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ int oval, val, err;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->msd_switch;
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->msd_switch = val;
/* Send switch change to the device */
err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_MSD_SWITCH,
0, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_msd_ctl = {
@@ -7702,21 +7401,18 @@ static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ int oval, val, err;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->standalone_switch;
val = !!ucontrol->value.integer.value[0];
if (oval == val)
- goto unlock;
+ return 0;
private->standalone_switch = val;
@@ -7724,12 +7420,8 @@ static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl,
err = scarlett2_usb_set_config(mixer,
SCARLETT2_CONFIG_STANDALONE_SWITCH,
0, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_standalone_ctl = {
@@ -7789,20 +7481,17 @@ static int scarlett2_power_status_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
if (private->power_status_updated) {
err = scarlett2_update_power_status(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->power_status;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_power_status_ctl_info(
@@ -7864,25 +7553,20 @@ static int scarlett2_bluetooth_volume_ctl_get(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int err = 0;
+ int err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
if (private->bluetooth_updated) {
err = scarlett2_update_bluetooth_volume(mixer);
if (err < 0)
- goto unlock;
+ return err;
}
ucontrol->value.integer.value[0] = private->bluetooth_volume;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return 0;
}
static int scarlett2_bluetooth_volume_ctl_put(struct snd_kcontrol *kctl,
@@ -7891,32 +7575,26 @@ static int scarlett2_bluetooth_volume_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, err = 0;
+ int oval, val, err;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
+ if (private->hwdep_in_use)
+ return -EBUSY;
oval = private->bluetooth_volume;
val = clamp(ucontrol->value.integer.value[0],
0L, (long)SCARLETT2_MAX_BLUETOOTH_VOLUME);
if (oval == val)
- goto unlock;
+ return 0;
private->bluetooth_volume = val;
err = scarlett2_usb_set_config(mixer,
SCARLETT2_CONFIG_BLUETOOTH_VOLUME,
0, val);
- if (err == 0)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static int scarlett2_bluetooth_volume_ctl_info(
@@ -8011,39 +7689,31 @@ static int scarlett2_spdif_mode_ctl_put(struct snd_kcontrol *kctl,
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int oval, val, err = 0;
+ int oval, val, err;
int i;
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
oval = private->spdif_mode;
val = ucontrol->value.enumerated.item[0];
- if (val < 0) {
- err = -EINVAL;
- goto unlock;
- }
+ if (val < 0)
+ return -EINVAL;
for (i = 0; i <= val; i++)
- if (private->info->spdif_mode_values[i] == 0xff) {
- err = -EINVAL;
- goto unlock;
- }
+ if (private->info->spdif_mode_values[i] == 0xff)
+ return -EINVAL;
if (oval == val)
- goto unlock;
+ return 0;
private->spdif_mode = val;
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_SPDIF_MODE, 0,
private->info->spdif_mode_values[val]);
- if (!err)
- err = 1;
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
+ return err < 0 ? err : 1;
}
static const struct snd_kcontrol_new scarlett2_spdif_mode_ctl = {
@@ -9140,9 +8810,8 @@ static int snd_scarlett2_controls_create(
*/
static void scarlett2_lock(struct scarlett2_data *private)
{
- mutex_lock(&private->data_mutex);
+ guard(mutex)(&private->data_mutex);
private->hwdep_in_use = 1;
- mutex_unlock(&private->data_mutex);
}
/* Call SCARLETT2_USB_GET_ERASE to get the erase progress */
@@ -9414,7 +9083,7 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw,
__le32 len;
} __packed req;
- u8 *resp;
+ u8 *resp __free(kfree) = NULL;
/* Flash segment must first be selected */
if (private->flash_write_state != SCARLETT2_FLASH_WRITE_STATE_SELECTED)
@@ -9460,20 +9129,14 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw,
err = scarlett2_usb(mixer, SCARLETT2_USB_READ_SEGMENT,
&req, sizeof(req), resp, count);
if (err < 0)
- goto error;
+ return err;
/* Copy the response to userspace */
- if (copy_to_user(buf, resp, count)) {
- err = -EFAULT;
- goto error;
- }
+ if (copy_to_user(buf, resp, count))
+ return -EFAULT;
*offset += count;
- err = count;
-
-error:
- kfree(resp);
- return err;
+ return count;
}
static long scarlett2_hwdep_write(struct snd_hwdep *hw,
@@ -9491,7 +9154,7 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw,
__le32 offset;
__le32 pad;
u8 data[];
- } __packed *req;
+ } __packed *req __free(kfree) = NULL;
/* Calculate the maximum permitted in data[] */
const size_t max_data_size = SCARLETT2_FLASH_RW_MAX -
@@ -9545,22 +9208,16 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw,
req->offset = cpu_to_le32(*offset);
req->pad = 0;
- if (copy_from_user(req->data, buf, count)) {
- err = -EFAULT;
- goto error;
- }
+ if (copy_from_user(req->data, buf, count))
+ return -EFAULT;
err = scarlett2_usb(mixer, SCARLETT2_USB_WRITE_SEGMENT,
req, len, NULL, 0);
if (err < 0)
- goto error;
+ return err;
*offset += count;
- err = count;
-
-error:
- kfree(req);
- return err;
+ return count;
}
static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file)
@@ -9610,7 +9267,7 @@ static ssize_t scarlett2_devmap_read(
loff_t pos)
{
struct usb_mixer_interface *mixer = entry->private_data;
- u8 *resp_buf;
+ u8 *resp_buf __free(kfree) = NULL;
const size_t block_size = SCARLETT2_DEVMAP_BLOCK_SIZE;
size_t copied = 0;
@@ -9649,15 +9306,11 @@ static ssize_t scarlett2_devmap_read(
req = cpu_to_le32(pos / block_size);
err = scarlett2_usb(mixer, SCARLETT2_USB_GET_DEVMAP,
&req, sizeof(req), resp_buf, read_size);
- if (err < 0) {
- kfree(resp_buf);
+ if (err < 0)
return copied ? copied : err;
- }
- if (copy_to_user(buf, resp_buf + offset, copy_size)) {
- kfree(resp_buf);
+ if (copy_to_user(buf, resp_buf + offset, copy_size))
return -EFAULT;
- }
buf += copy_size;
pos += copy_size;
@@ -9665,7 +9318,6 @@ static ssize_t scarlett2_devmap_read(
count -= copy_size;
}
- kfree(resp_buf);
return copied;
}
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index 236b69054867..1c5712c31f5e 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -152,12 +152,11 @@ static int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
unsigned char *buf, int size)
{
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
snd_usb_ctl_msg(chip->dev,
usb_rcvctrlpipe(chip->dev, 0),
SND_US16X08_URB_METER_REQUEST,
SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
- mutex_unlock(&chip->mutex);
return 0;
}
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index bff92505e408..54d01dfd820f 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -77,10 +77,10 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
if (atomic_read(&subs->stream->chip->shutdown))
return SNDRV_PCM_POS_XRUN;
- spin_lock(&subs->lock);
- hwptr_done = subs->hwptr_done;
- runtime->delay = snd_usb_pcm_delay(subs, runtime);
- spin_unlock(&subs->lock);
+ scoped_guard(spinlock, &subs->lock) {
+ hwptr_done = subs->hwptr_done;
+ runtime->delay = snd_usb_pcm_delay(subs, runtime);
+ }
return bytes_to_frames(runtime, hwptr_done);
}
@@ -560,9 +560,9 @@ int snd_usb_hw_params(struct snd_usb_substream *subs,
subs->sync_endpoint);
}
- mutex_lock(&chip->mutex);
- subs->cur_audiofmt = fmt;
- mutex_unlock(&chip->mutex);
+ scoped_guard(mutex, &chip->mutex) {
+ subs->cur_audiofmt = fmt;
+ }
if (!subs->data_endpoint->need_setup)
goto unlock;
@@ -611,14 +611,14 @@ int snd_usb_hw_free(struct snd_usb_substream *subs)
struct snd_usb_audio *chip = subs->stream->chip;
snd_media_stop_pipeline(subs);
- mutex_lock(&chip->mutex);
- subs->cur_audiofmt = NULL;
- mutex_unlock(&chip->mutex);
- if (!snd_usb_lock_shutdown(chip)) {
+ scoped_guard(mutex, &chip->mutex) {
+ subs->cur_audiofmt = NULL;
+ }
+ CLASS(snd_usb_lock, pm)(chip);
+ if (!pm.err) {
if (stop_endpoints(subs, false))
sync_pending_stops(subs);
close_endpoints(chip, subs);
- snd_usb_unlock_shutdown(chip);
}
return 0;
@@ -675,28 +675,26 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
int retry = 0;
int ret;
- ret = snd_usb_lock_shutdown(chip);
- if (ret < 0)
- return ret;
- if (snd_BUG_ON(!subs->data_endpoint)) {
- ret = -EIO;
- goto unlock;
- }
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0)
+ return pm.err;
+ if (snd_BUG_ON(!subs->data_endpoint))
+ return -EIO;
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
if (ret < 0)
- goto unlock;
+ return ret;
again:
if (subs->sync_endpoint) {
ret = snd_usb_endpoint_prepare(chip, subs->sync_endpoint);
if (ret < 0)
- goto unlock;
+ return ret;
}
ret = snd_usb_endpoint_prepare(chip, subs->data_endpoint);
if (ret < 0)
- goto unlock;
+ return ret;
else if (ret > 0)
snd_usb_set_format_quirk(subs, subs->cur_audiofmt);
ret = 0;
@@ -722,8 +720,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
goto again;
}
}
- unlock:
- snd_usb_unlock_shutdown(chip);
+
return ret;
}
@@ -1244,13 +1241,11 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream)
struct snd_usb_audio *chip = subs->stream->chip;
int ret;
- mutex_lock(&chip->mutex);
- if (subs->opened) {
- mutex_unlock(&chip->mutex);
- return -EBUSY;
+ scoped_guard(mutex, &chip->mutex) {
+ if (subs->opened)
+ return -EBUSY;
+ subs->opened = 1;
}
- subs->opened = 1;
- mutex_unlock(&chip->mutex);
runtime->hw = snd_usb_hardware;
/* need an explicit sync to catch applptr update in low-latency mode */
@@ -1281,9 +1276,9 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream)
err_resume:
snd_usb_autosuspend(subs->stream->chip);
err_open:
- mutex_lock(&chip->mutex);
- subs->opened = 0;
- mutex_unlock(&chip->mutex);
+ scoped_guard(mutex, &chip->mutex) {
+ subs->opened = 0;
+ }
return ret;
}
@@ -1298,18 +1293,20 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream)
snd_media_stop_pipeline(subs);
- if (!snd_usb_lock_shutdown(subs->stream->chip)) {
+ {
+ CLASS(snd_usb_lock, pm)(subs->stream->chip);
+ if (pm.err)
+ return pm.err;
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D1);
- snd_usb_unlock_shutdown(subs->stream->chip);
if (ret < 0)
return ret;
}
subs->pcm_substream = NULL;
snd_usb_autosuspend(subs->stream->chip);
- mutex_lock(&chip->mutex);
- subs->opened = 0;
- mutex_unlock(&chip->mutex);
+ scoped_guard(mutex, &chip->mutex) {
+ subs->opened = 0;
+ }
return 0;
}
@@ -1325,7 +1322,6 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
unsigned int stride, frames, bytes, oldptr;
int i, period_elapsed = 0;
- unsigned long flags;
unsigned char *cp;
int current_frame_number;
@@ -1358,22 +1354,21 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
oldbytes, bytes);
}
/* update the current pointer */
- spin_lock_irqsave(&subs->lock, flags);
- oldptr = subs->hwptr_done;
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= subs->buffer_bytes)
- subs->hwptr_done -= subs->buffer_bytes;
- frames = (bytes + (oldptr % stride)) / stride;
- subs->transfer_done += frames;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- period_elapsed = 1;
- }
-
- /* realign last_frame_number */
- subs->last_frame_number = current_frame_number;
+ scoped_guard(spinlock_irqsave, &subs->lock) {
+ oldptr = subs->hwptr_done;
+ subs->hwptr_done += bytes;
+ if (subs->hwptr_done >= subs->buffer_bytes)
+ subs->hwptr_done -= subs->buffer_bytes;
+ frames = (bytes + (oldptr % stride)) / stride;
+ subs->transfer_done += frames;
+ if (subs->transfer_done >= runtime->period_size) {
+ subs->transfer_done -= runtime->period_size;
+ period_elapsed = 1;
+ }
- spin_unlock_irqrestore(&subs->lock, flags);
+ /* realign last_frame_number */
+ subs->last_frame_number = current_frame_number;
+ }
/* copy a data chunk */
if (oldptr + bytes > subs->buffer_bytes) {
unsigned int bytes1 = subs->buffer_bytes - oldptr;
@@ -1533,8 +1528,6 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
int counts;
unsigned int transfer_done, frame_limit, avail = 0;
int i, stride, period_elapsed = 0;
- unsigned long flags;
- int err = 0;
stride = ep->stride;
@@ -1542,106 +1535,101 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
ctx->queued = 0;
urb->number_of_packets = 0;
- spin_lock_irqsave(&subs->lock, flags);
- frame_limit = subs->frame_limit + ep->max_urb_frames;
- transfer_done = subs->transfer_done;
-
- if (subs->lowlatency_playback &&
- runtime->state != SNDRV_PCM_STATE_DRAINING) {
- unsigned int hwptr = subs->hwptr_done / stride;
+ scoped_guard(spinlock_irqsave, &subs->lock) {
+ frame_limit = subs->frame_limit + ep->max_urb_frames;
+ transfer_done = subs->transfer_done;
- /* calculate the byte offset-in-buffer of the appl_ptr */
- avail = (runtime->control->appl_ptr - runtime->hw_ptr_base)
- % runtime->buffer_size;
- if (avail <= hwptr)
- avail += runtime->buffer_size;
- avail -= hwptr;
- }
+ if (subs->lowlatency_playback &&
+ runtime->state != SNDRV_PCM_STATE_DRAINING) {
+ unsigned int hwptr = subs->hwptr_done / stride;
+
+ /* calculate the byte offset-in-buffer of the appl_ptr */
+ avail = (runtime->control->appl_ptr - runtime->hw_ptr_base)
+ % runtime->buffer_size;
+ if (avail <= hwptr)
+ avail += runtime->buffer_size;
+ avail -= hwptr;
+ }
- for (i = 0; i < ctx->packets; i++) {
- counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
- if (counts < 0)
- break;
- /* set up descriptor */
- urb->iso_frame_desc[i].offset = frames * stride;
- urb->iso_frame_desc[i].length = counts * stride;
- frames += counts;
- avail -= counts;
- urb->number_of_packets++;
- transfer_done += counts;
- if (transfer_done >= runtime->period_size) {
- transfer_done -= runtime->period_size;
- frame_limit = 0;
- period_elapsed = 1;
- if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
- if (transfer_done > 0) {
- /* FIXME: fill-max mode is not
- * supported yet */
- frames -= transfer_done;
- counts -= transfer_done;
- urb->iso_frame_desc[i].length =
- counts * stride;
- transfer_done = 0;
- }
- i++;
- if (i < ctx->packets) {
- /* add a transfer delimiter */
- urb->iso_frame_desc[i].offset =
- frames * stride;
- urb->iso_frame_desc[i].length = 0;
- urb->number_of_packets++;
- }
+ for (i = 0; i < ctx->packets; i++) {
+ counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
+ if (counts < 0)
break;
+ /* set up descriptor */
+ urb->iso_frame_desc[i].offset = frames * stride;
+ urb->iso_frame_desc[i].length = counts * stride;
+ frames += counts;
+ avail -= counts;
+ urb->number_of_packets++;
+ transfer_done += counts;
+ if (transfer_done >= runtime->period_size) {
+ transfer_done -= runtime->period_size;
+ frame_limit = 0;
+ period_elapsed = 1;
+ if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
+ if (transfer_done > 0) {
+ /* FIXME: fill-max mode is not
+ * supported yet */
+ frames -= transfer_done;
+ counts -= transfer_done;
+ urb->iso_frame_desc[i].length =
+ counts * stride;
+ transfer_done = 0;
+ }
+ i++;
+ if (i < ctx->packets) {
+ /* add a transfer delimiter */
+ urb->iso_frame_desc[i].offset =
+ frames * stride;
+ urb->iso_frame_desc[i].length = 0;
+ urb->number_of_packets++;
+ }
+ break;
+ }
}
+ /* finish at the period boundary or after enough frames */
+ if ((period_elapsed || transfer_done >= frame_limit) &&
+ !snd_usb_endpoint_implicit_feedback_sink(ep))
+ break;
}
- /* finish at the period boundary or after enough frames */
- if ((period_elapsed || transfer_done >= frame_limit) &&
- !snd_usb_endpoint_implicit_feedback_sink(ep))
- break;
- }
- if (!frames) {
- err = -EAGAIN;
- goto unlock;
- }
-
- bytes = frames * stride;
- subs->transfer_done = transfer_done;
- subs->frame_limit = frame_limit;
- if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U16_LE &&
- subs->cur_audiofmt->dsd_dop)) {
- fill_playback_urb_dsd_dop(subs, urb, bytes);
- } else if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U8 &&
- subs->cur_audiofmt->dsd_bitrev)) {
- fill_playback_urb_dsd_bitrev(subs, urb, bytes);
- } else {
- /* usual PCM */
- if (!subs->tx_length_quirk)
- copy_to_urb(subs, urb, 0, stride, bytes);
- else
- bytes = copy_to_urb_quirk(subs, urb, stride, bytes);
+ if (!frames)
+ return -EAGAIN;
+
+ bytes = frames * stride;
+ subs->transfer_done = transfer_done;
+ subs->frame_limit = frame_limit;
+ if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U16_LE &&
+ subs->cur_audiofmt->dsd_dop)) {
+ fill_playback_urb_dsd_dop(subs, urb, bytes);
+ } else if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U8 &&
+ subs->cur_audiofmt->dsd_bitrev)) {
+ fill_playback_urb_dsd_bitrev(subs, urb, bytes);
+ } else {
+ /* usual PCM */
+ if (!subs->tx_length_quirk)
+ copy_to_urb(subs, urb, 0, stride, bytes);
+ else
+ bytes = copy_to_urb_quirk(subs, urb, stride, bytes);
/* bytes is now amount of outgoing data */
- }
+ }
- subs->last_frame_number = usb_get_current_frame_number(subs->dev);
+ subs->last_frame_number = usb_get_current_frame_number(subs->dev);
- if (subs->trigger_tstamp_pending_update) {
- /* this is the first actual URB submitted,
- * update trigger timestamp to reflect actual start time
- */
- snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
- subs->trigger_tstamp_pending_update = false;
- }
+ if (subs->trigger_tstamp_pending_update) {
+ /* this is the first actual URB submitted,
+ * update trigger timestamp to reflect actual start time
+ */
+ snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
+ subs->trigger_tstamp_pending_update = false;
+ }
- if (period_elapsed && !subs->running && subs->lowlatency_playback) {
- subs->period_elapsed_pending = 1;
- period_elapsed = 0;
+ if (period_elapsed && !subs->running && subs->lowlatency_playback) {
+ subs->period_elapsed_pending = 1;
+ period_elapsed = 0;
+ }
}
- unlock:
- spin_unlock_irqrestore(&subs->lock, flags);
- if (err < 0)
- return err;
urb->transfer_buffer_length = bytes;
if (period_elapsed) {
if (in_stream_lock)
@@ -1659,24 +1647,23 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
static void retire_playback_urb(struct snd_usb_substream *subs,
struct urb *urb)
{
- unsigned long flags;
struct snd_urb_ctx *ctx = urb->context;
bool period_elapsed = false;
- spin_lock_irqsave(&subs->lock, flags);
- if (ctx->queued) {
- if (subs->inflight_bytes >= ctx->queued)
- subs->inflight_bytes -= ctx->queued;
- else
- subs->inflight_bytes = 0;
- }
+ scoped_guard(spinlock_irqsave, &subs->lock) {
+ if (ctx->queued) {
+ if (subs->inflight_bytes >= ctx->queued)
+ subs->inflight_bytes -= ctx->queued;
+ else
+ subs->inflight_bytes = 0;
+ }
- subs->last_frame_number = usb_get_current_frame_number(subs->dev);
- if (subs->running) {
- period_elapsed = subs->period_elapsed_pending;
- subs->period_elapsed_pending = 0;
+ subs->last_frame_number = usb_get_current_frame_number(subs->dev);
+ if (subs->running) {
+ period_elapsed = subs->period_elapsed_pending;
+ subs->period_elapsed_pending = 0;
+ }
}
- spin_unlock_irqrestore(&subs->lock, flags);
if (period_elapsed)
snd_pcm_period_elapsed(subs->pcm_substream);
}
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index c8b967bd7065..f4b7a7ff3203 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -193,7 +193,7 @@ static void proc_dump_substream_status(struct snd_usb_audio *chip,
struct snd_usb_substream *subs,
struct snd_info_buffer *buffer)
{
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (subs->running) {
snd_iprintf(buffer, " Status: Running\n");
if (subs->cur_audiofmt) {
@@ -204,7 +204,6 @@ static void proc_dump_substream_status(struct snd_usb_audio *chip,
} else {
snd_iprintf(buffer, " Status: Stop\n");
}
- mutex_unlock(&chip->mutex);
}
static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_offload.c
index 9ad76fff741b..cfb30a195364 100644
--- a/sound/usb/qcom/qc_audio_offload.c
+++ b/sound/usb/qcom/qc_audio_offload.c
@@ -755,7 +755,7 @@ static void qmi_stop_session(void)
int if_idx;
int idx;
- mutex_lock(&qdev_mutex);
+ guard(mutex)(&qdev_mutex);
/* find all active intf for set alt 0 and cleanup usb audio dev */
for (idx = 0; idx < SNDRV_CARDS; idx++) {
if (!atomic_read(&uadev[idx].in_use))
@@ -791,11 +791,9 @@ static void qmi_stop_session(void)
disable_audio_stream(subs);
}
atomic_set(&uadev[idx].in_use, 0);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
uaudio_dev_cleanup(&uadev[idx]);
- mutex_unlock(&chip->mutex);
}
- mutex_unlock(&qdev_mutex);
}
/**
@@ -821,8 +819,8 @@ static int uaudio_sideband_notifier(struct usb_interface *intf,
chip = usb_get_intfdata(intf);
- mutex_lock(&qdev_mutex);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&qdev_mutex);
+ guard(mutex)(&chip->mutex);
dev = &uadev[chip->card->number];
@@ -836,9 +834,6 @@ static int uaudio_sideband_notifier(struct usb_interface *intf,
}
}
- mutex_unlock(&chip->mutex);
- mutex_unlock(&qdev_mutex);
-
return 0;
}
@@ -972,21 +967,21 @@ static int enable_audio_stream(struct snd_usb_substream *subs,
goto put_suspend;
if (!atomic_read(&chip->shutdown)) {
- ret = snd_usb_lock_shutdown(chip);
- if (ret < 0)
+ CLASS(snd_usb_lock, pm)(chip);
+ if (pm.err < 0) {
+ ret = pm.err;
goto detach_ep;
+ }
if (subs->sync_endpoint) {
ret = snd_usb_endpoint_prepare(chip, subs->sync_endpoint);
if (ret < 0)
- goto unlock;
+ goto detach_ep;
}
ret = snd_usb_endpoint_prepare(chip, subs->data_endpoint);
if (ret < 0)
- goto unlock;
-
- snd_usb_unlock_shutdown(chip);
+ goto detach_ep;
dev_dbg(uaudio_qdev->data->dev,
"selected %s iface:%d altsetting:%d datainterval:%dus\n",
@@ -1000,9 +995,6 @@ static int enable_audio_stream(struct snd_usb_substream *subs,
return 0;
-unlock:
- snd_usb_unlock_shutdown(chip);
-
detach_ep:
snd_usb_hw_free(subs);
@@ -1584,17 +1576,15 @@ static void handle_uaudio_stream_req(struct qmi_handle *handle,
goto response;
}
- mutex_lock(&chip->mutex);
- if (req_msg->enable) {
- if (info_idx < 0 || chip->system_suspend || subs->opened) {
- ret = -EBUSY;
- mutex_unlock(&chip->mutex);
-
- goto response;
+ scoped_guard(mutex, &chip->mutex) {
+ if (req_msg->enable) {
+ if (info_idx < 0 || chip->system_suspend || subs->opened) {
+ ret = -EBUSY;
+ goto response;
+ }
+ subs->opened = 1;
}
- subs->opened = 1;
}
- mutex_unlock(&chip->mutex);
if (req_msg->service_interval_valid) {
ret = get_data_interval_from_si(subs,
@@ -1617,9 +1607,8 @@ static void handle_uaudio_stream_req(struct qmi_handle *handle,
ret = prepare_qmi_response(subs, req_msg, &resp,
info_idx);
if (ret < 0) {
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
subs->opened = 0;
- mutex_unlock(&chip->mutex);
}
} else {
info = &uadev[pcm_card_num].info[info_idx];
@@ -1650,14 +1639,13 @@ static void handle_uaudio_stream_req(struct qmi_handle *handle,
}
disable_audio_stream(subs);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
subs->opened = 0;
- mutex_unlock(&chip->mutex);
}
response:
if (!req_msg->enable && ret != -EINVAL && ret != -ENODEV) {
- mutex_lock(&chip->mutex);
+ guard(mutex)(&chip->mutex);
if (info_idx >= 0) {
info = &uadev[pcm_card_num].info[info_idx];
uaudio_dev_intf_cleanup(uadev[pcm_card_num].udev,
@@ -1666,7 +1654,6 @@ response:
if (atomic_read(&uadev[pcm_card_num].in_use))
kref_put(&uadev[pcm_card_num].kref,
uaudio_dev_release);
- mutex_unlock(&chip->mutex);
}
mutex_unlock(&qdev_mutex);
@@ -1769,12 +1756,12 @@ static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip)
!usb_qmi_get_pcm_num(chip, 0))
return;
- mutex_lock(&qdev_mutex);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&qdev_mutex);
+ guard(mutex)(&chip->mutex);
if (!uadev[chip->card->number].chip) {
sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
if (!sdev)
- goto exit;
+ return;
sb = xhci_sideband_register(intf, XHCI_SIDEBAND_VENDOR,
uaudio_sideband_notifier);
@@ -1813,9 +1800,6 @@ static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip)
snd_soc_usb_connect(uaudio_qdev->auxdev->dev.parent, sdev);
}
- mutex_unlock(&chip->mutex);
- mutex_unlock(&qdev_mutex);
-
return;
unreg_xhci:
@@ -1825,9 +1809,6 @@ free_sdev:
kfree(sdev);
uadev[chip->card->number].sdev = NULL;
uadev[chip->card->number].chip = NULL;
-exit:
- mutex_unlock(&chip->mutex);
- mutex_unlock(&qdev_mutex);
}
/**
@@ -1863,16 +1844,13 @@ static void qc_usb_audio_offload_disconnect(struct snd_usb_audio *chip)
if (card_num >= SNDRV_CARDS)
return;
- mutex_lock(&qdev_mutex);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&qdev_mutex);
+ guard(mutex)(&chip->mutex);
dev = &uadev[card_num];
/* Device has already been cleaned up, or never populated */
- if (!dev->chip) {
- mutex_unlock(&chip->mutex);
- mutex_unlock(&qdev_mutex);
+ if (!dev->chip)
return;
- }
/* cleaned up already */
if (!dev->udev)
@@ -1893,9 +1871,6 @@ done:
kfree(dev->sdev);
dev->sdev = NULL;
}
- mutex_unlock(&chip->mutex);
-
- mutex_unlock(&qdev_mutex);
}
/**
@@ -1920,13 +1895,10 @@ static void qc_usb_audio_offload_suspend(struct usb_interface *intf,
if (card_num >= SNDRV_CARDS)
return;
- mutex_lock(&qdev_mutex);
- mutex_lock(&chip->mutex);
+ guard(mutex)(&qdev_mutex);
+ guard(mutex)(&chip->mutex);
uaudio_send_disconnect_ind(chip);
-
- mutex_unlock(&chip->mutex);
- mutex_unlock(&qdev_mutex);
}
static struct snd_usb_platform_ops offload_ops = {
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 766db7d00cbc..634cb4fb586f 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1599,9 +1599,6 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
/* presonus studio 1810c: skip altsets incompatible with device_setup */
if (chip->usb_id == USB_ID(0x194f, 0x010c))
return s1810c_skip_setting_quirk(chip, iface, altno);
- /* presonus studio 1824c: skip altsets incompatible with device_setup */
- if (chip->usb_id == USB_ID(0x194f, 0x010d))
- return s1810c_skip_setting_quirk(chip, iface, altno);
return 0;
}
@@ -2200,9 +2197,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x0572, 0x1b08, /* Conexant Systems (Rockwell), Inc. */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x0572, 0x1b09, /* Conexant Systems (Rockwell), Inc. */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x05a3, 0x9420, /* ELP HD USB Camera */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x05a7, 0x1020, /* Bose Companion 5 */
@@ -2243,18 +2240,22 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x0b05, 0x18a6, /* ASUSTek Computer, Inc. */
+ QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE),
DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x0bda, 0x498a, /* Realtek Semiconductor Corp. */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE | QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE),
DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x0c45, 0x636b, /* Microdia JP001 USB Camera */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x0d8c, 0x000c, /* C-Media */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
+ DEVICE_FLG(0x0d8c, 0x0012, /* C-Media */
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x0d8c, 0x0014, /* C-Media */
- QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
@@ -2264,7 +2265,7 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x12d1, 0x3a07, /* Huawei Technologies Co., Ltd. */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE | QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE),
DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
@@ -2304,7 +2305,7 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x19f7, 0x0003, /* RODE NT-USB */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x1bcf, 0x2281, /* HD Webcam */
@@ -2356,7 +2357,7 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE | QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE),
DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */
@@ -2368,13 +2369,13 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x2d99, 0x0026, /* HECATE G2 GAMING HEADSET */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */
- QUIRK_FLAG_MIXER_MIN_MUTE),
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */
@@ -2442,7 +2443,85 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
{} /* terminator */
};
-void snd_usb_init_quirk_flags(struct snd_usb_audio *chip)
+#define QUIRK_STRING_ENTRY(x) \
+ [QUIRK_TYPE_ ## x] = __stringify(x)
+
+static const char *const snd_usb_audio_quirk_flag_names[] = {
+ QUIRK_STRING_ENTRY(GET_SAMPLE_RATE),
+ QUIRK_STRING_ENTRY(SHARE_MEDIA_DEVICE),
+ QUIRK_STRING_ENTRY(ALIGN_TRANSFER),
+ QUIRK_STRING_ENTRY(TX_LENGTH),
+ QUIRK_STRING_ENTRY(PLAYBACK_FIRST),
+ QUIRK_STRING_ENTRY(SKIP_CLOCK_SELECTOR),
+ QUIRK_STRING_ENTRY(IGNORE_CLOCK_SOURCE),
+ QUIRK_STRING_ENTRY(ITF_USB_DSD_DAC),
+ QUIRK_STRING_ENTRY(CTL_MSG_DELAY),
+ QUIRK_STRING_ENTRY(CTL_MSG_DELAY_1M),
+ QUIRK_STRING_ENTRY(CTL_MSG_DELAY_5M),
+ QUIRK_STRING_ENTRY(IFACE_DELAY),
+ QUIRK_STRING_ENTRY(VALIDATE_RATES),
+ QUIRK_STRING_ENTRY(DISABLE_AUTOSUSPEND),
+ QUIRK_STRING_ENTRY(IGNORE_CTL_ERROR),
+ QUIRK_STRING_ENTRY(DSD_RAW),
+ QUIRK_STRING_ENTRY(SET_IFACE_FIRST),
+ QUIRK_STRING_ENTRY(GENERIC_IMPLICIT_FB),
+ QUIRK_STRING_ENTRY(SKIP_IMPLICIT_FB),
+ QUIRK_STRING_ENTRY(IFACE_SKIP_CLOSE),
+ QUIRK_STRING_ENTRY(FORCE_IFACE_RESET),
+ QUIRK_STRING_ENTRY(FIXED_RATE),
+ QUIRK_STRING_ENTRY(MIC_RES_16),
+ QUIRK_STRING_ENTRY(MIC_RES_384),
+ QUIRK_STRING_ENTRY(MIXER_PLAYBACK_MIN_MUTE),
+ QUIRK_STRING_ENTRY(MIXER_CAPTURE_MIN_MUTE),
+ NULL
+};
+
+const char *snd_usb_quirk_flag_find_name(unsigned long index)
+{
+ if (index >= ARRAY_SIZE(snd_usb_audio_quirk_flag_names))
+ return NULL;
+
+ return snd_usb_audio_quirk_flag_names[index];
+}
+
+u32 snd_usb_quirk_flags_from_name(const char *name)
+{
+ int i;
+
+ if (!name || !*name)
+ return 0;
+
+ for (i = 0; snd_usb_audio_quirk_flag_names[i]; i++) {
+ if (strcasecmp(name, snd_usb_audio_quirk_flag_names[i]) == 0)
+ return BIT_U32(i);
+ }
+
+ return 0;
+}
+
+void snd_usb_apply_flag_dbg(const char *reason,
+ struct snd_usb_audio *chip,
+ unsigned long flag)
+{
+ unsigned long bit;
+
+ for_each_set_bit(bit, &flag, BYTES_TO_BITS(sizeof(flag))) {
+ const char *name = snd_usb_audio_quirk_flag_names[bit];
+
+ if (name)
+ usb_audio_dbg(chip,
+ "From %s apply quirk flag %s for device %04x:%04x\n",
+ reason, name, USB_ID_VENDOR(chip->usb_id),
+ USB_ID_PRODUCT(chip->usb_id));
+ else
+ usb_audio_warn(chip,
+ "From %s apply unknown quirk flag 0x%lx for device %04x:%04x\n",
+ reason, bit, USB_ID_VENDOR(chip->usb_id),
+ USB_ID_PRODUCT(chip->usb_id));
+ }
+}
+
+void snd_usb_init_quirk_flags_table(struct snd_usb_audio *chip)
{
const struct usb_audio_quirk_flags_table *p;
@@ -2450,12 +2529,97 @@ void snd_usb_init_quirk_flags(struct snd_usb_audio *chip)
if (chip->usb_id == p->id ||
(!USB_ID_PRODUCT(p->id) &&
USB_ID_VENDOR(chip->usb_id) == USB_ID_VENDOR(p->id))) {
- usb_audio_dbg(chip,
- "Set quirk_flags 0x%x for device %04x:%04x\n",
- p->flags, USB_ID_VENDOR(chip->usb_id),
- USB_ID_PRODUCT(chip->usb_id));
+ snd_usb_apply_flag_dbg("builtin table", chip, p->flags);
chip->quirk_flags |= p->flags;
return;
}
}
}
+
+void snd_usb_init_quirk_flags_parse_string(struct snd_usb_audio *chip,
+ const char *str)
+{
+ u16 chip_vid = USB_ID_VENDOR(chip->usb_id);
+ u16 chip_pid = USB_ID_PRODUCT(chip->usb_id);
+ u32 mask_flags, unmask_flags, bit;
+ char *p, *field, *flag;
+ bool is_unmask;
+ u16 vid, pid;
+
+ char *val __free(kfree) = kstrdup(str, GFP_KERNEL);
+
+ if (!val)
+ return;
+
+ for (p = val; p && *p;) {
+ /* Each entry consists of VID:PID:flags */
+ field = strsep(&p, ":");
+ if (!field)
+ break;
+
+ if (strcmp(field, "*") == 0)
+ vid = 0;
+ else if (kstrtou16(field, 16, &vid))
+ break;
+
+ field = strsep(&p, ":");
+ if (!field)
+ break;
+
+ if (strcmp(field, "*") == 0)
+ pid = 0;
+ else if (kstrtou16(field, 16, &pid))
+ break;
+
+ field = strsep(&p, ";");
+ if (!field || !*field)
+ break;
+
+ if ((vid != 0 && vid != chip_vid) ||
+ (pid != 0 && pid != chip_pid))
+ continue;
+
+ /* Collect the flags */
+ mask_flags = 0;
+ unmask_flags = 0;
+ while (field && *field) {
+ flag = strsep(&field, "|");
+
+ if (!flag)
+ break;
+
+ if (*flag == '!') {
+ is_unmask = true;
+ flag++;
+ } else {
+ is_unmask = false;
+ }
+
+ if (!kstrtou32(flag, 16, &bit)) {
+ if (is_unmask)
+ unmask_flags |= bit;
+ else
+ mask_flags |= bit;
+
+ break;
+ }
+
+ bit = snd_usb_quirk_flags_from_name(flag);
+
+ if (bit) {
+ if (is_unmask)
+ unmask_flags |= bit;
+ else
+ mask_flags |= bit;
+ } else {
+ pr_warn("snd_usb_audio: unknown flag %s while parsing param quirk_flags\n",
+ flag);
+ }
+ }
+
+ chip->quirk_flags &= ~unmask_flags;
+ chip->quirk_flags |= mask_flags;
+ snd_usb_apply_flag_dbg("module param", chip,
+ chip->quirk_flags);
+ }
+}
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index f9bfd5ac7bab..f24d6a5a197a 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -48,6 +48,15 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
struct audioformat *fp,
int stream);
-void snd_usb_init_quirk_flags(struct snd_usb_audio *chip);
+void snd_usb_apply_flag_dbg(const char *reason,
+ struct snd_usb_audio *chip,
+ unsigned long flag);
+
+void snd_usb_init_quirk_flags_table(struct snd_usb_audio *chip);
+void snd_usb_init_quirk_flags_parse_string(struct snd_usb_audio *chip,
+ const char *str);
+
+const char *snd_usb_quirk_flag_find_name(unsigned long flag);
+u32 snd_usb_quirk_flags_from_name(const char *name);
#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 1ef4d39978df..79978cae9799 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -139,6 +139,29 @@ struct snd_usb_audio_quirk {
int snd_usb_lock_shutdown(struct snd_usb_audio *chip);
void snd_usb_unlock_shutdown(struct snd_usb_audio *chip);
+/* auto-cleanup */
+struct __snd_usb_lock {
+ struct snd_usb_audio *chip;
+ int err;
+};
+
+static inline struct __snd_usb_lock __snd_usb_lock_shutdown(struct snd_usb_audio *chip)
+{
+ struct __snd_usb_lock T = { .chip = chip };
+ T.err = snd_usb_lock_shutdown(chip);
+ return T;
+}
+
+static inline void __snd_usb_unlock_shutdown(struct __snd_usb_lock *lock)
+{
+ if (!lock->err)
+ snd_usb_unlock_shutdown(lock->chip);
+}
+
+DEFINE_CLASS(snd_usb_lock, struct __snd_usb_lock,
+ __snd_usb_unlock_shutdown(&(_T)), __snd_usb_lock_shutdown(chip),
+ struct snd_usb_audio *chip)
+
extern bool snd_usb_use_vmalloc;
extern bool snd_usb_skip_validation;
@@ -196,35 +219,70 @@ extern bool snd_usb_skip_validation;
* for the given endpoint.
* QUIRK_FLAG_MIC_RES_16 and QUIRK_FLAG_MIC_RES_384
* Set the fixed resolution for Mic Capture Volume (mostly for webcams)
- * QUIRK_FLAG_MIXER_MIN_MUTE
+ * QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE
* Set minimum volume control value as mute for devices where the lowest
* playback value represents muted state instead of minimum audible volume
+ * QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE
+ * Similar to QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE, but for capture streams
*/
-#define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0)
-#define QUIRK_FLAG_SHARE_MEDIA_DEVICE (1U << 1)
-#define QUIRK_FLAG_ALIGN_TRANSFER (1U << 2)
-#define QUIRK_FLAG_TX_LENGTH (1U << 3)
-#define QUIRK_FLAG_PLAYBACK_FIRST (1U << 4)
-#define QUIRK_FLAG_SKIP_CLOCK_SELECTOR (1U << 5)
-#define QUIRK_FLAG_IGNORE_CLOCK_SOURCE (1U << 6)
-#define QUIRK_FLAG_ITF_USB_DSD_DAC (1U << 7)
-#define QUIRK_FLAG_CTL_MSG_DELAY (1U << 8)
-#define QUIRK_FLAG_CTL_MSG_DELAY_1M (1U << 9)
-#define QUIRK_FLAG_CTL_MSG_DELAY_5M (1U << 10)
-#define QUIRK_FLAG_IFACE_DELAY (1U << 11)
-#define QUIRK_FLAG_VALIDATE_RATES (1U << 12)
-#define QUIRK_FLAG_DISABLE_AUTOSUSPEND (1U << 13)
-#define QUIRK_FLAG_IGNORE_CTL_ERROR (1U << 14)
-#define QUIRK_FLAG_DSD_RAW (1U << 15)
-#define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16)
-#define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17)
-#define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18)
-#define QUIRK_FLAG_IFACE_SKIP_CLOSE (1U << 19)
-#define QUIRK_FLAG_FORCE_IFACE_RESET (1U << 20)
-#define QUIRK_FLAG_FIXED_RATE (1U << 21)
-#define QUIRK_FLAG_MIC_RES_16 (1U << 22)
-#define QUIRK_FLAG_MIC_RES_384 (1U << 23)
-#define QUIRK_FLAG_MIXER_MIN_MUTE (1U << 24)
+enum {
+ QUIRK_TYPE_GET_SAMPLE_RATE = 0,
+ QUIRK_TYPE_SHARE_MEDIA_DEVICE = 1,
+ QUIRK_TYPE_ALIGN_TRANSFER = 2,
+ QUIRK_TYPE_TX_LENGTH = 3,
+ QUIRK_TYPE_PLAYBACK_FIRST = 4,
+ QUIRK_TYPE_SKIP_CLOCK_SELECTOR = 5,
+ QUIRK_TYPE_IGNORE_CLOCK_SOURCE = 6,
+ QUIRK_TYPE_ITF_USB_DSD_DAC = 7,
+ QUIRK_TYPE_CTL_MSG_DELAY = 8,
+ QUIRK_TYPE_CTL_MSG_DELAY_1M = 9,
+ QUIRK_TYPE_CTL_MSG_DELAY_5M = 10,
+ QUIRK_TYPE_IFACE_DELAY = 11,
+ QUIRK_TYPE_VALIDATE_RATES = 12,
+ QUIRK_TYPE_DISABLE_AUTOSUSPEND = 13,
+ QUIRK_TYPE_IGNORE_CTL_ERROR = 14,
+ QUIRK_TYPE_DSD_RAW = 15,
+ QUIRK_TYPE_SET_IFACE_FIRST = 16,
+ QUIRK_TYPE_GENERIC_IMPLICIT_FB = 17,
+ QUIRK_TYPE_SKIP_IMPLICIT_FB = 18,
+ QUIRK_TYPE_IFACE_SKIP_CLOSE = 19,
+ QUIRK_TYPE_FORCE_IFACE_RESET = 20,
+ QUIRK_TYPE_FIXED_RATE = 21,
+ QUIRK_TYPE_MIC_RES_16 = 22,
+ QUIRK_TYPE_MIC_RES_384 = 23,
+ QUIRK_TYPE_MIXER_PLAYBACK_MIN_MUTE = 24,
+ QUIRK_TYPE_MIXER_CAPTURE_MIN_MUTE = 25,
+/* Please also edit snd_usb_audio_quirk_flag_names */
+};
+
+#define QUIRK_FLAG(x) BIT_U32(QUIRK_TYPE_ ## x)
+
+#define QUIRK_FLAG_GET_SAMPLE_RATE QUIRK_FLAG(GET_SAMPLE_RATE)
+#define QUIRK_FLAG_SHARE_MEDIA_DEVICE QUIRK_FLAG(SHARE_MEDIA_DEVICE)
+#define QUIRK_FLAG_ALIGN_TRANSFER QUIRK_FLAG(ALIGN_TRANSFER)
+#define QUIRK_FLAG_TX_LENGTH QUIRK_FLAG(TX_LENGTH)
+#define QUIRK_FLAG_PLAYBACK_FIRST QUIRK_FLAG(PLAYBACK_FIRST)
+#define QUIRK_FLAG_SKIP_CLOCK_SELECTOR QUIRK_FLAG(SKIP_CLOCK_SELECTOR)
+#define QUIRK_FLAG_IGNORE_CLOCK_SOURCE QUIRK_FLAG(IGNORE_CLOCK_SOURCE)
+#define QUIRK_FLAG_ITF_USB_DSD_DAC QUIRK_FLAG(ITF_USB_DSD_DAC)
+#define QUIRK_FLAG_CTL_MSG_DELAY QUIRK_FLAG(CTL_MSG_DELAY)
+#define QUIRK_FLAG_CTL_MSG_DELAY_1M QUIRK_FLAG(CTL_MSG_DELAY_1M)
+#define QUIRK_FLAG_CTL_MSG_DELAY_5M QUIRK_FLAG(CTL_MSG_DELAY_5M)
+#define QUIRK_FLAG_IFACE_DELAY QUIRK_FLAG(IFACE_DELAY)
+#define QUIRK_FLAG_VALIDATE_RATES QUIRK_FLAG(VALIDATE_RATES)
+#define QUIRK_FLAG_DISABLE_AUTOSUSPEND QUIRK_FLAG(DISABLE_AUTOSUSPEND)
+#define QUIRK_FLAG_IGNORE_CTL_ERROR QUIRK_FLAG(IGNORE_CTL_ERROR)
+#define QUIRK_FLAG_DSD_RAW QUIRK_FLAG(DSD_RAW)
+#define QUIRK_FLAG_SET_IFACE_FIRST QUIRK_FLAG(SET_IFACE_FIRST)
+#define QUIRK_FLAG_GENERIC_IMPLICIT_FB QUIRK_FLAG(GENERIC_IMPLICIT_FB)
+#define QUIRK_FLAG_SKIP_IMPLICIT_FB QUIRK_FLAG(SKIP_IMPLICIT_FB)
+#define QUIRK_FLAG_IFACE_SKIP_CLOSE QUIRK_FLAG(IFACE_SKIP_CLOSE)
+#define QUIRK_FLAG_FORCE_IFACE_RESET QUIRK_FLAG(FORCE_IFACE_RESET)
+#define QUIRK_FLAG_FIXED_RATE QUIRK_FLAG(FIXED_RATE)
+#define QUIRK_FLAG_MIC_RES_16 QUIRK_FLAG(MIC_RES_16)
+#define QUIRK_FLAG_MIC_RES_384 QUIRK_FLAG(MIC_RES_384)
+#define QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE QUIRK_FLAG(MIXER_PLAYBACK_MIN_MUTE)
+#define QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE QUIRK_FLAG(MIXER_CAPTURE_MIN_MUTE)
#endif /* __USBAUDIO_H */
diff --git a/sound/usb/usx2y/Makefile b/sound/usb/usx2y/Makefile
index fc033aba03a4..9db87ae39ee9 100644
--- a/sound/usb/usx2y/Makefile
+++ b/sound/usb/usx2y/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
snd-usb-usx2y-y := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
snd-usb-us122l-y := us122l.o
+snd-usb-us144mkii-y := us144mkii.o us144mkii_pcm.o us144mkii_playback.o us144mkii_capture.o us144mkii_midi.o us144mkii_controls.o
obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
obj-$(CONFIG_SND_USB_US122L) += snd-usb-us122l.o
+obj-$(CONFIG_SND_USB_US144MKII) += snd-usb-us144mkii.o \ No newline at end of file
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 2ace3ba46091..011ea96e9779 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -97,10 +97,10 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
struct us122l *us122l = vmf->vma->vm_private_data;
struct usb_stream *s;
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
s = us122l->sk.s;
if (!s)
- goto unlock;
+ return VM_FAULT_SIGBUS;
offset = vmf->pgoff << PAGE_SHIFT;
if (offset < PAGE_ALIGN(s->read_size)) {
@@ -108,21 +108,17 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
} else {
offset -= PAGE_ALIGN(s->read_size);
if (offset >= PAGE_ALIGN(s->write_size))
- goto unlock;
+ return VM_FAULT_SIGBUS;
vaddr = us122l->sk.write_page + offset;
}
page = virt_to_page(vaddr);
get_page(page);
- mutex_unlock(&us122l->mutex);
vmf->page = page;
return 0;
-unlock:
- mutex_unlock(&us122l->mutex);
- return VM_FAULT_SIGBUS;
}
@@ -163,12 +159,11 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
usb_autopm_put_interface(iface);
if (us122l->first == file)
us122l->first = NULL;
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
if (us122l->master == file)
us122l->master = us122l->slave;
us122l->slave = NULL;
- mutex_unlock(&us122l->mutex);
return 0;
}
@@ -179,23 +174,19 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
struct us122l *us122l = hw->private_data;
unsigned long offset;
struct usb_stream *s;
- int err = 0;
bool read;
offset = area->vm_pgoff << PAGE_SHIFT;
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
s = us122l->sk.s;
read = offset < s->read_size;
- if (read && area->vm_flags & VM_WRITE) {
- err = -EPERM;
- goto out;
- }
+ if (read && area->vm_flags & VM_WRITE)
+ return -EPERM;
/* if userspace tries to mmap beyond end of our buffer, fail */
if (size > PAGE_ALIGN(read ? s->read_size : s->write_size)) {
dev_warn(hw->card->dev, "%s: size %lu > %u\n", __func__,
size, read ? s->read_size : s->write_size);
- err = -EINVAL;
- goto out;
+ return -EINVAL;
}
area->vm_ops = &usb_stream_hwdep_vm_ops;
@@ -203,9 +194,7 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
if (!read)
vm_flags_set(area, VM_DONTEXPAND);
area->vm_private_data = us122l;
-out:
- mutex_unlock(&us122l->mutex);
- return err;
+ return 0;
}
static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
@@ -361,7 +350,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
snd_power_wait(hw->card);
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
s = us122l->sk.s;
if (!us122l->master) {
us122l->master = file;
@@ -381,7 +370,6 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
err = 1;
}
unlock:
- mutex_unlock(&us122l->mutex);
wake_up_all(&us122l->sk.sleep);
return err;
}
@@ -577,9 +565,9 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
snd_card_disconnect(card);
us122l = US122L(card);
- mutex_lock(&us122l->mutex);
- us122l_stop(us122l);
- mutex_unlock(&us122l->mutex);
+ scoped_guard(mutex, &us122l->mutex) {
+ us122l_stop(us122l);
+ }
/* release the midi resources */
list_for_each(p, &us122l->midi_list) {
@@ -611,9 +599,8 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
list_for_each(p, &us122l->midi_list)
snd_usbmidi_input_stop(p);
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
usb_stream_stop(&us122l->sk);
- mutex_unlock(&us122l->mutex);
return 0;
}
@@ -633,7 +620,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
if (!us122l)
return 0;
- mutex_lock(&us122l->mutex);
+ guard(mutex)(&us122l->mutex);
/* needed, doesn't restart without: */
if (us122l->is_us144) {
err = usb_set_interface(us122l->dev, 0, 1);
@@ -664,7 +651,6 @@ static int snd_us122l_resume(struct usb_interface *intf)
list_for_each(p, &us122l->midi_list)
snd_usbmidi_input_start(p);
unlock:
- mutex_unlock(&us122l->mutex);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return err;
}
@@ -686,12 +672,6 @@ static const struct usb_device_id snd_us122l_usb_id_table[] = {
.idVendor = 0x0644,
.idProduct = USB_ID_US122MKII
},
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US144MKII,
- .driver_info = US122L_FLAG_US144
- },
{ /* terminator */ }
};
MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
diff --git a/sound/usb/usx2y/us144mkii.c b/sound/usb/usx2y/us144mkii.c
new file mode 100644
index 000000000000..f6572a576c15
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii.c
@@ -0,0 +1,620 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+/*
+ * ALSA Driver for TASCAM US-144MKII Audio Interface
+ */
+
+#include "us144mkii.h"
+
+MODULE_AUTHOR("Å erif Rami <ramiserifpersia@gmail.com>");
+MODULE_DESCRIPTION("ALSA Driver for TASCAM US-144MKII");
+MODULE_LICENSE("GPL");
+
+/**
+ * @brief Module parameters for ALSA card instantiation.
+ *
+ * These parameters allow users to configure how the ALSA sound card
+ * for the TASCAM US-144MKII is instantiated.
+ *
+ * @param index: Array of integers specifying the ALSA card index for each
+ * device. Defaults to -1 (automatic).
+ * @param id: Array of strings specifying the ALSA card ID for each device.
+ * Defaults to "US144MKII".
+ * @param enable: Array of booleans to enable or disable each device.
+ * Defaults to {1, 0, ..., 0} (first device enabled).
+ * @param dev_idx: Internal counter for the number of TASCAM devices probed.
+ */
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static bool enable[SNDRV_CARDS] = { 1, [1 ...(SNDRV_CARDS - 1)] = 0 };
+static int dev_idx;
+
+static int tascam_probe(struct usb_interface *intf,
+ const struct usb_device_id *usb_id);
+static void tascam_disconnect(struct usb_interface *intf);
+static int tascam_suspend(struct usb_interface *intf, pm_message_t message);
+static int tascam_resume(struct usb_interface *intf);
+
+void tascam_free_urbs(struct tascam_card *tascam)
+{
+ int i;
+
+ usb_kill_anchored_urbs(&tascam->playback_anchor);
+ for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
+ if (tascam->playback_urbs[i]) {
+ usb_free_coherent(
+ tascam->dev, tascam->playback_urb_alloc_size,
+ tascam->playback_urbs[i]->transfer_buffer,
+ tascam->playback_urbs[i]->transfer_dma);
+ usb_free_urb(tascam->playback_urbs[i]);
+ tascam->playback_urbs[i] = NULL;
+ }
+ }
+
+ usb_kill_anchored_urbs(&tascam->feedback_anchor);
+ for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
+ if (tascam->feedback_urbs[i]) {
+ usb_free_coherent(
+ tascam->dev, tascam->feedback_urb_alloc_size,
+ tascam->feedback_urbs[i]->transfer_buffer,
+ tascam->feedback_urbs[i]->transfer_dma);
+ usb_free_urb(tascam->feedback_urbs[i]);
+ tascam->feedback_urbs[i] = NULL;
+ }
+ }
+
+ usb_kill_anchored_urbs(&tascam->capture_anchor);
+ for (i = 0; i < NUM_CAPTURE_URBS; i++) {
+ if (tascam->capture_urbs[i]) {
+ usb_free_coherent(
+ tascam->dev, tascam->capture_urb_alloc_size,
+ tascam->capture_urbs[i]->transfer_buffer,
+ tascam->capture_urbs[i]->transfer_dma);
+ usb_free_urb(tascam->capture_urbs[i]);
+ tascam->capture_urbs[i] = NULL;
+ }
+ }
+
+ usb_kill_anchored_urbs(&tascam->midi_in_anchor);
+ for (i = 0; i < NUM_MIDI_IN_URBS; i++) {
+ if (tascam->midi_in_urbs[i]) {
+ usb_free_coherent(
+ tascam->dev, MIDI_IN_BUF_SIZE,
+ tascam->midi_in_urbs[i]->transfer_buffer,
+ tascam->midi_in_urbs[i]->transfer_dma);
+ usb_free_urb(tascam->midi_in_urbs[i]);
+ tascam->midi_in_urbs[i] = NULL;
+ }
+ }
+
+ usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+ for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
+ if (tascam->midi_out_urbs[i]) {
+ usb_free_coherent(
+ tascam->dev, MIDI_OUT_BUF_SIZE,
+ tascam->midi_out_urbs[i]->transfer_buffer,
+ tascam->midi_out_urbs[i]->transfer_dma);
+ usb_free_urb(tascam->midi_out_urbs[i]);
+ tascam->midi_out_urbs[i] = NULL;
+ }
+ }
+
+ kfree(tascam->capture_routing_buffer);
+ tascam->capture_routing_buffer = NULL;
+ kfree(tascam->capture_decode_dst_block);
+ tascam->capture_decode_dst_block = NULL;
+ kfree(tascam->capture_decode_raw_block);
+ tascam->capture_decode_raw_block = NULL;
+ kfree(tascam->capture_ring_buffer);
+ tascam->capture_ring_buffer = NULL;
+}
+
+int tascam_alloc_urbs(struct tascam_card *tascam)
+{
+ int i;
+ size_t max_packet_size;
+
+ max_packet_size = ((96000 / 8000) + 2) * BYTES_PER_FRAME;
+ tascam->playback_urb_alloc_size =
+ max_packet_size * PLAYBACK_URB_PACKETS;
+
+ for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
+ struct urb *urb =
+ usb_alloc_urb(PLAYBACK_URB_PACKETS, GFP_KERNEL);
+
+ if (!urb)
+ goto error;
+ tascam->playback_urbs[i] = urb;
+
+ urb->transfer_buffer = usb_alloc_coherent(
+ tascam->dev, tascam->playback_urb_alloc_size,
+ GFP_KERNEL, &urb->transfer_dma);
+ if (!urb->transfer_buffer)
+ goto error;
+
+ urb->dev = tascam->dev;
+ urb->pipe = usb_sndisocpipe(tascam->dev, EP_AUDIO_OUT);
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = 1;
+ urb->context = tascam;
+ urb->complete = playback_urb_complete;
+ }
+
+ tascam->feedback_urb_alloc_size =
+ FEEDBACK_PACKET_SIZE * FEEDBACK_URB_PACKETS;
+
+ for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
+ struct urb *f_urb =
+ usb_alloc_urb(FEEDBACK_URB_PACKETS, GFP_KERNEL);
+
+ if (!f_urb)
+ goto error;
+ tascam->feedback_urbs[i] = f_urb;
+
+ f_urb->transfer_buffer = usb_alloc_coherent(
+ tascam->dev, tascam->feedback_urb_alloc_size,
+ GFP_KERNEL, &f_urb->transfer_dma);
+ if (!f_urb->transfer_buffer)
+ goto error;
+
+ f_urb->dev = tascam->dev;
+ f_urb->pipe =
+ usb_rcvisocpipe(tascam->dev, EP_PLAYBACK_FEEDBACK);
+ f_urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ f_urb->interval = 4;
+ f_urb->context = tascam;
+ f_urb->complete = feedback_urb_complete;
+ }
+
+ tascam->capture_urb_alloc_size = CAPTURE_URB_SIZE;
+ for (i = 0; i < NUM_CAPTURE_URBS; i++) {
+ struct urb *c_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!c_urb)
+ goto error;
+ tascam->capture_urbs[i] = c_urb;
+
+ c_urb->transfer_buffer = usb_alloc_coherent(
+ tascam->dev, tascam->capture_urb_alloc_size, GFP_KERNEL,
+ &c_urb->transfer_dma);
+ if (!c_urb->transfer_buffer)
+ goto error;
+
+ usb_fill_bulk_urb(c_urb, tascam->dev,
+ usb_rcvbulkpipe(tascam->dev, EP_AUDIO_IN),
+ c_urb->transfer_buffer,
+ tascam->capture_urb_alloc_size,
+ capture_urb_complete, tascam);
+ c_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ }
+
+ /* MIDI URB and buffer allocation */
+ for (i = 0; i < NUM_MIDI_IN_URBS; i++) {
+ struct urb *m_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!m_urb)
+ goto error;
+ tascam->midi_in_urbs[i] = m_urb;
+ m_urb->transfer_buffer =
+ usb_alloc_coherent(tascam->dev, MIDI_IN_BUF_SIZE,
+ GFP_KERNEL, &m_urb->transfer_dma);
+ if (!m_urb->transfer_buffer)
+ goto error;
+ usb_fill_bulk_urb(m_urb, tascam->dev,
+ usb_rcvbulkpipe(tascam->dev, EP_MIDI_IN),
+ m_urb->transfer_buffer, MIDI_IN_BUF_SIZE,
+ tascam_midi_in_urb_complete, tascam);
+ m_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ }
+
+ for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
+ struct urb *m_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!m_urb)
+ goto error;
+ tascam->midi_out_urbs[i] = m_urb;
+ m_urb->transfer_buffer =
+ usb_alloc_coherent(tascam->dev, MIDI_OUT_BUF_SIZE,
+ GFP_KERNEL, &m_urb->transfer_dma);
+ if (!m_urb->transfer_buffer)
+ goto error;
+ usb_fill_bulk_urb(m_urb, tascam->dev,
+ usb_sndbulkpipe(tascam->dev, EP_MIDI_OUT),
+ m_urb->transfer_buffer,
+ 0, /* length set later */
+ tascam_midi_out_urb_complete, tascam);
+ m_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ }
+
+ tascam->capture_ring_buffer =
+ kmalloc(CAPTURE_RING_BUFFER_SIZE, GFP_KERNEL);
+ if (!tascam->capture_ring_buffer)
+ goto error;
+
+ tascam->capture_decode_raw_block =
+ kmalloc(RAW_BYTES_PER_DECODE_BLOCK, GFP_KERNEL);
+ if (!tascam->capture_decode_raw_block)
+ goto error;
+
+ tascam->capture_decode_dst_block =
+ kmalloc(FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME *
+ DECODED_SAMPLE_SIZE,
+ GFP_KERNEL);
+ if (!tascam->capture_decode_dst_block)
+ goto error;
+
+ tascam->capture_routing_buffer =
+ kmalloc(FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME *
+ DECODED_SAMPLE_SIZE,
+ GFP_KERNEL);
+ if (!tascam->capture_routing_buffer)
+ goto error;
+
+ return 0;
+
+error:
+ dev_err(tascam->card->dev, "Failed to allocate URBs\n");
+ tascam_free_urbs(tascam);
+ return -ENOMEM;
+}
+
+void tascam_stop_work_handler(struct work_struct *work)
+{
+ struct tascam_card *tascam =
+ container_of(work, struct tascam_card, stop_work);
+
+ usb_kill_anchored_urbs(&tascam->playback_anchor);
+ usb_kill_anchored_urbs(&tascam->feedback_anchor);
+ usb_kill_anchored_urbs(&tascam->capture_anchor);
+ atomic_set(&tascam->active_urbs, 0);
+}
+
+/**
+ * tascam_card_private_free() - Frees private data associated with the sound
+ * card.
+ * @card: Pointer to the ALSA sound card instance.
+ *
+ * This function is called when the sound card is being freed. It releases
+ * resources allocated for the tascam_card structure, including the MIDI
+ * input FIFO and decrements the USB device reference count.
+ */
+static void tascam_card_private_free(struct snd_card *card)
+{
+ struct tascam_card *tascam = card->private_data;
+
+ if (tascam) {
+ kfifo_free(&tascam->midi_in_fifo);
+ if (tascam->dev) {
+ usb_put_dev(tascam->dev);
+ tascam->dev = NULL;
+ }
+ }
+}
+
+/**
+ * tascam_suspend() - Handles device suspension.
+ * @intf: The USB interface being suspended.
+ * @message: Power management message.
+ *
+ * This function is called when the device is suspended. It stops all active
+ * streams, kills all URBs, and sends a vendor-specific deep sleep command
+ * to the device to ensure a stable low-power state.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct tascam_card *tascam = usb_get_intfdata(intf);
+
+ if (!tascam)
+ return 0;
+
+ snd_pcm_suspend_all(tascam->pcm);
+
+ cancel_work_sync(&tascam->stop_work);
+ cancel_work_sync(&tascam->capture_work);
+ cancel_work_sync(&tascam->midi_in_work);
+ cancel_work_sync(&tascam->midi_out_work);
+ cancel_work_sync(&tascam->stop_pcm_work);
+ usb_kill_anchored_urbs(&tascam->playback_anchor);
+ usb_kill_anchored_urbs(&tascam->capture_anchor);
+ usb_kill_anchored_urbs(&tascam->feedback_anchor);
+ usb_kill_anchored_urbs(&tascam->midi_in_anchor);
+ usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+
+ dev_info(&intf->dev, "sending deep sleep command\n");
+ int err = usb_control_msg(tascam->dev, usb_sndctrlpipe(tascam->dev, 0),
+ VENDOR_REQ_DEEP_SLEEP, RT_H2D_VENDOR_DEV,
+ 0x0000, 0x0000, NULL, 0, USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ dev_err(&intf->dev, "deep sleep command failed: %d\n", err);
+
+ return 0;
+}
+
+/**
+ * tascam_resume() - Handles device resumption from suspend.
+ * @intf: The USB interface being resumed.
+ *
+ * This function is called when the device resumes from suspend. It
+ * re-establishes the active USB interface settings and re-configures the sample
+ * rate if it was previously active.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int tascam_resume(struct usb_interface *intf)
+{
+ struct tascam_card *tascam = usb_get_intfdata(intf);
+ int err;
+
+ if (!tascam)
+ return 0;
+
+ dev_info(&intf->dev, "resuming TASCAM US-144MKII\n");
+
+ /*
+ * The device requires a full re-initialization sequence upon resume.
+ * First, re-establish the active USB interface settings.
+ */
+ err = usb_set_interface(tascam->dev, 0, 1);
+ if (err < 0) {
+ dev_err(&intf->dev,
+ "resume: failed to set alt setting on intf 0: %d\n",
+ err);
+ return err;
+ }
+ err = usb_set_interface(tascam->dev, 1, 1);
+ if (err < 0) {
+ dev_err(&intf->dev,
+ "resume: failed to set alt setting on intf 1: %d\n",
+ err);
+ return err;
+ }
+
+ /* Re-configure the sample rate if one was previously active */
+ if (tascam->current_rate > 0)
+ us144mkii_configure_device_for_rate(tascam,
+ tascam->current_rate);
+
+ return 0;
+}
+
+static void tascam_error_timer(struct timer_list *t)
+{
+ struct tascam_card *tascam =
+ container_of(t, struct tascam_card, error_timer);
+
+ if (atomic_read(&tascam->midi_in_active))
+ schedule_work(&tascam->midi_in_work);
+ if (atomic_read(&tascam->midi_out_active))
+ schedule_work(&tascam->midi_out_work);
+}
+
+/**
+ * tascam_probe() - Probes for the TASCAM US-144MKII device.
+ * @intf: The USB interface being probed.
+ * @usb_id: The USB device ID.
+ *
+ * This function is the entry point for the USB driver when a matching device
+ * is found. It performs initial device setup, including:
+ * - Checking for the second interface (MIDI) and associating it.
+ * - Performing a vendor-specific handshake with the device.
+ * - Setting alternate settings for USB interfaces.
+ * - Creating and registering the ALSA sound card, PCM device, and MIDI device.
+ * - Allocating and initializing URBs for audio and MIDI transfers.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int tascam_probe(struct usb_interface *intf,
+ const struct usb_device_id *usb_id)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct snd_card *card;
+ struct tascam_card *tascam;
+ int err;
+ char *handshake_buf __free(kfree) = NULL;
+
+ if (dev->speed != USB_SPEED_HIGH)
+ dev_info(
+ &dev->dev,
+ "Device is connected to a USB 1.1 port, this is not supported.\n");
+
+ /* The device has two interfaces; we drive both from this driver. */
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ tascam = usb_get_intfdata(usb_ifnum_to_if(dev, 0));
+ if (tascam) {
+ usb_set_intfdata(intf, tascam);
+ tascam->iface1 = intf;
+ }
+ return 0; /* Let the core handle this interface */
+ }
+
+ if (dev_idx >= SNDRV_CARDS) {
+ dev_err(&dev->dev, "Too many TASCAM devices present");
+ return -ENODEV;
+ }
+
+ if (!enable[dev_idx]) {
+ dev_info(&dev->dev, "TASCAM US-144MKII device disabled");
+ return -ENOENT;
+ }
+
+ handshake_buf = kmalloc(1, GFP_KERNEL);
+ if (!handshake_buf)
+ return -ENOMEM;
+
+ /* Perform vendor-specific handshake */
+ err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ VENDOR_REQ_MODE_CONTROL, RT_D2H_VENDOR_DEV,
+ MODE_VAL_HANDSHAKE_READ, 0x0000, handshake_buf, 1,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0) {
+ dev_err(&dev->dev, "Handshake read failed with %d\n", err);
+ return err;
+ }
+
+ if (handshake_buf[0] != 0x12 && handshake_buf[0] != 0x16 &&
+ handshake_buf[0] != 0x30 && handshake_buf[0] != 0x32) {
+ dev_err(&dev->dev, "Unexpected handshake value: 0x%x\n",
+ handshake_buf[0]);
+ return -ENODEV;
+ }
+
+ /* Set alternate settings to enable audio/MIDI endpoints */
+ err = usb_set_interface(dev, 0, 1);
+ if (err < 0) {
+ dev_err(&dev->dev,
+ "Failed to set alt setting 1 on interface 0: %d\n",
+ err);
+ return err;
+ }
+
+ err = usb_set_interface(dev, 1, 1);
+ if (err < 0) {
+ dev_err(&dev->dev,
+ "Failed to set alt setting 1 on interface 1: %d\n",
+ err);
+ return err;
+ }
+
+ err = snd_card_new(&dev->dev, index[dev_idx], id[dev_idx], THIS_MODULE,
+ sizeof(struct tascam_card), &card);
+ if (err < 0) {
+ dev_err(&dev->dev, "Failed to create sound card instance\n");
+ return err;
+ }
+
+ tascam = card->private_data;
+ card->private_free = tascam_card_private_free;
+ tascam->dev = usb_get_dev(dev);
+ tascam->card = card;
+ tascam->iface0 = intf;
+ tascam->digital_out_source = 1;
+ tascam->capture_34_source = 1;
+
+ spin_lock_init(&tascam->lock);
+ spin_lock_init(&tascam->midi_in_lock);
+ spin_lock_init(&tascam->midi_out_lock);
+ init_usb_anchor(&tascam->playback_anchor);
+ init_usb_anchor(&tascam->capture_anchor);
+ init_usb_anchor(&tascam->feedback_anchor);
+ init_usb_anchor(&tascam->midi_in_anchor);
+ init_usb_anchor(&tascam->midi_out_anchor);
+
+ timer_setup(&tascam->error_timer, tascam_error_timer, 0);
+
+ INIT_WORK(&tascam->stop_work, tascam_stop_work_handler);
+ INIT_WORK(&tascam->stop_pcm_work, tascam_stop_pcm_work_handler);
+ INIT_WORK(&tascam->capture_work, tascam_capture_work_handler);
+ init_completion(&tascam->midi_out_drain_completion);
+
+ if (kfifo_alloc(&tascam->midi_in_fifo, MIDI_IN_FIFO_SIZE, GFP_KERNEL)) {
+ snd_card_free(card);
+ return -ENOMEM;
+ }
+
+ strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+ if (le16_to_cpu(dev->descriptor.idProduct) == USB_PID_TASCAM_US144) {
+ strscpy(card->shortname, "TASCAM US-144",
+ sizeof(card->shortname));
+ } else if (le16_to_cpu(dev->descriptor.idProduct) == USB_PID_TASCAM_US144MKII) {
+ strscpy(card->shortname, "TASCAM US-144MKII",
+ sizeof(card->shortname));
+ } else {
+ strscpy(card->shortname, "TASCAM Unknown",
+ sizeof(card->shortname));
+ }
+ snprintf(card->longname, sizeof(card->longname), "%s (%04x:%04x) at %s",
+ card->shortname, USB_VID_TASCAM, dev->descriptor.idProduct,
+ dev_name(&dev->dev));
+
+ err = snd_pcm_new(card, "US144MKII PCM", 0, 1, 1, &tascam->pcm);
+ if (err < 0)
+ goto free_card;
+ tascam->pcm->private_data = tascam;
+ strscpy(tascam->pcm->name, "US144MKII PCM", sizeof(tascam->pcm->name));
+
+ err = tascam_init_pcm(tascam->pcm);
+ if (err < 0)
+ goto free_card;
+
+ err = tascam_create_midi(tascam);
+ if (err < 0)
+ goto free_card;
+
+ err = tascam_create_controls(tascam);
+ if (err < 0)
+ goto free_card;
+
+ err = tascam_alloc_urbs(tascam);
+ if (err < 0)
+ goto free_card;
+
+ err = snd_card_register(card);
+ if (err < 0)
+ goto free_card;
+
+ usb_set_intfdata(intf, tascam);
+
+ dev_idx++;
+ return 0;
+
+free_card:
+ tascam_free_urbs(tascam);
+ snd_card_free(card);
+ return err;
+}
+
+/**
+ * tascam_disconnect() - Disconnects the TASCAM US-144MKII device.
+ * @intf: The USB interface being disconnected.
+ *
+ * This function is called when the device is disconnected from the system.
+ * It cleans up all allocated resources, including killing URBs, freeing
+ * the sound card, and releasing memory.
+ */
+static void tascam_disconnect(struct usb_interface *intf)
+{
+ struct tascam_card *tascam = usb_get_intfdata(intf);
+
+ if (!tascam)
+ return;
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+ /* Ensure all deferred work is complete before freeing resources */
+ snd_card_disconnect(tascam->card);
+ cancel_work_sync(&tascam->stop_work);
+ cancel_work_sync(&tascam->capture_work);
+ cancel_work_sync(&tascam->midi_in_work);
+ cancel_work_sync(&tascam->midi_out_work);
+ cancel_work_sync(&tascam->stop_pcm_work);
+
+ usb_kill_anchored_urbs(&tascam->playback_anchor);
+ usb_kill_anchored_urbs(&tascam->capture_anchor);
+ usb_kill_anchored_urbs(&tascam->feedback_anchor);
+ usb_kill_anchored_urbs(&tascam->midi_in_anchor);
+ usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+ timer_delete_sync(&tascam->error_timer);
+ tascam_free_urbs(tascam);
+ snd_card_free(tascam->card);
+ dev_idx--;
+ }
+}
+
+static const struct usb_device_id tascam_usb_ids[] = {
+ { USB_DEVICE(USB_VID_TASCAM, USB_PID_TASCAM_US144) },
+ { USB_DEVICE(USB_VID_TASCAM, USB_PID_TASCAM_US144MKII) },
+ { /* Terminating entry */ }
+};
+MODULE_DEVICE_TABLE(usb, tascam_usb_ids);
+
+static struct usb_driver tascam_alsa_driver = {
+ .name = DRIVER_NAME,
+ .probe = tascam_probe,
+ .disconnect = tascam_disconnect,
+ .suspend = tascam_suspend,
+ .resume = tascam_resume,
+ .id_table = tascam_usb_ids,
+};
+
+module_usb_driver(tascam_alsa_driver);
diff --git a/sound/usb/usx2y/us144mkii.h b/sound/usb/usx2y/us144mkii.h
new file mode 100644
index 000000000000..95c4341f038a
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii.h
@@ -0,0 +1,367 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#ifndef __US144MKII_H
+#define __US144MKII_H
+
+#include <linux/kfifo.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+#include <sound/control.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+
+#define DRIVER_NAME "us144mkii"
+
+/* --- USB Device Identification --- */
+#define USB_VID_TASCAM 0x0644
+#define USB_PID_TASCAM_US144 0x800f
+#define USB_PID_TASCAM_US144MKII 0x8020
+
+/* --- USB Endpoints (Alternate Setting 1) --- */
+#define EP_PLAYBACK_FEEDBACK 0x81
+#define EP_AUDIO_OUT 0x02
+#define EP_MIDI_IN 0x83
+#define EP_MIDI_OUT 0x04
+#define EP_AUDIO_IN 0x86
+
+/* --- USB Control Message Protocol --- */
+#define RT_H2D_CLASS_EP (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT)
+#define RT_D2H_CLASS_EP (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT)
+#define RT_H2D_VENDOR_DEV (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+#define RT_D2H_VENDOR_DEV (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+
+enum uac_request {
+ UAC_SET_CUR = 0x01,
+ UAC_GET_CUR = 0x81,
+};
+
+enum uac_control_selector {
+ UAC_SAMPLING_FREQ_CONTROL = 0x0100,
+};
+
+enum tascam_vendor_request {
+ VENDOR_REQ_REGISTER_WRITE = 0x41,
+ VENDOR_REQ_DEEP_SLEEP = 0x44,
+ VENDOR_REQ_MODE_CONTROL = 0x49,
+};
+
+enum tascam_mode_value {
+ MODE_VAL_HANDSHAKE_READ = 0x0000,
+ MODE_VAL_CONFIG = 0x0010,
+ MODE_VAL_STREAM_START = 0x0030,
+};
+
+#define HANDSHAKE_SUCCESS_VAL 0x12
+
+enum tascam_register {
+ REG_ADDR_UNKNOWN_0D = 0x0d04,
+ REG_ADDR_UNKNOWN_0E = 0x0e00,
+ REG_ADDR_UNKNOWN_0F = 0x0f00,
+ REG_ADDR_RATE_44100 = 0x1000,
+ REG_ADDR_RATE_48000 = 0x1002,
+ REG_ADDR_RATE_88200 = 0x1008,
+ REG_ADDR_RATE_96000 = 0x100a,
+ REG_ADDR_UNKNOWN_11 = 0x110b,
+};
+
+#define REG_VAL_ENABLE 0x0101
+
+/* --- URB Configuration --- */
+#define NUM_PLAYBACK_URBS 4
+#define PLAYBACK_URB_PACKETS 8
+#define NUM_FEEDBACK_URBS 4
+#define FEEDBACK_URB_PACKETS 1
+#define FEEDBACK_PACKET_SIZE 3
+#define NUM_CAPTURE_URBS 8
+#define CAPTURE_URB_SIZE 512
+#define CAPTURE_RING_BUFFER_SIZE (CAPTURE_URB_SIZE * NUM_CAPTURE_URBS * 4)
+#define NUM_MIDI_IN_URBS 4
+#define MIDI_IN_BUF_SIZE 64
+#define MIDI_IN_FIFO_SIZE (MIDI_IN_BUF_SIZE * NUM_MIDI_IN_URBS)
+#define MIDI_OUT_BUF_SIZE 64
+#define NUM_MIDI_OUT_URBS 4
+#define USB_CTRL_TIMEOUT_MS 1000
+#define FEEDBACK_SYNC_LOSS_THRESHOLD 41
+
+/* --- Audio Format Configuration --- */
+#define BYTES_PER_SAMPLE 3
+#define NUM_CHANNELS 4
+#define BYTES_PER_FRAME (NUM_CHANNELS * BYTES_PER_SAMPLE)
+#define FEEDBACK_ACCUMULATOR_SIZE 128
+
+/* --- Capture Decoding Defines --- */
+#define DECODED_CHANNELS_PER_FRAME 4
+#define DECODED_SAMPLE_SIZE 4
+#define FRAMES_PER_DECODE_BLOCK 8
+#define RAW_BYTES_PER_DECODE_BLOCK 512
+
+/**
+ * struct us144mkii_frame_pattern_observer - State for dynamic feedback
+ * patterns.
+ * @sample_rate_khz: The current sample rate in kHz.
+ * @base_feedback_value: The nominal feedback value for the current rate.
+ * @feedback_offset: An offset to align the feedback value range.
+ * @full_frame_patterns: A 2D array of pre-calculated packet size patterns.
+ * @current_index: The current index into the pattern array.
+ * @previous_index: The previous index, used for state tracking.
+ * @sync_locked: A flag indicating if the pattern has locked to the stream.
+ */
+struct us144mkii_frame_pattern_observer {
+ unsigned int sample_rate_khz;
+ unsigned int base_feedback_value;
+ int feedback_offset;
+ unsigned int full_frame_patterns[5][8];
+ unsigned int current_index;
+ unsigned int previous_index;
+ bool sync_locked;
+};
+
+/**
+ * struct tascam_card - Main driver data structure for the TASCAM US-144MKII.
+ * @dev: Pointer to the USB device.
+ * @iface0: Pointer to USB interface 0 (audio).
+ * @iface1: Pointer to USB interface 1 (MIDI).
+ * @card: Pointer to the ALSA sound card instance.
+ * @pcm: Pointer to the ALSA PCM device.
+ * @rmidi: Pointer to the ALSA rawmidi device.
+ *
+ * @playback_substream: Pointer to the active playback PCM substream.
+ * @playback_urbs: Array of URBs for playback.
+ * @playback_urb_alloc_size: Size of allocated buffer for each playback URB.
+ * @feedback_urbs: Array of URBs for feedback.
+ * @feedback_urb_alloc_size: Size of allocated buffer for each feedback URB.
+ * @playback_active: Atomic flag indicating if playback is active.
+ * @playback_frames_consumed: Total frames consumed by playback.
+ * @driver_playback_pos: Current position in the ALSA playback buffer (frames).
+ * @last_period_pos: Last reported period position for playback.
+ *
+ * @capture_substream: Pointer to the active capture PCM substream.
+ * @capture_urbs: Array of URBs for capture.
+ * @capture_urb_alloc_size: Size of allocated buffer for each capture URB.
+ * @capture_active: Atomic flag indicating if capture is active.
+ * @driver_capture_pos: Current position in the ALSA capture buffer (frames).
+ * @capture_frames_processed: Total frames processed for capture.
+ * @last_capture_period_pos: Last reported period position for capture.
+ * @capture_ring_buffer: Ring buffer for raw capture data from USB.
+ * @capture_ring_buffer_read_ptr: Read pointer for the capture ring buffer.
+ * @capture_ring_buffer_write_ptr: Write pointer for the capture ring buffer.
+ * @capture_decode_raw_block: Buffer for a raw 512-byte capture block.
+ * @capture_decode_dst_block: Buffer for decoded 32-bit capture samples.
+ * @capture_routing_buffer: Intermediate buffer for capture routing.
+ * @capture_work: Work struct for deferred capture processing.
+ * @stop_work: Work struct for deferred stream stopping.
+ * @stop_pcm_work: Work struct for stopping PCM due to a fatal error (e.g.
+ * xrun).
+ *
+ * @midi_in_substream: Pointer to the active MIDI input substream.
+ * @midi_out_substream: Pointer to the active MIDI output substream.
+ * @midi_in_urbs: Array of URBs for MIDI input.
+ * @midi_out_urbs: Array of URBs for MIDI output.
+ * @midi_in_active: Atomic flag indicating if MIDI input is active.
+ * @midi_out_active: Atomic flag indicating if MIDI output is active.
+ * @midi_in_fifo: FIFO for raw MIDI input data.
+ * @midi_in_work: Work struct for deferred MIDI input processing.
+ * @midi_out_work: Work struct for deferred MIDI output processing.
+ * @midi_in_lock: Spinlock for MIDI input FIFO.
+ * @midi_out_lock: Spinlock for MIDI output.
+ * @midi_out_urbs_in_flight: Bitmap of MIDI output URBs currently in flight.
+ * @midi_running_status: Stores the last MIDI status byte for running status.
+ * @error_timer: Timer for MIDI error retry logic.
+ *
+ * @lock: Main spinlock for protecting shared driver state.
+ * @active_urbs: Atomic counter for active URBs.
+ * @current_rate: Currently configured sample rate of the device.
+ * @line_out_source: Source for Line Outputs (0: Playback 1-2, 1: Playback 3-4).
+ * @digital_out_source: Source for Digital Outputs (0: Playback 1-2, 1: Playback
+ * 3-4).
+ * @capture_12_source: Source for Capture channels 1-2 (0: Analog In, 1: Digital
+ * In).
+ * @capture_34_source: Source for Capture channels 3-4 (0: Analog In, 1: Digital
+ * In).
+ *
+ * @feedback_accumulator_pattern: Stores the calculated frames per packet for
+ * feedback.
+ * @feedback_pattern_out_idx: Read index for feedback_accumulator_pattern.
+ * @feedback_pattern_in_idx: Write index for feedback_accumulator_pattern.
+ * @feedback_synced: Flag indicating if feedback is synced.
+ * @feedback_consecutive_errors: Counter for consecutive feedback errors.
+ * @feedback_urb_skip_count: Number of feedback URBs to skip initially for
+ * stabilization.
+ * @fpo: Holds the state for the dynamic feedback pattern generation.
+ *
+ * @playback_anchor: USB anchor for playback URBs.
+ * @capture_anchor: USB anchor for capture URBs.
+ * @feedback_anchor: USB anchor for feedback URBs.
+ * @midi_in_anchor: USB anchor for MIDI input URBs.
+ * @midi_out_anchor: USB anchor for MIDI output URBs.
+ */
+struct tascam_card {
+ /* --- Core device pointers --- */
+ struct usb_device *dev;
+ struct usb_interface *iface0;
+ struct usb_interface *iface1;
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ struct snd_rawmidi *rmidi;
+
+ /* --- PCM Substreams --- */
+ struct snd_pcm_substream *playback_substream;
+ struct snd_pcm_substream *capture_substream;
+
+ /* --- URBs and Anchors --- */
+ struct urb *playback_urbs[NUM_PLAYBACK_URBS];
+ size_t playback_urb_alloc_size;
+ struct urb *feedback_urbs[NUM_FEEDBACK_URBS];
+ size_t feedback_urb_alloc_size;
+ struct urb *capture_urbs[NUM_CAPTURE_URBS];
+ size_t capture_urb_alloc_size;
+ struct urb *midi_in_urbs[NUM_MIDI_IN_URBS];
+ struct urb *midi_out_urbs[NUM_MIDI_OUT_URBS];
+ struct usb_anchor playback_anchor;
+ struct usb_anchor capture_anchor;
+ struct usb_anchor feedback_anchor;
+ struct usb_anchor midi_in_anchor;
+ struct usb_anchor midi_out_anchor;
+
+ /* --- Stream State --- */
+ spinlock_t lock;
+ atomic_t playback_active;
+ atomic_t capture_active;
+ atomic_t active_urbs;
+ int current_rate;
+
+ /* --- Playback State --- */
+ u64 playback_frames_consumed;
+ snd_pcm_uframes_t driver_playback_pos;
+ u64 last_period_pos;
+
+ /* --- Capture State --- */
+ u64 capture_frames_processed;
+ snd_pcm_uframes_t driver_capture_pos;
+ u64 last_capture_period_pos;
+ u8 *capture_ring_buffer;
+ size_t capture_ring_buffer_read_ptr;
+ size_t capture_ring_buffer_write_ptr;
+ u8 *capture_decode_raw_block;
+ s32 *capture_decode_dst_block;
+ s32 *capture_routing_buffer;
+
+ /* --- MIDI State --- */
+ struct snd_rawmidi_substream *midi_in_substream;
+ struct snd_rawmidi_substream *midi_out_substream;
+ atomic_t midi_in_active;
+ atomic_t midi_out_active;
+ struct kfifo midi_in_fifo;
+ spinlock_t midi_in_lock;
+ spinlock_t midi_out_lock;
+ unsigned long midi_out_urbs_in_flight;
+ u8 midi_running_status;
+ struct timer_list error_timer;
+ struct completion midi_out_drain_completion;
+
+ /* --- Feedback Sync State --- */
+ unsigned int feedback_accumulator_pattern[FEEDBACK_ACCUMULATOR_SIZE];
+ unsigned int feedback_pattern_out_idx;
+ unsigned int feedback_pattern_in_idx;
+ bool feedback_synced;
+ unsigned int feedback_consecutive_errors;
+ unsigned int feedback_urb_skip_count;
+ struct us144mkii_frame_pattern_observer fpo;
+
+ /* --- Workqueues --- */
+ struct work_struct stop_work;
+ struct work_struct stop_pcm_work;
+ struct work_struct capture_work;
+ struct work_struct midi_in_work;
+ struct work_struct midi_out_work;
+
+ /* --- Mixer/Routing State --- */
+ unsigned int line_out_source;
+ unsigned int digital_out_source;
+ unsigned int capture_12_source;
+ unsigned int capture_34_source;
+};
+
+/* main.c */
+/**
+ * tascam_free_urbs() - Free all allocated URBs and associated buffers.
+ * @tascam: the tascam_card instance
+ *
+ * This function kills, unlinks, and frees all playback, feedback, capture,
+ * and MIDI URBs, along with their transfer buffers and the capture
+ * ring/decode buffers.
+ */
+void tascam_free_urbs(struct tascam_card *tascam);
+
+/**
+ * tascam_alloc_urbs() - Allocate all URBs and associated buffers.
+ * @tascam: the tascam_card instance
+ *
+ * This function allocates and initializes all URBs for playback, feedback,
+ * capture, and MIDI, as well as the necessary buffers for data processing.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_alloc_urbs(struct tascam_card *tascam);
+
+/**
+ * tascam_stop_work_handler() - Work handler to stop all active streams.
+ * @work: Pointer to the work_struct.
+ *
+ * This function is scheduled to stop all active URBs (playback, feedback,
+ * capture) and reset the active_urbs counter.
+ */
+void tascam_stop_work_handler(struct work_struct *work);
+
+/* us144mkii_pcm.h */
+#include "us144mkii_pcm.h"
+
+/* us144mkii_midi.c */
+/**
+ * tascam_midi_in_urb_complete() - Completion handler for MIDI IN URBs
+ * @urb: The completed URB.
+ *
+ * This function runs in interrupt context. It places the raw data from the
+ * USB endpoint into a kfifo and schedules a work item to process it later,
+ * ensuring the interrupt handler remains fast.
+ */
+void tascam_midi_in_urb_complete(struct urb *urb);
+
+/**
+ * tascam_midi_out_urb_complete() - Completion handler for MIDI OUT bulk URB.
+ * @urb: The completed URB.
+ *
+ * This function runs in interrupt context. It marks the output URB as no
+ * longer in-flight. It then re-schedules the work handler to check for and
+ * send any more data waiting in the ALSA buffer. This is a safe, non-blocking
+ * way to continue the data transmission chain.
+ */
+void tascam_midi_out_urb_complete(struct urb *urb);
+
+/**
+ * tascam_create_midi() - Create and initialize the ALSA rawmidi device.
+ * @tascam: The driver instance.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_create_midi(struct tascam_card *tascam);
+
+/* us144mkii_controls.c */
+/**
+ * tascam_create_controls() - Creates and adds ALSA mixer controls for the
+ * device.
+ * @tascam: The driver instance.
+ *
+ * This function registers custom ALSA controls for managing audio routing
+ * (line out source, digital out source, capture 1-2 source, capture 3-4 source)
+ * and displaying the current sample rate.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_create_controls(struct tascam_card *tascam);
+
+#endif /* __US144MKII_H */
diff --git a/sound/usb/usx2y/us144mkii_capture.c b/sound/usb/usx2y/us144mkii_capture.c
new file mode 100644
index 000000000000..00188ff6cd51
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_capture.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#include "us144mkii.h"
+
+/**
+ * tascam_capture_open() - Opens the PCM capture substream.
+ * @substream: The ALSA PCM substream to open.
+ *
+ * This function sets the hardware parameters for the capture substream
+ * and stores a reference to the substream in the driver's private data.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_open(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+
+ substream->runtime->hw = tascam_pcm_hw;
+ tascam->capture_substream = substream;
+ atomic_set(&tascam->capture_active, 0);
+
+ return 0;
+}
+
+/**
+ * tascam_capture_close() - Closes the PCM capture substream.
+ * @substream: The ALSA PCM substream to close.
+ *
+ * This function clears the reference to the capture substream in the
+ * driver's private data.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_close(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+
+ tascam->capture_substream = NULL;
+
+ return 0;
+}
+
+/**
+ * tascam_capture_prepare() - Prepares the PCM capture substream for use.
+ * @substream: The ALSA PCM substream to prepare.
+ *
+ * This function initializes capture-related counters and ring buffer pointers.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_prepare(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+
+ tascam->driver_capture_pos = 0;
+ tascam->capture_frames_processed = 0;
+ tascam->last_capture_period_pos = 0;
+ tascam->capture_ring_buffer_read_ptr = 0;
+ tascam->capture_ring_buffer_write_ptr = 0;
+
+ return 0;
+}
+
+/**
+ * tascam_capture_pointer() - Returns the current capture pointer position.
+ * @substream: The ALSA PCM substream.
+ *
+ * This function returns the current position of the capture pointer within
+ * the ALSA ring buffer, in frames.
+ *
+ * Return: The current capture pointer position in frames.
+ */
+static snd_pcm_uframes_t
+tascam_capture_pointer(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ u64 pos;
+
+ if (!atomic_read(&tascam->capture_active))
+ return 0;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ pos = tascam->capture_frames_processed;
+ }
+
+ if (runtime->buffer_size == 0)
+ return 0;
+
+ return do_div(pos, runtime->buffer_size);
+}
+
+/**
+ * tascam_capture_ops - ALSA PCM operations for capture.
+ *
+ * This structure defines the callback functions for capture stream operations,
+ * including open, close, ioctl, hardware parameters, hardware free, prepare,
+ * trigger, and pointer.
+ */
+const struct snd_pcm_ops tascam_capture_ops = {
+ .open = tascam_capture_open,
+ .close = tascam_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = tascam_pcm_hw_params,
+ .hw_free = tascam_pcm_hw_free,
+ .prepare = tascam_capture_prepare,
+ .trigger = tascam_pcm_trigger,
+ .pointer = tascam_capture_pointer,
+};
+
+/**
+ * decode_tascam_capture_block() - Decodes a raw 512-byte block from the device.
+ * @src_block: Pointer to the 512-byte raw source block.
+ * @dst_block: Pointer to the destination buffer for decoded audio frames.
+ *
+ * The device sends audio data in a complex, multiplexed format. This function
+ * demultiplexes the bits from the raw block into 8 frames of 4-channel,
+ * 24-bit audio (stored in 32-bit containers).
+ */
+static void decode_tascam_capture_block(const u8 *src_block, s32 *dst_block)
+{
+ int frame, bit;
+
+ memset(dst_block, 0,
+ FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME *
+ DECODED_SAMPLE_SIZE);
+
+ for (frame = 0; frame < FRAMES_PER_DECODE_BLOCK; ++frame) {
+ const u8 *p_src_frame_base = src_block + frame * 64;
+ s32 *p_dst_frame = dst_block + frame * 4;
+
+ s32 ch[4] = { 0 };
+
+ for (bit = 0; bit < 24; ++bit) {
+ u8 byte1 = p_src_frame_base[bit];
+ u8 byte2 = p_src_frame_base[bit + 32];
+
+ ch[0] = (ch[0] << 1) | (byte1 & 1);
+ ch[2] = (ch[2] << 1) | ((byte1 >> 1) & 1);
+
+ ch[1] = (ch[1] << 1) | (byte2 & 1);
+ ch[3] = (ch[3] << 1) | ((byte2 >> 1) & 1);
+ }
+
+ /*
+ * The result is a 24-bit sample. Shift left by 8 to align it to
+ * the most significant bits of a 32-bit integer (S32_LE format).
+ */
+ p_dst_frame[0] = ch[0] << 8;
+ p_dst_frame[1] = ch[1] << 8;
+ p_dst_frame[2] = ch[2] << 8;
+ p_dst_frame[3] = ch[3] << 8;
+ }
+}
+
+void tascam_capture_work_handler(struct work_struct *work)
+{
+ struct tascam_card *tascam =
+ container_of(work, struct tascam_card, capture_work);
+ struct snd_pcm_substream *substream = tascam->capture_substream;
+ struct snd_pcm_runtime *runtime;
+ u8 *raw_block = tascam->capture_decode_raw_block;
+ s32 *decoded_block = tascam->capture_decode_dst_block;
+ s32 *routed_block = tascam->capture_routing_buffer;
+
+ if (!substream || !substream->runtime)
+ return;
+ runtime = substream->runtime;
+
+ if (!raw_block || !decoded_block || !routed_block) {
+ dev_err(tascam->card->dev,
+ "Capture decode/routing buffers not allocated!\n");
+ return;
+ }
+
+ while (atomic_read(&tascam->capture_active)) {
+ size_t write_ptr, read_ptr, available_data;
+ bool can_process;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ write_ptr = tascam->capture_ring_buffer_write_ptr;
+ read_ptr = tascam->capture_ring_buffer_read_ptr;
+ available_data = (write_ptr >= read_ptr) ?
+ (write_ptr - read_ptr) :
+ (CAPTURE_RING_BUFFER_SIZE -
+ read_ptr + write_ptr);
+ can_process =
+ (available_data >= RAW_BYTES_PER_DECODE_BLOCK);
+
+ if (can_process) {
+ size_t bytes_to_end =
+ CAPTURE_RING_BUFFER_SIZE - read_ptr;
+ if (bytes_to_end >=
+ RAW_BYTES_PER_DECODE_BLOCK) {
+ memcpy(raw_block,
+ tascam->capture_ring_buffer +
+ read_ptr,
+ RAW_BYTES_PER_DECODE_BLOCK);
+ } else {
+ memcpy(raw_block,
+ tascam->capture_ring_buffer +
+ read_ptr,
+ bytes_to_end);
+ memcpy(raw_block + bytes_to_end,
+ tascam->capture_ring_buffer,
+ RAW_BYTES_PER_DECODE_BLOCK -
+ bytes_to_end);
+ }
+ tascam->capture_ring_buffer_read_ptr =
+ (read_ptr +
+ RAW_BYTES_PER_DECODE_BLOCK) %
+ CAPTURE_RING_BUFFER_SIZE;
+ }
+ }
+
+ if (!can_process)
+ break;
+
+ decode_tascam_capture_block(raw_block, decoded_block);
+ process_capture_routing_us144mkii(tascam, decoded_block,
+ routed_block);
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (atomic_read(&tascam->capture_active)) {
+ int f;
+
+ for (f = 0; f < FRAMES_PER_DECODE_BLOCK; ++f) {
+ u8 *dst_frame_start =
+ runtime->dma_area +
+ frames_to_bytes(
+ runtime,
+ tascam->driver_capture_pos);
+ s32 *routed_frame_start =
+ routed_block +
+ (f * NUM_CHANNELS);
+ int c;
+
+ for (c = 0; c < NUM_CHANNELS; c++) {
+ u8 *dst_channel =
+ dst_frame_start +
+ (c * BYTES_PER_SAMPLE);
+ s32 *src_channel_s32 =
+ routed_frame_start + c;
+
+ memcpy(dst_channel,
+ ((char *)src_channel_s32) +
+ 1,
+ 3);
+ }
+
+ tascam->driver_capture_pos =
+ (tascam->driver_capture_pos +
+ 1) %
+ runtime->buffer_size;
+ }
+ }
+ }
+ }
+}
+
+void capture_urb_complete(struct urb *urb)
+{
+ struct tascam_card *tascam = urb->context;
+ int ret;
+
+ if (urb->status) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN && urb->status != -ENODEV &&
+ urb->status != -EPROTO)
+ dev_err_ratelimited(tascam->card->dev,
+ "Capture URB failed: %d\n",
+ urb->status);
+ goto out;
+ }
+ if (!tascam || !atomic_read(&tascam->capture_active))
+ goto out;
+
+ if (urb->actual_length > 0) {
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ size_t write_ptr = tascam->capture_ring_buffer_write_ptr;
+ size_t bytes_to_end = CAPTURE_RING_BUFFER_SIZE - write_ptr;
+
+ if (urb->actual_length > bytes_to_end) {
+ memcpy(tascam->capture_ring_buffer + write_ptr,
+ urb->transfer_buffer, bytes_to_end);
+ memcpy(tascam->capture_ring_buffer,
+ urb->transfer_buffer + bytes_to_end,
+ urb->actual_length - bytes_to_end);
+ } else {
+ memcpy(tascam->capture_ring_buffer + write_ptr,
+ urb->transfer_buffer,
+ urb->actual_length);
+ }
+
+ tascam->capture_ring_buffer_write_ptr =
+ (write_ptr + urb->actual_length) %
+ CAPTURE_RING_BUFFER_SIZE;
+ }
+
+ schedule_work(&tascam->capture_work);
+ }
+
+ usb_get_urb(urb);
+ usb_anchor_urb(urb, &tascam->capture_anchor);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret < 0) {
+ dev_err_ratelimited(tascam->card->dev,
+ "Failed to resubmit capture URB: %d\n",
+ ret);
+ usb_unanchor_urb(urb);
+ usb_put_urb(urb);
+ atomic_dec(
+ &tascam->active_urbs); /* Decrement on failed resubmission */
+ }
+out:
+ usb_put_urb(urb);
+}
+
diff --git a/sound/usb/usx2y/us144mkii_controls.c b/sound/usb/usx2y/us144mkii_controls.c
new file mode 100644
index 000000000000..5d69441ef414
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_controls.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#include "us144mkii.h"
+
+/**
+ * @brief Text descriptions for playback output source options.
+ *
+ * Used by ALSA kcontrol elements to provide user-friendly names for
+ * the playback routing options (e.g., "Playback 1-2", "Playback 3-4").
+ */
+static const char *const playback_source_texts[] = { "Playback 1-2",
+ "Playback 3-4" };
+
+/**
+ * @brief Text descriptions for capture input source options.
+ *
+ * Used by ALSA kcontrol elements to provide user-friendly names for
+ * the capture routing options (e.g., "Analog In", "Digital In").
+ */
+static const char *const capture_source_texts[] = { "Analog In", "Digital In" };
+
+/**
+ * tascam_playback_source_info() - ALSA control info callback for playback
+ * source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @uinfo: The ALSA control element info structure to fill.
+ *
+ * This function provides information about the enumerated playback source
+ * control, including its type, count, and available items (Playback 1-2,
+ * Playback 3-4).
+ *
+ * Return: 0 on success.
+ */
+static int tascam_playback_source_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ return snd_ctl_enum_info(uinfo, 1, 2, playback_source_texts);
+}
+
+/**
+ * tascam_line_out_get() - ALSA control get callback for Line Outputs Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure to fill.
+ *
+ * This function retrieves the current selection for the Line Outputs source
+ * (Playback 1-2 or Playback 3-4) from the driver's private data and populates
+ * the ALSA control element value.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_line_out_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ ucontrol->value.enumerated.item[0] = tascam->line_out_source;
+ }
+ return 0;
+}
+
+/**
+ * tascam_line_out_put() - ALSA control put callback for Line Outputs Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure containing the new value.
+ *
+ * This function sets the Line Outputs source (Playback 1-2 or Playback 3-4)
+ * based on the user's selection from the ALSA control element. It validates
+ * the input and updates the driver's private data.
+ *
+ * Return: 1 if the value was changed, 0 if unchanged, or a negative error code.
+ */
+static int tascam_line_out_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+
+ if (ucontrol->value.enumerated.item[0] > 1)
+ return -EINVAL;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->line_out_source != ucontrol->value.enumerated.item[0]) {
+ tascam->line_out_source = ucontrol->value.enumerated.item[0];
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+/**
+ * tascam_line_out_control - ALSA kcontrol definition for Line Outputs Source.
+ *
+ * This defines a new ALSA mixer control named "Line OUTPUTS Source" that allows
+ * the user to select between "Playback 1-2" and "Playback 3-4" for the analog
+ * line outputs of the device. It uses the `tascam_playback_source_info` for
+ * information and `tascam_line_out_get`/`tascam_line_out_put` for value
+ * handling.
+ */
+static const struct snd_kcontrol_new tascam_line_out_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Line Playback Source",
+ .info = tascam_playback_source_info,
+ .get = tascam_line_out_get,
+ .put = tascam_line_out_put,
+};
+
+/**
+ * tascam_digital_out_get() - ALSA control get callback for Digital Outputs
+ * Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure to fill.
+ *
+ * This function retrieves the current selection for the Digital Outputs source
+ * (Playback 1-2 or Playback 3-4) from the driver's private data and populates
+ * the ALSA control element value.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_digital_out_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ ucontrol->value.enumerated.item[0] = tascam->digital_out_source;
+ }
+ return 0;
+}
+
+/**
+ * tascam_digital_out_put() - ALSA control put callback for Digital Outputs
+ * Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure containing the new value.
+ *
+ * This function sets the Digital Outputs source (Playback 1-2 or Playback 3-4)
+ * based on the user's selection from the ALSA control element. It validates
+ * the input and updates the driver's private data.
+ *
+ * Return: 1 if the value was changed, 0 if unchanged, or a negative error code.
+ */
+static int tascam_digital_out_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+
+ if (ucontrol->value.enumerated.item[0] > 1)
+ return -EINVAL;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->digital_out_source != ucontrol->value.enumerated.item[0]) {
+ tascam->digital_out_source = ucontrol->value.enumerated.item[0];
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+/**
+ * tascam_digital_out_control - ALSA kcontrol definition for Digital Outputs
+ * Source.
+ *
+ * This defines a new ALSA mixer control named "Digital OUTPUTS Source" that
+ * allows the user to select between "Playback 1-2" and "Playback 3-4" for the
+ * digital outputs of the device. It uses the `tascam_playback_source_info` for
+ * information and `tascam_digital_out_get`/`tascam_digital_out_put` for value
+ * handling.
+ */
+static const struct snd_kcontrol_new tascam_digital_out_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Digital Playback Source",
+ .info = tascam_playback_source_info,
+ .get = tascam_digital_out_get,
+ .put = tascam_digital_out_put,
+};
+
+/**
+ * tascam_capture_source_info() - ALSA control info callback for capture source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @uinfo: The ALSA control element info structure to fill.
+ *
+ * This function provides information about the enumerated capture source
+ * control, including its type, count, and available items (Analog In, Digital
+ * In).
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_source_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ return snd_ctl_enum_info(uinfo, 1, 2, capture_source_texts);
+}
+
+/**
+ * tascam_capture_12_get() - ALSA control get callback for Capture channels 1
+ * and 2 Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure to fill.
+ *
+ * This function retrieves the current selection for the Capture channels 1 and
+ * 2 source (Analog In or Digital In) from the driver's private data and
+ * populates the ALSA control element value.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_12_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ ucontrol->value.enumerated.item[0] = tascam->capture_12_source;
+ }
+ return 0;
+}
+
+/**
+ * tascam_capture_12_put() - ALSA control put callback for Capture channels 1
+ * and 2 Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure containing the new value.
+ *
+ * This function sets the Capture channels 1 and 2 source (Analog In or Digital
+ * In) based on the user's selection from the ALSA control element. It validates
+ * the input and updates the driver's private data.
+ *
+ * Return: 1 if the value was changed, 0 if unchanged, or a negative error code.
+ */
+static int tascam_capture_12_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+
+ if (ucontrol->value.enumerated.item[0] > 1)
+ return -EINVAL;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->capture_12_source != ucontrol->value.enumerated.item[0]) {
+ tascam->capture_12_source = ucontrol->value.enumerated.item[0];
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+/**
+ * tascam_capture_12_control - ALSA kcontrol definition for Capture channels 1
+ * and 2 Source.
+ *
+ * This defines a new ALSA mixer control named "ch1 and ch2 Source" that allows
+ * the user to select between "Analog In" and "Digital In" for the first two
+ * capture channels of the device. It uses the `tascam_capture_source_info` for
+ * information and `tascam_capture_12_get`/`tascam_capture_12_put` for value
+ * handling.
+ */
+static const struct snd_kcontrol_new tascam_capture_12_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Ch1/2 Capture Source",
+ .info = tascam_capture_source_info,
+ .get = tascam_capture_12_get,
+ .put = tascam_capture_12_put,
+};
+
+/**
+ * tascam_capture_34_get() - ALSA control get callback for Capture channels 3
+ * and 4 Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure to fill.
+ *
+ * This function retrieves the current selection for the Capture channels 3 and
+ * 4 source (Analog In or Digital In) from the driver's private data and
+ * populates the ALSA control element value.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_capture_34_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ ucontrol->value.enumerated.item[0] = tascam->capture_34_source;
+ }
+ return 0;
+}
+
+/**
+ * tascam_capture_34_put() - ALSA control put callback for Capture channels 3
+ * and 4 Source.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure containing the new value.
+ *
+ * This function sets the Capture channels 3 and 4 source (Analog In or Digital
+ * In) based on the user's selection from the ALSA control element. It validates
+ * the input and updates the driver's private data.
+ *
+ * Return: 1 if the value was changed, 0 if unchanged, or a negative error code.
+ */
+static int tascam_capture_34_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+
+ if (ucontrol->value.enumerated.item[0] > 1)
+ return -EINVAL;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->capture_34_source != ucontrol->value.enumerated.item[0]) {
+ tascam->capture_34_source = ucontrol->value.enumerated.item[0];
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+/**
+ * tascam_capture_34_control - ALSA kcontrol definition for Capture channels 3
+ * and 4 Source.
+ *
+ * This defines a new ALSA mixer control named "ch3 and ch4 Source" that allows
+ * the user to select between "Analog In" and "Digital In" for the third and
+ * fourth capture channels of the device. It uses the
+ * `tascam_capture_source_info` for information and
+ * `tascam_capture_34_get`/`tascam_capture_34_put` for value handling.
+ */
+static const struct snd_kcontrol_new tascam_capture_34_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Ch3/4 Capture Source",
+ .info = tascam_capture_source_info,
+ .get = tascam_capture_34_get,
+ .put = tascam_capture_34_put,
+};
+
+/**
+ * tascam_samplerate_info() - ALSA control info callback for Sample Rate.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @uinfo: The ALSA control element info structure to fill.
+ *
+ * This function provides information about the Sample Rate control, defining
+ * it as an integer type with a minimum value of 0 and a maximum of 96000.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_samplerate_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 96000;
+ return 0;
+}
+
+/**
+ * tascam_samplerate_get() - ALSA control get callback for Sample Rate.
+ * @kcontrol: The ALSA kcontrol instance.
+ * @ucontrol: The ALSA control element value structure to fill.
+ *
+ * This function retrieves the current sample rate from the device via a USB
+ * control message and populates the ALSA control element value. If the rate
+ * is already known (i.e., `current_rate` is set), it returns that value
+ * directly.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int tascam_samplerate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tascam_card *tascam =
+ (struct tascam_card *)snd_kcontrol_chip(kcontrol);
+ u8 *buf __free(kfree) = NULL;
+ int err;
+ u32 rate = 0;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->current_rate > 0) {
+ ucontrol->value.integer.value[0] = tascam->current_rate;
+ return 0;
+ }
+ }
+
+ buf = kmalloc(3, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ err = usb_control_msg(tascam->dev, usb_rcvctrlpipe(tascam->dev, 0),
+ UAC_GET_CUR, RT_D2H_CLASS_EP,
+ UAC_SAMPLING_FREQ_CONTROL, EP_AUDIO_IN, buf, 3,
+ USB_CTRL_TIMEOUT_MS);
+
+ if (err >= 3)
+ rate = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+
+ ucontrol->value.integer.value[0] = rate;
+ return 0;
+}
+
+/**
+ * tascam_samplerate_control - ALSA kcontrol definition for Sample Rate.
+ *
+ * This defines a new ALSA mixer control named "Sample Rate" that displays
+ * the current sample rate of the device. It is a read-only control.
+ */
+static const struct snd_kcontrol_new tascam_samplerate_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sample Rate",
+ .info = tascam_samplerate_info,
+ .get = tascam_samplerate_get,
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+};
+
+int tascam_create_controls(struct tascam_card *tascam)
+{
+ int err;
+
+ err = snd_ctl_add(tascam->card,
+ snd_ctl_new1(&tascam_line_out_control, tascam));
+ if (err < 0)
+ return err;
+ err = snd_ctl_add(tascam->card,
+ snd_ctl_new1(&tascam_digital_out_control, tascam));
+ if (err < 0)
+ return err;
+ err = snd_ctl_add(tascam->card,
+ snd_ctl_new1(&tascam_capture_12_control, tascam));
+ if (err < 0)
+ return err;
+ err = snd_ctl_add(tascam->card,
+ snd_ctl_new1(&tascam_capture_34_control, tascam));
+ if (err < 0)
+ return err;
+
+ err = snd_ctl_add(tascam->card,
+ snd_ctl_new1(&tascam_samplerate_control, tascam));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
diff --git a/sound/usb/usx2y/us144mkii_midi.c b/sound/usb/usx2y/us144mkii_midi.c
new file mode 100644
index 000000000000..ed2afec2a89a
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_midi.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#include "us144mkii.h"
+
+/**
+ * tascam_midi_in_work_handler() - Deferred work for processing MIDI input.
+ * @work: The work_struct instance.
+ *
+ * This function runs in a thread context. It safely reads raw USB data from
+ * the kfifo, processes it by stripping protocol-specific padding bytes, and
+ * passes the clean MIDI data to the ALSA rawmidi subsystem.
+ */
+static void tascam_midi_in_work_handler(struct work_struct *work)
+{
+ struct tascam_card *tascam =
+ container_of(work, struct tascam_card, midi_in_work);
+ u8 buf[9];
+ u8 clean_buf[8];
+ unsigned int count, clean_count;
+
+ if (!tascam->midi_in_substream)
+ return;
+
+ while (kfifo_out_spinlocked(&tascam->midi_in_fifo, buf, sizeof(buf),
+ &tascam->midi_in_lock) == sizeof(buf)) {
+ clean_count = 0;
+ for (count = 0; count < 8; ++count) {
+ if (buf[count] != 0xfd)
+ clean_buf[clean_count++] = buf[count];
+ }
+
+ if (clean_count > 0)
+ snd_rawmidi_receive(tascam->midi_in_substream,
+ clean_buf, clean_count);
+ }
+}
+
+void tascam_midi_in_urb_complete(struct urb *urb)
+{
+ struct tascam_card *tascam = urb->context;
+ int ret;
+
+ if (!tascam)
+ goto out;
+
+ if (urb->status) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN && urb->status != -EPROTO) {
+ dev_err_ratelimited(tascam->card->dev,
+ "MIDI IN URB failed: status %d\n",
+ urb->status);
+ }
+ goto out;
+ }
+
+ if (atomic_read(&tascam->midi_in_active) &&
+ urb->actual_length > 0) {
+ kfifo_in_spinlocked(&tascam->midi_in_fifo, urb->transfer_buffer,
+ urb->actual_length, &tascam->midi_in_lock);
+ schedule_work(&tascam->midi_in_work);
+ }
+
+ usb_get_urb(urb);
+ usb_anchor_urb(urb, &tascam->midi_in_anchor);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret < 0) {
+ dev_err(tascam->card->dev,
+ "Failed to resubmit MIDI IN URB: error %d\n", ret);
+ usb_unanchor_urb(urb);
+ goto out;
+ }
+
+out:
+ usb_put_urb(urb);
+}
+
+/**
+ * tascam_midi_in_open() - Opens the MIDI input substream.
+ * @substream: The ALSA rawmidi substream to open.
+ *
+ * This function stores a reference to the MIDI input substream in the
+ * driver's private data.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_midi_in_open(struct snd_rawmidi_substream *substream)
+{
+ struct tascam_card *tascam = substream->rmidi->private_data;
+
+ tascam->midi_in_substream = substream;
+ return 0;
+}
+
+/**
+ * tascam_midi_in_close() - Closes the MIDI input substream.
+ * @substream: The ALSA rawmidi substream to close.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_midi_in_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+/**
+ * tascam_midi_in_trigger() - Triggers MIDI input stream activity.
+ * @substream: The ALSA rawmidi substream.
+ * @up: Boolean indicating whether to start (1) or stop (0) the stream.
+ *
+ * This function starts or stops the MIDI input URBs based on the 'up'
+ * parameter. When starting, it resets the kfifo and submits all MIDI input
+ * URBs. When stopping, it kills all anchored MIDI input URBs and cancels the
+ * associated workqueue.
+ */
+static void tascam_midi_in_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ struct tascam_card *tascam = substream->rmidi->private_data;
+ int i, err;
+
+ if (up) {
+ if (atomic_xchg(&tascam->midi_in_active, 1) == 0) {
+ scoped_guard(spinlock_irqsave, &tascam->midi_in_lock)
+ {
+ kfifo_reset(&tascam->midi_in_fifo);
+ }
+
+ for (i = 0; i < NUM_MIDI_IN_URBS; i++) {
+ usb_get_urb(tascam->midi_in_urbs[i]);
+ usb_anchor_urb(tascam->midi_in_urbs[i],
+ &tascam->midi_in_anchor);
+ err = usb_submit_urb(tascam->midi_in_urbs[i],
+ GFP_KERNEL);
+ if (err < 0) {
+ dev_err(tascam->card->dev,
+ "Failed to submit MIDI IN URB %d: %d\n",
+ i, err);
+ usb_unanchor_urb(
+ tascam->midi_in_urbs[i]);
+ usb_put_urb(tascam->midi_in_urbs[i]);
+ }
+ }
+ }
+ } else {
+ if (atomic_xchg(&tascam->midi_in_active, 0) == 1) {
+ usb_kill_anchored_urbs(&tascam->midi_in_anchor);
+ cancel_work_sync(&tascam->midi_in_work);
+ }
+ }
+}
+
+/**
+ * tascam_midi_in_ops - ALSA rawmidi operations for MIDI input.
+ *
+ * This structure defines the callback functions for MIDI input stream
+ * operations, including open, close, and trigger.
+ */
+static const struct snd_rawmidi_ops tascam_midi_in_ops = {
+ .open = tascam_midi_in_open,
+ .close = tascam_midi_in_close,
+ .trigger = tascam_midi_in_trigger,
+};
+
+void tascam_midi_out_urb_complete(struct urb *urb)
+{
+ struct tascam_card *tascam = urb->context;
+ int i, urb_index = -1;
+
+ if (urb->status) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN) {
+ dev_err_ratelimited(tascam->card->dev,
+ "MIDI OUT URB failed: %d\n",
+ urb->status);
+ }
+ goto out;
+ }
+
+ if (!tascam)
+ goto out;
+
+ for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
+ if (tascam->midi_out_urbs[i] == urb) {
+ urb_index = i;
+ break;
+ }
+ }
+
+ if (urb_index < 0) {
+ dev_err_ratelimited(tascam->card->dev,
+ "Unknown MIDI OUT URB completed!\n");
+ goto out;
+ }
+
+ scoped_guard(spinlock_irqsave, &tascam->midi_out_lock)
+ {
+ clear_bit(urb_index, &tascam->midi_out_urbs_in_flight);
+ }
+
+ if (atomic_read(&tascam->midi_out_active))
+ schedule_work(&tascam->midi_out_work);
+
+out:
+ usb_put_urb(urb);
+}
+
+/**
+ * tascam_midi_out_work_handler() - Deferred work for sending MIDI data
+ * @work: The work_struct instance.
+ *
+ * This function handles the proprietary output protocol: take the raw MIDI
+ * message bytes from the application, place them at the start of a 9-byte
+ * buffer, pad the rest with 0xFD, and add a terminator byte (0x00).
+ * This function pulls as many bytes as will fit into one packet from the
+ * ALSA buffer and sends them.
+ */
+static void tascam_midi_out_work_handler(struct work_struct *work)
+{
+ struct tascam_card *tascam =
+ container_of(work, struct tascam_card, midi_out_work);
+ struct snd_rawmidi_substream *substream = tascam->midi_out_substream;
+ int i;
+
+ if (!substream || !atomic_read(&tascam->midi_out_active))
+ return;
+
+ while (snd_rawmidi_transmit_peek(substream, (u8[]){ 0 }, 1) == 1) {
+ int urb_index;
+ struct urb *urb;
+ u8 *buf;
+ int bytes_to_send;
+
+ scoped_guard(spinlock_irqsave, &tascam->midi_out_lock) {
+ urb_index = -1;
+ for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
+ if (!test_bit(
+ i,
+ &tascam->midi_out_urbs_in_flight)) {
+ urb_index = i;
+ break;
+ }
+ }
+
+ if (urb_index < 0)
+ return; /* No free URBs, will be rescheduled by
+ * completion handler
+ */
+
+ urb = tascam->midi_out_urbs[urb_index];
+ buf = urb->transfer_buffer;
+ bytes_to_send = snd_rawmidi_transmit(substream, buf, 8);
+
+ if (bytes_to_send <= 0)
+ break; /* No more data */
+
+ if (bytes_to_send < 9)
+ memset(buf + bytes_to_send, 0xfd,
+ 9 - bytes_to_send);
+ buf[8] = 0xe0;
+
+ set_bit(urb_index, &tascam->midi_out_urbs_in_flight);
+ urb->transfer_buffer_length = 9;
+ }
+
+ usb_get_urb(urb);
+ usb_anchor_urb(urb, &tascam->midi_out_anchor);
+ if (usb_submit_urb(urb, GFP_KERNEL) < 0) {
+ dev_err_ratelimited(
+ tascam->card->dev,
+ "Failed to submit MIDI OUT URB %d\n",
+ urb_index);
+ scoped_guard(spinlock_irqsave, &tascam->midi_out_lock)
+ {
+ clear_bit(urb_index,
+ &tascam->midi_out_urbs_in_flight);
+ }
+ usb_unanchor_urb(urb);
+ usb_put_urb(urb);
+ break; /* Stop on error */
+ }
+ }
+}
+
+/**
+ * tascam_midi_out_open() - Opens the MIDI output substream.
+ * @substream: The ALSA rawmidi substream to open.
+ *
+ * This function stores a reference to the MIDI output substream in the
+ * driver's private data and initializes the MIDI running status.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_midi_out_open(struct snd_rawmidi_substream *substream)
+{
+ struct tascam_card *tascam = substream->rmidi->private_data;
+
+ tascam->midi_out_substream = substream;
+ /* Initialize the running status state for the packet packer. */
+ tascam->midi_running_status = 0;
+ return 0;
+}
+
+/**
+ * tascam_midi_out_close() - Closes the MIDI output substream.
+ * @substream: The ALSA rawmidi substream to close.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_midi_out_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+/**
+ * tascam_midi_out_drain() - Drains the MIDI output stream.
+ * @substream: The ALSA rawmidi substream.
+ *
+ * This function cancels any pending MIDI output work and kills all
+ * anchored MIDI output URBs, ensuring all data is sent or discarded.
+ */
+static void tascam_midi_out_drain(struct snd_rawmidi_substream *substream)
+{
+ struct tascam_card *tascam = substream->rmidi->private_data;
+ bool in_flight = true;
+
+ while (in_flight) {
+ in_flight = false;
+ for (int i = 0; i < NUM_MIDI_OUT_URBS; i++) {
+ if (test_bit(i, &tascam->midi_out_urbs_in_flight)) {
+ in_flight = true;
+ break;
+ }
+ }
+ if (in_flight)
+ schedule_timeout_uninterruptible(1);
+ }
+
+ cancel_work_sync(&tascam->midi_out_work);
+ usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+}
+
+/**
+ * tascam_midi_out_trigger() - Triggers MIDI output stream activity.
+ * @substream: The ALSA rawmidi substream.
+ * @up: Boolean indicating whether to start (1) or stop (0) the stream.
+ *
+ * This function starts or stops the MIDI output workqueue based on the
+ * 'up' parameter.
+ */
+static void tascam_midi_out_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ struct tascam_card *tascam = substream->rmidi->private_data;
+
+ if (up) {
+ atomic_set(&tascam->midi_out_active, 1);
+ schedule_work(&tascam->midi_out_work);
+ } else {
+ atomic_set(&tascam->midi_out_active, 0);
+ }
+}
+
+/**
+ * tascam_midi_out_ops - ALSA rawmidi operations for MIDI output.
+ *
+ * This structure defines the callback functions for MIDI output stream
+ * operations, including open, close, trigger, and drain.
+ */
+static const struct snd_rawmidi_ops tascam_midi_out_ops = {
+ .open = tascam_midi_out_open,
+ .close = tascam_midi_out_close,
+ .trigger = tascam_midi_out_trigger,
+ .drain = tascam_midi_out_drain,
+};
+
+int tascam_create_midi(struct tascam_card *tascam)
+{
+ int err;
+
+ err = snd_rawmidi_new(tascam->card, "US144MKII MIDI", 0, 1, 1,
+ &tascam->rmidi);
+ if (err < 0)
+ return err;
+
+ strscpy(tascam->rmidi->name, "US144MKII MIDI",
+ sizeof(tascam->rmidi->name));
+ tascam->rmidi->private_data = tascam;
+
+ snd_rawmidi_set_ops(tascam->rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &tascam_midi_in_ops);
+ snd_rawmidi_set_ops(tascam->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &tascam_midi_out_ops);
+
+ tascam->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+
+ INIT_WORK(&tascam->midi_in_work, tascam_midi_in_work_handler);
+ INIT_WORK(&tascam->midi_out_work, tascam_midi_out_work_handler);
+
+ return 0;
+}
diff --git a/sound/usb/usx2y/us144mkii_pcm.c b/sound/usb/usx2y/us144mkii_pcm.c
new file mode 100644
index 000000000000..0c84304d4624
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_pcm.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#include "us144mkii.h"
+
+/**
+ * fpo_init_pattern() - Generates a packet distribution pattern.
+ * @size: The number of elements in the pattern array (e.g., 8).
+ * @pattern_array: Pointer to the array to be populated.
+ * @initial_value: The base value to initialize each element with.
+ * @target_sum: The desired sum of all elements in the final array.
+ *
+ * This function initializes an array with a base value and then iteratively
+ * adjusts the elements to match a target sum, distributing the difference
+ * as evenly as possible.
+ */
+static void fpo_init_pattern(unsigned int size, unsigned int *pattern_array,
+ unsigned int initial_value, int target_sum)
+{
+ int diff, i;
+
+ if (!size)
+ return;
+
+ for (i = 0; i < size; ++i)
+ pattern_array[i] = initial_value;
+
+ diff = target_sum - (size * initial_value);
+ for (i = 0; i < abs(diff); ++i) {
+ if (diff > 0)
+ pattern_array[i]++;
+ else
+ pattern_array[i]--;
+ }
+}
+
+const struct snd_pcm_hardware tascam_pcm_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),
+ .rate_min = 44100,
+ .rate_max = 96000,
+ .channels_min = NUM_CHANNELS,
+ .channels_max = NUM_CHANNELS,
+ .buffer_bytes_max = 1024 * 1024,
+ .period_bytes_min = 48 * BYTES_PER_FRAME,
+ .period_bytes_max = 1024 * BYTES_PER_FRAME,
+ .periods_min = 2,
+ .periods_max = 1024,
+};
+
+void process_playback_routing_us144mkii(struct tascam_card *tascam,
+ const u8 *src_buffer, u8 *dst_buffer,
+ size_t frames)
+{
+ size_t f;
+ const u8 *src_12, *src_34;
+ u8 *dst_line, *dst_digital;
+
+ for (f = 0; f < frames; ++f) {
+ src_12 = src_buffer + f * BYTES_PER_FRAME;
+ src_34 = src_12 + (2 * BYTES_PER_SAMPLE);
+ dst_line = dst_buffer + f * BYTES_PER_FRAME;
+ dst_digital = dst_line + (2 * BYTES_PER_SAMPLE);
+
+ /* LINE OUTPUTS (ch1/2 on device) */
+ if (tascam->line_out_source == 0) /* "ch1 and ch2" */
+ memcpy(dst_line, src_12, 2 * BYTES_PER_SAMPLE);
+ else /* "ch3 and ch4" */
+ memcpy(dst_line, src_34, 2 * BYTES_PER_SAMPLE);
+
+ /* DIGITAL OUTPUTS (ch3/4 on device) */
+ if (tascam->digital_out_source == 0) /* "ch1 and ch2" */
+ memcpy(dst_digital, src_12, 2 * BYTES_PER_SAMPLE);
+ else /* "ch3 and ch4" */
+ memcpy(dst_digital, src_34, 2 * BYTES_PER_SAMPLE);
+ }
+}
+
+void process_capture_routing_us144mkii(struct tascam_card *tascam,
+ const s32 *decoded_block,
+ s32 *routed_block)
+{
+ int f;
+ const s32 *src_frame;
+ s32 *dst_frame;
+
+ for (f = 0; f < FRAMES_PER_DECODE_BLOCK; f++) {
+ src_frame = decoded_block + (f * DECODED_CHANNELS_PER_FRAME);
+ dst_frame = routed_block + (f * DECODED_CHANNELS_PER_FRAME);
+
+ /* ch1 and ch2 Source */
+ if (tascam->capture_12_source == 0) { /* analog inputs */
+ dst_frame[0] = src_frame[0]; /* Analog L */
+ dst_frame[1] = src_frame[1]; /* Analog R */
+ } else { /* digital inputs */
+ dst_frame[0] = src_frame[2]; /* Digital L */
+ dst_frame[1] = src_frame[3]; /* Digital R */
+ }
+
+ /* ch3 and ch4 Source */
+ if (tascam->capture_34_source == 0) { /* analog inputs */
+ dst_frame[2] = src_frame[0]; /* Analog L (Duplicate) */
+ dst_frame[3] = src_frame[1]; /* Analog R (Duplicate) */
+ } else { /* digital inputs */
+ dst_frame[2] = src_frame[2]; /* Digital L */
+ dst_frame[3] = src_frame[3]; /* Digital R */
+ }
+ }
+}
+
+int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate)
+{
+ struct usb_device *dev = tascam->dev;
+ u8 *rate_payload_buf __free(kfree) = NULL;
+ u16 rate_vendor_wValue;
+ int err = 0;
+ const u8 *current_payload_src;
+
+ static const u8 payload_44100[] = { 0x44, 0xac, 0x00 };
+ static const u8 payload_48000[] = { 0x80, 0xbb, 0x00 };
+ static const u8 payload_88200[] = { 0x88, 0x58, 0x01 };
+ static const u8 payload_96000[] = { 0x00, 0x77, 0x01 };
+
+ switch (rate) {
+ case 44100:
+ current_payload_src = payload_44100;
+ rate_vendor_wValue = REG_ADDR_RATE_44100;
+ break;
+ case 48000:
+ current_payload_src = payload_48000;
+ rate_vendor_wValue = REG_ADDR_RATE_48000;
+ break;
+ case 88200:
+ current_payload_src = payload_88200;
+ rate_vendor_wValue = REG_ADDR_RATE_88200;
+ break;
+ case 96000:
+ current_payload_src = payload_96000;
+ rate_vendor_wValue = REG_ADDR_RATE_96000;
+ break;
+ default:
+ dev_err(&dev->dev,
+ "Unsupported sample rate %d for configuration\n", rate);
+ return -EINVAL;
+ }
+
+ rate_payload_buf = kmemdup(current_payload_src, 3, GFP_KERNEL);
+ if (!rate_payload_buf)
+ return -ENOMEM;
+
+ dev_info(&dev->dev, "Configuring device for %d Hz\n", rate);
+
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_MODE_CONTROL, RT_H2D_VENDOR_DEV,
+ MODE_VAL_CONFIG, 0x0000, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
+ RT_H2D_CLASS_EP, UAC_SAMPLING_FREQ_CONTROL,
+ EP_AUDIO_IN, rate_payload_buf, 3,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
+ RT_H2D_CLASS_EP, UAC_SAMPLING_FREQ_CONTROL,
+ EP_AUDIO_OUT, rate_payload_buf, 3,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_REGISTER_WRITE, RT_H2D_VENDOR_DEV,
+ REG_ADDR_UNKNOWN_0D, REG_VAL_ENABLE, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_REGISTER_WRITE, RT_H2D_VENDOR_DEV,
+ REG_ADDR_UNKNOWN_0E, REG_VAL_ENABLE, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_REGISTER_WRITE, RT_H2D_VENDOR_DEV,
+ REG_ADDR_UNKNOWN_0F, REG_VAL_ENABLE, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_REGISTER_WRITE, RT_H2D_VENDOR_DEV,
+ rate_vendor_wValue, REG_VAL_ENABLE, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_REGISTER_WRITE, RT_H2D_VENDOR_DEV,
+ REG_ADDR_UNKNOWN_11, REG_VAL_ENABLE, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ VENDOR_REQ_MODE_CONTROL, RT_H2D_VENDOR_DEV,
+ MODE_VAL_STREAM_START, 0x0000, NULL, 0,
+ USB_CTRL_TIMEOUT_MS);
+ if (err < 0)
+ goto fail;
+ return 0;
+
+fail:
+ dev_err(&dev->dev,
+ "Device configuration failed at rate %d with error %d\n", rate,
+ err);
+ return err;
+}
+
+int tascam_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+ int err;
+ unsigned int rate = params_rate(params);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ tascam->fpo.sample_rate_khz = rate / 1000;
+ tascam->fpo.base_feedback_value = tascam->fpo.sample_rate_khz;
+ tascam->fpo.feedback_offset = 2;
+ tascam->fpo.current_index = 0;
+ tascam->fpo.previous_index = 0;
+ tascam->fpo.sync_locked = false;
+
+ unsigned int initial_value = tascam->fpo.sample_rate_khz / 8;
+
+ for (int i = 0; i < 5; i++) {
+ int target_sum = tascam->fpo.sample_rate_khz -
+ tascam->fpo.feedback_offset + i;
+ fpo_init_pattern(8, tascam->fpo.full_frame_patterns[i],
+ initial_value, target_sum);
+ }
+ }
+
+ if (tascam->current_rate != rate) {
+ err = us144mkii_configure_device_for_rate(tascam, rate);
+ if (err < 0) {
+ tascam->current_rate = 0;
+ return err;
+ }
+ tascam->current_rate = rate;
+ }
+
+ return 0;
+}
+
+int tascam_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+ int err = 0;
+ int i;
+ bool do_start = false;
+ bool do_stop = false;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ if (!atomic_read(&tascam->playback_active)) {
+ atomic_set(&tascam->playback_active, 1);
+ atomic_set(&tascam->capture_active, 1);
+ do_start = true;
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (atomic_read(&tascam->playback_active)) {
+ atomic_set(&tascam->playback_active, 0);
+ atomic_set(&tascam->capture_active, 0);
+ do_stop = true;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ }
+
+ if (do_start) {
+ if (atomic_read(&tascam->active_urbs) > 0) {
+ dev_warn(tascam->card->dev,
+ "Cannot start, URBs still active.\n");
+ return -EAGAIN;
+ }
+
+ for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
+ usb_get_urb(tascam->feedback_urbs[i]);
+ usb_anchor_urb(tascam->feedback_urbs[i],
+ &tascam->feedback_anchor);
+ err = usb_submit_urb(tascam->feedback_urbs[i],
+ GFP_ATOMIC);
+ if (err < 0) {
+ usb_unanchor_urb(tascam->feedback_urbs[i]);
+ usb_put_urb(tascam->feedback_urbs[i]);
+ atomic_dec(&tascam->active_urbs);
+ goto start_rollback;
+ }
+ atomic_inc(&tascam->active_urbs);
+ }
+ for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
+ usb_get_urb(tascam->playback_urbs[i]);
+ usb_anchor_urb(tascam->playback_urbs[i],
+ &tascam->playback_anchor);
+ err = usb_submit_urb(tascam->playback_urbs[i],
+ GFP_ATOMIC);
+ if (err < 0) {
+ usb_unanchor_urb(tascam->playback_urbs[i]);
+ usb_put_urb(tascam->playback_urbs[i]);
+ atomic_dec(&tascam->active_urbs);
+ goto start_rollback;
+ }
+ atomic_inc(&tascam->active_urbs);
+ }
+ for (i = 0; i < NUM_CAPTURE_URBS; i++) {
+ usb_get_urb(tascam->capture_urbs[i]);
+ usb_anchor_urb(tascam->capture_urbs[i],
+ &tascam->capture_anchor);
+ err = usb_submit_urb(tascam->capture_urbs[i],
+ GFP_ATOMIC);
+ if (err < 0) {
+ usb_unanchor_urb(tascam->capture_urbs[i]);
+ usb_put_urb(tascam->capture_urbs[i]);
+ atomic_dec(&tascam->active_urbs);
+ goto start_rollback;
+ }
+ atomic_inc(&tascam->active_urbs);
+ }
+
+ return 0;
+start_rollback:
+ dev_err(tascam->card->dev,
+ "Failed to submit URBs to start stream: %d\n", err);
+ do_stop = true;
+ }
+
+ if (do_stop)
+ schedule_work(&tascam->stop_work);
+
+ return err;
+}
+
+int tascam_init_pcm(struct snd_pcm *pcm)
+{
+ struct tascam_card *tascam = pcm->private_data;
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &tascam_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tascam_capture_ops);
+
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+ tascam->dev->dev.parent, 64 * 1024,
+ tascam_pcm_hw.buffer_bytes_max);
+
+ return 0;
+}
diff --git a/sound/usb/usx2y/us144mkii_pcm.h b/sound/usb/usx2y/us144mkii_pcm.h
new file mode 100644
index 000000000000..74da8564431b
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_pcm.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#ifndef __US144MKII_PCM_H
+#define __US144MKII_PCM_H
+
+#include "us144mkii.h"
+
+/**
+ * tascam_pcm_hw - Hardware capabilities for TASCAM US-144MKII PCM.
+ *
+ * Defines the supported PCM formats, rates, channels, and buffer/period sizes
+ * for the TASCAM US-144MKII audio interface.
+ */
+extern const struct snd_pcm_hardware tascam_pcm_hw;
+
+/**
+ * tascam_playback_ops - ALSA PCM operations for playback.
+ *
+ * This structure defines the callback functions for playback stream operations.
+ */
+extern const struct snd_pcm_ops tascam_playback_ops;
+
+/**
+ * tascam_capture_ops - ALSA PCM operations for capture.
+ *
+ * This structure defines the callback functions for capture stream operations.
+ */
+extern const struct snd_pcm_ops tascam_capture_ops;
+
+/**
+ * playback_urb_complete() - Completion handler for playback isochronous URBs.
+ * @urb: the completed URB
+ *
+ * This function runs in interrupt context. It calculates the number of bytes
+ * to send in the next set of packets based on the feedback-driven clock,
+ * copies the audio data from the ALSA ring buffer, and resubmits the URB.
+ */
+void playback_urb_complete(struct urb *urb);
+
+/**
+ * feedback_urb_complete() - Completion handler for feedback isochronous URBs.
+ * @urb: the completed URB
+ *
+ * This is the master clock for the driver. It runs in interrupt context.
+ * It reads the feedback value from the device, which indicates how many
+ * samples the device has consumed. This information is used to adjust the
+ * playback rate and to advance the capture stream pointer, keeping both
+ * streams in sync. It then calls snd_pcm_period_elapsed if necessary and
+ * resubmits itself.
+ */
+void feedback_urb_complete(struct urb *urb);
+
+/**
+ * capture_urb_complete() - Completion handler for capture bulk URBs.
+ * @urb: the completed URB
+ *
+ * This function runs in interrupt context. It copies the received raw data
+ * into an intermediate ring buffer and then schedules the workqueue to process
+ * it. It then resubmits the URB to receive more data.
+ */
+void capture_urb_complete(struct urb *urb);
+
+/**
+ * tascam_stop_pcm_work_handler() - Work handler to stop PCM streams.
+ * @work: Pointer to the work_struct.
+ *
+ * This function is scheduled to stop PCM streams (playback and capture)
+ * from a workqueue context, avoiding blocking operations in interrupt context.
+ */
+void tascam_stop_pcm_work_handler(struct work_struct *work);
+
+/**
+ * tascam_init_pcm() - Initializes the ALSA PCM device.
+ * @pcm: Pointer to the ALSA PCM device to initialize.
+ *
+ * This function sets up the PCM operations, adds ALSA controls for routing
+ * and sample rate, and preallocates pages for the PCM buffer.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_init_pcm(struct snd_pcm *pcm);
+
+/**
+ * us144mkii_configure_device_for_rate() - Set sample rate via USB control msgs
+ * @tascam: the tascam_card instance
+ * @rate: the target sample rate (e.g., 44100, 96000)
+ *
+ * This function sends a sequence of vendor-specific and UAC control messages
+ * to configure the device hardware for the specified sample rate.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate);
+
+/**
+ * process_playback_routing_us144mkii() - Apply playback routing matrix
+ * @tascam: The driver instance.
+ * @src_buffer: Buffer containing 4 channels of S24_3LE audio from ALSA.
+ * @dst_buffer: Buffer to be filled for the USB device.
+ * @frames: Number of frames to process.
+ */
+void process_playback_routing_us144mkii(struct tascam_card *tascam,
+ const u8 *src_buffer, u8 *dst_buffer,
+ size_t frames);
+
+/**
+ * process_capture_routing_us144mkii() - Apply capture routing matrix
+ * @tascam: The driver instance.
+ * @decoded_block: Buffer containing 4 channels of S32LE decoded audio.
+ * @routed_block: Buffer to be filled for ALSA.
+ */
+void process_capture_routing_us144mkii(struct tascam_card *tascam,
+ const s32 *decoded_block,
+ s32 *routed_block);
+
+/**
+ * tascam_pcm_hw_params() - Configures hardware parameters for PCM streams.
+ * @substream: The ALSA PCM substream.
+ * @params: The hardware parameters to apply.
+ *
+ * This function allocates pages for the PCM buffer and, for playback streams,
+ * selects the appropriate feedback patterns based on the requested sample rate.
+ * It also configures the device hardware for the selected sample rate if it
+ * has changed.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+
+/**
+ * tascam_pcm_hw_free() - Frees hardware parameters for PCM streams.
+ * @substream: The ALSA PCM substream.
+ *
+ * This function is a stub for freeing hardware-related resources.
+ *
+ * Return: 0 on success.
+ */
+int tascam_pcm_hw_free(struct snd_pcm_substream *substream);
+
+/**
+ * tascam_pcm_trigger() - Triggers the start or stop of PCM streams.
+ * @substream: The ALSA PCM substream.
+ * @cmd: The trigger command (e.g., SNDRV_PCM_TRIGGER_START).
+ *
+ * This function handles starting and stopping of playback and capture streams
+ * by submitting or killing the associated URBs.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
+
+/**
+ * tascam_capture_work_handler() - Deferred work for processing capture data.
+ * @work: the work_struct instance
+ *
+ * This function runs in a kernel thread context, not an IRQ context. It reads
+ * raw data from the capture ring buffer, decodes it, applies routing, and
+ * copies the final audio data into the ALSA capture ring buffer. This offloads
+ * the CPU-intensive decoding from the time-sensitive URB completion handlers.
+ */
+void tascam_capture_work_handler(struct work_struct *work);
+
+#endif /* __US144MKII_PCM_H */
diff --git a/sound/usb/usx2y/us144mkii_playback.c b/sound/usb/usx2y/us144mkii_playback.c
new file mode 100644
index 000000000000..0cb9699ec211
--- /dev/null
+++ b/sound/usb/usx2y/us144mkii_playback.c
@@ -0,0 +1,456 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2025 Å erif Rami <ramiserifpersia@gmail.com>
+
+#include "us144mkii.h"
+
+/**
+ * tascam_playback_open() - Opens the PCM playback substream.
+ * @substream: The ALSA PCM substream to open.
+ *
+ * This function sets the hardware parameters for the playback substream
+ * and stores a reference to the substream in the driver's private data.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_playback_open(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+
+ substream->runtime->hw = tascam_pcm_hw;
+ tascam->playback_substream = substream;
+ atomic_set(&tascam->playback_active, 0);
+
+ return 0;
+}
+
+/**
+ * tascam_playback_close() - Closes the PCM playback substream.
+ * @substream: The ALSA PCM substream to close.
+ *
+ * This function clears the reference to the playback substream in the
+ * driver's private data.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_playback_close(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+
+ tascam->playback_substream = NULL;
+
+ return 0;
+}
+
+/**
+ * tascam_playback_prepare() - Prepares the PCM playback substream for use.
+ * @substream: The ALSA PCM substream to prepare.
+ *
+ * This function initializes playback-related counters and flags, and configures
+ * the playback URBs with appropriate packet sizes based on the nominal frame
+ * rate.
+ *
+ * Return: 0 on success.
+ */
+static int tascam_playback_prepare(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int i, u;
+ size_t nominal_frames_per_packet, nominal_bytes_per_packet;
+ size_t total_bytes_in_urb;
+
+ tascam->driver_playback_pos = 0;
+ tascam->playback_frames_consumed = 0;
+ tascam->last_period_pos = 0;
+ tascam->feedback_pattern_in_idx = 0;
+ tascam->feedback_pattern_out_idx = 0;
+ tascam->feedback_synced = false;
+ tascam->feedback_consecutive_errors = 0;
+ tascam->feedback_urb_skip_count = NUM_FEEDBACK_URBS;
+
+ nominal_frames_per_packet = runtime->rate / 8000;
+ for (i = 0; i < FEEDBACK_ACCUMULATOR_SIZE; i++)
+ tascam->feedback_accumulator_pattern[i] =
+ nominal_frames_per_packet;
+
+ for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
+ struct urb *f_urb = tascam->feedback_urbs[i];
+ int j;
+
+ f_urb->number_of_packets = FEEDBACK_URB_PACKETS;
+ f_urb->transfer_buffer_length =
+ FEEDBACK_URB_PACKETS * FEEDBACK_PACKET_SIZE;
+ for (j = 0; j < FEEDBACK_URB_PACKETS; j++) {
+ f_urb->iso_frame_desc[j].offset =
+ j * FEEDBACK_PACKET_SIZE;
+ f_urb->iso_frame_desc[j].length = FEEDBACK_PACKET_SIZE;
+ }
+ }
+
+ nominal_bytes_per_packet = nominal_frames_per_packet * BYTES_PER_FRAME;
+ total_bytes_in_urb = nominal_bytes_per_packet * PLAYBACK_URB_PACKETS;
+
+ for (u = 0; u < NUM_PLAYBACK_URBS; u++) {
+ struct urb *urb = tascam->playback_urbs[u];
+
+ memset(urb->transfer_buffer, 0,
+ tascam->playback_urb_alloc_size);
+ urb->transfer_buffer_length = total_bytes_in_urb;
+ urb->number_of_packets = PLAYBACK_URB_PACKETS;
+ for (i = 0; i < PLAYBACK_URB_PACKETS; i++) {
+ urb->iso_frame_desc[i].offset =
+ i * nominal_bytes_per_packet;
+ urb->iso_frame_desc[i].length =
+ nominal_bytes_per_packet;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * tascam_playback_pointer() - Returns the current playback pointer position.
+ * @substream: The ALSA PCM substream.
+ *
+ * This function returns the current position of the playback pointer within
+ * the ALSA ring buffer, in frames.
+ *
+ * Return: The current playback pointer position in frames.
+ */
+static snd_pcm_uframes_t
+tascam_playback_pointer(struct snd_pcm_substream *substream)
+{
+ struct tascam_card *tascam = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ u64 pos;
+
+ if (!atomic_read(&tascam->playback_active))
+ return 0;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ pos = tascam->playback_frames_consumed;
+ }
+
+ if (runtime->buffer_size == 0)
+ return 0;
+
+ return do_div(pos, runtime->buffer_size);
+}
+
+/**
+ * tascam_playback_ops - ALSA PCM operations for playback.
+ *
+ * This structure defines the callback functions for playback stream operations,
+ * including open, close, ioctl, hardware parameters, hardware free, prepare,
+ * trigger, and pointer.
+ */
+const struct snd_pcm_ops tascam_playback_ops = {
+ .open = tascam_playback_open,
+ .close = tascam_playback_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = tascam_pcm_hw_params,
+ .hw_free = tascam_pcm_hw_free,
+ .prepare = tascam_playback_prepare,
+ .trigger = tascam_pcm_trigger,
+ .pointer = tascam_playback_pointer,
+};
+
+void playback_urb_complete(struct urb *urb)
+{
+ struct tascam_card *tascam = urb->context;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+ size_t total_bytes_for_urb = 0;
+ snd_pcm_uframes_t offset_frames;
+ snd_pcm_uframes_t frames_to_copy;
+ int ret, i;
+
+ if (urb->status) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN && urb->status != -ENODEV)
+ dev_err_ratelimited(tascam->card->dev,
+ "Playback URB failed: %d\n",
+ urb->status);
+ goto out;
+ }
+ if (!tascam || !atomic_read(&tascam->playback_active))
+ goto out;
+
+ substream = tascam->playback_substream;
+ if (!substream || !substream->runtime)
+ goto out;
+ runtime = substream->runtime;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ for (i = 0; i < urb->number_of_packets; i++) {
+ unsigned int frames_for_packet;
+ size_t bytes_for_packet;
+
+ if (tascam->feedback_synced) {
+ frames_for_packet =
+ tascam->feedback_accumulator_pattern
+ [tascam->feedback_pattern_out_idx];
+ tascam->feedback_pattern_out_idx =
+ (tascam->feedback_pattern_out_idx + 1) %
+ FEEDBACK_ACCUMULATOR_SIZE;
+ } else {
+ frames_for_packet = runtime->rate / 8000;
+ }
+ bytes_for_packet = frames_for_packet * BYTES_PER_FRAME;
+
+ urb->iso_frame_desc[i].offset = total_bytes_for_urb;
+ urb->iso_frame_desc[i].length = bytes_for_packet;
+ total_bytes_for_urb += bytes_for_packet;
+ }
+ urb->transfer_buffer_length = total_bytes_for_urb;
+
+ offset_frames = tascam->driver_playback_pos;
+ frames_to_copy = bytes_to_frames(runtime, total_bytes_for_urb);
+ tascam->driver_playback_pos =
+ (offset_frames + frames_to_copy) % runtime->buffer_size;
+ }
+
+ if (total_bytes_for_urb > 0) {
+ u8 *dst_buf = urb->transfer_buffer;
+
+ /* Handle ring buffer wrap-around */
+ if (offset_frames + frames_to_copy > runtime->buffer_size) {
+ size_t first_chunk_bytes = frames_to_bytes(
+ runtime, runtime->buffer_size - offset_frames);
+ size_t second_chunk_bytes =
+ total_bytes_for_urb - first_chunk_bytes;
+
+ memcpy(dst_buf,
+ runtime->dma_area +
+ frames_to_bytes(runtime, offset_frames),
+ first_chunk_bytes);
+ memcpy(dst_buf + first_chunk_bytes, runtime->dma_area,
+ second_chunk_bytes);
+ } else {
+ memcpy(dst_buf,
+ runtime->dma_area +
+ frames_to_bytes(runtime, offset_frames),
+ total_bytes_for_urb);
+ }
+
+ process_playback_routing_us144mkii(tascam, dst_buf, dst_buf,
+ frames_to_copy);
+ }
+
+ urb->dev = tascam->dev;
+ usb_get_urb(urb);
+ usb_anchor_urb(urb, &tascam->playback_anchor);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret < 0) {
+ dev_err_ratelimited(tascam->card->dev,
+ "Failed to resubmit playback URB: %d\n",
+ ret);
+ usb_unanchor_urb(urb);
+ usb_put_urb(urb);
+ atomic_dec(
+ &tascam->active_urbs); /* Decrement on failed resubmission */
+ }
+out:
+ usb_put_urb(urb);
+}
+
+void feedback_urb_complete(struct urb *urb)
+{
+ struct tascam_card *tascam = urb->context;
+ struct snd_pcm_substream *playback_ss, *capture_ss;
+ struct snd_pcm_runtime *playback_rt, *capture_rt;
+ u64 total_frames_in_urb = 0;
+ int ret, p;
+ unsigned int old_in_idx, new_in_idx;
+ bool playback_period_elapsed = false;
+ bool capture_period_elapsed = false;
+
+ if (urb->status) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN && urb->status != -ENODEV) {
+ dev_err_ratelimited(tascam->card->dev,
+ "Feedback URB failed: %d\n",
+ urb->status);
+ atomic_dec(
+ &tascam->active_urbs); /* Decrement on failed resubmission */
+ }
+ goto out;
+ }
+ if (!tascam || !atomic_read(&tascam->playback_active))
+ goto out;
+
+ playback_ss = tascam->playback_substream;
+ if (!playback_ss || !playback_ss->runtime)
+ goto out;
+ playback_rt = playback_ss->runtime;
+
+ capture_ss = tascam->capture_substream;
+ capture_rt = capture_ss ? capture_ss->runtime : NULL;
+
+ scoped_guard(spinlock_irqsave, &tascam->lock) {
+ if (tascam->feedback_urb_skip_count > 0) {
+ tascam->feedback_urb_skip_count--;
+ break;
+ }
+
+ old_in_idx = tascam->feedback_pattern_in_idx;
+
+ for (p = 0; p < urb->number_of_packets; p++) {
+ u8 feedback_value = 0;
+ const unsigned int *pattern;
+ bool packet_ok =
+ (urb->iso_frame_desc[p].status == 0 &&
+ urb->iso_frame_desc[p].actual_length >= 1);
+
+ if (packet_ok)
+ feedback_value =
+ *((u8 *)urb->transfer_buffer +
+ urb->iso_frame_desc[p].offset);
+
+ if (packet_ok) {
+ int delta = feedback_value -
+ tascam->fpo.base_feedback_value +
+ tascam->fpo.feedback_offset;
+ int pattern_idx;
+
+ if (delta < 0) {
+ pattern_idx =
+ 0; // Clamp to the lowest pattern
+ } else if (delta >= 5) {
+ pattern_idx =
+ 4; // Clamp to the highest pattern
+ } else {
+ pattern_idx = delta;
+ }
+
+ pattern =
+ tascam->fpo
+ .full_frame_patterns[pattern_idx];
+ tascam->feedback_consecutive_errors = 0;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ unsigned int in_idx =
+ (tascam->feedback_pattern_in_idx +
+ i) %
+ FEEDBACK_ACCUMULATOR_SIZE;
+
+ tascam->feedback_accumulator_pattern
+ [in_idx] = pattern[i];
+ total_frames_in_urb += pattern[i];
+ }
+ } else {
+ unsigned int nominal_frames =
+ playback_rt->rate / 8000;
+ int i;
+
+ if (tascam->feedback_synced) {
+ tascam->feedback_consecutive_errors++;
+ if (tascam->feedback_consecutive_errors >
+ FEEDBACK_SYNC_LOSS_THRESHOLD) {
+ dev_err(tascam->card->dev,
+ "Fatal: Feedback sync lost. Stopping stream.\n");
+ schedule_work(
+ &tascam->stop_pcm_work);
+ tascam->feedback_synced = false;
+ break;
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ unsigned int in_idx =
+ (tascam->feedback_pattern_in_idx +
+ i) %
+ FEEDBACK_ACCUMULATOR_SIZE;
+
+ tascam->feedback_accumulator_pattern
+ [in_idx] = nominal_frames;
+ total_frames_in_urb += nominal_frames;
+ }
+ }
+ tascam->feedback_pattern_in_idx =
+ (tascam->feedback_pattern_in_idx + 8) %
+ FEEDBACK_ACCUMULATOR_SIZE;
+ }
+
+ new_in_idx = tascam->feedback_pattern_in_idx;
+
+ if (!tascam->feedback_synced) {
+ unsigned int out_idx = tascam->feedback_pattern_out_idx;
+ bool is_ahead = (new_in_idx - out_idx) %
+ FEEDBACK_ACCUMULATOR_SIZE <
+ (FEEDBACK_ACCUMULATOR_SIZE / 2);
+ bool was_behind = (old_in_idx - out_idx) %
+ FEEDBACK_ACCUMULATOR_SIZE >=
+ (FEEDBACK_ACCUMULATOR_SIZE / 2);
+
+ if (is_ahead && was_behind) {
+ dev_dbg(tascam->card->dev,
+ "Sync Acquired! (in: %u, out: %u)\n",
+ new_in_idx, out_idx);
+ tascam->feedback_synced = true;
+ tascam->feedback_consecutive_errors = 0;
+ }
+ }
+
+ if (total_frames_in_urb > 0) {
+ tascam->playback_frames_consumed += total_frames_in_urb;
+ if (atomic_read(&tascam->capture_active))
+ tascam->capture_frames_processed +=
+ total_frames_in_urb;
+ }
+
+ if (playback_rt->period_size > 0) {
+ u64 current_period =
+ div_u64(tascam->playback_frames_consumed,
+ playback_rt->period_size);
+
+ if (current_period > tascam->last_period_pos) {
+ tascam->last_period_pos = current_period;
+ playback_period_elapsed = true;
+ }
+ }
+
+ if (atomic_read(&tascam->capture_active) && capture_rt &&
+ capture_rt->period_size > 0) {
+ u64 current_capture_period =
+ div_u64(tascam->capture_frames_processed,
+ capture_rt->period_size);
+
+ if (current_capture_period >
+ tascam->last_capture_period_pos) {
+ tascam->last_capture_period_pos =
+ current_capture_period;
+ capture_period_elapsed = true;
+ }
+ }
+ }
+ if (playback_period_elapsed)
+ snd_pcm_period_elapsed(playback_ss);
+ if (capture_period_elapsed)
+ snd_pcm_period_elapsed(capture_ss);
+
+ urb->dev = tascam->dev;
+ usb_get_urb(urb);
+ usb_anchor_urb(urb, &tascam->feedback_anchor);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret < 0) {
+ dev_err_ratelimited(tascam->card->dev,
+ "Failed to resubmit feedback URB: %d\n",
+ ret);
+ usb_unanchor_urb(urb);
+ usb_put_urb(urb);
+ }
+out:
+ usb_put_urb(urb);
+}
+
+void tascam_stop_pcm_work_handler(struct work_struct *work)
+{
+ struct tascam_card *tascam =
+ container_of(work, struct tascam_card, stop_pcm_work);
+
+ if (tascam->playback_substream)
+ snd_pcm_stop(tascam->playback_substream, SNDRV_PCM_STATE_XRUN);
+ if (tascam->capture_substream)
+ snd_pcm_stop(tascam->capture_substream, SNDRV_PCM_STATE_XRUN);
+}
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index acca8bead82e..c7c7ec9c228b 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -751,7 +751,6 @@ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
- int err = 0;
unsigned int rate = params_rate(hw_params);
snd_pcm_format_t format = params_format(hw_params);
struct snd_card *card = substream->pstr->pcm->card;
@@ -760,7 +759,7 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_substream *test_substream;
int i;
- mutex_lock(&usx2y(card)->pcm_mutex);
+ guard(mutex)(&usx2y(card)->pcm_mutex);
dev_dbg(&dev->dev->dev, "%s(%p, %p)\n", __func__, substream, hw_params);
/* all pcm substreams off one usx2y have to operate at the same
* rate & format
@@ -777,14 +776,11 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
test_substream->runtime->format != format) ||
(test_substream->runtime->rate &&
test_substream->runtime->rate != rate)) {
- err = -EINVAL;
- goto error;
+ return -EINVAL;
}
}
- error:
- mutex_unlock(&usx2y(card)->pcm_mutex);
- return err;
+ return 0;
}
/*
@@ -796,7 +792,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_usx2y_substream *subs = runtime->private_data;
struct snd_usx2y_substream *cap_subs, *playback_subs;
- mutex_lock(&subs->usx2y->pcm_mutex);
+ guard(mutex)(&subs->usx2y->pcm_mutex);
dev_dbg(&subs->usx2y->dev->dev, "%s(%p)\n", __func__, substream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -816,7 +812,6 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
usx2y_urbs_release(subs);
}
}
- mutex_unlock(&subs->usx2y->pcm_mutex);
return 0;
}
@@ -835,7 +830,7 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
dev_dbg(&usx2y->dev->dev, "%s(%p)\n", __func__, substream);
- mutex_lock(&usx2y->pcm_mutex);
+ guard(mutex)(&usx2y->pcm_mutex);
usx2y_subs_prepare(subs);
// Start hardware streams
// SyncStream first....
@@ -843,25 +838,23 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
if (usx2y->format != runtime->format) {
err = usx2y_format_set(usx2y, runtime->format);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
if (usx2y->rate != runtime->rate) {
err = usx2y_rate_set(usx2y, runtime->rate);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
dev_dbg(&usx2y->dev->dev, "%s: starting capture pipe for %s\n",
__func__, subs == capsubs ? "self" : "playpipe");
err = usx2y_urbs_start(capsubs);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
if (subs != capsubs && atomic_read(&subs->state) < STATE_PREPARED)
err = usx2y_urbs_start(subs);
- up_prepare_mutex:
- mutex_unlock(&usx2y->pcm_mutex);
return err;
}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 1b1496adb47e..7c90214485d9 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -365,7 +365,7 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
struct snd_usx2y_substream *playback_subs;
struct snd_usx2y_substream *cap_subs2;
- mutex_lock(&subs->usx2y->pcm_mutex);
+ guard(mutex)(&subs->usx2y->pcm_mutex);
dev_dbg(&subs->usx2y->dev->dev, "%s(%p)\n", __func__, substream);
cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
@@ -394,7 +394,6 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
usx2y_usbpcm_urbs_release(cap_subs2);
}
}
- mutex_unlock(&subs->usx2y->pcm_mutex);
return 0;
}
@@ -504,15 +503,13 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
dev_dbg(&usx2y->dev->dev, "snd_usx2y_pcm_prepare(%p)\n", substream);
- mutex_lock(&usx2y->pcm_mutex);
+ guard(mutex)(&usx2y->pcm_mutex);
if (!usx2y->hwdep_pcm_shm) {
usx2y->hwdep_pcm_shm = alloc_pages_exact(USX2Y_HWDEP_PCM_PAGES,
GFP_KERNEL);
- if (!usx2y->hwdep_pcm_shm) {
- err = -ENOMEM;
- goto up_prepare_mutex;
- }
+ if (!usx2y->hwdep_pcm_shm)
+ return -ENOMEM;
memset(usx2y->hwdep_pcm_shm, 0, USX2Y_HWDEP_PCM_PAGES);
}
@@ -523,19 +520,19 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
if (usx2y->format != runtime->format) {
err = usx2y_format_set(usx2y, runtime->format);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
if (usx2y->rate != runtime->rate) {
err = usx2y_rate_set(usx2y, runtime->rate);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
dev_dbg(&usx2y->dev->dev,
"starting capture pipe for %s\n", subs == capsubs ?
"self" : "playpipe");
err = usx2y_usbpcm_urbs_start(capsubs);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
if (subs != capsubs) {
@@ -547,14 +544,12 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
"Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
usx2y_iso_frames_per_buffer(runtime, usx2y),
usx2y->hwdep_pcm_shm->captured_iso_frames);
- if (msleep_interruptible(10)) {
- err = -ERESTARTSYS;
- goto up_prepare_mutex;
- }
+ if (msleep_interruptible(10))
+ return -ERESTARTSYS;
}
err = usx2y_usbpcm_urbs_start(subs);
if (err < 0)
- goto up_prepare_mutex;
+ return err;
}
dev_dbg(&usx2y->dev->dev,
"Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
@@ -564,8 +559,6 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
usx2y->hwdep_pcm_shm->capture_iso_start = -1;
}
- up_prepare_mutex:
- mutex_unlock(&usx2y->pcm_mutex);
return err;
}
@@ -646,11 +639,10 @@ static int snd_usx2y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
struct snd_card *card = hw->card;
int err;
- mutex_lock(&usx2y(card)->pcm_mutex);
+ guard(mutex)(&usx2y(card)->pcm_mutex);
err = usx2y_pcms_busy_check(card);
if (!err)
usx2y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- mutex_unlock(&usx2y(card)->pcm_mutex);
return err;
}
@@ -659,11 +651,10 @@ static int snd_usx2y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
struct snd_card *card = hw->card;
int err;
- mutex_lock(&usx2y(card)->pcm_mutex);
+ guard(mutex)(&usx2y(card)->pcm_mutex);
err = usx2y_pcms_busy_check(card);
if (!err)
usx2y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- mutex_unlock(&usx2y(card)->pcm_mutex);
return err;
}
diff --git a/sound/usb/validate.c b/sound/usb/validate.c
index a0d55b77c994..4bb4893f6e74 100644
--- a/sound/usb/validate.c
+++ b/sound/usb/validate.c
@@ -266,7 +266,11 @@ static const struct usb_desc_validator audio_validators[] = {
FUNC(UAC_VERSION_2, UAC_MIXER_UNIT, validate_mixer_unit),
FUNC(UAC_VERSION_2, UAC_SELECTOR_UNIT, validate_selector_unit),
FUNC(UAC_VERSION_2, UAC_FEATURE_UNIT, validate_uac2_feature_unit),
- /* UAC_VERSION_2, UAC2_EFFECT_UNIT: not implemented yet */
+ /* just a stop-gap, it should be a proper function for the array
+ * once if the unit is really parsed/used
+ */
+ FIXED(UAC_VERSION_2, UAC2_EFFECT_UNIT,
+ struct uac2_effect_unit_descriptor),
FUNC(UAC_VERSION_2, UAC2_PROCESSING_UNIT_V2, validate_processing_unit),
FUNC(UAC_VERSION_2, UAC2_EXTENSION_UNIT_V2, validate_processing_unit),
FIXED(UAC_VERSION_2, UAC2_CLOCK_SOURCE,
@@ -286,7 +290,8 @@ static const struct usb_desc_validator audio_validators[] = {
FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, validate_mixer_unit),
FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT, validate_selector_unit),
FUNC(UAC_VERSION_3, UAC3_FEATURE_UNIT, validate_uac3_feature_unit),
- /* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */
+ FIXED(UAC_VERSION_3, UAC3_EFFECT_UNIT,
+ struct uac2_effect_unit_descriptor), /* sharing the same struct */
FUNC(UAC_VERSION_3, UAC3_PROCESSING_UNIT, validate_processing_unit),
FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit),
FIXED(UAC_VERSION_3, UAC3_CLOCK_SOURCE,
diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
index 965209e1d872..52c5757585c6 100644
--- a/sound/virtio/virtio_card.c
+++ b/sound/virtio/virtio_card.c
@@ -85,9 +85,8 @@ static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
struct virtio_snd_event *event;
u32 length;
- unsigned long flags;
- spin_lock_irqsave(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
do {
virtqueue_disable_cb(vqueue);
while ((event = virtqueue_get_buf(vqueue, &length))) {
@@ -95,7 +94,6 @@ static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
virtsnd_event_send(vqueue, event, true, GFP_ATOMIC);
}
} while (!virtqueue_enable_cb(vqueue));
- spin_unlock_irqrestore(&queue->lock, flags);
}
/**
@@ -176,14 +174,12 @@ static void virtsnd_disable_event_vq(struct virtio_snd *snd)
struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
struct virtio_snd_event *event;
u32 length;
- unsigned long flags;
if (queue->vqueue) {
- spin_lock_irqsave(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
virtqueue_disable_cb(queue->vqueue);
while ((event = virtqueue_get_buf(queue->vqueue, &length)))
virtsnd_event_dispatch(snd, event);
- spin_unlock_irqrestore(&queue->lock, flags);
}
}
diff --git a/sound/virtio/virtio_ctl_msg.c b/sound/virtio/virtio_ctl_msg.c
index 9dabea01277f..6433c870f271 100644
--- a/sound/virtio/virtio_ctl_msg.c
+++ b/sound/virtio/virtio_ctl_msg.c
@@ -131,7 +131,6 @@ int virtsnd_ctl_msg_send(struct virtio_snd *snd, struct virtio_snd_msg *msg,
unsigned int nins = 0;
struct scatterlist *psgs[4];
bool notify = false;
- unsigned long flags;
int rc;
virtsnd_ctl_msg_ref(msg);
@@ -147,15 +146,15 @@ int virtsnd_ctl_msg_send(struct virtio_snd *snd, struct virtio_snd_msg *msg,
if (in_sgs)
psgs[nouts + nins++] = in_sgs;
- spin_lock_irqsave(&queue->lock, flags);
- rc = virtqueue_add_sgs(queue->vqueue, psgs, nouts, nins, msg,
- GFP_ATOMIC);
- if (!rc) {
- notify = virtqueue_kick_prepare(queue->vqueue);
+ scoped_guard(spinlock_irqsave, &queue->lock) {
+ rc = virtqueue_add_sgs(queue->vqueue, psgs, nouts, nins, msg,
+ GFP_ATOMIC);
+ if (!rc) {
+ notify = virtqueue_kick_prepare(queue->vqueue);
- list_add_tail(&msg->list, &snd->ctl_msgs);
+ list_add_tail(&msg->list, &snd->ctl_msgs);
+ }
}
- spin_unlock_irqrestore(&queue->lock, flags);
if (rc) {
dev_err(&vdev->dev, "failed to send control message (0x%08x)\n",
@@ -233,9 +232,8 @@ void virtsnd_ctl_msg_complete(struct virtio_snd_msg *msg)
void virtsnd_ctl_msg_cancel_all(struct virtio_snd *snd)
{
struct virtio_snd_queue *queue = virtsnd_control_queue(snd);
- unsigned long flags;
- spin_lock_irqsave(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
while (!list_empty(&snd->ctl_msgs)) {
struct virtio_snd_msg *msg =
list_first_entry(&snd->ctl_msgs, struct virtio_snd_msg,
@@ -243,7 +241,6 @@ void virtsnd_ctl_msg_cancel_all(struct virtio_snd *snd)
virtsnd_ctl_msg_complete(msg);
}
- spin_unlock_irqrestore(&queue->lock, flags);
}
/**
@@ -296,13 +293,11 @@ void virtsnd_ctl_notify_cb(struct virtqueue *vqueue)
struct virtio_snd_queue *queue = virtsnd_control_queue(snd);
struct virtio_snd_msg *msg;
u32 length;
- unsigned long flags;
- spin_lock_irqsave(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
do {
virtqueue_disable_cb(vqueue);
while ((msg = virtqueue_get_buf(vqueue, &length)))
virtsnd_ctl_msg_complete(msg);
} while (!virtqueue_enable_cb(vqueue));
- spin_unlock_irqrestore(&queue->lock, flags);
}
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
index 2f7c5e709f07..3602b6690fcd 100644
--- a/sound/virtio/virtio_pcm.c
+++ b/sound/virtio/virtio_pcm.c
@@ -515,10 +515,10 @@ void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event)
/* TODO: deal with shmem elapsed period */
break;
case VIRTIO_SND_EVT_PCM_XRUN:
- spin_lock(&vss->lock);
- if (vss->xfer_enabled)
- vss->xfer_xrun = true;
- spin_unlock(&vss->lock);
+ scoped_guard(spinlock, &vss->lock) {
+ if (vss->xfer_enabled)
+ vss->xfer_xrun = true;
+ }
break;
}
}
diff --git a/sound/virtio/virtio_pcm_msg.c b/sound/virtio/virtio_pcm_msg.c
index 8c32efaf4c52..9778020a7ba8 100644
--- a/sound/virtio/virtio_pcm_msg.c
+++ b/sound/virtio/virtio_pcm_msg.c
@@ -272,14 +272,8 @@ int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss, unsigned long offset,
*/
unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss)
{
- unsigned int num;
- unsigned long flags;
-
- spin_lock_irqsave(&vss->lock, flags);
- num = vss->msg_count;
- spin_unlock_irqrestore(&vss->lock, flags);
-
- return num;
+ guard(spinlock_irqsave)(&vss->lock);
+ return vss->msg_count;
}
/**
@@ -308,7 +302,7 @@ static void virtsnd_pcm_msg_complete(struct virtio_pcm_msg *msg,
* in the virtqueue. Therefore, on each completion of an I/O message,
* the hw_ptr value is unconditionally advanced.
*/
- spin_lock(&vss->lock);
+ guard(spinlock)(&vss->lock);
/*
* If the capture substream returned an incorrect status, then just
* increase the hw_ptr by the message size.
@@ -338,7 +332,6 @@ static void virtsnd_pcm_msg_complete(struct virtio_pcm_msg *msg,
} else if (!vss->msg_count) {
wake_up_all(&vss->msg_empty);
}
- spin_unlock(&vss->lock);
}
/**
@@ -351,15 +344,13 @@ static inline void virtsnd_pcm_notify_cb(struct virtio_snd_queue *queue)
{
struct virtio_pcm_msg *msg;
u32 written_bytes;
- unsigned long flags;
- spin_lock_irqsave(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
do {
virtqueue_disable_cb(queue->vqueue);
while ((msg = virtqueue_get_buf(queue->vqueue, &written_bytes)))
virtsnd_pcm_msg_complete(msg, written_bytes);
} while (!virtqueue_enable_cb(queue->vqueue));
- spin_unlock_irqrestore(&queue->lock, flags);
}
/**
diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
index ad12aae52fc3..6297a9c61e70 100644
--- a/sound/virtio/virtio_pcm_ops.c
+++ b/sound/virtio/virtio_pcm_ops.c
@@ -327,7 +327,6 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
struct virtio_snd *snd = vss->snd;
struct virtio_snd_queue *queue;
struct virtio_snd_msg *msg;
- unsigned long flags;
int rc = 0;
switch (command) {
@@ -335,23 +334,20 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
queue = virtsnd_pcm_queue(vss);
- spin_lock_irqsave(&queue->lock, flags);
- spin_lock(&vss->lock);
- if (vss->direction == SNDRV_PCM_STREAM_CAPTURE)
- rc = virtsnd_pcm_msg_send(vss, 0, vss->buffer_bytes);
- if (!rc)
+ scoped_guard(spinlock_irqsave, &queue->lock) {
+ guard(spinlock)(&vss->lock);
+ if (vss->direction == SNDRV_PCM_STREAM_CAPTURE)
+ rc = virtsnd_pcm_msg_send(vss, 0, vss->buffer_bytes);
+ if (rc)
+ return rc;
vss->xfer_enabled = true;
- spin_unlock(&vss->lock);
- spin_unlock_irqrestore(&queue->lock, flags);
- if (rc)
- return rc;
+ }
msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_START,
GFP_KERNEL);
if (!msg) {
- spin_lock_irqsave(&vss->lock, flags);
+ guard(spinlock_irqsave)(&vss->lock);
vss->xfer_enabled = false;
- spin_unlock_irqrestore(&vss->lock, flags);
return -ENOMEM;
}
@@ -364,9 +360,9 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
vss->stopped = true;
fallthrough;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&vss->lock, flags);
- vss->xfer_enabled = false;
- spin_unlock_irqrestore(&vss->lock, flags);
+ scoped_guard(spinlock_irqsave, &vss->lock) {
+ vss->xfer_enabled = false;
+ }
msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_STOP,
GFP_KERNEL);
@@ -480,38 +476,24 @@ static int virtsnd_pcm_pb_ack(struct snd_pcm_substream *substream)
{
struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
- unsigned long flags;
- int rc;
- spin_lock_irqsave(&queue->lock, flags);
- spin_lock(&vss->lock);
+ guard(spinlock_irqsave)(&queue->lock);
+ guard(spinlock)(&vss->lock);
- rc = snd_pcm_indirect_playback_transfer(substream, &vss->pcm_indirect,
- virtsnd_pcm_trans_copy);
-
- spin_unlock(&vss->lock);
- spin_unlock_irqrestore(&queue->lock, flags);
-
- return rc;
+ return snd_pcm_indirect_playback_transfer(substream, &vss->pcm_indirect,
+ virtsnd_pcm_trans_copy);
}
static int virtsnd_pcm_cp_ack(struct snd_pcm_substream *substream)
{
struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&queue->lock, flags);
- spin_lock(&vss->lock);
-
- rc = snd_pcm_indirect_capture_transfer(substream, &vss->pcm_indirect,
- virtsnd_pcm_trans_copy);
- spin_unlock(&vss->lock);
- spin_unlock_irqrestore(&queue->lock, flags);
+ guard(spinlock_irqsave)(&queue->lock);
+ guard(spinlock)(&vss->lock);
- return rc;
+ return snd_pcm_indirect_capture_transfer(substream, &vss->pcm_indirect,
+ virtsnd_pcm_trans_copy);
}
/* PCM substream operators map. */
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 01f49555c5f6..8e2a007311d3 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -171,13 +171,11 @@ static struct snd_pcm_substream *
had_substream_get(struct snd_intelhad *intelhaddata)
{
struct snd_pcm_substream *substream;
- unsigned long flags;
- spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
+ guard(spinlock_irqsave)(&intelhaddata->had_spinlock);
substream = intelhaddata->stream_info.substream;
if (substream)
intelhaddata->stream_info.substream_refcount++;
- spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
return substream;
}
@@ -186,11 +184,8 @@ had_substream_get(struct snd_intelhad *intelhaddata)
*/
static void had_substream_put(struct snd_intelhad *intelhaddata)
{
- unsigned long flags;
-
- spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
+ guard(spinlock_irqsave)(&intelhaddata->had_spinlock);
intelhaddata->stream_info.substream_refcount--;
- spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
}
static u32 had_config_offset(int pipe)
@@ -554,16 +549,13 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol,
memset(ucontrol->value.integer.value, 0,
sizeof(long) * HAD_MAX_CHANNEL);
- mutex_lock(&intelhaddata->mutex);
- if (!intelhaddata->chmap->chmap) {
- mutex_unlock(&intelhaddata->mutex);
+ guard(mutex)(&intelhaddata->mutex);
+ if (!intelhaddata->chmap->chmap)
return 0;
- }
chmap = intelhaddata->chmap->chmap;
for (i = 0; i < chmap->channels; i++)
ucontrol->value.integer.value[i] = chmap->map[i];
- mutex_unlock(&intelhaddata->mutex);
return 0;
}
@@ -949,10 +941,9 @@ static int had_process_ringbuf(struct snd_pcm_substream *substream,
struct snd_intelhad *intelhaddata)
{
int len, processed;
- unsigned long flags;
processed = 0;
- spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
+ guard(spinlock_irqsave)(&intelhaddata->had_spinlock);
for (;;) {
/* get the remaining bytes on the buffer */
had_read_register(intelhaddata,
@@ -961,25 +952,20 @@ static int had_process_ringbuf(struct snd_pcm_substream *substream,
if (len < 0 || len > intelhaddata->period_bytes) {
dev_dbg(intelhaddata->dev, "Invalid buf length %d\n",
len);
- len = -EPIPE;
- goto out;
+ return -EPIPE;
}
if (len > 0) /* OK, this is the current buffer */
break;
/* len=0 => already empty, check the next buffer */
- if (++processed >= intelhaddata->num_bds) {
- len = -EPIPE; /* all empty? - report underrun */
- goto out;
- }
+ if (++processed >= intelhaddata->num_bds)
+ return -EPIPE; /* all empty? - report underrun */
had_advance_ringbuf(substream, intelhaddata);
}
len = intelhaddata->period_bytes - len;
len += intelhaddata->period_bytes * intelhaddata->pcmbuf_head;
- out:
- spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
return len;
}
@@ -1095,10 +1081,10 @@ static int had_pcm_open(struct snd_pcm_substream *substream)
goto error;
/* expose PCM substream */
- spin_lock_irq(&intelhaddata->had_spinlock);
- intelhaddata->stream_info.substream = substream;
- intelhaddata->stream_info.substream_refcount++;
- spin_unlock_irq(&intelhaddata->had_spinlock);
+ scoped_guard(spinlock_irq, &intelhaddata->had_spinlock) {
+ intelhaddata->stream_info.substream = substream;
+ intelhaddata->stream_info.substream_refcount++;
+ }
return retval;
error:
@@ -1156,7 +1142,7 @@ static int had_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
intelhaddata = snd_pcm_substream_chip(substream);
- spin_lock(&intelhaddata->had_spinlock);
+ guard(spinlock)(&intelhaddata->had_spinlock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -1175,7 +1161,6 @@ static int had_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
default:
retval = -EINVAL;
}
- spin_unlock(&intelhaddata->had_spinlock);
return retval;
}
@@ -1314,21 +1299,20 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata)
{
struct snd_pcm_substream *substream;
- spin_lock_irq(&intelhaddata->had_spinlock);
- if (intelhaddata->connected) {
- dev_dbg(intelhaddata->dev, "Device already connected\n");
- spin_unlock_irq(&intelhaddata->had_spinlock);
- return;
- }
+ scoped_guard(spinlock_irq, &intelhaddata->had_spinlock) {
+ if (intelhaddata->connected) {
+ dev_dbg(intelhaddata->dev, "Device already connected\n");
+ return;
+ }
- /* Disable Audio */
- had_enable_audio(intelhaddata, false);
+ /* Disable Audio */
+ had_enable_audio(intelhaddata, false);
- intelhaddata->connected = true;
- dev_dbg(intelhaddata->dev,
- "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n",
+ intelhaddata->connected = true;
+ dev_dbg(intelhaddata->dev,
+ "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n",
__func__, __LINE__);
- spin_unlock_irq(&intelhaddata->had_spinlock);
+ }
had_build_channel_allocation_map(intelhaddata);
@@ -1347,22 +1331,20 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata)
{
struct snd_pcm_substream *substream;
- spin_lock_irq(&intelhaddata->had_spinlock);
- if (!intelhaddata->connected) {
- dev_dbg(intelhaddata->dev, "Device already disconnected\n");
- spin_unlock_irq(&intelhaddata->had_spinlock);
- return;
-
- }
+ scoped_guard(spinlock_irq, &intelhaddata->had_spinlock) {
+ if (!intelhaddata->connected) {
+ dev_dbg(intelhaddata->dev, "Device already disconnected\n");
+ return;
+ }
- /* Disable Audio */
- had_enable_audio(intelhaddata, false);
+ /* Disable Audio */
+ had_enable_audio(intelhaddata, false);
- intelhaddata->connected = false;
- dev_dbg(intelhaddata->dev,
- "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n",
+ intelhaddata->connected = false;
+ dev_dbg(intelhaddata->dev,
+ "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n",
__func__, __LINE__);
- spin_unlock_irq(&intelhaddata->had_spinlock);
+ }
kfree(intelhaddata->chmap->chmap);
intelhaddata->chmap->chmap = NULL;
@@ -1394,14 +1376,13 @@ static int had_iec958_get(struct snd_kcontrol *kcontrol,
{
struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
- mutex_lock(&intelhaddata->mutex);
+ guard(mutex)(&intelhaddata->mutex);
ucontrol->value.iec958.status[0] = (intelhaddata->aes_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (intelhaddata->aes_bits >> 8) & 0xff;
ucontrol->value.iec958.status[2] =
(intelhaddata->aes_bits >> 16) & 0xff;
ucontrol->value.iec958.status[3] =
(intelhaddata->aes_bits >> 24) & 0xff;
- mutex_unlock(&intelhaddata->mutex);
return 0;
}
@@ -1426,12 +1407,11 @@ static int had_iec958_put(struct snd_kcontrol *kcontrol,
(ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) |
(ucontrol->value.iec958.status[3] << 24);
- mutex_lock(&intelhaddata->mutex);
+ guard(mutex)(&intelhaddata->mutex);
if (intelhaddata->aes_bits != val) {
intelhaddata->aes_bits = val;
changed = 1;
}
- mutex_unlock(&intelhaddata->mutex);
return changed;
}
@@ -1448,10 +1428,9 @@ static int had_ctl_eld_get(struct snd_kcontrol *kcontrol,
{
struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
- mutex_lock(&intelhaddata->mutex);
+ guard(mutex)(&intelhaddata->mutex);
memcpy(ucontrol->value.bytes.data, intelhaddata->eld,
HDMI_MAX_ELD_BYTES);
- mutex_unlock(&intelhaddata->mutex);
return 0;
}
@@ -1642,9 +1621,9 @@ static void hdmi_lpe_audio_free(struct snd_card *card)
struct intel_hdmi_lpe_audio_pdata *pdata = card_ctx->dev->platform_data;
int port;
- spin_lock_irq(&pdata->lpe_audio_slock);
- pdata->notify_audio_lpe = NULL;
- spin_unlock_irq(&pdata->lpe_audio_slock);
+ scoped_guard(spinlock_irq, &pdata->lpe_audio_slock) {
+ pdata->notify_audio_lpe = NULL;
+ }
for_each_port(card_ctx, port) {
struct snd_intelhad *ctx = &card_ctx->pcm_ctx[port];
@@ -1805,9 +1784,9 @@ static int __hdmi_lpe_audio_probe(struct platform_device *pdev)
if (ret)
return ret;
- spin_lock_irq(&pdata->lpe_audio_slock);
- pdata->notify_audio_lpe = notify_audio_lpe;
- spin_unlock_irq(&pdata->lpe_audio_slock);
+ scoped_guard(spinlock_irq, &pdata->lpe_audio_slock) {
+ pdata->notify_audio_lpe = notify_audio_lpe;
+ }
pm_runtime_set_autosuspend_delay(&pdev->dev, INTEL_HDMI_AUDIO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pdev->dev);
diff --git a/sound/xen/xen_snd_front.c b/sound/xen/xen_snd_front.c
index b66e037710d0..c56d17479f05 100644
--- a/sound/xen/xen_snd_front.c
+++ b/sound/xen/xen_snd_front.c
@@ -62,12 +62,12 @@ int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl,
struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_HW_PARAM_QUERY);
- req->op.hw_param = *hw_param_req;
- mutex_unlock(&evtchnl->ring_io_lock);
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_HW_PARAM_QUERY);
+ req->op.hw_param = *hw_param_req;
+ }
ret = be_stream_do_io(evtchnl);
@@ -77,7 +77,6 @@ int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl,
if (ret == 0)
*hw_param_resp = evtchnl->u.req.resp.hw_param;
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
@@ -90,25 +89,24 @@ int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl,
struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
-
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_OPEN);
- req->op.open.pcm_format = format;
- req->op.open.pcm_channels = channels;
- req->op.open.pcm_rate = rate;
- req->op.open.buffer_sz = buffer_sz;
- req->op.open.period_sz = period_sz;
- req->op.open.gref_directory =
- xen_front_pgdir_shbuf_get_dir_start(shbuf);
- mutex_unlock(&evtchnl->ring_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
+
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_OPEN);
+ req->op.open.pcm_format = format;
+ req->op.open.pcm_channels = channels;
+ req->op.open.pcm_rate = rate;
+ req->op.open.buffer_sz = buffer_sz;
+ req->op.open.period_sz = period_sz;
+ req->op.open.gref_directory =
+ xen_front_pgdir_shbuf_get_dir_start(shbuf);
+ }
ret = be_stream_do_io(evtchnl);
if (ret == 0)
ret = be_stream_wait_io(evtchnl);
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
@@ -117,18 +115,17 @@ int xen_snd_front_stream_close(struct xen_snd_front_evtchnl *evtchnl)
__always_unused struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_CLOSE);
- mutex_unlock(&evtchnl->ring_io_lock);
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_CLOSE);
+ }
ret = be_stream_do_io(evtchnl);
if (ret == 0)
ret = be_stream_wait_io(evtchnl);
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
@@ -138,20 +135,19 @@ int xen_snd_front_stream_write(struct xen_snd_front_evtchnl *evtchnl,
struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_WRITE);
- req->op.rw.length = count;
- req->op.rw.offset = pos;
- mutex_unlock(&evtchnl->ring_io_lock);
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_WRITE);
+ req->op.rw.length = count;
+ req->op.rw.offset = pos;
+ }
ret = be_stream_do_io(evtchnl);
if (ret == 0)
ret = be_stream_wait_io(evtchnl);
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
@@ -161,20 +157,19 @@ int xen_snd_front_stream_read(struct xen_snd_front_evtchnl *evtchnl,
struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_READ);
- req->op.rw.length = count;
- req->op.rw.offset = pos;
- mutex_unlock(&evtchnl->ring_io_lock);
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_READ);
+ req->op.rw.length = count;
+ req->op.rw.offset = pos;
+ }
ret = be_stream_do_io(evtchnl);
if (ret == 0)
ret = be_stream_wait_io(evtchnl);
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
@@ -184,19 +179,18 @@ int xen_snd_front_stream_trigger(struct xen_snd_front_evtchnl *evtchnl,
struct xensnd_req *req;
int ret;
- mutex_lock(&evtchnl->u.req.req_io_lock);
+ guard(mutex)(&evtchnl->u.req.req_io_lock);
- mutex_lock(&evtchnl->ring_io_lock);
- req = be_stream_prepare_req(evtchnl, XENSND_OP_TRIGGER);
- req->op.trigger.type = type;
- mutex_unlock(&evtchnl->ring_io_lock);
+ scoped_guard(mutex, &evtchnl->ring_io_lock) {
+ req = be_stream_prepare_req(evtchnl, XENSND_OP_TRIGGER);
+ req->op.trigger.type = type;
+ }
ret = be_stream_do_io(evtchnl);
if (ret == 0)
ret = be_stream_wait_io(evtchnl);
- mutex_unlock(&evtchnl->u.req.req_io_lock);
return ret;
}
diff --git a/sound/xen/xen_snd_front_evtchnl.c b/sound/xen/xen_snd_front_evtchnl.c
index 26d1b3987887..2fbed8e4a490 100644
--- a/sound/xen/xen_snd_front_evtchnl.c
+++ b/sound/xen/xen_snd_front_evtchnl.c
@@ -28,7 +28,7 @@ static irqreturn_t evtchnl_interrupt_req(int irq, void *dev_id)
if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
return IRQ_HANDLED;
- mutex_lock(&channel->ring_io_lock);
+ guard(mutex)(&channel->ring_io_lock);
again:
rp = channel->u.req.ring.sring->rsp_prod;
@@ -80,7 +80,6 @@ again:
channel->u.req.ring.sring->rsp_event = i + 1;
}
- mutex_unlock(&channel->ring_io_lock);
return IRQ_HANDLED;
}
@@ -93,13 +92,13 @@ static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id)
if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
return IRQ_HANDLED;
- mutex_lock(&channel->ring_io_lock);
+ guard(mutex)(&channel->ring_io_lock);
prod = page->in_prod;
/* Ensure we see ring contents up to prod. */
virt_rmb();
if (prod == page->in_cons)
- goto out;
+ return IRQ_HANDLED;
/*
* Assume that the backend is trusted to always write sane values
@@ -125,8 +124,6 @@ static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id)
/* Ensure ring contents. */
virt_wmb();
-out:
- mutex_unlock(&channel->ring_io_lock);
return IRQ_HANDLED;
}
@@ -444,23 +441,23 @@ void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair
else
state = EVTCHNL_STATE_DISCONNECTED;
- mutex_lock(&evt_pair->req.ring_io_lock);
- evt_pair->req.state = state;
- mutex_unlock(&evt_pair->req.ring_io_lock);
+ scoped_guard(mutex, &evt_pair->req.ring_io_lock) {
+ evt_pair->req.state = state;
+ }
- mutex_lock(&evt_pair->evt.ring_io_lock);
- evt_pair->evt.state = state;
- mutex_unlock(&evt_pair->evt.ring_io_lock);
+ scoped_guard(mutex, &evt_pair->evt.ring_io_lock) {
+ evt_pair->evt.state = state;
+ }
}
void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair)
{
- mutex_lock(&evt_pair->req.ring_io_lock);
- evt_pair->req.evt_next_id = 0;
- mutex_unlock(&evt_pair->req.ring_io_lock);
+ scoped_guard(mutex, &evt_pair->req.ring_io_lock) {
+ evt_pair->req.evt_next_id = 0;
+ }
- mutex_lock(&evt_pair->evt.ring_io_lock);
- evt_pair->evt.evt_next_id = 0;
- mutex_unlock(&evt_pair->evt.ring_io_lock);
+ scoped_guard(mutex, &evt_pair->evt.ring_io_lock) {
+ evt_pair->evt.evt_next_id = 0;
+ }
}