aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97/bus.c2
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c4
-rw-r--r--sound/arm/pxa2xx-ac97.c4
-rw-r--r--sound/core/control.c38
-rw-r--r--sound/core/control_compat.c14
-rw-r--r--sound/core/control_led.c36
-rw-r--r--sound/core/hwdep.c6
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/init.c77
-rw-r--r--sound/core/memalloc.c444
-rw-r--r--sound/core/memalloc_local.h19
-rw-r--r--sound/core/oss/mixer_oss.c45
-rw-r--r--sound/core/oss/pcm_oss.c70
-rw-r--r--sound/core/oss/pcm_plugin.c26
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_compat.c6
-rw-r--r--sound/core/pcm_lib.c64
-rw-r--r--sound/core/pcm_local.h5
-rw-r--r--sound/core/pcm_memory.c21
-rw-r--r--sound/core/pcm_misc.c12
-rw-r--r--sound/core/pcm_native.c51
-rw-r--r--sound/core/rawmidi.c93
-rw-r--r--sound/core/rawmidi_compat.c4
-rw-r--r--sound/core/seq/oss/seq_oss.c26
-rw-r--r--sound/core/seq/oss/seq_oss_init.c10
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c33
-rw-r--r--sound/core/seq/oss/seq_oss_rw.c3
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c9
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c3
-rw-r--r--sound/core/seq/seq_clientmgr.c51
-rw-r--r--sound/core/seq/seq_dummy.c3
-rw-r--r--sound/core/seq/seq_fifo.c3
-rw-r--r--sound/core/seq/seq_memory.c6
-rw-r--r--sound/core/seq/seq_midi.c27
-rw-r--r--sound/core/seq/seq_queue.c21
-rw-r--r--sound/core/seq/seq_virmidi.c9
-rw-r--r--sound/core/sgbuf.c90
-rw-r--r--sound/core/sound.c3
-rw-r--r--sound/core/sound_oss.c3
-rw-r--r--sound/drivers/mpu401/mpu401.c9
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c19
-rw-r--r--sound/drivers/mtpav.c15
-rw-r--r--sound/drivers/mts64.c15
-rw-r--r--sound/drivers/opl3/opl3_lib.c42
-rw-r--r--sound/drivers/opl3/opl3_midi.c3
-rw-r--r--sound/drivers/opl3/opl3_oss.c6
-rw-r--r--sound/drivers/opl3/opl3_seq.c9
-rw-r--r--sound/drivers/portman2x4.c15
-rw-r--r--sound/drivers/serial-u16550.c27
-rw-r--r--sound/drivers/vx/vx_core.c60
-rw-r--r--sound/drivers/vx/vx_hwdep.c12
-rw-r--r--sound/drivers/vx/vx_mixer.c39
-rw-r--r--sound/drivers/vx/vx_pcm.c32
-rw-r--r--sound/firewire/Kconfig30
-rw-r--r--sound/firewire/amdtp-am824.c4
-rw-r--r--sound/firewire/amdtp-am824.h2
-rw-r--r--sound/firewire/amdtp-stream-trace.h2
-rw-r--r--sound/firewire/amdtp-stream.c1229
-rw-r--r--sound/firewire/amdtp-stream.h105
-rw-r--r--sound/firewire/bebob/bebob.c282
-rw-r--r--sound/firewire/bebob/bebob.h22
-rw-r--r--sound/firewire/bebob/bebob_stream.c90
-rw-r--r--sound/firewire/dice/dice-stream.c50
-rw-r--r--sound/firewire/dice/dice-transaction.c2
-rw-r--r--sound/firewire/dice/dice.c138
-rw-r--r--sound/firewire/dice/dice.h4
-rw-r--r--sound/firewire/digi00x/amdtp-dot.c9
-rw-r--r--sound/firewire/digi00x/digi00x-stream.c13
-rw-r--r--sound/firewire/digi00x/digi00x.c101
-rw-r--r--sound/firewire/digi00x/digi00x.h3
-rw-r--r--sound/firewire/fireface/amdtp-ff.c2
-rw-r--r--sound/firewire/fireface/ff-stream.c13
-rw-r--r--sound/firewire/fireface/ff.c90
-rw-r--r--sound/firewire/fireface/ff.h3
-rw-r--r--sound/firewire/fireworks/fireworks.c120
-rw-r--r--sound/firewire/fireworks/fireworks.h13
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c24
-rw-r--r--sound/firewire/lib.c32
-rw-r--r--sound/firewire/lib.h3
-rw-r--r--sound/firewire/motu/Makefile3
-rw-r--r--sound/firewire/motu/amdtp-motu.c139
-rw-r--r--sound/firewire/motu/motu-protocol-v1.c470
-rw-r--r--sound/firewire/motu/motu-protocol-v2.c181
-rw-r--r--sound/firewire/motu/motu-protocol-v3.c92
-rw-r--r--sound/firewire/motu/motu-stream.c34
-rw-r--r--sound/firewire/motu/motu.c91
-rw-r--r--sound/firewire/motu/motu.h47
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c55
-rw-r--r--sound/firewire/oxfw/oxfw.c259
-rw-r--r--sound/firewire/oxfw/oxfw.h19
-rw-r--r--sound/firewire/tascam/amdtp-tascam.c6
-rw-r--r--sound/firewire/tascam/tascam-stream.c26
-rw-r--r--sound/firewire/tascam/tascam.c92
-rw-r--r--sound/firewire/tascam/tascam.h3
-rw-r--r--sound/i2c/cs8427.c24
-rw-r--r--sound/i2c/other/ak4114.c3
-rw-r--r--sound/i2c/other/ak4117.c3
-rw-r--r--sound/i2c/tea6330t.c26
-rw-r--r--sound/isa/ad1816a/ad1816a.c23
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c27
-rw-r--r--sound/isa/als100.c18
-rw-r--r--sound/isa/azt2320.c21
-rw-r--r--sound/isa/cmi8330.c39
-rw-r--r--sound/isa/cs423x/cs4236.c21
-rw-r--r--sound/isa/cs423x/cs4236_lib.c12
-rw-r--r--sound/isa/es1688/es1688_lib.c3
-rw-r--r--sound/isa/es18xx.c51
-rw-r--r--sound/isa/gus/gus_main.c20
-rw-r--r--sound/isa/gus/gus_mem.c3
-rw-r--r--sound/isa/gus/gus_mixer.c6
-rw-r--r--sound/isa/gus/gus_pcm.c23
-rw-r--r--sound/isa/gus/gus_uart.c3
-rw-r--r--sound/isa/gus/gusclassic.c6
-rw-r--r--sound/isa/gus/gusextreme.c6
-rw-r--r--sound/isa/gus/gusmax.c36
-rw-r--r--sound/isa/gus/interwave.c90
-rw-r--r--sound/isa/opl3sa2.c68
-rw-r--r--sound/isa/opti9xx/miro.c27
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c27
-rw-r--r--sound/isa/sb/emu8000.c21
-rw-r--r--sound/isa/sb/emu8000_patch.c3
-rw-r--r--sound/isa/sb/emu8000_pcm.c6
-rw-r--r--sound/isa/sb/sb16.c65
-rw-r--r--sound/isa/sb/sb16_csp.c29
-rw-r--r--sound/isa/sb/sb16_main.c6
-rw-r--r--sound/isa/sb/sb8.c38
-rw-r--r--sound/isa/sb/sb8_main.c3
-rw-r--r--sound/isa/sb/sb8_midi.c3
-rw-r--r--sound/isa/sb/sb_common.c9
-rw-r--r--sound/isa/sb/sb_mixer.c55
-rw-r--r--sound/isa/wavefront/wavefront.c6
-rw-r--r--sound/isa/wavefront/wavefront_midi.c20
-rw-r--r--sound/isa/wavefront/wavefront_synth.c56
-rw-r--r--sound/isa/wss/wss_lib.c9
-rw-r--r--sound/mips/snd-n64.c4
-rw-r--r--sound/oss/dmasound/dmasound_core.c14
-rw-r--r--sound/parisc/harmony.c7
-rw-r--r--sound/pci/ac97/ac97_codec.c205
-rw-r--r--sound/pci/ac97/ac97_patch.c137
-rw-r--r--sound/pci/ad1889.c15
-rw-r--r--sound/pci/ak4531_codec.c9
-rw-r--r--sound/pci/als300.c22
-rw-r--r--sound/pci/als4000.c55
-rw-r--r--sound/pci/atiixp.c33
-rw-r--r--sound/pci/atiixp_modem.c40
-rw-r--r--sound/pci/au88x0/au88x0.c77
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c28
-rw-r--r--sound/pci/au88x0/au88x0_core.c47
-rw-r--r--sound/pci/au88x0/au88x0_eq.c20
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c3
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c14
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c15
-rw-r--r--sound/pci/azt3328.c3
-rw-r--r--sound/pci/bt87x.c3
-rw-r--r--sound/pci/ca0106/ca0106_main.c18
-rw-r--r--sound/pci/ca0106/ca_midi.c3
-rw-r--r--sound/pci/cmipci.c83
-rw-r--r--sound/pci/cs4281.c54
-rw-r--r--sound/pci/cs46xx/cs46xx.c31
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c51
-rw-r--r--sound/pci/cs46xx/dsp_spos.c3
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c28
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c10
-rw-r--r--sound/pci/echoaudio/darla20_dsp.c6
-rw-r--r--sound/pci/echoaudio/darla24_dsp.c6
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c3
-rw-r--r--sound/pci/echoaudio/echoaudio.c220
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c12
-rw-r--r--sound/pci/echoaudio/echoaudio_gml.c3
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c6
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c6
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c6
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c6
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c6
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c6
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c9
-rw-r--r--sound/pci/echoaudio/mia_dsp.c6
-rw-r--r--sound/pci/echoaudio/midi.c4
-rw-r--r--sound/pci/echoaudio/mona_dsp.c6
-rw-r--r--sound/pci/emu10k1/emu10k1.c42
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c3
-rw-r--r--sound/pci/emu10k1/emu10k1x.c85
-rw-r--r--sound/pci/emu10k1/emufx.c13
-rw-r--r--sound/pci/emu10k1/emumixer.c78
-rw-r--r--sound/pci/emu10k1/emumpu401.c12
-rw-r--r--sound/pci/emu10k1/emupcm.c24
-rw-r--r--sound/pci/emu10k1/memory.c21
-rw-r--r--sound/pci/emu10k1/p16v.c13
-rw-r--r--sound/pci/emu10k1/timer.c3
-rw-r--r--sound/pci/ens1370.c45
-rw-r--r--sound/pci/es1938.c42
-rw-r--r--sound/pci/es1968.c75
-rw-r--r--sound/pci/fm801.c63
-rw-r--r--sound/pci/hda/hda_bind.c7
-rw-r--r--sound/pci/hda/hda_codec.c10
-rw-r--r--sound/pci/hda/hda_generic.c2
-rw-r--r--sound/pci/hda/hda_intel.c22
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/hda_tegra.c7
-rw-r--r--sound/pci/hda/patch_ca0132.c2
-rw-r--r--sound/pci/hda/patch_realtek.c133
-rw-r--r--sound/pci/ice1712/delta.c6
-rw-r--r--sound/pci/ice1712/ews.c24
-rw-r--r--sound/pci/intel8x0.c50
-rw-r--r--sound/pci/intel8x0m.c38
-rw-r--r--sound/pci/korg1212/korg1212.c24
-rw-r--r--sound/pci/lx6464es/lx_core.c4
-rw-r--r--sound/pci/maestro3.c21
-rw-r--r--sound/pci/mixart/mixart.c29
-rw-r--r--sound/pci/mixart/mixart_hwdep.c17
-rw-r--r--sound/pci/mixart/mixart_mixer.c33
-rw-r--r--sound/pci/nm256/nm256.c27
-rw-r--r--sound/pci/pcxhr/pcxhr.c22
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c9
-rw-r--r--sound/pci/riptide/riptide.c88
-rw-r--r--sound/pci/rme32.c76
-rw-r--r--sound/pci/rme96.c148
-rw-r--r--sound/pci/rme9652/hdsp.c124
-rw-r--r--sound/pci/rme9652/rme9652.c98
-rw-r--r--sound/pci/sonicvibes.c67
-rw-r--r--sound/pci/trident/trident.c41
-rw-r--r--sound/pci/trident/trident.h1
-rw-r--r--sound/pci/trident/trident_main.c95
-rw-r--r--sound/pci/trident/trident_memory.c51
-rw-r--r--sound/pci/via82xx.c78
-rw-r--r--sound/pci/via82xx_modem.c52
-rw-r--r--sound/pci/vx222/vx222.c18
-rw-r--r--sound/pci/vx222/vx222_ops.c12
-rw-r--r--sound/pci/ymfpci/ymfpci.c71
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c72
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c3
-rw-r--r--sound/pcmcia/vx/vxp_mixer.c6
-rw-r--r--sound/pcmcia/vx/vxp_ops.c6
-rw-r--r--sound/pcmcia/vx/vxpocket.c3
-rw-r--r--sound/ppc/beep.c5
-rw-r--r--sound/ppc/daca.c24
-rw-r--r--sound/ppc/keywest.c6
-rw-r--r--sound/ppc/pmac.c6
-rw-r--r--sound/ppc/powermac.c27
-rw-r--r--sound/ppc/tumbler.c72
-rw-r--r--sound/soc/amd/Kconfig9
-rw-r--r--sound/soc/amd/Makefile1
-rw-r--r--sound/soc/amd/acp-da7219-max98357a.c12
-rw-r--r--sound/soc/amd/acp-pcm-dma.c20
-rw-r--r--sound/soc/amd/acp3x-rt5682-max9836.c14
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c10
-rw-r--r--sound/soc/amd/renoir/acp3x-pdm-dma.c8
-rw-r--r--sound/soc/amd/renoir/acp3x-rn.c7
-rw-r--r--sound/soc/amd/vangogh/Makefile9
-rw-r--r--sound/soc/amd/vangogh/acp5x-i2s.c427
-rw-r--r--sound/soc/amd/vangogh/acp5x-pcm-dma.c517
-rw-r--r--sound/soc/amd/vangogh/acp5x.h193
-rw-r--r--sound/soc/amd/vangogh/pci-acp5x.c326
-rw-r--r--sound/soc/amd/vangogh/vg_chip_offset_byte.h337
-rw-r--r--sound/soc/atmel/Kconfig1
-rw-r--r--sound/soc/atmel/atmel-i2s.c35
-rw-r--r--sound/soc/atmel/mchp-spdifrx.c6
-rw-r--r--sound/soc/atmel/mchp-spdiftx.c2
-rw-r--r--sound/soc/atmel/tse850-pcm5142.c2
-rw-r--r--sound/soc/bcm/cygnus-pcm.c2
-rw-r--r--sound/soc/codecs/Kconfig31
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ad193x.c30
-rw-r--r--sound/soc/codecs/ad193x.h4
-rw-r--r--sound/soc/codecs/cs42l42.c28
-rw-r--r--sound/soc/codecs/cs42l42.h2
-rw-r--r--sound/soc/codecs/cx20442.c12
-rw-r--r--sound/soc/codecs/ics43432.c4
-rw-r--r--sound/soc/codecs/lpass-rx-macro.c65
-rw-r--r--sound/soc/codecs/max98090.c4
-rw-r--r--sound/soc/codecs/max98373-sdw.c14
-rw-r--r--sound/soc/codecs/max98373.h2
-rw-r--r--sound/soc/codecs/max98390.c26
-rw-r--r--sound/soc/codecs/max98390.h1
-rw-r--r--sound/soc/codecs/mt6359-accdet.c25
-rw-r--r--sound/soc/codecs/rt1015.c46
-rw-r--r--sound/soc/codecs/rt1015.h2
-rw-r--r--sound/soc/codecs/rt1015p.c2
-rw-r--r--sound/soc/codecs/rt1308-sdw.c2
-rw-r--r--sound/soc/codecs/rt1316-sdw.c2
-rw-r--r--sound/soc/codecs/rt5514.c2
-rw-r--r--sound/soc/codecs/rt5640.c133
-rw-r--r--sound/soc/codecs/rt5640.h6
-rw-r--r--sound/soc/codecs/rt5645.c49
-rw-r--r--sound/soc/codecs/rt5682-i2c.c15
-rw-r--r--sound/soc/codecs/rt5682-sdw.c57
-rw-r--r--sound/soc/codecs/rt5682.c44
-rw-r--r--sound/soc/codecs/rt5682.h2
-rw-r--r--sound/soc/codecs/rt700-sdw.c36
-rw-r--r--sound/soc/codecs/rt700.c4
-rw-r--r--sound/soc/codecs/rt700.h2
-rw-r--r--sound/soc/codecs/rt711-sdca-sdw.c58
-rw-r--r--sound/soc/codecs/rt711-sdca.c8
-rw-r--r--sound/soc/codecs/rt711-sdca.h2
-rw-r--r--sound/soc/codecs/rt711-sdw.c36
-rw-r--r--sound/soc/codecs/rt711.c4
-rw-r--r--sound/soc/codecs/rt711.h2
-rw-r--r--sound/soc/codecs/rt715-sdca-sdw.c3
-rw-r--r--sound/soc/codecs/rt715-sdca-sdw.h1
-rw-r--r--sound/soc/codecs/rt715-sdca.c9
-rw-r--r--sound/soc/codecs/rt715-sdca.h3
-rw-r--r--sound/soc/codecs/rt715-sdw.c2
-rw-r--r--sound/soc/codecs/sdw-mockup.c310
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c10
-rw-r--r--sound/soc/codecs/wcd938x.c854
-rw-r--r--sound/soc/codecs/wcd938x.h1
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c6
-rw-r--r--sound/soc/codecs/wm_adsp.c7
-rw-r--r--sound/soc/dwc/Kconfig2
-rw-r--r--sound/soc/fsl/fsl_rpmsg.c20
-rw-r--r--sound/soc/fsl/fsl_spdif.c23
-rw-r--r--sound/soc/fsl/fsl_xcvr.c4
-rw-r--r--sound/soc/generic/simple-card-utils.c4
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c2
-rw-r--r--sound/soc/intel/boards/Kconfig1
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c31
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c328
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c63
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98927.c55
-rw-r--r--sound/soc/intel/boards/sof_cs42l42.c361
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.c17
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.h4
-rw-r--r--sound/soc/intel/boards/sof_pcm512x.c13
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c66
-rw-r--r--sound/soc/intel/boards/sof_sdw.c109
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h64
-rw-r--r--sound/soc/intel/boards/sof_sdw_max98373.c7
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1308.c3
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1316.c3
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt5682.c3
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt700.c3
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt711.c51
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt711_sdca.c52
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt715.c3
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt715_sdca.c3
-rw-r--r--sound/soc/intel/common/Makefile3
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cnl-match.c15
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-jsl-match.c8
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c166
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h17
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-tgl-match.c38
-rw-r--r--sound/soc/intel/skylake/skl-messages.c155
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c33
-rw-r--r--sound/soc/intel/skylake/skl-topology.c155
-rw-r--r--sound/soc/intel/skylake/skl-topology.h26
-rw-r--r--sound/soc/mediatek/Kconfig24
-rw-r--r--sound/soc/mediatek/Makefile1
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.c22
-rw-r--r--sound/soc/mediatek/common/mtk-base-afe.h10
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-afe-pcm.c43
-rw-r--r--sound/soc/mediatek/mt8192/mt8192-afe-pcm.c27
-rw-r--r--sound/soc/mediatek/mt8195/Makefile15
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-clk.c441
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-clk.h109
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-common.h158
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-pcm.c3281
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-audsys-clk.c214
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-audsys-clk.h15
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h93
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-dai-adda.c830
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-dai-etdm.c2639
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-dai-pcm.c389
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c1087
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-reg.h2796
-rw-r--r--sound/soc/pxa/pxa-ssp.c16
-rw-r--r--sound/soc/qcom/apq8016_sbc.c17
-rw-r--r--sound/soc/qcom/qdsp6/q6adm.c2
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.c2
-rw-r--r--sound/soc/rockchip/Kconfig14
-rw-r--r--sound/soc/samsung/aries_wm8994.c2
-rw-r--r--sound/soc/samsung/arndale.c4
-rw-r--r--sound/soc/samsung/h1940_uda1380.c2
-rw-r--r--sound/soc/samsung/littlemill.c2
-rw-r--r--sound/soc/samsung/midas_wm1811.c2
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c4
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c2
-rw-r--r--sound/soc/samsung/smartq_wm8987.c2
-rw-r--r--sound/soc/samsung/smdk_wm8580.c2
-rw-r--r--sound/soc/samsung/smdk_wm8994.c2
-rw-r--r--sound/soc/samsung/smdk_wm8994pcm.c2
-rw-r--r--sound/soc/samsung/tm2_wm5110.c6
-rw-r--r--sound/soc/samsung/tobermory.c2
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/Makefile4
-rw-r--r--sound/soc/sh/rcar/adg.c12
-rw-r--r--sound/soc/sh/rcar/core.c6
-rw-r--r--sound/soc/sh/rcar/dma.c2
-rw-r--r--sound/soc/sh/rcar/ssi.c6
-rw-r--r--sound/soc/sh/rz-ssi.c1074
-rw-r--r--sound/soc/soc-ac97.c14
-rw-r--r--sound/soc/soc-component.c4
-rw-r--r--sound/soc/soc-core.c38
-rw-r--r--sound/soc/soc-dai.c18
-rw-r--r--sound/soc/soc-dapm.c65
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c9
-rw-r--r--sound/soc/soc-jack.c15
-rw-r--r--sound/soc/soc-ops.c21
-rw-r--r--sound/soc/soc-pcm.c22
-rw-r--r--sound/soc/soc-topology.c23
-rw-r--r--sound/soc/sof/intel/Kconfig10
-rw-r--r--sound/soc/sof/intel/cnl.c6
-rw-r--r--sound/soc/sof/intel/hda-pcm.c16
-rw-r--r--sound/soc/sof/intel/hda-stream.c11
-rw-r--r--sound/soc/sof/intel/hda.c39
-rw-r--r--sound/soc/sof/intel/hda.h8
-rw-r--r--sound/soc/sof/intel/icl.c3
-rw-r--r--sound/soc/sof/intel/pci-tng.c1
-rw-r--r--sound/soc/sof/intel/shim.h3
-rw-r--r--sound/soc/sof/intel/tgl.c12
-rw-r--r--sound/soc/sof/sof-audio.c42
-rw-r--r--sound/soc/sof/sof-pci-dev.c9
-rw-r--r--sound/soc/tegra/tegra30_ahub.c6
-rw-r--r--sound/soc/tegra/tegra30_i2s.c8
-rw-r--r--sound/soc/ti/Kconfig1
-rw-r--r--sound/soc/ti/ams-delta.c11
-rw-r--r--sound/soc/ti/davinci-mcasp.c176
-rw-r--r--sound/soc/ti/j721e-evm.c30
-rw-r--r--sound/soc/ti/omap-abe-twl6040.c5
-rw-r--r--sound/soc/uniphier/aio-cpu.c4
-rw-r--r--sound/sparc/amd7930.c14
-rw-r--r--sound/sparc/cs4231.c10
-rw-r--r--sound/sparc/dbri.c11
-rw-r--r--sound/synth/emux/emux.c3
-rw-r--r--sound/synth/emux/emux_effect.c13
-rw-r--r--sound/synth/emux/emux_hwdep.c6
-rw-r--r--sound/synth/emux/emux_nrpn.c2
-rw-r--r--sound/synth/emux/soundfont.c46
-rw-r--r--sound/usb/card.h11
-rw-r--r--sound/usb/clock.c305
-rw-r--r--sound/usb/endpoint.c5
-rw-r--r--sound/usb/endpoint.h1
-rw-r--r--sound/usb/format.c2
-rw-r--r--sound/usb/media.c2
-rw-r--r--sound/usb/mixer.c8
-rw-r--r--sound/usb/mixer.h1
-rw-r--r--sound/usb/mixer_quirks.c6
-rw-r--r--sound/usb/mixer_s1810c.c2
-rw-r--r--sound/usb/mixer_scarlett.c2
-rw-r--r--sound/usb/mixer_scarlett_gen2.c3231
-rw-r--r--sound/usb/pcm.c214
-rw-r--r--sound/usb/pcm.h3
-rw-r--r--sound/usb/quirks-table.h70
-rw-r--r--sound/usb/usx2y/us122l.c63
-rw-r--r--sound/usb/usx2y/us122l.h2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c135
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.h2
-rw-r--r--sound/usb/usx2y/usb_stream.c82
-rw-r--r--sound/usb/usx2y/usb_stream.h23
-rw-r--r--sound/usb/usx2y/usbus428ctldefs.h104
-rw-r--r--sound/usb/usx2y/usbusx2y.c389
-rw-r--r--sound/usb/usx2y/usbusx2y.h65
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c684
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c627
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.h4
-rw-r--r--sound/x86/intel_hdmi_audio.c6
-rw-r--r--sound/x86/intel_hdmi_audio.h2
456 files changed, 28893 insertions, 7171 deletions
diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
index d9077e91382b..6ddf646cda65 100644
--- a/sound/ac97/bus.c
+++ b/sound/ac97/bus.c
@@ -520,7 +520,7 @@ static int ac97_bus_remove(struct device *dev)
struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
int ret;
- ret = pm_runtime_get_sync(dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 1c8e8131a716..a9e502a6cdeb 100644
--- a/sound/aoa/soundbus/i2sbus/pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
@@ -918,10 +918,8 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
}
cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
- if (!cii) {
- printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
+ if (!cii)
return -ENOMEM;
- }
/* use the private data to point to the codec info */
cii->sdev = soundbus_dev_get(dev);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 6322e6392594..a67e6685b00c 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -47,9 +47,7 @@ static unsigned short pxa2xx_ac97_legacy_read(struct snd_ac97 *ac97,
static void pxa2xx_ac97_legacy_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val)
{
- int __always_unused ret;
-
- ret = pxa2xx_ac97_write(ac97->num, reg, val);
+ pxa2xx_ac97_write(ac97->num, reg, val);
}
static const struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
diff --git a/sound/core/control.c b/sound/core/control.c
index 498e3701514a..a25c0d64d104 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -995,7 +995,10 @@ static int __snd_ctl_elem_info(struct snd_card *card,
#ifdef CONFIG_SND_DEBUG
info->access = 0;
#endif
- result = kctl->info(kctl, info);
+ result = snd_power_ref_and_wait(card);
+ if (!result)
+ result = kctl->info(kctl, info);
+ snd_power_unref(card);
if (result >= 0) {
snd_BUG_ON(info->access);
index_offset = snd_ctl_get_ioff(kctl, &info->id);
@@ -1042,9 +1045,6 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
- result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (result < 0)
- return result;
result = snd_ctl_elem_info(ctl, &info);
if (result < 0)
return result;
@@ -1088,7 +1088,10 @@ static int snd_ctl_elem_read(struct snd_card *card,
if (!snd_ctl_skip_validation(&info))
fill_remaining_elem_value(control, &info, pattern);
- ret = kctl->get(kctl, control);
+ ret = snd_power_ref_and_wait(card);
+ if (!ret)
+ ret = kctl->get(kctl, control);
+ snd_power_unref(card);
if (ret < 0)
return ret;
if (!snd_ctl_skip_validation(&info) &&
@@ -1113,10 +1116,6 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
if (IS_ERR(control))
return PTR_ERR(control);
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result < 0)
- goto error;
-
down_read(&card->controls_rwsem);
result = snd_ctl_elem_read(card, control);
up_read(&card->controls_rwsem);
@@ -1154,7 +1153,10 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
}
snd_ctl_build_ioff(&control->id, kctl, index_offset);
- result = kctl->put(kctl, control);
+ result = snd_power_ref_and_wait(card);
+ if (!result)
+ result = kctl->put(kctl, control);
+ snd_power_unref(card);
if (result < 0) {
up_write(&card->controls_rwsem);
return result;
@@ -1183,10 +1185,6 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
return PTR_ERR(control);
card = file->card;
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result < 0)
- goto error;
-
result = snd_ctl_elem_write(card, file, control);
if (result < 0)
goto error;
@@ -1669,7 +1667,7 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
{SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND},
};
struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
- int i;
+ int i, ret;
/* Check support of the request for this element. */
for (i = 0; i < ARRAY_SIZE(pairs); ++i) {
@@ -1687,7 +1685,11 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
vd->owner != NULL && vd->owner != file)
return -EPERM;
- return kctl->tlv.c(kctl, op_flag, size, buf);
+ ret = snd_power_ref_and_wait(file->card);
+ if (!ret)
+ ret = kctl->tlv.c(kctl, op_flag, size, buf);
+ snd_power_unref(file->card);
+ return ret;
}
static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id,
@@ -1815,11 +1817,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case SNDRV_CTL_IOCTL_POWER:
return -ENOPROTOOPT;
case SNDRV_CTL_IOCTL_POWER_STATE:
-#ifdef CONFIG_PM
- return put_user(card->power_state, ip) ? -EFAULT : 0;
-#else
return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
-#endif
}
down_read(&snd_ioctl_rwsem);
list_for_each_entry(p, &snd_control_ioctls, list) {
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 1d708aab9c98..470dabc60aa0 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -96,9 +96,6 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
goto error;
- err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (err < 0)
- goto error;
err = snd_ctl_elem_info(ctl, data);
if (err < 0)
goto error;
@@ -187,7 +184,10 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
return -ENOMEM;
}
info->id = *id;
- err = kctl->info(kctl, info);
+ err = snd_power_ref_and_wait(card);
+ if (!err)
+ err = kctl->info(kctl, info);
+ snd_power_unref(card);
up_read(&card->controls_rwsem);
if (err >= 0) {
err = info->type;
@@ -298,9 +298,6 @@ static int ctl_elem_read_user(struct snd_card *card,
if (err < 0)
goto error;
- err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err < 0)
- goto error;
err = snd_ctl_elem_read(card, data);
if (err < 0)
goto error;
@@ -326,9 +323,6 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
if (err < 0)
goto error;
- err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err < 0)
- goto error;
err = snd_ctl_elem_write(card, file, data);
if (err < 0)
goto error;
diff --git a/sound/core/control_led.c b/sound/core/control_led.c
index a90e31dbde61..764058cc345d 100644
--- a/sound/core/control_led.c
+++ b/sound/core/control_led.c
@@ -393,11 +393,11 @@ static void snd_ctl_led_dev_release(struct device *dev)
* sysfs
*/
-static ssize_t show_mode(struct device *dev,
+static ssize_t mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
- const char *str;
+ const char *str = NULL;
switch (led->mode) {
case MODE_FOLLOW_MUTE: str = "follow-mute"; break;
@@ -408,7 +408,8 @@ static ssize_t show_mode(struct device *dev,
return sprintf(buf, "%s\n", str);
}
-static ssize_t store_mode(struct device *dev, struct device_attribute *attr,
+static ssize_t mode_store(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
@@ -437,7 +438,7 @@ static ssize_t store_mode(struct device *dev, struct device_attribute *attr,
return count;
}
-static ssize_t show_brightness(struct device *dev,
+static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
@@ -445,8 +446,8 @@ static ssize_t show_brightness(struct device *dev,
return sprintf(buf, "%u\n", ledtrig_audio_get(led->trigger_type));
}
-static DEVICE_ATTR(mode, 0644, show_mode, store_mode);
-static DEVICE_ATTR(brightness, 0444, show_brightness, NULL);
+static DEVICE_ATTR_RW(mode);
+static DEVICE_ATTR_RO(brightness);
static struct attribute *snd_ctl_led_dev_attrs[] = {
&dev_attr_mode.attr,
@@ -580,22 +581,25 @@ static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, si
return count;
}
-static ssize_t parse_attach(struct device *dev, struct device_attribute *attr,
+static ssize_t attach_store(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
return set_led_id(led_card, buf, count, true);
}
-static ssize_t parse_detach(struct device *dev, struct device_attribute *attr,
+static ssize_t detach_store(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
return set_led_id(led_card, buf, count, false);
}
-static ssize_t ctl_reset(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t reset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
int err;
@@ -608,8 +612,8 @@ static ssize_t ctl_reset(struct device *dev, struct device_attribute *attr,
return count;
}
-static ssize_t ctl_list(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t list_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
struct snd_card *card;
@@ -642,10 +646,10 @@ static ssize_t ctl_list(struct device *dev,
return buf2 - buf;
}
-static DEVICE_ATTR(attach, 0200, NULL, parse_attach);
-static DEVICE_ATTR(detach, 0200, NULL, parse_detach);
-static DEVICE_ATTR(reset, 0200, NULL, ctl_reset);
-static DEVICE_ATTR(list, 0444, ctl_list, NULL);
+static DEVICE_ATTR_WO(attach);
+static DEVICE_ATTR_WO(detach);
+static DEVICE_ATTR_WO(reset);
+static DEVICE_ATTR_RO(list);
static struct attribute *snd_ctl_led_card_attrs[] = {
&dev_attr_attach.attr,
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 264b8ea64bc2..e95fa275c289 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -195,7 +195,8 @@ static int snd_hwdep_dsp_status(struct snd_hwdep *hw,
return -ENXIO;
memset(&info, 0, sizeof(info));
info.dsp_loaded = hw->dsp_loaded;
- if ((err = hw->ops.dsp_status(hw, &info)) < 0)
+ err = hw->ops.dsp_status(hw, &info);
+ if (err < 0)
return err;
if (copy_to_user(_info, &info, sizeof(info)))
return -EFAULT;
@@ -500,7 +501,8 @@ static void __init snd_hwdep_proc_init(void)
{
struct snd_info_entry *entry;
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
+ entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL);
+ if (entry) {
entry->c.text.read = snd_hwdep_proc_read;
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 83900485dd8c..1ba887c7954e 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -31,7 +31,8 @@ int snd_oss_info_register(int dev, int num, char *string)
return -ENXIO;
mutex_lock(&strings);
if (string == NULL) {
- if ((x = snd_sndstat_strings[num][dev]) != NULL) {
+ x = snd_sndstat_strings[num][dev];
+ if (x) {
kfree(x);
x = NULL;
}
diff --git a/sound/core/init.c b/sound/core/init.c
index ef41f5b3a240..1490568efdb0 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -220,6 +220,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
mutex_init(&card->memory_mutex);
#ifdef CONFIG_PM
init_waitqueue_head(&card->power_sleep);
+ init_waitqueue_head(&card->power_ref_sleep);
+ atomic_set(&card->power_ref, 0);
#endif
init_waitqueue_head(&card->remove_sleep);
card->sync_irq = -1;
@@ -442,6 +444,7 @@ int snd_card_disconnect(struct snd_card *card)
#ifdef CONFIG_PM
wake_up(&card->power_sleep);
+ snd_power_sync_ref(card);
#endif
return 0;
}
@@ -662,17 +665,15 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
}
EXPORT_SYMBOL(snd_card_set_id);
-static ssize_t
-card_id_show_attr(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct snd_card *card = container_of(dev, struct snd_card, card_dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", card->id);
}
-static ssize_t
-card_id_store_attr(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t id_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct snd_card *card = container_of(dev, struct snd_card, card_dev);
char buf1[sizeof(card->id)];
@@ -700,17 +701,16 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR(id, 0644, card_id_show_attr, card_id_store_attr);
+static DEVICE_ATTR_RW(id);
-static ssize_t
-card_number_show_attr(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t number_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct snd_card *card = container_of(dev, struct snd_card, card_dev);
return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
}
-static DEVICE_ATTR(number, 0444, card_number_show_attr, NULL);
+static DEVICE_ATTR_RO(number);
static struct attribute *card_dev_attrs[] = {
&dev_attr_id.attr,
@@ -770,7 +770,8 @@ int snd_card_register(struct snd_card *card)
card->registered = true;
}
- if ((err = snd_device_register_all(card)) < 0)
+ err = snd_device_register_all(card);
+ if (err < 0)
return err;
mutex_lock(&snd_card_mutex);
if (snd_cards[card->number]) {
@@ -813,7 +814,8 @@ static void snd_card_info_read(struct snd_info_entry *entry,
for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL) {
+ card = snd_cards[idx];
+ if (card) {
count++;
snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
idx,
@@ -837,7 +839,8 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL) {
+ card = snd_cards[idx];
+ if (card) {
count++;
snd_iprintf(buffer, "%s\n", card->longname);
}
@@ -859,7 +862,8 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
for (idx = 0; idx < SNDRV_CARDS; idx++) {
mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL)
+ card = snd_cards[idx];
+ if (card)
snd_iprintf(buffer, "%2i %s\n",
idx, card->module->name);
mutex_unlock(&snd_card_mutex);
@@ -1002,21 +1006,28 @@ EXPORT_SYMBOL(snd_card_file_remove);
#ifdef CONFIG_PM
/**
- * snd_power_wait - wait until the power-state is changed.
- * @card: soundcard structure
- * @power_state: expected power state
+ * snd_power_ref_and_wait - wait until the card gets powered up
+ * @card: soundcard structure
+ *
+ * Take the power_ref reference count of the given card, and
+ * wait until the card gets powered up to SNDRV_CTL_POWER_D0 state.
+ * The refcount is down again while sleeping until power-up, hence this
+ * function can be used for syncing the floating control ops accesses,
+ * typically around calling control ops.
*
- * Waits until the power-state is changed.
+ * The caller needs to pull down the refcount via snd_power_unref() later
+ * no matter whether the error is returned from this function or not.
*
- * Return: Zero if successful, or a negative error code.
+ * Return: Zero if successful, or a negative error code.
*/
-int snd_power_wait(struct snd_card *card, unsigned int power_state)
+int snd_power_ref_and_wait(struct snd_card *card)
{
wait_queue_entry_t wait;
int result = 0;
+ snd_power_ref(card);
/* fastpath */
- if (snd_power_get_state(card) == power_state)
+ if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0)
return 0;
init_waitqueue_entry(&wait, current);
add_wait_queue(&card->power_sleep, &wait);
@@ -1025,13 +1036,33 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
result = -ENODEV;
break;
}
- if (snd_power_get_state(card) == power_state)
+ if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0)
break;
+ snd_power_unref(card);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(30 * HZ);
+ snd_power_ref(card);
}
remove_wait_queue(&card->power_sleep, &wait);
return result;
}
+EXPORT_SYMBOL_GPL(snd_power_ref_and_wait);
+
+/**
+ * snd_power_wait - wait until the card gets powered up (old form)
+ * @card: soundcard structure
+ *
+ * Wait until the card gets powered up to SNDRV_CTL_POWER_D0 state.
+ *
+ * Return: Zero if successful, or a negative error code.
+ */
+int snd_power_wait(struct snd_card *card)
+{
+ int ret;
+
+ ret = snd_power_ref_and_wait(card);
+ snd_power_unref(card);
+ return ret;
+}
EXPORT_SYMBOL(snd_power_wait);
#endif /* CONFIG_PM */
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 966bef5acc75..83b79edfa52d 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -15,99 +15,27 @@
#include <asm/set_memory.h>
#endif
#include <sound/memalloc.h>
+#include "memalloc_local.h"
-/*
- *
- * Bus-specific memory allocators
- *
- */
-
-#ifdef CONFIG_HAS_DMA
-/* allocate the coherent DMA pages */
-static void snd_malloc_dev_pages(struct snd_dma_buffer *dmab, size_t size)
-{
- gfp_t gfp_flags;
+static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab);
- gfp_flags = GFP_KERNEL
- | __GFP_COMP /* compound page lets parts be mapped */
- | __GFP_NORETRY /* don't trigger OOM-killer */
- | __GFP_NOWARN; /* no stack trace print - this call is non-critical */
- dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr,
- gfp_flags);
-#ifdef CONFIG_X86
- if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
- set_memory_wc((unsigned long)dmab->area,
- PAGE_ALIGN(size) >> PAGE_SHIFT);
-#endif
-}
-
-/* free the coherent DMA pages */
-static void snd_free_dev_pages(struct snd_dma_buffer *dmab)
-{
-#ifdef CONFIG_X86
- if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
- set_memory_wb((unsigned long)dmab->area,
- PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT);
-#endif
- dma_free_coherent(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
-}
-
-#ifdef CONFIG_GENERIC_ALLOCATOR
-/**
- * snd_malloc_dev_iram - allocate memory from on-chip internal ram
- * @dmab: buffer allocation record to store the allocated data
- * @size: number of bytes to allocate from the iram
- *
- * This function requires iram phandle provided via of_node
- */
-static void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size)
+/* a cast to gfp flag from the dev pointer; for CONTINUOUS and VMALLOC types */
+static inline gfp_t snd_mem_get_gfp_flags(const struct snd_dma_buffer *dmab,
+ gfp_t default_gfp)
{
- struct device *dev = dmab->dev.dev;
- struct gen_pool *pool = NULL;
-
- dmab->area = NULL;
- dmab->addr = 0;
-
- if (dev->of_node)
- pool = of_gen_pool_get(dev->of_node, "iram", 0);
-
- if (!pool)
- return;
-
- /* Assign the pool into private_data field */
- dmab->private_data = pool;
-
- dmab->area = gen_pool_dma_alloc_align(pool, size, &dmab->addr,
- PAGE_SIZE);
+ if (!dmab->dev.dev)
+ return default_gfp;
+ else
+ return (__force gfp_t)(unsigned long)dmab->dev.dev;
}
-/**
- * snd_free_dev_iram - free allocated specific memory from on-chip internal ram
- * @dmab: buffer allocation record to store the allocated data
- */
-static void snd_free_dev_iram(struct snd_dma_buffer *dmab)
+static int __snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
{
- struct gen_pool *pool = dmab->private_data;
-
- if (pool && dmab->area)
- gen_pool_free(pool, (unsigned long)dmab->area, dmab->bytes);
-}
-#endif /* CONFIG_GENERIC_ALLOCATOR */
-#endif /* CONFIG_HAS_DMA */
-
-/*
- *
- * ALSA generic memory management
- *
- */
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-static inline gfp_t snd_mem_get_gfp_flags(const struct device *dev,
- gfp_t default_gfp)
-{
- if (!dev)
- return default_gfp;
- else
- return (__force gfp_t)(unsigned long)dev;
+ if (WARN_ON_ONCE(!ops || !ops->alloc))
+ return -EINVAL;
+ return ops->alloc(dmab, size);
}
/**
@@ -126,7 +54,7 @@ static inline gfp_t snd_mem_get_gfp_flags(const struct device *dev,
int snd_dma_alloc_pages(int type, struct device *device, size_t size,
struct snd_dma_buffer *dmab)
{
- gfp_t gfp;
+ int err;
if (WARN_ON(!size))
return -ENXIO;
@@ -140,43 +68,10 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
dmab->area = NULL;
dmab->addr = 0;
dmab->private_data = NULL;
- switch (type) {
- case SNDRV_DMA_TYPE_CONTINUOUS:
- gfp = snd_mem_get_gfp_flags(device, GFP_KERNEL);
- dmab->area = alloc_pages_exact(size, gfp);
- break;
- case SNDRV_DMA_TYPE_VMALLOC:
- gfp = snd_mem_get_gfp_flags(device, GFP_KERNEL | __GFP_HIGHMEM);
- dmab->area = __vmalloc(size, gfp);
- break;
-#ifdef CONFIG_HAS_DMA
-#ifdef CONFIG_GENERIC_ALLOCATOR
- case SNDRV_DMA_TYPE_DEV_IRAM:
- snd_malloc_dev_iram(dmab, size);
- if (dmab->area)
- break;
- /* Internal memory might have limited size and no enough space,
- * so if we fail to malloc, try to fetch memory traditionally.
- */
- dmab->dev.type = SNDRV_DMA_TYPE_DEV;
- fallthrough;
-#endif /* CONFIG_GENERIC_ALLOCATOR */
- case SNDRV_DMA_TYPE_DEV:
- case SNDRV_DMA_TYPE_DEV_UC:
- snd_malloc_dev_pages(dmab, size);
- break;
-#endif
-#ifdef CONFIG_SND_DMA_SGBUF
- case SNDRV_DMA_TYPE_DEV_SG:
- case SNDRV_DMA_TYPE_DEV_UC_SG:
- snd_malloc_sgbuf_pages(device, size, dmab, NULL);
- break;
-#endif
- default:
- pr_err("snd-malloc: invalid device type %d\n", type);
- return -ENXIO;
- }
- if (! dmab->area)
+ err = __snd_dma_alloc_pages(dmab, size);
+ if (err < 0)
+ return err;
+ if (!dmab->area)
return -ENOMEM;
dmab->bytes = size;
return 0;
@@ -217,7 +112,6 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
}
EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
-
/**
* snd_dma_free_pages - release the allocated buffer
* @dmab: the buffer allocation record to release
@@ -226,32 +120,288 @@ EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
*/
void snd_dma_free_pages(struct snd_dma_buffer *dmab)
{
- switch (dmab->dev.type) {
- case SNDRV_DMA_TYPE_CONTINUOUS:
- free_pages_exact(dmab->area, dmab->bytes);
- break;
- case SNDRV_DMA_TYPE_VMALLOC:
- vfree(dmab->area);
- break;
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
+
+ if (ops && ops->free)
+ ops->free(dmab);
+}
+EXPORT_SYMBOL(snd_dma_free_pages);
+
+/**
+ * snd_dma_buffer_mmap - perform mmap of the given DMA buffer
+ * @dmab: buffer allocation information
+ * @area: VM area information
+ */
+int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
+
+ if (ops && ops->mmap)
+ return ops->mmap(dmab, area);
+ else
+ return -ENOENT;
+}
+EXPORT_SYMBOL(snd_dma_buffer_mmap);
+
+/**
+ * snd_sgbuf_get_addr - return the physical address at the corresponding offset
+ * @dmab: buffer allocation information
+ * @offset: offset in the ring buffer
+ */
+dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset)
+{
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
+
+ if (ops && ops->get_addr)
+ return ops->get_addr(dmab, offset);
+ else
+ return dmab->addr + offset;
+}
+EXPORT_SYMBOL(snd_sgbuf_get_addr);
+
+/**
+ * snd_sgbuf_get_page - return the physical page at the corresponding offset
+ * @dmab: buffer allocation information
+ * @offset: offset in the ring buffer
+ */
+struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset)
+{
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
+
+ if (ops && ops->get_page)
+ return ops->get_page(dmab, offset);
+ else
+ return virt_to_page(dmab->area + offset);
+}
+EXPORT_SYMBOL(snd_sgbuf_get_page);
+
+/**
+ * snd_sgbuf_get_chunk_size - compute the max chunk size with continuous pages
+ * on sg-buffer
+ * @dmab: buffer allocation information
+ * @ofs: offset in the ring buffer
+ * @size: the requested size
+ */
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+ unsigned int ofs, unsigned int size)
+{
+ const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
+
+ if (ops && ops->get_chunk_size)
+ return ops->get_chunk_size(dmab, ofs, size);
+ else
+ return size;
+}
+EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
+
+/*
+ * Continuous pages allocator
+ */
+static int snd_dma_continuous_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+ gfp_t gfp = snd_mem_get_gfp_flags(dmab, GFP_KERNEL);
+
+ dmab->area = alloc_pages_exact(size, gfp);
+ return 0;
+}
+
+static void snd_dma_continuous_free(struct snd_dma_buffer *dmab)
+{
+ free_pages_exact(dmab->area, dmab->bytes);
+}
+
+static int snd_dma_continuous_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ return remap_pfn_range(area, area->vm_start,
+ dmab->addr >> PAGE_SHIFT,
+ area->vm_end - area->vm_start,
+ area->vm_page_prot);
+}
+
+static const struct snd_malloc_ops snd_dma_continuous_ops = {
+ .alloc = snd_dma_continuous_alloc,
+ .free = snd_dma_continuous_free,
+ .mmap = snd_dma_continuous_mmap,
+};
+
+/*
+ * VMALLOC allocator
+ */
+static int snd_dma_vmalloc_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+ gfp_t gfp = snd_mem_get_gfp_flags(dmab, GFP_KERNEL | __GFP_HIGHMEM);
+
+ dmab->area = __vmalloc(size, gfp);
+ return 0;
+}
+
+static void snd_dma_vmalloc_free(struct snd_dma_buffer *dmab)
+{
+ vfree(dmab->area);
+}
+
+static int snd_dma_vmalloc_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ return remap_vmalloc_range(area, dmab->area, 0);
+}
+
+static dma_addr_t snd_dma_vmalloc_get_addr(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ return page_to_phys(vmalloc_to_page(dmab->area + offset)) +
+ offset % PAGE_SIZE;
+}
+
+static struct page *snd_dma_vmalloc_get_page(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ return vmalloc_to_page(dmab->area + offset);
+}
+
+static unsigned int
+snd_dma_vmalloc_get_chunk_size(struct snd_dma_buffer *dmab,
+ unsigned int ofs, unsigned int size)
+{
+ ofs %= PAGE_SIZE;
+ size += ofs;
+ if (size > PAGE_SIZE)
+ size = PAGE_SIZE;
+ return size - ofs;
+}
+
+static const struct snd_malloc_ops snd_dma_vmalloc_ops = {
+ .alloc = snd_dma_vmalloc_alloc,
+ .free = snd_dma_vmalloc_free,
+ .mmap = snd_dma_vmalloc_mmap,
+ .get_addr = snd_dma_vmalloc_get_addr,
+ .get_page = snd_dma_vmalloc_get_page,
+ .get_chunk_size = snd_dma_vmalloc_get_chunk_size,
+};
+
#ifdef CONFIG_HAS_DMA
+/*
+ * IRAM allocator
+ */
#ifdef CONFIG_GENERIC_ALLOCATOR
- case SNDRV_DMA_TYPE_DEV_IRAM:
- snd_free_dev_iram(dmab);
- break;
+static int snd_dma_iram_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+ struct device *dev = dmab->dev.dev;
+ struct gen_pool *pool;
+
+ if (dev->of_node) {
+ pool = of_gen_pool_get(dev->of_node, "iram", 0);
+ /* Assign the pool into private_data field */
+ dmab->private_data = pool;
+
+ dmab->area = gen_pool_dma_alloc_align(pool, size, &dmab->addr,
+ PAGE_SIZE);
+ if (dmab->area)
+ return 0;
+ }
+
+ /* Internal memory might have limited size and no enough space,
+ * so if we fail to malloc, try to fetch memory traditionally.
+ */
+ dmab->dev.type = SNDRV_DMA_TYPE_DEV;
+ return __snd_dma_alloc_pages(dmab, size);
+}
+
+static void snd_dma_iram_free(struct snd_dma_buffer *dmab)
+{
+ struct gen_pool *pool = dmab->private_data;
+
+ if (pool && dmab->area)
+ gen_pool_free(pool, (unsigned long)dmab->area, dmab->bytes);
+}
+
+static int snd_dma_iram_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
+ return remap_pfn_range(area, area->vm_start,
+ dmab->addr >> PAGE_SHIFT,
+ area->vm_end - area->vm_start,
+ area->vm_page_prot);
+}
+
+static const struct snd_malloc_ops snd_dma_iram_ops = {
+ .alloc = snd_dma_iram_alloc,
+ .free = snd_dma_iram_free,
+ .mmap = snd_dma_iram_mmap,
+};
#endif /* CONFIG_GENERIC_ALLOCATOR */
- case SNDRV_DMA_TYPE_DEV:
- case SNDRV_DMA_TYPE_DEV_UC:
- snd_free_dev_pages(dmab);
- break;
+
+/*
+ * Coherent device pages allocator
+ */
+static int snd_dma_dev_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+ gfp_t gfp_flags;
+
+ gfp_flags = GFP_KERNEL
+ | __GFP_COMP /* compound page lets parts be mapped */
+ | __GFP_NORETRY /* don't trigger OOM-killer */
+ | __GFP_NOWARN; /* no stack trace print - this call is non-critical */
+ dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr,
+ gfp_flags);
+#ifdef CONFIG_X86
+ if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
+ set_memory_wc((unsigned long)dmab->area,
+ PAGE_ALIGN(size) >> PAGE_SHIFT);
#endif
+ return 0;
+}
+
+static void snd_dma_dev_free(struct snd_dma_buffer *dmab)
+{
+#ifdef CONFIG_X86
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
+ set_memory_wb((unsigned long)dmab->area,
+ PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT);
+#endif
+ dma_free_coherent(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
+}
+
+static int snd_dma_dev_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ return dma_mmap_coherent(dmab->dev.dev, area,
+ dmab->area, dmab->addr, dmab->bytes);
+}
+
+static const struct snd_malloc_ops snd_dma_dev_ops = {
+ .alloc = snd_dma_dev_alloc,
+ .free = snd_dma_dev_free,
+ .mmap = snd_dma_dev_mmap,
+};
+#endif /* CONFIG_HAS_DMA */
+
+/*
+ * Entry points
+ */
+static const struct snd_malloc_ops *dma_ops[] = {
+ [SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops,
+ [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops,
+#ifdef CONFIG_HAS_DMA
+ [SNDRV_DMA_TYPE_DEV] = &snd_dma_dev_ops,
+ [SNDRV_DMA_TYPE_DEV_UC] = &snd_dma_dev_ops,
+#ifdef CONFIG_GENERIC_ALLOCATOR
+ [SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops,
+#endif /* CONFIG_GENERIC_ALLOCATOR */
+#endif /* CONFIG_HAS_DMA */
#ifdef CONFIG_SND_DMA_SGBUF
- case SNDRV_DMA_TYPE_DEV_SG:
- case SNDRV_DMA_TYPE_DEV_UC_SG:
- snd_free_sgbuf_pages(dmab);
- break;
+ [SNDRV_DMA_TYPE_DEV_SG] = &snd_dma_sg_ops,
+ [SNDRV_DMA_TYPE_DEV_UC_SG] = &snd_dma_sg_ops,
#endif
- default:
- pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type);
- }
+};
+
+static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)
+{
+ if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN ||
+ dmab->dev.type >= ARRAY_SIZE(dma_ops)))
+ return NULL;
+ return dma_ops[dmab->dev.type];
}
-EXPORT_SYMBOL(snd_dma_free_pages);
diff --git a/sound/core/memalloc_local.h b/sound/core/memalloc_local.h
new file mode 100644
index 000000000000..dbea7f2aed07
--- /dev/null
+++ b/sound/core/memalloc_local.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#ifndef __MEMALLOC_LOCAL_H
+#define __MEMALLOC_LOCAL_H
+
+struct snd_malloc_ops {
+ int (*alloc)(struct snd_dma_buffer *dmab, size_t size);
+ void (*free)(struct snd_dma_buffer *dmab);
+ dma_addr_t (*get_addr)(struct snd_dma_buffer *dmab, size_t offset);
+ struct page *(*get_page)(struct snd_dma_buffer *dmab, size_t offset);
+ unsigned int (*get_chunk_size)(struct snd_dma_buffer *dmab,
+ unsigned int ofs, unsigned int size);
+ int (*mmap)(struct snd_dma_buffer *dmab, struct vm_area_struct *area);
+};
+
+#ifdef CONFIG_SND_DMA_SGBUF
+extern const struct snd_malloc_ops snd_dma_sg_ops;
+#endif
+
+#endif /* __MEMALLOC_LOCAL_H */
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index bec928327478..6a5abdd4271b 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -185,7 +185,8 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
int err;
unsigned int index;
- if ((err = mixer->get_recsrc(fmixer, &index)) < 0)
+ err = mixer->get_recsrc(fmixer, &index);
+ if (err < 0)
return err;
result = 1 << index;
} else {
@@ -517,7 +518,8 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
+ kctl = snd_ctl_find_numid(card, numid);
+ if (!kctl) {
up_read(&card->controls_rwsem);
return;
}
@@ -555,7 +557,8 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
+ kctl = snd_ctl_find_numid(card, numid);
+ if (!kctl) {
up_read(&card->controls_rwsem);
return;
}
@@ -620,7 +623,8 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
+ kctl = snd_ctl_find_numid(card, numid);
+ if (!kctl) {
up_read(&card->controls_rwsem);
return;
}
@@ -636,7 +640,8 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
if (uinfo->count > 1)
uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
- if ((res = kctl->put(kctl, uctl)) < 0)
+ res = kctl->put(kctl, uctl);
+ if (res < 0)
goto __unalloc;
if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
@@ -661,7 +666,8 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
+ kctl = snd_ctl_find_numid(card, numid);
+ if (!kctl) {
up_read(&card->controls_rwsem);
return;
}
@@ -681,7 +687,8 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
} else {
uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
}
- if ((res = kctl->put(kctl, uctl)) < 0)
+ res = kctl->put(kctl, uctl);
+ if (res < 0)
goto __unalloc;
if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
@@ -809,9 +816,11 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
err = -ENOENT;
goto __unlock;
}
- if ((err = kctl->info(kctl, uinfo)) < 0)
+ err = kctl->info(kctl, uinfo);
+ if (err < 0)
goto __unlock;
- if ((err = kctl->get(kctl, uctl)) < 0)
+ err = kctl->get(kctl, uctl);
+ if (err < 0)
goto __unlock;
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
@@ -860,7 +869,8 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
err = -ENOENT;
goto __unlock;
}
- if ((err = kctl->info(kctl, uinfo)) < 0)
+ err = kctl->info(kctl, uinfo);
+ if (err < 0)
goto __unlock;
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
@@ -915,7 +925,8 @@ static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *sl
up_read(&card->controls_rwsem);
return -ENOMEM;
}
- if ((err = kcontrol->info(kcontrol, info)) < 0) {
+ err = kcontrol->info(kcontrol, info);
+ if (err < 0) {
up_read(&card->controls_rwsem);
kfree(info);
return err;
@@ -1036,7 +1047,10 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer,
if (snd_mixer_oss_build_test_all(mixer, ptr, &slot))
return 0;
down_read(&mixer->card->controls_rwsem);
- if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {
+ kctl = NULL;
+ if (!ptr->index)
+ kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
+ if (kctl) {
struct snd_ctl_elem_info *uinfo;
uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
@@ -1343,9 +1357,10 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
if (mixer == NULL)
return -ENOMEM;
mutex_init(&mixer->reg_mutex);
- if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
- card, 0,
- &snd_mixer_oss_f_ops, card)) < 0) {
+ err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
+ card, 0,
+ &snd_mixer_oss_f_ops, card);
+ if (err < 0) {
dev_err(card->dev,
"unable to register OSS mixer device %i:%i\n",
card->number, 0);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 86c39ee01aaa..82a818734a5f 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -955,9 +955,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
if (!direct) {
/* add necessary plugins */
snd_pcm_oss_plugin_clear(substream);
- if ((err = snd_pcm_plug_format_plugins(substream,
- params,
- sparams)) < 0) {
+ err = snd_pcm_plug_format_plugins(substream, params, sparams);
+ if (err < 0) {
pcm_dbg(substream->pcm,
"snd_pcm_plug_format_plugins failed: %i\n", err);
snd_pcm_oss_plugin_clear(substream);
@@ -965,7 +964,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
}
if (runtime->oss.plugin_first) {
struct snd_pcm_plugin *plugin;
- if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
+ err = snd_pcm_plugin_build_io(substream, sparams, &plugin);
+ if (err < 0) {
pcm_dbg(substream->pcm,
"snd_pcm_plugin_build_io failed: %i\n", err);
snd_pcm_oss_plugin_clear(substream);
@@ -1011,7 +1011,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
sw_params->silence_size = frames;
}
- if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
+ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params);
+ if (err < 0) {
pcm_dbg(substream->pcm, "SW_PARAMS failed: %i\n", err);
goto failure;
}
@@ -1573,7 +1574,8 @@ static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file)
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
if (substream != NULL) {
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ err = snd_pcm_oss_make_ready(substream);
+ if (err < 0)
return err;
snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL);
}
@@ -1645,7 +1647,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
runtime = substream->runtime;
if (atomic_read(&substream->mmap_count))
goto __direct;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ err = snd_pcm_oss_make_ready(substream);
+ if (err < 0)
return err;
atomic_inc(&runtime->oss.rw_ref);
if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
@@ -1711,7 +1714,8 @@ unlock:
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
if (substream != NULL) {
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ err = snd_pcm_oss_make_ready(substream);
+ if (err < 0)
return err;
runtime = substream->runtime;
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
@@ -1758,7 +1762,8 @@ static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
+ err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream);
+ if (err < 0)
return err;
return substream->runtime->oss.rate;
}
@@ -1795,7 +1800,8 @@ static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
+ err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream);
+ if (err < 0)
return err;
return substream->runtime->oss.channels;
}
@@ -1805,7 +1811,8 @@ static int snd_pcm_oss_get_block_size(struct snd_pcm_oss_file *pcm_oss_file)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
+ err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream);
+ if (err < 0)
return err;
return substream->runtime->oss.period_bytes;
}
@@ -1820,7 +1827,8 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
const struct snd_mask *format_mask;
int fmt;
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
+ err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream);
+ if (err < 0)
return err;
if (atomic_read(&substream->mmap_count))
direct = 1;
@@ -1890,7 +1898,8 @@ static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
+ err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream);
+ if (err < 0)
return err;
return substream->runtime->oss.format;
}
@@ -2050,11 +2059,13 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
if (psubstream) {
- if ((err = snd_pcm_oss_make_ready(psubstream)) < 0)
+ err = snd_pcm_oss_make_ready(psubstream);
+ if (err < 0)
return err;
}
if (csubstream) {
- if ((err = snd_pcm_oss_make_ready(csubstream)) < 0)
+ err = snd_pcm_oss_make_ready(csubstream);
+ if (err < 0)
return err;
}
if (psubstream) {
@@ -2141,7 +2152,8 @@ static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file)
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
if (substream == NULL)
return -EINVAL;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ err = snd_pcm_oss_make_ready(substream);
+ if (err < 0)
return err;
runtime = substream->runtime;
if (runtime->oss.params || runtime->oss.prepare)
@@ -2168,7 +2180,8 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
substream = pcm_oss_file->streams[stream];
if (substream == NULL)
return -EINVAL;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
+ err = snd_pcm_oss_make_ready(substream);
+ if (err < 0)
return err;
runtime = substream->runtime;
if (runtime->oss.params || runtime->oss.prepare) {
@@ -2239,9 +2252,11 @@ static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stre
return -EINVAL;
runtime = substream->runtime;
- if (runtime->oss.params &&
- (err = snd_pcm_oss_change_params(substream, false)) < 0)
- return err;
+ if (runtime->oss.params) {
+ err = snd_pcm_oss_change_params(substream, false);
+ if (err < 0)
+ return err;
+ }
info.fragsize = runtime->oss.period_bytes;
info.fragstotal = runtime->periods;
@@ -2601,7 +2616,8 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long
case SNDCTL_DSP_SPEED:
if (get_user(res, p))
return -EFAULT;
- if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
+ res = snd_pcm_oss_set_rate(pcm_oss_file, res);
+ if (res < 0)
return res;
return put_user(res, p);
case SOUND_PCM_READ_RATE:
@@ -2613,7 +2629,8 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long
if (get_user(res, p))
return -EFAULT;
res = res > 0 ? 2 : 1;
- if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
+ res = snd_pcm_oss_set_channels(pcm_oss_file, res);
+ if (res < 0)
return res;
return put_user(--res, p);
case SNDCTL_DSP_GETBLKSIZE:
@@ -2829,7 +2846,8 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
snd_pcm_state_t ostate;
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(csubstream);
- if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING ||
+ ostate = runtime->status->state;
+ if (ostate != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream))
mask |= EPOLLIN | EPOLLRDNORM;
snd_pcm_stream_unlock_irq(csubstream);
@@ -3043,7 +3061,8 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
struct snd_pcm_str *pstr = &pcm->streams[stream];
if (pstr->substream_count == 0)
continue;
- if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root);
+ if (entry) {
entry->content = SNDRV_INFO_CONTENT_TEXT;
entry->mode = S_IFREG | 0644;
entry->c.text.read = snd_pcm_oss_proc_read;
@@ -3191,7 +3210,8 @@ static int __init alsa_pcm_oss_init(void)
adsp_map[i] = 1;
}
}
- if ((err = snd_pcm_notify(&snd_pcm_oss_notify, 0)) < 0)
+ err = snd_pcm_notify(&snd_pcm_oss_notify, 0);
+ if (err < 0)
return err;
return 0;
}
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index d5ca161d588c..061ba06bc926 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -59,7 +59,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
} else {
format = &plugin->dst_format;
}
- if ((width = snd_pcm_format_physical_width(format->format)) < 0)
+ width = snd_pcm_format_physical_width(format->format);
+ if (width < 0)
return width;
size = frames * format->channels * width;
if (snd_BUG_ON(size % 8))
@@ -572,7 +573,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
}
v = plugin->buf_channels;
*channels = v;
- if ((width = snd_pcm_format_physical_width(format->format)) < 0)
+ width = snd_pcm_format_physical_width(format->format);
+ if (width < 0)
return width;
nchannels = format->channels;
if (snd_BUG_ON(plugin->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
@@ -600,16 +602,17 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
while (plugin) {
if (frames <= 0)
return frames;
- if ((next = plugin->next) != NULL) {
+ next = plugin->next;
+ if (next) {
snd_pcm_sframes_t frames1 = frames;
if (plugin->dst_frames) {
frames1 = plugin->dst_frames(plugin, frames);
if (frames1 <= 0)
return frames1;
}
- if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
+ err = next->client_channels(next, frames1, &dst_channels);
+ if (err < 0)
return err;
- }
if (err != frames1) {
frames = err;
if (plugin->src_frames) {
@@ -621,7 +624,8 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
} else
dst_channels = NULL;
pdprintf("write plugin: %s, %li\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
+ frames = plugin->transfer(plugin, src_channels, dst_channels, frames);
+ if (frames < 0)
return frames;
src_channels = dst_channels;
plugin = next;
@@ -643,16 +647,18 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
src_channels = NULL;
plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
- if ((next = plugin->next) != NULL) {
- if ((err = plugin->client_channels(plugin, frames, &dst_channels)) < 0) {
+ next = plugin->next;
+ if (next) {
+ err = plugin->client_channels(plugin, frames, &dst_channels);
+ if (err < 0)
return err;
- }
frames = err;
} else {
dst_channels = dst_channels_final;
}
pdprintf("read plugin: %s, %li\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
+ frames = plugin->transfer(plugin, src_channels, dst_channels, frames);
+ if (frames < 0)
return frames;
plugin = next;
src_channels = dst_channels;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index b163164a83ec..6fd3677685d7 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1004,7 +1004,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
substream->pstr->substream_opened--;
}
-static ssize_t show_pcm_class(struct device *dev,
+static ssize_t pcm_class_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);
@@ -1024,7 +1024,7 @@ static ssize_t show_pcm_class(struct device *dev,
return sprintf(buf, "%s\n", str);
}
-static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL);
+static DEVICE_ATTR_RO(pcm_class);
static struct attribute *pcm_dev_attrs[] = {
&dev_attr_pcm_class.attr,
NULL
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 590a46a9e78d..a59de24695ec 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -239,7 +239,8 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime;
int err;
- if (! (runtime = substream->runtime))
+ runtime = substream->runtime;
+ if (!runtime)
return -ENOTTY;
data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -343,7 +344,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
- if ((ch = substream->runtime->channels) > 128)
+ ch = substream->runtime->channels;
+ if (ch > 128)
return -EINVAL;
if (get_user(buf, &data32->bufs) ||
get_user(frames, &data32->frames))
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b7e3d8f44511..7d5883432085 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1778,27 +1778,38 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
EXPORT_SYMBOL(snd_pcm_lib_ioctl);
/**
- * snd_pcm_period_elapsed - update the pcm status for the next period
- * @substream: the pcm substream instance
+ * snd_pcm_period_elapsed_under_stream_lock() - update the status of runtime for the next period
+ * under acquired lock of PCM substream.
+ * @substream: the instance of pcm substream.
+ *
+ * This function is called when the batch of audio data frames as the same size as the period of
+ * buffer is already processed in audio data transmission.
+ *
+ * The call of function updates the status of runtime with the latest position of audio data
+ * transmission, checks overrun and underrun over buffer, awaken user processes from waiting for
+ * available audio data frames, sampling audio timestamp, and performs stop or drain the PCM
+ * substream according to configured threshold.
+ *
+ * The function is intended to use for the case that PCM driver operates audio data frames under
+ * acquired lock of PCM substream; e.g. in callback of any operation of &snd_pcm_ops in process
+ * context. In any interrupt context, it's preferrable to use ``snd_pcm_period_elapsed()`` instead
+ * since lock of PCM substream should be acquired in advance.
*
- * This function is called from the interrupt handler when the
- * PCM has processed the period size. It will update the current
- * pointer, wake up sleepers, etc.
+ * Developer should pay enough attention that some callbacks in &snd_pcm_ops are done by the call of
+ * function:
*
- * Even if more than one periods have elapsed since the last call, you
- * have to call this only once.
+ * - .pointer - to retrieve current position of audio data transmission by frame count or XRUN state.
+ * - .trigger - with SNDRV_PCM_TRIGGER_STOP at XRUN or DRAINING state.
+ * - .get_time_info - to retrieve audio time stamp if needed.
+ *
+ * Even if more than one periods have elapsed since the last call, you have to call this only once.
*/
-void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
+void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
- unsigned long flags;
- if (snd_BUG_ON(!substream))
- return;
-
- snd_pcm_stream_lock_irqsave(substream, flags);
if (PCM_RUNTIME_CHECK(substream))
- goto _unlock;
+ return;
runtime = substream->runtime;
if (!snd_pcm_running(substream) ||
@@ -1811,7 +1822,30 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
#endif
_end:
kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
- _unlock:
+}
+EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock);
+
+/**
+ * snd_pcm_period_elapsed() - update the status of runtime for the next period by acquiring lock of
+ * PCM substream.
+ * @substream: the instance of PCM substream.
+ *
+ * This function is mostly similar to ``snd_pcm_period_elapsed_under_stream_lock()`` except for
+ * acquiring lock of PCM substream voluntarily.
+ *
+ * It's typically called by any type of IRQ handler when hardware IRQ occurs to notify event that
+ * the batch of audio data frames as the same size as the period of buffer is already processed in
+ * audio data transmission.
+ */
+void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+
+ if (snd_BUG_ON(!substream))
+ return;
+
+ snd_pcm_stream_lock_irqsave(substream, flags);
+ snd_pcm_period_elapsed_under_stream_lock(substream);
snd_pcm_stream_unlock_irqrestore(substream, flags);
}
EXPORT_SYMBOL(snd_pcm_period_elapsed);
diff --git a/sound/core/pcm_local.h b/sound/core/pcm_local.h
index e3b3558aeab6..fe9689b8a6a6 100644
--- a/sound/core/pcm_local.h
+++ b/sound/core/pcm_local.h
@@ -65,11 +65,6 @@ void __snd_pcm_xrun(struct snd_pcm_substream *substream);
void snd_pcm_group_init(struct snd_pcm_group *group);
void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq);
-#ifdef CONFIG_SND_DMA_SGBUF
-struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
- unsigned long offset);
-#endif
-
#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
/* loop over all PCM substreams */
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 542a75babdee..d7621ed105bd 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -337,27 +337,6 @@ void snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
}
EXPORT_SYMBOL(snd_pcm_set_managed_buffer_all);
-#ifdef CONFIG_SND_DMA_SGBUF
-/*
- * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
- * @substream: the pcm substream instance
- * @offset: the buffer offset
- *
- * Used as the page callback of PCM ops.
- *
- * Return: The page struct at the given buffer offset. %NULL on failure.
- */
-struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset)
-{
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
-
- unsigned int idx = offset >> PAGE_SHIFT;
- if (idx >= (unsigned int)sgbuf->pages)
- return NULL;
- return sgbuf->page_table[idx];
-}
-#endif /* CONFIG_SND_DMA_SGBUF */
-
/**
* snd_pcm_lib_malloc_pages - allocate the DMA buffer
* @substream: the substream to allocate the DMA buffer to
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 257d412eac5d..4866aed97aac 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -266,7 +266,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
- if ((val = pcm_formats[(INT)format].signd) < 0)
+ val = pcm_formats[(INT)format].signd;
+ if (val < 0)
return -EINVAL;
return val;
}
@@ -314,7 +315,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
- if ((val = pcm_formats[(INT)format].le) < 0)
+ val = pcm_formats[(INT)format].le;
+ if (val < 0)
return -EINVAL;
return val;
}
@@ -350,7 +352,8 @@ int snd_pcm_format_width(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
- if ((val = pcm_formats[(INT)format].width) == 0)
+ val = pcm_formats[(INT)format].width;
+ if (!val)
return -EINVAL;
return val;
}
@@ -368,7 +371,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
- if ((val = pcm_formats[(INT)format].phys) == 0)
+ val = pcm_formats[(INT)format].phys;
+ if (!val)
return -EINVAL;
return val;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 8dbe86cf2e4f..14e32825c339 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -768,7 +768,8 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
if (cpu_latency_qos_request_active(&substream->latency_pm_qos_req))
cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
- if ((usecs = period_to_usecs(runtime)) >= 0)
+ usecs = period_to_usecs(runtime);
+ if (usecs >= 0)
cpu_latency_qos_add_request(&substream->latency_pm_qos_req,
usecs);
return 0;
@@ -2658,7 +2659,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
goto error;
}
- if ((err = substream->ops->open(substream)) < 0)
+ err = substream->ops->open(substream);
+ if (err < 0)
goto error;
substream->hw_opened = 1;
@@ -2799,6 +2801,10 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
if (snd_BUG_ON(!substream))
return -ENXIO;
pcm = substream->pcm;
+
+ /* block until the device gets woken up as it may touch the hardware */
+ snd_power_wait(pcm->card);
+
mutex_lock(&pcm->open_mutex);
snd_pcm_release_substream(substream);
kfree(pcm_file);
@@ -3193,7 +3199,7 @@ static int snd_pcm_common_ioctl(struct file *file,
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
- res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0);
+ res = snd_power_wait(substream->pcm->card);
if (res < 0)
return res;
@@ -3638,24 +3644,6 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
}
#endif /* coherent mmap */
-static inline struct page *
-snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
-{
- void *vaddr = substream->runtime->dma_area + ofs;
-
- switch (substream->dma_buffer.dev.type) {
-#ifdef CONFIG_SND_DMA_SGBUF
- case SNDRV_DMA_TYPE_DEV_SG:
- case SNDRV_DMA_TYPE_DEV_UC_SG:
- return snd_pcm_sgbuf_ops_page(substream, ofs);
-#endif /* CONFIG_SND_DMA_SGBUF */
- case SNDRV_DMA_TYPE_VMALLOC:
- return vmalloc_to_page(vaddr);
- default:
- return virt_to_page(vaddr);
- }
-}
-
/*
* fault callback for mmapping a RAM page
*/
@@ -3677,7 +3665,7 @@ static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
if (substream->ops->page)
page = substream->ops->page(substream, offset);
else
- page = snd_pcm_default_page_ops(substream, offset);
+ page = snd_sgbuf_get_page(snd_pcm_get_dma_buf(substream), offset);
if (!page)
return VM_FAULT_SIGBUS;
get_page(page);
@@ -3712,22 +3700,9 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
-#ifdef CONFIG_GENERIC_ALLOCATOR
- if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_IRAM) {
- area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
- return remap_pfn_range(area, area->vm_start,
- substream->dma_buffer.addr >> PAGE_SHIFT,
- area->vm_end - area->vm_start, area->vm_page_prot);
- }
-#endif /* CONFIG_GENERIC_ALLOCATOR */
- if (IS_ENABLED(CONFIG_HAS_DMA) && !substream->ops->page &&
- (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV ||
- substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_UC))
- return dma_mmap_coherent(substream->dma_buffer.dev.dev,
- area,
- substream->runtime->dma_area,
- substream->runtime->dma_addr,
- substream->runtime->dma_bytes);
+ if (!substream->ops->page &&
+ !snd_dma_buffer_mmap(snd_pcm_get_dma_buf(substream), area))
+ return 0;
/* mmap with fault handler */
area->vm_ops = &snd_pcm_vm_ops_data_fault;
return 0;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index aca00af93afe..6c0a4a67ad2e 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -680,9 +680,12 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
bool is_input)
{
char *newbuf, *oldbuf;
+ unsigned int framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK;
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L)
return -EINVAL;
+ if (framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP && (params->buffer_size & 0x1f) != 0)
+ return -EINVAL;
if (params->avail_min < 1 || params->avail_min > params->buffer_size)
return -EINVAL;
if (params->buffer_size != runtime->buffer_size) {
@@ -720,8 +723,24 @@ EXPORT_SYMBOL(snd_rawmidi_output_params);
int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params *params)
{
+ unsigned int framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK;
+ unsigned int clock_type = params->mode & SNDRV_RAWMIDI_MODE_CLOCK_MASK;
+ int err;
+
+ if (framing == SNDRV_RAWMIDI_MODE_FRAMING_NONE && clock_type != SNDRV_RAWMIDI_MODE_CLOCK_NONE)
+ return -EINVAL;
+ else if (clock_type > SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW)
+ return -EINVAL;
+ if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
+ return -EINVAL;
snd_rawmidi_drain_input(substream);
- return resize_runtime_buffer(substream->runtime, params, true);
+ err = resize_runtime_buffer(substream->runtime, params, true);
+ if (err < 0)
+ return err;
+
+ substream->framing = framing;
+ substream->clock_type = clock_type;
+ return 0;
}
EXPORT_SYMBOL(snd_rawmidi_input_params);
@@ -963,6 +982,62 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
return -ENOIOCTLCMD;
}
+static int receive_with_tstamp_framing(struct snd_rawmidi_substream *substream,
+ const unsigned char *buffer, int src_count, const struct timespec64 *tstamp)
+{
+ struct snd_rawmidi_runtime *runtime = substream->runtime;
+ struct snd_rawmidi_framing_tstamp *dest_ptr;
+ struct snd_rawmidi_framing_tstamp frame = { .tv_sec = tstamp->tv_sec, .tv_nsec = tstamp->tv_nsec };
+ int dest_frames = 0;
+ int orig_count = src_count;
+ int frame_size = sizeof(struct snd_rawmidi_framing_tstamp);
+
+ BUILD_BUG_ON(frame_size != 0x20);
+ if (snd_BUG_ON((runtime->hw_ptr & 0x1f) != 0))
+ return -EINVAL;
+
+ while (src_count > 0) {
+ if ((int)(runtime->buffer_size - runtime->avail) < frame_size) {
+ runtime->xruns += src_count;
+ break;
+ }
+ if (src_count >= SNDRV_RAWMIDI_FRAMING_DATA_LENGTH)
+ frame.length = SNDRV_RAWMIDI_FRAMING_DATA_LENGTH;
+ else {
+ frame.length = src_count;
+ memset(frame.data, 0, SNDRV_RAWMIDI_FRAMING_DATA_LENGTH);
+ }
+ memcpy(frame.data, buffer, frame.length);
+ buffer += frame.length;
+ src_count -= frame.length;
+ dest_ptr = (struct snd_rawmidi_framing_tstamp *) (runtime->buffer + runtime->hw_ptr);
+ *dest_ptr = frame;
+ runtime->avail += frame_size;
+ runtime->hw_ptr += frame_size;
+ runtime->hw_ptr %= runtime->buffer_size;
+ dest_frames++;
+ }
+ return orig_count - src_count;
+}
+
+static struct timespec64 get_framing_tstamp(struct snd_rawmidi_substream *substream)
+{
+ struct timespec64 ts64 = {0, 0};
+
+ switch (substream->clock_type) {
+ case SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW:
+ ktime_get_raw_ts64(&ts64);
+ break;
+ case SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC:
+ ktime_get_ts64(&ts64);
+ break;
+ case SNDRV_RAWMIDI_MODE_CLOCK_REALTIME:
+ ktime_get_real_ts64(&ts64);
+ break;
+ }
+ return ts64;
+}
+
/**
* snd_rawmidi_receive - receive the input data from the device
* @substream: the rawmidi substream
@@ -977,6 +1052,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
const unsigned char *buffer, int count)
{
unsigned long flags;
+ struct timespec64 ts64 = get_framing_tstamp(substream);
int result = 0, count1;
struct snd_rawmidi_runtime *runtime = substream->runtime;
@@ -987,8 +1063,11 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
"snd_rawmidi_receive: input is not active!!!\n");
return -EINVAL;
}
+
spin_lock_irqsave(&runtime->lock, flags);
- if (count == 1) { /* special case, faster code */
+ if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) {
+ result = receive_with_tstamp_framing(substream, buffer, count, &ts64);
+ } else if (count == 1) { /* special case, faster code */
substream->bytes++;
if (runtime->avail < runtime->buffer_size) {
runtime->buffer[runtime->hw_ptr++] = buffer[0];
@@ -1541,6 +1620,8 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
struct snd_rawmidi_substream *substream;
struct snd_rawmidi_runtime *runtime;
unsigned long buffer_size, avail, xruns;
+ unsigned int clock_type;
+ static const char *clock_names[4] = { "none", "realtime", "monotonic", "monotonic raw" };
rmidi = entry->private_data;
snd_iprintf(buffer, "%s\n\n", rmidi->name);
@@ -1596,6 +1677,14 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
" Avail : %lu\n"
" Overruns : %lu\n",
buffer_size, avail, xruns);
+ if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) {
+ clock_type = substream->clock_type >> SNDRV_RAWMIDI_MODE_CLOCK_SHIFT;
+ if (!snd_BUG_ON(clock_type >= ARRAY_SIZE(clock_names)))
+ snd_iprintf(buffer,
+ " Framing : tstamp\n"
+ " Clock type : %s\n",
+ clock_names[clock_type]);
+ }
}
}
}
diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
index 7397130976d0..68a93443583c 100644
--- a/sound/core/rawmidi_compat.c
+++ b/sound/core/rawmidi_compat.c
@@ -13,7 +13,8 @@ struct snd_rawmidi_params32 {
u32 buffer_size;
u32 avail_min;
unsigned int no_active_sensing; /* avoid bit-field */
- unsigned char reserved[16];
+ unsigned int mode;
+ unsigned char reserved[12];
} __attribute__((packed));
static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
@@ -25,6 +26,7 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
if (get_user(params.stream, &src->stream) ||
get_user(params.buffer_size, &src->buffer_size) ||
get_user(params.avail_min, &src->avail_min) ||
+ get_user(params.mode, &src->mode) ||
get_user(val, &src->no_active_sensing))
return -EFAULT;
params.no_active_sensing = val;
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 250a92b18726..77c1214acd90 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -67,13 +67,16 @@ static int __init alsa_seq_oss_init(void)
{
int rc;
- if ((rc = register_device()) < 0)
+ rc = register_device();
+ if (rc < 0)
goto error;
- if ((rc = register_proc()) < 0) {
+ rc = register_proc();
+ if (rc < 0) {
unregister_device();
goto error;
}
- if ((rc = snd_seq_oss_create_client()) < 0) {
+ rc = snd_seq_oss_create_client();
+ if (rc < 0) {
unregister_proc();
unregister_device();
goto error;
@@ -133,7 +136,8 @@ odev_release(struct inode *inode, struct file *file)
{
struct seq_oss_devinfo *dp;
- if ((dp = file->private_data) == NULL)
+ dp = file->private_data;
+ if (!dp)
return 0;
mutex_lock(&register_mutex);
@@ -226,16 +230,18 @@ register_device(void)
int rc;
mutex_lock(&register_mutex);
- if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
- NULL, 0,
- &seq_oss_f_ops, NULL)) < 0) {
+ 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;
}
- if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
- NULL, 0,
- &seq_oss_f_ops, NULL)) < 0) {
+ rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
+ NULL, 0,
+ &seq_oss_f_ops, NULL);
+ 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);
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 4534a154b8c8..0ee4a5081fd6 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -94,10 +94,10 @@ snd_seq_oss_create_client(void)
port_callback.event_input = receive_announce;
port->kernel = &port_callback;
- call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, port);
- if ((system_port = port->addr.port) >= 0) {
+ if (call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, port) >= 0) {
struct snd_seq_port_subscribe subs;
+ system_port = port->addr.port;
memset(&subs, 0, sizeof(subs));
subs.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
subs.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
@@ -354,7 +354,8 @@ alloc_seq_queue(struct seq_oss_devinfo *dp)
qinfo.owner = system_client;
qinfo.locked = 1;
strcpy(qinfo.name, "OSS Sequencer Emulation");
- if ((rc = call_ctl(SNDRV_SEQ_IOCTL_CREATE_QUEUE, &qinfo)) < 0)
+ rc = call_ctl(SNDRV_SEQ_IOCTL_CREATE_QUEUE, &qinfo);
+ if (rc < 0)
return rc;
dp->queue = qinfo.queue;
return 0;
@@ -485,7 +486,8 @@ snd_seq_oss_system_info_read(struct snd_info_buffer *buf)
snd_iprintf(buf, "\nNumber of applications: %d\n", num_clients);
for (i = 0; i < num_clients; i++) {
snd_iprintf(buf, "\nApplication %d: ", i);
- if ((dp = client_table[i]) == NULL) {
+ dp = client_table[i];
+ if (!dp) {
snd_iprintf(buf, "*empty*\n");
continue;
}
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 3f82c196de46..1e3bf086f867 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -152,7 +152,8 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
/*
* look for the identical slot
*/
- if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) {
+ mdev = find_slot(pinfo->addr.client, pinfo->addr.port);
+ if (mdev) {
/* already exists */
snd_use_lock_free(&mdev->use_lock);
return 0;
@@ -218,7 +219,8 @@ snd_seq_oss_midi_check_exit_port(int client, int port)
unsigned long flags;
int index;
- if ((mdev = find_slot(client, port)) != NULL) {
+ 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);
@@ -250,7 +252,8 @@ snd_seq_oss_midi_clear_all(void)
spin_lock_irqsave(&register_lock, flags);
for (i = 0; i < max_midi_devs; i++) {
- if ((mdev = midi_devs[i]) != NULL) {
+ mdev = midi_devs[i];
+ if (mdev) {
snd_midi_event_free(mdev->coder);
kfree(mdev);
midi_devs[i] = NULL;
@@ -318,7 +321,8 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
struct seq_oss_midi *mdev;
struct snd_seq_port_subscribe subs;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return -ENODEV;
/* already used? */
@@ -384,7 +388,8 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
struct seq_oss_midi *mdev;
struct snd_seq_port_subscribe subs;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return -ENODEV;
if (! mdev->opened || mdev->devinfo != dp) {
snd_use_lock_free(&mdev->use_lock);
@@ -421,7 +426,8 @@ snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
struct seq_oss_midi *mdev;
int mode;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return 0;
mode = 0;
@@ -443,7 +449,8 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
{
struct seq_oss_midi *mdev;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return;
if (! mdev->opened) {
snd_use_lock_free(&mdev->use_lock);
@@ -491,7 +498,8 @@ snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_ad
{
struct seq_oss_midi *mdev;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return;
addr->client = mdev->client;
addr->port = mdev->port;
@@ -511,7 +519,8 @@ snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
if (dp->readq == NULL)
return 0;
- if ((mdev = find_slot(ev->source.client, ev->source.port)) == NULL)
+ 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);
@@ -623,7 +632,8 @@ snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, stru
{
struct seq_oss_midi *mdev;
- if ((mdev = get_mididev(dp, dev)) == 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);
@@ -642,7 +652,8 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info
{
struct seq_oss_midi *mdev;
- if ((mdev = get_mididev(dp, dev)) == NULL)
+ mdev = get_mididev(dp, dev);
+ if (!mdev)
return -ENXIO;
inf->device = dev;
inf->dev_type = 0; /* FIXME: ?? */
diff --git a/sound/core/seq/oss/seq_oss_rw.c b/sound/core/seq/oss/seq_oss_rw.c
index 537d5f423e20..8a142fd54a19 100644
--- a/sound/core/seq/oss/seq_oss_rw.c
+++ b/sound/core/seq/oss/seq_oss_rw.c
@@ -132,7 +132,8 @@ snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int count,
}
/* insert queue */
- if ((err = insert_queue(dp, &rec, opt)) < 0)
+ err = insert_queue(dp, &rec, opt);
+ if (err < 0)
break;
result += ev_size;
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 722f5059b300..e3394919daa0 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -451,7 +451,8 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
if (info->is_midi)
return 0;
- if ((rec = get_synthdev(dp, dev)) == NULL)
+ rec = get_synthdev(dp, dev);
+ if (!rec)
return -ENXIO;
if (rec->oper.load_patch == NULL)
@@ -569,7 +570,8 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
info = get_synthinfo_nospec(dp, dev);
if (!info || info->is_midi)
return -ENXIO;
- if ((rec = get_synthdev(dp, dev)) == NULL)
+ rec = get_synthdev(dp, dev);
+ if (!rec)
return -ENXIO;
if (rec->oper.ioctl == NULL)
rc = -ENXIO;
@@ -619,7 +621,8 @@ 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 {
- if ((rec = get_synthdev(dp, dev)) == NULL)
+ rec = get_synthdev(dp, dev);
+ if (!rec)
return -ENXIO;
inf->synth_type = rec->synth_type;
inf->synth_subtype = rec->synth_subtype;
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 0a02a59103b4..3e3209ce53b1 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -27,7 +27,8 @@ snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen)
struct seq_oss_writeq *q;
struct snd_seq_client_pool pool;
- if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
+ q = kzalloc(sizeof(*q), GFP_KERNEL);
+ if (!q)
return NULL;
q->dp = dp;
q->maxlen = maxlen;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index b6a24fb5e76b..2e9d695d336c 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -416,7 +416,10 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
if (snd_BUG_ON(!client))
return -ENXIO;
- if (!client->accept_input || (fifo = client->data.user.fifo) == NULL)
+ if (!client->accept_input)
+ return -ENXIO;
+ fifo = client->data.user.fifo;
+ if (!fifo)
return -ENXIO;
if (atomic_read(&fifo->overflow) > 0) {
@@ -435,9 +438,9 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
int nonblock;
nonblock = (file->f_flags & O_NONBLOCK) || result > 0;
- if ((err = snd_seq_fifo_cell_out(fifo, &cell, nonblock)) < 0) {
+ err = snd_seq_fifo_cell_out(fifo, &cell, nonblock);
+ if (err < 0)
break;
- }
if (snd_seq_ev_is_variable(&cell->event)) {
struct snd_seq_event tmpev;
tmpev = cell->event;
@@ -970,7 +973,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
return err;
/* we got a cell. enqueue it. */
- if ((err = snd_seq_enqueue_event(cell, atomic, hop)) < 0) {
+ err = snd_seq_enqueue_event(cell, atomic, hop);
+ if (err < 0) {
snd_seq_cell_free(cell);
return err;
}
@@ -1312,7 +1316,8 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
return -EINVAL;
}
if (client->type == KERNEL_CLIENT) {
- if ((callback = info->kernel) != NULL) {
+ callback = info->kernel;
+ if (callback) {
if (callback->owner)
port->owner = callback->owner;
port->private_data = callback->private_data;
@@ -1466,13 +1471,17 @@ static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
struct snd_seq_client *receiver = NULL, *sender = NULL;
struct snd_seq_client_port *sport = NULL, *dport = NULL;
- if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL)
+ receiver = snd_seq_client_use_ptr(subs->dest.client);
+ if (!receiver)
goto __end;
- if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
+ sender = snd_seq_client_use_ptr(subs->sender.client);
+ if (!sender)
goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
+ sport = snd_seq_port_use_ptr(sender, subs->sender.port);
+ if (!sport)
goto __end;
- if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL)
+ dport = snd_seq_port_use_ptr(receiver, subs->dest.port);
+ if (!dport)
goto __end;
result = check_subscription_permission(client, sport, dport, subs);
@@ -1508,13 +1517,17 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
struct snd_seq_client *receiver = NULL, *sender = NULL;
struct snd_seq_client_port *sport = NULL, *dport = NULL;
- if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL)
+ receiver = snd_seq_client_use_ptr(subs->dest.client);
+ if (!receiver)
goto __end;
- if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
+ sender = snd_seq_client_use_ptr(subs->sender.client);
+ if (!sender)
goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
+ sport = snd_seq_port_use_ptr(sender, subs->sender.port);
+ if (!sport)
goto __end;
- if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL)
+ dport = snd_seq_port_use_ptr(receiver, subs->dest.port);
+ if (!dport)
goto __end;
result = check_subscription_permission(client, sport, dport, subs);
@@ -1926,9 +1939,11 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
struct snd_seq_client_port *sport = NULL;
result = -EINVAL;
- if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
+ sender = snd_seq_client_use_ptr(subs->sender.client);
+ if (!sender)
goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
+ 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);
@@ -1955,9 +1970,11 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
struct list_head *p;
int i;
- if ((cptr = snd_seq_client_use_ptr(subs->root.client)) == NULL)
+ cptr = snd_seq_client_use_ptr(subs->root.client);
+ if (!cptr)
goto __end;
- if ((port = snd_seq_port_use_ptr(cptr, subs->root.port)) == NULL)
+ port = snd_seq_port_use_ptr(cptr, subs->root.port);
+ if (!port)
goto __end;
switch (subs->type) {
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index cd5a4cad8881..ac760b1e3d12 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -109,7 +109,8 @@ create_port(int idx, int type)
struct snd_seq_port_callback pcb;
struct snd_seq_dummy_port *rec;
- if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL)
+ rec = kzalloc(sizeof(*rec), GFP_KERNEL);
+ if (!rec)
return NULL;
rec->client = my_client;
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index eaaa8b5830bb..f8e02e98709a 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -143,7 +143,8 @@ static struct snd_seq_event_cell *fifo_cell_out(struct snd_seq_fifo *f)
{
struct snd_seq_event_cell *cell;
- if ((cell = f->head) != NULL) {
+ cell = f->head;
+ if (cell) {
f->head = cell->next;
/* reset tail if this was the last element */
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index e245bb6ba533..b7aee23fc387 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -69,7 +69,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
int len, err;
struct snd_seq_event_cell *cell;
- if ((len = get_var_len(event)) <= 0)
+ len = get_var_len(event);
+ if (len <= 0)
return len;
if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
@@ -133,7 +134,8 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
int len, newlen;
int err;
- if ((len = get_var_len(event)) < 0)
+ len = get_var_len(event);
+ if (len < 0)
return len;
newlen = len;
if (size_aligned > 0)
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 6825940ea2cf..4589aac09154 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -101,7 +101,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
if (snd_BUG_ON(!substream || !buf))
return -EINVAL;
runtime = substream->runtime;
- if ((tmp = runtime->avail) < count) {
+ tmp = runtime->avail;
+ if (tmp < count) {
if (printk_ratelimit())
pr_err("ALSA: seq_midi: MIDI output buffer overrun\n");
return -ENOMEM;
@@ -167,10 +168,11 @@ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe
struct snd_rawmidi_params params;
/* open midi port */
- if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
- msynth->subdevice,
- SNDRV_RAWMIDI_LFLG_INPUT,
- &msynth->input_rfile)) < 0) {
+ err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
+ msynth->subdevice,
+ SNDRV_RAWMIDI_LFLG_INPUT,
+ &msynth->input_rfile);
+ if (err < 0) {
pr_debug("ALSA: seq_midi: midi input open failed!!!\n");
return err;
}
@@ -178,7 +180,8 @@ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe
memset(&params, 0, sizeof(params));
params.avail_min = 1;
params.buffer_size = input_buffer_size;
- if ((err = snd_rawmidi_input_params(msynth->input_rfile.input, &params)) < 0) {
+ err = snd_rawmidi_input_params(msynth->input_rfile.input, &params);
+ if (err < 0) {
snd_rawmidi_kernel_release(&msynth->input_rfile);
return err;
}
@@ -209,10 +212,11 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
struct snd_rawmidi_params params;
/* open midi port */
- if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
- msynth->subdevice,
- SNDRV_RAWMIDI_LFLG_OUTPUT,
- &msynth->output_rfile)) < 0) {
+ err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
+ msynth->subdevice,
+ SNDRV_RAWMIDI_LFLG_OUTPUT,
+ &msynth->output_rfile);
+ if (err < 0) {
pr_debug("ALSA: seq_midi: midi output open failed!!!\n");
return err;
}
@@ -220,7 +224,8 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
params.avail_min = 1;
params.buffer_size = output_buffer_size;
params.no_active_sensing = 1;
- if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) {
+ err = snd_rawmidi_output_params(msynth->output_rfile.output, &params);
+ if (err < 0) {
snd_rawmidi_kernel_release(&msynth->output_rfile);
return err;
}
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 13cfc2d47fa7..d6c02dea976c 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -222,7 +222,8 @@ struct snd_seq_queue *snd_seq_queue_find_name(char *name)
struct snd_seq_queue *q;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) != NULL) {
+ q = queueptr(i);
+ if (q) {
if (strncmp(q->name, name, sizeof(q->name)) == 0)
return q;
queuefree(q);
@@ -432,7 +433,8 @@ int snd_seq_queue_timer_open(int queueid)
if (queue == NULL)
return -EINVAL;
tmr = queue->timer;
- if ((result = snd_seq_timer_open(queue)) < 0) {
+ result = snd_seq_timer_open(queue);
+ if (result < 0) {
snd_seq_timer_defaults(tmr);
result = snd_seq_timer_open(queue);
}
@@ -548,7 +550,8 @@ void snd_seq_queue_client_leave(int client)
/* delete own queues from queue list */
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queue_list_remove(i, client)) != NULL)
+ q = queue_list_remove(i, client);
+ if (q)
queue_delete(q);
}
@@ -556,7 +559,8 @@ void snd_seq_queue_client_leave(int client)
* they are not owned by this client
*/
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
+ q = queueptr(i);
+ if (!q)
continue;
if (test_bit(client, q->clients_bitmap)) {
snd_seq_prioq_leave(q->tickq, client, 0);
@@ -578,7 +582,8 @@ void snd_seq_queue_client_leave_cells(int client)
struct snd_seq_queue *q;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
+ q = queueptr(i);
+ if (!q)
continue;
snd_seq_prioq_leave(q->tickq, client, 0);
snd_seq_prioq_leave(q->timeq, client, 0);
@@ -593,7 +598,8 @@ void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info)
struct snd_seq_queue *q;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
+ q = queueptr(i);
+ if (!q)
continue;
if (test_bit(client, q->clients_bitmap) &&
(! (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) ||
@@ -724,7 +730,8 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry,
int owner;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
+ q = queueptr(i);
+ if (!q)
continue;
tmr = q->timer;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 77d7037d1476..4abc38c70cae 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -482,10 +482,11 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi
int err;
*rrmidi = NULL;
- if ((err = snd_rawmidi_new(card, "VirMidi", device,
- 16, /* may be configurable */
- 16, /* may be configurable */
- &rmidi)) < 0)
+ err = snd_rawmidi_new(card, "VirMidi", device,
+ 16, /* may be configurable */
+ 16, /* may be configurable */
+ &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, rmidi->id);
rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index 29ddb76187e5..232cf3f1bcb3 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -10,20 +10,34 @@
#include <linux/vmalloc.h>
#include <linux/export.h>
#include <sound/memalloc.h>
-
+#include "memalloc_local.h"
+
+struct snd_sg_page {
+ void *buf;
+ dma_addr_t addr;
+};
+
+struct snd_sg_buf {
+ int size; /* allocated byte size */
+ int pages; /* allocated pages */
+ int tblsize; /* allocated table size */
+ struct snd_sg_page *table; /* address table */
+ struct page **page_table; /* page table (for vmap/vunmap) */
+ struct device *dev;
+};
/* table entries are align to 32 */
#define SGBUF_TBL_ALIGN 32
#define sgbuf_align_table(tbl) ALIGN((tbl), SGBUF_TBL_ALIGN)
-int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
+static void snd_dma_sg_free(struct snd_dma_buffer *dmab)
{
struct snd_sg_buf *sgbuf = dmab->private_data;
struct snd_dma_buffer tmpb;
int i;
- if (! sgbuf)
- return -EINVAL;
+ if (!sgbuf)
+ return;
vunmap(dmab->area);
dmab->area = NULL;
@@ -45,15 +59,11 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
kfree(sgbuf->page_table);
kfree(sgbuf);
dmab->private_data = NULL;
-
- return 0;
}
#define MAX_ALLOC_PAGES 32
-void *snd_malloc_sgbuf_pages(struct device *device,
- size_t size, struct snd_dma_buffer *dmab,
- size_t *res_size)
+static int snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
{
struct snd_sg_buf *sgbuf;
unsigned int i, pages, chunk, maxpages;
@@ -63,18 +73,16 @@ void *snd_malloc_sgbuf_pages(struct device *device,
int type = SNDRV_DMA_TYPE_DEV;
pgprot_t prot = PAGE_KERNEL;
- dmab->area = NULL;
- dmab->addr = 0;
dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
- if (! sgbuf)
- return NULL;
+ if (!sgbuf)
+ return -ENOMEM;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG) {
type = SNDRV_DMA_TYPE_DEV_UC;
#ifdef pgprot_noncached
prot = pgprot_noncached(PAGE_KERNEL);
#endif
}
- sgbuf->dev = device;
+ sgbuf->dev = dmab->dev.dev;
pages = snd_sgbuf_aligned_pages(size);
sgbuf->tblsize = sgbuf_align_table(pages);
table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL);
@@ -94,12 +102,10 @@ void *snd_malloc_sgbuf_pages(struct device *device,
if (chunk > maxpages)
chunk = maxpages;
chunk <<= PAGE_SHIFT;
- if (snd_dma_alloc_pages_fallback(type, device,
+ if (snd_dma_alloc_pages_fallback(type, dmab->dev.dev,
chunk, &tmpb) < 0) {
if (!sgbuf->pages)
goto _failed;
- if (!res_size)
- goto _failed;
size = sgbuf->pages * PAGE_SIZE;
break;
}
@@ -124,27 +130,42 @@ void *snd_malloc_sgbuf_pages(struct device *device,
dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
if (! dmab->area)
goto _failed;
- if (res_size)
- *res_size = sgbuf->size;
- return dmab->area;
+ return 0;
_failed:
- snd_free_sgbuf_pages(dmab); /* free the table */
- return NULL;
+ snd_dma_sg_free(dmab); /* free the table */
+ return -ENOMEM;
}
-/*
- * compute the max chunk size with continuous pages on sg-buffer
- */
-unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
- unsigned int ofs, unsigned int size)
+static dma_addr_t snd_dma_sg_get_addr(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ struct snd_sg_buf *sgbuf = dmab->private_data;
+ dma_addr_t addr;
+
+ addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
+ addr &= ~((dma_addr_t)PAGE_SIZE - 1);
+ return addr + offset % PAGE_SIZE;
+}
+
+static struct page *snd_dma_sg_get_page(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ struct snd_sg_buf *sgbuf = dmab->private_data;
+ unsigned int idx = offset >> PAGE_SHIFT;
+
+ if (idx >= (unsigned int)sgbuf->pages)
+ return NULL;
+ return sgbuf->page_table[idx];
+}
+
+static unsigned int snd_dma_sg_get_chunk_size(struct snd_dma_buffer *dmab,
+ unsigned int ofs,
+ unsigned int size)
{
struct snd_sg_buf *sg = dmab->private_data;
unsigned int start, end, pg;
- if (!sg)
- return size;
-
start = ofs >> PAGE_SHIFT;
end = (ofs + size - 1) >> PAGE_SHIFT;
/* check page continuity */
@@ -160,4 +181,11 @@ unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
/* ok, all on continuous pages */
return size;
}
-EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
+
+const struct snd_malloc_ops snd_dma_sg_ops = {
+ .alloc = snd_dma_sg_alloc,
+ .free = snd_dma_sg_free,
+ .get_addr = snd_dma_sg_get_addr,
+ .get_page = snd_dma_sg_get_page,
+ .get_chunk_size = snd_dma_sg_get_chunk_size,
+};
diff --git a/sound/core/sound.c b/sound/core/sound.c
index af89e51dd44a..df5571d98629 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -357,7 +357,8 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
mutex_lock(&sound_mutex);
for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
- if (!(mptr = snd_minors[minor]))
+ mptr = snd_minors[minor];
+ if (!mptr)
continue;
if (mptr->card >= 0) {
if (mptr->device >= 0)
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 610f317bea9d..7ed0a2a91035 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -217,7 +217,8 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
mutex_lock(&sound_oss_mutex);
for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
- if (!(mptr = snd_oss_minors[minor]))
+ mptr = snd_oss_minors[minor];
+ if (!mptr)
continue;
if (mptr->card >= 0)
snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 8c552e25805a..d0b55dbb411a 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -104,7 +104,8 @@ static int snd_mpu401_probe(struct platform_device *devptr)
err = snd_mpu401_create(&devptr->dev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -182,7 +183,8 @@ static int snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
err = snd_mpu401_create(&pnp_dev->dev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -227,7 +229,8 @@ static int __init alsa_card_mpu401_init(void)
{
int i, err;
- if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
+ err = platform_driver_register(&snd_mpu401_driver);
+ if (err < 0)
return err;
for (i = 0; i < SNDRV_CARDS; i++) {
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 65982d6babfc..f435b9b4ae24 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -271,8 +271,11 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
int err;
mpu = substream->rmidi->private_data;
- if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
- return err;
+ if (mpu->open_input) {
+ err = mpu->open_input(mpu);
+ if (err < 0)
+ return err;
+ }
if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
if (snd_mpu401_do_reset(mpu) < 0)
goto error_out;
@@ -293,8 +296,11 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
int err;
mpu = substream->rmidi->private_data;
- if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
- return err;
+ if (mpu->open_output) {
+ err = mpu->open_output(mpu);
+ if (err < 0)
+ return err;
+ }
if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
if (snd_mpu401_do_reset(mpu) < 0)
goto error_out;
@@ -524,8 +530,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
- if ((err = snd_rawmidi_new(card, "MPU-401U", device,
- out_enable, in_enable, &rmidi)) < 0)
+ err = snd_rawmidi_new(card, "MPU-401U", device,
+ out_enable, in_enable, &rmidi);
+ if (err < 0)
return err;
mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
if (!mpu) {
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index df4b7f9cd50f..0e95b08d34d6 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -566,7 +566,8 @@ static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
*/
static int snd_mtpav_get_ISA(struct mtpav *mcard)
{
- if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
+ mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI");
+ if (!mcard->res_port) {
snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
return -EBUSY;
}
@@ -628,10 +629,11 @@ static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
hwports = 8;
mcard->num_ports = hwports;
- if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- &mcard->rmidi)) < 0)
+ rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
+ mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
+ mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
+ &mcard->rmidi);
+ if (rval < 0)
return rval;
rawmidi = mcard->rmidi;
rawmidi->private_data = mcard;
@@ -744,7 +746,8 @@ static int __init alsa_card_mtpav_init(void)
{
int err;
- if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
+ err = platform_driver_register(&snd_mtpav_driver);
+ if (err < 0)
return err;
device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 322d530ab07b..d3bc9e8c407d 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -950,7 +950,8 @@ static int snd_mts64_probe(struct platform_device *pdev)
goto free_pardev;
}
- if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {
+ err = snd_mts64_create(card, pardev, &mts);
+ if (err < 0) {
snd_printd("Cannot create main component\n");
goto release_pardev;
}
@@ -963,19 +964,22 @@ static int snd_mts64_probe(struct platform_device *pdev)
goto __err;
}
- if ((err = snd_mts64_rawmidi_create(card)) < 0) {
+ err = snd_mts64_rawmidi_create(card);
+ if (err < 0) {
snd_printd("Creating Rawmidi component failed\n");
goto __err;
}
/* init device */
- if ((err = mts64_device_init(p)) < 0)
+ err = mts64_device_init(p);
+ if (err < 0)
goto __err;
platform_set_drvdata(pdev, card);
/* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_printd("Cannot register card\n");
goto __err;
}
@@ -1031,7 +1035,8 @@ static int __init snd_mts64_module_init(void)
{
int err;
- if ((err = platform_driver_register(&snd_mts64_driver)) < 0)
+ err = platform_driver_register(&snd_mts64_driver);
+ if (err < 0)
return err;
if (parport_register_driver(&mts64_parport_driver) != 0) {
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 9259522483c8..6c1f1cc092d8 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -243,7 +243,8 @@ static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
tid.card = opl3->card->number;
tid.device = timer_no;
tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
+ err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer);
+ if (err >= 0) {
strcpy(timer->name, "AdLib timer #1");
timer->private_data = opl3;
timer->hw = snd_opl3_timer1;
@@ -263,7 +264,8 @@ static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
tid.card = opl3->card->number;
tid.device = timer_no;
tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
+ err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer);
+ if (err >= 0) {
strcpy(timer->name, "AdLib timer #2");
timer->private_data = opl3;
timer->hw = snd_opl3_timer2;
@@ -348,7 +350,8 @@ int snd_opl3_new(struct snd_card *card,
spin_lock_init(&opl3->reg_lock);
spin_lock_init(&opl3->timer_lock);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops);
+ if (err < 0) {
snd_opl3_free(opl3);
return err;
}
@@ -396,19 +399,23 @@ int snd_opl3_create(struct snd_card *card,
int err;
*ropl3 = NULL;
- if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
+ err = snd_opl3_new(card, hardware, &opl3);
+ if (err < 0)
return err;
if (! integrated) {
- if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
+ opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)");
+ if (!opl3->res_l_port) {
snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
snd_device_free(card, opl3);
return -EBUSY;
}
- if (r_port != 0 &&
- (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
- snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
- snd_device_free(card, opl3);
- return -EBUSY;
+ if (r_port != 0) {
+ opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)");
+ if (!opl3->res_r_port) {
+ snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
+ snd_device_free(card, opl3);
+ return -EBUSY;
+ }
}
}
opl3->l_port = l_port;
@@ -423,7 +430,8 @@ int snd_opl3_create(struct snd_card *card,
break;
default:
opl3->command = &snd_opl2_command;
- if ((err = snd_opl3_detect(opl3)) < 0) {
+ err = snd_opl3_detect(opl3);
+ if (err < 0) {
snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
opl3->l_port, opl3->r_port);
snd_device_free(card, opl3);
@@ -449,11 +457,14 @@ int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
{
int err;
- if (timer1_dev >= 0)
- if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
+ if (timer1_dev >= 0) {
+ err = snd_opl3_timer1_init(opl3, timer1_dev);
+ if (err < 0)
return err;
+ }
if (timer2_dev >= 0) {
- if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
+ err = snd_opl3_timer2_init(opl3, timer2_dev);
+ if (err < 0) {
snd_device_free(opl3->card, opl3->timer1);
opl3->timer1 = NULL;
return err;
@@ -477,7 +488,8 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
/* create hardware dependent device (direct FM) */
- if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
+ err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw);
+ if (err < 0) {
snd_device_free(card, opl3);
return err;
}
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index eb23c55323ae..e1b69c65c3c8 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -180,8 +180,7 @@ static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
/* kill two voices, EXPENSIVE */
bp++;
- voice_time = (voice_time > vp->time) ?
- voice_time : vp->time;
+ voice_time = max(voice_time, vp2->time);
}
} else {
/* allocate 2op voice */
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index c82c7c1c0714..7645365eec89 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -136,7 +136,8 @@ static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
if (snd_BUG_ON(!arg))
return -ENXIO;
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
+ err = snd_opl3_synth_setup(opl3);
+ if (err < 0)
return err;
/* fill the argument data */
@@ -144,7 +145,8 @@ static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
arg->addr.client = opl3->oss_chset->client;
arg->addr.port = opl3->oss_chset->port;
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
+ err = snd_opl3_synth_use_inc(opl3);
+ if (err < 0)
return err;
opl3->synth_mode = SNDRV_OPL3_MODE_SYNTH;
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index cd2a01b5e2e1..75de1299c3dc 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -92,7 +92,8 @@ static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe
struct snd_opl3 *opl3 = private_data;
int err;
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
+ err = snd_opl3_synth_setup(opl3);
+ if (err < 0)
return err;
if (use_internal_drums) {
@@ -107,7 +108,8 @@ static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe
}
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
+ err = snd_opl3_synth_use_inc(opl3);
+ if (err < 0)
return err;
}
opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
@@ -227,7 +229,8 @@ static int snd_opl3_seq_probe(struct device *_dev)
if (client < 0)
return client;
- if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
+ err = snd_opl3_synth_create_port(opl3);
+ if (err < 0) {
snd_seq_delete_kernel_client(client);
opl3->seq_client = -1;
return err;
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 2f4514ed47c5..52a656735365 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -749,7 +749,8 @@ static int snd_portman_probe(struct platform_device *pdev)
goto free_pardev;
}
- if ((err = portman_create(card, pardev, &pm)) < 0) {
+ err = portman_create(card, pardev, &pm);
+ if (err < 0) {
snd_printd("Cannot create main component\n");
goto release_pardev;
}
@@ -762,19 +763,22 @@ static int snd_portman_probe(struct platform_device *pdev)
goto __err;
}
- if ((err = snd_portman_rawmidi_create(card)) < 0) {
+ err = snd_portman_rawmidi_create(card);
+ if (err < 0) {
snd_printd("Creating Rawmidi component failed\n");
goto __err;
}
/* init device */
- if ((err = portman_device_init(pm)) < 0)
+ err = portman_device_init(pm);
+ if (err < 0)
goto __err;
platform_set_drvdata(pdev, card);
/* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_printd("Cannot register card\n");
goto __err;
}
@@ -831,7 +835,8 @@ static int __init snd_portman_module_init(void)
{
int err;
- if ((err = platform_driver_register(&snd_portman_driver)) < 0)
+ err = platform_driver_register(&snd_portman_driver);
+ if (err < 0)
return err;
if (parport_register_driver(&portman_parport_driver) != 0) {
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 6d5d1ca59ecf..da9983cba01c 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -783,7 +783,8 @@ static int snd_uart16550_create(struct snd_card *card,
int err;
- if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
+ uart = kzalloc(sizeof(*uart), GFP_KERNEL);
+ if (!uart)
return -ENOMEM;
uart->adaptor = adaptor;
uart->card = card;
@@ -792,7 +793,8 @@ static int snd_uart16550_create(struct snd_card *card,
uart->base = iobase;
uart->drop_on_full = droponfull;
- if ((err = snd_uart16550_detect(uart)) <= 0) {
+ err = snd_uart16550_detect(uart);
+ if (err <= 0) {
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
snd_uart16550_free(uart);
return -ENODEV;
@@ -818,7 +820,8 @@ static int snd_uart16550_create(struct snd_card *card,
uart->timer_running = 0;
/* Register device */
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops);
+ if (err < 0) {
snd_uart16550_free(uart);
return err;
}
@@ -932,14 +935,10 @@ static int snd_serial_probe(struct platform_device *devptr)
strcpy(card->driver, "Serial");
strcpy(card->shortname, "Serial MIDI (UART16550A)");
- if ((err = snd_uart16550_create(card,
- port[dev],
- irq[dev],
- speed[dev],
- base[dev],
- adaptor[dev],
- droponfull[dev],
- &uart)) < 0)
+ err = snd_uart16550_create(card, port[dev], irq[dev], speed[dev],
+ base[dev], adaptor[dev], droponfull[dev],
+ &uart);
+ if (err < 0)
goto _err;
err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
@@ -952,7 +951,8 @@ static int snd_serial_probe(struct platform_device *devptr)
uart->base,
uart->irq);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto _err;
platform_set_drvdata(devptr, card);
@@ -992,7 +992,8 @@ static int __init alsa_card_serial_init(void)
{
int i, cards, err;
- if ((err = platform_driver_register(&snd_serial_driver)) < 0)
+ err = platform_driver_register(&snd_serial_driver);
+ if (err < 0)
return err;
cards = 0;
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index a22e5b1a5458..a10449af5a76 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -110,20 +110,25 @@ static int vx_transfer_end(struct vx_core *chip, int cmd)
{
int err;
- if ((err = vx_reset_chk(chip)) < 0)
+ err = vx_reset_chk(chip);
+ if (err < 0)
return err;
/* irq MESS_READ/WRITE_END */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
+ err = vx_send_irq_dsp(chip, cmd);
+ if (err < 0)
return err;
/* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
+ err = vx_wait_isr_bit(chip, ISR_CHK);
+ if (err < 0)
return err;
/* If error, Read RX */
- if ((err = vx_inb(chip, ISR)) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
+ err = vx_inb(chip, ISR);
+ if (err & ISR_ERR) {
+ err = vx_wait_for_rx_full(chip);
+ if (err < 0) {
snd_printd(KERN_DEBUG "transfer_end: error in rx_full\n");
return err;
}
@@ -232,7 +237,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
if (chip->chip_status & VX_STAT_IS_STALE)
return -EBUSY;
- if ((err = vx_reset_chk(chip)) < 0) {
+ err = vx_reset_chk(chip);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: vx_reset_chk error\n");
return err;
}
@@ -254,7 +260,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
rmh->Cmd[0] &= MASK_1_WORD_COMMAND;
/* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
+ err = vx_wait_isr_bit(chip, ISR_TX_EMPTY);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: wait tx empty error\n");
return err;
}
@@ -265,18 +272,21 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
vx_outb(chip, TXL, rmh->Cmd[0] & 0xff);
/* Trigger irq MESSAGE */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESSAGE)) < 0) {
+ err = vx_send_irq_dsp(chip, IRQ_MESSAGE);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: send IRQ_MESSAGE error\n");
return err;
}
/* Wait for CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
+ err = vx_wait_isr_bit(chip, ISR_CHK);
+ if (err < 0)
return err;
/* If error, get error value from RX */
if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
+ err = vx_wait_for_rx_full(chip);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: rx_full read error\n");
return err;
}
@@ -292,7 +302,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
if (rmh->LgCmd > 1) {
for (i = 1; i < rmh->LgCmd; i++) {
/* Wait for TX ready */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
+ err = vx_wait_isr_bit(chip, ISR_TX_READY);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: tx_ready error\n");
return err;
}
@@ -303,13 +314,15 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
vx_outb(chip, TXL, rmh->Cmd[i] & 0xff);
/* Trigger irq MESS_READ_NEXT */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT)) < 0) {
+ err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: IRQ_READ_NEXT error\n");
return err;
}
}
/* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
+ err = vx_wait_isr_bit(chip, ISR_TX_READY);
+ if (err < 0) {
snd_printd(KERN_DEBUG "vx_send_msg: TX_READY error\n");
return err;
}
@@ -362,17 +375,21 @@ int vx_send_rih_nolock(struct vx_core *chip, int cmd)
#if 0
printk(KERN_DEBUG "send_rih: cmd = 0x%x\n", cmd);
#endif
- if ((err = vx_reset_chk(chip)) < 0)
+ err = vx_reset_chk(chip);
+ if (err < 0)
return err;
/* send the IRQ */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
+ err = vx_send_irq_dsp(chip, cmd);
+ if (err < 0)
return err;
/* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
+ err = vx_wait_isr_bit(chip, ISR_CHK);
+ if (err < 0)
return err;
/* If error, read RX */
if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0)
+ err = vx_wait_for_rx_full(chip);
+ if (err < 0)
return err;
err = vx_inb(chip, RXH) << 16;
err |= vx_inb(chip, RXM) << 8;
@@ -648,7 +665,8 @@ int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
vx_reset_board(chip, cold_reset);
vx_validate_irq(chip, 0);
- if ((err = snd_vx_load_boot_image(chip, boot)) < 0)
+ err = snd_vx_load_boot_image(chip, boot);
+ if (err < 0)
return err;
msleep(10);
@@ -678,7 +696,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
for (i = 0; i < dsp->size; i += 3) {
image = dsp->data + i;
/* Wait DSP ready for a new read */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
+ err = vx_wait_isr_bit(chip, ISR_TX_EMPTY);
+ if (err < 0) {
printk(KERN_ERR
"dsp loading error at position %d\n", i);
return err;
@@ -698,7 +717,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
msleep(200);
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
+ err = vx_wait_isr_bit(chip, ISR_CHK);
+ if (err < 0)
return err;
vx_toggle_dac_mute(chip, 0);
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 01baa6d872e9..efbb644edba1 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -78,15 +78,19 @@ int snd_vx_setup_firmware(struct vx_core *chip)
/* ok, we reached to the last one */
/* create the devices if not built yet */
- if ((err = snd_vx_pcm_new(chip)) < 0)
+ err = snd_vx_pcm_new(chip);
+ if (err < 0)
return err;
- if ((err = snd_vx_mixer_new(chip)) < 0)
+ err = snd_vx_mixer_new(chip);
+ if (err < 0)
return err;
- if (chip->ops->add_controls)
- if ((err = chip->ops->add_controls(chip)) < 0)
+ if (chip->ops->add_controls) {
+ err = chip->ops->add_controls(chip);
+ if (err < 0)
return err;
+ }
chip->chip_status |= VX_STAT_DEVICE_INIT;
chip->chip_status |= VX_STAT_CHIP_INIT;
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index 13099f8c84d6..53d78eb13c53 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -910,7 +910,8 @@ int snd_vx_mixer_new(struct vx_core *chip)
temp = vx_control_output_level;
temp.index = i;
temp.tlv.p = chip->hw->output_level_db_scale;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
@@ -921,22 +922,26 @@ int snd_vx_mixer_new(struct vx_core *chip)
temp.index = i;
temp.name = "PCM Playback Volume";
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
temp = vx_control_output_switch;
temp.index = i;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
temp = vx_control_monitor_gain;
temp.index = i;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
temp = vx_control_monitor_switch;
temp.index = i;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
for (i = 0; i < chip->hw->num_outs; i++) {
@@ -944,20 +949,25 @@ int snd_vx_mixer_new(struct vx_core *chip)
temp.index = i;
temp.name = "PCM Capture Volume";
temp.private_value = (i * 2) | (1 << 8);
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
/* Audio source */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip));
+ if (err < 0)
return err;
/* clock mode */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip));
+ if (err < 0)
return err;
/* IEC958 controls */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip));
+ if (err < 0)
return err;
/* VU, peak, saturation meters */
for (c = 0; c < 2; c++) {
@@ -968,7 +978,8 @@ int snd_vx_mixer_new(struct vx_core *chip)
temp = vx_control_saturation;
temp.index = i;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
sprintf(name, "%s VU Meter", dir[c]);
@@ -976,14 +987,16 @@ int snd_vx_mixer_new(struct vx_core *chip)
temp.index = i;
temp.name = name;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
sprintf(name, "%s Peak Meter", dir[c]);
temp = vx_control_peak_meter;
temp.index = i;
temp.name = name;
temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
}
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index daffda99b4f7..3924f5283745 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -341,10 +341,12 @@ static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
}
}
- if ((err = vx_conf_pipe(chip, pipe)) < 0)
+ err = vx_conf_pipe(chip, pipe);
+ if (err < 0)
return err;
- if ((err = vx_send_irqa(chip)) < 0)
+ err = vx_send_irqa(chip);
+ if (err < 0)
return err;
/* If it completes successfully, wait for the pipes
@@ -680,8 +682,9 @@ static void vx_pcm_playback_transfer(struct vx_core *chip,
if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
return;
for (i = 0; i < nchunks; i++) {
- if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
- chip->ibl.size)) < 0)
+ err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
+ chip->ibl.size);
+ if (err < 0)
return;
}
}
@@ -698,7 +701,8 @@ static void vx_pcm_playback_update(struct vx_core *chip,
struct snd_pcm_runtime *runtime = subs->runtime;
if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
- if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
+ err = vx_update_pipe_position(chip, runtime, pipe);
+ if (err < 0)
return;
if (pipe->transferred >= (int)runtime->period_size) {
pipe->transferred %= runtime->period_size;
@@ -747,11 +751,13 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
pipe->running = 0;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
+ err = vx_toggle_pipe(chip, pipe, 0);
+ if (err < 0)
return err;
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
+ err = vx_toggle_pipe(chip, pipe, 1);
+ if (err < 0)
return err;
break;
default:
@@ -792,13 +798,15 @@ static int vx_pcm_prepare(struct snd_pcm_substream *subs)
snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
vx_init_rmh(&rmh, CMD_FREE_PIPE);
vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
- if ((err = vx_send_msg(chip, &rmh)) < 0)
+ err = vx_send_msg(chip, &rmh);
+ if (err < 0)
return err;
vx_init_rmh(&rmh, CMD_RES_PIPE);
vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
if (data_mode)
rmh.Cmd[0] |= BIT_DATA_MODE;
- if ((err = vx_send_msg(chip, &rmh)) < 0)
+ err = vx_send_msg(chip, &rmh);
+ if (err < 0)
return err;
pipe->data_mode = data_mode;
}
@@ -810,7 +818,8 @@ static int vx_pcm_prepare(struct snd_pcm_substream *subs)
}
vx_set_clock(chip, runtime->rate);
- if ((err = vx_set_format(chip, pipe, runtime)) < 0)
+ err = vx_set_format(chip, pipe, runtime);
+ if (err < 0)
return err;
if (vx_is_pcmcia(chip)) {
@@ -1187,7 +1196,8 @@ int snd_vx_pcm_new(struct vx_core *chip)
unsigned int i;
int err;
- if ((err = vx_init_audio_io(chip)) < 0)
+ err = vx_init_audio_io(chip);
+ if (err < 0)
return err;
for (i = 0; i < chip->hw->num_codecs; i++) {
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 9897bd26a438..fd109bea4c53 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -18,8 +18,25 @@ config SND_DICE
select SND_HWDEP
select SND_FIREWIRE_LIB
help
- Say Y here to include support for many DACs based on the DICE
- chip family (DICE-II/Jr/Mini) which TC Applied Technologies produces.
+ Say Y here to include support for devices based on the DICE chip family
+ (DICE-II/TCD2210(Mini)/TCD2220(Jr.)) which TC Applied Technologies (TCAT) produced.
+ * Allen and Heath Zed R16
+ * Alesis iO 14/26 FireWire, MasterControl, MultiMix 8/12/16 FireWire
+ * Avid Mbox 3 Pro
+ * FlexRadio Systems FLEX-3000, FLEX-5000
+ * Focusrite Liquid Saffire 56
+ * Focusrite Saffire Pro 14, Pro 24, Pro 24 DSP, Pro 26, Pro 40(TCD2220)
+ * Harman Music Group Lexicon I-ONIX FW810S
+ * Loud Technologies Mackie Onyx Blackbird, Onyx 820i/1220i/1620i/1640i (latter models)
+ * M-Audio ProFire 610/2626
+ * Mytek Stereo192-DSD DAC
+ * Midas Klark Teknik VeniceF series
+ * PreSonus FireStudio, FireStudio Mobile, FireStudio Project, FireStudio Tube
+ * PreSonus StudioLive 16.4.2, 16.0.2, 24.4.2, 32.4.2
+ * Solid State Logic Duende Classic, Duende Mini
+ * TC Electronic Studio Konnekt 48, Konnekt 24D, Konnekt Live, Impact Twin
+ * TC Electronic Digital Konnekt x32, Desktop Konnekt 6
+ * Weiss Engineering ADC2, Vesta, Minerva, AFI1, DAC1, INT202, DAC202
To compile this driver as a module, choose M here: the module
will be called snd-dice.
@@ -38,7 +55,7 @@ config SND_OXFW
* Mackie(Loud) Onyx 1640i (former model)
* Mackie(Loud) Onyx Satellite
* Mackie(Loud) Tapco Link.Firewire
- * Mackie(Loud) d.4 pro
+ * Mackie(Loud) d.2 pro/d.4 pro (built-in FireWire card with OXFW971 ASIC)
* Mackie(Loud) U.420/U.420d
* TASCAM FireOne
* Stanton Controllers & Systems 1 Deck/Mixer
@@ -84,7 +101,7 @@ config SND_BEBOB
* PreSonus FIREBOX/FIREPOD/FP10/Inspire1394
* BridgeCo RDAudio1/Audio5
* Mackie Onyx 1220/1620/1640 (FireWire I/O Card)
- * Mackie d.2 (FireWire Option) and d.2 Pro
+ * Mackie d.2 (optional FireWire card with DM1000 ASIC)
* Stanton FinalScratch 2 (ScratchAmp)
* Tascam IF-FW/DM
* Behringer XENIX UFX 1204/1604
@@ -110,6 +127,7 @@ config SND_BEBOB
* M-Audio Ozonic/NRV10/ProfireLightBridge
* M-Audio FireWire 1814/ProjectMix IO
* Digidesign Mbox 2 Pro
+ * ToneWeal FW66
To compile this driver as a module, choose M here: the module
will be called snd-bebob.
@@ -148,12 +166,16 @@ config SND_FIREWIRE_MOTU
select SND_HWDEP
help
Say Y here to enable support for FireWire devices which MOTU produced:
+ * 828
+ * 896
* 828mk2
* Traveler
* Ultralite
* 8pre
* 828mk3 (FireWire only)
* 828mk3 (Hybrid)
+ * Ultralite mk3 (FireWire only)
+ * Ultralite mk3 (Hybrid)
* Audio Express
* 4pre
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c
index fea92e148790..d9c700f652bb 100644
--- a/sound/firewire/amdtp-am824.c
+++ b/sound/firewire/amdtp-am824.c
@@ -410,10 +410,10 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
* @s: the AMDTP stream to initialize
* @unit: the target of the stream
* @dir: the direction of stream
- * @flags: the packet transmission method to use
+ * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants.
*/
int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir, enum cip_flags flags)
+ enum amdtp_stream_direction dir, unsigned int flags)
{
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h
index 06d280783581..2b092b1061ba 100644
--- a/sound/firewire/amdtp-am824.h
+++ b/sound/firewire/amdtp-am824.h
@@ -45,5 +45,5 @@ void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
struct snd_rawmidi_substream *midi);
int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir, enum cip_flags flags);
+ enum amdtp_stream_direction dir, unsigned int flags);
#endif
diff --git a/sound/firewire/amdtp-stream-trace.h b/sound/firewire/amdtp-stream-trace.h
index aa53c13b89d3..5fd2aeccdfc2 100644
--- a/sound/firewire/amdtp-stream-trace.h
+++ b/sound/firewire/amdtp-stream-trace.h
@@ -49,7 +49,7 @@ TRACE_EVENT(amdtp_packet,
__entry->data_blocks = data_blocks;
__entry->data_block_counter = data_block_counter,
__entry->packet_index = packet_index;
- __entry->irq = !!in_interrupt();
+ __entry->irq = !!in_softirq();
__entry->index = index;
),
TP_printk(
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 5805c5de39fb..9be2260e4ca2 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -20,7 +20,7 @@
#define CYCLES_PER_SECOND 8000
#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
-#define OHCI_MAX_SECOND 8
+#define OHCI_SECOND_MODULUS 8
/* Always support Linux tracing subsystem. */
#define CREATE_TRACE_POINTS
@@ -33,7 +33,8 @@
#define TAG_NO_CIP_HEADER 0
#define TAG_CIP 1
-/* common isochronous packet header parameters */
+// Common Isochronous Packet (CIP) header parameters. Use two quadlets CIP header when supported.
+#define CIP_HEADER_QUADLETS 2
#define CIP_EOH_SHIFT 31
#define CIP_EOH (1u << CIP_EOH_SHIFT)
#define CIP_EOH_MASK 0x80000000
@@ -48,36 +49,46 @@
#define CIP_FMT_MASK 0x3f000000
#define CIP_FDF_MASK 0x00ff0000
#define CIP_FDF_SHIFT 16
+#define CIP_FDF_NO_DATA 0xff
#define CIP_SYT_MASK 0x0000ffff
#define CIP_SYT_NO_INFO 0xffff
+#define CIP_SYT_CYCLE_MODULUS 16
+#define CIP_NO_DATA ((CIP_FDF_NO_DATA << CIP_FDF_SHIFT) | CIP_SYT_NO_INFO)
+
+#define CIP_HEADER_SIZE (sizeof(__be32) * CIP_HEADER_QUADLETS)
/* Audio and Music transfer protocol specific parameters */
#define CIP_FMT_AM 0x10
#define AMDTP_FDF_NO_DATA 0xff
-// For iso header, tstamp and 2 CIP header.
-#define IR_CTX_HEADER_SIZE_CIP 16
// For iso header and tstamp.
-#define IR_CTX_HEADER_SIZE_NO_CIP 8
+#define IR_CTX_HEADER_DEFAULT_QUADLETS 2
+// Add nothing.
+#define IR_CTX_HEADER_SIZE_NO_CIP (sizeof(__be32) * IR_CTX_HEADER_DEFAULT_QUADLETS)
+// Add two quadlets CIP header.
+#define IR_CTX_HEADER_SIZE_CIP (IR_CTX_HEADER_SIZE_NO_CIP + CIP_HEADER_SIZE)
#define HEADER_TSTAMP_MASK 0x0000ffff
-#define IT_PKT_HEADER_SIZE_CIP 8 // For 2 CIP header.
+#define IT_PKT_HEADER_SIZE_CIP CIP_HEADER_SIZE
#define IT_PKT_HEADER_SIZE_NO_CIP 0 // Nothing.
-static void pcm_period_work(struct work_struct *work);
+// The initial firmware of OXFW970 can postpone transmission of packet during finishing
+// asynchronous transaction. This module accepts 5 cycles to skip as maximum to avoid buffer
+// overrun. Actual device can skip more, then this module stops the packet streaming.
+#define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5
/**
* amdtp_stream_init - initialize an AMDTP stream structure
* @s: the AMDTP stream to initialize
* @unit: the target of the stream
* @dir: the direction of stream
- * @flags: the packet transmission method to use
+ * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants.
* @fmt: the value of fmt field in CIP header
* @process_ctx_payloads: callback handler to process payloads of isoc context
* @protocol_size: the size to allocate newly for protocol
*/
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir, enum cip_flags flags,
+ enum amdtp_stream_direction dir, unsigned int flags,
unsigned int fmt,
amdtp_stream_process_ctx_payloads_t process_ctx_payloads,
unsigned int protocol_size)
@@ -94,18 +105,13 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->flags = flags;
s->context = ERR_PTR(-1);
mutex_init(&s->mutex);
- INIT_WORK(&s->period_work, pcm_period_work);
s->packet_index = 0;
- init_waitqueue_head(&s->callback_wait);
- s->callbacked = false;
+ init_waitqueue_head(&s->ready_wait);
s->fmt = fmt;
s->process_ctx_payloads = process_ctx_payloads;
- if (dir == AMDTP_OUT_STREAM)
- s->ctx_data.rx.syt_override = -1;
-
return 0;
}
EXPORT_SYMBOL(amdtp_stream_init);
@@ -183,14 +189,13 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
unsigned int maximum_usec_per_period;
int err;
- hw->info = SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ hw->info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_JOINT_DUPLEX |
SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID;
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
- /* SNDRV_PCM_INFO_BATCH */
hw->periods_min = 2;
hw->periods_max = UINT_MAX;
@@ -287,22 +292,29 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
s->syt_interval = amdtp_syt_intervals[sfc];
// default buffering in the device.
- if (s->direction == AMDTP_OUT_STREAM) {
- s->ctx_data.rx.transfer_delay =
- TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
-
- if (s->flags & CIP_BLOCKING) {
- // additional buffering needed to adjust for no-data
- // packets.
- s->ctx_data.rx.transfer_delay +=
- TICKS_PER_SECOND * s->syt_interval / rate;
- }
- }
+ s->transfer_delay = TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
+
+ // additional buffering needed to adjust for no-data packets.
+ if (s->flags & CIP_BLOCKING)
+ s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
return 0;
}
EXPORT_SYMBOL(amdtp_stream_set_parameters);
+// The CIP header is processed in context header apart from context payload.
+static int amdtp_stream_get_max_ctx_payload_size(struct amdtp_stream *s)
+{
+ unsigned int multiplier;
+
+ if (s->flags & CIP_JUMBO_PAYLOAD)
+ multiplier = IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES;
+ else
+ multiplier = 1;
+
+ return s->syt_interval * s->data_block_quadlets * sizeof(__be32) * multiplier;
+}
+
/**
* amdtp_stream_get_max_payload - get the stream's packet size
* @s: the AMDTP stream
@@ -312,16 +324,14 @@ EXPORT_SYMBOL(amdtp_stream_set_parameters);
*/
unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
{
- unsigned int multiplier = 1;
- unsigned int cip_header_size = 0;
+ unsigned int cip_header_size;
- if (s->flags & CIP_JUMBO_PAYLOAD)
- multiplier = 5;
if (!(s->flags & CIP_NO_HEADER))
- cip_header_size = sizeof(__be32) * 2;
+ cip_header_size = CIP_HEADER_SIZE;
+ else
+ cip_header_size = 0;
- return cip_header_size +
- s->syt_interval * s->data_block_quadlets * sizeof(__be32) * multiplier;
+ return cip_header_size + amdtp_stream_get_max_ctx_payload_size(s);
}
EXPORT_SYMBOL(amdtp_stream_get_max_payload);
@@ -333,32 +343,46 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload);
*/
void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
{
- cancel_work_sync(&s->period_work);
s->pcm_buffer_pointer = 0;
s->pcm_period_pointer = 0;
}
EXPORT_SYMBOL(amdtp_stream_pcm_prepare);
-static unsigned int calculate_data_blocks(unsigned int *data_block_state,
- bool is_blocking, bool is_no_info,
- unsigned int syt_interval, enum cip_sfc sfc)
+static void pool_blocking_data_blocks(struct amdtp_stream *s, struct seq_desc *descs,
+ const unsigned int seq_size, unsigned int seq_tail,
+ unsigned int count)
{
- unsigned int data_blocks;
+ const unsigned int syt_interval = s->syt_interval;
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ struct seq_desc *desc = descs + seq_tail;
- /* Blocking mode. */
- if (is_blocking) {
- /* This module generate empty packet for 'no data'. */
- if (is_no_info)
- data_blocks = 0;
+ if (desc->syt_offset != CIP_SYT_NO_INFO)
+ desc->data_blocks = syt_interval;
else
- data_blocks = syt_interval;
- /* Non-blocking mode. */
- } else {
+ desc->data_blocks = 0;
+
+ seq_tail = (seq_tail + 1) % seq_size;
+ }
+}
+
+static void pool_ideal_nonblocking_data_blocks(struct amdtp_stream *s, struct seq_desc *descs,
+ const unsigned int seq_size, unsigned int seq_tail,
+ unsigned int count)
+{
+ const enum cip_sfc sfc = s->sfc;
+ unsigned int state = s->ctx_data.rx.data_block_state;
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ struct seq_desc *desc = descs + seq_tail;
+
if (!cip_sfc_is_base_44100(sfc)) {
// Sample_rate / 8000 is an integer, and precomputed.
- data_blocks = *data_block_state;
+ desc->data_blocks = state;
} else {
- unsigned int phase = *data_block_state;
+ unsigned int phase = state;
/*
* This calculates the number of data blocks per packet so that
@@ -370,18 +394,19 @@ static unsigned int calculate_data_blocks(unsigned int *data_block_state,
*/
if (sfc == CIP_SFC_44100)
/* 6 6 5 6 5 6 5 ... */
- data_blocks = 5 + ((phase & 1) ^
- (phase == 0 || phase >= 40));
+ desc->data_blocks = 5 + ((phase & 1) ^ (phase == 0 || phase >= 40));
else
/* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
- data_blocks = 11 * (sfc >> 1) + (phase == 0);
+ desc->data_blocks = 11 * (sfc >> 1) + (phase == 0);
if (++phase >= (80 >> (sfc >> 1)))
phase = 0;
- *data_block_state = phase;
+ state = phase;
}
+
+ seq_tail = (seq_tail + 1) % seq_size;
}
- return data_blocks;
+ s->ctx_data.rx.data_block_state = state;
}
static unsigned int calculate_syt_offset(unsigned int *last_syt_offset,
@@ -423,6 +448,149 @@ static unsigned int calculate_syt_offset(unsigned int *last_syt_offset,
return syt_offset;
}
+static void pool_ideal_syt_offsets(struct amdtp_stream *s, struct seq_desc *descs,
+ const unsigned int seq_size, unsigned int seq_tail,
+ unsigned int count)
+{
+ const enum cip_sfc sfc = s->sfc;
+ unsigned int last = s->ctx_data.rx.last_syt_offset;
+ unsigned int state = s->ctx_data.rx.syt_offset_state;
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ struct seq_desc *desc = descs + seq_tail;
+
+ desc->syt_offset = calculate_syt_offset(&last, &state, sfc);
+
+ seq_tail = (seq_tail + 1) % seq_size;
+ }
+
+ s->ctx_data.rx.last_syt_offset = last;
+ s->ctx_data.rx.syt_offset_state = state;
+}
+
+static unsigned int compute_syt_offset(unsigned int syt, unsigned int cycle,
+ unsigned int transfer_delay)
+{
+ unsigned int cycle_lo = (cycle % CYCLES_PER_SECOND) & 0x0f;
+ unsigned int syt_cycle_lo = (syt & 0xf000) >> 12;
+ unsigned int syt_offset;
+
+ // Round up.
+ if (syt_cycle_lo < cycle_lo)
+ syt_cycle_lo += CIP_SYT_CYCLE_MODULUS;
+ syt_cycle_lo -= cycle_lo;
+
+ // Subtract transfer delay so that the synchronization offset is not so large
+ // at transmission.
+ syt_offset = syt_cycle_lo * TICKS_PER_CYCLE + (syt & 0x0fff);
+ if (syt_offset < transfer_delay)
+ syt_offset += CIP_SYT_CYCLE_MODULUS * TICKS_PER_CYCLE;
+
+ return syt_offset - transfer_delay;
+}
+
+// Both of the producer and consumer of the queue runs in the same clock of IEEE 1394 bus.
+// Additionally, the sequence of tx packets is severely checked against any discontinuity
+// before filling entries in the queue. The calculation is safe even if it looks fragile by
+// overrun.
+static unsigned int calculate_cached_cycle_count(struct amdtp_stream *s, unsigned int head)
+{
+ const unsigned int cache_size = s->ctx_data.tx.cache.size;
+ unsigned int cycles = s->ctx_data.tx.cache.tail;
+
+ if (cycles < head)
+ cycles += cache_size;
+ cycles -= head;
+
+ return cycles;
+}
+
+static void cache_seq(struct amdtp_stream *s, const struct pkt_desc *descs, unsigned int desc_count)
+{
+ const unsigned int transfer_delay = s->transfer_delay;
+ const unsigned int cache_size = s->ctx_data.tx.cache.size;
+ struct seq_desc *cache = s->ctx_data.tx.cache.descs;
+ unsigned int cache_tail = s->ctx_data.tx.cache.tail;
+ bool aware_syt = !(s->flags & CIP_UNAWARE_SYT);
+ int i;
+
+ for (i = 0; i < desc_count; ++i) {
+ struct seq_desc *dst = cache + cache_tail;
+ const struct pkt_desc *src = descs + i;
+
+ if (aware_syt && src->syt != CIP_SYT_NO_INFO)
+ dst->syt_offset = compute_syt_offset(src->syt, src->cycle, transfer_delay);
+ else
+ dst->syt_offset = CIP_SYT_NO_INFO;
+ dst->data_blocks = src->data_blocks;
+
+ cache_tail = (cache_tail + 1) % cache_size;
+ }
+
+ s->ctx_data.tx.cache.tail = cache_tail;
+}
+
+static void pool_ideal_seq_descs(struct amdtp_stream *s, unsigned int count)
+{
+ struct seq_desc *descs = s->ctx_data.rx.seq.descs;
+ unsigned int seq_tail = s->ctx_data.rx.seq.tail;
+ const unsigned int seq_size = s->ctx_data.rx.seq.size;
+
+ pool_ideal_syt_offsets(s, descs, seq_size, seq_tail, count);
+
+ if (s->flags & CIP_BLOCKING)
+ pool_blocking_data_blocks(s, descs, seq_size, seq_tail, count);
+ else
+ pool_ideal_nonblocking_data_blocks(s, descs, seq_size, seq_tail, count);
+
+ s->ctx_data.rx.seq.tail = (seq_tail + count) % seq_size;
+}
+
+static void pool_replayed_seq(struct amdtp_stream *s, unsigned int count)
+{
+ struct amdtp_stream *target = s->ctx_data.rx.replay_target;
+ const struct seq_desc *cache = target->ctx_data.tx.cache.descs;
+ const unsigned int cache_size = target->ctx_data.tx.cache.size;
+ unsigned int cache_head = s->ctx_data.rx.cache_head;
+ struct seq_desc *descs = s->ctx_data.rx.seq.descs;
+ const unsigned int seq_size = s->ctx_data.rx.seq.size;
+ unsigned int seq_tail = s->ctx_data.rx.seq.tail;
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ descs[seq_tail] = cache[cache_head];
+ seq_tail = (seq_tail + 1) % seq_size;
+ cache_head = (cache_head + 1) % cache_size;
+ }
+
+ s->ctx_data.rx.seq.tail = seq_tail;
+ s->ctx_data.rx.cache_head = cache_head;
+}
+
+static void pool_seq_descs(struct amdtp_stream *s, unsigned int count)
+{
+ struct amdtp_domain *d = s->domain;
+
+ if (!d->replay.enable || !s->ctx_data.rx.replay_target) {
+ pool_ideal_seq_descs(s, count);
+ } else {
+ if (!d->replay.on_the_fly) {
+ pool_replayed_seq(s, count);
+ } else {
+ struct amdtp_stream *tx = s->ctx_data.rx.replay_target;
+ const unsigned int cache_size = tx->ctx_data.tx.cache.size;
+ const unsigned int cache_head = s->ctx_data.rx.cache_head;
+ unsigned int cached_cycles = calculate_cached_cycle_count(tx, cache_head);
+
+ if (cached_cycles > count && cached_cycles > cache_size / 2)
+ pool_replayed_seq(s, count);
+ else
+ pool_ideal_seq_descs(s, count);
+ }
+ }
+}
+
static void update_pcm_pointers(struct amdtp_stream *s,
struct snd_pcm_substream *pcm,
unsigned int frames)
@@ -437,18 +605,21 @@ static void update_pcm_pointers(struct amdtp_stream *s,
s->pcm_period_pointer += frames;
if (s->pcm_period_pointer >= pcm->runtime->period_size) {
s->pcm_period_pointer -= pcm->runtime->period_size;
- queue_work(system_highpri_wq, &s->period_work);
- }
-}
-static void pcm_period_work(struct work_struct *work)
-{
- struct amdtp_stream *s = container_of(work, struct amdtp_stream,
- period_work);
- struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
-
- if (pcm)
- snd_pcm_period_elapsed(pcm);
+ // The program in user process should periodically check the status of intermediate
+ // buffer associated to PCM substream to process PCM frames in the buffer, instead
+ // of receiving notification of period elapsed by poll wait.
+ if (!pcm->runtime->no_period_wakeup) {
+ if (in_softirq()) {
+ // In software IRQ context for 1394 OHCI.
+ snd_pcm_period_elapsed(pcm);
+ } else {
+ // In process context of ALSA PCM application under acquired lock of
+ // PCM substream.
+ snd_pcm_period_elapsed_under_stream_lock(pcm);
+ }
+ }
+ }
}
static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params,
@@ -505,7 +676,7 @@ static void generate_cip_header(struct amdtp_stream *s, __be32 cip_header[2],
}
static void build_it_pkt_header(struct amdtp_stream *s, unsigned int cycle,
- struct fw_iso_packet *params,
+ struct fw_iso_packet *params, unsigned int header_length,
unsigned int data_blocks,
unsigned int data_block_counter,
unsigned int syt, unsigned int index)
@@ -516,16 +687,15 @@ static void build_it_pkt_header(struct amdtp_stream *s, unsigned int cycle,
payload_length = data_blocks * sizeof(__be32) * s->data_block_quadlets;
params->payload_length = payload_length;
- if (!(s->flags & CIP_NO_HEADER)) {
+ if (header_length > 0) {
cip_header = (__be32 *)params->header;
generate_cip_header(s, cip_header, data_block_counter, syt);
- params->header_length = 2 * sizeof(__be32);
- payload_length += params->header_length;
+ params->header_length = header_length;
} else {
cip_header = NULL;
}
- trace_amdtp_packet(s, cycle, cip_header, payload_length, data_blocks,
+ trace_amdtp_packet(s, cycle, cip_header, payload_length + header_length, data_blocks,
data_block_counter, s->packet_index, index);
}
@@ -569,8 +739,7 @@ static int check_cip_header(struct amdtp_stream *s, const __be32 *buf,
/* Calculate data blocks */
fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;
- if (payload_length < sizeof(__be32) * 2 ||
- (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
+ if (payload_length == 0 || (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
*data_blocks = 0;
} else {
unsigned int data_block_quadlets =
@@ -585,8 +754,7 @@ static int check_cip_header(struct amdtp_stream *s, const __be32 *buf,
if (s->flags & CIP_WRONG_DBS)
data_block_quadlets = s->data_block_quadlets;
- *data_blocks = (payload_length / sizeof(__be32) - 2) /
- data_block_quadlets;
+ *data_blocks = payload_length / sizeof(__be32) / data_block_quadlets;
}
/* Check data block counter continuity */
@@ -620,109 +788,163 @@ static int check_cip_header(struct amdtp_stream *s, const __be32 *buf,
*data_block_counter = dbc;
- *syt = cip_header[1] & CIP_SYT_MASK;
+ if (!(s->flags & CIP_UNAWARE_SYT))
+ *syt = cip_header[1] & CIP_SYT_MASK;
return 0;
}
static int parse_ir_ctx_header(struct amdtp_stream *s, unsigned int cycle,
const __be32 *ctx_header,
- unsigned int *payload_length,
unsigned int *data_blocks,
unsigned int *data_block_counter,
unsigned int *syt, unsigned int packet_index, unsigned int index)
{
+ unsigned int payload_length;
const __be32 *cip_header;
unsigned int cip_header_size;
- int err;
- *payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT;
+ payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT;
if (!(s->flags & CIP_NO_HEADER))
- cip_header_size = 8;
+ cip_header_size = CIP_HEADER_SIZE;
else
cip_header_size = 0;
- if (*payload_length > cip_header_size + s->ctx_data.tx.max_ctx_payload_length) {
+ if (payload_length > cip_header_size + s->ctx_data.tx.max_ctx_payload_length) {
dev_err(&s->unit->device,
"Detect jumbo payload: %04x %04x\n",
- *payload_length, cip_header_size + s->ctx_data.tx.max_ctx_payload_length);
+ payload_length, cip_header_size + s->ctx_data.tx.max_ctx_payload_length);
return -EIO;
}
if (cip_header_size > 0) {
- cip_header = ctx_header + 2;
- err = check_cip_header(s, cip_header, *payload_length,
- data_blocks, data_block_counter, syt);
- if (err < 0)
- return err;
+ if (payload_length >= cip_header_size) {
+ int err;
+
+ cip_header = ctx_header + IR_CTX_HEADER_DEFAULT_QUADLETS;
+ err = check_cip_header(s, cip_header, payload_length - cip_header_size,
+ data_blocks, data_block_counter, syt);
+ if (err < 0)
+ return err;
+ } else {
+ // Handle the cycle so that empty packet arrives.
+ cip_header = NULL;
+ *data_blocks = 0;
+ *syt = 0;
+ }
} else {
cip_header = NULL;
- err = 0;
- *data_blocks = *payload_length / sizeof(__be32) /
- s->data_block_quadlets;
+ *data_blocks = payload_length / sizeof(__be32) / s->data_block_quadlets;
*syt = 0;
if (*data_block_counter == UINT_MAX)
*data_block_counter = 0;
}
- trace_amdtp_packet(s, cycle, cip_header, *payload_length, *data_blocks,
+ trace_amdtp_packet(s, cycle, cip_header, payload_length, *data_blocks,
*data_block_counter, packet_index, index);
- return err;
+ return 0;
}
// In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On
// the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent
// it. Thus, via Linux firewire subsystem, we can get the 3 bits for second.
-static inline u32 compute_cycle_count(__be32 ctx_header_tstamp)
+static inline u32 compute_ohci_cycle_count(__be32 ctx_header_tstamp)
{
u32 tstamp = be32_to_cpu(ctx_header_tstamp) & HEADER_TSTAMP_MASK;
return (((tstamp >> 13) & 0x07) * 8000) + (tstamp & 0x1fff);
}
-static inline u32 increment_cycle_count(u32 cycle, unsigned int addend)
+static inline u32 increment_ohci_cycle_count(u32 cycle, unsigned int addend)
{
cycle += addend;
- if (cycle >= OHCI_MAX_SECOND * CYCLES_PER_SECOND)
- cycle -= OHCI_MAX_SECOND * CYCLES_PER_SECOND;
+ if (cycle >= OHCI_SECOND_MODULUS * CYCLES_PER_SECOND)
+ cycle -= OHCI_SECOND_MODULUS * CYCLES_PER_SECOND;
return cycle;
}
+static int compare_ohci_cycle_count(u32 lval, u32 rval)
+{
+ if (lval == rval)
+ return 0;
+ else if (lval < rval && rval - lval < OHCI_SECOND_MODULUS * CYCLES_PER_SECOND / 2)
+ return -1;
+ else
+ return 1;
+}
+
// Align to actual cycle count for the packet which is going to be scheduled.
// This module queued the same number of isochronous cycle as the size of queue
// to kip isochronous cycle, therefore it's OK to just increment the cycle by
// the size of queue for scheduled cycle.
-static inline u32 compute_it_cycle(const __be32 ctx_header_tstamp,
- unsigned int queue_size)
+static inline u32 compute_ohci_it_cycle(const __be32 ctx_header_tstamp,
+ unsigned int queue_size)
{
- u32 cycle = compute_cycle_count(ctx_header_tstamp);
- return increment_cycle_count(cycle, queue_size);
+ u32 cycle = compute_ohci_cycle_count(ctx_header_tstamp);
+ return increment_ohci_cycle_count(cycle, queue_size);
}
static int generate_device_pkt_descs(struct amdtp_stream *s,
struct pkt_desc *descs,
const __be32 *ctx_header,
- unsigned int packets)
+ unsigned int packets,
+ unsigned int *desc_count)
{
+ unsigned int next_cycle = s->next_cycle;
unsigned int dbc = s->data_block_counter;
unsigned int packet_index = s->packet_index;
unsigned int queue_size = s->queue_size;
int i;
int err;
+ *desc_count = 0;
for (i = 0; i < packets; ++i) {
- struct pkt_desc *desc = descs + i;
+ struct pkt_desc *desc = descs + *desc_count;
unsigned int cycle;
- unsigned int payload_length;
+ bool lost;
unsigned int data_blocks;
unsigned int syt;
- cycle = compute_cycle_count(ctx_header[1]);
+ cycle = compute_ohci_cycle_count(ctx_header[1]);
+ lost = (next_cycle != cycle);
+ if (lost) {
+ if (s->flags & CIP_NO_HEADER) {
+ // Fireface skips transmission just for an isoc cycle corresponding
+ // to empty packet.
+ unsigned int prev_cycle = next_cycle;
+
+ next_cycle = increment_ohci_cycle_count(next_cycle, 1);
+ lost = (next_cycle != cycle);
+ if (!lost) {
+ // Prepare a description for the skipped cycle for
+ // sequence replay.
+ desc->cycle = prev_cycle;
+ desc->syt = 0;
+ desc->data_blocks = 0;
+ desc->data_block_counter = dbc;
+ desc->ctx_payload = NULL;
+ ++desc;
+ ++(*desc_count);
+ }
+ } else if (s->flags & CIP_JUMBO_PAYLOAD) {
+ // OXFW970 skips transmission for several isoc cycles during
+ // asynchronous transaction. The sequence replay is impossible due
+ // to the reason.
+ unsigned int safe_cycle = increment_ohci_cycle_count(next_cycle,
+ IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES);
+ lost = (compare_ohci_cycle_count(safe_cycle, cycle) > 0);
+ }
+ if (lost) {
+ dev_err(&s->unit->device, "Detect discontinuity of cycle: %d %d\n",
+ next_cycle, cycle);
+ return -EIO;
+ }
+ }
- err = parse_ir_ctx_header(s, cycle, ctx_header, &payload_length,
- &data_blocks, &dbc, &syt, packet_index, i);
+ err = parse_ir_ctx_header(s, cycle, ctx_header, &data_blocks, &dbc, &syt,
+ packet_index, i);
if (err < 0)
return err;
@@ -735,12 +957,13 @@ static int generate_device_pkt_descs(struct amdtp_stream *s,
if (!(s->flags & CIP_DBC_IS_END_EVENT))
dbc = (dbc + desc->data_blocks) & 0xff;
- ctx_header +=
- s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header);
-
+ next_cycle = increment_ohci_cycle_count(next_cycle, 1);
+ ++(*desc_count);
+ ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header);
packet_index = (packet_index + 1) % queue_size;
}
+ s->next_cycle = next_cycle;
s->data_block_counter = dbc;
return 0;
@@ -757,29 +980,28 @@ static unsigned int compute_syt(unsigned int syt_offset, unsigned int cycle,
return syt & CIP_SYT_MASK;
}
-static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs,
- const __be32 *ctx_header, unsigned int packets,
- const struct seq_desc *seq_descs,
- unsigned int seq_size)
+static void generate_pkt_descs(struct amdtp_stream *s, const __be32 *ctx_header, unsigned int packets)
{
+ struct pkt_desc *descs = s->pkt_descs;
+ const struct seq_desc *seq_descs = s->ctx_data.rx.seq.descs;
+ const unsigned int seq_size = s->ctx_data.rx.seq.size;
unsigned int dbc = s->data_block_counter;
- unsigned int seq_index = s->ctx_data.rx.seq_index;
+ unsigned int seq_head = s->ctx_data.rx.seq.head;
+ bool aware_syt = !(s->flags & CIP_UNAWARE_SYT);
int i;
for (i = 0; i < packets; ++i) {
struct pkt_desc *desc = descs + i;
unsigned int index = (s->packet_index + i) % s->queue_size;
- const struct seq_desc *seq = seq_descs + seq_index;
- unsigned int syt;
+ const struct seq_desc *seq = seq_descs + seq_head;
- desc->cycle = compute_it_cycle(*ctx_header, s->queue_size);
+ desc->cycle = compute_ohci_it_cycle(*ctx_header, s->queue_size);
+
+ if (aware_syt && seq->syt_offset != CIP_SYT_NO_INFO)
+ desc->syt = compute_syt(seq->syt_offset, desc->cycle, s->transfer_delay);
+ else
+ desc->syt = CIP_SYT_NO_INFO;
- syt = seq->syt_offset;
- if (syt != CIP_SYT_NO_INFO) {
- syt = compute_syt(syt, desc->cycle,
- s->ctx_data.rx.transfer_delay);
- }
- desc->syt = syt;
desc->data_blocks = seq->data_blocks;
if (s->flags & CIP_DBC_IS_END_EVENT)
@@ -792,19 +1014,19 @@ static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs,
desc->ctx_payload = s->buffer.packets[index].buffer;
- seq_index = (seq_index + 1) % seq_size;
+ seq_head = (seq_head + 1) % seq_size;
++ctx_header;
}
s->data_block_counter = dbc;
- s->ctx_data.rx.seq_index = seq_index;
+ s->ctx_data.rx.seq.head = seq_head;
}
static inline void cancel_stream(struct amdtp_stream *s)
{
s->packet_index = -1;
- if (in_interrupt())
+ if (in_softirq())
amdtp_stream_pcm_abort(s);
WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN);
}
@@ -822,16 +1044,17 @@ static void process_ctx_payloads(struct amdtp_stream *s,
update_pcm_pointers(s, pcm, pcm_frames);
}
-static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
- size_t header_length, void *header,
- void *private_data)
+static void process_rx_packets(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data)
{
struct amdtp_stream *s = private_data;
const struct amdtp_domain *d = s->domain;
const __be32 *ctx_header = header;
- unsigned int events_per_period = s->ctx_data.rx.events_per_period;
+ const unsigned int events_per_period = d->events_per_period;
unsigned int event_count = s->ctx_data.rx.event_count;
+ unsigned int pkt_header_length;
unsigned int packets;
+ bool need_hw_irq;
int i;
if (s->packet_index < 0)
@@ -840,34 +1063,44 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
// Calculate the number of packets in buffer and check XRUN.
packets = header_length / sizeof(*ctx_header);
- generate_pkt_descs(s, s->pkt_descs, ctx_header, packets, d->seq_descs,
- d->seq_size);
+ pool_seq_descs(s, packets);
+
+ generate_pkt_descs(s, ctx_header, packets);
process_ctx_payloads(s, s->pkt_descs, packets);
+ if (!(s->flags & CIP_NO_HEADER))
+ pkt_header_length = IT_PKT_HEADER_SIZE_CIP;
+ else
+ pkt_header_length = 0;
+
+ if (s == d->irq_target) {
+ // At NO_PERIOD_WAKEUP mode, the packets for all IT/IR contexts are processed by
+ // the tasks of user process operating ALSA PCM character device by calling ioctl(2)
+ // with some requests, instead of scheduled hardware IRQ of an IT context.
+ struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
+ need_hw_irq = !pcm || !pcm->runtime->no_period_wakeup;
+ } else {
+ need_hw_irq = false;
+ }
+
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = s->pkt_descs + i;
- unsigned int syt;
struct {
struct fw_iso_packet params;
- __be32 header[IT_PKT_HEADER_SIZE_CIP / sizeof(__be32)];
+ __be32 header[CIP_HEADER_QUADLETS];
} template = { {0}, {0} };
bool sched_irq = false;
- if (s->ctx_data.rx.syt_override < 0)
- syt = desc->syt;
- else
- syt = s->ctx_data.rx.syt_override;
-
- build_it_pkt_header(s, desc->cycle, &template.params,
+ build_it_pkt_header(s, desc->cycle, &template.params, pkt_header_length,
desc->data_blocks, desc->data_block_counter,
- syt, i);
+ desc->syt, i);
if (s == s->domain->irq_target) {
event_count += desc->data_blocks;
if (event_count >= events_per_period) {
event_count -= events_per_period;
- sched_irq = true;
+ sched_irq = need_hw_irq;
}
}
@@ -880,13 +1113,99 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
s->ctx_data.rx.event_count = event_count;
}
-static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
- size_t header_length, void *header,
- void *private_data)
+static void skip_rx_packets(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+ const __be32 *ctx_header = header;
+ unsigned int packets;
+ unsigned int cycle;
+ int i;
+
+ if (s->packet_index < 0)
+ return;
+
+ packets = header_length / sizeof(*ctx_header);
+
+ cycle = compute_ohci_it_cycle(ctx_header[packets - 1], s->queue_size);
+ s->next_cycle = increment_ohci_cycle_count(cycle, 1);
+
+ for (i = 0; i < packets; ++i) {
+ struct fw_iso_packet params = {
+ .header_length = 0,
+ .payload_length = 0,
+ };
+ bool sched_irq = (s == d->irq_target && i == packets - 1);
+
+ if (queue_out_packet(s, &params, sched_irq) < 0) {
+ cancel_stream(s);
+ return;
+ }
+ }
+}
+
+static void irq_target_callback(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data);
+
+static void process_rx_packets_intermediately(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+ __be32 *ctx_header = header;
+ const unsigned int queue_size = s->queue_size;
+ unsigned int packets;
+ unsigned int offset;
+
+ if (s->packet_index < 0)
+ return;
+
+ packets = header_length / sizeof(*ctx_header);
+
+ offset = 0;
+ while (offset < packets) {
+ unsigned int cycle = compute_ohci_it_cycle(ctx_header[offset], queue_size);
+
+ if (compare_ohci_cycle_count(cycle, d->processing_cycle.rx_start) >= 0)
+ break;
+
+ ++offset;
+ }
+
+ if (offset > 0) {
+ unsigned int length = sizeof(*ctx_header) * offset;
+
+ skip_rx_packets(context, tstamp, length, ctx_header, private_data);
+ if (amdtp_streaming_error(s))
+ return;
+
+ ctx_header += offset;
+ header_length -= length;
+ }
+
+ if (offset < packets) {
+ s->ready_processing = true;
+ wake_up(&s->ready_wait);
+
+ process_rx_packets(context, tstamp, header_length, ctx_header, private_data);
+ if (amdtp_streaming_error(s))
+ return;
+
+ if (s == d->irq_target)
+ s->context->callback.sc = irq_target_callback;
+ else
+ s->context->callback.sc = process_rx_packets;
+ }
+}
+
+static void process_tx_packets(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data)
{
struct amdtp_stream *s = private_data;
__be32 *ctx_header = header;
unsigned int packets;
+ unsigned int desc_count;
int i;
int err;
@@ -896,14 +1215,20 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
// Calculate the number of packets in buffer and check XRUN.
packets = header_length / s->ctx_data.tx.ctx_header_size;
- err = generate_device_pkt_descs(s, s->pkt_descs, ctx_header, packets);
+ desc_count = 0;
+ err = generate_device_pkt_descs(s, s->pkt_descs, ctx_header, packets, &desc_count);
if (err < 0) {
if (err != -EAGAIN) {
cancel_stream(s);
return;
}
} else {
- process_ctx_payloads(s, s->pkt_descs, packets);
+ struct amdtp_domain *d = s->domain;
+
+ process_ctx_payloads(s, s->pkt_descs, desc_count);
+
+ if (d->replay.enable)
+ cache_seq(s, s->pkt_descs, desc_count);
}
for (i = 0; i < packets; ++i) {
@@ -916,79 +1241,194 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
}
}
-static void pool_ideal_seq_descs(struct amdtp_domain *d, unsigned int packets)
+static void drop_tx_packets(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data)
{
- struct amdtp_stream *irq_target = d->irq_target;
- unsigned int seq_tail = d->seq_tail;
- unsigned int seq_size = d->seq_size;
- unsigned int min_avail;
- struct amdtp_stream *s;
+ struct amdtp_stream *s = private_data;
+ const __be32 *ctx_header = header;
+ unsigned int packets;
+ unsigned int cycle;
+ int i;
- min_avail = d->seq_size;
- list_for_each_entry(s, &d->streams, list) {
- unsigned int seq_index;
- unsigned int avail;
+ if (s->packet_index < 0)
+ return;
+
+ packets = header_length / s->ctx_data.tx.ctx_header_size;
- if (s->direction == AMDTP_IN_STREAM)
- continue;
+ ctx_header += (packets - 1) * s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header);
+ cycle = compute_ohci_cycle_count(ctx_header[1]);
+ s->next_cycle = increment_ohci_cycle_count(cycle, 1);
- seq_index = s->ctx_data.rx.seq_index;
- avail = d->seq_tail;
- if (seq_index > avail)
- avail += d->seq_size;
- avail -= seq_index;
+ for (i = 0; i < packets; ++i) {
+ struct fw_iso_packet params = {0};
- if (avail < min_avail)
- min_avail = avail;
+ if (queue_in_packet(s, &params) < 0) {
+ cancel_stream(s);
+ return;
+ }
}
+}
- while (min_avail < packets) {
- struct seq_desc *desc = d->seq_descs + seq_tail;
+static void process_tx_packets_intermediately(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+ __be32 *ctx_header;
+ unsigned int packets;
+ unsigned int offset;
- desc->syt_offset = calculate_syt_offset(&d->last_syt_offset,
- &d->syt_offset_state, irq_target->sfc);
- desc->data_blocks = calculate_data_blocks(&d->data_block_state,
- !!(irq_target->flags & CIP_BLOCKING),
- desc->syt_offset == CIP_SYT_NO_INFO,
- irq_target->syt_interval, irq_target->sfc);
+ if (s->packet_index < 0)
+ return;
- ++seq_tail;
- seq_tail %= seq_size;
+ packets = header_length / s->ctx_data.tx.ctx_header_size;
- ++min_avail;
+ offset = 0;
+ ctx_header = header;
+ while (offset < packets) {
+ unsigned int cycle = compute_ohci_cycle_count(ctx_header[1]);
+
+ if (compare_ohci_cycle_count(cycle, d->processing_cycle.tx_start) >= 0)
+ break;
+
+ ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(__be32);
+ ++offset;
}
- d->seq_tail = seq_tail;
+ ctx_header = header;
+
+ if (offset > 0) {
+ size_t length = s->ctx_data.tx.ctx_header_size * offset;
+
+ drop_tx_packets(context, tstamp, length, ctx_header, s);
+ if (amdtp_streaming_error(s))
+ return;
+
+ ctx_header += length / sizeof(*ctx_header);
+ header_length -= length;
+ }
+
+ if (offset < packets) {
+ s->ready_processing = true;
+ wake_up(&s->ready_wait);
+
+ process_tx_packets(context, tstamp, header_length, ctx_header, s);
+ if (amdtp_streaming_error(s))
+ return;
+
+ context->callback.sc = process_tx_packets;
+ }
}
-static void irq_target_callback(struct fw_iso_context *context, u32 tstamp,
- size_t header_length, void *header,
- void *private_data)
+static void drop_tx_packets_initially(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header, void *private_data)
{
- struct amdtp_stream *irq_target = private_data;
- struct amdtp_domain *d = irq_target->domain;
- unsigned int packets = header_length / sizeof(__be32);
- struct amdtp_stream *s;
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+ __be32 *ctx_header;
+ unsigned int count;
+ unsigned int events;
+ int i;
+
+ if (s->packet_index < 0)
+ return;
+
+ count = header_length / s->ctx_data.tx.ctx_header_size;
+
+ // Attempt to detect any event in the batch of packets.
+ events = 0;
+ ctx_header = header;
+ for (i = 0; i < count; ++i) {
+ unsigned int payload_quads =
+ (be32_to_cpu(*ctx_header) >> ISO_DATA_LENGTH_SHIFT) / sizeof(__be32);
+ unsigned int data_blocks;
+
+ if (s->flags & CIP_NO_HEADER) {
+ data_blocks = payload_quads / s->data_block_quadlets;
+ } else {
+ __be32 *cip_headers = ctx_header + IR_CTX_HEADER_DEFAULT_QUADLETS;
+
+ if (payload_quads < CIP_HEADER_QUADLETS) {
+ data_blocks = 0;
+ } else {
+ payload_quads -= CIP_HEADER_QUADLETS;
+
+ if (s->flags & CIP_UNAWARE_SYT) {
+ data_blocks = payload_quads / s->data_block_quadlets;
+ } else {
+ u32 cip1 = be32_to_cpu(cip_headers[1]);
+
+ // NODATA packet can includes any data blocks but they are
+ // not available as event.
+ if ((cip1 & CIP_NO_DATA) == CIP_NO_DATA)
+ data_blocks = 0;
+ else
+ data_blocks = payload_quads / s->data_block_quadlets;
+ }
+ }
+ }
- // Record enough entries with extra 3 cycles at least.
- pool_ideal_seq_descs(d, packets + 3);
+ events += data_blocks;
- out_stream_callback(context, tstamp, header_length, header, irq_target);
- if (amdtp_streaming_error(irq_target))
- goto error;
+ ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(__be32);
+ }
+
+ drop_tx_packets(context, tstamp, header_length, header, s);
+
+ if (events > 0)
+ s->ctx_data.tx.event_starts = true;
+
+ // Decide the cycle count to begin processing content of packet in IR contexts.
+ {
+ unsigned int stream_count = 0;
+ unsigned int event_starts_count = 0;
+ unsigned int cycle = UINT_MAX;
+
+ list_for_each_entry(s, &d->streams, list) {
+ if (s->direction == AMDTP_IN_STREAM) {
+ ++stream_count;
+ if (s->ctx_data.tx.event_starts)
+ ++event_starts_count;
+ }
+ }
+
+ if (stream_count == event_starts_count) {
+ unsigned int next_cycle;
+
+ list_for_each_entry(s, &d->streams, list) {
+ if (s->direction != AMDTP_IN_STREAM)
+ continue;
+
+ next_cycle = increment_ohci_cycle_count(s->next_cycle,
+ d->processing_cycle.tx_init_skip);
+ if (cycle == UINT_MAX ||
+ compare_ohci_cycle_count(next_cycle, cycle) > 0)
+ cycle = next_cycle;
+
+ s->context->callback.sc = process_tx_packets_intermediately;
+ }
+
+ d->processing_cycle.tx_start = cycle;
+ }
+ }
+}
+
+static void process_ctxs_in_domain(struct amdtp_domain *d)
+{
+ struct amdtp_stream *s;
list_for_each_entry(s, &d->streams, list) {
- if (s != irq_target && amdtp_stream_running(s)) {
+ if (s != d->irq_target && amdtp_stream_running(s))
fw_iso_context_flush_completions(s->context);
- if (amdtp_streaming_error(s))
- goto error;
- }
+
+ if (amdtp_streaming_error(s))
+ goto error;
}
return;
error:
- if (amdtp_stream_running(irq_target))
- cancel_stream(irq_target);
+ if (amdtp_stream_running(d->irq_target))
+ cancel_stream(d->irq_target);
list_for_each_entry(s, &d->streams, list) {
if (amdtp_stream_running(s))
@@ -996,37 +1436,99 @@ error:
}
}
-// this is executed one time.
+static void irq_target_callback(struct fw_iso_context *context, u32 tstamp, size_t header_length,
+ void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+
+ process_rx_packets(context, tstamp, header_length, header, private_data);
+ process_ctxs_in_domain(d);
+}
+
+static void irq_target_callback_intermediately(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+
+ process_rx_packets_intermediately(context, tstamp, header_length, header, private_data);
+ process_ctxs_in_domain(d);
+}
+
+static void irq_target_callback_skip(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header, void *private_data)
+{
+ struct amdtp_stream *s = private_data;
+ struct amdtp_domain *d = s->domain;
+ bool ready_to_start;
+
+ skip_rx_packets(context, tstamp, header_length, header, private_data);
+ process_ctxs_in_domain(d);
+
+ if (d->replay.enable && !d->replay.on_the_fly) {
+ unsigned int rx_count = 0;
+ unsigned int rx_ready_count = 0;
+ struct amdtp_stream *rx;
+
+ list_for_each_entry(rx, &d->streams, list) {
+ struct amdtp_stream *tx;
+ unsigned int cached_cycles;
+
+ if (rx->direction != AMDTP_OUT_STREAM)
+ continue;
+ ++rx_count;
+
+ tx = rx->ctx_data.rx.replay_target;
+ cached_cycles = calculate_cached_cycle_count(tx, 0);
+ if (cached_cycles > tx->ctx_data.tx.cache.size / 2)
+ ++rx_ready_count;
+ }
+
+ ready_to_start = (rx_count == rx_ready_count);
+ } else {
+ ready_to_start = true;
+ }
+
+ // Decide the cycle count to begin processing content of packet in IT contexts. All of IT
+ // contexts are expected to start and get callback when reaching here.
+ if (ready_to_start) {
+ unsigned int cycle = s->next_cycle;
+ list_for_each_entry(s, &d->streams, list) {
+ if (s->direction != AMDTP_OUT_STREAM)
+ continue;
+
+ if (compare_ohci_cycle_count(s->next_cycle, cycle) > 0)
+ cycle = s->next_cycle;
+
+ if (s == d->irq_target)
+ s->context->callback.sc = irq_target_callback_intermediately;
+ else
+ s->context->callback.sc = process_rx_packets_intermediately;
+ }
+
+ d->processing_cycle.rx_start = cycle;
+ }
+}
+
+// This is executed one time. For in-stream, first packet has come. For out-stream, prepared to
+// transmit first packet.
static void amdtp_stream_first_callback(struct fw_iso_context *context,
u32 tstamp, size_t header_length,
void *header, void *private_data)
{
struct amdtp_stream *s = private_data;
- const __be32 *ctx_header = header;
- u32 cycle;
-
- /*
- * For in-stream, first packet has come.
- * For out-stream, prepared to transmit first packet
- */
- s->callbacked = true;
- wake_up(&s->callback_wait);
+ struct amdtp_domain *d = s->domain;
if (s->direction == AMDTP_IN_STREAM) {
- cycle = compute_cycle_count(ctx_header[1]);
-
- context->callback.sc = in_stream_callback;
+ context->callback.sc = drop_tx_packets_initially;
} else {
- cycle = compute_it_cycle(*ctx_header, s->queue_size);
-
- if (s == s->domain->irq_target)
- context->callback.sc = irq_target_callback;
+ if (s == d->irq_target)
+ context->callback.sc = irq_target_callback_skip;
else
- context->callback.sc = out_stream_callback;
+ context->callback.sc = skip_rx_packets;
}
- s->start_cycle = cycle;
-
context->callback.sc(context, tstamp, header_length, header, s);
}
@@ -1035,8 +1537,6 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
* @s: the AMDTP stream to start
* @channel: the isochronous channel on the bus
* @speed: firewire speed code
- * @start_cycle: the isochronous cycle to start the context. Start immediately
- * if negative value is given.
* @queue_size: The number of packets in the queue.
* @idle_irq_interval: the interval to queue packet during initial state.
*
@@ -1045,8 +1545,7 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
* device can be started.
*/
static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
- int start_cycle, unsigned int queue_size,
- unsigned int idle_irq_interval)
+ unsigned int queue_size, unsigned int idle_irq_interval)
{
bool is_irq_target = (s == s->domain->irq_target);
unsigned int ctx_header_size;
@@ -1075,27 +1574,21 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
}
// initialize packet buffer.
- max_ctx_payload_size = amdtp_stream_get_max_payload(s);
if (s->direction == AMDTP_IN_STREAM) {
dir = DMA_FROM_DEVICE;
type = FW_ISO_CONTEXT_RECEIVE;
- if (!(s->flags & CIP_NO_HEADER)) {
- max_ctx_payload_size -= 8;
+ if (!(s->flags & CIP_NO_HEADER))
ctx_header_size = IR_CTX_HEADER_SIZE_CIP;
- } else {
+ else
ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP;
- }
} else {
dir = DMA_TO_DEVICE;
type = FW_ISO_CONTEXT_TRANSMIT;
ctx_header_size = 0; // No effect for IT context.
-
- if (!(s->flags & CIP_NO_HEADER))
- max_ctx_payload_size -= IT_PKT_HEADER_SIZE_CIP;
}
+ max_ctx_payload_size = amdtp_stream_get_max_ctx_payload_size(s);
- err = iso_packets_buffer_init(&s->buffer, s->unit, queue_size,
- max_ctx_payload_size, dir);
+ err = iso_packets_buffer_init(&s->buffer, s->unit, queue_size, max_ctx_payload_size, dir);
if (err < 0)
goto err_unlock;
s->queue_size = queue_size;
@@ -1116,6 +1609,50 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
if (s->direction == AMDTP_IN_STREAM) {
s->ctx_data.tx.max_ctx_payload_length = max_ctx_payload_size;
s->ctx_data.tx.ctx_header_size = ctx_header_size;
+ s->ctx_data.tx.event_starts = false;
+
+ if (s->domain->replay.enable) {
+ // struct fw_iso_context.drop_overflow_headers is false therefore it's
+ // possible to cache much unexpectedly.
+ s->ctx_data.tx.cache.size = max_t(unsigned int, s->syt_interval * 2,
+ queue_size * 3 / 2);
+ s->ctx_data.tx.cache.tail = 0;
+ s->ctx_data.tx.cache.descs = kcalloc(s->ctx_data.tx.cache.size,
+ sizeof(*s->ctx_data.tx.cache.descs), GFP_KERNEL);
+ if (!s->ctx_data.tx.cache.descs) {
+ err = -ENOMEM;
+ goto err_context;
+ }
+ }
+ } else {
+ static const struct {
+ unsigned int data_block;
+ unsigned int syt_offset;
+ } *entry, initial_state[] = {
+ [CIP_SFC_32000] = { 4, 3072 },
+ [CIP_SFC_48000] = { 6, 1024 },
+ [CIP_SFC_96000] = { 12, 1024 },
+ [CIP_SFC_192000] = { 24, 1024 },
+ [CIP_SFC_44100] = { 0, 67 },
+ [CIP_SFC_88200] = { 0, 67 },
+ [CIP_SFC_176400] = { 0, 67 },
+ };
+
+ s->ctx_data.rx.seq.descs = kcalloc(queue_size, sizeof(*s->ctx_data.rx.seq.descs), GFP_KERNEL);
+ if (!s->ctx_data.rx.seq.descs) {
+ err = -ENOMEM;
+ goto err_context;
+ }
+ s->ctx_data.rx.seq.size = queue_size;
+ s->ctx_data.rx.seq.tail = 0;
+ s->ctx_data.rx.seq.head = 0;
+
+ entry = &initial_state[s->sfc];
+ s->ctx_data.rx.data_block_state = entry->data_block;
+ s->ctx_data.rx.syt_offset_state = entry->syt_offset;
+ s->ctx_data.rx.last_syt_offset = TICKS_PER_CYCLE;
+
+ s->ctx_data.rx.event_count = 0;
}
if (s->flags & CIP_NO_HEADER)
@@ -1158,8 +1695,8 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))
tag |= FW_ISO_CONTEXT_MATCH_TAG0;
- s->callbacked = false;
- err = fw_iso_context_start(s->context, start_cycle, 0, tag);
+ s->ready_processing = false;
+ err = fw_iso_context_start(s->context, -1, 0, tag);
if (err < 0)
goto err_pkt_descs;
@@ -1169,6 +1706,12 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
err_pkt_descs:
kfree(s->pkt_descs);
err_context:
+ if (s->direction == AMDTP_OUT_STREAM) {
+ kfree(s->ctx_data.rx.seq.descs);
+ } else {
+ if (s->domain->replay.enable)
+ kfree(s->ctx_data.tx.cache.descs);
+ }
fw_iso_context_destroy(s->context);
s->context = ERR_PTR(-1);
err_buffer:
@@ -1191,28 +1734,12 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
{
struct amdtp_stream *irq_target = d->irq_target;
+ // Process isochronous packets queued till recent isochronous cycle to handle PCM frames.
if (irq_target && amdtp_stream_running(irq_target)) {
- // This function is called in software IRQ context of
- // period_work or process context.
- //
- // When the software IRQ context was scheduled by software IRQ
- // context of IT contexts, queued packets were already handled.
- // Therefore, no need to flush the queue in buffer furthermore.
- //
- // When the process context reach here, some packets will be
- // already queued in the buffer. These packets should be handled
- // immediately to keep better granularity of PCM pointer.
- //
- // Later, the process context will sometimes schedules software
- // IRQ context of the period_work. Then, no need to flush the
- // queue by the same reason as described in the above
- if (current_work() != &s->period_work) {
- // Queued packet should be processed without any kernel
- // preemption to keep latency against bus cycle.
- preempt_disable();
+ // In software IRQ context, the call causes dead-lock to disable the tasklet
+ // synchronously.
+ if (!in_softirq())
fw_iso_context_flush_completions(irq_target->context);
- preempt_enable();
- }
}
return READ_ONCE(s->pcm_buffer_pointer);
@@ -1232,13 +1759,8 @@ int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s)
// Process isochronous packets for recent isochronous cycle to handle
// queued PCM frames.
- if (irq_target && amdtp_stream_running(irq_target)) {
- // Queued packet should be processed without any kernel
- // preemption to keep latency against bus cycle.
- preempt_disable();
+ if (irq_target && amdtp_stream_running(irq_target))
fw_iso_context_flush_completions(irq_target->context);
- preempt_enable();
- }
return 0;
}
@@ -1272,14 +1794,18 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
return;
}
- cancel_work_sync(&s->period_work);
fw_iso_context_stop(s->context);
fw_iso_context_destroy(s->context);
s->context = ERR_PTR(-1);
iso_packets_buffer_destroy(&s->buffer, s->unit);
kfree(s->pkt_descs);
- s->callbacked = false;
+ if (s->direction == AMDTP_OUT_STREAM) {
+ kfree(s->ctx_data.rx.seq.descs);
+ } else {
+ if (s->domain->replay.enable)
+ kfree(s->ctx_data.tx.cache.descs);
+ }
mutex_unlock(&s->mutex);
}
@@ -1311,8 +1837,6 @@ int amdtp_domain_init(struct amdtp_domain *d)
d->events_per_period = 0;
- d->seq_descs = NULL;
-
return 0;
}
EXPORT_SYMBOL_GPL(amdtp_domain_init);
@@ -1355,26 +1879,49 @@ int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
}
EXPORT_SYMBOL_GPL(amdtp_domain_add_stream);
-static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle)
+// Make the reference from rx stream to tx stream for sequence replay. When the number of tx streams
+// is less than the number of rx streams, the first tx stream is selected.
+static int make_association(struct amdtp_domain *d)
{
- int generation;
- int rcode;
- __be32 reg;
- u32 data;
-
- // This is a request to local 1394 OHCI controller and expected to
- // complete without any event waiting.
- generation = fw_card->generation;
- smp_rmb(); // node_id vs. generation.
- rcode = fw_run_transaction(fw_card, TCODE_READ_QUADLET_REQUEST,
- fw_card->node_id, generation, SCODE_100,
- CSR_REGISTER_BASE + CSR_CYCLE_TIME,
- &reg, sizeof(reg));
- if (rcode != RCODE_COMPLETE)
- return -EIO;
+ unsigned int dst_index = 0;
+ struct amdtp_stream *rx;
+
+ // Make association to replay target.
+ list_for_each_entry(rx, &d->streams, list) {
+ if (rx->direction == AMDTP_OUT_STREAM) {
+ unsigned int src_index = 0;
+ struct amdtp_stream *tx = NULL;
+ struct amdtp_stream *s;
+
+ list_for_each_entry(s, &d->streams, list) {
+ if (s->direction == AMDTP_IN_STREAM) {
+ if (dst_index == src_index) {
+ tx = s;
+ break;
+ }
+
+ ++src_index;
+ }
+ }
+ if (!tx) {
+ // Select the first entry.
+ list_for_each_entry(s, &d->streams, list) {
+ if (s->direction == AMDTP_IN_STREAM) {
+ tx = s;
+ break;
+ }
+ }
+ // No target is available to replay sequence.
+ if (!tx)
+ return -EINVAL;
+ }
- data = be32_to_cpu(reg);
- *cur_cycle = data >> 12;
+ rx->ctx_data.rx.replay_target = tx;
+ rx->ctx_data.rx.cache_head = 0;
+
+ ++dst_index;
+ }
+ }
return 0;
}
@@ -1382,39 +1929,44 @@ static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle)
/**
* amdtp_domain_start - start sending packets for isoc context in the domain.
* @d: the AMDTP domain.
- * @ir_delay_cycle: the cycle delay to start all IR contexts.
+ * @tx_init_skip_cycles: the number of cycles to skip processing packets at initial stage of IR
+ * contexts.
+ * @replay_seq: whether to replay the sequence of packet in IR context for the sequence of packet in
+ * IT context.
+ * @replay_on_the_fly: transfer rx packets according to nominal frequency, then begin to replay
+ * according to arrival of events in tx packets.
*/
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+ bool replay_on_the_fly)
{
- static const struct {
- unsigned int data_block;
- unsigned int syt_offset;
- } *entry, initial_state[] = {
- [CIP_SFC_32000] = { 4, 3072 },
- [CIP_SFC_48000] = { 6, 1024 },
- [CIP_SFC_96000] = { 12, 1024 },
- [CIP_SFC_192000] = { 24, 1024 },
- [CIP_SFC_44100] = { 0, 67 },
- [CIP_SFC_88200] = { 0, 67 },
- [CIP_SFC_176400] = { 0, 67 },
- };
unsigned int events_per_buffer = d->events_per_buffer;
unsigned int events_per_period = d->events_per_period;
- unsigned int idle_irq_interval;
unsigned int queue_size;
struct amdtp_stream *s;
- int cycle;
+ bool found = false;
int err;
+ if (replay_seq) {
+ err = make_association(d);
+ if (err < 0)
+ return err;
+ }
+ d->replay.enable = replay_seq;
+ d->replay.on_the_fly = replay_on_the_fly;
+
// Select an IT context as IRQ target.
list_for_each_entry(s, &d->streams, list) {
- if (s->direction == AMDTP_OUT_STREAM)
+ if (s->direction == AMDTP_OUT_STREAM) {
+ found = true;
break;
+ }
}
- if (!s)
+ if (!found)
return -ENXIO;
d->irq_target = s;
+ d->processing_cycle.tx_init_skip = tx_init_skip_cycles;
+
// This is a case that AMDTP streams in domain run just for MIDI
// substream. Use the number of events equivalent to 10 msec as
// interval of hardware IRQ.
@@ -1426,82 +1978,24 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
queue_size = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_buffer,
amdtp_rate_table[d->irq_target->sfc]);
- d->seq_descs = kcalloc(queue_size, sizeof(*d->seq_descs), GFP_KERNEL);
- if (!d->seq_descs)
- return -ENOMEM;
- d->seq_size = queue_size;
- d->seq_tail = 0;
-
- entry = &initial_state[s->sfc];
- d->data_block_state = entry->data_block;
- d->syt_offset_state = entry->syt_offset;
- d->last_syt_offset = TICKS_PER_CYCLE;
-
- if (ir_delay_cycle > 0) {
- struct fw_card *fw_card = fw_parent_device(s->unit)->card;
-
- err = get_current_cycle_time(fw_card, &cycle);
- if (err < 0)
- goto error;
-
- // No need to care overflow in cycle field because of enough
- // width.
- cycle += ir_delay_cycle;
-
- // Round up to sec field.
- if ((cycle & 0x00001fff) >= CYCLES_PER_SECOND) {
- unsigned int sec;
-
- // The sec field can overflow.
- sec = (cycle & 0xffffe000) >> 13;
- cycle = (++sec << 13) |
- ((cycle & 0x00001fff) / CYCLES_PER_SECOND);
- }
-
- // In OHCI 1394 specification, lower 2 bits are available for
- // sec field.
- cycle &= 0x00007fff;
- } else {
- cycle = -1;
- }
-
list_for_each_entry(s, &d->streams, list) {
- int cycle_match;
+ unsigned int idle_irq_interval = 0;
- if (s->direction == AMDTP_IN_STREAM) {
- cycle_match = cycle;
- } else {
- // IT context starts immediately.
- cycle_match = -1;
- s->ctx_data.rx.seq_index = 0;
+ if (s->direction == AMDTP_OUT_STREAM && s == d->irq_target) {
+ idle_irq_interval = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_period,
+ amdtp_rate_table[d->irq_target->sfc]);
}
- if (s != d->irq_target) {
- err = amdtp_stream_start(s, s->channel, s->speed,
- cycle_match, queue_size, 0);
- if (err < 0)
- goto error;
- }
+ // Starts immediately but actually DMA context starts several hundred cycles later.
+ err = amdtp_stream_start(s, s->channel, s->speed, queue_size, idle_irq_interval);
+ if (err < 0)
+ goto error;
}
- s = d->irq_target;
- s->ctx_data.rx.events_per_period = events_per_period;
- s->ctx_data.rx.event_count = 0;
- s->ctx_data.rx.seq_index = 0;
-
- idle_irq_interval = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_period,
- amdtp_rate_table[d->irq_target->sfc]);
- err = amdtp_stream_start(s, s->channel, s->speed, -1, queue_size,
- idle_irq_interval);
- if (err < 0)
- goto error;
-
return 0;
error:
list_for_each_entry(s, &d->streams, list)
amdtp_stream_stop(s);
- kfree(d->seq_descs);
- d->seq_descs = NULL;
return err;
}
EXPORT_SYMBOL_GPL(amdtp_domain_start);
@@ -1526,8 +2020,5 @@ void amdtp_domain_stop(struct amdtp_domain *d)
d->events_per_period = 0;
d->irq_target = NULL;
-
- kfree(d->seq_descs);
- d->seq_descs = NULL;
}
EXPORT_SYMBOL_GPL(amdtp_domain_stop);
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index a3daa1f2c1c4..1f957c946c95 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -35,6 +35,8 @@
* @CIP_NO_HEADERS: a lack of headers in packets
* @CIP_UNALIGHED_DBC: Only for in-stream. The value of dbc is not alighed to
* the value of current SYT_INTERVAL; e.g. initial value is not zero.
+ * @CIP_UNAWARE_SYT: For outgoing packet, the value in SYT field of CIP is 0xffff.
+ * For incoming packet, the value in SYT field of CIP is not handled.
*/
enum cip_flags {
CIP_NONBLOCKING = 0x00,
@@ -48,6 +50,7 @@ enum cip_flags {
CIP_HEADER_WITHOUT_EOH = 0x80,
CIP_NO_HEADER = 0x100,
CIP_UNALIGHED_DBC = 0x200,
+ CIP_UNAWARE_SYT = 0x400,
};
/**
@@ -112,7 +115,8 @@ typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)(
struct amdtp_domain;
struct amdtp_stream {
struct fw_unit *unit;
- enum cip_flags flags;
+ // The combination of cip_flags enumeration-constants.
+ unsigned int flags;
enum amdtp_stream_direction direction;
struct mutex mutex;
@@ -134,19 +138,37 @@ struct amdtp_stream {
// Fixed interval of dbc between previos/current
// packets.
unsigned int dbc_interval;
+
+ // The device starts multiplexing events to the packet.
+ bool event_starts;
+
+ struct {
+ struct seq_desc *descs;
+ unsigned int size;
+ unsigned int tail;
+ } cache;
} tx;
struct {
- // To calculate CIP data blocks and tstamp.
- unsigned int transfer_delay;
- unsigned int seq_index;
-
// To generate CIP header.
unsigned int fdf;
- int syt_override;
// To generate constant hardware IRQ.
unsigned int event_count;
- unsigned int events_per_period;
+
+ // To calculate CIP data blocks and tstamp.
+ struct {
+ struct seq_desc *descs;
+ unsigned int size;
+ unsigned int tail;
+ unsigned int head;
+ } seq;
+
+ unsigned int data_block_state;
+ unsigned int syt_offset_state;
+ unsigned int last_syt_offset;
+
+ struct amdtp_stream *replay_target;
+ unsigned int cache_head;
} rx;
} ctx_data;
@@ -157,20 +179,21 @@ struct amdtp_stream {
unsigned int sph;
unsigned int fmt;
- /* Internal flags. */
+ // Internal flags.
+ unsigned int transfer_delay;
enum cip_sfc sfc;
unsigned int syt_interval;
/* For a PCM substream processing. */
struct snd_pcm_substream *pcm;
- struct work_struct period_work;
snd_pcm_uframes_t pcm_buffer_pointer;
unsigned int pcm_period_pointer;
- /* To wait for first packet. */
- bool callbacked;
- wait_queue_head_t callback_wait;
- u32 start_cycle;
+ // To start processing content of packets at the same cycle in several contexts for
+ // each direction.
+ bool ready_processing;
+ wait_queue_head_t ready_wait;
+ unsigned int next_cycle;
/* For backends to process data blocks. */
void *protocol;
@@ -184,7 +207,7 @@ struct amdtp_stream {
};
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir, enum cip_flags flags,
+ enum amdtp_stream_direction dir, unsigned int flags,
unsigned int fmt,
amdtp_stream_process_ctx_payloads_t process_ctx_payloads,
unsigned int protocol_size);
@@ -259,21 +282,6 @@ static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
return sfc & 1;
}
-/**
- * amdtp_stream_wait_callback - sleep till callbacked or timeout
- * @s: the AMDTP stream
- * @timeout: msec till timeout
- *
- * If this function return false, the AMDTP stream should be stopped.
- */
-static inline bool amdtp_stream_wait_callback(struct amdtp_stream *s,
- unsigned int timeout)
-{
- return wait_event_timeout(s->callback_wait,
- s->callbacked,
- msecs_to_jiffies(timeout)) > 0;
-}
-
struct seq_desc {
unsigned int syt_offset;
unsigned int data_blocks;
@@ -287,13 +295,16 @@ struct amdtp_domain {
struct amdtp_stream *irq_target;
- struct seq_desc *seq_descs;
- unsigned int seq_size;
- unsigned int seq_tail;
+ struct {
+ unsigned int tx_init_skip;
+ unsigned int tx_start;
+ unsigned int rx_start;
+ } processing_cycle;
- unsigned int data_block_state;
- unsigned int syt_offset_state;
- unsigned int last_syt_offset;
+ struct {
+ bool enable:1;
+ bool on_the_fly:1;
+ } replay;
};
int amdtp_domain_init(struct amdtp_domain *d);
@@ -302,7 +313,8 @@ void amdtp_domain_destroy(struct amdtp_domain *d);
int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
int channel, int speed);
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle);
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+ bool replay_on_the_fly);
void amdtp_domain_stop(struct amdtp_domain *d);
static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d,
@@ -319,4 +331,25 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
struct amdtp_stream *s);
int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s);
+/**
+ * amdtp_domain_wait_ready - sleep till being ready to process packets or timeout
+ * @d: the AMDTP domain
+ * @timeout_ms: msec till timeout
+ *
+ * If this function return false, the AMDTP domain should be stopped.
+ */
+static inline bool amdtp_domain_wait_ready(struct amdtp_domain *d, unsigned int timeout_ms)
+{
+ struct amdtp_stream *s;
+
+ list_for_each_entry(s, &d->streams, list) {
+ unsigned int j = msecs_to_jiffies(timeout_ms);
+
+ if (wait_event_interruptible_timeout(s->ready_wait, s->ready_processing, j) <= 0)
+ return false;
+ }
+
+ return true;
+}
+
#endif
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index daeecfa8b9aa..06a7ced218e2 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -40,14 +40,12 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
#define VEN_EDIROL 0x000040ab
#define VEN_PRESONUS 0x00000a92
#define VEN_BRIDGECO 0x000007f5
-#define VEN_MACKIE1 0x0000000f
-#define VEN_MACKIE2 0x00000ff2
+#define VEN_MACKIE 0x00000ff2
#define VEN_STANTON 0x00001260
#define VEN_TASCAM 0x0000022e
#define VEN_BEHRINGER 0x00001564
#define VEN_APOGEE 0x000003db
#define VEN_ESI 0x00000f1b
-#define VEN_ACOUSTIC 0x00000002
#define VEN_CME 0x0000000a
#define VEN_PHONIC 0x00001496
#define VEN_LYNX 0x000019e5
@@ -56,14 +54,15 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
#define VEN_TERRATEC 0x00000aac
#define VEN_YAMAHA 0x0000a0de
#define VEN_FOCUSRITE 0x0000130e
-#define VEN_MAUDIO1 0x00000d6c
-#define VEN_MAUDIO2 0x000007f5
+#define VEN_MAUDIO 0x00000d6c
#define VEN_DIGIDESIGN 0x00a07e
+#define OUI_SHOUYO 0x002327
#define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000
#define MODEL_MAUDIO_AUDIOPHILE_BOTH 0x00010060
#define MODEL_MAUDIO_FW1814 0x00010071
#define MODEL_MAUDIO_PROJECTMIX 0x00010091
+#define MODEL_MAUDIO_PROFIRELIGHTBRIDGE 0x000100a1
static int
name_device(struct snd_bebob *bebob)
@@ -74,7 +73,6 @@ name_device(struct snd_bebob *bebob)
u32 hw_id;
u32 data[2] = {0};
u32 revision;
- u32 version;
int err;
/* get vendor name from root directory */
@@ -107,12 +105,6 @@ name_device(struct snd_bebob *bebob)
if (err < 0)
goto end;
- err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_BEBOB_VERSION,
- &version);
- if (err < 0)
- goto end;
- bebob->version = version;
-
strcpy(bebob->card->driver, "BeBoB");
strcpy(bebob->card->shortname, model);
strcpy(bebob->card->mixername, model);
@@ -135,6 +127,9 @@ bebob_card_free(struct snd_card *card)
mutex_unlock(&devices_mutex);
snd_bebob_stream_destroy_duplex(bebob);
+
+ mutex_destroy(&bebob->mutex);
+ fw_unit_put(bebob->unit);
}
static const struct snd_bebob_spec *
@@ -162,16 +157,55 @@ check_audiophile_booted(struct fw_unit *unit)
return strncmp(name, "FW Audiophile Bootloader", 24) != 0;
}
-static void
-do_registration(struct work_struct *work)
+static int detect_quirks(struct snd_bebob *bebob, const struct ieee1394_device_id *entry)
+{
+ if (entry->vendor_id == VEN_MAUDIO) {
+ switch (entry->model_id) {
+ case MODEL_MAUDIO_PROFIRELIGHTBRIDGE:
+ // M-Audio ProFire Lightbridge has a quirk to transfer packets with
+ // discontinuous cycle or data block counter in early stage of packet
+ // streaming. The cycle span from the first packet with event is variable.
+ bebob->quirks |= SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC;
+ break;
+ case MODEL_MAUDIO_FW1814:
+ case MODEL_MAUDIO_PROJECTMIX:
+ // At high sampling rate, M-Audio special firmware transmits empty packet
+ // with the value of dbc incremented by 8.
+ bebob->quirks |= SND_BEBOB_QUIRK_WRONG_DBC;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_bebob *bebob =
- container_of(work, struct snd_bebob, dwork.work);
unsigned int card_index;
+ struct snd_card *card;
+ struct snd_bebob *bebob;
+ const struct snd_bebob_spec *spec;
int err;
- if (bebob->registered)
- return;
+ if (entry->vendor_id == VEN_FOCUSRITE &&
+ entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)
+ spec = get_saffire_spec(unit);
+ else if (entry->vendor_id == VEN_MAUDIO &&
+ entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH &&
+ !check_audiophile_booted(unit))
+ spec = NULL;
+ else
+ spec = (const struct snd_bebob_spec *)entry->driver_data;
+
+ if (spec == NULL) {
+ // To boot up M-Audio models.
+ if (entry->vendor_id == VEN_MAUDIO || entry->vendor_id == VEN_BRIDGECO)
+ return snd_bebob_maudio_load_firmware(unit);
+ else
+ return -ENODEV;
+ }
mutex_lock(&devices_mutex);
for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
@@ -180,27 +214,40 @@ do_registration(struct work_struct *work)
}
if (card_index >= SNDRV_CARDS) {
mutex_unlock(&devices_mutex);
- return;
+ return -ENOENT;
}
- err = snd_card_new(&bebob->unit->device, index[card_index],
- id[card_index], THIS_MODULE, 0, &bebob->card);
+ 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;
+ return err;
}
+ card->private_free = bebob_card_free;
set_bit(card_index, devices_used);
mutex_unlock(&devices_mutex);
- bebob->card->private_free = bebob_card_free;
- bebob->card->private_data = bebob;
+ bebob = card->private_data;
+ bebob->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, bebob);
+ bebob->card = card;
+ bebob->card_index = card_index;
+
+ bebob->spec = spec;
+ mutex_init(&bebob->mutex);
+ spin_lock_init(&bebob->lock);
+ init_waitqueue_head(&bebob->hwdep_wait);
err = name_device(bebob);
if (err < 0)
goto error;
+ err = detect_quirks(bebob, entry);
+ if (err < 0)
+ goto error;
+
if (bebob->spec == &maudio_special_spec) {
- if (bebob->entry->model_id == MODEL_MAUDIO_FW1814)
+ if (entry->model_id == MODEL_MAUDIO_FW1814)
err = snd_bebob_maudio_special_discover(bebob, true);
else
err = snd_bebob_maudio_special_discover(bebob, false);
@@ -230,80 +277,26 @@ do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(bebob->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- bebob->registered = true;
-
- return;
-error:
- snd_card_free(bebob->card);
- dev_info(&bebob->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int
-bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
-{
- struct snd_bebob *bebob;
- const struct snd_bebob_spec *spec;
-
- if (entry->vendor_id == VEN_FOCUSRITE &&
- entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)
- spec = get_saffire_spec(unit);
- else if (entry->vendor_id == VEN_MAUDIO1 &&
- entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH &&
- !check_audiophile_booted(unit))
- spec = NULL;
- else
- spec = (const struct snd_bebob_spec *)entry->driver_data;
-
- if (spec == NULL) {
- if (entry->vendor_id == VEN_MAUDIO1 ||
- entry->vendor_id == VEN_MAUDIO2)
- return snd_bebob_maudio_load_firmware(unit);
- else
- return -ENODEV;
- }
-
- /* Allocate this independent of sound card instance. */
- bebob = devm_kzalloc(&unit->device, sizeof(struct snd_bebob),
- GFP_KERNEL);
- if (!bebob)
- return -ENOMEM;
- bebob->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, bebob);
-
- bebob->entry = entry;
- bebob->spec = spec;
- mutex_init(&bebob->mutex);
- spin_lock_init(&bebob->lock);
- init_waitqueue_head(&bebob->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&bebob->dwork, do_registration);
-
- if (entry->vendor_id != VEN_MAUDIO1 ||
- (entry->model_id != MODEL_MAUDIO_FW1814 &&
- entry->model_id != MODEL_MAUDIO_PROJECTMIX)) {
- snd_fw_schedule_registration(unit, &bebob->dwork);
- } else {
- /*
- * This is a workaround. This bus reset seems to have an effect
- * to make devices correctly handling transactions. Without
- * this, the devices have gap_count mismatch. This causes much
- * failure of transaction.
- *
- * Just after registration, user-land application receive
- * signals from dbus and starts I/Os. To avoid I/Os till the
- * future bus reset, registration is done in next update().
- */
- fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card,
- false, true);
+ if (entry->vendor_id == VEN_MAUDIO &&
+ (entry->model_id == MODEL_MAUDIO_FW1814 || entry->model_id == MODEL_MAUDIO_PROJECTMIX)) {
+ // This is a workaround. This bus reset seems to have an effect to make devices
+ // correctly handling transactions. Without this, the devices have gap_count
+ // mismatch. This causes much failure of transaction.
+ //
+ // Just after registration, user-land application receive signals from dbus and
+ // starts I/Os. To avoid I/Os till the future bus reset, registration is done in
+ // next update().
+ fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card, false, true);
}
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
/*
@@ -330,11 +323,7 @@ bebob_update(struct fw_unit *unit)
if (bebob == NULL)
return;
- /* Postpone a workqueue for deferred registration. */
- if (!bebob->registered)
- snd_fw_schedule_registration(unit, &bebob->dwork);
- else
- fcp_bus_reset(bebob->unit);
+ fcp_bus_reset(bebob->unit);
}
static void bebob_remove(struct fw_unit *unit)
@@ -344,20 +333,8 @@ static void bebob_remove(struct fw_unit *unit)
if (bebob == NULL)
return;
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&bebob->dwork);
-
- if (bebob->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(bebob->card);
- }
-
- mutex_destroy(&bebob->mutex);
- fw_unit_put(bebob->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(bebob->card);
}
static const struct snd_bebob_rate_spec normal_rate_spec = {
@@ -370,6 +347,22 @@ static const struct snd_bebob_spec spec_normal = {
.meter = NULL
};
+#define SPECIFIER_1394TA 0x00a02d
+
+// The immediate entry for version in unit directory differs depending on models:
+// * 0x010001
+// * 0x014001
+#define SND_BEBOB_DEV_ENTRY(vendor, model, data) \
+{ \
+ .match_flags = IEEE1394_MATCH_VENDOR_ID | \
+ IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID, \
+ .vendor_id = vendor, \
+ .model_id = model, \
+ .specifier_id = SPECIFIER_1394TA, \
+ .driver_data = (kernel_ulong_t)data \
+}
+
static const struct ieee1394_device_id bebob_id_table[] = {
/* Edirol, FA-66 */
SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal),
@@ -386,9 +379,9 @@ static const struct ieee1394_device_id bebob_id_table[] = {
/* BridgeCo, Audio5 */
SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal),
/* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */
- SND_BEBOB_DEV_ENTRY(VEN_MACKIE2, 0x00010065, &spec_normal),
- // Mackie, d.2 (Firewire option card) and d.2 Pro (the card is built-in).
- SND_BEBOB_DEV_ENTRY(VEN_MACKIE1, 0x00010067, &spec_normal),
+ SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal),
+ // Mackie, d.2 (optional Firewire card with DM1000).
+ SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal),
/* Stanton, ScratchAmp */
SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal),
/* Tascam, IF-FW DM */
@@ -410,17 +403,18 @@ static const struct ieee1394_device_id bebob_id_table[] = {
SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x01eeee, &spec_normal),
/* ESI, Quatafire610 */
SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal),
- /* AcousticReality, eARMasterOne */
- SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002, &spec_normal),
/* CME, MatrixKFW */
SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal),
- /* Phonic, Helix Board 12 MkII */
+ // Phonic Helix Board 12 FireWire MkII.
SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal),
- /* Phonic, Helix Board 18 MkII */
+ // Phonic Helix Board 18 FireWire MkII.
SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal),
- /* Phonic, Helix Board 24 MkII */
+ // Phonic Helix Board 24 FireWire MkII.
SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal),
- /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */
+ // Phonic FireFly 808 FireWire.
+ SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00080000, &spec_normal),
+ // Phonic FireFly 202, 302, 808 Universal.
+ // Phinic Helix Board 12/18/24 FireWire, 12/18/24 Universal
SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal),
/* Lynx, Aurora 8/16 (LT-FW) */
SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal),
@@ -438,7 +432,8 @@ static const struct ieee1394_device_id bebob_id_table[] = {
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec),
/* TerraTec Electronic GmbH, EWS MIC2/MIC8 */
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal),
- /* Terratec Electronic GmbH, Aureon 7.1 Firewire */
+ // Terratec Electronic GmbH, Aureon 7.1 Firewire.
+ // AcousticReality, eAR Master One, Eroica, Figaro, and Ciaccona. Perhaps Terratec OEM.
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal),
/* Yamaha, GO44 */
SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec),
@@ -447,45 +442,35 @@ static const struct ieee1394_device_id bebob_id_table[] = {
/* Focusrite, SaffirePro 26 I/O */
SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec),
/* Focusrite, SaffirePro 10 I/O */
- {
- // The combination of vendor_id and model_id is the same as the
- // same as the one of Liquid Saffire 56.
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID |
- IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .vendor_id = VEN_FOCUSRITE,
- .model_id = 0x000006,
- .specifier_id = 0x00a02d,
- .version = 0x010001,
- .driver_data = (kernel_ulong_t)&saffirepro_10_spec,
- },
+ SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x000006, &saffirepro_10_spec),
/* Focusrite, Saffire(no label and LE) */
SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, MODEL_FOCUSRITE_SAFFIRE_BOTH,
&saffire_spec),
- /* M-Audio, Firewire 410 */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO2, 0x00010058, NULL), /* bootloader */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO2, 0x00010046, &maudio_fw410_spec),
+ // M-Audio, Firewire 410. The vendor field is left as BridgeCo. AG.
+ SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010058, NULL),
+ SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010046, &maudio_fw410_spec),
/* M-Audio, Firewire Audiophile */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_AUDIOPHILE_BOTH,
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_AUDIOPHILE_BOTH,
&maudio_audiophile_spec),
/* M-Audio, Firewire Solo */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010062, &maudio_solo_spec),
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010062, &maudio_solo_spec),
/* M-Audio, Ozonic */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x0000000a, &maudio_ozonic_spec),
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x0000000a, &maudio_ozonic_spec),
/* M-Audio NRV10 */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010081, &maudio_nrv10_spec),
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010081, &maudio_nrv10_spec),
/* M-Audio, ProFireLightbridge */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x000100a1, &spec_normal),
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_PROFIRELIGHTBRIDGE, &spec_normal),
/* Firewire 1814 */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010070, NULL), /* bootloader */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_FW1814,
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010070, NULL), /* bootloader */
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_FW1814,
&maudio_special_spec),
/* M-Audio ProjectMix */
- SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_PROJECTMIX,
+ SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_PROJECTMIX,
&maudio_special_spec),
/* Digidesign Mbox 2 Pro */
SND_BEBOB_DEV_ENTRY(VEN_DIGIDESIGN, 0x0000a9, &spec_normal),
+ // Toneweal FW66.
+ SND_BEBOB_DEV_ENTRY(OUI_SHOUYO, 0x020002, &spec_normal),
/* IDs are unknown but able to be supported */
/* Apogee, Mini-ME Firewire */
/* Apogee, Mini-DAC Firewire */
@@ -496,11 +481,6 @@ static const struct ieee1394_device_id bebob_id_table[] = {
/* Infrasonic, Windy6 */
/* Mackie, Digital X Bus x.200 */
/* Mackie, Digital X Bus x.400 */
- /* Phonic, HB 12 */
- /* Phonic, HB 24 */
- /* Phonic, HB 18 */
- /* Phonic, FireFly 202 */
- /* Phonic, FireFly 302 */
/* Rolf Spuler, Firewire Guitar */
{}
};
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index 4e0ed84adbee..4d73ecb30d79 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -75,6 +75,11 @@ struct snd_bebob_spec {
const struct snd_bebob_meter_spec *meter;
};
+enum snd_bebob_quirk {
+ SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC = (1 << 0),
+ SND_BEBOB_QUIRK_WRONG_DBC = (1 << 1),
+};
+
struct snd_bebob {
struct snd_card *card;
struct fw_unit *unit;
@@ -83,11 +88,8 @@ struct snd_bebob {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
- const struct ieee1394_device_id *entry;
const struct snd_bebob_spec *spec;
+ unsigned int quirks; // Combination of snd_bebob_quirk enumerations.
unsigned int midi_input_ports;
unsigned int midi_output_ports;
@@ -113,9 +115,6 @@ struct snd_bebob {
/* for M-Audio special devices */
void *maudio_special_quirk;
- /* For BeBoB version quirk. */
- unsigned int version;
-
struct amdtp_domain domain;
};
@@ -254,13 +253,4 @@ extern const struct snd_bebob_spec maudio_special_spec;
int snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814);
int snd_bebob_maudio_load_firmware(struct fw_unit *unit);
-#define SND_BEBOB_DEV_ENTRY(vendor, model, data) \
-{ \
- .match_flags = IEEE1394_MATCH_VENDOR_ID | \
- IEEE1394_MATCH_MODEL_ID, \
- .vendor_id = vendor, \
- .model_id = model, \
- .driver_data = (kernel_ulong_t)data \
-}
-
#endif
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index b612ee3e33b6..8629b14ded76 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -7,8 +7,7 @@
#include "./bebob.h"
-#define CALLBACK_TIMEOUT 2500
-#define FW_ISO_RESOURCE_DELAY 1000
+#define READY_TIMEOUT_MS 4000
/*
* NOTE;
@@ -402,12 +401,6 @@ static void break_both_connections(struct snd_bebob *bebob)
{
cmp_connection_break(&bebob->in_conn);
cmp_connection_break(&bebob->out_conn);
-
- // These models seem to be in transition state for a longer time. When
- // accessing in the state, any transactions is corrupted. In the worst
- // case, the device is going to reboot.
- if (bebob->version < 2)
- msleep(600);
}
static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
@@ -437,6 +430,7 @@ static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
{
+ unsigned int flags = CIP_BLOCKING;
enum amdtp_stream_direction dir_stream;
struct cmp_connection *conn;
enum cmp_direction dir_conn;
@@ -452,32 +446,21 @@ static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
dir_conn = CMP_INPUT;
}
+ if (stream == &bebob->tx_stream) {
+ if (bebob->quirks & SND_BEBOB_QUIRK_WRONG_DBC)
+ flags |= CIP_EMPTY_HAS_WRONG_DBC;
+ }
+
err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
if (err < 0)
return err;
- err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING);
+ err = amdtp_am824_init(stream, bebob->unit, dir_stream, flags);
if (err < 0) {
cmp_connection_destroy(conn);
return err;
}
- if (stream == &bebob->tx_stream) {
- // BeBoB v3 transfers packets with these qurks:
- // - In the beginning of streaming, the value of dbc is
- // incremented even if no data blocks are transferred.
- // - The value of dbc is reset suddenly.
- if (bebob->version > 2)
- bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC |
- CIP_SKIP_DBC_ZERO_CHECK;
-
- // At high sampling rate, M-Audio special firmware transmits
- // empty packet with the value of dbc incremented by 8 but the
- // others are valid to IEC 61883-1.
- if (bebob->maudio_special_quirk)
- bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
- }
-
return 0;
}
@@ -624,9 +607,8 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
if (!amdtp_stream_running(&bebob->rx_stream)) {
enum snd_bebob_clock_type src;
- struct amdtp_stream *master, *slave;
unsigned int curr_rate;
- unsigned int ir_delay_cycle;
+ unsigned int tx_init_skip_cycles;
if (bebob->maudio_special_quirk) {
err = bebob->spec->rate->get(bebob, &curr_rate);
@@ -638,36 +620,28 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
if (err < 0)
return err;
- if (src != SND_BEBOB_CLOCK_TYPE_SYT) {
- master = &bebob->tx_stream;
- slave = &bebob->rx_stream;
- } else {
- master = &bebob->rx_stream;
- slave = &bebob->tx_stream;
- }
-
- err = start_stream(bebob, master);
+ err = start_stream(bebob, &bebob->rx_stream);
if (err < 0)
goto error;
- err = start_stream(bebob, slave);
+ err = start_stream(bebob, &bebob->tx_stream);
if (err < 0)
goto error;
- // The device postpones start of transmission mostly for 1 sec
- // after receives packets firstly. For safe, IR context starts
- // 0.4 sec (=3200 cycles) later to version 1 or 2 firmware,
- // 2.0 sec (=16000 cycles) for version 3 firmware. This is
- // within 2.5 sec (=CALLBACK_TIMEOUT).
- // Furthermore, some devices transfer isoc packets with
- // discontinuous counter in the beginning of packet streaming.
- // The delay has an effect to avoid detection of this
- // discontinuity.
- if (bebob->version < 2)
- ir_delay_cycle = 3200;
+ if (!(bebob->quirks & SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC))
+ tx_init_skip_cycles = 0;
else
- ir_delay_cycle = 16000;
- err = amdtp_domain_start(&bebob->domain, ir_delay_cycle);
+ tx_init_skip_cycles = 16000;
+
+ // MEMO: Some devices start packet transmission long enough after establishment of
+ // CMP connection. In the early stage of packet streaming, any device transfers
+ // NODATA packets. After several hundred cycles, it begins to multiplex event into
+ // the packet with adequate value of syt field in CIP header. Some devices are
+ // strictly to generate any discontinuity in the sequence of tx packet when they
+ // receives inadequate sequence of value in syt field of CIP header. In the case,
+ // the request to break CMP connection is often corrupted, then any transaction
+ // results in unrecoverable error, sometimes generate bus-reset.
+ err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, true, false);
if (err < 0)
goto error;
@@ -684,10 +658,9 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
}
}
- if (!amdtp_stream_wait_callback(&bebob->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&bebob->tx_stream,
- CALLBACK_TIMEOUT)) {
+ // Some devices postpone start of transmission mostly for 1 sec after receives
+ // packets firstly.
+ if (!amdtp_domain_wait_ready(&bebob->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
@@ -883,6 +856,11 @@ static int detect_midi_ports(struct snd_bebob *bebob,
err = avc_bridgeco_get_plug_ch_count(bebob->unit, addr, &ch_count);
if (err < 0)
break;
+ // Yamaha GO44, GO46, Terratec Phase 24, Phase x24 reports 0 for the number of
+ // channels in external output plug 3 (MIDI type) even if it has a pair of physical
+ // MIDI jacks. As a workaround, assume it as one.
+ if (ch_count == 0)
+ ch_count = 1;
*midi_ports += ch_count;
}
@@ -961,12 +939,12 @@ int snd_bebob_stream_discover(struct snd_bebob *bebob)
if (err < 0)
goto end;
- err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN,
+ err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN,
plugs[2], &bebob->midi_input_ports);
if (err < 0)
goto end;
- err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT,
+ err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT,
plugs[3], &bebob->midi_output_ports);
if (err < 0)
goto end;
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index c4dfe76500c2..f99e00083141 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -8,8 +8,8 @@
#include "dice.h"
-#define CALLBACK_TIMEOUT 200
-#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
+#define READY_TIMEOUT_MS 200
+#define NOTIFICATION_TIMEOUT_MS 100
struct reg_params {
unsigned int count;
@@ -57,13 +57,9 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
return -EINVAL;
}
-/*
- * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE
- * to GLOBAL_STATUS. Especially, just after powering on, these are different.
- */
-static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
+static int select_clock(struct snd_dice *dice, unsigned int rate)
{
- __be32 reg, nominal;
+ __be32 reg;
u32 data;
int i;
int err;
@@ -94,19 +90,8 @@ static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
return err;
if (wait_for_completion_timeout(&dice->clock_accepted,
- msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) {
- /*
- * Old versions of Dice firmware transfer no notification when
- * the same clock status as current one is set. In this case,
- * just check current clock status.
- */
- err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS,
- &nominal, sizeof(nominal));
- if (err < 0)
- return err;
- if (!(be32_to_cpu(nominal) & STATUS_SOURCE_LOCKED))
- return -ETIMEDOUT;
- }
+ msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
+ return -ETIMEDOUT;
return 0;
}
@@ -304,7 +289,7 @@ int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate,
// Just after owning the unit (GLOBAL_OWNER), the unit can
// return invalid stream formats. Selecting clock parameters
// have an effect for the unit to refine it.
- err = ensure_phase_lock(dice, rate);
+ err = select_clock(dice, rate);
if (err < 0)
return err;
@@ -459,20 +444,17 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice)
goto error;
}
- err = amdtp_domain_start(&dice->domain, 0);
+ // MEMO: The device immediately starts packet transmission when enabled. Some
+ // devices are strictly to generate any discontinuity in the sequence of tx packet
+ // when they receives invalid sequence of presentation time in CIP header. The
+ // sequence replay for media clock recovery can suppress the behaviour.
+ err = amdtp_domain_start(&dice->domain, 0, true, false);
if (err < 0)
goto error;
- for (i = 0; i < MAX_STREAMS; i++) {
- if ((i < tx_params.count &&
- !amdtp_stream_wait_callback(&dice->tx_stream[i],
- CALLBACK_TIMEOUT)) ||
- (i < rx_params.count &&
- !amdtp_stream_wait_callback(&dice->rx_stream[i],
- CALLBACK_TIMEOUT))) {
- err = -ETIMEDOUT;
- goto error;
- }
+ if (!amdtp_domain_wait_ready(&dice->domain, READY_TIMEOUT_MS)) {
+ err = -ETIMEDOUT;
+ goto error;
}
}
@@ -653,7 +635,7 @@ int snd_dice_stream_detect_current_formats(struct snd_dice *dice)
* invalid stream formats. Selecting clock parameters have an effect
* for the unit to refine it.
*/
- err = ensure_phase_lock(dice, rate);
+ err = select_clock(dice, rate);
if (err < 0)
return err;
diff --git a/sound/firewire/dice/dice-transaction.c b/sound/firewire/dice/dice-transaction.c
index 2c0dde29a024..92941ef83cd5 100644
--- a/sound/firewire/dice/dice-transaction.c
+++ b/sound/firewire/dice/dice-transaction.c
@@ -155,7 +155,7 @@ static void dice_notification(struct fw_card *card, struct fw_request *request,
fw_send_response(card, request, RCODE_COMPLETE);
- if (bits & NOTIFY_LOCK_CHG)
+ if (bits & NOTIFY_CLOCK_ACCEPTED)
complete(&dice->clock_accepted);
wake_up(&dice->hwdep_wait);
}
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 239d164b0eea..f75902bc8e74 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -135,22 +135,51 @@ static void dice_card_free(struct snd_card *card)
snd_dice_stream_destroy_duplex(dice);
snd_dice_transaction_destroy(dice);
+
+ mutex_destroy(&dice->mutex);
+ fw_unit_put(dice->unit);
}
-static void do_registration(struct work_struct *work)
+static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_dice *dice = container_of(work, struct snd_dice, dwork.work);
+ struct snd_card *card;
+ struct snd_dice *dice;
+ snd_dice_detect_formats_t detect_formats;
int err;
- if (dice->registered)
- return;
+ if (!entry->driver_data && entry->vendor_id != OUI_SSL) {
+ err = check_dice_category(unit);
+ if (err < 0)
+ return -ENODEV;
+ }
- err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
- &dice->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*dice), &card);
if (err < 0)
- return;
- dice->card->private_free = dice_card_free;
- dice->card->private_data = dice;
+ return err;
+ card->private_free = dice_card_free;
+
+ dice = card->private_data;
+ dice->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, dice);
+ dice->card = card;
+
+ if (!entry->driver_data)
+ detect_formats = snd_dice_stream_detect_current_formats;
+ else
+ detect_formats = (snd_dice_detect_formats_t)entry->driver_data;
+
+ // Below models are compliant to IEC 61883-1/6 and have no quirk at high sampling transfer
+ // frequency.
+ // * Avid M-Box 3 Pro
+ // * M-Audio Profire 610
+ // * M-Audio Profire 2626
+ if (entry->vendor_id == OUI_MAUDIO || entry->vendor_id == OUI_AVID)
+ dice->disable_double_pcm_frames = true;
+
+ spin_lock_init(&dice->lock);
+ mutex_init(&dice->mutex);
+ init_completion(&dice->clock_accepted);
+ init_waitqueue_head(&dice->hwdep_wait);
err = snd_dice_transaction_init(dice);
if (err < 0)
@@ -162,7 +191,7 @@ static void do_registration(struct work_struct *work)
dice_card_strings(dice);
- err = dice->detect_formats(dice);
+ err = detect_formats(dice);
if (err < 0)
goto error;
@@ -184,105 +213,34 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(dice->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- dice->registered = true;
-
- return;
-error:
- snd_card_free(dice->card);
- dev_info(&dice->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int dice_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_dice *dice;
- int err;
-
- if (!entry->driver_data && entry->vendor_id != OUI_SSL) {
- err = check_dice_category(unit);
- if (err < 0)
- return -ENODEV;
- }
-
- /* Allocate this independent of sound card instance. */
- dice = devm_kzalloc(&unit->device, sizeof(struct snd_dice), GFP_KERNEL);
- if (!dice)
- return -ENOMEM;
- dice->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, dice);
-
- if (!entry->driver_data) {
- dice->detect_formats = snd_dice_stream_detect_current_formats;
- } else {
- dice->detect_formats =
- (snd_dice_detect_formats_t)entry->driver_data;
- }
-
- // Below models are compliant to IEC 61883-1/6 and have no quirk at high sampling transfer
- // frequency.
- // * Avid M-Box 3 Pro
- // * M-Audio Profire 610
- // * M-Audio Profire 2626
- if (entry->vendor_id == OUI_MAUDIO || entry->vendor_id == OUI_AVID)
- dice->disable_double_pcm_frames = true;
-
- spin_lock_init(&dice->lock);
- mutex_init(&dice->mutex);
- init_completion(&dice->clock_accepted);
- init_waitqueue_head(&dice->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
- snd_fw_schedule_registration(unit, &dice->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void dice_remove(struct fw_unit *unit)
{
struct snd_dice *dice = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&dice->dwork);
-
- if (dice->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(dice->card);
- }
-
- mutex_destroy(&dice->mutex);
- fw_unit_put(dice->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(dice->card);
}
static void dice_bus_reset(struct fw_unit *unit)
{
struct snd_dice *dice = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!dice->registered)
- snd_fw_schedule_registration(unit, &dice->dwork);
-
/* The handler address register becomes initialized. */
snd_dice_transaction_reinit(dice);
- /*
- * After registration, userspace can start packet streaming, then this
- * code block works fine.
- */
- if (dice->registered) {
- mutex_lock(&dice->mutex);
- snd_dice_stream_update_duplex(dice);
- mutex_unlock(&dice->mutex);
- }
+ mutex_lock(&dice->mutex);
+ snd_dice_stream_update_duplex(dice);
+ mutex_unlock(&dice->mutex);
}
#define DICE_INTERFACE 0x000001
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 3c967d1b3605..fd440cc625f9 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -78,9 +78,6 @@ struct snd_dice {
spinlock_t lock;
struct mutex mutex;
- bool registered;
- struct delayed_work dwork;
-
/* Offsets for sub-addresses */
unsigned int global_offset;
unsigned int rx_offset;
@@ -93,7 +90,6 @@ struct snd_dice {
unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
unsigned int tx_midi_ports[MAX_STREAMS];
unsigned int rx_midi_ports[MAX_STREAMS];
- snd_dice_detect_formats_t detect_formats;
struct fw_address_handler notification_handler;
int owner_generation;
diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c
index d613642a2ce3..59b86c8d89e1 100644
--- a/sound/firewire/digi00x/amdtp-dot.c
+++ b/sound/firewire/digi00x/amdtp-dot.c
@@ -396,16 +396,13 @@ int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir)
{
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
- enum cip_flags flags;
+ unsigned int flags = CIP_NONBLOCKING | CIP_UNAWARE_SYT;
// Use different mode between incoming/outgoing.
- if (dir == AMDTP_IN_STREAM) {
- flags = CIP_NONBLOCKING;
+ if (dir == AMDTP_IN_STREAM)
process_ctx_payloads = process_ir_ctx_payloads;
- } else {
- flags = CIP_BLOCKING;
+ else
process_ctx_payloads = process_it_ctx_payloads;
- }
return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
process_ctx_payloads, sizeof(struct amdtp_dot));
diff --git a/sound/firewire/digi00x/digi00x-stream.c b/sound/firewire/digi00x/digi00x-stream.c
index 405d6903bfbc..a15f55b0dce3 100644
--- a/sound/firewire/digi00x/digi00x-stream.c
+++ b/sound/firewire/digi00x/digi00x-stream.c
@@ -7,7 +7,7 @@
#include "digi00x.h"
-#define CALLBACK_TIMEOUT 500
+#define READY_TIMEOUT_MS 200
const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT] = {
[SND_DG00X_RATE_44100] = 44100,
@@ -375,14 +375,15 @@ int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
if (err < 0)
goto error;
- err = amdtp_domain_start(&dg00x->domain, 0);
+ // NOTE: The device doesn't start packet transmission till receiving any packet.
+ // It ignores presentation time expressed by the value of syt field of CIP header
+ // in received packets. The sequence of the number of data blocks per packet is
+ // important for media clock recovery.
+ err = amdtp_domain_start(&dg00x->domain, 0, true, true);
if (err < 0)
goto error;
- if (!amdtp_stream_wait_callback(&dg00x->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&dg00x->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&dg00x->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
index ab8408966ec3..995302808c27 100644
--- a/sound/firewire/digi00x/digi00x.c
+++ b/sound/firewire/digi00x/digi00x.c
@@ -47,23 +47,32 @@ static void dg00x_card_free(struct snd_card *card)
snd_dg00x_stream_destroy_duplex(dg00x);
snd_dg00x_transaction_unregister(dg00x);
+
+ mutex_destroy(&dg00x->mutex);
+ fw_unit_put(dg00x->unit);
}
-static void do_registration(struct work_struct *work)
+static int snd_dg00x_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_dg00x *dg00x =
- container_of(work, struct snd_dg00x, dwork.work);
+ struct snd_card *card;
+ struct snd_dg00x *dg00x;
int err;
- if (dg00x->registered)
- return;
-
- err = snd_card_new(&dg00x->unit->device, -1, NULL, THIS_MODULE, 0,
- &dg00x->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*dg00x), &card);
if (err < 0)
- return;
- dg00x->card->private_free = dg00x_card_free;
- dg00x->card->private_data = dg00x;
+ return err;
+ card->private_free = dg00x_card_free;
+
+ dg00x = card->private_data;
+ dg00x->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, dg00x);
+ dg00x->card = card;
+
+ mutex_init(&dg00x->mutex);
+ spin_lock_init(&dg00x->lock);
+ init_waitqueue_head(&dg00x->hwdep_wait);
+
+ dg00x->is_console = entry->model_id == MODEL_CONSOLE;
err = name_card(dg00x);
if (err < 0)
@@ -91,85 +100,33 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(dg00x->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- dg00x->registered = true;
-
- return;
-error:
- snd_card_free(dg00x->card);
- dev_info(&dg00x->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int snd_dg00x_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_dg00x *dg00x;
-
- /* Allocate this independent of sound card instance. */
- dg00x = devm_kzalloc(&unit->device, sizeof(struct snd_dg00x),
- GFP_KERNEL);
- if (!dg00x)
- return -ENOMEM;
-
- dg00x->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, dg00x);
-
- mutex_init(&dg00x->mutex);
- spin_lock_init(&dg00x->lock);
- init_waitqueue_head(&dg00x->hwdep_wait);
-
- dg00x->is_console = entry->model_id == MODEL_CONSOLE;
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration);
- snd_fw_schedule_registration(unit, &dg00x->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void snd_dg00x_update(struct fw_unit *unit)
{
struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!dg00x->registered)
- snd_fw_schedule_registration(unit, &dg00x->dwork);
-
snd_dg00x_transaction_reregister(dg00x);
- /*
- * After registration, userspace can start packet streaming, then this
- * code block works fine.
- */
- if (dg00x->registered) {
- mutex_lock(&dg00x->mutex);
- snd_dg00x_stream_update_duplex(dg00x);
- mutex_unlock(&dg00x->mutex);
- }
+ mutex_lock(&dg00x->mutex);
+ snd_dg00x_stream_update_duplex(dg00x);
+ mutex_unlock(&dg00x->mutex);
}
static void snd_dg00x_remove(struct fw_unit *unit)
{
struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&dg00x->dwork);
-
- if (dg00x->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(dg00x->card);
- }
-
- mutex_destroy(&dg00x->mutex);
- fw_unit_put(dg00x->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(dg00x->card);
}
static const struct ieee1394_device_id snd_dg00x_id_table[] = {
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
index 129de8edd5ea..82b647d383c5 100644
--- a/sound/firewire/digi00x/digi00x.h
+++ b/sound/firewire/digi00x/digi00x.h
@@ -37,9 +37,6 @@ struct snd_dg00x {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
struct amdtp_stream tx_stream;
struct fw_iso_resources tx_resources;
diff --git a/sound/firewire/fireface/amdtp-ff.c b/sound/firewire/fireface/amdtp-ff.c
index 119c0076b17a..98177b0666d3 100644
--- a/sound/firewire/fireface/amdtp-ff.c
+++ b/sound/firewire/fireface/amdtp-ff.c
@@ -168,6 +168,6 @@ int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
else
process_ctx_payloads = process_it_ctx_payloads;
- return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0,
+ return amdtp_stream_init(s, unit, dir, CIP_BLOCKING | CIP_UNAWARE_SYT | CIP_NO_HEADER, 0,
process_ctx_payloads, sizeof(struct amdtp_ff));
}
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 5452115c0ef9..95bf405adb3d 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -7,7 +7,7 @@
#include "ff.h"
-#define CALLBACK_TIMEOUT_MS 200
+#define READY_TIMEOUT_MS 200
int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
enum snd_ff_stream_mode *mode)
@@ -199,14 +199,15 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
if (err < 0)
goto error;
- err = amdtp_domain_start(&ff->domain, 0);
+ // NOTE: The device doesn't transfer packets unless receiving any packet. The
+ // sequence of tx packets includes cycle skip corresponding to empty packet or
+ // NODATA packet in IEC 61883-1/6. The sequence of the number of data blocks per
+ // packet is important for media clock recovery.
+ err = amdtp_domain_start(&ff->domain, 0, true, true);
if (err < 0)
goto error;
- if (!amdtp_stream_wait_callback(&ff->rx_stream,
- CALLBACK_TIMEOUT_MS) ||
- !amdtp_stream_wait_callback(&ff->tx_stream,
- CALLBACK_TIMEOUT_MS)) {
+ if (!amdtp_domain_wait_ready(&ff->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
index bc39269415d2..7bf51d062021 100644
--- a/sound/firewire/fireface/ff.c
+++ b/sound/firewire/fireface/ff.c
@@ -42,22 +42,33 @@ static void ff_card_free(struct snd_card *card)
snd_ff_stream_destroy_duplex(ff);
snd_ff_transaction_unregister(ff);
+
+ mutex_destroy(&ff->mutex);
+ fw_unit_put(ff->unit);
}
-static void do_registration(struct work_struct *work)
+static int snd_ff_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work);
+ struct snd_card *card;
+ struct snd_ff *ff;
int err;
- if (ff->registered)
- return;
-
- err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0,
- &ff->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*ff), &card);
if (err < 0)
- return;
- ff->card->private_free = ff_card_free;
- ff->card->private_data = ff;
+ return err;
+ card->private_free = ff_card_free;
+
+ ff = card->private_data;
+ ff->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, ff);
+ ff->card = card;
+
+ mutex_init(&ff->mutex);
+ spin_lock_init(&ff->lock);
+ init_waitqueue_head(&ff->hwdep_wait);
+
+ ff->unit_version = entry->version;
+ ff->spec = (const struct snd_ff_spec *)entry->driver_data;
err = snd_ff_transaction_register(ff);
if (err < 0)
@@ -83,76 +94,31 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(ff->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- ff->registered = true;
-
- return;
-error:
- snd_card_free(ff->card);
- dev_info(&ff->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int snd_ff_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_ff *ff;
-
- ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL);
- if (!ff)
- return -ENOMEM;
- ff->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, ff);
-
- mutex_init(&ff->mutex);
- spin_lock_init(&ff->lock);
- init_waitqueue_head(&ff->hwdep_wait);
-
- ff->unit_version = entry->version;
- ff->spec = (const struct snd_ff_spec *)entry->driver_data;
-
- /* Register this sound card later. */
- INIT_DEFERRABLE_WORK(&ff->dwork, do_registration);
- snd_fw_schedule_registration(unit, &ff->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void snd_ff_update(struct fw_unit *unit)
{
struct snd_ff *ff = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!ff->registered)
- snd_fw_schedule_registration(unit, &ff->dwork);
-
snd_ff_transaction_reregister(ff);
- if (ff->registered)
- snd_ff_stream_update_duplex(ff);
+ snd_ff_stream_update_duplex(ff);
}
static void snd_ff_remove(struct fw_unit *unit)
{
struct snd_ff *ff = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_work_sync(&ff->dwork.work);
-
- if (ff->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(ff->card);
- }
-
- mutex_destroy(&ff->mutex);
- fw_unit_put(ff->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(ff->card);
}
static const struct snd_ff_spec spec_ff800 = {
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
index 705e7df4f929..0535f0b58b67 100644
--- a/sound/firewire/fireface/ff.h
+++ b/sound/firewire/fireface/ff.h
@@ -69,9 +69,6 @@ struct snd_ff {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
enum snd_ff_unit_version unit_version;
const struct snd_ff_spec *spec;
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index b1cc013a3540..ffb6dd796243 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -194,19 +194,19 @@ efw_card_free(struct snd_card *card)
snd_efw_stream_destroy_duplex(efw);
snd_efw_transaction_remove_instance(efw);
+
+ mutex_destroy(&efw->mutex);
+ fw_unit_put(efw->unit);
}
-static void
-do_registration(struct work_struct *work)
+static int efw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_efw *efw = container_of(work, struct snd_efw, dwork.work);
unsigned int card_index;
+ struct snd_card *card;
+ struct snd_efw *efw;
int err;
- if (efw->registered)
- return;
-
- /* check registered cards */
+ // 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])
@@ -214,26 +214,32 @@ do_registration(struct work_struct *work)
}
if (card_index >= SNDRV_CARDS) {
mutex_unlock(&devices_mutex);
- return;
+ return -ENOENT;
}
- err = snd_card_new(&efw->unit->device, index[card_index],
- id[card_index], THIS_MODULE, 0, &efw->card);
+ 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;
+ return err;
}
+ card->private_free = efw_card_free;
set_bit(card_index, devices_used);
mutex_unlock(&devices_mutex);
- efw->card->private_free = efw_card_free;
- efw->card->private_data = efw;
+ efw = card->private_data;
+ efw->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, efw);
+ efw->card = card;
+ efw->card_index = card_index;
+
+ mutex_init(&efw->mutex);
+ spin_lock_init(&efw->lock);
+ init_waitqueue_head(&efw->hwdep_wait);
- /* prepare response buffer */
- snd_efw_resp_buf_size = clamp(snd_efw_resp_buf_size,
- SND_EFW_RESPONSE_MAXIMUM_BYTES, 4096U);
- efw->resp_buf = devm_kzalloc(&efw->card->card_dev,
- snd_efw_resp_buf_size, GFP_KERNEL);
+ // prepare response buffer.
+ snd_efw_resp_buf_size = clamp(snd_efw_resp_buf_size, SND_EFW_RESPONSE_MAXIMUM_BYTES, 4096U);
+ efw->resp_buf = devm_kzalloc(&card->card_dev, snd_efw_resp_buf_size, GFP_KERNEL);
if (!efw->resp_buf) {
err = -ENOMEM;
goto error;
@@ -265,80 +271,48 @@ do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(efw->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- efw->registered = true;
-
- return;
-error:
- snd_card_free(efw->card);
- dev_info(&efw->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int
-efw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
-{
- struct snd_efw *efw;
-
- efw = devm_kzalloc(&unit->device, sizeof(struct snd_efw), GFP_KERNEL);
- if (efw == NULL)
- return -ENOMEM;
- efw->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, efw);
-
- mutex_init(&efw->mutex);
- spin_lock_init(&efw->lock);
- init_waitqueue_head(&efw->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&efw->dwork, do_registration);
- snd_fw_schedule_registration(unit, &efw->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void efw_update(struct fw_unit *unit)
{
struct snd_efw *efw = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!efw->registered)
- snd_fw_schedule_registration(unit, &efw->dwork);
-
snd_efw_transaction_bus_reset(efw->unit);
- /*
- * After registration, userspace can start packet streaming, then this
- * code block works fine.
- */
- if (efw->registered) {
- mutex_lock(&efw->mutex);
- snd_efw_stream_update_duplex(efw);
- mutex_unlock(&efw->mutex);
- }
+ mutex_lock(&efw->mutex);
+ snd_efw_stream_update_duplex(efw);
+ mutex_unlock(&efw->mutex);
}
static void efw_remove(struct fw_unit *unit)
{
struct snd_efw *efw = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&efw->dwork);
-
- if (efw->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(efw->card);
- }
+ // Block till all of ALSA character devices are released.
+ snd_card_free(efw->card);
+}
- mutex_destroy(&efw->mutex);
- fw_unit_put(efw->unit);
+#define SPECIFIER_1394TA 0x00a02d
+#define VERSION_EFW 0x010000
+
+#define SND_EFW_DEV_ENTRY(vendor, model) \
+{ \
+ .match_flags = IEEE1394_MATCH_VENDOR_ID | \
+ IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID | \
+ IEEE1394_MATCH_VERSION, \
+ .vendor_id = vendor,\
+ .model_id = model, \
+ .specifier_id = SPECIFIER_1394TA, \
+ .version = VERSION_EFW, \
}
static const struct ieee1394_device_id efw_id_table[] = {
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index 654e28a6669f..c8d5879efe28 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -65,9 +65,6 @@ struct snd_efw {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
/* for transaction */
u32 seqnum;
bool resp_addr_changable;
@@ -181,7 +178,7 @@ struct snd_efw_phys_meters {
} __packed;
enum snd_efw_clock_source {
SND_EFW_CLOCK_SOURCE_INTERNAL = 0,
- SND_EFW_CLOCK_SOURCE_SYTMATCH = 1,
+ // Unused.
SND_EFW_CLOCK_SOURCE_WORDCLOCK = 2,
SND_EFW_CLOCK_SOURCE_SPDIF = 3,
SND_EFW_CLOCK_SOURCE_ADAT_1 = 4,
@@ -227,12 +224,4 @@ int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode);
int snd_efw_create_hwdep_device(struct snd_efw *efw);
-#define SND_EFW_DEV_ENTRY(vendor, model) \
-{ \
- .match_flags = IEEE1394_MATCH_VENDOR_ID | \
- IEEE1394_MATCH_MODEL_ID, \
- .vendor_id = vendor,\
- .model_id = model \
-}
-
#endif
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 2206af0fef42..ac66f08acd6b 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -6,7 +6,7 @@
*/
#include "./fireworks.h"
-#define CALLBACK_TIMEOUT 100
+#define READY_TIMEOUT_MS 1000
static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{
@@ -29,7 +29,7 @@ static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
if (err < 0)
return err;
- err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING);
+ err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING | CIP_UNAWARE_SYT);
if (err < 0) {
amdtp_stream_destroy(stream);
cmp_connection_destroy(conn);
@@ -264,6 +264,15 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
return err;
if (!amdtp_stream_running(&efw->rx_stream)) {
+ unsigned int tx_init_skip_cycles;
+
+ // Audiofire 2/4 skip an isochronous cycle several thousands after starting
+ // packet transmission.
+ if (efw->is_fireworks3 && !efw->is_af9)
+ tx_init_skip_cycles = 6000;
+ else
+ tx_init_skip_cycles = 0;
+
err = start_stream(efw, &efw->rx_stream, rate);
if (err < 0)
goto error;
@@ -272,15 +281,14 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
if (err < 0)
goto error;
- err = amdtp_domain_start(&efw->domain, 0);
+ // NOTE: The device ignores presentation time expressed by the value of syt field
+ // of CIP header in received packets. The sequence of the number of data blocks per
+ // packet is important for media clock recovery.
+ err = amdtp_domain_start(&efw->domain, tx_init_skip_cycles, true, false);
if (err < 0)
goto error;
- // Wait first callback.
- if (!amdtp_stream_wait_callback(&efw->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&efw->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&efw->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index 85c4f4477c7f..e0a2337e8f27 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -67,38 +67,6 @@ int snd_fw_transaction(struct fw_unit *unit, int tcode,
}
EXPORT_SYMBOL(snd_fw_transaction);
-#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
-
-/**
- * snd_fw_schedule_registration - schedule work for sound card registration
- * @unit: an instance for unit on IEEE 1394 bus
- * @dwork: delayed work with callback function
- *
- * This function is not designed for general purposes. When new unit is
- * connected to IEEE 1394 bus, the bus is under bus-reset state because of
- * topological change. In this state, units tend to fail both of asynchronous
- * and isochronous communication. To avoid this problem, this function is used
- * to postpone sound card registration after the state. The callers must
- * set up instance of delayed work in advance.
- */
-void snd_fw_schedule_registration(struct fw_unit *unit,
- struct delayed_work *dwork)
-{
- u64 now, delay;
-
- now = get_jiffies_64();
- delay = fw_parent_device(unit)->card->reset_jiffies
- + msecs_to_jiffies(PROBE_DELAY_MS);
-
- if (time_after64(delay, now))
- delay -= now;
- else
- delay = 0;
-
- mod_delayed_work(system_wq, dwork, delay);
-}
-EXPORT_SYMBOL(snd_fw_schedule_registration);
-
MODULE_DESCRIPTION("FireWire audio helper functions");
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index dc815dc3933e..664dfdb9e58d 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -23,7 +23,4 @@ static inline bool rcode_is_permanent_error(int rcode)
return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
}
-void snd_fw_schedule_registration(struct fw_unit *unit,
- struct delayed_work *dwork);
-
#endif
diff --git a/sound/firewire/motu/Makefile b/sound/firewire/motu/Makefile
index 7c502d35103c..acdf66564fb0 100644
--- a/sound/firewire/motu/Makefile
+++ b/sound/firewire/motu/Makefile
@@ -3,5 +3,6 @@ CFLAGS_amdtp-motu.o := -I$(src)
snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \
motu-proc.o motu-pcm.o motu-midi.o motu-hwdep.o \
- motu-protocol-v2.o motu-protocol-v3.o
+ motu-protocol-v2.o motu-protocol-v3.o \
+ motu-protocol-v1.o
obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c
index edb31ac26868..5388b85fb60e 100644
--- a/sound/firewire/motu/amdtp-motu.c
+++ b/sound/firewire/motu/amdtp-motu.c
@@ -16,6 +16,14 @@
#define CIP_FMT_MOTU_TX_V3 0x22
#define MOTU_FDF_AM824 0x22
+#define TICKS_PER_CYCLE 3072
+#define CYCLES_PER_SECOND 8000
+#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
+
+#define CIP_SPH_CYCLE_SHIFT 12
+#define CIP_SPH_CYCLE_MASK 0x01fff000
+#define CIP_SPH_OFFSET_MASK 0x00000fff
+
/*
* Nominally 3125 bytes/second, but the MIDI port's clock might be
* 1% too slow, and the bus clock 100 ppm too fast.
@@ -23,14 +31,6 @@
#define MIDI_BYTES_PER_SECOND 3093
struct amdtp_motu {
- /* For timestamp processing. */
- unsigned int quotient_ticks_per_event;
- unsigned int remainder_ticks_per_event;
- unsigned int next_ticks;
- unsigned int next_accumulated;
- unsigned int next_cycles;
- unsigned int next_seconds;
-
unsigned int pcm_chunks;
unsigned int pcm_byte_offset;
@@ -41,26 +41,16 @@ struct amdtp_motu {
int midi_db_count;
unsigned int midi_db_interval;
+
+ struct amdtp_motu_cache *cache;
};
int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
unsigned int midi_ports,
struct snd_motu_packet_format *formats)
{
- static const struct {
- unsigned int quotient_ticks_per_event;
- unsigned int remainder_ticks_per_event;
- } params[] = {
- [CIP_SFC_44100] = { 557, 123 },
- [CIP_SFC_48000] = { 512, 0 },
- [CIP_SFC_88200] = { 278, 282 },
- [CIP_SFC_96000] = { 256, 0 },
- [CIP_SFC_176400] = { 139, 141 },
- [CIP_SFC_192000] = { 128, 0 },
- };
struct amdtp_motu *p = s->protocol;
unsigned int pcm_chunks, data_chunks, data_block_quadlets;
- unsigned int delay;
unsigned int mode;
int i, err;
@@ -97,19 +87,6 @@ int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
p->midi_db_count = 0;
p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND;
- /* IEEE 1394 bus requires. */
- delay = 0x2e00;
-
- /* For no-data or empty packets to adjust PCM sampling frequency. */
- delay += 8000 * 3072 * s->syt_interval / rate;
-
- p->next_seconds = 0;
- p->next_cycles = delay / 3072;
- p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event;
- p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event;
- p->next_ticks = delay % 3072;
- p->next_accumulated = 0;
-
return 0;
}
@@ -322,6 +299,34 @@ static void probe_tracepoints_events(struct amdtp_stream *s,
}
}
+static void cache_event_offsets(struct amdtp_motu_cache *cache, const __be32 *buf,
+ unsigned int data_blocks, unsigned int data_block_quadlets)
+{
+ unsigned int *event_offsets = cache->event_offsets;
+ const unsigned int cache_size = cache->size;
+ unsigned int cache_tail = cache->tail;
+ unsigned int base_tick = cache->tx_cycle_count * TICKS_PER_CYCLE;
+ int i;
+
+ for (i = 0; i < data_blocks; ++i) {
+ u32 sph = be32_to_cpu(*buf);
+ unsigned int tick;
+
+ tick = ((sph & CIP_SPH_CYCLE_MASK) >> CIP_SPH_CYCLE_SHIFT) * TICKS_PER_CYCLE +
+ (sph & CIP_SPH_OFFSET_MASK);
+
+ if (tick < base_tick)
+ tick += TICKS_PER_SECOND;
+ event_offsets[cache_tail] = tick - base_tick;
+
+ cache_tail = (cache_tail + 1) % cache_size;
+ buf += data_block_quadlets;
+ }
+
+ cache->tail = cache_tail;
+ cache->tx_cycle_count = (cache->tx_cycle_count + 1) % CYCLES_PER_SECOND;
+}
+
static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
@@ -331,12 +336,17 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
unsigned int pcm_frames = 0;
int i;
+ if (p->cache->tx_cycle_count == UINT_MAX)
+ p->cache->tx_cycle_count = (s->domain->processing_cycle.tx_start % CYCLES_PER_SECOND);
+
// For data block processing.
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__be32 *buf = desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;
+ cache_event_offsets(p->cache, buf, data_blocks, s->data_block_quadlets);
+
if (pcm) {
read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks;
@@ -354,46 +364,26 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
return pcm_frames;
}
-static inline void compute_next_elapse_from_start(struct amdtp_motu *p)
-{
- p->next_accumulated += p->remainder_ticks_per_event;
- if (p->next_accumulated >= 441) {
- p->next_accumulated -= 441;
- p->next_ticks++;
- }
-
- p->next_ticks += p->quotient_ticks_per_event;
- if (p->next_ticks >= 3072) {
- p->next_ticks -= 3072;
- p->next_cycles++;
- }
-
- if (p->next_cycles >= 8000) {
- p->next_cycles -= 8000;
- p->next_seconds++;
- }
-
- if (p->next_seconds >= 128)
- p->next_seconds -= 128;
-}
-
-static void write_sph(struct amdtp_stream *s, __be32 *buffer,
- unsigned int data_blocks)
+static void write_sph(struct amdtp_motu_cache *cache, __be32 *buffer, unsigned int data_blocks,
+ unsigned int data_block_quadlets)
{
- struct amdtp_motu *p = s->protocol;
- unsigned int next_cycles;
- unsigned int i;
- u32 sph;
+ unsigned int *event_offsets = cache->event_offsets;
+ const unsigned int cache_size = cache->size;
+ unsigned int cache_head = cache->head;
+ unsigned int base_tick = cache->rx_cycle_count * TICKS_PER_CYCLE;
+ int i;
for (i = 0; i < data_blocks; i++) {
- next_cycles = (s->start_cycle + p->next_cycles) % 8000;
- sph = ((next_cycles << 12) | p->next_ticks) & 0x01ffffff;
+ unsigned int tick = (base_tick + event_offsets[cache_head]) % TICKS_PER_SECOND;
+ u32 sph = ((tick / TICKS_PER_CYCLE) << CIP_SPH_CYCLE_SHIFT) | (tick % TICKS_PER_CYCLE);
*buffer = cpu_to_be32(sph);
- compute_next_elapse_from_start(p);
-
- buffer += s->data_block_quadlets;
+ cache_head = (cache_head + 1) % cache_size;
+ buffer += data_block_quadlets;
}
+
+ cache->head = cache_head;
+ cache->rx_cycle_count = (cache->rx_cycle_count + 1) % CYCLES_PER_SECOND;
}
static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
@@ -405,6 +395,9 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
unsigned int pcm_frames = 0;
int i;
+ if (p->cache->rx_cycle_count == UINT_MAX)
+ p->cache->rx_cycle_count = (s->domain->processing_cycle.rx_start % CYCLES_PER_SECOND);
+
// For data block processing.
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
@@ -423,7 +416,7 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
// TODO: how to interact control messages between userspace?
- write_sph(s, buf, data_blocks);
+ write_sph(p->cache, buf, data_blocks, s->data_block_quadlets);
}
// For tracepoints.
@@ -436,11 +429,12 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir,
- const struct snd_motu_spec *spec)
+ const struct snd_motu_spec *spec, struct amdtp_motu_cache *cache)
{
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
int fmt = CIP_FMT_MOTU;
- int flags = CIP_BLOCKING;
+ unsigned int flags = CIP_BLOCKING | CIP_UNAWARE_SYT;
+ struct amdtp_motu *p;
int err;
if (dir == AMDTP_IN_STREAM) {
@@ -478,9 +472,10 @@ int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
if (dir == AMDTP_OUT_STREAM) {
// Use fixed value for FDF field.
s->ctx_data.rx.fdf = MOTU_FDF_AM824;
- // Not used.
- s->ctx_data.rx.syt_override = 0xffff;
}
+ p = s->protocol;
+ p->cache = cache;
+
return 0;
}
diff --git a/sound/firewire/motu/motu-protocol-v1.c b/sound/firewire/motu/motu-protocol-v1.c
new file mode 100644
index 000000000000..f1d6a326dc07
--- /dev/null
+++ b/sound/firewire/motu/motu-protocol-v1.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+// motu-protocol-v1.c - a part of driver for MOTU FireWire series
+//
+// Copyright (c) 2021 Takashi Sakamoto <o-takashi@sakamocchi.jp>
+//
+// Licensed under the terms of the GNU General Public License, version 2.
+
+#include "motu.h"
+
+#include <linux/delay.h>
+
+// Status register for MOTU 828 (0x'ffff'f000'0b00).
+//
+// 0xffff0000: ISOC_COMM_CONTROL_MASK in motu-stream.c.
+// 0x00008000: mode of optical input interface.
+// 0x00008000: for S/PDIF signal.
+// 0x00000000: disabled or for ADAT signal.
+// 0x00004000: mode of optical output interface.
+// 0x00004000: for S/PDIF signal.
+// 0x00000000: disabled or for ADAT signal.
+// 0x00003f00: monitor input mode.
+// 0x00000800: analog-1/2
+// 0x00001a00: analog-3/4
+// 0x00002c00: analog-5/6
+// 0x00003e00: analog-7/8
+// 0x00000000: analog-1
+// 0x00000900: analog-2
+// 0x00001200: analog-3
+// 0x00001b00: analog-4
+// 0x00002400: analog-5
+// 0x00002d00: analog-6
+// 0x00003600: analog-7
+// 0x00003f00: analog-8
+// 0x00000080: enable stream input.
+// 0x00000040: disable monitor input.
+// 0x00000008: enable main out.
+// 0x00000004: rate of sampling clock.
+// 0x00000004: 48.0 kHz
+// 0x00000000: 44.1 kHz
+// 0x00000023: source of sampling clock.
+// 0x00000003: source packet header (SPH)
+// 0x00000002: S/PDIF on optical/coaxial interface.
+// 0x00000021: ADAT on optical interface
+// 0x00000001: ADAT on Dsub 9pin
+// 0x00000000: internal
+
+#define CLK_828_STATUS_OFFSET 0x0b00
+#define CLK_828_STATUS_MASK 0x0000ffff
+#define CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF 0x00008000
+#define CLK_828_STATUS_FLAG_OPT_OUT_IFACE_IS_SPDIF 0x00004000
+#define CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES 0x00000080
+#define CLK_828_STATUS_FLAG_ENABLE_OUTPUT 0x00000008
+#define CLK_828_STATUS_FLAG_RATE_48000 0x00000004
+#define CLK_828_STATUS_MASK_SRC 0x00000023
+#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000021
+#define CLK_828_STATUS_FLAG_SRC_SPH 0x00000003
+#define CLK_828_STATUS_FLAG_SRC_SPDIF 0x00000002
+#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000001
+#define CLK_828_STATUS_FLAG_SRC_INTERNAL 0x00000000
+
+// Status register for MOTU 896 (0x'ffff'f000'0b14).
+//
+// 0xf0000000: enable physical and stream input to DAC.
+// 0x80000000: disable
+// 0x40000000: disable
+// 0x20000000: enable (prior to the other bits)
+// 0x10000000: disable
+// 0x00000000: disable
+// 0x08000000: speed of word clock signal output on BNC interface.
+// 0x00000000: force to low rate (44.1/48.0 kHz).
+// 0x08000000: follow to system clock.
+// 0x04000000: something relevant to clock.
+// 0x03000000: enable output.
+// 0x02000000: enabled irreversibly once standing unless the device voluntarily disables it.
+// 0x01000000: enabled irreversibly once standing unless the device voluntarily disables it.
+// 0x00ffff00: monitor input mode.
+// 0x00000000: disabled
+// 0x00004800: analog-1/2
+// 0x00005a00: analog-3/4
+// 0x00006c00: analog-5/6
+// 0x00007e00: analog-7/8
+// 0x00104800: AES/EBU-1/2
+// 0x00004000: analog-1
+// 0x00004900: analog-2
+// 0x00005200: analog-3
+// 0x00005b00: analog-4
+// 0x00006400: analog-5
+// 0x00006d00: analog-6
+// 0x00007600: analog-7
+// 0x00007f00: analog-8
+// 0x00104000: AES/EBU-1
+// 0x00104900: AES/EBU-2
+// 0x00000060: sample rate conversion for AES/EBU input/output.
+// 0x00000000: None
+// 0x00000020: input signal is converted to system rate
+// 0x00000040: output is slave to input, ignoring system rate
+// 0x00000060: output is double rate than system rate
+// 0x00000018: nominal rate of sampling clock.
+// 0x00000000: 44.1 kHz
+// 0x00000008: 48.0 kHz
+// 0x00000010: 88.2 kHz
+// 0x00000018: 96.0 kHz
+// 0x00000007: source of sampling clock.
+// 0x00000000: internal
+// 0x00000001: ADAT on optical interface
+// 0x00000002: AES/EBU on XLR
+// 0x00000003: source packet header (SPH)
+// 0x00000004: word clock on BNC
+// 0x00000005: ADAT on Dsub 9pin
+
+#define CLK_896_STATUS_OFFSET 0x0b14
+#define CLK_896_STATUS_FLAG_FETCH_ENABLE 0x20000000
+#define CLK_896_STATUS_FLAG_OUTPUT_ON 0x03000000
+#define CLK_896_STATUS_MASK_SRC 0x00000007
+#define CLK_896_STATUS_FLAG_SRC_INTERNAL 0x00000000
+#define CLK_896_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000001
+#define CLK_896_STATUS_FLAG_SRC_AESEBU 0x00000002
+#define CLK_896_STATUS_FLAG_SRC_SPH 0x00000003
+#define CLK_896_STATUS_FLAG_SRC_WORD 0x00000004
+#define CLK_896_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000005
+#define CLK_896_STATUS_MASK_RATE 0x00000018
+#define CLK_896_STATUS_FLAG_RATE_44100 0x00000000
+#define CLK_896_STATUS_FLAG_RATE_48000 0x00000008
+#define CLK_896_STATUS_FLAG_RATE_88200 0x00000010
+#define CLK_896_STATUS_FLAG_RATE_96000 0x00000018
+
+static void parse_clock_rate_828(u32 data, unsigned int *rate)
+{
+ if (data & CLK_828_STATUS_FLAG_RATE_48000)
+ *rate = 48000;
+ else
+ *rate = 44100;
+}
+
+static int get_clock_rate_828(struct snd_motu *motu, unsigned int *rate)
+{
+ __be32 reg;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ parse_clock_rate_828(be32_to_cpu(reg), rate);
+
+ return 0;
+}
+
+static int parse_clock_rate_896(u32 data, unsigned int *rate)
+{
+ switch (data & CLK_896_STATUS_MASK_RATE) {
+ case CLK_896_STATUS_FLAG_RATE_44100:
+ *rate = 44100;
+ break;
+ case CLK_896_STATUS_FLAG_RATE_48000:
+ *rate = 48000;
+ break;
+ case CLK_896_STATUS_FLAG_RATE_88200:
+ *rate = 88200;
+ break;
+ case CLK_896_STATUS_FLAG_RATE_96000:
+ *rate = 96000;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int get_clock_rate_896(struct snd_motu *motu, unsigned int *rate)
+{
+ __be32 reg;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ return parse_clock_rate_896(be32_to_cpu(reg), rate);
+}
+
+int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu, unsigned int *rate)
+{
+ if (motu->spec == &snd_motu_spec_828)
+ return get_clock_rate_828(motu, rate);
+ else if (motu->spec == &snd_motu_spec_896)
+ return get_clock_rate_896(motu, rate);
+ else
+ return -ENXIO;
+}
+
+static int set_clock_rate_828(struct snd_motu *motu, unsigned int rate)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
+
+ data &= ~CLK_828_STATUS_FLAG_RATE_48000;
+ if (rate == 48000)
+ data |= CLK_828_STATUS_FLAG_RATE_48000;
+
+ reg = cpu_to_be32(data);
+ return snd_motu_transaction_write(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+}
+
+static int set_clock_rate_896(struct snd_motu *motu, unsigned int rate)
+{
+ unsigned int flag;
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg);
+
+ switch (rate) {
+ case 44100:
+ flag = CLK_896_STATUS_FLAG_RATE_44100;
+ break;
+ case 48000:
+ flag = CLK_896_STATUS_FLAG_RATE_48000;
+ break;
+ case 88200:
+ flag = CLK_896_STATUS_FLAG_RATE_88200;
+ break;
+ case 96000:
+ flag = CLK_896_STATUS_FLAG_RATE_96000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ data &= ~CLK_896_STATUS_MASK_RATE;
+ data |= flag;
+
+ reg = cpu_to_be32(data);
+ return snd_motu_transaction_write(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+}
+
+int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu, unsigned int rate)
+{
+ if (motu->spec == &snd_motu_spec_828)
+ return set_clock_rate_828(motu, rate);
+ else if (motu->spec == &snd_motu_spec_896)
+ return set_clock_rate_896(motu, rate);
+ else
+ return -ENXIO;
+}
+
+static int get_clock_source_828(struct snd_motu *motu, enum snd_motu_clock_source *src)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
+
+ switch (data & CLK_828_STATUS_MASK_SRC) {
+ case CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT:
+ *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
+ break;
+ case CLK_828_STATUS_FLAG_SRC_SPH:
+ *src = SND_MOTU_CLOCK_SOURCE_SPH;
+ break;
+ case CLK_828_STATUS_FLAG_SRC_SPDIF:
+ {
+ if (data & CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF)
+ *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
+ else
+ *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
+ break;
+ }
+ case CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB:
+ *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
+ break;
+ case CLK_828_STATUS_FLAG_SRC_INTERNAL:
+ *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int get_clock_source_896(struct snd_motu *motu, enum snd_motu_clock_source *src)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg);
+
+ switch (data & CLK_896_STATUS_MASK_SRC) {
+ case CLK_896_STATUS_FLAG_SRC_INTERNAL:
+ *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
+ break;
+ case CLK_896_STATUS_FLAG_SRC_ADAT_ON_OPT:
+ *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
+ break;
+ case CLK_896_STATUS_FLAG_SRC_AESEBU:
+ *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
+ break;
+ case CLK_896_STATUS_FLAG_SRC_SPH:
+ *src = SND_MOTU_CLOCK_SOURCE_SPH;
+ break;
+ case CLK_896_STATUS_FLAG_SRC_WORD:
+ *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
+ break;
+ case CLK_896_STATUS_FLAG_SRC_ADAT_ON_DSUB:
+ *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu, enum snd_motu_clock_source *src)
+{
+ if (motu->spec == &snd_motu_spec_828)
+ return get_clock_source_828(motu, src);
+ else if (motu->spec == &snd_motu_spec_896)
+ return get_clock_source_896(motu, src);
+ else
+ return -ENXIO;
+}
+
+static int switch_fetching_mode_828(struct snd_motu *motu, bool enable)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
+
+ data &= ~(CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT);
+ if (enable) {
+ // This transaction should be initiated after the device receives batch of packets
+ // since the device voluntarily mutes outputs. As a workaround, yield processor over
+ // 100 msec.
+ msleep(100);
+ data |= CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT;
+ }
+
+ reg = cpu_to_be32(data);
+ return snd_motu_transaction_write(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+}
+
+static int switch_fetching_mode_896(struct snd_motu *motu, bool enable)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg);
+
+ data &= ~CLK_896_STATUS_FLAG_FETCH_ENABLE;
+ if (enable)
+ data |= CLK_896_STATUS_FLAG_FETCH_ENABLE | CLK_896_STATUS_FLAG_OUTPUT_ON;
+
+ reg = cpu_to_be32(data);
+ return snd_motu_transaction_write(motu, CLK_896_STATUS_OFFSET, &reg, sizeof(reg));
+}
+
+int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu, bool enable)
+{
+ if (motu->spec == &snd_motu_spec_828)
+ return switch_fetching_mode_828(motu, enable);
+ else if (motu->spec == &snd_motu_spec_896)
+ return switch_fetching_mode_896(motu, enable);
+ else
+ return -ENXIO;
+}
+
+static int detect_packet_formats_828(struct snd_motu *motu)
+{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ motu->tx_packet_formats.pcm_byte_offset = 4;
+ motu->tx_packet_formats.msg_chunks = 2;
+
+ motu->rx_packet_formats.pcm_byte_offset = 4;
+ motu->rx_packet_formats.msg_chunks = 0;
+
+ err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, &reg, sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
+
+ // The number of chunks is just reduced when SPDIF is activated.
+ if (!(data & CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF))
+ motu->tx_packet_formats.pcm_chunks[0] += 8;
+
+ if (!(data & CLK_828_STATUS_FLAG_OPT_OUT_IFACE_IS_SPDIF))
+ motu->rx_packet_formats.pcm_chunks[0] += 8;
+
+ return 0;
+}
+
+static int detect_packet_formats_896(struct snd_motu *motu)
+{
+ // 24bit PCM frames follow to source packet header without message chunk.
+ motu->tx_packet_formats.pcm_byte_offset = 4;
+ motu->rx_packet_formats.pcm_byte_offset = 4;
+
+ // No message chunk in data block.
+ motu->tx_packet_formats.msg_chunks = 0;
+ motu->rx_packet_formats.msg_chunks = 0;
+
+ // Always enable optical interface for ADAT signal since the device have no registers
+ // to refer to current configuration.
+ motu->tx_packet_formats.pcm_chunks[0] += 8;
+ motu->tx_packet_formats.pcm_chunks[1] += 8;
+
+ motu->rx_packet_formats.pcm_chunks[0] += 8;
+ motu->rx_packet_formats.pcm_chunks[1] += 8;
+
+ return 0;
+}
+
+int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu)
+{
+ memcpy(motu->tx_packet_formats.pcm_chunks, motu->spec->tx_fixed_pcm_chunks,
+ sizeof(motu->tx_packet_formats.pcm_chunks));
+ memcpy(motu->rx_packet_formats.pcm_chunks, motu->spec->rx_fixed_pcm_chunks,
+ sizeof(motu->rx_packet_formats.pcm_chunks));
+
+ if (motu->spec == &snd_motu_spec_828)
+ return detect_packet_formats_828(motu);
+ else if (motu->spec == &snd_motu_spec_896)
+ return detect_packet_formats_896(motu);
+ else
+ return 0;
+}
+
+const struct snd_motu_spec snd_motu_spec_828 = {
+ .name = "828",
+ .protocol_version = SND_MOTU_PROTOCOL_V1,
+ .tx_fixed_pcm_chunks = {10, 0, 0},
+ .rx_fixed_pcm_chunks = {10, 0, 0},
+};
+
+const struct snd_motu_spec snd_motu_spec_896 = {
+ .name = "896",
+ .tx_fixed_pcm_chunks = {10, 10, 0},
+ .rx_fixed_pcm_chunks = {10, 10, 0},
+};
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c
index e59e69ab1538..93d5df1ae550 100644
--- a/sound/firewire/motu/motu-protocol-v2.c
+++ b/sound/firewire/motu/motu-protocol-v2.c
@@ -12,6 +12,13 @@
#define V2_CLOCK_RATE_SHIFT 3
#define V2_CLOCK_SRC_MASK 0x00000007
#define V2_CLOCK_SRC_SHIFT 0
+#define V2_CLOCK_SRC_AESEBU_ON_XLR 0x07
+#define V2_CLOCK_SRC_ADAT_ON_DSUB 0x05
+#define V2_CLOCK_SRC_WORD_ON_BNC 0x04
+#define V2_CLOCK_SRC_SPH 0x03
+#define V2_CLOCK_SRC_SPDIF 0x02 // on either coaxial or optical
+#define V2_CLOCK_SRC_ADAT_ON_OPT 0x01
+#define V2_CLOCK_SRC_INTERNAL 0x00
#define V2_CLOCK_FETCH_ENABLE 0x02000000
#define V2_CLOCK_MODEL_SPECIFIC 0x04000000
@@ -78,64 +85,51 @@ int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
sizeof(reg));
}
-static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data,
- enum snd_motu_clock_source *src)
+static int get_clock_source(struct snd_motu *motu, u32 data,
+ enum snd_motu_clock_source *src)
{
- switch (data) {
- case 0:
+ switch (data & V2_CLOCK_SRC_MASK) {
+ case V2_CLOCK_SRC_INTERNAL:
*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
break;
- case 1:
+ case V2_CLOCK_SRC_ADAT_ON_OPT:
+ *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
+ break;
+ case V2_CLOCK_SRC_SPDIF:
{
- __be32 reg;
-
- // To check the configuration of optical interface.
- int err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET,
- &reg, sizeof(reg));
- if (err < 0)
- return err;
-
- if (be32_to_cpu(reg) & 0x00000200)
- *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
- else
- *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
+ bool support_iec60958_on_opt = (motu->spec == &snd_motu_spec_828mk2 ||
+ motu->spec == &snd_motu_spec_traveler);
+
+ if (!support_iec60958_on_opt) {
+ *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
+ } else {
+ __be32 reg;
+
+ // To check the configuration of optical interface.
+ int err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg,
+ sizeof(reg));
+ if (err < 0)
+ return err;
+
+ if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
+ V2_OPT_IFACE_MODE_SPDIF)
+ *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
+ else
+ *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
+ }
break;
}
- case 2:
- *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
- break;
- case 3:
+ case V2_CLOCK_SRC_SPH:
*src = SND_MOTU_CLOCK_SOURCE_SPH;
break;
- case 4:
+ case V2_CLOCK_SRC_WORD_ON_BNC:
*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
break;
- case 5:
+ case V2_CLOCK_SRC_ADAT_ON_DSUB:
*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
break;
- default:
- *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
- break;
- }
-
- return 0;
-}
-
-static int v2_detect_clock_source(struct snd_motu *motu, u32 data,
- enum snd_motu_clock_source *src)
-{
- switch (data) {
- case 0:
- *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
- break;
- case 2:
- *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
- break;
- case 3:
- *src = SND_MOTU_CLOCK_SOURCE_SPH;
- break;
- case 4:
- *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
+ case V2_CLOCK_SRC_AESEBU_ON_XLR:
+ *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
break;
default:
*src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
@@ -145,17 +139,6 @@ static int v2_detect_clock_source(struct snd_motu *motu, u32 data,
return 0;
}
-static int get_clock_source(struct snd_motu *motu, u32 data,
- enum snd_motu_clock_source *src)
-{
- data &= V2_CLOCK_SRC_MASK;
- if (motu->spec == &snd_motu_spec_828mk2 ||
- motu->spec == &snd_motu_spec_traveler)
- return detect_clock_source_optical_model(motu, data, src);
- else
- return v2_detect_clock_source(motu, data, src);
-}
-
int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
enum snd_motu_clock_source *src)
{
@@ -235,59 +218,9 @@ int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
}
}
-static int detect_packet_formats_828mk2(struct snd_motu *motu, u32 data)
-{
- if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->tx_packet_formats.pcm_chunks[0] += 8;
- motu->tx_packet_formats.pcm_chunks[1] += 4;
- }
-
- if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->rx_packet_formats.pcm_chunks[0] += 8;
- motu->rx_packet_formats.pcm_chunks[1] += 4;
- }
-
- return 0;
-}
-
-static int detect_packet_formats_traveler(struct snd_motu *motu, u32 data)
-{
- if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->tx_packet_formats.pcm_chunks[0] += 8;
- motu->tx_packet_formats.pcm_chunks[1] += 4;
- }
-
- if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->rx_packet_formats.pcm_chunks[0] += 8;
- motu->rx_packet_formats.pcm_chunks[1] += 4;
- }
-
- return 0;
-}
-
-static int detect_packet_formats_8pre(struct snd_motu *motu, u32 data)
-{
- if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->tx_packet_formats.pcm_chunks[0] += 8;
- motu->tx_packet_formats.pcm_chunks[1] += 8;
- }
-
- if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
- V2_OPT_IFACE_MODE_ADAT) {
- motu->rx_packet_formats.pcm_chunks[0] += 8;
- motu->rx_packet_formats.pcm_chunks[1] += 8;
- }
-
- return 0;
-}
-
int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu)
{
+ bool has_two_opt_ifaces = (motu->spec == &snd_motu_spec_8pre);
__be32 reg;
u32 data;
int err;
@@ -311,14 +244,25 @@ int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu)
motu->spec->rx_fixed_pcm_chunks,
sizeof(motu->rx_packet_formats.pcm_chunks));
- if (motu->spec == &snd_motu_spec_828mk2)
- return detect_packet_formats_828mk2(motu, data);
- else if (motu->spec == &snd_motu_spec_traveler)
- return detect_packet_formats_traveler(motu, data);
- else if (motu->spec == &snd_motu_spec_8pre)
- return detect_packet_formats_8pre(motu, data);
- else
- return 0;
+ if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == V2_OPT_IFACE_MODE_ADAT) {
+ motu->tx_packet_formats.pcm_chunks[0] += 8;
+
+ if (!has_two_opt_ifaces)
+ motu->tx_packet_formats.pcm_chunks[1] += 4;
+ else
+ motu->tx_packet_formats.pcm_chunks[1] += 8;
+ }
+
+ if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) == V2_OPT_IFACE_MODE_ADAT) {
+ motu->rx_packet_formats.pcm_chunks[0] += 8;
+
+ if (!has_two_opt_ifaces)
+ motu->rx_packet_formats.pcm_chunks[1] += 4;
+ else
+ motu->rx_packet_formats.pcm_chunks[1] += 8;
+ }
+
+ return 0;
}
const struct snd_motu_spec snd_motu_spec_828mk2 = {
@@ -353,6 +297,7 @@ const struct snd_motu_spec snd_motu_spec_8pre = {
.protocol_version = SND_MOTU_PROTOCOL_V2,
.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
SND_MOTU_SPEC_TX_MIDI_2ND_Q,
- .tx_fixed_pcm_chunks = {10, 6, 0},
- .rx_fixed_pcm_chunks = {10, 6, 0},
+ // Two dummy chunks always in the end of data block.
+ .tx_fixed_pcm_chunks = {10, 10, 0},
+ .rx_fixed_pcm_chunks = {6, 6, 0},
};
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c
index 4e6b0e449ee4..56e4504e7ec9 100644
--- a/sound/firewire/motu/motu-protocol-v3.c
+++ b/sound/firewire/motu/motu-protocol-v3.c
@@ -13,6 +13,12 @@
#define V3_CLOCK_RATE_MASK 0x0000ff00
#define V3_CLOCK_RATE_SHIFT 8
#define V3_CLOCK_SOURCE_MASK 0x000000ff
+#define V3_CLOCK_SRC_INTERNAL 0x00
+#define V3_CLOCK_SRC_WORD_ON_BNC 0x01
+#define V3_CLOCK_SRC_SPH 0x02
+#define V3_CLOCK_SRC_SPDIF_ON_COAX 0x10
+#define V3_CLOCK_SRC_OPT_IFACE_A 0x18
+#define V3_CLOCK_SRC_OPT_IFACE_B 0x19
#define V3_OPT_IFACE_MODE_OFFSET 0x0c94
#define V3_ENABLE_OPT_IN_IFACE_A 0x00000001
@@ -97,28 +103,37 @@ int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
return 0;
}
-static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data,
- enum snd_motu_clock_source *src)
+int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
+ enum snd_motu_clock_source *src)
{
+ __be32 reg;
+ u32 data;
+ int err;
+
+ err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
+ sizeof(reg));
+ if (err < 0)
+ return err;
+ data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK;
+
switch (data) {
- case 0x00:
+ case V3_CLOCK_SRC_INTERNAL:
*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
break;
- case 0x01:
+ case V3_CLOCK_SRC_WORD_ON_BNC:
*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
break;
- case 0x02:
+ case V3_CLOCK_SRC_SPH:
*src = SND_MOTU_CLOCK_SOURCE_SPH;
break;
- case 0x10:
+ case V3_CLOCK_SRC_SPDIF_ON_COAX:
*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
break;
- case 0x18:
- case 0x19:
+ case V3_CLOCK_SRC_OPT_IFACE_A:
+ case V3_CLOCK_SRC_OPT_IFACE_B:
{
__be32 reg;
u32 options;
- int err;
err = snd_motu_transaction_read(motu,
V3_OPT_IFACE_MODE_OFFSET, &reg, sizeof(reg));
@@ -126,7 +141,7 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data,
return err;
options = be32_to_cpu(reg);
- if (data == 0x18) {
+ if (data == V3_CLOCK_SRC_OPT_IFACE_A) {
if (options & V3_NO_ADAT_OPT_IN_IFACE_A)
*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A;
else
@@ -137,7 +152,6 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data,
else
*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B;
}
-
break;
}
default:
@@ -148,49 +162,6 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data,
return 0;
}
-static int v3_detect_clock_source(struct snd_motu *motu, u32 data,
- enum snd_motu_clock_source *src)
-{
- switch (data) {
- case 0x00:
- *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
- break;
- case 0x01:
- *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
- break;
- case 0x02:
- *src = SND_MOTU_CLOCK_SOURCE_SPH;
- break;
- case 0x10:
- *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
- break;
- default:
- *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
- break;
- }
-
- return 0;
-}
-
-int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
- enum snd_motu_clock_source *src)
-{
- __be32 reg;
- u32 data;
- int err;
-
- err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
- sizeof(reg));
- if (err < 0)
- return err;
- data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK;
-
- if (motu->spec == &snd_motu_spec_828mk3)
- return detect_clock_source_828mk3(motu, data, src);
- else
- return v3_detect_clock_source(motu, data, src);
-}
-
int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
bool enable)
{
@@ -284,14 +255,14 @@ int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu)
motu->spec->rx_fixed_pcm_chunks,
sizeof(motu->rx_packet_formats.pcm_chunks));
- if (motu->spec == &snd_motu_spec_828mk3)
+ if (motu->spec == &snd_motu_spec_828mk3_fw || motu->spec == &snd_motu_spec_828mk3_hybrid)
return detect_packet_formats_828mk3(motu, data);
else
return 0;
}
-const struct snd_motu_spec snd_motu_spec_828mk3 = {
+const struct snd_motu_spec snd_motu_spec_828mk3_fw = {
.name = "828mk3",
.protocol_version = SND_MOTU_PROTOCOL_V3,
.flags = SND_MOTU_SPEC_RX_MIDI_3RD_Q |
@@ -300,6 +271,15 @@ const struct snd_motu_spec snd_motu_spec_828mk3 = {
.rx_fixed_pcm_chunks = {14, 14, 10},
};
+const struct snd_motu_spec snd_motu_spec_828mk3_hybrid = {
+ .name = "828mk3",
+ .protocol_version = SND_MOTU_PROTOCOL_V3,
+ .flags = SND_MOTU_SPEC_RX_MIDI_3RD_Q |
+ SND_MOTU_SPEC_TX_MIDI_3RD_Q,
+ .tx_fixed_pcm_chunks = {18, 18, 14},
+ .rx_fixed_pcm_chunks = {14, 14, 14}, // Additional 4 dummy chunks at higher rate.
+};
+
const struct snd_motu_spec snd_motu_spec_ultralite_mk3 = {
.name = "UltraLiteMk3",
.protocol_version = SND_MOTU_PROTOCOL_V3,
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
index 2028c5419f6f..9e6ca39ebd7f 100644
--- a/sound/firewire/motu/motu-stream.c
+++ b/sound/firewire/motu/motu-stream.c
@@ -7,7 +7,7 @@
#include "motu.h"
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
#define ISOC_COMM_CONTROL_OFFSET 0x0b00
#define ISOC_COMM_CONTROL_MASK 0xffff0000
@@ -153,6 +153,9 @@ int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
fw_iso_resources_free(&motu->tx_resources);
fw_iso_resources_free(&motu->rx_resources);
+ kfree(motu->cache.event_offsets);
+ motu->cache.event_offsets = NULL;
+
err = snd_motu_protocol_set_clock_rate(motu, rate);
if (err < 0) {
dev_err(&motu->unit->device,
@@ -181,6 +184,15 @@ int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
fw_iso_resources_free(&motu->rx_resources);
return err;
}
+
+ motu->cache.size = motu->tx_stream.syt_interval * frames_per_buffer;
+ motu->cache.event_offsets = kcalloc(motu->cache.size, sizeof(*motu->cache.event_offsets),
+ GFP_KERNEL);
+ if (!motu->cache.event_offsets) {
+ fw_iso_resources_free(&motu->tx_resources);
+ fw_iso_resources_free(&motu->rx_resources);
+ return -ENOMEM;
+ }
}
return 0;
@@ -260,14 +272,19 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu)
if (err < 0)
goto stop_streams;
- err = amdtp_domain_start(&motu->domain, 0);
+ motu->cache.tail = 0;
+ motu->cache.tx_cycle_count = UINT_MAX;
+ motu->cache.head = 0;
+ motu->cache.rx_cycle_count = UINT_MAX;
+
+ // NOTE: The device requires both of replay; the sequence of the number of data
+ // blocks per packet, and the sequence of source packet header per data block as
+ // presentation time.
+ err = amdtp_domain_start(&motu->domain, 0, true, false);
if (err < 0)
goto stop_streams;
- if (!amdtp_stream_wait_callback(&motu->tx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&motu->rx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&motu->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto stop_streams;
}
@@ -296,6 +313,9 @@ void snd_motu_stream_stop_duplex(struct snd_motu *motu)
fw_iso_resources_free(&motu->tx_resources);
fw_iso_resources_free(&motu->rx_resources);
+
+ kfree(motu->cache.event_offsets);
+ motu->cache.event_offsets = NULL;
}
}
@@ -317,7 +337,7 @@ static int init_stream(struct snd_motu *motu, struct amdtp_stream *s)
if (err < 0)
return err;
- err = amdtp_motu_init(s, motu->unit, dir, motu->spec);
+ err = amdtp_motu_init(s, motu->unit, dir, motu->spec, &motu->cache);
if (err < 0)
fw_iso_resources_destroy(resources);
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c
index a4929c1302dc..543136578c70 100644
--- a/sound/firewire/motu/motu.c
+++ b/sound/firewire/motu/motu.c
@@ -57,22 +57,31 @@ static void motu_card_free(struct snd_card *card)
snd_motu_transaction_unregister(motu);
snd_motu_stream_destroy_duplex(motu);
+
+ mutex_destroy(&motu->mutex);
+ fw_unit_put(motu->unit);
}
-static void do_registration(struct work_struct *work)
+static int motu_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_motu *motu = container_of(work, struct snd_motu, dwork.work);
+ struct snd_card *card;
+ struct snd_motu *motu;
int err;
- if (motu->registered)
- return;
-
- err = snd_card_new(&motu->unit->device, -1, NULL, THIS_MODULE, 0,
- &motu->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*motu), &card);
if (err < 0)
- return;
- motu->card->private_free = motu_card_free;
- motu->card->private_data = motu;
+ return err;
+ card->private_free = motu_card_free;
+
+ motu = card->private_data;
+ motu->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, motu);
+ motu->card = card;
+
+ motu->spec = (const struct snd_motu_spec *)entry->driver_data;
+ mutex_init(&motu->mutex);
+ spin_lock_init(&motu->lock);
+ init_waitqueue_head(&motu->hwdep_wait);
name_card(motu);
@@ -103,71 +112,28 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(motu->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- motu->registered = true;
-
- return;
-error:
- snd_card_free(motu->card);
- dev_info(&motu->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int motu_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_motu *motu;
-
- /* Allocate this independently of sound card instance. */
- motu = devm_kzalloc(&unit->device, sizeof(struct snd_motu), GFP_KERNEL);
- if (!motu)
- return -ENOMEM;
- motu->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, motu);
-
- motu->spec = (const struct snd_motu_spec *)entry->driver_data;
- mutex_init(&motu->mutex);
- spin_lock_init(&motu->lock);
- init_waitqueue_head(&motu->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&motu->dwork, do_registration);
- snd_fw_schedule_registration(unit, &motu->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void motu_remove(struct fw_unit *unit)
{
struct snd_motu *motu = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&motu->dwork);
-
- if (motu->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(motu->card);
- }
-
- mutex_destroy(&motu->mutex);
- fw_unit_put(motu->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(motu->card);
}
static void motu_bus_update(struct fw_unit *unit)
{
struct snd_motu *motu = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!motu->registered)
- snd_fw_schedule_registration(unit, &motu->dwork);
-
/* The handler address register becomes initialized. */
snd_motu_transaction_reregister(motu);
}
@@ -184,13 +150,16 @@ static void motu_bus_update(struct fw_unit *unit)
}
static const struct ieee1394_device_id motu_id_table[] = {
+ SND_MOTU_DEV_ENTRY(0x000001, &snd_motu_spec_828),
+ SND_MOTU_DEV_ENTRY(0x000002, &snd_motu_spec_896),
SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2),
SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler),
SND_MOTU_DEV_ENTRY(0x00000d, &snd_motu_spec_ultralite),
SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre),
- SND_MOTU_DEV_ENTRY(0x000015, &snd_motu_spec_828mk3), // FireWire only.
+ SND_MOTU_DEV_ENTRY(0x000015, &snd_motu_spec_828mk3_fw), // FireWire only.
SND_MOTU_DEV_ENTRY(0x000019, &snd_motu_spec_ultralite_mk3), // FireWire only.
- SND_MOTU_DEV_ENTRY(0x000035, &snd_motu_spec_828mk3), // Hybrid.
+ SND_MOTU_DEV_ENTRY(0x000030, &snd_motu_spec_ultralite_mk3), // Hybrid.
+ SND_MOTU_DEV_ENTRY(0x000035, &snd_motu_spec_828mk3_hybrid), // Hybrid.
SND_MOTU_DEV_ENTRY(0x000033, &snd_motu_spec_audio_express),
SND_MOTU_DEV_ENTRY(0x000045, &snd_motu_spec_4pre),
{ }
diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h
index 3d0236ee6716..73f36d1be515 100644
--- a/sound/firewire/motu/motu.h
+++ b/sound/firewire/motu/motu.h
@@ -39,15 +39,21 @@ struct snd_motu_packet_format {
unsigned char pcm_chunks[3];
};
+struct amdtp_motu_cache {
+ unsigned int *event_offsets;
+ unsigned int size;
+ unsigned int tail;
+ unsigned int tx_cycle_count;
+ unsigned int head;
+ unsigned int rx_cycle_count;
+};
+
struct snd_motu {
struct snd_card *card;
struct fw_unit *unit;
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
/* Model dependent information. */
const struct snd_motu_spec *spec;
@@ -70,6 +76,8 @@ struct snd_motu {
wait_queue_head_t hwdep_wait;
struct amdtp_domain domain;
+
+ struct amdtp_motu_cache cache;
};
enum snd_motu_spec_flags {
@@ -99,6 +107,7 @@ enum snd_motu_clock_source {
};
enum snd_motu_protocol_version {
+ SND_MOTU_PROTOCOL_V1,
SND_MOTU_PROTOCOL_V2,
SND_MOTU_PROTOCOL_V3,
};
@@ -106,25 +115,31 @@ enum snd_motu_protocol_version {
struct snd_motu_spec {
const char *const name;
enum snd_motu_protocol_version protocol_version;
- enum snd_motu_spec_flags flags;
+ // The combination of snd_motu_spec_flags enumeration-constants.
+ unsigned int flags;
unsigned char tx_fixed_pcm_chunks[3];
unsigned char rx_fixed_pcm_chunks[3];
};
+extern const struct snd_motu_spec snd_motu_spec_828;
+extern const struct snd_motu_spec snd_motu_spec_896;
+
extern const struct snd_motu_spec snd_motu_spec_828mk2;
extern const struct snd_motu_spec snd_motu_spec_traveler;
extern const struct snd_motu_spec snd_motu_spec_ultralite;
extern const struct snd_motu_spec snd_motu_spec_8pre;
-extern const struct snd_motu_spec snd_motu_spec_828mk3;
+extern const struct snd_motu_spec snd_motu_spec_828mk3_fw;
+extern const struct snd_motu_spec snd_motu_spec_828mk3_hybrid;
extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3;
extern const struct snd_motu_spec snd_motu_spec_audio_express;
extern const struct snd_motu_spec snd_motu_spec_4pre;
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir,
- const struct snd_motu_spec *spec);
+ const struct snd_motu_spec *spec,
+ struct amdtp_motu_cache *cache);
int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
unsigned int midi_ports,
struct snd_motu_packet_format *formats);
@@ -160,6 +175,16 @@ int snd_motu_create_midi_devices(struct snd_motu *motu);
int snd_motu_create_hwdep_device(struct snd_motu *motu);
+int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu,
+ unsigned int *rate);
+int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu,
+ unsigned int rate);
+int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu,
+ enum snd_motu_clock_source *src);
+int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu,
+ bool enable);
+int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu);
+
int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
unsigned int *rate);
int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
@@ -187,6 +212,8 @@ static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu,
return snd_motu_protocol_v2_get_clock_rate(motu, rate);
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
return snd_motu_protocol_v3_get_clock_rate(motu, rate);
+ else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
+ return snd_motu_protocol_v1_get_clock_rate(motu, rate);
else
return -ENXIO;
}
@@ -198,6 +225,8 @@ static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu,
return snd_motu_protocol_v2_set_clock_rate(motu, rate);
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
return snd_motu_protocol_v3_set_clock_rate(motu, rate);
+ else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
+ return snd_motu_protocol_v1_set_clock_rate(motu, rate);
else
return -ENXIO;
}
@@ -209,6 +238,8 @@ static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu,
return snd_motu_protocol_v2_get_clock_source(motu, source);
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
return snd_motu_protocol_v3_get_clock_source(motu, source);
+ else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
+ return snd_motu_protocol_v1_get_clock_source(motu, source);
else
return -ENXIO;
}
@@ -220,6 +251,8 @@ static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu,
return snd_motu_protocol_v2_switch_fetching_mode(motu, enable);
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
return snd_motu_protocol_v3_switch_fetching_mode(motu, enable);
+ else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
+ return snd_motu_protocol_v1_switch_fetching_mode(motu, enable);
else
return -ENXIO;
}
@@ -230,6 +263,8 @@ static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu)
return snd_motu_protocol_v2_cache_packet_formats(motu);
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
return snd_motu_protocol_v3_cache_packet_formats(motu);
+ else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
+ return snd_motu_protocol_v1_cache_packet_formats(motu);
else
return -ENXIO;
}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 80c9dc13f1b5..0ef242fdd3bc 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -9,7 +9,7 @@
#include <linux/delay.h>
#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
/*
* According to datasheet of Oxford Semiconductor:
@@ -153,12 +153,23 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
struct cmp_connection *conn;
enum cmp_direction c_dir;
enum amdtp_stream_direction s_dir;
+ unsigned int flags = CIP_UNAWARE_SYT;
int err;
+ if (!(oxfw->quirks & SND_OXFW_QUIRK_BLOCKING_TRANSMISSION))
+ flags |= CIP_NONBLOCKING;
+ else
+ flags |= CIP_BLOCKING;
+
if (stream == &oxfw->tx_stream) {
conn = &oxfw->out_conn;
c_dir = CMP_OUTPUT;
s_dir = AMDTP_IN_STREAM;
+
+ if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD)
+ flags |= CIP_JUMBO_PAYLOAD;
+ if (oxfw->quirks & SND_OXFW_QUIRK_WRONG_DBS)
+ flags |= CIP_WRONG_DBS;
} else {
conn = &oxfw->in_conn;
c_dir = CMP_INPUT;
@@ -169,24 +180,12 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
if (err < 0)
return err;
- err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
+ err = amdtp_am824_init(stream, oxfw->unit, s_dir, flags);
if (err < 0) {
cmp_connection_destroy(conn);
return err;
}
- /*
- * OXFW starts to transmit packets with non-zero dbc.
- * OXFW postpone transferring packets till handling any asynchronous
- * packets. As a result, next isochronous packet includes more data
- * blocks than IEC 61883-6 defines.
- */
- if (stream == &oxfw->tx_stream) {
- oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
- if (oxfw->wrong_dbs)
- oxfw->tx_stream.flags |= CIP_WRONG_DBS;
- }
-
return 0;
}
@@ -338,6 +337,9 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
}
if (!amdtp_stream_running(&oxfw->rx_stream)) {
+ unsigned int tx_init_skip_cycles = 0;
+ bool replay_seq = false;
+
err = start_stream(oxfw, &oxfw->rx_stream);
if (err < 0) {
dev_err(&oxfw->unit->device,
@@ -353,26 +355,27 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
"fail to prepare tx stream: %d\n", err);
goto error;
}
+
+ if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD) {
+ // Just after changing sampling transfer frequency, many cycles are
+ // skipped for packet transmission.
+ tx_init_skip_cycles = 400;
+ } else {
+ replay_seq = true;
+ }
}
- err = amdtp_domain_start(&oxfw->domain, 0);
+ // NOTE: The device ignores presentation time expressed by the value of syt field
+ // of CIP header in received packets. The sequence of the number of data blocks per
+ // packet is important for media clock recovery.
+ err = amdtp_domain_start(&oxfw->domain, tx_init_skip_cycles, replay_seq, false);
if (err < 0)
goto error;
- // Wait first packet.
- if (!amdtp_stream_wait_callback(&oxfw->rx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&oxfw->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
-
- if (oxfw->has_output) {
- if (!amdtp_stream_wait_callback(&oxfw->tx_stream,
- CALLBACK_TIMEOUT)) {
- err = -ETIMEDOUT;
- goto error;
- }
- }
}
return 0;
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 9eea25c46dc7..84971d78d152 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -23,6 +23,8 @@
#define OUI_APOGEE 0x0003db
#define MODEL_SATELLITE 0x00200f
+#define MODEL_SCS1M 0x001000
+#define MODEL_DUET_FW 0x01dddd
#define SPECIFIER_1394TA 0x00a02d
#define VERSION_AVC 0x010001
@@ -46,8 +48,6 @@ static bool detect_loud_models(struct fw_unit *unit)
"Onyx-i",
"Onyx 1640i",
"d.Pro",
- "Mackie Onyx Satellite",
- "Tapco LINK.firewire 4x6",
"U.420"};
char model[32];
int err;
@@ -60,7 +60,7 @@ static bool detect_loud_models(struct fw_unit *unit)
return match_string(models, ARRAY_SIZE(models), model) >= 0;
}
-static int name_card(struct snd_oxfw *oxfw)
+static int name_card(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
{
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
const struct compat_info *info;
@@ -88,10 +88,12 @@ static int name_card(struct snd_oxfw *oxfw)
goto end;
be32_to_cpus(&firmware);
+ if (firmware >> 20 == 0x970)
+ oxfw->quirks |= SND_OXFW_QUIRK_JUMBO_PAYLOAD;
+
/* to apply card definitions */
- if (oxfw->entry->vendor_id == VENDOR_GRIFFIN ||
- oxfw->entry->vendor_id == VENDOR_LACIE) {
- info = (const struct compat_info *)oxfw->entry->driver_data;
+ if (entry->vendor_id == VENDOR_GRIFFIN || entry->vendor_id == VENDOR_LACIE) {
+ info = (const struct compat_info *)entry->driver_data;
d = info->driver_name;
v = info->vendor_name;
m = info->model_name;
@@ -120,9 +122,12 @@ static void oxfw_card_free(struct snd_card *card)
if (oxfw->has_output || oxfw->has_input)
snd_oxfw_stream_destroy_duplex(oxfw);
+
+ mutex_destroy(&oxfw->mutex);
+ fw_unit_put(oxfw->unit);
}
-static int detect_quirks(struct snd_oxfw *oxfw)
+static int detect_quirks(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
{
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
struct fw_csr_iterator it;
@@ -133,28 +138,35 @@ static int detect_quirks(struct snd_oxfw *oxfw)
* Add ALSA control elements for two models to keep compatibility to
* old firewire-speaker module.
*/
- if (oxfw->entry->vendor_id == VENDOR_GRIFFIN)
+ if (entry->vendor_id == VENDOR_GRIFFIN)
return snd_oxfw_add_spkr(oxfw, false);
- if (oxfw->entry->vendor_id == VENDOR_LACIE)
+ if (entry->vendor_id == VENDOR_LACIE)
return snd_oxfw_add_spkr(oxfw, true);
/*
* Stanton models supports asynchronous transactions for unique MIDI
* messages.
*/
- if (oxfw->entry->vendor_id == OUI_STANTON) {
- /* No physical MIDI ports. */
+ if (entry->vendor_id == OUI_STANTON) {
+ oxfw->quirks |= SND_OXFW_QUIRK_SCS_TRANSACTION;
+ if (entry->model_id == MODEL_SCS1M)
+ oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION;
+
+ // No physical MIDI ports.
oxfw->midi_input_ports = 0;
oxfw->midi_output_ports = 0;
return snd_oxfw_scs1x_add(oxfw);
}
+ if (entry->vendor_id == OUI_APOGEE && entry->model_id == MODEL_DUET_FW)
+ oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION;
+
/*
* TASCAM FireOne has physical control and requires a pair of additional
* MIDI ports.
*/
- if (oxfw->entry->vendor_id == VENDOR_TASCAM) {
+ if (entry->vendor_id == VENDOR_TASCAM) {
oxfw->midi_input_ports++;
oxfw->midi_output_ports++;
return 0;
@@ -175,27 +187,35 @@ static int detect_quirks(struct snd_oxfw *oxfw)
* value in 'dbs' field of CIP header against its format information.
*/
if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
- oxfw->wrong_dbs = true;
+ oxfw->quirks |= SND_OXFW_QUIRK_WRONG_DBS;
return 0;
}
-static void do_registration(struct work_struct *work)
+static int oxfw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{
- struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work);
+ struct snd_card *card;
+ struct snd_oxfw *oxfw;
int err;
- if (oxfw->registered)
- return;
+ if (entry->vendor_id == VENDOR_LOUD && entry->model_id == 0 && !detect_loud_models(unit))
+ return -ENODEV;
- err = snd_card_new(&oxfw->unit->device, -1, NULL, THIS_MODULE, 0,
- &oxfw->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*oxfw), &card);
if (err < 0)
- return;
- oxfw->card->private_free = oxfw_card_free;
- oxfw->card->private_data = oxfw;
+ return err;
+ card->private_free = oxfw_card_free;
+
+ oxfw = card->private_data;
+ oxfw->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, oxfw);
+ oxfw->card = card;
- err = name_card(oxfw);
+ mutex_init(&oxfw->mutex);
+ spin_lock_init(&oxfw->lock);
+ init_waitqueue_head(&oxfw->hwdep_wait);
+
+ err = name_card(oxfw, entry);
if (err < 0)
goto error;
@@ -203,7 +223,7 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = detect_quirks(oxfw);
+ err = detect_quirks(oxfw, entry);
if (err < 0)
goto error;
@@ -227,85 +247,38 @@ static void do_registration(struct work_struct *work)
goto error;
}
- err = snd_card_register(oxfw->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- oxfw->registered = true;
-
- return;
-error:
- snd_card_free(oxfw->card);
- dev_info(&oxfw->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int oxfw_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_oxfw *oxfw;
-
- if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit))
- return -ENODEV;
-
- /* Allocate this independent of sound card instance. */
- oxfw = devm_kzalloc(&unit->device, sizeof(struct snd_oxfw), GFP_KERNEL);
- if (!oxfw)
- return -ENOMEM;
- oxfw->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, oxfw);
-
- oxfw->entry = entry;
- mutex_init(&oxfw->mutex);
- spin_lock_init(&oxfw->lock);
- init_waitqueue_head(&oxfw->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&oxfw->dwork, do_registration);
- snd_fw_schedule_registration(unit, &oxfw->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void oxfw_bus_reset(struct fw_unit *unit)
{
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
- if (!oxfw->registered)
- snd_fw_schedule_registration(unit, &oxfw->dwork);
-
fcp_bus_reset(oxfw->unit);
- if (oxfw->registered) {
- if (oxfw->has_output || oxfw->has_input) {
- mutex_lock(&oxfw->mutex);
- snd_oxfw_stream_update_duplex(oxfw);
- mutex_unlock(&oxfw->mutex);
- }
-
- if (oxfw->entry->vendor_id == OUI_STANTON)
- snd_oxfw_scs1x_update(oxfw);
+ if (oxfw->has_output || oxfw->has_input) {
+ mutex_lock(&oxfw->mutex);
+ snd_oxfw_stream_update_duplex(oxfw);
+ mutex_unlock(&oxfw->mutex);
}
+
+ if (oxfw->quirks & SND_OXFW_QUIRK_SCS_TRANSACTION)
+ snd_oxfw_scs1x_update(oxfw);
}
static void oxfw_remove(struct fw_unit *unit)
{
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&oxfw->dwork);
-
- if (oxfw->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(oxfw->card);
- }
-
- mutex_destroy(&oxfw->mutex);
- fw_unit_put(oxfw->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(oxfw->card);
}
static const struct compat_info griffin_firewave = {
@@ -320,81 +293,67 @@ static const struct compat_info lacie_speakers = {
.model_name = "FireWire Speakers",
};
+#define OXFW_DEV_ENTRY(vendor, model, data) \
+{ \
+ .match_flags = IEEE1394_MATCH_VENDOR_ID | \
+ IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID | \
+ IEEE1394_MATCH_VERSION, \
+ .vendor_id = vendor, \
+ .model_id = model, \
+ .specifier_id = SPECIFIER_1394TA, \
+ .version = VERSION_AVC, \
+ .driver_data = (kernel_ulong_t)data, \
+}
+
static const struct ieee1394_device_id oxfw_id_table[] = {
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID |
- IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .vendor_id = VENDOR_GRIFFIN,
- .model_id = 0x00f970,
- .specifier_id = SPECIFIER_1394TA,
- .version = VERSION_AVC,
- .driver_data = (kernel_ulong_t)&griffin_firewave,
- },
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID |
- IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .vendor_id = VENDOR_LACIE,
- .model_id = 0x00f970,
- .specifier_id = SPECIFIER_1394TA,
- .version = VERSION_AVC,
- .driver_data = (kernel_ulong_t)&lacie_speakers,
- },
- /* Behringer,F-Control Audio 202 */
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID,
- .vendor_id = VENDOR_BEHRINGER,
- .model_id = 0x00fc22,
- },
- /*
- * Any Mackie(Loud) models (name string/model id):
- * Onyx-i series (former models): 0x081216
- * Mackie Onyx Satellite: 0x00200f
- * Tapco LINK.firewire 4x6: 0x000460
- * d.4 pro: Unknown
- * U.420: Unknown
- * U.420d: Unknown
- */
+ //
+ // OXFW970 devices:
+ // Initial firmware has a quirk to postpone isoc packet transmission during finishing async
+ // transaction. As a result, several isochronous cycles are skipped to transfer the packets
+ // and the audio data frames which should have been transferred during the cycles are put
+ // into packet at the first isoc cycle after the postpone. Furthermore, the value of SYT
+ // field in CIP header is not reliable as synchronization timing,
+ //
+ OXFW_DEV_ENTRY(VENDOR_GRIFFIN, 0x00f970, &griffin_firewave),
+ OXFW_DEV_ENTRY(VENDOR_LACIE, 0x00f970, &lacie_speakers),
+ // Behringer,F-Control Audio 202. The value of SYT field is not reliable at all.
+ OXFW_DEV_ENTRY(VENDOR_BEHRINGER, 0x00fc22, NULL),
+ // Loud Technologies, Tapco Link.FireWire 4x6. The value of SYT field is always 0xffff.
+ OXFW_DEV_ENTRY(VENDOR_LOUD, 0x000460, NULL),
+ // Loud Technologies, Mackie Onyx Satellite. Although revised version of firmware is
+ // installed to avoid the postpone, the value of SYT field is always 0xffff.
+ OXFW_DEV_ENTRY(VENDOR_LOUD, MODEL_SATELLITE, NULL),
+ // Miglia HarmonyAudio. Not yet identified.
+
+ //
+ // OXFW971 devices:
+ // The value of SYT field in CIP header is enough reliable. Both of blocking and non-blocking
+ // transmission methods are available.
+ //
+ // Any Mackie(Loud) models (name string/model id):
+ // Onyx-i series (former models): 0x081216
+ // Onyx 1640i: 0x001640
+ // d.2 pro/d.4 pro (built-in card): Unknown
+ // U.420: Unknown
+ // U.420d: Unknown
{
.match_flags = IEEE1394_MATCH_VENDOR_ID |
IEEE1394_MATCH_SPECIFIER_ID |
IEEE1394_MATCH_VERSION,
.vendor_id = VENDOR_LOUD,
+ .model_id = 0,
.specifier_id = SPECIFIER_1394TA,
.version = VERSION_AVC,
},
- /* TASCAM, FireOne */
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID,
- .vendor_id = VENDOR_TASCAM,
- .model_id = 0x800007,
- },
- /* Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m) */
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID,
- .vendor_id = OUI_STANTON,
- .model_id = 0x001000,
- },
- /* Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d) */
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID,
- .vendor_id = OUI_STANTON,
- .model_id = 0x002000,
- },
- // APOGEE, duet FireWire
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID,
- .vendor_id = OUI_APOGEE,
- .model_id = 0x01dddd,
- },
+ // TASCAM, FireOne.
+ OXFW_DEV_ENTRY(VENDOR_TASCAM, 0x800007, NULL),
+ // Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m).
+ OXFW_DEV_ENTRY(OUI_STANTON, MODEL_SCS1M, NULL),
+ // Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d).
+ OXFW_DEV_ENTRY(OUI_STANTON, 0x002000, NULL),
+ // APOGEE, duet FireWire.
+ OXFW_DEV_ENTRY(OUI_APOGEE, MODEL_DUET_FW, NULL),
{ }
};
MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index fa2d7f9e2dc3..ee47abcb0c90 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -32,6 +32,18 @@
#include "../amdtp-am824.h"
#include "../cmp.h"
+enum snd_oxfw_quirk {
+ // Postpone transferring packets during handling asynchronous transaction. As a result,
+ // next isochronous packet includes more events than one packet can include.
+ SND_OXFW_QUIRK_JUMBO_PAYLOAD = 0x01,
+ // The dbs field of CIP header in tx packet is wrong.
+ SND_OXFW_QUIRK_WRONG_DBS = 0x02,
+ // Blocking transmission mode is used.
+ SND_OXFW_QUIRK_BLOCKING_TRANSMISSION = 0x04,
+ // Stanton SCS1.d and SCS1.m support unique transaction.
+ SND_OXFW_QUIRK_SCS_TRANSACTION = 0x08,
+};
+
/* This is an arbitrary number for convinience. */
#define SND_OXFW_STREAM_FORMAT_ENTRIES 10
struct snd_oxfw {
@@ -40,10 +52,8 @@ struct snd_oxfw {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
-
- bool wrong_dbs;
+ // The combination of snd_oxfw_quirk enumeration-constants.
+ unsigned int quirks;
bool has_output;
bool has_input;
u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
@@ -62,7 +72,6 @@ struct snd_oxfw {
bool dev_lock_changed;
wait_queue_head_t hwdep_wait;
- const struct ieee1394_device_id *entry;
void *spec;
struct amdtp_domain domain;
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
index f823a2ab3544..64d66a802545 100644
--- a/sound/firewire/tascam/amdtp-tascam.c
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -228,6 +228,7 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir, unsigned int pcm_channels)
{
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
+ unsigned int flags = CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK | CIP_UNAWARE_SYT;
struct amdtp_tscm *p;
unsigned int fmt;
int err;
@@ -240,8 +241,7 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
process_ctx_payloads = process_it_ctx_payloads;
}
- err = amdtp_stream_init(s, unit, dir,
- CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt,
+ err = amdtp_stream_init(s, unit, dir, flags, fmt,
process_ctx_payloads, sizeof(struct amdtp_tscm));
if (err < 0)
return 0;
@@ -249,8 +249,6 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
if (dir == AMDTP_OUT_STREAM) {
// Use fixed value for FDF field.
s->ctx_data.rx.fdf = 0x00;
- // Not used.
- s->ctx_data.rx.syt_override = 0x0000;
}
/* This protocol uses fixed number of data channels for PCM samples. */
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index eb07e1decf9b..53e094cc411f 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -11,7 +11,7 @@
#define CLOCK_STATUS_MASK 0xffff0000
#define CLOCK_CONFIG_MASK 0x0000ffff
-#define CALLBACK_TIMEOUT 500
+#define READY_TIMEOUT_MS 4000
static int get_clock(struct snd_tscm *tscm, u32 *data)
{
@@ -423,6 +423,8 @@ int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate,
fw_iso_resources_free(&tscm->rx_resources);
return err;
}
+
+ tscm->need_long_tx_init_skip = (rate != curr_rate);
}
return 0;
@@ -454,6 +456,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
if (!amdtp_stream_running(&tscm->rx_stream)) {
int spd = fw_parent_device(tscm->unit)->max_speed;
+ unsigned int tx_init_skip_cycles;
err = set_stream_formats(tscm, rate);
if (err < 0)
@@ -473,14 +476,23 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
if (err < 0)
goto error;
- err = amdtp_domain_start(&tscm->domain, 0);
+ if (tscm->need_long_tx_init_skip)
+ tx_init_skip_cycles = 16000;
+ else
+ tx_init_skip_cycles = 0;
+
+ // MEMO: Just after starting packet streaming, it transfers packets without any
+ // event. Enough after receiving the sequence of packets, it multiplexes events into
+ // the packet. However, just after changing sampling transfer frequency, it stops
+ // multiplexing during packet transmission. Enough after, it restarts multiplexing
+ // again. The device ignores presentation time expressed by the value of syt field
+ // of CIP header in received packets. The sequence of the number of data blocks per
+ // packet is important for media clock recovery.
+ err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true);
if (err < 0)
return err;
- if (!amdtp_stream_wait_callback(&tscm->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&tscm->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
@@ -502,6 +514,8 @@ void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
fw_iso_resources_free(&tscm->tx_resources);
fw_iso_resources_free(&tscm->rx_resources);
+
+ tscm->need_long_tx_init_skip = false;
}
}
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
index 75f2edd8e78f..eb58d3fcf087 100644
--- a/sound/firewire/tascam/tascam.c
+++ b/sound/firewire/tascam/tascam.c
@@ -90,19 +90,31 @@ static void tscm_card_free(struct snd_card *card)
snd_tscm_transaction_unregister(tscm);
snd_tscm_stream_destroy_duplex(tscm);
+
+ mutex_destroy(&tscm->mutex);
+ fw_unit_put(tscm->unit);
}
-static void do_registration(struct work_struct *work)
+static int snd_tscm_probe(struct fw_unit *unit,
+ const struct ieee1394_device_id *entry)
{
- struct snd_tscm *tscm = container_of(work, struct snd_tscm, dwork.work);
+ struct snd_card *card;
+ struct snd_tscm *tscm;
int err;
- err = snd_card_new(&tscm->unit->device, -1, NULL, THIS_MODULE, 0,
- &tscm->card);
+ err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*tscm), &card);
if (err < 0)
- return;
- tscm->card->private_free = tscm_card_free;
- tscm->card->private_data = tscm;
+ return err;
+ card->private_free = tscm_card_free;
+
+ tscm = card->private_data;
+ tscm->unit = fw_unit_get(unit);
+ dev_set_drvdata(&unit->device, tscm);
+ tscm->card = card;
+
+ mutex_init(&tscm->mutex);
+ spin_lock_init(&tscm->lock);
+ init_waitqueue_head(&tscm->hwdep_wait);
err = identify_model(tscm);
if (err < 0)
@@ -130,81 +142,33 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_card_register(tscm->card);
+ err = snd_card_register(card);
if (err < 0)
goto error;
- tscm->registered = true;
-
- return;
-error:
- snd_card_free(tscm->card);
- dev_info(&tscm->unit->device,
- "Sound card registration failed: %d\n", err);
-}
-
-static int snd_tscm_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *entry)
-{
- struct snd_tscm *tscm;
-
- /* Allocate this independent of sound card instance. */
- tscm = devm_kzalloc(&unit->device, sizeof(struct snd_tscm), GFP_KERNEL);
- if (!tscm)
- return -ENOMEM;
- tscm->unit = fw_unit_get(unit);
- dev_set_drvdata(&unit->device, tscm);
-
- mutex_init(&tscm->mutex);
- spin_lock_init(&tscm->lock);
- init_waitqueue_head(&tscm->hwdep_wait);
-
- /* Allocate and register this sound card later. */
- INIT_DEFERRABLE_WORK(&tscm->dwork, do_registration);
- snd_fw_schedule_registration(unit, &tscm->dwork);
-
return 0;
+error:
+ snd_card_free(card);
+ return err;
}
static void snd_tscm_update(struct fw_unit *unit)
{
struct snd_tscm *tscm = dev_get_drvdata(&unit->device);
- /* Postpone a workqueue for deferred registration. */
- if (!tscm->registered)
- snd_fw_schedule_registration(unit, &tscm->dwork);
-
snd_tscm_transaction_reregister(tscm);
- /*
- * After registration, userspace can start packet streaming, then this
- * code block works fine.
- */
- if (tscm->registered) {
- mutex_lock(&tscm->mutex);
- snd_tscm_stream_update_duplex(tscm);
- mutex_unlock(&tscm->mutex);
- }
+ mutex_lock(&tscm->mutex);
+ snd_tscm_stream_update_duplex(tscm);
+ mutex_unlock(&tscm->mutex);
}
static void snd_tscm_remove(struct fw_unit *unit)
{
struct snd_tscm *tscm = dev_get_drvdata(&unit->device);
- /*
- * Confirm to stop the work for registration before the sound card is
- * going to be released. The work is not scheduled again because bus
- * reset handler is not called anymore.
- */
- cancel_delayed_work_sync(&tscm->dwork);
-
- if (tscm->registered) {
- // Block till all of ALSA character devices are released.
- snd_card_free(tscm->card);
- }
-
- mutex_destroy(&tscm->mutex);
- fw_unit_put(tscm->unit);
+ // Block till all of ALSA character devices are released.
+ snd_card_free(tscm->card);
}
static const struct ieee1394_device_id snd_tscm_id_table[] = {
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index 78b7a08986a1..d07ffcb27be6 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -70,8 +70,6 @@ struct snd_tscm {
struct mutex mutex;
spinlock_t lock;
- bool registered;
- struct delayed_work dwork;
const struct snd_tscm_spec *spec;
struct fw_iso_resources tx_resources;
@@ -99,6 +97,7 @@ struct snd_tscm {
unsigned int push_pos;
struct amdtp_domain domain;
+ bool need_long_tx_init_skip;
};
#define TSCM_ADDR_BASE 0xffff00000000ull
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 8634d4f466b3..65012af6a36e 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -50,7 +50,8 @@ int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
buf[0] = reg & 0x7f;
buf[1] = val;
- if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
+ err = snd_i2c_sendbytes(device, buf, 2);
+ if (err != 2) {
snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x "
"to CS8427 (%i)\n", buf[0], buf[1], err);
return err < 0 ? err : -EIO;
@@ -65,12 +66,14 @@ static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
int err;
unsigned char buf;
- if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
+ err = snd_i2c_sendbytes(device, &reg, 1);
+ if (err != 1) {
snd_printk(KERN_ERR "unable to send register 0x%x byte "
"to CS8427\n", reg);
return err < 0 ? err : -EIO;
}
- if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
+ err = snd_i2c_readbytes(device, &buf, 1);
+ if (err != 1) {
snd_printk(KERN_ERR "unable to read register 0x%x byte "
"from CS8427\n", reg);
return err < 0 ? err : -EIO;
@@ -108,7 +111,8 @@ static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
if (!memcmp(hw_data, ndata, count))
return 0;
- if ((err = snd_cs8427_select_corudata(device, udata)) < 0)
+ err = snd_cs8427_select_corudata(device, udata);
+ if (err < 0)
return err;
memcpy(hw_data, ndata, count);
if (udata) {
@@ -209,7 +213,8 @@ int snd_cs8427_init(struct snd_i2c_bus *bus,
goto __fail;
/* send initial values */
memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
- if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
+ err = snd_i2c_sendbytes(device, initvals1, 7);
+ if (err != 7) {
err = err < 0 ? err : -EIO;
goto __fail;
}
@@ -217,11 +222,13 @@ int snd_cs8427_init(struct snd_i2c_bus *bus,
memset(buf, 0, 7);
/* from address 9 to 15 */
buf[0] = 9; /* register */
- if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
+ err = snd_i2c_sendbytes(device, buf, 7);
+ if (err != 7)
goto __fail;
/* send transfer initialization sequence */
memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
- if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
+ err = snd_i2c_sendbytes(device, initvals2, 4);
+ if (err != 4) {
err = err < 0 ? err : -EIO;
goto __fail;
}
@@ -383,7 +390,8 @@ static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
int err;
snd_i2c_lock(device->bus);
- if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
+ err = snd_i2c_sendbytes(device, &reg, 1);
+ if (err != 1) {
snd_printk(KERN_ERR "unable to send register 0x%x byte "
"to CS8427\n", reg);
snd_i2c_unlock(device->bus);
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 2ce0a97957ab..c0cffe28989b 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -97,7 +97,8 @@ int snd_ak4114_create(struct snd_card *card,
chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
+ err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);
+ if (err < 0)
goto __fail;
if (r_ak4114)
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index 905be2d0780b..1bc43e927d82 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -86,7 +86,8 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t
chip->rcs1 = reg_read(chip, AK4117_REG_RCS1);
chip->rcs2 = reg_read(chip, AK4117_REG_RCS2);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
+ err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);
+ if (err < 0)
goto __fail;
if (r_ak4117)
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index 08eb6a873768..037d6293f728 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -115,7 +115,8 @@ static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = tea->mright;
}
if (count > 0) {
- if ((err = snd_i2c_sendbytes(tea->device, bytes, count)) < 0)
+ err = snd_i2c_sendbytes(tea->device, bytes, count);
+ if (err < 0)
change = err;
}
snd_i2c_unlock(tea->bus);
@@ -160,7 +161,8 @@ static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol,
bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT];
bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT];
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 3)) < 0)
+ err = snd_i2c_sendbytes(tea->device, bytes, 3);
+ if (err < 0)
change = err;
snd_i2c_unlock(tea->bus);
return change;
@@ -207,7 +209,8 @@ static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol,
change = tea->regs[TEA6330T_SADDR_BASS] != val1;
bytes[0] = TEA6330T_SADDR_BASS;
bytes[1] = tea->regs[TEA6330T_SADDR_BASS] = val1;
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
+ err = snd_i2c_sendbytes(tea->device, bytes, 2);
+ if (err < 0)
change = err;
snd_i2c_unlock(tea->bus);
return change;
@@ -254,7 +257,8 @@ static int snd_tea6330t_put_treble(struct snd_kcontrol *kcontrol,
change = tea->regs[TEA6330T_SADDR_TREBLE] != val1;
bytes[0] = TEA6330T_SADDR_TREBLE;
bytes[1] = tea->regs[TEA6330T_SADDR_TREBLE] = val1;
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
+ err = snd_i2c_sendbytes(tea->device, bytes, 2);
+ if (err < 0)
change = err;
snd_i2c_unlock(tea->bus);
return change;
@@ -280,14 +284,15 @@ int snd_tea6330t_update_mixer(struct snd_card *card,
struct tea6330t *tea;
const struct snd_kcontrol_new *knew;
unsigned int idx;
- int err = -ENOMEM;
+ int err;
u8 default_treble, default_bass;
unsigned char bytes[7];
tea = kzalloc(sizeof(*tea), GFP_KERNEL);
if (tea == NULL)
return -ENOMEM;
- if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
+ err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device);
+ if (err < 0) {
kfree(tea);
return err;
}
@@ -327,18 +332,21 @@ int snd_tea6330t_update_mixer(struct snd_card *card,
bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
for (idx = 0; idx < 6; idx++)
bytes[idx+1] = tea->regs[idx];
- if ((err = snd_i2c_sendbytes(device, bytes, 7)) < 0)
+ err = snd_i2c_sendbytes(device, bytes, 7);
+ if (err < 0)
goto __error;
strcat(card->mixername, ",TEA6330T");
- if ((err = snd_component_add(card, "TEA6330T")) < 0)
+ err = snd_component_add(card, "TEA6330T");
+ if (err < 0)
goto __error;
for (idx = 0; idx < ARRAY_SIZE(snd_tea6330t_controls); idx++) {
knew = &snd_tea6330t_controls[idx];
if (tea->treble == 0 && !strcmp(knew->name, "Tone Control - Treble"))
continue;
- if ((err = snd_ctl_add(card, snd_ctl_new1(knew, tea))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(knew, tea));
+ if (err < 0)
goto __error;
}
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index f11af983b3b6..fa5bed0d5a6f 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -131,16 +131,18 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
return error;
chip = card->private_data;
- if ((error = snd_card_ad1816a_pnp(dev, pcard, pid))) {
+ error = snd_card_ad1816a_pnp(dev, pcard, pid);
+ if (error) {
snd_card_free(card);
return error;
}
- if ((error = snd_ad1816a_create(card, port[dev],
- irq[dev],
- dma1[dev],
- dma2[dev],
- chip)) < 0) {
+ error = snd_ad1816a_create(card, port[dev],
+ irq[dev],
+ dma1[dev],
+ dma2[dev],
+ chip);
+ if (error) {
snd_card_free(card);
return error;
}
@@ -152,12 +154,14 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d",
card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
- if ((error = snd_ad1816a_pcm(chip, 0)) < 0) {
+ error = snd_ad1816a_pcm(chip, 0);
+ if (error < 0) {
snd_card_free(card);
return error;
}
- if ((error = snd_ad1816a_mixer(chip)) < 0) {
+ error = snd_ad1816a_mixer(chip);
+ if (error < 0) {
snd_card_free(card);
return error;
}
@@ -189,7 +193,8 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
}
}
- if ((error = snd_card_register(card)) < 0) {
+ error = snd_card_register(card);
+ if (error < 0) {
snd_card_free(card);
return error;
}
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 01381fe7c0c9..6d4999b30461 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -155,7 +155,8 @@ static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
AD1816A_TIMER_IRQ_ENABLE, 0x0000);
}
- if (!((chip->mode &= ~mode) & AD1816A_MODE_OPEN))
+ chip->mode &= ~mode;
+ if (!(chip->mode & AD1816A_MODE_OPEN))
chip->mode = 0;
spin_unlock_irqrestore(&chip->lock, flags);
@@ -426,7 +427,8 @@ static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int error;
- if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)
+ error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK);
+ if (error < 0)
return error;
runtime->hw = snd_ad1816a_playback;
snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
@@ -441,7 +443,8 @@ static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int error;
- if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)
+ error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE);
+ if (error < 0)
return error;
runtime->hw = snd_ad1816a_capture;
snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
@@ -586,7 +589,8 @@ int snd_ad1816a_create(struct snd_card *card,
chip->dma1 = -1;
chip->dma2 = -1;
- if ((chip->res_port = request_region(port, 16, "AD1816A")) == NULL) {
+ chip->res_port = request_region(port, 16, "AD1816A");
+ if (!chip->res_port) {
snd_printk(KERN_ERR "ad1816a: can't grab port 0x%lx\n", port);
snd_ad1816a_free(chip);
return -EBUSY;
@@ -615,7 +619,8 @@ int snd_ad1816a_create(struct snd_card *card,
chip->port = port;
spin_lock_init(&chip->lock);
- if ((error = snd_ad1816a_probe(chip))) {
+ error = snd_ad1816a_probe(chip);
+ if (error) {
snd_ad1816a_free(chip);
return error;
}
@@ -623,7 +628,8 @@ int snd_ad1816a_create(struct snd_card *card,
snd_ad1816a_init(chip);
/* Register device */
- if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (error < 0) {
snd_ad1816a_free(chip);
return error;
}
@@ -652,7 +658,8 @@ int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device)
int error;
struct snd_pcm *pcm;
- if ((error = snd_pcm_new(chip->card, "AD1816A", device, 1, 1, &pcm)))
+ error = snd_pcm_new(chip->card, "AD1816A", device, 1, 1, &pcm);
+ if (error)
return error;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1816a_playback_ops);
@@ -682,7 +689,8 @@ int snd_ad1816a_timer(struct snd_ad1816a *chip, int device)
tid.card = chip->card->number;
tid.device = device;
tid.subdevice = 0;
- if ((error = snd_timer_new(chip->card, "AD1816A", &tid, &timer)) < 0)
+ error = snd_timer_new(chip->card, "AD1816A", &tid, &timer);
+ if (error < 0)
return error;
strcpy(timer->name, snd_ad1816a_chip_id(chip));
timer->private_data = chip;
@@ -944,7 +952,8 @@ int snd_ad1816a_mixer(struct snd_ad1816a *chip)
strcpy(card->mixername, snd_ad1816a_chip_id(chip));
for (idx = 0; idx < ARRAY_SIZE(snd_ad1816a_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1816a_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1816a_controls[idx], chip));
+ if (err < 0)
return err;
}
return 0;
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index bacb7a1b930c..d4597fdfe091 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -177,7 +177,8 @@ static int snd_card_als100_probe(int dev,
return error;
acard = card->private_data;
- if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) {
+ error = snd_card_als100_pnp(dev, acard, pcard, pid);
+ if (error) {
snd_card_free(card);
return error;
}
@@ -211,12 +212,14 @@ static int snd_card_als100_probe(int dev,
dma16[dev]);
}
- if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) {
+ error = snd_sb16dsp_pcm(chip, 0);
+ if (error < 0) {
snd_card_free(card);
return error;
}
- if ((error = snd_sbmixer_new(chip)) < 0) {
+ error = snd_sbmixer_new(chip);
+ if (error < 0) {
snd_card_free(card);
return error;
}
@@ -245,18 +248,21 @@ static int snd_card_als100_probe(int dev,
snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
fm_port[dev], fm_port[dev] + 2);
} else {
- if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
+ error = snd_opl3_timer_new(opl3, 0, 1);
+ if (error < 0) {
snd_card_free(card);
return error;
}
- if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (error < 0) {
snd_card_free(card);
return error;
}
}
}
- if ((error = snd_card_register(card)) < 0) {
+ error = snd_card_register(card);
+ if (error < 0) {
snd_card_free(card);
return error;
}
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index 867e9ae8f65a..dd5c059b3744 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -148,9 +148,11 @@ static int snd_card_azt2320_enable_wss(unsigned long port)
{
int error;
- if ((error = snd_card_azt2320_command(port, 0x09)))
+ error = snd_card_azt2320_command(port, 0x09);
+ if (error)
return error;
- if ((error = snd_card_azt2320_command(port, 0x00)))
+ error = snd_card_azt2320_command(port, 0x00);
+ if (error)
return error;
mdelay(5);
@@ -174,12 +176,14 @@ static int snd_card_azt2320_probe(int dev,
return error;
acard = card->private_data;
- if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) {
+ error = snd_card_azt2320_pnp(dev, acard, pcard, pid);
+ if (error) {
snd_card_free(card);
return error;
}
- if ((error = snd_card_azt2320_enable_wss(port[dev]))) {
+ error = snd_card_azt2320_enable_wss(port[dev]);
+ if (error) {
snd_card_free(card);
return error;
}
@@ -228,18 +232,21 @@ static int snd_card_azt2320_probe(int dev,
snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
fm_port[dev], fm_port[dev] + 2);
} else {
- if ((error = snd_opl3_timer_new(opl3, 1, 2)) < 0) {
+ error = snd_opl3_timer_new(opl3, 1, 2);
+ if (error < 0) {
snd_card_free(card);
return error;
}
- if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (error < 0) {
snd_card_free(card);
return error;
}
}
}
- if ((error = snd_card_register(card)) < 0) {
+ error = snd_card_register(card);
+ if (error < 0) {
snd_card_free(card);
return error;
}
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index bc112df10fc5..ef6d0a20efd8 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -284,7 +284,8 @@ static int cmi8330_add_sb_mixers(struct snd_sb *chip)
}
for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) {
- if ((err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx])) < 0)
+ err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx]);
+ if (err < 0)
return err;
}
return 0;
@@ -307,7 +308,8 @@ static int snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
}
#ifdef ENABLE_SB_MIXER
- if ((err = cmi8330_add_sb_mixers(acard->sb)) < 0)
+ err = cmi8330_add_sb_mixers(acard->sb);
+ if (err < 0)
return err;
#endif
return 0;
@@ -432,7 +434,8 @@ static int snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
snd_cmi8330_capture_open
};
- if ((err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm);
+ if (err < 0)
return err;
strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
pcm->private_data = chip;
@@ -536,18 +539,19 @@ static int snd_cmi8330_probe(struct snd_card *card, int dev)
return -ENODEV;
}
- if ((err = snd_sbdsp_create(card, sbport[dev],
- sbirq[dev],
- snd_sb16dsp_interrupt,
- sbdma8[dev],
- sbdma16[dev],
- SB_HW_AUTO, &acard->sb)) < 0) {
+ err = snd_sbdsp_create(card, sbport[dev],
+ sbirq[dev],
+ snd_sb16dsp_interrupt,
+ sbdma8[dev],
+ sbdma16[dev],
+ SB_HW_AUTO, &acard->sb);
+ if (err < 0) {
snd_printk(KERN_ERR PFX "SB16 device busy??\n");
return err;
}
if (acard->sb->hardware != SB_HW_16) {
snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
- return err;
+ return -ENODEV;
}
snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */
@@ -555,12 +559,14 @@ static int snd_cmi8330_probe(struct snd_card *card, int dev)
snd_wss_out(acard->wss, i,
snd_cmi8330_image[i - CMI8330_RMUX3D]);
- if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
+ err = snd_cmi8330_mixer(card, acard);
+ if (err < 0) {
snd_printk(KERN_ERR PFX "failed to create mixers\n");
return err;
}
- if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
+ err = snd_cmi8330_pcm(card, acard);
+ if (err < 0) {
snd_printk(KERN_ERR PFX "failed to create pcms\n");
return err;
}
@@ -622,7 +628,8 @@ static int snd_cmi8330_isa_probe(struct device *pdev,
err = snd_cmi8330_card_new(pdev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_cmi8330_probe(card, dev)) < 0) {
+ err = snd_cmi8330_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -683,12 +690,14 @@ static int snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
res = snd_cmi8330_card_new(&pcard->card->dev, dev, &card);
if (res < 0)
return res;
- if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) {
+ res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid);
+ if (res < 0) {
snd_printk(KERN_ERR PFX "PnP detection failed\n");
snd_card_free(card);
return res;
}
- if ((res = snd_cmi8330_probe(card, dev)) < 0) {
+ res = snd_cmi8330_probe(card, dev);
+ if (res < 0) {
snd_card_free(card);
return res;
}
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 186d7d4db45e..0b7fd17f8ecc 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -339,11 +339,13 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
int err;
acard = card->private_data;
- if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
- if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
+ if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT) {
+ acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB");
+ if (!acard->res_sb_port) {
printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
return -EBUSY;
}
+ }
err = snd_cs4236_create(card, port[dev], cport[dev],
irq[dev],
@@ -393,7 +395,8 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
OPL3_HW_OPL3_CS, 0, &opl3) < 0) {
printk(KERN_WARNING IDENT ": OPL3 not detected\n");
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0)
return err;
}
}
@@ -444,7 +447,8 @@ static int snd_cs423x_isa_probe(struct device *pdev,
err = snd_cs423x_card_new(pdev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_cs423x_probe(card, dev)) < 0) {
+ err = snd_cs423x_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -538,7 +542,8 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
snd_card_free(card);
return err;
}
- if ((err = snd_cs423x_probe(card, dev)) < 0) {
+ err = snd_cs423x_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -592,13 +597,15 @@ static int snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
res = snd_cs423x_card_new(&pcard->card->dev, dev, &card);
if (res < 0)
return res;
- if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) {
+ res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid);
+ if (res < 0) {
printk(KERN_ERR "isapnp detection failed and probing for " IDENT
" is not supported\n");
snd_card_free(card);
return res;
}
- if ((res = snd_cs423x_probe(card, dev)) < 0) {
+ res = snd_cs423x_probe(card, dev);
+ if (res < 0) {
snd_card_free(card);
return res;
}
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 52f05adb1870..63957aea456b 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -1030,12 +1030,14 @@ int snd_cs4236_mixer(struct snd_wss *chip)
if (chip->hardware == WSS_HW_CS4235 ||
chip->hardware == WSS_HW_CS4239) {
for (idx = 0; idx < ARRAY_SIZE(snd_cs4235_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip));
+ if (err < 0)
return err;
}
} else {
for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_controls[idx], chip));
+ if (err < 0)
return err;
}
}
@@ -1058,13 +1060,15 @@ int snd_cs4236_mixer(struct snd_wss *chip)
kcontrol = NULL;
}
for (idx = 0; idx < count; idx++, kcontrol++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip));
+ if (err < 0)
return err;
}
if (chip->hardware == WSS_HW_CS4237B ||
chip->hardware == WSS_HW_CS4238B) {
for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_iec958_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip));
+ if (err < 0)
return err;
}
}
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 1816e55c6edf..8554cb2263c1 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -971,7 +971,8 @@ int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
strcpy(card->mixername, snd_es1688_chip_id(chip));
for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es1688_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es1688_controls[idx], chip));
+ if (err < 0)
return err;
}
for (idx = 0; idx < ES1688_INIT_TABLE_SIZE; idx++) {
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 375a4a6a4717..68b9c59e1127 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1573,7 +1573,8 @@ static int snd_es18xx_identify(struct snd_es18xx *chip)
udelay(10);
chip->ctrl_port += inb(chip->port + 0x05);
- if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) {
+ chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL");
+ if (!chip->res_ctrl_port) {
snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port);
return -EBUSY;
}
@@ -1832,41 +1833,48 @@ static int snd_es18xx_mixer(struct snd_card *card)
break;
}
}
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
if (chip->caps & ES18XX_PCM2) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm2_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip));
+ if (err < 0)
return err;
}
} else {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm1_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip));
+ if (err < 0)
return err;
}
}
if (chip->caps & ES18XX_RECMIX) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip));
+ if (err < 0)
return err;
}
}
switch (chip->version) {
default:
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip));
+ if (err < 0)
return err;
break;
case 0x1869:
case 0x1879:
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip));
+ if (err < 0)
return err;
break;
}
if (chip->caps & ES18XX_SPATIALIZER) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_spatializer_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip));
+ if (err < 0)
return err;
}
}
@@ -1879,7 +1887,8 @@ static int snd_es18xx_mixer(struct snd_card *card)
else
chip->hw_switch = kctl;
kctl->private_free = snd_es18xx_hwv_free;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
@@ -2154,7 +2163,8 @@ static int snd_es18xx_isa_probe1(int dev, struct device *devptr)
err = snd_es18xx_card_new(devptr, dev, &card);
if (err < 0)
return err;
- if ((err = snd_audiodrive_probe(card, dev)) < 0) {
+ err = snd_audiodrive_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2169,19 +2179,22 @@ static int snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
static const int possible_dmas[] = {1, 0, 3, 5, -1};
if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ irq[dev] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
return -EBUSY;
}
}
if (dma1[dev] == SNDRV_AUTO_DMA) {
- if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ dma1[dev] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma1[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
return -EBUSY;
}
}
if (dma2[dev] == SNDRV_AUTO_DMA) {
- if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ dma2[dev] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma2[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
return -EBUSY;
}
@@ -2257,11 +2270,13 @@ static int snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
err = snd_es18xx_card_new(&pdev->dev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) {
+ err = snd_audiodrive_pnp(dev, card->private_data, pdev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_audiodrive_probe(card, dev)) < 0) {
+ err = snd_audiodrive_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2315,11 +2330,13 @@ static int snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
if (res < 0)
return res;
- if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) {
+ res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid);
+ if (res < 0) {
snd_card_free(card);
return res;
}
- if ((res = snd_audiodrive_probe(card, dev)) < 0) {
+ res = snd_audiodrive_probe(card, dev);
+ if (res < 0) {
snd_card_free(card);
return res;
}
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index b7518122a10d..3b46490271fe 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -156,12 +156,14 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.reg_timerctrl = GUSP(gus, TIMERCNTRL);
gus->gf1.reg_timerdata = GUSP(gus, TIMERDATA);
/* allocate resources */
- if ((gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)")) == NULL) {
+ gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)");
+ if (!gus->gf1.res_port1) {
snd_printk(KERN_ERR "gus: can't grab SB port 0x%lx\n", port);
snd_gus_free(gus);
return -EBUSY;
}
- if ((gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)")) == NULL) {
+ gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)");
+ if (!gus->gf1.res_port2) {
snd_printk(KERN_ERR "gus: can't grab synth port 0x%lx\n", port + 0x100);
snd_gus_free(gus);
return -EBUSY;
@@ -206,7 +208,8 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.pcm_channels = pcm_channels;
gus->gf1.volume_ramp = 25;
gus->gf1.smooth_pan = 1;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops);
+ if (err < 0) {
snd_gus_free(gus);
return err;
}
@@ -384,7 +387,7 @@ static int snd_gus_check_version(struct snd_gus_card * gus)
}
}
}
- strcpy(card->shortname, card->longname);
+ strscpy(card->shortname, card->longname, sizeof(card->shortname));
gus->uart_enable = 1; /* standard GUSes doesn't have midi uart trouble */
snd_gus_init_control(gus);
return 0;
@@ -395,14 +398,17 @@ int snd_gus_initialize(struct snd_gus_card *gus)
int err;
if (!gus->interwave) {
- if ((err = snd_gus_check_version(gus)) < 0) {
+ err = snd_gus_check_version(gus);
+ if (err < 0) {
snd_printk(KERN_ERR "version check failed\n");
return err;
}
- if ((err = snd_gus_detect_memory(gus)) < 0)
+ err = snd_gus_detect_memory(gus);
+ if (err < 0)
return err;
}
- if ((err = snd_gus_init_dma_irq(gus, 1)) < 0)
+ err = snd_gus_init_dma_irq(gus, 1);
+ if (err < 0)
return err;
snd_gf1_start(gus);
gus->initialized = 1;
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index cb02d18dde60..ff9480f249fe 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -210,7 +210,8 @@ int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address)
struct snd_gf1_mem_block *block;
snd_gf1_mem_lock(alloc, 0);
- if ((block = snd_gf1_mem_look(alloc, address)) != NULL) {
+ block = snd_gf1_mem_look(alloc, address);
+ if (block) {
result = snd_gf1_mem_xfree(alloc, block);
snd_gf1_mem_lock(alloc, 1);
return result;
diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
index 201d0c40d0d9..03f9cfcbf601 100644
--- a/sound/isa/gus/gus_mixer.c
+++ b/sound/isa/gus/gus_mixer.c
@@ -162,12 +162,14 @@ int snd_gf1_new_mixer(struct snd_gus_card * gus)
if (!gus->ics_flag) {
max = gus->ess_flag ? 1 : ARRAY_SIZE(snd_gf1_controls);
for (idx = 0; idx < max; idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_gf1_controls[idx], gus))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_gf1_controls[idx], gus));
+ if (err < 0)
return err;
}
} else {
for (idx = 0; idx < ARRAY_SIZE(snd_ics_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ics_controls[idx], gus))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_ics_controls[idx], gus));
+ if (err < 0)
return err;
}
}
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index aca4ab90e5bc..230f65a0e4b0 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -430,17 +430,19 @@ static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
snd_gf1_mem_free(&gus->gf1.mem_alloc, pcmp->memory);
pcmp->memory = 0;
}
- if ((block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
- SNDRV_GF1_MEM_OWNER_DRIVER,
- "GF1 PCM",
- runtime->dma_bytes, 1, 32,
- NULL)) == NULL)
+ block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
+ SNDRV_GF1_MEM_OWNER_DRIVER,
+ "GF1 PCM",
+ runtime->dma_bytes, 1, 32,
+ NULL);
+ if (!block)
return -ENOMEM;
pcmp->memory = block->ptr;
}
pcmp->voices = params_channels(hw_params);
if (pcmp->pvoices[0] == NULL) {
- if ((pcmp->pvoices[0] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0)) == NULL)
+ pcmp->pvoices[0] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0);
+ if (!pcmp->pvoices[0])
return -ENOMEM;
pcmp->pvoices[0]->handler_wave = snd_gf1_pcm_interrupt_wave;
pcmp->pvoices[0]->handler_volume = snd_gf1_pcm_interrupt_volume;
@@ -448,7 +450,8 @@ static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
pcmp->pvoices[0]->private_data = pcmp;
}
if (pcmp->voices > 1 && pcmp->pvoices[1] == NULL) {
- if ((pcmp->pvoices[1] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0)) == NULL)
+ pcmp->pvoices[1] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0);
+ if (!pcmp->pvoices[1])
return -ENOMEM;
pcmp->pvoices[1]->handler_wave = snd_gf1_pcm_interrupt_wave;
pcmp->pvoices[1]->handler_volume = snd_gf1_pcm_interrupt_volume;
@@ -689,7 +692,8 @@ static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream)
printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n",
(long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer);
#endif
- if ((err = snd_gf1_dma_init(gus)) < 0)
+ err = snd_gf1_dma_init(gus);
+ if (err < 0)
return err;
pcmp->flags = SNDRV_GF1_PCM_PFLG_NONE;
pcmp->substream = substream;
@@ -888,7 +892,8 @@ int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index)
kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
else
kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
kctl->id.index = control_index;
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index 4fb4ed79e262..3975848160e7 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -232,7 +232,8 @@ int snd_gf1_rawmidi_new(struct snd_gus_card *gus, int device)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, gus->interwave ? "AMD InterWave" : "GF1");
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_gf1_uart_output);
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 0fba5d8fe84f..bca1caa4968c 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -113,14 +113,16 @@ static int snd_gusclassic_detect(struct snd_gus_card *gus)
unsigned char d;
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 0) {
snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 1) {
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index da2b2ca6b721..a409a4a29afc 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -177,14 +177,16 @@ static int snd_gusextreme_detect(struct snd_gus_card *gus,
udelay(100);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 0) {
snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -EIO;
}
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 1) {
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -EIO;
}
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 24b945f1768d..ad118d462142 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -71,14 +71,16 @@ static int snd_gusmax_detect(struct snd_gus_card *gus)
unsigned char d;
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 0) {
snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 1) {
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
@@ -136,20 +138,24 @@ static int snd_gusmax_mixer(struct snd_wss *chip)
/* reassign AUXA to SYNTHESIZER */
strcpy(id1.name, "Aux Playback Switch");
strcpy(id2.name, "Synth Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "Synth Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
/* reassign AUXB to CD */
strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
#if 0
/* reassign Mono Input to MIC */
@@ -209,7 +215,8 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
- if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ xirq = snd_legacy_find_free_irq(possible_irqs);
+ if (xirq < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
err = -EBUSY;
goto _err;
@@ -217,7 +224,8 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
}
xdma1 = dma1[dev];
if (xdma1 == SNDRV_AUTO_DMA) {
- if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ xdma1 = snd_legacy_find_free_dma(possible_dmas);
+ if (xdma1 < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
err = -EBUSY;
goto _err;
@@ -225,7 +233,8 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
}
xdma2 = dma2[dev];
if (xdma2 == SNDRV_AUTO_DMA) {
- if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ xdma2 = snd_legacy_find_free_dma(possible_dmas);
+ if (xdma2 < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
err = -EBUSY;
goto _err;
@@ -260,13 +269,15 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
if (err < 0)
goto _err;
- if ((err = snd_gusmax_detect(gus)) < 0)
+ err = snd_gusmax_detect(gus);
+ if (err < 0)
goto _err;
maxcard->gus_status_reg = gus->gf1.reg_irqstat;
maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
snd_gusmax_init(dev, card, gus);
- if ((err = snd_gus_initialize(gus)) < 0)
+ err = snd_gus_initialize(gus);
+ if (err < 0)
goto _err;
if (!gus->max_flag) {
@@ -307,7 +318,8 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
goto _err;
if (pcm_channels[dev] > 0) {
- if ((err = snd_gf1_pcm_new(gus, 1, 1)) < 0)
+ err = snd_gf1_pcm_new(gus, 1, 1);
+ if (err < 0)
goto _err;
}
err = snd_gusmax_mixer(wss);
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 99581fba4ca8..755de47d0bb6 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -204,7 +204,8 @@ static int snd_interwave_detect_stb(struct snd_interwave *iwcard,
port = 0x360;
}
while (port <= 0x380) {
- if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)
+ iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)");
+ if (iwcard->i2c_res)
break;
port += 0x10;
}
@@ -217,11 +218,13 @@ static int snd_interwave_detect_stb(struct snd_interwave *iwcard,
}
sprintf(name, "InterWave-%i", card->number);
- if ((err = snd_i2c_bus_create(card, name, NULL, &bus)) < 0)
+ err = snd_i2c_bus_create(card, name, NULL, &bus);
+ if (err < 0)
return err;
bus->private_value = port;
bus->hw_ops.bit = &snd_interwave_i2c_bit_ops;
- if ((err = snd_tea6330t_detect(bus, 0)) < 0)
+ err = snd_tea6330t_detect(bus, 0);
+ if (err < 0)
return err;
*rbus = bus;
return 0;
@@ -241,14 +244,16 @@ static int snd_interwave_detect(struct snd_interwave *iwcard,
int d;
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 0) {
snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
udelay(160);
snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+ d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET);
+ if ((d & 0x07) != 1) {
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -ENODEV;
}
@@ -493,16 +498,20 @@ static int snd_interwave_mixer(struct snd_wss *chip)
#if 0
/* remove mono microphone controls */
strcpy(id1.name, "Mic Playback Switch");
- if ((err = snd_ctl_remove_id(card, &id1)) < 0)
+ err = snd_ctl_remove_id(card, &id1);
+ if (err < 0)
return err;
strcpy(id1.name, "Mic Playback Volume");
- if ((err = snd_ctl_remove_id(card, &id1)) < 0)
+ err = snd_ctl_remove_id(card, &id1);
+ if (err < 0)
return err;
#endif
/* add new master and mic controls */
- for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip));
+ if (err < 0)
return err;
+ }
snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);
snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);
snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);
@@ -510,20 +519,24 @@ static int snd_interwave_mixer(struct snd_wss *chip)
/* reassign AUXA to SYNTHESIZER */
strcpy(id1.name, "Aux Playback Switch");
strcpy(id2.name, "Synth Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "Synth Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
/* reassign AUXB to CD */
strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
return 0;
}
@@ -633,18 +646,20 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
xdma1 = dma1[dev];
xdma2 = dma2[dev];
- if ((err = snd_gus_create(card,
- port[dev],
- -xirq, xdma1, xdma2,
- 0, 32,
- pcm_channels[dev], effect[dev], &gus)) < 0)
+ err = snd_gus_create(card,
+ port[dev],
+ -xirq, xdma1, xdma2,
+ 0, 32,
+ pcm_channels[dev], effect[dev], &gus);
+ if (err < 0)
return err;
- if ((err = snd_interwave_detect(iwcard, gus, dev
+ err = snd_interwave_detect(iwcard, gus, dev
#ifdef SNDRV_STB
- , &i2c_bus
+ , &i2c_bus
#endif
- )) < 0)
+ );
+ if (err < 0)
return err;
iwcard->gus_status_reg = gus->gf1.reg_irqstat;
@@ -652,7 +667,8 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
snd_interwave_init(dev, gus);
snd_interwave_detect_memory(gus);
- if ((err = snd_gus_initialize(gus)) < 0)
+ err = snd_gus_initialize(gus);
+ if (err < 0)
return err;
if (request_irq(xirq, snd_interwave_interrupt, 0,
@@ -708,19 +724,23 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
strcpy(id1.name, "Master Playback Switch");
strcpy(id2.name, id1.name);
id2.index = 1;
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
strcpy(id1.name, "Master Playback Volume");
strcpy(id2.name, id1.name);
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
return err;
- if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
+ err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1);
+ if (err < 0)
return err;
}
#endif
gus->uart_enable = midi[dev];
- if ((err = snd_gf1_rawmidi_new(gus, 0)) < 0)
+ err = snd_gf1_rawmidi_new(gus, 0);
+ if (err < 0)
return err;
#ifndef SNDRV_STB
@@ -758,7 +778,8 @@ static int snd_interwave_isa_probe1(int dev, struct device *devptr)
if (err < 0)
return err;
- if ((err = snd_interwave_probe(card, dev)) < 0) {
+ err = snd_interwave_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -786,19 +807,22 @@ static int snd_interwave_isa_probe(struct device *pdev,
static const int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ irq[dev] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
return -EBUSY;
}
}
if (dma1[dev] == SNDRV_AUTO_DMA) {
- if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ dma1[dev] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma1[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
return -EBUSY;
}
}
if (dma2[dev] == SNDRV_AUTO_DMA) {
- if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+ dma2[dev] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma2[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
return -EBUSY;
}
@@ -853,11 +877,13 @@ static int snd_interwave_pnp_detect(struct pnp_card_link *pcard,
if (res < 0)
return res;
- if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) {
+ res = snd_interwave_pnp(dev, card->private_data, pcard, pid);
+ if (res < 0) {
snd_card_free(card);
return res;
}
- if ((res = snd_interwave_probe(card, dev)) < 0) {
+ res = snd_interwave_probe(card, dev);
+ if (res < 0) {
snd_card_free(card);
return res;
}
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 9bde11d1cfe8..6f42f869928c 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -208,7 +208,8 @@ static int snd_opl3sa2_detect(struct snd_card *card)
char str[2];
port = chip->port;
- if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) {
+ chip->res_port = request_region(port, 2, "OPL3-SA control");
+ if (!chip->res_port) {
snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
return -EBUSY;
}
@@ -239,14 +240,16 @@ static int snd_opl3sa2_detect(struct snd_card *card)
str[1] = 0;
strcat(card->shortname, str);
snd_opl3sa2_write(chip, OPL3SA2_MISC, tmp ^ 7);
- if ((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MISC)) != tmp) {
+ tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MISC);
+ if (tmp1 != tmp) {
snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1);
return -ENODEV;
}
/* try if the MIC register is accessible */
tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC);
snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a);
- if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) {
+ tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC);
+ if ((tmp1 & 0x9f) != 0x8a) {
snd_printd("OPL3-SA [0x%lx] detect (2) = 0x%x (0x%x)\n", port, tmp, tmp1);
return -ENODEV;
}
@@ -489,32 +492,38 @@ static int snd_opl3sa2_mixer(struct snd_card *card)
/* reassign AUX0 to CD */
strcpy(id1.name, "Aux Playback Switch");
strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
return err;
}
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
return err;
}
/* reassign AUX1 to FM */
strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
strcpy(id2.name, "FM Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
return err;
}
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "FM Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
return err;
}
/* add OPL3SA2 controls */
for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0)
+ kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
switch (idx) {
case 0: chip->master_switch = kctl; kctl->private_free = snd_opl3sa2_master_free; break;
@@ -522,9 +531,11 @@ static int snd_opl3sa2_mixer(struct snd_card *card)
}
}
if (chip->version > 2) {
- for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_tone_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_opl3sa2_tone_controls[idx], chip))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_tone_controls); idx++) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_opl3sa2_tone_controls[idx], chip));
+ if (err < 0)
return err;
+ }
}
return 0;
}
@@ -677,20 +688,24 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev)
if (err < 0)
return err;
if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
- if ((err = snd_opl3_create(card, fm_port[dev],
- fm_port[dev] + 2,
- OPL3_HW_OPL3, 0, &opl3)) < 0)
+ err = snd_opl3_create(card, fm_port[dev],
+ fm_port[dev] + 2,
+ OPL3_HW_OPL3, 0, &opl3);
+ if (err < 0)
return err;
- if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0)
+ err = snd_opl3_timer_new(opl3, 1, 2);
+ if (err < 0)
return err;
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0)
+ err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth);
+ if (err < 0)
return err;
}
if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
- midi_port[dev],
- MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi)) < 0)
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
+ midi_port[dev],
+ MPU401_INFO_IRQ_HOOK, -1,
+ &chip->rmidi);
+ if (err < 0)
return err;
}
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
@@ -721,11 +736,13 @@ static int snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
err = snd_opl3sa2_card_new(&pdev->dev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
+ err = snd_opl3sa2_pnp(dev, card->private_data, pdev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+ err = snd_opl3sa2_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -785,11 +802,13 @@ static int snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
err = snd_opl3sa2_card_new(&pdev->dev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
+ err = snd_opl3sa2_pnp(dev, card->private_data, pdev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+ err = snd_opl3sa2_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -865,7 +884,8 @@ static int snd_opl3sa2_isa_probe(struct device *pdev,
err = snd_opl3sa2_card_new(pdev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+ err = snd_opl3sa2_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index a510b201143c..e1fb7567fdcc 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -722,35 +722,43 @@ static int snd_miro_mixer(struct snd_card *card,
}
for (idx = 0; idx < ARRAY_SIZE(snd_miro_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro));
+ if (err < 0)
return err;
}
if ((miro->aci->aci_product == 'A') ||
(miro->aci->aci_product == 'B')) {
/* PCM1/PCM12 with power-amp and Line 2 */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro));
+ if (err < 0)
return err;
}
if ((miro->aci->aci_product == 'B') ||
(miro->aci->aci_product == 'C')) {
/* PCM12/PCM20 with mic-preamp */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro));
+ if (err < 0)
return err;
- if (miro->aci->aci_version >= 176)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
+ if (miro->aci->aci_version >= 176) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro));
+ if (err < 0)
return err;
+ }
}
if (miro->aci->aci_product == 'C') {
/* PCM20 with radio and 7 band equalizer */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro));
+ if (err < 0)
return err;
for (idx = 0; idx < ARRAY_SIZE(snd_miro_eq_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro));
+ if (err < 0)
return err;
}
}
@@ -1178,7 +1186,8 @@ static int snd_card_miro_detect(struct snd_card *card,
for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
- if ((err = snd_miro_init(chip, i)) < 0)
+ err = snd_miro_init(chip, i);
+ if (err < 0)
return err;
err = snd_miro_opti_check(chip);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 08e61d90057b..4bd1dc6707fc 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -970,32 +970,37 @@ static int snd_opti9xx_isa_probe(struct device *devptr,
#endif /* CS4231 || OPTi93X */
if (mpu_port == SNDRV_AUTO_PORT) {
- if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
+ mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
+ if (mpu_port < 0) {
snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
return -EBUSY;
}
}
if (irq == SNDRV_AUTO_IRQ) {
- if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ irq = snd_legacy_find_free_irq(possible_irqs);
+ if (irq < 0) {
snd_printk(KERN_ERR "unable to find a free IRQ\n");
return -EBUSY;
}
}
if (mpu_irq == SNDRV_AUTO_IRQ) {
- if ((mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
+ mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
+ if (mpu_irq < 0) {
snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
return -EBUSY;
}
}
if (dma1 == SNDRV_AUTO_DMA) {
- if ((dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
+ dma1 = snd_legacy_find_free_dma(possible_dma1s);
+ if (dma1 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA1\n");
return -EBUSY;
}
}
#if defined(CS4231) || defined(OPTi93X)
if (dma2 == SNDRV_AUTO_DMA) {
- if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) {
+ dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
+ if (dma2 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA2\n");
return -EBUSY;
}
@@ -1006,11 +1011,13 @@ static int snd_opti9xx_isa_probe(struct device *devptr,
if (error < 0)
return error;
- if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) {
+ error = snd_card_opti9xx_detect(card, card->private_data);
+ if (error < 0) {
snd_card_free(card);
return error;
}
- if ((error = snd_opti9xx_probe(card)) < 0) {
+ error = snd_opti9xx_probe(card);
+ if (error < 0) {
snd_card_free(card);
return error;
}
@@ -1111,7 +1118,8 @@ static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
return -ENODEV;
}
- if ((error = snd_opti9xx_init(chip, hw))) {
+ error = snd_opti9xx_init(chip, hw);
+ if (error) {
snd_card_free(card);
return error;
}
@@ -1121,7 +1129,8 @@ static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
snd_card_free(card);
return error;
}
- if ((error = snd_opti9xx_probe(card)) < 0) {
+ error = snd_opti9xx_probe(card);
+ if (error < 0) {
snd_card_free(card);
return error;
}
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 1c90421a88dc..5e4187940265 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -1020,6 +1020,7 @@ static const struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
static int
snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
{
+ struct snd_kcontrol *kctl;
int i, err = 0;
if (snd_BUG_ON(!emu || !card))
@@ -1029,10 +1030,11 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
memset(emu->controls, 0, sizeof(emu->controls));
for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
- if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) {
- emu->controls[i] = NULL;
+ kctl = snd_ctl_new1(mixer_defs[i], emu);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __error;
- }
+ emu->controls[i] = kctl;
}
return 0;
@@ -1095,9 +1097,10 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
hw->port1 = port;
hw->port2 = port + 0x400;
hw->port3 = port + 0x800;
- if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) ||
- !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) ||
- !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) {
+ hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1");
+ hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2");
+ hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3");
+ if (!hw->res_port1 || !hw->res_port2 || !hw->res_port3) {
snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
snd_emu8000_free(hw);
return -EBUSY;
@@ -1118,12 +1121,14 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
}
snd_emu8000_init_hw(hw);
- if ((err = snd_emu8000_create_mixer(card, hw)) < 0) {
+ err = snd_emu8000_create_mixer(card, hw);
+ if (err < 0) {
snd_emu8000_free(hw);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops);
+ if (err < 0) {
snd_emu8000_free(hw);
return err;
}
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 0cb94cafb4c9..8c1e7f2bfc34 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -191,7 +191,8 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
sp->v.truesize = truesize * 2; /* in bytes */
snd_emux_terminate_all(emu->emu);
- if ((rc = snd_emu8000_open_dma(emu, EMU8000_RAM_WRITE)) != 0)
+ rc = snd_emu8000_open_dma(emu, EMU8000_RAM_WRITE);
+ if (rc)
return rc;
/* Set the address to start writing at */
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 8e8257c574b0..f8d90a1e989b 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -626,7 +626,8 @@ static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
int err, i, ch;
snd_emux_terminate_all(rec->emu->emu);
- if ((err = emu8k_open_dram_for_pcm(rec->emu, rec->voices)) != 0)
+ err = emu8k_open_dram_for_pcm(rec->emu, rec->voices);
+ if (err)
return err;
rec->dram_opened = 1;
@@ -682,7 +683,8 @@ int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int inde
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm)) < 0)
+ err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
pcm->private_free = snd_emu8000_pcm_free;
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 63ef960abd25..d0f797c02841 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -332,14 +332,9 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
xdma8 = dma8[dev];
xdma16 = dma16[dev];
- if ((err = snd_sbdsp_create(card,
- port[dev],
- xirq,
- snd_sb16dsp_interrupt,
- xdma8,
- xdma16,
- SB_HW_AUTO,
- &chip)) < 0)
+ err = snd_sbdsp_create(card, port[dev], xirq, snd_sb16dsp_interrupt,
+ xdma8, xdma16, SB_HW_AUTO, &chip);
+ if (err < 0)
return err;
acard->chip = chip;
@@ -348,10 +343,14 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
return -ENODEV;
}
chip->mpu_port = mpu_port[dev];
- if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
- return err;
+ if (!is_isapnp_selected(dev)) {
+ err = snd_sb16dsp_configure(chip);
+ if (err < 0)
+ return err;
+ }
- if ((err = snd_sb16dsp_pcm(chip, 0)) < 0)
+ err = snd_sb16dsp_pcm(chip, 0);
+ if (err < 0)
return err;
strcpy(card->driver,
@@ -371,10 +370,11 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
xdma8 >= 0 ? "&" : "", xdma16);
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
- chip->mpu_port,
- MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi)) < 0)
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
+ chip->mpu_port,
+ MPU401_INFO_IRQ_HOOK, -1,
+ &chip->rmidi);
+ if (err < 0)
return err;
chip->rmidi_callback = snd_mpu401_uart_interrupt;
}
@@ -397,12 +397,14 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
#else
int seqdev = 1;
#endif
- if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0)
+ err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth);
+ if (err < 0)
return err;
}
}
- if ((err = snd_sbmixer_new(chip)) < 0)
+ err = snd_sbmixer_new(chip);
+ if (err < 0)
return err;
#ifdef CONFIG_SND_SB16_CSP
@@ -419,8 +421,9 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
#endif
#ifdef SNDRV_SBAWE_EMU8000
if (awe_port[dev] > 0) {
- if ((err = snd_emu8000_new(card, 1, awe_port[dev],
- seq_ports[dev], NULL)) < 0) {
+ err = snd_emu8000_new(card, 1, awe_port[dev],
+ seq_ports[dev], NULL);
+ if (err < 0) {
snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
return err;
@@ -435,7 +438,8 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
(mic_agc[dev] ? 0x00 : 0x01));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
return err;
return 0;
@@ -484,7 +488,8 @@ static int snd_sb16_isa_probe1(int dev, struct device *pdev)
awe_port[dev] = port[dev] + 0x400;
#endif
- if ((err = snd_sb16_probe(card, dev)) < 0) {
+ err = snd_sb16_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -506,19 +511,22 @@ static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
static const int possible_dmas16[] = {5, 6, 7, -1};
if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+ irq[dev] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
return -EBUSY;
}
}
if (dma8[dev] == SNDRV_AUTO_DMA) {
- if ((dma8[dev] = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
+ dma8[dev] = snd_legacy_find_free_dma(possible_dmas8);
+ if (dma8[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
return -EBUSY;
}
}
if (dma16[dev] == SNDRV_AUTO_DMA) {
- if ((dma16[dev] = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
+ dma16[dev] = snd_legacy_find_free_dma(possible_dmas16);
+ if (dma16[dev] < 0) {
snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
return -EBUSY;
}
@@ -591,8 +599,13 @@ static int snd_sb16_pnp_detect(struct pnp_card_link *pcard,
res = snd_sb16_card_new(&pcard->card->dev, dev, &card);
if (res < 0)
return res;
- if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 ||
- (res = snd_sb16_probe(card, dev)) < 0) {
+ res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid);
+ if (res < 0) {
+ snd_card_free(card);
+ return res;
+ }
+ res = snd_sb16_probe(card, dev);
+ if (res < 0) {
snd_card_free(card);
return res;
}
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 4789345a8fdd..5bbe6695689d 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -112,10 +112,12 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
if (csp_detect(chip, &version))
return -ENODEV;
- if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0)
+ err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw);
+ if (err < 0)
return err;
- if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p) {
snd_device_free(chip->card, hw);
return -ENOMEM;
}
@@ -1034,6 +1036,7 @@ static const struct snd_kcontrol_new snd_sb_qsound_space = {
static int snd_sb_qsound_build(struct snd_sb_csp * p)
{
struct snd_card *card;
+ struct snd_kcontrol *kctl;
int err;
if (snd_BUG_ON(!p))
@@ -1045,14 +1048,16 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p)
spin_lock_init(&p->q_lock);
- if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) {
- p->qsound_switch = NULL;
+ kctl = snd_ctl_new1(&snd_sb_qsound_switch, p);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __error;
- }
- if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) {
- p->qsound_space = NULL;
+ p->qsound_switch = kctl;
+ kctl = snd_ctl_new1(&snd_sb_qsound_space, p);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __error;
- }
+ p->qsound_space = kctl;
return 0;
@@ -1072,10 +1077,14 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
card = p->chip->card;
down_write(&card->controls_rwsem);
- if (p->qsound_switch)
+ if (p->qsound_switch) {
snd_ctl_remove(card, p->qsound_switch);
- if (p->qsound_space)
+ p->qsound_switch = NULL;
+ }
+ if (p->qsound_space) {
snd_ctl_remove(card, p->qsound_space);
+ p->qsound_space = NULL;
+ }
up_write(&card->controls_rwsem);
/* cancel pending transfer of QSound parameters */
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index aa4870531023..a9b87e159b2d 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -703,7 +703,8 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct
unsigned char nval, oval;
int change;
- if ((nval = ucontrol->value.enumerated.item[0]) > 2)
+ 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);
@@ -836,7 +837,8 @@ int snd_sb16dsp_pcm(struct snd_sb *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm);
+ if (err < 0)
return err;
sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index ed3a87ebe3f4..b08e6e7690c9 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -101,12 +101,10 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
if (port[dev] != SNDRV_AUTO_PORT) {
- if ((err = snd_sbdsp_create(card, port[dev], irq[dev],
- snd_sb8_interrupt,
- dma8[dev],
- -1,
- SB_HW_AUTO,
- &chip)) < 0)
+ err = snd_sbdsp_create(card, port[dev], irq[dev],
+ snd_sb8_interrupt, dma8[dev],
+ -1, SB_HW_AUTO, &chip);
+ if (err < 0)
goto _err;
} else {
/* auto-probe legacy ports */
@@ -145,32 +143,35 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
goto _err;
}
- if ((err = snd_sb8dsp_pcm(chip, 0)) < 0)
+ err = snd_sb8dsp_pcm(chip, 0);
+ if (err < 0)
goto _err;
- if ((err = snd_sbmixer_new(chip)) < 0)
+ err = snd_sbmixer_new(chip);
+ if (err < 0)
goto _err;
if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
- if ((err = snd_opl3_create(card, chip->port + 8, 0,
- OPL3_HW_AUTO, 1,
- &opl3)) < 0) {
+ err = snd_opl3_create(card, chip->port + 8, 0,
+ OPL3_HW_AUTO, 1, &opl3);
+ if (err < 0)
snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
- }
} else {
- if ((err = snd_opl3_create(card, chip->port, chip->port + 2,
- OPL3_HW_AUTO, 1,
- &opl3)) < 0) {
+ err = snd_opl3_create(card, chip->port, chip->port + 2,
+ OPL3_HW_AUTO, 1, &opl3);
+ if (err < 0) {
snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
chip->port, chip->port + 2);
}
}
if (err >= 0) {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0)
goto _err;
}
- if ((err = snd_sb8dsp_midi(chip, 0)) < 0)
+ err = snd_sb8dsp_midi(chip, 0);
+ if (err < 0)
goto _err;
strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
@@ -180,7 +181,8 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
chip->port,
irq[dev], dma8[dev]);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto _err;
dev_set_drvdata(pdev, card);
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 8d01692c4f2a..2ed176a5a574 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -567,7 +567,8 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device)
int err;
size_t max_prealloc = 64 * 1024;
- if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm);
+ if (err < 0)
return err;
sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index 8c01460539ed..618366d5d984 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -251,7 +251,8 @@ int snd_sb8dsp_midi(struct snd_sb *chip, int device)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, "SB8 MIDI");
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_sb8dsp_midi_output);
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 61ea4078aa95..57121218ed24 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -238,7 +238,8 @@ int snd_sbdsp_create(struct snd_card *card,
if (hardware == SB_HW_ALS4000)
goto __skip_allocation;
- if ((chip->res_port = request_region(port, 16, "SoundBlaster")) == NULL) {
+ chip->res_port = request_region(port, 16, "SoundBlaster");
+ if (!chip->res_port) {
snd_printk(KERN_ERR "sb: can't grab port 0x%lx\n", port);
snd_sbdsp_free(chip);
return -EBUSY;
@@ -267,11 +268,13 @@ int snd_sbdsp_create(struct snd_card *card,
__skip_allocation:
chip->card = card;
chip->hardware = hardware;
- if ((err = snd_sbdsp_probe(chip)) < 0) {
+ err = snd_sbdsp_probe(chip);
+ if (err < 0) {
snd_sbdsp_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_sbdsp_free(chip);
return err;
}
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 5de5506e7e60..fffd681e5bf7 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -485,7 +485,8 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty
strscpy(ctl->id.name, name, sizeof(ctl->id.name));
ctl->id.index = index;
ctl->private_value = value;
- if ((err = snd_ctl_add(chip->card, ctl)) < 0)
+ err = snd_ctl_add(chip->card, ctl);
+ if (err < 0)
return err;
return 0;
}
@@ -736,33 +737,36 @@ int snd_sbmixer_new(struct snd_sb *chip)
return 0; /* no mixer chip on SB1.x */
case SB_HW_20:
case SB_HW_201:
- if ((err = snd_sbmixer_init(chip,
- snd_sb20_controls,
- ARRAY_SIZE(snd_sb20_controls),
- snd_sb20_init_values,
- ARRAY_SIZE(snd_sb20_init_values),
- "CTL1335")) < 0)
+ err = snd_sbmixer_init(chip,
+ snd_sb20_controls,
+ ARRAY_SIZE(snd_sb20_controls),
+ snd_sb20_init_values,
+ ARRAY_SIZE(snd_sb20_init_values),
+ "CTL1335");
+ if (err < 0)
return err;
break;
case SB_HW_PRO:
case SB_HW_JAZZ16:
- if ((err = snd_sbmixer_init(chip,
- snd_sbpro_controls,
- ARRAY_SIZE(snd_sbpro_controls),
- snd_sbpro_init_values,
- ARRAY_SIZE(snd_sbpro_init_values),
- "CTL1345")) < 0)
+ err = snd_sbmixer_init(chip,
+ snd_sbpro_controls,
+ ARRAY_SIZE(snd_sbpro_controls),
+ snd_sbpro_init_values,
+ ARRAY_SIZE(snd_sbpro_init_values),
+ "CTL1345");
+ if (err < 0)
return err;
break;
case SB_HW_16:
case SB_HW_ALS100:
case SB_HW_CS5530:
- if ((err = snd_sbmixer_init(chip,
- snd_sb16_controls,
- ARRAY_SIZE(snd_sb16_controls),
- snd_sb16_init_values,
- ARRAY_SIZE(snd_sb16_init_values),
- "CTL1745")) < 0)
+ err = snd_sbmixer_init(chip,
+ snd_sb16_controls,
+ ARRAY_SIZE(snd_sb16_controls),
+ snd_sb16_init_values,
+ ARRAY_SIZE(snd_sb16_init_values),
+ "CTL1745");
+ if (err < 0)
return err;
break;
case SB_HW_ALS4000:
@@ -775,12 +779,13 @@ int snd_sbmixer_new(struct snd_sb *chip)
"ALS4000");
if (err < 0)
return err;
- if ((err = snd_sbmixer_init(chip,
- snd_als4000_controls,
- ARRAY_SIZE(snd_als4000_controls),
- snd_als4000_init_values,
- ARRAY_SIZE(snd_als4000_init_values),
- "ALS4000")) < 0)
+ err = snd_sbmixer_init(chip,
+ snd_als4000_controls,
+ ARRAY_SIZE(snd_als4000_controls),
+ snd_als4000_init_values,
+ ARRAY_SIZE(snd_als4000_init_values),
+ "ALS4000");
+ if (err < 0)
return err;
break;
case SB_HW_DT019X:
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index a4437971df2f..dfdeaf7b6bf4 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -555,7 +555,8 @@ static int snd_wavefront_isa_probe(struct device *pdev,
err = snd_wavefront_card_new(pdev, dev, &card);
if (err < 0)
return err;
- if ((err = snd_wavefront_probe(card, dev)) < 0) {
+ err = snd_wavefront_probe(card, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -610,7 +611,8 @@ static int snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
}
}
- if ((res = snd_wavefront_probe(card, dev)) < 0)
+ res = snd_wavefront_probe(card, dev);
+ if (res < 0)
return res;
pnp_set_card_drvdata(pcard, card);
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c
index a337a86f7a65..72e775ac7ad7 100644
--- a/sound/isa/wavefront/wavefront_midi.c
+++ b/sound/isa/wavefront/wavefront_midi.c
@@ -239,7 +239,8 @@ static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL)
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return -EIO;
spin_lock_irqsave (&midi->open, flags);
@@ -263,7 +264,8 @@ static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substrea
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL)
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return -EIO;
spin_lock_irqsave (&midi->open, flags);
@@ -287,7 +289,8 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL)
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return -EIO;
spin_lock_irqsave (&midi->open, flags);
@@ -310,7 +313,8 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL)
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return -EIO;
spin_lock_irqsave (&midi->open, flags);
@@ -333,9 +337,9 @@ static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *subst
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL) {
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return;
- }
spin_lock_irqsave (&midi->virtual, flags);
if (up) {
@@ -372,9 +376,9 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs
mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
- if ((midi = get_wavefront_midi (substream)) == NULL) {
+ midi = get_wavefront_midi(substream);
+ if (!midi)
return;
- }
spin_lock_irqsave (&midi->virtual, flags);
if (up) {
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index d6420d224d09..69cbc79fbb71 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -339,7 +339,8 @@ snd_wavefront_cmd (snd_wavefront_t *dev,
int c;
struct wavefront_command *wfcmd;
- if ((wfcmd = wavefront_get_command (cmd)) == NULL) {
+ wfcmd = wavefront_get_command(cmd);
+ if (!wfcmd) {
snd_printk ("command 0x%x not supported.\n",
cmd);
return 1;
@@ -391,7 +392,8 @@ snd_wavefront_cmd (snd_wavefront_t *dev,
for (i = 0; i < wfcmd->read_cnt; i++) {
- if ((c = wavefront_read (dev)) == -1) {
+ c = wavefront_read(dev);
+ if (c == -1) {
DPRINT (WF_DEBUG_IO, "bad read for byte "
"%d of 0x%x [%s].\n",
i, cmd, wfcmd->action);
@@ -401,7 +403,8 @@ snd_wavefront_cmd (snd_wavefront_t *dev,
/* Now handle errors. Lots of special cases here */
if (c == 0xff) {
- if ((c = wavefront_read (dev)) == -1) {
+ c = wavefront_read(dev);
+ if (c == -1) {
DPRINT (WF_DEBUG_IO, "bad read for "
"error byte at "
"read byte %d "
@@ -459,9 +462,9 @@ snd_wavefront_cmd (snd_wavefront_t *dev,
of the standard value.
*/
- if ((ack = wavefront_read (dev)) == 0) {
+ ack = wavefront_read(dev);
+ if (ack == 0)
ack = WF_ACK;
- }
if (ack != WF_ACK) {
if (ack == -1) {
@@ -475,7 +478,8 @@ snd_wavefront_cmd (snd_wavefront_t *dev,
if (ack == 0xff) { /* explicit error */
- if ((err = wavefront_read (dev)) == -1) {
+ err = wavefront_read(dev);
+ if (err == -1) {
DPRINT (WF_DEBUG_DATA,
"cannot read err "
"for 0x%x [%s].\n",
@@ -603,9 +607,9 @@ wavefront_delete_sample (snd_wavefront_t *dev, int sample_num)
wbuf[0] = sample_num & 0x7f;
wbuf[1] = sample_num >> 7;
- if ((x = snd_wavefront_cmd (dev, WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
+ x = snd_wavefront_cmd(dev, WFC_DELETE_SAMPLE, NULL, wbuf);
+ if (!x)
dev->sample_status[sample_num] = WF_ST_EMPTY;
- }
return x;
}
@@ -691,8 +695,9 @@ wavefront_get_patch_status (snd_wavefront_t *dev)
patchnum[0] = i & 0x7f;
patchnum[1] = i >> 7;
- if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PATCH, patchbuf,
- patchnum)) == 0) {
+ x = snd_wavefront_cmd(dev, WFC_UPLOAD_PATCH, patchbuf,
+ patchnum);
+ if (x == 0) {
dev->patch_status[i] |= WF_SLOT_FILLED;
p = (wavefront_patch *) patchbuf;
@@ -738,8 +743,9 @@ wavefront_get_program_status (snd_wavefront_t *dev)
for (i = 0; i < WF_MAX_PROGRAM; i++) {
prognum = i;
- if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PROGRAM, progbuf,
- &prognum)) == 0) {
+ x = snd_wavefront_cmd(dev, WFC_UPLOAD_PROGRAM, progbuf,
+ &prognum);
+ if (x == 0) {
dev->prog_status[i] |= WF_SLOT_USED;
@@ -894,9 +900,9 @@ wavefront_send_sample (snd_wavefront_t *dev,
if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
int x;
- if ((x = wavefront_find_free_sample (dev)) < 0) {
+ x = wavefront_find_free_sample(dev);
+ if (x < 0)
return -ENOMEM;
- }
snd_printk ("unspecified sample => %d\n", x);
header->number = x;
}
@@ -1137,7 +1143,8 @@ wavefront_send_sample (snd_wavefront_t *dev,
nothing to do with DMA at all.
*/
- if ((dma_ack = wavefront_read (dev)) != WF_DMA_ACK) {
+ dma_ack = wavefront_read(dev);
+ if (dma_ack != WF_DMA_ACK) {
if (dma_ack == -1) {
snd_printk ("upload sample "
"DMA ack timeout\n");
@@ -1282,14 +1289,16 @@ wavefront_fetch_multisample (snd_wavefront_t *dev,
char d[2];
int val;
- if ((val = wavefront_read (dev)) == -1) {
+ val = wavefront_read(dev);
+ if (val == -1) {
snd_printk ("upload multisample failed "
"during sample loop.\n");
return -EIO;
}
d[0] = val;
- if ((val = wavefront_read (dev)) == -1) {
+ val = wavefront_read(dev);
+ if (val == -1) {
snd_printk ("upload multisample failed "
"during sample loop.\n");
return -EIO;
@@ -1910,7 +1919,8 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
goto gone_bad;
}
- if ((hwv[0] = wavefront_read (dev)) == -1) {
+ hwv[0] = wavefront_read(dev);
+ if (hwv[0] == -1) {
snd_printk ("board not responding correctly.\n");
goto gone_bad;
}
@@ -1921,7 +1931,8 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
and tell us about it either way.
*/
- if ((hwv[0] = wavefront_read (dev)) == -1) {
+ hwv[0] = wavefront_read(dev);
+ if (hwv[0] == -1) {
snd_printk ("on-board RAM test failed "
"(bad error code).\n");
} else {
@@ -1934,7 +1945,8 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
/* We're OK, just get the next byte of the HW version response */
- if ((hwv[1] = wavefront_read (dev)) == -1) {
+ hwv[1] = wavefront_read(dev);
+ if (hwv[1] == -1) {
snd_printk ("incorrect h/w response.\n");
goto gone_bad;
}
@@ -2079,9 +2091,9 @@ wavefront_do_reset (snd_wavefront_t *dev)
about it.
*/
- if ((dev->freemem = wavefront_freemem (dev)) < 0) {
+ dev->freemem = wavefront_freemem(dev);
+ if (dev->freemem < 0)
goto gone_bad;
- }
snd_printk ("available DRAM %dk\n", dev->freemem / 1024);
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index ea5d3cdfe4e4..743e0f05e335 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1493,7 +1493,8 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream)
snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
if (chip->claim_dma) {
- if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
+ err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1);
+ if (err < 0)
return err;
}
@@ -1533,7 +1534,8 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream)
snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
if (chip->claim_dma) {
- if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
+ err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2);
+ if (err < 0)
return err;
}
@@ -1934,7 +1936,8 @@ int snd_wss_timer(struct snd_wss *chip, int device)
tid.card = chip->card->number;
tid.device = device;
tid.subdevice = 0;
- if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
+ err = snd_timer_new(chip->card, "CS4231", &tid, &timer);
+ if (err < 0)
return err;
strcpy(timer->name, snd_wss_chip_id(chip));
timer->private_data = chip;
diff --git a/sound/mips/snd-n64.c b/sound/mips/snd-n64.c
index e35e93157755..463a6fe589eb 100644
--- a/sound/mips/snd-n64.c
+++ b/sound/mips/snd-n64.c
@@ -338,6 +338,10 @@ static int __init n64audio_probe(struct platform_device *pdev)
strcpy(card->longname, "N64 Audio");
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ err = -EINVAL;
+ goto fail_dma_alloc;
+ }
if (devm_request_irq(&pdev->dev, res->start, n64audio_isr,
IRQF_SHARED, "N64 Audio", priv)) {
err = -EBUSY;
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 49679aa8631d..0c95828ac0b1 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -999,11 +999,9 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
case SNDCTL_DSP_RESET:
sq_reset();
return 0;
- break ;
case SNDCTL_DSP_GETFMTS:
fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */
return IOCTL_OUT(arg, fmt);
- break ;
case SNDCTL_DSP_GETBLKSIZE:
/* this should tell the caller about bytes that the app can
read/write - the app doesn't care about our internal buffers.
@@ -1020,7 +1018,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
size = write_sq.user_frag_size ;
}
return IOCTL_OUT(arg, size);
- break ;
case SNDCTL_DSP_POST:
/* all we are going to do is to tell the LL that any
partial frags can be queued for output.
@@ -1044,7 +1041,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
if (file->f_mode & shared_resource_owner)
shared_resources_initialised = 0 ;
return result ;
- break ;
case SOUND_PCM_READ_RATE:
return IOCTL_OUT(arg, dmasound.soft.speed);
case SNDCTL_DSP_SPEED:
@@ -1123,7 +1119,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
the value is 'random' and that the user _must_ check the actual
frags values using SNDCTL_DSP_GETBLKSIZE or similar */
return IOCTL_OUT(arg, data);
- break ;
case SNDCTL_DSP_GETOSPACE:
/*
*/
@@ -1234,31 +1229,22 @@ static char *get_afmt_string(int afmt)
switch(afmt) {
case AFMT_MU_LAW:
return "mu-law";
- break;
case AFMT_A_LAW:
return "A-law";
- break;
case AFMT_U8:
return "unsigned 8 bit";
- break;
case AFMT_S8:
return "signed 8 bit";
- break;
case AFMT_S16_BE:
return "signed 16 bit BE";
- break;
case AFMT_U16_BE:
return "unsigned 16 bit BE";
- break;
case AFMT_S16_LE:
return "signed 16 bit LE";
- break;
case AFMT_U16_LE:
return "unsigned 16 bit LE";
- break;
case 0:
return "format not set" ;
- break ;
default:
break ;
}
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index f2ca0a701987..1440db8b4177 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -915,10 +915,9 @@ snd_harmony_create(struct snd_card *card,
spin_lock_init(&h->mixer_lock);
spin_lock_init(&h->lock);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- h, &ops)) < 0) {
- goto free_and_ret;
- }
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, h, &ops);
+ if (err < 0)
+ goto free_and_ret;
*rchip = h;
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 012a7ee849e8..01f296d524ce 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1286,15 +1286,17 @@ static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx,
if (snd_ac97_try_bit(ac97, reg, 15)) {
sprintf(name, "%s Switch", pfx);
- if ((err = snd_ac97_cmute_new_stereo(card, name, reg,
- check_stereo, check_amix,
- ac97)) < 0)
+ err = snd_ac97_cmute_new_stereo(card, name, reg,
+ check_stereo, check_amix,
+ ac97);
+ if (err < 0)
return err;
}
check_volume_resolution(ac97, reg, &lo_max, &hi_max);
if (lo_max) {
sprintf(name, "%s Volume", pfx);
- if ((err = snd_ac97_cvol_new(card, name, reg, lo_max, hi_max, ac97)) < 0)
+ err = snd_ac97_cvol_new(card, name, reg, lo_max, hi_max, ac97);
+ if (err < 0)
return err;
}
return 0;
@@ -1333,9 +1335,11 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build center controls */
if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
&& !(ac97->flags & AC97_AD_MULTI)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0)
+ err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97));
+ if (err < 0)
return err;
snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 0, &max);
kctl->private_value &= ~(0xff << 16);
@@ -1347,9 +1351,11 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build LFE controls */
if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1))
&& !(ac97->flags & AC97_AD_MULTI)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0)
+ err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97));
+ if (err < 0)
return err;
snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 8, &max);
kctl->private_value &= ~(0xff << 16);
@@ -1362,23 +1368,26 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
if ((snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER))
&& !(ac97->flags & AC97_AD_MULTI)) {
/* Surround Master (0x38) is with stereo mutes */
- if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback",
- AC97_SURROUND_MASTER, 1, 0,
- ac97)) < 0)
+ err = snd_ac97_cmix_new_stereo(card, "Surround Playback",
+ AC97_SURROUND_MASTER, 1, 0,
+ ac97);
+ if (err < 0)
return err;
}
/* build headphone controls */
if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
- if ((err = snd_ac97_cmix_new(card, "Headphone Playback",
- AC97_HEADPHONE, 0, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Headphone Playback",
+ AC97_HEADPHONE, 0, ac97);
+ if (err < 0)
return err;
}
/* build master mono controls */
if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) {
- if ((err = snd_ac97_cmix_new(card, "Master Mono Playback",
- AC97_MASTER_MONO, 0, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Master Mono Playback",
+ AC97_MASTER_MONO, 0, ac97);
+ if (err < 0)
return err;
}
@@ -1386,7 +1395,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
if (!(ac97->flags & AC97_HAS_NO_TONE)) {
if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) {
for (idx = 0; idx < 2; idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (ac97->id == AC97_ID_YMF743 ||
ac97->id == AC97_ID_YMF753) {
@@ -1402,9 +1413,12 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) &&
((ac97->flags & AC97_HAS_PC_BEEP) ||
snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_4bit);
snd_ac97_write_cache(
ac97,
@@ -1417,8 +1431,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build Phone controls */
if (!(ac97->flags & AC97_HAS_NO_PHONE)) {
if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) {
- if ((err = snd_ac97_cmix_new(card, "Phone Playback",
- AC97_PHONE, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Phone Playback",
+ AC97_PHONE, 1, ac97);
+ if (err < 0)
return err;
}
}
@@ -1426,26 +1441,30 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build MIC controls */
if (!(ac97->flags & AC97_HAS_NO_MIC)) {
if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) {
- if ((err = snd_ac97_cmix_new(card, "Mic Playback",
- AC97_MIC, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Mic Playback",
+ AC97_MIC, 1, ac97);
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97));
+ if (err < 0)
return err;
}
}
/* build Line controls */
if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) {
- if ((err = snd_ac97_cmix_new(card, "Line Playback",
- AC97_LINE, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Line Playback",
+ AC97_LINE, 1, ac97);
+ if (err < 0)
return err;
}
/* build CD controls */
if (!(ac97->flags & AC97_HAS_NO_CD)) {
if (snd_ac97_try_volume_mix(ac97, AC97_CD)) {
- if ((err = snd_ac97_cmix_new(card, "CD Playback",
- AC97_CD, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "CD Playback",
+ AC97_CD, 1, ac97);
+ if (err < 0)
return err;
}
}
@@ -1453,8 +1472,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build Video controls */
if (!(ac97->flags & AC97_HAS_NO_VIDEO)) {
if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) {
- if ((err = snd_ac97_cmix_new(card, "Video Playback",
- AC97_VIDEO, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Video Playback",
+ AC97_VIDEO, 1, ac97);
+ if (err < 0)
return err;
}
}
@@ -1462,8 +1482,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build Aux controls */
if (!(ac97->flags & AC97_HAS_NO_AUX)) {
if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
- if ((err = snd_ac97_cmix_new(card, "Aux Playback",
- AC97_AUX, 1, ac97)) < 0)
+ err = snd_ac97_cmix_new(card, "Aux Playback",
+ AC97_AUX, 1, ac97);
+ if (err < 0)
return err;
}
}
@@ -1475,26 +1496,38 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
init_val = 0x9f9f;
else
init_val = 0x9f1f;
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_5bit);
ac97->spec.ad18xx.pcmreg[0] = init_val;
if (ac97->scaps & AC97_SCAP_SURROUND_DAC) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_5bit);
ac97->spec.ad18xx.pcmreg[1] = init_val;
}
if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_5bit);
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_5bit);
ac97->spec.ad18xx.pcmreg[2] = init_val;
}
@@ -1515,7 +1548,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
/* build Capture controls */
if (!(ac97->flags & AC97_HAS_NO_REC_GAIN)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_src, ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_src, ac97));
+ if (err < 0)
return err;
if (snd_ac97_try_bit(ac97, AC97_REC_GAIN, 15)) {
err = snd_ac97_cmute_new(card, "Capture Switch",
@@ -1523,7 +1557,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
if (err < 0)
return err;
}
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
set_tlv_db_scale(kctl, db_scale_rec_gain);
snd_ac97_write_cache(ac97, AC97_REC_SEL, 0x0000);
@@ -1531,52 +1567,62 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
}
/* build MIC Capture controls */
if (snd_ac97_try_volume_mix(ac97, AC97_REC_GAIN_MIC)) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97))) < 0)
+ for (idx = 0; idx < 2; idx++) {
+ kctl = snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
set_tlv_db_scale(kctl, db_scale_rec_gain);
snd_ac97_write_cache(ac97, AC97_REC_GAIN_MIC, 0x0000);
}
/* build PCM out path & mute control */
if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 15)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_PCM_OUT], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_PCM_OUT], ac97));
+ if (err < 0)
return err;
}
/* build Simulated Stereo Enhancement control */
if (ac97->caps & AC97_BC_SIM_STEREO) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97));
+ if (err < 0)
return err;
}
/* build 3D Stereo Enhancement control */
if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 13)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_3D], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_3D], ac97));
+ if (err < 0)
return err;
}
/* build Loudness control */
if (ac97->caps & AC97_BC_LOUDNESS) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97));
+ if (err < 0)
return err;
}
/* build Mono output select control */
if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 9)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MONO], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MONO], ac97));
+ if (err < 0)
return err;
}
/* build Mic select control */
if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 8)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MIC], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MIC], ac97));
+ if (err < 0)
return err;
}
/* build ADC/DAC loopback control */
if (enable_loopback && snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 7)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOOPBACK], ac97))) < 0)
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOOPBACK], ac97));
+ if (err < 0)
return err;
}
@@ -1592,11 +1638,15 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
snd_ac97_write(ac97, AC97_3D_CONTROL, val);
val = snd_ac97_read(ac97, AC97_3D_CONTROL);
val = val == 0x0606;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (val)
kctl->private_value = AC97_3D_CONTROL | (9 << 8) | (7 << 16);
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[1], ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_controls_3d[1], ac97);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (val)
kctl->private_value = AC97_3D_CONTROL | (1 << 8) | (7 << 16);
@@ -1613,14 +1663,18 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
if ((ac97->ext_id & AC97_EI_SPDIF) && !(ac97->scaps & AC97_SCAP_NO_SPDIF)) {
if (ac97->build_ops->build_spdif) {
- if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
+ err = ac97->build_ops->build_spdif(ac97);
+ if (err < 0)
return err;
} else {
- for (idx = 0; idx < 5; idx++)
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
+ for (idx = 0; idx < 5; idx++) {
+ err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97));
+ if (err < 0)
return err;
+ }
if (ac97->build_ops->build_post_spdif) {
- if ((err = ac97->build_ops->build_post_spdif(ac97)) < 0)
+ err = ac97->build_ops->build_post_spdif(ac97);
+ if (err < 0)
return err;
}
/* set default PCM S/PDIF params */
@@ -1632,9 +1686,11 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
}
/* build chip specific controls */
- if (ac97->build_ops->build_specific)
- if ((err = ac97->build_ops->build_specific(ac97)) < 0)
+ if (ac97->build_ops->build_specific) {
+ err = ac97->build_ops->build_specific(ac97);
+ if (err < 0)
return err;
+ }
if (snd_ac97_try_bit(ac97, AC97_POWERDOWN, 15)) {
kctl = snd_ac97_cnew(&snd_ac97_control_eapd, ac97);
@@ -1642,7 +1698,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
return -ENOMEM;
if (ac97->scaps & AC97_SCAP_INV_EAPD)
set_inv_eapd(ac97, kctl);
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
@@ -1664,14 +1721,18 @@ static int snd_ac97_modem_build(struct snd_card *card, struct snd_ac97 * ac97)
snd_ac97_write(ac97, AC97_MISC_AFE, 0x0);
/* build modem switches */
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97));
+ if (err < 0)
return err;
+ }
/* build chip specific controls */
- if (ac97->build_ops->build_specific)
- if ((err = ac97->build_ops->build_specific(ac97)) < 0)
+ if (ac97->build_ops->build_specific) {
+ err = ac97->build_ops->build_specific(ac97);
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -1916,7 +1977,8 @@ int snd_ac97_bus(struct snd_card *card, int num,
bus->clock = 48000;
spin_lock_init(&bus->bus_lock);
snd_ac97_bus_proc_init(bus);
- if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
+ if (err < 0) {
snd_ac97_bus_free(bus);
return err;
}
@@ -1944,7 +2006,8 @@ static int snd_ac97_dev_register(struct snd_device *device)
dev_set_name(&ac97->dev, "%d-%d:%s",
ac97->bus->card->number, ac97->num,
snd_ac97_get_short_name(ac97));
- if ((err = device_register(&ac97->dev)) < 0) {
+ err = device_register(&ac97->dev);
+ if (err < 0) {
ac97_err(ac97, "Can't register ac97 bus\n");
ac97->dev.bus = NULL;
return err;
@@ -2095,7 +2158,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO) && !(ac97->scaps & AC97_SCAP_AUDIO)) {
/* test if we can write to the record gain volume register */
snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a06);
- if (((err = snd_ac97_read(ac97, AC97_REC_GAIN)) & 0x7fff) == 0x0a06)
+ err = snd_ac97_read(ac97, AC97_REC_GAIN);
+ if ((err & 0x7fff) == 0x0a06)
ac97->scaps |= AC97_SCAP_AUDIO;
}
if (ac97->scaps & AC97_SCAP_AUDIO) {
@@ -2248,7 +2312,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
}
}
sprintf(comp, "AC97a:%08x", ac97->id);
- if ((err = snd_component_add(card, comp)) < 0) {
+ err = snd_component_add(card, comp);
+ if (err < 0) {
snd_ac97_free(ac97);
return err;
}
@@ -2268,7 +2333,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
}
}
sprintf(comp, "AC97m:%08x", ac97->id);
- if ((err = snd_component_add(card, comp)) < 0) {
+ err = snd_component_add(card, comp);
+ if (err < 0) {
snd_ac97_free(ac97);
return err;
}
@@ -2280,7 +2346,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
if (ac97_is_audio(ac97))
update_power_regs(ac97);
snd_ac97_proc_init(ac97);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops);
+ if (err < 0) {
snd_ac97_free(ac97);
return err;
}
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 1627a74baf3c..025c1666c1fc 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -29,9 +29,11 @@ static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontro
{
int idx, err;
- for (idx = 0; idx < count; idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97))) < 0)
+ for (idx = 0; idx < count; idx++) {
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97));
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -416,7 +418,8 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif));
+ if (err < 0)
return err;
return 0;
}
@@ -461,7 +464,8 @@ static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
int err, i;
for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97));
+ if (err < 0)
return err;
}
snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
@@ -491,7 +495,8 @@ static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
{
int err, i;
for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97));
+ if (err < 0)
return err;
}
/* patch for DVD noise */
@@ -631,7 +636,8 @@ static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
int err, i;
for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97));
+ if (err < 0)
return err;
}
snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808);
@@ -798,7 +804,8 @@ static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97)
int err, i;
for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97));
+ if (err < 0)
return err;
}
return 0;
@@ -809,7 +816,8 @@ static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97)
int err, i;
for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97));
+ if (err < 0)
return err;
}
snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
@@ -883,7 +891,8 @@ static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97)
struct snd_kcontrol *kctl;
int err;
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
+ err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97));
+ if (err < 0)
return err;
strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
@@ -896,11 +905,15 @@ static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
struct snd_kcontrol *kctl;
int err;
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
+ err = snd_ctl_add(ac97->bus->card, kctl);
+ if (err < 0)
return err;
strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
+ kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
+ err = snd_ctl_add(ac97->bus->card, kctl);
+ if (err < 0)
return err;
strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
@@ -927,18 +940,26 @@ static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
int err;
snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003);
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1)) < 0)
+ if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1)) {
+ err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1);
+ if (err < 0)
return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1)) < 0)
+ }
+ if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0)) {
+ err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1);
+ if (err < 0)
return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1)) < 0)
+ }
+ if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2)) {
+ err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1);
+ if (err < 0)
return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1)) < 0)
+ }
+ if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3)) {
+ err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1);
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -984,7 +1005,8 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
- if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1);
+ if (err < 0)
return err;
return patch_sigmatel_stac97xx_specific(ac97);
}
@@ -1262,14 +1284,17 @@ static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
int err;
/* con mask, pro mask, default */
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
+ if (err < 0)
return err;
/* switch, spsa */
- if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1);
+ if (err < 0)
return err;
switch (ac97->id & AC97_ID_CS_MASK) {
case AC97_ID_CS4205:
- if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1);
+ if (err < 0)
return err;
break;
}
@@ -1324,10 +1349,12 @@ static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
int err;
/* con mask, pro mask, default */
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
+ if (err < 0)
return err;
/* switch */
- if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1);
+ if (err < 0)
return err;
/* set default PCM S/PDIF params */
/* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
@@ -1592,7 +1619,8 @@ static int patch_ad1885_specific(struct snd_ac97 * ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885));
+ if (err < 0)
return err;
reset_tlv(ac97, "Headphone Playback Volume",
db_scale_6bit_6db_max);
@@ -1875,7 +1903,8 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97)
{
int err;
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
+ if (err < 0)
return err;
if (check_list(ac97, ad1981_jacks_denylist))
return 0;
@@ -2060,7 +2089,8 @@ static int patch_ad1980_specific(struct snd_ac97 *ac97)
{
int err;
- if ((err = patch_ad1888_specific(ac97)) < 0)
+ err = patch_ad1888_specific(ac97);
+ if (err < 0)
return err;
return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
}
@@ -2168,7 +2198,8 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
"Master Surround Playback");
snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
+ if (err < 0)
return err;
return patch_build_controls(ac97, snd_ac97_ad1985_controls,
@@ -2460,7 +2491,8 @@ static int patch_ad1986_specific(struct snd_ac97 *ac97)
{
int err;
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
+ err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
+ if (err < 0)
return err;
return patch_build_controls(ac97, snd_ac97_ad1986_controls,
@@ -2582,10 +2614,12 @@ static int patch_alc650_specific(struct snd_ac97 * ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650));
+ if (err < 0)
return err;
if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650));
+ if (err < 0)
return err;
}
if (ac97->id != AC97_ID_ALC650F)
@@ -2735,10 +2769,12 @@ static int patch_alc655_specific(struct snd_ac97 * ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655));
+ if (err < 0)
return err;
if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655));
+ if (err < 0)
return err;
}
return 0;
@@ -2847,10 +2883,12 @@ static int patch_alc850_specific(struct snd_ac97 *ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850));
+ if (err < 0)
return err;
if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655));
+ if (err < 0)
return err;
}
return 0;
@@ -3437,10 +3475,13 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
struct snd_kcontrol *kctl;
int err;
- if (snd_ac97_try_bit(ac97, 0x5a, 9))
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1)) < 0)
+ if (snd_ac97_try_bit(ac97, 0x5a, 9)) {
+ err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1);
+ if (err < 0)
return err;
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
+ }
+ err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1);
+ if (err < 0)
return err;
/* There is already a misnamed master switch. Rename it. */
@@ -3810,9 +3851,11 @@ static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = {
static int patch_it2646_specific(struct snd_ac97 * ac97)
{
int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646));
+ if (err < 0)
return err;
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646))) < 0)
+ err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646));
+ if (err < 0)
return err;
return 0;
}
@@ -3845,9 +3888,11 @@ AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
static int patch_si3036_specific(struct snd_ac97 * ac97)
{
int idx, err;
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++) {
+ err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97));
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -3912,9 +3957,11 @@ AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
static int patch_ucb1400_specific(struct snd_ac97 * ac97)
{
int idx, err;
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++) {
+ err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97));
+ if (err < 0)
return err;
+ }
return 0;
}
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 4520022801d9..5c78951dd596 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -852,7 +852,8 @@ snd_ad1889_create(struct snd_card *card,
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check PCI availability (32bit DMA) */
@@ -863,7 +864,8 @@ snd_ad1889_create(struct snd_card *card,
}
/* allocate chip specific data with zero-filled memory */
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -874,7 +876,8 @@ snd_ad1889_create(struct snd_card *card,
chip->irq = -1;
/* (1) PCI resource allocation */
- if ((err = pci_request_regions(pci, card->driver)) < 0)
+ err = pci_request_regions(pci, card->driver);
+ if (err < 0)
goto free_and_ret;
chip->bar = pci_resource_start(pci, 0);
@@ -900,12 +903,14 @@ snd_ad1889_create(struct snd_card *card,
card->sync_irq = chip->irq;
/* (2) initialization of the chip hardware */
- if ((err = snd_ad1889_init(chip)) < 0) {
+ err = snd_ad1889_init(chip);
+ if (err < 0) {
snd_ad1889_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_ad1889_free(chip);
return err;
}
diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c
index e0a81f99f79a..6af88e7b86f8 100644
--- a/sound/pci/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -384,7 +384,8 @@ int snd_ak4531_mixer(struct snd_card *card,
return -ENOMEM;
*ak4531 = *_ak4531;
mutex_init(&ak4531->reg_mutex);
- if ((err = snd_component_add(card, "AK4531")) < 0) {
+ err = snd_component_add(card, "AK4531");
+ if (err < 0) {
snd_ak4531_free(ak4531);
return err;
}
@@ -398,13 +399,15 @@ int snd_ak4531_mixer(struct snd_card *card,
ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]); /* recording source is mixer */
}
for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531));
+ if (err < 0) {
snd_ak4531_free(ak4531);
return err;
}
}
snd_ak4531_proc_init(card, ak4531);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops);
+ if (err < 0) {
snd_ak4531_free(ak4531);
return err;
}
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index bd4fd09e982b..668008fc21f7 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -298,7 +298,8 @@ static int snd_als300_ac97(struct snd_als300 *chip)
.read = snd_als300_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
@@ -621,7 +622,8 @@ static int snd_als300_create(struct snd_card *card,
};
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) {
@@ -643,7 +645,8 @@ static int snd_als300_create(struct snd_card *card,
chip->chip_type = chip_type;
spin_lock_init(&chip->reg_lock);
- if ((err = pci_request_regions(pci, "ALS300")) < 0) {
+ err = pci_request_regions(pci, "ALS300");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -673,14 +676,15 @@ static int snd_als300_create(struct snd_card *card,
return err;
}
- if ((err = snd_als300_new_pcm(chip)) < 0) {
+ err = snd_als300_new_pcm(chip);
+ if (err < 0) {
dev_err(card->dev, "Could not create PCM\n");
snd_als300_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_als300_free(chip);
return err;
}
@@ -741,7 +745,8 @@ static int snd_als300_probe(struct pci_dev *pci,
chip_type = pci_id->driver_data;
- if ((err = snd_als300_create(card, pci, chip_type, &chip)) < 0) {
+ err = snd_als300_create(card, pci, chip_type, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -758,7 +763,8 @@ static int snd_als300_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx irq %i",
card->shortname, chip->port, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 139ac2a3a0ef..509f317ee682 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -832,9 +832,10 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
}
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0) {
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- }
+
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n");
@@ -842,7 +843,8 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
return -ENXIO;
}
- if ((err = pci_request_regions(pci, "ALS4000")) < 0) {
+ err = pci_request_regions(pci, "ALS4000");
+ if (err < 0) {
pci_disable_device(pci);
return err;
}
@@ -869,17 +871,17 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
/* disable all legacy ISA stuff */
snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
- if ((err = snd_sbdsp_create(card,
- iobase + ALS4K_IOB_10_ADLIB_ADDR0,
- pci->irq,
+ err = snd_sbdsp_create(card,
+ iobase + ALS4K_IOB_10_ADLIB_ADDR0,
+ pci->irq,
/* internally registered as IRQF_SHARED in case of ALS4000 SB */
- snd_als4000_interrupt,
- -1,
- -1,
- SB_HW_ALS4000,
- &chip)) < 0) {
+ snd_als4000_interrupt,
+ -1,
+ -1,
+ SB_HW_ALS4000,
+ &chip);
+ if (err < 0)
goto out_err;
- }
acard->chip = chip;
chip->pci = pci;
@@ -892,11 +894,12 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->alt_port, chip->irq);
- if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
- iobase + ALS4K_IOB_30_MIDI_DATA,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_ALS4000,
+ iobase + ALS4K_IOB_30_MIDI_DATA,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &chip->rmidi);
+ if (err < 0) {
dev_err(&pci->dev, "no MPU-401 device at 0x%lx?\n",
iobase + ALS4K_IOB_30_MIDI_DATA);
goto out_err;
@@ -907,12 +910,13 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
* however there doesn't seem to be an ALSA API for this...
* SPECS_PAGE: 21 */
- if ((err = snd_als4000_pcm(chip, 0)) < 0) {
+ err = snd_als4000_pcm(chip, 0);
+ if (err < 0)
goto out_err;
- }
- if ((err = snd_sbmixer_new(chip)) < 0) {
+
+ err = snd_sbmixer_new(chip);
+ if (err < 0)
goto out_err;
- }
if (snd_opl3_create(card,
iobase + ALS4K_IOB_10_ADLIB_ADDR0,
@@ -922,16 +926,17 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
iobase + ALS4K_IOB_10_ADLIB_ADDR0,
iobase + ALS4K_IOB_12_ADLIB_ADDR2);
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0)
goto out_err;
- }
}
snd_als4000_create_gameport(acard, dev);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0)
goto out_err;
- }
+
pci_set_drvdata(pci, card);
dev++;
err = 0;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 579425ccbb6a..5f8aa35c4bea 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1039,7 +1039,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
/* direct SPDIF */
runtime->hw.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
}
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
runtime->private_data = dma;
@@ -1415,7 +1416,8 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock,
if (snd_atiixp_codec_detect(chip) < 0)
return -ENXIO;
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus);
+ if (err < 0)
return err;
pbus->clock = clock;
chip->ac97_bus = pbus;
@@ -1431,7 +1433,8 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock,
ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
if (! chip->spdif_over_aclink)
ac97.scaps |= AC97_SCAP_NO_SPDIF;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i]);
+ if (err < 0) {
chip->ac97[i] = NULL; /* to be sure */
dev_dbg(chip->card->dev,
"codec %d not available for audio\n", i);
@@ -1562,7 +1565,8 @@ static int snd_atiixp_create(struct snd_card *card,
struct atiixp *chip;
int err;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1576,7 +1580,8 @@ static int snd_atiixp_create(struct snd_card *card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- if ((err = pci_request_regions(pci, "ATI IXP AC97")) < 0) {
+ err = pci_request_regions(pci, "ATI IXP AC97");
+ if (err < 0) {
pci_disable_device(pci);
kfree(chip);
return err;
@@ -1599,7 +1604,8 @@ static int snd_atiixp_create(struct snd_card *card,
card->sync_irq = chip->irq;
pci_set_master(pci);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_atiixp_free(chip);
return err;
}
@@ -1622,19 +1628,23 @@ static int snd_atiixp_probe(struct pci_dev *pci,
strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
strcpy(card->shortname, "ATI IXP");
- if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
+ err = snd_atiixp_create(card, pci, &chip);
+ if (err < 0)
goto __error;
card->private_data = chip;
- if ((err = snd_atiixp_aclink_reset(chip)) < 0)
+ err = snd_atiixp_aclink_reset(chip);
+ if (err < 0)
goto __error;
chip->spdif_over_aclink = spdif_aclink;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
+ err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk);
+ if (err < 0)
goto __error;
- if ((err = snd_atiixp_pcm_new(chip)) < 0)
+ err = snd_atiixp_pcm_new(chip);
+ if (err < 0)
goto __error;
snd_atiixp_proc_init(chip);
@@ -1647,7 +1657,8 @@ static int snd_atiixp_probe(struct pci_dev *pci,
chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
chip->addr, chip->irq);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto __error;
pci_set_drvdata(pci, card);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 45e75afec7a0..9739c3a82777 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -856,12 +856,12 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
dma->substream = substream;
runtime->hw = snd_atiixp_pcm_hw;
dma->ac97_pcm_type = pcm_type;
- if ((err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates)) < 0)
+ err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &hw_constraints_rates);
+ if (err < 0)
return err;
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
runtime->private_data = dma;
@@ -1058,7 +1058,8 @@ static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
if (snd_atiixp_codec_detect(chip) < 0)
return -ENXIO;
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus);
+ if (err < 0)
return err;
pbus->clock = clock;
chip->ac97_bus = pbus;
@@ -1072,7 +1073,8 @@ static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
ac97.pci = chip->pci;
ac97.num = i;
ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i]);
+ if (err < 0) {
chip->ac97[i] = NULL; /* to be sure */
dev_dbg(chip->card->dev,
"codec %d not available for modem\n", i);
@@ -1192,7 +1194,8 @@ static int snd_atiixp_create(struct snd_card *card,
struct atiixp_modem *chip;
int err;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1206,7 +1209,8 @@ static int snd_atiixp_create(struct snd_card *card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- if ((err = pci_request_regions(pci, "ATI IXP MC97")) < 0) {
+ err = pci_request_regions(pci, "ATI IXP MC97");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1229,7 +1233,8 @@ static int snd_atiixp_create(struct snd_card *card,
card->sync_irq = chip->irq;
pci_set_master(pci);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_atiixp_free(chip);
return err;
}
@@ -1252,17 +1257,21 @@ static int snd_atiixp_probe(struct pci_dev *pci,
strcpy(card->driver, "ATIIXP-MODEM");
strcpy(card->shortname, "ATI IXP Modem");
- if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
+ err = snd_atiixp_create(card, pci, &chip);
+ if (err < 0)
goto __error;
card->private_data = chip;
- if ((err = snd_atiixp_aclink_reset(chip)) < 0)
+ err = snd_atiixp_aclink_reset(chip);
+ if (err < 0)
goto __error;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
+ err = snd_atiixp_mixer_new(chip, ac97_clock);
+ if (err < 0)
goto __error;
- if ((err = snd_atiixp_pcm_new(chip)) < 0)
+ err = snd_atiixp_pcm_new(chip);
+ if (err < 0)
goto __error;
snd_atiixp_proc_init(chip);
@@ -1272,7 +1281,8 @@ static int snd_atiixp_probe(struct pci_dev *pci,
sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
card->shortname, pci->revision, chip->addr, chip->irq);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto __error;
pci_set_drvdata(pci, card);
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 1b37b7225b1d..1f7fee470266 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -46,8 +46,9 @@ MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
static void vortex_fix_latency(struct pci_dev *vortex)
{
int rc;
- if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
- dev_info(&vortex->dev, "vortex latency is 0xff\n");
+ rc = pci_write_config_byte(vortex, 0x40, 0xff);
+ if (!rc) {
+ dev_info(&vortex->dev, "vortex latency is 0xff\n");
} else {
dev_warn(&vortex->dev,
"could not set vortex latency: pci error 0x%x\n", rc);
@@ -65,9 +66,12 @@ static void vortex_fix_agp_bridge(struct pci_dev *via)
* read the config and it is not already set
*/
- if (!(rc = pci_read_config_byte(via, 0x42, &value))
- && ((value & 0x10)
- || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) {
+ rc = pci_read_config_byte(via, 0x42, &value);
+ if (!rc) {
+ if (!(value & 0x10))
+ rc = pci_write_config_byte(via, 0x42, value | 0x10);
+ }
+ if (!rc) {
dev_info(&via->dev, "bridge config is 0x%x\n", value | 0x10);
} else {
dev_warn(&via->dev,
@@ -102,14 +106,16 @@ static void snd_vortex_workaround(struct pci_dev *vortex, int fix)
} else {
if (fix & 0x1)
vortex_fix_latency(vortex);
- if ((fix & 0x2) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8365_1, NULL)))
- vortex_fix_agp_bridge(via);
- if ((fix & 0x4) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_82C598_1, NULL)))
- vortex_fix_agp_bridge(via);
- if ((fix & 0x8) && (via = pci_get_device(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
+ if (fix & 0x2)
+ via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8365_1, NULL);
+ else if (fix & 0x4)
+ via = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C598_1, NULL);
+ else if (fix & 0x8)
+ via = pci_get_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
+ if (via)
vortex_fix_agp_bridge(via);
}
pci_dev_put(via);
@@ -147,7 +153,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
*rchip = NULL;
// check PCI availability (DMA).
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
dev_err(card->dev, "error to set DMA mask\n");
@@ -174,7 +181,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
// (1) PCI resource allocation
// Get MMIO area
//
- if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
+ err = pci_request_regions(pci, CARD_NAME_SHORT);
+ if (err)
goto regions_out;
chip->mmio = pci_ioremap_bar(pci, 0);
@@ -187,14 +195,15 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
/* Init audio core.
* This must be done before we do request_irq otherwise we can get spurious
* interrupts that we do not handle properly and make a mess of things */
- if ((err = vortex_core_init(chip)) != 0) {
+ err = vortex_core_init(chip);
+ if (err) {
dev_err(card->dev, "hw core init failed\n");
goto core_out;
}
- if ((err = request_irq(pci->irq, vortex_interrupt,
- IRQF_SHARED, KBUILD_MODNAME,
- chip)) != 0) {
+ err = request_irq(pci->irq, vortex_interrupt,
+ IRQF_SHARED, KBUILD_MODNAME, chip);
+ if (err) {
dev_err(card->dev, "cannot grab irq\n");
goto irq_out;
}
@@ -205,9 +214,9 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
// End of PCI setup.
// Register alsa root device.
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0)
goto alloc_out;
- }
*rchip = chip;
@@ -252,7 +261,8 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return err;
// (3)
- if ((err = snd_vortex_create(card, pci, &chip)) < 0) {
+ err = snd_vortex_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -278,12 +288,14 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
}
#ifndef CHIP_AU8820
// ADB SPDIF
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) {
+ err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1);
+ if (err < 0) {
snd_card_free(card);
return err;
}
// A3D
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) {
+ err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -297,12 +309,14 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
*/
#ifndef CHIP_AU8810
// WT pcm.
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) {
+ err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#endif
- if ((err = snd_vortex_midi(chip)) < 0) {
+ err = snd_vortex_midi(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -327,13 +341,13 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
#endif
// (5)
- if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
- &(chip->device))) < 0) {
+ err = pci_read_config_word(pci, PCI_DEVICE_ID, &chip->device);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = pci_read_config_word(pci, PCI_VENDOR_ID,
- &(chip->vendor))) < 0) {
+ err = pci_read_config_word(pci, PCI_VENDOR_ID, &chip->vendor);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -352,7 +366,8 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
#endif
// (6)
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 2db183f8826a..eabaee0463fe 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -849,46 +849,50 @@ static int vortex_a3d_register_controls(vortex_t *vortex)
int err, i;
/* HRTF controls. */
for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]);
+ if (!kcontrol)
return -ENOMEM;
kcontrol->id.numid = CTRLID_HRTF;
kcontrol->info = snd_vortex_a3d_hrtf_info;
kcontrol->put = snd_vortex_a3d_hrtf_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
}
/* ITD controls. */
for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]);
+ if (!kcontrol)
return -ENOMEM;
kcontrol->id.numid = CTRLID_ITD;
kcontrol->info = snd_vortex_a3d_itd_info;
kcontrol->put = snd_vortex_a3d_itd_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
}
/* ILD (gains) controls. */
for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]);
+ if (!kcontrol)
return -ENOMEM;
kcontrol->id.numid = CTRLID_GAINS;
kcontrol->info = snd_vortex_a3d_ild_info;
kcontrol->put = snd_vortex_a3d_ild_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
}
/* Filter controls. */
for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i]);
+ if (!kcontrol)
return -ENOMEM;
kcontrol->id.numid = CTRLID_FILTER;
kcontrol->info = snd_vortex_a3d_filter_info;
kcontrol->put = snd_vortex_a3d_filter_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
}
return 0;
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 5180f1bd1326..2ed5100b8cae 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2120,9 +2120,9 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
VORTEX_RESOURCE_DMA);
} else {
en = 1;
- if ((dma =
- vortex_adb_checkinout(vortex, NULL, en,
- VORTEX_RESOURCE_DMA)) < 0)
+ dma = vortex_adb_checkinout(vortex, NULL, en,
+ VORTEX_RESOURCE_DMA);
+ if (dma < 0)
return -EBUSY;
}
@@ -2140,18 +2140,20 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
/* Get SRC and MIXER hardware resources. */
if (stream->type != VORTEX_PCM_SPDIF) {
for (i = 0; i < nr_ch; i++) {
- if ((src[i] = vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_SRC)) < 0) {
+ src[i] = vortex_adb_checkinout(vortex,
+ stream->resources, en,
+ VORTEX_RESOURCE_SRC);
+ if (src[i] < 0) {
memset(stream->resources, 0,
sizeof(stream->resources));
return -EBUSY;
}
if (stream->type != VORTEX_PCM_A3D) {
- if ((mix[i] = vortex_adb_checkinout(vortex,
- stream->resources,
- en,
- VORTEX_RESOURCE_MIXIN)) < 0) {
+ mix[i] = vortex_adb_checkinout(vortex,
+ stream->resources,
+ en,
+ VORTEX_RESOURCE_MIXIN);
+ if (mix[i] < 0) {
memset(stream->resources,
0,
sizeof(stream->resources));
@@ -2162,10 +2164,10 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
}
#ifndef CHIP_AU8820
if (stream->type == VORTEX_PCM_A3D) {
- if ((a3d =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_A3D)) < 0) {
+ a3d = vortex_adb_checkinout(vortex,
+ stream->resources, en,
+ VORTEX_RESOURCE_A3D);
+ if (a3d < 0) {
memset(stream->resources, 0,
sizeof(stream->resources));
dev_err(vortex->card->dev,
@@ -2278,19 +2280,18 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
/* Get SRC and MIXER hardware resources. */
for (i = 0; i < nr_ch; i++) {
- if ((mix[i] =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_MIXOUT))
- < 0) {
+ mix[i] = vortex_adb_checkinout(vortex,
+ stream->resources, en,
+ VORTEX_RESOURCE_MIXOUT);
+ if (mix[i] < 0) {
memset(stream->resources, 0,
sizeof(stream->resources));
return -EBUSY;
}
- if ((src[i] =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_SRC)) < 0) {
+ src[i] = vortex_adb_checkinout(vortex,
+ stream->resources, en,
+ VORTEX_RESOURCE_SRC);
+ if (src[i] < 0) {
memset(stream->resources, 0,
sizeof(stream->resources));
return -EBUSY;
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 58e92f2a72c0..71c13100d7ef 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -873,29 +873,33 @@ static int vortex_eq_init(vortex_t *vortex)
vortex_Eqlzr_init(vortex);
- if ((kcontrol =
- snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex);
+ if (!kcontrol)
return -ENOMEM;
kcontrol->private_value = 0;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
/* EQ gain controls */
for (i = 0; i < 10; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_eq_kcontrol, vortex);
+ if (!kcontrol)
return -ENOMEM;
snprintf(kcontrol->id.name, sizeof(kcontrol->id.name),
"%s Playback Volume", EqBandLabels[i]);
kcontrol->private_value = i;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
//vortex->eqctrl[i] = kcontrol;
}
/* EQ band levels */
- if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
+ kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex);
+ if (!kcontrol)
return -ENOMEM;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
+ err = snd_ctl_add(vortex->card, kcontrol);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index 5b647682b683..aeba684b8d18 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -30,7 +30,8 @@ static int snd_vortex_mixer(vortex_t *vortex)
.read = vortex_codec_read,
};
- if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
// Initialize AC97 codec stuff.
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index 603494e7d30e..164f6b7039ab 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -68,9 +68,9 @@ static int snd_vortex_midi(vortex_t *vortex)
/* Create MPU401 instance. */
#ifdef VORTEX_MPU401_LEGACY
- if ((temp =
- snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
- MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
+ temp = snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
+ MPU401_INFO_IRQ_HOOK, -1, &rmidi);
+ if (temp) {
hwwrite(vortex->mmio, VORTEX_CTRL,
(hwread(vortex->mmio, VORTEX_CTRL) &
~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
@@ -78,10 +78,10 @@ static int snd_vortex_midi(vortex_t *vortex)
}
#else
port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
- if ((temp =
- snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
- MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO |
- MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
+ temp = snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
+ MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO |
+ MPU401_INFO_IRQ_HOOK, -1, &rmidi);
+ if (temp) {
hwwrite(vortex->mmio, VORTEX_CTRL,
(hwread(vortex->mmio, VORTEX_CTRL) &
~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index d019aa566de3..546f71220604 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -130,14 +130,14 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
int err;
/* Force equal size periods */
- if ((err =
- snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
/* Avoid PAGE_SIZE boundary to fall inside of a period. */
- if ((err =
- snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
+ err = snd_pcm_hw_constraint_pow2(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
+ if (err < 0)
return err;
snd_pcm_hw_constraint_step(runtime, 0,
@@ -658,7 +658,8 @@ static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(chip->card, kctl)) < 0)
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
return err;
}
}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 51dcf1bc4c0c..4ee7ab409807 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1194,7 +1194,8 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
sw = snd_azf3328_mixer_controls;
for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
++idx, ++sw) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip));
+ if (err < 0)
return err;
}
snd_component_add(card, "AZF3328 mixer");
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 91512b345d19..39bcfb81e81c 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -719,7 +719,8 @@ static int snd_bt87x_create(struct snd_card *card,
chip->irq = -1;
spin_lock_init(&chip->reg_lock);
- if ((err = pci_request_regions(pci, "Bt87x audio")) < 0) {
+ err = pci_request_regions(pci, "Bt87x audio");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index bee4710916c4..99778711006a 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -575,9 +575,11 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
*/
//channel->interrupt = snd_ca0106_pcm_channel_interrupt;
channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+ err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
+ if (err < 0)
return err;
snd_pcm_set_sync(substream);
@@ -668,10 +670,12 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre
*/
//channel->interrupt = snd_ca0106_pcm_channel_interrupt;
channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
//snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+ err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
+ if (err < 0)
return err;
return 0;
}
@@ -1166,7 +1170,8 @@ static int snd_ca0106_ac97(struct snd_ca0106 *chip)
.read = snd_ca0106_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
pbus->no_vra = 1; /* we don't need VRA */
@@ -1759,7 +1764,8 @@ static int snd_ca0106_midi(struct snd_ca0106 *chip, unsigned int channel)
midi->dev_id = chip;
- if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
+ err = ca_midi_init(chip, midi, 0, name);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index 18524e0a9102..957e60f64821 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -276,7 +276,8 @@ int ca_midi_init(void *dev_id, struct snd_ca_midi *midi, int device, char *name)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi);
+ if (err < 0)
return err;
midi->dev_id = dev_id;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 598446348da6..f44f118aacad 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1225,9 +1225,11 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
rate = subs->runtime->rate;
- if (up && do_ac3)
- if ((err = save_mixer_state(cm)) < 0)
+ if (up && do_ac3) {
+ err = save_mixer_state(cm);
+ if (err < 0)
return err;
+ }
spin_lock_irq(&cm->reg_lock);
cm->spdif_playback_avail = up;
@@ -1276,7 +1278,8 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream)
substream->runtime->channels == 2);
if (do_spdif && cm->can_ac3_hw)
do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
- if ((err = setup_spdif_playback(cm, substream, do_spdif, do_ac3)) < 0)
+ err = setup_spdif_playback(cm, substream, do_spdif, do_ac3);
+ if (err < 0)
return err;
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
}
@@ -1291,7 +1294,8 @@ static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream
do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
else
do_ac3 = 1; /* doesn't matter */
- if ((err = setup_spdif_playback(cm, substream, 1, do_ac3)) < 0)
+ err = setup_spdif_playback(cm, substream, 1, do_ac3);
+ if (err < 0)
return err;
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
}
@@ -1639,7 +1643,8 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
+ err = open_device_check(cm, CM_OPEN_PLAYBACK, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_playback;
if (cm->chip_version == 68) {
@@ -1665,7 +1670,8 @@ static int snd_cmipci_capture_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)
+ err = open_device_check(cm, CM_OPEN_CAPTURE, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_capture;
if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording
@@ -1689,7 +1695,9 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
+ /* use channel B */
+ err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_playback2;
mutex_lock(&cm->open_mutex);
@@ -1727,7 +1735,9 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */
+ /* use channel A */
+ err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream);
+ if (err < 0)
return err;
if (cm->can_ac3_hw) {
runtime->hw = snd_cmipci_playback_spdif;
@@ -1754,7 +1764,9 @@ static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */
+ /* use channel B */
+ err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_capture_spdif;
if (cm->can_96k && !(cm->chip_version == 68)) {
@@ -2650,7 +2662,8 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
"PCM Playback Volume"))
continue;
}
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm));
+ if (err < 0)
return err;
}
@@ -2675,13 +2688,19 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
return err;
}
if (cm->can_ac3_hw) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm))) < 0)
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm))) < 0)
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm))) < 0)
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
kctl->id.device = pcm_spdif_device;
}
@@ -2955,7 +2974,8 @@ static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
goto disable_fm;
}
}
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
dev_err(cm->card->dev, "cannot create OPL3 hwdep\n");
return err;
}
@@ -2987,7 +3007,8 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
*rcmipci = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
cm = kzalloc(sizeof(*cm), GFP_KERNEL);
@@ -3006,7 +3027,8 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
cm->channel[1].ch = 1;
cm->channel[0].is_dac = cm->channel[1].is_dac = 1; /* dual DAC mode */
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
+ err = pci_request_regions(pci, card->driver);
+ if (err < 0) {
kfree(cm);
pci_disable_device(pci);
return err;
@@ -3120,7 +3142,8 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
sprintf(card->longname, "%s%s at %#lx, irq %i",
card->shortname, modelstr, cm->iobase, cm->irq);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops);
+ if (err < 0) {
snd_cmipci_free(cm);
return err;
}
@@ -3172,32 +3195,36 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
/* create pcm devices */
pcm_index = pcm_spdif_index = 0;
- if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm_new(cm, pcm_index);
+ if (err < 0)
return err;
pcm_index++;
- if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm2_new(cm, pcm_index);
+ if (err < 0)
return err;
pcm_index++;
if (cm->can_ac3_hw || cm->can_ac3_sw) {
pcm_spdif_index = pcm_index;
- if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm_spdif_new(cm, pcm_index);
+ if (err < 0)
return err;
}
/* create mixer interface & switches */
- if ((err = snd_cmipci_mixer_new(cm, pcm_spdif_index)) < 0)
+ err = snd_cmipci_mixer_new(cm, pcm_spdif_index);
+ if (err < 0)
return err;
if (iomidi > 0) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- iomidi,
- (integrated_midi ?
- MPU401_INFO_INTEGRATED : 0) |
- MPU401_INFO_IRQ_HOOK,
- -1, &cm->rmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
+ iomidi,
+ (integrated_midi ?
+ MPU401_INFO_INTEGRATED : 0) |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &cm->rmidi);
+ if (err < 0)
dev_err(cm->card->dev,
"no UART401 device at 0x%lx\n", iomidi);
- }
}
#ifdef USE_VAR48KRATE
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index bf3bb70ffaf9..e122a168c148 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1068,23 +1068,28 @@ static int snd_cs4281_mixer(struct cs4281 *chip)
.read = snd_cs4281_ac97_read,
};
- if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_cs4281_mixer_free_ac97_bus;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_cs4281_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
if (chip->dual_codec) {
ac97.num = 1;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_secondary)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_secondary);
+ if (err < 0)
return err;
}
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_fm_vol, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_fm_vol, chip));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_pcm_vol, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_pcm_vol, chip));
+ if (err < 0)
return err;
return 0;
}
@@ -1308,7 +1313,8 @@ static int snd_cs4281_create(struct snd_card *card,
};
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
@@ -1326,7 +1332,8 @@ static int snd_cs4281_create(struct snd_card *card,
}
chip->dual_codec = dual_codec;
- if ((err = pci_request_regions(pci, "CS4281")) < 0) {
+ err = pci_request_regions(pci, "CS4281");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1356,7 +1363,8 @@ static int snd_cs4281_create(struct snd_card *card,
return tmp;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_cs4281_free(chip);
return err;
}
@@ -1395,12 +1403,14 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
* space between 0e4h and 0ffh to be written. */
snd_cs4281_pokeBA0(chip, BA0_CWPR, 0x4281);
- if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC1)) != (BA0_SERC1_SO1EN | BA0_SERC1_AC97)) {
+ tmp = snd_cs4281_peekBA0(chip, BA0_SERC1);
+ if (tmp != (BA0_SERC1_SO1EN | BA0_SERC1_AC97)) {
dev_err(chip->card->dev,
"SERC1 AC'97 check failed (0x%x)\n", tmp);
return -EIO;
}
- if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC2)) != (BA0_SERC2_SI1EN | BA0_SERC2_AC97)) {
+ tmp = snd_cs4281_peekBA0(chip, BA0_SERC2);
+ if (tmp != (BA0_SERC2_SI1EN | BA0_SERC2_AC97)) {
dev_err(chip->card->dev,
"SERC2 AC'97 check failed (0x%x)\n", tmp);
return -EIO;
@@ -1748,7 +1758,8 @@ static int snd_cs4281_midi(struct cs4281 *chip, int device)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, "CS4281");
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs4281_midi_output);
@@ -1881,32 +1892,38 @@ static int snd_cs4281_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) {
+ err = snd_cs4281_create(card, pci, &chip, dual_codec[dev]);
+ if (err < 0) {
snd_card_free(card);
return err;
}
card->private_data = chip;
- if ((err = snd_cs4281_mixer(chip)) < 0) {
+ err = snd_cs4281_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_cs4281_pcm(chip, 0)) < 0) {
+ err = snd_cs4281_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_cs4281_midi(chip, 0)) < 0) {
+ err = snd_cs4281_midi(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3)) < 0) {
+ err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3);
+ if (err < 0) {
snd_card_free(card);
return err;
}
opl3->private_data = chip;
opl3->command = snd_cs4281_opl3_command;
snd_opl3_init(opl3);
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1918,7 +1935,8 @@ static int snd_cs4281_probe(struct pci_dev *pci,
chip->ba0_addr,
chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 1db7b4112840..358ca84cbdea 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -70,45 +70,53 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
0, &card);
if (err < 0)
return err;
- if ((err = snd_cs46xx_create(card, pci,
- external_amp[dev], thinkpad[dev],
- &chip)) < 0) {
+ err = snd_cs46xx_create(card, pci,
+ external_amp[dev], thinkpad[dev],
+ &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
card->private_data = chip;
chip->accept_valid = mmap_valid[dev];
- if ((err = snd_cs46xx_pcm(chip, 0)) < 0) {
+ err = snd_cs46xx_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if ((err = snd_cs46xx_pcm_rear(chip, 1)) < 0) {
+ err = snd_cs46xx_pcm_rear(chip, 1);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_cs46xx_pcm_iec958(chip, 2)) < 0) {
+ err = snd_cs46xx_pcm_iec958(chip, 2);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#endif
- if ((err = snd_cs46xx_mixer(chip, 2)) < 0) {
+ err = snd_cs46xx_mixer(chip, 2);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
if (chip->nr_ac97_codecs ==2) {
- if ((err = snd_cs46xx_pcm_center_lfe(chip, 3)) < 0) {
+ err = snd_cs46xx_pcm_center_lfe(chip, 3);
+ if (err < 0) {
snd_card_free(card);
return err;
}
}
#endif
- if ((err = snd_cs46xx_midi(chip, 0)) < 0) {
+ err = snd_cs46xx_midi(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
+ err = snd_cs46xx_start_dsp(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -124,7 +132,8 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
chip->ba1_addr,
chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 37f516e6a5c2..1e1eb17f8e07 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1058,9 +1058,10 @@ static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46x
int unlinked = cpcm->pcm_channel->unlinked;
cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
- if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm,
- cpcm->hw_buf.addr,
- cpcm->pcm_channel_id)) == NULL) {
+ cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel(chip, sample_rate, cpcm,
+ cpcm->hw_buf.addr,
+ cpcm->pcm_channel_id);
+ if (!cpcm->pcm_channel) {
dev_err(chip->card->dev,
"failed to re-create virtual PCM channel\n");
return -ENOMEM;
@@ -1147,7 +1148,8 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
runtime->dma_addr = 0;
runtime->dma_bytes = 0;
}
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) {
+ 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
@@ -1295,7 +1297,8 @@ static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
runtime->dma_addr = 0;
runtime->dma_bytes = 0;
}
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
+ err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+ if (err < 0)
return err;
substream->ops = &snd_cs46xx_capture_indirect_ops;
}
@@ -1760,7 +1763,8 @@ int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1787,7 +1791,8 @@ int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1811,7 +1816,8 @@ int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1835,7 +1841,8 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -2414,7 +2421,8 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
/* test if we can write to the record gain volume register */
snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
- if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
+ err = snd_ac97_read(ac97, AC97_REC_GAIN);
+ if (err == 0x8a05)
return;
msleep(10);
@@ -2476,7 +2484,8 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
/* detect primary codec */
chip->nr_ac97_codecs = 0;
dev_dbg(chip->card->dev, "detecting primary codec\n");
- if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
@@ -2497,7 +2506,8 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
kctl->id.device = spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
@@ -2684,7 +2694,8 @@ int snd_cs46xx_midi(struct snd_cs46xx *chip, int device)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, "CS46XX");
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
@@ -3526,7 +3537,8 @@ static void hercules_mixer_init (struct snd_cs46xx *chip)
struct snd_kcontrol *kctl;
kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
- if ((err = snd_ctl_add(card, kctl)) < 0) {
+ err = snd_ctl_add(card, kctl);
+ if (err < 0) {
dev_err(card->dev,
"failed to initialize Hercules mixer (%d)\n",
err);
@@ -3871,7 +3883,8 @@ int snd_cs46xx_create(struct snd_card *card,
*rchip = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -3965,8 +3978,9 @@ int snd_cs46xx_create(struct snd_card *card,
for (idx = 0; idx < 5; idx++) {
region = &chip->region.idx[idx];
- if ((region->resource = request_mem_region(region->base, region->size,
- region->name)) == NULL) {
+ region->resource = request_mem_region(region->base, region->size,
+ region->name);
+ if (!region->resource) {
dev_err(chip->card->dev,
"unable to request memory region 0x%lx-0x%lx\n",
region->base, region->base + region->size - 1);
@@ -4005,7 +4019,8 @@ int snd_cs46xx_create(struct snd_card *card,
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_cs46xx_free(chip);
return err;
}
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 05f3f6dc918d..1db6bc58d6a6 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -617,7 +617,8 @@ static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry,
col = 0;
}
- if ( (symbol = cs46xx_dsp_lookup_symbol_addr (chip,i / sizeof(u32), SYMBOL_PARAMETER)) != NULL) {
+ symbol = cs46xx_dsp_lookup_symbol_addr(chip, i / sizeof(u32), SYMBOL_PARAMETER);
+ if (symbol) {
col = 0;
snd_iprintf (buffer,"\n%s:\n",symbol->symbol_name);
}
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 9b716b56d739..e048b45d9e7e 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -143,7 +143,8 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
.read = snd_cs5535audio_ac97_codec_read,
};
- if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
@@ -155,7 +156,8 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
/* set any OLPC-specific scaps */
olpc_prequirks(card, &ac97);
- if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97);
+ if (err < 0) {
dev_err(card->dev, "mixer failed\n");
return err;
}
@@ -266,7 +268,8 @@ static int snd_cs5535audio_create(struct snd_card *card,
};
*rcs5535au = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
@@ -286,7 +289,8 @@ static int snd_cs5535audio_create(struct snd_card *card,
cs5535au->pci = pci;
cs5535au->irq = -1;
- if ((err = pci_request_regions(pci, "CS5535 Audio")) < 0) {
+ err = pci_request_regions(pci, "CS5535 Audio");
+ if (err < 0) {
kfree(cs5535au);
goto pcifail;
}
@@ -304,8 +308,8 @@ static int snd_cs5535audio_create(struct snd_card *card,
card->sync_irq = cs5535au->irq;
pci_set_master(pci);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- cs5535au, &ops)) < 0)
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cs5535au, &ops);
+ if (err < 0)
goto sndfail;
*rcs5535au = cs5535au;
@@ -340,15 +344,18 @@ static int snd_cs5535audio_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0)
+ err = snd_cs5535audio_create(card, pci, &cs5535au);
+ if (err < 0)
goto probefail_out;
card->private_data = cs5535au;
- if ((err = snd_cs5535audio_mixer(cs5535au)) < 0)
+ err = snd_cs5535audio_mixer(cs5535au);
+ if (err < 0)
goto probefail_out;
- if ((err = snd_cs5535audio_pcm(cs5535au)) < 0)
+ err = snd_cs5535audio_pcm(cs5535au);
+ if (err < 0)
goto probefail_out;
strcpy(card->driver, DRIVER_NAME);
@@ -358,7 +365,8 @@ static int snd_cs5535audio_probe(struct pci_dev *pci,
card->shortname, card->driver,
cs5535au->port, cs5535au->irq);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto probefail_out;
pci_set_drvdata(pci, card);
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 4032b89b1fc1..5ff10fec7b90 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -87,8 +87,9 @@ static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream)
snd_pcm_limit_hw_rates(runtime);
cs5535au->playback_substream = substream;
runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]);
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
return 0;
@@ -342,8 +343,9 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
snd_pcm_limit_hw_rates(runtime);
cs5535au->capture_substream = substream;
runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]);
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
olpc_capture_open(cs5535au->ac97);
return 0;
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
index 320837ba7bab..0356efad7528 100644
--- a/sound/pci/echoaudio/darla20_dsp.c
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -36,7 +36,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw: could not initialize DSP comm page\n");
return err;
@@ -53,7 +54,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->asic_loaded = true;
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
index 8736b5e81ca3..b96300772aee 100644
--- a/sound/pci/echoaudio/darla24_dsp.c
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -36,7 +36,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw: could not initialize DSP comm page\n");
return err;
@@ -52,7 +53,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
ECHO_CLOCK_BIT_ESYNC;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index 6deb80c42f11..9e1f2cad0909 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -49,7 +49,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 9bd67ac33657..a62e5581ad14 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -301,38 +301,42 @@ static int pcm_open(struct snd_pcm_substream *substream,
snd_pcm_set_sync(substream);
/* Only mono and any even number of channels are allowed */
- if ((err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &pipe->constr)) < 0)
+ err = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &pipe->constr);
+ if (err < 0)
return err;
/* All periods should have the same size */
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
/* The hw accesses memory in chunks 32 frames long and they should be
32-bytes-aligned. It's not a requirement, but it seems that IRQs are
generated with a resolution of 32 frames. Thus we need the following */
- if ((err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 32)) < 0)
+ err = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
+ if (err < 0)
return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 32)) < 0)
+ err = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
+ if (err < 0)
return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- hw_rule_sample_rate, chip,
- SNDRV_PCM_HW_PARAM_RATE, -1)) < 0)
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ hw_rule_sample_rate, chip,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
return err;
/* Allocate a page for the scatter-gather list */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- &chip->pci->dev,
- PAGE_SIZE, &pipe->sgpage)) < 0) {
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+ &chip->pci->dev,
+ PAGE_SIZE, &pipe->sgpage);
+ if (err < 0) {
dev_err(chip->card->dev, "s-g list allocation failed\n");
return err;
}
@@ -358,18 +362,21 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream)
struct echoaudio *chip = snd_pcm_substream_chip(substream);
int err;
- if ((err = pcm_open(substream, num_analog_busses_in(chip) -
- substream->number)) < 0)
+ err = pcm_open(substream,
+ num_analog_busses_in(chip) - substream->number);
+ if (err < 0)
return err;
- if ((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)) < 0)
+ 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)
return err;
- if ((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)) < 0)
+ 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)
return err;
return 0;
@@ -387,19 +394,22 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream)
#else
max_channels = num_analog_busses_out(chip);
#endif
- if ((err = pcm_open(substream, max_channels - substream->number)) < 0)
+ err = pcm_open(substream, max_channels - substream->number);
+ if (err < 0)
return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_playback_channels_by_format,
- NULL,
- SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ hw_rule_playback_channels_by_format,
+ NULL,
+ SNDRV_PCM_HW_PARAM_FORMAT, -1);
+ if (err < 0)
return err;
- if ((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)) < 0)
+ 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)
return err;
return 0;
@@ -426,15 +436,17 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream)
if (err < 0)
goto din_exit;
- if ((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)) < 0)
+ 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;
- if ((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)) < 0)
+ 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;
din_exit:
@@ -463,17 +475,19 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream)
if (err < 0)
goto dout_exit;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_playback_channels_by_format,
- NULL, SNDRV_PCM_HW_PARAM_FORMAT,
- -1)) < 0)
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ hw_rule_playback_channels_by_format,
+ NULL, SNDRV_PCM_HW_PARAM_FORMAT,
+ -1);
+ if (err < 0)
goto dout_exit;
- if ((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)) < 0)
+ 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;
dout_exit:
@@ -907,8 +921,9 @@ static int snd_echo_new_pcm(struct echoaudio *chip)
separated */
/* PCM#0 Virtual outputs and analog inputs */
- if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip),
- num_analog_busses_in(chip), &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip),
+ num_analog_busses_in(chip), &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
chip->analog_pcm = pcm;
@@ -919,8 +934,9 @@ static int snd_echo_new_pcm(struct echoaudio *chip)
#ifdef ECHOCARD_HAS_DIGITAL_IO
/* PCM#1 Digital inputs, no outputs */
- if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0,
- num_digital_busses_in(chip), &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "Digital PCM", 1, 0,
+ num_digital_busses_in(chip), &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
chip->digital_pcm = pcm;
@@ -937,9 +953,10 @@ static int snd_echo_new_pcm(struct echoaudio *chip)
register two PCM devices: */
/* PCM#0 Analog i/o */
- if ((err = snd_pcm_new(chip->card, "Analog PCM", 0,
- num_analog_busses_out(chip),
- num_analog_busses_in(chip), &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "Analog PCM", 0,
+ num_analog_busses_out(chip),
+ num_analog_busses_in(chip), &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
chip->analog_pcm = pcm;
@@ -950,9 +967,10 @@ static int snd_echo_new_pcm(struct echoaudio *chip)
#ifdef ECHOCARD_HAS_DIGITAL_IO
/* PCM#1 Digital i/o */
- if ((err = snd_pcm_new(chip->card, "Digital PCM", 1,
- num_digital_busses_out(chip),
- num_digital_busses_in(chip), &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "Digital PCM", 1,
+ num_digital_busses_out(chip),
+ num_digital_busses_in(chip), &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
chip->digital_pcm = pcm;
@@ -1567,7 +1585,8 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
if (chip->input_clock != dclock) {
mutex_lock(&chip->mode_mutex);
spin_lock_irq(&chip->lock);
- if ((changed = set_input_clock(chip, dclock)) == 0)
+ changed = set_input_clock(chip, dclock);
+ if (!changed)
changed = 1; /* no errors */
spin_unlock_irq(&chip->lock);
mutex_unlock(&chip->mode_mutex);
@@ -1911,7 +1930,8 @@ static int snd_echo_create(struct snd_card *card,
pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0);
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(pci);
@@ -1943,8 +1963,9 @@ static int snd_echo_create(struct snd_card *card,
if (sz > PAGE_SIZE)
sz = PAGE_SIZE; /* We map only the required part */
- if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz,
- ECHOCARD_NAME)) == NULL) {
+ chip->iores = request_mem_region(chip->dsp_registers_phys, sz,
+ ECHOCARD_NAME);
+ if (!chip->iores) {
dev_err(chip->card->dev, "cannot get memory region\n");
snd_echo_free(chip);
return -EBUSY;
@@ -1988,7 +2009,8 @@ static int snd_echo_create(struct snd_card *card,
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_echo_free(chip);
return err;
}
@@ -2024,7 +2046,8 @@ static int snd_echo_probe(struct pci_dev *pci,
return err;
chip = NULL; /* Tells snd_echo_create to allocate chip */
- if ((err = snd_echo_create(card, pci, &chip)) < 0) {
+ err = snd_echo_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2040,7 +2063,8 @@ static int snd_echo_probe(struct pci_dev *pci,
card->shortname, pci_id->subdevice & 0x000f, dsp,
chip->dsp_registers_phys, chip->irq);
- if ((err = snd_echo_new_pcm(chip)) < 0) {
+ err = snd_echo_new_pcm(chip);
+ if (err < 0) {
dev_err(chip->card->dev, "new pcm error %d\n", err);
snd_card_free(card);
return err;
@@ -2048,7 +2072,8 @@ static int snd_echo_probe(struct pci_dev *pci,
#ifdef ECHOCARD_HAS_MIDI
if (chip->has_midi) { /* Some Mia's do not have midi */
- if ((err = snd_echo_midi_create(card, chip)) < 0) {
+ err = snd_echo_midi_create(card, chip);
+ if (err < 0) {
dev_err(chip->card->dev, "new midi error %d\n", err);
snd_card_free(card);
return err;
@@ -2058,7 +2083,8 @@ static int snd_echo_probe(struct pci_dev *pci,
#ifdef ECHOCARD_HAS_VMIXER
snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip));
+ if (err < 0)
goto ctl_error;
#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
err = snd_ctl_add(chip->card,
@@ -2074,39 +2100,48 @@ static int snd_echo_probe(struct pci_dev *pci,
#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_INPUT_GAIN
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip));
+ if (err < 0)
goto ctl_error;
#endif
#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
- if (!chip->hasnt_input_nominal_level)
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0)
+ if (!chip->hasnt_input_nominal_level) {
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip));
+ if (err < 0)
goto ctl_error;
+ }
#endif
#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip));
+ if (err < 0)
goto ctl_error;
#endif
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip));
+ if (err < 0)
goto ctl_error;
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip));
+ if (err < 0)
goto ctl_error;
#ifdef ECHOCARD_HAS_MONITOR
snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip);
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip));
+ if (err < 0)
goto ctl_error;
#endif
#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip));
+ if (err < 0)
goto ctl_error;
#endif
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip));
+ if (err < 0)
goto ctl_error;
#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
@@ -2116,7 +2151,8 @@ static int snd_echo_probe(struct pci_dev *pci,
if (chip->digital_modes & (1 << i))
chip->digital_mode_list[chip->num_digital_modes++] = i;
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip));
+ if (err < 0)
goto ctl_error;
#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
@@ -2129,20 +2165,24 @@ static int snd_echo_probe(struct pci_dev *pci,
if (chip->num_clock_sources > 1) {
chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip);
- if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0)
+ err = snd_ctl_add(chip->card, chip->clock_src_ctl);
+ if (err < 0)
goto ctl_error;
}
#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
#ifdef ECHOCARD_HAS_DIGITAL_IO
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip));
+ if (err < 0)
goto ctl_error;
#endif
#ifdef ECHOCARD_HAS_PHANTOM_POWER
- if (chip->has_phantom_power)
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0)
+ if (chip->has_phantom_power) {
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip));
+ if (err < 0)
goto ctl_error;
+ }
#endif
err = snd_card_register(card);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index d10d0e460f0b..2a40091d472c 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -349,7 +349,8 @@ static int load_dsp(struct echoaudio *chip, u16 *code)
/* If this board requires a resident loader, install it. */
#ifdef DSP_56361
- if ((i = install_resident_loader(chip)) < 0)
+ i = install_resident_loader(chip);
+ if (i < 0)
return i;
#endif
@@ -495,7 +496,8 @@ static int load_firmware(struct echoaudio *chip)
/* See if the ASIC is present and working - only if the DSP is already loaded */
if (chip->dsp_code) {
- if ((box_type = check_asic_status(chip)) >= 0)
+ box_type = check_asic_status(chip);
+ if (box_type >= 0)
return box_type;
/* ASIC check failed; force the DSP to reload */
chip->dsp_code = NULL;
@@ -509,7 +511,8 @@ static int load_firmware(struct echoaudio *chip)
if (err < 0)
return err;
- if ((box_type = load_asic(chip)) < 0)
+ box_type = load_asic(chip);
+ if (box_type < 0)
return box_type; /* error */
return box_type;
@@ -667,7 +670,8 @@ static int restore_dsp_rettings(struct echoaudio *chip)
{
int i, o, err;
- if ((err = check_asic_status(chip)) < 0)
+ err = check_asic_status(chip);
+ if (err < 0)
return err;
/* Gina20/Darla20 only. Should be harmless for other cards. */
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c
index eea6fe530ab4..248983fa2959 100644
--- a/sound/pci/echoaudio/echoaudio_gml.c
+++ b/sound/pci/echoaudio/echoaudio_gml.c
@@ -194,7 +194,8 @@ static int set_professional_spdif(struct echoaudio *chip, char prof)
}
}
- if ((err = write_control_reg(chip, control_reg, false)))
+ err = write_control_reg(chip, control_reg, false);
+ if (err)
return err;
chip->professional_spdif = prof;
dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
index b2377573de09..c93939850357 100644
--- a/sound/pci/echoaudio/gina20_dsp.c
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -40,7 +40,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -58,7 +59,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
ECHO_CLOCK_BIT_SPDIF;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 8eff2b4f5ceb..56e9d1b9b330 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -44,7 +44,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -74,7 +75,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
}
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
index c97dc83bbbdf..16eb082df56a 100644
--- a/sound/pci/echoaudio/indigo_dsp.c
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -41,7 +41,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -56,7 +57,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->asic_loaded = true;
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
index 2428b35f45d6..17a1d888d0b9 100644
--- a/sound/pci/echoaudio/indigodj_dsp.c
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -41,7 +41,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -56,7 +57,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->asic_loaded = true;
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
index 79b68ba70936..791787aa0744 100644
--- a/sound/pci/echoaudio/indigoio_dsp.c
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -41,7 +41,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -56,7 +57,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->asic_loaded = true;
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
index 5e5b6e288a2d..5fb5c4a4598b 100644
--- a/sound/pci/echoaudio/layla20_dsp.c
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -60,7 +61,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->output_clock_types =
ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index c02bc1dcc170..ef27805d63f6 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -62,11 +63,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
- if ((err = init_line_levels(chip)) < 0)
+ err = init_line_levels(chip);
+ if (err < 0)
return err;
return err;
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
index 8f612a09c5d0..8a4dffc68889 100644
--- a/sound/pci/echoaudio/mia_dsp.c
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -44,7 +44,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -62,7 +63,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
ECHO_CLOCK_BIT_SPDIF;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
index 6045a115cffe..cb72d27e809e 100644
--- a/sound/pci/echoaudio/midi.c
+++ b/sound/pci/echoaudio/midi.c
@@ -308,8 +308,8 @@ static int snd_echo_midi_create(struct snd_card *card,
{
int err;
- if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1,
- &chip->rmidi)) < 0)
+ err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, &chip->rmidi);
+ if (err < 0)
return err;
strcpy(chip->rmidi->name, card->shortname);
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index f77db83dd73d..f8e7bb6ce040 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -44,7 +44,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
return -ENODEV;
- if ((err = init_dsp_comm_page(chip))) {
+ err = init_dsp_comm_page(chip);
+ if (err) {
dev_err(chip->card->dev,
"init_hw - could not initialize DSP comm page\n");
return err;
@@ -67,7 +68,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
else
chip->dsp_code_to_load = FW_MONA_301_DSP;
- if ((err = load_firmware(chip)) < 0)
+ err = load_firmware(chip);
+ if (err < 0)
return err;
chip->bad_board = false;
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 45833bc2a7e7..887bfb3c1e17 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -107,18 +107,22 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
max_buffer_size[dev] = 32;
else if (max_buffer_size[dev] > 1024)
max_buffer_size[dev] = 1024;
- if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
- (long)max_buffer_size[dev] * 1024 * 1024,
- enable_ir[dev], subsystem[dev],
- &emu)) < 0)
+ err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
+ (long)max_buffer_size[dev] * 1024 * 1024,
+ enable_ir[dev], subsystem[dev],
+ &emu);
+ if (err < 0)
goto error;
card->private_data = emu;
emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
- if ((err = snd_emu10k1_pcm(emu, 0)) < 0)
+ err = snd_emu10k1_pcm(emu, 0);
+ if (err < 0)
goto error;
- if ((err = snd_emu10k1_pcm_mic(emu, 1)) < 0)
+ err = snd_emu10k1_pcm_mic(emu, 1);
+ if (err < 0)
goto error;
- if ((err = snd_emu10k1_pcm_efx(emu, 2)) < 0)
+ err = snd_emu10k1_pcm_efx(emu, 2);
+ if (err < 0)
goto error;
/* This stores the periods table. */
if (emu->card_capabilities->ca0151_chip) { /* P16V */
@@ -128,26 +132,33 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
goto error;
}
- if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0)
+ err = snd_emu10k1_mixer(emu, 0, 3);
+ if (err < 0)
goto error;
- if ((err = snd_emu10k1_timer(emu, 0)) < 0)
+ err = snd_emu10k1_timer(emu, 0);
+ if (err < 0)
goto error;
- if ((err = snd_emu10k1_pcm_multi(emu, 3)) < 0)
+ err = snd_emu10k1_pcm_multi(emu, 3);
+ if (err < 0)
goto error;
if (emu->card_capabilities->ca0151_chip) { /* P16V */
- if ((err = snd_p16v_pcm(emu, 4)) < 0)
+ err = snd_p16v_pcm(emu, 4);
+ if (err < 0)
goto error;
}
if (emu->audigy) {
- if ((err = snd_emu10k1_audigy_midi(emu)) < 0)
+ err = snd_emu10k1_audigy_midi(emu);
+ if (err < 0)
goto error;
} else {
- if ((err = snd_emu10k1_midi(emu)) < 0)
+ err = snd_emu10k1_midi(emu);
+ if (err < 0)
goto error;
}
- if ((err = snd_emu10k1_fx8010_new(emu, 0)) < 0)
+ err = snd_emu10k1_fx8010_new(emu, 0);
+ if (err < 0)
goto error;
#ifdef ENABLE_SYNTH
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
@@ -174,7 +185,8 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
"%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto error;
if (emu->card_capabilities->emu_model)
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 07471c3dcbed..dba1e9fc2eec 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -90,7 +90,8 @@ snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw)
if (best[i].voice >= 0) {
int ch;
vp = &emu->voices[best[i].voice];
- if ((ch = vp->ch) < 0) {
+ ch = vp->ch;
+ if (ch < 0) {
/*
dev_warn(emu->card->dev,
"synth_get_voice: ch < 0 (%d) ??", i);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index d9a12cd01647..89b0f3884067 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -349,7 +349,8 @@ static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voi
{
struct emu10k1x_pcm *epcm;
- if ((epcm = voice->epcm) == NULL)
+ epcm = voice->epcm;
+ if (!epcm)
return;
if (epcm->substream == NULL)
return;
@@ -371,10 +372,11 @@ static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
- }
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+ err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
+ if (err < 0)
return err;
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -550,10 +552,12 @@ static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
- return err;
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
+ if (err < 0)
+ return err;
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
@@ -722,7 +726,8 @@ static int snd_emu10k1x_ac97(struct emu10k1x *chip)
.read = snd_emu10k1x_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
pbus->no_vra = 1; /* we don't need VRA */
@@ -838,7 +843,8 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
if (device == 0)
capture = 1;
- if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
@@ -891,7 +897,8 @@ static int snd_emu10k1x_create(struct snd_card *card,
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28)) < 0) {
@@ -914,8 +921,8 @@ static int snd_emu10k1x_create(struct snd_card *card,
spin_lock_init(&chip->voice_lock);
chip->port = pci_resource_start(pci, 0);
- if ((chip->res_port = request_region(chip->port, 8,
- "EMU10K1X")) == NULL) {
+ chip->res_port = request_region(chip->port, 8, "EMU10K1X");
+ if (!chip->res_port) {
dev_err(card->dev, "cannot allocate the port 0x%lx\n",
chip->port);
snd_emu10k1x_free(chip);
@@ -991,8 +998,8 @@ static int snd_emu10k1x_create(struct snd_card *card,
outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_emu10k1x_free(chip);
return err;
}
@@ -1171,17 +1178,23 @@ static int snd_emu10k1x_mixer(struct emu10k1x *emu)
struct snd_kcontrol *kctl;
struct snd_card *card = emu->card;
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
return 0;
@@ -1488,7 +1501,8 @@ static int emu10k1x_midi_init(struct emu10k1x *emu,
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi);
+ if (err < 0)
return err;
midi->emu = emu;
spin_lock_init(&midi->open_lock);
@@ -1511,7 +1525,8 @@ static int snd_emu10k1x_midi(struct emu10k1x *emu)
struct emu10k1x_midi *midi = &emu->midi;
int err;
- if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
+ err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)");
+ if (err < 0)
return err;
midi->tx_enable = INTE_MIDITXENABLE;
@@ -1543,35 +1558,42 @@ static int snd_emu10k1x_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
+ err = snd_emu10k1x_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_pcm(chip, 0)) < 0) {
+ err = snd_emu10k1x_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_pcm(chip, 1)) < 0) {
+ err = snd_emu10k1x_pcm(chip, 1);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_pcm(chip, 2)) < 0) {
+ err = snd_emu10k1x_pcm(chip, 2);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_ac97(chip)) < 0) {
+ err = snd_emu10k1x_ac97(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_mixer(chip)) < 0) {
+ err = snd_emu10k1x_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_emu10k1x_midi(chip)) < 0) {
+ err = snd_emu10k1x_midi(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1583,7 +1605,8 @@ static int snd_emu10k1x_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx irq %i",
card->shortname, chip->port, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 80ef62a4a7c0..6cf7c8b1de47 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -436,7 +436,8 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
unsigned long flags;
spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
- if ((tmp = emu->fx8010.irq_handlers) == irq) {
+ tmp = emu->fx8010.irq_handlers;
+ if (tmp == irq) {
emu->fx8010.irq_handlers = tmp->next;
if (emu->fx8010.irq_handlers == NULL) {
snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
@@ -871,7 +872,9 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
}
knew.private_value = (unsigned long)ctl;
*ctl = *nctl;
- if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
+ kctl = snd_ctl_new1(&knew, emu);
+ err = snd_ctl_add(emu->card, kctl);
+ if (err < 0) {
kfree(ctl);
kfree(knew.tlv.p);
goto __error;
@@ -2403,7 +2406,8 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
while (ptr < 0x200)
OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
- if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
+ err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size);
+ if (err < 0)
goto __err;
icode->gpr_add_control_count = i;
icode->gpr_add_controls = controls;
@@ -2681,7 +2685,8 @@ int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
struct snd_hwdep *hw;
int err;
- if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
+ err = snd_hwdep_new(emu->card, "FX8010", device, &hw);
+ if (err < 0)
return err;
strcpy(hw->name, "EMU10K1 (FX8010)");
hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 8a6cbe67e29d..e9c0fe3b8446 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1119,7 +1119,8 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
tmp = reg & ~A_SPDIF_RATE_MASK;
tmp |= val;
- if ((change = (tmp != reg)))
+ change = (tmp != reg);
+ if (change)
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
spin_unlock_irqrestore(&emu->reg_lock, flags);
return change;
@@ -1903,7 +1904,8 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
.read = snd_emu10k1_ac97_read,
};
- if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
pbus->no_vra = 1; /* we don't need VRA */
@@ -1911,7 +1913,8 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
ac97.private_data = emu;
ac97.private_free = snd_emu10k1_mixer_free_ac97;
ac97.scaps = AC97_SCAP_NO_SPDIF;
- if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &emu->ac97);
+ if (err < 0) {
if (emu->card_capabilities->ac97_chip == 1)
return err;
dev_info(emu->card->dev,
@@ -1991,38 +1994,50 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
rename_ctl(card, "Aux2 Capture Volume", "Line3 Capture Volume");
rename_ctl(card, "Mic Capture Volume", "Unknown1 Capture Volume");
}
- if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
+ kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
+ kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
+ kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
+ kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
+ kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
+ kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu);
+ if (!kctl)
return -ENOMEM;
kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
/* initialize the routing and volume table for each pcm playback stream */
@@ -2069,42 +2084,53 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
/* sb live! and audigy */
- if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu);
+ if (!kctl)
return -ENOMEM;
if (!emu->audigy)
kctl->id.device = emu->pcm_efx->device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu);
+ if (!kctl)
return -ENOMEM;
if (!emu->audigy)
kctl->id.device = emu->pcm_efx->device;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
}
if (emu->card_capabilities->emu_model) {
; /* Disable the snd_audigy_spdif_shared_spdif */
} else if (emu->audigy) {
- if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
#if 0
- if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
#endif
} else if (! emu->card_capabilities->ecard) {
/* sb live! */
- if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
+ kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu);
+ if (!kctl)
return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
+ err = snd_ctl_add(card, kctl);
+ if (err)
return err;
}
if (emu->card_capabilities->ca0151_chip) { /* P16V */
- if ((err = snd_p16v_mixer(emu)))
+ err = snd_p16v_mixer(emu);
+ if (err)
return err;
}
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index b62c95150702..3ce9b2129ce6 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -319,7 +319,8 @@ static int emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *m
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi);
+ if (err < 0)
return err;
midi->emu = emu;
spin_lock_init(&midi->open_lock);
@@ -342,7 +343,8 @@ int snd_emu10k1_midi(struct snd_emu10k1 *emu)
struct snd_emu10k1_midi *midi = &emu->midi;
int err;
- if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
+ err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)");
+ if (err < 0)
return err;
midi->tx_enable = INTE_MIDITXENABLE;
@@ -360,7 +362,8 @@ int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
int err;
midi = &emu->midi;
- if ((err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)")) < 0)
+ err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)");
+ if (err < 0)
return err;
midi->tx_enable = INTE_MIDITXENABLE;
@@ -371,7 +374,8 @@ int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
midi->interrupt = snd_emu10k1_midi_interrupt;
midi = &emu->midi2;
- if ((err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2")) < 0)
+ err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2");
+ if (err < 0)
return err;
midi->tx_enable = INTE_A_MIDITXENABLE2;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index b2ddabb99438..b2701a4452d8 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -25,7 +25,8 @@ static void snd_emu10k1_pcm_interrupt(struct snd_emu10k1 *emu,
{
struct snd_emu10k1_pcm *epcm;
- if ((epcm = voice->epcm) == NULL)
+ epcm = voice->epcm;
+ if (!epcm)
return;
if (epcm->substream == NULL)
return;
@@ -399,7 +400,8 @@ static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream,
size_t alloc_size;
int err;
- if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
+ err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params));
+ if (err < 0)
return err;
alloc_size = params_buffer_bytes(hw_params);
@@ -1124,11 +1126,13 @@ static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream)
runtime->private_data = epcm;
runtime->private_free = snd_emu10k1_pcm_free_substream;
runtime->hw = snd_emu10k1_playback;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0) {
kfree(epcm);
return err;
}
- if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) {
+ err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
+ if (err < 0) {
kfree(epcm);
return err;
}
@@ -1380,7 +1384,8 @@ int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
@@ -1412,7 +1417,8 @@ int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device)
struct snd_pcm_substream *substream;
int err;
- if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
@@ -1446,7 +1452,8 @@ int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
@@ -1774,7 +1781,8 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device)
struct snd_kcontrol *kctl;
int err;
- if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 288e0fd2e47d..9d26535f3fa3 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -169,16 +169,20 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
struct snd_emu10k1_memblk *q;
/* calculate the expected size of empty region */
- if ((p = blk->mapped_link.prev) != &emu->mapped_link_head) {
+ p = blk->mapped_link.prev;
+ if (p != &emu->mapped_link_head) {
q = get_emu10k1_memblk(p, mapped_link);
start_page = q->mapped_page + q->pages;
- } else
+ } else {
start_page = 1;
- if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
+ }
+ p = blk->mapped_link.next;
+ if (p != &emu->mapped_link_head) {
q = get_emu10k1_memblk(p, mapped_link);
end_page = q->mapped_page;
- } else
+ } else {
end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
+ }
/* remove links */
list_del(&blk->mapped_link);
@@ -267,7 +271,8 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
spin_unlock_irqrestore(&emu->memblk_lock, flags);
return 0;
}
- if ((err = map_memblk(emu, blk)) < 0) {
+ err = map_memblk(emu, blk);
+ if (err < 0) {
/* no enough page - try to unmap some blocks */
/* starting from the oldest block */
p = emu->mapped_order_link_head.next;
@@ -454,13 +459,15 @@ static void get_single_page_range(struct snd_util_memhdr *hdr,
struct snd_emu10k1_memblk *q;
int first_page, last_page;
first_page = blk->first_page;
- if ((p = blk->mem.list.prev) != &hdr->block) {
+ p = blk->mem.list.prev;
+ if (p != &hdr->block) {
q = get_emu10k1_memblk(p, mem.list);
if (q->last_page == first_page)
first_page++; /* first page was already allocated */
}
last_page = blk->last_page;
- if ((p = blk->mem.list.next) != &hdr->block) {
+ p = blk->mem.list.next;
+ if (p != &hdr->block) {
q = get_emu10k1_memblk(p, mem.list);
if (q->first_page == last_page)
last_page--; /* last page was already allocated */
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 1099f102b365..ff2a3974c824 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -194,7 +194,8 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea
#endif /* debug */
/* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
runtime->sync.id32[0] = substream->pcm->card->number;
@@ -242,7 +243,8 @@ static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream
#endif /* debug */
/* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
return 0;
@@ -589,7 +591,8 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device)
/* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */
emu->p16v_device_offset = device;
- if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
+ err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm);
+ if (err < 0)
return err;
pcm->private_data = emu;
@@ -808,8 +811,8 @@ int snd_p16v_mixer(struct snd_emu10k1 *emu)
struct snd_card *card = emu->card;
for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
- emu))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i], emu));
+ if (err < 0)
return err;
}
return 0;
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
index c2803000aace..2435d3ba68f7 100644
--- a/sound/pci/emu10k1/timer.c
+++ b/sound/pci/emu10k1/timer.c
@@ -72,7 +72,8 @@ int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
tid.card = emu->card->number;
tid.device = device;
tid.subdevice = 0;
- if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
+ err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer);
+ if (err >= 0) {
strcpy(timer->name, "EMU10K1 timer");
timer->private_data = emu;
timer->hw = snd_emu10k1_timer_hw;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 3ccccdbc0029..728b69dad21b 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -672,7 +672,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
}
/* now wait for the stinkin' data (RDY) */
for (t = 0; t < POLL_COUNT; t++) {
- if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
+ x = inl(ES_REG(ensoniq, 1371_CODEC));
+ if (x & ES_1371_CODEC_RDY) {
if (is_ev1938(ensoniq)) {
for (t = 0; t < 100; t++)
inl(ES_REG(ensoniq, CONTROL));
@@ -1594,7 +1595,8 @@ static int snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
.wait = snd_es1371_codec_wait,
};
- if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
@@ -1602,7 +1604,8 @@ static int snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
ac97.private_free = snd_ensoniq_mixer_free_ac97;
ac97.pci = ensoniq->pci;
ac97.scaps = AC97_SCAP_AUDIO;
- if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97);
+ if (err < 0)
return err;
if (has_spdif > 0 ||
(!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) {
@@ -1722,7 +1725,8 @@ static int snd_ensoniq_1370_mixer(struct ensoniq *ensoniq)
ak4531.write = snd_es1370_codec_write;
ak4531.private_data = ensoniq;
ak4531.private_free = snd_ensoniq_mixer_free_ak4531;
- if ((err = snd_ak4531_mixer(card, &ak4531, &ensoniq->u.es1370.ak4531)) < 0)
+ err = snd_ak4531_mixer(card, &ak4531, &ensoniq->u.es1370.ak4531);
+ if (err < 0)
return err;
for (idx = 0; idx < ES1370_CONTROLS; idx++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_es1370_controls[idx], ensoniq));
@@ -2038,7 +2042,8 @@ static int snd_ensoniq_create(struct snd_card *card,
};
*rensoniq = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
if (ensoniq == NULL) {
@@ -2050,7 +2055,8 @@ static int snd_ensoniq_create(struct snd_card *card,
ensoniq->card = card;
ensoniq->pci = pci;
ensoniq->irq = -1;
- if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
+ err = pci_request_regions(pci, "Ensoniq AudioPCI");
+ if (err < 0) {
kfree(ensoniq);
pci_disable_device(pci);
return err;
@@ -2095,7 +2101,8 @@ static int snd_ensoniq_create(struct snd_card *card,
snd_ensoniq_chip_init(ensoniq);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops);
+ if (err < 0) {
snd_ensoniq_free(ensoniq);
return err;
}
@@ -2286,7 +2293,8 @@ static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device)
struct snd_rawmidi *rmidi;
int err;
- if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
+ err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi);
+ if (err < 0)
return err;
strcpy(rmidi->name, CHIP_NAME);
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
@@ -2357,33 +2365,39 @@ static int snd_audiopci_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) {
+ err = snd_ensoniq_create(card, pci, &ensoniq);
+ if (err < 0) {
snd_card_free(card);
return err;
}
card->private_data = ensoniq;
#ifdef CHIP1370
- if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) {
+ err = snd_ensoniq_1370_mixer(ensoniq);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#endif
#ifdef CHIP1371
- if ((err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev])) < 0) {
+ err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev]);
+ if (err < 0) {
snd_card_free(card);
return err;
}
#endif
- if ((err = snd_ensoniq_pcm(ensoniq, 0)) < 0) {
+ err = snd_ensoniq_pcm(ensoniq, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_ensoniq_pcm2(ensoniq, 1)) < 0) {
+ err = snd_ensoniq_pcm2(ensoniq, 1);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_ensoniq_midi(ensoniq, 0)) < 0) {
+ err = snd_ensoniq_midi(ensoniq, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2399,7 +2413,8 @@ static int snd_audiopci_probe(struct pci_dev *pci,
ensoniq->port,
ensoniq->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index afc66347d162..33b1eb347a27 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -293,7 +293,8 @@ static void snd_es1938_write_cmd(struct es1938 *chip, unsigned char cmd)
int i;
unsigned char v;
for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {
- if (!(v = inb(SLSB_REG(chip, READSTATUS)) & 0x80)) {
+ v = inb(SLSB_REG(chip, READSTATUS));
+ if (!(v & 0x80)) {
outb(cmd, SLSB_REG(chip, WRITEDATA));
return;
}
@@ -309,9 +310,11 @@ static int snd_es1938_get_byte(struct es1938 *chip)
{
int i;
unsigned char v;
- for (i = GET_LOOP_TIMEOUT; i; i--)
- if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
+ for (i = GET_LOOP_TIMEOUT; i; i--) {
+ v = inb(SLSB_REG(chip, STATUS));
+ if (v & 0x80)
return inb(SLSB_REG(chip, READDATA));
+ }
dev_err(chip->card->dev, "get_byte timeout: status 0x02%x\n", v);
return -ENODEV;
}
@@ -993,7 +996,8 @@ static int snd_es1938_new_pcm(struct es1938 *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm);
+ if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
@@ -1553,7 +1557,8 @@ static int snd_es1938_create(struct snd_card *card,
*rchip = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
@@ -1573,7 +1578,8 @@ static int snd_es1938_create(struct snd_card *card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
+ err = pci_request_regions(pci, "ESS Solo-1");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1599,7 +1605,8 @@ static int snd_es1938_create(struct snd_card *card,
snd_es1938_chip_init(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_es1938_free(chip);
return err;
}
@@ -1731,7 +1738,8 @@ static int snd_es1938_mixer(struct es1938 *chip)
kctl->private_free = snd_es1938_hwv_free;
break;
}
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
return 0;
@@ -1765,7 +1773,8 @@ static int snd_es1938_probe(struct pci_dev *pci,
return -ENODEV;
}
}
- if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
+ err = snd_es1938_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1778,11 +1787,13 @@ static int snd_es1938_probe(struct pci_dev *pci,
chip->revision,
chip->irq);
- if ((err = snd_es1938_new_pcm(chip, 0)) < 0) {
+ err = snd_es1938_new_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_es1938_mixer(chip)) < 0) {
+ err = snd_es1938_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1793,11 +1804,13 @@ static int snd_es1938_probe(struct pci_dev *pci,
dev_err(card->dev, "OPL3 not detected at 0x%lx\n",
SLSB_REG(chip, FMLOWADDR));
} else {
- if ((err = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
+ err = snd_opl3_timer_new(opl3, 0, 1);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1815,7 +1828,8 @@ static int snd_es1938_probe(struct pci_dev *pci,
snd_es1938_create_gameport(chip);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 5fa1861236f5..c038c1035c39 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1600,7 +1600,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
es->mode = ESM_MODE_CAPTURE;
/* get mixbuffer */
- if ((es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE)) == NULL) {
+ es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE);
+ if (!es->mixbuf) {
snd_es1968_free_apu_pair(chip, apu1);
snd_es1968_free_apu_pair(chip, apu2);
kfree(es);
@@ -1695,11 +1696,13 @@ static void es1968_measure_clock(struct es1968 *chip)
chip->clock = 48000; /* default clock value */
/* search 2 APUs (although one apu is enough) */
- if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
+ apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY);
+ if (apu < 0) {
dev_err(chip->card->dev, "Hmm, cannot find empty APU pair!?\n");
return;
}
- if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
+ memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE);
+ if (!memory) {
dev_warn(chip->card->dev,
"cannot allocate dma buffer - using default clock %d\n",
chip->clock);
@@ -1791,7 +1794,8 @@ snd_es1968_pcm(struct es1968 *chip, int device)
int err;
/* get DMA buffer */
- if ((err = snd_es1968_init_dmabuf(chip)) < 0)
+ err = snd_es1968_init_dmabuf(chip);
+ if (err < 0)
return err;
/* set PCMBAR */
@@ -1800,9 +1804,10 @@ snd_es1968_pcm(struct es1968 *chip, int device)
wave_set_register(chip, 0x01FE, chip->dma.addr >> 12);
wave_set_register(chip, 0x01FF, chip->dma.addr >> 12);
- if ((err = snd_pcm_new(chip->card, "ESS Maestro", device,
- chip->playback_streams,
- chip->capture_streams, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "ESS Maestro", device,
+ chip->playback_streams,
+ chip->capture_streams, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1953,7 +1958,8 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
struct es1968 *chip = dev_id;
u32 event;
- if (!(event = inb(chip->io_port + 0x1A)))
+ event = inb(chip->io_port + 0x1A);
+ if (!event)
return IRQ_NONE;
outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
@@ -2008,13 +2014,15 @@ snd_es1968_mixer(struct es1968 *chip)
.read = snd_es1968_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
pbus->no_vra = 1; /* ES1968 doesn't need VRA */
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
#ifndef CONFIG_SND_ES1968_INPUT
@@ -2661,7 +2669,8 @@ static int snd_es1968_create(struct snd_card *card,
*chip_ret = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) {
@@ -2692,7 +2701,8 @@ static int snd_es1968_create(struct snd_card *card,
chip->playback_streams = play_streams;
chip->capture_streams = capt_streams;
- if ((err = pci_request_regions(pci, "ESS Maestro")) < 0) {
+ err = pci_request_regions(pci, "ESS Maestro");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -2739,7 +2749,8 @@ static int snd_es1968_create(struct snd_card *card,
snd_es1968_chip_init(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_es1968_free(chip);
return err;
}
@@ -2804,14 +2815,15 @@ static int snd_es1968_probe(struct pci_dev *pci,
total_bufsize[dev] = 128;
if (total_bufsize[dev] > 4096)
total_bufsize[dev] = 4096;
- if ((err = snd_es1968_create(card, pci,
- total_bufsize[dev] * 1024, /* in bytes */
- pcm_substreams_p[dev],
- pcm_substreams_c[dev],
- pci_id->driver_data,
- use_pm[dev],
- radio_nr[dev],
- &chip)) < 0) {
+ err = snd_es1968_create(card, pci,
+ total_bufsize[dev] * 1024, /* in bytes */
+ pcm_substreams_p[dev],
+ pcm_substreams_c[dev],
+ pci_id->driver_data,
+ use_pm[dev],
+ radio_nr[dev],
+ &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2832,12 +2844,14 @@ static int snd_es1968_probe(struct pci_dev *pci,
break;
}
- if ((err = snd_es1968_pcm(chip, 0)) < 0) {
+ err = snd_es1968_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_es1968_mixer(chip)) < 0) {
+ err = snd_es1968_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2855,13 +2869,13 @@ static int snd_es1968_probe(struct pci_dev *pci,
}
}
if (enable_mpu[dev]) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- chip->io_port + ESM_MPU401_PORT,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
+ chip->io_port + ESM_MPU401_PORT,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &chip->rmidi);
+ if (err < 0)
dev_warn(card->dev, "skipping MPU-401 MIDI support..\n");
- }
}
snd_es1968_create_gameport(chip, dev);
@@ -2882,7 +2896,8 @@ static int snd_es1968_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->io_port, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 6279eb156e36..ed9dae87145b 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -659,7 +659,8 @@ static int snd_fm801_playback_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_CHANNELS,
&hw_constraints_channels);
}
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
return 0;
}
@@ -674,7 +675,8 @@ static int snd_fm801_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_fm801_capture;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&hw_constraints_rates);
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
return 0;
}
@@ -717,7 +719,8 @@ static int snd_fm801_pcm(struct fm801 *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm);
+ if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_fm801_playback_ops);
@@ -985,7 +988,8 @@ static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
struct fm801 *chip = snd_kcontrol_chip(kcontrol);
unsigned short val;
- if ((val = ucontrol->value.enumerated.item[0]) > 4)
+ val = ucontrol->value.enumerated.item[0];
+ if (val > 4)
return -EINVAL;
return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
}
@@ -1050,19 +1054,22 @@ static int snd_fm801_mixer(struct fm801 *chip)
.read = snd_fm801_codec_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_fm801_mixer_free_ac97_bus;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_fm801_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
if (chip->secondary) {
ac97.num = 1;
ac97.addr = chip->secondary_addr;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec);
+ if (err < 0)
return err;
}
for (i = 0; i < FM801_CONTROLS; i++) {
@@ -1213,7 +1220,8 @@ static int snd_fm801_create(struct snd_card *card,
};
*rchip = NULL;
- if ((err = pcim_enable_device(pci)) < 0)
+ err = pcim_enable_device(pci);
+ if (err < 0)
return err;
chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
@@ -1223,7 +1231,8 @@ static int snd_fm801_create(struct snd_card *card,
chip->dev = &pci->dev;
chip->irq = -1;
chip->tea575x_tuner = tea575x_tuner;
- if ((err = pci_request_regions(pci, "FM801")) < 0)
+ err = pci_request_regions(pci, "FM801");
+ if (err < 0)
return err;
chip->port = pci_resource_start(pci, 0);
@@ -1254,7 +1263,8 @@ static int snd_fm801_create(struct snd_card *card,
snd_fm801_chip_init(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_fm801_free(chip);
return err;
}
@@ -1327,7 +1337,8 @@ static int snd_card_fm801_probe(struct pci_dev *pci,
0, &card);
if (err < 0)
return err;
- if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
+ err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1342,35 +1353,41 @@ static int snd_card_fm801_probe(struct pci_dev *pci,
if (chip->tea575x_tuner & TUNER_ONLY)
goto __fm801_tuner_only;
- if ((err = snd_fm801_pcm(chip, 0)) < 0) {
+ err = snd_fm801_pcm(chip, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_fm801_mixer(chip)) < 0) {
+ err = snd_fm801_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
- chip->port + FM801_MPU401_DATA,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
+ chip->port + FM801_MPU401_DATA,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &chip->rmidi);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_create(card, chip->port + FM801_OPL3_BANK0,
- chip->port + FM801_OPL3_BANK1,
- OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) {
+ err = snd_opl3_create(card, chip->port + FM801_OPL3_BANK0,
+ chip->port + FM801_OPL3_BANK1,
+ OPL3_HW_OPL3_FM801, 1, &opl3);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
__fm801_tuner_only:
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 17a25e453f60..e8dee24c309d 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -167,8 +167,11 @@ static void hda_codec_driver_shutdown(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
- if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
- codec->patch_ops.reboot_notify(codec);
+ if (!pm_runtime_suspended(dev)) {
+ if (codec->patch_ops.reboot_notify)
+ codec->patch_ops.reboot_notify(codec);
+ snd_hda_codec_display_power(codec, false);
+ }
}
int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 5462f771c2f9..7a717e151156 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -798,7 +798,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
unsigned int power_state);
/* enable/disable display power per codec */
-static void codec_display_power(struct hda_codec *codec, bool enable)
+void snd_hda_codec_display_power(struct hda_codec *codec, bool enable)
{
if (codec->display_power_control)
snd_hdac_display_power(&codec->bus->core, codec->addr, enable);
@@ -810,7 +810,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
if (codec->registered)
return;
if (device_is_registered(hda_codec_dev(codec))) {
- codec_display_power(codec, true);
+ snd_hda_codec_display_power(codec, true);
pm_runtime_enable(hda_codec_dev(codec));
/* it was powered up in snd_hda_codec_new(), now all done */
snd_hda_power_down(codec);
@@ -836,7 +836,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
*/
if (codec->core.type == HDA_DEV_LEGACY)
snd_hdac_device_unregister(&codec->core);
- codec_display_power(codec, false);
+ snd_hda_codec_display_power(codec, false);
/*
* In the case of ASoC HD-audio bus, the device refcount is released in
@@ -2893,7 +2893,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
(codec_has_clkstop(codec) && codec_has_epss(codec) &&
(state & AC_PWRST_CLK_STOP_OK)))
snd_hdac_codec_link_down(&codec->core);
- codec_display_power(codec, false);
+ snd_hda_codec_display_power(codec, false);
return 0;
}
@@ -2905,7 +2905,7 @@ static int hda_codec_runtime_resume(struct device *dev)
if (!codec->card)
return 0;
- codec_display_power(codec, true);
+ snd_hda_codec_display_power(codec, true);
snd_hdac_codec_link_up(&codec->core);
hda_call_codec_resume(codec);
pm_runtime_mark_last_busy(dev);
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1f8018f9ce57..e97d00585e8e 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -1433,7 +1433,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
path = snd_hda_add_new_path(codec, dac, pin, 0);
}
if (!path) {
- dac = dacs[i] = 0;
+ dacs[i] = 0;
badness += bad->no_dac;
} else {
/* print_nid_path(codec, "output", path); */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 470753b36c8a..0322b289505e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -883,6 +883,14 @@ static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev)
return azx_get_pos_posbuf(chip, azx_dev);
}
+static void azx_shutdown_chip(struct azx *chip)
+{
+ azx_stop_chip(chip);
+ azx_enter_link_reset(chip);
+ azx_clear_irq_pending(chip);
+ display_power(chip, false);
+}
+
#ifdef CONFIG_PM
static DEFINE_MUTEX(card_list_lock);
static LIST_HEAD(card_list);
@@ -942,14 +950,6 @@ static bool azx_is_pm_ready(struct snd_card *card)
return true;
}
-static void __azx_runtime_suspend(struct azx *chip)
-{
- azx_stop_chip(chip);
- azx_enter_link_reset(chip);
- azx_clear_irq_pending(chip);
- display_power(chip, false);
-}
-
static void __azx_runtime_resume(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
@@ -1028,7 +1028,7 @@ static int azx_suspend(struct device *dev)
chip = card->private_data;
bus = azx_bus(chip);
- __azx_runtime_suspend(chip);
+ azx_shutdown_chip(chip);
if (bus->irq >= 0) {
free_irq(bus->irq, chip);
bus->irq = -1;
@@ -1107,7 +1107,7 @@ static int azx_runtime_suspend(struct device *dev)
/* enable controller wake up event */
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | STATESTS_INT_MASK);
- __azx_runtime_suspend(chip);
+ azx_shutdown_chip(chip);
trace_azx_runtime_suspend(chip);
return 0;
}
@@ -2385,7 +2385,7 @@ static void azx_shutdown(struct pci_dev *pci)
return;
chip = card->private_data;
if (chip && chip->running)
- azx_stop_chip(chip);
+ azx_shutdown_chip(chip);
}
/* PCI IDs */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 4c5589c10f1d..8d2503e8dad8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -709,6 +709,8 @@ void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
+void snd_hda_codec_display_power(struct hda_codec *codec, bool enable);
+
/*
*/
#define codec_err(codec, fmt, args...) \
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 6f2b743b9d75..ea700395bef4 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -235,11 +235,9 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev)
{
struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
struct hdac_bus *bus = azx_bus(chip);
- struct device *dev = hda->dev;
struct resource *res;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hda->regs = devm_ioremap_resource(dev, res);
+ hda->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(hda->regs))
return PTR_ERR(hda->regs);
@@ -262,6 +260,9 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
const char *sname, *drv_name = "tegra-hda";
struct device_node *np = pdev->dev.of_node;
+ if (irq_id < 0)
+ return irq_id;
+
err = hda_tegra_init_chip(chip, pdev);
if (err)
return err;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 49b4fdd2feab..b66e7bdbf483 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7598,7 +7598,7 @@ static void ca0132_alt_free_active_dma_channels(struct hda_codec *codec)
*/
static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
{
- const unsigned int dsp_dma_stream_ids[] = { 0x0c, 0x03, 0x04 };
+ static const unsigned int dsp_dma_stream_ids[] = { 0x0c, 0x03, 0x04 };
struct ca0132_spec *spec = codec->spec;
unsigned int i, tmp;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ab5113cccffa..1389cfd5e0db 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -385,6 +385,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
fallthrough;
case 0x10ec0215:
+ case 0x10ec0230:
case 0x10ec0233:
case 0x10ec0235:
case 0x10ec0236:
@@ -3054,6 +3055,7 @@ enum {
ALC269_TYPE_ALC257,
ALC269_TYPE_ALC215,
ALC269_TYPE_ALC225,
+ ALC269_TYPE_ALC287,
ALC269_TYPE_ALC294,
ALC269_TYPE_ALC300,
ALC269_TYPE_ALC623,
@@ -3090,6 +3092,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
case ALC269_TYPE_ALC257:
case ALC269_TYPE_ALC215:
case ALC269_TYPE_ALC225:
+ case ALC269_TYPE_ALC287:
case ALC269_TYPE_ALC294:
case ALC269_TYPE_ALC300:
case ALC269_TYPE_ALC623:
@@ -3153,6 +3156,7 @@ static void alc_disable_headset_jack_key(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x48, 0x0);
@@ -3180,6 +3184,7 @@ static void alc_enable_headset_jack_key(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x48, 0xd011);
@@ -3558,12 +3563,70 @@ static void alc256_shutup(struct hda_codec *codec)
}
}
+static void alc285_hp_init(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_pin = alc_get_hp_pin(spec);
+ int i, val;
+ int coef38, coef0d, coef36;
+
+ alc_update_coef_idx(codec, 0x4a, 1<<15, 1<<15); /* Reset HP JD */
+ coef38 = alc_read_coef_idx(codec, 0x38); /* Amp control */
+ coef0d = alc_read_coef_idx(codec, 0x0d); /* Digital Misc control */
+ coef36 = alc_read_coef_idx(codec, 0x36); /* Passthrough Control */
+ alc_update_coef_idx(codec, 0x38, 1<<4, 0x0);
+ alc_update_coef_idx(codec, 0x0d, 0x110, 0x0);
+
+ alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
+
+ if (hp_pin)
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+ msleep(130);
+ alc_update_coef_idx(codec, 0x36, 1<<14, 1<<14);
+ alc_update_coef_idx(codec, 0x36, 1<<13, 0x0);
+
+ if (hp_pin)
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+ msleep(10);
+ alc_write_coef_idx(codec, 0x67, 0x0); /* Set HP depop to manual mode */
+ alc_write_coefex_idx(codec, 0x58, 0x00, 0x7880);
+ alc_write_coefex_idx(codec, 0x58, 0x0f, 0xf049);
+ alc_update_coefex_idx(codec, 0x58, 0x03, 0x00f0, 0x00c0);
+
+ alc_write_coefex_idx(codec, 0x58, 0x00, 0xf888); /* HP depop procedure start */
+ val = alc_read_coefex_idx(codec, 0x58, 0x00);
+ for (i = 0; i < 20 && val & 0x8000; i++) {
+ msleep(50);
+ val = alc_read_coefex_idx(codec, 0x58, 0x00);
+ } /* Wait for depop procedure finish */
+
+ alc_write_coefex_idx(codec, 0x58, 0x00, val); /* write back the result */
+ alc_update_coef_idx(codec, 0x38, 1<<4, coef38);
+ alc_update_coef_idx(codec, 0x0d, 0x110, coef0d);
+ alc_update_coef_idx(codec, 0x36, 3<<13, coef36);
+
+ msleep(50);
+ alc_update_coef_idx(codec, 0x4a, 1<<15, 0);
+}
+
static void alc225_init(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
hda_nid_t hp_pin = alc_get_hp_pin(spec);
bool hp1_pin_sense, hp2_pin_sense;
+ if (spec->codec_variant != ALC269_TYPE_ALC287)
+ /* required only at boot or S3 and S4 resume time */
+ if (!spec->done_hp_init ||
+ is_s3_resume(codec) ||
+ is_s4_resume(codec)) {
+ alc285_hp_init(codec);
+ spec->done_hp_init = true;
+ }
+
if (!hp_pin)
hp_pin = 0x21;
msleep(30);
@@ -4744,6 +4807,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
@@ -4858,6 +4922,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
alc_process_coef_fw(codec, coef0255);
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x45, 0xc489);
@@ -5007,6 +5072,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x1b, 0x0e4b);
@@ -5105,6 +5171,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
@@ -5218,6 +5285,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
@@ -5318,6 +5386,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
val = alc_read_coef_idx(codec, 0x46);
is_ctia = (val & 0x0070) == 0x0070;
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x1b, 0x0e4b);
@@ -5611,6 +5680,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, alc255fw);
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, alc256fw);
@@ -6211,6 +6281,7 @@ static void alc_combo_jack_hp_jd_restart(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
break;
+ case 0x10ec0230:
case 0x10ec0235:
case 0x10ec0236:
case 0x10ec0255:
@@ -6343,6 +6414,24 @@ static void alc_fixup_no_int_mic(struct hda_codec *codec,
}
}
+static void alc285_fixup_hp_spectre_x360(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ static const hda_nid_t conn[] = { 0x02 };
+ static const struct hda_pintbl pincfgs[] = {
+ { 0x14, 0x90170110 }, /* rear speaker */
+ { }
+ };
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ snd_hda_apply_pincfgs(codec, pincfgs);
+ /* force front speaker to DAC1 */
+ snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
+ break;
+ }
+}
+
/* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c"
@@ -7810,6 +7899,8 @@ static const struct hda_fixup alc269_fixups[] = {
{ 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b },
{ }
},
+ .chained = true,
+ .chain_id = ALC289_FIXUP_ASUS_GA401,
},
[ALC285_FIXUP_HP_GPIO_LED] = {
.type = HDA_FIXUP_FUNC,
@@ -8127,13 +8218,8 @@ static const struct hda_fixup alc269_fixups[] = {
.chain_id = ALC269_FIXUP_HP_LINE1_MIC1_LED,
},
[ALC285_FIXUP_HP_SPECTRE_X360] = {
- .type = HDA_FIXUP_PINS,
- .v.pins = (const struct hda_pintbl[]) {
- { 0x14, 0x90170110 }, /* enable top speaker */
- {}
- },
- .chained = true,
- .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1,
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_hp_spectre_x360,
},
[ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP] = {
.type = HDA_FIXUP_FUNC,
@@ -8319,6 +8405,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
+ SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO),
SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
@@ -8336,19 +8423,26 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87f1, "HP ProBook 630 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f2, "HP ProBook 640 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
+ SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8862, "HP ProBook 445 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8863, "HP ProBook 445 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -8425,7 +8519,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x152d, 0x1082, "Quanta NL3", ALC269_FIXUP_LIFEBOOK),
SND_PCI_QUIRK(0x1558, 0x1323, "Clevo N130ZU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x1325, "Clevo N15[01][CW]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x1403, "Clevo N140CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -8460,11 +8554,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x8535, "Clevo NH50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x8536, "Clevo NH79D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
- SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
- SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[5|7][0-9]RZ[Q]", ALC269_FIXUP_DMIC),
+ SND_PCI_QUIRK(0x1558, 0x8550, "Clevo NH[57][0-9][ER][ACDH]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8551, "Clevo NH[57][0-9][ER][ACDH]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8560, "Clevo NH[57][0-9][ER][ACDH]Q", ALC269_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1558, 0x8561, "Clevo NH[57][0-9][ER][ACDH]Q", ALC269_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[57][0-9]RZ[Q]", ALC269_FIXUP_DMIC),
SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -8475,8 +8569,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1558, 0x9600, "Clevo N960K[PR]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x961d, "Clevo N960S[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL53RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
- SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL5XNU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL5[03]RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL50NU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0xb018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0xb019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1558, 0xb022, "Clevo NH77D[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9341,6 +9435,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->shutup = alc256_shutup;
spec->init_hook = alc256_init;
break;
+ case 0x10ec0230:
case 0x10ec0236:
case 0x10ec0256:
spec->codec_variant = ALC269_TYPE_ALC256;
@@ -9357,7 +9452,6 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0215:
case 0x10ec0245:
case 0x10ec0285:
- case 0x10ec0287:
case 0x10ec0289:
spec->codec_variant = ALC269_TYPE_ALC215;
spec->shutup = alc225_shutup;
@@ -9372,6 +9466,12 @@ static int patch_alc269(struct hda_codec *codec)
spec->init_hook = alc225_init;
spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
break;
+ case 0x10ec0287:
+ spec->codec_variant = ALC269_TYPE_ALC287;
+ spec->shutup = alc225_shutup;
+ spec->init_hook = alc225_init;
+ spec->gen.mixer_nid = 0; /* no loopback on ALC287 */
+ break;
case 0x10ec0234:
case 0x10ec0274:
case 0x10ec0294:
@@ -10632,6 +10732,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
+ HDA_CODEC_ENTRY(0x10ec0230, "ALC236", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 1d2a0287284b..08adf4dd1303 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -676,13 +676,15 @@ static int snd_ice1712_delta_init(struct snd_ice1712 *ice)
case ICE1712_SUBDEVICE_DELTA1010LT:
case ICE1712_SUBDEVICE_VX442:
case ICE1712_SUBDEVICE_DELTA66E:
- if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
+ err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c);
+ if (err < 0) {
dev_err(ice->card->dev, "unable to create I2C bus\n");
return err;
}
ice->i2c->private_data = ice;
ice->i2c->ops = &ap_cs8427_i2c_ops;
- if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
+ err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR);
+ if (err < 0)
return err;
break;
case ICE1712_SUBDEVICE_DELTA1010:
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 3794308313bf..8bb86b3c894e 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -442,7 +442,8 @@ static int snd_ice1712_ews_init(struct snd_ice1712 *ice)
ice->spec = spec;
/* create i2c */
- if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
+ err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c);
+ if (err < 0) {
dev_err(ice->card->dev, "unable to create I2C bus\n");
return err;
}
@@ -483,7 +484,8 @@ static int snd_ice1712_ews_init(struct snd_ice1712 *ice)
if (err < 0)
return err;
/* Check if the front module is connected */
- if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
+ err = snd_ice1712_ews88mt_chip_select(ice, 0x0f);
+ if (err < 0)
return err;
break;
case ICE1712_SUBDEVICE_EWS88D:
@@ -498,12 +500,14 @@ static int snd_ice1712_ews_init(struct snd_ice1712 *ice)
/* set up SPDIF interface */
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_EWX2496:
- if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
+ err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR);
+ if (err < 0)
return err;
snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
break;
case ICE1712_SUBDEVICE_DMX6FIRE:
- if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
+ err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR);
+ if (err < 0)
return err;
snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
break;
@@ -853,7 +857,8 @@ static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct s
int invert = (kcontrol->private_value >> 8) & 1;
int data;
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
+ data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT);
+ if (data < 0)
return data;
data = (data >> shift) & 1;
if (invert)
@@ -869,7 +874,8 @@ static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct s
int invert = (kcontrol->private_value >> 8) & 1;
int data, ndata;
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
+ data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT);
+ if (data < 0)
return data;
ndata = data & ~(1 << shift);
if (ucontrol->value.integer.value[0])
@@ -896,7 +902,8 @@ static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, str
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int data;
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
+ data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT);
+ if (data < 0)
return data;
ucontrol->value.integer.value[0] = data & 3;
return 0;
@@ -907,7 +914,8 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int data, ndata;
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
+ data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT);
+ if (data < 0)
return data;
ndata = data & ~3;
ndata |= (ucontrol->value.integer.value[0] & 3);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 5b124c4ad572..df3ba5c70de9 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -79,7 +79,7 @@ enum { \
ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
-};
+}
/* busmaster blocks */
DEFINE_REGSET(OFF, 0); /* offset */
@@ -538,7 +538,8 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
+ tmp = igetdword(chip, ICHREG(GLOB_STA));
+ if (tmp & ICH_RCS) {
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp &
~(chip->codec_ready_bits | ICH_GSCI));
@@ -559,7 +560,8 @@ static void snd_intel8x0_codec_read_test(struct intel8x0 *chip,
if (snd_intel8x0_codec_semaphore(chip, codec) >= 0) {
iagetword(chip, codec * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
+ tmp = igetdword(chip, ICHREG(GLOB_STA));
+ if (tmp & ICH_RCS) {
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp &
~(chip->codec_ready_bits | ICH_GSCI));
@@ -692,7 +694,7 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich
int status, civ, i, step;
int ack = 0;
- if (!ichdev->prepared || ichdev->suspended)
+ if (!(ichdev->prepared || chip->in_measurement) || ichdev->suspended)
return;
spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1105,7 +1107,8 @@ static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ich
runtime->hw.buffer_bytes_max = 64*1024;
runtime->hw.period_bytes_max = 64*1024;
}
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
runtime->private_data = ichdev;
return 0;
@@ -2190,7 +2193,8 @@ static int snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
udelay(1);
}
}
- if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus);
+ if (err < 0)
goto __err;
pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
if (ac97_clock >= 8000 && ac97_clock <= 48000)
@@ -2206,7 +2210,8 @@ static int snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
ac97.pci = chip->pci;
for (i = 0; i < codecs; i++) {
ac97.num = i;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i]);
+ if (err < 0) {
if (err != -EACCES)
dev_err(chip->card->dev,
"Unable to initialize codec #%d\n", i);
@@ -2491,11 +2496,13 @@ static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing)
int err;
if (chip->device_type != DEVICE_ALI) {
- if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0)
+ err = snd_intel8x0_ich_chip_init(chip, probing);
+ if (err < 0)
return err;
iagetword(chip, 0); /* clear semaphore flag */
} else {
- if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0)
+ err = snd_intel8x0_ali_chip_init(chip, probing);
+ if (err < 0)
return err;
}
@@ -2918,7 +2925,8 @@ static int snd_intel8x0_create(struct snd_card *card,
*r_intel8x0 = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -2950,7 +2958,8 @@ static int snd_intel8x0_create(struct snd_card *card,
pci->device == PCI_DEVICE_ID_INTEL_440MX)
chip->fix_nocache = 1; /* enable workaround */
- if ((err = pci_request_regions(pci, card->shortname)) < 0) {
+ err = pci_request_regions(pci, card->shortname);
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -3064,7 +3073,8 @@ static int snd_intel8x0_create(struct snd_card *card,
for (i = 0; i < chip->max_codecs; i++)
chip->codec_isr_bits |= chip->codec_bit[i];
- if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
+ err = snd_intel8x0_chip_init(chip, 1);
+ if (err < 0) {
snd_intel8x0_free(chip);
return err;
}
@@ -3079,7 +3089,8 @@ static int snd_intel8x0_create(struct snd_card *card,
chip->irq = pci->irq;
card->sync_irq = chip->irq;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_intel8x0_free(chip);
return err;
}
@@ -3186,18 +3197,20 @@ static int snd_intel8x0_probe(struct pci_dev *pci,
buggy_irq = 0;
}
- if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
- &chip)) < 0) {
+ err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
card->private_data = chip;
- if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
+ err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_intel8x0_pcm(chip)) < 0) {
+ err = snd_intel8x0_pcm(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -3217,7 +3230,8 @@ static int snd_intel8x0_probe(struct pci_dev *pci,
}
}
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 13ef838b26c1..b96fce6cbd83 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -57,7 +57,7 @@ enum { \
ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
-};
+}
/* busmaster blocks */
DEFINE_REGSET(OFF, 0); /* offset */
@@ -342,7 +342,8 @@ static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
+ tmp = igetdword(chip, ICHREG(GLOB_STA));
+ if (tmp & ICH_RCS) {
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA),
tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
@@ -800,7 +801,8 @@ static int snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
glob_sta = igetdword(chip, ICHREG(GLOB_STA));
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus);
+ if (err < 0)
goto __err;
pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
if (ac97_clock >= 8000 && ac97_clock <= 48000)
@@ -809,7 +811,8 @@ static int snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
ac97.pci = chip->pci;
ac97.num = glob_sta & ICH_SCR ? 1 : 0;
- if ((err = snd_ac97_mixer(pbus, &ac97, &x97)) < 0) {
+ err = snd_ac97_mixer(pbus, &ac97, &x97);
+ if (err < 0) {
dev_err(chip->card->dev,
"Unable to initialize codec #%d\n", ac97.num);
if (ac97.num == 0)
@@ -927,7 +930,8 @@ static int snd_intel8x0m_chip_init(struct intel8x0m *chip, int probing)
unsigned int i;
int err;
- if ((err = snd_intel8x0m_ich_chip_init(chip, probing)) < 0)
+ err = snd_intel8x0m_ich_chip_init(chip, probing);
+ if (err < 0)
return err;
iagetword(chip, 0); /* clear semaphore flag */
@@ -1075,7 +1079,8 @@ static int snd_intel8x0m_create(struct snd_card *card,
*r_intel8x0m = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1089,7 +1094,8 @@ static int snd_intel8x0m_create(struct snd_card *card,
chip->pci = pci;
chip->irq = -1;
- if ((err = pci_request_regions(pci, card->shortname)) < 0) {
+ err = pci_request_regions(pci, card->shortname);
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1167,7 +1173,8 @@ port_inited:
pci_set_master(pci);
- if ((err = snd_intel8x0m_chip_init(chip, 1)) < 0) {
+ err = snd_intel8x0m_chip_init(chip, 1);
+ if (err < 0) {
snd_intel8x0m_free(chip);
return err;
}
@@ -1181,7 +1188,8 @@ port_inited:
chip->irq = pci->irq;
card->sync_irq = chip->irq;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_intel8x0m_free(chip);
return err;
}
@@ -1238,17 +1246,20 @@ static int snd_intel8x0m_probe(struct pci_dev *pci,
}
strcat(card->shortname," Modem");
- if ((err = snd_intel8x0m_create(card, pci, pci_id->driver_data, &chip)) < 0) {
+ err = snd_intel8x0m_create(card, pci, pci_id->driver_data, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
card->private_data = chip;
- if ((err = snd_intel8x0m_mixer(chip, ac97_clock)) < 0) {
+ err = snd_intel8x0m_mixer(chip, ac97_clock);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_intel8x0m_pcm(chip)) < 0) {
+ err = snd_intel8x0m_pcm(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1258,7 +1269,8 @@ static int snd_intel8x0m_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at irq %i",
card->shortname, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 80ac3c6152ad..030e01b062e4 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1527,7 +1527,8 @@ static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
return 0;
}
- if ((err = snd_korg1212_SetRate(korg1212, params_rate(params))) < 0) {
+ err = snd_korg1212_SetRate(korg1212, params_rate(params));
+ if (err < 0) {
spin_unlock_irqrestore(&korg1212->lock, flags);
return err;
}
@@ -2159,7 +2160,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
};
* rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
@@ -2196,7 +2198,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
for (i=0; i<kAudioChannels; i++)
korg1212->volumePhase[i] = 0;
- if ((err = pci_request_regions(pci, "korg1212")) < 0) {
+ err = pci_request_regions(pci, "korg1212");
+ if (err < 0) {
kfree(korg1212);
pci_disable_device(pci);
return err;
@@ -2220,7 +2223,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
korg1212->iomem2, iomem2_size,
stateName[korg1212->cardState]);
- if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
+ korg1212->iobase = ioremap(korg1212->iomem, iomem_size);
+ if (!korg1212->iobase) {
snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
korg1212->iomem + iomem_size - 1);
snd_korg1212_free(korg1212);
@@ -2360,7 +2364,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
if (rc)
K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops);
+ if (err < 0) {
snd_korg1212_free(korg1212);
return err;
}
@@ -2385,7 +2390,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
- if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
+ err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm);
+ if (err < 0)
return err;
korg1212->pcm->private_data = korg1212;
@@ -2436,7 +2442,8 @@ snd_korg1212_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
+ err = snd_korg1212_create(card, pci, &korg1212);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2448,7 +2455,8 @@ snd_korg1212_probe(struct pci_dev *pci,
K1212_DEBUG_PRINTK("K1212_DEBUG: %s\n", card->longname);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index f884f5a6a61c..d3f58a3d17fb 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -674,10 +674,6 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
u32 channels = runtime->channels;
- if (runtime->channels != channels)
- dev_err(chip->card->dev, "channel count mismatch: %d vs %d",
- runtime->channels, channels);
-
mutex_lock(&chip->msg_lock);
lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index cdc4b6106252..77a484bc8c0d 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1765,7 +1765,8 @@ snd_m3_playback_open(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
int err;
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
+ err = snd_m3_substream_open(chip, subs);
+ if (err < 0)
return err;
runtime->hw = snd_m3_playback;
@@ -1789,7 +1790,8 @@ snd_m3_capture_open(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
int err;
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
+ err = snd_m3_substream_open(chip, subs);
+ if (err < 0)
return err;
runtime->hw = snd_m3_capture;
@@ -2036,12 +2038,14 @@ static int snd_m3_mixer(struct snd_m3 *chip)
.read = snd_m3_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
/* seems ac97 PCM needs initialization.. hack hack.. */
@@ -2642,16 +2646,19 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
if (err < 0)
goto free_chip;
- if ((err = snd_m3_mixer(chip)) < 0)
+ err = snd_m3_mixer(chip);
+ if (err < 0)
return err;
for (i = 0; i < chip->num_substreams; i++) {
struct m3_dma *s = &chip->substreams[i];
- if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
+ err = snd_m3_assp_client_init(chip, s, i);
+ if (err < 0)
return err;
}
- if ((err = snd_m3_pcm(chip, 0)) < 0)
+ err = snd_m3_pcm(chip, 0);
+ if (err < 0)
return err;
#ifdef CONFIG_SND_MAESTRO3_INPUT
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index a0bbb386dc25..1b078b789604 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -954,9 +954,10 @@ static int snd_mixart_pcm_analog(struct snd_mixart *chip)
char name[32];
sprintf(name, "miXart analog %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG,
- MIXART_PLAYBACK_STREAMS,
- MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
+ err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG,
+ MIXART_PLAYBACK_STREAMS,
+ MIXART_CAPTURE_STREAMS, &pcm);
+ if (err < 0) {
dev_err(chip->card->dev,
"cannot create the analog pcm %d\n", chip->chip_idx);
return err;
@@ -987,9 +988,10 @@ static int snd_mixart_pcm_digital(struct snd_mixart *chip)
char name[32];
sprintf(name, "miXart AES/EBU %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL,
- MIXART_PLAYBACK_STREAMS,
- MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
+ err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL,
+ MIXART_PLAYBACK_STREAMS,
+ MIXART_CAPTURE_STREAMS, &pcm);
+ if (err < 0) {
dev_err(chip->card->dev,
"cannot create the digital pcm %d\n", chip->chip_idx);
return err;
@@ -1042,7 +1044,8 @@ static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int
chip->mgr = mgr;
card->sync_irq = mgr->irq;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_mixart_chip_free(chip);
return err;
}
@@ -1243,7 +1246,8 @@ static int snd_mixart_probe(struct pci_dev *pci,
}
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(pci);
@@ -1267,7 +1271,8 @@ static int snd_mixart_probe(struct pci_dev *pci,
mgr->irq = -1;
/* resource assignment */
- if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
+ err = pci_request_regions(pci, CARD_NAME);
+ if (err < 0) {
kfree(mgr);
pci_disable_device(pci);
return err;
@@ -1332,7 +1337,8 @@ static int snd_mixart_probe(struct pci_dev *pci,
"Digigram miXart at 0x%lx & 0x%lx, irq %i [PCM #%d]",
mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq, i);
- if ((err = snd_mixart_create(mgr, card, i)) < 0) {
+ err = snd_mixart_create(mgr, card, i);
+ if (err < 0) {
snd_card_free(card);
snd_mixart_free(mgr);
return err;
@@ -1343,7 +1349,8 @@ static int snd_mixart_probe(struct pci_dev *pci,
snd_mixart_proc_init(mgr->chip[i]);
}
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_mixart_free(mgr);
return err;
}
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index f579f7698bba..689c0f995a9c 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -306,9 +306,13 @@ static int mixart_first_init(struct mixart_mgr *mgr)
int err;
struct mixart_msg request;
- if((err = mixart_enum_connectors(mgr)) < 0) return err;
+ err = mixart_enum_connectors(mgr);
+ if (err < 0)
+ return err;
- if((err = mixart_enum_physio(mgr)) < 0) return err;
+ err = mixart_enum_physio(mgr);
+ if (err < 0)
+ return err;
/* send a synchro command to card (necessary to do this before first MSG_STREAM_START_STREAM_GRP_PACKET) */
/* though why not here */
@@ -528,15 +532,18 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
for (card_index = 0; card_index < mgr->num_cards; card_index++) {
struct snd_mixart *chip = mgr->chip[card_index];
- if ((err = snd_mixart_create_pcm(chip)) < 0)
+ err = snd_mixart_create_pcm(chip);
+ if (err < 0)
return err;
if (card_index == 0) {
- if ((err = snd_mixart_create_mixer(chip->mgr)) < 0)
+ err = snd_mixart_create_mixer(chip->mgr);
+ if (err < 0)
return err;
}
- if ((err = snd_card_register(chip->card)) < 0)
+ err = snd_card_register(chip->card);
+ if (err < 0)
return err;
}
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index d2e7c3381267..2727f3345795 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -1114,10 +1114,12 @@ int snd_mixart_create_mixer(struct mixart_mgr *mgr)
temp = mixart_control_analog_level;
temp.name = "Master Playback Volume";
temp.private_value = 0; /* playback */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
/* output mute controls */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip));
+ if (err < 0)
return err;
/* analog input level control only on first two chips !*/
@@ -1125,7 +1127,8 @@ int snd_mixart_create_mixer(struct mixart_mgr *mgr)
temp = mixart_control_analog_level;
temp.name = "Master Capture Volume";
temp.private_value = 1; /* capture */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
@@ -1133,45 +1136,53 @@ int snd_mixart_create_mixer(struct mixart_mgr *mgr)
temp.name = "PCM Playback Volume";
temp.count = MIXART_PLAYBACK_STREAMS;
temp.private_value = 0; /* playback analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
temp.name = "PCM Capture Volume";
temp.count = 1;
temp.private_value = MIXART_VOL_REC_MASK; /* capture analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
temp.name = "AES Playback Volume";
temp.count = MIXART_PLAYBACK_STREAMS;
temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
temp.name = "AES Capture Volume";
temp.count = 0;
temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK; /* capture AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
temp = mixart_control_pcm_switch;
temp.name = "PCM Playback Switch";
temp.private_value = 0; /* playback analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
temp.name = "AES Playback Switch";
temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip));
+ if (err < 0)
return err;
}
/* monitoring */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip));
+ if (err < 0)
return err;
/* init all mixer data and program the master volumes/switches */
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 6cb689aa28c2..12d02d7d3b51 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1318,7 +1318,8 @@ snd_nm256_mixer(struct nm256 *chip)
if (! chip->ac97_regs)
return -ENOMEM;
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
@@ -1476,7 +1477,8 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
*chip_ret = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1568,7 +1570,8 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
chip->buffer_end = buffer_top;
else {
/* get buffer end pointer from signature */
- if ((err = snd_nm256_peek_for_sig(chip)) < 0)
+ err = snd_nm256_peek_for_sig(chip);
+ if (err < 0)
goto __error;
}
@@ -1618,7 +1621,8 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
// pci_set_master(pci); /* needed? */
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0)
goto __error;
*chip_ret = chip;
@@ -1700,7 +1704,8 @@ static int snd_nm256_probe(struct pci_dev *pci,
capture_bufsize = 4;
if (capture_bufsize > 128)
capture_bufsize = 128;
- if ((err = snd_nm256_create(card, pci, &chip)) < 0) {
+ err = snd_nm256_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1716,8 +1721,13 @@ static int snd_nm256_probe(struct pci_dev *pci,
chip->reset_workaround_2 = 1;
}
- if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
- (err = snd_nm256_mixer(chip)) < 0) {
+ err = snd_nm256_pcm(chip, 0);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ err = snd_nm256_mixer(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1727,7 +1737,8 @@ static int snd_nm256_probe(struct pci_dev *pci,
card->shortname,
chip->buffer_addr, chip->cport_addr, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 751f9744b089..96b9371c201a 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1134,9 +1134,10 @@ int pcxhr_create_pcm(struct snd_pcxhr *chip)
char name[32];
snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, 0,
- chip->nb_streams_play,
- chip->nb_streams_capt, &pcm)) < 0) {
+ err = snd_pcm_new(chip->card, name, 0,
+ chip->nb_streams_play,
+ chip->nb_streams_capt, &pcm);
+ if (err < 0) {
dev_err(chip->card->dev, "cannot create pcm %s\n", name);
return err;
}
@@ -1202,7 +1203,8 @@ static int pcxhr_create(struct pcxhr_mgr *mgr,
chip->nb_streams_capt = 1; /* or 1 stereo stream */
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
pcxhr_chip_free(chip);
return err;
}
@@ -1492,7 +1494,8 @@ static int pcxhr_probe(struct pci_dev *pci,
}
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(pci);
@@ -1537,7 +1540,8 @@ static int pcxhr_probe(struct pci_dev *pci,
mgr->granularity = PCXHR_GRANULARITY;
/* resource assignment */
- if ((err = pci_request_regions(pci, card_name)) < 0) {
+ err = pci_request_regions(pci, card_name);
+ if (err < 0) {
kfree(mgr);
pci_disable_device(pci);
return err;
@@ -1608,7 +1612,8 @@ static int pcxhr_probe(struct pci_dev *pci,
snprintf(card->longname, sizeof(card->longname),
"%s [PCM #%d]", mgr->name, i);
- if ((err = pcxhr_create(mgr, card, i)) < 0) {
+ err = pcxhr_create(mgr, card, i);
+ if (err < 0) {
snd_card_free(card);
pcxhr_free(mgr);
return err;
@@ -1618,7 +1623,8 @@ static int pcxhr_probe(struct pci_dev *pci,
/* init proc interface only for chip0 */
pcxhr_proc_init(mgr->chip[i]);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
pcxhr_free(mgr);
return err;
}
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 2258bd698844..249805065f61 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -322,14 +322,17 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
for (card_index = 0; card_index < mgr->num_cards; card_index++) {
struct snd_pcxhr *chip = mgr->chip[card_index];
- if ((err = pcxhr_create_pcm(chip)) < 0)
+ err = pcxhr_create_pcm(chip);
+ if (err < 0)
return err;
if (card_index == 0) {
- if ((err = pcxhr_create_mixer(chip->mgr)) < 0)
+ err = pcxhr_create_mixer(chip->mgr);
+ if (err < 0)
return err;
}
- if ((err = snd_card_register(chip->card)) < 0)
+ err = snd_card_register(chip->card);
+ if (err < 0)
return err;
}
err = pcxhr_start_pipes(mgr);
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 56827db97239..709a1a2cde20 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1087,9 +1087,15 @@ static irqreturn_t riptide_handleirq(int irq, void *dev_id)
substream[i] = chip->playback_substream[i];
substream[i] = chip->capture_substream;
for (i = 0; i < PLAYBACK_SUBSTREAMS + 1; i++) {
- if (substream[i] &&
- (runtime = substream[i]->runtime) &&
- (data = runtime->private_data) && data->state != ST_STOP) {
+ if (!substream[i])
+ continue;
+ runtime = substream[i]->runtime;
+ if (!runtime)
+ continue;
+ data = runtime->private_data;
+ if (!data)
+ continue;
+ if (data->state != ST_STOP) {
pos = 0;
for (j = 0; j < data->pages; j++) {
c = &data->sgdbuf[j];
@@ -1549,10 +1555,10 @@ snd_riptide_hw_params(struct snd_pcm_substream *substream,
(int)sgdlist->bytes);
if (sgdlist->area)
snd_dma_free_pages(sgdlist);
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- &chip->pci->dev,
- sizeof(struct sgd) * (DESC_MAX_MASK + 1),
- sgdlist)) < 0) {
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
+ sizeof(struct sgd) * (DESC_MAX_MASK + 1),
+ sgdlist);
+ if (err < 0) {
snd_printk(KERN_ERR "Riptide: failed to alloc %d dma bytes\n",
(int)sizeof(struct sgd) * (DESC_MAX_MASK + 1));
return err;
@@ -1677,9 +1683,9 @@ static int snd_riptide_pcm(struct snd_riptide *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err =
- snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
- &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
+ &pcm);
+ if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
&snd_riptide_playback_ops);
@@ -1766,14 +1772,16 @@ static int snd_riptide_initialize(struct snd_riptide *chip)
cif = chip->cif;
if (!cif) {
- if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL)
+ cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL);
+ if (!cif)
return -ENOMEM;
cif->hwport = (struct riptideport *)chip->port;
spin_lock_init(&cif->lock);
chip->cif = cif;
}
cif->is_reset = 0;
- if ((err = riptide_reset(cif, chip)) != 0)
+ err = riptide_reset(cif, chip);
+ if (err)
return err;
device_id = chip->device_id;
switch (device_id) {
@@ -1797,7 +1805,8 @@ static int snd_riptide_free(struct snd_riptide *chip)
if (!chip)
return 0;
- if ((cif = chip->cif)) {
+ cif = chip->cif;
+ if (cif) {
SET_GRESET(cif->hwport);
udelay(100);
UNSET_GRESET(cif->hwport);
@@ -1830,9 +1839,11 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
};
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL)))
+ chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL);
+ if (!chip)
return -ENOMEM;
spin_lock_init(&chip->lock);
@@ -1845,8 +1856,8 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
chip->handled_irqs = 0;
chip->cif = NULL;
- if ((chip->res_port =
- request_region(chip->port, 64, "RIPTIDE")) == NULL) {
+ chip->res_port = request_region(chip->port, 64, "RIPTIDE");
+ if (!chip->res_port) {
snd_printk(KERN_ERR
"Riptide: unable to grab region 0x%lx-0x%lx\n",
chip->port, chip->port + 64 - 1);
@@ -1868,12 +1879,14 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
card->sync_irq = chip->irq;
chip->device_id = pci->device;
pci_set_master(pci);
- if ((err = snd_riptide_initialize(chip)) < 0) {
+ err = snd_riptide_initialize(chip);
+ if (err < 0) {
snd_riptide_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_riptide_free(chip);
return err;
}
@@ -1903,7 +1916,8 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
for (i = 0; i < 64; i += 4)
snd_iprintf(buffer, "%c%02x: %08x",
(i % 16) ? ' ' : '\n', i, inl(chip->port + i));
- if ((cif = chip->cif)) {
+ cif = chip->cif;
+ if (cif) {
snd_iprintf(buffer,
"\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d",
chip->firmware.firmware.ASIC,
@@ -1922,10 +1936,11 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
}
snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams);
for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) {
- if (chip->playback_substream[i]
- && chip->playback_substream[i]->runtime
- && (data =
- chip->playback_substream[i]->runtime->private_data)) {
+ if (!chip->playback_substream[i] ||
+ !chip->playback_substream[i]->runtime)
+ continue;
+ data = chip->playback_substream[i]->runtime->private_data;
+ if (data) {
snd_iprintf(buffer,
"stream: %d mixer: %d source: %d (%d,%d)\n",
data->id, data->mixer, data->source,
@@ -1934,15 +1949,16 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "rate: %d\n", rate);
}
}
- if (chip->capture_substream
- && chip->capture_substream->runtime
- && (data = chip->capture_substream->runtime->private_data)) {
- snd_iprintf(buffer,
- "stream: %d mixer: %d source: %d (%d,%d)\n",
- data->id, data->mixer,
- data->source, data->intdec[0], data->intdec[1]);
- if (!(getsamplerate(cif, data->intdec, &rate)))
- snd_iprintf(buffer, "rate: %d\n", rate);
+ if (chip->capture_substream && chip->capture_substream->runtime) {
+ data = chip->capture_substream->runtime->private_data;
+ if (data) {
+ snd_iprintf(buffer,
+ "stream: %d mixer: %d source: %d (%d,%d)\n",
+ data->id, data->mixer,
+ data->source, data->intdec[0], data->intdec[1]);
+ if (!(getsamplerate(cif, data->intdec, &rate)))
+ snd_iprintf(buffer, "rate: %d\n", rate);
+ }
}
snd_iprintf(buffer, "Paths:\n");
i = getpaths(cif, p);
@@ -1973,12 +1989,14 @@ static int snd_riptide_mixer(struct snd_riptide *chip)
ac97.private_data = chip;
ac97.scaps = AC97_SCAP_SKIP_MODEM;
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus);
+ if (err < 0)
return err;
chip->ac97_bus = pbus;
ac97.pci = chip->pci;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
return err;
}
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 54f3e39f97f5..b5b357853c94 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -668,18 +668,24 @@ snd_rme32_playback_hw_params(struct snd_pcm_substream *substream,
}
spin_lock_irq(&rme32->lock);
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+ 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);
return -EIO;
}
- } else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
- spin_unlock_irq(&rme32->lock);
- return err;
+ } else {
+ err = snd_rme32_playback_setrate(rme32, params_rate(params));
+ if (err < 0) {
+ spin_unlock_irq(&rme32->lock);
+ return err;
+ }
}
- if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
+ err = snd_rme32_setformat(rme32, params_format(params));
+ if (err < 0) {
spin_unlock_irq(&rme32->lock);
return err;
}
@@ -723,15 +729,18 @@ snd_rme32_capture_hw_params(struct snd_pcm_substream *substream,
rme32->wcreg |= RME32_WCR_AUTOSYNC;
writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
+ err = snd_rme32_setformat(rme32, params_format(params));
+ if (err < 0) {
spin_unlock_irq(&rme32->lock);
return err;
}
- if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
+ err = snd_rme32_playback_setrate(rme32, params_rate(params));
+ if (err < 0) {
spin_unlock_irq(&rme32->lock);
return err;
}
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+ rate = snd_rme32_capture_getrate(rme32, &isadat);
+ if (rate > 0) {
if ((int)params_rate(params) != rate) {
spin_unlock_irq(&rme32->lock);
return -EIO;
@@ -854,8 +863,10 @@ static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
runtime->hw.rate_max = 96000;
}
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+ rate = 0;
+ if (rme32->rcreg & RME32_RCR_KMODE)
+ rate = snd_rme32_capture_getrate(rme32, &dummy);
+ if (rate > 0) {
/* AutoSync */
runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
@@ -895,7 +906,8 @@ static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
runtime->hw.rate_max = 96000;
}
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+ rate = snd_rme32_capture_getrate(rme32, &isadat);
+ if (rate > 0) {
if (isadat) {
return -EIO;
}
@@ -932,8 +944,10 @@ snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
runtime->hw = snd_rme32_adat_fd_info;
else
runtime->hw = snd_rme32_adat_info;
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+ rate = 0;
+ if (rme32->rcreg & RME32_RCR_KMODE)
+ rate = snd_rme32_capture_getrate(rme32, &dummy);
+ if (rate > 0) {
/* AutoSync */
runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
@@ -955,7 +969,8 @@ snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
runtime->hw = snd_rme32_adat_fd_info;
else
runtime->hw = snd_rme32_adat_info;
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+ rate = snd_rme32_capture_getrate(rme32, &isadat);
+ if (rate > 0) {
if (!isadat) {
return -EIO;
}
@@ -1307,10 +1322,12 @@ static int snd_rme32_create(struct rme32 *rme32)
rme32->irq = -1;
spin_lock_init(&rme32->lock);
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- if ((err = pci_request_regions(pci, "RME32")) < 0)
+ err = pci_request_regions(pci, "RME32");
+ if (err < 0)
return err;
rme32->port = pci_resource_start(rme32->pci, 0);
@@ -1334,9 +1351,9 @@ static int snd_rme32_create(struct rme32 *rme32)
pci_read_config_byte(pci, 8, &rme32->rev);
/* set up ALSA pcm device for S/PDIF */
- if ((err = snd_pcm_new(rme32->card, "Digi32 IEC958", 0, 1, 1, &rme32->spdif_pcm)) < 0) {
+ err = snd_pcm_new(rme32->card, "Digi32 IEC958", 0, 1, 1, &rme32->spdif_pcm);
+ if (err < 0)
return err;
- }
rme32->spdif_pcm->private_data = rme32;
rme32->spdif_pcm->private_free = snd_rme32_free_spdif_pcm;
strcpy(rme32->spdif_pcm->name, "Digi32 IEC958");
@@ -1363,11 +1380,10 @@ static int snd_rme32_create(struct rme32 *rme32)
rme32->adat_pcm = NULL;
}
else {
- if ((err = snd_pcm_new(rme32->card, "Digi32 ADAT", 1,
- 1, 1, &rme32->adat_pcm)) < 0)
- {
+ err = snd_pcm_new(rme32->card, "Digi32 ADAT", 1,
+ 1, 1, &rme32->adat_pcm);
+ if (err < 0)
return err;
- }
rme32->adat_pcm->private_data = rme32;
rme32->adat_pcm->private_free = snd_rme32_free_adat_pcm;
strcpy(rme32->adat_pcm->name, "Digi32 ADAT");
@@ -1410,9 +1426,9 @@ static int snd_rme32_create(struct rme32 *rme32)
/* init switch interface */
- if ((err = snd_rme32_create_switches(rme32->card, rme32)) < 0) {
+ err = snd_rme32_create_switches(rme32->card, rme32);
+ if (err < 0)
return err;
- }
/* init proc interface */
snd_rme32_proc_init(rme32);
@@ -1855,7 +1871,9 @@ static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32
struct snd_kcontrol *kctl;
for (idx = 0; idx < (int)ARRAY_SIZE(snd_rme32_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32))) < 0)
+ kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (idx == 1) /* IEC958 (S/PDIF) Stream */
rme32->spdif_ctl = kctl;
@@ -1899,7 +1917,8 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
rme32->pci = pci;
if (fullduplex[dev])
rme32->fullduplex_mode = 1;
- if ((err = snd_rme32_create(rme32)) < 0) {
+ err = snd_rme32_create(rme32);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1919,7 +1938,8 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
sprintf(card->longname, "%s (Rev. %d) at 0x%lx, irq %d",
card->shortname, rme32->rev, rme32->port, rme32->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 66082e9f526d..fc7ac077559c 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -666,12 +666,14 @@ snd_rme96_playback_getrate(struct rme96 *rme96)
int rate, dummy;
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- return rate;
+ snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) {
+ rate = snd_rme96_capture_getrate(rme96, &dummy);
+ if (rate > 0) {
+ /* slave clock */
+ return rate;
+ }
}
+
rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) +
(((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1);
switch (rate) {
@@ -984,10 +986,11 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
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)) > 0)
- {
+ 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;
@@ -1046,28 +1049,30 @@ snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
runtime->dma_bytes = RME96_BUFFER_SIZE;
spin_lock_irq(&rme96->lock);
- if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) {
+ err = snd_rme96_capture_setformat(rme96, params_format(params));
+ if (err < 0) {
spin_unlock_irq(&rme96->lock);
return err;
}
if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
- if ((err = snd_rme96_capture_analog_setrate(rme96,
- params_rate(params))) < 0)
- {
+ err = snd_rme96_capture_analog_setrate(rme96, params_rate(params));
+ if (err < 0) {
spin_unlock_irq(&rme96->lock);
return err;
}
- } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- if ((isadat && runtime->hw.channels_min == 2) ||
- (!isadat && runtime->hw.channels_min == 8))
- {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
+ } else {
+ rate = snd_rme96_capture_getrate(rme96, &isadat);
+ if (rate > 0) {
+ if ((int)params_rate(params) != rate) {
+ spin_unlock_irq(&rme96->lock);
+ return -EIO;
+ }
+ if ((isadat && runtime->hw.channels_min == 2) ||
+ (!isadat && runtime->hw.channels_min == 8)) {
+ spin_unlock_irq(&rme96->lock);
+ return -EIO;
+ }
+ }
}
snd_rme96_setframelog(rme96, params_channels(params), 0);
if (rme96->playback_periodsize != 0) {
@@ -1160,8 +1165,10 @@ rme96_set_buffer_size_constraint(struct rme96 *rme96,
snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
RME96_BUFFER_SIZE);
- if ((size = rme96->playback_periodsize) != 0 ||
- (size = rme96->capture_periodsize) != 0)
+ size = rme96->playback_periodsize;
+ if (!size)
+ size = rme96->capture_periodsize;
+ if (size)
snd_pcm_hw_constraint_single(runtime,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
size);
@@ -1191,13 +1198,14 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
runtime->hw = snd_rme96_playback_spdif_info;
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
+ snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) {
+ rate = snd_rme96_capture_getrate(rme96, &dummy);
+ if (rate > 0) {
+ /* slave clock */
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
}
rme96_set_buffer_size_constraint(rme96, runtime);
@@ -1217,16 +1225,16 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
runtime->hw = snd_rme96_capture_spdif_info;
- if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
- {
- if (isadat) {
- return -EIO;
- }
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
+ if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) {
+ rate = snd_rme96_capture_getrate(rme96, &isadat);
+ if (rate > 0) {
+ if (isadat)
+ return -EIO;
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
+ }
spin_lock_irq(&rme96->lock);
if (rme96->capture_substream) {
@@ -1260,14 +1268,16 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
runtime->hw = snd_rme96_playback_adat_info;
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
+ snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) {
+ rate = snd_rme96_capture_getrate(rme96, &dummy);
+ if (rate > 0) {
+ /* slave clock */
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
+ }
+
rme96_set_buffer_size_constraint(rme96, runtime);
return 0;
}
@@ -1286,7 +1296,8 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
expension cards AEB4/8-I are RME96_INPUT_INTERNAL */
return -EIO;
}
- if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+ rate = snd_rme96_capture_getrate(rme96, &isadat);
+ if (rate > 0) {
if (!isadat) {
return -EIO;
}
@@ -1603,10 +1614,12 @@ snd_rme96_create(struct rme96 *rme96)
rme96->irq = -1;
spin_lock_init(&rme96->lock);
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- if ((err = pci_request_regions(pci, "RME96")) < 0)
+ err = pci_request_regions(pci, "RME96");
+ if (err < 0)
return err;
rme96->port = pci_resource_start(rme96->pci, 0);
@@ -1630,11 +1643,11 @@ snd_rme96_create(struct rme96 *rme96)
pci_read_config_byte(pci, 8, &rme96->rev);
/* set up ALSA pcm device for S/PDIF */
- if ((err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0,
- 1, 1, &rme96->spdif_pcm)) < 0)
- {
+ err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0,
+ 1, 1, &rme96->spdif_pcm);
+ if (err < 0)
return err;
- }
+
rme96->spdif_pcm->private_data = rme96;
rme96->spdif_pcm->private_free = snd_rme96_free_spdif_pcm;
strcpy(rme96->spdif_pcm->name, "Digi96 IEC958");
@@ -1648,11 +1661,10 @@ snd_rme96_create(struct rme96 *rme96)
/* ADAT is not available on the base model */
rme96->adat_pcm = NULL;
} else {
- if ((err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1,
- 1, 1, &rme96->adat_pcm)) < 0)
- {
+ err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1,
+ 1, 1, &rme96->adat_pcm);
+ if (err < 0)
return err;
- }
rme96->adat_pcm->private_data = rme96;
rme96->adat_pcm->private_free = snd_rme96_free_adat_pcm;
strcpy(rme96->adat_pcm->name, "Digi96 ADAT");
@@ -1701,9 +1713,9 @@ snd_rme96_create(struct rme96 *rme96)
}
/* init switch interface */
- if ((err = snd_rme96_create_switches(rme96->card, rme96)) < 0) {
+ err = snd_rme96_create_switches(rme96->card, rme96);
+ if (err < 0)
return err;
- }
/* init proc interface */
snd_rme96_proc_init(rme96);
@@ -2336,16 +2348,20 @@ snd_rme96_create_switches(struct snd_card *card,
struct snd_kcontrol *kctl;
for (idx = 0; idx < 7; idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
+ kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (idx == 1) /* IEC958 (S/PDIF) Stream */
rme96->spdif_ctl = kctl;
}
if (RME96_HAS_ANALOG_OUT(rme96)) {
- for (idx = 7; idx < 10; idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
+ for (idx = 7; idx < 10; idx++) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96));
+ if (err < 0)
return err;
+ }
}
return 0;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 720297cbdf87..8457a4bbc3df 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -289,7 +289,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
return 104857600000000 / rate; // 100 MHz
return 110100480000000 / rate; // 105 MHz
*/
-#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */
+#define DDS_NUMERATOR 104857600000000ULL /* = 2^20 * 10^8 */
#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)
#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)
@@ -1318,11 +1318,13 @@ static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
spin_lock_irqsave (&hmidi->lock, flags);
if (hmidi->output) {
if (!snd_rawmidi_transmit_empty (hmidi->output)) {
- if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) {
+ n_pending = snd_hdsp_midi_output_possible(hmidi->hdsp, hmidi->id);
+ if (n_pending > 0) {
if (n_pending > (int)sizeof (buf))
n_pending = sizeof (buf);
- if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
+ to_write = snd_rawmidi_transmit(hmidi->output, buf, n_pending);
+ if (to_write > 0) {
for (i = 0; i < to_write; ++i)
snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]);
}
@@ -1341,7 +1343,8 @@ static int snd_hdsp_midi_input_read (struct hdsp_midi *hmidi)
int i;
spin_lock_irqsave (&hmidi->lock, flags);
- if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
+ 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);
@@ -3322,7 +3325,9 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
}
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
+ kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (idx == 1) /* IEC958 (S/PDIF) Stream */
hdsp->spdif_ctl = kctl;
@@ -3331,12 +3336,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
/* ADAT SyncCheck status */
snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
snd_hdsp_adat_sync_check.index = 1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
+ kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
for (idx = 1; idx < 3; ++idx) {
snd_hdsp_adat_sync_check.index = idx+1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
+ kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
}
@@ -3344,7 +3353,9 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
/* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
if (hdsp->io_type == H9632) {
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
+ kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
}
}
@@ -3362,8 +3373,10 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
/* AEB control for H96xx card */
if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
- return err;
+ kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
+ return err;
}
return 0;
@@ -3942,7 +3955,8 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
if (snd_BUG_ON(channel < 0 || channel >= hdsp->max_channels))
return NULL;
- if ((mapped_channel = hdsp->channel_map[channel]) < 0)
+ mapped_channel = hdsp->channel_map[channel];
+ if (mapped_channel < 0)
return NULL;
if (stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -4114,7 +4128,8 @@ static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
spin_lock_irq(&hdsp->lock);
if (! hdsp->clock_source_locked) {
- if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
+ 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;
@@ -4122,7 +4137,8 @@ static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
}
spin_unlock_irq(&hdsp->lock);
- if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
+ err = hdsp_set_interrupt_interval(hdsp, params_period_size(params));
+ if (err < 0) {
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return err;
}
@@ -4854,14 +4870,15 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0)
+ err = hdsp_get_iobox_version(hdsp);
+ if (err < 0)
return err;
}
memset(&hdsp_version, 0, sizeof(hdsp_version));
hdsp_version.io_type = hdsp->io_type;
hdsp_version.firmware_rev = hdsp->firmware_rev;
- if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
- return -EFAULT;
+ if (copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))
+ return -EFAULT;
break;
}
case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
@@ -4900,17 +4917,20 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
hdsp->state |= HDSP_FirmwareCached;
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
+ err = snd_hdsp_load_firmware_from_cache(hdsp);
+ if (err < 0)
return err;
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0)
+ err = snd_hdsp_enable_io(hdsp);
+ if (err < 0)
return err;
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
- if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
+ err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp);
+ if (err < 0) {
dev_err(hdsp->card->dev,
"error creating alsa devices\n");
return err;
@@ -4960,7 +4980,8 @@ static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
struct snd_hwdep *hw;
int err;
- if ((err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw)) < 0)
+ err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw);
+ if (err < 0)
return err;
hdsp->hwdep = hw;
@@ -4978,7 +4999,8 @@ static int snd_hdsp_create_pcm(struct snd_card *card, struct hdsp *hdsp)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm);
+ if (err < 0)
return err;
hdsp->pcm = pcm;
@@ -5084,28 +5106,32 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
{
int err;
- if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
+ err = snd_hdsp_create_pcm(card, hdsp);
+ if (err < 0) {
dev_err(card->dev,
"Error creating pcm interface\n");
return err;
}
- if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
+ err = snd_hdsp_create_midi(card, hdsp, 0);
+ if (err < 0) {
dev_err(card->dev,
"Error creating first midi interface\n");
return err;
}
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
- if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
+ err = snd_hdsp_create_midi(card, hdsp, 1);
+ if (err < 0) {
dev_err(card->dev,
"Error creating second midi interface\n");
return err;
}
}
- if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
+ err = snd_hdsp_create_controls(card, hdsp);
+ if (err < 0) {
dev_err(card->dev,
"Error creating ctl interface\n");
return err;
@@ -5119,7 +5145,8 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
hdsp->capture_substream = NULL;
hdsp->playback_substream = NULL;
- if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
+ err = snd_hdsp_set_defaults(hdsp);
+ if (err < 0) {
dev_err(card->dev,
"Error setting default values\n");
return err;
@@ -5130,7 +5157,8 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
hdsp->port, hdsp->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
dev_err(card->dev,
"error registering card\n");
return err;
@@ -5151,7 +5179,8 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
return 0;
if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0)
+ err = hdsp_get_iobox_version(hdsp);
+ if (err < 0)
return err;
if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
return 0;
@@ -5197,21 +5226,25 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
hdsp->state |= HDSP_FirmwareCached;
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
+ err = snd_hdsp_load_firmware_from_cache(hdsp);
+ if (err < 0)
return err;
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0)
+ err = snd_hdsp_enable_io(hdsp);
+ if (err < 0)
return err;
- if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
+ err = snd_hdsp_create_hwdep(hdsp->card, hdsp);
+ if (err < 0) {
dev_err(hdsp->card->dev,
"error creating hwdep device\n");
return err;
}
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
- if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
+ err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp);
+ if (err < 0) {
dev_err(hdsp->card->dev,
"error creating alsa devices\n");
return err;
@@ -5280,15 +5313,18 @@ static int snd_hdsp_create(struct snd_card *card,
is_9632 = 1;
}
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(hdsp->pci);
- if ((err = pci_request_regions(pci, "hdsp")) < 0)
+ err = pci_request_regions(pci, "hdsp");
+ if (err < 0)
return err;
hdsp->port = pci_resource_start(pci, 0);
- if ((hdsp->iobase = ioremap(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
+ hdsp->iobase = ioremap(hdsp->port, HDSP_IO_EXTENT);
+ if (!hdsp->iobase) {
dev_err(hdsp->card->dev, "unable to remap region 0x%lx-0x%lx\n",
hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
return -EBUSY;
@@ -5306,7 +5342,8 @@ static int snd_hdsp_create(struct snd_card *card,
hdsp->use_midi_work = 1;
hdsp->dds_value = 0;
- if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
+ err = snd_hdsp_initialize_memory(hdsp);
+ if (err < 0)
return err;
if (!is_9652 && !is_9632) {
@@ -5318,7 +5355,8 @@ static int snd_hdsp_create(struct snd_card *card,
return err;
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- if ((err = hdsp_request_fw_loader(hdsp)) < 0)
+ err = hdsp_request_fw_loader(hdsp);
+ if (err < 0)
/* we don't fail as this can happen
if userspace is not ready for
firmware upload
@@ -5331,7 +5369,8 @@ static int snd_hdsp_create(struct snd_card *card,
/* we defer initialization */
dev_info(hdsp->card->dev,
"card initialization pending : waiting for firmware\n");
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
+ err = snd_hdsp_create_hwdep(card, hdsp);
+ if (err < 0)
return err;
return 0;
} else {
@@ -5346,7 +5385,8 @@ static int snd_hdsp_create(struct snd_card *card,
}
}
- if ((err = snd_hdsp_enable_io(hdsp)) != 0)
+ err = snd_hdsp_enable_io(hdsp);
+ if (err)
return err;
if (is_9652)
@@ -5355,7 +5395,8 @@ static int snd_hdsp_create(struct snd_card *card,
if (is_9632)
hdsp->io_type = H9632;
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
+ err = snd_hdsp_create_hwdep(card, hdsp);
+ if (err < 0)
return err;
snd_hdsp_initialize_channels(hdsp);
@@ -5363,7 +5404,8 @@ static int snd_hdsp_create(struct snd_card *card,
hdsp->state |= HDSP_FirmwareLoaded;
- if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
+ err = snd_hdsp_create_alsa_devices(card, hdsp);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 7a4d395abcee..f1aad38760d6 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -433,9 +433,9 @@ static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
spin_lock_irq(&s->lock);
- if ((restart = s->running)) {
+ restart = s->running;
+ if (restart)
rme9652_stop(s);
- }
frames >>= 7;
n = 0;
@@ -518,16 +518,15 @@ static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
return -EBUSY;
}
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652->control_register &= ~(RME9652_freq | RME9652_DS);
rme9652->control_register |= rate;
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
if (rate & RME9652_DS) {
if (rme9652->ss_channels == RME9652_NCHANNELS) {
@@ -878,15 +877,14 @@ static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal)
/* XXX do we actually need to stop the card when we do this ? */
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
return 0;
}
@@ -943,15 +941,14 @@ static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in)
rme9652->control_register &= ~RME9652_inp;
rme9652->control_register |= rme9652_encode_spdif_in(in);
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
return 0;
}
@@ -1010,15 +1007,14 @@ static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out)
rme9652->control_register &= ~RME9652_opt_out;
}
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
return 0;
}
@@ -1086,15 +1082,14 @@ static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode)
break;
}
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
return 0;
}
@@ -1173,15 +1168,14 @@ static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref)
break;
}
- if ((restart = rme9652->running)) {
+ restart = rme9652->running;
+ if (restart)
rme9652_stop(rme9652);
- }
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
- if (restart) {
+ if (restart)
rme9652_start(rme9652);
- }
return 0;
}
@@ -1513,19 +1507,27 @@ static int snd_rme9652_create_controls(struct snd_card *card, struct snd_rme9652
struct snd_kcontrol *kctl;
for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
+ kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
if (idx == 1) /* IEC958 (S/PDIF) Stream */
rme9652->spdif_ctl = kctl;
}
- if (rme9652->ss_channels == RME9652_NCHANNELS)
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat3_check, rme9652))) < 0)
+ if (rme9652->ss_channels == RME9652_NCHANNELS) {
+ kctl = snd_ctl_new1(&snd_rme9652_adat3_check, rme9652);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
- if (rme9652->hw_rev >= 15)
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat1_input, rme9652))) < 0)
+ if (rme9652->hw_rev >= 15) {
+ kctl = snd_ctl_new1(&snd_rme9652_adat1_input, rme9652);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -1842,9 +1844,9 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS))
return NULL;
- if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
+ mapped_channel = rme9652->channel_map[channel];
+ if (mapped_channel < 0)
return NULL;
- }
if (stream == SNDRV_PCM_STREAM_CAPTURE) {
return rme9652->capture_buffer +
@@ -2021,12 +2023,14 @@ static int snd_rme9652_hw_params(struct snd_pcm_substream *substream,
/* how to make sure that the rate matches an externally-set one ?
*/
- if ((err = rme9652_set_rate(rme9652, params_rate(params))) < 0) {
+ err = rme9652_set_rate(rme9652, params_rate(params));
+ if (err < 0) {
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
return err;
}
- if ((err = rme9652_set_interrupt_interval(rme9652, params_period_size(params))) < 0) {
+ err = rme9652_set_interrupt_interval(rme9652, params_period_size(params));
+ if (err < 0) {
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return err;
}
@@ -2406,11 +2410,9 @@ static int snd_rme9652_create_pcm(struct snd_card *card,
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card,
- rme9652->card_name,
- 0, 1, 1, &pcm)) < 0) {
+ err = snd_pcm_new(card, rme9652->card_name, 0, 1, 1, &pcm);
+ if (err < 0)
return err;
- }
rme9652->pcm = pcm;
pcm->private_data = rme9652;
@@ -2450,12 +2452,14 @@ static int snd_rme9652_create(struct snd_card *card,
return -ENODEV;
}
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
spin_lock_init(&rme9652->lock);
- if ((err = pci_request_regions(pci, "rme9652")) < 0)
+ err = pci_request_regions(pci, "rme9652");
+ if (err < 0)
return err;
rme9652->port = pci_resource_start(pci, 0);
rme9652->iobase = ioremap(rme9652->port, RME9652_IO_EXTENT);
@@ -2528,17 +2532,17 @@ static int snd_rme9652_create(struct snd_card *card,
pci_set_master(rme9652->pci);
- if ((err = snd_rme9652_initialize_memory(rme9652)) < 0) {
+ err = snd_rme9652_initialize_memory(rme9652);
+ if (err < 0)
return err;
- }
- if ((err = snd_rme9652_create_pcm(card, rme9652)) < 0) {
+ err = snd_rme9652_create_pcm(card, rme9652);
+ if (err < 0)
return err;
- }
- if ((err = snd_rme9652_create_controls(card, rme9652)) < 0) {
+ err = snd_rme9652_create_controls(card, rme9652);
+ if (err < 0)
return err;
- }
snd_rme9652_proc_init(rme9652);
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 7de10997775f..03a48da897e3 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -852,7 +852,8 @@ static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm);
+ if (err < 0)
return err;
if (snd_BUG_ON(!pcm))
return -EINVAL;
@@ -1093,7 +1094,9 @@ static int snd_sonicvibes_mixer(struct sonicvibes *sonic)
strcpy(card->mixername, "S3 SonicVibes");
for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic))) < 0)
+ kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
switch (idx) {
case 0:
@@ -1226,7 +1229,8 @@ static int snd_sonicvibes_create(struct snd_card *card,
*rsonic = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
@@ -1246,7 +1250,8 @@ static int snd_sonicvibes_create(struct snd_card *card,
sonic->pci = pci;
sonic->irq = -1;
- if ((err = pci_request_regions(pci, "S3 SonicVibes")) < 0) {
+ err = pci_request_regions(pci, "S3 SonicVibes");
+ if (err < 0) {
kfree(sonic);
pci_disable_device(pci);
return err;
@@ -1289,14 +1294,16 @@ static int snd_sonicvibes_create(struct snd_card *card,
pci_write_config_dword(pci, 0x40, dmaa);
pci_write_config_dword(pci, 0x48, dmac);
- if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
+ sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A");
+ if (!sonic->res_dmaa) {
snd_sonicvibes_free(sonic);
dev_err(card->dev,
"unable to grab DDMA-A port at 0x%x-0x%x\n",
dmaa, dmaa + 0x10 - 1);
return -EBUSY;
}
- if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
+ sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C");
+ if (!sonic->res_dmac) {
snd_sonicvibes_free(sonic);
dev_err(card->dev,
"unable to grab DDMA-C port at 0x%x-0x%x\n",
@@ -1358,7 +1365,8 @@ static int snd_sonicvibes_create(struct snd_card *card,
#endif
sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops);
+ if (err < 0) {
snd_sonicvibes_free(sonic);
return err;
}
@@ -1405,9 +1413,11 @@ static int snd_sonicvibes_midi(struct sonicvibes *sonic,
mpu->private_data = sonic;
mpu->open_input = snd_sonicvibes_midi_input_open;
mpu->close_input = snd_sonicvibes_midi_input_close;
- for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
+ for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++) {
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic));
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -1439,10 +1449,11 @@ static int snd_sonic_probe(struct pci_dev *pci,
return -ENODEV;
}
}
- if ((err = snd_sonicvibes_create(card, pci,
- reverb[dev] ? 1 : 0,
- mge[dev] ? 1 : 0,
- &sonic)) < 0) {
+ err = snd_sonicvibes_create(card, pci,
+ reverb[dev] ? 1 : 0,
+ mge[dev] ? 1 : 0,
+ &sonic);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1455,30 +1466,35 @@ static int snd_sonic_probe(struct pci_dev *pci,
(unsigned long long)pci_resource_start(pci, 1),
sonic->irq);
- if ((err = snd_sonicvibes_pcm(sonic, 0)) < 0) {
+ err = snd_sonicvibes_pcm(sonic, 0);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_sonicvibes_mixer(sonic)) < 0) {
+ err = snd_sonicvibes_mixer(sonic);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
- sonic->midi_port,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &midi_uart)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
+ sonic->midi_port,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &midi_uart);
+ if (err < 0) {
snd_card_free(card);
return err;
}
snd_sonicvibes_midi(sonic, midi_uart);
- if ((err = snd_opl3_create(card, sonic->synth_port,
- sonic->synth_port + 2,
- OPL3_HW_OPL3_SV, 1, &opl3)) < 0) {
+ err = snd_opl3_create(card, sonic->synth_port,
+ sonic->synth_port + 2,
+ OPL3_HW_OPL3_SV, 1, &opl3);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1489,7 +1505,8 @@ static int snd_sonic_probe(struct pci_dev *pci,
return err;
}
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index a51041205f7c..60e4dca28c2b 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -67,11 +67,12 @@ static int snd_trident_probe(struct pci_dev *pci,
if (err < 0)
return err;
- if ((err = snd_trident_create(card, pci,
- pcm_channels[dev],
- ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
- wavetable_size[dev],
- &trident)) < 0) {
+ err = snd_trident_create(card, pci,
+ pcm_channels[dev],
+ ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
+ wavetable_size[dev],
+ &trident);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -100,38 +101,44 @@ static int snd_trident_probe(struct pci_dev *pci,
sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
card->shortname, trident->port, trident->irq);
- if ((err = snd_trident_pcm(trident, pcm_dev++)) < 0) {
+ err = snd_trident_pcm(trident, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
switch (trident->device) {
case TRIDENT_DEVICE_ID_DX:
case TRIDENT_DEVICE_ID_NX:
- if ((err = snd_trident_foldback_pcm(trident, pcm_dev++)) < 0) {
+ err = snd_trident_foldback_pcm(trident, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
break;
}
if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_trident_spdif_pcm(trident, pcm_dev++)) < 0) {
+ err = snd_trident_spdif_pcm(trident, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
}
- if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
- (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
- trident->midi_port,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &trident->rmidi)) < 0) {
- snd_card_free(card);
- return err;
+ if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
+ trident->midi_port,
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &trident->rmidi);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
}
snd_trident_create_gameport(trident);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h
index c7567edbe4c4..c579a44bb9ae 100644
--- a/sound/pci/trident/trident.h
+++ b/sound/pci/trident/trident.h
@@ -251,7 +251,6 @@ struct snd_trident_memblk_arg {
struct snd_trident_tlb {
__le32 *entries; /* 16k-aligned TLB table */
dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
- unsigned long * shadow_entries; /* shadow entries with virtual addresses */
struct snd_dma_buffer buffer;
struct snd_util_memhdr * memhdr; /* page allocation list */
struct snd_dma_buffer silent_page;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 20145143f6a6..cfbca3bd60ed 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2119,7 +2119,8 @@ int snd_trident_pcm(struct snd_trident *trident, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
+ err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = trident;
@@ -2178,7 +2179,8 @@ int snd_trident_foldback_pcm(struct snd_trident *trident, int device)
if (trident->device == TRIDENT_DEVICE_ID_NX)
num_chan = 4;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
+ err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback);
+ if (err < 0)
return err;
foldback->private_data = trident;
@@ -2228,7 +2230,8 @@ int snd_trident_spdif_pcm(struct snd_trident *trident, int device)
struct snd_pcm *spdif;
int err;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
+ err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif);
+ if (err < 0)
return err;
spdif->private_data = trident;
@@ -2921,7 +2924,8 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
if (!uctl)
return -ENOMEM;
- if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0)
+ err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus);
+ if (err < 0)
goto __out;
memset(&_ac97, 0, sizeof(_ac97));
@@ -2929,9 +2933,11 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
trident->ac97_detect = 1;
__again:
- if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) {
+ err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97);
+ if (err < 0) {
if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_trident_sis_reset(trident)) < 0)
+ err = snd_trident_sis_reset(trident);
+ if (err < 0)
goto __out;
if (retries-- > 0)
goto __again;
@@ -2962,10 +2968,14 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
trident->ac97_detect = 0;
if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0)
+ kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl->put(kctl, uctl);
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0)
+ kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl->put(kctl, uctl);
outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
@@ -2979,28 +2989,38 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
tmix = &trident->pcm_mixer[idx];
tmix->voice = NULL;
}
- if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL)
+ trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident);
+ if (!trident->ctl_vol)
goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_vol)))
+ err = snd_ctl_add(card, trident->ctl_vol);
+ if (err)
goto __out;
- if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL)
+ trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident);
+ if (!trident->ctl_pan)
goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_pan)))
+ err = snd_ctl_add(card, trident->ctl_pan);
+ if (err)
goto __out;
- if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL)
+ trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident);
+ if (!trident->ctl_rvol)
goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_rvol)))
+ err = snd_ctl_add(card, trident->ctl_rvol);
+ if (err)
goto __out;
- if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL)
+ trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident);
+ if (!trident->ctl_cvol)
goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_cvol)))
+ err = snd_ctl_add(card, trident->ctl_cvol);
+ if (err)
goto __out;
if (trident->device == TRIDENT_DEVICE_ID_NX) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0)
+ kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl->put(kctl, uctl);
}
@@ -3016,7 +3036,8 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
kctl->id.index++;
idx = kctl->id.index;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl->put(kctl, uctl);
@@ -3027,7 +3048,8 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
}
kctl->id.index = idx;
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
@@ -3037,7 +3059,8 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
}
kctl->id.index = idx;
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
@@ -3047,7 +3070,8 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
}
kctl->id.index = idx;
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
goto __out;
trident->spdif_pcm_ctl = kctl;
}
@@ -3307,12 +3331,6 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident)
}
trident->tlb.entries = (__le32 *)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
- /* allocate shadow TLB page table (virtual addresses) */
- trident->tlb.shadow_entries =
- vmalloc(array_size(SNDRV_TRIDENT_MAX_PAGES,
- sizeof(unsigned long)));
- if (!trident->tlb.shadow_entries)
- return -ENOMEM;
/* allocate and setup silent page and initialise TLB entries */
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &trident->pci->dev,
@@ -3321,10 +3339,8 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident)
return -ENOMEM;
}
memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
- for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
+ for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++)
trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
- trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area;
- }
/* use emu memory block manager code to manage tlb page allocation */
trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
@@ -3449,7 +3465,8 @@ static int snd_trident_sis_init(struct snd_trident *trident)
{
int err;
- if ((err = snd_trident_sis_reset(trident)) < 0)
+ err = snd_trident_sis_reset(trident);
+ if (err < 0)
return err;
snd_trident_stop_all_voices(trident);
@@ -3494,7 +3511,8 @@ int snd_trident_create(struct snd_card *card,
*rtrident = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 30 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(30))) {
@@ -3528,7 +3546,8 @@ int snd_trident_create(struct snd_card *card,
trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
pci_set_master(pci);
- if ((err = pci_request_regions(pci, "Trident Audio")) < 0) {
+ err = pci_request_regions(pci, "Trident Audio");
+ if (err < 0) {
kfree(trident);
pci_disable_device(pci);
return err;
@@ -3548,7 +3567,8 @@ int snd_trident_create(struct snd_card *card,
trident->tlb.entries = NULL;
trident->tlb.buffer.area = NULL;
if (trident->device == TRIDENT_DEVICE_ID_NX) {
- if ((err = snd_trident_tlb_alloc(trident)) < 0) {
+ err = snd_trident_tlb_alloc(trident);
+ if (err < 0) {
snd_trident_free(trident);
return err;
}
@@ -3576,12 +3596,14 @@ int snd_trident_create(struct snd_card *card,
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops);
+ if (err < 0) {
snd_trident_free(trident);
return err;
}
- if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0)
+ err = snd_trident_mixer(trident, pcm_spdif_device);
+ if (err < 0)
return err;
/* initialise synth voices */
@@ -3635,7 +3657,6 @@ static int snd_trident_free(struct snd_trident *trident)
snd_util_memhdr_free(trident->tlb.memhdr);
if (trident->tlb.silent_page.area)
snd_dma_free_pages(&trident->tlb.silent_page);
- vfree(trident->tlb.shadow_entries);
snd_dma_free_pages(&trident->tlb.buffer);
}
pci_release_regions(trident->pci);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index bb24dbf0530d..4ad3855101c9 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -19,11 +19,8 @@
/* page arguments of these two macros are Trident page (4096 bytes), not like
* aligned pages in others
*/
-#define __set_tlb_bus(trident,page,ptr,addr) \
- do { (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); \
- (trident)->tlb.shadow_entries[page] = (ptr); } while (0)
-#define __tlb_to_ptr(trident,page) \
- (void*)((trident)->tlb.shadow_entries[page])
+#define __set_tlb_bus(trident,page,addr) \
+ (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1))
#define __tlb_to_addr(trident,page) \
(dma_addr_t)le32_to_cpu((trident->tlb.entries[page]) & ~(SNDRV_TRIDENT_PAGE_SIZE - 1))
@@ -32,15 +29,13 @@
#define ALIGN_PAGE_SIZE PAGE_SIZE /* minimum page size for allocation */
#define MAX_ALIGN_PAGES SNDRV_TRIDENT_MAX_PAGES /* maxmium aligned pages */
/* fill TLB entrie(s) corresponding to page with ptr */
-#define set_tlb_bus(trident,page,ptr,addr) __set_tlb_bus(trident,page,ptr,addr)
+#define set_tlb_bus(trident,page,addr) __set_tlb_bus(trident,page,addr)
/* fill TLB entrie(s) corresponding to page with silence pointer */
-#define set_silent_tlb(trident,page) __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr)
+#define set_silent_tlb(trident,page) __set_tlb_bus(trident, page, trident->tlb.silent_page.addr)
/* get aligned page from offset address */
#define get_aligned_page(offset) ((offset) >> 12)
/* get offset address from aligned page */
#define aligned_page_offset(page) ((page) << 12)
-/* get buffer address from aligned page */
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, page)
/* get PCI physical address from aligned page */
#define page_to_addr(trident,page) __tlb_to_addr(trident, page)
@@ -50,22 +45,21 @@
#define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / 2)
#define get_aligned_page(offset) ((offset) >> 13)
#define aligned_page_offset(page) ((page) << 13)
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) << 1)
#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) << 1)
/* fill TLB entries -- we need to fill two entries */
static inline void set_tlb_bus(struct snd_trident *trident, int page,
- unsigned long ptr, dma_addr_t addr)
+ dma_addr_t addr)
{
page <<= 1;
- __set_tlb_bus(trident, page, ptr, addr);
- __set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
+ __set_tlb_bus(trident, page, addr);
+ __set_tlb_bus(trident, page+1, addr + SNDRV_TRIDENT_PAGE_SIZE);
}
static inline void set_silent_tlb(struct snd_trident *trident, int page)
{
page <<= 1;
- __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
- __set_tlb_bus(trident, page+1, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
+ __set_tlb_bus(trident, page, trident->tlb.silent_page.addr);
+ __set_tlb_bus(trident, page+1, trident->tlb.silent_page.addr);
}
#else
@@ -80,18 +74,16 @@ static inline void set_silent_tlb(struct snd_trident *trident, int page)
*/
#define get_aligned_page(offset) ((offset) / ALIGN_PAGE_SIZE)
#define aligned_page_offset(page) ((page) * ALIGN_PAGE_SIZE)
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) * UNIT_PAGES)
#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
/* fill TLB entries -- UNIT_PAGES entries must be filled */
static inline void set_tlb_bus(struct snd_trident *trident, int page,
- unsigned long ptr, dma_addr_t addr)
+ dma_addr_t addr)
{
int i;
page *= UNIT_PAGES;
for (i = 0; i < UNIT_PAGES; i++, page++) {
- __set_tlb_bus(trident, page, ptr, addr);
- ptr += SNDRV_TRIDENT_PAGE_SIZE;
+ __set_tlb_bus(trident, page, addr);
addr += SNDRV_TRIDENT_PAGE_SIZE;
}
}
@@ -100,20 +92,11 @@ static inline void set_silent_tlb(struct snd_trident *trident, int page)
int i;
page *= UNIT_PAGES;
for (i = 0; i < UNIT_PAGES; i++, page++)
- __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
+ __set_tlb_bus(trident, page, trident->tlb.silent_page.addr);
}
#endif /* PAGE_SIZE */
-/* calculate buffer pointer from offset address */
-static inline void *offset_ptr(struct snd_trident *trident, int offset)
-{
- char *ptr;
- ptr = page_to_ptr(trident, get_aligned_page(offset));
- ptr += offset % ALIGN_PAGE_SIZE;
- return (void*)ptr;
-}
-
/* first and last (aligned) pages of memory block */
#define firstpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
#define lastpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
@@ -201,14 +184,12 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident,
for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
unsigned long ofs = idx << PAGE_SHIFT;
dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- unsigned long ptr = (unsigned long)
- snd_pcm_sgbuf_get_ptr(substream, ofs);
if (! is_valid_page(addr)) {
__snd_util_mem_free(hdr, blk);
mutex_unlock(&hdr->block_mutex);
return NULL;
}
- set_tlb_bus(trident, page, ptr, addr);
+ set_tlb_bus(trident, page, addr);
}
mutex_unlock(&hdr->block_mutex);
return blk;
@@ -226,7 +207,6 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident,
int page;
struct snd_pcm_runtime *runtime = substream->runtime;
dma_addr_t addr;
- unsigned long ptr;
if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
@@ -245,15 +225,14 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident,
/* set TLB entries */
addr = runtime->dma_addr;
- ptr = (unsigned long)runtime->dma_area;
for (page = firstpg(blk); page <= lastpg(blk); page++,
- ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
+ addr += SNDRV_TRIDENT_PAGE_SIZE) {
if (! is_valid_page(addr)) {
__snd_util_mem_free(hdr, blk);
mutex_unlock(&hdr->block_mutex);
return NULL;
}
- set_tlb_bus(trident, page, ptr, addr);
+ set_tlb_bus(trident, page, addr);
}
mutex_unlock(&hdr->block_mutex);
return blk;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index fd1f2f9cfbc3..943813a06abc 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -515,7 +515,8 @@ static int snd_via82xx_codec_ready(struct via82xx *chip, int secondary)
while (timeout-- > 0) {
udelay(1);
- if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
+ val = snd_via82xx_codec_xread(chip);
+ if (!(val & VIA_REG_AC97_BUSY))
return val & 0xffff;
}
dev_err(chip->card->dev, "codec_ready: codec %i is not ready [0x%x]\n",
@@ -1023,7 +1024,8 @@ static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream)
int rate_changed;
u32 rbits;
- if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0)
+ rate_changed = via_lock_rate(&chip->rates[0], ac97_rate);
+ if (rate_changed < 0)
return rate_changed;
if (rate_changed)
snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
@@ -1197,7 +1199,8 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/* we may remove following constaint when we modify table entries
in interrupt */
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
if (use_src) {
@@ -1222,7 +1225,8 @@ static int snd_via686_playback_open(struct snd_pcm_substream *substream)
struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
int err;
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ err = snd_via82xx_pcm_open(chip, viadev, substream);
+ if (err < 0)
return err;
return 0;
}
@@ -1238,7 +1242,8 @@ static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
int err;
viadev = &chip->devs[chip->playback_devno + substream->number];
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ err = snd_via82xx_pcm_open(chip, viadev, substream);
+ if (err < 0)
return err;
stream = viadev->reg_offset / 0x10;
if (chip->dxs_controls[stream]) {
@@ -1275,7 +1280,8 @@ static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
.mask = 0,
};
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ err = snd_via82xx_pcm_open(chip, viadev, substream);
+ if (err < 0)
return err;
substream->runtime->hw.channels_max = 6;
if (chip->revision == VIA_REV_8233A)
@@ -1875,7 +1881,8 @@ static int snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_overrid
.wait = snd_via82xx_codec_wait,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
@@ -1885,7 +1892,8 @@ static int snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_overrid
ac97.private_free = snd_via82xx_mixer_free_ac97;
ac97.pci = chip->pci;
ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
@@ -2054,9 +2062,9 @@ static int snd_via686_init_misc(struct via82xx *chip)
break;
}
}
- if (mpu_port >= 0x200 &&
- (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
- != NULL) {
+ if (mpu_port >= 0x200)
+ chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401");
+ if (chip->mpu_res) {
if (rev_h)
legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */
legacy |= VIA_FUNC_ENABLE_MIDI;
@@ -2173,7 +2181,8 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
+ val = snd_via82xx_codec_xread(chip);
+ if (val & VIA_REG_AC97_BUSY)
dev_err(chip->card->dev,
"AC'97 codec is not ready [0x%x]\n", val);
@@ -2186,7 +2195,8 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
do {
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
+ val = snd_via82xx_codec_xread(chip);
+ if (val & VIA_REG_AC97_SECONDARY_VALID) {
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
@@ -2337,10 +2347,12 @@ static int snd_via82xx_create(struct snd_card *card,
.dev_free = snd_via82xx_dev_free,
};
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -2360,7 +2372,8 @@ static int snd_via82xx_create(struct snd_card *card,
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE,
chip->old_legacy & ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM));
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
+ err = pci_request_regions(pci, card->driver);
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -2380,12 +2393,14 @@ static int snd_via82xx_create(struct snd_card *card,
if (ac97_clock >= 8000 && ac97_clock <= 48000)
chip->ac97_clock = ac97_clock;
- if ((err = snd_via82xx_chip_init(chip)) < 0) {
+ err = snd_via82xx_chip_init(chip);
+ if (err < 0) {
snd_via82xx_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_via82xx_free(chip);
return err;
}
@@ -2541,24 +2556,31 @@ static int snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
- ac97_clock, &chip)) < 0)
+ err = snd_via82xx_create(card, pci, chip_type, pci->revision,
+ ac97_clock, &chip);
+ if (err < 0)
goto __error;
card->private_data = chip;
- if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
+ err = snd_via82xx_mixer_new(chip, ac97_quirk);
+ if (err < 0)
goto __error;
if (chip_type == TYPE_VIA686) {
- if ((err = snd_via686_pcm_new(chip)) < 0 ||
- (err = snd_via686_init_misc(chip)) < 0)
+ err = snd_via686_pcm_new(chip);
+ if (err < 0)
+ goto __error;
+ err = snd_via686_init_misc(chip);
+ if (err < 0)
goto __error;
} else {
if (chip_type == TYPE_VIA8233A) {
- if ((err = snd_via8233a_pcm_new(chip)) < 0)
+ err = snd_via8233a_pcm_new(chip);
+ if (err < 0)
goto __error;
// chip->dxs_fixed = 1; /* FIXME: use 48k for DXS #3? */
} else {
- if ((err = snd_via8233_pcm_new(chip)) < 0)
+ err = snd_via8233_pcm_new(chip);
+ if (err < 0)
goto __error;
if (dxs_support == VIA_DXS_48K)
chip->dxs_fixed = 1;
@@ -2569,7 +2591,8 @@ static int snd_via82xx_probe(struct pci_dev *pci,
chip->dxs_src = 1;
}
}
- if ((err = snd_via8233_init_misc(chip)) < 0)
+ err = snd_via8233_init_misc(chip);
+ if (err < 0)
goto __error;
}
@@ -2583,7 +2606,8 @@ static int snd_via82xx_probe(struct pci_dev *pci,
snd_via82xx_proc_init(chip);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 30253306f67c..07278a3dc8c1 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -369,7 +369,8 @@ static int snd_via82xx_codec_ready(struct via82xx_modem *chip, int secondary)
while (timeout-- > 0) {
udelay(1);
- if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
+ val = snd_via82xx_codec_xread(chip);
+ if (!(val & VIA_REG_AC97_BUSY))
return val & 0xffff;
}
dev_err(chip->card->dev, "codec_ready: codec %i is not ready [0x%x]\n",
@@ -738,13 +739,15 @@ static int snd_via82xx_modem_pcm_open(struct via82xx_modem *chip, struct viadev
runtime->hw = snd_via82xx_hw;
- if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates)) < 0)
+ err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &hw_constraints_rates);
+ if (err < 0)
return err;
/* we may remove following constaint when we modify table entries
in interrupt */
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
return err;
runtime->private_data = viadev;
@@ -878,7 +881,8 @@ static int snd_via82xx_mixer_new(struct via82xx_modem *chip)
.wait = snd_via82xx_codec_wait,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
@@ -890,7 +894,8 @@ static int snd_via82xx_mixer_new(struct via82xx_modem *chip)
ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
ac97.num = chip->ac97_secondary;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
return 0;
@@ -971,7 +976,8 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
+ val = snd_via82xx_codec_xread(chip);
+ if (val & VIA_REG_AC97_BUSY)
dev_err(chip->card->dev,
"AC'97 codec is not ready [0x%x]\n", val);
@@ -983,7 +989,8 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
VIA_REG_AC97_SECONDARY_VALID |
(VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
do {
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
+ val = snd_via82xx_codec_xread(chip);
+ if (val & VIA_REG_AC97_SECONDARY_VALID) {
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
@@ -1079,10 +1086,12 @@ static int snd_via82xx_create(struct snd_card *card,
.dev_free = snd_via82xx_dev_free,
};
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -1092,7 +1101,8 @@ static int snd_via82xx_create(struct snd_card *card,
chip->pci = pci;
chip->irq = -1;
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
+ err = pci_request_regions(pci, card->driver);
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1109,12 +1119,14 @@ static int snd_via82xx_create(struct snd_card *card,
if (ac97_clock >= 8000 && ac97_clock <= 48000)
chip->ac97_clock = ac97_clock;
- if ((err = snd_via82xx_chip_init(chip)) < 0) {
+ err = snd_via82xx_chip_init(chip);
+ if (err < 0) {
snd_via82xx_free(chip);
return err;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_via82xx_free(chip);
return err;
}
@@ -1154,14 +1166,17 @@ static int snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
- ac97_clock, &chip)) < 0)
+ err = snd_via82xx_create(card, pci, chip_type, pci->revision,
+ ac97_clock, &chip);
+ if (err < 0)
goto __error;
card->private_data = chip;
- if ((err = snd_via82xx_mixer_new(chip)) < 0)
+ err = snd_via82xx_mixer_new(chip);
+ if (err < 0)
goto __error;
- if ((err = snd_via686_pcm_new(chip)) < 0 )
+ err = snd_via686_pcm_new(chip);
+ if (err < 0)
goto __error;
/* disable interrupts */
@@ -1173,7 +1188,8 @@ static int snd_via82xx_probe(struct pci_dev *pci,
snd_via82xx_proc_init(chip);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 2a9e1a77a81a..04c7204cb7bc 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -133,7 +133,8 @@ static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
const struct snd_vx_ops *vx_ops;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(pci);
@@ -147,7 +148,8 @@ static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
vx = to_vx222(chip);
vx->pci = pci;
- if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
+ err = pci_request_regions(pci, CARD_NAME);
+ if (err < 0) {
snd_vx222_free(chip);
return err;
}
@@ -164,7 +166,8 @@ static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
chip->irq = pci->irq;
card->sync_irq = chip->irq;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_vx222_free(chip);
return err;
}
@@ -207,7 +210,8 @@ static int snd_vx222_probe(struct pci_dev *pci,
hw = &vx222_v2_hw;
break;
}
- if ((err = snd_vx222_create(card, pci, hw, &vx)) < 0) {
+ err = snd_vx222_create(card, pci, hw, &vx);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -223,12 +227,14 @@ static int snd_vx222_probe(struct pci_dev *pci,
vx->core.dev = &pci->dev;
#endif
- if ((err = snd_vx_setup_firmware(&vx->core)) < 0) {
+ err = snd_vx_setup_firmware(&vx->core);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index a05537202738..3e7e928b24f8 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -408,9 +408,11 @@ static int vx2_load_dsp(struct vx_core *vx, int index, const struct firmware *ds
switch (index) {
case 1:
/* xilinx image */
- if ((err = vx2_load_xilinx_binary(vx, dsp)) < 0)
+ err = vx2_load_xilinx_binary(vx, dsp);
+ if (err < 0)
return err;
- if ((err = vx2_test_xilinx(vx)) < 0)
+ err = vx2_test_xilinx(vx);
+ if (err < 0)
return err;
return 0;
case 2:
@@ -972,9 +974,11 @@ static int vx2_add_mic_controls(struct vx_core *_chip)
vx2_set_input_level(chip);
/* controls */
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip))) < 0)
+ err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip));
+ if (err < 0)
return err;
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
+ err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip));
+ if (err < 0)
return err;
return 0;
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 99be1490ef0e..7e32d57147ff 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -72,7 +72,8 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
if (io_port == 1) {
/* auto-detect */
- if (!(io_port = pci_resource_start(chip->pci, 2)))
+ io_port = pci_resource_start(chip->pci, 2);
+ if (!io_port)
return -ENODEV;
}
} else {
@@ -81,7 +82,8 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
for (io_port = 0x201; io_port <= 0x205; io_port++) {
if (io_port == 0x203)
continue;
- if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL)
+ r = request_region(io_port, 1, "YMFPCI gameport");
+ if (r)
break;
}
if (!r) {
@@ -102,10 +104,13 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
}
}
- if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) {
- dev_err(chip->card->dev,
- "joystick port %#x is in use.\n", io_port);
- return -EBUSY;
+ if (!r) {
+ r = request_region(io_port, 1, "YMFPCI gameport");
+ if (!r) {
+ dev_err(chip->card->dev,
+ "joystick port %#x is in use.\n", io_port);
+ return -EBUSY;
+ }
}
chip->gameport = gp = gameport_allocate_port();
@@ -193,8 +198,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
/* auto-detect */
fm_port[dev] = pci_resource_start(pci, 1);
}
- if (fm_port[dev] > 0 &&
- (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
+ if (fm_port[dev] > 0)
+ fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3");
+ if (fm_res) {
legacy_ctrl |= YMFPCI_LEGACY_FMEN;
pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
}
@@ -202,8 +208,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
/* auto-detect */
mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
}
- if (mpu_port[dev] > 0 &&
- (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
+ if (mpu_port[dev] > 0)
+ mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401");
+ if (mpu_res) {
legacy_ctrl |= YMFPCI_LEGACY_MEN;
pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
}
@@ -215,8 +222,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
case 0x3a8: legacy_ctrl2 |= 3; break;
default: fm_port[dev] = 0; break;
}
- if (fm_port[dev] > 0 &&
- (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
+ if (fm_port[dev] > 0)
+ fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3");
+ if (fm_res) {
legacy_ctrl |= YMFPCI_LEGACY_FMEN;
} else {
legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
@@ -229,8 +237,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
case 0x334: legacy_ctrl2 |= 3 << 4; break;
default: mpu_port[dev] = 0; break;
}
- if (mpu_port[dev] > 0 &&
- (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
+ if (mpu_port[dev] > 0)
+ mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401");
+ if (mpu_res) {
legacy_ctrl |= YMFPCI_LEGACY_MEN;
} else {
legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
@@ -244,9 +253,8 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
- if ((err = snd_ymfpci_create(card, pci,
- old_legacy_ctrl,
- &chip)) < 0) {
+ err = snd_ymfpci_create(card, pci, old_legacy_ctrl, &chip);
+ if (err < 0) {
release_and_free_resource(mpu_res);
release_and_free_resource(fm_res);
goto free_card;
@@ -287,11 +295,12 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
goto free_card;
if (chip->mpu_res) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
- mpu_port[dev],
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rawmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
+ mpu_port[dev],
+ MPU401_INFO_INTEGRATED |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &chip->rawmidi);
+ if (err < 0) {
dev_warn(card->dev,
"cannot initialize MPU401 at 0x%lx, skipping...\n",
mpu_port[dev]);
@@ -300,18 +309,22 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
}
}
if (chip->fm_res) {
- if ((err = snd_opl3_create(card,
- fm_port[dev],
- fm_port[dev] + 2,
- OPL3_HW_OPL3, 1, &opl3)) < 0) {
+ err = snd_opl3_create(card,
+ fm_port[dev],
+ fm_port[dev] + 2,
+ OPL3_HW_OPL3, 1, &opl3);
+ if (err < 0) {
dev_warn(card->dev,
"cannot initialize FM OPL3 at 0x%lx, skipping...\n",
fm_port[dev]);
legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
- } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- dev_err(card->dev, "cannot create opl3 hwdep\n");
- goto free_card;
+ } else {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
+ dev_err(card->dev, "cannot create opl3 hwdep\n");
+ goto free_card;
+ }
}
}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index cacc6a9d14c8..8fd060769882 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -292,7 +292,8 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_
struct snd_ymfpci_pcm *ypcm;
u32 pos, delta;
- if ((ypcm = voice->ypcm) == NULL)
+ ypcm = voice->ypcm;
+ if (!ypcm)
return;
if (ypcm->substream == NULL)
return;
@@ -628,7 +629,8 @@ static int snd_ymfpci_playback_hw_params(struct snd_pcm_substream *substream,
struct snd_ymfpci_pcm *ypcm = runtime->private_data;
int err;
- if ((err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params))) < 0)
+ err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params));
+ if (err < 0)
return err;
return 0;
}
@@ -932,7 +934,8 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
struct snd_ymfpci_pcm *ypcm;
int err;
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+ err = snd_ymfpci_playback_open_1(substream);
+ if (err < 0)
return err;
ypcm = runtime->private_data;
ypcm->output_front = 1;
@@ -954,7 +957,8 @@ static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream)
struct snd_ymfpci_pcm *ypcm;
int err;
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+ err = snd_ymfpci_playback_open_1(substream);
+ if (err < 0)
return err;
ypcm = runtime->private_data;
ypcm->output_front = 0;
@@ -982,7 +986,8 @@ static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream)
struct snd_ymfpci_pcm *ypcm;
int err;
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+ err = snd_ymfpci_playback_open_1(substream);
+ if (err < 0)
return err;
ypcm = runtime->private_data;
ypcm->output_front = 0;
@@ -1124,7 +1129,8 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1157,7 +1163,8 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1190,7 +1197,8 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1230,7 +1238,8 @@ int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
@@ -1785,7 +1794,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
.read = snd_ymfpci_codec_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+ if (err < 0)
return err;
chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */
@@ -1793,7 +1803,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_ymfpci_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
/* to be sure */
@@ -1801,7 +1812,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
AC97_EA_VRA|AC97_EA_VRM, 0);
for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip));
+ if (err < 0)
return err;
}
if (chip->ac97->ext_id & AC97_EI_SDAC) {
@@ -1814,27 +1826,37 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
/* add S/PDIF control */
if (snd_BUG_ON(!chip->pcm_spdif))
return -ENXIO;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
+ kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip);
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
return err;
kctl->id.device = chip->pcm_spdif->device;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip))) < 0)
+ kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip);
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
return err;
kctl->id.device = chip->pcm_spdif->device;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip))) < 0)
+ kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip);
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
return err;
kctl->id.device = chip->pcm_spdif->device;
chip->spdif_pcm_ctl = kctl;
/* direct recording source */
- if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
- (err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip))) < 0)
- return err;
+ if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754) {
+ kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip);
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
+ return err;
+ }
/*
* shared rear/line-in
*/
if (rear_switch) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip));
+ if (err < 0)
return err;
}
@@ -1847,7 +1869,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
kctl->id.device = chip->pcm->device;
kctl->id.subdevice = idx;
kctl->private_value = (unsigned long)substream;
- if ((err = snd_ctl_add(chip->card, kctl)) < 0)
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
return err;
chip->pcm_mixer[idx].left = 0x8000;
chip->pcm_mixer[idx].right = 0x8000;
@@ -1928,7 +1951,8 @@ int snd_ymfpci_timer(struct snd_ymfpci *chip, int device)
tid.card = chip->card->number;
tid.device = device;
tid.subdevice = 0;
- if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) {
+ err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer);
+ if (err >= 0) {
strcpy(timer->name, "YMFPCI timer");
timer->private_data = chip;
timer->hw = snd_ymfpci_timer_hw;
@@ -2334,7 +2358,8 @@ int snd_ymfpci_create(struct snd_card *card,
*rchip = NULL;
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -2357,7 +2382,8 @@ int snd_ymfpci_create(struct snd_card *card,
pci_set_master(pci);
chip->src441_used = -1;
- if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
+ chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI");
+ if (!chip->res_reg_area) {
dev_err(chip->card->dev,
"unable to grab memory region 0x%lx-0x%lx\n",
chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 144582350a05..8363ec08df5d 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -170,7 +170,8 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq
if (err < 0)
return err;
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c
index 0f59e4cca56d..bc2114475810 100644
--- a/sound/pcmcia/vx/vxp_mixer.c
+++ b/sound/pcmcia/vx/vxp_mixer.c
@@ -124,11 +124,13 @@ int vxp_add_mic_controls(struct vx_core *_chip)
/* mic level */
switch (_chip->type) {
case VX_TYPE_VXPOCKET:
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
+ err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip));
+ if (err < 0)
return err;
break;
case VX_TYPE_VXP440:
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip))) < 0)
+ err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip));
+ if (err < 0)
return err;
break;
}
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 45eeb0f57d59..4176abd73799 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -237,9 +237,11 @@ static int vxp_load_dsp(struct vx_core *vx, int index, const struct firmware *fw
switch (index) {
case 0:
/* xilinx boot */
- if ((err = vx_check_magic(vx)) < 0)
+ err = vx_check_magic(vx);
+ if (err < 0)
return err;
- if ((err = snd_vx_load_boot_image(vx, fw)) < 0)
+ err = snd_vx_load_boot_image(vx, fw);
+ if (err < 0)
return err;
return 0;
case 1:
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 636320489805..0dfb6a943b60 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -183,7 +183,8 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
chip->irq = irq;
card->sync_irq = chip->irq;
- if ((err = snd_vx_setup_firmware(chip)) < 0)
+ err = snd_vx_setup_firmware(chip);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 6bc586a5db0f..0f4bce1c0d4f 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -105,7 +105,10 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
}
chip = input_get_drvdata(dev);
- if (! chip || (beep = chip->beep) == NULL)
+ if (!chip)
+ return -1;
+ beep = chip->beep;
+ if (!beep)
return -1;
if (! hz) {
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index 1eb698dafd93..4da9278dd58a 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -84,7 +84,8 @@ static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->deemphasis ? 1 : 0;
return 0;
@@ -97,7 +98,8 @@ static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
struct pmac_daca *mix;
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
change = mix->deemphasis != ucontrol->value.integer.value[0];
if (change) {
@@ -123,7 +125,8 @@ static int daca_get_volume(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->left_vol;
ucontrol->value.integer.value[1] = mix->right_vol;
@@ -138,7 +141,8 @@ static int daca_put_volume(struct snd_kcontrol *kcontrol,
unsigned int vol[2];
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
vol[0] = ucontrol->value.integer.value[0];
vol[1] = ucontrol->value.integer.value[1];
@@ -162,7 +166,8 @@ static int daca_get_amp(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->amp_on ? 1 : 0;
return 0;
@@ -175,7 +180,8 @@ static int daca_put_amp(struct snd_kcontrol *kcontrol,
struct pmac_daca *mix;
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
change = mix->amp_on != ucontrol->value.integer.value[0];
if (change) {
@@ -248,7 +254,8 @@ int snd_pmac_daca_init(struct snd_pmac *chip)
mix->i2c.addr = DACA_I2C_ADDR;
mix->i2c.init_client = daca_init_client;
mix->i2c.name = "DACA";
- if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
+ err = snd_pmac_keywest_init(&mix->i2c);
+ if (err < 0)
return err;
/*
@@ -257,7 +264,8 @@ int snd_pmac_daca_init(struct snd_pmac *chip)
strcpy(chip->card->mixername, "PowerMac DACA");
for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip));
+ if (err < 0)
return err;
}
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index a8915100d6bb..6e5daae18f9d 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -114,7 +114,8 @@ int snd_pmac_tumbler_post_init(void)
if (!keywest_ctx || !keywest_ctx->client)
return -ENXIO;
- if ((err = keywest_ctx->init_client(keywest_ctx)) < 0) {
+ err = keywest_ctx->init_client(keywest_ctx);
+ if (err < 0) {
snd_printk(KERN_ERR "tumbler: %i :cannot initialize the MCS\n", err);
return err;
}
@@ -136,7 +137,8 @@ int snd_pmac_keywest_init(struct pmac_keywest *i2c)
keywest_ctx = i2c;
- if ((err = i2c_add_driver(&keywest_driver))) {
+ err = i2c_add_driver(&keywest_driver);
+ if (err) {
snd_printk(KERN_ERR "cannot register keywest i2c driver\n");
i2c_put_adapter(adap);
return err;
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 2e750b317be1..84058bbf9d12 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1160,7 +1160,8 @@ int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
chip->playback.stream = SNDRV_PCM_STREAM_PLAYBACK;
chip->capture.stream = SNDRV_PCM_STREAM_CAPTURE;
- if ((err = snd_pmac_detect(chip)) < 0)
+ err = snd_pmac_detect(chip);
+ if (err < 0)
goto __error;
if (snd_pmac_dbdma_alloc(chip, &chip->playback.cmd, PMAC_MAX_FRAGS + 1) < 0 ||
@@ -1299,7 +1300,8 @@ int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
/* Reset dbdma channels */
snd_pmac_dbdma_reset(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0)
goto __error;
*chip_return = chip;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 9fb51ebafde1..db414b61157e 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -48,7 +48,8 @@ static int snd_pmac_probe(struct platform_device *devptr)
if (err < 0)
return err;
- if ((err = snd_pmac_new(card, &chip)) < 0)
+ err = snd_pmac_new(card, &chip);
+ if (err < 0)
goto __error;
card->private_data = chip;
@@ -58,7 +59,8 @@ static int snd_pmac_probe(struct platform_device *devptr)
strcpy(card->shortname, "PowerMac Burgundy");
sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
card->shortname, chip->device_id, chip->subframe);
- if ((err = snd_pmac_burgundy_init(chip)) < 0)
+ err = snd_pmac_burgundy_init(chip);
+ if (err < 0)
goto __error;
break;
case PMAC_DACA:
@@ -66,7 +68,8 @@ static int snd_pmac_probe(struct platform_device *devptr)
strcpy(card->shortname, "PowerMac DACA");
sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
card->shortname, chip->device_id, chip->subframe);
- if ((err = snd_pmac_daca_init(chip)) < 0)
+ err = snd_pmac_daca_init(chip);
+ if (err < 0)
goto __error;
break;
case PMAC_TUMBLER:
@@ -76,7 +79,11 @@ static int snd_pmac_probe(struct platform_device *devptr)
sprintf(card->shortname, "PowerMac %s", name_ext);
sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
card->shortname, chip->device_id, chip->subframe);
- if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0)
+ err = snd_pmac_tumbler_init(chip);
+ if (err < 0)
+ goto __error;
+ err = snd_pmac_tumbler_post_init();
+ if (err < 0)
goto __error;
break;
case PMAC_AWACS:
@@ -92,7 +99,8 @@ static int snd_pmac_probe(struct platform_device *devptr)
name_ext = "";
sprintf(card->longname, "%s%s Rev %d",
card->shortname, name_ext, chip->revision);
- if ((err = snd_pmac_awacs_init(chip)) < 0)
+ err = snd_pmac_awacs_init(chip);
+ if (err < 0)
goto __error;
break;
default:
@@ -101,14 +109,16 @@ static int snd_pmac_probe(struct platform_device *devptr)
goto __error;
}
- if ((err = snd_pmac_pcm_new(chip)) < 0)
+ err = snd_pmac_pcm_new(chip);
+ if (err < 0)
goto __error;
chip->initialized = 1;
if (enable_beep)
snd_pmac_attach_beep(chip);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto __error;
platform_set_drvdata(devptr, card);
@@ -162,7 +172,8 @@ static int __init alsa_card_pmac_init(void)
{
int err;
- if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
+ err = platform_driver_register(&snd_pmac_driver);
+ if (err < 0)
return err;
device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
return 0;
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 6e5bdaa262b0..c65e74d7cd0a 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -402,7 +402,8 @@ static int tumbler_get_drc_value(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->drc_range;
return 0;
@@ -416,7 +417,8 @@ static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol,
unsigned int val;
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
val = ucontrol->value.integer.value[0];
if (chip->model == PMAC_TUMBLER) {
@@ -442,7 +444,8 @@ static int tumbler_get_drc_switch(struct snd_kcontrol *kcontrol,
{
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->drc_enable;
return 0;
@@ -455,7 +458,8 @@ static int tumbler_put_drc_switch(struct snd_kcontrol *kcontrol,
struct pmac_tumbler *mix;
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
change = mix->drc_enable != ucontrol->value.integer.value[0];
if (change) {
@@ -524,7 +528,8 @@ static int tumbler_get_mono(struct snd_kcontrol *kcontrol,
struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->mono_vol[info->index];
return 0;
@@ -539,7 +544,8 @@ static int tumbler_put_mono(struct snd_kcontrol *kcontrol,
unsigned int vol;
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
vol = ucontrol->value.integer.value[0];
if (vol >= info->max)
@@ -669,7 +675,8 @@ static int snapper_get_mix(struct snd_kcontrol *kcontrol,
int idx = (int)kcontrol->private_value;
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
ucontrol->value.integer.value[0] = mix->mix_vol[idx][0];
ucontrol->value.integer.value[1] = mix->mix_vol[idx][1];
@@ -685,7 +692,8 @@ static int snapper_put_mix(struct snd_kcontrol *kcontrol,
unsigned int vol[2];
int change;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
vol[0] = ucontrol->value.integer.value[0];
vol[1] = ucontrol->value.integer.value[1];
@@ -716,7 +724,8 @@ static int tumbler_get_mute_switch(struct snd_kcontrol *kcontrol,
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
struct pmac_tumbler *mix;
struct pmac_gpio *gp;
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
switch(kcontrol->private_value) {
case TUMBLER_MUTE_HP:
@@ -745,7 +754,8 @@ static int tumbler_put_mute_switch(struct snd_kcontrol *kcontrol,
if (chip->update_automute && chip->auto_mute)
return 0; /* don't touch in the auto-mute mode */
#endif
- if (! (mix = chip->mixer_data))
+ mix = chip->mixer_data;
+ if (!mix)
return -ENODEV;
switch(kcontrol->private_value) {
case TUMBLER_MUTE_HP:
@@ -1361,7 +1371,8 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
break;
}
}
- if ((err = tumbler_init(chip)) < 0)
+ err = tumbler_init(chip);
+ if (err < 0)
return err;
/* set up TAS */
@@ -1392,7 +1403,8 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
chipname = "Snapper";
}
- if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
+ err = snd_pmac_keywest_init(&mix->i2c);
+ if (err < 0)
return err;
/*
@@ -1402,28 +1414,34 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
if (chip->model == PMAC_TUMBLER) {
for (i = 0; i < ARRAY_SIZE(tumbler_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&tumbler_mixers[i], chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&tumbler_mixers[i], chip));
+ if (err < 0)
return err;
}
} else {
for (i = 0; i < ARRAY_SIZE(snapper_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snapper_mixers[i], chip))) < 0)
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snapper_mixers[i], chip));
+ if (err < 0)
return err;
}
}
chip->master_sw_ctl = snd_ctl_new1(&tumbler_hp_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
+ err = snd_ctl_add(chip->card, chip->master_sw_ctl);
+ if (err < 0)
return err;
chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
+ err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
+ if (err < 0)
return err;
if (mix->line_mute.addr != 0) {
chip->lineout_sw_ctl = snd_ctl_new1(&tumbler_lineout_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->lineout_sw_ctl)) < 0)
+ err = snd_ctl_add(chip->card, chip->lineout_sw_ctl);
+ if (err < 0)
return err;
}
chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
+ err = snd_ctl_add(chip->card, chip->drc_sw_ctl);
+ if (err < 0)
return err;
/* set initial DRC range to 60% */
@@ -1446,9 +1464,11 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
device_change_chip = chip;
#ifdef PMAC_SUPPORT_AUTOMUTE
- if ((mix->headphone_irq >=0 || mix->lineout_irq >= 0)
- && (err = snd_pmac_add_automute(chip)) < 0)
- return err;
+ if (mix->headphone_irq >= 0 || mix->lineout_irq >= 0) {
+ err = snd_pmac_add_automute(chip);
+ if (err < 0)
+ return err;
+ }
chip->detect_headphone = tumbler_detect_headphone;
chip->update_automute = tumbler_update_automute;
tumbler_update_automute(chip, 0); /* update the status only */
@@ -1456,8 +1476,9 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
/* activate headphone status interrupts */
if (mix->headphone_irq >= 0) {
unsigned char val;
- if ((err = request_irq(mix->headphone_irq, headphone_intr, 0,
- "Sound Headphone Detection", chip)) < 0)
+ err = request_irq(mix->headphone_irq, headphone_intr, 0,
+ "Sound Headphone Detection", chip);
+ if (err < 0)
return 0;
/* activate headphone status interrupts */
val = do_gpio_read(&mix->hp_detect);
@@ -1465,8 +1486,9 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip)
}
if (mix->lineout_irq >= 0) {
unsigned char val;
- if ((err = request_irq(mix->lineout_irq, headphone_intr, 0,
- "Sound Lineout Detection", chip)) < 0)
+ err = request_irq(mix->lineout_irq, headphone_intr, 0,
+ "Sound Lineout Detection", chip);
+ if (err < 0)
return 0;
/* activate headphone status interrupts */
val = do_gpio_read(&mix->line_detect);
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index ba5a85bf7412..49ff5e73e9ba 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -52,3 +52,12 @@ config SND_SOC_AMD_RENOIR_MACH
depends on SND_SOC_AMD_RENOIR
help
This option enables machine driver for DMIC
+
+config SND_SOC_AMD_ACP5x
+ tristate "AMD Audio Coprocessor-v5.x I2S support"
+ depends on X86 && PCI
+ help
+ This option enables ACP v5.x support on AMD platform
+
+ By enabling this flag build will trigger for ACP PCI driver,
+ ACP DMA driver, CPU DAI driver.
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
index e6df2f72a2a1..07150d26f315 100644
--- a/sound/soc/amd/Makefile
+++ b/sound/soc/amd/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += vangogh/
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
index 3c60c5f96dcb..b3df98a9f9f3 100644
--- a/sound/soc/amd/acp-da7219-max98357a.c
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -756,15 +756,9 @@ static int cz_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, machine);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "devm_snd_soc_register_card(%s) failed: %d\n",
- card->name, ret);
- else
- dev_dbg(&pdev->dev,
- "devm_snd_soc_register_card(%s) probe deferred: %d\n",
- card->name, ret);
- return ret;
+ return dev_err_probe(&pdev->dev, ret,
+ "devm_snd_soc_register_card(%s) failed\n",
+ card->name);
}
bt_uart_enable = !device_property_read_bool(&pdev->dev,
"bt-pad-enable");
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index cc1ce6f22caa..11b3c4f39eba 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -156,7 +156,7 @@ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num,
acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num);
}
-/* Initialize a dma descriptor in SRAM based on descritor information passed */
+/* Initialize a dma descriptor in SRAM based on descriptor information passed */
static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
u16 descr_idx,
acp_dma_dscr_transfer_t *descr_info)
@@ -288,7 +288,7 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
&dmadscr[i]);
}
pre_config_reset(acp_mmio, ch);
- /* Configure the DMA channel with the above descriptore */
+ /* Configure the DMA channel with the above descriptor */
config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
NUM_DSCRS_PER_CHANNEL,
ACP_DMA_PRIORITY_LEVEL_NORMAL);
@@ -322,7 +322,7 @@ static void acp_pte_config(void __iomem *acp_mmio, dma_addr_t addr,
high |= BIT(31);
acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
- /* Move to next physically contiguos page */
+ /* Move to next physically contiguous page */
addr += PAGE_SIZE;
}
}
@@ -602,11 +602,11 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL);
}
- /* initiailize Onion control DAGB register */
+ /* initialize Onion control DAGB register */
acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio,
mmACP_AXI2DAGB_ONION_CNTL);
- /* initiailize Garlic control DAGB registers */
+ /* initialize Garlic control DAGB registers */
acp_reg_write(ACP_GARLIC_CNTL_DEFAULT, acp_mmio,
mmACP_AXI2DAGB_GARLIC_CNTL);
@@ -621,7 +621,7 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
acp_reg_write(ACP_SRAM_BASE_ADDRESS, acp_mmio,
mmACP_DMA_DESC_BASE_ADDR);
- /* Num of descriptiors in SRAM 0x4, means 256 descriptors;(64 * 4) */
+ /* Num of descriptors in SRAM 0x4, means 256 descriptors;(64 * 4) */
acp_reg_write(0x4, acp_mmio, mmACP_DMA_DESC_MAX_NUM_DSCR);
acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK,
acp_mmio, mmACP_EXTERNAL_INTR_CNTL);
@@ -1035,13 +1035,6 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component,
return bytes_to_frames(runtime, pos);
}
-static int acp_dma_mmap(struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- return snd_pcm_lib_default_mmap(substream, vma);
-}
-
static int acp_dma_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
@@ -1205,7 +1198,6 @@ static const struct snd_soc_component_driver acp_asoc_platform = {
.hw_params = acp_dma_hw_params,
.trigger = acp_dma_trigger,
.pointer = acp_dma_pointer,
- .mmap = acp_dma_mmap,
.prepare = acp_dma_prepare,
.pcm_construct = acp_dma_new,
};
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
index d9980aba2910..e561464f7d60 100644
--- a/sound/soc/amd/acp3x-rt5682-max9836.c
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -512,17 +512,11 @@ static int acp3x_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "devm_snd_soc_register_card(%s) failed: %d\n",
- card->name, ret);
- else
- dev_dbg(&pdev->dev,
- "devm_snd_soc_register_card(%s) probe deferred: %d\n",
- card->name, ret);
+ return dev_err_probe(&pdev->dev, ret,
+ "devm_snd_soc_register_card(%s) failed\n",
+ card->name);
}
-
- return ret;
+ return 0;
}
static const struct acpi_device_id acp3x_audio_acpi_match[] = {
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 597d7c4b2a6b..75c06697fa09 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -147,7 +147,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
high |= BIT(31);
rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val
+ 4);
- /* Move to next physically contiguos page */
+ /* Move to next physically contiguous page */
val += 8;
addr += PAGE_SIZE;
}
@@ -320,13 +320,6 @@ static int acp3x_dma_new(struct snd_soc_component *component,
return 0;
}
-static int acp3x_dma_mmap(struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- return snd_pcm_lib_default_mmap(substream, vma);
-}
-
static int acp3x_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
@@ -370,7 +363,6 @@ static const struct snd_soc_component_driver acp3x_i2s_component = {
.close = acp3x_dma_close,
.hw_params = acp3x_dma_hw_params,
.pointer = acp3x_dma_pointer,
- .mmap = acp3x_dma_mmap,
.pcm_construct = acp3x_dma_new,
};
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 0391c28dd078..9dd22a2fa2e5 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -291,13 +291,6 @@ static int acp_pdm_dma_new(struct snd_soc_component *component,
return 0;
}
-static int acp_pdm_dma_mmap(struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- return snd_pcm_lib_default_mmap(substream, vma);
-}
-
static int acp_pdm_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
@@ -375,7 +368,6 @@ static const struct snd_soc_component_driver acp_pdm_component = {
.close = acp_pdm_dma_close,
.hw_params = acp_pdm_dma_hw_params,
.pointer = acp_pdm_dma_pointer,
- .mmap = acp_pdm_dma_mmap,
.pcm_construct = acp_pdm_dma_new,
};
diff --git a/sound/soc/amd/renoir/acp3x-rn.c b/sound/soc/amd/renoir/acp3x-rn.c
index 306134b89a82..5d979a7b77fb 100644
--- a/sound/soc/amd/renoir/acp3x-rn.c
+++ b/sound/soc/amd/renoir/acp3x-rn.c
@@ -54,10 +54,9 @@ static int acp_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, machine);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
- dev_err(&pdev->dev,
- "snd_soc_register_card(%s) failed: %d\n",
- acp_card.name, ret);
- return ret;
+ return dev_err_probe(&pdev->dev, ret,
+ "snd_soc_register_card(%s) failed\n",
+ card->name);
}
return 0;
}
diff --git a/sound/soc/amd/vangogh/Makefile b/sound/soc/amd/vangogh/Makefile
new file mode 100644
index 000000000000..3353f93dc610
--- /dev/null
+++ b/sound/soc/amd/vangogh/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Vangogh platform Support
+snd-pci-acp5x-objs := pci-acp5x.o
+snd-acp5x-i2s-objs := acp5x-i2s.o
+snd-acp5x-pcm-dma-objs := acp5x-pcm-dma.o
+
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-pci-acp5x.o
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-acp5x-i2s.o
+obj-$(CONFIG_SND_SOC_AMD_ACP5x) += snd-acp5x-pcm-dma.o
diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c
new file mode 100644
index 000000000000..2705e57eb713
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x-i2s.c
@@ -0,0 +1,427 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "acp5x.h"
+
+#define DRV_NAME "acp5x_i2s_playcap"
+
+static int acp5x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct i2s_dev_data *adata;
+ int mode;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+ mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_I2S:
+ adata->tdm_mode = TDM_DISABLE;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adata->tdm_mode = TDM_ENABLE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ mode = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
+ switch (mode) {
+ case SND_SOC_DAIFMT_CBC_CFC:
+ adata->master_mode = I2S_MASTER_MODE_ENABLE;
+ break;
+ case SND_SOC_DAIFMT_CBP_CFP:
+ adata->master_mode = I2S_MASTER_MODE_DISABLE;
+ break;
+ }
+ return 0;
+}
+
+static int acp5x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,
+ u32 tx_mask, u32 rx_mask,
+ int slots, int slot_width)
+{
+ struct i2s_dev_data *adata;
+ u32 frm_len;
+ u16 slot_len;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+
+ /* These values are as per Hardware Spec */
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+ break;
+ case SLOT_WIDTH_16:
+ slot_len = 16;
+ break;
+ case SLOT_WIDTH_24:
+ slot_len = 24;
+ break;
+ case SLOT_WIDTH_32:
+ slot_len = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ frm_len = FRM_LEN | (slots << 15) | (slot_len << 18);
+ adata->tdm_fmt = frm_len;
+ return 0;
+}
+
+static int acp5x_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp5x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+ union acp_i2stdm_mstrclkgen mclkgen;
+
+ u32 val;
+ u32 reg_val, frmt_reg, master_reg;
+ u32 lrclk_div_val, bclk_div_val;
+
+ lrclk_div_val = 0;
+ bclk_div_val = 0;
+ prtd = asoc_substream_to_rtd(substream);
+ rtd = substream->runtime->private_data;
+ card = prtd->card;
+ adata = snd_soc_dai_get_drvdata(dai);
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
+
+ /* These values are as per Hardware Spec */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ frmt_reg = ACP_HSTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_ITER;
+ frmt_reg = ACP_I2STDM_TXFRMT;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ frmt_reg = ACP_HSTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_IRER;
+ frmt_reg = ACP_I2STDM_RXFRMT;
+ }
+ }
+ if (adata->tdm_mode) {
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ acp_writel(val | 0x2, rtd->acp5x_base + reg_val);
+ acp_writel(adata->tdm_fmt, rtd->acp5x_base + frmt_reg);
+ }
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val &= ~ACP5x_ITER_IRER_SAMP_LEN_MASK;
+ val = val | (rtd->xfer_resolution << 3);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+
+ if (adata->master_mode) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ master_reg = ACP_I2STDM2_MSTRCLKGEN;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ master_reg = ACP_I2STDM0_MSTRCLKGEN;
+ break;
+ }
+ mclkgen.bits.i2stdm_master_mode = 0x1;
+ if (adata->tdm_mode)
+ mclkgen.bits.i2stdm_format_mode = 0x01;
+ else
+ mclkgen.bits.i2stdm_format_mode = 0x0;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 768;
+ break;
+ case 16000:
+ bclk_div_val = 384;
+ break;
+ case 24000:
+ bclk_div_val = 256;
+ break;
+ case 32000:
+ bclk_div_val = 192;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 128;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 64;
+ break;
+ case 192000:
+ bclk_div_val = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ switch (params_rate(params)) {
+ case 8000:
+ bclk_div_val = 384;
+ break;
+ case 16000:
+ bclk_div_val = 192;
+ break;
+ case 24000:
+ bclk_div_val = 128;
+ break;
+ case 32000:
+ bclk_div_val = 96;
+ break;
+ case 44100:
+ case 48000:
+ bclk_div_val = 64;
+ break;
+ case 88200:
+ case 96000:
+ bclk_div_val = 32;
+ break;
+ case 192000:
+ bclk_div_val = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lrclk_div_val = 64;
+ break;
+ default:
+ return -EINVAL;
+ }
+ mclkgen.bits.i2stdm_bclk_div_val = bclk_div_val;
+ mclkgen.bits.i2stdm_lrclk_div_val = lrclk_div_val;
+ acp_writel(mclkgen.u32_all, rtd->acp5x_base + master_reg);
+ }
+ return 0;
+}
+
+static int acp5x_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 buf_size, buf_reg;
+
+ rtd = substream->runtime->private_data;
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ buf_size = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rtd->bytescount = acp_get_byte_count(rtd,
+ substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ water_val =
+ ACP_HS_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_ITER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_TX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ ACP_I2S_TX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_ITER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_TX_RINGBUFSIZE;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ water_val =
+ ACP_HS_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_HSTDM_IRER;
+ ier_val = ACP_HSTDM_IER;
+ buf_reg = ACP_HS_RX_RINGBUFSIZE;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ ACP_I2S_RX_INTR_WATERMARK_SIZE;
+ reg_val = ACP_I2STDM_IRER;
+ ier_val = ACP_I2STDM_IER;
+ buf_reg = ACP_I2S_RX_RINGBUFSIZE;
+ }
+ }
+ acp_writel(period_bytes, rtd->acp5x_base + water_val);
+ acp_writel(buf_size, rtd->acp5x_base + buf_reg);
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val = val | BIT(0);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+ acp_writel(1, rtd->acp5x_base + ier_val);
+ ret = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_ITER;
+ }
+
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_IRER;
+ }
+ }
+ val = acp_readl(rtd->acp5x_base + reg_val);
+ val = val & ~BIT(0);
+ acp_writel(val, rtd->acp5x_base + reg_val);
+
+ if (!(acp_readl(rtd->acp5x_base + ACP_HSTDM_ITER) & BIT(0)) &&
+ !(acp_readl(rtd->acp5x_base + ACP_HSTDM_IRER) & BIT(0)))
+ acp_writel(0, rtd->acp5x_base + ACP_HSTDM_IER);
+ if (!(acp_readl(rtd->acp5x_base + ACP_I2STDM_ITER) & BIT(0)) &&
+ !(acp_readl(rtd->acp5x_base + ACP_I2STDM_IRER) & BIT(0)))
+ acp_writel(0, rtd->acp5x_base + ACP_I2STDM_IER);
+ ret = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static struct snd_soc_dai_ops acp5x_i2s_dai_ops = {
+ .hw_params = acp5x_i2s_hwparams,
+ .trigger = acp5x_i2s_trigger,
+ .set_fmt = acp5x_i2s_set_fmt,
+ .set_tdm_slot = acp5x_i2s_set_tdm_slot,
+};
+
+static const struct snd_soc_component_driver acp5x_dai_component = {
+ .name = "acp5x-i2s",
+};
+
+static struct snd_soc_dai_driver acp5x_i2s_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .ops = &acp5x_i2s_dai_ops,
+};
+
+static int acp5x_dai_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ int ret;
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
+ GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENOMEM;
+ }
+ adata->acp5x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp5x_base)
+ return -ENOMEM;
+
+ adata->master_mode = I2S_MASTER_MODE_ENABLE;
+ dev_set_drvdata(&pdev->dev, adata);
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &acp5x_dai_component,
+ &acp5x_i2s_dai, 1);
+ if (ret)
+ dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
+ return ret;
+}
+
+static struct platform_driver acp5x_dai_driver = {
+ .probe = acp5x_dai_probe,
+ .driver = {
+ .name = "acp5x_i2s_playcap",
+ },
+};
+
+module_platform_driver(acp5x_dai_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP5.x CPU DAI Driver");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
new file mode 100644
index 000000000000..f10de38976cb
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
@@ -0,0 +1,517 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "acp5x.h"
+
+#define DRV_NAME "acp5x_i2s_dma"
+
+static const struct snd_pcm_hardware acp5x_pcm_hardware_playback = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
+ .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
+ .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
+ .periods_min = PLAYBACK_MIN_NUM_PERIODS,
+ .periods_max = PLAYBACK_MAX_NUM_PERIODS,
+};
+
+static const struct snd_pcm_hardware acp5x_pcm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
+static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
+{
+ struct i2s_dev_data *vg_i2s_data;
+ u16 irq_flag;
+ u32 val;
+
+ vg_i2s_data = dev_id;
+ if (!vg_i2s_data)
+ return IRQ_NONE;
+
+ irq_flag = 0;
+ val = acp_readl(vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ if ((val & BIT(HS_TX_THRESHOLD)) && vg_i2s_data->play_stream) {
+ acp_writel(BIT(HS_TX_THRESHOLD), vg_i2s_data->acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->play_stream);
+ irq_flag = 1;
+ }
+ if ((val & BIT(I2S_TX_THRESHOLD)) && vg_i2s_data->i2ssp_play_stream) {
+ acp_writel(BIT(I2S_TX_THRESHOLD),
+ vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->i2ssp_play_stream);
+ irq_flag = 1;
+ }
+
+ if ((val & BIT(HS_RX_THRESHOLD)) && vg_i2s_data->capture_stream) {
+ acp_writel(BIT(HS_RX_THRESHOLD), vg_i2s_data->acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->capture_stream);
+ irq_flag = 1;
+ }
+ if ((val & BIT(I2S_RX_THRESHOLD)) && vg_i2s_data->i2ssp_capture_stream) {
+ acp_writel(BIT(I2S_RX_THRESHOLD),
+ vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(vg_i2s_data->i2ssp_capture_stream);
+ irq_flag = 1;
+ }
+
+ if (irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static void config_acp5x_dma(struct i2s_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val, acp_fifo_addr, reg_fifo_addr;
+ u32 reg_dma_size, reg_fifo_size;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ val = ACP_SRAM_HS_PB_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_PB_PTE_OFFSET;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ val = ACP_SRAM_HS_CP_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_CP_PTE_OFFSET;
+ }
+ }
+ /* Group Enable */
+ acp_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp5x_base +
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ acp_writel(PAGE_SIZE_4K_ENABLE, rtd->acp5x_base +
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ acp_writel(low, rtd->acp5x_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ acp_writel(high, rtd->acp5x_base + ACP_SCRATCH_REG_0 + val + 4);
+ /* Move to next physically contiguous page */
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_dma_size = ACP_HS_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ HS_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_TX_FIFOADDR;
+ reg_fifo_size = ACP_HS_TX_FIFOSIZE;
+ acp_writel(I2S_HS_TX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_HS_TX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = ACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
+ acp_writel(I2S_SP_TX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_I2S_TX_RINGBUFADDR);
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_dma_size = ACP_HS_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ HS_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_HS_RX_FIFOADDR;
+ reg_fifo_size = ACP_HS_RX_FIFOSIZE;
+ acp_writel(I2S_HS_RX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_HS_RX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_dma_size = ACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
+ acp_writel(I2S_SP_RX_MEM_WINDOW_START,
+ rtd->acp5x_base + ACP_I2S_RX_RINGBUFADDR);
+ }
+ }
+ acp_writel(DMA_SIZE, rtd->acp5x_base + reg_dma_size);
+ acp_writel(acp_fifo_addr, rtd->acp5x_base + reg_fifo_addr);
+ acp_writel(FIFO_SIZE, rtd->acp5x_base + reg_fifo_size);
+ acp_writel(BIT(I2S_RX_THRESHOLD) | BIT(HS_RX_THRESHOLD)
+ | BIT(I2S_TX_THRESHOLD) | BIT(HS_TX_THRESHOLD),
+ rtd->acp5x_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static int acp5x_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *i2s_data;
+ int ret;
+
+ runtime = substream->runtime;
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+
+ i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL);
+ if (!i2s_data)
+ return -ENOMEM;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = acp5x_pcm_hardware_playback;
+ else
+ runtime->hw = acp5x_pcm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(i2s_data);
+ return ret;
+ }
+ i2s_data->acp5x_base = adata->acp5x_base;
+ runtime->private_data = i2s_data;
+ return ret;
+}
+
+static int acp5x_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp5x_platform_info *pinfo;
+ struct i2s_dev_data *adata;
+ u64 size;
+
+ prtd = asoc_substream_to_rtd(substream);
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ adata = dev_get_drvdata(component->dev);
+ rtd = substream->runtime->private_data;
+
+ if (!rtd)
+ return -EINVAL;
+
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->play_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = substream;
+ }
+ } else {
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->capture_stream = substream;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = substream;
+ }
+ }
+ } else {
+ dev_err(component->dev, "pinfo failed\n");
+ return -EINVAL;
+ }
+ size = params_buffer_bytes(params);
+ rtd->dma_addr = substream->dma_buffer.addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ config_acp5x_dma(rtd, substream->stream);
+ return 0;
+}
+
+static snd_pcm_uframes_t acp5x_dma_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct i2s_stream_instance *rtd;
+ u32 pos;
+ u32 buffersize;
+ u64 bytescount;
+
+ rtd = substream->runtime->private_data;
+ buffersize = frames_to_bytes(substream->runtime,
+ substream->runtime->buffer_size);
+ bytescount = acp_get_byte_count(rtd, substream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(substream->runtime, pos);
+}
+
+static int acp5x_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp5x_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *ins;
+
+ prtd = asoc_substream_to_rtd(substream);
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+ ins = substream->runtime->private_data;
+ if (!ins)
+ return -EINVAL;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (ins->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->play_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_play_stream = NULL;
+ }
+ } else {
+ switch (ins->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ adata->capture_stream = NULL;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ adata->i2ssp_capture_stream = NULL;
+ }
+ }
+ kfree(ins);
+ return 0;
+}
+
+static const struct snd_soc_component_driver acp5x_i2s_component = {
+ .name = DRV_NAME,
+ .open = acp5x_dma_open,
+ .close = acp5x_dma_close,
+ .hw_params = acp5x_dma_hw_params,
+ .pointer = acp5x_dma_pointer,
+ .pcm_construct = acp5x_dma_new,
+};
+
+static int acp5x_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ unsigned int irqflags;
+ int status;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "platform_data not retrieved\n");
+ return -ENODEV;
+ }
+ irqflags = *((unsigned int *)(pdev->dev.platform_data));
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp5x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp5x_base)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
+ return -ENODEV;
+ }
+
+ adata->i2s_irq = res->start;
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp5x_i2s_component,
+ NULL, 0);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp i2s component\n");
+ return status;
+ }
+ status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
+ irqflags, "ACP5x_I2S_IRQ", adata);
+ if (status) {
+ dev_err(&pdev->dev, "ACP5x I2S IRQ request failed\n");
+ return status;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_allow(&pdev->dev);
+
+ return 0;
+}
+
+static int acp5x_audio_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+ return 0;
+}
+
+static int __maybe_unused acp5x_pcm_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+ u32 val, reg_val, frmt_val;
+
+ reg_val = 0;
+ frmt_val = 0;
+ adata = dev_get_drvdata(dev);
+
+ if (adata->play_stream && adata->play_stream->runtime) {
+ struct i2s_stream_instance *rtd =
+ adata->play_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_ITER;
+ frmt_val = ACP_HSTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_ITER;
+ frmt_val = ACP_I2STDM_TXFRMT;
+ }
+ acp_writel((rtd->xfer_resolution << 3),
+ rtd->acp5x_base + reg_val);
+ }
+
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ struct i2s_stream_instance *rtd =
+ adata->capture_stream->runtime->private_data;
+ config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ reg_val = ACP_HSTDM_IRER;
+ frmt_val = ACP_HSTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = ACP_I2STDM_IRER;
+ frmt_val = ACP_I2STDM_RXFRMT;
+ }
+ acp_writel((rtd->xfer_resolution << 3),
+ rtd->acp5x_base + reg_val);
+ }
+ if (adata->tdm_mode == TDM_ENABLE) {
+ acp_writel(adata->tdm_fmt, adata->acp5x_base + frmt_val);
+ val = acp_readl(adata->acp5x_base + reg_val);
+ acp_writel(val | 0x2, adata->acp5x_base + reg_val);
+ }
+ acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int __maybe_unused acp5x_pcm_suspend(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp_writel(0, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static int __maybe_unused acp5x_pcm_runtime_resume(struct device *dev)
+{
+ struct i2s_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
+ return 0;
+}
+
+static const struct dev_pm_ops acp5x_pm_ops = {
+ SET_RUNTIME_PM_OPS(acp5x_pcm_suspend,
+ acp5x_pcm_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(acp5x_pcm_suspend, acp5x_pcm_resume)
+};
+
+static struct platform_driver acp5x_dma_driver = {
+ .probe = acp5x_audio_probe,
+ .remove = acp5x_audio_remove,
+ .driver = {
+ .name = "acp5x_i2s_dma",
+ .pm = &acp5x_pm_ops,
+ },
+};
+
+module_platform_driver(acp5x_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP 5.x PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/vangogh/acp5x.h b/sound/soc/amd/vangogh/acp5x.h
new file mode 100644
index 000000000000..a808635f9740
--- /dev/null
+++ b/sound/soc/amd/vangogh/acp5x.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PCM Driver
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include "vg_chip_offset_byte.h"
+#include <sound/pcm.h>
+
+#define ACP5x_PHY_BASE_ADDRESS 0x1240000
+#define ACP_DEVICE_ID 0x15E2
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP_ERR_INTR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+
+#define ACP5x_DEVS 3
+#define ACP5x_REG_START 0x1240000
+#define ACP5x_REG_END 0x1250200
+#define ACP5x_I2STDM_REG_START 0x1242400
+#define ACP5x_I2STDM_REG_END 0x1242410
+#define ACP5x_HS_TDM_REG_START 0x1242814
+#define ACP5x_HS_TDM_REG_END 0x1242824
+#define I2S_MODE 0
+#define ACP5x_I2S_MODE 1
+#define ACP5x_RES 4
+#define I2S_RX_THRESHOLD 27
+#define I2S_TX_THRESHOLD 28
+#define HS_TX_THRESHOLD 24
+#define HS_RX_THRESHOLD 23
+
+#define I2S_SP_INSTANCE 1
+#define I2S_HS_INSTANCE 2
+
+#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
+#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
+#define ACP_SRAM_HS_PB_PTE_OFFSET 0x200
+#define ACP_SRAM_HS_CP_PTE_OFFSET 0x300
+#define PAGE_SIZE_4K_ENABLE 0x2
+#define I2S_SP_TX_MEM_WINDOW_START 0x4000000
+#define I2S_SP_RX_MEM_WINDOW_START 0x4020000
+#define I2S_HS_TX_MEM_WINDOW_START 0x4040000
+#define I2S_HS_RX_MEM_WINDOW_START 0x4060000
+
+#define SP_PB_FIFO_ADDR_OFFSET 0x500
+#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
+#define HS_PB_FIFO_ADDR_OFFSET 0x900
+#define HS_CAPT_FIFO_ADDR_OFFSET 0xB00
+#define PLAYBACK_MIN_NUM_PERIODS 2
+#define PLAYBACK_MAX_NUM_PERIODS 8
+#define PLAYBACK_MAX_PERIOD_SIZE 8192
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 1024
+
+#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
+#define FIFO_SIZE 0x100
+#define DMA_SIZE 0x40
+#define FRM_LEN 0x100
+
+#define I2S_MASTER_MODE_ENABLE 1
+#define I2S_MASTER_MODE_DISABLE 0
+
+#define SLOT_WIDTH_8 8
+#define SLOT_WIDTH_16 16
+#define SLOT_WIDTH_24 24
+#define SLOT_WIDTH_32 32
+#define TDM_ENABLE 1
+#define TDM_DISABLE 0
+#define ACP5x_ITER_IRER_SAMP_LEN_MASK 0x38
+
+struct i2s_dev_data {
+ bool tdm_mode;
+ bool master_mode;
+ unsigned int i2s_irq;
+ u16 i2s_instance;
+ u32 tdm_fmt;
+ void __iomem *acp5x_base;
+ struct snd_pcm_substream *play_stream;
+ struct snd_pcm_substream *capture_stream;
+ struct snd_pcm_substream *i2ssp_play_stream;
+ struct snd_pcm_substream *i2ssp_capture_stream;
+};
+
+struct i2s_stream_instance {
+ u16 num_pages;
+ u16 i2s_instance;
+ u16 direction;
+ u16 channels;
+ u32 xfer_resolution;
+ u32 val;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp5x_base;
+};
+
+union acp_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
+struct acp5x_platform_info {
+ u16 play_i2s_instance;
+ u16 cap_i2s_instance;
+};
+
+union acp_i2stdm_mstrclkgen {
+ struct {
+ u32 i2stdm_master_mode : 1;
+ u32 i2stdm_format_mode : 1;
+ u32 i2stdm_lrclk_div_val : 9;
+ u32 i2stdm_bclk_div_val : 11;
+ u32:10;
+ } bitfields, bits;
+ u32 u32_all;
+};
+
+/* common header file uses exact offset rather than relative
+ * offset which requires subtraction logic from base_addr
+ * for accessing ACP5x MMIO space registers
+ */
+static inline u32 acp_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP5x_PHY_BASE_ADDRESS);
+}
+
+static inline void acp_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP5x_PHY_BASE_ADDRESS);
+}
+
+static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
+ int direction)
+{
+ union acp_dma_count byte_count;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_TX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_TX_LINEARPOSCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_TX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_TX_LINEARPOSCNTR_LOW);
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_HS_INSTANCE:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_RX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_HS_RX_LINEARPOSCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count.bcount.high =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_RX_LINEARPOSCNTR_HIGH);
+ byte_count.bcount.low =
+ acp_readl(rtd->acp5x_base +
+ ACP_I2S_RX_LINEARPOSCNTR_LOW);
+ }
+ }
+ return byte_count.bytescount;
+}
diff --git a/sound/soc/amd/vangogh/pci-acp5x.c b/sound/soc/amd/vangogh/pci-acp5x.c
new file mode 100644
index 000000000000..a57b762d9f2e
--- /dev/null
+++ b/sound/soc/amd/vangogh/pci-acp5x.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD Vangogh ACP PCI Driver
+//
+// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+
+#include "acp5x.h"
+
+struct acp5x_dev_data {
+ void __iomem *acp5x_base;
+ bool acp5x_audio_mode;
+ struct resource *res;
+ struct platform_device *pdev[ACP5x_DEVS];
+};
+
+static int acp5x_power_on(void __iomem *acp5x_base)
+{
+ u32 val;
+ int timeout;
+
+ val = acp_readl(acp5x_base + ACP_PGFSM_STATUS);
+
+ if (val == 0)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) !=
+ ACP_POWER_ON_IN_PROGRESS)
+ acp_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+ acp5x_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_PGFSM_STATUS);
+ if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_ON)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int acp5x_reset(void __iomem *acp5x_base)
+{
+ u32 val;
+ int timeout;
+
+ acp_writel(1, acp5x_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ acp_writel(0, acp5x_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = acp_readl(acp5x_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void acp5x_enable_interrupts(void __iomem *acp5x_base)
+{
+ acp_writel(0x01, acp5x_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static void acp5x_disable_interrupts(void __iomem *acp5x_base)
+{
+ acp_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp5x_base +
+ ACP_EXTERNAL_INTR_STAT);
+ acp_writel(0x00, acp5x_base + ACP_EXTERNAL_INTR_CNTL);
+ acp_writel(0x00, acp5x_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int acp5x_init(void __iomem *acp5x_base)
+{
+ int ret;
+
+ /* power on */
+ ret = acp5x_power_on(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x power on failed\n");
+ return ret;
+ }
+ /* Reset */
+ ret = acp5x_reset(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x reset failed\n");
+ return ret;
+ }
+ acp5x_enable_interrupts(acp5x_base);
+ return 0;
+}
+
+static int acp5x_deinit(void __iomem *acp5x_base)
+{
+ int ret;
+
+ acp5x_disable_interrupts(acp5x_base);
+ /* Reset */
+ ret = acp5x_reset(acp5x_base);
+ if (ret) {
+ pr_err("ACP5x reset failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int snd_acp5x_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp5x_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP5x_DEVS];
+ unsigned int irqflags;
+ int ret, i;
+ u32 addr, val;
+
+ irqflags = IRQF_SHARED;
+ if (pci->revision != 0x50)
+ return -ENODEV;
+
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP5x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp5x_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ addr = pci_resource_start(pci, 0);
+ adata->acp5x_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp5x_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ ret = acp5x_init(adata->acp5x_base);
+ if (ret)
+ goto release_regions;
+
+ val = acp_readl(adata->acp5x_base + ACP_PIN_CONFIG);
+ switch (val) {
+ case I2S_MODE:
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource) * ACP5x_RES,
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res[0].name = "acp5x_i2s_iomem";
+ adata->res[0].flags = IORESOURCE_MEM;
+ adata->res[0].start = addr;
+ adata->res[0].end = addr + (ACP5x_REG_END - ACP5x_REG_START);
+
+ adata->res[1].name = "acp5x_i2s_sp";
+ adata->res[1].flags = IORESOURCE_MEM;
+ adata->res[1].start = addr + ACP5x_I2STDM_REG_START;
+ adata->res[1].end = addr + ACP5x_I2STDM_REG_END;
+
+ adata->res[2].name = "acp5x_i2s_hs";
+ adata->res[2].flags = IORESOURCE_MEM;
+ adata->res[2].start = addr + ACP5x_HS_TDM_REG_START;
+ adata->res[2].end = addr + ACP5x_HS_TDM_REG_END;
+
+ adata->res[3].name = "acp5x_i2s_irq";
+ adata->res[3].flags = IORESOURCE_IRQ;
+ adata->res[3].start = pci->irq;
+ adata->res[3].end = adata->res[3].start;
+
+ adata->acp5x_audio_mode = ACP5x_I2S_MODE;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo[0].name = "acp5x_i2s_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 4;
+ pdevinfo[0].res = &adata->res[0];
+ pdevinfo[0].data = &irqflags;
+ pdevinfo[0].size_data = sizeof(irqflags);
+
+ pdevinfo[1].name = "acp5x_i2s_playcap";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+ pdevinfo[1].num_res = 1;
+ pdevinfo[1].res = &adata->res[1];
+
+ pdevinfo[2].name = "acp5x_i2s_playcap";
+ pdevinfo[2].id = 1;
+ pdevinfo[2].parent = &pci->dev;
+ pdevinfo[2].num_res = 1;
+ pdevinfo[2].res = &adata->res[2];
+
+ for (i = 0; i < ACP5x_DEVS; i++) {
+ adata->pdev[i] =
+ platform_device_register_full(&pdevinfo[i]);
+ if (IS_ERR(adata->pdev[i])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[i].name);
+ ret = PTR_ERR(adata->pdev[i]);
+ goto unregister_devs;
+ }
+ }
+ break;
+ default:
+ dev_info(&pci->dev, "ACP audio mode : %d\n", val);
+ }
+ pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ return 0;
+
+unregister_devs:
+ for (--i; i >= 0; i--)
+ platform_device_unregister(adata->pdev[i]);
+de_init:
+ if (acp5x_deinit(adata->acp5x_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp5x_suspend(struct device *dev)
+{
+ int ret;
+ struct acp5x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp5x_deinit(adata->acp5x_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ else
+ dev_dbg(dev, "ACP de-initialized\n");
+
+ return ret;
+}
+
+static int __maybe_unused snd_acp5x_resume(struct device *dev)
+{
+ int ret;
+ struct acp5x_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = acp5x_init(adata->acp5x_base);
+ if (ret) {
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops acp5x_pm = {
+ SET_RUNTIME_PM_OPS(snd_acp5x_suspend,
+ snd_acp5x_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(snd_acp5x_suspend, snd_acp5x_resume)
+};
+
+static void snd_acp5x_remove(struct pci_dev *pci)
+{
+ struct acp5x_dev_data *adata;
+ int i, ret;
+
+ adata = pci_get_drvdata(pci);
+ if (adata->acp5x_audio_mode == ACP5x_I2S_MODE) {
+ for (i = 0; i < ACP5x_DEVS; i++)
+ platform_device_unregister(adata->pdev[i]);
+ }
+ ret = acp5x_deinit(adata->acp5x_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_acp5x_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_acp5x_ids);
+
+static struct pci_driver acp5x_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_acp5x_ids,
+ .probe = snd_acp5x_probe,
+ .remove = snd_acp5x_remove,
+ .driver = {
+ .pm = &acp5x_pm,
+ }
+};
+
+module_pci_driver(acp5x_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD Vangogh ACP PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/vangogh/vg_chip_offset_byte.h b/sound/soc/amd/vangogh/vg_chip_offset_byte.h
new file mode 100644
index 000000000000..b1165ae142b7
--- /dev/null
+++ b/sound/soc/amd/vangogh/vg_chip_offset_byte.h
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 5.x Register Documentation
+ *
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _acp_ip_OFFSET_HEADER
+#define _acp_ip_OFFSET_HEADER
+
+/* Registers from ACP_DMA block */
+#define ACP_DMA_CNTL_0 0x1240000
+#define ACP_DMA_CNTL_1 0x1240004
+#define ACP_DMA_CNTL_2 0x1240008
+#define ACP_DMA_CNTL_3 0x124000C
+#define ACP_DMA_CNTL_4 0x1240010
+#define ACP_DMA_CNTL_5 0x1240014
+#define ACP_DMA_CNTL_6 0x1240018
+#define ACP_DMA_CNTL_7 0x124001C
+#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define ACP_DMA_DSCR_CNT_0 0x1240040
+#define ACP_DMA_DSCR_CNT_1 0x1240044
+#define ACP_DMA_DSCR_CNT_2 0x1240048
+#define ACP_DMA_DSCR_CNT_3 0x124004C
+#define ACP_DMA_DSCR_CNT_4 0x1240050
+#define ACP_DMA_DSCR_CNT_5 0x1240054
+#define ACP_DMA_DSCR_CNT_6 0x1240058
+#define ACP_DMA_DSCR_CNT_7 0x124005C
+#define ACP_DMA_PRIO_0 0x1240060
+#define ACP_DMA_PRIO_1 0x1240064
+#define ACP_DMA_PRIO_2 0x1240068
+#define ACP_DMA_PRIO_3 0x124006C
+#define ACP_DMA_PRIO_4 0x1240070
+#define ACP_DMA_PRIO_5 0x1240074
+#define ACP_DMA_PRIO_6 0x1240078
+#define ACP_DMA_PRIO_7 0x124007C
+#define ACP_DMA_CUR_DSCR_0 0x1240080
+#define ACP_DMA_CUR_DSCR_1 0x1240084
+#define ACP_DMA_CUR_DSCR_2 0x1240088
+#define ACP_DMA_CUR_DSCR_3 0x124008C
+#define ACP_DMA_CUR_DSCR_4 0x1240090
+#define ACP_DMA_CUR_DSCR_5 0x1240094
+#define ACP_DMA_CUR_DSCR_6 0x1240098
+#define ACP_DMA_CUR_DSCR_7 0x124009C
+#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define ACP_DMA_ERR_STS_0 0x12400C0
+#define ACP_DMA_ERR_STS_1 0x12400C4
+#define ACP_DMA_ERR_STS_2 0x12400C8
+#define ACP_DMA_ERR_STS_3 0x12400CC
+#define ACP_DMA_ERR_STS_4 0x12400D0
+#define ACP_DMA_ERR_STS_5 0x12400D4
+#define ACP_DMA_ERR_STS_6 0x12400D8
+#define ACP_DMA_ERR_STS_7 0x12400DC
+#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define ACP_DMA_CH_STS 0x12400E8
+#define ACP_DMA_CH_GROUP 0x12400EC
+#define ACP_DMA_CH_RST_STS 0x12400F0
+
+/* Registers from ACP_AXI2AXIATU block */
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define ACPAXI2AXI_ATU_CTRL 0x1240C40
+
+/* Registers from ACP_CLKRST block */
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+
+/* Registers from ACP_MISC block */
+#define ACP_EXTERNAL_INTR_ENB 0x1241800
+#define ACP_EXTERNAL_INTR_CNTL 0x1241804
+#define ACP_EXTERNAL_INTR_STAT 0x1241808
+#define ACP_ERROR_STATUS 0x12418C4
+#define ACP_SW_I2S_ERROR_REASON 0x12418C8
+#define ACP_MEM_PG_STS 0x12418CC
+#define ACP_PGMEM_DEEP_SLEEP_CTRL 0x12418D0
+#define ACP_PGMEM_SHUT_DOWN_CTRL 0x12418D4
+
+/* Registers from ACP_PGFSM block */
+#define ACP_PIN_CONFIG 0x1241400
+#define ACP_PAD_PULLUP_CTRL 0x1241404
+#define ACP_PAD_PULLDOWN_CTRL 0x1241408
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x124140C
+#define ACP_PAD_SCHMEN_CTRL 0x1241410
+#define ACP_SW_PAD_KEEPER_EN 0x1241414
+#define ACP_SW_WAKE_EN 0x1241418
+#define ACP_I2S_WAKE_EN 0x124141C
+#define ACP_PME_EN 0x1241420
+#define ACP_PGFSM_CONTROL 0x1241424
+#define ACP_PGFSM_STATUS 0x1241428
+#define ACP_CLKMUX_SEL 0x124142C
+#define ACP_DEVICE_STATE 0x1241430
+#define AZ_DEVICE_STATE 0x1241434
+#define ACP_INTR_URGENCY_TIMER 0x1241438
+#define AZ_INTR_URGENCY_TIMER 0x124143C
+#define ACP_AON_SW_INTR_TRIG 0x1241440
+
+/* Registers from ACP_SCRATCH block */
+#define ACP_SCRATCH_REG_0 0x1250000
+#define ACP_SCRATCH_REG_1 0x1250004
+#define ACP_SCRATCH_REG_2 0x1250008
+#define ACP_SCRATCH_REG_3 0x125000C
+#define ACP_SCRATCH_REG_4 0x1250010
+#define ACP_SCRATCH_REG_5 0x1250014
+#define ACP_SCRATCH_REG_6 0x1250018
+#define ACP_SCRATCH_REG_7 0x125001C
+#define ACP_SCRATCH_REG_8 0x1250020
+#define ACP_SCRATCH_REG_9 0x1250024
+#define ACP_SCRATCH_REG_10 0x1250028
+#define ACP_SCRATCH_REG_11 0x125002C
+#define ACP_SCRATCH_REG_12 0x1250030
+#define ACP_SCRATCH_REG_13 0x1250034
+#define ACP_SCRATCH_REG_14 0x1250038
+#define ACP_SCRATCH_REG_15 0x125003C
+#define ACP_SCRATCH_REG_16 0x1250040
+#define ACP_SCRATCH_REG_17 0x1250044
+#define ACP_SCRATCH_REG_18 0x1250048
+#define ACP_SCRATCH_REG_19 0x125004C
+#define ACP_SCRATCH_REG_20 0x1250050
+#define ACP_SCRATCH_REG_21 0x1250054
+#define ACP_SCRATCH_REG_22 0x1250058
+#define ACP_SCRATCH_REG_23 0x125005C
+#define ACP_SCRATCH_REG_24 0x1250060
+#define ACP_SCRATCH_REG_25 0x1250064
+#define ACP_SCRATCH_REG_26 0x1250068
+#define ACP_SCRATCH_REG_27 0x125006C
+#define ACP_SCRATCH_REG_28 0x1250070
+#define ACP_SCRATCH_REG_29 0x1250074
+#define ACP_SCRATCH_REG_30 0x1250078
+#define ACP_SCRATCH_REG_31 0x125007C
+#define ACP_SCRATCH_REG_32 0x1250080
+#define ACP_SCRATCH_REG_33 0x1250084
+#define ACP_SCRATCH_REG_34 0x1250088
+#define ACP_SCRATCH_REG_35 0x125008C
+#define ACP_SCRATCH_REG_36 0x1250090
+#define ACP_SCRATCH_REG_37 0x1250094
+#define ACP_SCRATCH_REG_38 0x1250098
+#define ACP_SCRATCH_REG_39 0x125009C
+#define ACP_SCRATCH_REG_40 0x12500A0
+#define ACP_SCRATCH_REG_41 0x12500A4
+#define ACP_SCRATCH_REG_42 0x12500A8
+#define ACP_SCRATCH_REG_43 0x12500AC
+#define ACP_SCRATCH_REG_44 0x12500B0
+#define ACP_SCRATCH_REG_45 0x12500B4
+#define ACP_SCRATCH_REG_46 0x12500B8
+#define ACP_SCRATCH_REG_47 0x12500BC
+#define ACP_SCRATCH_REG_48 0x12500C0
+#define ACP_SCRATCH_REG_49 0x12500C4
+#define ACP_SCRATCH_REG_50 0x12500C8
+#define ACP_SCRATCH_REG_51 0x12500CC
+#define ACP_SCRATCH_REG_52 0x12500D0
+#define ACP_SCRATCH_REG_53 0x12500D4
+#define ACP_SCRATCH_REG_54 0x12500D8
+#define ACP_SCRATCH_REG_55 0x12500DC
+#define ACP_SCRATCH_REG_56 0x12500E0
+#define ACP_SCRATCH_REG_57 0x12500E4
+#define ACP_SCRATCH_REG_58 0x12500E8
+#define ACP_SCRATCH_REG_59 0x12500EC
+#define ACP_SCRATCH_REG_60 0x12500F0
+#define ACP_SCRATCH_REG_61 0x12500F4
+#define ACP_SCRATCH_REG_62 0x12500F8
+#define ACP_SCRATCH_REG_63 0x12500FC
+#define ACP_SCRATCH_REG_64 0x1250100
+#define ACP_SCRATCH_REG_65 0x1250104
+#define ACP_SCRATCH_REG_66 0x1250108
+#define ACP_SCRATCH_REG_67 0x125010C
+#define ACP_SCRATCH_REG_68 0x1250110
+#define ACP_SCRATCH_REG_69 0x1250114
+#define ACP_SCRATCH_REG_70 0x1250118
+#define ACP_SCRATCH_REG_71 0x125011C
+#define ACP_SCRATCH_REG_72 0x1250120
+#define ACP_SCRATCH_REG_73 0x1250124
+#define ACP_SCRATCH_REG_74 0x1250128
+#define ACP_SCRATCH_REG_75 0x125012C
+#define ACP_SCRATCH_REG_76 0x1250130
+#define ACP_SCRATCH_REG_77 0x1250134
+#define ACP_SCRATCH_REG_78 0x1250138
+#define ACP_SCRATCH_REG_79 0x125013C
+#define ACP_SCRATCH_REG_80 0x1250140
+#define ACP_SCRATCH_REG_81 0x1250144
+#define ACP_SCRATCH_REG_82 0x1250148
+#define ACP_SCRATCH_REG_83 0x125014C
+#define ACP_SCRATCH_REG_84 0x1250150
+#define ACP_SCRATCH_REG_85 0x1250154
+#define ACP_SCRATCH_REG_86 0x1250158
+#define ACP_SCRATCH_REG_87 0x125015C
+#define ACP_SCRATCH_REG_88 0x1250160
+#define ACP_SCRATCH_REG_89 0x1250164
+#define ACP_SCRATCH_REG_90 0x1250168
+#define ACP_SCRATCH_REG_91 0x125016C
+#define ACP_SCRATCH_REG_92 0x1250170
+#define ACP_SCRATCH_REG_93 0x1250174
+#define ACP_SCRATCH_REG_94 0x1250178
+#define ACP_SCRATCH_REG_95 0x125017C
+#define ACP_SCRATCH_REG_96 0x1250180
+#define ACP_SCRATCH_REG_97 0x1250184
+#define ACP_SCRATCH_REG_98 0x1250188
+#define ACP_SCRATCH_REG_99 0x125018C
+#define ACP_SCRATCH_REG_100 0x1250190
+#define ACP_SCRATCH_REG_101 0x1250194
+#define ACP_SCRATCH_REG_102 0x1250198
+#define ACP_SCRATCH_REG_103 0x125019C
+#define ACP_SCRATCH_REG_104 0x12501A0
+#define ACP_SCRATCH_REG_105 0x12501A4
+#define ACP_SCRATCH_REG_106 0x12501A8
+#define ACP_SCRATCH_REG_107 0x12501AC
+#define ACP_SCRATCH_REG_108 0x12501B0
+#define ACP_SCRATCH_REG_109 0x12501B4
+#define ACP_SCRATCH_REG_110 0x12501B8
+#define ACP_SCRATCH_REG_111 0x12501BC
+#define ACP_SCRATCH_REG_112 0x12501C0
+#define ACP_SCRATCH_REG_113 0x12501C4
+#define ACP_SCRATCH_REG_114 0x12501C8
+#define ACP_SCRATCH_REG_115 0x12501CC
+#define ACP_SCRATCH_REG_116 0x12501D0
+#define ACP_SCRATCH_REG_117 0x12501D4
+#define ACP_SCRATCH_REG_118 0x12501D8
+#define ACP_SCRATCH_REG_119 0x12501DC
+#define ACP_SCRATCH_REG_120 0x12501E0
+#define ACP_SCRATCH_REG_121 0x12501E4
+#define ACP_SCRATCH_REG_122 0x12501E8
+#define ACP_SCRATCH_REG_123 0x12501EC
+#define ACP_SCRATCH_REG_124 0x12501F0
+#define ACP_SCRATCH_REG_125 0x12501F4
+#define ACP_SCRATCH_REG_126 0x12501F8
+#define ACP_SCRATCH_REG_127 0x12501FC
+#define ACP_SCRATCH_REG_128 0x1250200
+
+/* Registers from ACP_AUDIO_BUFFERS block */
+#define ACP_I2S_RX_RINGBUFADDR 0x1242000
+#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define ACP_I2S_RX_FIFOADDR 0x124200C
+#define ACP_I2S_RX_FIFOSIZE 0x1242010
+#define ACP_I2S_RX_DMA_SIZE 0x1242014
+#define ACP_I2S_RX_LINEARPOSCNTR_HIGH 0x1242018
+#define ACP_I2S_RX_LINEARPOSCNTR_LOW 0x124201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define ACP_I2S_TX_RINGBUFADDR 0x1242024
+#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define ACP_I2S_TX_FIFOADDR 0x1242030
+#define ACP_I2S_TX_FIFOSIZE 0x1242034
+#define ACP_I2S_TX_DMA_SIZE 0x1242038
+#define ACP_I2S_TX_LINEARPOSCNTR_HIGH 0x124203C
+#define ACP_I2S_TX_LINEARPOSCNTR_LOW 0x1242040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define ACP_BT_RX_RINGBUFADDR 0x1242048
+#define ACP_BT_RX_RINGBUFSIZE 0x124204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define ACP_BT_RX_FIFOADDR 0x1242054
+#define ACP_BT_RX_FIFOSIZE 0x1242058
+#define ACP_BT_RX_DMA_SIZE 0x124205C
+#define ACP_BT_RX_LINEARPOSCNTR_HIGH 0x1242060
+#define ACP_BT_RX_LINEARPOSCNTR_LOW 0x1242064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define ACP_BT_TX_RINGBUFADDR 0x124206C
+#define ACP_BT_TX_RINGBUFSIZE 0x1242070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define ACP_BT_TX_FIFOADDR 0x1242078
+#define ACP_BT_TX_FIFOSIZE 0x124207C
+#define ACP_BT_TX_DMA_SIZE 0x1242080
+#define ACP_BT_TX_LINEARPOSCNTR_HIGH 0x1242084
+#define ACP_BT_TX_LINEARPOSCNTR_LOW 0x1242088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define ACP_HS_RX_RINGBUFADDR 0x1242090
+#define ACP_HS_RX_RINGBUFSIZE 0x1242094
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define ACP_HS_RX_FIFOADDR 0x124209C
+#define ACP_HS_RX_FIFOSIZE 0x12420A0
+#define ACP_HS_RX_DMA_SIZE 0x12420A4
+#define ACP_HS_RX_LINEARPOSCNTR_HIGH 0x12420A8
+#define ACP_HS_RX_LINEARPOSCNTR_LOW 0x12420AC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define ACP_HS_TX_RINGBUFADDR 0x12420B4
+#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define ACP_HS_TX_FIFOADDR 0x12420C0
+#define ACP_HS_TX_FIFOSIZE 0x12420C4
+#define ACP_HS_TX_DMA_SIZE 0x12420C8
+#define ACP_HS_TX_LINEARPOSCNTR_HIGH 0x12420CC
+#define ACP_HS_TX_LINEARPOSCNTR_LOW 0x12420D0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+/* Registers from ACP_I2S_TDM block */
+#define ACP_I2STDM_IER 0x1242400
+#define ACP_I2STDM_IRER 0x1242404
+#define ACP_I2STDM_RXFRMT 0x1242408
+#define ACP_I2STDM_ITER 0x124240C
+#define ACP_I2STDM_TXFRMT 0x1242410
+#define ACP_I2STDM0_MSTRCLKGEN 0x1242414
+#define ACP_I2STDM1_MSTRCLKGEN 0x1242418
+#define ACP_I2STDM2_MSTRCLKGEN 0x124241C
+#define ACP_I2STDM_REFCLKGEN 0x1242420
+
+/* Registers from ACP_BT_TDM block */
+#define ACP_BTTDM_IER 0x1242800
+#define ACP_BTTDM_IRER 0x1242804
+#define ACP_BTTDM_RXFRMT 0x1242808
+#define ACP_BTTDM_ITER 0x124280C
+#define ACP_BTTDM_TXFRMT 0x1242810
+#define ACP_HSTDM_IER 0x1242814
+#define ACP_HSTDM_IRER 0x1242818
+#define ACP_HSTDM_RXFRMT 0x124281C
+#define ACP_HSTDM_ITER 0x1242820
+#define ACP_HSTDM_TXFRMT 0x1242824
+#endif
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index ec04e3386bc0..8617793ed955 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -11,7 +11,6 @@ if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC
bool
- depends on HAS_DMA
config SND_ATMEL_SOC_DMA
bool
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
index e8fe1a7a4d83..6b3d9c05eaf2 100644
--- a/sound/soc/atmel/atmel-i2s.c
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -200,6 +200,7 @@ struct atmel_i2s_dev {
unsigned int fmt;
const struct atmel_i2s_gck_param *gck_param;
const struct atmel_i2s_caps *caps;
+ int clk_use_no;
};
static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
@@ -321,9 +322,16 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
{
struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- unsigned int mr = 0;
+ unsigned int mr = 0, mr_mask;
int ret;
+ mr_mask = ATMEL_I2SC_MR_FORMAT_MASK | ATMEL_I2SC_MR_MODE_MASK |
+ ATMEL_I2SC_MR_DATALENGTH_MASK;
+ if (is_playback)
+ mr_mask |= ATMEL_I2SC_MR_TXMONO;
+ else
+ mr_mask |= ATMEL_I2SC_MR_RXMONO;
+
switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
mr |= ATMEL_I2SC_MR_FORMAT_I2S;
@@ -402,7 +410,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
+ return regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
}
static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
@@ -495,18 +503,28 @@ static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
/* If master starts, enable the audio clock. */
- if (is_master && mck_enabled)
- err = atmel_i2s_switch_mck_generator(dev, true);
- if (err)
- return err;
+ if (is_master && mck_enabled) {
+ if (!dev->clk_use_no) {
+ err = atmel_i2s_switch_mck_generator(dev, true);
+ if (err)
+ return err;
+ }
+ dev->clk_use_no++;
+ }
err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
if (err)
return err;
/* If master stops, disable the audio clock. */
- if (is_master && !mck_enabled)
- err = atmel_i2s_switch_mck_generator(dev, false);
+ if (is_master && !mck_enabled) {
+ if (dev->clk_use_no == 1) {
+ err = atmel_i2s_switch_mck_generator(dev, false);
+ if (err)
+ return err;
+ }
+ dev->clk_use_no--;
+ }
return err;
}
@@ -542,6 +560,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = {
},
.ops = &atmel_i2s_dai_ops,
.symmetric_rate = 1,
+ .symmetric_sample_bits = 1,
};
static const struct snd_soc_component_driver atmel_i2s_component = {
diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
index e6ded6f8453f..bcd4f3e4fb0f 100644
--- a/sound/soc/atmel/mchp-spdifrx.c
+++ b/sound/soc/atmel/mchp-spdifrx.c
@@ -56,7 +56,7 @@
/* Validity Bit Mode */
#define SPDIFRX_MR_VBMODE_MASK GENAMSK(1, 1)
#define SPDIFRX_MR_VBMODE_ALWAYS_LOAD \
- (0 << 1) /* Load sample regardles of validity bit value */
+ (0 << 1) /* Load sample regardless of validity bit value */
#define SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 \
(1 << 1) /* Load sample only if validity bit is 0 */
@@ -519,7 +519,7 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev,
/* check for new data available */
ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
msecs_to_jiffies(100));
- /* IP might not be started or valid stream might not be prezent */
+ /* IP might not be started or valid stream might not be present */
if (ret < 0) {
dev_dbg(dev->dev, "channel status for channel %d timeout\n",
channel);
@@ -571,7 +571,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
mchp_spdifrx_isr_blockend_en(dev);
ret = wait_for_completion_interruptible_timeout(&user_data->done,
msecs_to_jiffies(100));
- /* IP might not be started or valid stream might not be prezent */
+ /* IP might not be started or valid stream might not be present */
if (ret <= 0) {
dev_dbg(dev->dev, "user data for channel %d timeout\n",
channel);
diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c
index 3bd350afb743..d24380046435 100644
--- a/sound/soc/atmel/mchp-spdiftx.c
+++ b/sound/soc/atmel/mchp-spdiftx.c
@@ -80,7 +80,7 @@
#define SPDIFTX_MR_VALID1 BIT(24)
#define SPDIFTX_MR_VALID2 BIT(25)
-/* Disable Null Frame on underrrun */
+/* Disable Null Frame on underrun */
#define SPDIFTX_MR_DNFR_MASK GENMASK(27, 27)
#define SPDIFTX_MR_DNFR_INVALID (0 << 27)
#define SPDIFTX_MR_DNFR_VALID (1 << 27)
diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c
index 59e2edb22b3a..50c3dc6936f9 100644
--- a/sound/soc/atmel/tse850-pcm5142.c
+++ b/sound/soc/atmel/tse850-pcm5142.c
@@ -23,7 +23,7 @@
// IN2 +---o--+------------+--o---+ OUT2
// loop2 relays
//
-// The 'loop1' gpio pin controlls two relays, which are either in loop
+// The 'loop1' gpio pin controls two relays, which are either in loop
// position, meaning that input and output are directly connected, or
// they are in mixer position, meaning that the signal is passed through
// the 'Sum' mixer. Similarly for 'loop2'.
diff --git a/sound/soc/bcm/cygnus-pcm.c b/sound/soc/bcm/cygnus-pcm.c
index 56b71b965624..3abeaf0f1b1c 100644
--- a/sound/soc/bcm/cygnus-pcm.c
+++ b/sound/soc/bcm/cygnus-pcm.c
@@ -729,7 +729,7 @@ static struct snd_soc_component_driver cygnus_soc_platform = {
int cygnus_soc_platform_register(struct device *dev,
struct cygnus_audio *cygaud)
{
- int rc = 0;
+ int rc;
dev_dbg(dev, "%s Enter\n", __func__);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d24edb01c19b..82ee233a269d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -187,6 +187,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_RT715_SDCA_SDW
imply SND_SOC_RT1308_SDW
imply SND_SOC_RT1316_SDW
+ imply SND_SOC_SDW_MOCKUP
imply SND_SOC_SGTL5000
imply SND_SOC_SI476X
imply SND_SOC_SIMPLE_AMPLIFIER
@@ -693,7 +694,7 @@ config SND_SOC_CS47L15
config SND_SOC_CS47L24
tristate
- depends on MFD_CS47L24
+ depends on MFD_CS47L24 && MFD_ARIZONA
config SND_SOC_CS47L35
tristate
@@ -847,7 +848,7 @@ config SND_SOC_HDAC_HDA
select SND_HDA
config SND_SOC_ICS43432
- tristate
+ tristate "ICS43423 and compatible i2s microphones"
config SND_SOC_INNO_RK3036
tristate "Inno codec driver for RK3036 SoC"
@@ -1287,6 +1288,23 @@ config SND_SOC_RT715_SDCA_SDW
select REGMAP_SOUNDWIRE
select REGMAP_SOUNDWIRE_MBQ
+config SND_SOC_SDW_MOCKUP
+ tristate "SoundWire mockup codec"
+ depends on EXPERT
+ depends on SOUNDWIRE
+ help
+ This option enables a SoundWire mockup codec that does not drive the
+ bus, take part in the command/command protocol or generate data on a
+ Source port.
+ This option is only intended to be used for tests on a device
+ with a connector, in combination with a bus analyzer, or to test new
+ topologies that differ from the actual hardware layout.
+ This mockup device could be totally virtual but could also be a
+ real physical one with one key restriction: it is not allowed by the
+ SoundWire specification to be configured via a sideband mechanism and
+ generate audio data for capture. However, nothing prevents such a
+ peripheral device from snooping the bus.
+
#Freescale sgtl5000 codec
config SND_SOC_SGTL5000
tristate "Freescale SGTL5000 CODEC"
@@ -1564,6 +1582,7 @@ config SND_SOC_WCD938X
config SND_SOC_WCD938X_SDW
tristate "WCD9380/WCD9385 Codec - SDW"
select SND_SOC_WCD938X
+ select SND_SOC_WCD_MBHC
depends on SOUNDWIRE
select REGMAP_SOUNDWIRE
help
@@ -1595,11 +1614,11 @@ config SND_SOC_WM5100
config SND_SOC_WM5102
tristate
- depends on MFD_WM5102
+ depends on MFD_WM5102 && MFD_ARIZONA
config SND_SOC_WM5110
tristate
- depends on MFD_WM5110
+ depends on MFD_WM5110 && MFD_ARIZONA
config SND_SOC_WM8350
tristate
@@ -1764,11 +1783,11 @@ config SND_SOC_WM8996
config SND_SOC_WM8997
tristate
- depends on MFD_WM8997
+ depends on MFD_WM8997 && MFD_ARIZONA
config SND_SOC_WM8998
tristate
- depends on MFD_WM8998
+ depends on MFD_WM8998 && MFD_ARIZONA
config SND_SOC_WM9081
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7bb38c370842..8dcea2c4604a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -203,6 +203,7 @@ snd-soc-rt711-objs := rt711.o rt711-sdw.o
snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o
snd-soc-rt715-objs := rt715.o rt715-sdw.o
snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o
+snd-soc-sdw-mockup-objs := sdw-mockup.o
snd-soc-sgtl5000-objs := sgtl5000.o
snd-soc-alc5623-objs := alc5623.o
snd-soc-alc5632-objs := alc5632.o
@@ -530,6 +531,7 @@ obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o
obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o
obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o
+obj-$(CONFIG_SND_SOC_SDW_MOCKUP) += snd-soc-sdw-mockup.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index f37ab7eda615..278a55af158b 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -316,6 +316,13 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
int word_len = 0, master_rate = 0;
struct snd_soc_component *component = dai->component;
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
+ bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ u8 dacc0;
+
+ dev_dbg(dai->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
+ __func__, params_rate(params), params_format(params),
+ params_width(params), params_channels(params));
+
/* bit size */
switch (params_width(params)) {
@@ -346,6 +353,25 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
break;
}
+ if (is_playback) {
+ switch (params_rate(params)) {
+ case 48000:
+ dacc0 = AD193X_DAC_SR_48;
+ break;
+ case 96000:
+ dacc0 = AD193X_DAC_SR_96;
+ break;
+ case 192000:
+ dacc0 = AD193X_DAC_SR_192;
+ break;
+ default:
+ dev_err(dai->dev, "invalid sampling rate: %d\n", params_rate(params));
+ return -EINVAL;
+ }
+
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, AD193X_DAC_SR_MASK, dacc0);
+ }
+
regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
AD193X_PLL_INPUT_MASK, master_rate);
@@ -385,7 +411,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
@@ -407,7 +433,7 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 377854712c20..61f4648861d5 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -37,6 +37,10 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
#define AD193X_PLL_CLK_SRC_MCLK (1 << 1)
#define AD193X_DAC_CTRL0 0x02
#define AD193X_DAC_POWERDOWN 0x01
+#define AD193X_DAC_SR_MASK 0x06
+#define AD193X_DAC_SR_48 (0 << 1)
+#define AD193X_DAC_SR_96 (1 << 1)
+#define AD193X_DAC_SR_192 (2 << 1)
#define AD193X_DAC_SERFMT_MASK 0xC0
#define AD193X_DAC_SERFMT_STEREO (0 << 6)
#define AD193X_DAC_SERFMT_TDM (1 << 6)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index 99c022be94a6..fb1e4c33e27d 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -586,6 +586,7 @@ struct cs42l42_pll_params {
* Table 4-5 from the Datasheet
*/
static const struct cs42l42_pll_params pll_ratio_table[] = {
+ { 1411200, 0, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2},
{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
{ 2304000, 0, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2},
{ 2400000, 0, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2},
@@ -843,6 +844,13 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
if (channels == 1)
cs42l42->bclk *= 2;
+ /*
+ * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
+ * more than assumed (which would result in overclocking).
+ */
+ if (params_width(params) == 24)
+ cs42l42->bclk = (cs42l42->bclk / 3) * 4;
+
switch(substream->stream) {
case SNDRV_PCM_STREAM_CAPTURE:
if (channels == 2) {
@@ -890,10 +898,23 @@ static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
{
struct snd_soc_component *component = dai->component;
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
+ int i;
- cs42l42->sclk = freq;
+ if (freq == 0) {
+ cs42l42->sclk = 0;
+ return 0;
+ }
- return 0;
+ for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
+ if (pll_ratio_table[i].sclk == freq) {
+ cs42l42->sclk = freq;
+ return 0;
+ }
+ }
+
+ dev_err(component->dev, "SCLK %u not supported\n", freq);
+
+ return -EINVAL;
}
static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
@@ -2106,4 +2127,7 @@ MODULE_DESCRIPTION("ASoC CS42L42 driver");
MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
MODULE_AUTHOR("Michael White, Cirrus Logic Inc, <michael.white@cirrus.com>");
+MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Vitaly Rodionov <vitalyr@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index 112ffcf938c3..8734f6828f3e 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -79,7 +79,7 @@
#define CS42L42_HP_PDN_SHIFT 3
#define CS42L42_HP_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT)
#define CS42L42_ADC_PDN_SHIFT 2
-#define CS42L42_ADC_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT)
+#define CS42L42_ADC_PDN_MASK (1 << CS42L42_ADC_PDN_SHIFT)
#define CS42L42_PDN_ALL_SHIFT 0
#define CS42L42_PDN_ALL_MASK (1 << CS42L42_PDN_ALL_SHIFT)
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 61dfa86d444d..13258f3ca9aa 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -206,7 +206,7 @@ static int cx20442_write(struct snd_soc_component *component, unsigned int reg,
*/
/* Modem init: echo off, digital speaker off, quiet off, voice mode */
-static const char *v253_init = "ate0m0q0+fclass=8\r";
+static const char v253_init[] = "ate0m0q0+fclass=8\r";
/* Line discipline .open() */
static int v253_open(struct tty_struct *tty)
@@ -259,8 +259,8 @@ static int v253_hangup(struct tty_struct *tty)
}
/* Line discipline .receive_buf() */
-static void v253_receive(struct tty_struct *tty,
- const unsigned char *cp, char *fp, int count)
+static void v253_receive(struct tty_struct *tty, const unsigned char *cp,
+ const char *fp, int count)
{
struct snd_soc_component *component = tty->disc_data;
struct cx20442_priv *cx20442;
@@ -279,11 +279,6 @@ static void v253_receive(struct tty_struct *tty,
}
}
-/* Line discipline .write_wakeup() */
-static void v253_wakeup(struct tty_struct *tty)
-{
-}
-
struct tty_ldisc_ops v253_ops = {
.name = "cx20442",
.owner = THIS_MODULE,
@@ -291,7 +286,6 @@ struct tty_ldisc_ops v253_ops = {
.close = v253_close,
.hangup = v253_hangup,
.receive_buf = v253_receive,
- .write_wakeup = v253_wakeup,
};
EXPORT_SYMBOL_GPL(v253_ops);
diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c
index 47e749f03940..de4c8460ab3d 100644
--- a/sound/soc/codecs/ics43432.c
+++ b/sound/soc/codecs/ics43432.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * I2S MEMS microphone driver for InvenSense ICS-43432
+ * I2S MEMS microphone driver for InvenSense ICS-43432 and similar
+ * MEMS-based microphones.
*
* - Non configurable.
* - I2S interface, 64 BCLs per frame, 32 bits per channel, 24 bit data
@@ -53,6 +54,7 @@ static int ics43432_probe(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id ics43432_ids[] = {
{ .compatible = "invensense,ics43432", },
+ { .compatible = "cui,cmm-4030d-261", },
{ }
};
MODULE_DEVICE_TABLE(of, ics43432_ids);
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index 3622961f7c2c..196b06898eeb 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -1722,42 +1722,43 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
case RX_MACRO_AIF2_PB:
case RX_MACRO_AIF3_PB:
case RX_MACRO_AIF4_PB:
- for (j = 0; j < INTERP_MAX; j++) {
- reg = CDC_RX_RXn_RX_PATH_CTL(j);
- mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j);
- dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(j);
-
- if (mute) {
- snd_soc_component_update_bits(component, reg,
- CDC_RX_PATH_PGA_MUTE_MASK,
- CDC_RX_PATH_PGA_MUTE_ENABLE);
- snd_soc_component_update_bits(component, mix_reg,
- CDC_RX_PATH_PGA_MUTE_MASK,
- CDC_RX_PATH_PGA_MUTE_ENABLE);
- } else {
- snd_soc_component_update_bits(component, reg,
- CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
- snd_soc_component_update_bits(component, mix_reg,
- CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
- }
-
- if (j == INTERP_AUX)
- dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL;
+ for (j = 0; j < INTERP_MAX; j++) {
+ reg = CDC_RX_RXn_RX_PATH_CTL(j);
+ mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j);
+ dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(j);
+
+ if (mute) {
+ snd_soc_component_update_bits(component, reg,
+ CDC_RX_PATH_PGA_MUTE_MASK,
+ CDC_RX_PATH_PGA_MUTE_ENABLE);
+ snd_soc_component_update_bits(component, mix_reg,
+ CDC_RX_PATH_PGA_MUTE_MASK,
+ CDC_RX_PATH_PGA_MUTE_ENABLE);
+ } else {
+ snd_soc_component_update_bits(component, reg,
+ CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
+ snd_soc_component_update_bits(component, mix_reg,
+ CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
+ }
- int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
- int_mux_cfg1 = int_mux_cfg0 + 4;
- int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
- int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1);
+ if (j == INTERP_AUX)
+ dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL;
- if (snd_soc_component_read(component, dsm_reg) & 0x01) {
- if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0))
- snd_soc_component_update_bits(component, reg, 0x20, 0x20);
- if (int_mux_cfg1_val & 0x0F) {
- snd_soc_component_update_bits(component, reg, 0x20, 0x20);
- snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20);
+ int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
+ int_mux_cfg1 = int_mux_cfg0 + 4;
+ int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
+ int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1);
+
+ if (snd_soc_component_read(component, dsm_reg) & 0x01) {
+ if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0))
+ snd_soc_component_update_bits(component, reg, 0x20, 0x20);
+ if (int_mux_cfg1_val & 0x0F) {
+ snd_soc_component_update_bits(component, reg, 0x20, 0x20);
+ snd_soc_component_update_bits(component, mix_reg, 0x20,
+ 0x20);
+ }
}
}
- }
break;
default:
break;
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index bc30a1dc7530..b45ec35cd63c 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2158,13 +2158,11 @@ static void max98090_jack_work(struct work_struct *work)
msleep(50);
- reg = snd_soc_component_read(component, M98090_REG_JACK_STATUS);
+ snd_soc_component_read(component, M98090_REG_JACK_STATUS);
/* Weak pull up allows only insertion detection */
snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
M98090_JDWK_MASK, M98090_JDWK_MASK);
- } else {
- reg = snd_soc_component_read(component, M98090_REG_JACK_STATUS);
}
reg = snd_soc_component_read(component, M98090_REG_JACK_STATUS);
diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c
index f3a12205cd48..dc520effc61c 100644
--- a/sound/soc/codecs/max98373-sdw.c
+++ b/sound/soc/codecs/max98373-sdw.c
@@ -271,7 +271,7 @@ static __maybe_unused int max98373_resume(struct device *dev)
struct max98373_priv *max98373 = dev_get_drvdata(dev);
unsigned long time;
- if (!max98373->hw_init)
+ if (!max98373->first_hw_init)
return 0;
if (!slave->unattach_request)
@@ -362,7 +362,7 @@ static int max98373_io_init(struct sdw_slave *slave)
struct device *dev = &slave->dev;
struct max98373_priv *max98373 = dev_get_drvdata(dev);
- if (max98373->pm_init_once) {
+ if (max98373->first_hw_init) {
regcache_cache_only(max98373->regmap, false);
regcache_cache_bypass(max98373->regmap, true);
}
@@ -370,7 +370,7 @@ static int max98373_io_init(struct sdw_slave *slave)
/*
* PM runtime is only enabled when a Slave reports as Attached
*/
- if (!max98373->pm_init_once) {
+ if (!max98373->first_hw_init) {
/* set autosuspend parameters */
pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
@@ -462,12 +462,12 @@ static int max98373_io_init(struct sdw_slave *slave)
regmap_write(max98373->regmap, MAX98373_R20B5_BDE_EN, 1);
regmap_write(max98373->regmap, MAX98373_R20E2_LIMITER_EN, 1);
- if (max98373->pm_init_once) {
+ if (max98373->first_hw_init) {
regcache_cache_bypass(max98373->regmap, false);
regcache_mark_dirty(max98373->regmap);
}
- max98373->pm_init_once = true;
+ max98373->first_hw_init = true;
max98373->hw_init = true;
pm_runtime_mark_last_busy(dev);
@@ -787,6 +787,8 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
max98373->cache = devm_kcalloc(dev, max98373->cache_num,
sizeof(*max98373->cache),
GFP_KERNEL);
+ if (!max98373->cache)
+ return -ENOMEM;
for (i = 0; i < max98373->cache_num; i++)
max98373->cache[i].reg = max98373_sdw_cache_reg[i];
@@ -795,7 +797,7 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
max98373_slot_config(dev, max98373);
max98373->hw_init = false;
- max98373->pm_init_once = false;
+ max98373->first_hw_init = false;
/* codec registration */
ret = devm_snd_soc_register_component(dev, &soc_codec_dev_max98373_sdw,
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
index 73a2cf69d84a..e1810b3b1620 100644
--- a/sound/soc/codecs/max98373.h
+++ b/sound/soc/codecs/max98373.h
@@ -226,7 +226,7 @@ struct max98373_priv {
/* variables to support soundwire */
struct sdw_slave *slave;
bool hw_init;
- bool pm_init_once;
+ bool first_hw_init;
int slot;
unsigned int rx_mask;
};
diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c
index 94773ccee9d5..b392567c2b3e 100644
--- a/sound/soc/codecs/max98390.c
+++ b/sound/soc/codecs/max98390.c
@@ -765,17 +765,26 @@ static int max98390_dsm_init(struct snd_soc_component *component)
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
product = dmi_get_system_info(DMI_PRODUCT_NAME);
- if (vendor && product) {
- snprintf(filename, sizeof(filename), "dsm_param_%s_%s.bin",
- vendor, product);
+ if (!strcmp(max98390->dsm_param_name, "default")) {
+ if (vendor && product) {
+ snprintf(filename, sizeof(filename),
+ "dsm_param_%s_%s.bin", vendor, product);
+ } else {
+ sprintf(filename, "dsm_param.bin");
+ }
} else {
- sprintf(filename, "dsm_param.bin");
+ snprintf(filename, sizeof(filename), "%s",
+ max98390->dsm_param_name);
}
ret = request_firmware(&fw, filename, component->dev);
if (ret) {
ret = request_firmware(&fw, "dsm_param.bin", component->dev);
- if (ret)
- goto err;
+ if (ret) {
+ ret = request_firmware(&fw, "dsmparam.bin",
+ component->dev);
+ if (ret)
+ goto err;
+ }
}
dev_dbg(component->dev,
@@ -1047,6 +1056,11 @@ static int max98390_i2c_probe(struct i2c_client *i2c,
__func__, max98390->ref_rdc_value,
max98390->ambient_temp_value);
+ ret = device_property_read_string(&i2c->dev, "maxim,dsm_param_name",
+ &max98390->dsm_param_name);
+ if (ret)
+ max98390->dsm_param_name = "default";
+
/* voltage/current slot configuration */
max98390_slot_config(i2c, max98390);
diff --git a/sound/soc/codecs/max98390.h b/sound/soc/codecs/max98390.h
index e31516717d3b..c250740f73a2 100644
--- a/sound/soc/codecs/max98390.h
+++ b/sound/soc/codecs/max98390.h
@@ -662,5 +662,6 @@ struct max98390_priv {
unsigned int i_l_slot;
unsigned int ref_rdc_value;
unsigned int ambient_temp_value;
+ const char *dsm_param_name;
};
#endif
diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c
index 78314187d37e..6d3d170144a0 100644
--- a/sound/soc/codecs/mt6359-accdet.c
+++ b/sound/soc/codecs/mt6359-accdet.c
@@ -234,7 +234,7 @@ static void recover_eint_setting(struct mt6359_accdet *priv)
static void mt6359_accdet_recover_jd_setting(struct mt6359_accdet *priv)
{
- int ret = 0;
+ int ret;
unsigned int value = 0;
regmap_update_bits(priv->regmap, ACCDET_IRQ_ADDR,
@@ -461,7 +461,7 @@ static irqreturn_t mt6359_accdet_irq(int irq, void *data)
{
struct mt6359_accdet *priv = data;
unsigned int irq_val = 0, val = 0, value = 0;
- int ret = 0;
+ int ret;
mutex_lock(&priv->res_lock);
regmap_read(priv->regmap, ACCDET_IRQ_ADDR, &irq_val);
@@ -551,7 +551,7 @@ static irqreturn_t mt6359_accdet_irq(int irq, void *data)
static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv)
{
- int ret = 0;
+ int ret;
struct device *dev = priv->dev;
struct device_node *node = NULL;
int pwm_deb[15] = {0};
@@ -926,7 +926,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
{
struct mt6359_accdet *priv;
struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
- int ret = 0;
+ int ret;
dev_dbg(&pdev->dev, "%s(), dev name %s\n",
__func__, dev_name(&pdev->dev));
@@ -1057,22 +1057,7 @@ static struct platform_driver mt6359_accdet_driver = {
.probe = mt6359_accdet_probe,
};
-static int __init mt6359_accdet_driver_init(void)
-{
- int ret = 0;
-
- ret = platform_driver_register(&mt6359_accdet_driver);
- if (ret)
- return -ENODEV;
- return 0;
-}
-
-static void __exit mt6359_accdet_driver_exit(void)
-{
- platform_driver_unregister(&mt6359_accdet_driver);
-}
-module_init(mt6359_accdet_driver_init);
-module_exit(mt6359_accdet_driver_exit);
+module_platform_driver(mt6359_accdet_driver)
/* Module information */
MODULE_DESCRIPTION("MT6359 ALSA SoC codec jack driver");
diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c
index 9238f12999aa..c0c5952cdff7 100644
--- a/sound/soc/codecs/rt1015.c
+++ b/sound/soc/codecs/rt1015.c
@@ -547,31 +547,6 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static void rt1015_flush_work(struct work_struct *work)
-{
- struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv,
- flush_work.work);
- struct snd_soc_component *component = rt1015->component;
- unsigned int val, i;
-
- for (i = 0; i < 200; ++i) {
- usleep_range(1000, 1500);
- dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i);
- regmap_read(rt1015->regmap, RT1015_CLK_DET, &val);
- if (val & 0x800)
- break;
- }
-
- regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
- regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
- regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
-
- if (val & 0x800)
- dev_dbg(component->dev, "Flush DAC completed.\n");
- else
- dev_warn(component->dev, "Fail to flush DAC data.\n");
-}
-
static const struct snd_kcontrol_new rt1015_snd_controls[] = {
SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT,
127, 0, dac_vol_tlv),
@@ -630,10 +605,6 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
}
break;
- case SND_SOC_DAPM_POST_PMU:
- regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
- break;
-
case SND_SOC_DAPM_POST_PMD:
if (rt1015->bypass_boost == RT1015_Enable_Boost) {
snd_soc_component_write(component,
@@ -653,8 +624,6 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
RT1015_SYS_RST2, 0x0b9a);
}
rt1015->dac_is_used = 0;
-
- cancel_delayed_work_sync(&rt1015->flush_work);
break;
default:
@@ -687,8 +656,6 @@ static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
}
break;
case SND_SOC_DAPM_POST_PMU:
- if (rt1015->hw_config == RT1015_HW_28)
- schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10));
msleep(rt1015->pdata.power_up_delay_ms);
break;
default:
@@ -702,7 +669,7 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
NULL, 0),
SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0,
- r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ r1015_dac_event, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0,
rt1015_amp_drv_event, SND_SOC_DAPM_PRE_PMU |
@@ -722,7 +689,7 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
- int pre_div, bclk_ms, frame_size, lrck;
+ int pre_div, frame_size, lrck;
unsigned int val_len = 0;
lrck = params_rate(params);
@@ -739,10 +706,7 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- bclk_ms = frame_size > 32;
-
- dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
- bclk_ms, pre_div, dai->id);
+ dev_dbg(component->dev, "pre_div is %d for iis %d\n", pre_div, dai->id);
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
lrck, pre_div, dai->id);
@@ -1028,7 +992,6 @@ static int rt1015_probe(struct snd_soc_component *component)
snd_soc_component_get_drvdata(component);
rt1015->component = component;
- INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work);
return 0;
}
@@ -1037,7 +1000,6 @@ static void rt1015_remove(struct snd_soc_component *component)
{
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
- cancel_delayed_work_sync(&rt1015->flush_work);
regmap_write(rt1015->regmap, RT1015_RESET, 0);
}
@@ -1180,8 +1142,6 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
return ret;
}
- rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28;
-
ret = regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val);
if (ret) {
dev_err(&i2c->dev,
diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h
index 14344532048e..c9f636af7fd1 100644
--- a/sound/soc/codecs/rt1015.h
+++ b/sound/soc/codecs/rt1015.h
@@ -444,8 +444,6 @@ struct rt1015_priv {
int bypass_boost;
int dac_is_used;
int cali_done;
- int hw_config;
- struct delayed_work flush_work;
};
#endif /* __RT1015_H__ */
diff --git a/sound/soc/codecs/rt1015p.c b/sound/soc/codecs/rt1015p.c
index 40f2063aefbe..415cfb3b2f0d 100644
--- a/sound/soc/codecs/rt1015p.c
+++ b/sound/soc/codecs/rt1015p.c
@@ -127,6 +127,7 @@ static int rt1015p_platform_probe(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id rt1015p_device_id[] = {
{ .compatible = "realtek,rt1015p" },
+ { .compatible = "realtek,rt1019p" },
{}
};
MODULE_DEVICE_TABLE(of, rt1015p_device_id);
@@ -135,6 +136,7 @@ MODULE_DEVICE_TABLE(of, rt1015p_device_id);
#ifdef CONFIG_ACPI
static const struct acpi_device_id rt1015p_acpi_match[] = {
{ "RTL1015", 0},
+ { "RTL1019", 0},
{ },
};
MODULE_DEVICE_TABLE(acpi, rt1015p_acpi_match);
diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c
index 1c226994aebd..f716668de640 100644
--- a/sound/soc/codecs/rt1308-sdw.c
+++ b/sound/soc/codecs/rt1308-sdw.c
@@ -709,7 +709,7 @@ static int __maybe_unused rt1308_dev_resume(struct device *dev)
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt1308->hw_init)
+ if (!rt1308->first_hw_init)
return 0;
if (!slave->unattach_request)
diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c
index 3b029c56467d..09b4914bba1b 100644
--- a/sound/soc/codecs/rt1316-sdw.c
+++ b/sound/soc/codecs/rt1316-sdw.c
@@ -701,7 +701,7 @@ static int __maybe_unused rt1316_dev_resume(struct device *dev)
struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt1316->hw_init)
+ if (!rt1316->first_hw_init)
return 0;
if (!slave->unattach_request)
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 7081142a355e..4b1ad5054e8d 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -494,7 +494,7 @@ static const struct snd_kcontrol_new rt5514_sto2_dmic_mux =
*/
static int rt5514_calc_dmic_clk(struct snd_soc_component *component, int rate)
{
- int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
+ static const int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
int i;
if (rate < 1000000 * div[0]) {
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 9523f4b5c800..cd1db5caabad 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2093,7 +2093,7 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
-static void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
+void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
@@ -2105,8 +2105,9 @@ static void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
snd_soc_dapm_sync_unlocked(dapm);
snd_soc_dapm_mutex_unlock(dapm);
}
+EXPORT_SYMBOL_GPL(rt5640_enable_micbias1_for_ovcd);
-static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component)
+void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
@@ -2117,6 +2118,7 @@ static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component
snd_soc_dapm_sync_unlocked(dapm);
snd_soc_dapm_mutex_unlock(dapm);
}
+EXPORT_SYMBOL_GPL(rt5640_disable_micbias1_for_ovcd);
static void rt5640_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
{
@@ -2241,7 +2243,7 @@ static void rt5640_button_press_work(struct work_struct *work)
schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
}
-static int rt5640_detect_headset(struct snd_soc_component *component)
+int rt5640_detect_headset(struct snd_soc_component *component, struct gpio_desc *hp_det_gpio)
{
int i, headset_count = 0, headphone_count = 0;
@@ -2259,8 +2261,13 @@ static int rt5640_detect_headset(struct snd_soc_component *component)
msleep(JACK_SETTLE_TIME);
/* Check the jack is still connected before checking ovcd */
- if (!rt5640_jack_inserted(component))
- return 0;
+ if (hp_det_gpio) {
+ if (gpiod_get_value_cansleep(hp_det_gpio))
+ return 0;
+ } else {
+ if (!rt5640_jack_inserted(component))
+ return 0;
+ }
if (rt5640_micbias1_ovcd(component)) {
/*
@@ -2285,6 +2292,7 @@ static int rt5640_detect_headset(struct snd_soc_component *component)
dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
return SND_JACK_HEADPHONE;
}
+EXPORT_SYMBOL_GPL(rt5640_detect_headset);
static void rt5640_jack_work(struct work_struct *work)
{
@@ -2309,7 +2317,7 @@ static void rt5640_jack_work(struct work_struct *work)
/* Jack inserted */
WARN_ON(rt5640->ovcd_irq_enabled);
rt5640_enable_micbias1_for_ovcd(component);
- status = rt5640_detect_headset(component);
+ status = rt5640_detect_headset(component, NULL);
if (status == SND_JACK_HEADSET) {
/* Enable ovcd IRQ for button press detect. */
rt5640_enable_micbias1_ovcd_irq(component);
@@ -2362,10 +2370,59 @@ static void rt5640_cancel_work(void *data)
cancel_delayed_work_sync(&rt5640->bp_work);
}
+void rt5640_set_ovcd_params(struct snd_soc_component *component)
+{
+ struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+ snd_soc_component_write(component, RT5640_PR_BASE + RT5640_BIAS_CUR4,
+ 0xa800 | rt5640->ovcd_sf);
+
+ snd_soc_component_update_bits(component, RT5640_MICBIAS,
+ RT5640_MIC1_OVTH_MASK | RT5640_MIC1_OVCD_MASK,
+ rt5640->ovcd_th | RT5640_MIC1_OVCD_EN);
+
+ /*
+ * The over-current-detect is only reliable in detecting the absence
+ * of over-current, when the mic-contact in the jack is short-circuited,
+ * the hardware periodically retries if it can apply the bias-current
+ * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
+ * 10% of the time, as we poll the ovcd status bit we might hit that
+ * 10%, so we enable sticky mode and when checking OVCD we clear the
+ * status, msleep() a bit and then check to get a reliable reading.
+ */
+ snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+ RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
+}
+EXPORT_SYMBOL_GPL(rt5640_set_ovcd_params);
+
+static void rt5640_disable_jack_detect(struct snd_soc_component *component)
+{
+ struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+ /*
+ * soc_remove_component() force-disables jack and thus rt5640->jack
+ * could be NULL at the time of driver's module unloading.
+ */
+ if (!rt5640->jack)
+ return;
+
+ free_irq(rt5640->irq, rt5640);
+ rt5640_cancel_work(rt5640);
+
+ if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+ rt5640_disable_micbias1_ovcd_irq(component);
+ rt5640_disable_micbias1_for_ovcd(component);
+ snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+ }
+
+ rt5640->jack = NULL;
+}
+
static void rt5640_enable_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack)
{
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+ int ret;
/* Select JD-source */
snd_soc_component_update_bits(component, RT5640_JD_CTRL,
@@ -2385,24 +2442,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
/* Enabling jd2 in general control 2 */
snd_soc_component_write(component, RT5640_DUMMY2, 0x4001);
- snd_soc_component_write(component, RT5640_PR_BASE + RT5640_BIAS_CUR4,
- 0xa800 | rt5640->ovcd_sf);
-
- snd_soc_component_update_bits(component, RT5640_MICBIAS,
- RT5640_MIC1_OVTH_MASK | RT5640_MIC1_OVCD_MASK,
- rt5640->ovcd_th | RT5640_MIC1_OVCD_EN);
-
- /*
- * The over-current-detect is only reliable in detecting the absence
- * of over-current, when the mic-contact in the jack is short-circuited,
- * the hardware periodically retries if it can apply the bias-current
- * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
- * 10% of the time, as we poll the ovcd status bit we might hit that
- * 10%, so we enable sticky mode and when checking OVCD we clear the
- * status, msleep() a bit and then check to get a reliable reading.
- */
- snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
- RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
+ rt5640_set_ovcd_params(component);
/*
* All IRQs get or-ed together, so we need the jack IRQ to report 0
@@ -2423,32 +2463,19 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
rt5640_enable_micbias1_ovcd_irq(component);
}
- enable_irq(rt5640->irq);
- /* sync initial jack state */
- queue_work(system_long_wq, &rt5640->jack_work);
-}
-
-static void rt5640_disable_jack_detect(struct snd_soc_component *component)
-{
- struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
-
- /*
- * soc_remove_component() force-disables jack and thus rt5640->jack
- * could be NULL at the time of driver's module unloading.
- */
- if (!rt5640->jack)
+ ret = request_irq(rt5640->irq, rt5640_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "rt5640", rt5640);
+ if (ret) {
+ dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
+ rt5640->irq = -ENXIO;
+ /* Undo above settings */
+ rt5640_disable_jack_detect(component);
return;
-
- disable_irq(rt5640->irq);
- rt5640_cancel_work(rt5640);
-
- if (rt5640->jack->status & SND_JACK_MICROPHONE) {
- rt5640_disable_micbias1_ovcd_irq(component);
- rt5640_disable_micbias1_for_ovcd(component);
- snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
}
- rt5640->jack = NULL;
+ /* sync initial jack state */
+ queue_work(system_long_wq, &rt5640->jack_work);
}
static int rt5640_set_jack(struct snd_soc_component *component,
@@ -2836,18 +2863,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
if (ret)
return ret;
- ret = devm_request_irq(&i2c->dev, rt5640->irq, rt5640_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
- | IRQF_ONESHOT, "rt5640", rt5640);
- if (ret == 0) {
- /* Gets re-enabled by rt5640_set_jack() */
- disable_irq(rt5640->irq);
- } else {
- dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n",
- rt5640->irq, ret);
- rt5640->irq = -ENXIO;
- }
-
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt5640,
rt5640_dai, ARRAY_SIZE(rt5640_dai));
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 4fd47f2b936b..2c28f83e338a 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -10,6 +10,7 @@
#define _RT5640_H
#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
#include <linux/workqueue.h>
#include <dt-bindings/sound/rt5640.h>
@@ -2157,4 +2158,9 @@ int rt5640_dmic_enable(struct snd_soc_component *component,
int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
unsigned int filter_mask, unsigned int clk_src);
+void rt5640_set_ovcd_params(struct snd_soc_component *component);
+void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component);
+void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component);
+int rt5640_detect_headset(struct snd_soc_component *component, struct gpio_desc *hp_det_gpio);
+
#endif
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 438fa18bcb55..9408ee63cb26 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3388,44 +3388,30 @@ static int rt5645_probe(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
- int ret = 0;
rt5645->component = component;
switch (rt5645->codec_type) {
case CODEC_TYPE_RT5645:
- ret = snd_soc_dapm_new_controls(dapm,
+ snd_soc_dapm_new_controls(dapm,
rt5645_specific_dapm_widgets,
ARRAY_SIZE(rt5645_specific_dapm_widgets));
- if (ret < 0)
- goto exit;
-
- ret = snd_soc_dapm_add_routes(dapm,
+ snd_soc_dapm_add_routes(dapm,
rt5645_specific_dapm_routes,
ARRAY_SIZE(rt5645_specific_dapm_routes));
- if (ret < 0)
- goto exit;
-
if (rt5645->v_id < 3) {
- ret = snd_soc_dapm_add_routes(dapm,
+ snd_soc_dapm_add_routes(dapm,
rt5645_old_dapm_routes,
ARRAY_SIZE(rt5645_old_dapm_routes));
- if (ret < 0)
- goto exit;
}
break;
case CODEC_TYPE_RT5650:
- ret = snd_soc_dapm_new_controls(dapm,
+ snd_soc_dapm_new_controls(dapm,
rt5650_specific_dapm_widgets,
ARRAY_SIZE(rt5650_specific_dapm_widgets));
- if (ret < 0)
- goto exit;
-
- ret = snd_soc_dapm_add_routes(dapm,
+ snd_soc_dapm_add_routes(dapm,
rt5650_specific_dapm_routes,
ARRAY_SIZE(rt5650_specific_dapm_routes));
- if (ret < 0)
- goto exit;
break;
}
@@ -3433,17 +3419,9 @@ static int rt5645_probe(struct snd_soc_component *component)
/* for JD function */
if (rt5645->pdata.jd_mode) {
- ret = snd_soc_dapm_force_enable_pin(dapm, "JD Power");
- if (ret < 0)
- goto exit;
-
- ret = snd_soc_dapm_force_enable_pin(dapm, "LDO2");
- if (ret < 0)
- goto exit;
-
- ret = snd_soc_dapm_sync(dapm);
- if (ret < 0)
- goto exit;
+ snd_soc_dapm_force_enable_pin(dapm, "JD Power");
+ snd_soc_dapm_force_enable_pin(dapm, "LDO2");
+ snd_soc_dapm_sync(dapm);
}
if (rt5645->pdata.long_name)
@@ -3454,14 +3432,9 @@ static int rt5645_probe(struct snd_soc_component *component)
GFP_KERNEL);
if (!rt5645->eq_param)
- ret = -ENOMEM;
-exit:
- /*
- * If there was an error above, everything will be cleaned up by the
- * caller if we return an error here. This will be done with a later
- * call to rt5645_remove().
- */
- return ret;
+ return -ENOMEM;
+
+ return 0;
}
static void rt5645_remove(struct snd_soc_component *component)
diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c
index 4a56a52adab5..b9d5d7a0975b 100644
--- a/sound/soc/codecs/rt5682-i2c.c
+++ b/sound/soc/codecs/rt5682-i2c.c
@@ -117,6 +117,13 @@ static struct snd_soc_dai_driver rt5682_dai[] = {
},
};
+static void rt5682_i2c_disable_regulators(void *data)
+{
+ struct rt5682_priv *rt5682 = data;
+
+ regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies);
+}
+
static int rt5682_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -157,6 +164,11 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ ret = devm_add_action_or_reset(&i2c->dev, rt5682_i2c_disable_regulators,
+ rt5682);
+ if (ret)
+ return ret;
+
ret = regulator_bulk_enable(ARRAY_SIZE(rt5682->supplies),
rt5682->supplies);
if (ret) {
@@ -282,10 +294,7 @@ static void rt5682_i2c_shutdown(struct i2c_client *client)
static int rt5682_i2c_remove(struct i2c_client *client)
{
- struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
-
rt5682_i2c_shutdown(client);
- regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies);
return 0;
}
diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
index e78ba3b064c4..31a4f286043e 100644
--- a/sound/soc/codecs/rt5682-sdw.c
+++ b/sound/soc/codecs/rt5682-sdw.c
@@ -344,6 +344,8 @@ static int rt5682_sdw_init(struct device *dev, struct regmap *regmap,
rt5682->sdw_regmap = regmap;
rt5682->is_sdw = true;
+ mutex_init(&rt5682->disable_irq_lock);
+
rt5682->regmap = devm_regmap_init(dev, NULL, dev,
&rt5682_sdw_indirect_regmap);
if (IS_ERR(rt5682->regmap)) {
@@ -378,6 +380,8 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
int ret = 0, loop = 10;
unsigned int val;
+ rt5682->disable_irq = false;
+
if (rt5682->hw_init)
return 0;
@@ -400,6 +404,11 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
pm_runtime_get_noresume(&slave->dev);
+ if (rt5682->first_hw_init) {
+ regcache_cache_only(rt5682->regmap, false);
+ regcache_cache_bypass(rt5682->regmap, true);
+ }
+
while (loop > 0) {
regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val);
if (val == DEVICE_ID)
@@ -408,14 +417,11 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
usleep_range(30000, 30005);
loop--;
}
+
if (val != DEVICE_ID) {
dev_err(dev, "Device with ID register %x is not rt5682\n", val);
- return -ENODEV;
- }
-
- if (rt5682->first_hw_init) {
- regcache_cache_only(rt5682->regmap, false);
- regcache_cache_bypass(rt5682->regmap, true);
+ ret = -ENODEV;
+ goto err_nodev;
}
rt5682_calibrate(rt5682);
@@ -486,10 +492,11 @@ reinit:
rt5682->hw_init = true;
rt5682->first_hw_init = true;
+err_nodev:
pm_runtime_mark_last_busy(&slave->dev);
pm_runtime_put_autosuspend(&slave->dev);
- dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
+ dev_dbg(&slave->dev, "%s hw_init complete: %d\n", __func__, ret);
return ret;
}
@@ -676,10 +683,12 @@ static int rt5682_interrupt_callback(struct sdw_slave *slave,
dev_dbg(&slave->dev,
"%s control_port_stat=%x", __func__, status->control_port);
- if (status->control_port & 0x4) {
+ mutex_lock(&rt5682->disable_irq_lock);
+ if (status->control_port & 0x4 && !rt5682->disable_irq) {
mod_delayed_work(system_power_efficient_wq,
&rt5682->jack_detect_work, msecs_to_jiffies(rt5682->irq_work_delay_time));
}
+ mutex_unlock(&rt5682->disable_irq_lock);
return 0;
}
@@ -737,13 +746,41 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev)
return 0;
}
+static int __maybe_unused rt5682_dev_system_suspend(struct device *dev)
+{
+ struct rt5682_priv *rt5682 = dev_get_drvdata(dev);
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ int ret;
+
+ if (!rt5682->hw_init)
+ return 0;
+
+ /*
+ * prevent new interrupts from being handled after the
+ * deferred work completes and before the parent disables
+ * interrupts on the link
+ */
+ mutex_lock(&rt5682->disable_irq_lock);
+ rt5682->disable_irq = true;
+ ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1,
+ SDW_SCP_INT1_IMPL_DEF, 0);
+ mutex_unlock(&rt5682->disable_irq_lock);
+
+ if (ret < 0) {
+ /* log but don't prevent suspend from happening */
+ dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:", __func__);
+ }
+
+ return rt5682_dev_suspend(dev);
+}
+
static int __maybe_unused rt5682_dev_resume(struct device *dev)
{
struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt5682_priv *rt5682 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt5682->hw_init)
+ if (!rt5682->first_hw_init)
return 0;
if (!slave->unattach_request)
@@ -765,7 +802,7 @@ regmap_sync:
}
static const struct dev_pm_ops rt5682_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(rt5682_dev_system_suspend, rt5682_dev_resume)
SET_RUNTIME_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume, NULL)
};
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
index abcd6f483788..fcf442b8a732 100644
--- a/sound/soc/codecs/rt5682.c
+++ b/sound/soc/codecs/rt5682.c
@@ -2915,10 +2915,46 @@ static void rt5682_remove(struct snd_soc_component *component)
static int rt5682_suspend(struct snd_soc_component *component)
{
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
+ unsigned int val;
if (rt5682->is_sdw)
return 0;
+ cancel_delayed_work_sync(&rt5682->jack_detect_work);
+ cancel_delayed_work_sync(&rt5682->jd_check_work);
+ if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
+ snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
+ RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
+ RT5682_CTRL_MB1_REG | RT5682_CTRL_MB2_REG);
+ val = snd_soc_component_read(component,
+ RT5682_CBJ_CTRL_2) & RT5682_JACK_TYPE_MASK;
+
+ switch (val) {
+ case 0x1:
+ snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
+ RT5682_SAR_SEL_MB1_MASK | RT5682_SAR_SEL_MB2_MASK,
+ RT5682_SAR_SEL_MB1_NOSEL | RT5682_SAR_SEL_MB2_SEL);
+ break;
+ case 0x2:
+ snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
+ RT5682_SAR_SEL_MB1_MASK | RT5682_SAR_SEL_MB2_MASK,
+ RT5682_SAR_SEL_MB1_SEL | RT5682_SAR_SEL_MB2_NOSEL);
+ break;
+ default:
+ break;
+ }
+
+ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3,
+ RT5682_PWR_CBJ, 0);
+
+ /* enter SAR ADC power saving mode */
+ snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
+ RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_BUTDET_RST_MASK, 0);
+ snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
+ RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_BUTDET_RST_MASK,
+ RT5682_SAR_BUTT_DET_EN | RT5682_SAR_BUTDET_POW_SAV | RT5682_SAR_BUTDET_RST_NORMAL);
+ }
+
regcache_cache_only(rt5682->regmap, true);
regcache_mark_dirty(rt5682->regmap);
return 0;
@@ -2934,6 +2970,14 @@ static int rt5682_resume(struct snd_soc_component *component)
regcache_cache_only(rt5682->regmap, false);
regcache_sync(rt5682->regmap);
+ if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
+ snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
+ RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
+ RT5682_CTRL_MB1_FSM | RT5682_CTRL_MB2_FSM);
+ snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3,
+ RT5682_PWR_CBJ, RT5682_PWR_CBJ);
+ }
+
mod_delayed_work(system_power_efficient_wq,
&rt5682->jack_detect_work, msecs_to_jiffies(250));
diff --git a/sound/soc/codecs/rt5682.h b/sound/soc/codecs/rt5682.h
index 74ff66767016..b59221048ebf 100644
--- a/sound/soc/codecs/rt5682.h
+++ b/sound/soc/codecs/rt5682.h
@@ -1415,6 +1415,8 @@ struct rt5682_priv {
struct regulator_bulk_data supplies[RT5682_NUM_SUPPLIES];
struct delayed_work jack_detect_work;
struct delayed_work jd_check_work;
+ struct mutex disable_irq_lock; /* imp-def irq lock protection */
+ bool disable_irq;
struct mutex calibrate_mutex;
struct sdw_slave *slave;
enum sdw_slave_status status;
diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c
index ff9c081fd52a..bda594899664 100644
--- a/sound/soc/codecs/rt700-sdw.c
+++ b/sound/soc/codecs/rt700-sdw.c
@@ -418,10 +418,12 @@ static int rt700_interrupt_callback(struct sdw_slave *slave,
dev_dbg(&slave->dev,
"%s control_port_stat=%x", __func__, status->control_port);
- if (status->control_port & 0x4) {
+ mutex_lock(&rt700->disable_irq_lock);
+ if (status->control_port & 0x4 && !rt700->disable_irq) {
mod_delayed_work(system_power_efficient_wq,
&rt700->jack_detect_work, msecs_to_jiffies(250));
}
+ mutex_unlock(&rt700->disable_irq_lock);
return 0;
}
@@ -490,6 +492,34 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev)
return 0;
}
+static int __maybe_unused rt700_dev_system_suspend(struct device *dev)
+{
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ struct rt700_priv *rt700 = dev_get_drvdata(dev);
+ int ret;
+
+ if (!rt700->hw_init)
+ return 0;
+
+ /*
+ * prevent new interrupts from being handled after the
+ * deferred work completes and before the parent disables
+ * interrupts on the link
+ */
+ mutex_lock(&rt700->disable_irq_lock);
+ rt700->disable_irq = true;
+ ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1,
+ SDW_SCP_INT1_IMPL_DEF, 0);
+ mutex_unlock(&rt700->disable_irq_lock);
+
+ if (ret < 0) {
+ /* log but don't prevent suspend from happening */
+ dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:", __func__);
+ }
+
+ return rt700_dev_suspend(dev);
+}
+
#define RT700_PROBE_TIMEOUT 5000
static int __maybe_unused rt700_dev_resume(struct device *dev)
@@ -498,7 +528,7 @@ static int __maybe_unused rt700_dev_resume(struct device *dev)
struct rt700_priv *rt700 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt700->hw_init)
+ if (!rt700->first_hw_init)
return 0;
if (!slave->unattach_request)
@@ -521,7 +551,7 @@ regmap_sync:
}
static const struct dev_pm_ops rt700_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(rt700_dev_suspend, rt700_dev_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(rt700_dev_system_suspend, rt700_dev_resume)
SET_RUNTIME_PM_OPS(rt700_dev_suspend, rt700_dev_resume, NULL)
};
diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c
index 01af9d9dd3ca..921382724f9c 100644
--- a/sound/soc/codecs/rt700.c
+++ b/sound/soc/codecs/rt700.c
@@ -1112,6 +1112,8 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap,
rt700->sdw_regmap = sdw_regmap;
rt700->regmap = regmap;
+ mutex_init(&rt700->disable_irq_lock);
+
/*
* Mark hw_init to false
* HW init will be performed when device reports present
@@ -1133,6 +1135,8 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave)
{
struct rt700_priv *rt700 = dev_get_drvdata(dev);
+ rt700->disable_irq = false;
+
if (rt700->hw_init)
return 0;
diff --git a/sound/soc/codecs/rt700.h b/sound/soc/codecs/rt700.h
index 794ee2e29051..bed9d1de6d5b 100644
--- a/sound/soc/codecs/rt700.h
+++ b/sound/soc/codecs/rt700.h
@@ -23,6 +23,8 @@ struct rt700_priv {
struct delayed_work jack_detect_work;
struct delayed_work jack_btn_check_work;
int jack_type;
+ struct mutex disable_irq_lock; /* imp-def irq lock protection */
+ bool disable_irq;
};
struct sdw_stream_data {
diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
index 9685c8905468..aaf5af153d3f 100644
--- a/sound/soc/codecs/rt711-sdca-sdw.c
+++ b/sound/soc/codecs/rt711-sdca-sdw.c
@@ -75,6 +75,16 @@ static bool rt711_sdca_mbq_readable_register(struct device *dev, unsigned int re
case 0x5b00000 ... 0x5b000ff:
case 0x5f00000 ... 0x5f000ff:
case 0x6100000 ... 0x61000ff:
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_L):
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_R):
+ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_L):
+ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_R):
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_L):
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_R):
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
+ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
+ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
+ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
return true;
default:
return false;
@@ -246,6 +256,15 @@ static int rt711_sdca_interrupt_callback(struct sdw_slave *slave,
scp_sdca_stat2 = rt711->scp_sdca_stat2;
}
+ /*
+ * The critical section below intentionally protects a rather large piece of code.
+ * We don't want to allow the system suspend to disable an interrupt while we are
+ * processing it, which could be problematic given the quirky SoundWire interrupt
+ * scheme. We do want however to prevent new workqueues from being scheduled if
+ * the disable_irq flag was set during system suspend.
+ */
+ mutex_lock(&rt711->disable_irq_lock);
+
ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT1);
if (ret < 0)
goto io_error;
@@ -304,13 +323,16 @@ static int rt711_sdca_interrupt_callback(struct sdw_slave *slave,
"%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,
rt711->scp_sdca_stat1, rt711->scp_sdca_stat2);
- if (status->sdca_cascade)
+ if (status->sdca_cascade && !rt711->disable_irq)
mod_delayed_work(system_power_efficient_wq,
&rt711->jack_detect_work, msecs_to_jiffies(30));
+ mutex_unlock(&rt711->disable_irq_lock);
+
return 0;
io_error:
+ mutex_unlock(&rt711->disable_irq_lock);
pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
return ret;
}
@@ -372,6 +394,36 @@ static int __maybe_unused rt711_sdca_dev_suspend(struct device *dev)
return 0;
}
+static int __maybe_unused rt711_sdca_dev_system_suspend(struct device *dev)
+{
+ struct rt711_sdca_priv *rt711_sdca = dev_get_drvdata(dev);
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ int ret1, ret2;
+
+ if (!rt711_sdca->hw_init)
+ return 0;
+
+ /*
+ * prevent new interrupts from being handled after the
+ * deferred work completes and before the parent disables
+ * interrupts on the link
+ */
+ mutex_lock(&rt711_sdca->disable_irq_lock);
+ rt711_sdca->disable_irq = true;
+ ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1,
+ SDW_SCP_SDCA_INTMASK_SDCA_0, 0);
+ ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2,
+ SDW_SCP_SDCA_INTMASK_SDCA_8, 0);
+ mutex_unlock(&rt711_sdca->disable_irq_lock);
+
+ if (ret1 < 0 || ret2 < 0) {
+ /* log but don't prevent suspend from happening */
+ dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__);
+ }
+
+ return rt711_sdca_dev_suspend(dev);
+}
+
#define RT711_PROBE_TIMEOUT 5000
static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
@@ -380,7 +432,7 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt711->hw_init)
+ if (!rt711->first_hw_init)
return 0;
if (!slave->unattach_request)
@@ -403,7 +455,7 @@ regmap_sync:
}
static const struct dev_pm_ops rt711_sdca_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(rt711_sdca_dev_suspend, rt711_sdca_dev_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(rt711_sdca_dev_system_suspend, rt711_sdca_dev_resume)
SET_RUNTIME_PM_OPS(rt711_sdca_dev_suspend, rt711_sdca_dev_resume, NULL)
};
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
index 24a084e0b48a..2e992589f1e4 100644
--- a/sound/soc/codecs/rt711-sdca.c
+++ b/sound/soc/codecs/rt711-sdca.c
@@ -1411,6 +1411,8 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap,
rt711->regmap = regmap;
rt711->mbq_regmap = mbq_regmap;
+ mutex_init(&rt711->disable_irq_lock);
+
/*
* Mark hw_init to false
* HW init will be performed when device reports present
@@ -1494,12 +1496,16 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave)
int ret = 0;
unsigned int val;
+ rt711->disable_irq = false;
+
if (rt711->hw_init)
return 0;
if (rt711->first_hw_init) {
regcache_cache_only(rt711->regmap, false);
regcache_cache_bypass(rt711->regmap, true);
+ regcache_cache_only(rt711->mbq_regmap, false);
+ regcache_cache_bypass(rt711->mbq_regmap, true);
} else {
/*
* PM runtime is only enabled when a Slave reports as Attached
@@ -1565,6 +1571,8 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave)
if (rt711->first_hw_init) {
regcache_cache_bypass(rt711->regmap, false);
regcache_mark_dirty(rt711->regmap);
+ regcache_cache_bypass(rt711->mbq_regmap, false);
+ regcache_mark_dirty(rt711->mbq_regmap);
} else
rt711->first_hw_init = true;
diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711-sdca.h
index 43ae82b7fdb3..498ca687c47b 100644
--- a/sound/soc/codecs/rt711-sdca.h
+++ b/sound/soc/codecs/rt711-sdca.h
@@ -27,6 +27,8 @@ struct rt711_sdca_priv {
struct delayed_work jack_detect_work;
struct delayed_work jack_btn_check_work;
struct mutex calibrate_mutex; /* for headset calibration */
+ struct mutex disable_irq_lock; /* SDCA irq lock protection */
+ bool disable_irq;
int jack_type, jd_src;
unsigned int scp_sdca_stat1, scp_sdca_stat2;
int hw_ver;
diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c
index 8f5ebe92d407..bda2cc9439c9 100644
--- a/sound/soc/codecs/rt711-sdw.c
+++ b/sound/soc/codecs/rt711-sdw.c
@@ -423,10 +423,12 @@ static int rt711_interrupt_callback(struct sdw_slave *slave,
dev_dbg(&slave->dev,
"%s control_port_stat=%x", __func__, status->control_port);
- if (status->control_port & 0x4) {
+ mutex_lock(&rt711->disable_irq_lock);
+ if (status->control_port & 0x4 && !rt711->disable_irq) {
mod_delayed_work(system_power_efficient_wq,
&rt711->jack_detect_work, msecs_to_jiffies(250));
}
+ mutex_unlock(&rt711->disable_irq_lock);
return 0;
}
@@ -493,6 +495,34 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev)
return 0;
}
+static int __maybe_unused rt711_dev_system_suspend(struct device *dev)
+{
+ struct rt711_priv *rt711 = dev_get_drvdata(dev);
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ int ret;
+
+ if (!rt711->hw_init)
+ return 0;
+
+ /*
+ * prevent new interrupts from being handled after the
+ * deferred work completes and before the parent disables
+ * interrupts on the link
+ */
+ mutex_lock(&rt711->disable_irq_lock);
+ rt711->disable_irq = true;
+ ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1,
+ SDW_SCP_INT1_IMPL_DEF, 0);
+ mutex_unlock(&rt711->disable_irq_lock);
+
+ if (ret < 0) {
+ /* log but don't prevent suspend from happening */
+ dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:", __func__);
+ }
+
+ return rt711_dev_suspend(dev);
+}
+
#define RT711_PROBE_TIMEOUT 5000
static int __maybe_unused rt711_dev_resume(struct device *dev)
@@ -501,7 +531,7 @@ static int __maybe_unused rt711_dev_resume(struct device *dev)
struct rt711_priv *rt711 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt711->hw_init)
+ if (!rt711->first_hw_init)
return 0;
if (!slave->unattach_request)
@@ -524,7 +554,7 @@ regmap_sync:
}
static const struct dev_pm_ops rt711_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(rt711_dev_suspend, rt711_dev_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(rt711_dev_system_suspend, rt711_dev_resume)
SET_RUNTIME_PM_OPS(rt711_dev_suspend, rt711_dev_resume, NULL)
};
diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c
index abaf150cc087..a7c5608a0ef8 100644
--- a/sound/soc/codecs/rt711.c
+++ b/sound/soc/codecs/rt711.c
@@ -1196,6 +1196,8 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap,
rt711->sdw_regmap = sdw_regmap;
rt711->regmap = regmap;
+ mutex_init(&rt711->disable_irq_lock);
+
/*
* Mark hw_init to false
* HW init will be performed when device reports present
@@ -1220,6 +1222,8 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave)
{
struct rt711_priv *rt711 = dev_get_drvdata(dev);
+ rt711->disable_irq = false;
+
if (rt711->hw_init)
return 0;
diff --git a/sound/soc/codecs/rt711.h b/sound/soc/codecs/rt711.h
index 5f2ba1341085..f50f8c8d0934 100644
--- a/sound/soc/codecs/rt711.h
+++ b/sound/soc/codecs/rt711.h
@@ -25,6 +25,8 @@ struct rt711_priv {
struct work_struct calibration_work;
struct mutex calibrate_mutex; /* for headset calibration */
int jack_type, jd_src;
+ struct mutex disable_irq_lock; /* imp-def irq lock protection */
+ bool disable_irq;
};
struct sdw_stream_data {
diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c
index 1350798406f0..a5c673f43d82 100644
--- a/sound/soc/codecs/rt715-sdca-sdw.c
+++ b/sound/soc/codecs/rt715-sdca-sdw.c
@@ -70,6 +70,7 @@ static bool rt715_sdca_mbq_readable_register(struct device *dev, unsigned int re
case 0x2000036:
case 0x2000037:
case 0x2000039:
+ case 0x2000044:
case 0x6100000:
return true;
default:
@@ -224,7 +225,7 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt715->hw_init)
+ if (!rt715->first_hw_init)
return 0;
if (!slave->unattach_request)
diff --git a/sound/soc/codecs/rt715-sdca-sdw.h b/sound/soc/codecs/rt715-sdca-sdw.h
index cd365bb60747..0cbc14844f8c 100644
--- a/sound/soc/codecs/rt715-sdca-sdw.h
+++ b/sound/soc/codecs/rt715-sdca-sdw.h
@@ -113,6 +113,7 @@ static const struct reg_default rt715_mbq_reg_defaults_sdca[] = {
{ 0x2000036, 0x0000 },
{ 0x2000037, 0x0000 },
{ 0x2000039, 0xaa81 },
+ { 0x2000044, 0x0202 },
{ 0x6100000, 0x0100 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 },
diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
index 7db76c19e048..66e166568c50 100644
--- a/sound/soc/codecs/rt715-sdca.c
+++ b/sound/soc/codecs/rt715-sdca.c
@@ -997,7 +997,7 @@ int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,
* HW init will be performed when device reports present
*/
rt715->hw_init = false;
- rt715->first_init = false;
+ rt715->first_hw_init = false;
ret = devm_snd_soc_register_component(dev,
&soc_codec_dev_rt715_sdca,
@@ -1018,7 +1018,7 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
/*
* PM runtime is only enabled when a Slave reports as Attached
*/
- if (!rt715->first_init) {
+ if (!rt715->first_hw_init) {
/* set autosuspend parameters */
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
pm_runtime_use_autosuspend(&slave->dev);
@@ -1031,7 +1031,7 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
pm_runtime_enable(&slave->dev);
- rt715->first_init = true;
+ rt715->first_hw_init = true;
}
pm_runtime_get_noresume(&slave->dev);
@@ -1054,6 +1054,9 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
RT715_REV_1, 0x40, 0x40);
}
+ /* DFLL Calibration trigger */
+ rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
+ RT715_DFLL_VAD, 0x1, 0x1);
/* trigger mode = VAD enable */
regmap_write(rt715->regmap,
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h
index 85ce4d95e5eb..90881b455ece 100644
--- a/sound/soc/codecs/rt715-sdca.h
+++ b/sound/soc/codecs/rt715-sdca.h
@@ -27,7 +27,7 @@ struct rt715_sdca_priv {
enum sdw_slave_status status;
struct sdw_bus_params params;
bool hw_init;
- bool first_init;
+ bool first_hw_init;
int l_is_unmute;
int r_is_unmute;
int hw_sdw_ver;
@@ -81,6 +81,7 @@ struct rt715_sdca_kcontrol_private {
#define RT715_AD_FUNC_EN 0x36
#define RT715_REV_1 0x37
#define RT715_SDW_INPUT_SEL 0x39
+#define RT715_DFLL_VAD 0x44
#define RT715_EXT_DMIC_CLK_CTRL2 0x54
/* Index (NID:61h) */
diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c
index 81a1dd77b6f6..a7b21b03c08b 100644
--- a/sound/soc/codecs/rt715-sdw.c
+++ b/sound/soc/codecs/rt715-sdw.c
@@ -541,7 +541,7 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
struct rt715_priv *rt715 = dev_get_drvdata(dev);
unsigned long time;
- if (!rt715->hw_init)
+ if (!rt715->first_hw_init)
return 0;
if (!slave->unattach_request)
diff --git a/sound/soc/codecs/sdw-mockup.c b/sound/soc/codecs/sdw-mockup.c
new file mode 100644
index 000000000000..a4f79eb2c69d
--- /dev/null
+++ b/sound/soc/codecs/sdw-mockup.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// sdw-mockup.c -- a mockup SoundWire codec for tests where only the host
+// drives the bus.
+//
+// Copyright(c) 2021 Intel Corporation
+//
+//
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <linux/soundwire/sdw_registers.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+struct sdw_mockup_priv {
+ struct sdw_slave *slave;
+};
+
+struct sdw_stream_data {
+ struct sdw_stream_runtime *sdw_stream;
+};
+
+static int sdw_mockup_component_probe(struct snd_soc_component *component)
+{
+ return 0;
+}
+
+static void sdw_mockup_component_remove(struct snd_soc_component *component)
+{
+}
+
+static const struct snd_soc_component_driver snd_soc_sdw_mockup_component = {
+ .probe = sdw_mockup_component_probe,
+ .remove = sdw_mockup_component_remove,
+};
+
+static int sdw_mockup_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
+ int direction)
+{
+ struct sdw_stream_data *stream;
+
+ if (!sdw_stream)
+ return 0;
+
+ stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+ if (!stream)
+ return -ENOMEM;
+
+ stream->sdw_stream = sdw_stream;
+
+ /* Use tx_mask or rx_mask to configure stream tag and set dma_data */
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ dai->playback_dma_data = stream;
+ else
+ dai->capture_dma_data = stream;
+
+ return 0;
+}
+
+static void sdw_mockup_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct sdw_stream_data *stream;
+
+ stream = snd_soc_dai_get_dma_data(dai, substream);
+ snd_soc_dai_set_dma_data(dai, substream, NULL);
+ kfree(stream);
+}
+
+static int sdw_mockup_pcm_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 sdw_mockup_priv *sdw_mockup = snd_soc_component_get_drvdata(component);
+ struct sdw_stream_config stream_config;
+ struct sdw_port_config port_config;
+ enum sdw_data_direction direction;
+ struct sdw_stream_data *stream;
+ int num_channels;
+ int port;
+ int ret;
+
+ stream = snd_soc_dai_get_dma_data(dai, substream);
+ if (!stream)
+ return -EINVAL;
+
+ if (!sdw_mockup->slave)
+ return -EINVAL;
+
+ /* SoundWire specific configuration */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ direction = SDW_DATA_DIR_RX;
+ port = 1;
+ } else {
+ direction = SDW_DATA_DIR_TX;
+ port = 8;
+ }
+
+ stream_config.frame_rate = params_rate(params);
+ stream_config.ch_count = params_channels(params);
+ stream_config.bps = snd_pcm_format_width(params_format(params));
+ stream_config.direction = direction;
+
+ num_channels = params_channels(params);
+ port_config.ch_mask = (1 << num_channels) - 1;
+ port_config.num = port;
+
+ ret = sdw_stream_add_slave(sdw_mockup->slave, &stream_config,
+ &port_config, 1, stream->sdw_stream);
+ if (ret)
+ dev_err(dai->dev, "Unable to configure port\n");
+
+ return ret;
+}
+
+static int sdw_mockup_pcm_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+ struct sdw_mockup_priv *sdw_mockup = snd_soc_component_get_drvdata(component);
+ struct sdw_stream_data *stream =
+ snd_soc_dai_get_dma_data(dai, substream);
+
+ if (!sdw_mockup->slave)
+ return -EINVAL;
+
+ sdw_stream_remove_slave(sdw_mockup->slave, stream->sdw_stream);
+ return 0;
+}
+
+static const struct snd_soc_dai_ops sdw_mockup_ops = {
+ .hw_params = sdw_mockup_pcm_hw_params,
+ .hw_free = sdw_mockup_pcm_hw_free,
+ .set_sdw_stream = sdw_mockup_set_sdw_stream,
+ .shutdown = sdw_mockup_shutdown,
+};
+
+static struct snd_soc_dai_driver sdw_mockup_dai[] = {
+ {
+ .name = "sdw-mockup-aif1",
+ .id = 1,
+ .playback = {
+ .stream_name = "DP1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .capture = {
+ .stream_name = "DP8 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &sdw_mockup_ops,
+ },
+};
+
+static int sdw_mockup_update_status(struct sdw_slave *slave,
+ enum sdw_slave_status status)
+{
+ return 0;
+}
+
+static int sdw_mockup_read_prop(struct sdw_slave *slave)
+{
+ struct sdw_slave_prop *prop = &slave->prop;
+ int nval;
+ int i, j;
+ u32 bit;
+ unsigned long addr;
+ struct sdw_dpn_prop *dpn;
+
+ prop->paging_support = false;
+
+ /*
+ * first we need to allocate memory for set bits in port lists
+ * the port allocation is completely arbitrary:
+ * DP0 is not supported
+ * DP1 is sink
+ * DP8 is source
+ */
+ prop->source_ports = BIT(8);
+ prop->sink_ports = BIT(1);
+
+ 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 = true;
+ 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 = true;
+ j++;
+ }
+
+ prop->simple_clk_stop_capable = true;
+
+ /* wake-up event */
+ prop->wake_capable = 0;
+
+ return 0;
+}
+
+static int sdw_mockup_bus_config(struct sdw_slave *slave,
+ struct sdw_bus_params *params)
+{
+ return 0;
+}
+
+static int sdw_mockup_interrupt_callback(struct sdw_slave *slave,
+ struct sdw_slave_intr_status *status)
+{
+ return 0;
+}
+
+static const struct sdw_slave_ops sdw_mockup_slave_ops = {
+ .read_prop = sdw_mockup_read_prop,
+ .interrupt_callback = sdw_mockup_interrupt_callback,
+ .update_status = sdw_mockup_update_status,
+ .bus_config = sdw_mockup_bus_config,
+};
+
+static int sdw_mockup_sdw_probe(struct sdw_slave *slave,
+ const struct sdw_device_id *id)
+{
+ struct device *dev = &slave->dev;
+ struct sdw_mockup_priv *sdw_mockup;
+ int ret;
+
+ sdw_mockup = devm_kzalloc(dev, sizeof(*sdw_mockup), GFP_KERNEL);
+ if (!sdw_mockup)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, sdw_mockup);
+ sdw_mockup->slave = slave;
+
+ ret = devm_snd_soc_register_component(dev,
+ &snd_soc_sdw_mockup_component,
+ sdw_mockup_dai,
+ ARRAY_SIZE(sdw_mockup_dai));
+
+ return ret;
+}
+
+static int sdw_mockup_sdw_remove(struct sdw_slave *slave)
+{
+ return 0;
+}
+
+/*
+ * Intel reserved parts ID with the following mapping expected:
+ * 0xAAAA: generic full-duplex codec
+ * 0xAA55: headset codec (mock-up of RT711/RT5682) - full-duplex
+ * 0x55AA: amplifier (mock-up of RT1308/Maxim 98373) - playback only with
+ * IV feedback
+ * 0x5555: mic codec (mock-up of RT715) - capture-only
+ */
+static const struct sdw_device_id sdw_mockup_id[] = {
+ SDW_SLAVE_ENTRY_EXT(0x0105, 0xAAAA, 0x0, 0, 0),
+ SDW_SLAVE_ENTRY_EXT(0x0105, 0xAA55, 0x0, 0, 0),
+ SDW_SLAVE_ENTRY_EXT(0x0105, 0x55AA, 0x0, 0, 0),
+ SDW_SLAVE_ENTRY_EXT(0x0105, 0x5555, 0x0, 0, 0),
+ {},
+};
+MODULE_DEVICE_TABLE(sdw, sdw_mockup_id);
+
+static struct sdw_driver sdw_mockup_sdw_driver = {
+ .driver = {
+ .name = "sdw-mockup",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdw_mockup_sdw_probe,
+ .remove = sdw_mockup_sdw_remove,
+ .ops = &sdw_mockup_slave_ops,
+ .id_table = sdw_mockup_id,
+};
+module_sdw_driver(sdw_mockup_sdw_driver);
+
+MODULE_DESCRIPTION("ASoC SDW mockup codec driver");
+MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 2e9175b37dc9..d39c7d52ecfd 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -714,7 +714,7 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
unsigned long adc_clock_rate, dac_clock_rate;
int ret;
- struct clk_bulk_data clocks[] = {
+ static struct clk_bulk_data clocks[] = {
{ .id = "pll" },
{ .id = "nadc" },
{ .id = "madc" },
@@ -878,7 +878,7 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
{
int ret;
- struct clk_bulk_data clocks[] = {
+ static struct clk_bulk_data clocks[] = {
{ .id = "madc" },
{ .id = "mdac" },
{ .id = "bdiv" },
@@ -994,7 +994,7 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
u32 tmp_reg;
int ret;
- struct clk_bulk_data clocks[] = {
+ static struct clk_bulk_data clocks[] = {
{ .id = "codec_clkin" },
{ .id = "pll" },
{ .id = "bdiv" },
@@ -1131,7 +1131,7 @@ static struct snd_soc_dai_driver aic32x4_tas2505_dai = {
.playback = {
.stream_name = "Playback",
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = AIC32X4_FORMATS,},
.ops = &aic32x4_ops,
@@ -1144,7 +1144,7 @@ static int aic32x4_tas2505_component_probe(struct snd_soc_component *component)
u32 tmp_reg;
int ret;
- struct clk_bulk_data clocks[] = {
+ static struct clk_bulk_data clocks[] = {
{ .id = "codec_clkin" },
{ .id = "pll" },
{ .id = "bdiv" },
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index 2fcc97370be2..f0daf8defcf1 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -21,6 +21,7 @@
#include <linux/regulator/consumer.h>
#include "wcd-clsh-v2.h"
+#include "wcd-mbhc-v2.h"
#include "wcd938x.h"
#define WCD938X_MAX_MICBIAS (4)
@@ -173,6 +174,11 @@ struct wcd938x_priv {
struct device *rxdev;
struct device_node *rxnode, *txnode;
struct regmap *regmap;
+ struct mutex micb_lock;
+ /* mbhc module */
+ struct wcd_mbhc *wcd_mbhc;
+ struct wcd_mbhc_config mbhc_cfg;
+ struct wcd_mbhc_intr intr_ids;
struct wcd_clsh_ctrl *clsh_info;
struct irq_domain *virq;
struct regmap_irq_chip *wcd_regmap_irq_chip;
@@ -201,24 +207,70 @@ struct wcd938x_priv {
bool bcs_dis;
};
-enum {
- MIC_BIAS_1 = 1,
- MIC_BIAS_2,
- MIC_BIAS_3,
- MIC_BIAS_4
-};
-
-enum {
- MICB_PULLUP_ENABLE,
- MICB_PULLUP_DISABLE,
- MICB_ENABLE,
- MICB_DISABLE,
-};
-
static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(line_gain, 600, -3000);
static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);
+struct wcd938x_mbhc_zdet_param {
+ u16 ldo_ctl;
+ u16 noff;
+ u16 nshift;
+ u16 btn5;
+ u16 btn6;
+ u16 btn7;
+};
+
+static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
+ WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD938X_ANA_MBHC_MECH, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD938X_ANA_MBHC_MECH, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD938X_ANA_MBHC_MECH, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x30),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD938X_ANA_MBHC_ELECT, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD938X_ANA_MBHC_MECH, 0x04),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD938X_ANA_MBHC_MECH, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD938X_ANA_MBHC_ELECT, 0x06),
+ WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD938X_ANA_MBHC_ELECT, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD938X_MBHC_NEW_CTL_1, 0x03),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD938X_MBHC_NEW_CTL_2, 0x03),
+ WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD938X_HPH_OCP_CTL, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x07),
+ WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD938X_ANA_MBHC_ELECT, 0x70),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0xFF),
+ WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD938X_ANA_MICB2, 0xC0),
+ WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD938X_HPH_CNP_WG_TIME, 0xFF),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD938X_ANA_HPH, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD938X_ANA_HPH, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD938X_ANA_HPH, 0xC0),
+ WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD938X_MBHC_CTL_BCS, 0x02),
+ WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD938X_MBHC_NEW_CTL_2, 0x70),
+ WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD938X_HPH_PA_CTL2, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD938X_HPH_PA_CTL2, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD938X_HPH_L_TEST, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD938X_HPH_R_TEST, 0x01),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x20),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD938X_MBHC_NEW_CTL_1, 0x08),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD938X_MBHC_NEW_FSM_STATUS, 0x40),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD938X_MBHC_NEW_FSM_STATUS, 0x80),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD938X_MBHC_NEW_ADC_RESULT, 0xFF),
+ WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD938X_ANA_MICB2, 0x3F),
+ WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD938X_MBHC_NEW_CTL_1, 0x10),
+ WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD938X_MBHC_NEW_CTL_1, 0x04),
+ WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD938X_ANA_MBHC_ZDET, 0x02),
+};
+
static const struct reg_default wcd938x_defaults[] = {
{WCD938X_ANA_PAGE_REGISTER, 0x00},
{WCD938X_ANA_BIAS, 0x00},
@@ -1360,7 +1412,6 @@ static int wcd938x_io_init(struct wcd938x_priv *wcd938x)
static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
struct sdw_port_config *port_config,
- u32 mstr_port_num,
u8 enable)
{
u8 ch_mask, port_num;
@@ -1380,14 +1431,12 @@ static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 ch_id, u8 enable)
{
- u8 port_num, mstr_port_num;
+ u8 port_num;
port_num = wcd->ch_info[ch_id].port_num;
- mstr_port_num = wcd->port_map[port_num - 1];
return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id],
&wcd->port_config[port_num],
- mstr_port_num,
enable);
}
@@ -1623,7 +1672,6 @@ static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
- int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1651,7 +1699,7 @@ static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 0);
break;
}
- return ret;
+ return 0;
}
@@ -1728,6 +1776,8 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
snd_soc_component_write_field(component, WCD938X_ANA_HPH,
WCD938X_HPHR_EN_MASK, 0);
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_PRE_HPHR_PA_OFF);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -1743,6 +1793,8 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
}
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_HPHR_PA_OFF);
snd_soc_component_write_field(component, WCD938X_ANA_HPH,
WCD938X_HPHR_REF_EN_MASK, 0);
snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL1,
@@ -1830,6 +1882,7 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
snd_soc_component_write_field(component, WCD938X_ANA_HPH,
WCD938X_HPHL_EN_MASK, 0);
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -1845,6 +1898,8 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
}
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_HPHL_PA_OFF);
snd_soc_component_write_field(component, WCD938X_ANA_HPH,
WCD938X_HPHL_REF_EN_MASK, 0);
snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
@@ -1866,7 +1921,6 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int hph_mode = wcd938x->hph_mode;
- int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1902,7 +1956,7 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
WCD938X_EN_CUR_DET_MASK, 1);
break;
}
- return ret;
+ return 0;
}
static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
@@ -2355,7 +2409,14 @@ static int wcd938x_micbias_control(struct snd_soc_component *component,
snd_soc_component_write_field(component, micb_reg,
WCD938X_MICB_EN_MASK,
WCD938X_MICB_ENABLE);
+ if (micb_num == MIC_BIAS_2)
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_MICBIAS_2_ON);
}
+ if (micb_num == MIC_BIAS_2 && is_dapm)
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_DAPM_MICBIAS_2_ON);
+
break;
case MICB_DISABLE:
@@ -2369,10 +2430,19 @@ static int wcd938x_micbias_control(struct snd_soc_component *component,
WCD938X_MICB_PULL_UP);
else if ((wcd938x->micb_ref[micb_index] == 0) &&
(wcd938x->pullup_ref[micb_index] == 0)) {
+ if (micb_num == MIC_BIAS_2)
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_PRE_MICBIAS_2_OFF);
snd_soc_component_write_field(component, micb_reg,
WCD938X_MICB_EN_MASK, 0);
+ if (micb_num == MIC_BIAS_2)
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_MICBIAS_2_OFF);
}
+ if (is_dapm && micb_num == MIC_BIAS_2)
+ wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
+ WCD_EVENT_POST_DAPM_MICBIAS_2_OFF);
break;
}
@@ -2845,6 +2915,704 @@ static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
}
+/* MBHC related */
+static void wcd938x_mbhc_clk_setup(struct snd_soc_component *component,
+ bool enable)
+{
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_1,
+ WCD938X_MBHC_CTL_RCO_EN_MASK, enable);
+}
+
+static void wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component *component,
+ bool enable)
+{
+ snd_soc_component_write_field(component, WCD938X_ANA_MBHC_ELECT,
+ WCD938X_ANA_MBHC_BIAS_EN, enable);
+}
+
+static void wcd938x_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, WCD938X_ANA_MBHC_BTN0 + i,
+ WCD938X_MBHC_BTN_VTH_MASK, vth);
+ dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n",
+ __func__, i, btn_high[i], vth);
+ }
+}
+
+static bool wcd938x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
+{
+ u8 val;
+
+ if (micb_num == MIC_BIAS_2) {
+ val = snd_soc_component_read_field(component,
+ WCD938X_ANA_MICB2,
+ WCD938X_ANA_MICB2_ENABLE_MASK);
+ if (val == WCD938X_MICB_ENABLE)
+ return true;
+ }
+ return false;
+}
+
+static void wcd938x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component,
+ int pull_up_cur)
+{
+ /* Default pull up current to 2uA */
+ if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA)
+ pull_up_cur = HS_PULLUP_I_2P0_UA;
+
+ snd_soc_component_write_field(component,
+ WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT,
+ WCD938X_HSDET_PULLUP_C_MASK, pull_up_cur);
+}
+
+static int wcd938x_mbhc_request_micbias(struct snd_soc_component *component,
+ int micb_num, int req)
+{
+ return wcd938x_micbias_control(component, micb_num, req, false);
+}
+
+static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
+ bool enable)
+{
+ if (enable) {
+ snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
+ WCD938X_RAMP_SHIFT_CTRL_MASK, 0x0C);
+ snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
+ WCD938X_RAMP_EN_MASK, 1);
+ } else {
+ snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
+ WCD938X_RAMP_EN_MASK, 0);
+ snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
+ WCD938X_RAMP_SHIFT_CTRL_MASK, 0);
+ }
+}
+
+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)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
+
+ switch (micb_num) {
+ case MIC_BIAS_1:
+ micb_reg = WCD938X_ANA_MICB1;
+ break;
+ case MIC_BIAS_2:
+ micb_reg = WCD938X_ANA_MICB2;
+ break;
+ case MIC_BIAS_3:
+ micb_reg = WCD938X_ANA_MICB3;
+ break;
+ case MIC_BIAS_4:
+ micb_reg = WCD938X_ANA_MICB4;
+ break;
+ default:
+ return -EINVAL;
+ }
+ mutex_lock(&wcd938x->micb_lock);
+ /*
+ * If requested micbias voltage is same as current micbias
+ * voltage, then just return. Otherwise, adjust voltage as
+ * per requested value. If micbias is already enabled, then
+ * to avoid slow micbias ramp-up or down enable pull-up
+ * momentarily, change the micbias value and then re-enable
+ * micbias.
+ */
+ micb_en = snd_soc_component_read_field(component, micb_reg,
+ WCD938X_MICB_EN_MASK);
+ 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);
+ if (req_vout_ctl < 0) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (cur_vout_ctl == req_vout_ctl) {
+ ret = 0;
+ goto exit;
+ }
+
+ if (micb_en == WCD938X_MICB_ENABLE)
+ snd_soc_component_write_field(component, micb_reg,
+ WCD938X_MICB_EN_MASK,
+ WCD938X_MICB_PULL_UP);
+
+ snd_soc_component_write_field(component, micb_reg,
+ WCD938X_MICB_VOUT_MASK,
+ req_vout_ctl);
+
+ if (micb_en == WCD938X_MICB_ENABLE) {
+ snd_soc_component_write_field(component, micb_reg,
+ WCD938X_MICB_EN_MASK,
+ WCD938X_MICB_ENABLE);
+ /*
+ * Add 2ms delay as per HW requirement after enabling
+ * micbias
+ */
+ usleep_range(2000, 2100);
+ }
+exit:
+ mutex_unlock(&wcd938x->micb_lock);
+ return ret;
+}
+
+static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
+ int micb_num, bool req_en)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ int rc, micb_mv;
+
+ if (micb_num != MIC_BIAS_2)
+ return -EINVAL;
+ /*
+ * If device tree micbias level is already above the minimum
+ * voltage needed to detect threshold microphone, then do
+ * not change the micbias, just return.
+ */
+ if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ return 0;
+
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
+
+ rc = wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
+
+ return rc;
+}
+
+static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x,
+ s16 *d1_a, u16 noff,
+ int32_t *zdet)
+{
+ int i;
+ int val, val1;
+ s16 c1;
+ s32 x1, d1;
+ int32_t denom;
+ int minCode_param[] = {
+ 3277, 1639, 820, 410, 205, 103, 52, 26
+ };
+
+ regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20);
+ for (i = 0; i < WCD938X_ZDET_NUM_MEASUREMENTS; i++) {
+ regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val);
+ if (val & 0x80)
+ break;
+ }
+ val = val << 0x8;
+ regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1);
+ val |= val1;
+ regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00);
+ x1 = WCD938X_MBHC_GET_X1(val);
+ c1 = WCD938X_MBHC_GET_C1(val);
+ /* If ramp is not complete, give additional 5ms */
+ if ((c1 < 2) && x1)
+ usleep_range(5000, 5050);
+
+ if (!c1 || !x1) {
+ pr_err("%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
+ __func__, c1, x1);
+ goto ramp_down;
+ }
+ d1 = d1_a[c1];
+ denom = (x1 * d1) - (1 << (14 - noff));
+ if (denom > 0)
+ *zdet = (WCD938X_MBHC_ZDET_CONST * 1000) / denom;
+ else if (x1 < minCode_param[noff])
+ *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE;
+
+ pr_err("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
+ __func__, d1, c1, x1, *zdet);
+ramp_down:
+ i = 0;
+ while (x1) {
+ regmap_read(wcd938x->regmap,
+ WCD938X_ANA_MBHC_RESULT_1, &val);
+ regmap_read(wcd938x->regmap,
+ WCD938X_ANA_MBHC_RESULT_2, &val1);
+ val = val << 0x08;
+ val |= val1;
+ x1 = WCD938X_MBHC_GET_X1(val);
+ i++;
+ if (i == WCD938X_ZDET_NUM_MEASUREMENTS)
+ break;
+ }
+}
+
+static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component,
+ struct wcd938x_mbhc_zdet_param *zdet_param,
+ int32_t *zl, int32_t *zr, s16 *d1_a)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ int32_t zdet = 0;
+
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
+ WCD938X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
+ snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN5,
+ WCD938X_VTH_MASK, zdet_param->btn5);
+ snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN6,
+ WCD938X_VTH_MASK, zdet_param->btn6);
+ snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN7,
+ WCD938X_VTH_MASK, zdet_param->btn7);
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
+ WCD938X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
+ snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_RAMP_CTL,
+ 0x0F, zdet_param->nshift);
+
+ if (!zl)
+ goto z_right;
+ /* Start impedance measurement for HPH_L */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ZDET, 0x80, 0x80);
+ dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n",
+ __func__, zdet_param->noff);
+ wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ZDET, 0x80, 0x00);
+
+ *zl = zdet;
+
+z_right:
+ if (!zr)
+ return;
+ /* Start impedance measurement for HPH_R */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ZDET, 0x40, 0x40);
+ dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n",
+ __func__, zdet_param->noff);
+ wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ZDET, 0x40, 0x00);
+
+ *zr = zdet;
+}
+
+static inline void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
+ int32_t *z_val, int flag_l_r)
+{
+ s16 q1;
+ int q1_cal;
+
+ if (*z_val < (WCD938X_ZDET_VAL_400/1000))
+ q1 = snd_soc_component_read(component,
+ WCD938X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
+ else
+ q1 = snd_soc_component_read(component,
+ WCD938X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
+ if (q1 & 0x80)
+ q1_cal = (10000 - ((q1 & 0x7F) * 25));
+ else
+ q1_cal = (10000 + (q1 * 25));
+ if (q1_cal > 0)
+ *z_val = ((*z_val) * 10000) / q1_cal;
+}
+
+static void wcd938x_wcd_mbhc_calc_impedance(struct snd_soc_component *component,
+ uint32_t *zl, uint32_t *zr)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ s16 reg0, reg1, reg2, reg3, reg4;
+ int32_t z1L, z1R, z1Ls;
+ int zMono, z_diff1, z_diff2;
+ bool is_fsm_disable = false;
+ struct wcd938x_mbhc_zdet_param zdet_param[] = {
+ {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
+ {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
+ {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
+ {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
+ };
+ struct wcd938x_mbhc_zdet_param *zdet_param_ptr = NULL;
+ s16 d1_a[][4] = {
+ {0, 30, 90, 30},
+ {0, 30, 30, 5},
+ {0, 30, 30, 5},
+ {0, 30, 30, 5},
+ };
+ s16 *d1 = NULL;
+
+ reg0 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN5);
+ reg1 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN6);
+ reg2 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN7);
+ reg3 = snd_soc_component_read(component, WCD938X_MBHC_CTL_CLK);
+ reg4 = snd_soc_component_read(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL);
+
+ if (snd_soc_component_read(component, WCD938X_ANA_MBHC_ELECT) & 0x80) {
+ is_fsm_disable = true;
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ELECT, 0x80, 0x00);
+ }
+
+ /* For NO-jack, disable L_DET_EN before Z-det measurements */
+ if (wcd938x->mbhc_cfg.hphl_swh)
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_MECH, 0x80, 0x00);
+
+ /* Turn off 100k pull down on HPHL */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_MECH, 0x01, 0x00);
+
+ /* Disable surge protection before impedance detection.
+ * This is done to give correct value for high impedance.
+ */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
+ /* 1ms delay needed after disable surge protection */
+ usleep_range(1000, 1010);
+
+ /* First get impedance on Left */
+ d1 = d1_a[1];
+ zdet_param_ptr = &zdet_param[1];
+ wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
+
+ if (!WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
+ goto left_ch_impedance;
+
+ /* Second ramp for left ch */
+ if (z1L < WCD938X_ZDET_VAL_32) {
+ zdet_param_ptr = &zdet_param[0];
+ d1 = d1_a[0];
+ } else if ((z1L > WCD938X_ZDET_VAL_400) &&
+ (z1L <= WCD938X_ZDET_VAL_1200)) {
+ zdet_param_ptr = &zdet_param[2];
+ d1 = d1_a[2];
+ } else if (z1L > WCD938X_ZDET_VAL_1200) {
+ zdet_param_ptr = &zdet_param[3];
+ d1 = d1_a[3];
+ }
+ wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
+
+left_ch_impedance:
+ if ((z1L == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
+ (z1L > WCD938X_ZDET_VAL_100K)) {
+ *zl = WCD938X_ZDET_FLOATING_IMPEDANCE;
+ zdet_param_ptr = &zdet_param[1];
+ d1 = d1_a[1];
+ } else {
+ *zl = z1L/1000;
+ wcd938x_wcd_mbhc_qfuse_cal(component, zl, 0);
+ }
+ dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
+ __func__, *zl);
+
+ /* Start of right impedance ramp and calculation */
+ wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
+ if (WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
+ if (((z1R > WCD938X_ZDET_VAL_1200) &&
+ (zdet_param_ptr->noff == 0x6)) ||
+ ((*zl) != WCD938X_ZDET_FLOATING_IMPEDANCE))
+ goto right_ch_impedance;
+ /* Second ramp for right ch */
+ if (z1R < WCD938X_ZDET_VAL_32) {
+ zdet_param_ptr = &zdet_param[0];
+ d1 = d1_a[0];
+ } else if ((z1R > WCD938X_ZDET_VAL_400) &&
+ (z1R <= WCD938X_ZDET_VAL_1200)) {
+ zdet_param_ptr = &zdet_param[2];
+ d1 = d1_a[2];
+ } else if (z1R > WCD938X_ZDET_VAL_1200) {
+ zdet_param_ptr = &zdet_param[3];
+ d1 = d1_a[3];
+ }
+ wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
+ }
+right_ch_impedance:
+ if ((z1R == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
+ (z1R > WCD938X_ZDET_VAL_100K)) {
+ *zr = WCD938X_ZDET_FLOATING_IMPEDANCE;
+ } else {
+ *zr = z1R/1000;
+ wcd938x_wcd_mbhc_qfuse_cal(component, zr, 1);
+ }
+ dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
+ __func__, *zr);
+
+ /* Mono/stereo detection */
+ if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) &&
+ (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE)) {
+ dev_dbg(component->dev,
+ "%s: plug type is invalid or extension cable\n",
+ __func__);
+ goto zdet_complete;
+ }
+ if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
+ (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
+ ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
+ ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
+ dev_dbg(component->dev,
+ "%s: Mono plug type with one ch floating or shorted to GND\n",
+ __func__);
+ wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
+ goto zdet_complete;
+ }
+ snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
+ WCD938X_HPHPA_GND_OVR_MASK, 1);
+ snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
+ WCD938X_HPHPA_GND_R_MASK, 1);
+ if (*zl < (WCD938X_ZDET_VAL_32/1000))
+ wcd938x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1);
+ else
+ wcd938x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1);
+ snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
+ WCD938X_HPHPA_GND_R_MASK, 0);
+ snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
+ WCD938X_HPHPA_GND_OVR_MASK, 0);
+ z1Ls /= 1000;
+ wcd938x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
+ /* Parallel of left Z and 9 ohm pull down resistor */
+ zMono = ((*zl) * 9) / ((*zl) + 9);
+ z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
+ z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
+ if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
+ dev_dbg(component->dev, "%s: stereo plug type detected\n",
+ __func__);
+ wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_STEREO);
+ } else {
+ dev_dbg(component->dev, "%s: MONO plug type detected\n",
+ __func__);
+ wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
+ }
+
+ /* Enable surge protection again after impedance detection */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
+zdet_complete:
+ snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0);
+ snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1);
+ snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN7, reg2);
+ /* Turn on 100k pull down on HPHL */
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_MECH, 0x01, 0x01);
+
+ /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
+ if (wcd938x->mbhc_cfg.hphl_swh)
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_MECH, 0x80, 0x80);
+
+ snd_soc_component_write(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, reg4);
+ snd_soc_component_write(component, WCD938X_MBHC_CTL_CLK, reg3);
+ if (is_fsm_disable)
+ regmap_update_bits(wcd938x->regmap,
+ WCD938X_ANA_MBHC_ELECT, 0x80, 0x80);
+}
+
+static void wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
+ bool enable)
+{
+ if (enable) {
+ snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
+ WCD938X_MBHC_HSG_PULLUP_COMP_EN, 1);
+ snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
+ WCD938X_MBHC_GND_DET_EN_MASK, 1);
+ } else {
+ snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
+ WCD938X_MBHC_GND_DET_EN_MASK, 0);
+ snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
+ WCD938X_MBHC_HSG_PULLUP_COMP_EN, 0);
+ }
+}
+
+static void wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
+ bool enable)
+{
+ snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
+ WCD938X_HPHPA_GND_R_MASK, enable);
+ snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
+ WCD938X_HPHPA_GND_L_MASK, enable);
+}
+
+static void wcd938x_mbhc_moisture_config(struct snd_soc_component *component)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+
+ if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, R_OFF);
+ return;
+ }
+
+ /* Do not enable moisture detection if jack type is NC */
+ if (!wcd938x->mbhc_cfg.hphl_swh) {
+ dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
+ __func__);
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, R_OFF);
+ return;
+ }
+
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
+}
+
+static void wcd938x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+
+ if (enable)
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
+ else
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, R_OFF);
+}
+
+static bool wcd938x_mbhc_get_moisture_status(struct snd_soc_component *component)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ bool ret = false;
+
+ if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, R_OFF);
+ goto done;
+ }
+
+ /* Do not enable moisture detection if jack type is NC */
+ if (!wcd938x->mbhc_cfg.hphl_swh) {
+ dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
+ __func__);
+ snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
+ WCD938X_M_RTH_CTL_MASK, R_OFF);
+ goto done;
+ }
+
+ /*
+ * If moisture_en is already enabled, then skip to plug type
+ * detection.
+ */
+ if (snd_soc_component_read_field(component, WCD938X_MBHC_NEW_CTL_2, WCD938X_M_RTH_CTL_MASK))
+ goto done;
+
+ wcd938x_mbhc_moisture_detect_en(component, true);
+ /* Read moisture comparator status */
+ ret = ((snd_soc_component_read(component, WCD938X_MBHC_NEW_FSM_STATUS)
+ & 0x20) ? 0 : 1);
+
+done:
+ return ret;
+
+}
+
+static void wcd938x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component,
+ bool enable)
+{
+ snd_soc_component_write_field(component,
+ WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,
+ WCD938X_MOISTURE_EN_POLLING_MASK, enable);
+}
+
+static const struct wcd_mbhc_cb mbhc_cb = {
+ .clk_setup = wcd938x_mbhc_clk_setup,
+ .mbhc_bias = wcd938x_mbhc_mbhc_bias_control,
+ .set_btn_thr = wcd938x_mbhc_program_btn_thr,
+ .micbias_enable_status = wcd938x_mbhc_micb_en_status,
+ .hph_pull_up_control_v2 = wcd938x_mbhc_hph_l_pull_up_control,
+ .mbhc_micbias_control = wcd938x_mbhc_request_micbias,
+ .mbhc_micb_ramp_control = wcd938x_mbhc_micb_ramp_control,
+ .mbhc_micb_ctrl_thr_mic = wcd938x_mbhc_micb_ctrl_threshold_mic,
+ .compute_impedance = wcd938x_wcd_mbhc_calc_impedance,
+ .mbhc_gnd_det_ctrl = wcd938x_mbhc_gnd_det_ctrl,
+ .hph_pull_down_ctrl = wcd938x_mbhc_hph_pull_down_ctrl,
+ .mbhc_moisture_config = wcd938x_mbhc_moisture_config,
+ .mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
+ .mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
+ .mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
+};
+
+static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+
+ ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc);
+
+ return 0;
+}
+
+static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ uint32_t zl, zr;
+ bool hphr;
+ struct soc_mixer_control *mc;
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+
+ mc = (struct soc_mixer_control *)(kcontrol->private_value);
+ hphr = mc->shift;
+ wcd_mbhc_get_impedance(wcd938x->wcd_mbhc, &zl, &zr);
+ dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
+ ucontrol->value.integer.value[0] = hphr ? zr : zl;
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new hph_type_detect_controls[] = {
+ SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
+ wcd938x_get_hph_type, NULL),
+};
+
+static const struct snd_kcontrol_new impedance_detect_controls[] = {
+ SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
+ wcd938x_hph_impedance_get, NULL),
+ SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
+ wcd938x_hph_impedance_get, NULL),
+};
+
+static int wcd938x_mbhc_init(struct snd_soc_component *component)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ struct wcd_mbhc_intr *intr_ids = &wcd938x->intr_ids;
+
+ intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_MBHC_SW_DET);
+ intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_MBHC_BUTTON_PRESS_DET);
+ intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET);
+ intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
+ intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_MBHC_ELECT_INS_REM_DET);
+ intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_HPHL_OCP_INT);
+ intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
+ WCD938X_IRQ_HPHR_OCP_INT);
+
+ wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
+
+ snd_soc_add_component_controls(component, impedance_detect_controls,
+ ARRAY_SIZE(impedance_detect_controls));
+ snd_soc_add_component_controls(component, hph_type_detect_controls,
+ ARRAY_SIZE(hph_type_detect_controls));
+
+ return 0;
+}
+/* END MBHC */
+
static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
SOC_SINGLE_EXT("HPHL_COMP Switch", WCD938X_COMP_L, 0, 1, 0,
wcd938x_get_compander, wcd938x_set_compander),
@@ -3225,15 +3993,6 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"EAR", NULL, "EAR PGA"},
};
-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_set_micbias_data(struct wcd938x_priv *wcd938x)
{
int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
@@ -3372,10 +4131,27 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
default:
break;
}
+
+ ret = wcd938x_mbhc_init(component);
+ if (ret)
+ dev_err(component->dev, "mbhc initialization failed\n");
err:
return ret;
}
+static int wcd938x_codec_set_jack(struct snd_soc_component *comp,
+ struct snd_soc_jack *jack, void *data)
+{
+ struct wcd938x_priv *wcd = dev_get_drvdata(comp->dev);
+
+ if (!jack)
+ return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack);
+
+ wcd_mbhc_stop(wcd->wcd_mbhc);
+
+ return 0;
+}
+
static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
.name = "wcd938x_codec",
.probe = wcd938x_soc_codec_probe,
@@ -3385,6 +4161,7 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
.num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
.dapm_routes = wcd938x_audio_map,
.num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
+ .set_jack = wcd938x_codec_set_jack,
};
static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
@@ -3420,6 +4197,7 @@ static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_pri
static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device *dev)
{
+ struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg;
int ret;
wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
@@ -3448,6 +4226,17 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
wcd938x_dt_parse_micbias_info(dev, wcd938x);
+ 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->linein_th = 5000;
+ cfg->hs_thr = 1700;
+ cfg->hph_thr = 50;
+
+ wcd_dt_parse_mbhc_data(dev, cfg);
+
return 0;
}
@@ -3679,6 +4468,7 @@ static int wcd938x_probe(struct platform_device *pdev)
return -ENOMEM;
dev_set_drvdata(dev, wcd938x);
+ mutex_init(&wcd938x->micb_lock);
ret = wcd938x_populate_dt_data(wcd938x, dev);
if (ret) {
@@ -3703,7 +4493,7 @@ static int wcd938x_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
pm_runtime_idle(dev);
- return ret;
+ return 0;
}
static int wcd938x_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wcd938x.h b/sound/soc/codecs/wcd938x.h
index 07b08de4cebf..ea82039e7843 100644
--- a/sound/soc/codecs/wcd938x.h
+++ b/sound/soc/codecs/wcd938x.h
@@ -658,7 +658,6 @@ struct wcd938x_sdw_priv {
struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
struct wcd938x_sdw_ch_info *ch_info;
bool port_enable[WCD938X_MAX_SWR_CH_IDS];
- int port_map[WCD938X_MAX_SWR_PORTS];
int active_ports;
int num_ports;
bool is_tx;
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 536339e43dc7..e4018ba3b19a 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -912,13 +912,13 @@ void wm8958_dsp2_init(struct snd_soc_component *component)
/* We don't *require* firmware and don't want to delay boot */
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
"wm8958_mbc.wfw", component->dev, GFP_KERNEL,
component, wm8958_mbc_loaded);
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
"wm8958_mbc_vss.wfw", component->dev, GFP_KERNEL,
component, wm8958_mbc_vss_loaded);
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
"wm8958_enh_eq.wfw", component->dev, GFP_KERNEL,
component, wm8958_enh_eq_loaded);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index a4d4cbf716a1..f7c800927cb2 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2031,10 +2031,9 @@ static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp,
if (!pos->subname)
continue;
if (strncmp(pos->subname, name, pos->subname_len) == 0 &&
- strncmp(pos->fw_name, fw_txt,
- SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0 &&
- pos->alg_region.alg == alg &&
- pos->alg_region.type == type) {
+ pos->fw_name == fw_txt &&
+ pos->alg_region.alg == alg &&
+ pos->alg_region.type == type) {
rslt = pos;
break;
}
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index 0cd1a15f40aa..71a58f7ac13a 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SND_DESIGNWARE_I2S
tristate "Synopsys I2S Device Driver"
- depends on CLKDEV_LOOKUP
+ depends on HAVE_CLK
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y or M if you want to add support for I2S driver for
diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c
index ea5c973e2e84..d60f4dac6c1b 100644
--- a/sound/soc/fsl/fsl_rpmsg.c
+++ b/sound/soc/fsl/fsl_rpmsg.c
@@ -165,25 +165,25 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
}
/* Get the optional clocks */
- rpmsg->ipg = devm_clk_get(&pdev->dev, "ipg");
+ rpmsg->ipg = devm_clk_get_optional(&pdev->dev, "ipg");
if (IS_ERR(rpmsg->ipg))
- rpmsg->ipg = NULL;
+ return PTR_ERR(rpmsg->ipg);
- rpmsg->mclk = devm_clk_get(&pdev->dev, "mclk");
+ rpmsg->mclk = devm_clk_get_optional(&pdev->dev, "mclk");
if (IS_ERR(rpmsg->mclk))
- rpmsg->mclk = NULL;
+ return PTR_ERR(rpmsg->mclk);
- rpmsg->dma = devm_clk_get(&pdev->dev, "dma");
+ rpmsg->dma = devm_clk_get_optional(&pdev->dev, "dma");
if (IS_ERR(rpmsg->dma))
- rpmsg->dma = NULL;
+ return PTR_ERR(rpmsg->dma);
- rpmsg->pll8k = devm_clk_get(&pdev->dev, "pll8k");
+ rpmsg->pll8k = devm_clk_get_optional(&pdev->dev, "pll8k");
if (IS_ERR(rpmsg->pll8k))
- rpmsg->pll8k = NULL;
+ return PTR_ERR(rpmsg->pll8k);
- rpmsg->pll11k = devm_clk_get(&pdev->dev, "pll11k");
+ rpmsg->pll11k = devm_clk_get_optional(&pdev->dev, "pll11k");
if (IS_ERR(rpmsg->pll11k))
- rpmsg->pll11k = NULL;
+ return PTR_ERR(rpmsg->pll11k);
platform_set_drvdata(pdev, rpmsg);
pm_runtime_enable(&pdev->dev);
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 2252a4a62fa5..8ffb1a6048d6 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1438,14 +1438,27 @@ static int fsl_spdif_probe(struct platform_device *pdev)
&spdif_priv->cpu_dai_drv, 1);
if (ret) {
dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
- return ret;
+ goto err_pm_disable;
}
ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE);
- if (ret && ret != -EPROBE_DEFER)
- dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret, "imx_pcm_dma_init failed\n");
+ goto err_pm_disable;
+ }
return ret;
+
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ return ret;
+}
+
+static int fsl_spdif_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
}
#ifdef CONFIG_PM
@@ -1454,6 +1467,9 @@ static int fsl_spdif_runtime_suspend(struct device *dev)
struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
int i;
+ /* Disable all the interrupts */
+ regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SIE, 0xffffff, 0);
+
regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
&spdif_priv->regcache_srpc);
regcache_cache_only(spdif_priv->regmap, true);
@@ -1551,6 +1567,7 @@ static struct platform_driver fsl_spdif_driver = {
.pm = &fsl_spdif_pm,
},
.probe = fsl_spdif_probe,
+ .remove = fsl_spdif_remove,
};
module_platform_driver(fsl_spdif_driver);
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index fb7c29fc39d7..31c5ee641fe7 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -1189,10 +1189,8 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
/* get IRQs */
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "no irq[0]: %d\n", irq);
+ if (irq < 0)
return irq;
- }
ret = devm_request_irq(dev, irq, irq0_isr, 0, pdev->name, xcvr);
if (ret) {
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 677f7da93b4b..10c63b73900c 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -640,8 +640,8 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
cnf_num += li->num[i].codecs;
}
- dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL);
- dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dai_props), GFP_KERNEL);
+ dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL);
+ dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dlcs), GFP_KERNEL);
if (!dais || !dlcs)
return -ENOMEM;
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index a8a9aa0057d3..4e8382097e61 100644
--- a/sound/soc/intel/atom/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -128,7 +128,7 @@ int sst_post_message_mrfld(struct intel_sst_drv *sst_drv_ctx,
while (header.p.header_high.part.busy) {
if (loop_count > 25) {
dev_err(sst_drv_ctx->dev,
- "sst: Busy wait failed, cant send this msg\n");
+ "sst: Busy wait failed, can't send this msg\n");
retval = -EBUSY;
goto out;
}
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 7e29b0d911e2..046955bf717c 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -602,6 +602,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
select SND_SOC_DMIC
select SND_SOC_INTEL_HDA_DSP_COMMON
select SND_SOC_INTEL_SOF_MAXIM_COMMON
+ select SND_SOC_SDW_MOCKUP
help
Add support for Intel SoundWire-based platforms connected to
MAX98373, RT700, RT711, RT1308 and RT715
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index a0af91580184..055248f104b2 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -37,6 +37,7 @@ struct byt_cht_es8316_private {
struct clk *mclk;
struct snd_soc_jack jack;
struct gpio_desc *speaker_en_gpio;
+ struct device *codec_dev;
bool speaker_en;
};
@@ -461,6 +462,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
const struct dmi_system_id *dmi_id;
struct device *dev = &pdev->dev;
struct snd_soc_acpi_mach *mach;
+ struct fwnode_handle *fwnode;
const char *platform_name;
struct acpi_device *adev;
struct device *codec_dev;
@@ -491,6 +493,9 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
+ } else {
+ dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
+ return -ENXIO;
}
/* override plaform name, if required */
@@ -535,15 +540,25 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
}
/* get speaker enable GPIO */
- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
+ codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
if (quirk & BYT_CHT_ES8316_JD_INVERTED)
props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
if (cnt) {
- ret = device_add_properties(codec_dev, props);
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode)) {
+ put_device(codec_dev);
+ return PTR_ERR(fwnode);
+ }
+
+ ret = device_add_software_node(codec_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
+
if (ret) {
put_device(codec_dev);
return ret;
@@ -555,7 +570,6 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
gpiod_get_index(codec_dev, "speaker-enable", 0,
/* see comment in byt_cht_es8316_resume */
GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
- put_device(codec_dev);
if (IS_ERR(priv->speaker_en_gpio)) {
ret = PTR_ERR(priv->speaker_en_gpio);
@@ -567,7 +581,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
dev_err(dev, "get speaker GPIO failed: %d\n", ret);
fallthrough;
case -EPROBE_DEFER:
- return ret;
+ goto err_put_codec;
}
}
@@ -605,10 +619,15 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
if (ret) {
gpiod_put(priv->speaker_en_gpio);
dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
- return ret;
+ goto err_put_codec;
}
platform_set_drvdata(pdev, &byt_cht_es8316_card);
return 0;
+
+err_put_codec:
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
+ return ret;
}
static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
@@ -617,6 +636,8 @@ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
gpiod_put(priv->speaker_en_gpio);
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
return 0;
}
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 91a6d712eb58..05667a33d919 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -18,6 +18,8 @@
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <sound/pcm.h>
@@ -73,6 +75,10 @@ enum {
#define BYT_RT5640_MCLK_EN BIT(22)
#define BYT_RT5640_MCLK_25MHZ BIT(23)
#define BYT_RT5640_NO_SPEAKERS BIT(24)
+#define BYT_RT5640_LINEOUT BIT(25)
+#define BYT_RT5640_LINEOUT_AS_HP2 BIT(26)
+#define BYT_RT5640_HSMIC2_ON_IN1 BIT(27)
+#define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28)
#define BYTCR_INPUT_DEFAULTS \
(BYT_RT5640_IN3_MAP | \
@@ -86,7 +92,10 @@ enum {
struct byt_rt5640_private {
struct snd_soc_jack jack;
+ struct snd_soc_jack jack2;
+ struct gpio_desc *hsmic_detect;
struct clk *mclk;
+ struct device *codec_dev;
};
static bool is_bytcr;
@@ -125,6 +134,8 @@ static void log_quirks(struct device *dev)
dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
break;
}
+ if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
+ dev_info(dev, "quirk HSMIC2_ON_IN1 enabled\n");
if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
BYT_RT5640_JDSRC(byt_rt5640_quirk));
@@ -135,10 +146,16 @@ static void log_quirks(struct device *dev)
}
if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
dev_info(dev, "quirk JD_NOT_INV enabled\n");
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
+ dev_info(dev, "quirk JD_HP_ELITEPAD_1000G2 enabled\n");
if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
dev_info(dev, "quirk MONO_SPEAKER enabled\n");
if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)
dev_info(dev, "quirk NO_SPEAKERS enabled\n");
+ if (byt_rt5640_quirk & BYT_RT5640_LINEOUT)
+ dev_info(dev, "quirk LINEOUT enabled\n");
+ if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
+ dev_info(dev, "quirk LINEOUT_AS_HP2 enabled\n");
if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
dev_info(dev, "quirk DIFF_MIC enabled\n");
if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
@@ -224,6 +241,20 @@ static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
#define BYT_CODEC_DAI1 "rt5640-aif1"
#define BYT_CODEC_DAI2 "rt5640-aif2"
+static struct snd_soc_dai *byt_rt5640_get_codec_dai(struct snd_soc_dapm_context *dapm)
+{
+ struct snd_soc_card *card = dapm->card;
+ struct snd_soc_dai *codec_dai;
+
+ codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+ if (!codec_dai)
+ codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
+ if (!codec_dai)
+ dev_err(card->dev, "Error codec dai not found\n");
+
+ return codec_dai;
+}
+
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
@@ -233,15 +264,9 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
int ret;
- codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+ codec_dai = byt_rt5640_get_codec_dai(dapm);
if (!codec_dai)
- codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
-
- if (!codec_dai) {
- dev_err(card->dev,
- "Codec dai not found; Unable to set platform clock\n");
return -EIO;
- }
if (SND_SOC_DAPM_EVENT_ON(event)) {
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
@@ -276,23 +301,48 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
return 0;
}
+static int byt_rt5640_event_lineout(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ unsigned int gpio_ctrl3_val = RT5640_GP1_PF_OUT;
+ struct snd_soc_dai *codec_dai;
+
+ if (!(byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2))
+ return 0;
+
+ /*
+ * On devices which use line-out as a second headphones output,
+ * the codec's GPIO1 pin is used to enable an external HP-amp.
+ */
+
+ codec_dai = byt_rt5640_get_codec_dai(w->dapm);
+ if (!codec_dai)
+ return -EIO;
+
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ gpio_ctrl3_val |= RT5640_GP1_OUT_HI;
+
+ snd_soc_component_update_bits(codec_dai->component, RT5640_GPIO_CTRL3,
+ RT5640_GP1_PF_MASK | RT5640_GP1_OUT_MASK, gpio_ctrl3_val);
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
SND_SOC_DAPM_MIC("Internal Mic", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_LINE("Line Out", byt_rt5640_event_lineout),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
-
};
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
{"Headphone", NULL, "Platform Clock"},
{"Headset Mic", NULL, "Platform Clock"},
- {"Internal Mic", NULL, "Platform Clock"},
- {"Speaker", NULL, "Platform Clock"},
-
{"Headset Mic", NULL, "MICBIAS1"},
{"IN2P", NULL, "Headset Mic"},
{"Headphone", NULL, "HPOL"},
@@ -300,23 +350,33 @@ static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
+ {"Internal Mic", NULL, "Platform Clock"},
{"DMIC1", NULL, "Internal Mic"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
+ {"Internal Mic", NULL, "Platform Clock"},
{"DMIC2", NULL, "Internal Mic"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
+ {"Internal Mic", NULL, "Platform Clock"},
{"Internal Mic", NULL, "MICBIAS1"},
{"IN1P", NULL, "Internal Mic"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
+ {"Internal Mic", NULL, "Platform Clock"},
{"Internal Mic", NULL, "MICBIAS1"},
{"IN3P", NULL, "Internal Mic"},
};
+static const struct snd_soc_dapm_route byt_rt5640_hsmic2_in1_map[] = {
+ {"Headset Mic 2", NULL, "Platform Clock"},
+ {"Headset Mic 2", NULL, "MICBIAS1"},
+ {"IN1P", NULL, "Headset Mic 2"},
+};
+
static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
@@ -354,6 +414,7 @@ static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
};
static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
+ {"Speaker", NULL, "Platform Clock"},
{"Speaker", NULL, "SPOLP"},
{"Speaker", NULL, "SPOLN"},
{"Speaker", NULL, "SPORP"},
@@ -361,15 +422,24 @@ static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
};
static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
+ {"Speaker", NULL, "Platform Clock"},
{"Speaker", NULL, "SPOLP"},
{"Speaker", NULL, "SPOLN"},
};
+static const struct snd_soc_dapm_route byt_rt5640_lineout_map[] = {
+ {"Line Out", NULL, "Platform Clock"},
+ {"Line Out", NULL, "LOUTR"},
+ {"Line Out", NULL, "LOUTL"},
+};
+
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic 2"),
SOC_DAPM_PIN_SWITCH("Internal Mic"),
SOC_DAPM_PIN_SWITCH("Speaker"),
+ SOC_DAPM_PIN_SWITCH("Line Out"),
};
static struct snd_soc_jack_pin rt5640_pins[] = {
@@ -383,6 +453,75 @@ static struct snd_soc_jack_pin rt5640_pins[] = {
},
};
+static struct snd_soc_jack_pin rt5640_pins2[] = {
+ {
+ /* The 2nd headset jack uses lineout with an external HP-amp */
+ .pin = "Line Out",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic 2",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+struct snd_soc_jack_gpio rt5640_jack_gpio = {
+ .name = "hp-detect",
+ .report = SND_JACK_HEADSET,
+ .invert = true,
+ .debounce_time = 200,
+};
+
+struct snd_soc_jack_gpio rt5640_jack2_gpio = {
+ .name = "hp2-detect",
+ .report = SND_JACK_HEADSET,
+ .invert = true,
+ .debounce_time = 200,
+};
+
+static const struct acpi_gpio_params acpi_gpio0 = { 0, 0, false };
+static const struct acpi_gpio_params acpi_gpio1 = { 1, 0, false };
+static const struct acpi_gpio_params acpi_gpio2 = { 2, 0, false };
+
+static const struct acpi_gpio_mapping byt_rt5640_hp_elitepad_1000g2_gpios[] = {
+ { "hp-detect-gpios", &acpi_gpio0, 1, },
+ { "headset-mic-detect-gpios", &acpi_gpio1, 1, },
+ { "hp2-detect-gpios", &acpi_gpio2, 1, },
+ { },
+};
+
+static int byt_rt5640_hp_elitepad_1000g2_jack1_check(void *data)
+{
+ struct byt_rt5640_private *priv = data;
+ int jack_status, mic_status;
+
+ jack_status = gpiod_get_value_cansleep(rt5640_jack_gpio.desc);
+ if (jack_status)
+ return 0;
+
+ mic_status = gpiod_get_value_cansleep(priv->hsmic_detect);
+ if (mic_status)
+ return SND_JACK_HEADPHONE;
+ else
+ return SND_JACK_HEADSET;
+}
+
+static int byt_rt5640_hp_elitepad_1000g2_jack2_check(void *data)
+{
+ struct snd_soc_component *component = data;
+ int jack_status, report;
+
+ jack_status = gpiod_get_value_cansleep(rt5640_jack2_gpio.desc);
+ if (jack_status)
+ return 0;
+
+ rt5640_enable_micbias1_for_ovcd(component);
+ report = rt5640_detect_headset(component, rt5640_jack2_gpio.desc);
+ rt5640_disable_micbias1_for_ovcd(component);
+
+ return report;
+}
+
static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -590,8 +729,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
},
- .driver_data = (void *)(BYT_RT5640_IN1_MAP |
- BYT_RT5640_MCLK_EN),
+ .driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
+ BYT_RT5640_MCLK_EN |
+ BYT_RT5640_LINEOUT |
+ BYT_RT5640_LINEOUT_AS_HP2 |
+ BYT_RT5640_HSMIC2_ON_IN1 |
+ BYT_RT5640_JD_HP_ELITEP_1000G2),
},
{ /* HP Pavilion x2 10-k0XX, 10-n0XX */
.matches = {
@@ -912,15 +1055,13 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
+static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
+ struct byt_rt5640_private *priv)
{
struct property_entry props[MAX_NO_PROPS] = {};
- struct device *i2c_dev;
- int ret, cnt = 0;
-
- i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
- if (!i2c_dev)
- return -EPROBE_DEFER;
+ struct fwnode_handle *fwnode;
+ int cnt = 0;
+ int ret;
switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
case BYT_RT5640_DMIC1_MAP:
@@ -960,8 +1101,15 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
- ret = device_add_properties(i2c_dev, props);
- put_device(i2c_dev);
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode)) {
+ /* put_device() is handled in caller */
+ return PTR_ERR(fwnode);
+ }
+
+ ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
return ret;
}
@@ -1021,6 +1169,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
if (ret)
return ret;
+ if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1) {
+ ret = snd_soc_dapm_add_routes(&card->dapm,
+ byt_rt5640_hsmic2_in1_map,
+ ARRAY_SIZE(byt_rt5640_hsmic2_in1_map));
+ if (ret)
+ return ret;
+ }
+
if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
ret = snd_soc_dapm_add_routes(&card->dapm,
byt_rt5640_ssp2_aif2_map,
@@ -1053,6 +1209,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
if (ret)
return ret;
+ if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
+ ret = snd_soc_dapm_add_routes(&card->dapm,
+ byt_rt5640_lineout_map,
+ ARRAY_SIZE(byt_rt5640_lineout_map));
+ if (ret)
+ return ret;
+ }
+
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
/*
* The firmware might enable the clock at
@@ -1093,9 +1257,53 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
snd_soc_component_set_jack(component, &priv->jack, NULL);
}
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
+ ret = snd_soc_card_jack_new(card, "Headset",
+ SND_JACK_HEADSET,
+ &priv->jack, rt5640_pins,
+ ARRAY_SIZE(rt5640_pins));
+ if (ret)
+ return ret;
+
+ ret = snd_soc_card_jack_new(card, "Headset 2",
+ SND_JACK_HEADSET,
+ &priv->jack2, rt5640_pins2,
+ ARRAY_SIZE(rt5640_pins2));
+ if (ret)
+ return ret;
+
+ rt5640_jack_gpio.data = priv;
+ rt5640_jack_gpio.gpiod_dev = priv->codec_dev;
+ rt5640_jack_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack1_check;
+ ret = snd_soc_jack_add_gpios(&priv->jack, 1, &rt5640_jack_gpio);
+ if (ret)
+ return ret;
+
+ rt5640_set_ovcd_params(component);
+ rt5640_jack2_gpio.data = component;
+ rt5640_jack2_gpio.gpiod_dev = priv->codec_dev;
+ rt5640_jack2_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack2_check;
+ ret = snd_soc_jack_add_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
+ if (ret) {
+ snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
+ return ret;
+ }
+ }
+
return 0;
}
+static void byt_rt5640_exit(struct snd_soc_pcm_runtime *runtime)
+{
+ struct snd_soc_card *card = runtime->card;
+ struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
+ snd_soc_jack_free_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
+ snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
+ }
+}
+
static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -1208,6 +1416,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = byt_rt5640_init,
+ .exit = byt_rt5640_exit,
.ops = &byt_rt5640_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
@@ -1218,7 +1427,7 @@ static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
#endif
-static char byt_rt5640_components[32]; /* = "cfg-spk:* cfg-mic:*" */
+static char byt_rt5640_components[64]; /* = "cfg-spk:* cfg-mic:* ..." */
static int byt_rt5640_suspend(struct snd_soc_card *card)
{
@@ -1288,10 +1497,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" };
__maybe_unused const char *spk_type;
const struct dmi_system_id *dmi_id;
+ const char *headset2_string = "";
+ const char *lineout_string = "";
struct byt_rt5640_private *priv;
struct snd_soc_acpi_mach *mach;
const char *platform_name;
struct acpi_device *adev;
+ struct device *codec_dev;
bool sof_parent;
int ret_val = 0;
int dai_index = 0;
@@ -1324,6 +1536,9 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
+ } else {
+ dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
+ return -ENXIO;
}
/*
@@ -1400,10 +1615,29 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_quirk = quirk_override;
}
+ codec_dev = acpi_get_first_physical_node(adev);
+ if (!codec_dev)
+ return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
+
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
+ acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
+ byt_rt5640_hp_elitepad_1000g2_gpios);
+
+ priv->hsmic_detect = devm_fwnode_gpiod_get(&pdev->dev, codec_dev->fwnode,
+ "headset-mic-detect", GPIOD_IN,
+ "headset-mic-detect");
+ if (IS_ERR(priv->hsmic_detect)) {
+ ret_val = PTR_ERR(priv->hsmic_detect);
+ dev_err_probe(&pdev->dev, ret_val, "getting hsmic-detect GPIO\n");
+ goto err_device;
+ }
+ }
+
/* Must be called before register_card, also see declaration comment. */
- ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
+ ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
if (ret_val)
- return ret_val;
+ goto err_remove_gpios;
log_quirks(&pdev->dev);
@@ -1434,7 +1668,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
* for all other errors, including -EPROBE_DEFER
*/
if (ret_val != -ENOENT)
- return ret_val;
+ goto err;
byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
}
}
@@ -1450,9 +1684,20 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
spk_type = "stereo";
}
+ if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
+ if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
+ lineout_string = " cfg-hp2:lineout";
+ else
+ lineout_string = " cfg-lineout:2";
+ }
+
+ if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
+ headset2_string = " cfg-hs2:in1";
+
snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
- "cfg-spk:%d cfg-mic:%s aif:%d", cfg_spk,
- map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif);
+ "cfg-spk:%d cfg-mic:%s aif:%d%s%s", cfg_spk,
+ map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif,
+ lineout_string, headset2_string);
byt_rt5640_card.components = byt_rt5640_components;
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
@@ -1467,7 +1712,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
platform_name);
if (ret_val)
- return ret_val;
+ goto err;
sof_parent = snd_soc_acpi_sof_parent(&pdev->dev);
@@ -1489,10 +1734,32 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
if (ret_val) {
dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
ret_val);
- return ret_val;
+ goto err;
}
platform_set_drvdata(pdev, &byt_rt5640_card);
return ret_val;
+
+err:
+ device_remove_software_node(priv->codec_dev);
+err_remove_gpios:
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
+ acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
+err_device:
+ put_device(priv->codec_dev);
+ return ret_val;
+}
+
+static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+
+ if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
+ acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
+
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
+ return 0;
}
static struct platform_driver snd_byt_rt5640_mc_driver = {
@@ -1500,6 +1767,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = {
.name = "bytcr_rt5640",
},
.probe = snd_byt_rt5640_mc_probe,
+ .remove = snd_byt_rt5640_mc_remove,
};
module_platform_driver(snd_byt_rt5640_mc_driver);
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index e13c0c63a949..e94c9124d4f4 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -85,6 +85,7 @@ struct byt_rt5651_private {
struct gpio_desc *ext_amp_gpio;
struct gpio_desc *hp_detect;
struct snd_soc_jack jack;
+ struct device *codec_dev;
};
static const struct acpi_gpio_mapping *byt_rt5651_gpios;
@@ -527,10 +528,13 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
+static int byt_rt5651_add_codec_device_props(struct device *i2c_dev,
+ struct byt_rt5651_private *priv)
{
struct property_entry props[MAX_NO_PROPS] = {};
+ struct fwnode_handle *fwnode;
int cnt = 0;
+ int ret;
props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
BYT_RT5651_JDSRC(byt_rt5651_quirk));
@@ -547,7 +551,17 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV)
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
- return device_add_properties(i2c_dev, props);
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode)) {
+ /* put_device(i2c_dev) is handled in caller */
+ return PTR_ERR(fwnode);
+ }
+
+ ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
+
+ return ret;
}
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
@@ -920,13 +934,13 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
- return -ENODEV;
+ return -ENXIO;
}
- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
- byt_rt5651_codec_name);
+ codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
/*
* swap SSP0 if bytcr is detected
@@ -994,11 +1008,9 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
}
/* Must be called before register_card, also see declaration comment. */
- ret_val = byt_rt5651_add_codec_device_props(codec_dev);
- if (ret_val) {
- put_device(codec_dev);
- return ret_val;
- }
+ ret_val = byt_rt5651_add_codec_device_props(codec_dev, priv);
+ if (ret_val)
+ goto err_device;
/* Cherry Trail devices use an external amplifier enable gpio */
if (soc_intel_is_cht() && !byt_rt5651_gpios)
@@ -1022,8 +1034,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
ret_val);
fallthrough;
case -EPROBE_DEFER:
- put_device(codec_dev);
- return ret_val;
+ goto err;
}
}
priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev,
@@ -1042,14 +1053,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
ret_val);
fallthrough;
case -EPROBE_DEFER:
- put_device(codec_dev);
- return ret_val;
+ goto err;
}
}
}
- put_device(codec_dev);
-
log_quirks(&pdev->dev);
if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
@@ -1073,7 +1081,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
* for all other errors, including -EPROBE_DEFER
*/
if (ret_val != -ENOENT)
- return ret_val;
+ goto err;
byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
}
}
@@ -1102,7 +1110,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
platform_name);
if (ret_val)
- return ret_val;
+ goto err;
sof_parent = snd_soc_acpi_sof_parent(&pdev->dev);
@@ -1124,10 +1132,26 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (ret_val) {
dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
ret_val);
- return ret_val;
+ goto err;
}
platform_set_drvdata(pdev, &byt_rt5651_card);
return ret_val;
+
+err:
+ device_remove_software_node(priv->codec_dev);
+err_device:
+ put_device(priv->codec_dev);
+ return ret_val;
+}
+
+static int snd_byt_rt5651_mc_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
+
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
+ return 0;
}
static struct platform_driver snd_byt_rt5651_mc_driver = {
@@ -1135,6 +1159,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = {
.name = "bytcr_rt5651",
},
.probe = snd_byt_rt5651_mc_probe,
+ .remove = snd_byt_rt5651_mc_remove,
};
module_platform_driver(snd_byt_rt5651_mc_driver);
diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
index a31a7a7bbf66..2b43459adc33 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
@@ -199,7 +199,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
}
if (!strcmp(codec_dai->component->name, MAX98373_DEV0_NAME)) {
ret = snd_soc_dai_set_tdm_slot(codec_dai,
- 0x03, 3, 8, 24);
+ 0x30, 3, 8, 16);
if (ret < 0) {
dev_err(runtime->dev,
"DEV0 TDM slot err:%d\n", ret);
@@ -208,10 +208,10 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
}
if (!strcmp(codec_dai->component->name, MAX98373_DEV1_NAME)) {
ret = snd_soc_dai_set_tdm_slot(codec_dai,
- 0x0C, 3, 8, 24);
+ 0xC0, 3, 8, 16);
if (ret < 0) {
dev_err(runtime->dev,
- "DEV0 TDM slot err:%d\n", ret);
+ "DEV1 TDM slot err:%d\n", ret);
return ret;
}
}
@@ -311,24 +311,6 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
* The above 2 loops are mutually exclusive based on the stream direction,
* thus rtd_dpcm variable will never be overwritten
*/
- /*
- * Topology for kblda7219m98373 & kblmax98373 supports only S24_LE,
- * where as kblda7219m98927 & kblmax98927 supports S16_LE by default.
- * Skipping the port wise FE and BE configuration for kblda7219m98373 &
- * kblmax98373 as the topology (FE & BE) supports S24_LE only.
- */
-
- if (!strcmp(rtd->card->name, "kblda7219m98373") ||
- !strcmp(rtd->card->name, "kblmax98373")) {
- /* The ADSP will convert the FE rate to 48k, stereo */
- rate->min = rate->max = 48000;
- chan->min = chan->max = DUAL_CHANNEL;
-
- /* set SSP to 24 bit */
- snd_mask_none(fmt);
- snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
- return 0;
- }
/*
* The ADSP will convert the FE rate to 48k, stereo, 24 bit
@@ -479,31 +461,20 @@ static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
static int kbl_fe_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
/*
* On this platform for PCM device we support,
* 48Khz
* stereo
+ * 16 bit audio
*/
runtime->hw.channels_max = DUAL_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels);
- /*
- * Setup S24_LE (32 bit container and 24 bit valid data) for
- * kblda7219m98373 & kblmax98373. For kblda7219m98927 &
- * kblmax98927 keeping it as 16/16 due to topology FW dependency.
- */
- if (!strcmp(soc_rt->card->name, "kblda7219m98373") ||
- !strcmp(soc_rt->card->name, "kblmax98373")) {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_LE;
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
-
- } else {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
- snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
- }
+
+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+ snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
@@ -536,23 +507,11 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels_quad);
- /*
- * Topology for kblda7219m98373 & kblmax98373 supports only S24_LE.
- * The DMIC also configured for S24_LE. Forcing the DMIC format to
- * S24_LE due to the topology FW dependency.
- */
- if (!strcmp(soc_rt->card->name, "kblda7219m98373") ||
- !strcmp(soc_rt->card->name, "kblmax98373")) {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_LE;
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- }
-
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
}
diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c
index 42aadf801f72..ce78c1879887 100644
--- a/sound/soc/intel/boards/sof_cs42l42.c
+++ b/sound/soc/intel/boards/sof_cs42l42.c
@@ -16,6 +16,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/sof.h>
#include <sound/soc-acpi.h>
#include <dt-bindings/sound/cs42l42.h>
#include "../../codecs/hdac_hdmi.h"
@@ -36,7 +37,20 @@
#define SOF_CS42L42_NUM_HDMIDEV_MASK (GENMASK(9, 7))
#define SOF_CS42L42_NUM_HDMIDEV(quirk) \
(((quirk) << SOF_CS42L42_NUM_HDMIDEV_SHIFT) & SOF_CS42L42_NUM_HDMIDEV_MASK)
-#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(10)
+#define SOF_CS42L42_DAILINK_SHIFT 10
+#define SOF_CS42L42_DAILINK_MASK (GENMASK(24, 10))
+#define SOF_CS42L42_DAILINK(link1, link2, link3, link4, link5) \
+ ((((link1) | ((link2) << 3) | ((link3) << 6) | ((link4) << 9) | ((link5) << 12)) << SOF_CS42L42_DAILINK_SHIFT) & SOF_CS42L42_DAILINK_MASK)
+#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(25)
+#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(26)
+
+enum {
+ LINK_NONE = 0,
+ LINK_HP = 1,
+ LINK_SPK = 2,
+ LINK_DMIC = 3,
+ LINK_HDMI = 4,
+};
/* Default: SSP2 */
static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2);
@@ -122,7 +136,12 @@ static int sof_cs42l42_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int clk_freq, ret;
- clk_freq = 3072000; /* BCLK freq */
+ clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */
+
+ if (clk_freq <= 0) {
+ dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq);
+ return -EINVAL;
+ }
/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
@@ -259,133 +278,168 @@ static struct snd_soc_dai_link_component dmic_component[] = {
}
};
-static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
- int ssp_codec,
- int ssp_amp,
- int dmic_be_num,
- int hdmi_num)
+static int create_spk_amp_dai_links(struct device *dev,
+ struct snd_soc_dai_link *links,
+ struct snd_soc_dai_link_component *cpus,
+ int *id, int ssp_amp)
{
- struct snd_soc_dai_link_component *idisp_components;
- struct snd_soc_dai_link_component *cpus;
- struct snd_soc_dai_link *links;
- int i, id = 0;
-
- links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
- sof_audio_card_cs42l42.num_links, GFP_KERNEL);
- cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
- sof_audio_card_cs42l42.num_links, GFP_KERNEL);
- if (!links || !cpus)
- goto devm_err;
+ int ret = 0;
/* speaker amp */
- if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) {
- links[id].name = devm_kasprintf(dev, GFP_KERNEL,
- "SSP%d-Codec", ssp_amp);
- if (!links[id].name)
- goto devm_err;
+ if (!(sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT))
+ return 0;
- links[id].id = id;
+ links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec",
+ ssp_amp);
+ if (!links[*id].name) {
+ ret = -ENOMEM;
+ goto devm_err;
+ }
- if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) {
- max_98357a_dai_link(&links[id]);
- } else {
- dev_err(dev, "no amp defined\n");
- goto devm_err;
- }
+ links[*id].id = *id;
- links[id].platforms = platform_component;
- links[id].num_platforms = ARRAY_SIZE(platform_component);
- links[id].dpcm_playback = 1;
- links[id].no_pcm = 1;
- links[id].cpus = &cpus[id];
- links[id].num_cpus = 1;
-
- links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
- "SSP%d Pin",
- ssp_amp);
- if (!links[id].cpus->dai_name)
- goto devm_err;
+ if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) {
+ max_98357a_dai_link(&links[*id]);
+ } else if (sof_cs42l42_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
+ max_98360a_dai_link(&links[*id]);
+ } else {
+ dev_err(dev, "no amp defined\n");
+ ret = -EINVAL;
+ goto devm_err;
+ }
- id++;
+ links[*id].platforms = platform_component;
+ links[*id].num_platforms = ARRAY_SIZE(platform_component);
+ links[*id].dpcm_playback = 1;
+ links[*id].no_pcm = 1;
+ links[*id].cpus = &cpus[*id];
+ links[*id].num_cpus = 1;
+
+ links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SSP%d Pin", ssp_amp);
+ if (!links[*id].cpus->dai_name) {
+ ret = -ENOMEM;
+ goto devm_err;
}
+ (*id)++;
+
+devm_err:
+ return ret;
+}
+
+static int create_hp_codec_dai_links(struct device *dev,
+ struct snd_soc_dai_link *links,
+ struct snd_soc_dai_link_component *cpus,
+ int *id, int ssp_codec)
+{
/* codec SSP */
- links[id].name = devm_kasprintf(dev, GFP_KERNEL,
- "SSP%d-Codec", ssp_codec);
- if (!links[id].name)
+ links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec",
+ ssp_codec);
+ if (!links[*id].name)
goto devm_err;
- links[id].id = id;
- links[id].codecs = cs42l42_component;
- links[id].num_codecs = ARRAY_SIZE(cs42l42_component);
- links[id].platforms = platform_component;
- links[id].num_platforms = ARRAY_SIZE(platform_component);
- links[id].init = sof_cs42l42_init;
- links[id].exit = sof_cs42l42_exit;
- links[id].ops = &sof_cs42l42_ops;
- links[id].dpcm_playback = 1;
- links[id].dpcm_capture = 1;
- links[id].no_pcm = 1;
- links[id].cpus = &cpus[id];
- links[id].num_cpus = 1;
-
- links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
- "SSP%d Pin",
- ssp_codec);
- if (!links[id].cpus->dai_name)
+ links[*id].id = *id;
+ links[*id].codecs = cs42l42_component;
+ links[*id].num_codecs = ARRAY_SIZE(cs42l42_component);
+ links[*id].platforms = platform_component;
+ links[*id].num_platforms = ARRAY_SIZE(platform_component);
+ links[*id].init = sof_cs42l42_init;
+ links[*id].exit = sof_cs42l42_exit;
+ links[*id].ops = &sof_cs42l42_ops;
+ links[*id].dpcm_playback = 1;
+ links[*id].dpcm_capture = 1;
+ links[*id].no_pcm = 1;
+ links[*id].cpus = &cpus[*id];
+ links[*id].num_cpus = 1;
+
+ links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SSP%d Pin",
+ ssp_codec);
+ if (!links[*id].cpus->dai_name)
goto devm_err;
- id++;
+ (*id)++;
+
+ return 0;
+
+devm_err:
+ return -ENOMEM;
+}
+
+static int create_dmic_dai_links(struct device *dev,
+ struct snd_soc_dai_link *links,
+ struct snd_soc_dai_link_component *cpus,
+ int *id, int dmic_be_num)
+{
+ int i;
/* dmic */
- if (dmic_be_num > 0) {
- /* at least we have dmic01 */
- links[id].name = "dmic01";
- links[id].cpus = &cpus[id];
- links[id].cpus->dai_name = "DMIC01 Pin";
- links[id].init = dmic_init;
- if (dmic_be_num > 1) {
- /* set up 2 BE links at most */
- links[id + 1].name = "dmic16k";
- links[id + 1].cpus = &cpus[id + 1];
- links[id + 1].cpus->dai_name = "DMIC16k Pin";
- dmic_be_num = 2;
- }
+ if (dmic_be_num <= 0)
+ return 0;
+
+ /* at least we have dmic01 */
+ links[*id].name = "dmic01";
+ links[*id].cpus = &cpus[*id];
+ links[*id].cpus->dai_name = "DMIC01 Pin";
+ links[*id].init = dmic_init;
+ if (dmic_be_num > 1) {
+ /* set up 2 BE links at most */
+ links[*id + 1].name = "dmic16k";
+ links[*id + 1].cpus = &cpus[*id + 1];
+ links[*id + 1].cpus->dai_name = "DMIC16k Pin";
+ dmic_be_num = 2;
}
for (i = 0; i < dmic_be_num; i++) {
- links[id].id = id;
- links[id].num_cpus = 1;
- links[id].codecs = dmic_component;
- links[id].num_codecs = ARRAY_SIZE(dmic_component);
- links[id].platforms = platform_component;
- links[id].num_platforms = ARRAY_SIZE(platform_component);
- links[id].ignore_suspend = 1;
- links[id].dpcm_capture = 1;
- links[id].no_pcm = 1;
- id++;
+ links[*id].id = *id;
+ links[*id].num_cpus = 1;
+ links[*id].codecs = dmic_component;
+ links[*id].num_codecs = ARRAY_SIZE(dmic_component);
+ links[*id].platforms = platform_component;
+ links[*id].num_platforms = ARRAY_SIZE(platform_component);
+ links[*id].ignore_suspend = 1;
+ links[*id].dpcm_capture = 1;
+ links[*id].no_pcm = 1;
+
+ (*id)++;
}
+ return 0;
+}
+
+static int create_hdmi_dai_links(struct device *dev,
+ struct snd_soc_dai_link *links,
+ struct snd_soc_dai_link_component *cpus,
+ int *id, int hdmi_num)
+{
+ struct snd_soc_dai_link_component *idisp_components;
+ int i;
+
/* HDMI */
- if (hdmi_num > 0) {
- idisp_components = devm_kzalloc(dev,
- sizeof(struct snd_soc_dai_link_component) *
- hdmi_num, GFP_KERNEL);
- if (!idisp_components)
- goto devm_err;
- }
+ if (hdmi_num <= 0)
+ return 0;
+
+ idisp_components = devm_kzalloc(dev,
+ sizeof(struct snd_soc_dai_link_component) *
+ hdmi_num, GFP_KERNEL);
+ if (!idisp_components)
+ goto devm_err;
+
for (i = 1; i <= hdmi_num; i++) {
- links[id].name = devm_kasprintf(dev, GFP_KERNEL,
- "iDisp%d", i);
- if (!links[id].name)
+ links[*id].name = devm_kasprintf(dev, GFP_KERNEL,
+ "iDisp%d", i);
+ if (!links[*id].name)
goto devm_err;
- links[id].id = id;
- links[id].cpus = &cpus[id];
- links[id].num_cpus = 1;
- links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
- "iDisp%d Pin", i);
- if (!links[id].cpus->dai_name)
+ links[*id].id = *id;
+ links[*id].cpus = &cpus[*id];
+ links[*id].num_cpus = 1;
+ links[*id].cpus->dai_name = devm_kasprintf(dev,
+ GFP_KERNEL,
+ "iDisp%d Pin",
+ i);
+ if (!links[*id].cpus->dai_name)
goto devm_err;
idisp_components[i - 1].name = "ehdaudio0D2";
@@ -396,14 +450,86 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
if (!idisp_components[i - 1].dai_name)
goto devm_err;
- links[id].codecs = &idisp_components[i - 1];
- links[id].num_codecs = 1;
- links[id].platforms = platform_component;
- links[id].num_platforms = ARRAY_SIZE(platform_component);
- links[id].init = sof_hdmi_init;
- links[id].dpcm_playback = 1;
- links[id].no_pcm = 1;
- id++;
+ links[*id].codecs = &idisp_components[i - 1];
+ links[*id].num_codecs = 1;
+ links[*id].platforms = platform_component;
+ links[*id].num_platforms = ARRAY_SIZE(platform_component);
+ links[*id].init = sof_hdmi_init;
+ links[*id].dpcm_playback = 1;
+ links[*id].no_pcm = 1;
+
+ (*id)++;
+ }
+
+ return 0;
+
+devm_err:
+ return -ENOMEM;
+}
+
+static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
+ int ssp_codec,
+ int ssp_amp,
+ int dmic_be_num,
+ int hdmi_num)
+{
+ struct snd_soc_dai_link_component *cpus;
+ struct snd_soc_dai_link *links;
+ int ret, id = 0, link_seq;
+
+ links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
+ sof_audio_card_cs42l42.num_links, GFP_KERNEL);
+ cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
+ sof_audio_card_cs42l42.num_links, GFP_KERNEL);
+ if (!links || !cpus)
+ goto devm_err;
+
+ link_seq = (sof_cs42l42_quirk & SOF_CS42L42_DAILINK_MASK) >> SOF_CS42L42_DAILINK_SHIFT;
+
+ while (link_seq) {
+ int link_type = link_seq & 0x07;
+
+ switch (link_type) {
+ case LINK_HP:
+ ret = create_hp_codec_dai_links(dev, links, cpus, &id, ssp_codec);
+ if (ret < 0) {
+ dev_err(dev, "fail to create hp codec dai links, ret %d\n",
+ ret);
+ goto devm_err;
+ }
+ break;
+ case LINK_SPK:
+ ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp);
+ if (ret < 0) {
+ dev_err(dev, "fail to create spk amp dai links, ret %d\n",
+ ret);
+ goto devm_err;
+ }
+ break;
+ case LINK_DMIC:
+ ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num);
+ if (ret < 0) {
+ dev_err(dev, "fail to create dmic dai links, ret %d\n",
+ ret);
+ goto devm_err;
+ }
+ break;
+ case LINK_HDMI:
+ ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num);
+ if (ret < 0) {
+ dev_err(dev, "fail to create hdmi dai links, ret %d\n",
+ ret);
+ goto devm_err;
+ }
+ break;
+ case LINK_NONE:
+ /* caught here if it's not used as terminator in macro */
+ default:
+ dev_err(dev, "invalid link type %d\n", link_type);
+ goto devm_err;
+ }
+
+ link_seq >>= 3;
}
return links;
@@ -484,7 +610,16 @@ static const struct platform_device_id board_ids[] = {
.driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) |
SOF_SPEAKER_AMP_PRESENT |
SOF_MAX98357A_SPEAKER_AMP_PRESENT |
- SOF_CS42L42_SSP_AMP(1)),
+ SOF_CS42L42_SSP_AMP(1)) |
+ SOF_CS42L42_DAILINK(LINK_SPK, LINK_HP, LINK_DMIC, LINK_HDMI, LINK_NONE),
+ },
+ {
+ .name = "jsl_cs4242_mx98360a",
+ .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_MAX98360A_SPEAKER_AMP_PRESENT |
+ SOF_CS42L42_SSP_AMP(1)) |
+ SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_NONE),
},
{ }
};
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c
index e9c52f8b6428..e66dfe666915 100644
--- a/sound/soc/intel/boards/sof_maxim_common.c
+++ b/sound/soc/intel/boards/sof_maxim_common.c
@@ -134,7 +134,7 @@ void max_98373_set_codec_conf(struct snd_soc_card *card)
EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON);
/*
- * Maxim MAX98357A
+ * Maxim MAX98357A/MAX98360A
*/
static const struct snd_kcontrol_new max_98357a_kcontrols[] = {
SOC_DAPM_PIN_SWITCH("Spk"),
@@ -156,6 +156,13 @@ static struct snd_soc_dai_link_component max_98357a_components[] = {
}
};
+static struct snd_soc_dai_link_component max_98360a_components[] = {
+ {
+ .name = MAX_98360A_DEV0_NAME,
+ .dai_name = MAX_98357A_CODEC_DAI,
+ }
+};
+
static int max_98357a_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
@@ -193,5 +200,13 @@ void max_98357a_dai_link(struct snd_soc_dai_link *link)
}
EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
+void max_98360a_dai_link(struct snd_soc_dai_link *link)
+{
+ link->codecs = max_98360a_components;
+ link->num_codecs = ARRAY_SIZE(max_98360a_components);
+ link->init = max_98357a_init;
+}
+EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
+
MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/intel/boards/sof_maxim_common.h b/sound/soc/intel/boards/sof_maxim_common.h
index 2674f1e373ef..3ff5e8fec4de 100644
--- a/sound/soc/intel/boards/sof_maxim_common.h
+++ b/sound/soc/intel/boards/sof_maxim_common.h
@@ -25,11 +25,13 @@ void max_98373_set_codec_conf(struct snd_soc_card *card);
int max_98373_trigger(struct snd_pcm_substream *substream, int cmd);
/*
- * Maxim MAX98357A
+ * Maxim MAX98357A/MAX98360A
*/
#define MAX_98357A_CODEC_DAI "HiFi"
#define MAX_98357A_DEV0_NAME "MX98357A:00"
+#define MAX_98360A_DEV0_NAME "MX98360A:00"
void max_98357a_dai_link(struct snd_soc_dai_link *link);
+void max_98360a_dai_link(struct snd_soc_dai_link *link);
#endif /* __SOF_MAXIM_COMMON_H */
diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c
index 2ec9c62366e2..6815204e58d5 100644
--- a/sound/soc/intel/boards/sof_pcm512x.c
+++ b/sound/soc/intel/boards/sof_pcm512x.c
@@ -26,11 +26,16 @@
#define SOF_PCM512X_SSP_CODEC(quirk) ((quirk) & GENMASK(3, 0))
#define SOF_PCM512X_SSP_CODEC_MASK (GENMASK(3, 0))
+#define SOF_PCM512X_ENABLE_SSP_CAPTURE BIT(4)
+#define SOF_PCM512X_ENABLE_DMIC BIT(5)
#define IDISP_CODEC_MASK 0x4
/* Default: SSP5 */
-static unsigned long sof_pcm512x_quirk = SOF_PCM512X_SSP_CODEC(5);
+static unsigned long sof_pcm512x_quirk =
+ SOF_PCM512X_SSP_CODEC(5) |
+ SOF_PCM512X_ENABLE_SSP_CAPTURE |
+ SOF_PCM512X_ENABLE_DMIC;
static bool is_legacy_cpu;
@@ -244,8 +249,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].dpcm_playback = 1;
/*
* capture only supported with specific versions of the Hifiberry DAC+
- * links[id].dpcm_capture = 1;
*/
+ if (sof_pcm512x_quirk & SOF_PCM512X_ENABLE_SSP_CAPTURE)
+ links[id].dpcm_capture = 1;
links[id].no_pcm = 1;
links[id].cpus = &cpus[id];
links[id].num_cpus = 1;
@@ -380,6 +386,9 @@ static int sof_audio_probe(struct platform_device *pdev)
ssp_codec = sof_pcm512x_quirk & SOF_PCM512X_SSP_CODEC_MASK;
+ if (!(sof_pcm512x_quirk & SOF_PCM512X_ENABLE_DMIC))
+ dmic_be_num = 0;
+
/* compute number of dai links */
sof_audio_card_pcm512x.num_links = 1 + dmic_be_num + hdmi_num;
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index 39217223d50c..f096bd6d69be 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -162,6 +162,20 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
SOF_RT5682_SSP_AMP(2) |
SOF_RT5682_NUM_HDMIDEV(4)),
},
+ {
+ .callback = sof_rt5682_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
+ DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
+ },
+ .driver_data = (void *)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_MAX98373_SPEAKER_AMP_PRESENT |
+ SOF_RT5682_SSP_AMP(2) |
+ SOF_RT5682_NUM_HDMIDEV(4)),
+ },
{}
};
@@ -456,10 +470,6 @@ static const struct snd_kcontrol_new sof_controls[] = {
};
-static const struct snd_kcontrol_new speaker_controls[] = {
- SOC_DAPM_PIN_SWITCH("Spk"),
-};
-
static const struct snd_soc_dapm_widget sof_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -467,10 +477,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = {
SND_SOC_DAPM_SPK("Right Spk", NULL),
};
-static const struct snd_soc_dapm_widget speaker_widgets[] = {
- SND_SOC_DAPM_SPK("Spk", NULL),
-};
-
static const struct snd_soc_dapm_widget dmic_widgets[] = {
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
};
@@ -484,11 +490,6 @@ static const struct snd_soc_dapm_route sof_map[] = {
{ "IN1P", NULL, "Headset Mic" },
};
-static const struct snd_soc_dapm_route speaker_map[] = {
- /* speaker */
- { "Spk", NULL, "Speaker" },
-};
-
static const struct snd_soc_dapm_route speaker_map_lr[] = {
{ "Left Spk", NULL, "Left SPO" },
{ "Right Spk", NULL, "Right SPO" },
@@ -505,34 +506,6 @@ static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd)
ARRAY_SIZE(speaker_map_lr));
}
-static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_card *card = rtd->card;
- int ret;
-
- ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets,
- ARRAY_SIZE(speaker_widgets));
- if (ret) {
- dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
- /* Don't need to add routes if widget addition failed */
- return ret;
- }
-
- ret = snd_soc_add_card_controls(card, speaker_controls,
- ARRAY_SIZE(speaker_controls));
- if (ret) {
- dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map,
- ARRAY_SIZE(speaker_map));
-
- if (ret)
- dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
- return ret;
-}
-
static int dmic_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
@@ -594,13 +567,6 @@ static struct snd_soc_dai_link_component dmic_component[] = {
}
};
-static struct snd_soc_dai_link_component max98360a_component[] = {
- {
- .name = "MX98360A:00",
- .dai_name = "HiFi",
- }
-};
-
static struct snd_soc_dai_link_component rt1015_components[] = {
{
.name = "i2c-10EC1015:00",
@@ -775,9 +741,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].dpcm_capture = 1;
} else if (sof_rt5682_quirk &
SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
- links[id].codecs = max98360a_component;
- links[id].num_codecs = ARRAY_SIZE(max98360a_component);
- links[id].init = speaker_codec_init;
+ max_98360a_dai_link(&links[id]);
} else if (sof_rt5682_quirk &
SOF_RT1011_SPEAKER_AMP_PRESENT) {
sof_rt1011_dai_link(&links[id]);
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index e9118234b30e..6602eda89e8e 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -13,8 +13,9 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
+#include "../../codecs/rt711.h"
-unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1;
+unsigned long sof_sdw_quirk = RT711_JD1;
static int quirk_override = -1;
module_param_named(quirk, quirk_override, int, 0444);
MODULE_PARM_DESC(quirk, "Board-specific quirk override");
@@ -63,7 +64,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
},
- .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+ .driver_data = (void *)(RT711_JD2 |
SOF_RT715_DAI_ID_FIX),
},
{
@@ -73,7 +74,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
},
- .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+ .driver_data = (void *)(RT711_JD2 |
SOF_RT715_DAI_ID_FIX),
},
{
@@ -82,7 +83,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
},
- .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+ .driver_data = (void *)(RT711_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
@@ -92,7 +93,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
},
- .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+ .driver_data = (void *)(RT711_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
@@ -114,7 +115,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
"Tiger Lake Client Platform"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_RT711_JD_SRC_JD1 |
+ RT711_JD1 |
SOF_SDW_PCH_DMIC |
SOF_SSP_PORT(SOF_I2S_SSP2)),
},
@@ -125,17 +126,29 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_RT711_JD_SRC_JD2 |
+ RT711_JD2 |
SOF_RT715_DAI_ID_FIX),
},
{
+ /* Dell XPS 9710 */
+ .callback = sof_sdw_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D")
+ },
+ .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+ RT711_JD2 |
+ SOF_RT715_DAI_ID_FIX |
+ SOF_SDW_FOUR_SPK),
+ },
+ {
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_RT711_JD_SRC_JD2 |
+ RT711_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
@@ -175,7 +188,18 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_SDW_PCH_DMIC |
- SOF_RT711_JD_SRC_JD2),
+ RT711_JD2),
+ },
+ {
+ /* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */
+ .callback = sof_sdw_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"),
+ },
+ .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+ SOF_SDW_PCH_DMIC |
+ RT711_JD1),
},
/* TigerLake-SDCA devices */
{
@@ -185,7 +209,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32")
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_RT711_JD_SRC_JD2 |
+ RT711_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
@@ -196,7 +220,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
},
- .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
+ .driver_data = (void *)(RT711_JD2_100K |
SOF_SDW_TGL_HDMI |
SOF_RT715_DAI_ID_FIX |
SOF_BT_OFFLOAD_SSP(2) |
@@ -328,6 +352,20 @@ static const struct snd_soc_ops sdw_ops = {
.shutdown = sdw_shutdown,
};
+static int sof_sdw_mic_codec_mockup_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links,
+ struct sof_sdw_codec_info *info,
+ bool playback)
+{
+ /*
+ * force DAI link to use same ID as RT715 and DMIC
+ * to reuse topologies
+ */
+ dai_links->id = SDW_DMIC_DAI_ID;
+ return 0;
+}
+
static struct sof_sdw_codec_info codec_info_list[] = {
{
.part_id = 0x700,
@@ -410,6 +448,34 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.dai_name = "rt5682-sdw",
.init = sof_sdw_rt5682_init,
},
+ {
+ .part_id = 0xaaaa, /* generic codec mockup */
+ .version_id = 0,
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .init = NULL,
+ },
+ {
+ .part_id = 0xaa55, /* headset codec mockup */
+ .version_id = 0,
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .init = NULL,
+ },
+ {
+ .part_id = 0x55aa, /* amplifier mockup */
+ .version_id = 0,
+ .direction = {true, false},
+ .dai_name = "sdw-mockup-aif1",
+ .init = NULL,
+ },
+ {
+ .part_id = 0x5555,
+ .version_id = 0,
+ .direction = {false, true},
+ .dai_name = "sdw-mockup-aif1",
+ .init = sof_sdw_mic_codec_mockup_init,
+ },
};
static inline int find_codec_info_part(u64 adr)
@@ -600,13 +666,13 @@ static int create_codec_dai_name(struct device *dev,
comp_index = i + offset;
if (is_unique_device(link, sdw_version, mfg_id, part_id,
class_id, i)) {
- codec_str = "sdw:%x:%x:%x:%x";
+ codec_str = "sdw:%01x:%04x:%04x:%02x";
codec[comp_index].name =
devm_kasprintf(dev, GFP_KERNEL, codec_str,
link_id, mfg_id, part_id,
class_id);
} else {
- codec_str = "sdw:%x:%x:%x:%x:%x";
+ codec_str = "sdw:%01x:%04x:%04x:%02x:%01x";
codec[comp_index].name =
devm_kasprintf(dev, GFP_KERNEL, codec_str,
link_id, mfg_id, part_id,
@@ -632,7 +698,8 @@ static int create_codec_dai_name(struct device *dev,
return 0;
}
-static int set_codec_init_func(const struct snd_soc_acpi_link_adr *link,
+static int set_codec_init_func(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
bool playback, int group_id)
{
@@ -655,7 +722,8 @@ static int set_codec_init_func(const struct snd_soc_acpi_link_adr *link,
if (link->adr_d[i].endpoints->group_id != group_id)
continue;
if (codec_info_list[codec_index].init)
- codec_info_list[codec_index].init(link,
+ codec_info_list[codec_index].init(card,
+ link,
dai_links,
&codec_info_list[codec_index],
playback);
@@ -740,7 +808,8 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
return 0;
}
-static int create_sdw_dailink(struct device *dev, int *be_index,
+static int create_sdw_dailink(struct snd_soc_card *card,
+ struct device *dev, int *be_index,
struct snd_soc_dai_link *dai_links,
int sdw_be_num, int sdw_cpu_dai_num,
struct snd_soc_dai_link_component *cpus,
@@ -861,7 +930,7 @@ static int create_sdw_dailink(struct device *dev, int *be_index,
codecs, codec_num,
NULL, &sdw_ops);
- ret = set_codec_init_func(link, dai_links + (*be_index)++,
+ ret = set_codec_init_func(card, link, dai_links + (*be_index)++,
playback, group_id);
if (ret < 0) {
dev_err(dev, "failed to init codec %d", codec_index);
@@ -1042,7 +1111,7 @@ static int sof_card_dai_links_create(struct device *dev,
group_generated[endpoint->group_id])
continue;
- ret = create_sdw_dailink(dev, &be_id, links, sdw_be_num,
+ ret = create_sdw_dailink(card, dev, &be_id, links, sdw_be_num,
sdw_cpu_dai_num, cpus, adr_link,
&cpu_id, group_generated,
codec_conf, codec_conf_count,
@@ -1105,7 +1174,7 @@ SSP:
ssp_components, 1,
NULL, info->ops);
- ret = info->init(NULL, links + link_id, info, 0);
+ ret = info->init(card, NULL, links + link_id, info, 0);
if (ret < 0)
return ret;
@@ -1328,7 +1397,7 @@ static int mc_remove(struct platform_device *pdev)
for_each_card_prelinks(card, j, link) {
if (!strcmp(link->codecs[0].dai_name,
codec_info_list[i].dai_name)) {
- ret = codec_info_list[i].exit(&pdev->dev, link);
+ ret = codec_info_list[i].exit(card, link);
if (ret)
dev_warn(&pdev->dev,
"codec exit failed %d\n",
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index ec5740486b75..b35f5a9b96f5 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -23,11 +23,6 @@
#define SDW_MAX_GROUPS 9
enum {
- SOF_RT711_JD_SRC_JD1 = 1,
- SOF_RT711_JD_SRC_JD2 = 2,
-};
-
-enum {
SOF_PRE_TGL_HDMI_COUNT = 3,
SOF_TGL_HDMI_COUNT = 4,
};
@@ -41,21 +36,21 @@ enum {
SOF_I2S_SSP5 = BIT(5),
};
-#define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(1, 0))
-#define SOF_SDW_FOUR_SPK BIT(2)
-#define SOF_SDW_TGL_HDMI BIT(3)
-#define SOF_SDW_PCH_DMIC BIT(4)
-#define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 5)
-#define SOF_SSP_GET_PORT(quirk) (((quirk) >> 5) & GENMASK(5, 0))
-#define SOF_RT715_DAI_ID_FIX BIT(11)
-#define SOF_SDW_NO_AGGREGATION BIT(12)
+#define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
+#define SOF_SDW_FOUR_SPK BIT(4)
+#define SOF_SDW_TGL_HDMI BIT(5)
+#define SOF_SDW_PCH_DMIC BIT(6)
+#define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 7)
+#define SOF_SSP_GET_PORT(quirk) (((quirk) >> 7) & GENMASK(5, 0))
+#define SOF_RT715_DAI_ID_FIX BIT(13)
+#define SOF_SDW_NO_AGGREGATION BIT(14)
/* BT audio offload: reserve 3 bits for future */
-#define SOF_BT_OFFLOAD_SSP_SHIFT 13
-#define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(15, 13))
+#define SOF_BT_OFFLOAD_SSP_SHIFT 15
+#define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(17, 15))
#define SOF_BT_OFFLOAD_SSP(quirk) \
(((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
-#define SOF_SSP_BT_OFFLOAD_PRESENT BIT(16)
+#define SOF_SSP_BT_OFFLOAD_PRESENT BIT(18)
struct sof_sdw_codec_info {
const int part_id;
@@ -67,12 +62,13 @@ struct sof_sdw_codec_info {
const char *dai_name;
const struct snd_soc_ops *ops;
- int (*init)(const struct snd_soc_acpi_link_adr *link,
+ int (*init)(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
- int (*exit)(struct device *dev, struct snd_soc_dai_link *dai_link);
+ int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
bool late_probe;
int (*codec_card_late_probe)(struct snd_soc_card *card);
};
@@ -81,6 +77,7 @@ struct mc_private {
struct list_head hdmi_pcm_list;
bool idisp_codec;
struct snd_soc_jack sdw_headset;
+ struct device *headset_codec_dev; /* only one headset per card */
};
extern unsigned long sof_sdw_quirk;
@@ -100,21 +97,24 @@ int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card);
int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
/* RT711 support */
-int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt711_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
-int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link);
+int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
/* RT711-SDCA support */
-int sof_sdw_rt711_sdca_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt711_sdca_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
-int sof_sdw_rt711_sdca_exit(struct device *dev, struct snd_soc_dai_link *dai_link);
+int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
/* RT700 support */
-int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt700_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
@@ -122,31 +122,36 @@ int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
/* RT1308 support */
extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops;
-int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt1308_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT1316 support */
-int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt1316_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT715 support */
-int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt715_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT715-SDCA support */
-int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt715_sdca_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* MAX98373 support */
-int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_mx8373_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
@@ -154,7 +159,8 @@ int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link,
int sof_sdw_mx8373_late_probe(struct snd_soc_card *card);
/* RT5682 support */
-int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt5682_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_max98373.c
index 25daef910aee..77a3f32db11e 100644
--- a/sound/soc/intel/boards/sof_sdw_max98373.c
+++ b/sound/soc/intel/boards/sof_sdw_max98373.c
@@ -90,7 +90,7 @@ static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enabl
static int mx8373_sdw_prepare(struct snd_pcm_substream *substream)
{
- int ret = 0;
+ int ret;
/* according to soc_pcm_prepare dai link prepare is called first */
ret = sdw_prepare(substream);
@@ -102,7 +102,7 @@ static int mx8373_sdw_prepare(struct snd_pcm_substream *substream)
static int mx8373_sdw_hw_free(struct snd_pcm_substream *substream)
{
- int ret = 0;
+ int ret;
/* according to soc_pcm_hw_free dai link free is called first */
ret = sdw_hw_free(substream);
@@ -120,7 +120,8 @@ static const struct snd_soc_ops max_98373_sdw_ops = {
.shutdown = sdw_shutdown,
};
-int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_mx8373_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c
index 0d476f6f6313..f078fb1aad02 100644
--- a/sound/soc/intel/boards/sof_sdw_rt1308.c
+++ b/sound/soc/intel/boards/sof_sdw_rt1308.c
@@ -127,7 +127,8 @@ struct snd_soc_ops sof_sdw_rt1308_i2s_ops = {
.hw_params = rt1308_i2s_hw_params,
};
-int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt1308_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c
index d6e1ebf18d57..58194b380232 100644
--- a/sound/soc/intel/boards/sof_sdw_rt1316.c
+++ b/sound/soc/intel/boards/sof_sdw_rt1316.c
@@ -89,7 +89,8 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd)
return second_spk_init(rtd);
}
-int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt1316_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/intel/boards/sof_sdw_rt5682.c
index 5fa1a59615b6..ea55479609a8 100644
--- a/sound/soc/intel/boards/sof_sdw_rt5682.c
+++ b/sound/soc/intel/boards/sof_sdw_rt5682.c
@@ -111,7 +111,8 @@ static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
-int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt5682_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/intel/boards/sof_sdw_rt700.c
index 21e7e4a81779..bb9584c8f866 100644
--- a/sound/soc/intel/boards/sof_sdw_rt700.c
+++ b/sound/soc/intel/boards/sof_sdw_rt700.c
@@ -110,7 +110,8 @@ static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
-int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt700_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c
index 04074c09dded..c38b70c9fac3 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711.c
@@ -21,23 +21,23 @@
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int rt711_add_codec_device_props(const char *sdw_dev_name)
+static int rt711_add_codec_device_props(struct device *sdw_dev)
{
struct property_entry props[MAX_NO_PROPS] = {};
- struct device *sdw_dev;
+ struct fwnode_handle *fwnode;
int ret;
- sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name);
- if (!sdw_dev)
- return -EPROBE_DEFER;
+ if (!SOF_RT711_JDSRC(sof_sdw_quirk))
+ return 0;
+ props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk));
- if (SOF_RT711_JDSRC(sof_sdw_quirk)) {
- props[0] = PROPERTY_ENTRY_U32("realtek,jd-src",
- SOF_RT711_JDSRC(sof_sdw_quirk));
- }
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode))
+ return PTR_ERR(fwnode);
+
+ ret = device_add_software_node(sdw_dev, to_software_node(fwnode));
- ret = device_add_properties(sdw_dev, props);
- put_device(sdw_dev);
+ fwnode_handle_put(fwnode);
return ret;
}
@@ -135,26 +135,24 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
-int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link)
+int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
- struct device *sdw_dev;
-
- sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL,
- dai_link->codecs[0].name);
- if (!sdw_dev)
- return -EINVAL;
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
- device_remove_properties(sdw_dev);
- put_device(sdw_dev);
+ device_remove_software_node(ctx->headset_codec_dev);
+ put_device(ctx->headset_codec_dev);
return 0;
}
-int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt711_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct device *sdw_dev;
int ret;
/*
@@ -164,9 +162,16 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
if (!playback)
return 0;
- ret = rt711_add_codec_device_props(dai_links->codecs[0].name);
- if (ret < 0)
+ sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name);
+ if (!sdw_dev)
+ return -EPROBE_DEFER;
+
+ ret = rt711_add_codec_device_props(sdw_dev);
+ if (ret < 0) {
+ put_device(sdw_dev);
return ret;
+ }
+ ctx->headset_codec_dev = sdw_dev;
dai_links->init = rt711_rtd_init;
diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
index 19496f0f9110..4215ddc36419 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
@@ -21,23 +21,24 @@
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int rt711_sdca_add_codec_device_props(const char *sdw_dev_name)
+static int rt711_sdca_add_codec_device_props(struct device *sdw_dev)
{
struct property_entry props[MAX_NO_PROPS] = {};
- struct device *sdw_dev;
+ struct fwnode_handle *fwnode;
int ret;
- sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name);
- if (!sdw_dev)
- return -EPROBE_DEFER;
+ if (!SOF_RT711_JDSRC(sof_sdw_quirk))
+ return 0;
- if (SOF_RT711_JDSRC(sof_sdw_quirk)) {
- props[0] = PROPERTY_ENTRY_U32("realtek,jd-src",
- SOF_RT711_JDSRC(sof_sdw_quirk));
- }
+ props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk));
- ret = device_add_properties(sdw_dev, props);
- put_device(sdw_dev);
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode))
+ return PTR_ERR(fwnode);
+
+ ret = device_add_software_node(sdw_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
return ret;
}
@@ -135,26 +136,24 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
-int sof_sdw_rt711_sdca_exit(struct device *dev, struct snd_soc_dai_link *dai_link)
+int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
- struct device *sdw_dev;
-
- sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL,
- dai_link->codecs[0].name);
- if (!sdw_dev)
- return -EINVAL;
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
- device_remove_properties(sdw_dev);
- put_device(sdw_dev);
+ device_remove_software_node(ctx->headset_codec_dev);
+ put_device(ctx->headset_codec_dev);
return 0;
}
-int sof_sdw_rt711_sdca_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt711_sdca_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct device *sdw_dev;
int ret;
/*
@@ -164,9 +163,16 @@ int sof_sdw_rt711_sdca_init(const struct snd_soc_acpi_link_adr *link,
if (!playback)
return 0;
- ret = rt711_sdca_add_codec_device_props(dai_links->codecs[0].name);
- if (ret < 0)
+ sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name);
+ if (!sdw_dev)
+ return -EPROBE_DEFER;
+
+ ret = rt711_sdca_add_codec_device_props(sdw_dev);
+ if (ret < 0) {
+ put_device(sdw_dev);
return ret;
+ }
+ ctx->headset_codec_dev = sdw_dev;
dai_links->init = rt711_sdca_rtd_init;
diff --git a/sound/soc/intel/boards/sof_sdw_rt715.c b/sound/soc/intel/boards/sof_sdw_rt715.c
index 9b298f79e784..c8af3780cbc3 100644
--- a/sound/soc/intel/boards/sof_sdw_rt715.c
+++ b/sound/soc/intel/boards/sof_sdw_rt715.c
@@ -24,7 +24,8 @@ static int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
-int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt715_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c
index c056e56a139b..85d3d8c355cc 100644
--- a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c
+++ b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c
@@ -24,7 +24,8 @@ static int rt715_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
-int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link,
+int sof_sdw_rt715_sdca_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index 12a205ccdeeb..fef0b2d1de68 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -9,7 +9,8 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \
soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \
soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \
- soc-acpi-intel-hda-match.o
+ soc-acpi-intel-hda-match.o \
+ soc-acpi-intel-sdw-mockup-match.o
obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
index 39dad32564e6..94b650767e11 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
@@ -9,6 +9,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#include "../skylake/skl.h"
+#include "soc-acpi-intel-sdw-mockup-match.h"
static struct skl_machine_pdata cnl_pdata = {
.use_tplg_pcm = true,
@@ -60,6 +61,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[] = {
.sof_fw_filename = "sof-cnl.ri",
.sof_tplg_filename = "sof-cnl-rt5682-sdw2.tplg"
},
+ {
+ .link_mask = GENMASK(3, 0),
+ .links = sdw_mockup_headset_2amps_mic,
+ .drv_name = "sof_sdw",
+ .sof_fw_filename = "sof-cnl.ri",
+ .sof_tplg_filename = "sof-cml-rt711-rt1308-rt715.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = sdw_mockup_headset_1amp_mic,
+ .drv_name = "sof_sdw",
+ .sof_fw_filename = "sof-cnl.ri",
+ .sof_tplg_filename = "sof-cml-rt711-rt1308-mono-rt715.tplg",
+ },
{}
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
index 3586ce72c42c..69ff7286d357 100644
--- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
@@ -73,6 +73,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.quirk_data = &mx98360a_spk,
.sof_tplg_filename = "sof-jsl-rt5682-mx98360a.tplg",
},
+ {
+ .id = "10134242",
+ .drv_name = "jsl_cs4242_mx98360a",
+ .sof_fw_filename = "sof-jsl.ri",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &mx98360a_spk,
+ .sof_tplg_filename = "sof-jsl-cs42l42-mx98360a.tplg",
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c
new file mode 100644
index 000000000000..a3d33997736a
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// soc-acpi-intel-sdw-mockup-match.c - tables and support for SoundWire
+// mockup device ACPI enumeration.
+//
+// Copyright (c) 2021, Intel Corporation.
+//
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include "soc-acpi-intel-sdw-mockup-match.h"
+
+static const struct snd_soc_acpi_endpoint sdw_mockup_single_endpoint = {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+};
+
+static const struct snd_soc_acpi_endpoint sdw_mockup_l_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint sdw_mockup_r_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_headset_0_adr[] = {
+ {
+ .adr = 0x0000000105AA5500ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_headset0"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_headset_1_adr[] = {
+ {
+ .adr = 0x0001000105AA5500ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_headset1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_amp_1_adr[] = {
+ {
+ .adr = 0x000100010555AA00ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_amp1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_amp_2_adr[] = {
+ {
+ .adr = 0x000200010555AA00ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_amp2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_mic_0_adr[] = {
+ {
+ .adr = 0x0000000105555500ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_mic0"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_mic_3_adr[] = {
+ {
+ .adr = 0x0003000105555500ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_single_endpoint,
+ .name_prefix = "sdw_mockup_mic3"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_amp_1_group1_adr[] = {
+ {
+ .adr = 0x000100010555AA00ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_l_endpoint,
+ .name_prefix = "sdw_mockup_amp1_l"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device sdw_mockup_amp_2_group1_adr[] = {
+ {
+ .adr = 0x000200010555AA00ull,
+ .num_endpoints = 1,
+ .endpoints = &sdw_mockup_r_endpoint,
+ .name_prefix = "sdw_mockup_amp2_r"
+ }
+};
+
+const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(sdw_mockup_headset_0_adr),
+ .adr_d = sdw_mockup_headset_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(sdw_mockup_amp_1_adr),
+ .adr_d = sdw_mockup_amp_1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(sdw_mockup_mic_3_adr),
+ .adr_d = sdw_mockup_mic_3_adr,
+ },
+ {}
+};
+
+const struct snd_soc_acpi_link_adr sdw_mockup_headset_2amps_mic[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(sdw_mockup_headset_0_adr),
+ .adr_d = sdw_mockup_headset_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(sdw_mockup_amp_1_group1_adr),
+ .adr_d = sdw_mockup_amp_1_group1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(sdw_mockup_amp_2_group1_adr),
+ .adr_d = sdw_mockup_amp_2_group1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(sdw_mockup_mic_3_adr),
+ .adr_d = sdw_mockup_mic_3_adr,
+ },
+ {}
+};
+
+const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(sdw_mockup_headset_1_adr),
+ .adr_d = sdw_mockup_headset_1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(sdw_mockup_amp_2_adr),
+ .adr_d = sdw_mockup_amp_2_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(sdw_mockup_mic_0_adr),
+ .adr_d = sdw_mockup_mic_0_adr,
+ },
+ {}
+};
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h
new file mode 100644
index 000000000000..c99eecd19e03
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * soc-acpi-intel-sdw-mockup-match.h - tables and support for SoundWire
+ * mockup device ACPI enumeration.
+ *
+ * Copyright (c) 2021, Intel Corporation.
+ *
+ */
+
+#ifndef _SND_SOC_ACPI_INTEL_SDW_MOCKUP_MATCH
+#define _SND_SOC_ACPI_INTEL_SDW_MOCKUP_MATCH
+
+extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[];
+extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_2amps_mic[];
+extern const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[];
+
+#endif
diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
index 66595e3ab13f..785d5f5f8a9c 100644
--- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
@@ -8,6 +8,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include "soc-acpi-intel-sdw-mockup-match.h"
static const struct snd_soc_acpi_codecs tgl_codecs = {
.num_codecs = 1,
@@ -196,6 +197,15 @@ static const struct snd_soc_acpi_link_adr tgl_rvp[] = {
{}
};
+static const struct snd_soc_acpi_link_adr tgl_rvp_headset_only[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr_d = rt711_0_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr tgl_hp[] = {
{
.mask = BIT(0),
@@ -351,6 +361,28 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
+ /* mockup tests need to be first */
+ {
+ .link_mask = GENMASK(3, 0),
+ .links = sdw_mockup_headset_2amps_mic,
+ .drv_name = "sof_sdw",
+ .sof_fw_filename = "sof-tgl.ri",
+ .sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = sdw_mockup_headset_1amp_mic,
+ .drv_name = "sof_sdw",
+ .sof_fw_filename = "sof-tgl.ri",
+ .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(2),
+ .links = sdw_mockup_mic_headset_1amp,
+ .drv_name = "sof_sdw",
+ .sof_fw_filename = "sof-tgl.ri",
+ .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg",
+ },
{
.link_mask = 0x7,
.links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0,
@@ -398,6 +430,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg",
},
+ {
+ .link_mask = 0x1, /* rt711 on link 0 */
+ .links = tgl_rvp_headset_only,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-tgl-rt711.tplg",
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 476ef1897961..eaad180af42e 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -472,6 +472,75 @@ static void skl_set_base_module_format(struct skl_dev *skl,
base_cfg->is_pages = res->is_pages;
}
+static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
+ struct skl_module_fmt *format)
+{
+ pin_fmt->number_of_channels = format->channels;
+ pin_fmt->s_freq = format->s_freq;
+ pin_fmt->bit_depth = format->bit_depth;
+ pin_fmt->valid_bit_depth = format->valid_bit_depth;
+ pin_fmt->ch_cfg = format->ch_cfg;
+ pin_fmt->sample_type = format->sample_type;
+ pin_fmt->channel_map = format->ch_map;
+ pin_fmt->interleaving = format->interleaving_style;
+}
+
+/*
+ * Any module configuration begins with a base module configuration but
+ * can be followed by a generic extension containing audio format for all
+ * module's pins that are in use.
+ */
+static void skl_set_base_ext_module_format(struct skl_dev *skl,
+ struct skl_module_cfg *mconfig,
+ struct skl_base_cfg_ext *base_cfg_ext)
+{
+ struct skl_module *module = mconfig->module;
+ struct skl_module_pin_resources *pin_res;
+ struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
+ struct skl_module_res *res = &module->resources[mconfig->res_idx];
+ struct skl_module_fmt *format;
+ struct skl_pin_format *pin_fmt;
+ char *params;
+ int i;
+
+ base_cfg_ext->nr_input_pins = res->nr_input_pins;
+ base_cfg_ext->nr_output_pins = res->nr_output_pins;
+ base_cfg_ext->priv_param_length =
+ mconfig->formats_config[SKL_PARAM_INIT].caps_size;
+
+ for (i = 0; i < res->nr_input_pins; i++) {
+ pin_res = &res->input[i];
+ pin_fmt = &base_cfg_ext->pins_fmt[i];
+
+ pin_fmt->pin_idx = pin_res->pin_index;
+ pin_fmt->buf_size = pin_res->buf_size;
+
+ format = &fmt->inputs[pin_res->pin_index].fmt;
+ fill_pin_params(&pin_fmt->audio_fmt, format);
+ }
+
+ for (i = 0; i < res->nr_output_pins; i++) {
+ pin_res = &res->output[i];
+ pin_fmt = &base_cfg_ext->pins_fmt[res->nr_input_pins + i];
+
+ pin_fmt->pin_idx = pin_res->pin_index;
+ pin_fmt->buf_size = pin_res->buf_size;
+
+ format = &fmt->outputs[pin_res->pin_index].fmt;
+ fill_pin_params(&pin_fmt->audio_fmt, format);
+ }
+
+ if (!base_cfg_ext->priv_param_length)
+ return;
+
+ params = (char *)base_cfg_ext + sizeof(struct skl_base_cfg_ext);
+ params += (base_cfg_ext->nr_input_pins + base_cfg_ext->nr_output_pins) *
+ sizeof(struct skl_pin_format);
+
+ memcpy(params, mconfig->formats_config[SKL_PARAM_INIT].caps,
+ mconfig->formats_config[SKL_PARAM_INIT].caps_size);
+}
+
/*
* Copies copier capabilities into copier module and updates copier module
* config size.
@@ -479,15 +548,15 @@ static void skl_set_base_module_format(struct skl_dev *skl,
static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
struct skl_cpr_cfg *cpr_mconfig)
{
- if (mconfig->formats_config.caps_size == 0)
+ if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
return;
memcpy(cpr_mconfig->gtw_cfg.config_data,
- mconfig->formats_config.caps,
- mconfig->formats_config.caps_size);
+ mconfig->formats_config[SKL_PARAM_INIT].caps,
+ mconfig->formats_config[SKL_PARAM_INIT].caps_size);
cpr_mconfig->gtw_cfg.config_length =
- (mconfig->formats_config.caps_size) / 4;
+ (mconfig->formats_config[SKL_PARAM_INIT].caps_size) / 4;
}
#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
@@ -738,28 +807,6 @@ static void skl_set_copier_format(struct skl_dev *skl,
}
/*
- * Algo module are DSP pre processing modules. Algo module take base module
- * configuration and params
- */
-
-static void skl_set_algo_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_algo_cfg *algo_mcfg)
-{
- struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
-
- skl_set_base_module_format(skl, mconfig, base_cfg);
-
- if (mconfig->formats_config.caps_size == 0)
- return;
-
- memcpy(algo_mcfg->params,
- mconfig->formats_config.caps,
- mconfig->formats_config.caps_size);
-
-}
-
-/*
* Mic select module allows selecting one or many input channels, thus
* acting as a demux.
*
@@ -781,12 +828,14 @@ static void skl_set_base_outfmt_format(struct skl_dev *skl,
static u16 skl_get_module_param_size(struct skl_dev *skl,
struct skl_module_cfg *mconfig)
{
+ struct skl_module_res *res;
+ struct skl_module *module = mconfig->module;
u16 param_size;
switch (mconfig->m_type) {
case SKL_MODULE_TYPE_COPIER:
param_size = sizeof(struct skl_cpr_cfg);
- param_size += mconfig->formats_config.caps_size;
+ param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
return param_size;
case SKL_MODULE_TYPE_SRCINT:
@@ -795,22 +844,24 @@ static u16 skl_get_module_param_size(struct skl_dev *skl,
case SKL_MODULE_TYPE_UPDWMIX:
return sizeof(struct skl_up_down_mixer_cfg);
- case SKL_MODULE_TYPE_ALGO:
- param_size = sizeof(struct skl_base_cfg);
- param_size += mconfig->formats_config.caps_size;
- return param_size;
-
case SKL_MODULE_TYPE_BASE_OUTFMT:
case SKL_MODULE_TYPE_MIC_SELECT:
- case SKL_MODULE_TYPE_KPB:
return sizeof(struct skl_base_outfmt_cfg);
- default:
- /*
- * return only base cfg when no specific module type is
- * specified
- */
+ case SKL_MODULE_TYPE_MIXER:
+ case SKL_MODULE_TYPE_KPB:
return sizeof(struct skl_base_cfg);
+
+ case SKL_MODULE_TYPE_ALGO:
+ default:
+ res = &module->resources[mconfig->res_idx];
+
+ param_size = sizeof(struct skl_base_cfg) + sizeof(struct skl_base_cfg_ext);
+ param_size += (res->nr_input_pins + res->nr_output_pins) *
+ sizeof(struct skl_pin_format);
+ param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
+
+ return param_size;
}
return 0;
@@ -851,20 +902,23 @@ static int skl_set_module_format(struct skl_dev *skl,
skl_set_updown_mixer_format(skl, module_config, *param_data);
break;
- case SKL_MODULE_TYPE_ALGO:
- skl_set_algo_format(skl, module_config, *param_data);
- break;
-
case SKL_MODULE_TYPE_BASE_OUTFMT:
case SKL_MODULE_TYPE_MIC_SELECT:
- case SKL_MODULE_TYPE_KPB:
skl_set_base_outfmt_format(skl, module_config, *param_data);
break;
- default:
+ case SKL_MODULE_TYPE_MIXER:
+ case SKL_MODULE_TYPE_KPB:
skl_set_base_module_format(skl, module_config, *param_data);
break;
+ case SKL_MODULE_TYPE_ALGO:
+ default:
+ skl_set_base_module_format(skl, module_config, *param_data);
+ skl_set_base_ext_module_format(skl, module_config,
+ *param_data +
+ sizeof(struct skl_base_cfg));
+ break;
}
dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
@@ -1085,19 +1139,6 @@ int skl_unbind_modules(struct skl_dev *skl,
return ret;
}
-static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
- struct skl_module_fmt *format)
-{
- pin_fmt->number_of_channels = format->channels;
- pin_fmt->s_freq = format->s_freq;
- pin_fmt->bit_depth = format->bit_depth;
- pin_fmt->valid_bit_depth = format->valid_bit_depth;
- pin_fmt->ch_cfg = format->ch_cfg;
- pin_fmt->sample_type = format->sample_type;
- pin_fmt->channel_map = format->ch_map;
- pin_fmt->interleaving = format->interleaving_style;
-}
-
#define CPR_SINK_FMT_PARAM_ID 2
/*
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index b1ca64d2f7ea..9ecaf6a1e847 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -1214,13 +1214,6 @@ static snd_pcm_uframes_t skl_platform_soc_pointer(
return bytes_to_frames(substream->runtime, pos);
}
-static int skl_platform_soc_mmap(struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- struct vm_area_struct *area)
-{
- return snd_pcm_lib_default_mmap(substream, area);
-}
-
static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
u64 nsec)
{
@@ -1317,21 +1310,6 @@ static int skl_get_module_info(struct skl_dev *skl,
return -EIO;
}
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (guid_equal(uuid_mod, &module->uuid)) {
- mconfig->id.module_id = module->id;
- if (mconfig->module)
- mconfig->module->loadable = module->is_loadable;
- ret = 0;
- break;
- }
- }
-
- if (ret)
- return ret;
-
- uuid_mod = &module->uuid;
- ret = -EIO;
for (i = 0; i < skl->nr_modules; i++) {
skl_module = skl->modules[i];
uuid_tplg = &skl_module->uuid;
@@ -1341,10 +1319,18 @@ static int skl_get_module_info(struct skl_dev *skl,
break;
}
}
+
if (skl->nr_modules && ret)
return ret;
+ ret = -EIO;
list_for_each_entry(module, &skl->uuid_list, list) {
+ if (guid_equal(uuid_mod, &module->uuid)) {
+ mconfig->id.module_id = module->id;
+ mconfig->module->loadable = module->is_loadable;
+ ret = 0;
+ }
+
for (i = 0; i < MAX_IN_QUEUE; i++) {
pin_id = &mconfig->m_in_pin[i].id;
if (guid_equal(&pin_id->mod_uuid, &module->uuid))
@@ -1358,7 +1344,7 @@ static int skl_get_module_info(struct skl_dev *skl,
}
}
- return 0;
+ return ret;
}
static int skl_populate_modules(struct skl_dev *skl)
@@ -1460,7 +1446,6 @@ static const struct snd_soc_component_driver skl_component = {
.trigger = skl_platform_soc_trigger,
.pointer = skl_platform_soc_pointer,
.get_time_info = skl_platform_soc_get_time_info,
- .mmap = skl_platform_soc_mmap,
.pcm_construct = skl_platform_soc_new,
.module_get_upon_open = 1, /* increment refcount when a pcm is opened */
};
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index c0fdab39e7c2..b036852d6889 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -113,7 +113,7 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg)
{
- struct skl_module_iface *iface = &mcfg->module->formats[0];
+ struct skl_module_iface *iface = &mcfg->module->formats[mcfg->fmt_idx];
dev_dbg(skl->dev, "Dumping config\n");
dev_dbg(skl->dev, "Input Format:\n");
@@ -195,8 +195,8 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
struct skl_module_fmt *in_fmt, *out_fmt;
/* Fixups will be applied to pin 0 only */
- in_fmt = &m_cfg->module->formats[0].inputs[0].fmt;
- out_fmt = &m_cfg->module->formats[0].outputs[0].fmt;
+ in_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].inputs[0].fmt;
+ out_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].outputs[0].fmt;
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (is_fe) {
@@ -239,9 +239,9 @@ static void skl_tplg_update_buffer_size(struct skl_dev *skl,
/* Since fixups is applied to pin 0 only, ibs, obs needs
* change for pin 0 only
*/
- res = &mcfg->module->resources[0];
- in_fmt = &mcfg->module->formats[0].inputs[0].fmt;
- out_fmt = &mcfg->module->formats[0].outputs[0].fmt;
+ res = &mcfg->module->resources[mcfg->res_idx];
+ in_fmt = &mcfg->module->formats[mcfg->fmt_idx].inputs[0].fmt;
+ out_fmt = &mcfg->module->formats[mcfg->fmt_idx].outputs[0].fmt;
if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
multiplier = 5;
@@ -292,7 +292,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx];
/* check if we already have blob */
- if (m_cfg->formats_config.caps_size > 0)
+ if (m_cfg->formats_config[SKL_PARAM_INIT].caps_size > 0)
return 0;
dev_dbg(skl->dev, "Applying default cfg blob\n");
@@ -328,8 +328,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type,
s_fmt, ch, s_freq, dir, dev_type);
if (cfg) {
- m_cfg->formats_config.caps_size = cfg->size;
- m_cfg->formats_config.caps = (u32 *) &cfg->caps;
+ m_cfg->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
+ m_cfg->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
} else {
dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n",
m_cfg->vbus_id, link_type, dir);
@@ -386,9 +386,9 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
struct skl_algo_data *bc;
struct skl_specific_cfg *sp_cfg;
- if (mconfig->formats_config.caps_size > 0 &&
- mconfig->formats_config.set_params == SKL_PARAM_SET) {
- sp_cfg = &mconfig->formats_config;
+ if (mconfig->formats_config[SKL_PARAM_SET].caps_size > 0 &&
+ mconfig->formats_config[SKL_PARAM_SET].set_params == SKL_PARAM_SET) {
+ sp_cfg = &mconfig->formats_config[SKL_PARAM_SET];
ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size,
sp_cfg->param_id, mconfig);
@@ -438,8 +438,10 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
if (bc->set_params != SKL_PARAM_INIT)
continue;
- mconfig->formats_config.caps = (u32 *)bc->params;
- mconfig->formats_config.caps_size = bc->size;
+ mconfig->formats_config[SKL_PARAM_INIT].caps =
+ (u32 *)bc->params;
+ mconfig->formats_config[SKL_PARAM_INIT].caps_size =
+ bc->size;
break;
}
@@ -498,8 +500,6 @@ skl_tplg_init_pipe_modules(struct skl_dev *skl, struct skl_pipe *pipe)
mconfig->id.module_id, mconfig->guid);
if (ret < 0)
return ret;
-
- mconfig->m_state = SKL_MODULE_LOADED;
}
/* prepare the DMA if the module is gateway cpr */
@@ -558,8 +558,7 @@ static int skl_tplg_unload_pipe_modules(struct skl_dev *skl,
mconfig = w_module->w->priv;
uuid_mod = (guid_t *)mconfig->guid;
- if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod &&
- mconfig->m_state > SKL_MODULE_UNINIT) {
+ if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod) {
ret = skl->dsp->fw_ops.unload_mod(skl->dsp,
mconfig->id.module_id);
if (ret < 0)
@@ -641,8 +640,9 @@ skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig)
return 0;
}
- if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) {
- dev_dbg(skl->dev, "No conn_type detected, take 0th config\n");
+ if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE || pipe->nr_cfgs == 1) {
+ dev_dbg(skl->dev, "No conn_type or just 1 pathcfg, taking 0th for %d\n",
+ pipe->ppl_id);
pipe->cur_config_idx = 0;
pipe->memory_pages = pconfig->mem_pages;
@@ -801,9 +801,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
return 0;
}
- if (mconfig->formats_config.caps_size > 0 &&
- mconfig->formats_config.set_params == SKL_PARAM_BIND) {
- sp_cfg = &mconfig->formats_config;
+ if (mconfig->formats_config[SKL_PARAM_BIND].caps_size > 0 &&
+ mconfig->formats_config[SKL_PARAM_BIND].set_params ==
+ SKL_PARAM_BIND) {
+ sp_cfg = &mconfig->formats_config[SKL_PARAM_BIND];
ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size,
sp_cfg->param_id, mconfig);
@@ -1463,12 +1464,6 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
if (ac->params) {
- /*
- * Widget data is expected to be stripped of T and L
- */
- size -= 2 * sizeof(unsigned int);
- data += 2;
-
if (size > ac->max)
return -EINVAL;
ac->size = size;
@@ -1505,7 +1500,8 @@ static int skl_tplg_mic_control_get(struct snd_kcontrol *kcontrol,
static int skl_fill_mic_sel_params(struct skl_module_cfg *mconfig,
struct skl_mic_sel_config *mic_cfg, struct device *dev)
{
- struct skl_specific_cfg *sp_cfg = &mconfig->formats_config;
+ struct skl_specific_cfg *sp_cfg =
+ &mconfig->formats_config[SKL_PARAM_INIT];
sp_cfg->caps_size = sizeof(struct skl_mic_sel_config);
sp_cfg->set_params = SKL_PARAM_SET;
@@ -1637,11 +1633,12 @@ int skl_tplg_update_pipe_params(struct device *dev,
struct skl_module_cfg *mconfig,
struct skl_pipe_params *params)
{
- struct skl_module_res *res = &mconfig->module->resources[0];
+ struct skl_module_res *res;
struct skl_dev *skl = get_skl_ctx(dev);
struct skl_module_fmt *format = NULL;
u8 cfg_idx = mconfig->pipe->cur_config_idx;
+ res = &mconfig->module->resources[mconfig->res_idx];
skl_tplg_fill_dma_id(mconfig, params);
mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx;
mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx;
@@ -1650,9 +1647,9 @@ int skl_tplg_update_pipe_params(struct device *dev,
return 0;
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
- format = &mconfig->module->formats[0].inputs[0].fmt;
+ format = &mconfig->module->formats[mconfig->fmt_idx].inputs[0].fmt;
else
- format = &mconfig->module->formats[0].outputs[0].fmt;
+ format = &mconfig->module->formats[mconfig->fmt_idx].outputs[0].fmt;
/* set the hw_params */
format->s_freq = params->s_freq;
@@ -1827,7 +1824,7 @@ static u8 skl_tplg_be_link_type(int dev_type)
* Fill the BE gateway parameters
* The BE gateway expects a blob of parameters which are kept in the ACPI
* NHLT blob, so query the blob for interface type (i2s/pdm) and instance.
- * The port can have multiple settings so pick based on the PCM
+ * The port can have multiple settings so pick based on the pipeline
* parameters
*/
static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
@@ -1835,6 +1832,8 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
struct skl_pipe_params *params)
{
struct nhlt_specific_cfg *cfg;
+ struct skl_pipe *pipe = mconfig->pipe;
+ struct skl_pipe_fmt *pipe_fmt;
struct skl_dev *skl = get_skl_ctx(dai->dev);
int link_type = skl_tplg_be_link_type(mconfig->dev_type);
u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type);
@@ -1844,20 +1843,23 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
if (link_type == NHLT_LINK_HDA)
return 0;
+ if (pipe->direction == SNDRV_PCM_STREAM_PLAYBACK)
+ pipe_fmt = &pipe->configs[pipe->pipe_config_idx].out_fmt;
+ else
+ pipe_fmt = &pipe->configs[pipe->pipe_config_idx].in_fmt;
+
/* update the blob based on virtual bus_id*/
cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
- params->s_fmt, params->ch,
- params->s_freq, params->stream,
+ pipe_fmt->bps, pipe_fmt->channels,
+ pipe_fmt->freq, pipe->direction,
dev_type);
if (cfg) {
- mconfig->formats_config.caps_size = cfg->size;
- mconfig->formats_config.caps = (u32 *) &cfg->caps;
+ mconfig->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
+ mconfig->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
} else {
- dev_err(dai->dev, "Blob NULL for id %x type %d dirn %d\n",
- mconfig->vbus_id, link_type,
- params->stream);
- dev_err(dai->dev, "PCM: ch %d, freq %d, fmt %d\n",
- params->ch, params->s_freq, params->s_fmt);
+ dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n",
+ mconfig->vbus_id, link_type, params->stream,
+ params->ch, params->s_freq, params->s_fmt);
return -EINVAL;
}
@@ -2570,19 +2572,26 @@ static int skl_tplg_get_token(struct device *dev,
break;
+ case SKL_TKN_U32_FMT_CFG_IDX:
+ if (tkn_elem->value > SKL_MAX_PARAMS_TYPES)
+ return -EINVAL;
+
+ mconfig->fmt_cfg_idx = tkn_elem->value;
+ break;
+
case SKL_TKN_U32_CAPS_SIZE:
- mconfig->formats_config.caps_size =
+ mconfig->formats_config[mconfig->fmt_cfg_idx].caps_size =
tkn_elem->value;
break;
case SKL_TKN_U32_CAPS_SET_PARAMS:
- mconfig->formats_config.set_params =
+ mconfig->formats_config[mconfig->fmt_cfg_idx].set_params =
tkn_elem->value;
break;
case SKL_TKN_U32_CAPS_PARAMS_ID:
- mconfig->formats_config.param_id =
+ mconfig->formats_config[mconfig->fmt_cfg_idx].param_id =
tkn_elem->value;
break;
@@ -2796,6 +2805,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
struct skl_dfw_v4_module *dfw =
(struct skl_dfw_v4_module *)tplg_w->priv.data;
int ret;
+ int idx = mconfig->fmt_cfg_idx;
dev_dbg(dev, "Parsing Skylake v4 widget topology data\n");
@@ -2829,7 +2839,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
mconfig->dev_type = dfw->dev_type;
mconfig->hw_conn_type = dfw->hw_conn_type;
mconfig->time_slot = dfw->time_slot;
- mconfig->formats_config.caps_size = dfw->caps.caps_size;
+ mconfig->formats_config[idx].caps_size = dfw->caps.caps_size;
mconfig->m_in_pin = devm_kcalloc(dev,
MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin),
@@ -2850,21 +2860,39 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
dfw->is_dynamic_out_pin,
mconfig->module->max_output_pins);
- if (mconfig->formats_config.caps_size) {
- mconfig->formats_config.set_params = dfw->caps.set_params;
- mconfig->formats_config.param_id = dfw->caps.param_id;
- mconfig->formats_config.caps =
- devm_kzalloc(dev, mconfig->formats_config.caps_size,
+ if (mconfig->formats_config[idx].caps_size) {
+ mconfig->formats_config[idx].set_params = dfw->caps.set_params;
+ mconfig->formats_config[idx].param_id = dfw->caps.param_id;
+ mconfig->formats_config[idx].caps =
+ devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
GFP_KERNEL);
- if (!mconfig->formats_config.caps)
+ if (!mconfig->formats_config[idx].caps)
return -ENOMEM;
- memcpy(mconfig->formats_config.caps, dfw->caps.caps,
+ memcpy(mconfig->formats_config[idx].caps, dfw->caps.caps,
dfw->caps.caps_size);
}
return 0;
}
+static int skl_tplg_get_caps_data(struct device *dev, char *data,
+ struct skl_module_cfg *mconfig)
+{
+ int idx = mconfig->fmt_cfg_idx;
+
+ if (mconfig->formats_config[idx].caps_size > 0) {
+ mconfig->formats_config[idx].caps =
+ devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
+ GFP_KERNEL);
+ if (!mconfig->formats_config[idx].caps)
+ return -ENOMEM;
+ memcpy(mconfig->formats_config[idx].caps, data,
+ mconfig->formats_config[idx].caps_size);
+ }
+
+ return mconfig->formats_config[idx].caps_size;
+}
+
/*
* Parse the private data for the token and corresponding value.
* The private data can have multiple data blocks. So, a data block
@@ -2925,18 +2953,14 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
if (block_type == SKL_TYPE_TUPLE) {
ret = skl_tplg_get_tokens(dev, data,
skl, mconfig, block_size);
-
- if (ret < 0)
- return ret;
-
- --num_blocks;
} else {
- if (mconfig->formats_config.caps_size > 0)
- memcpy(mconfig->formats_config.caps, data,
- mconfig->formats_config.caps_size);
- --num_blocks;
- ret = mconfig->formats_config.caps_size;
+ ret = skl_tplg_get_caps_data(dev, data, mconfig);
}
+
+ if (ret < 0)
+ return ret;
+
+ --num_blocks;
off += ret;
}
@@ -3027,6 +3051,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index,
*/
mconfig->id.module_id = -1;
+ /* To provide backward compatibility, set default as SKL_PARAM_INIT */
+ mconfig->fmt_cfg_idx = SKL_PARAM_INIT;
+
/* Parse private data for tuples */
ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
if (ret < 0)
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index fb011862fb24..f0695b2ac5dd 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -81,6 +81,8 @@ enum skl_s_freq {
SKL_FS_INVALID
};
+#define SKL_MAX_PARAMS_TYPES 4
+
enum skl_widget_type {
SKL_WIDGET_VMIXER = 1,
SKL_WIDGET_MIXER = 2,
@@ -150,6 +152,21 @@ struct skl_up_down_mixer_cfg {
u32 ch_map;
} __packed;
+struct skl_pin_format {
+ u32 pin_idx;
+ u32 buf_size;
+ struct skl_audio_data_format audio_fmt;
+} __packed;
+
+struct skl_base_cfg_ext {
+ u16 nr_input_pins;
+ u16 nr_output_pins;
+ u8 reserved[8];
+ u32 priv_param_length;
+ /* Input pin formats followed by output ones. */
+ struct skl_pin_format pins_fmt[0];
+} __packed;
+
struct skl_algo_cfg {
struct skl_base_cfg base_cfg;
char params[];
@@ -311,10 +328,8 @@ struct skl_pipe {
enum skl_module_state {
SKL_MODULE_UNINIT = 0,
- SKL_MODULE_LOADED = 1,
- SKL_MODULE_INIT_DONE = 2,
- SKL_MODULE_BIND_DONE = 3,
- SKL_MODULE_UNLOADED = 4,
+ SKL_MODULE_INIT_DONE = 1,
+ SKL_MODULE_BIND_DONE = 2,
};
enum d0i3_capability {
@@ -373,6 +388,7 @@ struct skl_module_cfg {
struct skl_module *module;
int res_idx;
int fmt_idx;
+ int fmt_cfg_idx;
u8 domain;
bool homogenous_inputs;
bool homogenous_outputs;
@@ -403,7 +419,7 @@ struct skl_module_cfg {
enum skl_hw_conn_type hw_conn_type;
enum skl_module_state m_state;
struct skl_pipe *pipe;
- struct skl_specific_cfg formats_config;
+ struct skl_specific_cfg formats_config[SKL_MAX_PARAMS_TYPES];
struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE];
};
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 74dae4332d17..cf567a89f421 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -184,3 +184,27 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682
with the MT6359 RT1015 RT5682 audio codec.
Select Y if you have such device.
If unsure select "N".
+
+config SND_SOC_MT8195
+ tristate "ASoC support for Mediatek MT8195 chip"
+ select SND_SOC_MEDIATEK
+ help
+ This adds ASoC platform driver support for Mediatek MT8195 chip
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
+config SND_SOC_MT8195_MT6359_RT1019_RT5682
+ tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
+ depends on I2C
+ depends on SND_SOC_MT8195
+ select SND_SOC_MT6359
+ select SND_SOC_RT1015P
+ select SND_SOC_RT5682_I2C
+ select SND_SOC_DMIC
+ select SND_SOC_HDMI_CODEC
+ help
+ This adds ASoC driver for Mediatek MT8195 boards
+ with the MT6359 RT1019 RT5682 audio codec.
+ Select Y if you have such device.
+ If unsure select "N".
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index f6cb6b8508e3..34778ca12106 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
+obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index 3cb2adf420bb..baaa5881b1d4 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
substream->runtime->dma_area,
substream->runtime->dma_bytes);
- memset_io(substream->runtime->dma_area, 0,
+ memset_io((void __force __iomem *)substream->runtime->dma_area, 0,
substream->runtime->dma_bytes);
/* set addr */
@@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
phys_buf_addr_upper_32);
}
- /* set MSB to 33-bit */
- if (memif->data->msb_reg >= 0)
+ /*
+ * set MSB to 33-bit, for memif address
+ * only for memif base address, if msb_end_reg exists
+ */
+ if (memif->data->msb_reg)
mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
1, msb_at_bit33, memif->data->msb_shift);
+ /* set MSB to 33-bit, for memif end address */
+ if (memif->data->msb_end_reg)
+ mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
+ 1, msb_at_bit33,
+ memif->data->msb_end_shift);
+
return 0;
}
EXPORT_SYMBOL_GPL(mtk_memif_set_addr);
@@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe,
else
mono = (channel == 1) ? 1 : 0;
+ /* for specific configuration of memif mono mode */
+ if (memif->data->int_odd_flag_reg)
+ mtk_regmap_update_bits(afe->regmap,
+ memif->data->int_odd_flag_reg,
+ 1, mono,
+ memif->data->int_odd_flag_shift);
+
return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
1, mono, memif->data->mono_shift);
}
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index a6f68c68581c..ef83e78c22a8 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -29,6 +29,8 @@ struct mtk_base_memif_data {
int quad_ch_reg;
int quad_ch_mask;
int quad_ch_shift;
+ int int_odd_flag_reg;
+ int int_odd_flag_shift;
int enable_reg;
int enable_shift;
int hd_reg;
@@ -37,10 +39,13 @@ struct mtk_base_memif_data {
int hd_align_mshift;
int msb_reg;
int msb_shift;
- int msb2_reg;
- int msb2_shift;
+ int msb_end_reg;
+ int msb_end_shift;
int agent_disable_reg;
int agent_disable_shift;
+ int ch_num_reg;
+ int ch_num_shift;
+ int ch_num_maskbit;
/* playback memif only */
int pbuf_reg;
int pbuf_mask;
@@ -62,6 +67,7 @@ struct mtk_base_irq_data {
int irq_en_shift;
int irq_clr_reg;
int irq_clr_shift;
+ int irq_status_shift;
};
struct device;
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
index c4a598cbbdaa..14e77df06b01 100644
--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
@@ -1119,25 +1119,26 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(afe->regmap)) {
dev_err(dev, "could not get regmap from parent\n");
- return PTR_ERR(afe->regmap);
+ ret = PTR_ERR(afe->regmap);
+ goto err_pm_disable;
}
ret = regmap_attach_dev(dev, afe->regmap, &mt8183_afe_regmap_config);
if (ret) {
dev_warn(dev, "regmap_attach_dev fail, ret %d\n", ret);
- return ret;
+ goto err_pm_disable;
}
rstc = devm_reset_control_get(dev, "audiosys");
if (IS_ERR(rstc)) {
ret = PTR_ERR(rstc);
dev_err(dev, "could not get audiosys reset:%d\n", ret);
- return ret;
+ goto err_pm_disable;
}
ret = reset_control_reset(rstc);
if (ret) {
dev_err(dev, "failed to trigger audio reset:%d\n", ret);
- return ret;
+ goto err_pm_disable;
}
/* enable clock for regcache get default value from hw */
@@ -1147,7 +1148,7 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
ret = regmap_reinit_cache(afe->regmap, &mt8183_afe_regmap_config);
if (ret) {
dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret);
- return ret;
+ goto err_pm_disable;
}
pm_runtime_put_sync(&pdev->dev);
@@ -1160,8 +1161,10 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
afe->memif_size = MT8183_MEMIF_NUM;
afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
GFP_KERNEL);
- if (!afe->memif)
- return -ENOMEM;
+ if (!afe->memif) {
+ ret = -ENOMEM;
+ goto err_pm_disable;
+ }
for (i = 0; i < afe->memif_size; i++) {
afe->memif[i].data = &memif_data[i];
@@ -1178,22 +1181,26 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
afe->irqs_size = MT8183_IRQ_NUM;
afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
GFP_KERNEL);
- if (!afe->irqs)
- return -ENOMEM;
+ if (!afe->irqs) {
+ ret = -ENOMEM;
+ goto err_pm_disable;
+ }
for (i = 0; i < afe->irqs_size; i++)
afe->irqs[i].irq_data = &irq_data[i];
/* request irq */
irq_id = platform_get_irq(pdev, 0);
- if (irq_id < 0)
- return irq_id;
+ if (irq_id < 0) {
+ ret = irq_id;
+ goto err_pm_disable;
+ }
ret = devm_request_irq(dev, irq_id, mt8183_afe_irq_handler,
IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
if (ret) {
dev_err(dev, "could not request_irq for asys-isr\n");
- return ret;
+ goto err_pm_disable;
}
/* init sub_dais */
@@ -1204,7 +1211,7 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret) {
dev_warn(afe->dev, "dai register i %d fail, ret %d\n",
i, ret);
- return ret;
+ goto err_pm_disable;
}
}
@@ -1213,7 +1220,7 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret) {
dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
ret);
- return ret;
+ goto err_pm_disable;
}
afe->mtk_afe_hardware = &mt8183_afe_hardware;
@@ -1229,7 +1236,7 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
NULL, 0);
if (ret) {
dev_warn(dev, "err_platform\n");
- return ret;
+ goto err_pm_disable;
}
ret = devm_snd_soc_register_component(afe->dev,
@@ -1238,10 +1245,14 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
afe->num_dai_drivers);
if (ret) {
dev_warn(dev, "err_dai_component\n");
- return ret;
+ goto err_pm_disable;
}
return ret;
+
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ return ret;
}
static int mt8183_afe_pcm_dev_remove(struct platform_device *pdev)
diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
index 7a1724f5ff4c..31c280339c50 100644
--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
@@ -2229,12 +2229,13 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(afe->regmap)) {
dev_err(dev, "could not get regmap from parent\n");
- return PTR_ERR(afe->regmap);
+ ret = PTR_ERR(afe->regmap);
+ goto err_pm_disable;
}
ret = regmap_attach_dev(dev, afe->regmap, &mt8192_afe_regmap_config);
if (ret) {
dev_warn(dev, "regmap_attach_dev fail, ret %d\n", ret);
- return ret;
+ goto err_pm_disable;
}
/* enable clock for regcache get default value from hw */
@@ -2244,7 +2245,7 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
ret = regmap_reinit_cache(afe->regmap, &mt8192_afe_regmap_config);
if (ret) {
dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret);
- return ret;
+ goto err_pm_disable;
}
pm_runtime_put_sync(&pdev->dev);
@@ -2257,8 +2258,10 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
afe->memif_size = MT8192_MEMIF_NUM;
afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
GFP_KERNEL);
- if (!afe->memif)
- return -ENOMEM;
+ if (!afe->memif) {
+ ret = -ENOMEM;
+ goto err_pm_disable;
+ }
for (i = 0; i < afe->memif_size; i++) {
afe->memif[i].data = &memif_data[i];
@@ -2272,22 +2275,26 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
afe->irqs_size = MT8192_IRQ_NUM;
afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
GFP_KERNEL);
- if (!afe->irqs)
- return -ENOMEM;
+ if (!afe->irqs) {
+ ret = -ENOMEM;
+ goto err_pm_disable;
+ }
for (i = 0; i < afe->irqs_size; i++)
afe->irqs[i].irq_data = &irq_data[i];
/* request irq */
irq_id = platform_get_irq(pdev, 0);
- if (irq_id < 0)
- return irq_id;
+ if (irq_id < 0) {
+ ret = irq_id;
+ goto err_pm_disable;
+ }
ret = devm_request_irq(dev, irq_id, mt8192_afe_irq_handler,
IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
if (ret) {
dev_err(dev, "could not request_irq for Afe_ISR_Handle\n");
- return ret;
+ goto err_pm_disable;
}
/* init sub_dais */
diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile
new file mode 100644
index 000000000000..44775f400b40
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/Makefile
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# platform driver
+snd-soc-mt8195-afe-objs := \
+ mt8195-audsys-clk.o \
+ mt8195-afe-clk.o \
+ mt8195-afe-pcm.o \
+ mt8195-dai-adda.o \
+ mt8195-dai-etdm.o \
+ mt8195-dai-pcm.o
+
+obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o
diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
new file mode 100644
index 000000000000..8420b2c71332
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8195-afe-clk.c -- Mediatek 8195 afe clock ctrl
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+
+#include "mt8195-afe-common.h"
+#include "mt8195-afe-clk.h"
+#include "mt8195-reg.h"
+#include "mt8195-audsys-clk.h"
+
+static const char *aud_clks[MT8195_CLK_NUM] = {
+ /* xtal */
+ [MT8195_CLK_XTAL_26M] = "clk26m",
+ /* divider */
+ [MT8195_CLK_TOP_APLL1] = "apll1_ck",
+ [MT8195_CLK_TOP_APLL2] = "apll2_ck",
+ [MT8195_CLK_TOP_APLL12_DIV0] = "apll12_div0",
+ [MT8195_CLK_TOP_APLL12_DIV1] = "apll12_div1",
+ [MT8195_CLK_TOP_APLL12_DIV2] = "apll12_div2",
+ [MT8195_CLK_TOP_APLL12_DIV3] = "apll12_div3",
+ [MT8195_CLK_TOP_APLL12_DIV9] = "apll12_div9",
+ /* mux */
+ [MT8195_CLK_TOP_A1SYS_HP_SEL] = "a1sys_hp_sel",
+ [MT8195_CLK_TOP_AUD_INTBUS_SEL] = "aud_intbus_sel",
+ [MT8195_CLK_TOP_AUDIO_H_SEL] = "audio_h_sel",
+ [MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL] = "audio_local_bus_sel",
+ [MT8195_CLK_TOP_DPTX_M_SEL] = "dptx_m_sel",
+ [MT8195_CLK_TOP_I2SO1_M_SEL] = "i2so1_m_sel",
+ [MT8195_CLK_TOP_I2SO2_M_SEL] = "i2so2_m_sel",
+ [MT8195_CLK_TOP_I2SI1_M_SEL] = "i2si1_m_sel",
+ [MT8195_CLK_TOP_I2SI2_M_SEL] = "i2si2_m_sel",
+ /* clock gate */
+ [MT8195_CLK_INFRA_AO_AUDIO_26M_B] = "infra_ao_audio_26m_b",
+ [MT8195_CLK_SCP_ADSP_AUDIODSP] = "scp_adsp_audiodsp",
+ /* afe clock gate */
+ [MT8195_CLK_AUD_AFE] = "aud_afe",
+ [MT8195_CLK_AUD_APLL] = "aud_apll",
+ [MT8195_CLK_AUD_APLL2] = "aud_apll2",
+ [MT8195_CLK_AUD_DAC] = "aud_dac",
+ [MT8195_CLK_AUD_ADC] = "aud_adc",
+ [MT8195_CLK_AUD_DAC_HIRES] = "aud_dac_hires",
+ [MT8195_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp",
+ [MT8195_CLK_AUD_ADC_HIRES] = "aud_adc_hires",
+ [MT8195_CLK_AUD_ADDA6_ADC] = "aud_adda6_adc",
+ [MT8195_CLK_AUD_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires",
+ [MT8195_CLK_AUD_I2SIN] = "aud_i2sin",
+ [MT8195_CLK_AUD_TDM_IN] = "aud_tdm_in",
+ [MT8195_CLK_AUD_I2S_OUT] = "aud_i2s_out",
+ [MT8195_CLK_AUD_TDM_OUT] = "aud_tdm_out",
+ [MT8195_CLK_AUD_HDMI_OUT] = "aud_hdmi_out",
+ [MT8195_CLK_AUD_ASRC11] = "aud_asrc11",
+ [MT8195_CLK_AUD_ASRC12] = "aud_asrc12",
+ [MT8195_CLK_AUD_A1SYS] = "aud_a1sys",
+ [MT8195_CLK_AUD_A2SYS] = "aud_a2sys",
+ [MT8195_CLK_AUD_PCMIF] = "aud_pcmif",
+ [MT8195_CLK_AUD_MEMIF_UL1] = "aud_memif_ul1",
+ [MT8195_CLK_AUD_MEMIF_UL2] = "aud_memif_ul2",
+ [MT8195_CLK_AUD_MEMIF_UL3] = "aud_memif_ul3",
+ [MT8195_CLK_AUD_MEMIF_UL4] = "aud_memif_ul4",
+ [MT8195_CLK_AUD_MEMIF_UL5] = "aud_memif_ul5",
+ [MT8195_CLK_AUD_MEMIF_UL6] = "aud_memif_ul6",
+ [MT8195_CLK_AUD_MEMIF_UL8] = "aud_memif_ul8",
+ [MT8195_CLK_AUD_MEMIF_UL9] = "aud_memif_ul9",
+ [MT8195_CLK_AUD_MEMIF_UL10] = "aud_memif_ul10",
+ [MT8195_CLK_AUD_MEMIF_DL2] = "aud_memif_dl2",
+ [MT8195_CLK_AUD_MEMIF_DL3] = "aud_memif_dl3",
+ [MT8195_CLK_AUD_MEMIF_DL6] = "aud_memif_dl6",
+ [MT8195_CLK_AUD_MEMIF_DL7] = "aud_memif_dl7",
+ [MT8195_CLK_AUD_MEMIF_DL8] = "aud_memif_dl8",
+ [MT8195_CLK_AUD_MEMIF_DL10] = "aud_memif_dl10",
+ [MT8195_CLK_AUD_MEMIF_DL11] = "aud_memif_dl11",
+};
+
+int mt8195_afe_get_mclk_source_clk_id(int sel)
+{
+ switch (sel) {
+ case MT8195_MCK_SEL_26M:
+ return MT8195_CLK_XTAL_26M;
+ case MT8195_MCK_SEL_APLL1:
+ return MT8195_CLK_TOP_APLL1;
+ case MT8195_MCK_SEL_APLL2:
+ return MT8195_CLK_TOP_APLL2;
+ default:
+ return -EINVAL;
+ }
+}
+
+int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int clk_id = mt8195_afe_get_mclk_source_clk_id(apll);
+
+ if (clk_id < 0) {
+ dev_dbg(afe->dev, "invalid clk id\n");
+ return 0;
+ }
+
+ return clk_get_rate(afe_priv->clk[clk_id]);
+}
+
+int mt8195_afe_get_default_mclk_source_by_rate(int rate)
+{
+ return ((rate % 8000) == 0) ?
+ MT8195_MCK_SEL_APLL1 : MT8195_MCK_SEL_APLL2;
+}
+
+int mt8195_afe_init_clock(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int i;
+
+ mt8195_audsys_clk_register(afe);
+
+ afe_priv->clk =
+ devm_kcalloc(afe->dev, MT8195_CLK_NUM, sizeof(*afe_priv->clk),
+ GFP_KERNEL);
+ if (!afe_priv->clk)
+ return -ENOMEM;
+
+ for (i = 0; i < MT8195_CLK_NUM; i++) {
+ afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
+ if (IS_ERR(afe_priv->clk[i])) {
+ dev_dbg(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
+ __func__, aud_clks[i],
+ PTR_ERR(afe_priv->clk[i]));
+ return PTR_ERR(afe_priv->clk[i]);
+ }
+ }
+
+ return 0;
+}
+
+void mt8195_afe_deinit_clock(struct mtk_base_afe *afe)
+{
+ mt8195_audsys_clk_unregister(afe);
+}
+
+int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to enable clk\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ dev_dbg(afe->dev, "NULL clk\n");
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt8195_afe_enable_clk);
+
+void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ if (clk)
+ clk_disable_unprepare(clk);
+ else
+ dev_dbg(afe->dev, "NULL clk\n");
+}
+EXPORT_SYMBOL_GPL(mt8195_afe_disable_clk);
+
+int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_prepare(clk);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to prepare clk\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ dev_dbg(afe->dev, "NULL clk\n");
+ }
+ return 0;
+}
+
+void mt8195_afe_unprepare_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ if (clk)
+ clk_unprepare(clk);
+ else
+ dev_dbg(afe->dev, "NULL clk\n");
+}
+
+int mt8195_afe_enable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_enable(clk);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to clk enable\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ dev_dbg(afe->dev, "NULL clk\n");
+ }
+ return 0;
+}
+
+void mt8195_afe_disable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk)
+{
+ if (clk)
+ clk_disable(clk);
+ else
+ dev_dbg(afe->dev, "NULL clk\n");
+}
+
+int mt8195_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
+ unsigned int rate)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_set_rate(clk, rate);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to set clk rate\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int mt8195_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
+ struct clk *parent)
+{
+ int ret;
+
+ if (clk && parent) {
+ ret = clk_set_parent(clk, parent);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to set clk parent\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int get_top_cg_reg(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8195_TOP_CG_A1SYS_TIMING:
+ case MT8195_TOP_CG_A2SYS_TIMING:
+ case MT8195_TOP_CG_26M_TIMING:
+ return ASYS_TOP_CON;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_mask(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8195_TOP_CG_A1SYS_TIMING:
+ return ASYS_TOP_CON_A1SYS_TIMING_ON;
+ case MT8195_TOP_CG_A2SYS_TIMING:
+ return ASYS_TOP_CON_A2SYS_TIMING_ON;
+ case MT8195_TOP_CG_26M_TIMING:
+ return ASYS_TOP_CON_26M_TIMING_ON;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_on_val(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8195_TOP_CG_A1SYS_TIMING:
+ case MT8195_TOP_CG_A2SYS_TIMING:
+ case MT8195_TOP_CG_26M_TIMING:
+ return get_top_cg_mask(cg_type);
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_off_val(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8195_TOP_CG_A1SYS_TIMING:
+ case MT8195_TOP_CG_A2SYS_TIMING:
+ case MT8195_TOP_CG_26M_TIMING:
+ return 0;
+ default:
+ return get_top_cg_mask(cg_type);
+ }
+}
+
+static int mt8195_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
+{
+ unsigned int reg = get_top_cg_reg(cg_type);
+ unsigned int mask = get_top_cg_mask(cg_type);
+ unsigned int val = get_top_cg_on_val(cg_type);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+ return 0;
+}
+
+static int mt8195_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
+{
+ unsigned int reg = get_top_cg_reg(cg_type);
+ unsigned int mask = get_top_cg_mask(cg_type);
+ unsigned int val = get_top_cg_off_val(cg_type);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+ return 0;
+}
+
+int mt8195_afe_enable_reg_rw_clk(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int i;
+ unsigned int clk_array[] = {
+ MT8195_CLK_SCP_ADSP_AUDIODSP, /* bus clock for infra */
+ MT8195_CLK_TOP_AUDIO_H_SEL, /* clock for ADSP bus */
+ MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL, /* bus clock for DRAM access */
+ MT8195_CLK_TOP_AUD_INTBUS_SEL, /* bus clock for AFE SRAM access */
+ MT8195_CLK_INFRA_AO_AUDIO_26M_B, /* audio 26M clock */
+ MT8195_CLK_AUD_AFE, /* AFE HW master switch */
+ MT8195_CLK_AUD_A1SYS_HP, /* AFE HW clock*/
+ MT8195_CLK_AUD_A1SYS, /* AFE HW clock */
+ };
+
+ for (i = 0; i < ARRAY_SIZE(clk_array); i++)
+ mt8195_afe_enable_clk(afe, afe_priv->clk[clk_array[i]]);
+
+ return 0;
+}
+
+int mt8195_afe_disable_reg_rw_clk(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int i;
+ unsigned int clk_array[] = {
+ MT8195_CLK_AUD_A1SYS,
+ MT8195_CLK_AUD_A1SYS_HP,
+ MT8195_CLK_AUD_AFE,
+ MT8195_CLK_INFRA_AO_AUDIO_26M_B,
+ MT8195_CLK_TOP_AUD_INTBUS_SEL,
+ MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL,
+ MT8195_CLK_TOP_AUDIO_H_SEL,
+ MT8195_CLK_SCP_ADSP_AUDIODSP,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(clk_array); i++)
+ mt8195_afe_disable_clk(afe, afe_priv->clk[clk_array[i]]);
+
+ return 0;
+}
+
+static int mt8195_afe_enable_afe_on(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
+ return 0;
+}
+
+static int mt8195_afe_disable_afe_on(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
+ return 0;
+}
+
+static int mt8195_afe_enable_timing_sys(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int i;
+ unsigned int clk_array[] = {
+ MT8195_CLK_AUD_A1SYS,
+ MT8195_CLK_AUD_A2SYS,
+ };
+ unsigned int cg_array[] = {
+ MT8195_TOP_CG_A1SYS_TIMING,
+ MT8195_TOP_CG_A2SYS_TIMING,
+ MT8195_TOP_CG_26M_TIMING,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(clk_array); i++)
+ mt8195_afe_enable_clk(afe, afe_priv->clk[clk_array[i]]);
+
+ for (i = 0; i < ARRAY_SIZE(cg_array); i++)
+ mt8195_afe_enable_top_cg(afe, cg_array[i]);
+
+ return 0;
+}
+
+static int mt8195_afe_disable_timing_sys(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int i;
+ unsigned int clk_array[] = {
+ MT8195_CLK_AUD_A2SYS,
+ MT8195_CLK_AUD_A1SYS,
+ };
+ unsigned int cg_array[] = {
+ MT8195_TOP_CG_26M_TIMING,
+ MT8195_TOP_CG_A2SYS_TIMING,
+ MT8195_TOP_CG_A1SYS_TIMING,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(cg_array); i++)
+ mt8195_afe_disable_top_cg(afe, cg_array[i]);
+
+ for (i = 0; i < ARRAY_SIZE(clk_array); i++)
+ mt8195_afe_disable_clk(afe, afe_priv->clk[clk_array[i]]);
+
+ return 0;
+}
+
+int mt8195_afe_enable_main_clock(struct mtk_base_afe *afe)
+{
+ mt8195_afe_enable_timing_sys(afe);
+
+ mt8195_afe_enable_afe_on(afe);
+
+ return 0;
+}
+
+int mt8195_afe_disable_main_clock(struct mtk_base_afe *afe)
+{
+ mt8195_afe_disable_afe_on(afe);
+
+ mt8195_afe_disable_timing_sys(afe);
+
+ return 0;
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.h b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h
new file mode 100644
index 000000000000..f8e6eeb29a89
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-afe-clk.h -- Mediatek 8195 afe clock ctrl definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#ifndef _MT8195_AFE_CLK_H_
+#define _MT8195_AFE_CLK_H_
+
+enum {
+ /* xtal */
+ MT8195_CLK_XTAL_26M,
+ /* divider */
+ MT8195_CLK_TOP_APLL1,
+ MT8195_CLK_TOP_APLL2,
+ MT8195_CLK_TOP_APLL12_DIV0,
+ MT8195_CLK_TOP_APLL12_DIV1,
+ MT8195_CLK_TOP_APLL12_DIV2,
+ MT8195_CLK_TOP_APLL12_DIV3,
+ MT8195_CLK_TOP_APLL12_DIV9,
+ /* mux */
+ MT8195_CLK_TOP_A1SYS_HP_SEL,
+ MT8195_CLK_TOP_AUD_INTBUS_SEL,
+ MT8195_CLK_TOP_AUDIO_H_SEL,
+ MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL,
+ MT8195_CLK_TOP_DPTX_M_SEL,
+ MT8195_CLK_TOP_I2SO1_M_SEL,
+ MT8195_CLK_TOP_I2SO2_M_SEL,
+ MT8195_CLK_TOP_I2SI1_M_SEL,
+ MT8195_CLK_TOP_I2SI2_M_SEL,
+ /* clock gate */
+ MT8195_CLK_INFRA_AO_AUDIO_26M_B,
+ MT8195_CLK_SCP_ADSP_AUDIODSP,
+ MT8195_CLK_AUD_AFE,
+ MT8195_CLK_AUD_APLL,
+ MT8195_CLK_AUD_APLL2,
+ MT8195_CLK_AUD_DAC,
+ MT8195_CLK_AUD_ADC,
+ MT8195_CLK_AUD_DAC_HIRES,
+ MT8195_CLK_AUD_A1SYS_HP,
+ MT8195_CLK_AUD_ADC_HIRES,
+ MT8195_CLK_AUD_ADDA6_ADC,
+ MT8195_CLK_AUD_ADDA6_ADC_HIRES,
+ MT8195_CLK_AUD_I2SIN,
+ MT8195_CLK_AUD_TDM_IN,
+ MT8195_CLK_AUD_I2S_OUT,
+ MT8195_CLK_AUD_TDM_OUT,
+ MT8195_CLK_AUD_HDMI_OUT,
+ MT8195_CLK_AUD_ASRC11,
+ MT8195_CLK_AUD_ASRC12,
+ MT8195_CLK_AUD_A1SYS,
+ MT8195_CLK_AUD_A2SYS,
+ MT8195_CLK_AUD_PCMIF,
+ MT8195_CLK_AUD_MEMIF_UL1,
+ MT8195_CLK_AUD_MEMIF_UL2,
+ MT8195_CLK_AUD_MEMIF_UL3,
+ MT8195_CLK_AUD_MEMIF_UL4,
+ MT8195_CLK_AUD_MEMIF_UL5,
+ MT8195_CLK_AUD_MEMIF_UL6,
+ MT8195_CLK_AUD_MEMIF_UL8,
+ MT8195_CLK_AUD_MEMIF_UL9,
+ MT8195_CLK_AUD_MEMIF_UL10,
+ MT8195_CLK_AUD_MEMIF_DL2,
+ MT8195_CLK_AUD_MEMIF_DL3,
+ MT8195_CLK_AUD_MEMIF_DL6,
+ MT8195_CLK_AUD_MEMIF_DL7,
+ MT8195_CLK_AUD_MEMIF_DL8,
+ MT8195_CLK_AUD_MEMIF_DL10,
+ MT8195_CLK_AUD_MEMIF_DL11,
+ MT8195_CLK_NUM,
+};
+
+enum {
+ MT8195_MCK_SEL_26M,
+ MT8195_MCK_SEL_APLL1,
+ MT8195_MCK_SEL_APLL2,
+ MT8195_MCK_SEL_APLL3,
+ MT8195_MCK_SEL_APLL4,
+ MT8195_MCK_SEL_APLL5,
+ MT8195_MCK_SEL_HDMIRX_APLL,
+ MT8195_MCK_SEL_NUM,
+};
+
+struct mtk_base_afe;
+
+int mt8195_afe_get_mclk_source_clk_id(int sel);
+int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
+int mt8195_afe_get_default_mclk_source_by_rate(int rate);
+int mt8195_afe_init_clock(struct mtk_base_afe *afe);
+void mt8195_afe_deinit_clock(struct mtk_base_afe *afe);
+int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
+void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
+int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk);
+void mt8195_afe_unprepare_clk(struct mtk_base_afe *afe, struct clk *clk);
+int mt8195_afe_enable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk);
+void mt8195_afe_disable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk);
+int mt8195_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
+ unsigned int rate);
+int mt8195_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
+ struct clk *parent);
+int mt8195_afe_enable_main_clock(struct mtk_base_afe *afe);
+int mt8195_afe_disable_main_clock(struct mtk_base_afe *afe);
+int mt8195_afe_enable_reg_rw_clk(struct mtk_base_afe *afe);
+int mt8195_afe_disable_reg_rw_clk(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-common.h b/sound/soc/mediatek/mt8195/mt8195-afe-common.h
new file mode 100644
index 000000000000..f93f439e2bd9
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-common.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-afe-common.h -- Mediatek 8195 audio driver definitions
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#ifndef _MT_8195_AFE_COMMON_H_
+#define _MT_8195_AFE_COMMON_H_
+
+#include <sound/soc.h>
+#include <linux/list.h>
+#include <linux/regmap.h>
+#include "../common/mtk-base-afe.h"
+
+enum {
+ MT8195_DAI_START,
+ MT8195_AFE_MEMIF_START = MT8195_DAI_START,
+ MT8195_AFE_MEMIF_DL2 = MT8195_AFE_MEMIF_START,
+ MT8195_AFE_MEMIF_DL3,
+ MT8195_AFE_MEMIF_DL6,
+ MT8195_AFE_MEMIF_DL7,
+ MT8195_AFE_MEMIF_DL8,
+ MT8195_AFE_MEMIF_DL10,
+ MT8195_AFE_MEMIF_DL11,
+ MT8195_AFE_MEMIF_UL_START,
+ MT8195_AFE_MEMIF_UL1 = MT8195_AFE_MEMIF_UL_START,
+ MT8195_AFE_MEMIF_UL2,
+ MT8195_AFE_MEMIF_UL3,
+ MT8195_AFE_MEMIF_UL4,
+ MT8195_AFE_MEMIF_UL5,
+ MT8195_AFE_MEMIF_UL6,
+ MT8195_AFE_MEMIF_UL8,
+ MT8195_AFE_MEMIF_UL9,
+ MT8195_AFE_MEMIF_UL10,
+ MT8195_AFE_MEMIF_END,
+ MT8195_AFE_MEMIF_NUM = (MT8195_AFE_MEMIF_END - MT8195_AFE_MEMIF_START),
+ MT8195_AFE_IO_START = MT8195_AFE_MEMIF_END,
+ MT8195_AFE_IO_DL_SRC = MT8195_AFE_IO_START,
+ MT8195_AFE_IO_DPTX,
+ MT8195_AFE_IO_ETDM_START,
+ MT8195_AFE_IO_ETDM1_IN = MT8195_AFE_IO_ETDM_START,
+ MT8195_AFE_IO_ETDM2_IN,
+ MT8195_AFE_IO_ETDM1_OUT,
+ MT8195_AFE_IO_ETDM2_OUT,
+ MT8195_AFE_IO_ETDM3_OUT,
+ MT8195_AFE_IO_ETDM_END,
+ MT8195_AFE_IO_ETDM_NUM =
+ (MT8195_AFE_IO_ETDM_END - MT8195_AFE_IO_ETDM_START),
+ MT8195_AFE_IO_PCM = MT8195_AFE_IO_ETDM_END,
+ MT8195_AFE_IO_UL_SRC1,
+ MT8195_AFE_IO_UL_SRC2,
+ MT8195_AFE_IO_END,
+ MT8195_AFE_IO_NUM = (MT8195_AFE_IO_END - MT8195_AFE_IO_START),
+ MT8195_DAI_END = MT8195_AFE_IO_END,
+ MT8195_DAI_NUM = (MT8195_DAI_END - MT8195_DAI_START),
+};
+
+enum {
+ MT8195_TOP_CG_A1SYS_TIMING,
+ MT8195_TOP_CG_A2SYS_TIMING,
+ MT8195_TOP_CG_26M_TIMING,
+ MT8195_TOP_CG_NUM,
+};
+
+enum {
+ MT8195_AFE_IRQ_1,
+ MT8195_AFE_IRQ_2,
+ MT8195_AFE_IRQ_3,
+ MT8195_AFE_IRQ_8,
+ MT8195_AFE_IRQ_9,
+ MT8195_AFE_IRQ_10,
+ MT8195_AFE_IRQ_13,
+ MT8195_AFE_IRQ_14,
+ MT8195_AFE_IRQ_15,
+ MT8195_AFE_IRQ_16,
+ MT8195_AFE_IRQ_17,
+ MT8195_AFE_IRQ_18,
+ MT8195_AFE_IRQ_19,
+ MT8195_AFE_IRQ_20,
+ MT8195_AFE_IRQ_21,
+ MT8195_AFE_IRQ_22,
+ MT8195_AFE_IRQ_23,
+ MT8195_AFE_IRQ_24,
+ MT8195_AFE_IRQ_25,
+ MT8195_AFE_IRQ_26,
+ MT8195_AFE_IRQ_27,
+ MT8195_AFE_IRQ_28,
+ MT8195_AFE_IRQ_NUM,
+};
+
+enum {
+ MT8195_ETDM_OUT1_1X_EN = 9,
+ MT8195_ETDM_OUT2_1X_EN = 10,
+ MT8195_ETDM_OUT3_1X_EN = 11,
+ MT8195_ETDM_IN1_1X_EN = 12,
+ MT8195_ETDM_IN2_1X_EN = 13,
+ MT8195_ETDM_IN1_NX_EN = 25,
+ MT8195_ETDM_IN2_NX_EN = 26,
+};
+
+enum {
+ MT8195_MTKAIF_MISO_0,
+ MT8195_MTKAIF_MISO_1,
+ MT8195_MTKAIF_MISO_2,
+ MT8195_MTKAIF_MISO_NUM,
+};
+
+struct mtk_dai_memif_irq_priv {
+ unsigned int asys_timing_sel;
+};
+
+struct mtkaif_param {
+ bool mtkaif_calibration_ok;
+ int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
+ int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
+ int mtkaif_dmic_on;
+ int mtkaif_adda6_only;
+};
+
+struct clk;
+
+struct mt8195_afe_private {
+ struct clk **clk;
+ struct clk_lookup **lookup;
+ struct regmap *topckgen;
+ int pm_runtime_bypass_reg_ctl;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry **debugfs_dentry;
+#endif
+ int afe_on_ref_cnt;
+ int top_cg_ref_cnt[MT8195_TOP_CG_NUM];
+ spinlock_t afe_ctrl_lock; /* Lock for afe control */
+ struct mtk_dai_memif_irq_priv irq_priv[MT8195_AFE_IRQ_NUM];
+ struct mtkaif_param mtkaif_params;
+
+ /* dai */
+ void *dai_priv[MT8195_DAI_NUM];
+};
+
+int mt8195_afe_fs_timing(unsigned int rate);
+/* dai register */
+int mt8195_dai_adda_register(struct mtk_base_afe *afe);
+int mt8195_dai_etdm_register(struct mtk_base_afe *afe);
+int mt8195_dai_pcm_register(struct mtk_base_afe *afe);
+
+#define MT8195_SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put, id) \
+{ \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_enum_double, \
+ .get = xhandler_get, .put = xhandler_put, \
+ .device = id, \
+ .private_value = (unsigned long)&xenum, \
+}
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
new file mode 100644
index 000000000000..6635c3f72ecc
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
@@ -0,0 +1,3281 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek ALSA SoC AFE platform driver for 8195
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include "mt8195-afe-common.h"
+#include "mt8195-afe-clk.h"
+#include "mt8195-reg.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
+
+#define MT8195_MEMIF_BUFFER_BYTES_ALIGN (0x40)
+#define MT8195_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
+
+struct mtk_dai_memif_priv {
+ unsigned int asys_timing_sel;
+};
+
+static const struct snd_pcm_hardware mt8195_afe_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .period_bytes_min = 64,
+ .period_bytes_max = 256 * 1024,
+ .periods_min = 2,
+ .periods_max = 256,
+ .buffer_bytes_max = 256 * 2 * 1024,
+};
+
+struct mt8195_afe_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+static const struct mt8195_afe_rate mt8195_afe_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 12000, .reg_value = 1, },
+ { .rate = 16000, .reg_value = 2, },
+ { .rate = 24000, .reg_value = 3, },
+ { .rate = 32000, .reg_value = 4, },
+ { .rate = 48000, .reg_value = 5, },
+ { .rate = 96000, .reg_value = 6, },
+ { .rate = 192000, .reg_value = 7, },
+ { .rate = 384000, .reg_value = 8, },
+ { .rate = 7350, .reg_value = 16, },
+ { .rate = 11025, .reg_value = 17, },
+ { .rate = 14700, .reg_value = 18, },
+ { .rate = 22050, .reg_value = 19, },
+ { .rate = 29400, .reg_value = 20, },
+ { .rate = 44100, .reg_value = 21, },
+ { .rate = 88200, .reg_value = 22, },
+ { .rate = 176400, .reg_value = 23, },
+ { .rate = 352800, .reg_value = 24, },
+};
+
+int mt8195_afe_fs_timing(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mt8195_afe_rates); i++)
+ if (mt8195_afe_rates[i].rate == rate)
+ return mt8195_afe_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static int mt8195_memif_fs(struct snd_pcm_substream *substream,
+ unsigned int rate)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_component *component =
+ snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ struct mtk_base_afe_memif *memif = &afe->memif[id];
+ int fs = mt8195_afe_fs_timing(rate);
+
+ switch (memif->data->id) {
+ case MT8195_AFE_MEMIF_DL10:
+ fs = MT8195_ETDM_OUT3_1X_EN;
+ break;
+ case MT8195_AFE_MEMIF_UL8:
+ fs = MT8195_ETDM_IN1_NX_EN;
+ break;
+ case MT8195_AFE_MEMIF_UL3:
+ fs = MT8195_ETDM_IN2_NX_EN;
+ break;
+ default:
+ break;
+ }
+
+ return fs;
+}
+
+static int mt8195_irq_fs(struct snd_pcm_substream *substream,
+ unsigned int rate)
+{
+ int fs = mt8195_memif_fs(substream, rate);
+
+ switch (fs) {
+ case MT8195_ETDM_IN1_NX_EN:
+ fs = MT8195_ETDM_IN1_1X_EN;
+ break;
+ case MT8195_ETDM_IN2_NX_EN:
+ fs = MT8195_ETDM_IN2_1X_EN;
+ break;
+ default:
+ break;
+ }
+
+ return fs;
+}
+
+enum {
+ MT8195_AFE_CM0,
+ MT8195_AFE_CM1,
+ MT8195_AFE_CM2,
+ MT8195_AFE_CM_NUM,
+};
+
+struct mt8195_afe_channel_merge {
+ int id;
+ int reg;
+ unsigned int sel_shift;
+ unsigned int sel_maskbit;
+ unsigned int sel_default;
+ unsigned int ch_num_shift;
+ unsigned int ch_num_maskbit;
+ unsigned int en_shift;
+ unsigned int en_maskbit;
+ unsigned int update_cnt_shift;
+ unsigned int update_cnt_maskbit;
+ unsigned int update_cnt_default;
+};
+
+static const struct mt8195_afe_channel_merge
+ mt8195_afe_cm[MT8195_AFE_CM_NUM] = {
+ [MT8195_AFE_CM0] = {
+ .id = MT8195_AFE_CM0,
+ .reg = AFE_CM0_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x3f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+ [MT8195_AFE_CM1] = {
+ .id = MT8195_AFE_CM1,
+ .reg = AFE_CM1_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x1f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+ [MT8195_AFE_CM2] = {
+ .id = MT8195_AFE_CM2,
+ .reg = AFE_CM2_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x1f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+};
+
+static int mt8195_afe_memif_is_ul(int id)
+{
+ if (id >= MT8195_AFE_MEMIF_UL_START && id < MT8195_AFE_MEMIF_END)
+ return 1;
+ else
+ return 0;
+}
+
+static const struct mt8195_afe_channel_merge*
+mt8195_afe_found_cm(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = -EINVAL;
+
+ if (mt8195_afe_memif_is_ul(dai->id) == 0)
+ return NULL;
+
+ switch (dai->id) {
+ case MT8195_AFE_MEMIF_UL9:
+ id = MT8195_AFE_CM0;
+ break;
+ case MT8195_AFE_MEMIF_UL2:
+ id = MT8195_AFE_CM1;
+ break;
+ case MT8195_AFE_MEMIF_UL10:
+ id = MT8195_AFE_CM2;
+ break;
+ default:
+ break;
+ }
+
+ if (id < 0) {
+ dev_dbg(afe->dev, "%s, memif %d cannot find CM!\n",
+ __func__, dai->id);
+ return NULL;
+ }
+
+ return &mt8195_afe_cm[id];
+}
+
+static int mt8195_afe_config_cm(struct mtk_base_afe *afe,
+ const struct mt8195_afe_channel_merge *cm,
+ unsigned int channels)
+{
+ if (!cm)
+ return -EINVAL;
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->sel_maskbit << cm->sel_shift,
+ cm->sel_default << cm->sel_shift);
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->ch_num_maskbit << cm->ch_num_shift,
+ (channels - 1) << cm->ch_num_shift);
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->update_cnt_maskbit << cm->update_cnt_shift,
+ cm->update_cnt_default << cm->update_cnt_shift);
+
+ return 0;
+}
+
+static int mt8195_afe_enable_cm(struct mtk_base_afe *afe,
+ const struct mt8195_afe_channel_merge *cm,
+ bool enable)
+{
+ if (!cm)
+ return -EINVAL;
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->en_maskbit << cm->en_shift,
+ enable << cm->en_shift);
+
+ return 0;
+}
+
+static int
+mt8195_afe_paired_memif_clk_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai,
+ int enable)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ int clk_id;
+
+ if (id != MT8195_AFE_MEMIF_DL8 && id != MT8195_AFE_MEMIF_DL10)
+ return 0;
+
+ if (enable) {
+ clk_id = MT8195_CLK_AUD_MEMIF_DL10;
+ mt8195_afe_prepare_clk(afe, afe_priv->clk[clk_id]);
+ clk_id = MT8195_CLK_AUD_MEMIF_DL8;
+ mt8195_afe_prepare_clk(afe, afe_priv->clk[clk_id]);
+ } else {
+ clk_id = MT8195_CLK_AUD_MEMIF_DL8;
+ mt8195_afe_unprepare_clk(afe, afe_priv->clk[clk_id]);
+ clk_id = MT8195_CLK_AUD_MEMIF_DL10;
+ mt8195_afe_unprepare_clk(afe, afe_priv->clk[clk_id]);
+ }
+
+ return 0;
+}
+
+static int
+mt8195_afe_paired_memif_clk_enable(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai,
+ int enable)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ int clk_id;
+
+ if (id != MT8195_AFE_MEMIF_DL8 && id != MT8195_AFE_MEMIF_DL10)
+ return 0;
+
+ if (enable) {
+ /* DL8_DL10_MEM */
+ clk_id = MT8195_CLK_AUD_MEMIF_DL10;
+ mt8195_afe_enable_clk_atomic(afe, afe_priv->clk[clk_id]);
+ udelay(1);
+ /* DL8_DL10_AGENT */
+ clk_id = MT8195_CLK_AUD_MEMIF_DL8;
+ mt8195_afe_enable_clk_atomic(afe, afe_priv->clk[clk_id]);
+ } else {
+ /* DL8_DL10_AGENT */
+ clk_id = MT8195_CLK_AUD_MEMIF_DL8;
+ mt8195_afe_disable_clk_atomic(afe, afe_priv->clk[clk_id]);
+ /* DL8_DL10_MEM */
+ clk_id = MT8195_CLK_AUD_MEMIF_DL10;
+ mt8195_afe_disable_clk_atomic(afe, afe_priv->clk[clk_id]);
+ }
+
+ return 0;
+}
+
+static int mt8195_afe_fe_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ int ret = 0;
+
+ mt8195_afe_paired_memif_clk_prepare(substream, dai, 1);
+
+ ret = mtk_afe_fe_startup(substream, dai);
+
+ snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ MT8195_MEMIF_BUFFER_BYTES_ALIGN);
+
+ if (id != MT8195_AFE_MEMIF_DL7)
+ goto out;
+
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ 1,
+ MT8195_MEMIF_DL7_MAX_PERIOD_SIZE);
+ if (ret < 0)
+ dev_dbg(afe->dev, "hw_constraint_minmax failed\n");
+out:
+ return ret;
+}
+
+static void mt8195_afe_fe_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ mtk_afe_fe_shutdown(substream, dai);
+ mt8195_afe_paired_memif_clk_prepare(substream, dai, 0);
+}
+
+static int mt8195_afe_fe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ struct mtk_base_afe_memif *memif = &afe->memif[id];
+ const struct mtk_base_memif_data *data = memif->data;
+ const struct mt8195_afe_channel_merge *cm = mt8195_afe_found_cm(dai);
+ unsigned int ch_num = params_channels(params);
+
+ mt8195_afe_config_cm(afe, cm, params_channels(params));
+
+ if (data->ch_num_reg >= 0) {
+ regmap_update_bits(afe->regmap, data->ch_num_reg,
+ data->ch_num_maskbit << data->ch_num_shift,
+ ch_num << data->ch_num_shift);
+ }
+
+ return mtk_afe_fe_hw_params(substream, params, dai);
+}
+
+static int mt8195_afe_fe_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ return mtk_afe_fe_hw_free(substream, dai);
+}
+
+static int mt8195_afe_fe_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ return mtk_afe_fe_prepare(substream, dai);
+}
+
+static int mt8195_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ const struct mt8195_afe_channel_merge *cm = mt8195_afe_found_cm(dai);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ mt8195_afe_enable_cm(afe, cm, true);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ mt8195_afe_enable_cm(afe, cm, false);
+ break;
+ default:
+ break;
+ }
+
+ ret = mtk_afe_fe_trigger(substream, cmd, dai);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ mt8195_afe_paired_memif_clk_enable(substream, dai, 1);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ mt8195_afe_paired_memif_clk_enable(substream, dai, 0);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int mt8195_afe_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ return 0;
+}
+
+static const struct snd_soc_dai_ops mt8195_afe_fe_dai_ops = {
+ .startup = mt8195_afe_fe_startup,
+ .shutdown = mt8195_afe_fe_shutdown,
+ .hw_params = mt8195_afe_fe_hw_params,
+ .hw_free = mt8195_afe_fe_hw_free,
+ .prepare = mt8195_afe_fe_prepare,
+ .trigger = mt8195_afe_fe_trigger,
+ .set_fmt = mt8195_afe_fe_set_fmt,
+};
+
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
+ SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000 |\
+ SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000 |\
+ SNDRV_PCM_RATE_352800 |\
+ SNDRV_PCM_RATE_384000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mt8195_memif_dai_driver[] = {
+ /* FE DAIs: memory intefaces to CPU */
+ {
+ .name = "DL2",
+ .id = MT8195_AFE_MEMIF_DL2,
+ .playback = {
+ .stream_name = "DL2",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL3",
+ .id = MT8195_AFE_MEMIF_DL3,
+ .playback = {
+ .stream_name = "DL3",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL6",
+ .id = MT8195_AFE_MEMIF_DL6,
+ .playback = {
+ .stream_name = "DL6",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL7",
+ .id = MT8195_AFE_MEMIF_DL7,
+ .playback = {
+ .stream_name = "DL7",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL8",
+ .id = MT8195_AFE_MEMIF_DL8,
+ .playback = {
+ .stream_name = "DL8",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL10",
+ .id = MT8195_AFE_MEMIF_DL10,
+ .playback = {
+ .stream_name = "DL10",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL11",
+ .id = MT8195_AFE_MEMIF_DL11,
+ .playback = {
+ .stream_name = "DL11",
+ .channels_min = 1,
+ .channels_max = 48,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL1",
+ .id = MT8195_AFE_MEMIF_UL1,
+ .capture = {
+ .stream_name = "UL1",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL2",
+ .id = MT8195_AFE_MEMIF_UL2,
+ .capture = {
+ .stream_name = "UL2",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL3",
+ .id = MT8195_AFE_MEMIF_UL3,
+ .capture = {
+ .stream_name = "UL3",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL4",
+ .id = MT8195_AFE_MEMIF_UL4,
+ .capture = {
+ .stream_name = "UL4",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL5",
+ .id = MT8195_AFE_MEMIF_UL5,
+ .capture = {
+ .stream_name = "UL5",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL6",
+ .id = MT8195_AFE_MEMIF_UL6,
+ .capture = {
+ .stream_name = "UL6",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL8",
+ .id = MT8195_AFE_MEMIF_UL8,
+ .capture = {
+ .stream_name = "UL8",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL9",
+ .id = MT8195_AFE_MEMIF_UL9,
+ .capture = {
+ .stream_name = "UL9",
+ .channels_min = 1,
+ .channels_max = 32,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL10",
+ .id = MT8195_AFE_MEMIF_UL10,
+ .capture = {
+ .stream_name = "UL10",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8195_afe_fe_dai_ops,
+ },
+};
+
+static const struct snd_kcontrol_new o002_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN2, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN2, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN2, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN2, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN2_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN2_2, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN2_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o003_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN3, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN3, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN3, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN3, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN3_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN3_2, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN3_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o004_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN4, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN4, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN4, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN4_2, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN4_5, 10, 1, 0),
+};
+
+static const struct snd_kcontrol_new o005_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN5, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN5, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN5, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN5_2, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN5_5, 11, 1, 0),
+};
+
+static const struct snd_kcontrol_new o006_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN6, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN6, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN6, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN6_2, 12, 1, 0),
+};
+
+static const struct snd_kcontrol_new o007_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN7, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN7, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN7, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN7_2, 13, 1, 0),
+};
+
+static const struct snd_kcontrol_new o008_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN8, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN8, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN8_2, 14, 1, 0),
+};
+
+static const struct snd_kcontrol_new o009_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN9, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN9, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN9_2, 15, 1, 0),
+};
+
+static const struct snd_kcontrol_new o010_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN10, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN10, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN10_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN10_2, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o011_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN11, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN11, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN11_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN11_2, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o012_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN12, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN12_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN12_1, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN12_2, 10, 1, 0),
+};
+
+static const struct snd_kcontrol_new o013_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN13, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN13_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN13_1, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN13_2, 11, 1, 0),
+};
+
+static const struct snd_kcontrol_new o014_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN14, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN14_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN14_1, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN14_2, 12, 1, 0),
+};
+
+static const struct snd_kcontrol_new o015_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN15, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN15_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN15_1, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN15_2, 13, 1, 0),
+};
+
+static const struct snd_kcontrol_new o016_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN16, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN16_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN16_1, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN16_2, 14, 1, 0),
+};
+
+static const struct snd_kcontrol_new o017_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN17, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN17_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN17_1, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN17_2, 15, 1, 0),
+};
+
+static const struct snd_kcontrol_new o018_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN18_1, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I080 Switch", AFE_CONN18_2, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new o019_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN19_1, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I081 Switch", AFE_CONN19_2, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new o020_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN20_1, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I082 Switch", AFE_CONN20_2, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new o021_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN21_1, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I083 Switch", AFE_CONN21_2, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new o022_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN22_1, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I084 Switch", AFE_CONN22_2, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new o023_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN23_1, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I085 Switch", AFE_CONN23_2, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new o024_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN24_1, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I086 Switch", AFE_CONN24_2, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new o025_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN25_1, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I087 Switch", AFE_CONN25_2, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new o026_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN26_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I088 Switch", AFE_CONN26_2, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new o027_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN27_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I089 Switch", AFE_CONN27_2, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new o028_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN28_1, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I090 Switch", AFE_CONN28_2, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new o029_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN29_1, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I091 Switch", AFE_CONN29_2, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new o030_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN30_1, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I092 Switch", AFE_CONN30_2, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new o031_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN31_1, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I093 Switch", AFE_CONN31_2, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new o032_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN32_1, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I094 Switch", AFE_CONN32_2, 30, 1, 0),
+};
+
+static const struct snd_kcontrol_new o033_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN33_1, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I095 Switch", AFE_CONN33_2, 31, 1, 0),
+};
+
+static const struct snd_kcontrol_new o034_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN34, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN34, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN34, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN34, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN34_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN34_2, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN34_5, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN34_5, 10, 1, 0),
+};
+
+static const struct snd_kcontrol_new o035_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN35, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN35, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN35, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN35, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN35_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN35_2, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I137 Switch", AFE_CONN35_4, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I139 Switch", AFE_CONN35_4, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN35_5, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN35_5, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN35_5, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN35_5, 11, 1, 0),
+};
+
+static const struct snd_kcontrol_new o036_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN36, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN36, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN36, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN36_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN36_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o037_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN37, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN37, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN37, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN37_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN37_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o038_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN38, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new o039_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN39, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new o040_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN40, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN40, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN40, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN40_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o041_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN41, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN41, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN41, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN41_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o042_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN42, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN42, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN42_5, 10, 1, 0),
+};
+
+static const struct snd_kcontrol_new o043_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN43, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN43, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN43_5, 11, 1, 0),
+};
+
+static const struct snd_kcontrol_new o044_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN44, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN44, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new o045_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN45, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN45, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new o046_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN46, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN46, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new o047_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN47, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN47, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new o182_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN182, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new o183_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN183, 25, 1, 0),
+};
+
+static const char * const dl8_dl11_data_sel_mux_text[] = {
+ "dl8", "dl11",
+};
+
+static SOC_ENUM_SINGLE_DECL(dl8_dl11_data_sel_mux_enum,
+ AFE_DAC_CON2, 0, dl8_dl11_data_sel_mux_text);
+
+static const struct snd_kcontrol_new dl8_dl11_data_sel_mux =
+ SOC_DAPM_ENUM("DL8_DL11 Sink", dl8_dl11_data_sel_mux_enum);
+
+static const struct snd_soc_dapm_widget mt8195_memif_widgets[] = {
+ /* DL6 */
+ SND_SOC_DAPM_MIXER("I000", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I001", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL3 */
+ SND_SOC_DAPM_MIXER("I020", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I021", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL11 */
+ SND_SOC_DAPM_MIXER("I022", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I023", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I024", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I025", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I026", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I027", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I028", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I029", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I030", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I031", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I034", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I035", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I036", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I037", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I038", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I039", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I040", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I041", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I042", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I043", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I044", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I045", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL11/DL8 */
+ SND_SOC_DAPM_MIXER("I046", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I047", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I048", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I049", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I050", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I051", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I052", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I053", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I054", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I055", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I056", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I057", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I058", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I059", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I060", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I061", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I062", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I063", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I064", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I065", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I066", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I067", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I068", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I069", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL2 */
+ SND_SOC_DAPM_MIXER("I070", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I071", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("DL8_DL11 Mux",
+ SND_SOC_NOPM, 0, 0, &dl8_dl11_data_sel_mux),
+
+ /* UL9 */
+ SND_SOC_DAPM_MIXER("O002", SND_SOC_NOPM, 0, 0,
+ o002_mix, ARRAY_SIZE(o002_mix)),
+ SND_SOC_DAPM_MIXER("O003", SND_SOC_NOPM, 0, 0,
+ o003_mix, ARRAY_SIZE(o003_mix)),
+ SND_SOC_DAPM_MIXER("O004", SND_SOC_NOPM, 0, 0,
+ o004_mix, ARRAY_SIZE(o004_mix)),
+ SND_SOC_DAPM_MIXER("O005", SND_SOC_NOPM, 0, 0,
+ o005_mix, ARRAY_SIZE(o005_mix)),
+ SND_SOC_DAPM_MIXER("O006", SND_SOC_NOPM, 0, 0,
+ o006_mix, ARRAY_SIZE(o006_mix)),
+ SND_SOC_DAPM_MIXER("O007", SND_SOC_NOPM, 0, 0,
+ o007_mix, ARRAY_SIZE(o007_mix)),
+ SND_SOC_DAPM_MIXER("O008", SND_SOC_NOPM, 0, 0,
+ o008_mix, ARRAY_SIZE(o008_mix)),
+ SND_SOC_DAPM_MIXER("O009", SND_SOC_NOPM, 0, 0,
+ o009_mix, ARRAY_SIZE(o009_mix)),
+ SND_SOC_DAPM_MIXER("O010", SND_SOC_NOPM, 0, 0,
+ o010_mix, ARRAY_SIZE(o010_mix)),
+ SND_SOC_DAPM_MIXER("O011", SND_SOC_NOPM, 0, 0,
+ o011_mix, ARRAY_SIZE(o011_mix)),
+ SND_SOC_DAPM_MIXER("O012", SND_SOC_NOPM, 0, 0,
+ o012_mix, ARRAY_SIZE(o012_mix)),
+ SND_SOC_DAPM_MIXER("O013", SND_SOC_NOPM, 0, 0,
+ o013_mix, ARRAY_SIZE(o013_mix)),
+ SND_SOC_DAPM_MIXER("O014", SND_SOC_NOPM, 0, 0,
+ o014_mix, ARRAY_SIZE(o014_mix)),
+ SND_SOC_DAPM_MIXER("O015", SND_SOC_NOPM, 0, 0,
+ o015_mix, ARRAY_SIZE(o015_mix)),
+ SND_SOC_DAPM_MIXER("O016", SND_SOC_NOPM, 0, 0,
+ o016_mix, ARRAY_SIZE(o016_mix)),
+ SND_SOC_DAPM_MIXER("O017", SND_SOC_NOPM, 0, 0,
+ o017_mix, ARRAY_SIZE(o017_mix)),
+ SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0,
+ o018_mix, ARRAY_SIZE(o018_mix)),
+ SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0,
+ o019_mix, ARRAY_SIZE(o019_mix)),
+ SND_SOC_DAPM_MIXER("O020", SND_SOC_NOPM, 0, 0,
+ o020_mix, ARRAY_SIZE(o020_mix)),
+ SND_SOC_DAPM_MIXER("O021", SND_SOC_NOPM, 0, 0,
+ o021_mix, ARRAY_SIZE(o021_mix)),
+ SND_SOC_DAPM_MIXER("O022", SND_SOC_NOPM, 0, 0,
+ o022_mix, ARRAY_SIZE(o022_mix)),
+ SND_SOC_DAPM_MIXER("O023", SND_SOC_NOPM, 0, 0,
+ o023_mix, ARRAY_SIZE(o023_mix)),
+ SND_SOC_DAPM_MIXER("O024", SND_SOC_NOPM, 0, 0,
+ o024_mix, ARRAY_SIZE(o024_mix)),
+ SND_SOC_DAPM_MIXER("O025", SND_SOC_NOPM, 0, 0,
+ o025_mix, ARRAY_SIZE(o025_mix)),
+ SND_SOC_DAPM_MIXER("O026", SND_SOC_NOPM, 0, 0,
+ o026_mix, ARRAY_SIZE(o026_mix)),
+ SND_SOC_DAPM_MIXER("O027", SND_SOC_NOPM, 0, 0,
+ o027_mix, ARRAY_SIZE(o027_mix)),
+ SND_SOC_DAPM_MIXER("O028", SND_SOC_NOPM, 0, 0,
+ o028_mix, ARRAY_SIZE(o028_mix)),
+ SND_SOC_DAPM_MIXER("O029", SND_SOC_NOPM, 0, 0,
+ o029_mix, ARRAY_SIZE(o029_mix)),
+ SND_SOC_DAPM_MIXER("O030", SND_SOC_NOPM, 0, 0,
+ o030_mix, ARRAY_SIZE(o030_mix)),
+ SND_SOC_DAPM_MIXER("O031", SND_SOC_NOPM, 0, 0,
+ o031_mix, ARRAY_SIZE(o031_mix)),
+ SND_SOC_DAPM_MIXER("O032", SND_SOC_NOPM, 0, 0,
+ o032_mix, ARRAY_SIZE(o032_mix)),
+ SND_SOC_DAPM_MIXER("O033", SND_SOC_NOPM, 0, 0,
+ o033_mix, ARRAY_SIZE(o033_mix)),
+
+ /* UL4 */
+ SND_SOC_DAPM_MIXER("O034", SND_SOC_NOPM, 0, 0,
+ o034_mix, ARRAY_SIZE(o034_mix)),
+ SND_SOC_DAPM_MIXER("O035", SND_SOC_NOPM, 0, 0,
+ o035_mix, ARRAY_SIZE(o035_mix)),
+
+ /* UL5 */
+ SND_SOC_DAPM_MIXER("O036", SND_SOC_NOPM, 0, 0,
+ o036_mix, ARRAY_SIZE(o036_mix)),
+ SND_SOC_DAPM_MIXER("O037", SND_SOC_NOPM, 0, 0,
+ o037_mix, ARRAY_SIZE(o037_mix)),
+
+ /* UL10 */
+ SND_SOC_DAPM_MIXER("O038", SND_SOC_NOPM, 0, 0,
+ o038_mix, ARRAY_SIZE(o038_mix)),
+ SND_SOC_DAPM_MIXER("O039", SND_SOC_NOPM, 0, 0,
+ o039_mix, ARRAY_SIZE(o039_mix)),
+ SND_SOC_DAPM_MIXER("O182", SND_SOC_NOPM, 0, 0,
+ o182_mix, ARRAY_SIZE(o182_mix)),
+ SND_SOC_DAPM_MIXER("O183", SND_SOC_NOPM, 0, 0,
+ o183_mix, ARRAY_SIZE(o183_mix)),
+
+ /* UL2 */
+ SND_SOC_DAPM_MIXER("O040", SND_SOC_NOPM, 0, 0,
+ o040_mix, ARRAY_SIZE(o040_mix)),
+ SND_SOC_DAPM_MIXER("O041", SND_SOC_NOPM, 0, 0,
+ o041_mix, ARRAY_SIZE(o041_mix)),
+ SND_SOC_DAPM_MIXER("O042", SND_SOC_NOPM, 0, 0,
+ o042_mix, ARRAY_SIZE(o042_mix)),
+ SND_SOC_DAPM_MIXER("O043", SND_SOC_NOPM, 0, 0,
+ o043_mix, ARRAY_SIZE(o043_mix)),
+ SND_SOC_DAPM_MIXER("O044", SND_SOC_NOPM, 0, 0,
+ o044_mix, ARRAY_SIZE(o044_mix)),
+ SND_SOC_DAPM_MIXER("O045", SND_SOC_NOPM, 0, 0,
+ o045_mix, ARRAY_SIZE(o045_mix)),
+ SND_SOC_DAPM_MIXER("O046", SND_SOC_NOPM, 0, 0,
+ o046_mix, ARRAY_SIZE(o046_mix)),
+ SND_SOC_DAPM_MIXER("O047", SND_SOC_NOPM, 0, 0,
+ o047_mix, ARRAY_SIZE(o047_mix)),
+};
+
+static const struct snd_soc_dapm_route mt8195_memif_routes[] = {
+ {"I000", NULL, "DL6"},
+ {"I001", NULL, "DL6"},
+
+ {"I020", NULL, "DL3"},
+ {"I021", NULL, "DL3"},
+
+ {"I022", NULL, "DL11"},
+ {"I023", NULL, "DL11"},
+ {"I024", NULL, "DL11"},
+ {"I025", NULL, "DL11"},
+ {"I026", NULL, "DL11"},
+ {"I027", NULL, "DL11"},
+ {"I028", NULL, "DL11"},
+ {"I029", NULL, "DL11"},
+ {"I030", NULL, "DL11"},
+ {"I031", NULL, "DL11"},
+ {"I032", NULL, "DL11"},
+ {"I033", NULL, "DL11"},
+ {"I034", NULL, "DL11"},
+ {"I035", NULL, "DL11"},
+ {"I036", NULL, "DL11"},
+ {"I037", NULL, "DL11"},
+ {"I038", NULL, "DL11"},
+ {"I039", NULL, "DL11"},
+ {"I040", NULL, "DL11"},
+ {"I041", NULL, "DL11"},
+ {"I042", NULL, "DL11"},
+ {"I043", NULL, "DL11"},
+ {"I044", NULL, "DL11"},
+ {"I045", NULL, "DL11"},
+
+ {"DL8_DL11 Mux", "dl8", "DL8"},
+ {"DL8_DL11 Mux", "dl11", "DL11"},
+
+ {"I046", NULL, "DL8_DL11 Mux"},
+ {"I047", NULL, "DL8_DL11 Mux"},
+ {"I048", NULL, "DL8_DL11 Mux"},
+ {"I049", NULL, "DL8_DL11 Mux"},
+ {"I050", NULL, "DL8_DL11 Mux"},
+ {"I051", NULL, "DL8_DL11 Mux"},
+ {"I052", NULL, "DL8_DL11 Mux"},
+ {"I053", NULL, "DL8_DL11 Mux"},
+ {"I054", NULL, "DL8_DL11 Mux"},
+ {"I055", NULL, "DL8_DL11 Mux"},
+ {"I056", NULL, "DL8_DL11 Mux"},
+ {"I057", NULL, "DL8_DL11 Mux"},
+ {"I058", NULL, "DL8_DL11 Mux"},
+ {"I059", NULL, "DL8_DL11 Mux"},
+ {"I060", NULL, "DL8_DL11 Mux"},
+ {"I061", NULL, "DL8_DL11 Mux"},
+ {"I062", NULL, "DL8_DL11 Mux"},
+ {"I063", NULL, "DL8_DL11 Mux"},
+ {"I064", NULL, "DL8_DL11 Mux"},
+ {"I065", NULL, "DL8_DL11 Mux"},
+ {"I066", NULL, "DL8_DL11 Mux"},
+ {"I067", NULL, "DL8_DL11 Mux"},
+ {"I068", NULL, "DL8_DL11 Mux"},
+ {"I069", NULL, "DL8_DL11 Mux"},
+
+ {"I070", NULL, "DL2"},
+ {"I071", NULL, "DL2"},
+
+ {"UL9", NULL, "O002"},
+ {"UL9", NULL, "O003"},
+ {"UL9", NULL, "O004"},
+ {"UL9", NULL, "O005"},
+ {"UL9", NULL, "O006"},
+ {"UL9", NULL, "O007"},
+ {"UL9", NULL, "O008"},
+ {"UL9", NULL, "O009"},
+ {"UL9", NULL, "O010"},
+ {"UL9", NULL, "O011"},
+ {"UL9", NULL, "O012"},
+ {"UL9", NULL, "O013"},
+ {"UL9", NULL, "O014"},
+ {"UL9", NULL, "O015"},
+ {"UL9", NULL, "O016"},
+ {"UL9", NULL, "O017"},
+ {"UL9", NULL, "O018"},
+ {"UL9", NULL, "O019"},
+ {"UL9", NULL, "O020"},
+ {"UL9", NULL, "O021"},
+ {"UL9", NULL, "O022"},
+ {"UL9", NULL, "O023"},
+ {"UL9", NULL, "O024"},
+ {"UL9", NULL, "O025"},
+ {"UL9", NULL, "O026"},
+ {"UL9", NULL, "O027"},
+ {"UL9", NULL, "O028"},
+ {"UL9", NULL, "O029"},
+ {"UL9", NULL, "O030"},
+ {"UL9", NULL, "O031"},
+ {"UL9", NULL, "O032"},
+ {"UL9", NULL, "O033"},
+
+ {"UL4", NULL, "O034"},
+ {"UL4", NULL, "O035"},
+
+ {"UL5", NULL, "O036"},
+ {"UL5", NULL, "O037"},
+
+ {"UL10", NULL, "O038"},
+ {"UL10", NULL, "O039"},
+ {"UL10", NULL, "O182"},
+ {"UL10", NULL, "O183"},
+
+ {"UL2", NULL, "O040"},
+ {"UL2", NULL, "O041"},
+ {"UL2", NULL, "O042"},
+ {"UL2", NULL, "O043"},
+ {"UL2", NULL, "O044"},
+ {"UL2", NULL, "O045"},
+ {"UL2", NULL, "O046"},
+ {"UL2", NULL, "O047"},
+
+ {"O004", "I000 Switch", "I000"},
+ {"O005", "I001 Switch", "I001"},
+
+ {"O006", "I000 Switch", "I000"},
+ {"O007", "I001 Switch", "I001"},
+
+ {"O010", "I022 Switch", "I022"},
+ {"O011", "I023 Switch", "I023"},
+ {"O012", "I024 Switch", "I024"},
+ {"O013", "I025 Switch", "I025"},
+ {"O014", "I026 Switch", "I026"},
+ {"O015", "I027 Switch", "I027"},
+ {"O016", "I028 Switch", "I028"},
+ {"O017", "I029 Switch", "I029"},
+
+ {"O010", "I046 Switch", "I046"},
+ {"O011", "I047 Switch", "I047"},
+ {"O012", "I048 Switch", "I048"},
+ {"O013", "I049 Switch", "I049"},
+ {"O014", "I050 Switch", "I050"},
+ {"O015", "I051 Switch", "I051"},
+ {"O016", "I052 Switch", "I052"},
+ {"O017", "I053 Switch", "I053"},
+ {"O002", "I022 Switch", "I022"},
+ {"O003", "I023 Switch", "I023"},
+ {"O004", "I024 Switch", "I024"},
+ {"O005", "I025 Switch", "I025"},
+ {"O006", "I026 Switch", "I026"},
+ {"O007", "I027 Switch", "I027"},
+ {"O008", "I028 Switch", "I028"},
+ {"O009", "I029 Switch", "I029"},
+ {"O010", "I030 Switch", "I030"},
+ {"O011", "I031 Switch", "I031"},
+ {"O012", "I032 Switch", "I032"},
+ {"O013", "I033 Switch", "I033"},
+ {"O014", "I034 Switch", "I034"},
+ {"O015", "I035 Switch", "I035"},
+ {"O016", "I036 Switch", "I036"},
+ {"O017", "I037 Switch", "I037"},
+ {"O018", "I038 Switch", "I038"},
+ {"O019", "I039 Switch", "I039"},
+ {"O020", "I040 Switch", "I040"},
+ {"O021", "I041 Switch", "I041"},
+ {"O022", "I042 Switch", "I042"},
+ {"O023", "I043 Switch", "I043"},
+ {"O024", "I044 Switch", "I044"},
+ {"O025", "I045 Switch", "I045"},
+ {"O026", "I046 Switch", "I046"},
+ {"O027", "I047 Switch", "I047"},
+ {"O028", "I048 Switch", "I048"},
+ {"O029", "I049 Switch", "I049"},
+ {"O030", "I050 Switch", "I050"},
+ {"O031", "I051 Switch", "I051"},
+ {"O032", "I052 Switch", "I052"},
+ {"O033", "I053 Switch", "I053"},
+
+ {"O002", "I000 Switch", "I000"},
+ {"O003", "I001 Switch", "I001"},
+ {"O002", "I020 Switch", "I020"},
+ {"O003", "I021 Switch", "I021"},
+ {"O002", "I070 Switch", "I070"},
+ {"O003", "I071 Switch", "I071"},
+
+ {"O034", "I000 Switch", "I000"},
+ {"O035", "I001 Switch", "I001"},
+ {"O034", "I002 Switch", "I002"},
+ {"O035", "I003 Switch", "I003"},
+ {"O034", "I012 Switch", "I012"},
+ {"O035", "I013 Switch", "I013"},
+ {"O034", "I020 Switch", "I020"},
+ {"O035", "I021 Switch", "I021"},
+ {"O034", "I070 Switch", "I070"},
+ {"O035", "I071 Switch", "I071"},
+ {"O034", "I072 Switch", "I072"},
+ {"O035", "I073 Switch", "I073"},
+
+ {"O036", "I000 Switch", "I000"},
+ {"O037", "I001 Switch", "I001"},
+ {"O036", "I012 Switch", "I012"},
+ {"O037", "I013 Switch", "I013"},
+ {"O036", "I020 Switch", "I020"},
+ {"O037", "I021 Switch", "I021"},
+ {"O036", "I070 Switch", "I070"},
+ {"O037", "I071 Switch", "I071"},
+ {"O036", "I168 Switch", "I168"},
+ {"O037", "I169 Switch", "I169"},
+
+ {"O038", "I022 Switch", "I022"},
+ {"O039", "I023 Switch", "I023"},
+ {"O182", "I024 Switch", "I024"},
+ {"O183", "I025 Switch", "I025"},
+
+ {"O040", "I022 Switch", "I022"},
+ {"O041", "I023 Switch", "I023"},
+ {"O042", "I024 Switch", "I024"},
+ {"O043", "I025 Switch", "I025"},
+ {"O044", "I026 Switch", "I026"},
+ {"O045", "I027 Switch", "I027"},
+ {"O046", "I028 Switch", "I028"},
+ {"O047", "I029 Switch", "I029"},
+
+ {"O040", "I002 Switch", "I002"},
+ {"O041", "I003 Switch", "I003"},
+ {"O002", "I012 Switch", "I012"},
+ {"O003", "I013 Switch", "I013"},
+ {"O004", "I014 Switch", "I014"},
+ {"O005", "I015 Switch", "I015"},
+ {"O006", "I016 Switch", "I016"},
+ {"O007", "I017 Switch", "I017"},
+ {"O008", "I018 Switch", "I018"},
+ {"O009", "I019 Switch", "I019"},
+
+ {"O040", "I012 Switch", "I012"},
+ {"O041", "I013 Switch", "I013"},
+ {"O042", "I014 Switch", "I014"},
+ {"O043", "I015 Switch", "I015"},
+ {"O044", "I016 Switch", "I016"},
+ {"O045", "I017 Switch", "I017"},
+ {"O046", "I018 Switch", "I018"},
+ {"O047", "I019 Switch", "I019"},
+
+ {"O002", "I072 Switch", "I072"},
+ {"O003", "I073 Switch", "I073"},
+ {"O004", "I074 Switch", "I074"},
+ {"O005", "I075 Switch", "I075"},
+ {"O006", "I076 Switch", "I076"},
+ {"O007", "I077 Switch", "I077"},
+ {"O008", "I078 Switch", "I078"},
+ {"O009", "I079 Switch", "I079"},
+
+ {"O010", "I072 Switch", "I072"},
+ {"O011", "I073 Switch", "I073"},
+ {"O012", "I074 Switch", "I074"},
+ {"O013", "I075 Switch", "I075"},
+ {"O014", "I076 Switch", "I076"},
+ {"O015", "I077 Switch", "I077"},
+ {"O016", "I078 Switch", "I078"},
+ {"O017", "I079 Switch", "I079"},
+ {"O018", "I080 Switch", "I080"},
+ {"O019", "I081 Switch", "I081"},
+ {"O020", "I082 Switch", "I082"},
+ {"O021", "I083 Switch", "I083"},
+ {"O022", "I084 Switch", "I084"},
+ {"O023", "I085 Switch", "I085"},
+ {"O024", "I086 Switch", "I086"},
+ {"O025", "I087 Switch", "I087"},
+ {"O026", "I088 Switch", "I088"},
+ {"O027", "I089 Switch", "I089"},
+ {"O028", "I090 Switch", "I090"},
+ {"O029", "I091 Switch", "I091"},
+ {"O030", "I092 Switch", "I092"},
+ {"O031", "I093 Switch", "I093"},
+ {"O032", "I094 Switch", "I094"},
+ {"O033", "I095 Switch", "I095"},
+
+ {"O002", "I168 Switch", "I168"},
+ {"O003", "I169 Switch", "I169"},
+ {"O004", "I170 Switch", "I170"},
+ {"O005", "I171 Switch", "I171"},
+
+ {"O034", "I168 Switch", "I168"},
+ {"O035", "I168 Switch", "I168"},
+ {"O035", "I169 Switch", "I169"},
+
+ {"O034", "I170 Switch", "I170"},
+ {"O035", "I170 Switch", "I170"},
+ {"O035", "I171 Switch", "I171"},
+
+ {"O040", "I168 Switch", "I168"},
+ {"O041", "I169 Switch", "I169"},
+ {"O042", "I170 Switch", "I170"},
+ {"O043", "I171 Switch", "I171"},
+};
+
+static const char * const mt8195_afe_1x_en_sel_text[] = {
+ "a1sys_a2sys", "a3sys", "a4sys",
+};
+
+static const unsigned int mt8195_afe_1x_en_sel_values[] = {
+ 0, 1, 2,
+};
+
+static int mt8195_memif_1x_en_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ unsigned int dai_id = kcontrol->id.device;
+ long val = ucontrol->value.integer.value[0];
+ int ret = 0;
+
+ memif_priv = afe_priv->dai_priv[dai_id];
+
+ if (val == memif_priv->asys_timing_sel)
+ return 0;
+
+ ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+
+ memif_priv->asys_timing_sel = val;
+
+ return ret;
+}
+
+static int mt8195_asys_irq_1x_en_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ unsigned int id = kcontrol->id.device;
+ long val = ucontrol->value.integer.value[0];
+ int ret = 0;
+
+ if (val == afe_priv->irq_priv[id].asys_timing_sel)
+ return 0;
+
+ ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+
+ afe_priv->irq_priv[id].asys_timing_sel = val;
+
+ return ret;
+}
+
+static SOC_VALUE_ENUM_SINGLE_DECL(dl2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 18, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 20, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 22, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl7_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 24, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 26, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 28, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl11_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 30, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul1_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 0, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 2, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 4, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul4_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 6, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul5_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 8, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 10, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 12, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul9_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 14, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 16, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq1_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 0, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 2, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 4, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq4_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 6, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq5_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 8, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 10, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq7_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 12, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 14, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq9_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 16, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 18, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq11_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 20, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq12_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 22, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq13_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 24, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq14_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 26, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq15_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 28, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq16_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 30, 0x3,
+ mt8195_afe_1x_en_sel_text,
+ mt8195_afe_1x_en_sel_values);
+
+static const struct snd_kcontrol_new mt8195_memif_controls[] = {
+ MT8195_SOC_ENUM_EXT("dl2_1x_en_sel",
+ dl2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL2),
+ MT8195_SOC_ENUM_EXT("dl3_1x_en_sel",
+ dl3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL3),
+ MT8195_SOC_ENUM_EXT("dl6_1x_en_sel",
+ dl6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL6),
+ MT8195_SOC_ENUM_EXT("dl7_1x_en_sel",
+ dl7_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL7),
+ MT8195_SOC_ENUM_EXT("dl8_1x_en_sel",
+ dl8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL8),
+ MT8195_SOC_ENUM_EXT("dl10_1x_en_sel",
+ dl10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL10),
+ MT8195_SOC_ENUM_EXT("dl11_1x_en_sel",
+ dl11_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_DL11),
+ MT8195_SOC_ENUM_EXT("ul1_1x_en_sel",
+ ul1_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL1),
+ MT8195_SOC_ENUM_EXT("ul2_1x_en_sel",
+ ul2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL2),
+ MT8195_SOC_ENUM_EXT("ul3_1x_en_sel",
+ ul3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL3),
+ MT8195_SOC_ENUM_EXT("ul4_1x_en_sel",
+ ul4_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL4),
+ MT8195_SOC_ENUM_EXT("ul5_1x_en_sel",
+ ul5_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL5),
+ MT8195_SOC_ENUM_EXT("ul6_1x_en_sel",
+ ul6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL6),
+ MT8195_SOC_ENUM_EXT("ul8_1x_en_sel",
+ ul8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL8),
+ MT8195_SOC_ENUM_EXT("ul9_1x_en_sel",
+ ul9_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL9),
+ MT8195_SOC_ENUM_EXT("ul10_1x_en_sel",
+ ul10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_memif_1x_en_sel_put,
+ MT8195_AFE_MEMIF_UL10),
+ MT8195_SOC_ENUM_EXT("asys_irq1_1x_en_sel",
+ asys_irq1_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_13),
+ MT8195_SOC_ENUM_EXT("asys_irq2_1x_en_sel",
+ asys_irq2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_14),
+ MT8195_SOC_ENUM_EXT("asys_irq3_1x_en_sel",
+ asys_irq3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_15),
+ MT8195_SOC_ENUM_EXT("asys_irq4_1x_en_sel",
+ asys_irq4_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_16),
+ MT8195_SOC_ENUM_EXT("asys_irq5_1x_en_sel",
+ asys_irq5_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_17),
+ MT8195_SOC_ENUM_EXT("asys_irq6_1x_en_sel",
+ asys_irq6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_18),
+ MT8195_SOC_ENUM_EXT("asys_irq7_1x_en_sel",
+ asys_irq7_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_19),
+ MT8195_SOC_ENUM_EXT("asys_irq8_1x_en_sel",
+ asys_irq8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_20),
+ MT8195_SOC_ENUM_EXT("asys_irq9_1x_en_sel",
+ asys_irq9_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_21),
+ MT8195_SOC_ENUM_EXT("asys_irq10_1x_en_sel",
+ asys_irq10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_22),
+ MT8195_SOC_ENUM_EXT("asys_irq11_1x_en_sel",
+ asys_irq11_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_23),
+ MT8195_SOC_ENUM_EXT("asys_irq12_1x_en_sel",
+ asys_irq12_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_24),
+ MT8195_SOC_ENUM_EXT("asys_irq13_1x_en_sel",
+ asys_irq13_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_25),
+ MT8195_SOC_ENUM_EXT("asys_irq14_1x_en_sel",
+ asys_irq14_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_26),
+ MT8195_SOC_ENUM_EXT("asys_irq15_1x_en_sel",
+ asys_irq15_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_27),
+ MT8195_SOC_ENUM_EXT("asys_irq16_1x_en_sel",
+ asys_irq16_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8195_asys_irq_1x_en_sel_put,
+ MT8195_AFE_IRQ_28),
+};
+
+static const struct snd_soc_component_driver mt8195_afe_pcm_dai_component = {
+ .name = "mt8195-afe-pcm-dai",
+};
+
+static const struct mtk_base_memif_data memif_data[MT8195_AFE_MEMIF_NUM] = {
+ [MT8195_AFE_MEMIF_DL2] = {
+ .name = "DL2",
+ .id = MT8195_AFE_MEMIF_DL2,
+ .reg_ofs_base = AFE_DL2_BASE,
+ .reg_ofs_cur = AFE_DL2_CUR,
+ .reg_ofs_end = AFE_DL2_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON0,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 18,
+ .hd_reg = AFE_DL2_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 18,
+ .ch_num_reg = AFE_DL2_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 18,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 18,
+ },
+ [MT8195_AFE_MEMIF_DL3] = {
+ .name = "DL3",
+ .id = MT8195_AFE_MEMIF_DL3,
+ .reg_ofs_base = AFE_DL3_BASE,
+ .reg_ofs_cur = AFE_DL3_CUR,
+ .reg_ofs_end = AFE_DL3_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON0,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 19,
+ .hd_reg = AFE_DL3_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 19,
+ .ch_num_reg = AFE_DL3_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 19,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 19,
+ },
+ [MT8195_AFE_MEMIF_DL6] = {
+ .name = "DL6",
+ .id = MT8195_AFE_MEMIF_DL6,
+ .reg_ofs_base = AFE_DL6_BASE,
+ .reg_ofs_cur = AFE_DL6_CUR,
+ .reg_ofs_end = AFE_DL6_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 0,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 22,
+ .hd_reg = AFE_DL6_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 22,
+ .ch_num_reg = AFE_DL6_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 22,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 22,
+ },
+ [MT8195_AFE_MEMIF_DL7] = {
+ .name = "DL7",
+ .id = MT8195_AFE_MEMIF_DL7,
+ .reg_ofs_base = AFE_DL7_BASE,
+ .reg_ofs_cur = AFE_DL7_CUR,
+ .reg_ofs_end = AFE_DL7_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 23,
+ .hd_reg = AFE_DL7_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 23,
+ .ch_num_reg = AFE_DL7_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 23,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 23,
+ },
+ [MT8195_AFE_MEMIF_DL8] = {
+ .name = "DL8",
+ .id = MT8195_AFE_MEMIF_DL8,
+ .reg_ofs_base = AFE_DL8_BASE,
+ .reg_ofs_cur = AFE_DL8_CUR,
+ .reg_ofs_end = AFE_DL8_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 24,
+ .hd_reg = AFE_DL8_CON0,
+ .hd_shift = 6,
+ .agent_disable_reg = -1,
+ .agent_disable_shift = 0,
+ .ch_num_reg = AFE_DL8_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x3f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 24,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 24,
+ },
+ [MT8195_AFE_MEMIF_DL10] = {
+ .name = "DL10",
+ .id = MT8195_AFE_MEMIF_DL10,
+ .reg_ofs_base = AFE_DL10_BASE,
+ .reg_ofs_cur = AFE_DL10_CUR,
+ .reg_ofs_end = AFE_DL10_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 20,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 26,
+ .hd_reg = AFE_DL10_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = -1,
+ .agent_disable_shift = 0,
+ .ch_num_reg = AFE_DL10_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 26,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 26,
+ },
+ [MT8195_AFE_MEMIF_DL11] = {
+ .name = "DL11",
+ .id = MT8195_AFE_MEMIF_DL11,
+ .reg_ofs_base = AFE_DL11_BASE,
+ .reg_ofs_cur = AFE_DL11_CUR,
+ .reg_ofs_end = AFE_DL11_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 25,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 27,
+ .hd_reg = AFE_DL11_CON0,
+ .hd_shift = 7,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 27,
+ .ch_num_reg = AFE_DL11_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x7f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 27,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 27,
+ },
+ [MT8195_AFE_MEMIF_UL1] = {
+ .name = "UL1",
+ .id = MT8195_AFE_MEMIF_UL1,
+ .reg_ofs_base = AFE_UL1_BASE,
+ .reg_ofs_cur = AFE_UL1_CUR,
+ .reg_ofs_end = AFE_UL1_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = AFE_UL1_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL1_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 1,
+ .hd_reg = AFE_UL1_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 0,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 0,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 0,
+ },
+ [MT8195_AFE_MEMIF_UL2] = {
+ .name = "UL2",
+ .id = MT8195_AFE_MEMIF_UL2,
+ .reg_ofs_base = AFE_UL2_BASE,
+ .reg_ofs_cur = AFE_UL2_CUR,
+ .reg_ofs_end = AFE_UL2_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 5,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL2_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL2_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 2,
+ .hd_reg = AFE_UL2_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 1,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 1,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 1,
+ },
+ [MT8195_AFE_MEMIF_UL3] = {
+ .name = "UL3",
+ .id = MT8195_AFE_MEMIF_UL3,
+ .reg_ofs_base = AFE_UL3_BASE,
+ .reg_ofs_cur = AFE_UL3_CUR,
+ .reg_ofs_end = AFE_UL3_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL3_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL3_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 3,
+ .hd_reg = AFE_UL3_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 2,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 2,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 2,
+ },
+ [MT8195_AFE_MEMIF_UL4] = {
+ .name = "UL4",
+ .id = MT8195_AFE_MEMIF_UL4,
+ .reg_ofs_base = AFE_UL4_BASE,
+ .reg_ofs_cur = AFE_UL4_CUR,
+ .reg_ofs_end = AFE_UL4_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL4_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL4_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 4,
+ .hd_reg = AFE_UL4_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 3,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 3,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 3,
+ },
+ [MT8195_AFE_MEMIF_UL5] = {
+ .name = "UL5",
+ .id = MT8195_AFE_MEMIF_UL5,
+ .reg_ofs_base = AFE_UL5_BASE,
+ .reg_ofs_cur = AFE_UL5_CUR,
+ .reg_ofs_end = AFE_UL5_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 20,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL5_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL5_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 5,
+ .hd_reg = AFE_UL5_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 4,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 4,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 4,
+ },
+ [MT8195_AFE_MEMIF_UL6] = {
+ .name = "UL6",
+ .id = MT8195_AFE_MEMIF_UL6,
+ .reg_ofs_base = AFE_UL6_BASE,
+ .reg_ofs_cur = AFE_UL6_CUR,
+ .reg_ofs_end = AFE_UL6_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = AFE_UL6_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL6_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 6,
+ .hd_reg = AFE_UL6_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 5,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 5,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 5,
+ },
+ [MT8195_AFE_MEMIF_UL8] = {
+ .name = "UL8",
+ .id = MT8195_AFE_MEMIF_UL8,
+ .reg_ofs_base = AFE_UL8_BASE,
+ .reg_ofs_cur = AFE_UL8_CUR,
+ .reg_ofs_end = AFE_UL8_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 5,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL8_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL8_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 8,
+ .hd_reg = AFE_UL8_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 7,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 7,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 7,
+ },
+ [MT8195_AFE_MEMIF_UL9] = {
+ .name = "UL9",
+ .id = MT8195_AFE_MEMIF_UL9,
+ .reg_ofs_base = AFE_UL9_BASE,
+ .reg_ofs_cur = AFE_UL9_CUR,
+ .reg_ofs_end = AFE_UL9_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL9_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL9_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 9,
+ .hd_reg = AFE_UL9_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 8,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 8,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 8,
+ },
+ [MT8195_AFE_MEMIF_UL10] = {
+ .name = "UL10",
+ .id = MT8195_AFE_MEMIF_UL10,
+ .reg_ofs_base = AFE_UL10_BASE,
+ .reg_ofs_cur = AFE_UL10_CUR,
+ .reg_ofs_end = AFE_UL10_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL10_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL10_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 10,
+ .hd_reg = AFE_UL10_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 9,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 9,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 9,
+ },
+};
+
+static const struct mtk_base_irq_data irq_data[MT8195_AFE_IRQ_NUM] = {
+ [MT8195_AFE_IRQ_1] = {
+ .id = MT8195_AFE_IRQ_1,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ1_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 0,
+ .irq_status_shift = 16,
+ },
+ [MT8195_AFE_IRQ_2] = {
+ .id = MT8195_AFE_IRQ_2,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ2_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 1,
+ .irq_status_shift = 17,
+ },
+ [MT8195_AFE_IRQ_3] = {
+ .id = MT8195_AFE_IRQ_3,
+ .irq_cnt_reg = AFE_IRQ3_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ3_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 2,
+ .irq_status_shift = 18,
+ },
+ [MT8195_AFE_IRQ_8] = {
+ .id = MT8195_AFE_IRQ_8,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ8_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 7,
+ .irq_status_shift = 23,
+ },
+ [MT8195_AFE_IRQ_9] = {
+ .id = MT8195_AFE_IRQ_9,
+ .irq_cnt_reg = AFE_IRQ9_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ9_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 8,
+ .irq_status_shift = 24,
+ },
+ [MT8195_AFE_IRQ_10] = {
+ .id = MT8195_AFE_IRQ_10,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ10_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 9,
+ .irq_status_shift = 25,
+ },
+ [MT8195_AFE_IRQ_13] = {
+ .id = MT8195_AFE_IRQ_13,
+ .irq_cnt_reg = ASYS_IRQ1_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ1_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ1_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 0,
+ .irq_status_shift = 0,
+ },
+ [MT8195_AFE_IRQ_14] = {
+ .id = MT8195_AFE_IRQ_14,
+ .irq_cnt_reg = ASYS_IRQ2_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ2_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ2_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 1,
+ .irq_status_shift = 1,
+ },
+ [MT8195_AFE_IRQ_15] = {
+ .id = MT8195_AFE_IRQ_15,
+ .irq_cnt_reg = ASYS_IRQ3_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ3_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ3_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 2,
+ .irq_status_shift = 2,
+ },
+ [MT8195_AFE_IRQ_16] = {
+ .id = MT8195_AFE_IRQ_16,
+ .irq_cnt_reg = ASYS_IRQ4_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ4_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ4_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 3,
+ .irq_status_shift = 3,
+ },
+ [MT8195_AFE_IRQ_17] = {
+ .id = MT8195_AFE_IRQ_17,
+ .irq_cnt_reg = ASYS_IRQ5_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ5_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ5_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 4,
+ .irq_status_shift = 4,
+ },
+ [MT8195_AFE_IRQ_18] = {
+ .id = MT8195_AFE_IRQ_18,
+ .irq_cnt_reg = ASYS_IRQ6_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ6_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ6_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 5,
+ .irq_status_shift = 5,
+ },
+ [MT8195_AFE_IRQ_19] = {
+ .id = MT8195_AFE_IRQ_19,
+ .irq_cnt_reg = ASYS_IRQ7_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ7_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ7_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 6,
+ .irq_status_shift = 6,
+ },
+ [MT8195_AFE_IRQ_20] = {
+ .id = MT8195_AFE_IRQ_20,
+ .irq_cnt_reg = ASYS_IRQ8_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ8_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ8_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 7,
+ .irq_status_shift = 7,
+ },
+ [MT8195_AFE_IRQ_21] = {
+ .id = MT8195_AFE_IRQ_21,
+ .irq_cnt_reg = ASYS_IRQ9_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ9_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ9_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 8,
+ .irq_status_shift = 8,
+ },
+ [MT8195_AFE_IRQ_22] = {
+ .id = MT8195_AFE_IRQ_22,
+ .irq_cnt_reg = ASYS_IRQ10_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ10_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ10_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 9,
+ .irq_status_shift = 9,
+ },
+ [MT8195_AFE_IRQ_23] = {
+ .id = MT8195_AFE_IRQ_23,
+ .irq_cnt_reg = ASYS_IRQ11_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ11_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ11_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 10,
+ .irq_status_shift = 10,
+ },
+ [MT8195_AFE_IRQ_24] = {
+ .id = MT8195_AFE_IRQ_24,
+ .irq_cnt_reg = ASYS_IRQ12_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ12_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ12_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 11,
+ .irq_status_shift = 11,
+ },
+ [MT8195_AFE_IRQ_25] = {
+ .id = MT8195_AFE_IRQ_25,
+ .irq_cnt_reg = ASYS_IRQ13_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ13_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ13_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 12,
+ .irq_status_shift = 12,
+ },
+ [MT8195_AFE_IRQ_26] = {
+ .id = MT8195_AFE_IRQ_26,
+ .irq_cnt_reg = ASYS_IRQ14_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ14_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ14_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 13,
+ .irq_status_shift = 13,
+ },
+ [MT8195_AFE_IRQ_27] = {
+ .id = MT8195_AFE_IRQ_27,
+ .irq_cnt_reg = ASYS_IRQ15_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ15_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ15_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 14,
+ .irq_status_shift = 14,
+ },
+ [MT8195_AFE_IRQ_28] = {
+ .id = MT8195_AFE_IRQ_28,
+ .irq_cnt_reg = ASYS_IRQ16_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ16_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ16_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 15,
+ .irq_status_shift = 15,
+ },
+};
+
+static const int mt8195_afe_memif_const_irqs[MT8195_AFE_MEMIF_NUM] = {
+ [MT8195_AFE_MEMIF_DL2] = MT8195_AFE_IRQ_13,
+ [MT8195_AFE_MEMIF_DL3] = MT8195_AFE_IRQ_14,
+ [MT8195_AFE_MEMIF_DL6] = MT8195_AFE_IRQ_15,
+ [MT8195_AFE_MEMIF_DL7] = MT8195_AFE_IRQ_1,
+ [MT8195_AFE_MEMIF_DL8] = MT8195_AFE_IRQ_16,
+ [MT8195_AFE_MEMIF_DL10] = MT8195_AFE_IRQ_17,
+ [MT8195_AFE_MEMIF_DL11] = MT8195_AFE_IRQ_18,
+ [MT8195_AFE_MEMIF_UL1] = MT8195_AFE_IRQ_3,
+ [MT8195_AFE_MEMIF_UL2] = MT8195_AFE_IRQ_19,
+ [MT8195_AFE_MEMIF_UL3] = MT8195_AFE_IRQ_20,
+ [MT8195_AFE_MEMIF_UL4] = MT8195_AFE_IRQ_21,
+ [MT8195_AFE_MEMIF_UL5] = MT8195_AFE_IRQ_22,
+ [MT8195_AFE_MEMIF_UL6] = MT8195_AFE_IRQ_9,
+ [MT8195_AFE_MEMIF_UL8] = MT8195_AFE_IRQ_23,
+ [MT8195_AFE_MEMIF_UL9] = MT8195_AFE_IRQ_24,
+ [MT8195_AFE_MEMIF_UL10] = MT8195_AFE_IRQ_25,
+};
+
+static bool mt8195_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ /* these auto-gen reg has read-only bit, so put it as volatile */
+ /* volatile reg cannot be cached, so cannot be set when power off */
+ switch (reg) {
+ case AUDIO_TOP_CON0:
+ case AUDIO_TOP_CON1:
+ case AUDIO_TOP_CON3:
+ case AUDIO_TOP_CON4:
+ case AUDIO_TOP_CON5:
+ case AUDIO_TOP_CON6:
+ case ASYS_IRQ_CLR:
+ case ASYS_IRQ_STATUS:
+ case ASYS_IRQ_MON1:
+ case ASYS_IRQ_MON2:
+ case AFE_IRQ_MCU_CLR:
+ case AFE_IRQ_STATUS:
+ case AFE_IRQ3_CON_MON:
+ case AFE_IRQ_MCU_MON2:
+ case ADSP_IRQ_STATUS:
+ case AFE_APLL_TUNER_CFG:
+ case AFE_APLL_TUNER_CFG1:
+ case AUDIO_TOP_STA0:
+ case AUDIO_TOP_STA1:
+ case AFE_GAIN1_CUR:
+ case AFE_GAIN2_CUR:
+ case AFE_IEC_BURST_INFO:
+ case AFE_IEC_CHL_STAT0:
+ case AFE_IEC_CHL_STAT1:
+ case AFE_IEC_CHR_STAT0:
+ case AFE_IEC_CHR_STAT1:
+ case AFE_SPDIFIN_CHSTS1:
+ case AFE_SPDIFIN_CHSTS2:
+ case AFE_SPDIFIN_CHSTS3:
+ case AFE_SPDIFIN_CHSTS4:
+ case AFE_SPDIFIN_CHSTS5:
+ case AFE_SPDIFIN_CHSTS6:
+ case AFE_SPDIFIN_DEBUG1:
+ case AFE_SPDIFIN_DEBUG2:
+ case AFE_SPDIFIN_DEBUG3:
+ case AFE_SPDIFIN_DEBUG4:
+ case AFE_SPDIFIN_EC:
+ case AFE_SPDIFIN_CKLOCK_CFG:
+ case AFE_SPDIFIN_BR_DBG1:
+ case AFE_SPDIFIN_CKFBDIV:
+ case AFE_SPDIFIN_INT_EXT:
+ case AFE_SPDIFIN_INT_EXT2:
+ case SPDIFIN_FREQ_STATUS:
+ case SPDIFIN_USERCODE1:
+ case SPDIFIN_USERCODE2:
+ case SPDIFIN_USERCODE3:
+ case SPDIFIN_USERCODE4:
+ case SPDIFIN_USERCODE5:
+ case SPDIFIN_USERCODE6:
+ case SPDIFIN_USERCODE7:
+ case SPDIFIN_USERCODE8:
+ case SPDIFIN_USERCODE9:
+ case SPDIFIN_USERCODE10:
+ case SPDIFIN_USERCODE11:
+ case SPDIFIN_USERCODE12:
+ case AFE_SPDIFIN_APLL_TUNER_CFG:
+ case AFE_LINEIN_APLL_TUNER_MON:
+ case AFE_EARC_APLL_TUNER_MON:
+ case AFE_CM0_MON:
+ case AFE_CM1_MON:
+ case AFE_CM2_MON:
+ case AFE_MPHONE_MULTI_DET_MON0:
+ case AFE_MPHONE_MULTI_DET_MON1:
+ case AFE_MPHONE_MULTI_DET_MON2:
+ case AFE_MPHONE_MULTI2_DET_MON0:
+ case AFE_MPHONE_MULTI2_DET_MON1:
+ case AFE_MPHONE_MULTI2_DET_MON2:
+ case AFE_ADDA_MTKAIF_MON0:
+ case AFE_ADDA_MTKAIF_MON1:
+ case AFE_AUD_PAD_TOP:
+ case AFE_ADDA6_MTKAIF_MON0:
+ case AFE_ADDA6_MTKAIF_MON1:
+ case AFE_ADDA6_SRC_DEBUG_MON0:
+ case AFE_ADDA6_UL_SRC_MON0:
+ case AFE_ADDA6_UL_SRC_MON1:
+ case AFE_ASRC11_NEW_CON8:
+ case AFE_ASRC11_NEW_CON9:
+ case AFE_ASRC12_NEW_CON8:
+ case AFE_ASRC12_NEW_CON9:
+ case AFE_LRCK_CNT:
+ case AFE_DAC_MON0:
+ case AFE_DL2_CUR:
+ case AFE_DL3_CUR:
+ case AFE_DL6_CUR:
+ case AFE_DL7_CUR:
+ case AFE_DL8_CUR:
+ case AFE_DL10_CUR:
+ case AFE_DL11_CUR:
+ case AFE_UL1_CUR:
+ case AFE_UL2_CUR:
+ case AFE_UL3_CUR:
+ case AFE_UL4_CUR:
+ case AFE_UL5_CUR:
+ case AFE_UL6_CUR:
+ case AFE_UL8_CUR:
+ case AFE_UL9_CUR:
+ case AFE_UL10_CUR:
+ case AFE_DL8_CHK_SUM1:
+ case AFE_DL8_CHK_SUM2:
+ case AFE_DL8_CHK_SUM3:
+ case AFE_DL8_CHK_SUM4:
+ case AFE_DL8_CHK_SUM5:
+ case AFE_DL8_CHK_SUM6:
+ case AFE_DL10_CHK_SUM1:
+ case AFE_DL10_CHK_SUM2:
+ case AFE_DL10_CHK_SUM3:
+ case AFE_DL10_CHK_SUM4:
+ case AFE_DL10_CHK_SUM5:
+ case AFE_DL10_CHK_SUM6:
+ case AFE_DL11_CHK_SUM1:
+ case AFE_DL11_CHK_SUM2:
+ case AFE_DL11_CHK_SUM3:
+ case AFE_DL11_CHK_SUM4:
+ case AFE_DL11_CHK_SUM5:
+ case AFE_DL11_CHK_SUM6:
+ case AFE_UL1_CHK_SUM1:
+ case AFE_UL1_CHK_SUM2:
+ case AFE_UL2_CHK_SUM1:
+ case AFE_UL2_CHK_SUM2:
+ case AFE_UL3_CHK_SUM1:
+ case AFE_UL3_CHK_SUM2:
+ case AFE_UL4_CHK_SUM1:
+ case AFE_UL4_CHK_SUM2:
+ case AFE_UL5_CHK_SUM1:
+ case AFE_UL5_CHK_SUM2:
+ case AFE_UL6_CHK_SUM1:
+ case AFE_UL6_CHK_SUM2:
+ case AFE_UL8_CHK_SUM1:
+ case AFE_UL8_CHK_SUM2:
+ case AFE_DL2_CHK_SUM1:
+ case AFE_DL2_CHK_SUM2:
+ case AFE_DL3_CHK_SUM1:
+ case AFE_DL3_CHK_SUM2:
+ case AFE_DL6_CHK_SUM1:
+ case AFE_DL6_CHK_SUM2:
+ case AFE_DL7_CHK_SUM1:
+ case AFE_DL7_CHK_SUM2:
+ case AFE_UL9_CHK_SUM1:
+ case AFE_UL9_CHK_SUM2:
+ case AFE_BUS_MON1:
+ case UL1_MOD2AGT_CNT_LAT:
+ case UL2_MOD2AGT_CNT_LAT:
+ case UL3_MOD2AGT_CNT_LAT:
+ case UL4_MOD2AGT_CNT_LAT:
+ case UL5_MOD2AGT_CNT_LAT:
+ case UL6_MOD2AGT_CNT_LAT:
+ case UL8_MOD2AGT_CNT_LAT:
+ case UL9_MOD2AGT_CNT_LAT:
+ case UL10_MOD2AGT_CNT_LAT:
+ case AFE_MEMIF_BUF_FULL_MON:
+ case AFE_MEMIF_BUF_MON1:
+ case AFE_MEMIF_BUF_MON3:
+ case AFE_MEMIF_BUF_MON4:
+ case AFE_MEMIF_BUF_MON5:
+ case AFE_MEMIF_BUF_MON6:
+ case AFE_MEMIF_BUF_MON7:
+ case AFE_MEMIF_BUF_MON8:
+ case AFE_MEMIF_BUF_MON9:
+ case AFE_MEMIF_BUF_MON10:
+ case DL2_AGENT2MODULE_CNT:
+ case DL3_AGENT2MODULE_CNT:
+ case DL6_AGENT2MODULE_CNT:
+ case DL7_AGENT2MODULE_CNT:
+ case DL8_AGENT2MODULE_CNT:
+ case DL10_AGENT2MODULE_CNT:
+ case DL11_AGENT2MODULE_CNT:
+ case UL1_MODULE2AGENT_CNT:
+ case UL2_MODULE2AGENT_CNT:
+ case UL3_MODULE2AGENT_CNT:
+ case UL4_MODULE2AGENT_CNT:
+ case UL5_MODULE2AGENT_CNT:
+ case UL6_MODULE2AGENT_CNT:
+ case UL8_MODULE2AGENT_CNT:
+ case UL9_MODULE2AGENT_CNT:
+ case UL10_MODULE2AGENT_CNT:
+ case AFE_DMIC0_SRC_DEBUG_MON0:
+ case AFE_DMIC0_UL_SRC_MON0:
+ case AFE_DMIC0_UL_SRC_MON1:
+ case AFE_DMIC1_SRC_DEBUG_MON0:
+ case AFE_DMIC1_UL_SRC_MON0:
+ case AFE_DMIC1_UL_SRC_MON1:
+ case AFE_DMIC2_SRC_DEBUG_MON0:
+ case AFE_DMIC2_UL_SRC_MON0:
+ case AFE_DMIC2_UL_SRC_MON1:
+ case AFE_DMIC3_SRC_DEBUG_MON0:
+ case AFE_DMIC3_UL_SRC_MON0:
+ case AFE_DMIC3_UL_SRC_MON1:
+ case DMIC_GAIN1_CUR:
+ case DMIC_GAIN2_CUR:
+ case DMIC_GAIN3_CUR:
+ case DMIC_GAIN4_CUR:
+ case ETDM_IN1_MONITOR:
+ case ETDM_IN2_MONITOR:
+ case ETDM_OUT1_MONITOR:
+ case ETDM_OUT2_MONITOR:
+ case ETDM_OUT3_MONITOR:
+ case AFE_ADDA_SRC_DEBUG_MON0:
+ case AFE_ADDA_SRC_DEBUG_MON1:
+ case AFE_ADDA_DL_SDM_FIFO_MON:
+ case AFE_ADDA_DL_SRC_LCH_MON:
+ case AFE_ADDA_DL_SRC_RCH_MON:
+ case AFE_ADDA_DL_SDM_OUT_MON:
+ case AFE_GASRC0_NEW_CON8:
+ case AFE_GASRC0_NEW_CON9:
+ case AFE_GASRC0_NEW_CON12:
+ case AFE_GASRC1_NEW_CON8:
+ case AFE_GASRC1_NEW_CON9:
+ case AFE_GASRC1_NEW_CON12:
+ case AFE_GASRC2_NEW_CON8:
+ case AFE_GASRC2_NEW_CON9:
+ case AFE_GASRC2_NEW_CON12:
+ case AFE_GASRC3_NEW_CON8:
+ case AFE_GASRC3_NEW_CON9:
+ case AFE_GASRC3_NEW_CON12:
+ case AFE_GASRC4_NEW_CON8:
+ case AFE_GASRC4_NEW_CON9:
+ case AFE_GASRC4_NEW_CON12:
+ case AFE_GASRC5_NEW_CON8:
+ case AFE_GASRC5_NEW_CON9:
+ case AFE_GASRC5_NEW_CON12:
+ case AFE_GASRC6_NEW_CON8:
+ case AFE_GASRC6_NEW_CON9:
+ case AFE_GASRC6_NEW_CON12:
+ case AFE_GASRC7_NEW_CON8:
+ case AFE_GASRC7_NEW_CON9:
+ case AFE_GASRC7_NEW_CON12:
+ case AFE_GASRC8_NEW_CON8:
+ case AFE_GASRC8_NEW_CON9:
+ case AFE_GASRC8_NEW_CON12:
+ case AFE_GASRC9_NEW_CON8:
+ case AFE_GASRC9_NEW_CON9:
+ case AFE_GASRC9_NEW_CON12:
+ case AFE_GASRC10_NEW_CON8:
+ case AFE_GASRC10_NEW_CON9:
+ case AFE_GASRC10_NEW_CON12:
+ case AFE_GASRC11_NEW_CON8:
+ case AFE_GASRC11_NEW_CON9:
+ case AFE_GASRC11_NEW_CON12:
+ case AFE_GASRC12_NEW_CON8:
+ case AFE_GASRC12_NEW_CON9:
+ case AFE_GASRC12_NEW_CON12:
+ case AFE_GASRC13_NEW_CON8:
+ case AFE_GASRC13_NEW_CON9:
+ case AFE_GASRC13_NEW_CON12:
+ case AFE_GASRC14_NEW_CON8:
+ case AFE_GASRC14_NEW_CON9:
+ case AFE_GASRC14_NEW_CON12:
+ case AFE_GASRC15_NEW_CON8:
+ case AFE_GASRC15_NEW_CON9:
+ case AFE_GASRC15_NEW_CON12:
+ case AFE_GASRC16_NEW_CON8:
+ case AFE_GASRC16_NEW_CON9:
+ case AFE_GASRC16_NEW_CON12:
+ case AFE_GASRC17_NEW_CON8:
+ case AFE_GASRC17_NEW_CON9:
+ case AFE_GASRC17_NEW_CON12:
+ case AFE_GASRC18_NEW_CON8:
+ case AFE_GASRC18_NEW_CON9:
+ case AFE_GASRC18_NEW_CON12:
+ case AFE_GASRC19_NEW_CON8:
+ case AFE_GASRC19_NEW_CON9:
+ case AFE_GASRC19_NEW_CON12:
+ return true;
+ default:
+ return false;
+ };
+}
+
+static const struct regmap_config mt8195_afe_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .volatile_reg = mt8195_is_volatile_reg,
+ .max_register = AFE_MAX_REGISTER,
+ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
+ .cache_type = REGCACHE_FLAT,
+};
+
+#define AFE_IRQ_CLR_BITS (0x387)
+#define ASYS_IRQ_CLR_BITS (0xffff)
+
+static irqreturn_t mt8195_afe_irq_handler(int irq_id, void *dev_id)
+{
+ struct mtk_base_afe *afe = dev_id;
+ unsigned int val = 0;
+ unsigned int asys_irq_clr_bits = 0;
+ unsigned int afe_irq_clr_bits = 0;
+ unsigned int irq_status_bits = 0;
+ unsigned int irq_clr_bits = 0;
+ unsigned int mcu_irq_mask = 0;
+ int i = 0;
+ int ret = 0;
+
+ ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &val);
+ if (ret) {
+ dev_info(afe->dev, "%s irq status err\n", __func__);
+ afe_irq_clr_bits = AFE_IRQ_CLR_BITS;
+ asys_irq_clr_bits = ASYS_IRQ_CLR_BITS;
+ goto err_irq;
+ }
+
+ ret = regmap_read(afe->regmap, AFE_IRQ_MASK, &mcu_irq_mask);
+ if (ret) {
+ dev_info(afe->dev, "%s read irq mask err\n", __func__);
+ afe_irq_clr_bits = AFE_IRQ_CLR_BITS;
+ asys_irq_clr_bits = ASYS_IRQ_CLR_BITS;
+ goto err_irq;
+ }
+
+ /* only clr cpu irq */
+ val &= mcu_irq_mask;
+
+ for (i = 0; i < MT8195_AFE_MEMIF_NUM; i++) {
+ struct mtk_base_afe_memif *memif = &afe->memif[i];
+ struct mtk_base_irq_data const *irq_data;
+
+ if (memif->irq_usage < 0)
+ continue;
+
+ irq_data = afe->irqs[memif->irq_usage].irq_data;
+
+ irq_status_bits = BIT(irq_data->irq_status_shift);
+ irq_clr_bits = BIT(irq_data->irq_clr_shift);
+
+ if (!(val & irq_status_bits))
+ continue;
+
+ if (irq_data->irq_clr_reg == ASYS_IRQ_CLR)
+ asys_irq_clr_bits |= irq_clr_bits;
+ else
+ afe_irq_clr_bits |= irq_clr_bits;
+
+ snd_pcm_period_elapsed(memif->substream);
+ }
+
+err_irq:
+ /* clear irq */
+ if (asys_irq_clr_bits)
+ regmap_write(afe->regmap, ASYS_IRQ_CLR, asys_irq_clr_bits);
+ if (afe_irq_clr_bits)
+ regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, afe_irq_clr_bits);
+
+ return IRQ_HANDLED;
+}
+
+static int mt8195_afe_runtime_suspend(struct device *dev)
+{
+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
+ goto skip_regmap;
+
+ mt8195_afe_disable_main_clock(afe);
+
+ regcache_cache_only(afe->regmap, true);
+ regcache_mark_dirty(afe->regmap);
+
+skip_regmap:
+ mt8195_afe_disable_reg_rw_clk(afe);
+
+ return 0;
+}
+
+static int mt8195_afe_runtime_resume(struct device *dev)
+{
+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+ mt8195_afe_enable_reg_rw_clk(afe);
+
+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
+ goto skip_regmap;
+
+ regcache_cache_only(afe->regmap, false);
+ regcache_sync(afe->regmap);
+
+ mt8195_afe_enable_main_clock(afe);
+skip_regmap:
+ return 0;
+}
+
+static int mt8195_afe_component_probe(struct snd_soc_component *component)
+{
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ int ret = 0;
+
+ snd_soc_component_init_regmap(component, afe->regmap);
+
+ ret = mtk_afe_add_sub_dai_control(component);
+
+ return ret;
+}
+
+static const struct snd_soc_component_driver mt8195_afe_component = {
+ .name = AFE_PCM_NAME,
+ .pointer = mtk_afe_pcm_pointer,
+ .pcm_construct = mtk_afe_pcm_new,
+ .probe = mt8195_afe_component_probe,
+};
+
+static int init_memif_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ int i;
+
+ for (i = MT8195_AFE_MEMIF_START; i < MT8195_AFE_MEMIF_END; i++) {
+ memif_priv = devm_kzalloc(afe->dev,
+ sizeof(struct mtk_dai_memif_priv),
+ GFP_KERNEL);
+ if (!memif_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[i] = memif_priv;
+ }
+
+ return 0;
+}
+
+static int mt8195_dai_memif_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mt8195_memif_dai_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mt8195_memif_dai_driver);
+
+ dai->dapm_widgets = mt8195_memif_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mt8195_memif_widgets);
+ dai->dapm_routes = mt8195_memif_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mt8195_memif_routes);
+ dai->controls = mt8195_memif_controls;
+ dai->num_controls = ARRAY_SIZE(mt8195_memif_controls);
+
+ return init_memif_priv_data(afe);
+}
+
+typedef int (*dai_register_cb)(struct mtk_base_afe *);
+static const dai_register_cb dai_register_cbs[] = {
+ mt8195_dai_adda_register,
+ mt8195_dai_etdm_register,
+ mt8195_dai_pcm_register,
+ mt8195_dai_memif_register,
+};
+
+static const struct reg_sequence mt8195_afe_reg_defaults[] = {
+ { AFE_IRQ_MASK, 0x387ffff },
+ { AFE_IRQ3_CON, BIT(30) },
+ { AFE_IRQ9_CON, BIT(30) },
+ { ETDM_IN1_CON4, 0x12000100 },
+ { ETDM_IN2_CON4, 0x12000100 },
+};
+
+static const struct reg_sequence mt8195_cg_patch[] = {
+ { AUDIO_TOP_CON0, 0xfffffffb },
+ { AUDIO_TOP_CON1, 0xfffffffa },
+};
+
+static int mt8195_afe_init_registers(struct mtk_base_afe *afe)
+{
+ return regmap_multi_reg_write(afe->regmap,
+ mt8195_afe_reg_defaults,
+ ARRAY_SIZE(mt8195_afe_reg_defaults));
+}
+
+static void mt8195_afe_parse_of(struct mtk_base_afe *afe,
+ struct device_node *np)
+{
+#if IS_ENABLED(CONFIG_SND_SOC_MT6359)
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+ afe_priv->topckgen = syscon_regmap_lookup_by_phandle(afe->dev->of_node,
+ "mediatek,topckgen");
+ if (IS_ERR(afe_priv->topckgen)) {
+ dev_info(afe->dev, "%s() Cannot find topckgen controller: %ld\n",
+ __func__, PTR_ERR(afe_priv->topckgen));
+ }
+#endif
+}
+
+static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev)
+{
+ struct mtk_base_afe *afe;
+ struct mt8195_afe_private *afe_priv;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ int i, irq_id, ret;
+ struct snd_soc_component *component;
+
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
+ if (ret)
+ return ret;
+
+ afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
+ if (!afe)
+ return -ENOMEM;
+
+ afe->platform_priv = devm_kzalloc(dev, sizeof(*afe_priv),
+ GFP_KERNEL);
+ if (!afe->platform_priv)
+ return -ENOMEM;
+
+ afe_priv = afe->platform_priv;
+ afe->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(afe->base_addr))
+ return PTR_ERR(afe->base_addr);
+
+ /* initial audio related clock */
+ ret = mt8195_afe_init_clock(afe);
+ if (ret) {
+ dev_err(dev, "init clock error\n");
+ return ret;
+ }
+
+ spin_lock_init(&afe_priv->afe_ctrl_lock);
+
+ mutex_init(&afe->irq_alloc_lock);
+
+ /* irq initialize */
+ afe->irqs_size = MT8195_AFE_IRQ_NUM;
+ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
+ GFP_KERNEL);
+ if (!afe->irqs)
+ return -ENOMEM;
+
+ for (i = 0; i < afe->irqs_size; i++)
+ afe->irqs[i].irq_data = &irq_data[i];
+
+ /* init memif */
+ afe->memif_size = MT8195_AFE_MEMIF_NUM;
+ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
+ GFP_KERNEL);
+ if (!afe->memif)
+ return -ENOMEM;
+
+ for (i = 0; i < afe->memif_size; i++) {
+ afe->memif[i].data = &memif_data[i];
+ afe->memif[i].irq_usage = mt8195_afe_memif_const_irqs[i];
+ afe->memif[i].const_irq = 1;
+ afe->irqs[afe->memif[i].irq_usage].irq_occupyed = true;
+ }
+
+ /* request irq */
+ irq_id = platform_get_irq(pdev, 0);
+ if (irq_id < 0) {
+ dev_err(dev, "%s no irq found\n", dev->of_node->name);
+ return -ENXIO;
+ }
+
+ ret = devm_request_irq(dev, irq_id, mt8195_afe_irq_handler,
+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
+ if (ret) {
+ dev_err(dev, "could not request_irq for asys-isr\n");
+ return ret;
+ }
+
+ /* init sub_dais */
+ INIT_LIST_HEAD(&afe->sub_dais);
+
+ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
+ ret = dai_register_cbs[i](afe);
+ if (ret) {
+ dev_warn(dev, "dai register i %d fail, ret %d\n",
+ i, ret);
+ return ret;
+ }
+ }
+
+ /* init dai_driver and component_driver */
+ ret = mtk_afe_combine_sub_dai(afe);
+ if (ret) {
+ dev_warn(dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
+ ret);
+ return ret;
+ }
+
+ afe->mtk_afe_hardware = &mt8195_afe_hardware;
+ afe->memif_fs = mt8195_memif_fs;
+ afe->irq_fs = mt8195_irq_fs;
+
+ afe->runtime_resume = mt8195_afe_runtime_resume;
+ afe->runtime_suspend = mt8195_afe_runtime_suspend;
+
+ platform_set_drvdata(pdev, afe);
+
+ mt8195_afe_parse_of(afe, pdev->dev.of_node);
+
+ pm_runtime_enable(dev);
+ if (!pm_runtime_enabled(dev)) {
+ ret = mt8195_afe_runtime_resume(dev);
+ if (ret)
+ return ret;
+ }
+
+ /* enable clock for regcache get default value from hw */
+ afe_priv->pm_runtime_bypass_reg_ctl = true;
+ pm_runtime_get_sync(dev);
+
+ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
+ &mt8195_afe_regmap_config);
+ if (IS_ERR(afe->regmap)) {
+ ret = PTR_ERR(afe->regmap);
+ goto err_pm_put;
+ }
+
+ ret = regmap_register_patch(afe->regmap, mt8195_cg_patch,
+ ARRAY_SIZE(mt8195_cg_patch));
+ if (ret < 0) {
+ dev_err(dev, "Failed to apply cg patch\n");
+ goto err_pm_put;
+ }
+
+ /* register component */
+ ret = devm_snd_soc_register_component(dev, &mt8195_afe_component,
+ NULL, 0);
+ if (ret) {
+ dev_warn(dev, "err_platform\n");
+ goto err_pm_put;
+ }
+
+ component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
+ if (!component) {
+ ret = -ENOMEM;
+ goto err_pm_put;
+ }
+
+ ret = snd_soc_component_initialize(component,
+ &mt8195_afe_pcm_dai_component,
+ dev);
+ if (ret)
+ goto err_pm_put;
+
+#ifdef CONFIG_DEBUG_FS
+ component->debugfs_prefix = "pcm";
+#endif
+
+ ret = snd_soc_add_component(component,
+ afe->dai_drivers,
+ afe->num_dai_drivers);
+ if (ret) {
+ dev_warn(dev, "err_dai_component\n");
+ goto err_pm_put;
+ }
+
+ mt8195_afe_init_registers(afe);
+
+ pm_runtime_put_sync(dev);
+ afe_priv->pm_runtime_bypass_reg_ctl = false;
+
+ regcache_cache_only(afe->regmap, true);
+ regcache_mark_dirty(afe->regmap);
+
+ return 0;
+
+err_pm_put:
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static int mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
+{
+ struct mtk_base_afe *afe = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_component(&pdev->dev);
+
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ mt8195_afe_runtime_suspend(&pdev->dev);
+
+ mt8195_afe_deinit_clock(afe);
+ return 0;
+}
+
+static const struct of_device_id mt8195_afe_pcm_dt_match[] = {
+ {.compatible = "mediatek,mt8195-audio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt8195_afe_pcm_dt_match);
+
+static const struct dev_pm_ops mt8195_afe_pm_ops = {
+ SET_RUNTIME_PM_OPS(mt8195_afe_runtime_suspend,
+ mt8195_afe_runtime_resume, NULL)
+};
+
+static struct platform_driver mt8195_afe_pcm_driver = {
+ .driver = {
+ .name = "mt8195-audio",
+ .of_match_table = mt8195_afe_pcm_dt_match,
+#ifdef CONFIG_PM
+ .pm = &mt8195_afe_pm_ops,
+#endif
+ },
+ .probe = mt8195_afe_pcm_dev_probe,
+ .remove = mt8195_afe_pcm_dev_remove,
+};
+
+module_platform_driver(mt8195_afe_pcm_driver);
+
+MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8195");
+MODULE_AUTHOR("Bicycle Tsai <bicycle.tsai@mediatek.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
new file mode 100644
index 000000000000..740aa6ddda0e
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "mt8195-afe-common.h"
+#include "mt8195-audsys-clk.h"
+#include "mt8195-audsys-clkid.h"
+#include "mt8195-reg.h"
+
+struct afe_gate {
+ int id;
+ const char *name;
+ const char *parent_name;
+ int reg;
+ u8 bit;
+ const struct clk_ops *ops;
+ unsigned long flags;
+ u8 cg_flags;
+};
+
+#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .reg = _reg, \
+ .bit = _bit, \
+ .flags = _flags, \
+ .cg_flags = _cgflags, \
+ }
+
+#define GATE_AFE(_id, _name, _parent, _reg, _bit) \
+ GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, \
+ CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE)
+
+#define GATE_AUD0(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)
+
+#define GATE_AUD1(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)
+
+#define GATE_AUD3(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)
+
+#define GATE_AUD4(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)
+
+#define GATE_AUD5(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)
+
+#define GATE_AUD6(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)
+
+static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
+ /* AUD0 */
+ GATE_AUD0(CLK_AUD_AFE, "aud_afe", "a1sys_hp_sel", 2),
+ GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4),
+ GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10),
+ GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11),
+ GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18),
+ GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19),
+ GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20),
+ GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21),
+ GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23),
+ GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24),
+ GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25),
+ GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26),
+ GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27),
+ GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28),
+ GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31),
+
+ /* AUD1 */
+ GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2),
+ GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10),
+ GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11),
+ GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12),
+ GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13),
+ GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14),
+ GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16),
+ GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17),
+ GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18),
+ GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19),
+
+ /* AUD3 */
+ GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5),
+ GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7),
+
+ /* AUD4 */
+ GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0),
+ GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1),
+ GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6),
+ GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7),
+ GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8),
+ GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16),
+ GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17),
+ GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
+ GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20),
+ GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21),
+ GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22),
+ GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24),
+ GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30),
+ GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31),
+
+ /* AUD5 */
+ GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0),
+ GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1),
+ GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2),
+ GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3),
+ GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4),
+ GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5),
+ GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7),
+ GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8),
+ GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9),
+ GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18),
+ GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19),
+ GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22),
+ GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23),
+ GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24),
+ GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26),
+ GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27),
+
+ /* AUD6 */
+ GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0),
+ GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1),
+ GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2),
+ GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3),
+ GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4),
+ GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5),
+ GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6),
+ GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7),
+ GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8),
+ GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9),
+ GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10),
+ GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11),
+ GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12),
+ GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13),
+ GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14),
+ GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15),
+ GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16),
+ GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17),
+ GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18),
+ GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19),
+};
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk;
+ struct clk_lookup *cl;
+ int i;
+
+ afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
+ sizeof(*afe_priv->lookup),
+ GFP_KERNEL);
+
+ if (!afe_priv->lookup)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
+ const struct afe_gate *gate = &aud_clks[i];
+
+ clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
+ gate->flags, afe->base_addr + gate->reg,
+ gate->bit, gate->cg_flags, NULL);
+
+ if (IS_ERR(clk)) {
+ dev_err(afe->dev, "Failed to register clk %s: %ld\n",
+ gate->name, PTR_ERR(clk));
+ continue;
+ }
+
+ /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
+ cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+ if (!cl)
+ return -ENOMEM;
+
+ cl->clk = clk;
+ cl->con_id = gate->name;
+ cl->dev_id = dev_name(afe->dev);
+ clkdev_add(cl);
+
+ afe_priv->lookup[i] = cl;
+ }
+
+ return 0;
+}
+
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk;
+ struct clk_lookup *cl;
+ int i;
+
+ if (!afe_priv)
+ return;
+
+ for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+ cl = afe_priv->lookup[i];
+ if (!cl)
+ continue;
+
+ clk = cl->clk;
+ clk_unregister_gate(clk);
+
+ clkdev_drop(cl);
+ }
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
new file mode 100644
index 000000000000..239d31016ba7
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLK_H_
+#define _MT8195_AUDSYS_CLK_H_
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
new file mode 100644
index 000000000000..4dd0a5c8b8fa
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clkid.h -- Mediatek 8195 audsys clock id definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLKID_H_
+#define _MT8195_AUDSYS_CLKID_H_
+
+enum{
+ CLK_AUD_AFE,
+ CLK_AUD_LRCK_CNT,
+ CLK_AUD_SPDIFIN_TUNER_APLL,
+ CLK_AUD_SPDIFIN_TUNER_DBG,
+ CLK_AUD_UL_TML,
+ CLK_AUD_APLL1_TUNER,
+ CLK_AUD_APLL2_TUNER,
+ CLK_AUD_TOP0_SPDF,
+ CLK_AUD_APLL,
+ CLK_AUD_APLL2,
+ CLK_AUD_DAC,
+ CLK_AUD_DAC_PREDIS,
+ CLK_AUD_TML,
+ CLK_AUD_ADC,
+ CLK_AUD_DAC_HIRES,
+ CLK_AUD_A1SYS_HP,
+ CLK_AUD_AFE_DMIC1,
+ CLK_AUD_AFE_DMIC2,
+ CLK_AUD_AFE_DMIC3,
+ CLK_AUD_AFE_DMIC4,
+ CLK_AUD_AFE_26M_DMIC_TM,
+ CLK_AUD_UL_TML_HIRES,
+ CLK_AUD_ADC_HIRES,
+ CLK_AUD_ADDA6_ADC,
+ CLK_AUD_ADDA6_ADC_HIRES,
+ CLK_AUD_LINEIN_TUNER,
+ CLK_AUD_EARC_TUNER,
+ CLK_AUD_I2SIN,
+ CLK_AUD_TDM_IN,
+ CLK_AUD_I2S_OUT,
+ CLK_AUD_TDM_OUT,
+ CLK_AUD_HDMI_OUT,
+ CLK_AUD_ASRC11,
+ CLK_AUD_ASRC12,
+ CLK_AUD_MULTI_IN,
+ CLK_AUD_INTDIR,
+ CLK_AUD_A1SYS,
+ CLK_AUD_A2SYS,
+ CLK_AUD_PCMIF,
+ CLK_AUD_A3SYS,
+ CLK_AUD_A4SYS,
+ CLK_AUD_MEMIF_UL1,
+ CLK_AUD_MEMIF_UL2,
+ CLK_AUD_MEMIF_UL3,
+ CLK_AUD_MEMIF_UL4,
+ CLK_AUD_MEMIF_UL5,
+ CLK_AUD_MEMIF_UL6,
+ CLK_AUD_MEMIF_UL8,
+ CLK_AUD_MEMIF_UL9,
+ CLK_AUD_MEMIF_UL10,
+ CLK_AUD_MEMIF_DL2,
+ CLK_AUD_MEMIF_DL3,
+ CLK_AUD_MEMIF_DL6,
+ CLK_AUD_MEMIF_DL7,
+ CLK_AUD_MEMIF_DL8,
+ CLK_AUD_MEMIF_DL10,
+ CLK_AUD_MEMIF_DL11,
+ CLK_AUD_GASRC0,
+ CLK_AUD_GASRC1,
+ CLK_AUD_GASRC2,
+ CLK_AUD_GASRC3,
+ CLK_AUD_GASRC4,
+ CLK_AUD_GASRC5,
+ CLK_AUD_GASRC6,
+ CLK_AUD_GASRC7,
+ CLK_AUD_GASRC8,
+ CLK_AUD_GASRC9,
+ CLK_AUD_GASRC10,
+ CLK_AUD_GASRC11,
+ CLK_AUD_GASRC12,
+ CLK_AUD_GASRC13,
+ CLK_AUD_GASRC14,
+ CLK_AUD_GASRC15,
+ CLK_AUD_GASRC16,
+ CLK_AUD_GASRC17,
+ CLK_AUD_GASRC18,
+ CLK_AUD_GASRC19,
+ CLK_AUD_NR_CLK,
+};
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
new file mode 100644
index 000000000000..878dec0b69ed
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI ADDA Control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+#define ADDA_DL_GAIN_LOOPBACK 0x1800
+#define ADDA_HIRES_THRES 48000
+
+enum {
+ SUPPLY_SEQ_CLOCK_SEL,
+ SUPPLY_SEQ_CLOCK_ON,
+ SUPPLY_SEQ_ADDA_DL_ON,
+ SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+ SUPPLY_SEQ_ADDA_UL_ON,
+ SUPPLY_SEQ_ADDA_AFE_ON,
+};
+
+enum {
+ MTK_AFE_ADDA_DL_RATE_8K = 0,
+ MTK_AFE_ADDA_DL_RATE_11K = 1,
+ MTK_AFE_ADDA_DL_RATE_12K = 2,
+ MTK_AFE_ADDA_DL_RATE_16K = 3,
+ MTK_AFE_ADDA_DL_RATE_22K = 4,
+ MTK_AFE_ADDA_DL_RATE_24K = 5,
+ MTK_AFE_ADDA_DL_RATE_32K = 6,
+ MTK_AFE_ADDA_DL_RATE_44K = 7,
+ MTK_AFE_ADDA_DL_RATE_48K = 8,
+ MTK_AFE_ADDA_DL_RATE_96K = 9,
+ MTK_AFE_ADDA_DL_RATE_192K = 10,
+};
+
+enum {
+ MTK_AFE_ADDA_UL_RATE_8K = 0,
+ MTK_AFE_ADDA_UL_RATE_16K = 1,
+ MTK_AFE_ADDA_UL_RATE_32K = 2,
+ MTK_AFE_ADDA_UL_RATE_48K = 3,
+ MTK_AFE_ADDA_UL_RATE_96K = 4,
+ MTK_AFE_ADDA_UL_RATE_192K = 5,
+};
+
+enum {
+ DELAY_DATA_MISO1 = 0,
+ DELAY_DATA_MISO0 = 1,
+ DELAY_DATA_MISO2 = 1,
+};
+
+enum {
+ MTK_AFE_ADDA,
+ MTK_AFE_ADDA6,
+};
+
+struct mtk_dai_adda_priv {
+ bool hires_required;
+};
+
+static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
+ unsigned int rate)
+{
+ switch (rate) {
+ case 8000:
+ return MTK_AFE_ADDA_DL_RATE_8K;
+ case 11025:
+ return MTK_AFE_ADDA_DL_RATE_11K;
+ case 12000:
+ return MTK_AFE_ADDA_DL_RATE_12K;
+ case 16000:
+ return MTK_AFE_ADDA_DL_RATE_16K;
+ case 22050:
+ return MTK_AFE_ADDA_DL_RATE_22K;
+ case 24000:
+ return MTK_AFE_ADDA_DL_RATE_24K;
+ case 32000:
+ return MTK_AFE_ADDA_DL_RATE_32K;
+ case 44100:
+ return MTK_AFE_ADDA_DL_RATE_44K;
+ case 48000:
+ return MTK_AFE_ADDA_DL_RATE_48K;
+ case 96000:
+ return MTK_AFE_ADDA_DL_RATE_96K;
+ case 192000:
+ return MTK_AFE_ADDA_DL_RATE_192K;
+ default:
+ dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+ __func__, rate);
+ return MTK_AFE_ADDA_DL_RATE_48K;
+ }
+}
+
+static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
+ unsigned int rate)
+{
+ switch (rate) {
+ case 8000:
+ return MTK_AFE_ADDA_UL_RATE_8K;
+ case 16000:
+ return MTK_AFE_ADDA_UL_RATE_16K;
+ case 32000:
+ return MTK_AFE_ADDA_UL_RATE_32K;
+ case 48000:
+ return MTK_AFE_ADDA_UL_RATE_48K;
+ case 96000:
+ return MTK_AFE_ADDA_UL_RATE_96K;
+ case 192000:
+ return MTK_AFE_ADDA_UL_RATE_192K;
+ default:
+ dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+ __func__, rate);
+ return MTK_AFE_ADDA_UL_RATE_48K;
+ }
+}
+
+static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int delay_data;
+ int delay_cycle;
+ unsigned int mask = 0;
+ unsigned int val = 0;
+
+ /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
+ mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+ val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+
+ regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
+ regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val);
+
+ mask = RG_RX_PROTOCOL2;
+ val = RG_RX_PROTOCOL2;
+ regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
+
+ if (!param->mtkaif_calibration_ok) {
+ dev_info(afe->dev, "%s(), calibration fail\n", __func__);
+ return 0;
+ }
+
+ /* set delay for ch1, ch2 */
+ if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >=
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+ delay_data = DELAY_DATA_MISO1;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] -
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+ } else {
+ delay_data = DELAY_DATA_MISO0;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0];
+ }
+
+ val = 0;
+ mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+ val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+ MTKAIF_RXIF_DELAY_CYCLE_MASK;
+ val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+ regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
+
+ /* set delay between ch3 and ch2 */
+ if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >=
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+ delay_data = DELAY_DATA_MISO1;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] -
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+ } else {
+ delay_data = DELAY_DATA_MISO2;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+ param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2];
+ }
+
+ val = 0;
+ mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+ val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+ MTKAIF_RXIF_DELAY_CYCLE_MASK;
+ val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+ regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val);
+
+ return 0;
+}
+
+static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ mt8195_adda_mtkaif_init(afe);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+ usleep_range(125, 135);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic)
+{
+ unsigned int reg = 0;
+ unsigned int mask = 0;
+ unsigned int val = 0;
+
+ switch (adda) {
+ case MTK_AFE_ADDA:
+ reg = AFE_ADDA_UL_SRC_CON0;
+ break;
+ case MTK_AFE_ADDA6:
+ reg = AFE_ADDA6_UL_SRC_CON0;
+ break;
+ default:
+ dev_info(afe->dev, "%s(), wrong parameter\n", __func__);
+ return;
+ }
+
+ mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
+ UL_MODE_3P25M_CH2_CTL);
+
+ /* turn on dmic, ch1, ch2 */
+ if (dmic)
+ val = mask;
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+}
+
+static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+ usleep_range(125, 135);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ unsigned int val;
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on);
+
+ val = (param->mtkaif_adda6_only ?
+ ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0);
+
+ regmap_update_bits(afe->regmap,
+ AFE_ADDA_MTKAIF_SYNCWORD_CFG,
+ ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE,
+ val);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+ usleep_range(125, 135);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL];
+ struct clk *clk_parent;
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1];
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M];
+ break;
+ default:
+ return 0;
+ }
+ mt8195_afe_set_clk_parent(afe, clk, clk_parent);
+
+ return 0;
+}
+
+static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
+ const char *name)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int dai_id;
+
+ if (strstr(name, "aud_adc_hires"))
+ dai_id = MT8195_AFE_IO_UL_SRC1;
+ else if (strstr(name, "aud_adda6_adc_hires"))
+ dai_id = MT8195_AFE_IO_UL_SRC2;
+ else if (strstr(name, "aud_dac_hires"))
+ dai_id = MT8195_AFE_IO_DL_SRC;
+ else
+ return NULL;
+
+ return afe_priv->dai_priv[dai_id];
+}
+
+static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ struct snd_soc_dapm_widget *w = source;
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mtk_dai_adda_priv *adda_priv;
+
+ adda_priv = get_adda_priv_by_name(afe, w->name);
+
+ if (!adda_priv) {
+ dev_info(afe->dev, "adda_priv == NULL");
+ return 0;
+ }
+
+ return (adda_priv->hires_required) ? 1 : 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
+};
+
+static const char * const adda_dlgain_mux_map[] = {
+ "Bypass", "Connect",
+};
+
+static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
+ SND_SOC_NOPM, 0,
+ adda_dlgain_mux_map);
+
+static const struct snd_kcontrol_new adda_dlgain_mux_control =
+ SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
+
+static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
+ SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
+ mtk_dai_adda_o176_mix,
+ ARRAY_SIZE(mtk_dai_adda_o176_mix)),
+ SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
+ mtk_dai_adda_o177_mix,
+ ARRAY_SIZE(mtk_dai_adda_o177_mix)),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
+ AFE_ADDA_UL_DL_CON0,
+ ADDA_AFE_ON_SHIFT, 0,
+ NULL,
+ 0),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
+ AFE_ADDA_DL_SRC2_CON0,
+ DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
+ mtk_adda_dl_event,
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+ AFE_ADDA_UL_SRC_CON0,
+ UL_SRC_ON_TMP_CTL_SHIFT, 0,
+ mtk_adda_ul_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+ AFE_ADDA6_UL_SRC_CON0,
+ UL_SRC_ON_TMP_CTL_SHIFT, 0,
+ mtk_adda6_ul_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
+ SND_SOC_NOPM,
+ 0, 0,
+ mtk_audio_hires_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+ SND_SOC_NOPM,
+ 0, 0,
+ mtk_adda_mtkaif_cfg_event,
+ SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
+ &adda_dlgain_mux_control),
+
+ SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
+ DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
+
+ SND_SOC_DAPM_INPUT("ADDA_INPUT"),
+ SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
+
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
+ {"ADDA Capture", NULL, "ADDA Enable"},
+ {"ADDA Capture", NULL, "ADDA Capture Enable"},
+ {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
+ {"ADDA Capture", NULL, "aud_adc"},
+ {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
+ {"aud_adc_hires", NULL, "AUDIO_HIRES"},
+
+ {"ADDA6 Capture", NULL, "ADDA Enable"},
+ {"ADDA6 Capture", NULL, "ADDA6 Capture Enable"},
+ {"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"},
+ {"ADDA6 Capture", NULL, "aud_adda6_adc"},
+ {"ADDA6 Capture", NULL, "aud_adda6_adc_hires",
+ mtk_afe_adda_hires_connect},
+ {"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"},
+
+ {"I168", NULL, "ADDA Capture"},
+ {"I169", NULL, "ADDA Capture"},
+ {"I170", NULL, "ADDA6 Capture"},
+ {"I171", NULL, "ADDA6 Capture"},
+
+ {"ADDA Playback", NULL, "ADDA Enable"},
+ {"ADDA Playback", NULL, "ADDA Playback Enable"},
+ {"ADDA Playback", NULL, "aud_dac"},
+ {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
+ {"aud_dac_hires", NULL, "AUDIO_HIRES"},
+
+ {"DL_GAIN", NULL, "O176"},
+ {"DL_GAIN", NULL, "O177"},
+
+ {"DL_GAIN_MUX", "Bypass", "O176"},
+ {"DL_GAIN_MUX", "Bypass", "O177"},
+ {"DL_GAIN_MUX", "Connect", "DL_GAIN"},
+
+ {"ADDA Playback", NULL, "DL_GAIN_MUX"},
+
+ {"O176", "I000 Switch", "I000"},
+ {"O177", "I001 Switch", "I001"},
+
+ {"O176", "I002 Switch", "I002"},
+ {"O177", "I003 Switch", "I003"},
+
+ {"O176", "I020 Switch", "I020"},
+ {"O177", "I021 Switch", "I021"},
+
+ {"O176", "I022 Switch", "I022"},
+ {"O177", "I023 Switch", "I023"},
+
+ {"O176", "I070 Switch", "I070"},
+ {"O177", "I071 Switch", "I071"},
+
+ {"ADDA Capture", NULL, "ADDA_INPUT"},
+ {"ADDA6 Capture", NULL, "ADDA_INPUT"},
+ {"ADDA_OUTPUT", NULL, "ADDA Playback"},
+};
+
+static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+ unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+ unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]);
+
+ regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value));
+ return 0;
+}
+
+static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+ unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+ unsigned int value = 0;
+
+ regmap_read(afe->regmap, reg, &value);
+
+ ucontrol->value.integer.value[0] = ((value & mask) >>
+ DL_2_GAIN_CTL_PRE_SHIFT);
+ return 0;
+}
+
+static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+ ucontrol->value.integer.value[0] = param->mtkaif_adda6_only;
+ return 0;
+}
+
+static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int mtkaif_adda6_only;
+
+ mtkaif_adda6_only = ucontrol->value.integer.value[0];
+
+ dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
+ __func__, kcontrol->id.name, mtkaif_adda6_only);
+
+ param->mtkaif_adda6_only = mtkaif_adda6_only;
+
+ return 0;
+}
+
+static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+ ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
+ return 0;
+}
+
+static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int dmic_on;
+
+ dmic_on = ucontrol->value.integer.value[0];
+
+ dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
+ __func__, kcontrol->id.name, dmic_on);
+
+ param->mtkaif_dmic_on = dmic_on;
+ return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
+ SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0,
+ mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put),
+ SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0,
+ mt8195_adda_dmic_get, mt8195_adda_dmic_set),
+ SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0,
+ mt8195_adda6_only_get,
+ mt8195_adda6_only_set),
+};
+
+static int mtk_dai_da_configure(struct mtk_base_afe *afe,
+ unsigned int rate, int id)
+{
+ unsigned int val = 0;
+ unsigned int mask = 0;
+
+ /* set sampling rate */
+ mask |= DL_2_INPUT_MODE_CTL_MASK;
+ val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate));
+
+ /* turn off saturation */
+ mask |= DL_2_CH1_SATURATION_EN_CTL;
+ mask |= DL_2_CH2_SATURATION_EN_CTL;
+
+ /* turn off mute function */
+ mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+ mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+ val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+ val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+
+ /* set voice input data if input sample rate is 8k or 16k */
+ mask |= DL_2_VOICE_MODE_CTL_PRE;
+ if (rate == 8000 || rate == 16000)
+ val |= DL_2_VOICE_MODE_CTL_PRE;
+
+ regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* new 2nd sdm */
+ mask |= DL_USE_NEW_2ND_SDM;
+ val |= DL_USE_NEW_2ND_SDM;
+ regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);
+
+ return 0;
+}
+
+static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
+ unsigned int rate, int id)
+{
+ unsigned int val = 0;
+ unsigned int mask = 0;
+
+ mask |= UL_VOICE_MODE_CTL_MASK;
+ val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate));
+
+ switch (id) {
+ case MT8195_AFE_IO_UL_SRC1:
+ regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
+ mask, val);
+ break;
+ case MT8195_AFE_IO_UL_SRC2:
+ regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0,
+ mask, val);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
+ unsigned int rate = params_rate(params);
+ int id = dai->id;
+ int ret = 0;
+
+ dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
+ __func__, id, substream->stream, rate);
+
+ if (rate > ADDA_HIRES_THRES)
+ adda_priv->hires_required = 1;
+ else
+ adda_priv->hires_required = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = mtk_dai_da_configure(afe, rate, id);
+ else
+ ret = mtk_dai_ad_configure(afe, rate, id);
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
+ .hw_params = mtk_dai_adda_hw_params,
+};
+
+/* dai driver */
+#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
+ SNDRV_PCM_RATE_96000 |\
+ SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_CAPTURE_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)
+
+#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
+ {
+ .name = "DL_SRC",
+ .id = MT8195_AFE_IO_DL_SRC,
+ .playback = {
+ .stream_name = "ADDA Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_ADDA_PLAYBACK_RATES,
+ .formats = MTK_ADDA_FORMATS,
+ },
+ .ops = &mtk_dai_adda_ops,
+ },
+ {
+ .name = "UL_SRC1",
+ .id = MT8195_AFE_IO_UL_SRC1,
+ .capture = {
+ .stream_name = "ADDA Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_ADDA_CAPTURE_RATES,
+ .formats = MTK_ADDA_FORMATS,
+ },
+ .ops = &mtk_dai_adda_ops,
+ },
+ {
+ .name = "UL_SRC2",
+ .id = MT8195_AFE_IO_UL_SRC2,
+ .capture = {
+ .stream_name = "ADDA6 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_ADDA_CAPTURE_RATES,
+ .formats = MTK_ADDA_FORMATS,
+ },
+ .ops = &mtk_dai_adda_ops,
+ },
+};
+
+static int init_adda_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv;
+ int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC,
+ MT8195_AFE_IO_UL_SRC1,
+ MT8195_AFE_IO_UL_SRC2};
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
+ adda_priv = devm_kzalloc(afe->dev,
+ sizeof(struct mtk_dai_adda_priv),
+ GFP_KERNEL);
+ if (!adda_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
+ }
+
+ return 0;
+}
+
+int mt8195_dai_adda_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_adda_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
+
+ dai->dapm_widgets = mtk_dai_adda_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
+ dai->dapm_routes = mtk_dai_adda_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
+ dai->controls = mtk_dai_adda_controls;
+ dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
+
+ return init_adda_priv_data(afe);
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
new file mode 100644
index 000000000000..bd9876cf02c8
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
@@ -0,0 +1,2639 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI eTDM Control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+#define MT8195_ETDM_MAX_CHANNELS 24
+#define MT8195_ETDM_NORMAL_MAX_BCK_RATE 24576000
+#define ETDM_TO_DAI_ID(x) ((x) + MT8195_AFE_IO_ETDM_START)
+#define ENUM_TO_STR(x) #x
+
+enum {
+ MTK_DAI_ETDM_FORMAT_I2S = 0,
+ MTK_DAI_ETDM_FORMAT_LJ,
+ MTK_DAI_ETDM_FORMAT_RJ,
+ MTK_DAI_ETDM_FORMAT_EIAJ,
+ MTK_DAI_ETDM_FORMAT_DSPA,
+ MTK_DAI_ETDM_FORMAT_DSPB,
+};
+
+enum {
+ MTK_DAI_ETDM_DATA_ONE_PIN = 0,
+ MTK_DAI_ETDM_DATA_MULTI_PIN,
+};
+
+enum {
+ ETDM_IN,
+ ETDM_OUT,
+};
+
+enum {
+ ETDM_IN_FROM_PAD,
+ ETDM_IN_FROM_ETDM_OUT1,
+ ETDM_IN_FROM_ETDM_OUT2,
+};
+
+enum {
+ ETDM_IN_SLAVE_FROM_PAD,
+ ETDM_IN_SLAVE_FROM_ETDM_OUT1,
+ ETDM_IN_SLAVE_FROM_ETDM_OUT2,
+};
+
+enum {
+ ETDM_OUT_SLAVE_FROM_PAD,
+ ETDM_OUT_SLAVE_FROM_ETDM_IN1,
+ ETDM_OUT_SLAVE_FROM_ETDM_IN2,
+};
+
+enum {
+ COWORK_ETDM_NONE = 0,
+ COWORK_ETDM_IN1_M = 2,
+ COWORK_ETDM_IN1_S = 3,
+ COWORK_ETDM_IN2_M = 4,
+ COWORK_ETDM_IN2_S = 5,
+ COWORK_ETDM_OUT1_M = 10,
+ COWORK_ETDM_OUT1_S = 11,
+ COWORK_ETDM_OUT2_M = 12,
+ COWORK_ETDM_OUT2_S = 13,
+ COWORK_ETDM_OUT3_M = 14,
+ COWORK_ETDM_OUT3_S = 15,
+};
+
+enum {
+ ETDM_RELATCH_TIMING_A1A2SYS,
+ ETDM_RELATCH_TIMING_A3SYS,
+ ETDM_RELATCH_TIMING_A4SYS,
+};
+
+enum {
+ ETDM_SYNC_NONE,
+ ETDM_SYNC_FROM_IN1,
+ ETDM_SYNC_FROM_IN2,
+ ETDM_SYNC_FROM_OUT1,
+ ETDM_SYNC_FROM_OUT2,
+ ETDM_SYNC_FROM_OUT3,
+};
+
+struct etdm_con_reg {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ unsigned int con4;
+ unsigned int con5;
+};
+
+struct mtk_dai_etdm_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+struct mtk_dai_etdm_priv {
+ unsigned int clock_mode;
+ unsigned int data_mode;
+ bool slave_mode;
+ bool lrck_inv;
+ bool bck_inv;
+ unsigned int format;
+ unsigned int slots;
+ unsigned int lrck_width;
+ unsigned int mclk_freq;
+ unsigned int mclk_apll;
+ unsigned int mclk_dir;
+ int cowork_source_id; //dai id
+ unsigned int cowork_slv_count;
+ int cowork_slv_id[MT8195_AFE_IO_ETDM_NUM - 1]; //dai_id
+ bool in_disable_ch[MT8195_ETDM_MAX_CHANNELS];
+ unsigned int en_ref_cnt;
+};
+
+static const struct mtk_dai_etdm_rate mt8195_etdm_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 12000, .reg_value = 1, },
+ { .rate = 16000, .reg_value = 2, },
+ { .rate = 24000, .reg_value = 3, },
+ { .rate = 32000, .reg_value = 4, },
+ { .rate = 48000, .reg_value = 5, },
+ { .rate = 96000, .reg_value = 7, },
+ { .rate = 192000, .reg_value = 9, },
+ { .rate = 384000, .reg_value = 11, },
+ { .rate = 11025, .reg_value = 16, },
+ { .rate = 22050, .reg_value = 17, },
+ { .rate = 44100, .reg_value = 18, },
+ { .rate = 88200, .reg_value = 19, },
+ { .rate = 176400, .reg_value = 20, },
+ { .rate = 352800, .reg_value = 21, },
+};
+
+static int get_etdm_fs_timing(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mt8195_etdm_rates); i++)
+ if (mt8195_etdm_rates[i].rate == rate)
+ return mt8195_etdm_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static unsigned int get_etdm_ch_fixup(unsigned int channels)
+{
+ if (channels > 16)
+ return 24;
+ else if (channels > 8)
+ return 16;
+ else if (channels > 4)
+ return 8;
+ else if (channels > 2)
+ return 4;
+ else
+ return 2;
+}
+
+static int get_etdm_reg(unsigned int dai_id, struct etdm_con_reg *etdm_reg)
+{
+ switch (dai_id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ etdm_reg->con0 = ETDM_IN1_CON0;
+ etdm_reg->con1 = ETDM_IN1_CON1;
+ etdm_reg->con2 = ETDM_IN1_CON2;
+ etdm_reg->con3 = ETDM_IN1_CON3;
+ etdm_reg->con4 = ETDM_IN1_CON4;
+ etdm_reg->con5 = ETDM_IN1_CON5;
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ etdm_reg->con0 = ETDM_IN2_CON0;
+ etdm_reg->con1 = ETDM_IN2_CON1;
+ etdm_reg->con2 = ETDM_IN2_CON2;
+ etdm_reg->con3 = ETDM_IN2_CON3;
+ etdm_reg->con4 = ETDM_IN2_CON4;
+ etdm_reg->con5 = ETDM_IN2_CON5;
+ break;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ etdm_reg->con0 = ETDM_OUT1_CON0;
+ etdm_reg->con1 = ETDM_OUT1_CON1;
+ etdm_reg->con2 = ETDM_OUT1_CON2;
+ etdm_reg->con3 = ETDM_OUT1_CON3;
+ etdm_reg->con4 = ETDM_OUT1_CON4;
+ etdm_reg->con5 = ETDM_OUT1_CON5;
+ break;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ etdm_reg->con0 = ETDM_OUT2_CON0;
+ etdm_reg->con1 = ETDM_OUT2_CON1;
+ etdm_reg->con2 = ETDM_OUT2_CON2;
+ etdm_reg->con3 = ETDM_OUT2_CON3;
+ etdm_reg->con4 = ETDM_OUT2_CON4;
+ etdm_reg->con5 = ETDM_OUT2_CON5;
+ break;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ case MT8195_AFE_IO_DPTX:
+ etdm_reg->con0 = ETDM_OUT3_CON0;
+ etdm_reg->con1 = ETDM_OUT3_CON1;
+ etdm_reg->con2 = ETDM_OUT3_CON2;
+ etdm_reg->con3 = ETDM_OUT3_CON3;
+ etdm_reg->con4 = ETDM_OUT3_CON4;
+ etdm_reg->con5 = ETDM_OUT3_CON5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int get_etdm_dir(unsigned int dai_id)
+{
+ switch (dai_id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ case MT8195_AFE_IO_ETDM2_IN:
+ return ETDM_IN;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ case MT8195_AFE_IO_ETDM2_OUT:
+ case MT8195_AFE_IO_ETDM3_OUT:
+ return ETDM_OUT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int get_etdm_wlen(unsigned int bitwidth)
+{
+ return bitwidth <= 16 ? 16 : 32;
+}
+
+static int is_cowork_mode(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+
+ return (etdm_data->cowork_slv_count > 0 ||
+ etdm_data->cowork_source_id != COWORK_ETDM_NONE);
+}
+
+static int sync_to_dai_id(int source_sel)
+{
+ switch (source_sel) {
+ case ETDM_SYNC_FROM_IN1:
+ return MT8195_AFE_IO_ETDM1_IN;
+ case ETDM_SYNC_FROM_IN2:
+ return MT8195_AFE_IO_ETDM2_IN;
+ case ETDM_SYNC_FROM_OUT1:
+ return MT8195_AFE_IO_ETDM1_OUT;
+ case ETDM_SYNC_FROM_OUT2:
+ return MT8195_AFE_IO_ETDM2_OUT;
+ case ETDM_SYNC_FROM_OUT3:
+ return MT8195_AFE_IO_ETDM3_OUT;
+ default:
+ return 0;
+ }
+}
+
+static int get_etdm_cowork_master_id(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+ int dai_id = etdm_data->cowork_source_id;
+
+ if (dai_id == COWORK_ETDM_NONE)
+ dai_id = dai->id;
+
+ return dai_id;
+}
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o048_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN48, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN48, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN48_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN48_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o049_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN49, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN49, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN49_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN49_2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o050_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN50, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN50_1, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o051_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN51, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN51_1, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o052_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN52, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN52_1, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o053_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN53, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN53_1, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o054_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN54, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN54_1, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o055_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN55, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN55_1, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o056_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN56, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN56_1, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o057_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN57, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN57_1, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o058_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN58_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN58_1, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o059_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN59_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN59_1, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o060_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN60_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN60_1, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o061_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN61_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN61_1, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o062_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN62_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN62_1, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o063_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN63_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN63_1, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o064_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN64_1, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I062 Switch", AFE_CONN64_1, 30, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o065_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN65_1, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I063 Switch", AFE_CONN65_1, 31, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o066_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN66_1, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I064 Switch", AFE_CONN66_2, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o067_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN67_1, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I065 Switch", AFE_CONN67_2, 1, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o068_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN68_1, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I066 Switch", AFE_CONN68_2, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o069_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN69_1, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I067 Switch", AFE_CONN69_2, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o070_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN70_1, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I068 Switch", AFE_CONN70_2, 4, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o071_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN71_1, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I069 Switch", AFE_CONN71_2, 5, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o072_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN72, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN72, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN72_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN72_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o073_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN73, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN73, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN73_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN73_2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o074_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN74, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN74_1, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o075_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN75, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN75_1, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o076_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN76, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN76_1, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o077_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN77, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN77_1, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o078_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN78, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN78_1, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o079_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN79, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN79_1, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o080_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN80, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN80_1, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o081_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN81, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN81_1, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o082_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN82_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN82_1, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o083_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN83_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN83_1, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o084_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN84_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN84_1, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o085_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN85_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN85_1, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o086_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN86_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN86_1, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o087_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN87_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN87_1, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o088_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN88_1, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I062 Switch", AFE_CONN88_1, 30, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o089_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN89_1, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I063 Switch", AFE_CONN89_1, 31, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o090_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN90_1, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I064 Switch", AFE_CONN90_2, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o091_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN91_1, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I065 Switch", AFE_CONN91_2, 1, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o092_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN92_1, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I066 Switch", AFE_CONN92_2, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o093_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN93_1, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I067 Switch", AFE_CONN93_2, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o094_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN94_1, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I068 Switch", AFE_CONN94_2, 4, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o095_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN95_1, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I069 Switch", AFE_CONN95_2, 5, 1, 0),
+};
+
+static const char * const mt8195_etdm_clk_src_sel_text[] = {
+ "26m",
+ "a1sys_a2sys",
+ "a3sys",
+ "a4sys",
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_text);
+
+static const char * const hdmitx_dptx_mux_map[] = {
+ "Disconnect", "Connect",
+};
+
+static int hdmitx_dptx_mux_map_value[] = {
+ 0, 1,
+};
+
+/* HDMI_OUT_MUX */
+static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(hdmi_out_mux_map_enum,
+ SND_SOC_NOPM,
+ 0,
+ 1,
+ hdmitx_dptx_mux_map,
+ hdmitx_dptx_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_out_mux_control =
+ SOC_DAPM_ENUM("HDMI_OUT_MUX", hdmi_out_mux_map_enum);
+
+/* DPTX_OUT_MUX */
+static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_out_mux_map_enum,
+ SND_SOC_NOPM,
+ 0,
+ 1,
+ hdmitx_dptx_mux_map,
+ hdmitx_dptx_mux_map_value);
+
+static const struct snd_kcontrol_new dptx_out_mux_control =
+ SOC_DAPM_ENUM("DPTX_OUT_MUX", dptx_out_mux_map_enum);
+
+/* HDMI_CH0_MUX ~ HDMI_CH7_MUX */
+static const char *const afe_conn_hdmi_mux_map[] = {
+ "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
+};
+
+static int afe_conn_hdmi_mux_map_value[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 0,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch0_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 4,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch1_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 8,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch2_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 12,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch3_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 16,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch4_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 20,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch5_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 24,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch6_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 28,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch7_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum);
+
+static int mt8195_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int source = ucontrol->value.enumerated.item[0];
+ unsigned int val;
+ unsigned int mask;
+ unsigned int reg;
+
+ if (source >= e->items)
+ return -EINVAL;
+
+ reg = 0;
+ if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
+ reg = ETDM_OUT1_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
+ reg = ETDM_OUT2_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
+ reg = ETDM_OUT3_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
+ reg = ETDM_IN1_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ val = ETDM_IN_CON2_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
+ reg = ETDM_IN2_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ val = ETDM_IN_CON2_CLOCK(source);
+ }
+
+ if (reg)
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ return 0;
+}
+
+static int mt8195_etdm_clk_src_sel_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int value = 0;
+ unsigned int reg = 0;
+ unsigned int mask = 0;
+ unsigned int shift = 0;
+
+ if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
+ reg = ETDM_OUT1_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
+ reg = ETDM_OUT2_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
+ reg = ETDM_OUT3_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
+ reg = ETDM_IN1_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
+ reg = ETDM_IN2_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ }
+
+ if (reg)
+ regmap_read(afe->regmap, reg, &value);
+
+ value &= mask;
+ value >>= shift;
+ ucontrol->value.enumerated.item[0] = value;
+ return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_etdm_controls[] = {
+ SOC_ENUM_EXT("ETDM_OUT1_Clock_Source",
+ etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_get,
+ mt8195_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_OUT2_Clock_Source",
+ etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_get,
+ mt8195_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_OUT3_Clock_Source",
+ etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_get,
+ mt8195_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_IN1_Clock_Source",
+ etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_get,
+ mt8195_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_IN2_Clock_Source",
+ etdmout_clk_src_enum,
+ mt8195_etdm_clk_src_sel_get,
+ mt8195_etdm_clk_src_sel_put),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
+ /* eTDM_IN2 */
+ SND_SOC_DAPM_MIXER("I012", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I013", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I014", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I015", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I016", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I017", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I018", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I019", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* eTDM_IN1 */
+ SND_SOC_DAPM_MIXER("I072", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I073", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I074", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I075", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I076", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I077", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I078", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I079", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I080", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I081", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I082", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I083", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I084", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I085", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I086", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I087", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I088", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I089", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I090", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I091", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I092", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I093", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I094", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I095", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* eTDM_OUT2 */
+ SND_SOC_DAPM_MIXER("O048", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o048_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o048_mix)),
+ SND_SOC_DAPM_MIXER("O049", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o049_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o049_mix)),
+ SND_SOC_DAPM_MIXER("O050", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o050_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o050_mix)),
+ SND_SOC_DAPM_MIXER("O051", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o051_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o051_mix)),
+ SND_SOC_DAPM_MIXER("O052", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o052_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o052_mix)),
+ SND_SOC_DAPM_MIXER("O053", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o053_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o053_mix)),
+ SND_SOC_DAPM_MIXER("O054", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o054_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o054_mix)),
+ SND_SOC_DAPM_MIXER("O055", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o055_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o055_mix)),
+ SND_SOC_DAPM_MIXER("O056", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o056_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o056_mix)),
+ SND_SOC_DAPM_MIXER("O057", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o057_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o057_mix)),
+ SND_SOC_DAPM_MIXER("O058", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o058_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o058_mix)),
+ SND_SOC_DAPM_MIXER("O059", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o059_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o059_mix)),
+ SND_SOC_DAPM_MIXER("O060", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o060_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o060_mix)),
+ SND_SOC_DAPM_MIXER("O061", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o061_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o061_mix)),
+ SND_SOC_DAPM_MIXER("O062", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o062_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o062_mix)),
+ SND_SOC_DAPM_MIXER("O063", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o063_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o063_mix)),
+ SND_SOC_DAPM_MIXER("O064", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o064_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o064_mix)),
+ SND_SOC_DAPM_MIXER("O065", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o065_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o065_mix)),
+ SND_SOC_DAPM_MIXER("O066", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o066_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o066_mix)),
+ SND_SOC_DAPM_MIXER("O067", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o067_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o067_mix)),
+ SND_SOC_DAPM_MIXER("O068", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o068_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o068_mix)),
+ SND_SOC_DAPM_MIXER("O069", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o069_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o069_mix)),
+ SND_SOC_DAPM_MIXER("O070", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o070_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o070_mix)),
+ SND_SOC_DAPM_MIXER("O071", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o071_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o071_mix)),
+
+ /* eTDM_OUT1 */
+ SND_SOC_DAPM_MIXER("O072", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o072_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o072_mix)),
+ SND_SOC_DAPM_MIXER("O073", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o073_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o073_mix)),
+ SND_SOC_DAPM_MIXER("O074", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o074_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o074_mix)),
+ SND_SOC_DAPM_MIXER("O075", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o075_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o075_mix)),
+ SND_SOC_DAPM_MIXER("O076", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o076_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o076_mix)),
+ SND_SOC_DAPM_MIXER("O077", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o077_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o077_mix)),
+ SND_SOC_DAPM_MIXER("O078", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o078_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o078_mix)),
+ SND_SOC_DAPM_MIXER("O079", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o079_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o079_mix)),
+ SND_SOC_DAPM_MIXER("O080", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o080_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o080_mix)),
+ SND_SOC_DAPM_MIXER("O081", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o081_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o081_mix)),
+ SND_SOC_DAPM_MIXER("O082", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o082_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o082_mix)),
+ SND_SOC_DAPM_MIXER("O083", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o083_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o083_mix)),
+ SND_SOC_DAPM_MIXER("O084", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o084_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o084_mix)),
+ SND_SOC_DAPM_MIXER("O085", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o085_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o085_mix)),
+ SND_SOC_DAPM_MIXER("O086", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o086_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o086_mix)),
+ SND_SOC_DAPM_MIXER("O087", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o087_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o087_mix)),
+ SND_SOC_DAPM_MIXER("O088", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o088_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o088_mix)),
+ SND_SOC_DAPM_MIXER("O089", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o089_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o089_mix)),
+ SND_SOC_DAPM_MIXER("O090", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o090_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o090_mix)),
+ SND_SOC_DAPM_MIXER("O091", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o091_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o091_mix)),
+ SND_SOC_DAPM_MIXER("O092", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o092_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o092_mix)),
+ SND_SOC_DAPM_MIXER("O093", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o093_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o093_mix)),
+ SND_SOC_DAPM_MIXER("O094", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o094_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o094_mix)),
+ SND_SOC_DAPM_MIXER("O095", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o095_mix,
+ ARRAY_SIZE(mtk_dai_etdm_o095_mix)),
+
+ /* eTDM_OUT3 */
+ SND_SOC_DAPM_MUX("HDMI_OUT_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_out_mux_control),
+ SND_SOC_DAPM_MUX("DPTX_OUT_MUX", SND_SOC_NOPM, 0, 0,
+ &dptx_out_mux_control),
+
+ SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch0_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch1_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch2_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch3_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch4_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch5_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch6_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch7_mux_control),
+
+ SND_SOC_DAPM_INPUT("ETDM_INPUT"),
+ SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
+ {"I012", NULL, "ETDM2 Capture"},
+ {"I013", NULL, "ETDM2 Capture"},
+ {"I014", NULL, "ETDM2 Capture"},
+ {"I015", NULL, "ETDM2 Capture"},
+ {"I016", NULL, "ETDM2 Capture"},
+ {"I017", NULL, "ETDM2 Capture"},
+ {"I018", NULL, "ETDM2 Capture"},
+ {"I019", NULL, "ETDM2 Capture"},
+
+ {"I072", NULL, "ETDM1 Capture"},
+ {"I073", NULL, "ETDM1 Capture"},
+ {"I074", NULL, "ETDM1 Capture"},
+ {"I075", NULL, "ETDM1 Capture"},
+ {"I076", NULL, "ETDM1 Capture"},
+ {"I077", NULL, "ETDM1 Capture"},
+ {"I078", NULL, "ETDM1 Capture"},
+ {"I079", NULL, "ETDM1 Capture"},
+ {"I080", NULL, "ETDM1 Capture"},
+ {"I081", NULL, "ETDM1 Capture"},
+ {"I082", NULL, "ETDM1 Capture"},
+ {"I083", NULL, "ETDM1 Capture"},
+ {"I084", NULL, "ETDM1 Capture"},
+ {"I085", NULL, "ETDM1 Capture"},
+ {"I086", NULL, "ETDM1 Capture"},
+ {"I087", NULL, "ETDM1 Capture"},
+ {"I088", NULL, "ETDM1 Capture"},
+ {"I089", NULL, "ETDM1 Capture"},
+ {"I090", NULL, "ETDM1 Capture"},
+ {"I091", NULL, "ETDM1 Capture"},
+ {"I092", NULL, "ETDM1 Capture"},
+ {"I093", NULL, "ETDM1 Capture"},
+ {"I094", NULL, "ETDM1 Capture"},
+ {"I095", NULL, "ETDM1 Capture"},
+
+ {"UL8", NULL, "ETDM1 Capture"},
+ {"UL3", NULL, "ETDM2 Capture"},
+
+ {"ETDM2 Playback", NULL, "O048"},
+ {"ETDM2 Playback", NULL, "O049"},
+ {"ETDM2 Playback", NULL, "O050"},
+ {"ETDM2 Playback", NULL, "O051"},
+ {"ETDM2 Playback", NULL, "O052"},
+ {"ETDM2 Playback", NULL, "O053"},
+ {"ETDM2 Playback", NULL, "O054"},
+ {"ETDM2 Playback", NULL, "O055"},
+ {"ETDM2 Playback", NULL, "O056"},
+ {"ETDM2 Playback", NULL, "O057"},
+ {"ETDM2 Playback", NULL, "O058"},
+ {"ETDM2 Playback", NULL, "O059"},
+ {"ETDM2 Playback", NULL, "O060"},
+ {"ETDM2 Playback", NULL, "O061"},
+ {"ETDM2 Playback", NULL, "O062"},
+ {"ETDM2 Playback", NULL, "O063"},
+ {"ETDM2 Playback", NULL, "O064"},
+ {"ETDM2 Playback", NULL, "O065"},
+ {"ETDM2 Playback", NULL, "O066"},
+ {"ETDM2 Playback", NULL, "O067"},
+ {"ETDM2 Playback", NULL, "O068"},
+ {"ETDM2 Playback", NULL, "O069"},
+ {"ETDM2 Playback", NULL, "O070"},
+ {"ETDM2 Playback", NULL, "O071"},
+
+ {"ETDM1 Playback", NULL, "O072"},
+ {"ETDM1 Playback", NULL, "O073"},
+ {"ETDM1 Playback", NULL, "O074"},
+ {"ETDM1 Playback", NULL, "O075"},
+ {"ETDM1 Playback", NULL, "O076"},
+ {"ETDM1 Playback", NULL, "O077"},
+ {"ETDM1 Playback", NULL, "O078"},
+ {"ETDM1 Playback", NULL, "O079"},
+ {"ETDM1 Playback", NULL, "O080"},
+ {"ETDM1 Playback", NULL, "O081"},
+ {"ETDM1 Playback", NULL, "O082"},
+ {"ETDM1 Playback", NULL, "O083"},
+ {"ETDM1 Playback", NULL, "O084"},
+ {"ETDM1 Playback", NULL, "O085"},
+ {"ETDM1 Playback", NULL, "O086"},
+ {"ETDM1 Playback", NULL, "O087"},
+ {"ETDM1 Playback", NULL, "O088"},
+ {"ETDM1 Playback", NULL, "O089"},
+ {"ETDM1 Playback", NULL, "O090"},
+ {"ETDM1 Playback", NULL, "O091"},
+ {"ETDM1 Playback", NULL, "O092"},
+ {"ETDM1 Playback", NULL, "O093"},
+ {"ETDM1 Playback", NULL, "O094"},
+ {"ETDM1 Playback", NULL, "O095"},
+
+ {"O048", "I020 Switch", "I020"},
+ {"O049", "I021 Switch", "I021"},
+
+ {"O048", "I022 Switch", "I022"},
+ {"O049", "I023 Switch", "I023"},
+ {"O050", "I024 Switch", "I024"},
+ {"O051", "I025 Switch", "I025"},
+ {"O052", "I026 Switch", "I026"},
+ {"O053", "I027 Switch", "I027"},
+ {"O054", "I028 Switch", "I028"},
+ {"O055", "I029 Switch", "I029"},
+ {"O056", "I030 Switch", "I030"},
+ {"O057", "I031 Switch", "I031"},
+ {"O058", "I032 Switch", "I032"},
+ {"O059", "I033 Switch", "I033"},
+ {"O060", "I034 Switch", "I034"},
+ {"O061", "I035 Switch", "I035"},
+ {"O062", "I036 Switch", "I036"},
+ {"O063", "I037 Switch", "I037"},
+ {"O064", "I038 Switch", "I038"},
+ {"O065", "I039 Switch", "I039"},
+ {"O066", "I040 Switch", "I040"},
+ {"O067", "I041 Switch", "I041"},
+ {"O068", "I042 Switch", "I042"},
+ {"O069", "I043 Switch", "I043"},
+ {"O070", "I044 Switch", "I044"},
+ {"O071", "I045 Switch", "I045"},
+
+ {"O048", "I046 Switch", "I046"},
+ {"O049", "I047 Switch", "I047"},
+ {"O050", "I048 Switch", "I048"},
+ {"O051", "I049 Switch", "I049"},
+ {"O052", "I050 Switch", "I050"},
+ {"O053", "I051 Switch", "I051"},
+ {"O054", "I052 Switch", "I052"},
+ {"O055", "I053 Switch", "I053"},
+ {"O056", "I054 Switch", "I054"},
+ {"O057", "I055 Switch", "I055"},
+ {"O058", "I056 Switch", "I056"},
+ {"O059", "I057 Switch", "I057"},
+ {"O060", "I058 Switch", "I058"},
+ {"O061", "I059 Switch", "I059"},
+ {"O062", "I060 Switch", "I060"},
+ {"O063", "I061 Switch", "I061"},
+ {"O064", "I062 Switch", "I062"},
+ {"O065", "I063 Switch", "I063"},
+ {"O066", "I064 Switch", "I064"},
+ {"O067", "I065 Switch", "I065"},
+ {"O068", "I066 Switch", "I066"},
+ {"O069", "I067 Switch", "I067"},
+ {"O070", "I068 Switch", "I068"},
+ {"O071", "I069 Switch", "I069"},
+
+ {"O048", "I070 Switch", "I070"},
+ {"O049", "I071 Switch", "I071"},
+
+ {"O072", "I020 Switch", "I020"},
+ {"O073", "I021 Switch", "I021"},
+
+ {"O072", "I022 Switch", "I022"},
+ {"O073", "I023 Switch", "I023"},
+ {"O074", "I024 Switch", "I024"},
+ {"O075", "I025 Switch", "I025"},
+ {"O076", "I026 Switch", "I026"},
+ {"O077", "I027 Switch", "I027"},
+ {"O078", "I028 Switch", "I028"},
+ {"O079", "I029 Switch", "I029"},
+ {"O080", "I030 Switch", "I030"},
+ {"O081", "I031 Switch", "I031"},
+ {"O082", "I032 Switch", "I032"},
+ {"O083", "I033 Switch", "I033"},
+ {"O084", "I034 Switch", "I034"},
+ {"O085", "I035 Switch", "I035"},
+ {"O086", "I036 Switch", "I036"},
+ {"O087", "I037 Switch", "I037"},
+ {"O088", "I038 Switch", "I038"},
+ {"O089", "I039 Switch", "I039"},
+ {"O090", "I040 Switch", "I040"},
+ {"O091", "I041 Switch", "I041"},
+ {"O092", "I042 Switch", "I042"},
+ {"O093", "I043 Switch", "I043"},
+ {"O094", "I044 Switch", "I044"},
+ {"O095", "I045 Switch", "I045"},
+
+ {"O072", "I046 Switch", "I046"},
+ {"O073", "I047 Switch", "I047"},
+ {"O074", "I048 Switch", "I048"},
+ {"O075", "I049 Switch", "I049"},
+ {"O076", "I050 Switch", "I050"},
+ {"O077", "I051 Switch", "I051"},
+ {"O078", "I052 Switch", "I052"},
+ {"O079", "I053 Switch", "I053"},
+ {"O080", "I054 Switch", "I054"},
+ {"O081", "I055 Switch", "I055"},
+ {"O082", "I056 Switch", "I056"},
+ {"O083", "I057 Switch", "I057"},
+ {"O084", "I058 Switch", "I058"},
+ {"O085", "I059 Switch", "I059"},
+ {"O086", "I060 Switch", "I060"},
+ {"O087", "I061 Switch", "I061"},
+ {"O088", "I062 Switch", "I062"},
+ {"O089", "I063 Switch", "I063"},
+ {"O090", "I064 Switch", "I064"},
+ {"O091", "I065 Switch", "I065"},
+ {"O092", "I066 Switch", "I066"},
+ {"O093", "I067 Switch", "I067"},
+ {"O094", "I068 Switch", "I068"},
+ {"O095", "I069 Switch", "I069"},
+
+ {"O072", "I070 Switch", "I070"},
+ {"O073", "I071 Switch", "I071"},
+
+ {"HDMI_CH0_MUX", "CH0", "DL10"},
+ {"HDMI_CH0_MUX", "CH1", "DL10"},
+ {"HDMI_CH0_MUX", "CH2", "DL10"},
+ {"HDMI_CH0_MUX", "CH3", "DL10"},
+ {"HDMI_CH0_MUX", "CH4", "DL10"},
+ {"HDMI_CH0_MUX", "CH5", "DL10"},
+ {"HDMI_CH0_MUX", "CH6", "DL10"},
+ {"HDMI_CH0_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH1_MUX", "CH0", "DL10"},
+ {"HDMI_CH1_MUX", "CH1", "DL10"},
+ {"HDMI_CH1_MUX", "CH2", "DL10"},
+ {"HDMI_CH1_MUX", "CH3", "DL10"},
+ {"HDMI_CH1_MUX", "CH4", "DL10"},
+ {"HDMI_CH1_MUX", "CH5", "DL10"},
+ {"HDMI_CH1_MUX", "CH6", "DL10"},
+ {"HDMI_CH1_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH2_MUX", "CH0", "DL10"},
+ {"HDMI_CH2_MUX", "CH1", "DL10"},
+ {"HDMI_CH2_MUX", "CH2", "DL10"},
+ {"HDMI_CH2_MUX", "CH3", "DL10"},
+ {"HDMI_CH2_MUX", "CH4", "DL10"},
+ {"HDMI_CH2_MUX", "CH5", "DL10"},
+ {"HDMI_CH2_MUX", "CH6", "DL10"},
+ {"HDMI_CH2_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH3_MUX", "CH0", "DL10"},
+ {"HDMI_CH3_MUX", "CH1", "DL10"},
+ {"HDMI_CH3_MUX", "CH2", "DL10"},
+ {"HDMI_CH3_MUX", "CH3", "DL10"},
+ {"HDMI_CH3_MUX", "CH4", "DL10"},
+ {"HDMI_CH3_MUX", "CH5", "DL10"},
+ {"HDMI_CH3_MUX", "CH6", "DL10"},
+ {"HDMI_CH3_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH4_MUX", "CH0", "DL10"},
+ {"HDMI_CH4_MUX", "CH1", "DL10"},
+ {"HDMI_CH4_MUX", "CH2", "DL10"},
+ {"HDMI_CH4_MUX", "CH3", "DL10"},
+ {"HDMI_CH4_MUX", "CH4", "DL10"},
+ {"HDMI_CH4_MUX", "CH5", "DL10"},
+ {"HDMI_CH4_MUX", "CH6", "DL10"},
+ {"HDMI_CH4_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH5_MUX", "CH0", "DL10"},
+ {"HDMI_CH5_MUX", "CH1", "DL10"},
+ {"HDMI_CH5_MUX", "CH2", "DL10"},
+ {"HDMI_CH5_MUX", "CH3", "DL10"},
+ {"HDMI_CH5_MUX", "CH4", "DL10"},
+ {"HDMI_CH5_MUX", "CH5", "DL10"},
+ {"HDMI_CH5_MUX", "CH6", "DL10"},
+ {"HDMI_CH5_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH6_MUX", "CH0", "DL10"},
+ {"HDMI_CH6_MUX", "CH1", "DL10"},
+ {"HDMI_CH6_MUX", "CH2", "DL10"},
+ {"HDMI_CH6_MUX", "CH3", "DL10"},
+ {"HDMI_CH6_MUX", "CH4", "DL10"},
+ {"HDMI_CH6_MUX", "CH5", "DL10"},
+ {"HDMI_CH6_MUX", "CH6", "DL10"},
+ {"HDMI_CH6_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH7_MUX", "CH0", "DL10"},
+ {"HDMI_CH7_MUX", "CH1", "DL10"},
+ {"HDMI_CH7_MUX", "CH2", "DL10"},
+ {"HDMI_CH7_MUX", "CH3", "DL10"},
+ {"HDMI_CH7_MUX", "CH4", "DL10"},
+ {"HDMI_CH7_MUX", "CH5", "DL10"},
+ {"HDMI_CH7_MUX", "CH6", "DL10"},
+ {"HDMI_CH7_MUX", "CH7", "DL10"},
+
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH0_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH1_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH2_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH3_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH4_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH5_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH6_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH7_MUX"},
+
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH0_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH1_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH2_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH3_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH4_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH5_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH6_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH7_MUX"},
+
+ {"ETDM3 Playback", NULL, "HDMI_OUT_MUX"},
+ {"DPTX Playback", NULL, "DPTX_OUT_MUX"},
+
+ {"ETDM_OUTPUT", NULL, "DPTX Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM1 Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM2 Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM3 Playback"},
+ {"ETDM1 Capture", NULL, "ETDM_INPUT"},
+ {"ETDM2 Capture", NULL, "ETDM_INPUT"},
+};
+
+static int mt8195_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id)
+{
+ int ret = 0;
+ struct etdm_con_reg etdm_reg;
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ unsigned long flags;
+
+ spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
+ etdm_data->en_ref_cnt++;
+ if (etdm_data->en_ref_cnt == 1) {
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ goto out;
+
+ regmap_update_bits(afe->regmap, etdm_reg.con0,
+ ETDM_CON0_EN, ETDM_CON0_EN);
+ }
+out:
+ spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
+ return ret;
+}
+
+static int mt8195_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id)
+{
+ int ret = 0;
+ struct etdm_con_reg etdm_reg;
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ unsigned long flags;
+
+ spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
+ if (etdm_data->en_ref_cnt > 0) {
+ etdm_data->en_ref_cnt--;
+ if (etdm_data->en_ref_cnt == 0) {
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ goto out;
+
+ regmap_update_bits(afe->regmap, etdm_reg.con0,
+ ETDM_CON0_EN, 0);
+ }
+ }
+out:
+ spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
+ return 0;
+}
+
+static int etdm_cowork_slv_sel(int id, int slave_mode)
+{
+ if (slave_mode) {
+ switch (id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ return COWORK_ETDM_IN1_S;
+ case MT8195_AFE_IO_ETDM2_IN:
+ return COWORK_ETDM_IN2_S;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ return COWORK_ETDM_OUT1_S;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ return COWORK_ETDM_OUT2_S;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ return COWORK_ETDM_OUT3_S;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ switch (id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ return COWORK_ETDM_IN1_M;
+ case MT8195_AFE_IO_ETDM2_IN:
+ return COWORK_ETDM_IN2_M;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ return COWORK_ETDM_OUT1_M;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ return COWORK_ETDM_OUT2_M;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ return COWORK_ETDM_OUT3_M;
+ default:
+ return -EINVAL;
+ }
+ }
+}
+
+static int mt8195_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ unsigned int reg = 0;
+ unsigned int mask;
+ unsigned int val;
+ int cowork_source_sel;
+
+ if (etdm_data->cowork_source_id == COWORK_ETDM_NONE)
+ return 0;
+
+ cowork_source_sel = etdm_cowork_slv_sel(etdm_data->cowork_source_id,
+ etdm_data->slave_mode);
+ if (cowork_source_sel < 0)
+ return cowork_source_sel;
+
+ switch (dai_id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ reg = ETDM_COWORK_CON1;
+ mask = ETDM_IN1_SLAVE_SEL_MASK;
+ val = ETDM_IN1_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_IN2_SLAVE_SEL_MASK;
+ val = ETDM_IN2_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ reg = ETDM_COWORK_CON0;
+ mask = ETDM_OUT1_SLAVE_SEL_MASK;
+ val = ETDM_OUT1_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT2_SLAVE_SEL_MASK;
+ val = ETDM_OUT2_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT3_SLAVE_SEL_MASK;
+ val = ETDM_OUT3_SLAVE_SEL(cowork_source_sel);
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_get_cg_id_by_dai_id(int dai_id)
+{
+ int cg_id = -1;
+
+ switch (dai_id) {
+ case MT8195_AFE_IO_DPTX:
+ cg_id = MT8195_CLK_AUD_HDMI_OUT;
+ break;
+ case MT8195_AFE_IO_ETDM1_IN:
+ cg_id = MT8195_CLK_AUD_TDM_IN;
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ cg_id = MT8195_CLK_AUD_I2SIN;
+ break;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ cg_id = MT8195_CLK_AUD_TDM_OUT;
+ break;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ cg_id = MT8195_CLK_AUD_I2S_OUT;
+ break;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ cg_id = MT8195_CLK_AUD_HDMI_OUT;
+ break;
+ default:
+ break;
+ }
+
+ return cg_id;
+}
+
+static int mtk_dai_etdm_get_clk_id_by_dai_id(int dai_id)
+{
+ int clk_id = -1;
+
+ switch (dai_id) {
+ case MT8195_AFE_IO_DPTX:
+ clk_id = MT8195_CLK_TOP_DPTX_M_SEL;
+ break;
+ case MT8195_AFE_IO_ETDM1_IN:
+ clk_id = MT8195_CLK_TOP_I2SI1_M_SEL;
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ clk_id = MT8195_CLK_TOP_I2SI2_M_SEL;
+ break;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ clk_id = MT8195_CLK_TOP_I2SO1_M_SEL;
+ break;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ clk_id = MT8195_CLK_TOP_I2SO2_M_SEL;
+ break;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ default:
+ break;
+ }
+
+ return clk_id;
+}
+
+static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)
+{
+ int clk_id = -1;
+
+ switch (dai_id) {
+ case MT8195_AFE_IO_DPTX:
+ clk_id = MT8195_CLK_TOP_APLL12_DIV9;
+ break;
+ case MT8195_AFE_IO_ETDM1_IN:
+ clk_id = MT8195_CLK_TOP_APLL12_DIV0;
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ clk_id = MT8195_CLK_TOP_APLL12_DIV1;
+ break;
+ case MT8195_AFE_IO_ETDM1_OUT:
+ clk_id = MT8195_CLK_TOP_APLL12_DIV2;
+ break;
+ case MT8195_AFE_IO_ETDM2_OUT:
+ clk_id = MT8195_CLK_TOP_APLL12_DIV3;
+ break;
+ case MT8195_AFE_IO_ETDM3_OUT:
+ default:
+ break;
+ }
+
+ return clk_id;
+}
+
+static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+
+ if (clkdiv_id < 0)
+ return -EINVAL;
+
+ mt8195_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+
+ if (clkdiv_id < 0)
+ return -EINVAL;
+
+ mt8195_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);
+
+ return 0;
+}
+
+/* dai ops */
+static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int cg_id;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ mtk_dai_etdm_enable_mclk(afe, mst_dai_id);
+
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
+ if (cg_id >= 0)
+ mt8195_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
+ if (cg_id >= 0)
+ mt8195_afe_enable_clk(afe,
+ afe_priv->clk[cg_id]);
+ }
+ } else {
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+ if (cg_id >= 0)
+ mt8195_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+ }
+
+ return 0;
+}
+
+static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int cg_id;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
+ if (cg_id >= 0)
+ mt8195_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
+ if (cg_id >= 0)
+ mt8195_afe_disable_clk(afe,
+ afe_priv->clk[cg_id]);
+ }
+ mtk_dai_etdm_disable_mclk(afe, mst_dai_id);
+ } else {
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+ if (cg_id >= 0)
+ mt8195_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+
+ mtk_dai_etdm_disable_mclk(afe, dai->id);
+ }
+}
+
+static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,
+ int dai_id, unsigned int rate)
+{
+ unsigned int mode = 0;
+ unsigned int reg = 0;
+ unsigned int val = 0;
+ unsigned int mask = (ETDM_IN_AFIFO_MODE_MASK | ETDM_IN_USE_AFIFO);
+
+ if (rate != 0)
+ mode = mt8195_afe_fs_timing(rate);
+
+ switch (dai_id) {
+ case MT8195_AFE_IO_ETDM1_IN:
+ reg = ETDM_IN1_AFIFO_CON;
+ if (rate == 0)
+ mode = MT8195_ETDM_IN1_1X_EN;
+ break;
+ case MT8195_AFE_IO_ETDM2_IN:
+ reg = ETDM_IN2_AFIFO_CON;
+ if (rate == 0)
+ mode = MT8195_ETDM_IN2_1X_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = (mode | ETDM_IN_USE_AFIFO);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+ return 0;
+}
+
+static int mtk_dai_etdm_in_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int data_mode = etdm_data->data_mode;
+ unsigned int lrck_width = etdm_data->lrck_width;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int i;
+ int ret;
+
+ dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",
+ __func__, rate, channels, dai_id);
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE)
+ slave_mode = true;
+
+ /* afifo */
+ if (slave_mode)
+ mtk_dai_etdm_fifo_mode(afe, dai_id, 0);
+ else
+ mtk_dai_etdm_fifo_mode(afe, dai_id, rate);
+
+ /* con1 */
+ if (lrck_width > 0) {
+ mask |= (ETDM_IN_CON1_LRCK_AUTO_MODE |
+ ETDM_IN_CON1_LRCK_WIDTH_MASK);
+ val |= ETDM_IN_CON1_LRCK_WIDTH(lrck_width);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con2 */
+ if (!slave_mode) {
+ mask |= ETDM_IN_CON2_UPDATE_GAP_MASK;
+ if (rate == 352800 || rate == 384000)
+ val |= ETDM_IN_CON2_UPDATE_GAP(4);
+ else
+ val |= ETDM_IN_CON2_UPDATE_GAP(3);
+ }
+ mask |= (ETDM_IN_CON2_MULTI_IP_2CH_MODE |
+ ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK);
+ if (data_mode == MTK_DAI_ETDM_DATA_MULTI_PIN) {
+ val |= ETDM_IN_CON2_MULTI_IP_2CH_MODE |
+ ETDM_IN_CON2_MULTI_IP_TOTAL_CH(channels);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con2, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con3 */
+ mask |= ETDM_IN_CON3_DISABLE_OUT_MASK;
+ for (i = 0; i < channels; i += 2) {
+ if (etdm_data->in_disable_ch[i] &&
+ etdm_data->in_disable_ch[i + 1])
+ val |= ETDM_IN_CON3_DISABLE_OUT(i >> 1);
+ }
+ if (!slave_mode) {
+ mask |= ETDM_IN_CON3_FS_MASK;
+ val |= ETDM_IN_CON3_FS(get_etdm_fs_timing(rate));
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con3, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con4 */
+ mask |= (ETDM_IN_CON4_MASTER_LRCK_INV | ETDM_IN_CON4_MASTER_BCK_INV |
+ ETDM_IN_CON4_SLAVE_LRCK_INV | ETDM_IN_CON4_SLAVE_BCK_INV);
+ if (slave_mode) {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_IN_CON4_SLAVE_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_IN_CON4_SLAVE_BCK_INV;
+ } else {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_IN_CON4_MASTER_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_IN_CON4_MASTER_BCK_INV;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con5 */
+ mask |= ETDM_IN_CON5_LR_SWAP_MASK;
+ mask |= ETDM_IN_CON5_ENABLE_ODD_MASK;
+ for (i = 0; i < channels; i += 2) {
+ if (etdm_data->in_disable_ch[i] &&
+ !etdm_data->in_disable_ch[i + 1]) {
+ if (i == (channels - 2))
+ val |= ETDM_IN_CON5_LR_SWAP(15);
+ else
+ val |= ETDM_IN_CON5_LR_SWAP(i >> 1);
+ val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);
+ } else if (!etdm_data->in_disable_ch[i] &&
+ etdm_data->in_disable_ch[i + 1]) {
+ val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);
+ }
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);
+ return 0;
+}
+
+static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int lrck_width = etdm_data->lrck_width;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int ret;
+ int fs = 0;
+
+ dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",
+ __func__, rate, channels, dai_id);
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE)
+ slave_mode = true;
+
+ /* con0 */
+ mask = ETDM_OUT_CON0_RELATCH_DOMAIN_MASK;
+ val = ETDM_OUT_CON0_RELATCH_DOMAIN(ETDM_RELATCH_TIMING_A1A2SYS);
+ regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con1 */
+ if (lrck_width > 0) {
+ mask |= (ETDM_OUT_CON1_LRCK_AUTO_MODE |
+ ETDM_OUT_CON1_LRCK_WIDTH_MASK);
+ val |= ETDM_OUT_CON1_LRCK_WIDTH(lrck_width);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ if (slave_mode) {
+ /* con2 */
+ mask = (ETDM_OUT_CON2_LRCK_DELAY_BCK_INV |
+ ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN);
+ val = (ETDM_OUT_CON2_LRCK_DELAY_BCK_INV |
+ ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN);
+ regmap_update_bits(afe->regmap, etdm_reg.con2,
+ mask, val);
+ mask = 0;
+ val = 0;
+ } else {
+ /* con4 */
+ mask |= ETDM_OUT_CON4_FS_MASK;
+ val |= ETDM_OUT_CON4_FS(get_etdm_fs_timing(rate));
+ }
+
+ mask |= ETDM_OUT_CON4_RELATCH_EN_MASK;
+ if (dai_id == MT8195_AFE_IO_ETDM1_OUT)
+ fs = MT8195_ETDM_OUT1_1X_EN;
+ else if (dai_id == MT8195_AFE_IO_ETDM2_OUT)
+ fs = MT8195_ETDM_OUT2_1X_EN;
+
+ val |= ETDM_OUT_CON4_RELATCH_EN(fs);
+
+ regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con5 */
+ mask |= (ETDM_OUT_CON5_MASTER_LRCK_INV | ETDM_OUT_CON5_MASTER_BCK_INV |
+ ETDM_OUT_CON5_SLAVE_LRCK_INV | ETDM_OUT_CON5_SLAVE_BCK_INV);
+ if (slave_mode) {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_OUT_CON5_SLAVE_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_OUT_CON5_SLAVE_BCK_INV;
+ } else {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_OUT_CON5_MASTER_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_OUT_CON5_MASTER_BCK_INV;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+ int apll;
+ int apll_clk_id;
+ struct etdm_con_reg etdm_reg;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int ret = 0;
+
+ if (clk_id < 0 || clkdiv_id < 0)
+ return 0;
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ mask |= ETDM_CON1_MCLK_OUTPUT;
+ if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+ val |= ETDM_CON1_MCLK_OUTPUT;
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ if (etdm_data->mclk_freq) {
+ apll = etdm_data->mclk_apll;
+ apll_clk_id = mt8195_afe_get_mclk_source_clk_id(apll);
+ if (apll_clk_id < 0)
+ return apll_clk_id;
+
+ /* select apll */
+ ret = mt8195_afe_set_clk_parent(afe, afe_priv->clk[clk_id],
+ afe_priv->clk[apll_clk_id]);
+ if (ret)
+ return ret;
+
+ /* set rate */
+ ret = mt8195_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
+ etdm_data->mclk_freq);
+ } else {
+ if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+ dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__);
+ }
+ return ret;
+}
+
+static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ unsigned int bit_width,
+ int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int etdm_channels;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ unsigned int bck;
+ unsigned int wlen = get_etdm_wlen(bit_width);
+ int ret;
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE)
+ slave_mode = true;
+
+ dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n",
+ __func__, etdm_data->format, etdm_data->data_mode,
+ etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
+ etdm_data->clock_mode, etdm_data->slave_mode);
+ dev_dbg(afe->dev, "%s rate %u channels %u bitwiedh %u, id %d\n",
+ __func__, rate, channels, bit_width, dai_id);
+
+ etdm_channels = (etdm_data->data_mode == MTK_DAI_ETDM_DATA_ONE_PIN) ?
+ get_etdm_ch_fixup(channels) : 2;
+
+ bck = rate * etdm_channels * wlen;
+ if (bck > MT8195_ETDM_NORMAL_MAX_BCK_RATE) {
+ dev_info(afe->dev, "%s bck rate %u not support\n",
+ __func__, bck);
+ return -EINVAL;
+ }
+
+ /* con0 */
+ mask |= ETDM_CON0_BIT_LEN_MASK;
+ val |= ETDM_CON0_BIT_LEN(bit_width);
+ mask |= ETDM_CON0_WORD_LEN_MASK;
+ val |= ETDM_CON0_WORD_LEN(wlen);
+ mask |= ETDM_CON0_FORMAT_MASK;
+ val |= ETDM_CON0_FORMAT(etdm_data->format);
+ mask |= ETDM_CON0_CH_NUM_MASK;
+ val |= ETDM_CON0_CH_NUM(etdm_channels);
+
+ mask |= ETDM_CON0_SLAVE_MODE;
+ if (slave_mode) {
+ if (dai_id == MT8195_AFE_IO_ETDM1_OUT &&
+ etdm_data->cowork_source_id == COWORK_ETDM_NONE) {
+ dev_info(afe->dev, "%s id %d only support master mode\n",
+ __func__, dai_id);
+ return -EINVAL;
+ }
+ val |= ETDM_CON0_SLAVE_MODE;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);
+
+ if (get_etdm_dir(dai_id) == ETDM_IN)
+ mtk_dai_etdm_in_configure(afe, rate, channels, dai_id);
+ else
+ mtk_dai_etdm_out_configure(afe, rate, channels, dai_id);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ unsigned int rate = params_rate(params);
+ unsigned int bit_width = params_width(params);
+ unsigned int channels = params_channels(params);
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ dev_dbg(afe->dev, "%s '%s' period %u-%u\n",
+ __func__, snd_pcm_stream_str(substream),
+ params_period_size(params), params_periods(params));
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+
+ ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, mst_dai_id);
+ if (ret)
+ return ret;
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, slv_dai_id);
+ if (ret)
+ return ret;
+
+ ret = mt8195_etdm_sync_mode_configure(afe, slv_dai_id);
+ if (ret)
+ return ret;
+ }
+ } else {
+ ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, dai->id);
+ }
+
+ return ret;
+}
+
+static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ //open master first
+ ret |= mt8195_afe_enable_etdm(afe, mst_dai_id);
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret |= mt8195_afe_enable_etdm(afe, slv_dai_id);
+ }
+ } else {
+ ret = mt8195_afe_enable_etdm(afe, dai->id);
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret |= mt8195_afe_disable_etdm(afe, slv_dai_id);
+ }
+ // close master at last
+ ret |= mt8195_afe_disable_etdm(afe, mst_dai_id);
+ } else {
+ ret = mt8195_afe_disable_etdm(afe, dai->id);
+ }
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ int apll;
+ int apll_rate;
+
+ if (freq == 0) {
+ etdm_data->mclk_freq = freq;
+ return 0;
+ }
+
+ apll = mt8195_afe_get_default_mclk_source_by_rate(freq);
+ apll_rate = mt8195_afe_get_mclk_source_rate(afe, apll);
+
+ if (freq > apll_rate) {
+ dev_info(afe->dev, "freq %d > apll rate %d\n", freq, apll_rate);
+ return -EINVAL;
+ }
+
+ if (apll_rate % freq != 0) {
+ dev_info(afe->dev, "APLL%d cannot generate freq Hz\n", apll);
+ return -EINVAL;
+ }
+
+ etdm_data->mclk_apll = apll;
+ etdm_data->mclk_freq = freq;
+
+ return 0;
+}
+
+static int mtk_dai_etdm_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+ int dai_id;
+
+ dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",
+ __func__, dai->id, freq, dir);
+ if (is_cowork_mode(dai))
+ dai_id = get_etdm_cowork_master_id(dai);
+ else
+ dai_id = dai->id;
+
+ etdm_data = afe_priv->dai_priv[dai_id];
+ etdm_data->mclk_dir = dir;
+ return mtk_dai_etdm_cal_mclk(afe, freq, dai_id);
+}
+
+static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d slot_width %d\n",
+ __func__, dai->id, slot_width);
+
+ etdm_data->slots = slots;
+ etdm_data->lrck_width = slot_width;
+ return 0;
+}
+
+static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_LJ;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_RJ;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ etdm_data->bck_inv = false;
+ etdm_data->lrck_inv = false;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ etdm_data->bck_inv = false;
+ etdm_data->lrck_inv = true;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ etdm_data->bck_inv = true;
+ etdm_data->lrck_inv = false;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ etdm_data->bck_inv = true;
+ etdm_data->lrck_inv = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ etdm_data->slave_mode = true;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ etdm_data->slave_mode = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+
+ if (cg_id >= 0)
+ mt8195_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+
+ return 0;
+}
+
+static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+
+ mtk_dai_etdm_disable_mclk(afe, dai->id);
+
+ if (cg_id >= 0)
+ mt8195_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+}
+
+static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)
+{
+ switch (channel) {
+ case 1 ... 2:
+ return AFE_DPTX_CON_CH_EN_2CH;
+ case 3 ... 4:
+ return AFE_DPTX_CON_CH_EN_4CH;
+ case 5 ... 6:
+ return AFE_DPTX_CON_CH_EN_6CH;
+ case 7 ... 8:
+ return AFE_DPTX_CON_CH_EN_8CH;
+ default:
+ return AFE_DPTX_CON_CH_EN_2CH;
+ }
+}
+
+static unsigned int mtk_dai_get_dptx_ch(unsigned int ch)
+{
+ return (ch > 2) ?
+ AFE_DPTX_CON_CH_NUM_8CH : AFE_DPTX_CON_CH_NUM_2CH;
+}
+
+static unsigned int mtk_dai_get_dptx_wlen(snd_pcm_format_t format)
+{
+ return snd_pcm_format_physical_width(format) <= 16 ?
+ AFE_DPTX_CON_16BIT : AFE_DPTX_CON_24BIT;
+}
+
+static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+ unsigned int rate = params_rate(params);
+ unsigned int channels = params_channels(params);
+ snd_pcm_format_t format = params_format(params);
+ int width = snd_pcm_format_physical_width(format);
+ int ret = 0;
+
+ /* dptx configure */
+ if (dai->id == MT8195_AFE_IO_DPTX) {
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_CH_EN_MASK,
+ mtk_dai_get_dptx_ch_en(channels));
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_CH_NUM_MASK,
+ mtk_dai_get_dptx_ch(channels));
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_16BIT_MASK,
+ mtk_dai_get_dptx_wlen(format));
+
+ if (mtk_dai_get_dptx_ch(channels) == AFE_DPTX_CON_CH_NUM_8CH) {
+ etdm_data->data_mode = MTK_DAI_ETDM_DATA_ONE_PIN;
+ channels = 8;
+ } else {
+ channels = 2;
+ }
+ } else {
+ etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;
+ }
+
+ ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);
+
+ return ret;
+}
+
+static int mtk_dai_hdmitx_dptx_trigger(struct snd_pcm_substream *substream,
+ int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+
+ dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ /* enable dptx interface */
+ if (dai->id == MT8195_AFE_IO_DPTX)
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_ON_MASK,
+ AFE_DPTX_CON_ON);
+
+ /* enable etdm_out3 */
+ ret = mt8195_afe_enable_etdm(afe, dai->id);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ /* disable etdm_out3 */
+ ret = mt8195_afe_disable_etdm(afe, dai->id);
+
+ /* disable dptx interface */
+ if (dai->id == MT8195_AFE_IO_DPTX)
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_ON_MASK, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id,
+ unsigned int freq,
+ int dir)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",
+ __func__, dai->id, freq, dir);
+
+ etdm_data->mclk_dir = dir;
+ return mtk_dai_etdm_cal_mclk(afe, freq, dai->id);
+}
+
+static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
+ .startup = mtk_dai_etdm_startup,
+ .shutdown = mtk_dai_etdm_shutdown,
+ .hw_params = mtk_dai_etdm_hw_params,
+ .trigger = mtk_dai_etdm_trigger,
+ .set_sysclk = mtk_dai_etdm_set_sysclk,
+ .set_fmt = mtk_dai_etdm_set_fmt,
+ .set_tdm_slot = mtk_dai_etdm_set_tdm_slot,
+};
+
+static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {
+ .startup = mtk_dai_hdmitx_dptx_startup,
+ .shutdown = mtk_dai_hdmitx_dptx_shutdown,
+ .hw_params = mtk_dai_hdmitx_dptx_hw_params,
+ .trigger = mtk_dai_hdmitx_dptx_trigger,
+ .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk,
+ .set_fmt = mtk_dai_etdm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_384000)
+
+#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static int mtk_dai_etdm_probe(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d\n", __func__, dai->id);
+
+ if (etdm_data->mclk_freq) {
+ dev_dbg(afe->dev, "MCLK always on, rate %d\n",
+ etdm_data->mclk_freq);
+ pm_runtime_get_sync(afe->dev);
+ mtk_dai_etdm_mclk_configure(afe, dai->id);
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+ pm_runtime_put_sync(afe->dev);
+ }
+ return 0;
+}
+
+static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = {
+ {
+ .name = "DPTX",
+ .id = MT8195_AFE_IO_DPTX,
+ .playback = {
+ .stream_name = "DPTX Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_hdmitx_dptx_ops,
+ },
+ {
+ .name = "ETDM1_IN",
+ .id = MT8195_AFE_IO_ETDM1_IN,
+ .capture = {
+ .stream_name = "ETDM1 Capture",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM2_IN",
+ .id = MT8195_AFE_IO_ETDM2_IN,
+ .capture = {
+ .stream_name = "ETDM2 Capture",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM1_OUT",
+ .id = MT8195_AFE_IO_ETDM1_OUT,
+ .playback = {
+ .stream_name = "ETDM1 Playback",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM2_OUT",
+ .id = MT8195_AFE_IO_ETDM2_OUT,
+ .playback = {
+ .stream_name = "ETDM2 Playback",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM3_OUT",
+ .id = MT8195_AFE_IO_ETDM3_OUT,
+ .playback = {
+ .stream_name = "ETDM3 Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_hdmitx_dptx_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+};
+
+static void mt8195_etdm_update_sync_info(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ struct mtk_dai_etdm_priv *mst_data;
+ int i;
+ int mst_dai_id;
+
+ for (i = MT8195_AFE_IO_ETDM_START; i < MT8195_AFE_IO_ETDM_END; i++) {
+ etdm_data = afe_priv->dai_priv[i];
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE) {
+ mst_dai_id = etdm_data->cowork_source_id;
+ mst_data = afe_priv->dai_priv[mst_dai_id];
+ if (mst_data->cowork_source_id != COWORK_ETDM_NONE)
+ dev_info(afe->dev, "%s [%d] wrong sync source\n"
+ , __func__, i);
+ mst_data->cowork_slv_id[mst_data->cowork_slv_count] = i;
+ mst_data->cowork_slv_count++;
+ }
+ }
+}
+
+static void mt8195_dai_etdm_parse_of(struct mtk_base_afe *afe)
+{
+ const struct device_node *of_node = afe->dev->of_node;
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int i, j;
+ char prop[48];
+ u8 disable_chn[MT8195_ETDM_MAX_CHANNELS];
+ int max_chn = MT8195_ETDM_MAX_CHANNELS;
+ u32 sel;
+ int ret;
+ int dai_id;
+ unsigned int sync_id;
+ struct {
+ const char *name;
+ const unsigned int sync_id;
+ } of_afe_etdms[MT8195_AFE_IO_ETDM_NUM] = {
+ {"etdm-in1", ETDM_SYNC_FROM_IN1},
+ {"etdm-in2", ETDM_SYNC_FROM_IN2},
+ {"etdm-out1", ETDM_SYNC_FROM_OUT1},
+ {"etdm-out2", ETDM_SYNC_FROM_OUT2},
+ {"etdm-out3", ETDM_SYNC_FROM_OUT3},
+ };
+
+ for (i = 0; i < MT8195_AFE_IO_ETDM_NUM; i++) {
+ dai_id = ETDM_TO_DAI_ID(i);
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-mclk-always-on-rate",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_u32(of_node, prop, &sel);
+ if (ret == 0) {
+ etdm_data->mclk_dir = SND_SOC_CLOCK_OUT;
+ if (mtk_dai_etdm_cal_mclk(afe, sel, dai_id))
+ dev_info(afe->dev, "%s unsupported mclk %uHz\n",
+ __func__, sel);
+ }
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-multi-pin-mode",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ etdm_data->data_mode = of_property_read_bool(of_node, prop);
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-cowork-source",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_u32(of_node, prop, &sel);
+ if (ret == 0) {
+ if (sel >= MT8195_AFE_IO_ETDM_NUM) {
+ dev_info(afe->dev, "%s invalid id=%d\n",
+ __func__, sel);
+ etdm_data->cowork_source_id = COWORK_ETDM_NONE;
+ } else {
+ sync_id = of_afe_etdms[sel].sync_id;
+ etdm_data->cowork_source_id =
+ sync_to_dai_id(sync_id);
+ }
+ } else {
+ etdm_data->cowork_source_id = COWORK_ETDM_NONE;
+ }
+ }
+
+ /* etdm in only */
+ for (i = 0; i < 2; i++) {
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-chn-disabled",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_variable_u8_array(of_node, prop,
+ disable_chn,
+ 1, max_chn);
+ if (ret < 0)
+ continue;
+
+ for (j = 0; j < ret; j++) {
+ if (disable_chn[j] >= MT8195_ETDM_MAX_CHANNELS)
+ dev_info(afe->dev, "%s [%d] invalid chn %u\n",
+ __func__, j, disable_chn[j]);
+ else
+ etdm_data->in_disable_ch[disable_chn[j]] = true;
+ }
+ }
+ mt8195_etdm_update_sync_info(afe);
+}
+
+static int init_etdm_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_priv;
+ int i;
+
+ for (i = MT8195_AFE_IO_ETDM_START; i < MT8195_AFE_IO_ETDM_END; i++) {
+ etdm_priv = devm_kzalloc(afe->dev,
+ sizeof(struct mtk_dai_etdm_priv),
+ GFP_KERNEL);
+ if (!etdm_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[i] = etdm_priv;
+ }
+
+ afe_priv->dai_priv[MT8195_AFE_IO_DPTX] =
+ afe_priv->dai_priv[MT8195_AFE_IO_ETDM3_OUT];
+
+ mt8195_dai_etdm_parse_of(afe);
+ return 0;
+}
+
+int mt8195_dai_etdm_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_etdm_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver);
+
+ dai->dapm_widgets = mtk_dai_etdm_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets);
+ dai->dapm_routes = mtk_dai_etdm_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes);
+ dai->controls = mtk_dai_etdm_controls;
+ dai->num_controls = ARRAY_SIZE(mtk_dai_etdm_controls);
+
+ return init_etdm_priv_data(afe);
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
new file mode 100644
index 000000000000..5d10d2c4c991
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI PCM I/F Control
+ *
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+enum {
+ MTK_DAI_PCM_FMT_I2S,
+ MTK_DAI_PCM_FMT_EIAJ,
+ MTK_DAI_PCM_FMT_MODEA,
+ MTK_DAI_PCM_FMT_MODEB,
+};
+
+enum {
+ MTK_DAI_PCM_CLK_A1SYS,
+ MTK_DAI_PCM_CLK_A2SYS,
+ MTK_DAI_PCM_CLK_26M_48K,
+ MTK_DAI_PCM_CLK_26M_441K,
+};
+
+struct mtk_dai_pcm_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+struct mtk_dai_pcmif_priv {
+ unsigned int slave_mode;
+ unsigned int lrck_inv;
+ unsigned int bck_inv;
+ unsigned int format;
+};
+
+static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 16000, .reg_value = 1, },
+ { .rate = 32000, .reg_value = 2, },
+ { .rate = 48000, .reg_value = 3, },
+ { .rate = 11025, .reg_value = 1, },
+ { .rate = 22050, .reg_value = 2, },
+ { .rate = 44100, .reg_value = 3, },
+};
+
+static int mtk_dai_pcm_mode(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
+ if (mtk_dai_pcm_rates[i].rate == rate)
+ return mtk_dai_pcm_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+ SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
+ mtk_dai_pcm_o000_mix,
+ ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
+ SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
+ mtk_dai_pcm_o001_mix,
+ ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
+
+ SND_SOC_DAPM_INPUT("PCM1_INPUT"),
+ SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+ {"I002", NULL, "PCM1 Capture"},
+ {"I003", NULL, "PCM1 Capture"},
+
+ {"O000", "I000 Switch", "I000"},
+ {"O001", "I001 Switch", "I001"},
+
+ {"O000", "I070 Switch", "I070"},
+ {"O001", "I071 Switch", "I071"},
+
+ {"PCM1 Playback", NULL, "O000"},
+ {"PCM1 Playback", NULL, "O001"},
+
+ {"PCM1_OUTPUT", NULL, "PCM1 Playback"},
+ {"PCM1 Capture", NULL, "PCM1_INPUT"},
+};
+
+static void mtk_dai_pcm_enable(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+ PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN);
+}
+
+static void mtk_dai_pcm_disable(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+ PCM_INTF_CON1_PCM_EN, 0x0);
+}
+
+static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime * const runtime = substream->runtime;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+ unsigned int slave_mode = pcmif_priv->slave_mode;
+ unsigned int lrck_inv = pcmif_priv->lrck_inv;
+ unsigned int bck_inv = pcmif_priv->bck_inv;
+ unsigned int fmt = pcmif_priv->format;
+ unsigned int bit_width = dai->sample_bits;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int fs = 0;
+ int mode = 0;
+
+ /* sync freq mode */
+ fs = mt8195_afe_fs_timing(runtime->rate);
+ if (fs < 0)
+ return -EINVAL;
+ val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
+ mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
+
+ /* clk domain sel */
+ if (runtime->rate % 8000)
+ val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
+ else
+ val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
+ mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
+
+ regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
+
+ val = 0;
+ mask = 0;
+
+ /* pcm mode */
+ mode = mtk_dai_pcm_mode(runtime->rate);
+ if (mode < 0)
+ return -EINVAL;
+ val |= PCM_INTF_CON1_PCM_MODE(mode);
+ mask |= PCM_INTF_CON1_PCM_MODE_MASK;
+
+ /* pcm format */
+ val |= PCM_INTF_CON1_PCM_FMT(fmt);
+ mask |= PCM_INTF_CON1_PCM_FMT_MASK;
+
+ /* pcm sync length */
+ if (fmt == MTK_DAI_PCM_FMT_MODEA ||
+ fmt == MTK_DAI_PCM_FMT_MODEB)
+ val |= PCM_INTF_CON1_SYNC_LENGTH(1);
+ else
+ val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
+ mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
+
+ /* pcm bits, word length */
+ if (bit_width > 16) {
+ val |= PCM_INTF_CON1_PCM_24BIT;
+ val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
+ } else {
+ val |= PCM_INTF_CON1_PCM_16BIT;
+ val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
+ }
+ mask |= PCM_INTF_CON1_PCM_BIT_MASK;
+ mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
+
+ /* master/slave */
+ if (!slave_mode) {
+ val |= PCM_INTF_CON1_PCM_MASTER;
+
+ if (lrck_inv)
+ val |= PCM_INTF_CON1_SYNC_OUT_INV;
+ if (bck_inv)
+ val |= PCM_INTF_CON1_BCLK_OUT_INV;
+ mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
+ } else {
+ val |= PCM_INTF_CON1_PCM_SLAVE;
+
+ if (lrck_inv)
+ val |= PCM_INTF_CON1_SYNC_IN_INV;
+ if (bck_inv)
+ val |= PCM_INTF_CON1_BCLK_IN_INV;
+ mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
+
+ /* TODO: add asrc setting for slave mode */
+ }
+ mask |= PCM_INTF_CON1_PCM_M_S_MASK;
+
+ regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
+
+ return 0;
+}
+
+/* dai ops */
+static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+ if (dai->component->active)
+ return 0;
+
+ mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+ mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+ mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+
+ return 0;
+}
+
+static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+ if (dai->component->active)
+ return;
+
+ mtk_dai_pcm_disable(afe);
+
+ mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+ mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+ mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+}
+
+static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+
+ if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+ snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE))
+ return 0;
+
+ ret = mtk_dai_pcm_configure(substream, dai);
+ if (ret)
+ return ret;
+
+ mtk_dai_pcm_enable(afe);
+
+ return 0;
+}
+
+static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ pcmif_priv->bck_inv = 0;
+ pcmif_priv->lrck_inv = 0;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ pcmif_priv->bck_inv = 0;
+ pcmif_priv->lrck_inv = 1;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ pcmif_priv->bck_inv = 1;
+ pcmif_priv->lrck_inv = 0;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ pcmif_priv->bck_inv = 1;
+ pcmif_priv->lrck_inv = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ pcmif_priv->slave_mode = 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ pcmif_priv->slave_mode = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
+ .startup = mtk_dai_pcm_startup,
+ .shutdown = mtk_dai_pcm_shutdown,
+ .prepare = mtk_dai_pcm_prepare,
+ .set_fmt = mtk_dai_pcm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+ {
+ .name = "PCM1",
+ .id = MT8195_AFE_IO_PCM,
+ .playback = {
+ .stream_name = "PCM1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .capture = {
+ .stream_name = "PCM1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mtk_dai_pcm_ops,
+ .symmetric_rate = 1,
+ .symmetric_sample_bits = 1,
+ },
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv;
+
+ pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
+ GFP_KERNEL);
+ if (!pcmif_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv;
+ return 0;
+}
+
+int mt8195_dai_pcm_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_pcm_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+
+ dai->dapm_widgets = mtk_dai_pcm_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+ dai->dapm_routes = mtk_dai_pcm_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+ return init_pcmif_priv_data(afe);
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
new file mode 100644
index 000000000000..5dc217f59bd6
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -0,0 +1,1087 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt8195-mt6359-rt1019-rt5682.c --
+// MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Trevor Wu <trevor.wu@mediatek.com>
+//
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/rt5682.h>
+#include <sound/soc.h>
+#include "../../codecs/mt6359.h"
+#include "../../codecs/rt5682.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "mt8195-afe-common.h"
+
+#define RT1019_CODEC_DAI "HiFi"
+#define RT1019_DEV0_NAME "rt1019p"
+
+#define RT5682_CODEC_DAI "rt5682-aif1"
+#define RT5682_DEV0_NAME "rt5682.2-001a"
+
+struct mt8195_mt6359_rt1019_rt5682_priv {
+ struct snd_soc_jack headset_jack;
+ struct snd_soc_jack dp_jack;
+ struct snd_soc_jack hdmi_jack;
+};
+
+static const struct snd_soc_dapm_widget
+ mt8195_mt6359_rt1019_rt5682_widgets[] = {
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
+ /* speaker */
+ { "Speakers", NULL, "Speaker" },
+ /* headset */
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+ { "IN1P", NULL, "Headset Mic" },
+};
+
+static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ unsigned int rate = params_rate(params);
+ unsigned int mclk_fs_ratio = 128;
+ unsigned int mclk_fs = rate * mclk_fs_ratio;
+ int bitwidth;
+ int ret;
+
+ bitwidth = snd_pcm_format_width(params_format(params));
+ if (bitwidth < 0) {
+ dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
+ return bitwidth;
+ }
+
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
+ if (ret) {
+ dev_err(card->dev, "failed to set tdm slot\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
+ RT5682_PLL1_S_BCLK1,
+ params_rate(params) * 64,
+ params_rate(params) * 512);
+ if (ret) {
+ dev_err(card->dev, "failed to set pll\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ RT5682_SCLK_S_PLL1,
+ params_rate(params) * 512,
+ SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(card->dev, "failed to set sysclk\n");
+ return ret;
+ }
+
+ return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
+}
+
+static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
+ .hw_params = mt8195_rt5682_etdm_hw_params,
+};
+
+#define CKSYS_AUD_TOP_CFG 0x032c
+#define CKSYS_AUD_TOP_MON 0x0330
+
+static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *cmpnt_afe =
+ snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
+ struct mt8195_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int phase;
+ unsigned int monitor;
+ int mtkaif_calibration_num_phase;
+ int test_done_1, test_done_2, test_done_3;
+ int cycle_1, cycle_2, cycle_3;
+ int prev_cycle_1, prev_cycle_2, prev_cycle_3;
+ int chosen_phase_1, chosen_phase_2, chosen_phase_3;
+ int counter;
+ bool mtkaif_calibration_ok;
+ int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
+ int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
+ int i;
+
+ dev_info(afe->dev, "%s(), start\n", __func__);
+
+ param->mtkaif_calibration_ok = false;
+ for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) {
+ param->mtkaif_chosen_phase[i] = -1;
+ param->mtkaif_phase_cycle[i] = 0;
+ mtkaif_chosen_phase[i] = -1;
+ mtkaif_phase_cycle[i] = 0;
+ }
+
+ if (IS_ERR(afe_priv->topckgen)) {
+ dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
+ __func__);
+ return 0;
+ }
+
+ pm_runtime_get_sync(afe->dev);
+ mt6359_mtkaif_calibration_enable(cmpnt_codec);
+
+ /* set test type to synchronizer pulse */
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
+ mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */
+ mtkaif_calibration_ok = true;
+
+ for (phase = 0;
+ phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
+ phase++) {
+ mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+ phase, phase, phase);
+
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0x1, 0x1);
+
+ test_done_1 = 0;
+ test_done_2 = 0;
+ test_done_3 = 0;
+ cycle_1 = -1;
+ cycle_2 = -1;
+ cycle_3 = -1;
+ counter = 0;
+ while (!(test_done_1 & test_done_2 & test_done_3)) {
+ regmap_read(afe_priv->topckgen,
+ CKSYS_AUD_TOP_MON, &monitor);
+ test_done_1 = (monitor >> 28) & 0x1;
+ test_done_2 = (monitor >> 29) & 0x1;
+ test_done_3 = (monitor >> 30) & 0x1;
+ if (test_done_1 == 1)
+ cycle_1 = monitor & 0xf;
+
+ if (test_done_2 == 1)
+ cycle_2 = (monitor >> 4) & 0xf;
+
+ if (test_done_3 == 1)
+ cycle_3 = (monitor >> 8) & 0xf;
+
+ /* handle if never test done */
+ if (++counter > 10000) {
+ dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n",
+ __func__,
+ cycle_1, cycle_2, cycle_3, monitor);
+ mtkaif_calibration_ok = false;
+ break;
+ }
+ }
+
+ if (phase == 0) {
+ prev_cycle_1 = cycle_1;
+ prev_cycle_2 = cycle_2;
+ prev_cycle_3 = cycle_3;
+ }
+
+ if (cycle_1 != prev_cycle_1 &&
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1;
+ mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1;
+ }
+
+ if (cycle_2 != prev_cycle_2 &&
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1;
+ mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2;
+ }
+
+ if (cycle_3 != prev_cycle_3 &&
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1;
+ mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3;
+ }
+
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0x1, 0x0);
+
+ if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 &&
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 &&
+ mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0)
+ break;
+ }
+
+ if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+ mtkaif_calibration_ok = false;
+ chosen_phase_1 = 0;
+ } else {
+ chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0];
+ }
+
+ if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+ mtkaif_calibration_ok = false;
+ chosen_phase_2 = 0;
+ } else {
+ chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1];
+ }
+
+ if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+ mtkaif_calibration_ok = false;
+ chosen_phase_3 = 0;
+ } else {
+ chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2];
+ }
+
+ mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+ chosen_phase_1,
+ chosen_phase_2,
+ chosen_phase_3);
+
+ mt6359_mtkaif_calibration_disable(cmpnt_codec);
+ pm_runtime_put(afe->dev);
+
+ param->mtkaif_calibration_ok = mtkaif_calibration_ok;
+ param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1;
+ param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2;
+ param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3;
+ for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++)
+ param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
+
+ dev_info(afe->dev, "%s(), end, calibration ok %d\n",
+ __func__, param->mtkaif_calibration_ok);
+
+ return 0;
+}
+
+static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+
+ /* set mtkaif protocol */
+ mt6359_set_mtkaif_protocol(cmpnt_codec,
+ MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
+
+ /* mtkaif calibration */
+ mt8195_mt6359_mtkaif_calibration(rtd);
+
+ return 0;
+}
+
+static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+ snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_jack *jack = &priv->headset_jack;
+ int ret;
+
+ ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_BTN_0 |
+ SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+ SND_JACK_BTN_3,
+ jack, NULL, 0);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+};
+
+static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ /* fix BE i2s format to 32bit, clean param mask first */
+ snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+ 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+ params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+ return 0;
+}
+
+static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream)
+{
+ static const unsigned int rates[] = {
+ 48000
+ };
+ static const unsigned int channels[] = {
+ 2, 4, 6, 8
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+ };
+
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = {
+ .startup = mt8195_hdmitx_dptx_startup,
+};
+
+static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ unsigned int rate = params_rate(params);
+ unsigned int mclk_fs_ratio = 256;
+ unsigned int mclk_fs = rate * mclk_fs_ratio;
+
+ return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs,
+ SND_SOC_CLOCK_OUT);
+}
+
+static struct snd_soc_ops mt8195_dptx_ops = {
+ .hw_params = mt8195_dptx_hw_params,
+};
+
+static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+ snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ int ret = 0;
+
+ ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
+ &priv->dp_jack, NULL, 0);
+ if (ret)
+ return ret;
+
+ return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
+}
+
+static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+ snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ int ret = 0;
+
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+ &priv->hdmi_jack, NULL, 0);
+ if (ret)
+ return ret;
+
+ return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
+}
+
+static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+
+{
+ /* fix BE i2s format to 32bit, clean param mask first */
+ snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+ 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+ params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+ return 0;
+}
+
+static int mt8195_playback_startup(struct snd_pcm_substream *substream)
+{
+ static const unsigned int rates[] = {
+ 48000
+ };
+ static const unsigned int channels[] = {
+ 2
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+ };
+
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops mt8195_playback_ops = {
+ .startup = mt8195_playback_startup,
+};
+
+static int mt8195_capture_startup(struct snd_pcm_substream *substream)
+{
+ static const unsigned int rates[] = {
+ 48000
+ };
+ static const unsigned int channels[] = {
+ 1, 2
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+ };
+ static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+ };
+
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_rates);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops mt8195_capture_ops = {
+ .startup = mt8195_capture_startup,
+};
+
+enum {
+ DAI_LINK_DL2_FE,
+ DAI_LINK_DL3_FE,
+ DAI_LINK_DL6_FE,
+ DAI_LINK_DL7_FE,
+ DAI_LINK_DL8_FE,
+ DAI_LINK_DL10_FE,
+ DAI_LINK_DL11_FE,
+ DAI_LINK_UL1_FE,
+ DAI_LINK_UL2_FE,
+ DAI_LINK_UL3_FE,
+ DAI_LINK_UL4_FE,
+ DAI_LINK_UL5_FE,
+ DAI_LINK_UL6_FE,
+ DAI_LINK_UL8_FE,
+ DAI_LINK_UL9_FE,
+ DAI_LINK_UL10_FE,
+ DAI_LINK_DL_SRC_BE,
+ DAI_LINK_DPTX_BE,
+ DAI_LINK_ETDM1_IN_BE,
+ DAI_LINK_ETDM2_IN_BE,
+ DAI_LINK_ETDM1_OUT_BE,
+ DAI_LINK_ETDM2_OUT_BE,
+ DAI_LINK_ETDM3_OUT_BE,
+ DAI_LINK_PCM1_BE,
+ DAI_LINK_UL_SRC1_BE,
+ DAI_LINK_UL_SRC2_BE,
+};
+
+/* FE */
+SND_SOC_DAILINK_DEFS(DL2_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL3_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL6_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL7_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL8_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL10_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL11_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL1_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL2_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL3_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL4_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL5_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL6_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL8_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL9_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL10_FE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+/* BE */
+SND_SOC_DAILINK_DEFS(DL_SRC_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+ "mt6359-snd-codec-aif1")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DPTX_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+ DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+ RT5682_CODEC_DAI)),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+ DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+ RT5682_CODEC_DAI)),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
+ DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME,
+ RT1019_CODEC_DAI)),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(PCM1_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC1_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+ "mt6359-snd-codec-aif1"),
+ COMP_CODEC("dmic-codec",
+ "dmic-hifi")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+ "mt6359-snd-codec-aif2")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
+ /* FE */
+ [DAI_LINK_DL2_FE] = {
+ .name = "DL2_FE",
+ .stream_name = "DL2 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_playback_ops,
+ SND_SOC_DAILINK_REG(DL2_FE),
+ },
+ [DAI_LINK_DL3_FE] = {
+ .name = "DL3_FE",
+ .stream_name = "DL3 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_playback_ops,
+ SND_SOC_DAILINK_REG(DL3_FE),
+ },
+ [DAI_LINK_DL6_FE] = {
+ .name = "DL6_FE",
+ .stream_name = "DL6 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_playback_ops,
+ SND_SOC_DAILINK_REG(DL6_FE),
+ },
+ [DAI_LINK_DL7_FE] = {
+ .name = "DL7_FE",
+ .stream_name = "DL7 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(DL7_FE),
+ },
+ [DAI_LINK_DL8_FE] = {
+ .name = "DL8_FE",
+ .stream_name = "DL8 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_playback_ops,
+ SND_SOC_DAILINK_REG(DL8_FE),
+ },
+ [DAI_LINK_DL10_FE] = {
+ .name = "DL10_FE",
+ .stream_name = "DL10 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_hdmitx_dptx_playback_ops,
+ SND_SOC_DAILINK_REG(DL10_FE),
+ },
+ [DAI_LINK_DL11_FE] = {
+ .name = "DL11_FE",
+ .stream_name = "DL11 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_playback_ops,
+ SND_SOC_DAILINK_REG(DL11_FE),
+ },
+ [DAI_LINK_UL1_FE] = {
+ .name = "UL1_FE",
+ .stream_name = "UL1 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(UL1_FE),
+ },
+ [DAI_LINK_UL2_FE] = {
+ .name = "UL2_FE",
+ .stream_name = "UL2 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL2_FE),
+ },
+ [DAI_LINK_UL3_FE] = {
+ .name = "UL3_FE",
+ .stream_name = "UL3 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL3_FE),
+ },
+ [DAI_LINK_UL4_FE] = {
+ .name = "UL4_FE",
+ .stream_name = "UL4 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL4_FE),
+ },
+ [DAI_LINK_UL5_FE] = {
+ .name = "UL5_FE",
+ .stream_name = "UL5 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL5_FE),
+ },
+ [DAI_LINK_UL6_FE] = {
+ .name = "UL6_FE",
+ .stream_name = "UL6 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(UL6_FE),
+ },
+ [DAI_LINK_UL8_FE] = {
+ .name = "UL8_FE",
+ .stream_name = "UL8 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL8_FE),
+ },
+ [DAI_LINK_UL9_FE] = {
+ .name = "UL9_FE",
+ .stream_name = "UL9 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL9_FE),
+ },
+ [DAI_LINK_UL10_FE] = {
+ .name = "UL10_FE",
+ .stream_name = "UL10 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .ops = &mt8195_capture_ops,
+ SND_SOC_DAILINK_REG(UL10_FE),
+ },
+ /* BE */
+ [DAI_LINK_DL_SRC_BE] = {
+ .name = "DL_SRC_BE",
+ .init = mt8195_mt6359_init,
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(DL_SRC_BE),
+ },
+ [DAI_LINK_DPTX_BE] = {
+ .name = "DPTX_BE",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .ops = &mt8195_dptx_ops,
+ .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
+ SND_SOC_DAILINK_REG(DPTX_BE),
+ },
+ [DAI_LINK_ETDM1_IN_BE] = {
+ .name = "ETDM1_IN_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(ETDM1_IN_BE),
+ },
+ [DAI_LINK_ETDM2_IN_BE] = {
+ .name = "ETDM2_IN_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_capture = 1,
+ .init = mt8195_rt5682_init,
+ .ops = &mt8195_rt5682_etdm_ops,
+ .be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+ SND_SOC_DAILINK_REG(ETDM2_IN_BE),
+ },
+ [DAI_LINK_ETDM1_OUT_BE] = {
+ .name = "ETDM1_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_playback = 1,
+ .ops = &mt8195_rt5682_etdm_ops,
+ .be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+ SND_SOC_DAILINK_REG(ETDM1_OUT_BE),
+ },
+ [DAI_LINK_ETDM2_OUT_BE] = {
+ .name = "ETDM2_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(ETDM2_OUT_BE),
+ },
+ [DAI_LINK_ETDM3_OUT_BE] = {
+ .name = "ETDM3_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_playback = 1,
+ .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
+ SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
+ },
+ [DAI_LINK_PCM1_BE] = {
+ .name = "PCM1_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(PCM1_BE),
+ },
+ [DAI_LINK_UL_SRC1_BE] = {
+ .name = "UL_SRC1_BE",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(UL_SRC1_BE),
+ },
+ [DAI_LINK_UL_SRC2_BE] = {
+ .name = "UL_SRC2_BE",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(UL_SRC2_BE),
+ },
+};
+
+static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
+ .name = "mt8195_r1019_5682",
+ .owner = THIS_MODULE,
+ .dai_link = mt8195_mt6359_rt1019_rt5682_dai_links,
+ .num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links),
+ .controls = mt8195_mt6359_rt1019_rt5682_controls,
+ .num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls),
+ .dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
+ .dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
+ .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
+};
+
+static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card;
+ struct device_node *platform_node;
+ struct snd_soc_dai_link *dai_link;
+ struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
+ int ret, i;
+
+ card->dev = &pdev->dev;
+
+ platform_node = of_parse_phandle(pdev->dev.of_node,
+ "mediatek,platform", 0);
+ if (!platform_node) {
+ dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
+ return -EINVAL;
+ }
+
+ for_each_card_prelinks(card, i, dai_link) {
+ if (!dai_link->platforms->name)
+ dai_link->platforms->of_node = platform_node;
+
+ if (strcmp(dai_link->name, "DPTX_BE") == 0) {
+ dai_link->codecs->of_node =
+ of_parse_phandle(pdev->dev.of_node,
+ "mediatek,dptx-codec", 0);
+ if (!dai_link->codecs->of_node) {
+ dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n");
+ return -EINVAL;
+ }
+
+ dai_link->codecs->name = NULL;
+ dai_link->codecs->dai_name = "i2s-hifi";
+ dai_link->init = mt8195_dptx_codec_init;
+ }
+
+ if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
+ dai_link->codecs->of_node =
+ of_parse_phandle(pdev->dev.of_node,
+ "mediatek,hdmi-codec", 0);
+ if (!dai_link->codecs->of_node) {
+ dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n");
+ return -EINVAL;
+ }
+
+ dai_link->codecs->name = NULL;
+ dai_link->codecs->dai_name = "i2s-hifi";
+ dai_link->init = mt8195_hdmi_codec_init;
+ }
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ snd_soc_card_set_drvdata(card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret)
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+ __func__, ret);
+ return ret;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = {
+ {.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",},
+ {}
+};
+#endif
+
+static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = {
+ .poweroff = snd_soc_poweroff,
+ .restore = snd_soc_resume,
+};
+
+static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = {
+ .driver = {
+ .name = "mt8195_mt6359_rt1019_rt5682",
+#ifdef CONFIG_OF
+ .of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match,
+#endif
+ .pm = &mt8195_mt6359_rt1019_rt5682_pm_ops,
+ },
+ .probe = mt8195_mt6359_rt1019_rt5682_dev_probe,
+};
+
+module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver");
+MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card");
diff --git a/sound/soc/mediatek/mt8195/mt8195-reg.h b/sound/soc/mediatek/mt8195/mt8195-reg.h
new file mode 100644
index 000000000000..d06f9cf85a4e
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-reg.h
@@ -0,0 +1,2796 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-reg.h -- Mediatek 8195 audio driver reg definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#ifndef _MT8195_REG_H_
+#define _MT8195_REG_H_
+
+#define AFE_SRAM_BASE (0x10880000)
+#define AFE_SRAM_SIZE (0x10000)
+
+#define AUDIO_TOP_CON0 (0x0000)
+#define AUDIO_TOP_CON1 (0x0004)
+#define AUDIO_TOP_CON2 (0x0008)
+#define AUDIO_TOP_CON3 (0x000c)
+#define AUDIO_TOP_CON4 (0x0010)
+#define AUDIO_TOP_CON5 (0x0014)
+#define AUDIO_TOP_CON6 (0x0018)
+#define AFE_MAS_HADDR_MSB (0x0020)
+#define PWR1_ASM_CON1 (0x0108)
+#define ASYS_IRQ_CONFIG (0x0110)
+#define ASYS_IRQ1_CON (0x0114)
+#define ASYS_IRQ2_CON (0x0118)
+#define ASYS_IRQ3_CON (0x011c)
+#define ASYS_IRQ4_CON (0x0120)
+#define ASYS_IRQ5_CON (0x0124)
+#define ASYS_IRQ6_CON (0x0128)
+#define ASYS_IRQ7_CON (0x012c)
+#define ASYS_IRQ8_CON (0x0130)
+#define ASYS_IRQ9_CON (0x0134)
+#define ASYS_IRQ10_CON (0x0138)
+#define ASYS_IRQ11_CON (0x013c)
+#define ASYS_IRQ12_CON (0x0140)
+#define ASYS_IRQ13_CON (0x0144)
+#define ASYS_IRQ14_CON (0x0148)
+#define ASYS_IRQ15_CON (0x014c)
+#define ASYS_IRQ16_CON (0x0150)
+#define ASYS_IRQ_CLR (0x0154)
+#define ASYS_IRQ_STATUS (0x0158)
+#define ASYS_IRQ_MON1 (0x015c)
+#define ASYS_IRQ_MON2 (0x0160)
+#define AFE_IRQ1_CON (0x0164)
+#define AFE_IRQ2_CON (0x0168)
+#define AFE_IRQ3_CON (0x016c)
+#define AFE_IRQ_MCU_CLR (0x0170)
+#define AFE_IRQ_STATUS (0x0174)
+#define AFE_IRQ_MASK (0x0178)
+#define ASYS_IRQ_MASK (0x017c)
+#define AFE_IRQ3_CON_MON (0x01b0)
+#define AFE_IRQ_MCU_MON2 (0x01b4)
+#define AFE_IRQ8_CON (0x01b8)
+#define AFE_IRQ9_CON (0x01bc)
+#define AFE_IRQ10_CON (0x01c0)
+#define AFE_IRQ9_CON_MON (0x01c4)
+#define ADSP_IRQ_MASK (0x01c8)
+#define ADSP_IRQ_STATUS (0x01cc)
+#define AFE_SINEGEN_CON0 (0x01f0)
+#define AFE_SINEGEN_CON1 (0x01f4)
+#define AFE_SINEGEN_CON2 (0x01f8)
+#define AFE_SINEGEN_CON3 (0x01fc)
+#define AFE_SPDIF_OUT_CON0 (0x0380)
+#define AFE_TDMOUT_CONN0 (0x0390)
+#define PWR1_ASM_CON2 (0x03b0)
+#define PWR1_ASM_CON3 (0x03b4)
+#define PWR1_ASM_CON4 (0x03b8)
+#define AFE_APLL_TUNER_CFG (0x03f8)
+#define AFE_APLL_TUNER_CFG1 (0x03fc)
+#define AUDIO_TOP_STA0 (0x0400)
+#define AUDIO_TOP_STA1 (0x0404)
+#define AFE_GAIN1_CON0 (0x0410)
+#define AFE_GAIN1_CON1 (0x0414)
+#define AFE_GAIN1_CON2 (0x0418)
+#define AFE_GAIN1_CON3 (0x041c)
+#define AFE_GAIN1_CUR (0x0424)
+#define AFE_GAIN2_CON0 (0x0428)
+#define AFE_GAIN2_CON1 (0x042c)
+#define AFE_GAIN2_CON2 (0x0430)
+#define AFE_GAIN2_CON3 (0x0434)
+#define AFE_GAIN2_CUR (0x043c)
+#define AFE_IEC_CFG (0x0480)
+#define AFE_IEC_NSNUM (0x0484)
+#define AFE_IEC_BURST_INFO (0x0488)
+#define AFE_IEC_BURST_LEN (0x048c)
+#define AFE_IEC_NSADR (0x0490)
+#define AFE_IEC_CHL_STAT0 (0x04a0)
+#define AFE_IEC_CHL_STAT1 (0x04a4)
+#define AFE_IEC_CHR_STAT0 (0x04a8)
+#define AFE_IEC_CHR_STAT1 (0x04ac)
+#define AFE_SPDIFIN_CFG0 (0x0500)
+#define AFE_SPDIFIN_CFG1 (0x0504)
+#define AFE_SPDIFIN_CHSTS1 (0x0508)
+#define AFE_SPDIFIN_CHSTS2 (0x050c)
+#define AFE_SPDIFIN_CHSTS3 (0x0510)
+#define AFE_SPDIFIN_CHSTS4 (0x0514)
+#define AFE_SPDIFIN_CHSTS5 (0x0518)
+#define AFE_SPDIFIN_CHSTS6 (0x051c)
+#define AFE_SPDIFIN_DEBUG1 (0x0520)
+#define AFE_SPDIFIN_DEBUG2 (0x0524)
+#define AFE_SPDIFIN_DEBUG3 (0x0528)
+#define AFE_SPDIFIN_DEBUG4 (0x052c)
+#define AFE_SPDIFIN_EC (0x0530)
+#define AFE_SPDIFIN_CKLOCK_CFG (0x0534)
+#define AFE_SPDIFIN_BR (0x053c)
+#define AFE_SPDIFIN_BR_DBG1 (0x0540)
+#define AFE_SPDIFIN_CKFBDIV (0x0544)
+#define AFE_SPDIFIN_INT_EXT (0x0548)
+#define AFE_SPDIFIN_INT_EXT2 (0x054c)
+#define SPDIFIN_FREQ_INFO (0x0550)
+#define SPDIFIN_FREQ_INFO_2 (0x0554)
+#define SPDIFIN_FREQ_INFO_3 (0x0558)
+#define SPDIFIN_FREQ_STATUS (0x055c)
+#define SPDIFIN_USERCODE1 (0x0560)
+#define SPDIFIN_USERCODE2 (0x0564)
+#define SPDIFIN_USERCODE3 (0x0568)
+#define SPDIFIN_USERCODE4 (0x056c)
+#define SPDIFIN_USERCODE5 (0x0570)
+#define SPDIFIN_USERCODE6 (0x0574)
+#define SPDIFIN_USERCODE7 (0x0578)
+#define SPDIFIN_USERCODE8 (0x057c)
+#define SPDIFIN_USERCODE9 (0x0580)
+#define SPDIFIN_USERCODE10 (0x0584)
+#define SPDIFIN_USERCODE11 (0x0588)
+#define SPDIFIN_USERCODE12 (0x058c)
+#define AFE_SPDIFIN_APLL_TUNER_CFG (0x0594)
+#define AFE_SPDIFIN_APLL_TUNER_CFG1 (0x0598)
+#define ASYS_TOP_CON (0x0600)
+#define AFE_LINEIN_APLL_TUNER_CFG (0x0610)
+#define AFE_LINEIN_APLL_TUNER_MON (0x0614)
+#define AFE_EARC_APLL_TUNER_CFG (0x0618)
+#define AFE_EARC_APLL_TUNER_MON (0x061c)
+#define PWR2_TOP_CON0 (0x0634)
+#define PWR2_TOP_CON1 (0x0638)
+#define PCM_INTF_CON1 (0x063c)
+#define PCM_INTF_CON2 (0x0640)
+#define AFE_CM0_CON (0x0660)
+#define AFE_CM1_CON (0x0664)
+#define AFE_CM2_CON (0x0668)
+#define AFE_CM0_MON (0x0670)
+#define AFE_CM1_MON (0x0674)
+#define AFE_CM2_MON (0x0678)
+#define AFE_MPHONE_MULTI_CON0 (0x06a4)
+#define AFE_MPHONE_MULTI_CON1 (0x06a8)
+#define AFE_MPHONE_MULTI_CON2 (0x06ac)
+#define AFE_MPHONE_MULTI_MON (0x06b0)
+#define AFE_MPHONE_MULTI_DET_REG_CON0 (0x06b4)
+#define AFE_MPHONE_MULTI_DET_REG_CON1 (0x06b8)
+#define AFE_MPHONE_MULTI_DET_REG_CON2 (0x06bc)
+#define AFE_MPHONE_MULTI_DET_REG_CON3 (0x06c0)
+#define AFE_MPHONE_MULTI_DET_MON0 (0x06c4)
+#define AFE_MPHONE_MULTI_DET_MON1 (0x06c8)
+#define AFE_MPHONE_MULTI_DET_MON2 (0x06d0)
+#define AFE_MPHONE_MULTI2_CON0 (0x06d4)
+#define AFE_MPHONE_MULTI2_CON1 (0x06d8)
+#define AFE_MPHONE_MULTI2_CON2 (0x06dc)
+#define AFE_MPHONE_MULTI2_MON (0x06e0)
+#define AFE_MPHONE_MULTI2_DET_REG_CON0 (0x06e4)
+#define AFE_MPHONE_MULTI2_DET_REG_CON1 (0x06e8)
+#define AFE_MPHONE_MULTI2_DET_REG_CON2 (0x06ec)
+#define AFE_MPHONE_MULTI2_DET_REG_CON3 (0x06f0)
+#define AFE_MPHONE_MULTI2_DET_MON0 (0x06f4)
+#define AFE_MPHONE_MULTI2_DET_MON1 (0x06f8)
+#define AFE_MPHONE_MULTI2_DET_MON2 (0x06fc)
+#define AFE_ADDA_IIR_COEF_02_01 (0x0700)
+#define AFE_ADDA_IIR_COEF_04_03 (0x0704)
+#define AFE_ADDA_IIR_COEF_06_05 (0x0708)
+#define AFE_ADDA_IIR_COEF_08_07 (0x070c)
+#define AFE_ADDA_IIR_COEF_10_09 (0x0710)
+#define AFE_ADDA_ULCF_CFG_02_01 (0x0714)
+#define AFE_ADDA_ULCF_CFG_04_03 (0x0718)
+#define AFE_ADDA_ULCF_CFG_06_05 (0x071c)
+#define AFE_ADDA_ULCF_CFG_08_07 (0x0720)
+#define AFE_ADDA_ULCF_CFG_10_09 (0x0724)
+#define AFE_ADDA_ULCF_CFG_12_11 (0x0728)
+#define AFE_ADDA_ULCF_CFG_14_13 (0x072c)
+#define AFE_ADDA_ULCF_CFG_16_15 (0x0730)
+#define AFE_ADDA_ULCF_CFG_18_17 (0x0734)
+#define AFE_ADDA_ULCF_CFG_20_19 (0x0738)
+#define AFE_ADDA_ULCF_CFG_22_21 (0x073c)
+#define AFE_ADDA_ULCF_CFG_24_23 (0x0740)
+#define AFE_ADDA_ULCF_CFG_26_25 (0x0744)
+#define AFE_ADDA_ULCF_CFG_28_27 (0x0748)
+#define AFE_ADDA_ULCF_CFG_30_29 (0x074c)
+#define AFE_ADDA6_IIR_COEF_02_01 (0x0750)
+#define AFE_ADDA6_IIR_COEF_04_03 (0x0754)
+#define AFE_ADDA6_IIR_COEF_06_05 (0x0758)
+#define AFE_ADDA6_IIR_COEF_08_07 (0x075c)
+#define AFE_ADDA6_IIR_COEF_10_09 (0x0760)
+#define AFE_ADDA6_ULCF_CFG_02_01 (0x0764)
+#define AFE_ADDA6_ULCF_CFG_04_03 (0x0768)
+#define AFE_ADDA6_ULCF_CFG_06_05 (0x076c)
+#define AFE_ADDA6_ULCF_CFG_08_07 (0x0770)
+#define AFE_ADDA6_ULCF_CFG_10_09 (0x0774)
+#define AFE_ADDA6_ULCF_CFG_12_11 (0x0778)
+#define AFE_ADDA6_ULCF_CFG_14_13 (0x077c)
+#define AFE_ADDA6_ULCF_CFG_16_15 (0x0780)
+#define AFE_ADDA6_ULCF_CFG_18_17 (0x0784)
+#define AFE_ADDA6_ULCF_CFG_20_19 (0x0788)
+#define AFE_ADDA6_ULCF_CFG_22_21 (0x078c)
+#define AFE_ADDA6_ULCF_CFG_24_23 (0x0790)
+#define AFE_ADDA6_ULCF_CFG_26_25 (0x0794)
+#define AFE_ADDA6_ULCF_CFG_28_27 (0x0798)
+#define AFE_ADDA6_ULCF_CFG_30_29 (0x079c)
+#define AFE_ADDA_MTKAIF_CFG0 (0x07a0)
+#define AFE_ADDA_MTKAIF_SYNCWORD_CFG (0x07a8)
+#define AFE_ADDA_MTKAIF_RX_CFG0 (0x07b4)
+#define AFE_ADDA_MTKAIF_RX_CFG1 (0x07b8)
+#define AFE_ADDA_MTKAIF_RX_CFG2 (0x07bc)
+#define AFE_ADDA_MTKAIF_MON0 (0x07c8)
+#define AFE_ADDA_MTKAIF_MON1 (0x07cc)
+#define AFE_AUD_PAD_TOP (0x07d4)
+#define AFE_ADDA6_MTKAIF_MON0 (0x07d8)
+#define AFE_ADDA6_MTKAIF_MON1 (0x07dc)
+#define AFE_ADDA6_MTKAIF_CFG0 (0x07e0)
+#define AFE_ADDA6_MTKAIF_RX_CFG0 (0x07e4)
+#define AFE_ADDA6_MTKAIF_RX_CFG1 (0x07e8)
+#define AFE_ADDA6_MTKAIF_RX_CFG2 (0x07ec)
+#define AFE_ADDA6_TOP_CON0 (0x07f0)
+#define AFE_ADDA6_UL_SRC_CON0 (0x07f4)
+#define AFE_ADDA6_UL_SRC_CON1 (0x07f8)
+#define AFE_ADDA6_SRC_DEBUG (0x0800)
+#define AFE_ADDA6_SRC_DEBUG_MON0 (0x0804)
+#define AFE_ADDA6_UL_SRC_MON0 (0x0818)
+#define AFE_ADDA6_UL_SRC_MON1 (0x081c)
+#define AFE_CONN0_5 (0x0830)
+#define AFE_CONN1_5 (0x0834)
+#define AFE_CONN2_5 (0x0838)
+#define AFE_CONN3_5 (0x083c)
+#define AFE_CONN4_5 (0x0840)
+#define AFE_CONN5_5 (0x0844)
+#define AFE_CONN6_5 (0x0848)
+#define AFE_CONN7_5 (0x084c)
+#define AFE_CONN8_5 (0x0850)
+#define AFE_CONN9_5 (0x0854)
+#define AFE_CONN10_5 (0x0858)
+#define AFE_CONN11_5 (0x085c)
+#define AFE_CONN12_5 (0x0860)
+#define AFE_CONN13_5 (0x0864)
+#define AFE_CONN14_5 (0x0868)
+#define AFE_CONN15_5 (0x086c)
+#define AFE_CONN16_5 (0x0870)
+#define AFE_CONN17_5 (0x0874)
+#define AFE_CONN18_5 (0x0878)
+#define AFE_CONN19_5 (0x087c)
+#define AFE_CONN20_5 (0x0880)
+#define AFE_CONN21_5 (0x0884)
+#define AFE_CONN22_5 (0x0888)
+#define AFE_CONN23_5 (0x088c)
+#define AFE_CONN24_5 (0x0890)
+#define AFE_CONN25_5 (0x0894)
+#define AFE_CONN26_5 (0x0898)
+#define AFE_CONN27_5 (0x089c)
+#define AFE_CONN28_5 (0x08a0)
+#define AFE_CONN29_5 (0x08a4)
+#define AFE_CONN30_5 (0x08a8)
+#define AFE_CONN31_5 (0x08ac)
+#define AFE_CONN32_5 (0x08b0)
+#define AFE_CONN33_5 (0x08b4)
+#define AFE_CONN34_5 (0x08b8)
+#define AFE_CONN35_5 (0x08bc)
+#define AFE_CONN36_5 (0x08c0)
+#define AFE_CONN37_5 (0x08c4)
+#define AFE_CONN38_5 (0x08c8)
+#define AFE_CONN39_5 (0x08cc)
+#define AFE_CONN40_5 (0x08d0)
+#define AFE_CONN41_5 (0x08d4)
+#define AFE_CONN42_5 (0x08d8)
+#define AFE_CONN43_5 (0x08dc)
+#define AFE_CONN44_5 (0x08e0)
+#define AFE_CONN45_5 (0x08e4)
+#define AFE_CONN46_5 (0x08e8)
+#define AFE_CONN47_5 (0x08ec)
+#define AFE_CONN48_5 (0x08f0)
+#define AFE_CONN49_5 (0x08f4)
+#define AFE_CONN50_5 (0x08f8)
+#define AFE_CONN51_5 (0x08fc)
+#define AFE_CONN52_5 (0x0900)
+#define AFE_CONN53_5 (0x0904)
+#define AFE_CONN54_5 (0x0908)
+#define AFE_CONN55_5 (0x090c)
+#define AFE_CONN56_5 (0x0910)
+#define AFE_CONN57_5 (0x0914)
+#define AFE_CONN58_5 (0x0918)
+#define AFE_CONN59_5 (0x091c)
+#define AFE_CONN60_5 (0x0920)
+#define AFE_CONN61_5 (0x0924)
+#define AFE_CONN62_5 (0x0928)
+#define AFE_CONN63_5 (0x092c)
+#define AFE_CONN64_5 (0x0930)
+#define AFE_CONN65_5 (0x0934)
+#define AFE_CONN66_5 (0x0938)
+#define AFE_CONN67_5 (0x093c)
+#define AFE_CONN68_5 (0x0940)
+#define AFE_CONN69_5 (0x0944)
+#define AFE_CONN70_5 (0x0948)
+#define AFE_CONN71_5 (0x094c)
+#define AFE_CONN72_5 (0x0950)
+#define AFE_CONN73_5 (0x0954)
+#define AFE_CONN74_5 (0x0958)
+#define AFE_CONN75_5 (0x095c)
+#define AFE_CONN76_5 (0x0960)
+#define AFE_CONN77_5 (0x0964)
+#define AFE_CONN78_5 (0x0968)
+#define AFE_CONN79_5 (0x096c)
+#define AFE_CONN80_5 (0x0970)
+#define AFE_CONN81_5 (0x0974)
+#define AFE_CONN82_5 (0x0978)
+#define AFE_CONN83_5 (0x097c)
+#define AFE_CONN84_5 (0x0980)
+#define AFE_CONN85_5 (0x0984)
+#define AFE_CONN86_5 (0x0988)
+#define AFE_CONN87_5 (0x098c)
+#define AFE_CONN88_5 (0x0990)
+#define AFE_CONN89_5 (0x0994)
+#define AFE_CONN90_5 (0x0998)
+#define AFE_CONN91_5 (0x099c)
+#define AFE_CONN92_5 (0x09a0)
+#define AFE_CONN93_5 (0x09a4)
+#define AFE_CONN94_5 (0x09a8)
+#define AFE_CONN95_5 (0x09ac)
+#define AFE_CONN96_5 (0x09b0)
+#define AFE_CONN97_5 (0x09b4)
+#define AFE_CONN98_5 (0x09b8)
+#define AFE_CONN99_5 (0x09bc)
+#define AFE_CONN100_5 (0x09c0)
+#define AFE_CONN101_5 (0x09c4)
+#define AFE_CONN102_5 (0x09c8)
+#define AFE_CONN103_5 (0x09cc)
+#define AFE_CONN104_5 (0x09d0)
+#define AFE_CONN105_5 (0x09d4)
+#define AFE_CONN106_5 (0x09d8)
+#define AFE_CONN107_5 (0x09dc)
+#define AFE_CONN108_5 (0x09e0)
+#define AFE_CONN109_5 (0x09e4)
+#define AFE_CONN110_5 (0x09e8)
+#define AFE_CONN111_5 (0x09ec)
+#define AFE_CONN112_5 (0x09f0)
+#define AFE_CONN113_5 (0x09f4)
+#define AFE_CONN114_5 (0x09f8)
+#define AFE_CONN115_5 (0x09fc)
+#define AFE_CONN116_5 (0x0a00)
+#define AFE_CONN117_5 (0x0a04)
+#define AFE_CONN118_5 (0x0a08)
+#define AFE_CONN119_5 (0x0a0c)
+#define AFE_CONN120_5 (0x0a10)
+#define AFE_CONN121_5 (0x0a14)
+#define AFE_CONN122_5 (0x0a18)
+#define AFE_CONN123_5 (0x0a1c)
+#define AFE_CONN124_5 (0x0a20)
+#define AFE_CONN125_5 (0x0a24)
+#define AFE_CONN126_5 (0x0a28)
+#define AFE_CONN127_5 (0x0a2c)
+#define AFE_CONN128_5 (0x0a30)
+#define AFE_CONN129_5 (0x0a34)
+#define AFE_CONN130_5 (0x0a38)
+#define AFE_CONN131_5 (0x0a3c)
+#define AFE_CONN132_5 (0x0a40)
+#define AFE_CONN133_5 (0x0a44)
+#define AFE_CONN134_5 (0x0a48)
+#define AFE_CONN135_5 (0x0a4c)
+#define AFE_CONN136_5 (0x0a50)
+#define AFE_CONN137_5 (0x0a54)
+#define AFE_CONN138_5 (0x0a58)
+#define AFE_CONN139_5 (0x0a5c)
+#define AFE_CONN_RS_5 (0x0a60)
+#define AFE_CONN_DI_5 (0x0a64)
+#define AFE_CONN_16BIT_5 (0x0a68)
+#define AFE_CONN_24BIT_5 (0x0a6c)
+#define AFE_ASRC11_NEW_CON0 (0x0d80)
+#define AFE_ASRC11_NEW_CON1 (0x0d84)
+#define AFE_ASRC11_NEW_CON2 (0x0d88)
+#define AFE_ASRC11_NEW_CON3 (0x0d8c)
+#define AFE_ASRC11_NEW_CON4 (0x0d90)
+#define AFE_ASRC11_NEW_CON5 (0x0d94)
+#define AFE_ASRC11_NEW_CON6 (0x0d98)
+#define AFE_ASRC11_NEW_CON7 (0x0d9c)
+#define AFE_ASRC11_NEW_CON8 (0x0da0)
+#define AFE_ASRC11_NEW_CON9 (0x0da4)
+#define AFE_ASRC11_NEW_CON10 (0x0da8)
+#define AFE_ASRC11_NEW_CON11 (0x0dac)
+#define AFE_ASRC11_NEW_CON13 (0x0db4)
+#define AFE_ASRC11_NEW_CON14 (0x0db8)
+#define AFE_ASRC12_NEW_CON0 (0x0dc0)
+#define AFE_ASRC12_NEW_CON1 (0x0dc4)
+#define AFE_ASRC12_NEW_CON2 (0x0dc8)
+#define AFE_ASRC12_NEW_CON3 (0x0dcc)
+#define AFE_ASRC12_NEW_CON4 (0x0dd0)
+#define AFE_ASRC12_NEW_CON5 (0x0dd4)
+#define AFE_ASRC12_NEW_CON6 (0x0dd8)
+#define AFE_ASRC12_NEW_CON7 (0x0ddc)
+#define AFE_ASRC12_NEW_CON8 (0x0de0)
+#define AFE_ASRC12_NEW_CON9 (0x0de4)
+#define AFE_ASRC12_NEW_CON10 (0x0de8)
+#define AFE_ASRC12_NEW_CON11 (0x0dec)
+#define AFE_ASRC12_NEW_CON13 (0x0df4)
+#define AFE_ASRC12_NEW_CON14 (0x0df8)
+#define AFE_LRCK_CNT (0x1018)
+#define AFE_DAC_CON0 (0x1200)
+#define AFE_DAC_CON1 (0x1204)
+#define AFE_DAC_CON2 (0x1208)
+#define AFE_DAC_MON0 (0x1218)
+#define AFE_DL2_BASE (0x1250)
+#define AFE_DL2_CUR (0x1254)
+#define AFE_DL2_END (0x1258)
+#define AFE_DL2_CON0 (0x125c)
+#define AFE_DL3_BASE (0x1260)
+#define AFE_DL3_CUR (0x1264)
+#define AFE_DL3_END (0x1268)
+#define AFE_DL3_CON0 (0x126c)
+#define AFE_DL6_BASE (0x1290)
+#define AFE_DL6_CUR (0x1294)
+#define AFE_DL6_END (0x1298)
+#define AFE_DL6_CON0 (0x129c)
+#define AFE_DL7_BASE (0x12a0)
+#define AFE_DL7_CUR (0x12a4)
+#define AFE_DL7_END (0x12a8)
+#define AFE_DL7_CON0 (0x12ac)
+#define AFE_DL8_BASE (0x12b0)
+#define AFE_DL8_CUR (0x12b4)
+#define AFE_DL8_END (0x12b8)
+#define AFE_DL8_CON0 (0x12bc)
+#define AFE_DL10_BASE (0x12d0)
+#define AFE_DL10_CUR (0x12d4)
+#define AFE_DL10_END (0x12d8)
+#define AFE_DL10_CON0 (0x12dc)
+#define AFE_DL11_BASE (0x12e0)
+#define AFE_DL11_CUR (0x12e4)
+#define AFE_DL11_END (0x12e8)
+#define AFE_DL11_CON0 (0x12ec)
+#define AFE_UL1_BASE (0x1300)
+#define AFE_UL1_CUR (0x1304)
+#define AFE_UL1_END (0x1308)
+#define AFE_UL1_CON0 (0x130c)
+#define AFE_UL2_BASE (0x1310)
+#define AFE_UL2_CUR (0x1314)
+#define AFE_UL2_END (0x1318)
+#define AFE_UL2_CON0 (0x131c)
+#define AFE_UL3_BASE (0x1320)
+#define AFE_UL3_CUR (0x1324)
+#define AFE_UL3_END (0x1328)
+#define AFE_UL3_CON0 (0x132c)
+#define AFE_UL4_BASE (0x1330)
+#define AFE_UL4_CUR (0x1334)
+#define AFE_UL4_END (0x1338)
+#define AFE_UL4_CON0 (0x133c)
+#define AFE_UL5_BASE (0x1340)
+#define AFE_UL5_CUR (0x1344)
+#define AFE_UL5_END (0x1348)
+#define AFE_UL5_CON0 (0x134c)
+#define AFE_UL6_BASE (0x1350)
+#define AFE_UL6_CUR (0x1354)
+#define AFE_UL6_END (0x1358)
+#define AFE_UL6_CON0 (0x135c)
+#define AFE_UL8_BASE (0x1370)
+#define AFE_UL8_CUR (0x1374)
+#define AFE_UL8_END (0x1378)
+#define AFE_UL8_CON0 (0x137c)
+#define AFE_UL9_BASE (0x1380)
+#define AFE_UL9_CUR (0x1384)
+#define AFE_UL9_END (0x1388)
+#define AFE_UL9_CON0 (0x138c)
+#define AFE_UL10_BASE (0x13d0)
+#define AFE_UL10_CUR (0x13d4)
+#define AFE_UL10_END (0x13d8)
+#define AFE_UL10_CON0 (0x13dc)
+#define AFE_DL8_CHK_SUM1 (0x1400)
+#define AFE_DL8_CHK_SUM2 (0x1404)
+#define AFE_DL8_CHK_SUM3 (0x1408)
+#define AFE_DL8_CHK_SUM4 (0x140c)
+#define AFE_DL8_CHK_SUM5 (0x1410)
+#define AFE_DL8_CHK_SUM6 (0x1414)
+#define AFE_DL10_CHK_SUM1 (0x1418)
+#define AFE_DL10_CHK_SUM2 (0x141c)
+#define AFE_DL10_CHK_SUM3 (0x1420)
+#define AFE_DL10_CHK_SUM4 (0x1424)
+#define AFE_DL10_CHK_SUM5 (0x1428)
+#define AFE_DL10_CHK_SUM6 (0x142c)
+#define AFE_DL11_CHK_SUM1 (0x1430)
+#define AFE_DL11_CHK_SUM2 (0x1434)
+#define AFE_DL11_CHK_SUM3 (0x1438)
+#define AFE_DL11_CHK_SUM4 (0x143c)
+#define AFE_DL11_CHK_SUM5 (0x1440)
+#define AFE_DL11_CHK_SUM6 (0x1444)
+#define AFE_UL1_CHK_SUM1 (0x1450)
+#define AFE_UL1_CHK_SUM2 (0x1454)
+#define AFE_UL2_CHK_SUM1 (0x1458)
+#define AFE_UL2_CHK_SUM2 (0x145c)
+#define AFE_UL3_CHK_SUM1 (0x1460)
+#define AFE_UL3_CHK_SUM2 (0x1464)
+#define AFE_UL4_CHK_SUM1 (0x1468)
+#define AFE_UL4_CHK_SUM2 (0x146c)
+#define AFE_UL5_CHK_SUM1 (0x1470)
+#define AFE_UL5_CHK_SUM2 (0x1474)
+#define AFE_UL6_CHK_SUM1 (0x1478)
+#define AFE_UL6_CHK_SUM2 (0x147c)
+#define AFE_UL8_CHK_SUM1 (0x1488)
+#define AFE_UL8_CHK_SUM2 (0x148c)
+#define AFE_DL2_CHK_SUM1 (0x14a0)
+#define AFE_DL2_CHK_SUM2 (0x14a4)
+#define AFE_DL3_CHK_SUM1 (0x14b0)
+#define AFE_DL3_CHK_SUM2 (0x14b4)
+#define AFE_DL6_CHK_SUM1 (0x14e0)
+#define AFE_DL6_CHK_SUM2 (0x14e4)
+#define AFE_DL7_CHK_SUM1 (0x14f0)
+#define AFE_DL7_CHK_SUM2 (0x14f4)
+#define AFE_UL9_CHK_SUM1 (0x1528)
+#define AFE_UL9_CHK_SUM2 (0x152c)
+#define AFE_BUS_MON1 (0x1540)
+#define UL1_MOD2AGT_CNT_LAT (0x1568)
+#define UL2_MOD2AGT_CNT_LAT (0x156c)
+#define UL3_MOD2AGT_CNT_LAT (0x1570)
+#define UL4_MOD2AGT_CNT_LAT (0x1574)
+#define UL5_MOD2AGT_CNT_LAT (0x1578)
+#define UL6_MOD2AGT_CNT_LAT (0x157c)
+#define UL8_MOD2AGT_CNT_LAT (0x1588)
+#define UL9_MOD2AGT_CNT_LAT (0x158c)
+#define UL10_MOD2AGT_CNT_LAT (0x1590)
+#define AFE_MEMIF_AGENT_FS_CON0 (0x15a0)
+#define AFE_MEMIF_AGENT_FS_CON1 (0x15a4)
+#define AFE_MEMIF_AGENT_FS_CON2 (0x15a8)
+#define AFE_MEMIF_AGENT_FS_CON3 (0x15ac)
+#define AFE_MEMIF_BURST_CFG (0x1600)
+#define AFE_MEMIF_BUF_FULL_MON (0x1610)
+#define AFE_MEMIF_BUF_MON1 (0x161c)
+#define AFE_MEMIF_BUF_MON3 (0x1624)
+#define AFE_MEMIF_BUF_MON4 (0x1628)
+#define AFE_MEMIF_BUF_MON5 (0x162c)
+#define AFE_MEMIF_BUF_MON6 (0x1630)
+#define AFE_MEMIF_BUF_MON7 (0x1634)
+#define AFE_MEMIF_BUF_MON8 (0x1638)
+#define AFE_MEMIF_BUF_MON9 (0x163c)
+#define AFE_MEMIF_BUF_MON10 (0x1640)
+#define DL2_AGENT2MODULE_CNT (0x1678)
+#define DL3_AGENT2MODULE_CNT (0x167c)
+#define DL6_AGENT2MODULE_CNT (0x1688)
+#define DL7_AGENT2MODULE_CNT (0x168c)
+#define DL8_AGENT2MODULE_CNT (0x1690)
+#define DL10_AGENT2MODULE_CNT (0x1698)
+#define DL11_AGENT2MODULE_CNT (0x169c)
+#define UL1_MODULE2AGENT_CNT (0x16a0)
+#define UL2_MODULE2AGENT_CNT (0x16a4)
+#define UL3_MODULE2AGENT_CNT (0x16a8)
+#define UL4_MODULE2AGENT_CNT (0x16ac)
+#define UL5_MODULE2AGENT_CNT (0x16b0)
+#define UL6_MODULE2AGENT_CNT (0x16b4)
+#define UL8_MODULE2AGENT_CNT (0x16bc)
+#define UL9_MODULE2AGENT_CNT (0x16c0)
+#define UL10_MODULE2AGENT_CNT (0x16c4)
+#define AFE_SECURE_CON2 (0x1798)
+#define AFE_SECURE_CON1 (0x179c)
+#define AFE_SECURE_CON (0x17a0)
+#define AFE_SRAM_BOUND (0x17a4)
+#define AFE_SE_SECURE_CON (0x17a8)
+#define AFE_SECURE_MASK_LOOPBACK (0x17bc)
+#define AFE_SECURE_SIDEBAND0 (0x1908)
+#define AFE_SECURE_SIDEBAND1 (0x190c)
+#define AFE_SECURE_SIDEBAND2 (0x1910)
+#define AFE_SECURE_SIDEBAND3 (0x1914)
+#define AFE_SECURE_MASK_BASE_ADR_MSB (0x1920)
+#define AFE_SECURE_MASK_END_ADR_MSB (0x1924)
+#define AFE_NORMAL_BASE_ADR_MSB (0x192c)
+#define AFE_NORMAL_END_ADR_MSB (0x1930)
+#define AFE_SECURE_MASK_LOOPBACK0 (0x1940)
+#define AFE_SECURE_MASK_LOOPBACK1 (0x1944)
+#define AFE_SECURE_MASK_LOOPBACK2 (0x1948)
+#define AFE_LOOPBACK_CFG0 (0x1950)
+#define AFE_LOOPBACK_CFG1 (0x1954)
+#define AFE_LOOPBACK_CFG2 (0x1958)
+#define AFE_DMIC0_UL_SRC_CON0 (0x1a00)
+#define AFE_DMIC0_UL_SRC_CON1 (0x1a04)
+#define AFE_DMIC0_SRC_DEBUG (0x1a08)
+#define AFE_DMIC0_SRC_DEBUG_MON0 (0x1a0c)
+#define AFE_DMIC0_UL_SRC_MON0 (0x1a10)
+#define AFE_DMIC0_UL_SRC_MON1 (0x1a14)
+#define AFE_DMIC0_IIR_COEF_02_01 (0x1a18)
+#define AFE_DMIC0_IIR_COEF_04_03 (0x1a1c)
+#define AFE_DMIC0_IIR_COEF_06_05 (0x1a20)
+#define AFE_DMIC0_IIR_COEF_08_07 (0x1a24)
+#define AFE_DMIC0_IIR_COEF_10_09 (0x1a28)
+#define AFE_DMIC1_UL_SRC_CON0 (0x1a68)
+#define AFE_DMIC1_UL_SRC_CON1 (0x1a6c)
+#define AFE_DMIC1_SRC_DEBUG (0x1a70)
+#define AFE_DMIC1_SRC_DEBUG_MON0 (0x1a74)
+#define AFE_DMIC1_UL_SRC_MON0 (0x1a78)
+#define AFE_DMIC1_UL_SRC_MON1 (0x1a7c)
+#define AFE_DMIC1_IIR_COEF_02_01 (0x1a80)
+#define AFE_DMIC1_IIR_COEF_04_03 (0x1a84)
+#define AFE_DMIC1_IIR_COEF_06_05 (0x1a88)
+#define AFE_DMIC1_IIR_COEF_08_07 (0x1a8c)
+#define AFE_DMIC1_IIR_COEF_10_09 (0x1a90)
+#define AFE_DMIC2_UL_SRC_CON0 (0x1ad0)
+#define AFE_DMIC2_UL_SRC_CON1 (0x1ad4)
+#define AFE_DMIC2_SRC_DEBUG (0x1ad8)
+#define AFE_DMIC2_SRC_DEBUG_MON0 (0x1adc)
+#define AFE_DMIC2_UL_SRC_MON0 (0x1ae0)
+#define AFE_DMIC2_UL_SRC_MON1 (0x1ae4)
+#define AFE_DMIC2_IIR_COEF_02_01 (0x1ae8)
+#define AFE_DMIC2_IIR_COEF_04_03 (0x1aec)
+#define AFE_DMIC2_IIR_COEF_06_05 (0x1af0)
+#define AFE_DMIC2_IIR_COEF_08_07 (0x1af4)
+#define AFE_DMIC2_IIR_COEF_10_09 (0x1af8)
+#define AFE_DMIC3_UL_SRC_CON0 (0x1b38)
+#define AFE_DMIC3_UL_SRC_CON1 (0x1b3c)
+#define AFE_DMIC3_SRC_DEBUG (0x1b40)
+#define AFE_DMIC3_SRC_DEBUG_MON0 (0x1b44)
+#define AFE_DMIC3_UL_SRC_MON0 (0x1b48)
+#define AFE_DMIC3_UL_SRC_MON1 (0x1b4c)
+#define AFE_DMIC3_IIR_COEF_02_01 (0x1b50)
+#define AFE_DMIC3_IIR_COEF_04_03 (0x1b54)
+#define AFE_DMIC3_IIR_COEF_06_05 (0x1b58)
+#define AFE_DMIC3_IIR_COEF_08_07 (0x1b5c)
+#define AFE_DMIC3_IIR_COEF_10_09 (0x1b60)
+#define DMIC_BYPASS_HW_GAIN (0x1bf0)
+#define DMIC_GAIN1_CON0 (0x1c00)
+#define DMIC_GAIN1_CON1 (0x1c04)
+#define DMIC_GAIN1_CON2 (0x1c08)
+#define DMIC_GAIN1_CON3 (0x1c0c)
+#define DMIC_GAIN1_CUR (0x1c10)
+#define DMIC_GAIN2_CON0 (0x1c20)
+#define DMIC_GAIN2_CON1 (0x1c24)
+#define DMIC_GAIN2_CON2 (0x1c28)
+#define DMIC_GAIN2_CON3 (0x1c2c)
+#define DMIC_GAIN2_CUR (0x1c30)
+#define DMIC_GAIN3_CON0 (0x1c40)
+#define DMIC_GAIN3_CON1 (0x1c44)
+#define DMIC_GAIN3_CON2 (0x1c48)
+#define DMIC_GAIN3_CON3 (0x1c4c)
+#define DMIC_GAIN3_CUR (0x1c50)
+#define DMIC_GAIN4_CON0 (0x1c60)
+#define DMIC_GAIN4_CON1 (0x1c64)
+#define DMIC_GAIN4_CON2 (0x1c68)
+#define DMIC_GAIN4_CON3 (0x1c6c)
+#define DMIC_GAIN4_CUR (0x1c70)
+#define ETDM_OUT1_DSD_FADE_CON (0x2260)
+#define ETDM_OUT1_DSD_FADE_CON1 (0x2264)
+#define ETDM_OUT3_DSD_FADE_CON (0x2280)
+#define ETDM_OUT3_DSD_FADE_CON1 (0x2284)
+#define ETDM_IN1_AFIFO_CON (0x2294)
+#define ETDM_IN2_AFIFO_CON (0x2298)
+#define ETDM_IN1_MONITOR (0x22c0)
+#define ETDM_IN2_MONITOR (0x22c4)
+#define ETDM_OUT1_MONITOR (0x22d0)
+#define ETDM_OUT2_MONITOR (0x22d4)
+#define ETDM_OUT3_MONITOR (0x22d8)
+#define ETDM_COWORK_SEC_CON0 (0x22e0)
+#define ETDM_COWORK_SEC_CON1 (0x22e4)
+#define ETDM_COWORK_SEC_CON2 (0x22e8)
+#define ETDM_COWORK_SEC_CON3 (0x22ec)
+#define ETDM_COWORK_CON0 (0x22f0)
+#define ETDM_COWORK_CON1 (0x22f4)
+#define ETDM_COWORK_CON2 (0x22f8)
+#define ETDM_COWORK_CON3 (0x22fc)
+#define ETDM_IN1_CON0 (0x2300)
+#define ETDM_IN1_CON1 (0x2304)
+#define ETDM_IN1_CON2 (0x2308)
+#define ETDM_IN1_CON3 (0x230c)
+#define ETDM_IN1_CON4 (0x2310)
+#define ETDM_IN1_CON5 (0x2314)
+#define ETDM_IN1_CON6 (0x2318)
+#define ETDM_IN1_CON7 (0x231c)
+#define ETDM_IN2_CON0 (0x2320)
+#define ETDM_IN2_CON1 (0x2324)
+#define ETDM_IN2_CON2 (0x2328)
+#define ETDM_IN2_CON3 (0x232c)
+#define ETDM_IN2_CON4 (0x2330)
+#define ETDM_IN2_CON5 (0x2334)
+#define ETDM_IN2_CON6 (0x2338)
+#define ETDM_IN2_CON7 (0x233c)
+#define ETDM_OUT1_CON0 (0x2380)
+#define ETDM_OUT1_CON1 (0x2384)
+#define ETDM_OUT1_CON2 (0x2388)
+#define ETDM_OUT1_CON3 (0x238c)
+#define ETDM_OUT1_CON4 (0x2390)
+#define ETDM_OUT1_CON5 (0x2394)
+#define ETDM_OUT1_CON6 (0x2398)
+#define ETDM_OUT1_CON7 (0x239c)
+#define ETDM_OUT2_CON0 (0x23a0)
+#define ETDM_OUT2_CON1 (0x23a4)
+#define ETDM_OUT2_CON2 (0x23a8)
+#define ETDM_OUT2_CON3 (0x23ac)
+#define ETDM_OUT2_CON4 (0x23b0)
+#define ETDM_OUT2_CON5 (0x23b4)
+#define ETDM_OUT2_CON6 (0x23b8)
+#define ETDM_OUT2_CON7 (0x23bc)
+#define ETDM_OUT3_CON0 (0x23c0)
+#define ETDM_OUT3_CON1 (0x23c4)
+#define ETDM_OUT3_CON2 (0x23c8)
+#define ETDM_OUT3_CON3 (0x23cc)
+#define ETDM_OUT3_CON4 (0x23d0)
+#define ETDM_OUT3_CON5 (0x23d4)
+#define ETDM_OUT3_CON6 (0x23d8)
+#define ETDM_OUT3_CON7 (0x23dc)
+#define ETDM_OUT3_CON8 (0x23e0)
+#define ETDM_OUT1_CON8 (0x23e4)
+#define ETDM_OUT2_CON8 (0x23e8)
+#define GASRC_TIMING_CON0 (0x2414)
+#define GASRC_TIMING_CON1 (0x2418)
+#define GASRC_TIMING_CON2 (0x241c)
+#define GASRC_TIMING_CON3 (0x2420)
+#define GASRC_TIMING_CON4 (0x2424)
+#define GASRC_TIMING_CON5 (0x2428)
+#define GASRC_TIMING_CON6 (0x242c)
+#define GASRC_TIMING_CON7 (0x2430)
+#define A3_A4_TIMING_SEL0 (0x2440)
+#define A3_A4_TIMING_SEL1 (0x2444)
+#define A3_A4_TIMING_SEL2 (0x2448)
+#define A3_A4_TIMING_SEL3 (0x244c)
+#define A3_A4_TIMING_SEL4 (0x2450)
+#define A3_A4_TIMING_SEL5 (0x2454)
+#define A3_A4_TIMING_SEL6 (0x2458)
+#define ASYS_TOP_DEBUG (0x2500)
+#define AFE_DPTX_CON (0x2558)
+#define AFE_DPTX_MON (0x255c)
+#define AFE_ADDA_DL_SRC2_CON0 (0x2d00)
+#define AFE_ADDA_DL_SRC2_CON1 (0x2d04)
+#define AFE_ADDA_TOP_CON0 (0x2d0c)
+#define AFE_ADDA_UL_DL_CON0 (0x2d10)
+#define AFE_ADDA_SRC_DEBUG (0x2d14)
+#define AFE_ADDA_SRC_DEBUG_MON0 (0x2d18)
+#define AFE_ADDA_SRC_DEBUG_MON1 (0x2d20)
+#define AFE_ADDA_PREDIS_CON0 (0x2d24)
+#define AFE_ADDA_PREDIS_CON1 (0x2d28)
+#define AFE_ADDA_PREDIS_CON2 (0x2d2c)
+#define AFE_ADDA_PREDIS_CON3 (0x2d30)
+#define AFE_ADDA_DL_SDM_DCCOMP_CON (0x2d34)
+#define AFE_ADDA_DL_SDM_TEST (0x2d38)
+#define AFE_ADDA_DL_DC_COMP_CFG0 (0x2d3c)
+#define AFE_ADDA_DL_DC_COMP_CFG1 (0x2d40)
+#define AFE_ADDA_DL_SDM_FIFO_MON (0x2d44)
+#define AFE_ADDA_DL_SRC_LCH_MON (0x2d50)
+#define AFE_ADDA_DL_SRC_RCH_MON (0x2d54)
+#define AFE_ADDA_DL_SDM_OUT_MON (0x2d58)
+#define AFE_ADDA_DL_SDM_DITHER_CON (0x2d5c)
+#define AFE_ADDA_DL_SDM_AUTO_RESET_CON (0x2d60)
+#define AFE_ADDA_UL_SRC_CON0 (0x2e3c)
+#define AFE_ADDA_UL_SRC_CON1 (0x2e40)
+#define AFE_CONN0 (0x3000)
+#define AFE_CONN0_1 (0x3004)
+#define AFE_CONN0_2 (0x3008)
+#define AFE_CONN0_3 (0x300c)
+#define AFE_CONN0_4 (0x3010)
+#define AFE_CONN1 (0x3014)
+#define AFE_CONN1_1 (0x3018)
+#define AFE_CONN1_2 (0x301c)
+#define AFE_CONN1_3 (0x3020)
+#define AFE_CONN1_4 (0x3024)
+#define AFE_CONN2 (0x3028)
+#define AFE_CONN2_1 (0x302c)
+#define AFE_CONN2_2 (0x3030)
+#define AFE_CONN2_3 (0x3034)
+#define AFE_CONN2_4 (0x3038)
+#define AFE_CONN3 (0x303c)
+#define AFE_CONN3_1 (0x3040)
+#define AFE_CONN3_2 (0x3044)
+#define AFE_CONN3_3 (0x3048)
+#define AFE_CONN3_4 (0x304c)
+#define AFE_CONN4 (0x3050)
+#define AFE_CONN4_1 (0x3054)
+#define AFE_CONN4_2 (0x3058)
+#define AFE_CONN4_3 (0x305c)
+#define AFE_CONN4_4 (0x3060)
+#define AFE_CONN5 (0x3064)
+#define AFE_CONN5_1 (0x3068)
+#define AFE_CONN5_2 (0x306c)
+#define AFE_CONN5_3 (0x3070)
+#define AFE_CONN5_4 (0x3074)
+#define AFE_CONN6 (0x3078)
+#define AFE_CONN6_1 (0x307c)
+#define AFE_CONN6_2 (0x3080)
+#define AFE_CONN6_3 (0x3084)
+#define AFE_CONN6_4 (0x3088)
+#define AFE_CONN7 (0x308c)
+#define AFE_CONN7_1 (0x3090)
+#define AFE_CONN7_2 (0x3094)
+#define AFE_CONN7_3 (0x3098)
+#define AFE_CONN7_4 (0x309c)
+#define AFE_CONN8 (0x30a0)
+#define AFE_CONN8_1 (0x30a4)
+#define AFE_CONN8_2 (0x30a8)
+#define AFE_CONN8_3 (0x30ac)
+#define AFE_CONN8_4 (0x30b0)
+#define AFE_CONN9 (0x30b4)
+#define AFE_CONN9_1 (0x30b8)
+#define AFE_CONN9_2 (0x30bc)
+#define AFE_CONN9_3 (0x30c0)
+#define AFE_CONN9_4 (0x30c4)
+#define AFE_CONN10 (0x30c8)
+#define AFE_CONN10_1 (0x30cc)
+#define AFE_CONN10_2 (0x30d0)
+#define AFE_CONN10_3 (0x30d4)
+#define AFE_CONN10_4 (0x30d8)
+#define AFE_CONN11 (0x30dc)
+#define AFE_CONN11_1 (0x30e0)
+#define AFE_CONN11_2 (0x30e4)
+#define AFE_CONN11_3 (0x30e8)
+#define AFE_CONN11_4 (0x30ec)
+#define AFE_CONN12 (0x30f0)
+#define AFE_CONN12_1 (0x30f4)
+#define AFE_CONN12_2 (0x30f8)
+#define AFE_CONN12_3 (0x30fc)
+#define AFE_CONN12_4 (0x3100)
+#define AFE_CONN13 (0x3104)
+#define AFE_CONN13_1 (0x3108)
+#define AFE_CONN13_2 (0x310c)
+#define AFE_CONN13_3 (0x3110)
+#define AFE_CONN13_4 (0x3114)
+#define AFE_CONN14 (0x3118)
+#define AFE_CONN14_1 (0x311c)
+#define AFE_CONN14_2 (0x3120)
+#define AFE_CONN14_3 (0x3124)
+#define AFE_CONN14_4 (0x3128)
+#define AFE_CONN15 (0x312c)
+#define AFE_CONN15_1 (0x3130)
+#define AFE_CONN15_2 (0x3134)
+#define AFE_CONN15_3 (0x3138)
+#define AFE_CONN15_4 (0x313c)
+#define AFE_CONN16 (0x3140)
+#define AFE_CONN16_1 (0x3144)
+#define AFE_CONN16_2 (0x3148)
+#define AFE_CONN16_3 (0x314c)
+#define AFE_CONN16_4 (0x3150)
+#define AFE_CONN17 (0x3154)
+#define AFE_CONN17_1 (0x3158)
+#define AFE_CONN17_2 (0x315c)
+#define AFE_CONN17_3 (0x3160)
+#define AFE_CONN17_4 (0x3164)
+#define AFE_CONN18 (0x3168)
+#define AFE_CONN18_1 (0x316c)
+#define AFE_CONN18_2 (0x3170)
+#define AFE_CONN18_3 (0x3174)
+#define AFE_CONN18_4 (0x3178)
+#define AFE_CONN19 (0x317c)
+#define AFE_CONN19_1 (0x3180)
+#define AFE_CONN19_2 (0x3184)
+#define AFE_CONN19_3 (0x3188)
+#define AFE_CONN19_4 (0x318c)
+#define AFE_CONN20 (0x3190)
+#define AFE_CONN20_1 (0x3194)
+#define AFE_CONN20_2 (0x3198)
+#define AFE_CONN20_3 (0x319c)
+#define AFE_CONN20_4 (0x31a0)
+#define AFE_CONN21 (0x31a4)
+#define AFE_CONN21_1 (0x31a8)
+#define AFE_CONN21_2 (0x31ac)
+#define AFE_CONN21_3 (0x31b0)
+#define AFE_CONN21_4 (0x31b4)
+#define AFE_CONN22 (0x31b8)
+#define AFE_CONN22_1 (0x31bc)
+#define AFE_CONN22_2 (0x31c0)
+#define AFE_CONN22_3 (0x31c4)
+#define AFE_CONN22_4 (0x31c8)
+#define AFE_CONN23 (0x31cc)
+#define AFE_CONN23_1 (0x31d0)
+#define AFE_CONN23_2 (0x31d4)
+#define AFE_CONN23_3 (0x31d8)
+#define AFE_CONN23_4 (0x31dc)
+#define AFE_CONN24 (0x31e0)
+#define AFE_CONN24_1 (0x31e4)
+#define AFE_CONN24_2 (0x31e8)
+#define AFE_CONN24_3 (0x31ec)
+#define AFE_CONN24_4 (0x31f0)
+#define AFE_CONN25 (0x31f4)
+#define AFE_CONN25_1 (0x31f8)
+#define AFE_CONN25_2 (0x31fc)
+#define AFE_CONN25_3 (0x3200)
+#define AFE_CONN25_4 (0x3204)
+#define AFE_CONN26 (0x3208)
+#define AFE_CONN26_1 (0x320c)
+#define AFE_CONN26_2 (0x3210)
+#define AFE_CONN26_3 (0x3214)
+#define AFE_CONN26_4 (0x3218)
+#define AFE_CONN27 (0x321c)
+#define AFE_CONN27_1 (0x3220)
+#define AFE_CONN27_2 (0x3224)
+#define AFE_CONN27_3 (0x3228)
+#define AFE_CONN27_4 (0x322c)
+#define AFE_CONN28 (0x3230)
+#define AFE_CONN28_1 (0x3234)
+#define AFE_CONN28_2 (0x3238)
+#define AFE_CONN28_3 (0x323c)
+#define AFE_CONN28_4 (0x3240)
+#define AFE_CONN29 (0x3244)
+#define AFE_CONN29_1 (0x3248)
+#define AFE_CONN29_2 (0x324c)
+#define AFE_CONN29_3 (0x3250)
+#define AFE_CONN29_4 (0x3254)
+#define AFE_CONN30 (0x3258)
+#define AFE_CONN30_1 (0x325c)
+#define AFE_CONN30_2 (0x3260)
+#define AFE_CONN30_3 (0x3264)
+#define AFE_CONN30_4 (0x3268)
+#define AFE_CONN31 (0x326c)
+#define AFE_CONN31_1 (0x3270)
+#define AFE_CONN31_2 (0x3274)
+#define AFE_CONN31_3 (0x3278)
+#define AFE_CONN31_4 (0x327c)
+#define AFE_CONN32 (0x3280)
+#define AFE_CONN32_1 (0x3284)
+#define AFE_CONN32_2 (0x3288)
+#define AFE_CONN32_3 (0x328c)
+#define AFE_CONN32_4 (0x3290)
+#define AFE_CONN33 (0x3294)
+#define AFE_CONN33_1 (0x3298)
+#define AFE_CONN33_2 (0x329c)
+#define AFE_CONN33_3 (0x32a0)
+#define AFE_CONN33_4 (0x32a4)
+#define AFE_CONN34 (0x32a8)
+#define AFE_CONN34_1 (0x32ac)
+#define AFE_CONN34_2 (0x32b0)
+#define AFE_CONN34_3 (0x32b4)
+#define AFE_CONN34_4 (0x32b8)
+#define AFE_CONN35 (0x32bc)
+#define AFE_CONN35_1 (0x32c0)
+#define AFE_CONN35_2 (0x32c4)
+#define AFE_CONN35_3 (0x32c8)
+#define AFE_CONN35_4 (0x32cc)
+#define AFE_CONN36 (0x32d0)
+#define AFE_CONN36_1 (0x32d4)
+#define AFE_CONN36_2 (0x32d8)
+#define AFE_CONN36_3 (0x32dc)
+#define AFE_CONN36_4 (0x32e0)
+#define AFE_CONN37 (0x32e4)
+#define AFE_CONN37_1 (0x32e8)
+#define AFE_CONN37_2 (0x32ec)
+#define AFE_CONN37_3 (0x32f0)
+#define AFE_CONN37_4 (0x32f4)
+#define AFE_CONN38 (0x32f8)
+#define AFE_CONN38_1 (0x32fc)
+#define AFE_CONN38_2 (0x3300)
+#define AFE_CONN38_3 (0x3304)
+#define AFE_CONN38_4 (0x3308)
+#define AFE_CONN39 (0x330c)
+#define AFE_CONN39_1 (0x3310)
+#define AFE_CONN39_2 (0x3314)
+#define AFE_CONN39_3 (0x3318)
+#define AFE_CONN39_4 (0x331c)
+#define AFE_CONN40 (0x3320)
+#define AFE_CONN40_1 (0x3324)
+#define AFE_CONN40_2 (0x3328)
+#define AFE_CONN40_3 (0x332c)
+#define AFE_CONN40_4 (0x3330)
+#define AFE_CONN41 (0x3334)
+#define AFE_CONN41_1 (0x3338)
+#define AFE_CONN41_2 (0x333c)
+#define AFE_CONN41_3 (0x3340)
+#define AFE_CONN41_4 (0x3344)
+#define AFE_CONN42 (0x3348)
+#define AFE_CONN42_1 (0x334c)
+#define AFE_CONN42_2 (0x3350)
+#define AFE_CONN42_3 (0x3354)
+#define AFE_CONN42_4 (0x3358)
+#define AFE_CONN43 (0x335c)
+#define AFE_CONN43_1 (0x3360)
+#define AFE_CONN43_2 (0x3364)
+#define AFE_CONN43_3 (0x3368)
+#define AFE_CONN43_4 (0x336c)
+#define AFE_CONN44 (0x3370)
+#define AFE_CONN44_1 (0x3374)
+#define AFE_CONN44_2 (0x3378)
+#define AFE_CONN44_3 (0x337c)
+#define AFE_CONN44_4 (0x3380)
+#define AFE_CONN45 (0x3384)
+#define AFE_CONN45_1 (0x3388)
+#define AFE_CONN45_2 (0x338c)
+#define AFE_CONN45_3 (0x3390)
+#define AFE_CONN45_4 (0x3394)
+#define AFE_CONN46 (0x3398)
+#define AFE_CONN46_1 (0x339c)
+#define AFE_CONN46_2 (0x33a0)
+#define AFE_CONN46_3 (0x33a4)
+#define AFE_CONN46_4 (0x33a8)
+#define AFE_CONN47 (0x33ac)
+#define AFE_CONN47_1 (0x33b0)
+#define AFE_CONN47_2 (0x33b4)
+#define AFE_CONN47_3 (0x33b8)
+#define AFE_CONN47_4 (0x33bc)
+#define AFE_CONN48 (0x33c0)
+#define AFE_CONN48_1 (0x33c4)
+#define AFE_CONN48_2 (0x33c8)
+#define AFE_CONN48_3 (0x33cc)
+#define AFE_CONN48_4 (0x33d0)
+#define AFE_CONN49 (0x33d4)
+#define AFE_CONN49_1 (0x33d8)
+#define AFE_CONN49_2 (0x33dc)
+#define AFE_CONN49_3 (0x33e0)
+#define AFE_CONN49_4 (0x33e4)
+#define AFE_CONN50 (0x33e8)
+#define AFE_CONN50_1 (0x33ec)
+#define AFE_CONN50_2 (0x33f0)
+#define AFE_CONN50_3 (0x33f4)
+#define AFE_CONN50_4 (0x33f8)
+#define AFE_CONN51 (0x33fc)
+#define AFE_CONN51_1 (0x3400)
+#define AFE_CONN51_2 (0x3404)
+#define AFE_CONN51_3 (0x3408)
+#define AFE_CONN51_4 (0x340c)
+#define AFE_CONN52 (0x3410)
+#define AFE_CONN52_1 (0x3414)
+#define AFE_CONN52_2 (0x3418)
+#define AFE_CONN52_3 (0x341c)
+#define AFE_CONN52_4 (0x3420)
+#define AFE_CONN53 (0x3424)
+#define AFE_CONN53_1 (0x3428)
+#define AFE_CONN53_2 (0x342c)
+#define AFE_CONN53_3 (0x3430)
+#define AFE_CONN53_4 (0x3434)
+#define AFE_CONN54 (0x3438)
+#define AFE_CONN54_1 (0x343c)
+#define AFE_CONN54_2 (0x3440)
+#define AFE_CONN54_3 (0x3444)
+#define AFE_CONN54_4 (0x3448)
+#define AFE_CONN55 (0x344c)
+#define AFE_CONN55_1 (0x3450)
+#define AFE_CONN55_2 (0x3454)
+#define AFE_CONN55_3 (0x3458)
+#define AFE_CONN55_4 (0x345c)
+#define AFE_CONN56 (0x3460)
+#define AFE_CONN56_1 (0x3464)
+#define AFE_CONN56_2 (0x3468)
+#define AFE_CONN56_3 (0x346c)
+#define AFE_CONN56_4 (0x3470)
+#define AFE_CONN57 (0x3474)
+#define AFE_CONN57_1 (0x3478)
+#define AFE_CONN57_2 (0x347c)
+#define AFE_CONN57_3 (0x3480)
+#define AFE_CONN57_4 (0x3484)
+#define AFE_CONN58 (0x3488)
+#define AFE_CONN58_1 (0x348c)
+#define AFE_CONN58_2 (0x3490)
+#define AFE_CONN58_3 (0x3494)
+#define AFE_CONN58_4 (0x3498)
+#define AFE_CONN59 (0x349c)
+#define AFE_CONN59_1 (0x34a0)
+#define AFE_CONN59_2 (0x34a4)
+#define AFE_CONN59_3 (0x34a8)
+#define AFE_CONN59_4 (0x34ac)
+#define AFE_CONN60 (0x34b0)
+#define AFE_CONN60_1 (0x34b4)
+#define AFE_CONN60_2 (0x34b8)
+#define AFE_CONN60_3 (0x34bc)
+#define AFE_CONN60_4 (0x34c0)
+#define AFE_CONN61 (0x34c4)
+#define AFE_CONN61_1 (0x34c8)
+#define AFE_CONN61_2 (0x34cc)
+#define AFE_CONN61_3 (0x34d0)
+#define AFE_CONN61_4 (0x34d4)
+#define AFE_CONN62 (0x34d8)
+#define AFE_CONN62_1 (0x34dc)
+#define AFE_CONN62_2 (0x34e0)
+#define AFE_CONN62_3 (0x34e4)
+#define AFE_CONN62_4 (0x34e8)
+#define AFE_CONN63 (0x34ec)
+#define AFE_CONN63_1 (0x34f0)
+#define AFE_CONN63_2 (0x34f4)
+#define AFE_CONN63_3 (0x34f8)
+#define AFE_CONN63_4 (0x34fc)
+#define AFE_CONN64 (0x3500)
+#define AFE_CONN64_1 (0x3504)
+#define AFE_CONN64_2 (0x3508)
+#define AFE_CONN64_3 (0x350c)
+#define AFE_CONN64_4 (0x3510)
+#define AFE_CONN65 (0x3514)
+#define AFE_CONN65_1 (0x3518)
+#define AFE_CONN65_2 (0x351c)
+#define AFE_CONN65_3 (0x3520)
+#define AFE_CONN65_4 (0x3524)
+#define AFE_CONN66 (0x3528)
+#define AFE_CONN66_1 (0x352c)
+#define AFE_CONN66_2 (0x3530)
+#define AFE_CONN66_3 (0x3534)
+#define AFE_CONN66_4 (0x3538)
+#define AFE_CONN67 (0x353c)
+#define AFE_CONN67_1 (0x3540)
+#define AFE_CONN67_2 (0x3544)
+#define AFE_CONN67_3 (0x3548)
+#define AFE_CONN67_4 (0x354c)
+#define AFE_CONN68 (0x3550)
+#define AFE_CONN68_1 (0x3554)
+#define AFE_CONN68_2 (0x3558)
+#define AFE_CONN68_3 (0x355c)
+#define AFE_CONN68_4 (0x3560)
+#define AFE_CONN69 (0x3564)
+#define AFE_CONN69_1 (0x3568)
+#define AFE_CONN69_2 (0x356c)
+#define AFE_CONN69_3 (0x3570)
+#define AFE_CONN69_4 (0x3574)
+#define AFE_CONN70 (0x3578)
+#define AFE_CONN70_1 (0x357c)
+#define AFE_CONN70_2 (0x3580)
+#define AFE_CONN70_3 (0x3584)
+#define AFE_CONN70_4 (0x3588)
+#define AFE_CONN71 (0x358c)
+#define AFE_CONN71_1 (0x3590)
+#define AFE_CONN71_2 (0x3594)
+#define AFE_CONN71_3 (0x3598)
+#define AFE_CONN71_4 (0x359c)
+#define AFE_CONN72 (0x35a0)
+#define AFE_CONN72_1 (0x35a4)
+#define AFE_CONN72_2 (0x35a8)
+#define AFE_CONN72_3 (0x35ac)
+#define AFE_CONN72_4 (0x35b0)
+#define AFE_CONN73 (0x35b4)
+#define AFE_CONN73_1 (0x35b8)
+#define AFE_CONN73_2 (0x35bc)
+#define AFE_CONN73_3 (0x35c0)
+#define AFE_CONN73_4 (0x35c4)
+#define AFE_CONN74 (0x35c8)
+#define AFE_CONN74_1 (0x35cc)
+#define AFE_CONN74_2 (0x35d0)
+#define AFE_CONN74_3 (0x35d4)
+#define AFE_CONN74_4 (0x35d8)
+#define AFE_CONN75 (0x35dc)
+#define AFE_CONN75_1 (0x35e0)
+#define AFE_CONN75_2 (0x35e4)
+#define AFE_CONN75_3 (0x35e8)
+#define AFE_CONN75_4 (0x35ec)
+#define AFE_CONN76 (0x35f0)
+#define AFE_CONN76_1 (0x35f4)
+#define AFE_CONN76_2 (0x35f8)
+#define AFE_CONN76_3 (0x35fc)
+#define AFE_CONN76_4 (0x3600)
+#define AFE_CONN77 (0x3604)
+#define AFE_CONN77_1 (0x3608)
+#define AFE_CONN77_2 (0x360c)
+#define AFE_CONN77_3 (0x3610)
+#define AFE_CONN77_4 (0x3614)
+#define AFE_CONN78 (0x3618)
+#define AFE_CONN78_1 (0x361c)
+#define AFE_CONN78_2 (0x3620)
+#define AFE_CONN78_3 (0x3624)
+#define AFE_CONN78_4 (0x3628)
+#define AFE_CONN79 (0x362c)
+#define AFE_CONN79_1 (0x3630)
+#define AFE_CONN79_2 (0x3634)
+#define AFE_CONN79_3 (0x3638)
+#define AFE_CONN79_4 (0x363c)
+#define AFE_CONN80 (0x3640)
+#define AFE_CONN80_1 (0x3644)
+#define AFE_CONN80_2 (0x3648)
+#define AFE_CONN80_3 (0x364c)
+#define AFE_CONN80_4 (0x3650)
+#define AFE_CONN81 (0x3654)
+#define AFE_CONN81_1 (0x3658)
+#define AFE_CONN81_2 (0x365c)
+#define AFE_CONN81_3 (0x3660)
+#define AFE_CONN81_4 (0x3664)
+#define AFE_CONN82 (0x3668)
+#define AFE_CONN82_1 (0x366c)
+#define AFE_CONN82_2 (0x3670)
+#define AFE_CONN82_3 (0x3674)
+#define AFE_CONN82_4 (0x3678)
+#define AFE_CONN83 (0x367c)
+#define AFE_CONN83_1 (0x3680)
+#define AFE_CONN83_2 (0x3684)
+#define AFE_CONN83_3 (0x3688)
+#define AFE_CONN83_4 (0x368c)
+#define AFE_CONN84 (0x3690)
+#define AFE_CONN84_1 (0x3694)
+#define AFE_CONN84_2 (0x3698)
+#define AFE_CONN84_3 (0x369c)
+#define AFE_CONN84_4 (0x36a0)
+#define AFE_CONN85 (0x36a4)
+#define AFE_CONN85_1 (0x36a8)
+#define AFE_CONN85_2 (0x36ac)
+#define AFE_CONN85_3 (0x36b0)
+#define AFE_CONN85_4 (0x36b4)
+#define AFE_CONN86 (0x36b8)
+#define AFE_CONN86_1 (0x36bc)
+#define AFE_CONN86_2 (0x36c0)
+#define AFE_CONN86_3 (0x36c4)
+#define AFE_CONN86_4 (0x36c8)
+#define AFE_CONN87 (0x36cc)
+#define AFE_CONN87_1 (0x36d0)
+#define AFE_CONN87_2 (0x36d4)
+#define AFE_CONN87_3 (0x36d8)
+#define AFE_CONN87_4 (0x36dc)
+#define AFE_CONN88 (0x36e0)
+#define AFE_CONN88_1 (0x36e4)
+#define AFE_CONN88_2 (0x36e8)
+#define AFE_CONN88_3 (0x36ec)
+#define AFE_CONN88_4 (0x36f0)
+#define AFE_CONN89 (0x36f4)
+#define AFE_CONN89_1 (0x36f8)
+#define AFE_CONN89_2 (0x36fc)
+#define AFE_CONN89_3 (0x3700)
+#define AFE_CONN89_4 (0x3704)
+#define AFE_CONN90 (0x3708)
+#define AFE_CONN90_1 (0x370c)
+#define AFE_CONN90_2 (0x3710)
+#define AFE_CONN90_3 (0x3714)
+#define AFE_CONN90_4 (0x3718)
+#define AFE_CONN91 (0x371c)
+#define AFE_CONN91_1 (0x3720)
+#define AFE_CONN91_2 (0x3724)
+#define AFE_CONN91_3 (0x3728)
+#define AFE_CONN91_4 (0x372c)
+#define AFE_CONN92 (0x3730)
+#define AFE_CONN92_1 (0x3734)
+#define AFE_CONN92_2 (0x3738)
+#define AFE_CONN92_3 (0x373c)
+#define AFE_CONN92_4 (0x3740)
+#define AFE_CONN93 (0x3744)
+#define AFE_CONN93_1 (0x3748)
+#define AFE_CONN93_2 (0x374c)
+#define AFE_CONN93_3 (0x3750)
+#define AFE_CONN93_4 (0x3754)
+#define AFE_CONN94 (0x3758)
+#define AFE_CONN94_1 (0x375c)
+#define AFE_CONN94_2 (0x3760)
+#define AFE_CONN94_3 (0x3764)
+#define AFE_CONN94_4 (0x3768)
+#define AFE_CONN95 (0x376c)
+#define AFE_CONN95_1 (0x3770)
+#define AFE_CONN95_2 (0x3774)
+#define AFE_CONN95_3 (0x3778)
+#define AFE_CONN95_4 (0x377c)
+#define AFE_CONN96 (0x3780)
+#define AFE_CONN96_1 (0x3784)
+#define AFE_CONN96_2 (0x3788)
+#define AFE_CONN96_3 (0x378c)
+#define AFE_CONN96_4 (0x3790)
+#define AFE_CONN97 (0x3794)
+#define AFE_CONN97_1 (0x3798)
+#define AFE_CONN97_2 (0x379c)
+#define AFE_CONN97_3 (0x37a0)
+#define AFE_CONN97_4 (0x37a4)
+#define AFE_CONN98 (0x37a8)
+#define AFE_CONN98_1 (0x37ac)
+#define AFE_CONN98_2 (0x37b0)
+#define AFE_CONN98_3 (0x37b4)
+#define AFE_CONN98_4 (0x37b8)
+#define AFE_CONN99 (0x37bc)
+#define AFE_CONN99_1 (0x37c0)
+#define AFE_CONN99_2 (0x37c4)
+#define AFE_CONN99_3 (0x37c8)
+#define AFE_CONN99_4 (0x37cc)
+#define AFE_CONN100 (0x37d0)
+#define AFE_CONN100_1 (0x37d4)
+#define AFE_CONN100_2 (0x37d8)
+#define AFE_CONN100_3 (0x37dc)
+#define AFE_CONN100_4 (0x37e0)
+#define AFE_CONN101 (0x37e4)
+#define AFE_CONN101_1 (0x37e8)
+#define AFE_CONN101_2 (0x37ec)
+#define AFE_CONN101_3 (0x37f0)
+#define AFE_CONN101_4 (0x37f4)
+#define AFE_CONN102 (0x37f8)
+#define AFE_CONN102_1 (0x37fc)
+#define AFE_CONN102_2 (0x3800)
+#define AFE_CONN102_3 (0x3804)
+#define AFE_CONN102_4 (0x3808)
+#define AFE_CONN103 (0x380c)
+#define AFE_CONN103_1 (0x3810)
+#define AFE_CONN103_2 (0x3814)
+#define AFE_CONN103_3 (0x3818)
+#define AFE_CONN103_4 (0x381c)
+#define AFE_CONN104 (0x3820)
+#define AFE_CONN104_1 (0x3824)
+#define AFE_CONN104_2 (0x3828)
+#define AFE_CONN104_3 (0x382c)
+#define AFE_CONN104_4 (0x3830)
+#define AFE_CONN105 (0x3834)
+#define AFE_CONN105_1 (0x3838)
+#define AFE_CONN105_2 (0x383c)
+#define AFE_CONN105_3 (0x3840)
+#define AFE_CONN105_4 (0x3844)
+#define AFE_CONN106 (0x3848)
+#define AFE_CONN106_1 (0x384c)
+#define AFE_CONN106_2 (0x3850)
+#define AFE_CONN106_3 (0x3854)
+#define AFE_CONN106_4 (0x3858)
+#define AFE_CONN107 (0x385c)
+#define AFE_CONN107_1 (0x3860)
+#define AFE_CONN107_2 (0x3864)
+#define AFE_CONN107_3 (0x3868)
+#define AFE_CONN107_4 (0x386c)
+#define AFE_CONN108 (0x3870)
+#define AFE_CONN108_1 (0x3874)
+#define AFE_CONN108_2 (0x3878)
+#define AFE_CONN108_3 (0x387c)
+#define AFE_CONN108_4 (0x3880)
+#define AFE_CONN109 (0x3884)
+#define AFE_CONN109_1 (0x3888)
+#define AFE_CONN109_2 (0x388c)
+#define AFE_CONN109_3 (0x3890)
+#define AFE_CONN109_4 (0x3894)
+#define AFE_CONN110 (0x3898)
+#define AFE_CONN110_1 (0x389c)
+#define AFE_CONN110_2 (0x38a0)
+#define AFE_CONN110_3 (0x38a4)
+#define AFE_CONN110_4 (0x38a8)
+#define AFE_CONN111 (0x38ac)
+#define AFE_CONN111_1 (0x38b0)
+#define AFE_CONN111_2 (0x38b4)
+#define AFE_CONN111_3 (0x38b8)
+#define AFE_CONN111_4 (0x38bc)
+#define AFE_CONN112 (0x38c0)
+#define AFE_CONN112_1 (0x38c4)
+#define AFE_CONN112_2 (0x38c8)
+#define AFE_CONN112_3 (0x38cc)
+#define AFE_CONN112_4 (0x38d0)
+#define AFE_CONN113 (0x38d4)
+#define AFE_CONN113_1 (0x38d8)
+#define AFE_CONN113_2 (0x38dc)
+#define AFE_CONN113_3 (0x38e0)
+#define AFE_CONN113_4 (0x38e4)
+#define AFE_CONN114 (0x38e8)
+#define AFE_CONN114_1 (0x38ec)
+#define AFE_CONN114_2 (0x38f0)
+#define AFE_CONN114_3 (0x38f4)
+#define AFE_CONN114_4 (0x38f8)
+#define AFE_CONN115 (0x38fc)
+#define AFE_CONN115_1 (0x3900)
+#define AFE_CONN115_2 (0x3904)
+#define AFE_CONN115_3 (0x3908)
+#define AFE_CONN115_4 (0x390c)
+#define AFE_CONN116 (0x3910)
+#define AFE_CONN116_1 (0x3914)
+#define AFE_CONN116_2 (0x3918)
+#define AFE_CONN116_3 (0x391c)
+#define AFE_CONN116_4 (0x3920)
+#define AFE_CONN117 (0x3924)
+#define AFE_CONN117_1 (0x3928)
+#define AFE_CONN117_2 (0x392c)
+#define AFE_CONN117_3 (0x3930)
+#define AFE_CONN117_4 (0x3934)
+#define AFE_CONN118 (0x3938)
+#define AFE_CONN118_1 (0x393c)
+#define AFE_CONN118_2 (0x3940)
+#define AFE_CONN118_3 (0x3944)
+#define AFE_CONN118_4 (0x3948)
+#define AFE_CONN119 (0x394c)
+#define AFE_CONN119_1 (0x3950)
+#define AFE_CONN119_2 (0x3954)
+#define AFE_CONN119_3 (0x3958)
+#define AFE_CONN119_4 (0x395c)
+#define AFE_CONN120 (0x3960)
+#define AFE_CONN120_1 (0x3964)
+#define AFE_CONN120_2 (0x3968)
+#define AFE_CONN120_3 (0x396c)
+#define AFE_CONN120_4 (0x3970)
+#define AFE_CONN121 (0x3974)
+#define AFE_CONN121_1 (0x3978)
+#define AFE_CONN121_2 (0x397c)
+#define AFE_CONN121_3 (0x3980)
+#define AFE_CONN121_4 (0x3984)
+#define AFE_CONN122 (0x3988)
+#define AFE_CONN122_1 (0x398c)
+#define AFE_CONN122_2 (0x3990)
+#define AFE_CONN122_3 (0x3994)
+#define AFE_CONN122_4 (0x3998)
+#define AFE_CONN123 (0x399c)
+#define AFE_CONN123_1 (0x39a0)
+#define AFE_CONN123_2 (0x39a4)
+#define AFE_CONN123_3 (0x39a8)
+#define AFE_CONN123_4 (0x39ac)
+#define AFE_CONN124 (0x39b0)
+#define AFE_CONN124_1 (0x39b4)
+#define AFE_CONN124_2 (0x39b8)
+#define AFE_CONN124_3 (0x39bc)
+#define AFE_CONN124_4 (0x39c0)
+#define AFE_CONN125 (0x39c4)
+#define AFE_CONN125_1 (0x39c8)
+#define AFE_CONN125_2 (0x39cc)
+#define AFE_CONN125_3 (0x39d0)
+#define AFE_CONN125_4 (0x39d4)
+#define AFE_CONN126 (0x39d8)
+#define AFE_CONN126_1 (0x39dc)
+#define AFE_CONN126_2 (0x39e0)
+#define AFE_CONN126_3 (0x39e4)
+#define AFE_CONN126_4 (0x39e8)
+#define AFE_CONN127 (0x39ec)
+#define AFE_CONN127_1 (0x39f0)
+#define AFE_CONN127_2 (0x39f4)
+#define AFE_CONN127_3 (0x39f8)
+#define AFE_CONN127_4 (0x39fc)
+#define AFE_CONN128 (0x3a00)
+#define AFE_CONN128_1 (0x3a04)
+#define AFE_CONN128_2 (0x3a08)
+#define AFE_CONN128_3 (0x3a0c)
+#define AFE_CONN128_4 (0x3a10)
+#define AFE_CONN129 (0x3a14)
+#define AFE_CONN129_1 (0x3a18)
+#define AFE_CONN129_2 (0x3a1c)
+#define AFE_CONN129_3 (0x3a20)
+#define AFE_CONN129_4 (0x3a24)
+#define AFE_CONN130 (0x3a28)
+#define AFE_CONN130_1 (0x3a2c)
+#define AFE_CONN130_2 (0x3a30)
+#define AFE_CONN130_3 (0x3a34)
+#define AFE_CONN130_4 (0x3a38)
+#define AFE_CONN131 (0x3a3c)
+#define AFE_CONN131_1 (0x3a40)
+#define AFE_CONN131_2 (0x3a44)
+#define AFE_CONN131_3 (0x3a48)
+#define AFE_CONN131_4 (0x3a4c)
+#define AFE_CONN132 (0x3a50)
+#define AFE_CONN132_1 (0x3a54)
+#define AFE_CONN132_2 (0x3a58)
+#define AFE_CONN132_3 (0x3a5c)
+#define AFE_CONN132_4 (0x3a60)
+#define AFE_CONN133 (0x3a64)
+#define AFE_CONN133_1 (0x3a68)
+#define AFE_CONN133_2 (0x3a6c)
+#define AFE_CONN133_3 (0x3a70)
+#define AFE_CONN133_4 (0x3a74)
+#define AFE_CONN134 (0x3a78)
+#define AFE_CONN134_1 (0x3a7c)
+#define AFE_CONN134_2 (0x3a80)
+#define AFE_CONN134_3 (0x3a84)
+#define AFE_CONN134_4 (0x3a88)
+#define AFE_CONN135 (0x3a8c)
+#define AFE_CONN135_1 (0x3a90)
+#define AFE_CONN135_2 (0x3a94)
+#define AFE_CONN135_3 (0x3a98)
+#define AFE_CONN135_4 (0x3a9c)
+#define AFE_CONN136 (0x3aa0)
+#define AFE_CONN136_1 (0x3aa4)
+#define AFE_CONN136_2 (0x3aa8)
+#define AFE_CONN136_3 (0x3aac)
+#define AFE_CONN136_4 (0x3ab0)
+#define AFE_CONN137 (0x3ab4)
+#define AFE_CONN137_1 (0x3ab8)
+#define AFE_CONN137_2 (0x3abc)
+#define AFE_CONN137_3 (0x3ac0)
+#define AFE_CONN137_4 (0x3ac4)
+#define AFE_CONN138 (0x3ac8)
+#define AFE_CONN138_1 (0x3acc)
+#define AFE_CONN138_2 (0x3ad0)
+#define AFE_CONN138_3 (0x3ad4)
+#define AFE_CONN138_4 (0x3ad8)
+#define AFE_CONN139 (0x3adc)
+#define AFE_CONN139_1 (0x3ae0)
+#define AFE_CONN139_2 (0x3ae4)
+#define AFE_CONN139_3 (0x3ae8)
+#define AFE_CONN139_4 (0x3aec)
+#define AFE_CONN_RS (0x3af0)
+#define AFE_CONN_RS_1 (0x3af4)
+#define AFE_CONN_RS_2 (0x3af8)
+#define AFE_CONN_RS_3 (0x3afc)
+#define AFE_CONN_RS_4 (0x3b00)
+#define AFE_CONN_16BIT (0x3b04)
+#define AFE_CONN_16BIT_1 (0x3b08)
+#define AFE_CONN_16BIT_2 (0x3b0c)
+#define AFE_CONN_16BIT_3 (0x3b10)
+#define AFE_CONN_16BIT_4 (0x3b14)
+#define AFE_CONN_24BIT (0x3b18)
+#define AFE_CONN_24BIT_1 (0x3b1c)
+#define AFE_CONN_24BIT_2 (0x3b20)
+#define AFE_CONN_24BIT_3 (0x3b24)
+#define AFE_CONN_24BIT_4 (0x3b28)
+#define AFE_CONN_DI (0x3b2c)
+#define AFE_CONN_DI_1 (0x3b30)
+#define AFE_CONN_DI_2 (0x3b34)
+#define AFE_CONN_DI_3 (0x3b38)
+#define AFE_CONN_DI_4 (0x3b3c)
+#define AFE_CONN176 (0x3ea0)
+#define AFE_CONN176_1 (0x3ea4)
+#define AFE_CONN176_2 (0x3ea8)
+#define AFE_CONN176_3 (0x3eac)
+#define AFE_CONN176_4 (0x3eb0)
+#define AFE_CONN176_5 (0x3eb4)
+#define AFE_CONN177 (0x3eb8)
+#define AFE_CONN177_1 (0x3ebc)
+#define AFE_CONN177_2 (0x3ec0)
+#define AFE_CONN177_3 (0x3ec4)
+#define AFE_CONN177_4 (0x3ec8)
+#define AFE_CONN177_5 (0x3ecc)
+#define AFE_CONN182 (0x3f30)
+#define AFE_CONN182_1 (0x3f34)
+#define AFE_CONN182_2 (0x3f38)
+#define AFE_CONN182_3 (0x3f3c)
+#define AFE_CONN182_4 (0x3f40)
+#define AFE_CONN182_5 (0x3f44)
+#define AFE_CONN183 (0x3f48)
+#define AFE_CONN183_1 (0x3f4c)
+#define AFE_CONN183_2 (0x3f50)
+#define AFE_CONN183_3 (0x3f54)
+#define AFE_CONN183_4 (0x3f58)
+#define AFE_CONN183_5 (0x3f5c)
+#define AFE_SECURE_MASK_CONN0 (0x4000)
+#define AFE_SECURE_MASK_CONN0_1 (0x4004)
+#define AFE_SECURE_MASK_CONN0_2 (0x4008)
+#define AFE_SECURE_MASK_CONN0_3 (0x400c)
+#define AFE_SECURE_MASK_CONN0_4 (0x4010)
+#define AFE_SECURE_MASK_CONN1 (0x4014)
+#define AFE_SECURE_MASK_CONN1_1 (0x4018)
+#define AFE_SECURE_MASK_CONN1_2 (0x401c)
+#define AFE_SECURE_MASK_CONN1_3 (0x4020)
+#define AFE_SECURE_MASK_CONN1_4 (0x4024)
+#define AFE_SECURE_MASK_CONN2 (0x4028)
+#define AFE_SECURE_MASK_CONN2_1 (0x402c)
+#define AFE_SECURE_MASK_CONN2_2 (0x4030)
+#define AFE_SECURE_MASK_CONN2_3 (0x4034)
+#define AFE_SECURE_MASK_CONN2_4 (0x4038)
+#define AFE_SECURE_MASK_CONN3 (0x403c)
+#define AFE_SECURE_MASK_CONN3_1 (0x4040)
+#define AFE_SECURE_MASK_CONN3_2 (0x4044)
+#define AFE_SECURE_MASK_CONN3_3 (0x4048)
+#define AFE_SECURE_MASK_CONN3_4 (0x404c)
+#define AFE_SECURE_MASK_CONN4 (0x4050)
+#define AFE_SECURE_MASK_CONN4_1 (0x4054)
+#define AFE_SECURE_MASK_CONN4_2 (0x4058)
+#define AFE_SECURE_MASK_CONN4_3 (0x405c)
+#define AFE_SECURE_MASK_CONN4_4 (0x4060)
+#define AFE_SECURE_MASK_CONN5 (0x4064)
+#define AFE_SECURE_MASK_CONN5_1 (0x4068)
+#define AFE_SECURE_MASK_CONN5_2 (0x406c)
+#define AFE_SECURE_MASK_CONN5_3 (0x4070)
+#define AFE_SECURE_MASK_CONN5_4 (0x4074)
+#define AFE_SECURE_MASK_CONN6 (0x4078)
+#define AFE_SECURE_MASK_CONN6_1 (0x407c)
+#define AFE_SECURE_MASK_CONN6_2 (0x4080)
+#define AFE_SECURE_MASK_CONN6_3 (0x4084)
+#define AFE_SECURE_MASK_CONN6_4 (0x4088)
+#define AFE_SECURE_MASK_CONN7 (0x408c)
+#define AFE_SECURE_MASK_CONN7_1 (0x4090)
+#define AFE_SECURE_MASK_CONN7_2 (0x4094)
+#define AFE_SECURE_MASK_CONN7_3 (0x4098)
+#define AFE_SECURE_MASK_CONN7_4 (0x409c)
+#define AFE_SECURE_MASK_CONN8 (0x40a0)
+#define AFE_SECURE_MASK_CONN8_1 (0x40a4)
+#define AFE_SECURE_MASK_CONN8_2 (0x40a8)
+#define AFE_SECURE_MASK_CONN8_3 (0x40ac)
+#define AFE_SECURE_MASK_CONN8_4 (0x40b0)
+#define AFE_SECURE_MASK_CONN9 (0x40b4)
+#define AFE_SECURE_MASK_CONN9_1 (0x40b8)
+#define AFE_SECURE_MASK_CONN9_2 (0x40bc)
+#define AFE_SECURE_MASK_CONN9_3 (0x40c0)
+#define AFE_SECURE_MASK_CONN9_4 (0x40c4)
+#define AFE_SECURE_MASK_CONN10 (0x40c8)
+#define AFE_SECURE_MASK_CONN10_1 (0x40cc)
+#define AFE_SECURE_MASK_CONN10_2 (0x40d0)
+#define AFE_SECURE_MASK_CONN10_3 (0x40d4)
+#define AFE_SECURE_MASK_CONN10_4 (0x40d8)
+#define AFE_SECURE_MASK_CONN11 (0x40dc)
+#define AFE_SECURE_MASK_CONN11_1 (0x40e0)
+#define AFE_SECURE_MASK_CONN11_2 (0x40e4)
+#define AFE_SECURE_MASK_CONN11_3 (0x40e8)
+#define AFE_SECURE_MASK_CONN11_4 (0x40ec)
+#define AFE_SECURE_MASK_CONN12 (0x40f0)
+#define AFE_SECURE_MASK_CONN12_1 (0x40f4)
+#define AFE_SECURE_MASK_CONN12_2 (0x40f8)
+#define AFE_SECURE_MASK_CONN12_3 (0x40fc)
+#define AFE_SECURE_MASK_CONN12_4 (0x4100)
+#define AFE_SECURE_MASK_CONN13 (0x4104)
+#define AFE_SECURE_MASK_CONN13_1 (0x4108)
+#define AFE_SECURE_MASK_CONN13_2 (0x410c)
+#define AFE_SECURE_MASK_CONN13_3 (0x4110)
+#define AFE_SECURE_MASK_CONN13_4 (0x4114)
+#define AFE_SECURE_MASK_CONN14 (0x4118)
+#define AFE_SECURE_MASK_CONN14_1 (0x411c)
+#define AFE_SECURE_MASK_CONN14_2 (0x4120)
+#define AFE_SECURE_MASK_CONN14_3 (0x4124)
+#define AFE_SECURE_MASK_CONN14_4 (0x4128)
+#define AFE_SECURE_MASK_CONN15 (0x412c)
+#define AFE_SECURE_MASK_CONN15_1 (0x4130)
+#define AFE_SECURE_MASK_CONN15_2 (0x4134)
+#define AFE_SECURE_MASK_CONN15_3 (0x4138)
+#define AFE_SECURE_MASK_CONN15_4 (0x413c)
+#define AFE_SECURE_MASK_CONN16 (0x4140)
+#define AFE_SECURE_MASK_CONN16_1 (0x4144)
+#define AFE_SECURE_MASK_CONN16_2 (0x4148)
+#define AFE_SECURE_MASK_CONN16_3 (0x414c)
+#define AFE_SECURE_MASK_CONN16_4 (0x4150)
+#define AFE_SECURE_MASK_CONN17 (0x4154)
+#define AFE_SECURE_MASK_CONN17_1 (0x4158)
+#define AFE_SECURE_MASK_CONN17_2 (0x415c)
+#define AFE_SECURE_MASK_CONN17_3 (0x4160)
+#define AFE_SECURE_MASK_CONN17_4 (0x4164)
+#define AFE_SECURE_MASK_CONN18 (0x4168)
+#define AFE_SECURE_MASK_CONN18_1 (0x416c)
+#define AFE_SECURE_MASK_CONN18_2 (0x4170)
+#define AFE_SECURE_MASK_CONN18_3 (0x4174)
+#define AFE_SECURE_MASK_CONN18_4 (0x4178)
+#define AFE_SECURE_MASK_CONN19 (0x417c)
+#define AFE_SECURE_MASK_CONN19_1 (0x4180)
+#define AFE_SECURE_MASK_CONN19_2 (0x4184)
+#define AFE_SECURE_MASK_CONN19_3 (0x4188)
+#define AFE_SECURE_MASK_CONN19_4 (0x418c)
+#define AFE_SECURE_MASK_CONN20 (0x4190)
+#define AFE_SECURE_MASK_CONN20_1 (0x4194)
+#define AFE_SECURE_MASK_CONN20_2 (0x4198)
+#define AFE_SECURE_MASK_CONN20_3 (0x419c)
+#define AFE_SECURE_MASK_CONN20_4 (0x41a0)
+#define AFE_SECURE_MASK_CONN21 (0x41a4)
+#define AFE_SECURE_MASK_CONN21_1 (0x41a8)
+#define AFE_SECURE_MASK_CONN21_2 (0x41ac)
+#define AFE_SECURE_MASK_CONN21_3 (0x41b0)
+#define AFE_SECURE_MASK_CONN21_4 (0x41b4)
+#define AFE_SECURE_MASK_CONN22 (0x41b8)
+#define AFE_SECURE_MASK_CONN22_1 (0x41bc)
+#define AFE_SECURE_MASK_CONN22_2 (0x41c0)
+#define AFE_SECURE_MASK_CONN22_3 (0x41c4)
+#define AFE_SECURE_MASK_CONN22_4 (0x41c8)
+#define AFE_SECURE_MASK_CONN23 (0x41cc)
+#define AFE_SECURE_MASK_CONN23_1 (0x41d0)
+#define AFE_SECURE_MASK_CONN23_2 (0x41d4)
+#define AFE_SECURE_MASK_CONN23_3 (0x41d8)
+#define AFE_SECURE_MASK_CONN23_4 (0x41dc)
+#define AFE_SECURE_MASK_CONN24 (0x41e0)
+#define AFE_SECURE_MASK_CONN24_1 (0x41e4)
+#define AFE_SECURE_MASK_CONN24_2 (0x41e8)
+#define AFE_SECURE_MASK_CONN24_3 (0x41ec)
+#define AFE_SECURE_MASK_CONN24_4 (0x41f0)
+#define AFE_SECURE_MASK_CONN25 (0x41f4)
+#define AFE_SECURE_MASK_CONN25_1 (0x41f8)
+#define AFE_SECURE_MASK_CONN25_2 (0x41fc)
+#define AFE_SECURE_MASK_CONN25_3 (0x4200)
+#define AFE_SECURE_MASK_CONN25_4 (0x4204)
+#define AFE_SECURE_MASK_CONN26 (0x4208)
+#define AFE_SECURE_MASK_CONN26_1 (0x420c)
+#define AFE_SECURE_MASK_CONN26_2 (0x4210)
+#define AFE_SECURE_MASK_CONN26_3 (0x4214)
+#define AFE_SECURE_MASK_CONN26_4 (0x4218)
+#define AFE_SECURE_MASK_CONN27 (0x421c)
+#define AFE_SECURE_MASK_CONN27_1 (0x4220)
+#define AFE_SECURE_MASK_CONN27_2 (0x4224)
+#define AFE_SECURE_MASK_CONN27_3 (0x4228)
+#define AFE_SECURE_MASK_CONN27_4 (0x422c)
+#define AFE_SECURE_MASK_CONN28 (0x4230)
+#define AFE_SECURE_MASK_CONN28_1 (0x4234)
+#define AFE_SECURE_MASK_CONN28_2 (0x4238)
+#define AFE_SECURE_MASK_CONN28_3 (0x423c)
+#define AFE_SECURE_MASK_CONN28_4 (0x4240)
+#define AFE_SECURE_MASK_CONN29 (0x4244)
+#define AFE_SECURE_MASK_CONN29_1 (0x4248)
+#define AFE_SECURE_MASK_CONN29_2 (0x424c)
+#define AFE_SECURE_MASK_CONN29_3 (0x4250)
+#define AFE_SECURE_MASK_CONN29_4 (0x4254)
+#define AFE_SECURE_MASK_CONN30 (0x4258)
+#define AFE_SECURE_MASK_CONN30_1 (0x425c)
+#define AFE_SECURE_MASK_CONN30_2 (0x4260)
+#define AFE_SECURE_MASK_CONN30_3 (0x4264)
+#define AFE_SECURE_MASK_CONN30_4 (0x4268)
+#define AFE_SECURE_MASK_CONN31 (0x426c)
+#define AFE_SECURE_MASK_CONN31_1 (0x4270)
+#define AFE_SECURE_MASK_CONN31_2 (0x4274)
+#define AFE_SECURE_MASK_CONN31_3 (0x4278)
+#define AFE_SECURE_MASK_CONN31_4 (0x427c)
+#define AFE_SECURE_MASK_CONN32 (0x4280)
+#define AFE_SECURE_MASK_CONN32_1 (0x4284)
+#define AFE_SECURE_MASK_CONN32_2 (0x4288)
+#define AFE_SECURE_MASK_CONN32_3 (0x428c)
+#define AFE_SECURE_MASK_CONN32_4 (0x4290)
+#define AFE_SECURE_MASK_CONN33 (0x4294)
+#define AFE_SECURE_MASK_CONN33_1 (0x4298)
+#define AFE_SECURE_MASK_CONN33_2 (0x429c)
+#define AFE_SECURE_MASK_CONN33_3 (0x42a0)
+#define AFE_SECURE_MASK_CONN33_4 (0x42a4)
+#define AFE_SECURE_MASK_CONN34 (0x42a8)
+#define AFE_SECURE_MASK_CONN34_1 (0x42ac)
+#define AFE_SECURE_MASK_CONN34_2 (0x42b0)
+#define AFE_SECURE_MASK_CONN34_3 (0x42b4)
+#define AFE_SECURE_MASK_CONN34_4 (0x42b8)
+#define AFE_SECURE_MASK_CONN35 (0x42bc)
+#define AFE_SECURE_MASK_CONN35_1 (0x42c0)
+#define AFE_SECURE_MASK_CONN35_2 (0x42c4)
+#define AFE_SECURE_MASK_CONN35_3 (0x42c8)
+#define AFE_SECURE_MASK_CONN35_4 (0x42cc)
+#define AFE_SECURE_MASK_CONN36 (0x42d0)
+#define AFE_SECURE_MASK_CONN36_1 (0x42d4)
+#define AFE_SECURE_MASK_CONN36_2 (0x42d8)
+#define AFE_SECURE_MASK_CONN36_3 (0x42dc)
+#define AFE_SECURE_MASK_CONN36_4 (0x42e0)
+#define AFE_SECURE_MASK_CONN37 (0x42e4)
+#define AFE_SECURE_MASK_CONN37_1 (0x42e8)
+#define AFE_SECURE_MASK_CONN37_2 (0x42ec)
+#define AFE_SECURE_MASK_CONN37_3 (0x42f0)
+#define AFE_SECURE_MASK_CONN37_4 (0x42f4)
+#define AFE_SECURE_MASK_CONN38 (0x42f8)
+#define AFE_SECURE_MASK_CONN38_1 (0x42fc)
+#define AFE_SECURE_MASK_CONN38_2 (0x4300)
+#define AFE_SECURE_MASK_CONN38_3 (0x4304)
+#define AFE_SECURE_MASK_CONN38_4 (0x4308)
+#define AFE_SECURE_MASK_CONN39 (0x430c)
+#define AFE_SECURE_MASK_CONN39_1 (0x4310)
+#define AFE_SECURE_MASK_CONN39_2 (0x4314)
+#define AFE_SECURE_MASK_CONN39_3 (0x4318)
+#define AFE_SECURE_MASK_CONN39_4 (0x431c)
+#define AFE_SECURE_MASK_CONN40 (0x4320)
+#define AFE_SECURE_MASK_CONN40_1 (0x4324)
+#define AFE_SECURE_MASK_CONN40_2 (0x4328)
+#define AFE_SECURE_MASK_CONN40_3 (0x432c)
+#define AFE_SECURE_MASK_CONN40_4 (0x4330)
+#define AFE_SECURE_MASK_CONN41 (0x4334)
+#define AFE_SECURE_MASK_CONN41_1 (0x4338)
+#define AFE_SECURE_MASK_CONN41_2 (0x433c)
+#define AFE_SECURE_MASK_CONN41_3 (0x4340)
+#define AFE_SECURE_MASK_CONN41_4 (0x4344)
+#define AFE_SECURE_MASK_CONN42 (0x4348)
+#define AFE_SECURE_MASK_CONN42_1 (0x434c)
+#define AFE_SECURE_MASK_CONN42_2 (0x4350)
+#define AFE_SECURE_MASK_CONN42_3 (0x4354)
+#define AFE_SECURE_MASK_CONN42_4 (0x4358)
+#define AFE_SECURE_MASK_CONN43 (0x435c)
+#define AFE_SECURE_MASK_CONN43_1 (0x4360)
+#define AFE_SECURE_MASK_CONN43_2 (0x4364)
+#define AFE_SECURE_MASK_CONN43_3 (0x4368)
+#define AFE_SECURE_MASK_CONN43_4 (0x436c)
+#define AFE_SECURE_MASK_CONN44 (0x4370)
+#define AFE_SECURE_MASK_CONN44_1 (0x4374)
+#define AFE_SECURE_MASK_CONN44_2 (0x4378)
+#define AFE_SECURE_MASK_CONN44_3 (0x437c)
+#define AFE_SECURE_MASK_CONN44_4 (0x4380)
+#define AFE_SECURE_MASK_CONN45 (0x4384)
+#define AFE_SECURE_MASK_CONN45_1 (0x4388)
+#define AFE_SECURE_MASK_CONN45_2 (0x438c)
+#define AFE_SECURE_MASK_CONN45_3 (0x4390)
+#define AFE_SECURE_MASK_CONN45_4 (0x4394)
+#define AFE_SECURE_MASK_CONN46 (0x4398)
+#define AFE_SECURE_MASK_CONN46_1 (0x439c)
+#define AFE_SECURE_MASK_CONN46_2 (0x43a0)
+#define AFE_SECURE_MASK_CONN46_3 (0x43a4)
+#define AFE_SECURE_MASK_CONN46_4 (0x43a8)
+#define AFE_SECURE_MASK_CONN47 (0x43ac)
+#define AFE_SECURE_MASK_CONN47_1 (0x43b0)
+#define AFE_SECURE_MASK_CONN47_2 (0x43b4)
+#define AFE_SECURE_MASK_CONN47_3 (0x43b8)
+#define AFE_SECURE_MASK_CONN47_4 (0x43bc)
+#define AFE_SECURE_MASK_CONN48 (0x43c0)
+#define AFE_SECURE_MASK_CONN48_1 (0x43c4)
+#define AFE_SECURE_MASK_CONN48_2 (0x43c8)
+#define AFE_SECURE_MASK_CONN48_3 (0x43cc)
+#define AFE_SECURE_MASK_CONN48_4 (0x43d0)
+#define AFE_SECURE_MASK_CONN49 (0x43d4)
+#define AFE_SECURE_MASK_CONN49_1 (0x43d8)
+#define AFE_SECURE_MASK_CONN49_2 (0x43dc)
+#define AFE_SECURE_MASK_CONN49_3 (0x43e0)
+#define AFE_SECURE_MASK_CONN49_4 (0x43e4)
+#define AFE_SECURE_MASK_CONN50 (0x43e8)
+#define AFE_SECURE_MASK_CONN50_1 (0x43ec)
+#define AFE_SECURE_MASK_CONN50_2 (0x43f0)
+#define AFE_SECURE_MASK_CONN50_3 (0x43f4)
+#define AFE_SECURE_MASK_CONN50_4 (0x43f8)
+#define AFE_SECURE_MASK_CONN51 (0x43fc)
+#define AFE_SECURE_MASK_CONN51_1 (0x4400)
+#define AFE_SECURE_MASK_CONN51_2 (0x4404)
+#define AFE_SECURE_MASK_CONN51_3 (0x4408)
+#define AFE_SECURE_MASK_CONN51_4 (0x440c)
+#define AFE_SECURE_MASK_CONN52 (0x4410)
+#define AFE_SECURE_MASK_CONN52_1 (0x4414)
+#define AFE_SECURE_MASK_CONN52_2 (0x4418)
+#define AFE_SECURE_MASK_CONN52_3 (0x441c)
+#define AFE_SECURE_MASK_CONN52_4 (0x4420)
+#define AFE_SECURE_MASK_CONN53 (0x4424)
+#define AFE_SECURE_MASK_CONN53_1 (0x4428)
+#define AFE_SECURE_MASK_CONN53_2 (0x442c)
+#define AFE_SECURE_MASK_CONN53_3 (0x4430)
+#define AFE_SECURE_MASK_CONN53_4 (0x4434)
+#define AFE_SECURE_MASK_CONN54 (0x4438)
+#define AFE_SECURE_MASK_CONN54_1 (0x443c)
+#define AFE_SECURE_MASK_CONN54_2 (0x4440)
+#define AFE_SECURE_MASK_CONN54_3 (0x4444)
+#define AFE_SECURE_MASK_CONN54_4 (0x4448)
+#define AFE_SECURE_MASK_CONN55 (0x444c)
+#define AFE_SECURE_MASK_CONN55_1 (0x4450)
+#define AFE_SECURE_MASK_CONN55_2 (0x4454)
+#define AFE_SECURE_MASK_CONN55_3 (0x4458)
+#define AFE_SECURE_MASK_CONN55_4 (0x445c)
+#define AFE_SECURE_MASK_CONN56 (0x4460)
+#define AFE_SECURE_MASK_CONN56_1 (0x4464)
+#define AFE_SECURE_MASK_CONN56_2 (0x4468)
+#define AFE_SECURE_MASK_CONN56_3 (0x446c)
+#define AFE_SECURE_MASK_CONN56_4 (0x4470)
+#define AFE_SECURE_MASK_CONN57 (0x4474)
+#define AFE_SECURE_MASK_CONN57_1 (0x4478)
+#define AFE_SECURE_MASK_CONN57_2 (0x447c)
+#define AFE_SECURE_MASK_CONN57_3 (0x4480)
+#define AFE_SECURE_MASK_CONN57_4 (0x4484)
+#define AFE_SECURE_MASK_CONN58 (0x4488)
+#define AFE_SECURE_MASK_CONN58_1 (0x448c)
+#define AFE_SECURE_MASK_CONN58_2 (0x4490)
+#define AFE_SECURE_MASK_CONN58_3 (0x4494)
+#define AFE_SECURE_MASK_CONN58_4 (0x4498)
+#define AFE_SECURE_MASK_CONN59 (0x449c)
+#define AFE_SECURE_MASK_CONN59_1 (0x44a0)
+#define AFE_SECURE_MASK_CONN59_2 (0x44a4)
+#define AFE_SECURE_MASK_CONN59_3 (0x44a8)
+#define AFE_SECURE_MASK_CONN59_4 (0x44ac)
+#define AFE_SECURE_MASK_CONN60 (0x44b0)
+#define AFE_SECURE_MASK_CONN60_1 (0x44b4)
+#define AFE_SECURE_MASK_CONN60_2 (0x44b8)
+#define AFE_SECURE_MASK_CONN60_3 (0x44bc)
+#define AFE_SECURE_MASK_CONN60_4 (0x44c0)
+#define AFE_SECURE_MASK_CONN61 (0x44c4)
+#define AFE_SECURE_MASK_CONN61_1 (0x44c8)
+#define AFE_SECURE_MASK_CONN61_2 (0x44cc)
+#define AFE_SECURE_MASK_CONN61_3 (0x44d0)
+#define AFE_SECURE_MASK_CONN61_4 (0x44d4)
+#define AFE_SECURE_MASK_CONN62 (0x44d8)
+#define AFE_SECURE_MASK_CONN62_1 (0x44dc)
+#define AFE_SECURE_MASK_CONN62_2 (0x44e0)
+#define AFE_SECURE_MASK_CONN62_3 (0x44e4)
+#define AFE_SECURE_MASK_CONN62_4 (0x44e8)
+#define AFE_SECURE_MASK_CONN63 (0x44ec)
+#define AFE_SECURE_MASK_CONN63_1 (0x44f0)
+#define AFE_SECURE_MASK_CONN63_2 (0x44f4)
+#define AFE_SECURE_MASK_CONN63_3 (0x44f8)
+#define AFE_SECURE_MASK_CONN63_4 (0x44fc)
+#define AFE_SECURE_MASK_CONN64 (0x4500)
+#define AFE_SECURE_MASK_CONN64_1 (0x4504)
+#define AFE_SECURE_MASK_CONN64_2 (0x4508)
+#define AFE_SECURE_MASK_CONN64_3 (0x450c)
+#define AFE_SECURE_MASK_CONN64_4 (0x4510)
+#define AFE_SECURE_MASK_CONN65 (0x4514)
+#define AFE_SECURE_MASK_CONN65_1 (0x4518)
+#define AFE_SECURE_MASK_CONN65_2 (0x451c)
+#define AFE_SECURE_MASK_CONN65_3 (0x4520)
+#define AFE_SECURE_MASK_CONN65_4 (0x4524)
+#define AFE_SECURE_MASK_CONN66 (0x4528)
+#define AFE_SECURE_MASK_CONN66_1 (0x452c)
+#define AFE_SECURE_MASK_CONN66_2 (0x4530)
+#define AFE_SECURE_MASK_CONN66_3 (0x4534)
+#define AFE_SECURE_MASK_CONN66_4 (0x4538)
+#define AFE_SECURE_MASK_CONN67 (0x453c)
+#define AFE_SECURE_MASK_CONN67_1 (0x4540)
+#define AFE_SECURE_MASK_CONN67_2 (0x4544)
+#define AFE_SECURE_MASK_CONN67_3 (0x4548)
+#define AFE_SECURE_MASK_CONN67_4 (0x454c)
+#define AFE_SECURE_MASK_CONN68 (0x4550)
+#define AFE_SECURE_MASK_CONN68_1 (0x4554)
+#define AFE_SECURE_MASK_CONN68_2 (0x4558)
+#define AFE_SECURE_MASK_CONN68_3 (0x455c)
+#define AFE_SECURE_MASK_CONN68_4 (0x4560)
+#define AFE_SECURE_MASK_CONN69 (0x4564)
+#define AFE_SECURE_MASK_CONN69_1 (0x4568)
+#define AFE_SECURE_MASK_CONN69_2 (0x456c)
+#define AFE_SECURE_MASK_CONN69_3 (0x4570)
+#define AFE_SECURE_MASK_CONN69_4 (0x4574)
+#define AFE_SECURE_MASK_CONN70 (0x4578)
+#define AFE_SECURE_MASK_CONN70_1 (0x457c)
+#define AFE_SECURE_MASK_CONN70_2 (0x4580)
+#define AFE_SECURE_MASK_CONN70_3 (0x4584)
+#define AFE_SECURE_MASK_CONN70_4 (0x4588)
+#define AFE_SECURE_MASK_CONN71 (0x458c)
+#define AFE_SECURE_MASK_CONN71_1 (0x4590)
+#define AFE_SECURE_MASK_CONN71_2 (0x4594)
+#define AFE_SECURE_MASK_CONN71_3 (0x4598)
+#define AFE_SECURE_MASK_CONN71_4 (0x459c)
+#define AFE_SECURE_MASK_CONN72 (0x45a0)
+#define AFE_SECURE_MASK_CONN72_1 (0x45a4)
+#define AFE_SECURE_MASK_CONN72_2 (0x45a8)
+#define AFE_SECURE_MASK_CONN72_3 (0x45ac)
+#define AFE_SECURE_MASK_CONN72_4 (0x45b0)
+#define AFE_SECURE_MASK_CONN73 (0x45b4)
+#define AFE_SECURE_MASK_CONN73_1 (0x45b8)
+#define AFE_SECURE_MASK_CONN73_2 (0x45bc)
+#define AFE_SECURE_MASK_CONN73_3 (0x45c0)
+#define AFE_SECURE_MASK_CONN73_4 (0x45c4)
+#define AFE_SECURE_MASK_CONN74 (0x45c8)
+#define AFE_SECURE_MASK_CONN74_1 (0x45cc)
+#define AFE_SECURE_MASK_CONN74_2 (0x45d0)
+#define AFE_SECURE_MASK_CONN74_3 (0x45d4)
+#define AFE_SECURE_MASK_CONN74_4 (0x45d8)
+#define AFE_SECURE_MASK_CONN75 (0x45dc)
+#define AFE_SECURE_MASK_CONN75_1 (0x45e0)
+#define AFE_SECURE_MASK_CONN75_2 (0x45e4)
+#define AFE_SECURE_MASK_CONN75_3 (0x45e8)
+#define AFE_SECURE_MASK_CONN75_4 (0x45ec)
+#define AFE_SECURE_MASK_CONN76 (0x45f0)
+#define AFE_SECURE_MASK_CONN76_1 (0x45f4)
+#define AFE_SECURE_MASK_CONN76_2 (0x45f8)
+#define AFE_SECURE_MASK_CONN76_3 (0x45fc)
+#define AFE_SECURE_MASK_CONN76_4 (0x4600)
+#define AFE_SECURE_MASK_CONN77 (0x4604)
+#define AFE_SECURE_MASK_CONN77_1 (0x4608)
+#define AFE_SECURE_MASK_CONN77_2 (0x460c)
+#define AFE_SECURE_MASK_CONN77_3 (0x4610)
+#define AFE_SECURE_MASK_CONN77_4 (0x4614)
+#define AFE_SECURE_MASK_CONN78 (0x4618)
+#define AFE_SECURE_MASK_CONN78_1 (0x461c)
+#define AFE_SECURE_MASK_CONN78_2 (0x4620)
+#define AFE_SECURE_MASK_CONN78_3 (0x4624)
+#define AFE_SECURE_MASK_CONN78_4 (0x4628)
+#define AFE_SECURE_MASK_CONN79 (0x462c)
+#define AFE_SECURE_MASK_CONN79_1 (0x4630)
+#define AFE_SECURE_MASK_CONN79_2 (0x4634)
+#define AFE_SECURE_MASK_CONN79_3 (0x4638)
+#define AFE_SECURE_MASK_CONN79_4 (0x463c)
+#define AFE_SECURE_MASK_CONN80 (0x4640)
+#define AFE_SECURE_MASK_CONN80_1 (0x4644)
+#define AFE_SECURE_MASK_CONN80_2 (0x4648)
+#define AFE_SECURE_MASK_CONN80_3 (0x464c)
+#define AFE_SECURE_MASK_CONN80_4 (0x4650)
+#define AFE_SECURE_MASK_CONN81 (0x4654)
+#define AFE_SECURE_MASK_CONN81_1 (0x4658)
+#define AFE_SECURE_MASK_CONN81_2 (0x465c)
+#define AFE_SECURE_MASK_CONN81_3 (0x4660)
+#define AFE_SECURE_MASK_CONN81_4 (0x4664)
+#define AFE_SECURE_MASK_CONN82 (0x4668)
+#define AFE_SECURE_MASK_CONN82_1 (0x466c)
+#define AFE_SECURE_MASK_CONN82_2 (0x4670)
+#define AFE_SECURE_MASK_CONN82_3 (0x4674)
+#define AFE_SECURE_MASK_CONN82_4 (0x4678)
+#define AFE_SECURE_MASK_CONN83 (0x467c)
+#define AFE_SECURE_MASK_CONN83_1 (0x4680)
+#define AFE_SECURE_MASK_CONN83_2 (0x4684)
+#define AFE_SECURE_MASK_CONN83_3 (0x4688)
+#define AFE_SECURE_MASK_CONN83_4 (0x468c)
+#define AFE_SECURE_MASK_CONN84 (0x4690)
+#define AFE_SECURE_MASK_CONN84_1 (0x4694)
+#define AFE_SECURE_MASK_CONN84_2 (0x4698)
+#define AFE_SECURE_MASK_CONN84_3 (0x469c)
+#define AFE_SECURE_MASK_CONN84_4 (0x46a0)
+#define AFE_SECURE_MASK_CONN85 (0x46a4)
+#define AFE_SECURE_MASK_CONN85_1 (0x46a8)
+#define AFE_SECURE_MASK_CONN85_2 (0x46ac)
+#define AFE_SECURE_MASK_CONN85_3 (0x46b0)
+#define AFE_SECURE_MASK_CONN85_4 (0x46b4)
+#define AFE_SECURE_MASK_CONN86 (0x46b8)
+#define AFE_SECURE_MASK_CONN86_1 (0x46bc)
+#define AFE_SECURE_MASK_CONN86_2 (0x46c0)
+#define AFE_SECURE_MASK_CONN86_3 (0x46c4)
+#define AFE_SECURE_MASK_CONN86_4 (0x46c8)
+#define AFE_SECURE_MASK_CONN87 (0x46cc)
+#define AFE_SECURE_MASK_CONN87_1 (0x46d0)
+#define AFE_SECURE_MASK_CONN87_2 (0x46d4)
+#define AFE_SECURE_MASK_CONN87_3 (0x46d8)
+#define AFE_SECURE_MASK_CONN87_4 (0x46dc)
+#define AFE_SECURE_MASK_CONN88 (0x46e0)
+#define AFE_SECURE_MASK_CONN88_1 (0x46e4)
+#define AFE_SECURE_MASK_CONN88_2 (0x46e8)
+#define AFE_SECURE_MASK_CONN88_3 (0x46ec)
+#define AFE_SECURE_MASK_CONN88_4 (0x46f0)
+#define AFE_SECURE_MASK_CONN89 (0x46f4)
+#define AFE_SECURE_MASK_CONN89_1 (0x46f8)
+#define AFE_SECURE_MASK_CONN89_2 (0x46fc)
+#define AFE_SECURE_MASK_CONN89_3 (0x4700)
+#define AFE_SECURE_MASK_CONN89_4 (0x4704)
+#define AFE_SECURE_MASK_CONN90 (0x4708)
+#define AFE_SECURE_MASK_CONN90_1 (0x470c)
+#define AFE_SECURE_MASK_CONN90_2 (0x4710)
+#define AFE_SECURE_MASK_CONN90_3 (0x4714)
+#define AFE_SECURE_MASK_CONN90_4 (0x4718)
+#define AFE_SECURE_MASK_CONN91 (0x471c)
+#define AFE_SECURE_MASK_CONN91_1 (0x4720)
+#define AFE_SECURE_MASK_CONN91_2 (0x4724)
+#define AFE_SECURE_MASK_CONN91_3 (0x4728)
+#define AFE_SECURE_MASK_CONN91_4 (0x472c)
+#define AFE_SECURE_MASK_CONN92 (0x4730)
+#define AFE_SECURE_MASK_CONN92_1 (0x4734)
+#define AFE_SECURE_MASK_CONN92_2 (0x4738)
+#define AFE_SECURE_MASK_CONN92_3 (0x473c)
+#define AFE_SECURE_MASK_CONN92_4 (0x4740)
+#define AFE_SECURE_MASK_CONN93 (0x4744)
+#define AFE_SECURE_MASK_CONN93_1 (0x4748)
+#define AFE_SECURE_MASK_CONN93_2 (0x474c)
+#define AFE_SECURE_MASK_CONN93_3 (0x4750)
+#define AFE_SECURE_MASK_CONN93_4 (0x4754)
+#define AFE_SECURE_MASK_CONN94 (0x4758)
+#define AFE_SECURE_MASK_CONN94_1 (0x475c)
+#define AFE_SECURE_MASK_CONN94_2 (0x4760)
+#define AFE_SECURE_MASK_CONN94_3 (0x4764)
+#define AFE_SECURE_MASK_CONN94_4 (0x4768)
+#define AFE_SECURE_MASK_CONN95 (0x476c)
+#define AFE_SECURE_MASK_CONN95_1 (0x4770)
+#define AFE_SECURE_MASK_CONN95_2 (0x4774)
+#define AFE_SECURE_MASK_CONN95_3 (0x4778)
+#define AFE_SECURE_MASK_CONN95_4 (0x477c)
+#define AFE_SECURE_MASK_CONN96 (0x4780)
+#define AFE_SECURE_MASK_CONN96_1 (0x4784)
+#define AFE_SECURE_MASK_CONN96_2 (0x4788)
+#define AFE_SECURE_MASK_CONN96_3 (0x478c)
+#define AFE_SECURE_MASK_CONN96_4 (0x4790)
+#define AFE_SECURE_MASK_CONN97 (0x4794)
+#define AFE_SECURE_MASK_CONN97_1 (0x4798)
+#define AFE_SECURE_MASK_CONN97_2 (0x479c)
+#define AFE_SECURE_MASK_CONN97_3 (0x47a0)
+#define AFE_SECURE_MASK_CONN97_4 (0x47a4)
+#define AFE_SECURE_MASK_CONN98 (0x47a8)
+#define AFE_SECURE_MASK_CONN98_1 (0x47ac)
+#define AFE_SECURE_MASK_CONN98_2 (0x47b0)
+#define AFE_SECURE_MASK_CONN98_3 (0x47b4)
+#define AFE_SECURE_MASK_CONN98_4 (0x47b8)
+#define AFE_SECURE_MASK_CONN99 (0x47bc)
+#define AFE_SECURE_MASK_CONN99_1 (0x47c0)
+#define AFE_SECURE_MASK_CONN99_2 (0x47c4)
+#define AFE_SECURE_MASK_CONN99_3 (0x47c8)
+#define AFE_SECURE_MASK_CONN99_4 (0x47cc)
+#define AFE_SECURE_MASK_CONN100 (0x47d0)
+#define AFE_SECURE_MASK_CONN100_1 (0x47d4)
+#define AFE_SECURE_MASK_CONN100_2 (0x47d8)
+#define AFE_SECURE_MASK_CONN100_3 (0x47dc)
+#define AFE_SECURE_MASK_CONN100_4 (0x47e0)
+#define AFE_SECURE_MASK_CONN101 (0x47e4)
+#define AFE_SECURE_MASK_CONN101_1 (0x47e8)
+#define AFE_SECURE_MASK_CONN101_2 (0x47ec)
+#define AFE_SECURE_MASK_CONN101_3 (0x47f0)
+#define AFE_SECURE_MASK_CONN101_4 (0x47f4)
+#define AFE_SECURE_MASK_CONN102 (0x47f8)
+#define AFE_SECURE_MASK_CONN102_1 (0x47fc)
+#define AFE_SECURE_MASK_CONN102_2 (0x4800)
+#define AFE_SECURE_MASK_CONN102_3 (0x4804)
+#define AFE_SECURE_MASK_CONN102_4 (0x4808)
+#define AFE_SECURE_MASK_CONN103 (0x480c)
+#define AFE_SECURE_MASK_CONN103_1 (0x4810)
+#define AFE_SECURE_MASK_CONN103_2 (0x4814)
+#define AFE_SECURE_MASK_CONN103_3 (0x4818)
+#define AFE_SECURE_MASK_CONN103_4 (0x481c)
+#define AFE_SECURE_MASK_CONN104 (0x4820)
+#define AFE_SECURE_MASK_CONN104_1 (0x4824)
+#define AFE_SECURE_MASK_CONN104_2 (0x4828)
+#define AFE_SECURE_MASK_CONN104_3 (0x482c)
+#define AFE_SECURE_MASK_CONN104_4 (0x4830)
+#define AFE_SECURE_MASK_CONN105 (0x4834)
+#define AFE_SECURE_MASK_CONN105_1 (0x4838)
+#define AFE_SECURE_MASK_CONN105_2 (0x483c)
+#define AFE_SECURE_MASK_CONN105_3 (0x4840)
+#define AFE_SECURE_MASK_CONN105_4 (0x4844)
+#define AFE_SECURE_MASK_CONN106 (0x4848)
+#define AFE_SECURE_MASK_CONN106_1 (0x484c)
+#define AFE_SECURE_MASK_CONN106_2 (0x4850)
+#define AFE_SECURE_MASK_CONN106_3 (0x4854)
+#define AFE_SECURE_MASK_CONN106_4 (0x4858)
+#define AFE_SECURE_MASK_CONN107 (0x485c)
+#define AFE_SECURE_MASK_CONN107_1 (0x4860)
+#define AFE_SECURE_MASK_CONN107_2 (0x4864)
+#define AFE_SECURE_MASK_CONN107_3 (0x4868)
+#define AFE_SECURE_MASK_CONN107_4 (0x486c)
+#define AFE_SECURE_MASK_CONN108 (0x4870)
+#define AFE_SECURE_MASK_CONN108_1 (0x4874)
+#define AFE_SECURE_MASK_CONN108_2 (0x4878)
+#define AFE_SECURE_MASK_CONN108_3 (0x487c)
+#define AFE_SECURE_MASK_CONN108_4 (0x4880)
+#define AFE_SECURE_MASK_CONN109 (0x4884)
+#define AFE_SECURE_MASK_CONN109_1 (0x4888)
+#define AFE_SECURE_MASK_CONN109_2 (0x488c)
+#define AFE_SECURE_MASK_CONN109_3 (0x4890)
+#define AFE_SECURE_MASK_CONN109_4 (0x4894)
+#define AFE_SECURE_MASK_CONN110 (0x4898)
+#define AFE_SECURE_MASK_CONN110_1 (0x489c)
+#define AFE_SECURE_MASK_CONN110_2 (0x48a0)
+#define AFE_SECURE_MASK_CONN110_3 (0x48a4)
+#define AFE_SECURE_MASK_CONN110_4 (0x48a8)
+#define AFE_SECURE_MASK_CONN111 (0x48ac)
+#define AFE_SECURE_MASK_CONN111_1 (0x48b0)
+#define AFE_SECURE_MASK_CONN111_2 (0x48b4)
+#define AFE_SECURE_MASK_CONN111_3 (0x48b8)
+#define AFE_SECURE_MASK_CONN111_4 (0x48bc)
+#define AFE_SECURE_MASK_CONN112 (0x48c0)
+#define AFE_SECURE_MASK_CONN112_1 (0x48c4)
+#define AFE_SECURE_MASK_CONN112_2 (0x48c8)
+#define AFE_SECURE_MASK_CONN112_3 (0x48cc)
+#define AFE_SECURE_MASK_CONN112_4 (0x48d0)
+#define AFE_SECURE_MASK_CONN113 (0x48d4)
+#define AFE_SECURE_MASK_CONN113_1 (0x48d8)
+#define AFE_SECURE_MASK_CONN113_2 (0x48dc)
+#define AFE_SECURE_MASK_CONN113_3 (0x48e0)
+#define AFE_SECURE_MASK_CONN113_4 (0x48e4)
+#define AFE_SECURE_MASK_CONN114 (0x48e8)
+#define AFE_SECURE_MASK_CONN114_1 (0x48ec)
+#define AFE_SECURE_MASK_CONN114_2 (0x48f0)
+#define AFE_SECURE_MASK_CONN114_3 (0x48f4)
+#define AFE_SECURE_MASK_CONN114_4 (0x48f8)
+#define AFE_SECURE_MASK_CONN115 (0x48fc)
+#define AFE_SECURE_MASK_CONN115_1 (0x4900)
+#define AFE_SECURE_MASK_CONN115_2 (0x4904)
+#define AFE_SECURE_MASK_CONN115_3 (0x4908)
+#define AFE_SECURE_MASK_CONN115_4 (0x490c)
+#define AFE_SECURE_MASK_CONN116 (0x4910)
+#define AFE_SECURE_MASK_CONN116_1 (0x4914)
+#define AFE_SECURE_MASK_CONN116_2 (0x4918)
+#define AFE_SECURE_MASK_CONN116_3 (0x491c)
+#define AFE_SECURE_MASK_CONN116_4 (0x4920)
+#define AFE_SECURE_MASK_CONN117 (0x4924)
+#define AFE_SECURE_MASK_CONN117_1 (0x4928)
+#define AFE_SECURE_MASK_CONN117_2 (0x492c)
+#define AFE_SECURE_MASK_CONN117_3 (0x4930)
+#define AFE_SECURE_MASK_CONN117_4 (0x4934)
+#define AFE_SECURE_MASK_CONN118 (0x4938)
+#define AFE_SECURE_MASK_CONN118_1 (0x493c)
+#define AFE_SECURE_MASK_CONN118_2 (0x4940)
+#define AFE_SECURE_MASK_CONN118_3 (0x4944)
+#define AFE_SECURE_MASK_CONN118_4 (0x4948)
+#define AFE_SECURE_MASK_CONN119 (0x494c)
+#define AFE_SECURE_MASK_CONN119_1 (0x4950)
+#define AFE_SECURE_MASK_CONN119_2 (0x4954)
+#define AFE_SECURE_MASK_CONN119_3 (0x4958)
+#define AFE_SECURE_MASK_CONN119_4 (0x495c)
+#define AFE_SECURE_MASK_CONN120 (0x4960)
+#define AFE_SECURE_MASK_CONN120_1 (0x4964)
+#define AFE_SECURE_MASK_CONN120_2 (0x4968)
+#define AFE_SECURE_MASK_CONN120_3 (0x496c)
+#define AFE_SECURE_MASK_CONN120_4 (0x4970)
+#define AFE_SECURE_MASK_CONN121 (0x4974)
+#define AFE_SECURE_MASK_CONN121_1 (0x4978)
+#define AFE_SECURE_MASK_CONN121_2 (0x497c)
+#define AFE_SECURE_MASK_CONN121_3 (0x4980)
+#define AFE_SECURE_MASK_CONN121_4 (0x4984)
+#define AFE_SECURE_MASK_CONN122 (0x4988)
+#define AFE_SECURE_MASK_CONN122_1 (0x498c)
+#define AFE_SECURE_MASK_CONN122_2 (0x4990)
+#define AFE_SECURE_MASK_CONN122_3 (0x4994)
+#define AFE_SECURE_MASK_CONN122_4 (0x4998)
+#define AFE_SECURE_MASK_CONN123 (0x499c)
+#define AFE_SECURE_MASK_CONN123_1 (0x49a0)
+#define AFE_SECURE_MASK_CONN123_2 (0x49a4)
+#define AFE_SECURE_MASK_CONN123_3 (0x49a8)
+#define AFE_SECURE_MASK_CONN123_4 (0x49ac)
+#define AFE_SECURE_MASK_CONN124 (0x49b0)
+#define AFE_SECURE_MASK_CONN124_1 (0x49b4)
+#define AFE_SECURE_MASK_CONN124_2 (0x49b8)
+#define AFE_SECURE_MASK_CONN124_3 (0x49bc)
+#define AFE_SECURE_MASK_CONN124_4 (0x49c0)
+#define AFE_SECURE_MASK_CONN125 (0x49c4)
+#define AFE_SECURE_MASK_CONN125_1 (0x49c8)
+#define AFE_SECURE_MASK_CONN125_2 (0x49cc)
+#define AFE_SECURE_MASK_CONN125_3 (0x49d0)
+#define AFE_SECURE_MASK_CONN125_4 (0x49d4)
+#define AFE_SECURE_MASK_CONN126 (0x49d8)
+#define AFE_SECURE_MASK_CONN126_1 (0x49dc)
+#define AFE_SECURE_MASK_CONN126_2 (0x49e0)
+#define AFE_SECURE_MASK_CONN126_3 (0x49e4)
+#define AFE_SECURE_MASK_CONN126_4 (0x49e8)
+#define AFE_SECURE_MASK_CONN127 (0x49ec)
+#define AFE_SECURE_MASK_CONN127_1 (0x49f0)
+#define AFE_SECURE_MASK_CONN127_2 (0x49f4)
+#define AFE_SECURE_MASK_CONN127_3 (0x49f8)
+#define AFE_SECURE_MASK_CONN127_4 (0x49fc)
+#define AFE_SECURE_MASK_CONN128 (0x4a00)
+#define AFE_SECURE_MASK_CONN128_1 (0x4a04)
+#define AFE_SECURE_MASK_CONN128_2 (0x4a08)
+#define AFE_SECURE_MASK_CONN128_3 (0x4a0c)
+#define AFE_SECURE_MASK_CONN128_4 (0x4a10)
+#define AFE_SECURE_MASK_CONN129 (0x4a14)
+#define AFE_SECURE_MASK_CONN129_1 (0x4a18)
+#define AFE_SECURE_MASK_CONN129_2 (0x4a1c)
+#define AFE_SECURE_MASK_CONN129_3 (0x4a20)
+#define AFE_SECURE_MASK_CONN129_4 (0x4a24)
+#define AFE_SECURE_MASK_CONN130 (0x4a28)
+#define AFE_SECURE_MASK_CONN130_1 (0x4a2c)
+#define AFE_SECURE_MASK_CONN130_2 (0x4a30)
+#define AFE_SECURE_MASK_CONN130_3 (0x4a34)
+#define AFE_SECURE_MASK_CONN130_4 (0x4a38)
+#define AFE_SECURE_MASK_CONN131 (0x4a3c)
+#define AFE_SECURE_MASK_CONN131_1 (0x4a40)
+#define AFE_SECURE_MASK_CONN131_2 (0x4a44)
+#define AFE_SECURE_MASK_CONN131_3 (0x4a48)
+#define AFE_SECURE_MASK_CONN131_4 (0x4a4c)
+#define AFE_SECURE_MASK_CONN132 (0x4a50)
+#define AFE_SECURE_MASK_CONN132_1 (0x4a54)
+#define AFE_SECURE_MASK_CONN132_2 (0x4a58)
+#define AFE_SECURE_MASK_CONN132_3 (0x4a5c)
+#define AFE_SECURE_MASK_CONN132_4 (0x4a60)
+#define AFE_SECURE_MASK_CONN133 (0x4a64)
+#define AFE_SECURE_MASK_CONN133_1 (0x4a68)
+#define AFE_SECURE_MASK_CONN133_2 (0x4a6c)
+#define AFE_SECURE_MASK_CONN133_3 (0x4a70)
+#define AFE_SECURE_MASK_CONN133_4 (0x4a74)
+#define AFE_SECURE_MASK_CONN134 (0x4a78)
+#define AFE_SECURE_MASK_CONN134_1 (0x4a7c)
+#define AFE_SECURE_MASK_CONN134_2 (0x4a80)
+#define AFE_SECURE_MASK_CONN134_3 (0x4a84)
+#define AFE_SECURE_MASK_CONN134_4 (0x4a88)
+#define AFE_SECURE_MASK_CONN135 (0x4a8c)
+#define AFE_SECURE_MASK_CONN135_1 (0x4a90)
+#define AFE_SECURE_MASK_CONN135_2 (0x4a94)
+#define AFE_SECURE_MASK_CONN135_3 (0x4a98)
+#define AFE_SECURE_MASK_CONN135_4 (0x4a9c)
+#define AFE_SECURE_MASK_CONN136 (0x4aa0)
+#define AFE_SECURE_MASK_CONN136_1 (0x4aa4)
+#define AFE_SECURE_MASK_CONN136_2 (0x4aa8)
+#define AFE_SECURE_MASK_CONN136_3 (0x4aac)
+#define AFE_SECURE_MASK_CONN136_4 (0x4ab0)
+#define AFE_SECURE_MASK_CONN137 (0x4ab4)
+#define AFE_SECURE_MASK_CONN137_1 (0x4ab8)
+#define AFE_SECURE_MASK_CONN137_2 (0x4abc)
+#define AFE_SECURE_MASK_CONN137_3 (0x4ac0)
+#define AFE_SECURE_MASK_CONN137_4 (0x4ac4)
+#define AFE_SECURE_MASK_CONN138 (0x4ac8)
+#define AFE_SECURE_MASK_CONN138_1 (0x4acc)
+#define AFE_SECURE_MASK_CONN138_2 (0x4ad0)
+#define AFE_SECURE_MASK_CONN138_3 (0x4ad4)
+#define AFE_SECURE_MASK_CONN138_4 (0x4ad8)
+#define AFE_SECURE_MASK_CONN139 (0x4adc)
+#define AFE_SECURE_MASK_CONN139_1 (0x4ae0)
+#define AFE_SECURE_MASK_CONN139_2 (0x4ae4)
+#define AFE_SECURE_MASK_CONN139_3 (0x4ae8)
+#define AFE_SECURE_MASK_CONN139_4 (0x4aec)
+#define AFE_SECURE_MASK_CONN_RS (0x4af0)
+#define AFE_SECURE_MASK_CONN_RS_1 (0x4af4)
+#define AFE_SECURE_MASK_CONN_RS_2 (0x4af8)
+#define AFE_SECURE_MASK_CONN_RS_3 (0x4afc)
+#define AFE_SECURE_MASK_CONN_RS_4 (0x4b00)
+#define AFE_SECURE_MASK_CONN_16BIT (0x4b04)
+#define AFE_SECURE_MASK_CONN_16BIT_1 (0x4b08)
+#define AFE_SECURE_MASK_CONN_16BIT_2 (0x4b0c)
+#define AFE_SECURE_MASK_CONN_16BIT_3 (0x4b10)
+#define AFE_SECURE_MASK_CONN_16BIT_4 (0x4b14)
+#define AFE_SECURE_MASK_CONN_24BIT (0x4b18)
+#define AFE_SECURE_MASK_CONN_24BIT_1 (0x4b1c)
+#define AFE_SECURE_MASK_CONN_24BIT_2 (0x4b20)
+#define AFE_SECURE_MASK_CONN_24BIT_3 (0x4b24)
+#define AFE_SECURE_MASK_CONN_24BIT_4 (0x4b28)
+#define AFE_GASRC0_NEW_CON0 (0x4c40)
+#define AFE_GASRC0_NEW_CON1 (0x4c44)
+#define AFE_GASRC0_NEW_CON2 (0x4c48)
+#define AFE_GASRC0_NEW_CON3 (0x4c4c)
+#define AFE_GASRC0_NEW_CON4 (0x4c50)
+#define AFE_GASRC0_NEW_CON5 (0x4c54)
+#define AFE_GASRC0_NEW_CON6 (0x4c58)
+#define AFE_GASRC0_NEW_CON7 (0x4c5c)
+#define AFE_GASRC0_NEW_CON8 (0x4c60)
+#define AFE_GASRC0_NEW_CON9 (0x4c64)
+#define AFE_GASRC0_NEW_CON10 (0x4c68)
+#define AFE_GASRC0_NEW_CON11 (0x4c6c)
+#define AFE_GASRC0_NEW_CON12 (0x4c70)
+#define AFE_GASRC0_NEW_CON13 (0x4c74)
+#define AFE_GASRC0_NEW_CON14 (0x4c78)
+#define AFE_GASRC1_NEW_CON0 (0x4c80)
+#define AFE_GASRC1_NEW_CON1 (0x4c84)
+#define AFE_GASRC1_NEW_CON2 (0x4c88)
+#define AFE_GASRC1_NEW_CON3 (0x4c8c)
+#define AFE_GASRC1_NEW_CON4 (0x4c90)
+#define AFE_GASRC1_NEW_CON5 (0x4c94)
+#define AFE_GASRC1_NEW_CON6 (0x4c98)
+#define AFE_GASRC1_NEW_CON7 (0x4c9c)
+#define AFE_GASRC1_NEW_CON8 (0x4ca0)
+#define AFE_GASRC1_NEW_CON9 (0x4ca4)
+#define AFE_GASRC1_NEW_CON10 (0x4ca8)
+#define AFE_GASRC1_NEW_CON11 (0x4cac)
+#define AFE_GASRC1_NEW_CON12 (0x4cb0)
+#define AFE_GASRC1_NEW_CON13 (0x4cb4)
+#define AFE_GASRC1_NEW_CON14 (0x4cb8)
+#define AFE_GASRC2_NEW_CON0 (0x4cc0)
+#define AFE_GASRC2_NEW_CON1 (0x4cc4)
+#define AFE_GASRC2_NEW_CON2 (0x4cc8)
+#define AFE_GASRC2_NEW_CON3 (0x4ccc)
+#define AFE_GASRC2_NEW_CON4 (0x4cd0)
+#define AFE_GASRC2_NEW_CON5 (0x4cd4)
+#define AFE_GASRC2_NEW_CON6 (0x4cd8)
+#define AFE_GASRC2_NEW_CON7 (0x4cdc)
+#define AFE_GASRC2_NEW_CON8 (0x4ce0)
+#define AFE_GASRC2_NEW_CON9 (0x4ce4)
+#define AFE_GASRC2_NEW_CON10 (0x4ce8)
+#define AFE_GASRC2_NEW_CON11 (0x4cec)
+#define AFE_GASRC2_NEW_CON12 (0x4cf0)
+#define AFE_GASRC2_NEW_CON13 (0x4cf4)
+#define AFE_GASRC2_NEW_CON14 (0x4cf8)
+#define AFE_GASRC3_NEW_CON0 (0x4d00)
+#define AFE_GASRC3_NEW_CON1 (0x4d04)
+#define AFE_GASRC3_NEW_CON2 (0x4d08)
+#define AFE_GASRC3_NEW_CON3 (0x4d0c)
+#define AFE_GASRC3_NEW_CON4 (0x4d10)
+#define AFE_GASRC3_NEW_CON5 (0x4d14)
+#define AFE_GASRC3_NEW_CON6 (0x4d18)
+#define AFE_GASRC3_NEW_CON7 (0x4d1c)
+#define AFE_GASRC3_NEW_CON8 (0x4d20)
+#define AFE_GASRC3_NEW_CON9 (0x4d24)
+#define AFE_GASRC3_NEW_CON10 (0x4d28)
+#define AFE_GASRC3_NEW_CON11 (0x4d2c)
+#define AFE_GASRC3_NEW_CON12 (0x4d30)
+#define AFE_GASRC3_NEW_CON13 (0x4d34)
+#define AFE_GASRC3_NEW_CON14 (0x4d38)
+#define AFE_GASRC4_NEW_CON0 (0x4d40)
+#define AFE_GASRC4_NEW_CON1 (0x4d44)
+#define AFE_GASRC4_NEW_CON2 (0x4d48)
+#define AFE_GASRC4_NEW_CON3 (0x4d4c)
+#define AFE_GASRC4_NEW_CON4 (0x4d50)
+#define AFE_GASRC4_NEW_CON5 (0x4d54)
+#define AFE_GASRC4_NEW_CON6 (0x4d58)
+#define AFE_GASRC4_NEW_CON7 (0x4d5c)
+#define AFE_GASRC4_NEW_CON8 (0x4d60)
+#define AFE_GASRC4_NEW_CON9 (0x4d64)
+#define AFE_GASRC4_NEW_CON10 (0x4d68)
+#define AFE_GASRC4_NEW_CON11 (0x4d6c)
+#define AFE_GASRC4_NEW_CON12 (0x4d70)
+#define AFE_GASRC4_NEW_CON13 (0x4d74)
+#define AFE_GASRC4_NEW_CON14 (0x4d78)
+#define AFE_GASRC5_NEW_CON0 (0x4d80)
+#define AFE_GASRC5_NEW_CON1 (0x4d84)
+#define AFE_GASRC5_NEW_CON2 (0x4d88)
+#define AFE_GASRC5_NEW_CON3 (0x4d8c)
+#define AFE_GASRC5_NEW_CON4 (0x4d90)
+#define AFE_GASRC5_NEW_CON5 (0x4d94)
+#define AFE_GASRC5_NEW_CON6 (0x4d98)
+#define AFE_GASRC5_NEW_CON7 (0x4d9c)
+#define AFE_GASRC5_NEW_CON8 (0x4da0)
+#define AFE_GASRC5_NEW_CON9 (0x4da4)
+#define AFE_GASRC5_NEW_CON10 (0x4da8)
+#define AFE_GASRC5_NEW_CON11 (0x4dac)
+#define AFE_GASRC5_NEW_CON12 (0x4db0)
+#define AFE_GASRC5_NEW_CON13 (0x4db4)
+#define AFE_GASRC5_NEW_CON14 (0x4db8)
+#define AFE_GASRC6_NEW_CON0 (0x4dc0)
+#define AFE_GASRC6_NEW_CON1 (0x4dc4)
+#define AFE_GASRC6_NEW_CON2 (0x4dc8)
+#define AFE_GASRC6_NEW_CON3 (0x4dcc)
+#define AFE_GASRC6_NEW_CON4 (0x4dd0)
+#define AFE_GASRC6_NEW_CON5 (0x4dd4)
+#define AFE_GASRC6_NEW_CON6 (0x4dd8)
+#define AFE_GASRC6_NEW_CON7 (0x4ddc)
+#define AFE_GASRC6_NEW_CON8 (0x4de0)
+#define AFE_GASRC6_NEW_CON9 (0x4de4)
+#define AFE_GASRC6_NEW_CON10 (0x4de8)
+#define AFE_GASRC6_NEW_CON11 (0x4dec)
+#define AFE_GASRC6_NEW_CON12 (0x4df0)
+#define AFE_GASRC6_NEW_CON13 (0x4df4)
+#define AFE_GASRC6_NEW_CON14 (0x4df8)
+#define AFE_GASRC7_NEW_CON0 (0x4e00)
+#define AFE_GASRC7_NEW_CON1 (0x4e04)
+#define AFE_GASRC7_NEW_CON2 (0x4e08)
+#define AFE_GASRC7_NEW_CON3 (0x4e0c)
+#define AFE_GASRC7_NEW_CON4 (0x4e10)
+#define AFE_GASRC7_NEW_CON5 (0x4e14)
+#define AFE_GASRC7_NEW_CON6 (0x4e18)
+#define AFE_GASRC7_NEW_CON7 (0x4e1c)
+#define AFE_GASRC7_NEW_CON8 (0x4e20)
+#define AFE_GASRC7_NEW_CON9 (0x4e24)
+#define AFE_GASRC7_NEW_CON10 (0x4e28)
+#define AFE_GASRC7_NEW_CON11 (0x4e2c)
+#define AFE_GASRC7_NEW_CON12 (0x4e30)
+#define AFE_GASRC7_NEW_CON13 (0x4e34)
+#define AFE_GASRC7_NEW_CON14 (0x4e38)
+#define AFE_GASRC8_NEW_CON0 (0x4e40)
+#define AFE_GASRC8_NEW_CON1 (0x4e44)
+#define AFE_GASRC8_NEW_CON2 (0x4e48)
+#define AFE_GASRC8_NEW_CON3 (0x4e4c)
+#define AFE_GASRC8_NEW_CON4 (0x4e50)
+#define AFE_GASRC8_NEW_CON5 (0x4e54)
+#define AFE_GASRC8_NEW_CON6 (0x4e58)
+#define AFE_GASRC8_NEW_CON7 (0x4e5c)
+#define AFE_GASRC8_NEW_CON8 (0x4e60)
+#define AFE_GASRC8_NEW_CON9 (0x4e64)
+#define AFE_GASRC8_NEW_CON10 (0x4e68)
+#define AFE_GASRC8_NEW_CON11 (0x4e6c)
+#define AFE_GASRC8_NEW_CON12 (0x4e70)
+#define AFE_GASRC8_NEW_CON13 (0x4e74)
+#define AFE_GASRC8_NEW_CON14 (0x4e78)
+#define AFE_GASRC9_NEW_CON0 (0x4e80)
+#define AFE_GASRC9_NEW_CON1 (0x4e84)
+#define AFE_GASRC9_NEW_CON2 (0x4e88)
+#define AFE_GASRC9_NEW_CON3 (0x4e8c)
+#define AFE_GASRC9_NEW_CON4 (0x4e90)
+#define AFE_GASRC9_NEW_CON5 (0x4e94)
+#define AFE_GASRC9_NEW_CON6 (0x4e98)
+#define AFE_GASRC9_NEW_CON7 (0x4e9c)
+#define AFE_GASRC9_NEW_CON8 (0x4ea0)
+#define AFE_GASRC9_NEW_CON9 (0x4ea4)
+#define AFE_GASRC9_NEW_CON10 (0x4ea8)
+#define AFE_GASRC9_NEW_CON11 (0x4eac)
+#define AFE_GASRC9_NEW_CON12 (0x4eb0)
+#define AFE_GASRC9_NEW_CON13 (0x4eb4)
+#define AFE_GASRC9_NEW_CON14 (0x4eb8)
+#define AFE_GASRC10_NEW_CON0 (0x4ec0)
+#define AFE_GASRC10_NEW_CON1 (0x4ec4)
+#define AFE_GASRC10_NEW_CON2 (0x4ec8)
+#define AFE_GASRC10_NEW_CON3 (0x4ecc)
+#define AFE_GASRC10_NEW_CON4 (0x4ed0)
+#define AFE_GASRC10_NEW_CON5 (0x4ed4)
+#define AFE_GASRC10_NEW_CON6 (0x4ed8)
+#define AFE_GASRC10_NEW_CON7 (0x4edc)
+#define AFE_GASRC10_NEW_CON8 (0x4ee0)
+#define AFE_GASRC10_NEW_CON9 (0x4ee4)
+#define AFE_GASRC10_NEW_CON10 (0x4ee8)
+#define AFE_GASRC10_NEW_CON11 (0x4eec)
+#define AFE_GASRC10_NEW_CON12 (0x4ef0)
+#define AFE_GASRC10_NEW_CON13 (0x4ef4)
+#define AFE_GASRC10_NEW_CON14 (0x4ef8)
+#define AFE_GASRC11_NEW_CON0 (0x4f00)
+#define AFE_GASRC11_NEW_CON1 (0x4f04)
+#define AFE_GASRC11_NEW_CON2 (0x4f08)
+#define AFE_GASRC11_NEW_CON3 (0x4f0c)
+#define AFE_GASRC11_NEW_CON4 (0x4f10)
+#define AFE_GASRC11_NEW_CON5 (0x4f14)
+#define AFE_GASRC11_NEW_CON6 (0x4f18)
+#define AFE_GASRC11_NEW_CON7 (0x4f1c)
+#define AFE_GASRC11_NEW_CON8 (0x4f20)
+#define AFE_GASRC11_NEW_CON9 (0x4f24)
+#define AFE_GASRC11_NEW_CON10 (0x4f28)
+#define AFE_GASRC11_NEW_CON11 (0x4f2c)
+#define AFE_GASRC11_NEW_CON12 (0x4f30)
+#define AFE_GASRC11_NEW_CON13 (0x4f34)
+#define AFE_GASRC11_NEW_CON14 (0x4f38)
+#define AFE_GASRC12_NEW_CON0 (0x4f40)
+#define AFE_GASRC12_NEW_CON1 (0x4f44)
+#define AFE_GASRC12_NEW_CON2 (0x4f48)
+#define AFE_GASRC12_NEW_CON3 (0x4f4c)
+#define AFE_GASRC12_NEW_CON4 (0x4f50)
+#define AFE_GASRC12_NEW_CON5 (0x4f54)
+#define AFE_GASRC12_NEW_CON6 (0x4f58)
+#define AFE_GASRC12_NEW_CON7 (0x4f5c)
+#define AFE_GASRC12_NEW_CON8 (0x4f60)
+#define AFE_GASRC12_NEW_CON9 (0x4f64)
+#define AFE_GASRC12_NEW_CON10 (0x4f68)
+#define AFE_GASRC12_NEW_CON11 (0x4f6c)
+#define AFE_GASRC12_NEW_CON12 (0x4f70)
+#define AFE_GASRC12_NEW_CON13 (0x4f74)
+#define AFE_GASRC12_NEW_CON14 (0x4f78)
+#define AFE_GASRC13_NEW_CON0 (0x4f80)
+#define AFE_GASRC13_NEW_CON1 (0x4f84)
+#define AFE_GASRC13_NEW_CON2 (0x4f88)
+#define AFE_GASRC13_NEW_CON3 (0x4f8c)
+#define AFE_GASRC13_NEW_CON4 (0x4f90)
+#define AFE_GASRC13_NEW_CON5 (0x4f94)
+#define AFE_GASRC13_NEW_CON6 (0x4f98)
+#define AFE_GASRC13_NEW_CON7 (0x4f9c)
+#define AFE_GASRC13_NEW_CON8 (0x4fa0)
+#define AFE_GASRC13_NEW_CON9 (0x4fa4)
+#define AFE_GASRC13_NEW_CON10 (0x4fa8)
+#define AFE_GASRC13_NEW_CON11 (0x4fac)
+#define AFE_GASRC13_NEW_CON12 (0x4fb0)
+#define AFE_GASRC13_NEW_CON13 (0x4fb4)
+#define AFE_GASRC13_NEW_CON14 (0x4fb8)
+#define AFE_GASRC14_NEW_CON0 (0x4fc0)
+#define AFE_GASRC14_NEW_CON1 (0x4fc4)
+#define AFE_GASRC14_NEW_CON2 (0x4fc8)
+#define AFE_GASRC14_NEW_CON3 (0x4fcc)
+#define AFE_GASRC14_NEW_CON4 (0x4fd0)
+#define AFE_GASRC14_NEW_CON5 (0x4fd4)
+#define AFE_GASRC14_NEW_CON6 (0x4fd8)
+#define AFE_GASRC14_NEW_CON7 (0x4fdc)
+#define AFE_GASRC14_NEW_CON8 (0x4fe0)
+#define AFE_GASRC14_NEW_CON9 (0x4fe4)
+#define AFE_GASRC14_NEW_CON10 (0x4fe8)
+#define AFE_GASRC14_NEW_CON11 (0x4fec)
+#define AFE_GASRC14_NEW_CON12 (0x4ff0)
+#define AFE_GASRC14_NEW_CON13 (0x4ff4)
+#define AFE_GASRC14_NEW_CON14 (0x4ff8)
+#define AFE_GASRC15_NEW_CON0 (0x5000)
+#define AFE_GASRC15_NEW_CON1 (0x5004)
+#define AFE_GASRC15_NEW_CON2 (0x5008)
+#define AFE_GASRC15_NEW_CON3 (0x500c)
+#define AFE_GASRC15_NEW_CON4 (0x5010)
+#define AFE_GASRC15_NEW_CON5 (0x5014)
+#define AFE_GASRC15_NEW_CON6 (0x5018)
+#define AFE_GASRC15_NEW_CON7 (0x501c)
+#define AFE_GASRC15_NEW_CON8 (0x5020)
+#define AFE_GASRC15_NEW_CON9 (0x5024)
+#define AFE_GASRC15_NEW_CON10 (0x5028)
+#define AFE_GASRC15_NEW_CON11 (0x502c)
+#define AFE_GASRC15_NEW_CON12 (0x5030)
+#define AFE_GASRC15_NEW_CON13 (0x5034)
+#define AFE_GASRC15_NEW_CON14 (0x5038)
+#define AFE_GASRC16_NEW_CON0 (0x5040)
+#define AFE_GASRC16_NEW_CON1 (0x5044)
+#define AFE_GASRC16_NEW_CON2 (0x5048)
+#define AFE_GASRC16_NEW_CON3 (0x504c)
+#define AFE_GASRC16_NEW_CON4 (0x5050)
+#define AFE_GASRC16_NEW_CON5 (0x5054)
+#define AFE_GASRC16_NEW_CON6 (0x5058)
+#define AFE_GASRC16_NEW_CON7 (0x505c)
+#define AFE_GASRC16_NEW_CON8 (0x5060)
+#define AFE_GASRC16_NEW_CON9 (0x5064)
+#define AFE_GASRC16_NEW_CON10 (0x5068)
+#define AFE_GASRC16_NEW_CON11 (0x506c)
+#define AFE_GASRC16_NEW_CON12 (0x5070)
+#define AFE_GASRC16_NEW_CON13 (0x5074)
+#define AFE_GASRC16_NEW_CON14 (0x5078)
+#define AFE_GASRC17_NEW_CON0 (0x5080)
+#define AFE_GASRC17_NEW_CON1 (0x5084)
+#define AFE_GASRC17_NEW_CON2 (0x5088)
+#define AFE_GASRC17_NEW_CON3 (0x508c)
+#define AFE_GASRC17_NEW_CON4 (0x5090)
+#define AFE_GASRC17_NEW_CON5 (0x5094)
+#define AFE_GASRC17_NEW_CON6 (0x5098)
+#define AFE_GASRC17_NEW_CON7 (0x509c)
+#define AFE_GASRC17_NEW_CON8 (0x50a0)
+#define AFE_GASRC17_NEW_CON9 (0x50a4)
+#define AFE_GASRC17_NEW_CON10 (0x50a8)
+#define AFE_GASRC17_NEW_CON11 (0x50ac)
+#define AFE_GASRC17_NEW_CON12 (0x50b0)
+#define AFE_GASRC17_NEW_CON13 (0x50b4)
+#define AFE_GASRC17_NEW_CON14 (0x50b8)
+#define AFE_GASRC18_NEW_CON0 (0x50c0)
+#define AFE_GASRC18_NEW_CON1 (0x50c4)
+#define AFE_GASRC18_NEW_CON2 (0x50c8)
+#define AFE_GASRC18_NEW_CON3 (0x50cc)
+#define AFE_GASRC18_NEW_CON4 (0x50d0)
+#define AFE_GASRC18_NEW_CON5 (0x50d4)
+#define AFE_GASRC18_NEW_CON6 (0x50d8)
+#define AFE_GASRC18_NEW_CON7 (0x50dc)
+#define AFE_GASRC18_NEW_CON8 (0x50e0)
+#define AFE_GASRC18_NEW_CON9 (0x50e4)
+#define AFE_GASRC18_NEW_CON10 (0x50e8)
+#define AFE_GASRC18_NEW_CON11 (0x50ec)
+#define AFE_GASRC18_NEW_CON12 (0x50f0)
+#define AFE_GASRC18_NEW_CON13 (0x50f4)
+#define AFE_GASRC18_NEW_CON14 (0x50f8)
+#define AFE_GASRC19_NEW_CON0 (0x5100)
+#define AFE_GASRC19_NEW_CON1 (0x5104)
+#define AFE_GASRC19_NEW_CON2 (0x5108)
+#define AFE_GASRC19_NEW_CON3 (0x510c)
+#define AFE_GASRC19_NEW_CON4 (0x5110)
+#define AFE_GASRC19_NEW_CON5 (0x5114)
+#define AFE_GASRC19_NEW_CON6 (0x5118)
+#define AFE_GASRC19_NEW_CON7 (0x511c)
+#define AFE_GASRC19_NEW_CON8 (0x5120)
+#define AFE_GASRC19_NEW_CON9 (0x5124)
+#define AFE_GASRC19_NEW_CON10 (0x5128)
+#define AFE_GASRC19_NEW_CON11 (0x512c)
+#define AFE_GASRC19_NEW_CON12 (0x5130)
+#define AFE_GASRC19_NEW_CON13 (0x5134)
+#define AFE_GASRC19_NEW_CON14 (0x5138)
+
+#define AFE_MAX_REGISTER (AFE_GASRC19_NEW_CON14)
+
+/* ASYS_TOP_CON */
+#define ASYS_TOP_CON_A1SYS_TIMING_ON BIT(0)
+#define ASYS_TOP_CON_A2SYS_TIMING_ON BIT(1)
+#define ASYS_TOP_CON_A3SYS_TIMING_ON BIT(4)
+#define ASYS_TOP_CON_A4SYS_TIMING_ON BIT(5)
+#define ASYS_TOP_CON_26M_TIMING_ON BIT(2)
+
+/* PWR2_TOP_CON0 */
+#define PWR2_TOP_CON_DMIC8_SRC_SEL_MASK GENMASK(31, 29)
+#define PWR2_TOP_CON_DMIC7_SRC_SEL_MASK GENMASK(28, 26)
+#define PWR2_TOP_CON_DMIC6_SRC_SEL_MASK GENMASK(25, 23)
+#define PWR2_TOP_CON_DMIC5_SRC_SEL_MASK GENMASK(22, 20)
+#define PWR2_TOP_CON_DMIC4_SRC_SEL_MASK GENMASK(19, 17)
+#define PWR2_TOP_CON_DMIC3_SRC_SEL_MASK GENMASK(16, 14)
+#define PWR2_TOP_CON_DMIC2_SRC_SEL_MASK GENMASK(13, 11)
+#define PWR2_TOP_CON_DMIC1_SRC_SEL_MASK GENMASK(10, 8)
+#define PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(x) ((x) << 29)
+#define PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(x) ((x) << 26)
+#define PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(x) ((x) << 23)
+#define PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(x) ((x) << 20)
+#define PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(x) ((x) << 17)
+#define PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(x) ((x) << 14)
+#define PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(x) ((x) << 11)
+#define PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(x) ((x) << 8)
+
+/* PWR2_TOP_CON1 */
+#define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1)
+
+/* PCM_INTF_CON1 */
+#define PCM_INTF_CON1_SYNC_OUT_INV BIT(23)
+#define PCM_INTF_CON1_BCLK_OUT_INV BIT(22)
+#define PCM_INTF_CON1_CLK_OUT_INV_MASK GENMASK(23, 22)
+#define PCM_INTF_CON1_SYNC_IN_INV BIT(21)
+#define PCM_INTF_CON1_BCLK_IN_INV BIT(20)
+#define PCM_INTF_CON1_CLK_IN_INV_MASK GENMASK(21, 20)
+#define PCM_INTF_CON1_PCM_24BIT (0x1 << 16)
+#define PCM_INTF_CON1_PCM_16BIT (0x0 << 16)
+#define PCM_INTF_CON1_PCM_BIT_MASK BIT(16)
+#define PCM_INTF_CON1_PCM_WLEN_32BCK (0x0 << 14)
+#define PCM_INTF_CON1_PCM_WLEN_64BCK (0x1 << 14)
+#define PCM_INTF_CON1_PCM_WLEN_MASK BIT(14)
+#define PCM_INTF_CON1_SYNC_LENGTH(x) (((x) & 0x1f) << 9)
+#define PCM_INTF_CON1_SYNC_LENGTH_MASK (0x1f << 9)
+#define PCM_INTF_CON1_PCM_SLAVE (0x1 << 5)
+#define PCM_INTF_CON1_PCM_MASTER (0x0 << 5)
+#define PCM_INTF_CON1_PCM_M_S_MASK BIT(5)
+#define PCM_INTF_CON1_PCM_MODE(x) (((x) & 0x3) << 3)
+#define PCM_INTF_CON1_PCM_MODE_MASK (0x3 << 3)
+#define PCM_INTF_CON1_PCM_FMT(x) (((x) & 0x3) << 1)
+#define PCM_INTF_CON1_PCM_FMT_MASK (0x3 << 1)
+#define PCM_INTF_CON1_PCM_EN BIT(0)
+
+/* PCM_INTF_CON2 */
+#define PCM_INTF_CON2_CLK_DOMAIN_SEL(x) (((x) & 0x3) << 23)
+#define PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK (0x3 << 23)
+#define PCM_INTF_CON2_SYNC_FREQ_MODE(x) (((x) & 0x1f) << 12)
+#define PCM_INTF_CON2_SYNC_FREQ_MODE_MASK (0x1f << 12)
+#define PCM_INTF_CON2_PCM_TX2RX_LPBK BIT(8)
+
+/* AFE_MPHONE_MULTIx_CON0 */
+#define AFE_MPHONE_MULTI_CON0_16BIT_SWAP BIT(3)
+#define AFE_MPHONE_MULTI_CON0_16BIT_SWAP_MASK BIT(3)
+#define AFE_MPHONE_MULTI_CON0_24BIT_DATA (0x1 << 1)
+#define AFE_MPHONE_MULTI_CON0_16BIT_DATA (0x0 << 1)
+#define AFE_MPHONE_MULIT_CON0_24BIT_DATA_MASK BIT(1)
+#define AFE_MPHONE_MULTI_CON0_EN BIT(0)
+#define AFE_MPHONE_MULTI_CON0_EN_MASK BIT(0)
+
+/* AFE_MPHONE_MULTIx_CON1 */
+#define AFE_MPHONE_MULTI_CON1_SYNC_ON BIT(24)
+#define AFE_MPHONE_MULTI_CON1_SYNC_ON_MASK BIT(24)
+#define AFE_MPHONE_MULTI_CON1_24BIT_SWAP_BYPASS BIT(22)
+#define AFE_MPHONE_MULTI_CON1_24BIT_SWAP_BYPASS_MASK BIT(22)
+#define AFE_MPHONE_MULTI_CON1_NON_COMPACT_MODE (0x1 << 19)
+#define AFE_MPHONE_MULTI_CON1_COMPACT_MODE (0x0 << 19)
+#define AFE_MPHONE_MULTI_CON1_NON_COMPACT_MODE_MASK BIT(19)
+#define AFE_MPHONE_MULTI_CON1_HBR_MODE BIT(18)
+#define AFE_MPHONE_MULTI_CON1_HBR_MODE_MASK BIT(18)
+#define AFE_MPHONE_MULTI_CON1_LRCK_32_CYCLE (0x2 << 16)
+#define AFE_MPHONE_MULTI_CON1_LRCK_24_CYCLE (0x1 << 16)
+#define AFE_MPHONE_MULTI_CON1_LRCK_16_CYCLE (0x0 << 16)
+#define AFE_MPHONE_MULTI_CON1_LRCK_CYCLE_SEL_MASK GENMASK(17, 16)
+#define AFE_MPHONE_MULTI_CON1_LRCK_INV BIT(15)
+#define AFE_MPHONE_MULTI_CON1_LRCK_INV_MASK BIT(15)
+#define AFE_MPHONE_MULTI_CON1_DELAY_DATA BIT(14)
+#define AFE_MPHONE_MULTI_CON1_DELAY_DATA_MASK BIT(14)
+#define AFE_MPHONE_MULTI_CON1_LEFT_ALIGN BIT(13)
+#define AFE_MPHONE_MULTI_CON1_LEFT_ALIGN_MASK BIT(13)
+#define AFE_MPHONE_MULTI_CON1_BIT_NUM(x) ((((x) - 1) & 0x1f) << 8)
+#define AFE_MPHONE_MULTI_CON1_BIT_NUM_MASK GENMASK(12, 8)
+#define AFE_MPHONE_MULTI_CON1_BCK_INV BIT(6)
+#define AFE_MPHONE_MULTI_CON1_BCK_INV_MASK BIT(6)
+#define AFE_MPHONE_MULTI_CON1_CH_NUM(x) ((((x) >> 1) - 1) & 0x3)
+#define AFE_MPHONE_MULTI_CON1_CH_NUM_MASK GENMASK(1, 0)
+
+/* AFE_MPHONE_MULTIx_CON2 */
+#define AFE_MPHONE_MULTI_CON2_SEL_SPDIFIN BIT(19)
+#define AFE_MPHONE_MULTI_CON2_SEL_SPDIFIN_MASK BIT(19)
+
+/* AFE_AUD_PAD_TOP */
+#define RG_RX_PROTOCOL2 BIT(3)
+#define RG_RX_FIFO_ON BIT(0)
+
+/* AFE_ADDA_MTKAIF_CFG0 */
+#define MTKAIF_RXIF_CLKINV_ADC BIT(31)
+#define MTKAIF_RXIF_PROTOCOL2 BIT(16)
+#define MTKAIF_TXIF_PROTOCOL2 BIT(4)
+#define MTKAIF_TXIF_8TO5 BIT(2)
+#define MTKAIF_RXIF_8TO5 BIT(1)
+#define MTKAIF_IF_LOOPBACK1 BIT(0)
+
+/* AFE_ADDA_MTKAIF_RX_CFG2 */
+#define MTKAIF_RXIF_DELAY_CYCLE(x) ((x) << 12)
+#define MTKAIF_RXIF_DELAY_CYCLE_MASK GENMASK(15, 12)
+#define MTKAIF_RXIF_DELAY_DATA BIT(8)
+#define MTKAIF_RXIF_DELAY_DATA_SHIFT 8
+
+/* AFE_ADDA_MTKAIF_SYNCWORD_CFG */
+#define ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE BIT(23)
+
+/* AFE_DMICx_UL_SRC_CON0 */
+#define AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH1(x) (((x) & 0x7) << 27)
+#define AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH2(x) (((x) & 0x7) << 24)
+#define AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL BIT(23)
+#define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL BIT(22)
+#define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL BIT(21)
+#define AFE_DMIC_UL_VOICE_MODE(x) (((x) & 0x7) << 17)
+#define AFE_DMIC_UL_CON0_VOCIE_MODE_8K AFE_DMIC_UL_VOICE_MODE(0)
+#define AFE_DMIC_UL_CON0_VOCIE_MODE_16K AFE_DMIC_UL_VOICE_MODE(1)
+#define AFE_DMIC_UL_CON0_VOCIE_MODE_32K AFE_DMIC_UL_VOICE_MODE(2)
+#define AFE_DMIC_UL_CON0_VOCIE_MODE_48K AFE_DMIC_UL_VOICE_MODE(3)
+#define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(x) (((x) & 0x7) << 7)
+#define AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL BIT(10)
+#define AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL BIT(1)
+#define AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL BIT(0)
+
+/* ETDM_INx_AFIFO_CON */
+#define ETDM_IN_USE_AFIFO BIT(8)
+#define ETDM_IN_AFIFO_CLOCK(x) ((x) << 5)
+#define ETDM_IN_AFIFO_CLOCK_MASK GENMASK(7, 5)
+#define ETDM_IN_AFIFO_MODE(x) ((x) << 0)
+#define ETDM_IN_AFIFO_MODE_MASK GENMASK(4, 0)
+
+/* ETDM_COWORK_CON0 */
+#define ETDM_OUT1_SLAVE_SEL(x) ((x) << 20)
+#define ETDM_OUT1_SLAVE_SEL_MASK GENMASK(23, 20)
+#define ETDM_OUT1_SLAVE_SEL_SHIFT 20
+
+/* ETDM_COWORK_CON1 */
+#define ETDM_IN1_SDATA_SEL(x) ((x) << 20)
+#define ETDM_IN1_SDATA_SEL_MASK GENMASK(23, 20)
+#define ETDM_IN1_SDATA_SEL_SHIFT 20
+#define ETDM_IN1_SDATA0_SEL(x) ((x) << 16)
+#define ETDM_IN1_SDATA0_SEL_MASK GENMASK(19, 16)
+#define ETDM_IN1_SDATA0_SEL_SHIFT 16
+#define ETDM_IN1_SLAVE_SEL(x) ((x) << 8)
+#define ETDM_IN1_SLAVE_SEL_MASK GENMASK(11, 8)
+#define ETDM_IN1_SLAVE_SEL_SHIFT 8
+
+/* ETDM_COWORK_CON2 */
+#define ETDM_IN2_SLAVE_SEL(x) ((x) << 24)
+#define ETDM_IN2_SLAVE_SEL_MASK GENMASK(27, 24)
+#define ETDM_IN2_SLAVE_SEL_SHIFT 24
+#define ETDM_OUT3_SLAVE_SEL(x) ((x) << 20)
+#define ETDM_OUT3_SLAVE_SEL_MASK GENMASK(23, 20)
+#define ETDM_OUT3_SLAVE_SEL_SHIFT 20
+#define ETDM_OUT2_SLAVE_SEL(x) ((x) << 8)
+#define ETDM_OUT2_SLAVE_SEL_MASK GENMASK(11, 8)
+#define ETDM_OUT2_SLAVE_SEL_SHIFT 8
+
+/* ETDM_COWORK_CON3 */
+#define ETDM_IN2_SDATA_SEL(x) ((x) << 4)
+#define ETDM_IN2_SDATA_SEL_MASK GENMASK(7, 4)
+#define ETDM_IN2_SDATA_SEL_SHIFT 4
+#define ETDM_IN2_SDATA0_SEL(x) ((x) << 0)
+#define ETDM_IN2_SDATA0_SEL_MASK GENMASK(3, 0)
+#define ETDM_IN2_SDATA0_SEL_SHIFT 0
+
+/* ETDM_x_CONx */
+#define ETDM_CON0_CH_NUM(x) (((x) - 1) << 23)
+#define ETDM_CON0_CH_NUM_MASK GENMASK(27, 23)
+#define ETDM_CON0_WORD_LEN(x) (((x) - 1) << 16)
+#define ETDM_CON0_WORD_LEN_MASK GENMASK(20, 16)
+#define ETDM_CON0_BIT_LEN(x) (((x) - 1) << 11)
+#define ETDM_CON0_BIT_LEN_MASK GENMASK(15, 11)
+#define ETDM_CON0_FORMAT(x) ((x) << 6)
+#define ETDM_CON0_FORMAT_MASK GENMASK(8, 6)
+#define ETDM_CON0_SLAVE_MODE BIT(5)
+#define ETDM_CON0_EN BIT(0)
+
+#define ETDM_OUT_CON0_RELATCH_DOMAIN(x) ((x) << 28)
+#define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK GENMASK(29, 28)
+
+#define ETDM_CON1_MCLK_OUTPUT BIT(16)
+#define ETDM_IN_CON1_LRCK_AUTO_MODE BIT(31)
+#define ETDM_IN_CON1_LRCK_WIDTH(x) (((x) - 1) << 20)
+#define ETDM_IN_CON1_LRCK_WIDTH_MASK GENMASK(29, 20)
+#define ETDM_OUT_CON1_LRCK_AUTO_MODE BIT(29)
+#define ETDM_OUT_CON1_LRCK_WIDTH(x) (((x) - 1) << 19)
+#define ETDM_OUT_CON1_LRCK_WIDTH_MASK GENMASK(28, 19)
+
+#define ETDM_IN_CON2_MULTI_IP_2CH_MODE BIT(31)
+#define ETDM_IN_CON2_MULTI_IP_TOTAL_CH(x) (((x) - 1) << 15)
+#define ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK GENMASK(19, 15)
+#define ETDM_IN_CON2_CLOCK(x) ((x) << 10)
+#define ETDM_IN_CON2_CLOCK_MASK GENMASK(12, 10)
+#define ETDM_IN_CON2_CLOCK_SHIFT 10
+#define ETDM_IN_CON2_UPDATE_GAP(x) ((x) << 5)
+#define ETDM_IN_CON2_UPDATE_GAP_MASK GENMASK(9, 5)
+
+#define ETDM_OUT_CON2_LRCK_DELAY_BCK_INV BIT(30)
+#define ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN BIT(29)
+
+#define ETDM_IN_CON3_FS(x) ((x) << 26)
+#define ETDM_IN_CON3_FS_MASK GENMASK(30, 26)
+#define ETDM_IN_CON3_DISABLE_OUT(x) BIT(((x) & 0xf))
+#define ETDM_IN_CON3_DISABLE_OUT_MASK GENMASK(15, 0)
+
+#define ETDM_IN_CON4_MASTER_LRCK_INV BIT(19)
+#define ETDM_IN_CON4_MASTER_BCK_INV BIT(18)
+#define ETDM_IN_CON4_SLAVE_LRCK_INV BIT(17)
+#define ETDM_IN_CON4_SLAVE_BCK_INV BIT(16)
+
+#define ETDM_OUT_CON4_RELATCH_EN(x) ((x) << 24)
+#define ETDM_OUT_CON4_RELATCH_EN_MASK GENMASK(28, 24)
+#define ETDM_OUT_CON4_CLOCK(x) ((x) << 6)
+#define ETDM_OUT_CON4_CLOCK_MASK GENMASK(8, 6)
+#define ETDM_OUT_CON4_CLOCK_SHIFT 6
+#define ETDM_OUT_CON4_FS(x) ((x) << 0)
+#define ETDM_OUT_CON4_FS_MASK GENMASK(4, 0)
+
+#define ETDM_IN_CON5_LR_SWAP(x) BIT(((x) & 0xf) + 16)
+#define ETDM_IN_CON5_LR_SWAP_MASK GENMASK(31, 16)
+#define ETDM_IN_CON5_ENABLE_ODD(x) BIT(((x) & 0xf))
+#define ETDM_IN_CON5_ENABLE_ODD_MASK GENMASK(15, 0)
+
+#define ETDM_OUT_CON5_MASTER_LRCK_INV BIT(10)
+#define ETDM_OUT_CON5_MASTER_BCK_INV BIT(9)
+#define ETDM_OUT_CON5_SLAVE_LRCK_INV BIT(8)
+#define ETDM_OUT_CON5_SLAVE_BCK_INV BIT(7)
+
+/* AFE_DPTX_CON */
+#define AFE_DPTX_CON_CH_EN(x) (((x) & 0xff) << 8)
+#define AFE_DPTX_CON_CH_EN_2CH (AFE_DPTX_CON_CH_EN(GENMASK(1, 0)))
+#define AFE_DPTX_CON_CH_EN_4CH (AFE_DPTX_CON_CH_EN(GENMASK(3, 0)))
+#define AFE_DPTX_CON_CH_EN_6CH (AFE_DPTX_CON_CH_EN(GENMASK(5, 0)))
+#define AFE_DPTX_CON_CH_EN_8CH (AFE_DPTX_CON_CH_EN(GENMASK(7, 0)))
+#define AFE_DPTX_CON_CH_EN_MASK GENMASK(15, 8)
+#define AFE_DPTX_CON_16BIT (0x1 << 2)
+#define AFE_DPTX_CON_24BIT (0x0 << 2)
+#define AFE_DPTX_CON_16BIT_MASK BIT(2)
+#define AFE_DPTX_CON_CH_NUM(x) (((x) & 0x1) << 1)
+#define AFE_DPTX_CON_CH_NUM_2CH (AFE_DPTX_CON_CH_NUM(0))
+#define AFE_DPTX_CON_CH_NUM_8CH (AFE_DPTX_CON_CH_NUM(1))
+#define AFE_DPTX_CON_CH_NUM_MASK (0x1 << 1)
+#define AFE_DPTX_CON_ON BIT(0)
+#define AFE_DPTX_CON_ON_MASK BIT(0)
+
+/* AFE_ADDA_UL_DL_CON0 */
+#define ADDA_AFE_ON_SHIFT 0
+
+/* AFE_ADDA_DL_SRC2_CON0 */
+#define DL_2_INPUT_MODE_CTL(x) ((x) << 28)
+#define DL_2_INPUT_MODE_CTL_MASK GENMASK(31, 28)
+#define DL_2_CH1_SATURATION_EN_CTL BIT(27)
+#define DL_2_CH2_SATURATION_EN_CTL BIT(26)
+#define DL_2_MUTE_CH1_OFF_CTL_PRE BIT(12)
+#define DL_2_MUTE_CH2_OFF_CTL_PRE BIT(11)
+#define DL_2_VOICE_MODE_CTL_PRE BIT(5)
+#define DL_2_GAIN_ON_CTL_PRE_SHIFT 1
+#define DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT 0
+
+/* AFE_ADDA_DL_SRC2_CON1 */
+#define DL_2_GAIN_CTL_PRE(x) ((x) << 16)
+#define DL_2_GAIN_CTL_PRE_MASK GENMASK(31, 16)
+#define DL_2_GAIN_CTL_PRE_SHIFT 16
+
+/* AFE_ADDA_TOP_CON0 */
+#define C_LOOPBACK_MODE_CTL_MASK GENMASK(15, 12)
+#define DL_INPUT_FROM_SINEGEN (4 << 12)
+
+/* AFE_ADDA_DL_SDM_DCCOMP_CON */
+#define DL_USE_NEW_2ND_SDM BIT(30)
+#define ATTGAIN_CTL_MASK GENMASK(5, 0)
+
+/* AFE_ADDA_UL_SRC_CON0 */
+#define UL_MODE_3P25M_CH2_CTL BIT(22)
+#define UL_MODE_3P25M_CH1_CTL BIT(21)
+#define UL_VOICE_MODE_CTL(x) ((x) << 17)
+#define UL_VOICE_MODE_CTL_MASK GENMASK(19, 17)
+#define UL_LOOPBACK_MODE_CTL BIT(2)
+#define UL_SDM3_LEVEL_CTL BIT(1)
+#define UL_SRC_ON_TMP_CTL_SHIFT 0
+
+#endif
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index b941adcbb8f9..939e7e28486a 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -61,22 +61,6 @@ static void dump_registers(struct ssp_device *ssp)
pxa_ssp_read_reg(ssp, SSACD));
}
-static void pxa_ssp_enable(struct ssp_device *ssp)
-{
- uint32_t sscr0;
-
- sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
- __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-static void pxa_ssp_disable(struct ssp_device *ssp)
-{
- uint32_t sscr0;
-
- sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
- __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4,
int out, struct snd_dmaengine_dai_dma_data *dma)
{
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
index 08a05f0ecad7..ba2a98268ee4 100644
--- a/sound/soc/qcom/apq8016_sbc.c
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -30,6 +30,13 @@ struct apq8016_sbc_data {
#define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17)
#define MIC_CTRL_TLMM_SCLK_EN BIT(1)
#define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16))
+#define SPKR_CTL_TLMM_MCLK_EN BIT(1)
+#define SPKR_CTL_TLMM_SCLK_EN BIT(2)
+#define SPKR_CTL_TLMM_DATA1_EN BIT(3)
+#define SPKR_CTL_TLMM_WS_OUT_SEL_MASK GENMASK(7, 6)
+#define SPKR_CTL_TLMM_WS_OUT_SEL_SEC BIT(6)
+#define SPKR_CTL_TLMM_WS_EN_SEL_MASK GENMASK(19, 18)
+#define SPKR_CTL_TLMM_WS_EN_SEL_SEC BIT(18)
#define DEFAULT_MCLK_RATE 9600000
static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd)
@@ -40,6 +47,7 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_card *card = rtd->card;
struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card);
int i, rval;
+ u32 value;
switch (cpu_dai->id) {
case MI2S_PRIMARY:
@@ -53,6 +61,15 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd)
MIC_CTRL_TLMM_SCLK_EN,
pdata->mic_iomux);
break;
+ case MI2S_SECONDARY:
+ /* Clear TLMM_WS_OUT_SEL and TLMM_WS_EN_SEL fields */
+ value = readl(pdata->spkr_iomux) &
+ ~(SPKR_CTL_TLMM_WS_OUT_SEL_MASK | SPKR_CTL_TLMM_WS_EN_SEL_MASK);
+ /* Configure the Sec MI2S to TLMM */
+ writel(value | SPKR_CTL_TLMM_MCLK_EN | SPKR_CTL_TLMM_SCLK_EN |
+ SPKR_CTL_TLMM_DATA1_EN | SPKR_CTL_TLMM_WS_OUT_SEL_SEC |
+ SPKR_CTL_TLMM_WS_EN_SEL_SEC, pdata->spkr_iomux);
+ break;
case MI2S_TERTIARY:
writel(readl(pdata->mic_iomux) | MIC_CTRL_TER_WS_SLAVE_SEL |
MIC_CTRL_TLMM_SCLK_EN,
diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c
index 1855b805eba2..3d831b635524 100644
--- a/sound/soc/qcom/qdsp6/q6adm.c
+++ b/sound/soc/qcom/qdsp6/q6adm.c
@@ -465,7 +465,7 @@ int q6adm_matrix_map(struct device *dev, int path,
struct apr_pkt *pkt;
uint16_t *copps_list;
int pkt_size, ret, i, copp_idx;
- void *matrix_map = NULL;
+ void *matrix_map;
struct q6copp *copp;
/* Assumes port_ids have already been validated during adm_open */
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 36bf8bd4edd7..9251d8548965 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -1624,7 +1624,7 @@ EXPORT_SYMBOL_GPL(q6asm_write_async);
static void q6asm_reset_buf_state(struct audio_client *ac)
{
- struct audio_port_data *port = NULL;
+ struct audio_port_data *port;
unsigned long flags;
spin_lock_irqsave(&ac->lock, flags);
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index d610b553ea3b..053097b73e28 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -9,7 +9,7 @@ config SND_SOC_ROCKCHIP
config SND_SOC_ROCKCHIP_I2S
tristate "Rockchip I2S Device Driver"
- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+ depends on HAVE_CLK && SND_SOC_ROCKCHIP
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y or M if you want to add support for I2S driver for
@@ -18,7 +18,7 @@ config SND_SOC_ROCKCHIP_I2S
config SND_SOC_ROCKCHIP_PDM
tristate "Rockchip PDM Controller Driver"
- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+ depends on HAVE_CLK && SND_SOC_ROCKCHIP
select SND_SOC_GENERIC_DMAENGINE_PCM
select RATIONAL
help
@@ -28,7 +28,7 @@ config SND_SOC_ROCKCHIP_PDM
config SND_SOC_ROCKCHIP_SPDIF
tristate "Rockchip SPDIF Device Driver"
- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+ depends on HAVE_CLK && SND_SOC_ROCKCHIP
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y or M if you want to add support for SPDIF driver for
@@ -36,7 +36,7 @@ config SND_SOC_ROCKCHIP_SPDIF
config SND_SOC_ROCKCHIP_MAX98090
tristate "ASoC support for Rockchip boards using a MAX98090 codec"
- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
select SND_SOC_ROCKCHIP_I2S
select SND_SOC_MAX98090
select SND_SOC_TS3A227E
@@ -47,7 +47,7 @@ config SND_SOC_ROCKCHIP_MAX98090
config SND_SOC_ROCKCHIP_RT5645
tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
select SND_SOC_ROCKCHIP_I2S
select SND_SOC_RT5645
help
@@ -56,7 +56,7 @@ config SND_SOC_ROCKCHIP_RT5645
config SND_SOC_RK3288_HDMI_ANALOG
tristate "ASoC support multiple codecs for Rockchip RK3288 boards"
- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
select SND_SOC_ROCKCHIP_I2S
select SND_SOC_HDMI_CODEC
select SND_SOC_ES8328_I2C
@@ -68,7 +68,7 @@ config SND_SOC_RK3288_HDMI_ANALOG
config SND_SOC_RK3399_GRU_SOUND
tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards"
- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK && SPI
select SND_SOC_ROCKCHIP_I2S
select SND_SOC_MAX98357A
select SND_SOC_RT5514
diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c
index 0ac5956ba270..313ab650f8d9 100644
--- a/sound/soc/samsung/aries_wm8994.c
+++ b/sound/soc/samsung/aries_wm8994.c
@@ -310,7 +310,7 @@ static int aries_hw_free(struct snd_pcm_substream *substream)
/*
* Main DAI operations
*/
-static struct snd_soc_ops aries_ops = {
+static const struct snd_soc_ops aries_ops = {
.hw_params = aries_hw_params,
.hw_free = aries_hw_free,
};
diff --git a/sound/soc/samsung/arndale.c b/sound/soc/samsung/arndale.c
index 28587375813a..606ac5e33a8e 100644
--- a/sound/soc/samsung/arndale.c
+++ b/sound/soc/samsung/arndale.c
@@ -48,7 +48,7 @@ static int arndale_rt5631_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops arndale_rt5631_ops = {
+static const struct snd_soc_ops arndale_rt5631_ops = {
.hw_params = arndale_rt5631_hw_params,
};
@@ -80,7 +80,7 @@ static int arndale_wm1811_hw_params(struct snd_pcm_substream *substream,
rclk + 1, SND_SOC_CLOCK_IN);
}
-static struct snd_soc_ops arndale_wm1811_ops = {
+static const struct snd_soc_ops arndale_wm1811_ops = {
.hw_params = arndale_wm1811_hw_params,
};
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 8aa78ff640f5..c994e67d1eaf 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -112,7 +112,7 @@ static int h1940_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops h1940_ops = {
+static const struct snd_soc_ops h1940_ops = {
.startup = h1940_startup,
.hw_params = h1940_hw_params,
};
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index a1ff1400857e..390f2dd735ad 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -130,7 +130,7 @@ static int littlemill_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops littlemill_ops = {
+static const struct snd_soc_ops littlemill_ops = {
.hw_params = littlemill_hw_params,
};
diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c
index 1f9a553edf19..a2019535a0b1 100644
--- a/sound/soc/samsung/midas_wm1811.c
+++ b/sound/soc/samsung/midas_wm1811.c
@@ -129,7 +129,7 @@ static int midas_aif1_hw_params(struct snd_pcm_substream *substream,
return midas_start_fll1(rtd, pll_out);
}
-static struct snd_soc_ops midas_aif1_ops = {
+static const struct snd_soc_ops midas_aif1_ops = {
.hw_params = midas_aif1_hw_params,
};
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 9266070e0181..c98b68567a89 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -106,7 +106,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
/*
* Neo1973 WM8753 HiFi DAI opserations.
*/
-static struct snd_soc_ops neo1973_hifi_ops = {
+static const struct snd_soc_ops neo1973_hifi_ops = {
.hw_params = neo1973_hifi_hw_params,
.hw_free = neo1973_hifi_hw_free,
};
@@ -158,7 +158,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
}
-static struct snd_soc_ops neo1973_voice_ops = {
+static const struct snd_soc_ops neo1973_voice_ops = {
.hw_params = neo1973_voice_hw_params,
.hw_free = neo1973_voice_hw_free,
};
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 400a7f77c711..6ea1c8cc9167 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -62,7 +62,7 @@ static struct snd_soc_jack_gpio hp_jack_gpios[] = {
},
};
-static struct snd_soc_ops rx1950_ops = {
+static const struct snd_soc_ops rx1950_ops = {
.startup = rx1950_startup,
.hw_params = rx1950_hw_params,
};
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index c95629becbc3..cee39ad16667 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -70,7 +70,7 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
/*
* SmartQ WM8987 HiFi DAI operations.
*/
-static struct snd_soc_ops smartq_hifi_ops = {
+static const struct snd_soc_ops smartq_hifi_ops = {
.hw_params = smartq_hifi_hw_params,
};
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index ed753a2f202e..78703d095a6f 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -86,7 +86,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,
/*
* SMDK WM8580 DAI operations.
*/
-static struct snd_soc_ops smdk_ops = {
+static const struct snd_soc_ops smdk_ops = {
.hw_params = smdk_hw_params,
};
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 39a7a449f554..7661b637946d 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -73,7 +73,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,
/*
* SMDK WM8994 DAI operations.
*/
-static struct snd_soc_ops smdk_ops = {
+static const struct snd_soc_ops smdk_ops = {
.hw_params = smdk_hw_params,
};
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c
index a01640576f71..029448f5bedb 100644
--- a/sound/soc/samsung/smdk_wm8994pcm.c
+++ b/sound/soc/samsung/smdk_wm8994pcm.c
@@ -85,7 +85,7 @@ static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops smdk_wm8994_pcm_ops = {
+static const struct snd_soc_ops smdk_wm8994_pcm_ops = {
.hw_params = smdk_wm8994_pcm_hw_params,
};
diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c
index 84c2c63d5a87..a2c77e6defec 100644
--- a/sound/soc/samsung/tm2_wm5110.c
+++ b/sound/soc/samsung/tm2_wm5110.c
@@ -126,7 +126,7 @@ static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
return tm2_start_sysclk(rtd->card);
}
-static struct snd_soc_ops tm2_aif1_ops = {
+static const struct snd_soc_ops tm2_aif1_ops = {
.hw_params = tm2_aif1_hw_params,
};
@@ -200,7 +200,7 @@ static int tm2_aif2_hw_free(struct snd_pcm_substream *substream)
return ret;
}
-static struct snd_soc_ops tm2_aif2_ops = {
+static const struct snd_soc_ops tm2_aif2_ops = {
.hw_params = tm2_aif2_hw_params,
.hw_free = tm2_aif2_hw_free,
};
@@ -254,7 +254,7 @@ static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops tm2_hdmi_ops = {
+static const struct snd_soc_ops tm2_hdmi_ops = {
.hw_params = tm2_hdmi_hw_params,
};
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index c962d2c2a7f7..15223d860cb7 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -105,7 +105,7 @@ static int tobermory_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops tobermory_ops = {
+static const struct snd_soc_ops tobermory_ops = {
.hw_params = tobermory_hw_params,
};
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 346c806ba390..ae46f187cc2a 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -45,6 +45,12 @@ config SND_SOC_RCAR
help
This option enables R-Car SRU/SCU/SSIU/SSI sound support
+config SND_SOC_RZ
+ tristate "RZ/G2L series SSIF-2 support"
+ depends on ARCH_R9A07G044 || COMPILE_TEST
+ help
+ This option enables RZ/G2L SSIF-2 sound support.
+
##
## Boards
##
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index 51bd7c81671c..f6fd79948f6a 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -22,3 +22,7 @@ snd-soc-migor-objs := migor.o
obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
+
+# RZ/G2L
+snd-soc-rz-ssi-objs := rz-ssi.o
+obj-$(CONFIG_SND_SOC_RZ) += snd-soc-rz-ssi.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 0ebee1ed06a9..5f1e72edfee0 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -391,9 +391,9 @@ static struct clk *rsnd_adg_create_null_clk(struct rsnd_priv *priv,
struct clk *clk;
clk = clk_register_fixed_rate(dev, name, parent, 0, 0);
- if (IS_ERR(clk)) {
+ if (IS_ERR_OR_NULL(clk)) {
dev_err(dev, "create null clk error\n");
- return NULL;
+ return ERR_CAST(clk);
}
return clk;
@@ -430,9 +430,9 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv)
for (i = 0; i < CLKMAX; i++) {
clk = devm_clk_get(dev, clk_name[i]);
- if (IS_ERR(clk))
+ if (IS_ERR_OR_NULL(clk))
clk = rsnd_adg_null_clk_get(priv);
- if (IS_ERR(clk))
+ if (IS_ERR_OR_NULL(clk))
goto err;
adg->clk[i] = clk;
@@ -582,7 +582,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
if (!count) {
clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
parent_clk_name, 0, req_rate[0]);
- if (IS_ERR(clk))
+ if (IS_ERR_OR_NULL(clk))
goto err;
adg->clkout[CLKOUT] = clk;
@@ -596,7 +596,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
clk = clk_register_fixed_rate(dev, clkout_name[i],
parent_clk_name, 0,
req_rate[0]);
- if (IS_ERR(clk))
+ if (IS_ERR_OR_NULL(clk))
goto err;
adg->clkout[i] = clk;
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 5e382b5c9d45..978bd0406729 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -426,19 +426,19 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
{
- enum rsnd_mod_type playback_mods[] = {
+ static const enum rsnd_mod_type playback_mods[] = {
RSND_MOD_SRC,
RSND_MOD_CMD,
RSND_MOD_SSIU,
};
- enum rsnd_mod_type capture_mods[] = {
+ static const enum rsnd_mod_type capture_mods[] = {
RSND_MOD_CMD,
RSND_MOD_SRC,
RSND_MOD_SSIU,
};
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
struct rsnd_mod *tmod = NULL;
- enum rsnd_mod_type *mods =
+ const enum rsnd_mod_type *mods =
rsnd_io_is_play(io) ?
playback_mods : capture_mods;
int i;
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 82d16e037d9a..16c6e0265749 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -102,7 +102,7 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
if (dmaen->chan)
- dmaengine_terminate_all(dmaen->chan);
+ dmaengine_terminate_sync(dmaen->chan);
return 0;
}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 27f34ca6059d..87e606f688d3 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -165,7 +165,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
static u32 rsnd_ssi_multi_secondaries(struct rsnd_dai_stream *io)
{
- enum rsnd_mod_type types[] = {
+ static const enum rsnd_mod_type types[] = {
RSND_MOD_SSIM1,
RSND_MOD_SSIM2,
RSND_MOD_SSIM3,
@@ -228,7 +228,7 @@ unsigned int rsnd_ssi_clk_query(struct rsnd_dai *rdai,
int param1, int param2, int *idx)
{
struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
- int ssi_clk_mul_table[] = {
+ static const int ssi_clk_mul_table[] = {
1, 2, 4, 8, 16, 6, 12,
};
int j, ret;
@@ -1079,7 +1079,7 @@ static void rsnd_ssi_connect(struct rsnd_mod *mod,
struct rsnd_dai_stream *io)
{
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
- enum rsnd_mod_type types[] = {
+ static const enum rsnd_mod_type types[] = {
RSND_MOD_SSI,
RSND_MOD_SSIM1,
RSND_MOD_SSIM2,
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
new file mode 100644
index 000000000000..fa0cc08f70ec
--- /dev/null
+++ b/sound/soc/sh/rz-ssi.c
@@ -0,0 +1,1074 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Renesas RZ/G2L ASoC Serial Sound Interface (SSIF-2) Driver
+//
+// Copyright (C) 2021 Renesas Electronics Corp.
+// Copyright (C) 2019 Chris Brandt.
+//
+
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <sound/soc.h>
+
+/* REGISTER OFFSET */
+#define SSICR 0x000
+#define SSISR 0x004
+#define SSIFCR 0x010
+#define SSIFSR 0x014
+#define SSIFTDR 0x018
+#define SSIFRDR 0x01c
+#define SSIOFR 0x020
+#define SSISCR 0x024
+
+/* SSI REGISTER BITS */
+#define SSICR_DWL(x) (((x) & 0x7) << 19)
+#define SSICR_SWL(x) (((x) & 0x7) << 16)
+#define SSICR_MST BIT(14)
+#define SSICR_CKDV(x) (((x) & 0xf) << 4)
+
+#define SSICR_CKS BIT(30)
+#define SSICR_TUIEN BIT(29)
+#define SSICR_TOIEN BIT(28)
+#define SSICR_RUIEN BIT(27)
+#define SSICR_ROIEN BIT(26)
+#define SSICR_MST BIT(14)
+#define SSICR_BCKP BIT(13)
+#define SSICR_LRCKP BIT(12)
+#define SSICR_CKDV(x) (((x) & 0xf) << 4)
+#define SSICR_TEN BIT(1)
+#define SSICR_REN BIT(0)
+
+#define SSISR_TUIRQ BIT(29)
+#define SSISR_TOIRQ BIT(28)
+#define SSISR_RUIRQ BIT(27)
+#define SSISR_ROIRQ BIT(26)
+#define SSISR_IIRQ BIT(25)
+
+#define SSIFCR_AUCKE BIT(31)
+#define SSIFCR_SSIRST BIT(16)
+#define SSIFCR_TIE BIT(3)
+#define SSIFCR_RIE BIT(2)
+#define SSIFCR_TFRST BIT(1)
+#define SSIFCR_RFRST BIT(0)
+
+#define SSIFSR_TDC_MASK 0x3f
+#define SSIFSR_TDC_SHIFT 24
+#define SSIFSR_RDC_MASK 0x3f
+#define SSIFSR_RDC_SHIFT 8
+
+#define SSIFSR_TDC(x) (((x) & 0x1f) << 24)
+#define SSIFSR_TDE BIT(16)
+#define SSIFSR_RDC(x) (((x) & 0x1f) << 8)
+#define SSIFSR_RDF BIT(0)
+
+#define SSIOFR_LRCONT BIT(8)
+
+#define SSISCR_TDES(x) (((x) & 0x1f) << 8)
+#define SSISCR_RDFS(x) (((x) & 0x1f) << 0)
+
+/* Pre allocated buffers sizes */
+#define PREALLOC_BUFFER (SZ_32K)
+#define PREALLOC_BUFFER_MAX (SZ_32K)
+
+#define SSI_RATES SNDRV_PCM_RATE_8000_48000 /* 8k-44.1kHz */
+#define SSI_FMTS SNDRV_PCM_FMTBIT_S16_LE
+#define SSI_CHAN_MIN 2
+#define SSI_CHAN_MAX 2
+#define SSI_FIFO_DEPTH 32
+
+struct rz_ssi_priv;
+
+struct rz_ssi_stream {
+ struct rz_ssi_priv *priv;
+ struct snd_pcm_substream *substream;
+ int fifo_sample_size; /* sample capacity of SSI FIFO */
+ int dma_buffer_pos; /* The address for the next DMA descriptor */
+ int period_counter; /* for keeping track of periods transferred */
+ int sample_width;
+ int buffer_pos; /* current frame position in the buffer */
+ int running; /* 0=stopped, 1=running */
+
+ int uerr_num;
+ int oerr_num;
+
+ struct dma_chan *dma_ch;
+
+ int (*transfer)(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm);
+};
+
+struct rz_ssi_priv {
+ void __iomem *base;
+ struct platform_device *pdev;
+ struct reset_control *rstc;
+ struct device *dev;
+ struct clk *sfr_clk;
+ struct clk *clk;
+
+ phys_addr_t phys;
+ int irq_int;
+ int irq_tx;
+ int irq_rx;
+
+ spinlock_t lock;
+
+ /*
+ * The SSI supports full-duplex transmission and reception.
+ * However, if an error occurs, channel reset (both transmission
+ * and reception reset) is required.
+ * So it is better to use as half-duplex (playing and recording
+ * should be done on separate channels).
+ */
+ struct rz_ssi_stream playback;
+ struct rz_ssi_stream capture;
+
+ /* clock */
+ unsigned long audio_mck;
+ unsigned long audio_clk_1;
+ unsigned long audio_clk_2;
+
+ bool lrckp_fsync_fall; /* LR clock polarity (SSICR.LRCKP) */
+ bool bckp_rise; /* Bit clock polarity (SSICR.BCKP) */
+ bool dma_rt;
+};
+
+static void rz_ssi_dma_complete(void *data);
+
+static void rz_ssi_reg_writel(struct rz_ssi_priv *priv, uint reg, u32 data)
+{
+ writel(data, (priv->base + reg));
+}
+
+static u32 rz_ssi_reg_readl(struct rz_ssi_priv *priv, uint reg)
+{
+ return readl(priv->base + reg);
+}
+
+static void rz_ssi_reg_mask_setl(struct rz_ssi_priv *priv, uint reg,
+ u32 bclr, u32 bset)
+{
+ u32 val;
+
+ val = readl(priv->base + reg);
+ val = (val & ~bclr) | bset;
+ writel(val, (priv->base + reg));
+}
+
+static inline struct snd_soc_dai *
+rz_ssi_get_dai(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+ return asoc_rtd_to_cpu(rtd, 0);
+}
+
+static inline bool rz_ssi_stream_is_play(struct rz_ssi_priv *ssi,
+ struct snd_pcm_substream *substream)
+{
+ return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+}
+
+static inline struct rz_ssi_stream *
+rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_pcm_substream *substream)
+{
+ struct rz_ssi_stream *stream = &ssi->playback;
+
+ if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ stream = &ssi->capture;
+
+ return stream;
+}
+
+static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi)
+{
+ return (ssi->playback.dma_ch && (ssi->dma_rt || ssi->capture.dma_ch));
+}
+
+static int rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
+ struct rz_ssi_stream *strm)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&ssi->lock, flags);
+ ret = !!(strm->substream && strm->substream->runtime);
+ spin_unlock_irqrestore(&ssi->lock, flags);
+
+ return ret;
+}
+
+static int rz_ssi_stream_init(struct rz_ssi_priv *ssi,
+ struct rz_ssi_stream *strm,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ strm->substream = substream;
+ strm->sample_width = samples_to_bytes(runtime, 1);
+ strm->dma_buffer_pos = 0;
+ strm->period_counter = 0;
+ strm->buffer_pos = 0;
+
+ strm->oerr_num = 0;
+ strm->uerr_num = 0;
+ strm->running = 0;
+
+ /* fifo init */
+ strm->fifo_sample_size = SSI_FIFO_DEPTH;
+
+ return 0;
+}
+
+static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi,
+ struct rz_ssi_stream *strm)
+{
+ struct snd_soc_dai *dai = rz_ssi_get_dai(strm->substream);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ssi->lock, flags);
+ strm->substream = NULL;
+ spin_unlock_irqrestore(&ssi->lock, flags);
+
+ if (strm->oerr_num > 0)
+ dev_info(dai->dev, "overrun = %d\n", strm->oerr_num);
+
+ if (strm->uerr_num > 0)
+ dev_info(dai->dev, "underrun = %d\n", strm->uerr_num);
+}
+
+static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate,
+ unsigned int channels)
+{
+ static s8 ckdv[16] = { 1, 2, 4, 8, 16, 32, 64, 128,
+ 6, 12, 24, 48, 96, -1, -1, -1 };
+ unsigned int channel_bits = 32; /* System Word Length */
+ unsigned long bclk_rate = rate * channels * channel_bits;
+ unsigned int div;
+ unsigned int i;
+ u32 ssicr = 0;
+ u32 clk_ckdv;
+
+ /* Clear AUCKE so we can set MST */
+ rz_ssi_reg_writel(ssi, SSIFCR, 0);
+
+ /* Continue to output LRCK pin even when idle */
+ rz_ssi_reg_writel(ssi, SSIOFR, SSIOFR_LRCONT);
+ if (ssi->audio_clk_1 && ssi->audio_clk_2) {
+ if (ssi->audio_clk_1 % bclk_rate)
+ ssi->audio_mck = ssi->audio_clk_2;
+ else
+ ssi->audio_mck = ssi->audio_clk_1;
+ }
+
+ /* Clock setting */
+ ssicr |= SSICR_MST;
+ if (ssi->audio_mck == ssi->audio_clk_1)
+ ssicr |= SSICR_CKS;
+ if (ssi->bckp_rise)
+ ssicr |= SSICR_BCKP;
+ if (ssi->lrckp_fsync_fall)
+ ssicr |= SSICR_LRCKP;
+
+ /* Determine the clock divider */
+ clk_ckdv = 0;
+ div = ssi->audio_mck / bclk_rate;
+ /* try to find an match */
+ for (i = 0; i < ARRAY_SIZE(ckdv); i++) {
+ if (ckdv[i] == div) {
+ clk_ckdv = i;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(ckdv)) {
+ dev_err(ssi->dev, "Rate not divisible by audio clock source\n");
+ return -EINVAL;
+ }
+
+ /*
+ * DWL: Data Word Length = 16 bits
+ * SWL: System Word Length = 32 bits
+ */
+ ssicr |= SSICR_CKDV(clk_ckdv);
+ ssicr |= SSICR_DWL(1) | SSICR_SWL(3);
+ rz_ssi_reg_writel(ssi, SSICR, ssicr);
+ rz_ssi_reg_writel(ssi, SSIFCR,
+ (SSIFCR_AUCKE | SSIFCR_TFRST | SSIFCR_RFRST));
+
+ return 0;
+}
+
+static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
+{
+ bool is_play = rz_ssi_stream_is_play(ssi, strm->substream);
+ u32 ssicr, ssifcr;
+
+ ssicr = rz_ssi_reg_readl(ssi, SSICR);
+ ssifcr = rz_ssi_reg_readl(ssi, SSIFCR) & ~0xF;
+
+ /* FIFO interrupt thresholds */
+ if (rz_ssi_is_dma_enabled(ssi))
+ rz_ssi_reg_writel(ssi, SSISCR, 0);
+ else
+ rz_ssi_reg_writel(ssi, SSISCR,
+ SSISCR_TDES(strm->fifo_sample_size / 2 - 1) |
+ SSISCR_RDFS(0));
+
+ /* enable IRQ */
+ if (is_play) {
+ ssicr |= SSICR_TUIEN | SSICR_TOIEN;
+ ssifcr |= SSIFCR_TIE | SSIFCR_RFRST;
+ } else {
+ ssicr |= SSICR_RUIEN | SSICR_ROIEN;
+ ssifcr |= SSIFCR_RIE | SSIFCR_TFRST;
+ }
+
+ rz_ssi_reg_writel(ssi, SSICR, ssicr);
+ rz_ssi_reg_writel(ssi, SSIFCR, ssifcr);
+
+ /* Clear all error flags */
+ rz_ssi_reg_mask_setl(ssi, SSISR,
+ (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ |
+ SSISR_RUIRQ), 0);
+
+ strm->running = 1;
+ ssicr |= is_play ? SSICR_TEN : SSICR_REN;
+ rz_ssi_reg_writel(ssi, SSICR, ssicr);
+
+ return 0;
+}
+
+static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
+{
+ int timeout;
+
+ strm->running = 0;
+
+ /* Disable TX/RX */
+ rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0);
+
+ /* Cancel all remaining DMA transactions */
+ if (rz_ssi_is_dma_enabled(ssi))
+ dmaengine_terminate_async(strm->dma_ch);
+
+ /* Disable irqs */
+ rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN |
+ SSICR_RUIEN | SSICR_ROIEN, 0);
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_TIE | SSIFCR_RIE, 0);
+
+ /* Clear all error flags */
+ rz_ssi_reg_mask_setl(ssi, SSISR,
+ (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ |
+ SSISR_RUIRQ), 0);
+
+ /* Wait for idle */
+ timeout = 100;
+ while (--timeout) {
+ if (rz_ssi_reg_readl(ssi, SSISR) & SSISR_IIRQ)
+ break;
+ udelay(1);
+ }
+
+ if (!timeout)
+ dev_info(ssi->dev, "timeout waiting for SSI idle\n");
+
+ /* Hold FIFOs in reset */
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, 0,
+ SSIFCR_TFRST | SSIFCR_RFRST);
+
+ return 0;
+}
+
+static void rz_ssi_pointer_update(struct rz_ssi_stream *strm, int frames)
+{
+ struct snd_pcm_substream *substream = strm->substream;
+ struct snd_pcm_runtime *runtime;
+ int current_period;
+
+ if (!strm->running || !substream || !substream->runtime)
+ return;
+
+ runtime = substream->runtime;
+ strm->buffer_pos += frames;
+ WARN_ON(strm->buffer_pos > runtime->buffer_size);
+
+ /* ring buffer */
+ if (strm->buffer_pos == runtime->buffer_size)
+ strm->buffer_pos = 0;
+
+ current_period = strm->buffer_pos / runtime->period_size;
+ if (strm->period_counter != current_period) {
+ snd_pcm_period_elapsed(strm->substream);
+ strm->period_counter = current_period;
+ }
+}
+
+static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
+{
+ struct snd_pcm_substream *substream = strm->substream;
+ struct snd_pcm_runtime *runtime;
+ u16 *buf;
+ int fifo_samples;
+ int frames_left;
+ int samples = 0;
+ int i;
+
+ if (!rz_ssi_stream_is_valid(ssi, strm))
+ return -EINVAL;
+
+ runtime = substream->runtime;
+ /* frames left in this period */
+ frames_left = runtime->period_size - (strm->buffer_pos %
+ runtime->period_size);
+ if (frames_left == 0)
+ frames_left = runtime->period_size;
+
+ /* Samples in RX FIFO */
+ fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >>
+ SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK;
+
+ /* Only read full frames at a time */
+ while (frames_left && (fifo_samples >= runtime->channels)) {
+ samples += runtime->channels;
+ fifo_samples -= runtime->channels;
+ frames_left--;
+ }
+
+ /* not enough samples yet */
+ if (samples == 0)
+ return 0;
+
+ /* calculate new buffer index */
+ buf = (u16 *)(runtime->dma_area);
+ buf += strm->buffer_pos * runtime->channels;
+
+ /* Note, only supports 16-bit samples */
+ for (i = 0; i < samples; i++)
+ *buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
+
+ rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
+ rz_ssi_pointer_update(strm, samples / runtime->channels);
+
+ /*
+ * If we finished this period, but there are more samples in
+ * the RX FIFO, call this function again
+ */
+ if (frames_left == 0 && fifo_samples >= runtime->channels)
+ rz_ssi_pio_recv(ssi, strm);
+
+ return 0;
+}
+
+static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
+{
+ struct snd_pcm_substream *substream = strm->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int sample_space;
+ int samples = 0;
+ int frames_left;
+ int i;
+ u32 ssifsr;
+ u16 *buf;
+
+ if (!rz_ssi_stream_is_valid(ssi, strm))
+ return -EINVAL;
+
+ /* frames left in this period */
+ frames_left = runtime->period_size - (strm->buffer_pos %
+ runtime->period_size);
+ if (frames_left == 0)
+ frames_left = runtime->period_size;
+
+ sample_space = strm->fifo_sample_size;
+ ssifsr = rz_ssi_reg_readl(ssi, SSIFSR);
+ sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK;
+
+ /* Only add full frames at a time */
+ while (frames_left && (sample_space >= runtime->channels)) {
+ samples += runtime->channels;
+ sample_space -= runtime->channels;
+ frames_left--;
+ }
+
+ /* no space to send anything right now */
+ if (samples == 0)
+ return 0;
+
+ /* calculate new buffer index */
+ buf = (u16 *)(runtime->dma_area);
+ buf += strm->buffer_pos * runtime->channels;
+
+ /* Note, only supports 16-bit samples */
+ for (i = 0; i < samples; i++)
+ rz_ssi_reg_writel(ssi, SSIFTDR, ((u32)(*buf++) << 16));
+
+ rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_TDE, 0);
+ rz_ssi_pointer_update(strm, samples / runtime->channels);
+
+ return 0;
+}
+
+static irqreturn_t rz_ssi_interrupt(int irq, void *data)
+{
+ struct rz_ssi_stream *strm = NULL;
+ struct rz_ssi_priv *ssi = data;
+ u32 ssisr = rz_ssi_reg_readl(ssi, SSISR);
+
+ if (ssi->playback.substream)
+ strm = &ssi->playback;
+ else if (ssi->capture.substream)
+ strm = &ssi->capture;
+ else
+ return IRQ_HANDLED; /* Left over TX/RX interrupt */
+
+ if (irq == ssi->irq_int) { /* error or idle */
+ if (ssisr & SSISR_TUIRQ)
+ strm->uerr_num++;
+ if (ssisr & SSISR_TOIRQ)
+ strm->oerr_num++;
+ if (ssisr & SSISR_RUIRQ)
+ strm->uerr_num++;
+ if (ssisr & SSISR_ROIRQ)
+ strm->oerr_num++;
+
+ if (ssisr & (SSISR_TUIRQ | SSISR_TOIRQ | SSISR_RUIRQ |
+ SSISR_ROIRQ)) {
+ /* Error handling */
+ /* You must reset (stop/restart) after each interrupt */
+ rz_ssi_stop(ssi, strm);
+
+ /* Clear all flags */
+ rz_ssi_reg_mask_setl(ssi, SSISR, SSISR_TOIRQ |
+ SSISR_TUIRQ | SSISR_ROIRQ |
+ SSISR_RUIRQ, 0);
+
+ /* Add/remove more data */
+ strm->transfer(ssi, strm);
+
+ /* Resume */
+ rz_ssi_start(ssi, strm);
+ }
+ }
+
+ if (!strm->running)
+ return IRQ_HANDLED;
+
+ /* tx data empty */
+ if (irq == ssi->irq_tx)
+ strm->transfer(ssi, &ssi->playback);
+
+ /* rx data full */
+ if (irq == ssi->irq_rx) {
+ strm->transfer(ssi, &ssi->capture);
+ rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi,
+ struct dma_chan *dma_ch, bool is_play)
+{
+ struct dma_slave_config cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+
+ cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+ cfg.dst_addr = ssi->phys + SSIFTDR;
+ cfg.src_addr = ssi->phys + SSIFRDR;
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+
+ return dmaengine_slave_config(dma_ch, &cfg);
+}
+
+static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi,
+ struct rz_ssi_stream *strm)
+{
+ struct snd_pcm_substream *substream = strm->substream;
+ struct dma_async_tx_descriptor *desc;
+ struct snd_pcm_runtime *runtime;
+ enum dma_transfer_direction dir;
+ u32 dma_paddr, dma_size;
+ int amount;
+
+ if (!rz_ssi_stream_is_valid(ssi, strm))
+ return -EINVAL;
+
+ runtime = substream->runtime;
+ if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
+ /*
+ * Stream is ending, so do not queue up any more DMA
+ * transfers otherwise we play partial sound clips
+ * because we can't shut off the DMA quick enough.
+ */
+ return 0;
+
+ dir = rz_ssi_stream_is_play(ssi, substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+
+ /* Always transfer 1 period */
+ amount = runtime->period_size;
+
+ /* DMA physical address and size */
+ dma_paddr = runtime->dma_addr + frames_to_bytes(runtime,
+ strm->dma_buffer_pos);
+ dma_size = frames_to_bytes(runtime, amount);
+ desc = dmaengine_prep_slave_single(strm->dma_ch, dma_paddr, dma_size,
+ dir,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(ssi->dev, "dmaengine_prep_slave_single() fail\n");
+ return -ENOMEM;
+ }
+
+ desc->callback = rz_ssi_dma_complete;
+ desc->callback_param = strm;
+
+ if (dmaengine_submit(desc) < 0) {
+ dev_err(ssi->dev, "dmaengine_submit() fail\n");
+ return -EIO;
+ }
+
+ /* Update DMA pointer */
+ strm->dma_buffer_pos += amount;
+ if (strm->dma_buffer_pos >= runtime->buffer_size)
+ strm->dma_buffer_pos = 0;
+
+ /* Start DMA */
+ dma_async_issue_pending(strm->dma_ch);
+
+ return 0;
+}
+
+static void rz_ssi_dma_complete(void *data)
+{
+ struct rz_ssi_stream *strm = (struct rz_ssi_stream *)data;
+
+ if (!strm->running || !strm->substream || !strm->substream->runtime)
+ return;
+
+ /* Note that next DMA transaction has probably already started */
+ rz_ssi_pointer_update(strm, strm->substream->runtime->period_size);
+
+ /* Queue up another DMA transaction */
+ rz_ssi_dma_transfer(strm->priv, strm);
+}
+
+static void rz_ssi_release_dma_channels(struct rz_ssi_priv *ssi)
+{
+ if (ssi->playback.dma_ch) {
+ dma_release_channel(ssi->playback.dma_ch);
+ ssi->playback.dma_ch = NULL;
+ if (ssi->dma_rt)
+ ssi->dma_rt = false;
+ }
+
+ if (ssi->capture.dma_ch) {
+ dma_release_channel(ssi->capture.dma_ch);
+ ssi->capture.dma_ch = NULL;
+ }
+}
+
+static int rz_ssi_dma_request(struct rz_ssi_priv *ssi, struct device *dev)
+{
+ ssi->playback.dma_ch = dma_request_chan(dev, "tx");
+ if (IS_ERR(ssi->playback.dma_ch))
+ ssi->playback.dma_ch = NULL;
+
+ ssi->capture.dma_ch = dma_request_chan(dev, "rx");
+ if (IS_ERR(ssi->capture.dma_ch))
+ ssi->capture.dma_ch = NULL;
+
+ if (!ssi->playback.dma_ch && !ssi->capture.dma_ch) {
+ ssi->playback.dma_ch = dma_request_chan(dev, "rt");
+ if (IS_ERR(ssi->playback.dma_ch)) {
+ ssi->playback.dma_ch = NULL;
+ goto no_dma;
+ }
+
+ ssi->dma_rt = true;
+ }
+
+ if (!rz_ssi_is_dma_enabled(ssi))
+ goto no_dma;
+
+ if (ssi->playback.dma_ch &&
+ (rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, true) < 0))
+ goto no_dma;
+
+ if (ssi->capture.dma_ch &&
+ (rz_ssi_dma_slave_config(ssi, ssi->capture.dma_ch, false) < 0))
+ goto no_dma;
+
+ return 0;
+
+no_dma:
+ rz_ssi_release_dma_channels(ssi);
+
+ return -ENODEV;
+}
+
+static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);
+ struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream);
+ int ret = 0, i, num_transfer = 1;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* Soft Reset */
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST);
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);
+ udelay(5);
+
+ ret = rz_ssi_stream_init(ssi, strm, substream);
+ if (ret)
+ goto done;
+
+ if (ssi->dma_rt) {
+ bool is_playback;
+
+ is_playback = rz_ssi_stream_is_play(ssi, substream);
+ ret = rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch,
+ is_playback);
+ /* Fallback to pio */
+ if (ret < 0) {
+ ssi->playback.transfer = rz_ssi_pio_send;
+ ssi->capture.transfer = rz_ssi_pio_recv;
+ rz_ssi_release_dma_channels(ssi);
+ }
+ }
+
+ /* For DMA, queue up multiple DMA descriptors */
+ if (rz_ssi_is_dma_enabled(ssi))
+ num_transfer = 4;
+
+ for (i = 0; i < num_transfer; i++) {
+ ret = strm->transfer(ssi, strm);
+ if (ret)
+ goto done;
+ }
+
+ ret = rz_ssi_start(ssi, strm);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ rz_ssi_stop(ssi, strm);
+ rz_ssi_stream_quit(ssi, strm);
+ break;
+ }
+
+done:
+ return ret;
+}
+
+static int rz_ssi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBC_CFC:
+ break;
+ default:
+ dev_err(ssi->dev, "Codec should be clk and frame consumer\n");
+ return -EINVAL;
+ }
+
+ /*
+ * set clock polarity
+ *
+ * "normal" BCLK = Signal is available at rising edge of BCLK
+ * "normal" FSYNC = (I2S) Left ch starts with falling FSYNC edge
+ */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ ssi->bckp_rise = false;
+ ssi->lrckp_fsync_fall = false;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ ssi->bckp_rise = false;
+ ssi->lrckp_fsync_fall = true;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ ssi->bckp_rise = true;
+ ssi->lrckp_fsync_fall = false;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ ssi->bckp_rise = true;
+ ssi->lrckp_fsync_fall = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* only i2s support */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ break;
+ default:
+ dev_err(ssi->dev, "Only I2S mode is supported.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);
+ unsigned int sample_bits = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
+ unsigned int channels = params_channels(params);
+
+ if (sample_bits != 16) {
+ dev_err(ssi->dev, "Unsupported sample width: %d\n",
+ sample_bits);
+ return -EINVAL;
+ }
+
+ if (channels != 2) {
+ dev_err(ssi->dev, "Number of channels not matched: %d\n",
+ channels);
+ return -EINVAL;
+ }
+
+ return rz_ssi_clk_setup(ssi, params_rate(params),
+ params_channels(params));
+}
+
+static const struct snd_soc_dai_ops rz_ssi_dai_ops = {
+ .trigger = rz_ssi_dai_trigger,
+ .set_fmt = rz_ssi_dai_set_fmt,
+ .hw_params = rz_ssi_dai_hw_params,
+};
+
+static const struct snd_pcm_hardware rz_ssi_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .buffer_bytes_max = PREALLOC_BUFFER,
+ .period_bytes_min = 32,
+ .period_bytes_max = 8192,
+ .channels_min = SSI_CHAN_MIN,
+ .channels_max = SSI_CHAN_MAX,
+ .periods_min = 1,
+ .periods_max = 32,
+ .fifo_size = 32 * 2,
+};
+
+static int rz_ssi_pcm_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ snd_soc_set_runtime_hwparams(substream, &rz_ssi_pcm_hardware);
+
+ return snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+}
+
+static snd_pcm_uframes_t rz_ssi_pcm_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_soc_dai *dai = rz_ssi_get_dai(substream);
+ struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);
+ struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream);
+
+ return strm->buffer_pos;
+}
+
+static int rz_ssi_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ rtd->card->snd_card->dev,
+ PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
+ return 0;
+}
+
+static struct snd_soc_dai_driver rz_ssi_soc_dai[] = {
+ {
+ .name = "rz-ssi-dai",
+ .playback = {
+ .rates = SSI_RATES,
+ .formats = SSI_FMTS,
+ .channels_min = SSI_CHAN_MIN,
+ .channels_max = SSI_CHAN_MAX,
+ },
+ .capture = {
+ .rates = SSI_RATES,
+ .formats = SSI_FMTS,
+ .channels_min = SSI_CHAN_MIN,
+ .channels_max = SSI_CHAN_MAX,
+ },
+ .ops = &rz_ssi_dai_ops,
+ },
+};
+
+static const struct snd_soc_component_driver rz_ssi_soc_component = {
+ .name = "rz-ssi",
+ .open = rz_ssi_pcm_open,
+ .pointer = rz_ssi_pcm_pointer,
+ .pcm_construct = rz_ssi_pcm_new,
+};
+
+static int rz_ssi_probe(struct platform_device *pdev)
+{
+ struct rz_ssi_priv *ssi;
+ struct clk *audio_clk;
+ struct resource *res;
+ int ret;
+
+ ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL);
+ if (!ssi)
+ return -ENOMEM;
+
+ ssi->pdev = pdev;
+ ssi->dev = &pdev->dev;
+ ssi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(ssi->base))
+ return PTR_ERR(ssi->base);
+
+ ssi->phys = res->start;
+ ssi->clk = devm_clk_get(&pdev->dev, "ssi");
+ if (IS_ERR(ssi->clk))
+ return PTR_ERR(ssi->clk);
+
+ ssi->sfr_clk = devm_clk_get(&pdev->dev, "ssi_sfr");
+ if (IS_ERR(ssi->sfr_clk))
+ return PTR_ERR(ssi->sfr_clk);
+
+ audio_clk = devm_clk_get(&pdev->dev, "audio_clk1");
+ if (IS_ERR(audio_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk),
+ "no audio clk1");
+
+ ssi->audio_clk_1 = clk_get_rate(audio_clk);
+ audio_clk = devm_clk_get(&pdev->dev, "audio_clk2");
+ if (IS_ERR(audio_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk),
+ "no audio clk2");
+
+ ssi->audio_clk_2 = clk_get_rate(audio_clk);
+ if (!(ssi->audio_clk_1 || ssi->audio_clk_2))
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "no audio clk1 or audio clk2");
+
+ ssi->audio_mck = ssi->audio_clk_1 ? ssi->audio_clk_1 : ssi->audio_clk_2;
+
+ /* Detect DMA support */
+ ret = rz_ssi_dma_request(ssi, &pdev->dev);
+ if (ret < 0) {
+ dev_warn(&pdev->dev, "DMA not available, using PIO\n");
+ ssi->playback.transfer = rz_ssi_pio_send;
+ ssi->capture.transfer = rz_ssi_pio_recv;
+ } else {
+ dev_info(&pdev->dev, "DMA enabled");
+ ssi->playback.transfer = rz_ssi_dma_transfer;
+ ssi->capture.transfer = rz_ssi_dma_transfer;
+ }
+
+ ssi->playback.priv = ssi;
+ ssi->capture.priv = ssi;
+
+ /* Error Interrupt */
+ ssi->irq_int = platform_get_irq_byname(pdev, "int_req");
+ if (ssi->irq_int < 0)
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Unable to get SSI int_req IRQ\n");
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_int, &rz_ssi_interrupt,
+ 0, dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (int_req)\n");
+
+ if (!rz_ssi_is_dma_enabled(ssi)) {
+ /* Tx and Rx interrupts (pio only) */
+ ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx");
+ if (ssi->irq_tx < 0)
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Unable to get SSI dma_tx IRQ\n");
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_tx,
+ &rz_ssi_interrupt, 0,
+ dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (dma_tx)\n");
+
+ ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx");
+ if (ssi->irq_rx < 0)
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Unable to get SSI dma_rx IRQ\n");
+
+ ret = devm_request_irq(&pdev->dev, ssi->irq_rx,
+ &rz_ssi_interrupt, 0,
+ dev_name(&pdev->dev), ssi);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "irq request error (dma_rx)\n");
+ }
+
+ ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(ssi->rstc))
+ return PTR_ERR(ssi->rstc);
+
+ reset_control_deassert(ssi->rstc);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_resume_and_get(&pdev->dev);
+
+ spin_lock_init(&ssi->lock);
+ dev_set_drvdata(&pdev->dev, ssi);
+ ret = devm_snd_soc_register_component(&pdev->dev, &rz_ssi_soc_component,
+ rz_ssi_soc_dai,
+ ARRAY_SIZE(rz_ssi_soc_dai));
+ if (ret < 0) {
+ rz_ssi_release_dma_channels(ssi);
+
+ pm_runtime_put(ssi->dev);
+ pm_runtime_disable(ssi->dev);
+ reset_control_assert(ssi->rstc);
+ dev_err(&pdev->dev, "failed to register snd component\n");
+ }
+
+ return ret;
+}
+
+static int rz_ssi_remove(struct platform_device *pdev)
+{
+ struct rz_ssi_priv *ssi = dev_get_drvdata(&pdev->dev);
+
+ rz_ssi_release_dma_channels(ssi);
+
+ pm_runtime_put(ssi->dev);
+ pm_runtime_disable(ssi->dev);
+ reset_control_assert(ssi->rstc);
+
+ return 0;
+}
+
+static const struct of_device_id rz_ssi_of_match[] = {
+ { .compatible = "renesas,rz-ssi", },
+ {/* Sentinel */},
+};
+MODULE_DEVICE_TABLE(of, rz_ssi_of_match);
+
+static struct platform_driver rz_ssi_driver = {
+ .driver = {
+ .name = "rz-ssi-pcm-audio",
+ .of_match_table = rz_ssi_of_match,
+ },
+ .probe = rz_ssi_probe,
+ .remove = rz_ssi_remove,
+};
+
+module_platform_driver(rz_ssi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas RZ/G2L ASoC Serial Sound Interface Driver");
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index 65db083e242b..5f49e3dec3fc 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -34,14 +34,6 @@ struct snd_ac97_reset_cfg {
int gpio_reset;
};
-struct snd_ac97_gpio_priv {
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
- unsigned int gpios_set;
- struct snd_soc_component *component;
-};
-
static struct snd_ac97_bus soc_ac97_bus = {
.ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
};
@@ -52,6 +44,12 @@ static void soc_ac97_device_release(struct device *dev)
}
#ifdef CONFIG_GPIOLIB
+struct snd_ac97_gpio_priv {
+ struct gpio_chip gpio_chip;
+ unsigned int gpios_set;
+ struct snd_soc_component *component;
+};
+
static inline struct snd_soc_component *gpio_to_component(struct gpio_chip *chip)
{
struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
index c8dfd0de30e4..8e8d917d22f8 100644
--- a/sound/soc/soc-component.c
+++ b/sound/soc/soc-component.c
@@ -1171,10 +1171,10 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
void *stream)
{
struct snd_soc_component *component;
- int i, ret;
+ int i;
for_each_rtd_components(rtd, i, component) {
- ret = pm_runtime_get_sync(component->dev);
+ int ret = pm_runtime_get_sync(component->dev);
if (ret < 0 && ret != -EACCES) {
pm_runtime_put_noidle(component->dev);
return soc_component_ret(component, ret);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 11974d27060e..c830e96afba2 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -580,7 +580,7 @@ int snd_soc_suspend(struct device *dev)
* Due to the resume being scheduled into a workqueue we could
* suspend before that's finished - wait for it to complete.
*/
- snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
+ snd_power_wait(card->snd_card);
/* we're going to block userspace touching us until resume completes */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
@@ -1718,7 +1718,7 @@ static void append_dmi_string(struct snd_soc_card *card, const char *str)
*/
int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
{
- const char *vendor, *product, *product_version, *board;
+ const char *vendor, *product, *board;
if (card->long_name)
return 0; /* long name already set by driver or from DMI */
@@ -1738,13 +1738,14 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
product = dmi_get_system_info(DMI_PRODUCT_NAME);
if (product && is_dmi_valid(product)) {
+ const char *product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);
+
append_dmi_string(card, product);
/*
* some vendors like Lenovo may only put a self-explanatory
* name in the product version field
*/
- product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);
if (product_version && is_dmi_valid(product_version))
append_dmi_string(card, product_version);
}
@@ -2236,13 +2237,12 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
const struct snd_kcontrol_new *controls, int num_controls,
const char *prefix, void *data)
{
- int err, i;
+ int i;
for (i = 0; i < num_controls; i++) {
const struct snd_kcontrol_new *control = &controls[i];
-
- err = snd_ctl_add(card, snd_soc_cnew(control, data,
- control->name, prefix));
+ int err = snd_ctl_add(card, snd_soc_cnew(control, data,
+ control->name, prefix));
if (err < 0) {
dev_err(dev, "ASoC: Failed to add %s: %d\n",
control->name, err);
@@ -2716,11 +2716,10 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);
*/
void snd_soc_unregister_component(struct device *dev)
{
- struct snd_soc_component *component;
-
mutex_lock(&client_mutex);
while (1) {
- component = snd_soc_lookup_component_nolocked(dev, NULL);
+ struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, NULL);
+
if (!component)
break;
@@ -2774,7 +2773,7 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
struct device_node *np = card->dev->of_node;
struct snd_soc_dapm_widget *widgets;
const char *template, *wname;
- int i, j, num_widgets, ret;
+ int i, j, num_widgets;
num_widgets = of_property_count_strings(np, propname);
if (num_widgets < 0) {
@@ -2804,8 +2803,8 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
}
for (i = 0; i < num_widgets; i++) {
- ret = of_property_read_string_index(np, propname,
- 2 * i, &template);
+ int ret = of_property_read_string_index(np, propname,
+ 2 * i, &template);
if (ret) {
dev_err(card->dev,
"ASoC: Property '%s' index %d read error:%d\n",
@@ -2928,7 +2927,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
struct device_node *np = card->dev->of_node;
int num_routes;
struct snd_soc_dapm_route *routes;
- int i, ret;
+ int i;
num_routes = of_property_count_strings(np, propname);
if (num_routes < 0 || num_routes & 1) {
@@ -2948,8 +2947,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
}
for (i = 0; i < num_routes; i++) {
- ret = of_property_read_string_index(np, propname,
- 2 * i, &routes[i].sink);
+ int ret = of_property_read_string_index(np, propname,
+ 2 * i, &routes[i].sink);
if (ret) {
dev_err(card->dev,
"ASoC: Property '%s' index %d could not be read: %d\n",
@@ -3053,7 +3052,7 @@ EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_from_bitmap);
unsigned int snd_soc_daifmt_parse_format(struct device_node *np,
const char *prefix)
{
- int ret, i;
+ int ret;
char prop[128];
unsigned int format = 0;
int bit, frame;
@@ -3087,6 +3086,8 @@ unsigned int snd_soc_daifmt_parse_format(struct device_node *np,
ret = of_property_read_string(np, prop, &str);
}
if (ret == 0) {
+ int i;
+
for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
if (strcmp(str, of_fmt_table[i].name) == 0) {
format |= of_fmt_table[i].val;
@@ -3200,12 +3201,11 @@ int snd_soc_get_dai_name(const struct of_phandle_args *args,
const char **dai_name)
{
struct snd_soc_component *pos;
- struct device_node *component_of_node;
int ret = -EPROBE_DEFER;
mutex_lock(&client_mutex);
for_each_component(pos) {
- component_of_node = soc_component_to_node(pos);
+ struct device_node *component_of_node = soc_component_to_node(pos);
if (component_of_node != args->np)
continue;
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index a56dcc8d6fb7..3db0fcf24385 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -492,18 +492,16 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
*/
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
{
- struct snd_soc_dai_link_component *cpu;
- struct snd_soc_dai_link_component *codec;
- struct snd_soc_dai *dai;
bool supported[SNDRV_PCM_STREAM_LAST + 1];
- bool supported_cpu;
- bool supported_codec;
int direction;
- int i;
for_each_pcm_streams(direction) {
- supported_cpu = false;
- supported_codec = false;
+ struct snd_soc_dai_link_component *cpu;
+ struct snd_soc_dai_link_component *codec;
+ struct snd_soc_dai *dai;
+ bool supported_cpu = false;
+ bool supported_codec = false;
+ int i;
for_each_link_cpus(dai_link, i, cpu) {
dai = snd_soc_find_dai_with_mutex(cpu);
@@ -597,11 +595,11 @@ int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order)
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai;
- int i, ret = 0;
+ int i;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->pcm_new) {
- ret = dai->driver->pcm_new(rtd, dai);
+ int ret = dai->driver->pcm_new(rtd, dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 91bf939d5233..7b67f1e19ae9 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -650,12 +650,11 @@ static struct snd_soc_dapm_widget *
dapm_wcache_lookup(struct snd_soc_dapm_wcache *wcache, const char *name)
{
struct snd_soc_dapm_widget *w = wcache->widget;
- struct list_head *wlist;
- const int depth = 2;
- int i = 0;
if (w) {
- wlist = &w->dapm->card->widgets;
+ struct list_head *wlist = &w->dapm->card->widgets;
+ const int depth = 2;
+ int i = 0;
list_for_each_entry_from(w, wlist, list) {
if (!strcmp(name, w->name))
@@ -748,10 +747,11 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
{
const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, item;
+ unsigned int item;
int i;
if (e->reg != SND_SOC_NOPM) {
+ unsigned int val;
val = soc_dapm_read(dapm, e->reg);
val = (val >> e->shift_l) & e->mask;
item = snd_soc_enum_val_to_item(e, val);
@@ -782,14 +782,14 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i,
struct soc_mixer_control *mc = (struct soc_mixer_control *)
p->sink->kcontrol_news[i].private_value;
unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- unsigned int val;
if (reg != SND_SOC_NOPM) {
- val = soc_dapm_read(p->sink->dapm, reg);
+ unsigned int shift = mc->shift;
+ unsigned int max = mc->max;
+ unsigned int mask = (1 << fls(max)) - 1;
+ unsigned int val = soc_dapm_read(p->sink->dapm, reg);
+
/*
* The nth_path argument allows this function to know
* which path of a kcontrol it is setting the initial
@@ -1060,10 +1060,10 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
/* create new dapm volume control */
static int dapm_new_pga(struct snd_soc_dapm_widget *w)
{
- int i, ret;
+ int i;
for (i = 0; i < w->num_kcontrols; i++) {
- ret = dapm_create_or_share_kcontrol(w, i);
+ int ret = dapm_create_or_share_kcontrol(w, i);
if (ret < 0)
return ret;
}
@@ -1074,10 +1074,7 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
/* create new dapm dai link control */
static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
{
- int i, ret;
- struct snd_kcontrol *kcontrol;
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct snd_card *card = dapm->card->snd_card;
+ int i;
struct snd_soc_pcm_runtime *rtd = w->priv;
/* create control for links with > 1 config */
@@ -1086,9 +1083,12 @@ static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
/* add kcontrol */
for (i = 0; i < w->num_kcontrols; i++) {
- kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w,
- w->name, NULL);
- ret = snd_ctl_add(card, kcontrol);
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_card *card = dapm->card->snd_card;
+ struct snd_kcontrol *kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
+ w, w->name, NULL);
+ int ret = snd_ctl_add(card, kcontrol);
+
if (ret < 0) {
dev_err(dapm->dev,
"ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
@@ -1528,7 +1528,7 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
struct snd_soc_dapm_widget *w, int event)
{
const char *ev_name;
- int power, ret;
+ int power;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1564,6 +1564,8 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
return;
if (w->event && (w->event_flags & event)) {
+ int ret;
+
pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
w->name, ev_name);
soc_dapm_async_complete(w->dapm);
@@ -1645,7 +1647,7 @@ static void dapm_seq_run(struct snd_soc_card *card,
int cur_subseq = -1;
int cur_reg = SND_SOC_NOPM;
struct snd_soc_dapm_context *cur_dapm = NULL;
- int ret, i;
+ int i;
int *sort;
if (power_up)
@@ -1654,7 +1656,7 @@ static void dapm_seq_run(struct snd_soc_card *card,
sort = dapm_down_seq;
list_for_each_entry_safe(w, n, list, power_list) {
- ret = 0;
+ int ret = 0;
/* Do we need to apply any queued changes? */
if (sort[w->id] != cur_sort || w->reg != cur_reg ||
@@ -3004,7 +3006,6 @@ err:
static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route)
{
- struct snd_soc_dapm_widget *wsource, *wsink;
struct snd_soc_dapm_path *path, *p;
const char *sink;
const char *source;
@@ -3042,8 +3043,8 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
}
if (path) {
- wsource = path->source;
- wsink = path->sink;
+ struct snd_soc_dapm_widget *wsource = path->source;
+ struct snd_soc_dapm_widget *wsink = path->sink;
dapm_mark_dirty(wsource, "Route removed");
dapm_mark_dirty(wsink, "Route removed");
@@ -3079,11 +3080,11 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num)
{
- int i, r, ret = 0;
+ int i, ret = 0;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
for (i = 0; i < num; i++) {
- r = snd_soc_dapm_add_route(dapm, route);
+ int r = snd_soc_dapm_add_route(dapm, route);
if (r < 0) {
dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n",
route->source,
@@ -3187,12 +3188,12 @@ static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num)
{
- int i, err;
+ int i;
int ret = 0;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
for (i = 0; i < num; i++) {
- err = snd_soc_dapm_weak_route(dapm, route);
+ int err = snd_soc_dapm_weak_route(dapm, route);
if (err)
ret = err;
route++;
@@ -3783,13 +3784,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num)
{
- struct snd_soc_dapm_widget *w;
int i;
int ret = 0;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
for (i = 0; i < num; i++) {
- w = snd_soc_dapm_new_control_unlocked(dapm, widget);
+ struct snd_soc_dapm_widget *w = snd_soc_dapm_new_control_unlocked(dapm, widget);
if (IS_ERR(w)) {
ret = PTR_ERR(w);
break;
@@ -4365,11 +4365,12 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
int event)
{
struct snd_soc_dapm_widget *w;
- unsigned int ep;
w = snd_soc_dai_get_widget(dai, stream);
if (w) {
+ unsigned int ep;
+
dapm_mark_dirty(w, "stream event");
if (w->id == snd_soc_dapm_dai_in) {
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 9ef80a48707e..4aa48c74f21a 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -79,7 +79,6 @@ static int dmaengine_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_hw_params *params,
struct dma_slave_config *slave_config);
struct dma_slave_config slave_config;
- int ret;
memset(&slave_config, 0, sizeof(slave_config));
@@ -89,7 +88,7 @@ static int dmaengine_pcm_hw_params(struct snd_soc_component *component,
prepare_slave_config = pcm->config->prepare_slave_config;
if (prepare_slave_config) {
- ret = prepare_slave_config(substream, params, &slave_config);
+ int ret = prepare_slave_config(substream, params, &slave_config);
if (ret)
return ret;
@@ -230,7 +229,6 @@ static int dmaengine_pcm_new(struct snd_soc_component *component,
struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
const struct snd_dmaengine_pcm_config *config = pcm->config;
struct device *dev = component->dev;
- struct snd_pcm_substream *substream;
size_t prealloc_buffer_size;
size_t max_buffer_size;
unsigned int i;
@@ -244,7 +242,7 @@ static int dmaengine_pcm_new(struct snd_soc_component *component,
}
for_each_pcm_streams(i) {
- substream = rtd->pcm->streams[i].substream;
+ struct snd_pcm_substream *substream = rtd->pcm->streams[i].substream;
if (!substream)
continue;
@@ -307,14 +305,13 @@ static int dmaengine_copy_user(struct snd_soc_component *component,
bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
void *dma_ptr = runtime->dma_area + hwoff +
channel * (runtime->dma_bytes / runtime->channels);
- int ret;
if (is_playback)
if (copy_from_user(dma_ptr, buf, bytes))
return -EFAULT;
if (process) {
- ret = process(substream, channel, hwoff, (__force void *)buf, bytes);
+ int ret = process(substream, channel, hwoff, (__force void *)buf, bytes);
if (ret < 0)
return ret;
}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 0f1820f36b4d..d798765d168c 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -17,12 +17,6 @@
#include <linux/suspend.h>
#include <trace/events/asoc.h>
-struct jack_gpio_tbl {
- int count;
- struct snd_soc_jack *jack;
- struct snd_soc_jack_gpio *gpios;
-};
-
/**
* snd_soc_jack_report - Report the current status for a jack
*
@@ -42,7 +36,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
struct snd_soc_dapm_context *dapm;
struct snd_soc_jack_pin *pin;
unsigned int sync = 0;
- int enable;
if (!jack)
return;
@@ -58,7 +51,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
trace_snd_soc_jack_notify(jack, status);
list_for_each_entry(pin, &jack->pins, list) {
- enable = pin->mask & jack->status;
+ int enable = pin->mask & jack->status;
if (pin->invert)
enable = !enable;
@@ -208,6 +201,12 @@ void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);
#ifdef CONFIG_GPIOLIB
+struct jack_gpio_tbl {
+ int count;
+ struct snd_soc_jack *jack;
+ struct snd_soc_jack_gpio *gpios;
+};
+
/* gpio detect */
static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
{
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 58527247df83..08eaa9ddf191 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -407,7 +407,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
int min = mc->min;
unsigned int mask = (1U << (fls(min + max) - 1)) - 1;
int err = 0;
- unsigned int val, val_mask, val2;
+ unsigned int val, val_mask;
val_mask = mask << shift;
val = (ucontrol->value.integer.value[0] + min) & mask;
@@ -418,6 +418,8 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
return err;
if (snd_soc_volsw_is_stereo(mc)) {
+ unsigned int val2;
+
val_mask = mask << rshift;
val2 = (ucontrol->value.integer.value[1] + min) & mask;
val2 = val2 << rshift;
@@ -573,7 +575,6 @@ int snd_soc_limit_volume(struct snd_soc_card *card,
const char *name, int max)
{
struct snd_kcontrol *kctl;
- struct soc_mixer_control *mc;
int ret = -EINVAL;
/* Sanity check for name and max */
@@ -582,7 +583,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card,
kctl = snd_soc_card_get_kcontrol(card, name);
if (kctl) {
- mc = (struct soc_mixer_control *)kctl->private_value;
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
if (max <= mc->max) {
mc->platform_max = max;
ret = 0;
@@ -811,11 +812,10 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
long min = mc->min;
long max = mc->max;
long val = 0;
- unsigned int regval;
unsigned int i;
for (i = 0; i < regcount; i++) {
- regval = snd_soc_component_read(component, regbase+i);
+ unsigned int regval = snd_soc_component_read(component, regbase+i);
val |= (regval & regwmask) << (regwshift*(regcount-i-1));
}
val &= mask;
@@ -856,17 +856,16 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
unsigned long mask = (1UL<<mc->nbits)-1;
long max = mc->max;
long val = ucontrol->value.integer.value[0];
- unsigned int i, regval, regmask;
- int err;
+ unsigned int i;
if (invert)
val = max - val;
val &= mask;
for (i = 0; i < regcount; i++) {
- regval = (val >> (regwshift*(regcount-i-1))) & regwmask;
- regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask;
- err = snd_soc_component_update_bits(component, regbase+i,
- regmask, regval);
+ unsigned int regval = (val >> (regwshift*(regcount-i-1))) & regwmask;
+ unsigned int regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask;
+ int err = snd_soc_component_update_bits(component, regbase+i,
+ regmask, regval);
if (err < 0)
return err;
}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index d1c570ca21ea..48f71bb81a2f 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -449,13 +449,12 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai;
struct snd_soc_dai *codec_dai;
- struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
int stream = substream->stream;
int i;
unsigned int bits = 0, cpu_bits = 0;
for_each_rtd_codec_dais(rtd, i, codec_dai) {
- pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream);
+ struct snd_soc_pcm_stream *pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream);
if (pcm_codec->sig_bits == 0) {
bits = 0;
@@ -465,7 +464,7 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
}
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
- pcm_cpu = snd_soc_dai_get_pcm_stream(cpu_dai, stream);
+ struct snd_soc_pcm_stream *pcm_cpu = snd_soc_dai_get_pcm_stream(cpu_dai, stream);
if (pcm_cpu->sig_bits == 0) {
cpu_bits = 0;
@@ -634,10 +633,10 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *component;
- int i, r, ret = 0;
+ int i, ret = 0;
for_each_rtd_components(rtd, i, component) {
- r = snd_soc_component_close(component, substream, rollback);
+ int r = snd_soc_component_close(component, substream, rollback);
if (r < 0)
ret = r; /* use last ret */
@@ -1318,13 +1317,12 @@ void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
static bool dpcm_be_is_active(struct snd_soc_dpcm *dpcm, int stream,
struct snd_soc_dapm_widget_list *list)
{
- struct snd_soc_dapm_widget *widget;
struct snd_soc_dai *dai;
unsigned int i;
/* is there a valid DAI widget for this BE */
for_each_rtd_dais(dpcm->be, i, dai) {
- widget = snd_soc_dai_get_widget(dai, stream);
+ struct snd_soc_dapm_widget *widget = snd_soc_dai_get_widget(dai, stream);
/*
* The BE is pruned only if none of the dai
@@ -1637,7 +1635,6 @@ static void dpcm_runtime_setup_be_chan(struct snd_pcm_substream *substream)
for_each_dpcm_be(fe, stream, dpcm) {
struct snd_soc_pcm_runtime *be = dpcm->be;
- struct snd_soc_pcm_stream *codec_stream;
struct snd_soc_pcm_stream *cpu_stream;
struct snd_soc_dai *dai;
int i;
@@ -1660,7 +1657,8 @@ static void dpcm_runtime_setup_be_chan(struct snd_pcm_substream *substream)
* DAIs connected to a single CPU DAI, use CPU DAI's directly
*/
if (be->num_codecs == 1) {
- codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream);
+ struct snd_soc_pcm_stream *codec_stream = snd_soc_dai_get_pcm_stream(
+ asoc_rtd_to_codec(be, 0), stream);
soc_pcm_hw_update_chan(hw, codec_stream);
}
@@ -2591,9 +2589,7 @@ open_end:
static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
int *playback, int *capture)
{
- struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai;
- int stream;
int i;
if (rtd->dai_link->dynamic && rtd->num_cpus > 1) {
@@ -2603,6 +2599,8 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
}
if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
+ int stream;
+
if (rtd->dai_link->dpcm_playback) {
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -2637,6 +2635,8 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
}
}
} else {
+ struct snd_soc_dai *codec_dai;
+
/* Adapt stream for codec2codec links */
int cpu_capture = rtd->dai_link->params ?
SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 0a24d0d409d2..f6e5ac3e0314 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -1035,7 +1035,6 @@ err_denum:
static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
struct snd_soc_tplg_hdr *hdr)
{
- struct snd_soc_tplg_ctl_hdr *control_hdr;
int ret;
int i;
@@ -1043,8 +1042,7 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
soc_tplg_get_offset(tplg));
for (i = 0; i < le32_to_cpu(hdr->count); i++) {
-
- control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
+ struct snd_soc_tplg_ctl_hdr *control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
if (le32_to_cpu(control_hdr->size) != sizeof(*control_hdr)) {
dev_err(tplg->dev, "ASoC: invalid control size\n");
@@ -1583,15 +1581,16 @@ err:
static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg,
struct snd_soc_tplg_hdr *hdr)
{
- struct snd_soc_tplg_dapm_widget *widget;
- int ret, count, i;
+ int count, i;
count = le32_to_cpu(hdr->count);
dev_dbg(tplg->dev, "ASoC: adding %d DAPM widgets\n", count);
for (i = 0; i < count; i++) {
- widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos;
+ struct snd_soc_tplg_dapm_widget *widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos;
+ int ret;
+
if (le32_to_cpu(widget->size) != sizeof(*widget)) {
dev_err(tplg->dev, "ASoC: invalid widget size\n");
return -EINVAL;
@@ -2125,10 +2124,9 @@ static struct snd_soc_dai_link *snd_soc_find_dai_link(struct snd_soc_card *card,
const char *stream_name)
{
struct snd_soc_pcm_runtime *rtd;
- struct snd_soc_dai_link *link;
for_each_card_rtds(card, rtd) {
- link = rtd->dai_link;
+ struct snd_soc_dai_link *link = rtd->dai_link;
if (link->id != id)
continue;
@@ -2346,15 +2344,16 @@ err:
static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
struct snd_soc_tplg_hdr *hdr)
{
- struct snd_soc_tplg_dai *dai;
int count;
- int i, ret;
+ int i;
count = le32_to_cpu(hdr->count);
/* config the existing BE DAIs */
for (i = 0; i < count; i++) {
- dai = (struct snd_soc_tplg_dai *)tplg->pos;
+ struct snd_soc_tplg_dai *dai = (struct snd_soc_tplg_dai *)tplg->pos;
+ int ret;
+
if (le32_to_cpu(dai->size) != sizeof(*dai)) {
dev_err(tplg->dev, "ASoC: invalid physical DAI size\n");
return -EINVAL;
@@ -2572,13 +2571,13 @@ static int soc_tplg_load_header(struct soc_tplg *tplg,
/* process the topology file headers */
static int soc_tplg_process_headers(struct soc_tplg *tplg)
{
- struct snd_soc_tplg_hdr *hdr;
int ret;
tplg->pass = SOC_TPLG_PASS_START;
/* process the header types from start to end */
while (tplg->pass <= SOC_TPLG_PASS_END) {
+ struct snd_soc_tplg_hdr *hdr;
tplg->hdr_pos = tplg->fw->data;
hdr = (struct snd_soc_tplg_hdr *)tplg->hdr_pos;
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 4447f515e8b1..88b6176af021 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -249,16 +249,6 @@ config SND_SOC_SOF_HDA_PROBES
Say Y if you want to enable probes.
If unsure, select "N".
-config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1
- bool "SOF enable DMI Link L1"
- help
- This option enables DMI L1 for both playback and capture
- and disables known workarounds for specific HDAudio platforms.
- Only use to look into power optimizations on platforms not
- affected by DMI L1 issues. This option is not recommended.
- Say Y if you want to enable DMI Link L1.
- If unsure, select "N".
-
endif ## SND_SOC_SOF_HDA_COMMON
config SND_SOC_SOF_HDA_LINK_BASELINE
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 821f25fbcf08..e115e12a856f 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -347,6 +347,9 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
.rom_init_timeout = 300,
.ssp_count = CNL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
@@ -363,5 +366,8 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(jsl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index df00db8369c7..cc8ddef37f37 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -15,6 +15,7 @@
* Hardware interface for generic Intel audio DSP HDA IP
*/
+#include <linux/moduleparam.h>
#include <sound/hda_register.h>
#include <sound/pcm_params.h>
#include "../sof-audio.h"
@@ -27,6 +28,10 @@
#define SDnFMT_BITS(x) ((x) << 4)
#define SDnFMT_CHAN(x) ((x) << 0)
+static bool hda_always_enable_dmi_l1;
+module_param_named(always_enable_dmi_l1, hda_always_enable_dmi_l1, bool, 0444);
+MODULE_PARM_DESC(always_enable_dmi_l1, "SOF HDA always enable DMI l1");
+
u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate)
{
switch (rate) {
@@ -216,6 +221,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_component *scomp = sdev->component;
struct hdac_ext_stream *dsp_stream;
struct snd_sof_pcm *spcm;
@@ -228,8 +234,14 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
return -EINVAL;
}
- /* All playback and D0i3 compatible streams are DMI L1 capable */
- if (direction == SNDRV_PCM_STREAM_PLAYBACK ||
+ /*
+ * All playback streams are DMI L1 capable, capture streams need
+ * pause push/release to be disabled
+ */
+ if (hda_always_enable_dmi_l1 && direction == SNDRV_PCM_STREAM_CAPTURE)
+ runtime->hw.info &= ~SNDRV_PCM_INFO_PAUSE;
+
+ if (hda_always_enable_dmi_l1 ||
spcm->stream[substream->stream].d0i3_compatible)
flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE;
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 40a3993ae2cb..63c367478f1c 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -197,11 +197,10 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
* Workaround to address a known issue with host DMA that results
* in xruns during pause/release in capture scenarios.
*/
- if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
- if (stream && !(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE))
- snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
- HDA_VS_INTEL_EM2,
- HDA_VS_INTEL_EM2_L1SEN, 0);
+ if (!(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE))
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
+ HDA_VS_INTEL_EM2,
+ HDA_VS_INTEL_EM2_L1SEN, 0);
return stream;
}
@@ -240,7 +239,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
spin_unlock_irq(&bus->reg_lock);
/* Enable DMI L1 if permitted */
- if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1) && dmi_l1_enable)
+ if (dmi_l1_enable)
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2,
HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN);
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 891e6e1b9121..f60e2c57d3d0 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -41,6 +41,17 @@
#define EXCEPT_MAX_HDR_SIZE 0x400
#define HDA_EXT_ROM_STATUS_SIZE 8
+static const struct sof_intel_dsp_desc
+ *get_chip_info(struct snd_sof_pdata *pdata)
+{
+ const struct sof_dev_desc *desc = pdata->desc;
+ const struct sof_intel_dsp_desc *chip_info;
+
+ chip_info = desc->chip_info;
+
+ return chip_info;
+}
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
/*
@@ -155,6 +166,8 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
memset(&res, 0, sizeof(res));
res.mmio_base = sdev->bar[HDA_DSP_BAR];
+ res.shim_base = hdev->desc->sdw_shim_base;
+ res.alh_base = hdev->desc->sdw_alh_base;
res.irq = sdev->ipc_irq;
res.handle = hdev->info.handle;
res.parent = sdev->dev;
@@ -215,7 +228,7 @@ static int hda_sdw_exit(struct snd_sof_dev *sdev)
return 0;
}
-static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
+bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hdev;
bool ret = false;
@@ -241,6 +254,17 @@ out:
return ret;
}
+static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
+{
+ const struct sof_intel_dsp_desc *chip;
+
+ chip = get_chip_info(sdev->pdata);
+ if (chip && chip->check_sdw_irq)
+ return chip->check_sdw_irq(sdev);
+
+ return false;
+}
+
static irqreturn_t hda_dsp_sdw_thread(int irq, void *context)
{
return sdw_intel_thread(irq, context);
@@ -253,7 +277,7 @@ static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev)
hdev = sdev->pdata->hw_pdata;
if (hdev->sdw &&
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
- HDA_DSP_REG_SNDW_WAKE_STS))
+ hdev->desc->sdw_shim_base + SDW_SHIM_WAKESTS))
return true;
return false;
@@ -672,17 +696,6 @@ skip_soundwire:
return 0;
}
-static const struct sof_intel_dsp_desc
- *get_chip_info(struct snd_sof_pdata *pdata)
-{
- const struct sof_dev_desc *desc = pdata->desc;
- const struct sof_intel_dsp_desc *chip_info;
-
- chip_info = desc->chip_info;
-
- return chip_info;
-}
-
static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context)
{
struct snd_sof_dev *sdev = context;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 4d44f8910393..4fdfb108645c 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -233,7 +233,6 @@
#define HDA_DSP_REG_ADSPIS2 (HDA_DSP_GEN_BASE + 0x14)
#define HDA_DSP_REG_ADSPIS2_SNDW BIT(5)
-#define HDA_DSP_REG_SNDW_WAKE_STS 0x2C192
/* Intel HD Audio Inter-Processor Communication Registers */
#define HDA_DSP_IPC_BASE 0x40
@@ -692,6 +691,7 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);
int hda_sdw_startup(struct snd_sof_dev *sdev);
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable);
void hda_sdw_process_wakeen(struct snd_sof_dev *sdev);
+bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev);
#else
@@ -737,6 +737,12 @@ static inline bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev)
static inline void hda_sdw_process_wakeen(struct snd_sof_dev *sdev)
{
}
+
+static inline bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev)
+{
+ return false;
+}
+
#endif
/* common dai driver */
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index 88a74be8a0c1..ee095b8f2d01 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -142,5 +142,8 @@ const struct sof_intel_dsp_desc icl_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c
index 4ee1da397d4e..4bded668b672 100644
--- a/sound/soc/sof/intel/pci-tng.c
+++ b/sound/soc/sof/intel/pci-tng.c
@@ -15,7 +15,6 @@
#include <sound/sof.h>
#include "../ops.h"
#include "atom.h"
-#include "shim.h"
#include "../sof-pci-dev.h"
#include "../sof-audio.h"
diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h
index 529f68d0ca47..e9f7d4d7fcce 100644
--- a/sound/soc/sof/intel/shim.h
+++ b/sound/soc/sof/intel/shim.h
@@ -164,6 +164,9 @@ struct sof_intel_dsp_desc {
int rom_init_timeout;
int ssp_count; /* ssp count of the platform */
int ssp_base_offset; /* base address of the SSPs */
+ u32 sdw_shim_base;
+ u32 sdw_alh_base;
+ bool (*check_sdw_irq)(struct snd_sof_dev *sdev);
};
extern const struct snd_sof_dsp_ops sof_tng_ops;
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index 2ed788304414..199d41a7dc9b 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -137,6 +137,9 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
@@ -153,6 +156,9 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(tglh_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
@@ -169,6 +175,9 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(ehl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
@@ -185,5 +194,8 @@ const struct sof_intel_dsp_desc adls_chip_info = {
.rom_init_timeout = 300,
.ssp_count = ICL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
+ .sdw_shim_base = SDW_SHIM_BASE,
+ .sdw_alh_base = SDW_ALH_BASE,
+ .check_sdw_irq = hda_common_check_sdw_irq,
};
EXPORT_SYMBOL_NS(adls_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 510883cd9107..989912f2b739 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -433,11 +433,10 @@ struct snd_sof_dai *snd_sof_find_dai(struct snd_soc_component *scomp,
return NULL;
}
-/*
- * Helper to get SSP MCLK from a pcm_runtime.
- * Return 0 if not exist.
- */
-int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd)
+#define SOF_DAI_CLK_INTEL_SSP_MCLK 0
+#define SOF_DAI_CLK_INTEL_SSP_BCLK 1
+
+static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
{
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
@@ -450,17 +449,46 @@ int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd)
switch (dai->dai_config->type) {
case SOF_DAI_INTEL_SSP:
- return dai->dai_config->ssp.mclk_rate;
+ switch (clk_type) {
+ case SOF_DAI_CLK_INTEL_SSP_MCLK:
+ return dai->dai_config->ssp.mclk_rate;
+ case SOF_DAI_CLK_INTEL_SSP_BCLK:
+ return dai->dai_config->ssp.bclk_rate;
+ default:
+ dev_err(rtd->dev, "fail to get SSP clk %d rate\n",
+ clk_type);
+ return -EINVAL;
+ }
+ break;
default:
/* not yet implemented for platforms other than the above */
- dev_err(rtd->dev, "mclk for dai_config->type %d not supported yet!\n",
+ dev_err(rtd->dev, "DAI type %d not supported yet!\n",
dai->dai_config->type);
return -EINVAL;
}
}
+
+/*
+ * Helper to get SSP MCLK from a pcm_runtime.
+ * Return 0 if not exist.
+ */
+int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd)
+{
+ return sof_dai_get_clk(rtd, SOF_DAI_CLK_INTEL_SSP_MCLK);
+}
EXPORT_SYMBOL(sof_dai_get_mclk);
/*
+ * Helper to get SSP BCLK from a pcm_runtime.
+ * Return 0 if not exist.
+ */
+int sof_dai_get_bclk(struct snd_soc_pcm_runtime *rtd)
+{
+ return sof_dai_get_clk(rtd, SOF_DAI_CLK_INTEL_SSP_BCLK);
+}
+EXPORT_SYMBOL(sof_dai_get_bclk);
+
+/*
* SOF Driver enumeration.
*/
int sof_machine_check(struct snd_sof_dev *sdev)
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index 03119462f9e2..bc9e70765678 100644
--- a/sound/soc/sof/sof-pci-dev.c
+++ b/sound/soc/sof/sof-pci-dev.c
@@ -50,6 +50,15 @@ static const struct dmi_system_id sof_tplg_table[] = {
},
.driver_data = "sof-tgl-rt5682-ssp0-max98373-ssp2.tplg",
},
+ {
+ .callback = sof_tplg_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
+ DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
+ },
+ .driver_data = "sof-adl-rt5682-ssp0-max98373-ssp2.tplg",
+ },
{}
};
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index b3e1df693381..ef011a488ceb 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -512,16 +512,14 @@ static const struct of_device_id tegra30_ahub_of_match[] = {
static int tegra30_ahub_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
const struct tegra30_ahub_soc_data *soc_data;
struct resource *res0;
void __iomem *regs_apbif, *regs_ahub;
int ret = 0;
- match = of_match_device(tegra30_ahub_of_match, &pdev->dev);
- if (!match)
+ soc_data = of_device_get_match_data(&pdev->dev);
+ if (!soc_data)
return -EINVAL;
- soc_data = match->data;
ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
GFP_KERNEL);
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 36344f0a64c1..084a533bf4f2 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -406,7 +406,7 @@ static const struct of_device_id tegra30_i2s_of_match[] = {
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra30_i2s *i2s;
- const struct of_device_id *match;
+ const struct tegra30_i2s_soc_data *soc_data;
u32 cif_ids[2];
void __iomem *regs;
int ret;
@@ -418,13 +418,13 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
}
dev_set_drvdata(&pdev->dev, i2s);
- match = of_match_device(tegra30_i2s_of_match, &pdev->dev);
- if (!match) {
+ soc_data = of_device_get_match_data(&pdev->dev);
+ if (!soc_data) {
dev_err(&pdev->dev, "Error: No device match found\n");
ret = -ENODEV;
goto err;
}
- i2s->soc_data = (struct tegra30_i2s_soc_data *)match->data;
+ i2s->soc_data = soc_data;
i2s->dai = tegra30_i2s_dai_template;
i2s->dai.name = dev_name(&pdev->dev);
diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig
index 698d7bc84dcf..1d9fe3fca193 100644
--- a/sound/soc/ti/Kconfig
+++ b/sound/soc/ti/Kconfig
@@ -35,6 +35,7 @@ config SND_SOC_DAVINCI_MCASP
various Texas Instruments SoCs like:
- daVinci devices
- Sitara line of SoCs (AM335x, AM438x, etc)
+ - OMAP4
- DRA7x devices
- Keystone devices
- K3 devices (am654, j721e)
diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c
index aba0017e870b..ecd24d412a9b 100644
--- a/sound/soc/ti/ams-delta.c
+++ b/sound/soc/ti/ams-delta.c
@@ -337,8 +337,8 @@ static int cx81801_hangup(struct tty_struct *tty)
}
/* Line discipline .receive_buf() */
-static void cx81801_receive(struct tty_struct *tty,
- const unsigned char *cp, char *fp, int count)
+static void cx81801_receive(struct tty_struct *tty, const unsigned char *cp,
+ const char *fp, int count)
{
struct snd_soc_component *component = tty->disc_data;
const unsigned char *c;
@@ -396,6 +396,7 @@ static void cx81801_wakeup(struct tty_struct *tty)
static struct tty_ldisc_ops cx81801_ops = {
.name = "cx81801",
+ .num = N_V253,
.owner = THIS_MODULE,
.open = cx81801_open,
.close = cx81801_close,
@@ -503,7 +504,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Register optional line discipline for over the modem control */
- ret = tty_register_ldisc(N_V253, &cx81801_ops);
+ ret = tty_register_ldisc(&cx81801_ops);
if (ret) {
dev_warn(card->dev,
"Failed to register line discipline, "
@@ -582,9 +583,7 @@ static int ams_delta_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- if (tty_unregister_ldisc(N_V253) != 0)
- dev_warn(&pdev->dev,
- "failed to unregister V253 line discipline\n");
+ tty_unregister_ldisc(&cx81801_ops);
snd_soc_unregister_card(card);
card->dev = NULL;
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c
index 017a5a5e56cd..56a19eeec5c7 100644
--- a/sound/soc/ti/davinci-mcasp.c
+++ b/sound/soc/ti/davinci-mcasp.c
@@ -83,6 +83,8 @@ struct davinci_mcasp {
struct snd_pcm_substream *substreams[2];
unsigned int dai_fmt;
+ u32 iec958_status;
+
/* Audio can not be enabled due to missing parameter(s) */
bool missing_audio_param;
@@ -757,6 +759,9 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
+ return 0;
+
dev_dbg(mcasp->dev,
"%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
__func__, tx_mask, rx_mask, slots, slot_width);
@@ -827,6 +832,20 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate),
RXROT(7));
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask);
+ } else {
+ /*
+ * according to the TRM it should be TXROT=0, this one works:
+ * 16 bit to 23-8 (TXROT=6, rotate 24 bits)
+ * 24 bit to 23-0 (TXROT=0, rotate 0 bits)
+ *
+ * TXROT = 0 only works with 24bit samples
+ */
+ tx_rotate = (sample_width / 4 + 2) & 0x7;
+
+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate),
+ TXROT(7));
+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(15),
+ TXSSZ(0x0F));
}
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask);
@@ -842,10 +861,16 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
u8 tx_ser = 0;
u8 rx_ser = 0;
u8 slots = mcasp->tdm_slots;
- u8 max_active_serializers = (channels + slots - 1) / slots;
- u8 max_rx_serializers, max_tx_serializers;
+ u8 max_active_serializers, max_rx_serializers, max_tx_serializers;
int active_serializers, numevt;
u32 reg;
+
+ /* In DIT mode we only allow maximum of one serializers for now */
+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
+ max_active_serializers = 1;
+ else
+ max_active_serializers = (channels + slots - 1) / slots;
+
/* Default configuration */
if (mcasp->version < MCASP_VERSION_3)
mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
@@ -1031,16 +1056,18 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
unsigned int rate)
{
- u32 cs_value = 0;
- u8 *cs_bytes = (u8*) &cs_value;
+ u8 *cs_bytes = (u8 *)&mcasp->iec958_status;
- /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
- and LSB first */
- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
+ if (!mcasp->dat_port)
+ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSEL);
+ else
+ mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSEL);
/* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE | FSXMOD(0x180));
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, 0xFFFF);
+
/* Set the TX tdm : for all the slots */
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
@@ -1049,16 +1076,8 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
- /* Only 44100 and 48000 are valid, both have the same setting */
- mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
-
- /* Enable the DIT */
- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
-
/* Set S/PDIF channel status bits */
- cs_bytes[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
- cs_bytes[1] = IEC958_AES1_CON_PCM_CODER;
-
+ cs_bytes[3] &= ~IEC958_AES3_CON_FS;
switch (rate) {
case 22050:
cs_bytes[3] |= IEC958_AES3_CON_FS_22050;
@@ -1088,12 +1107,15 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
cs_bytes[3] |= IEC958_AES3_CON_FS_192000;
break;
default:
- printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
+ dev_err(mcasp->dev, "unsupported sampling rate: %d\n", rate);
return -EINVAL;
}
- mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, cs_value);
- mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, cs_value);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, mcasp->iec958_status);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, mcasp->iec958_status);
+
+ /* Enable the DIT */
+ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
return 0;
}
@@ -1237,12 +1259,18 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
int slots = mcasp->tdm_slots;
int rate = params_rate(params);
int sbits = params_width(params);
+ unsigned int bclk_target;
if (mcasp->slot_width)
sbits = mcasp->slot_width;
+ if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE)
+ bclk_target = rate * sbits * slots;
+ else
+ bclk_target = rate * 128;
+
davinci_mcasp_calc_clk_div(mcasp, mcasp->sysclk_freq,
- rate * sbits * slots, true);
+ bclk_target, true);
}
ret = mcasp_common_hw_param(mcasp, substream->stream,
@@ -1598,6 +1626,77 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.set_tdm_slot = davinci_mcasp_set_tdm_slot,
};
+static int davinci_mcasp_iec958_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+
+ return 0;
+}
+
+static int davinci_mcasp_iec958_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uctl)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+
+ memcpy(uctl->value.iec958.status, &mcasp->iec958_status,
+ sizeof(mcasp->iec958_status));
+
+ return 0;
+}
+
+static int davinci_mcasp_iec958_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uctl)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+
+ memcpy(&mcasp->iec958_status, uctl->value.iec958.status,
+ sizeof(mcasp->iec958_status));
+
+ return 0;
+}
+
+static int davinci_mcasp_iec958_con_mask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+
+ memset(ucontrol->value.iec958.status, 0xff, sizeof(mcasp->iec958_status));
+ return 0;
+}
+
+static const struct snd_kcontrol_new davinci_mcasp_iec958_ctls[] = {
+ {
+ .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE),
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .info = davinci_mcasp_iec958_info,
+ .get = davinci_mcasp_iec958_get,
+ .put = davinci_mcasp_iec958_put,
+ }, {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
+ .info = davinci_mcasp_iec958_info,
+ .get = davinci_mcasp_iec958_con_mask_get,
+ },
+};
+
+static void davinci_mcasp_init_iec958_status(struct davinci_mcasp *mcasp)
+{
+ unsigned char *cs = (u8 *)&mcasp->iec958_status;
+
+ cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
+ cs[1] = IEC958_AES1_CON_PCM_CODER;
+ cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
+ cs[3] = IEC958_AES3_CON_CLOCK_1000PPM;
+}
+
static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
@@ -1605,6 +1704,12 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
dai->playback_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
dai->capture_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) {
+ davinci_mcasp_init_iec958_status(mcasp);
+ snd_soc_add_dai_controls(dai, davinci_mcasp_iec958_ctls,
+ ARRAY_SIZE(davinci_mcasp_iec958_ctls));
+ }
+
return 0;
}
@@ -1651,7 +1756,8 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
.channels_min = 1,
.channels_max = 384,
.rates = DAVINCI_MCASP_RATES,
- .formats = DAVINCI_MCASP_PCM_FMTS,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE,
},
.ops = &davinci_mcasp_dai_ops,
},
@@ -1688,6 +1794,12 @@ static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
.version = MCASP_VERSION_4,
};
+static struct davinci_mcasp_pdata omap_mcasp_pdata = {
+ .tx_dma_offset = 0x200,
+ .rx_dma_offset = 0,
+ .version = MCASP_VERSION_OMAP,
+};
+
static const struct of_device_id mcasp_dt_ids[] = {
{
.compatible = "ti,dm646x-mcasp-audio",
@@ -1705,6 +1817,10 @@ static const struct of_device_id mcasp_dt_ids[] = {
.compatible = "ti,dra7-mcasp-audio",
.data = &dra7_mcasp_pdata,
},
+ {
+ .compatible = "ti,omap4-mcasp-audio",
+ .data = &omap_mcasp_pdata,
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
@@ -1871,6 +1987,8 @@ out:
} else {
mcasp->tdm_slots = pdata->tdm_slots;
}
+ } else {
+ mcasp->tdm_slots = 32;
}
mcasp->num_serializer = pdata->num_serializer;
@@ -2242,10 +2360,17 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
dma_data->filter_data = "tx";
- if (dat)
+ if (dat) {
dma_data->addr = dat->start;
- else
+ /*
+ * According to the TRM there should be 0x200 offset added to
+ * the DAT port address
+ */
+ if (mcasp->version == MCASP_VERSION_OMAP)
+ dma_data->addr += davinci_mcasp_txdma_offset(mcasp->pdata);
+ } else {
dma_data->addr = mem->start + davinci_mcasp_txdma_offset(mcasp->pdata);
+ }
/* RX is not valid in DIT mode */
@@ -2310,7 +2435,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
ret = edma_pcm_platform_register(&pdev->dev);
break;
case PCM_SDMA:
- ret = sdma_pcm_platform_register(&pdev->dev, "tx", "rx");
+ if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE)
+ ret = sdma_pcm_platform_register(&pdev->dev, "tx", "rx");
+ else
+ ret = sdma_pcm_platform_register(&pdev->dev, "tx", NULL);
break;
case PCM_UDMA:
ret = udma_pcm_platform_register(&pdev->dev);
diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c
index 265bbc5a2f96..9347f982c3e1 100644
--- a/sound/soc/ti/j721e-evm.c
+++ b/sound/soc/ti/j721e-evm.c
@@ -23,8 +23,11 @@
*/
#define J721E_CODEC_CONF_COUNT 5
-#define J721E_AUDIO_DOMAIN_CPB 0
-#define J721E_AUDIO_DOMAIN_IVI 1
+enum j721e_audio_domain_id {
+ J721E_AUDIO_DOMAIN_CPB = 0,
+ J721E_AUDIO_DOMAIN_IVI,
+ J721E_AUDIO_DOMAIN_LAST,
+};
#define J721E_CLK_PARENT_48000 0
#define J721E_CLK_PARENT_44100 1
@@ -78,7 +81,7 @@ struct j721e_priv {
u32 pll_rates[2];
unsigned int hsdiv_rates[2];
- struct j721e_audio_domain audio_domains[2];
+ struct j721e_audio_domain audio_domains[J721E_AUDIO_DOMAIN_LAST];
struct mutex mutex;
};
@@ -199,9 +202,8 @@ static int j721e_configure_refclk(struct j721e_priv *priv,
if (domain->parent_clk_id == -1 || priv->hsdiv_rates[domain->parent_clk_id] != scki) {
dev_dbg(priv->dev,
- "%s configuration for %u Hz: %s, %dxFS (SCKI: %u Hz)\n",
- audio_domain == J721E_AUDIO_DOMAIN_CPB ? "CPB" : "IVI",
- rate,
+ "domain%u configuration for %u Hz: %s, %dxFS (SCKI: %u Hz)\n",
+ audio_domain, rate,
clk_id == J721E_CLK_PARENT_48000 ? "PLL4" : "PLL15",
ratios_for_pcm3168a[i], scki);
@@ -263,10 +265,11 @@ static int j721e_audio_startup(struct snd_pcm_substream *substream)
domain->active++;
- if (priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].rate)
- active_rate = priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].rate;
- else
- active_rate = priv->audio_domains[J721E_AUDIO_DOMAIN_IVI].rate;
+ for (i = 0; i < J721E_AUDIO_DOMAIN_LAST; i++) {
+ active_rate = priv->audio_domains[i].rate;
+ if (active_rate)
+ break;
+ }
if (active_rate)
ret = snd_pcm_hw_constraint_single(substream->runtime,
@@ -825,7 +828,7 @@ static int j721e_soc_probe(struct platform_device *pdev)
struct snd_soc_card *card;
const struct of_device_id *match;
struct j721e_priv *priv;
- int link_cnt, conf_cnt, ret;
+ int link_cnt, conf_cnt, ret, i;
if (!node) {
dev_err(&pdev->dev, "of node is missing.\n");
@@ -849,8 +852,9 @@ static int j721e_soc_probe(struct platform_device *pdev)
if (!priv->dai_links)
return -ENOMEM;
- priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].parent_clk_id = -1;
- priv->audio_domains[J721E_AUDIO_DOMAIN_IVI].parent_clk_id = -1;
+ for (i = 0; i < J721E_AUDIO_DOMAIN_LAST; i++)
+ priv->audio_domains[i].parent_clk_id = -1;
+
priv->dev = &pdev->dev;
card = &priv->card;
card->dev = &pdev->dev;
diff --git a/sound/soc/ti/omap-abe-twl6040.c b/sound/soc/ti/omap-abe-twl6040.c
index 91cc9a4f44d7..2e3d1eea77c1 100644
--- a/sound/soc/ti/omap-abe-twl6040.c
+++ b/sound/soc/ti/omap-abe-twl6040.c
@@ -292,11 +292,6 @@ static int omap_abe_probe(struct platform_device *pdev)
card->fully_routed = 1;
- if (!priv->mclk_freq) {
- dev_err(&pdev->dev, "MCLK frequency missing\n");
- return -ENODEV;
- }
-
card->dai_link = priv->dai_links;
card->num_links = num_links;
diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index cf9814130067..4e8d5f7532ba 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -128,8 +128,8 @@ static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
{
struct uniphier_aio_pll *pll;
- int mul[] = { 1, 1, 1, 2, };
- int div[] = { 2, 3, 1, 3, };
+ static const int mul[] = { 1, 1, 1, 2, };
+ static const int div[] = { 2, 3, 1, 3, };
int i;
if (!is_valid_pll(aio->chip, pll_id))
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index d24ae00878f5..c434b69a83f1 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -975,8 +975,9 @@ static int snd_amd7930_create(struct snd_card *card,
spin_unlock_irqrestore(&amd->lock, flags);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- amd, &snd_amd7930_dev_ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+ amd, &snd_amd7930_dev_ops);
+ if (err < 0) {
snd_amd7930_free(amd);
return err;
}
@@ -1019,13 +1020,16 @@ static int amd7930_sbus_probe(struct platform_device *op)
irq, dev_num, &amd)) < 0)
goto out_err;
- if ((err = snd_amd7930_pcm(amd)) < 0)
+ err = snd_amd7930_pcm(amd);
+ if (err < 0)
goto out_err;
- if ((err = snd_amd7930_mixer(amd)) < 0)
+ err = snd_amd7930_mixer(amd);
+ if (err < 0)
goto out_err;
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto out_err;
amd->next = amd7930_list;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 35c17803a430..2942c8c7a236 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1828,8 +1828,9 @@ static int snd_cs4231_sbus_create(struct snd_card *card,
}
snd_cs4231_init(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &snd_cs4231_sbus_dev_ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+ chip, &snd_cs4231_sbus_dev_ops);
+ if (err < 0) {
snd_cs4231_sbus_free(chip);
return err;
}
@@ -2020,8 +2021,9 @@ static int snd_cs4231_ebus_create(struct snd_card *card,
}
snd_cs4231_init(chip);
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &snd_cs4231_ebus_dev_ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+ chip, &snd_cs4231_ebus_dev_ops);
+ if (err < 0) {
snd_cs4231_ebus_free(chip);
return err;
}
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index b055f5839578..6b84f66e4af4 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2226,11 +2226,12 @@ static int snd_dbri_pcm(struct snd_card *card)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card,
- /* ID */ "sun_dbri",
- /* device */ 0,
- /* playback count */ 1,
- /* capture count */ 1, &pcm)) < 0)
+ err = snd_pcm_new(card,
+ /* ID */ "sun_dbri",
+ /* device */ 0,
+ /* playback count */ 1,
+ /* capture count */ 1, &pcm);
+ if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index f65e6c7b139f..49d1976a132c 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -104,7 +104,8 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch
if (emu->sflist == NULL)
return -ENOMEM;
- if ((err = snd_emux_init_hwdep(emu)) < 0)
+ err = snd_emux_init_hwdep(emu);
+ if (err < 0)
return err;
snd_emux_init_voices(emu);
diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c
index afd119b11f39..3c7314f5fb19 100644
--- a/sound/synth/emux/emux_effect.c
+++ b/sound/synth/emux/emux_effect.c
@@ -181,7 +181,10 @@ snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
fx->flag[type] = mode;
/* do we need to modify the register in realtime ? */
- if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
+ if (!parm_defs[type].update)
+ return;
+ offset = parm_defs[type].offset;
+ if (offset < 0)
return;
#ifdef SNDRV_LITTLE_ENDIAN
@@ -223,13 +226,17 @@ snd_emux_setup_effect(struct snd_emux_voice *vp)
unsigned char *srcp;
int i;
- if (! (fx = chan->private))
+ fx = chan->private;
+ if (!fx)
return;
/* modify the register values via effect table */
for (i = 0; i < EMUX_FX_END; i++) {
int offset;
- if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
+ if (!fx->flag[i])
+ continue;
+ offset = parm_defs[i].offset;
+ if (offset < 0)
continue;
#ifdef SNDRV_LITTLE_ENDIAN
if (parm_defs[i].type & PARM_IS_ALIGN_HI)
diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c
index 8a965e2f160a..81719bfb8ed7 100644
--- a/sound/synth/emux/emux_hwdep.c
+++ b/sound/synth/emux/emux_hwdep.c
@@ -116,7 +116,8 @@ snd_emux_init_hwdep(struct snd_emux *emu)
struct snd_hwdep *hw;
int err;
- if ((err = snd_hwdep_new(emu->card, SNDRV_EMUX_HWDEP_NAME, emu->hwdep_idx, &hw)) < 0)
+ err = snd_hwdep_new(emu->card, SNDRV_EMUX_HWDEP_NAME, emu->hwdep_idx, &hw);
+ if (err < 0)
return err;
emu->hwdep = hw;
strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
@@ -127,7 +128,8 @@ snd_emux_init_hwdep(struct snd_emux *emu)
hw->ops.ioctl_compat = snd_emux_hwdep_ioctl;
hw->exclusive = 1;
hw->private_data = emu;
- if ((err = snd_card_register(emu->card)) < 0)
+ err = snd_card_register(emu->card);
+ if (err < 0)
return err;
return 0;
diff --git a/sound/synth/emux/emux_nrpn.c b/sound/synth/emux/emux_nrpn.c
index 7eed5791972c..8056422ed7c5 100644
--- a/sound/synth/emux/emux_nrpn.c
+++ b/sound/synth/emux/emux_nrpn.c
@@ -69,7 +69,7 @@ static const int gs_sense[] =
DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
};
-/* effect sensitivies for XG controls:
+/* effect sensitivities for XG controls:
* adjusted for chaos 8MB soundfonts
*/
static const int xg_sense[] =
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 9ebc711afa6b..16f00097cb95 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -108,7 +108,7 @@ snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
* Deal with a soundfont patch. Any driver could use these routines
* although it was designed for the AWE64.
*
- * The sample_write and callargs pararameters allow a callback into
+ * The sample_write and callargs parameters allow a callback into
* the actual driver to write sample data to the board or whatever
* it wants to do with it.
*/
@@ -349,7 +349,8 @@ sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
{
struct snd_sf_zone *zp;
- if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
+ zp = kzalloc(sizeof(*zp), GFP_KERNEL);
+ if (!zp)
return NULL;
zp->next = sf->zones;
sf->zones = zp;
@@ -381,7 +382,8 @@ sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
{
struct snd_sf_sample *sp;
- if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
+ sp = kzalloc(sizeof(*sp), GFP_KERNEL);
+ if (!sp)
return NULL;
sp->next = sf->samples;
@@ -451,7 +453,8 @@ load_map(struct snd_sf_list *sflist, const void __user *data, int count)
}
/* create a new zone */
- if ((zp = sf_zone_new(sflist, sf)) == NULL)
+ zp = sf_zone_new(sflist, sf);
+ if (!zp)
return -ENOMEM;
zp->bank = map.map_bank;
@@ -514,7 +517,8 @@ load_info(struct snd_sf_list *sflist, const void __user *data, long count)
int i;
/* patch must be opened */
- if ((sf = sflist->currsf) == NULL)
+ sf = sflist->currsf;
+ if (!sf)
return -EINVAL;
if (is_special_type(sf->type))
@@ -579,9 +583,9 @@ load_info(struct snd_sf_list *sflist, const void __user *data, long count)
init_voice_parm(&tmpzone.v.parm);
/* create a new zone */
- if ((zone = sf_zone_new(sflist, sf)) == NULL) {
+ zone = sf_zone_new(sflist, sf);
+ if (!zone)
return -ENOMEM;
- }
/* copy the temporary data */
zone->bank = tmpzone.bank;
@@ -700,7 +704,8 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
long off;
/* patch must be opened */
- if ((sf = sflist->currsf) == NULL)
+ sf = sflist->currsf;
+ if (!sf)
return -EINVAL;
if (is_special_type(sf->type))
@@ -723,7 +728,8 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
}
/* Allocate a new sample structure */
- if ((sp = sf_sample_new(sflist, sf)) == NULL)
+ sp = sf_sample_new(sflist, sf);
+ if (!sp)
return -ENOMEM;
sp->v = sample_info;
@@ -793,7 +799,7 @@ snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
amount <<= 1;
s = (amount >> 24) & 0x7f;
low = (amount >> 16) & 0xff;
- /* linear approxmimation by lower 8 bit */
+ /* linear approximation by lower 8 bit */
v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
v -= offset;
v = (v * ratio) >> 16;
@@ -958,7 +964,8 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data,
sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
if (sf == NULL)
return -ENOMEM;
- if ((smp = sf_sample_new(sflist, sf)) == NULL)
+ smp = sf_sample_new(sflist, sf);
+ if (!smp)
return -ENOMEM;
sample_id = sflist->sample_counter;
smp->v.sample = sample_id;
@@ -996,7 +1003,8 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data,
smp->v.sf_id = sf->id;
/* set up voice info */
- if ((zone = sf_zone_new(sflist, sf)) == NULL) {
+ zone = sf_zone_new(sflist, sf);
+ if (!zone) {
sf_sample_delete(sflist, sf, smp);
return -ENOMEM;
}
@@ -1181,7 +1189,8 @@ add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
}
/* prepend this zone */
- if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
+ index = get_index(cur->bank, cur->instr, cur->v.low);
+ if (index < 0)
return;
cur->next_zone = zone; /* zone link */
cur->next_instr = sflist->presets[index]; /* preset table link */
@@ -1197,7 +1206,8 @@ delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
int index;
struct snd_sf_zone *p;
- if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
+ index = get_index(zp->bank, zp->instr, zp->v.low);
+ if (index < 0)
return;
for (p = sflist->presets[index]; p; p = p->next_instr) {
while (p->next_instr == zp) {
@@ -1257,7 +1267,8 @@ search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
int index;
struct snd_sf_zone *zp;
- if ((index = get_index(bank, preset, key)) < 0)
+ index = get_index(bank, preset, key);
+ if (index < 0)
return NULL;
for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
if (zp->instr == preset && zp->bank == bank)
@@ -1386,7 +1397,8 @@ snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
{
struct snd_sf_list *sflist;
- if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
+ sflist = kzalloc(sizeof(*sflist), GFP_KERNEL);
+ if (!sflist)
return NULL;
mutex_init(&sflist->presets_mutex);
@@ -1421,7 +1433,7 @@ snd_sf_free(struct snd_sf_list *sflist)
/*
* Remove all samples
- * The soundcard should be silet before calling this function.
+ * The soundcard should be silent before calling this function.
*/
int
snd_soundfont_remove_samples(struct snd_sf_list *sflist)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index a741e7da83a2..6c0a052a28f9 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -19,7 +19,7 @@ struct audioformat {
unsigned char iface; /* interface number */
unsigned char altsetting; /* corresponding alternate setting */
unsigned char ep_idx; /* endpoint array index */
- unsigned char altset_idx; /* array index of altenate setting */
+ unsigned char altset_idx; /* array index of alternate setting */
unsigned char attributes; /* corresponding attributes of cs endpoint */
unsigned char endpoint; /* endpoint */
unsigned char ep_attr; /* endpoint attributes */
@@ -54,6 +54,7 @@ struct snd_urb_ctx {
struct snd_usb_endpoint *ep;
int index; /* index for urb array */
int packets; /* number of packets per urb */
+ int queued; /* queued data bytes by this urb */
int packet_size[MAX_PACKS_HS]; /* size of packets for next submission */
struct list_head ready_list;
};
@@ -157,9 +158,12 @@ struct snd_usb_substream {
unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */
unsigned int running: 1; /* running status */
+ unsigned int period_elapsed_pending; /* delay period handling */
+ unsigned int buffer_bytes; /* buffer size in bytes */
+ unsigned int inflight_bytes; /* in-flight data bytes on buffer (for playback) */
unsigned int hwptr_done; /* processed byte position in the buffer */
- unsigned int transfer_done; /* processed frames since last period update */
+ unsigned int transfer_done; /* processed frames since last period update */
unsigned int frame_limit; /* limits number of packets in URB */
/* data and sync endpoints for this stream */
@@ -174,8 +178,7 @@ struct snd_usb_substream {
struct list_head fmt_list; /* format list */
spinlock_t lock;
- int last_frame_number; /* stored frame number */
- int last_delay; /* stored delay */
+ unsigned int last_frame_number; /* stored frame number */
struct {
int marker;
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 17bbde73d4d1..52de52288e10 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -21,82 +21,77 @@
#include "clock.h"
#include "quirks.h"
+union uac23_clock_source_desc {
+ struct uac_clock_source_descriptor v2;
+ struct uac3_clock_source_descriptor v3;
+};
+
+union uac23_clock_selector_desc {
+ struct uac_clock_selector_descriptor v2;
+ struct uac3_clock_selector_descriptor v3;
+};
+
+union uac23_clock_multiplier_desc {
+ struct uac_clock_multiplier_descriptor v2;
+ struct uac_clock_multiplier_descriptor v3;
+};
+
+#define GET_VAL(p, proto, field) \
+ ((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)
+
static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,
- bool (*validator)(void *, int), u8 type)
+ bool (*validator)(void *, int, int),
+ u8 type, int proto)
{
void *cs = NULL;
while ((cs = snd_usb_find_csint_desc(iface->extra, iface->extralen,
cs, type))) {
- if (validator(cs, id))
+ if (validator(cs, id, proto))
return cs;
}
return NULL;
}
-static bool validate_clock_source_v2(void *p, int id)
+static bool validate_clock_source(void *p, int id, int proto)
{
- struct uac_clock_source_descriptor *cs = p;
- return cs->bClockID == id;
-}
+ union uac23_clock_source_desc *cs = p;
-static bool validate_clock_source_v3(void *p, int id)
-{
- struct uac3_clock_source_descriptor *cs = p;
- return cs->bClockID == id;
+ return GET_VAL(cs, proto, bClockID) == id;
}
-static bool validate_clock_selector_v2(void *p, int id)
+static bool validate_clock_selector(void *p, int id, int proto)
{
- struct uac_clock_selector_descriptor *cs = p;
- return cs->bClockID == id;
-}
+ union uac23_clock_selector_desc *cs = p;
-static bool validate_clock_selector_v3(void *p, int id)
-{
- struct uac3_clock_selector_descriptor *cs = p;
- return cs->bClockID == id;
+ return GET_VAL(cs, proto, bClockID) == id;
}
-static bool validate_clock_multiplier_v2(void *p, int id)
+static bool validate_clock_multiplier(void *p, int id, int proto)
{
- struct uac_clock_multiplier_descriptor *cs = p;
- return cs->bClockID == id;
-}
+ union uac23_clock_multiplier_desc *cs = p;
-static bool validate_clock_multiplier_v3(void *p, int id)
-{
- struct uac3_clock_multiplier_descriptor *cs = p;
- return cs->bClockID == id;
+ return GET_VAL(cs, proto, bClockID) == id;
}
-#define DEFINE_FIND_HELPER(name, obj, validator, type) \
-static obj *name(struct usb_host_interface *iface, int id) \
-{ \
- return find_uac_clock_desc(iface, id, validator, type); \
+#define DEFINE_FIND_HELPER(name, obj, validator, type2, type3) \
+static obj *name(struct snd_usb_audio *chip, int id, int proto) \
+{ \
+ return find_uac_clock_desc(chip->ctrl_intf, id, validator, \
+ proto == UAC_VERSION_3 ? (type3) : (type2), \
+ proto); \
}
DEFINE_FIND_HELPER(snd_usb_find_clock_source,
- struct uac_clock_source_descriptor,
- validate_clock_source_v2, UAC2_CLOCK_SOURCE);
-DEFINE_FIND_HELPER(snd_usb_find_clock_source_v3,
- struct uac3_clock_source_descriptor,
- validate_clock_source_v3, UAC3_CLOCK_SOURCE);
-
+ union uac23_clock_source_desc, validate_clock_source,
+ UAC2_CLOCK_SOURCE, UAC3_CLOCK_SOURCE);
DEFINE_FIND_HELPER(snd_usb_find_clock_selector,
- struct uac_clock_selector_descriptor,
- validate_clock_selector_v2, UAC2_CLOCK_SELECTOR);
-DEFINE_FIND_HELPER(snd_usb_find_clock_selector_v3,
- struct uac3_clock_selector_descriptor,
- validate_clock_selector_v3, UAC3_CLOCK_SELECTOR);
-
+ union uac23_clock_selector_desc, validate_clock_selector,
+ UAC2_CLOCK_SELECTOR, UAC3_CLOCK_SELECTOR);
DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier,
- struct uac_clock_multiplier_descriptor,
- validate_clock_multiplier_v2, UAC2_CLOCK_MULTIPLIER);
-DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier_v3,
- struct uac3_clock_multiplier_descriptor,
- validate_clock_multiplier_v3, UAC3_CLOCK_MULTIPLIER);
+ union uac23_clock_multiplier_desc, validate_clock_multiplier,
+ UAC2_CLOCK_MULTIPLIER, UAC3_CLOCK_MULTIPLIER);
static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
{
@@ -159,14 +154,13 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
int count;
unsigned char data;
struct usb_device *dev = chip->dev;
+ union uac23_clock_source_desc *cs_desc;
- if (fmt->protocol == UAC_VERSION_2) {
- struct uac_clock_source_descriptor *cs_desc =
- snd_usb_find_clock_source(chip->ctrl_intf, source_id);
-
- if (!cs_desc)
- return false;
+ cs_desc = snd_usb_find_clock_source(chip, source_id, fmt->protocol);
+ if (!cs_desc)
+ return false;
+ if (fmt->protocol == UAC_VERSION_2) {
/*
* Assume the clock is valid if clock source supports only one
* single sample rate, the terminal is connected directly to it
@@ -175,8 +169,8 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
* reports that clock is invalid.
*/
if (fmt->nr_rates == 1 &&
- (fmt->clock & 0xff) == cs_desc->bClockID &&
- (cs_desc->bmAttributes & 0x3) !=
+ (fmt->clock & 0xff) == cs_desc->v2.bClockID &&
+ (cs_desc->v2.bmAttributes & 0x3) !=
UAC_CLOCK_SOURCE_TYPE_EXT)
return true;
}
@@ -222,22 +216,16 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
unsigned char data;
struct usb_device *dev = chip->dev;
u32 bmControls;
+ union uac23_clock_source_desc *cs_desc;
- if (fmt->protocol == UAC_VERSION_3) {
- struct uac3_clock_source_descriptor *cs_desc =
- snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id);
-
- if (!cs_desc)
- return false;
- bmControls = le32_to_cpu(cs_desc->bmControls);
- } else { /* UAC_VERSION_1/2 */
- struct uac_clock_source_descriptor *cs_desc =
- snd_usb_find_clock_source(chip->ctrl_intf, source_id);
+ cs_desc = snd_usb_find_clock_source(chip, source_id, fmt->protocol);
+ if (!cs_desc)
+ return false;
- if (!cs_desc)
- return false;
- bmControls = cs_desc->bmControls;
- }
+ if (fmt->protocol == UAC_VERSION_3)
+ bmControls = le32_to_cpu(cs_desc->v3.bmControls);
+ else
+ bmControls = cs_desc->v2.bmControls;
/* If a clock source can't tell us whether it's valid, we assume it is */
if (!uac_v2v3_control_is_readable(bmControls,
@@ -267,9 +255,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
const struct audioformat *fmt, int entity_id,
unsigned long *visited, bool validate)
{
- struct uac_clock_source_descriptor *source;
- struct uac_clock_selector_descriptor *selector;
- struct uac_clock_multiplier_descriptor *multiplier;
+ union uac23_clock_source_desc *source;
+ union uac23_clock_selector_desc *selector;
+ union uac23_clock_multiplier_desc *multiplier;
+ int ret, i, cur, err, pins, clock_id;
+ const u8 *sources;
+ int proto = fmt->protocol;
entity_id &= 0xff;
@@ -281,9 +272,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
}
/* first, see if the ID we're looking for is a clock source already */
- source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
+ source = snd_usb_find_clock_source(chip, entity_id, proto);
if (source) {
- entity_id = source->bClockID;
+ entity_id = GET_VAL(source, proto, bClockID);
if (validate && !uac_clock_source_is_valid(chip, fmt,
entity_id)) {
usb_audio_err(chip,
@@ -294,35 +285,43 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
return entity_id;
}
- selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
+ selector = snd_usb_find_clock_selector(chip, entity_id, proto);
if (selector) {
- int ret, i, cur, err;
+ pins = GET_VAL(selector, proto, bNrInPins);
+ clock_id = GET_VAL(selector, proto, bClockID);
+ sources = GET_VAL(selector, proto, baCSourceID);
+ cur = 0;
- if (selector->bNrInPins == 1) {
+ if (pins == 1) {
ret = 1;
goto find_source;
}
/* the entity ID we are looking for is a selector.
* find out what it currently selects */
- ret = uac_clock_selector_get_val(chip, selector->bClockID);
- if (ret < 0)
- return ret;
+ ret = uac_clock_selector_get_val(chip, clock_id);
+ if (ret < 0) {
+ if (!chip->autoclock)
+ return ret;
+ goto find_others;
+ }
/* Selector values are one-based */
- if (ret > selector->bNrInPins || ret < 1) {
+ if (ret > pins || ret < 1) {
usb_audio_err(chip,
"%s(): selector reported illegal value, id %d, ret %d\n",
- __func__, selector->bClockID, ret);
+ __func__, clock_id, ret);
- return -EINVAL;
+ if (!chip->autoclock)
+ return -EINVAL;
+ goto find_others;
}
find_source:
cur = ret;
ret = __uac_clock_find_source(chip, fmt,
- selector->baCSourceID[ret - 1],
+ sources[ret - 1],
visited, validate);
if (ret > 0) {
err = uac_clock_selector_set_val(chip, entity_id, cur);
@@ -333,13 +332,14 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
if (!validate || ret > 0 || !chip->autoclock)
return ret;
+ find_others:
/* The current clock source is invalid, try others. */
- for (i = 1; i <= selector->bNrInPins; i++) {
+ for (i = 1; i <= pins; i++) {
if (i == cur)
continue;
ret = __uac_clock_find_source(chip, fmt,
- selector->baCSourceID[i - 1],
+ sources[i - 1],
visited, true);
if (ret < 0)
continue;
@@ -358,116 +358,15 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
}
/* FIXME: multipliers only act as pass-thru element for now */
- multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
+ multiplier = snd_usb_find_clock_multiplier(chip, entity_id, proto);
if (multiplier)
return __uac_clock_find_source(chip, fmt,
- multiplier->bCSourceID,
+ GET_VAL(multiplier, proto, bCSourceID),
visited, validate);
return -EINVAL;
}
-static int __uac3_clock_find_source(struct snd_usb_audio *chip,
- const struct audioformat *fmt, int entity_id,
- unsigned long *visited, bool validate)
-{
- struct uac3_clock_source_descriptor *source;
- struct uac3_clock_selector_descriptor *selector;
- struct uac3_clock_multiplier_descriptor *multiplier;
-
- entity_id &= 0xff;
-
- if (test_and_set_bit(entity_id, visited)) {
- usb_audio_warn(chip,
- "%s(): recursive clock topology detected, id %d.\n",
- __func__, entity_id);
- return -EINVAL;
- }
-
- /* first, see if the ID we're looking for is a clock source already */
- source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id);
- if (source) {
- entity_id = source->bClockID;
- if (validate && !uac_clock_source_is_valid(chip, fmt,
- entity_id)) {
- usb_audio_err(chip,
- "clock source %d is not valid, cannot use\n",
- entity_id);
- return -ENXIO;
- }
- return entity_id;
- }
-
- selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id);
- if (selector) {
- int ret, i, cur, err;
-
- /* the entity ID we are looking for is a selector.
- * find out what it currently selects */
- ret = uac_clock_selector_get_val(chip, selector->bClockID);
- if (ret < 0)
- return ret;
-
- /* Selector values are one-based */
-
- if (ret > selector->bNrInPins || ret < 1) {
- usb_audio_err(chip,
- "%s(): selector reported illegal value, id %d, ret %d\n",
- __func__, selector->bClockID, ret);
-
- return -EINVAL;
- }
-
- cur = ret;
- ret = __uac3_clock_find_source(chip, fmt,
- selector->baCSourceID[ret - 1],
- visited, validate);
- if (ret > 0) {
- err = uac_clock_selector_set_val(chip, entity_id, cur);
- if (err < 0)
- return err;
- }
-
- if (!validate || ret > 0 || !chip->autoclock)
- return ret;
-
- /* The current clock source is invalid, try others. */
- for (i = 1; i <= selector->bNrInPins; i++) {
- int err;
-
- if (i == cur)
- continue;
-
- ret = __uac3_clock_find_source(chip, fmt,
- selector->baCSourceID[i - 1],
- visited, true);
- if (ret < 0)
- continue;
-
- err = uac_clock_selector_set_val(chip, entity_id, i);
- if (err < 0)
- continue;
-
- usb_audio_info(chip,
- "found and selected valid clock source %d\n",
- ret);
- return ret;
- }
-
- return -ENXIO;
- }
-
- /* FIXME: multipliers only act as pass-thru element for now */
- multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf,
- entity_id);
- if (multiplier)
- return __uac3_clock_find_source(chip, fmt,
- multiplier->bCSourceID,
- visited, validate);
-
- return -EINVAL;
-}
-
/*
* For all kinds of sample rate settings and other device queries,
* the clock source (end-leaf) must be used. However, clock selectors,
@@ -487,10 +386,8 @@ int snd_usb_clock_find_source(struct snd_usb_audio *chip,
switch (fmt->protocol) {
case UAC_VERSION_2:
- return __uac_clock_find_source(chip, fmt, fmt->clock, visited,
- validate);
case UAC_VERSION_3:
- return __uac3_clock_find_source(chip, fmt, fmt->clock, visited,
+ return __uac_clock_find_source(chip, fmt, fmt->clock, visited,
validate);
default:
return -EINVAL;
@@ -593,18 +490,13 @@ int snd_usb_set_sample_rate_v2v3(struct snd_usb_audio *chip,
u32 bmControls;
__le32 data;
int err;
+ union uac23_clock_source_desc *cs_desc;
- if (fmt->protocol == UAC_VERSION_3) {
- struct uac3_clock_source_descriptor *cs_desc;
-
- cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
- bmControls = le32_to_cpu(cs_desc->bmControls);
- } else {
- struct uac_clock_source_descriptor *cs_desc;
-
- cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
- bmControls = cs_desc->bmControls;
- }
+ cs_desc = snd_usb_find_clock_source(chip, clock, fmt->protocol);
+ if (fmt->protocol == UAC_VERSION_3)
+ bmControls = le32_to_cpu(cs_desc->v3.bmControls);
+ else
+ bmControls = cs_desc->v2.bmControls;
writeable = uac_v2v3_control_is_writeable(bmControls,
UAC2_CS_CONTROL_SAM_FREQ);
@@ -642,6 +534,13 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip,
* rate.
*/
clock = snd_usb_clock_find_source(chip, fmt, false);
+
+ /* Denon DN-X1600 hardcoded
+ * Sample rate seems to be set on the hardware itself
+ */
+ if (chip->usb_id == USB_ID(0x154e, 0x500e))
+ return 0;
+
if (clock < 0)
return clock;
}
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 014c43862826..4f856771216b 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -275,6 +275,7 @@ static void prepare_silent_urb(struct snd_usb_endpoint *ep,
urb->number_of_packets = ctx->packets;
urb->transfer_buffer_length = offs * ep->stride + ctx->packets * extra;
+ ctx->queued = 0;
}
/*
@@ -644,7 +645,7 @@ static bool endpoint_compatible(struct snd_usb_endpoint *ep,
}
/*
- * Check whether the given fp and hw params are compatbile with the current
+ * Check whether the given fp and hw params are compatible with the current
* setup of the target EP for implicit feedback sync
*/
bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
@@ -1244,7 +1245,7 @@ static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
*
* This function sets up the EP to be fully usable state.
* It's called either from hw_params or prepare callback.
- * The function checks need_setup flag, and perfoms nothing unless needed,
+ * The function checks need_setup flag, and performs nothing unless needed,
* so it's safe to call this multiple times.
*
* This returns zero if unchanged, 1 if the configuration has changed,
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index eea4ca49876d..a668f675b52b 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -19,7 +19,6 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep);
int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep);
-void snd_usb_endpoint_suspend(struct snd_usb_endpoint *ep);
bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
struct snd_usb_endpoint *ep,
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 2287f8c65315..eb216fef4ba7 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -223,9 +223,11 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
continue;
/* C-Media CM6501 mislabels its 96 kHz altsetting */
/* Terratec Aureon 7.1 USB C-Media 6206, too */
+ /* Ozone Z90 USB C-Media, too */
if (rate == 48000 && nr_rates == 1 &&
(chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
chip->usb_id == USB_ID(0x0d8c, 0x0102) ||
+ chip->usb_id == USB_ID(0x0d8c, 0x0078) ||
chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&
fp->altsetting == 5 && fp->maxpacksize == 392)
rate = 96000;
diff --git a/sound/usb/media.c b/sound/usb/media.c
index 812017eacbcf..840f42cb9272 100644
--- a/sound/usb/media.c
+++ b/sound/usb/media.c
@@ -285,7 +285,7 @@ snd_mixer_init:
ret);
if (!media_devnode_is_registered(mdev->devnode)) {
- /* dont'register if snd_media_mixer_init() failed */
+ /* don't register if snd_media_mixer_init() failed */
if (ret)
goto create_fail;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 428d581f988f..30b3e128e28d 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -3294,8 +3294,9 @@ static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
struct usb_mixer_elem_list *list)
{
struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
- static const char * const val_types[] = {"BOOLEAN", "INV_BOOLEAN",
- "S8", "U8", "S16", "U16"};
+ static const char * const val_types[] = {
+ "BOOLEAN", "INV_BOOLEAN", "S8", "U8", "S16", "U16", "S32", "U32",
+ };
snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
"channels=%i, type=\"%s\"\n", cval->head.id,
cval->control, cval->cmask, cval->channels,
@@ -3605,6 +3606,9 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
int c, err, idx;
+ if (cval->val_type == USB_MIXER_BESPOKEN)
+ return 0;
+
if (cval->cmask) {
idx = 0;
for (c = 0; c < MAX_CHANNELS; c++) {
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index e5a01f17bf3c..ea41e7a1f7bf 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -55,6 +55,7 @@ enum {
USB_MIXER_U16,
USB_MIXER_S32,
USB_MIXER_U32,
+ USB_MIXER_BESPOKEN, /* non-standard type */
};
typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 37ad77524c0b..0a3cb8fd7d00 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -3060,6 +3060,12 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
case USB_ID(0x1235, 0x8203): /* Focusrite Scarlett 6i6 2nd Gen */
case USB_ID(0x1235, 0x8204): /* Focusrite Scarlett 18i8 2nd Gen */
case USB_ID(0x1235, 0x8201): /* Focusrite Scarlett 18i20 2nd Gen */
+ case USB_ID(0x1235, 0x8211): /* Focusrite Scarlett Solo 3rd Gen */
+ case USB_ID(0x1235, 0x8210): /* Focusrite Scarlett 2i2 3rd Gen */
+ case USB_ID(0x1235, 0x8212): /* Focusrite Scarlett 4i4 3rd Gen */
+ case USB_ID(0x1235, 0x8213): /* Focusrite Scarlett 8i6 3rd Gen */
+ case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */
+ case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */
err = snd_scarlett_gen2_init(mixer);
break;
diff --git a/sound/usb/mixer_s1810c.c b/sound/usb/mixer_s1810c.c
index c53a9773f310..0255089c9efb 100644
--- a/sound/usb/mixer_s1810c.c
+++ b/sound/usb/mixer_s1810c.c
@@ -163,7 +163,7 @@ snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a,
}
/*
- * When opening Universal Control the program periodicaly
+ * When opening Universal Control the program periodically
* sends and receives state packets for syncinc state between
* the device and the host.
*
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c
index 691b95466d0f..0d6e4f15bf77 100644
--- a/sound/usb/mixer_scarlett.c
+++ b/sound/usb/mixer_scarlett.c
@@ -21,7 +21,7 @@
* Auto-detection via UAC2 is not feasible to properly discover the vast
* majority of features. It's related to both Linux/ALSA's UAC2 as well as
* Focusrite's implementation of it. Eventually quirks may be sufficient but
- * right now it's a major headache to work arount these things.
+ * right now it's a major headache to work around these things.
*
* NB. Neither the OSX nor the win driver provided by Focusrite performs
* discovery, they seem to operate the same as this driver.
diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
index 4caf379d5b99..f9d698a37153 100644
--- a/sound/usb/mixer_scarlett_gen2.c
+++ b/sound/usb/mixer_scarlett_gen2.c
@@ -1,8 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Focusrite Scarlett 6i6/18i8/18i20 Gen 2 Driver for ALSA
+ * Focusrite Scarlett Gen 2/3 Driver for ALSA
*
- * Copyright (c) 2018-2019 by Geoffrey D. Bennett <g at b4.vu>
+ * Supported models:
+ * - 6i6/18i8/18i20 Gen 2
+ * - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3
+ *
+ * Copyright (c) 2018-2021 by Geoffrey D. Bennett <g at b4.vu>
+ * Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com>
*
* Based on the Scarlett (Gen 1) Driver for ALSA:
*
@@ -19,10 +24,6 @@
* David Henningsson <david.henningsson at canonical.com>
*/
-/* Mixer Interface for the Focusrite Scarlett 6i6/18i8/18i20 Gen 2 audio
- * interface. Based on the Gen 1 driver and rewritten.
- */
-
/* The protocol was reverse engineered by looking at the communication
* between Focusrite Control 2.3.4 and the Focusrite(R) Scarlett 18i20
* (firmware 1083) using usbmon in July-August 2018.
@@ -32,12 +33,33 @@
* Scarlett 6i6 support added in June 2019 (thanks to Martin Wittmann
* for providing usbmon output and testing).
*
- * This ALSA mixer gives access to:
+ * Scarlett 4i4/8i6 Gen 3 support added in May 2020 (thanks to Laurent
+ * Debricon for donating a 4i4 and to Fredrik Unger for providing 8i6
+ * usbmon output and testing).
+ *
+ * Scarlett 18i8/18i20 Gen 3 support added in June 2020 (thanks to
+ * Darren Jaeckel, Alex Sedlack, and Clovis Lunel for providing usbmon
+ * output, protocol traces and testing).
+ *
+ * Support for loading mixer volume and mux configuration from the
+ * interface during driver initialisation added in May 2021 (thanks to
+ * Vladimir Sadovnikov for figuring out how).
+ *
+ * Support for Solo/2i2 Gen 3 added in May 2021 (thanks to Alexander
+ * Vorona for 2i2 protocol traces).
+ *
+ * Support for phantom power, direct monitoring, speaker switching,
+ * and talkback added in May-June 2021.
+ *
+ * This ALSA mixer gives access to (model-dependent):
* - input, output, mixer-matrix muxes
- * - 18x10 mixer-matrix gain stages
- * - gain/volume controls
+ * - mixer-matrix gain stages
+ * - gain/volume/mute controls
* - level meters
- * - line/inst level and pad controls
+ * - line/inst level, pad, and air controls
+ * - phantom power, direct monitor, speaker switching, and talkback
+ * controls
+ * - disable/enable MSD mode
*
* <ditaa>
* /--------------\ 18chn 20chn /--------------\
@@ -90,6 +112,14 @@
* \--------------/
* </ditaa>
*
+ * Gen 3 devices have a Mass Storage Device (MSD) mode where a small
+ * disk with registration and driver download information is presented
+ * to the host. To access the full functionality of the device without
+ * proprietary software, MSD mode can be disabled by:
+ * - holding down the 48V button for five seconds while powering on
+ * the device, or
+ * - using this driver and alsamixer to change the "MSD Mode" setting
+ * to Off and power-cycling the device
*/
#include <linux/slab.h>
@@ -108,6 +138,9 @@
/* device_setup value to enable */
#define SCARLETT2_ENABLE 0x01
+/* device_setup value to allow turning MSD mode back on */
+#define SCARLETT2_MSD_ENABLE 0x02
+
/* some gui mixers can't handle negative ctl values */
#define SCARLETT2_VOLUME_BIAS 127
@@ -117,11 +150,12 @@
#define SCARLETT2_MIXER_MAX_DB 6
#define SCARLETT2_MIXER_MAX_VALUE \
((SCARLETT2_MIXER_MAX_DB - SCARLETT2_MIXER_MIN_DB) * 2)
+#define SCARLETT2_MIXER_VALUE_COUNT (SCARLETT2_MIXER_MAX_VALUE + 1)
/* map from (dB + 80) * 2 to mixer value
* for dB in 0 .. 172: int(8192 * pow(10, ((dB - 160) / 2 / 20)))
*/
-static const u16 scarlett2_mixer_values[173] = {
+static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
@@ -143,23 +177,23 @@ static const u16 scarlett2_mixer_values[173] = {
/* Maximum number of level and pad switches */
#define SCARLETT2_LEVEL_SWITCH_MAX 2
-#define SCARLETT2_PAD_SWITCH_MAX 4
+#define SCARLETT2_PAD_SWITCH_MAX 8
+#define SCARLETT2_AIR_SWITCH_MAX 8
+#define SCARLETT2_PHANTOM_SWITCH_MAX 2
/* Maximum number of inputs to the mixer */
-#define SCARLETT2_INPUT_MIX_MAX 18
+#define SCARLETT2_INPUT_MIX_MAX 25
/* Maximum number of outputs from the mixer */
-#define SCARLETT2_OUTPUT_MIX_MAX 10
+#define SCARLETT2_OUTPUT_MIX_MAX 12
/* Maximum size of the data in the USB mux assignment message:
- * 18 inputs, 20 outputs, 18 matrix inputs, 8 spare
+ * 20 inputs, 20 outputs, 25 matrix inputs, 12 spare
*/
-#define SCARLETT2_MUX_MAX 64
+#define SCARLETT2_MUX_MAX 77
-/* Number of meters:
- * 18 inputs, 20 outputs, 18 matrix inputs
- */
-#define SCARLETT2_NUM_METERS 56
+/* Maximum number of meters (sum of output port counts) */
+#define SCARLETT2_MAX_METERS 65
/* Hardware port types:
* - None (no input to mux)
@@ -170,74 +204,219 @@ static const u16 scarlett2_mixer_values[173] = {
* - PCM I/O
*/
enum {
- SCARLETT2_PORT_TYPE_NONE = 0,
+ SCARLETT2_PORT_TYPE_NONE = 0,
SCARLETT2_PORT_TYPE_ANALOGUE = 1,
- SCARLETT2_PORT_TYPE_SPDIF = 2,
- SCARLETT2_PORT_TYPE_ADAT = 3,
- SCARLETT2_PORT_TYPE_MIX = 4,
- SCARLETT2_PORT_TYPE_PCM = 5,
- SCARLETT2_PORT_TYPE_COUNT = 6,
+ SCARLETT2_PORT_TYPE_SPDIF = 2,
+ SCARLETT2_PORT_TYPE_ADAT = 3,
+ SCARLETT2_PORT_TYPE_MIX = 4,
+ SCARLETT2_PORT_TYPE_PCM = 5,
+ SCARLETT2_PORT_TYPE_COUNT = 6,
};
-/* Count of total I/O and number available at each sample rate */
+/* I/O count of each port type kept in struct scarlett2_ports */
enum {
- SCARLETT2_PORT_IN = 0,
- SCARLETT2_PORT_OUT = 1,
- SCARLETT2_PORT_OUT_44 = 2,
- SCARLETT2_PORT_OUT_88 = 3,
- SCARLETT2_PORT_OUT_176 = 4,
- SCARLETT2_PORT_DIRECTIONS = 5,
+ SCARLETT2_PORT_IN = 0,
+ SCARLETT2_PORT_OUT = 1,
+ SCARLETT2_PORT_DIRNS = 2,
};
-/* Hardware buttons on the 18i20 */
-#define SCARLETT2_BUTTON_MAX 2
+/* Dim/Mute buttons on the 18i20 */
+enum {
+ SCARLETT2_BUTTON_MUTE = 0,
+ SCARLETT2_BUTTON_DIM = 1,
+ SCARLETT2_DIM_MUTE_COUNT = 2,
+};
-static const char *const scarlett2_button_names[SCARLETT2_BUTTON_MAX] = {
+static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
"Mute", "Dim"
};
/* Description of each hardware port type:
- * - id: hardware ID for this port type
- * - num: number of sources/destinations of this port type
+ * - id: hardware ID of this port type
* - src_descr: printf format string for mux input selections
* - src_num_offset: added to channel number for the fprintf
* - dst_descr: printf format string for mixer controls
*/
-struct scarlett2_ports {
+struct scarlett2_port {
u16 id;
- int num[SCARLETT2_PORT_DIRECTIONS];
const char * const src_descr;
int src_num_offset;
const char * const dst_descr;
};
+static const struct scarlett2_port scarlett2_ports[SCARLETT2_PORT_TYPE_COUNT] = {
+ [SCARLETT2_PORT_TYPE_NONE] = {
+ .id = 0x000,
+ .src_descr = "Off"
+ },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = {
+ .id = 0x080,
+ .src_descr = "Analogue %d",
+ .src_num_offset = 1,
+ .dst_descr = "Analogue Output %02d Playback"
+ },
+ [SCARLETT2_PORT_TYPE_SPDIF] = {
+ .id = 0x180,
+ .src_descr = "S/PDIF %d",
+ .src_num_offset = 1,
+ .dst_descr = "S/PDIF Output %d Playback"
+ },
+ [SCARLETT2_PORT_TYPE_ADAT] = {
+ .id = 0x200,
+ .src_descr = "ADAT %d",
+ .src_num_offset = 1,
+ .dst_descr = "ADAT Output %d Playback"
+ },
+ [SCARLETT2_PORT_TYPE_MIX] = {
+ .id = 0x300,
+ .src_descr = "Mix %c",
+ .src_num_offset = 'A',
+ .dst_descr = "Mixer Input %02d Capture"
+ },
+ [SCARLETT2_PORT_TYPE_PCM] = {
+ .id = 0x600,
+ .src_descr = "PCM %d",
+ .src_num_offset = 1,
+ .dst_descr = "PCM %02d Capture"
+ },
+};
+
+/* Number of mux tables: one for each band of sample rates
+ * (44.1/48kHz, 88.2/96kHz, and 176.4/176kHz)
+ */
+#define SCARLETT2_MUX_TABLES 3
+
+/* Maximum number of entries in a mux table */
+#define SCARLETT2_MAX_MUX_ENTRIES 10
+
+/* One entry within mux_assignment defines the port type and range of
+ * ports to add to the set_mux message. The end of the list is marked
+ * with count == 0.
+ */
+struct scarlett2_mux_entry {
+ u8 port_type;
+ u8 start;
+ u8 count;
+};
+
struct scarlett2_device_info {
- u8 line_out_hw_vol; /* line out hw volume is sw controlled */
- u8 button_count; /* number of buttons */
- u8 level_input_count; /* inputs with level selectable */
- u8 pad_input_count; /* inputs with pad selectable */
+ u32 usb_id; /* USB device identifier */
+
+ /* Gen 3 devices have an internal MSD mode switch that needs
+ * to be disabled in order to access the full functionality of
+ * the device.
+ */
+ u8 has_msd_mode;
+
+ /* Gen 3 devices without a mixer have a different
+ * configuration set
+ */
+ u8 has_mixer;
+
+ /* line out hw volume is sw controlled */
+ u8 line_out_hw_vol;
+
+ /* support for main/alt speaker switching */
+ u8 has_speaker_switching;
+
+ /* support for talkback microphone */
+ u8 has_talkback;
+
+ /* the number of analogue inputs with a software switchable
+ * level control that can be set to line or instrument
+ */
+ u8 level_input_count;
+
+ /* the first input with a level control (0-based) */
+ u8 level_input_first;
+
+ /* the number of analogue inputs with a software switchable
+ * 10dB pad control
+ */
+ u8 pad_input_count;
+
+ /* the number of analogue inputs with a software switchable
+ * "air" control
+ */
+ u8 air_input_count;
+
+ /* the number of phantom (48V) software switchable controls */
+ u8 phantom_count;
+
+ /* the number of inputs each phantom switch controls */
+ u8 inputs_per_phantom;
+
+ /* the number of direct monitor options
+ * (0 = none, 1 = mono only, 2 = mono/stereo)
+ */
+ u8 direct_monitor;
+
+ /* remap analogue outputs; 18i8 Gen 3 has "line 3/4" connected
+ * internally to the analogue 7/8 outputs
+ */
+ u8 line_out_remap_enable;
+ u8 line_out_remap[SCARLETT2_ANALOGUE_MAX];
+
+ /* additional description for the line out volume controls */
const char * const line_out_descrs[SCARLETT2_ANALOGUE_MAX];
- struct scarlett2_ports ports[SCARLETT2_PORT_TYPE_COUNT];
+
+ /* number of sources/destinations of each port type */
+ const int port_count[SCARLETT2_PORT_TYPE_COUNT][SCARLETT2_PORT_DIRNS];
+
+ /* layout/order of the entries in the set_mux message */
+ struct scarlett2_mux_entry mux_assignment[SCARLETT2_MUX_TABLES]
+ [SCARLETT2_MAX_MUX_ENTRIES];
};
-struct scarlett2_mixer_data {
+struct scarlett2_data {
struct usb_mixer_interface *mixer;
struct mutex usb_mutex; /* prevent sending concurrent USB requests */
struct mutex data_mutex; /* lock access to this data */
struct delayed_work work;
const struct scarlett2_device_info *info;
+ __u8 bInterfaceNumber;
+ __u8 bEndpointAddress;
+ __u16 wMaxPacketSize;
+ __u8 bInterval;
int num_mux_srcs;
+ int num_mux_dsts;
u16 scarlett2_seq;
+ u8 sync_updated;
u8 vol_updated;
+ u8 input_other_updated;
+ u8 monitor_other_updated;
+ u8 mux_updated;
+ u8 speaker_switching_switched;
+ u8 sync;
u8 master_vol;
u8 vol[SCARLETT2_ANALOGUE_MAX];
u8 vol_sw_hw_switch[SCARLETT2_ANALOGUE_MAX];
+ u8 mute_switch[SCARLETT2_ANALOGUE_MAX];
u8 level_switch[SCARLETT2_LEVEL_SWITCH_MAX];
u8 pad_switch[SCARLETT2_PAD_SWITCH_MAX];
- u8 buttons[SCARLETT2_BUTTON_MAX];
+ u8 dim_mute[SCARLETT2_DIM_MUTE_COUNT];
+ u8 air_switch[SCARLETT2_AIR_SWITCH_MAX];
+ u8 phantom_switch[SCARLETT2_PHANTOM_SWITCH_MAX];
+ u8 phantom_persistence;
+ u8 direct_monitor_switch;
+ u8 speaker_switching_switch;
+ u8 talkback_switch;
+ u8 talkback_map[SCARLETT2_OUTPUT_MIX_MAX];
+ u8 msd_switch;
+ struct snd_kcontrol *sync_ctl;
struct snd_kcontrol *master_vol_ctl;
struct snd_kcontrol *vol_ctls[SCARLETT2_ANALOGUE_MAX];
- struct snd_kcontrol *button_ctls[SCARLETT2_BUTTON_MAX];
+ struct snd_kcontrol *sw_hw_ctls[SCARLETT2_ANALOGUE_MAX];
+ struct snd_kcontrol *mute_ctls[SCARLETT2_ANALOGUE_MAX];
+ struct snd_kcontrol *dim_mute_ctls[SCARLETT2_DIM_MUTE_COUNT];
+ struct snd_kcontrol *level_ctls[SCARLETT2_LEVEL_SWITCH_MAX];
+ struct snd_kcontrol *pad_ctls[SCARLETT2_PAD_SWITCH_MAX];
+ struct snd_kcontrol *air_ctls[SCARLETT2_AIR_SWITCH_MAX];
+ struct snd_kcontrol *phantom_ctls[SCARLETT2_PHANTOM_SWITCH_MAX];
+ struct snd_kcontrol *mux_ctls[SCARLETT2_MUX_MAX];
+ struct snd_kcontrol *direct_monitor_ctl;
+ struct snd_kcontrol *speaker_switching_ctl;
+ struct snd_kcontrol *talkback_ctl;
u8 mux[SCARLETT2_MUX_MAX];
u8 mix[SCARLETT2_INPUT_MIX_MAX * SCARLETT2_OUTPUT_MIX_MAX];
};
@@ -245,66 +424,56 @@ struct scarlett2_mixer_data {
/*** Model-specific data ***/
static const struct scarlett2_device_info s6i6_gen2_info = {
- /* The first two analogue inputs can be switched between line
- * and instrument levels.
- */
- .level_input_count = 2,
+ .usb_id = USB_ID(0x1235, 0x8203),
- /* The first two analogue inputs have an optional pad. */
+ .has_mixer = 1,
+ .level_input_count = 2,
.pad_input_count = 2,
.line_out_descrs = {
- "Monitor L",
- "Monitor R",
- "Headphones L",
- "Headphones R",
+ "Headphones 1 L",
+ "Headphones 1 R",
+ "Headphones 2 L",
+ "Headphones 2 R",
},
- .ports = {
- [SCARLETT2_PORT_TYPE_NONE] = {
- .id = 0x000,
- .num = { 1, 0, 8, 8, 8 },
- .src_descr = "Off",
- .src_num_offset = 0,
- },
- [SCARLETT2_PORT_TYPE_ANALOGUE] = {
- .id = 0x080,
- .num = { 4, 4, 4, 4, 4 },
- .src_descr = "Analogue %d",
- .src_num_offset = 1,
- .dst_descr = "Analogue Output %02d Playback"
- },
- [SCARLETT2_PORT_TYPE_SPDIF] = {
- .id = 0x180,
- .num = { 2, 2, 2, 2, 2 },
- .src_descr = "S/PDIF %d",
- .src_num_offset = 1,
- .dst_descr = "S/PDIF Output %d Playback"
- },
- [SCARLETT2_PORT_TYPE_MIX] = {
- .id = 0x300,
- .num = { 10, 18, 18, 18, 18 },
- .src_descr = "Mix %c",
- .src_num_offset = 65,
- .dst_descr = "Mixer Input %02d Capture"
- },
- [SCARLETT2_PORT_TYPE_PCM] = {
- .id = 0x600,
- .num = { 6, 6, 6, 6, 6 },
- .src_descr = "PCM %d",
- .src_num_offset = 1,
- .dst_descr = "PCM %02d Capture"
- },
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 4, 4 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 10, 18 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 6, 6 },
},
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ } },
};
static const struct scarlett2_device_info s18i8_gen2_info = {
- /* The first two analogue inputs can be switched between line
- * and instrument levels.
- */
- .level_input_count = 2,
+ .usb_id = USB_ID(0x1235, 0x8204),
- /* The first four analogue inputs have an optional pad. */
+ .has_mixer = 1,
+ .level_input_count = 2,
.pad_input_count = 4,
.line_out_descrs = {
@@ -316,62 +485,44 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
"Headphones 2 R",
},
- .ports = {
- [SCARLETT2_PORT_TYPE_NONE] = {
- .id = 0x000,
- .num = { 1, 0, 8, 8, 4 },
- .src_descr = "Off",
- .src_num_offset = 0,
- },
- [SCARLETT2_PORT_TYPE_ANALOGUE] = {
- .id = 0x080,
- .num = { 8, 6, 6, 6, 6 },
- .src_descr = "Analogue %d",
- .src_num_offset = 1,
- .dst_descr = "Analogue Output %02d Playback"
- },
- [SCARLETT2_PORT_TYPE_SPDIF] = {
- .id = 0x180,
- /* S/PDIF outputs aren't available at 192kHz
- * but are included in the USB mux I/O
- * assignment message anyway
- */
- .num = { 2, 2, 2, 2, 2 },
- .src_descr = "S/PDIF %d",
- .src_num_offset = 1,
- .dst_descr = "S/PDIF Output %d Playback"
- },
- [SCARLETT2_PORT_TYPE_ADAT] = {
- .id = 0x200,
- .num = { 8, 0, 0, 0, 0 },
- .src_descr = "ADAT %d",
- .src_num_offset = 1,
- },
- [SCARLETT2_PORT_TYPE_MIX] = {
- .id = 0x300,
- .num = { 10, 18, 18, 18, 18 },
- .src_descr = "Mix %c",
- .src_num_offset = 65,
- .dst_descr = "Mixer Input %02d Capture"
- },
- [SCARLETT2_PORT_TYPE_PCM] = {
- .id = 0x600,
- .num = { 20, 18, 18, 14, 10 },
- .src_descr = "PCM %d",
- .src_num_offset = 1,
- .dst_descr = "PCM %02d Capture"
- },
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 8, 6 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_ADAT] = { 8, 0 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 10, 18 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 8, 18 },
},
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 18 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 6 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 14 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 6 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 6 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 4 },
+ { 0, 0, 0 },
+ } },
};
static const struct scarlett2_device_info s18i20_gen2_info = {
- /* The analogue line outputs on the 18i20 can be switched
- * between software and hardware volume control
- */
- .line_out_hw_vol = 1,
+ .usb_id = USB_ID(0x1235, 0x8201),
- /* Mute and dim buttons */
- .button_count = 2,
+ .has_mixer = 1,
+ .line_out_hw_vol = 1,
.line_out_descrs = {
"Monitor L",
@@ -386,99 +537,364 @@ static const struct scarlett2_device_info s18i20_gen2_info = {
"Headphones 2 R",
},
- .ports = {
- [SCARLETT2_PORT_TYPE_NONE] = {
- .id = 0x000,
- .num = { 1, 0, 8, 8, 6 },
- .src_descr = "Off",
- .src_num_offset = 0,
- },
- [SCARLETT2_PORT_TYPE_ANALOGUE] = {
- .id = 0x080,
- .num = { 8, 10, 10, 10, 10 },
- .src_descr = "Analogue %d",
- .src_num_offset = 1,
- .dst_descr = "Analogue Output %02d Playback"
- },
- [SCARLETT2_PORT_TYPE_SPDIF] = {
- /* S/PDIF outputs aren't available at 192kHz
- * but are included in the USB mux I/O
- * assignment message anyway
- */
- .id = 0x180,
- .num = { 2, 2, 2, 2, 2 },
- .src_descr = "S/PDIF %d",
- .src_num_offset = 1,
- .dst_descr = "S/PDIF Output %d Playback"
- },
- [SCARLETT2_PORT_TYPE_ADAT] = {
- .id = 0x200,
- .num = { 8, 8, 8, 4, 0 },
- .src_descr = "ADAT %d",
- .src_num_offset = 1,
- .dst_descr = "ADAT Output %d Playback"
- },
- [SCARLETT2_PORT_TYPE_MIX] = {
- .id = 0x300,
- .num = { 10, 18, 18, 18, 18 },
- .src_descr = "Mix %c",
- .src_num_offset = 65,
- .dst_descr = "Mixer Input %02d Capture"
- },
- [SCARLETT2_PORT_TYPE_PCM] = {
- .id = 0x600,
- .num = { 20, 18, 18, 14, 10 },
- .src_descr = "PCM %d",
- .src_num_offset = 1,
- .dst_descr = "PCM %02d Capture"
- },
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 8, 10 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_ADAT] = { 8, 8 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 10, 18 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 20, 18 },
},
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 18 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ADAT, 0, 8 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 14 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ADAT, 0, 4 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 8 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 18 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 6 },
+ { 0, 0, 0 },
+ } },
+};
+
+static const struct scarlett2_device_info solo_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8211),
+
+ .has_msd_mode = 1,
+ .level_input_count = 1,
+ .level_input_first = 1,
+ .air_input_count = 1,
+ .phantom_count = 1,
+ .inputs_per_phantom = 1,
+ .direct_monitor = 1,
+};
+
+static const struct scarlett2_device_info s2i2_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8210),
+
+ .has_msd_mode = 1,
+ .level_input_count = 2,
+ .air_input_count = 2,
+ .phantom_count = 1,
+ .inputs_per_phantom = 2,
+ .direct_monitor = 2,
+};
+
+static const struct scarlett2_device_info s4i4_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8212),
+
+ .has_msd_mode = 1,
+ .has_mixer = 1,
+ .level_input_count = 2,
+ .pad_input_count = 2,
+ .air_input_count = 2,
+ .phantom_count = 1,
+ .inputs_per_phantom = 2,
+
+ .line_out_descrs = {
+ "Monitor L",
+ "Monitor R",
+ "Headphones L",
+ "Headphones R",
+ },
+
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 4, 4 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 6, 8 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 4, 6 },
+ },
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 16 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 16 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 6 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 16 },
+ { 0, 0, 0 },
+ } },
+};
+
+static const struct scarlett2_device_info s8i6_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8213),
+
+ .has_msd_mode = 1,
+ .has_mixer = 1,
+ .level_input_count = 2,
+ .pad_input_count = 2,
+ .air_input_count = 2,
+ .phantom_count = 1,
+ .inputs_per_phantom = 2,
+
+ .line_out_descrs = {
+ "Headphones 1 L",
+ "Headphones 1 R",
+ "Headphones 2 L",
+ "Headphones 2 R",
+ },
+
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 6, 4 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 8, 8 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 6, 10 },
+ },
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 8 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_PCM, 8, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 18 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 8 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_PCM, 8, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 18 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 8 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_PCM, 8, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 8 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 18 },
+ { 0, 0, 0 },
+ } },
+};
+
+static const struct scarlett2_device_info s18i8_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8214),
+
+ .has_msd_mode = 1,
+ .has_mixer = 1,
+ .line_out_hw_vol = 1,
+ .has_speaker_switching = 1,
+ .level_input_count = 2,
+ .pad_input_count = 4,
+ .air_input_count = 4,
+ .phantom_count = 2,
+ .inputs_per_phantom = 2,
+
+ .line_out_remap_enable = 1,
+ .line_out_remap = { 0, 1, 6, 7, 2, 3, 4, 5 },
+
+ .line_out_descrs = {
+ "Monitor L",
+ "Monitor R",
+ "Alt Monitor L",
+ "Alt Monitor R",
+ "Headphones 1 L",
+ "Headphones 1 R",
+ "Headphones 2 L",
+ "Headphones 2 R",
+ },
+
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 8, 8 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_ADAT] = { 8, 0 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 10, 20 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 8, 20 },
+ },
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_PCM, 12, 8 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 6, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 2, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_PCM, 10, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 20 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 10 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_PCM, 12, 4 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 6, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 2, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_PCM, 10, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 20 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 10 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 6, 2 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 2, 4 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 20 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 10 },
+ { 0, 0, 0 },
+ } },
+};
+
+static const struct scarlett2_device_info s18i20_gen3_info = {
+ .usb_id = USB_ID(0x1235, 0x8215),
+
+ .has_msd_mode = 1,
+ .has_mixer = 1,
+ .line_out_hw_vol = 1,
+ .has_speaker_switching = 1,
+ .has_talkback = 1,
+ .level_input_count = 2,
+ .pad_input_count = 8,
+ .air_input_count = 8,
+ .phantom_count = 2,
+ .inputs_per_phantom = 4,
+
+ .line_out_descrs = {
+ "Monitor 1 L",
+ "Monitor 1 R",
+ "Monitor 2 L",
+ "Monitor 2 R",
+ NULL,
+ NULL,
+ "Headphones 1 L",
+ "Headphones 1 R",
+ "Headphones 2 L",
+ "Headphones 2 R",
+ },
+
+ .port_count = {
+ [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 },
+ [SCARLETT2_PORT_TYPE_ANALOGUE] = { 9, 10 },
+ [SCARLETT2_PORT_TYPE_SPDIF] = { 2, 2 },
+ [SCARLETT2_PORT_TYPE_ADAT] = { 8, 8 },
+ [SCARLETT2_PORT_TYPE_MIX] = { 12, 25 },
+ [SCARLETT2_PORT_TYPE_PCM] = { 20, 20 },
+ },
+
+ .mux_assignment = { {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 8 },
+ { SCARLETT2_PORT_TYPE_PCM, 10, 10 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ADAT, 0, 8 },
+ { SCARLETT2_PORT_TYPE_PCM, 8, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 25 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 12 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 8 },
+ { SCARLETT2_PORT_TYPE_PCM, 10, 8 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_ADAT, 0, 8 },
+ { SCARLETT2_PORT_TYPE_PCM, 8, 2 },
+ { SCARLETT2_PORT_TYPE_MIX, 0, 25 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 10 },
+ { 0, 0, 0 },
+ }, {
+ { SCARLETT2_PORT_TYPE_PCM, 0, 10 },
+ { SCARLETT2_PORT_TYPE_ANALOGUE, 0, 10 },
+ { SCARLETT2_PORT_TYPE_SPDIF, 0, 2 },
+ { SCARLETT2_PORT_TYPE_NONE, 0, 24 },
+ { 0, 0, 0 },
+ } },
+};
+
+static const struct scarlett2_device_info *scarlett2_devices[] = {
+ /* Supported Gen 2 devices */
+ &s6i6_gen2_info,
+ &s18i8_gen2_info,
+ &s18i20_gen2_info,
+
+ /* Supported Gen 3 devices */
+ &solo_gen3_info,
+ &s2i2_gen3_info,
+ &s4i4_gen3_info,
+ &s8i6_gen3_info,
+ &s18i8_gen3_info,
+ &s18i20_gen3_info,
+
+ /* End of list */
+ NULL
};
/* get the starting port index number for a given port type/direction */
-static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
- int direction, int port_type)
+static int scarlett2_get_port_start_num(
+ const int port_count[][SCARLETT2_PORT_DIRNS],
+ int direction, int port_type)
{
int i, num = 0;
for (i = 0; i < port_type; i++)
- num += ports[i].num[direction];
+ num += port_count[i][direction];
return num;
}
/*** USB Interactions ***/
-/* Vendor-Specific Interface, Endpoint, MaxPacketSize, Interval */
-#define SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE 5
-#define SCARLETT2_USB_INTERRUPT_ENDPOINT 4
-#define SCARLETT2_USB_INTERRUPT_MAX_DATA 64
-#define SCARLETT2_USB_INTERRUPT_INTERVAL 3
-
-/* Interrupt flags for volume and mute/dim button changes */
-#define SCARLETT2_USB_INTERRUPT_VOL_CHANGE 0x400000
-#define SCARLETT2_USB_INTERRUPT_BUTTON_CHANGE 0x200000
+/* Notifications from the interface */
+#define SCARLETT2_USB_NOTIFY_SYNC 0x00000008
+#define SCARLETT2_USB_NOTIFY_DIM_MUTE 0x00200000
+#define SCARLETT2_USB_NOTIFY_MONITOR 0x00400000
+#define SCARLETT2_USB_NOTIFY_INPUT_OTHER 0x00800000
+#define SCARLETT2_USB_NOTIFY_MONITOR_OTHER 0x01000000
/* Commands for sending/receiving requests/responses */
-#define SCARLETT2_USB_VENDOR_SPECIFIC_CMD_REQ 2
-#define SCARLETT2_USB_VENDOR_SPECIFIC_CMD_RESP 3
-
-#define SCARLETT2_USB_INIT_SEQ 0x00000000
-#define SCARLETT2_USB_GET_METER_LEVELS 0x00001001
-#define SCARLETT2_USB_SET_MIX 0x00002002
-#define SCARLETT2_USB_SET_MUX 0x00003002
-#define SCARLETT2_USB_GET_DATA 0x00800000
-#define SCARLETT2_USB_SET_DATA 0x00800001
-#define SCARLETT2_USB_DATA_CMD 0x00800002
+#define SCARLETT2_USB_CMD_INIT 0
+#define SCARLETT2_USB_CMD_REQ 2
+#define SCARLETT2_USB_CMD_RESP 3
+
+#define SCARLETT2_USB_INIT_1 0x00000000
+#define SCARLETT2_USB_INIT_2 0x00000002
+#define SCARLETT2_USB_GET_METER 0x00001001
+#define SCARLETT2_USB_GET_MIX 0x00002001
+#define SCARLETT2_USB_SET_MIX 0x00002002
+#define SCARLETT2_USB_GET_MUX 0x00003001
+#define SCARLETT2_USB_SET_MUX 0x00003002
+#define SCARLETT2_USB_GET_SYNC 0x00006004
+#define SCARLETT2_USB_GET_DATA 0x00800000
+#define SCARLETT2_USB_SET_DATA 0x00800001
+#define SCARLETT2_USB_DATA_CMD 0x00800002
+
#define SCARLETT2_USB_CONFIG_SAVE 6
#define SCARLETT2_USB_VOLUME_STATUS_OFFSET 0x31
#define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1
-/* volume status is read together (matches scarlett2_config_items[]) */
+/* volume status is read together (matches scarlett2_config_items[1]) */
struct scarlett2_usb_volume_status {
- /* mute & dim buttons */
- u8 buttons[SCARLETT2_BUTTON_MAX];
+ /* dim/mute buttons */
+ u8 dim_mute[SCARLETT2_DIM_MUTE_COUNT];
u8 pad1;
@@ -488,7 +904,8 @@ struct scarlett2_usb_volume_status {
/* actual volume of output inc. dim (-18dB) */
s16 hw_vol[SCARLETT2_ANALOGUE_MAX];
- u8 pad2[SCARLETT2_ANALOGUE_MAX];
+ /* internal mute buttons */
+ u8 mute_switch[SCARLETT2_ANALOGUE_MAX];
/* sw (0) or hw (1) controlled */
u8 sw_hw_switch[SCARLETT2_ANALOGUE_MAX];
@@ -501,16 +918,25 @@ struct scarlett2_usb_volume_status {
/* Configuration parameters that can be read and written */
enum {
- SCARLETT2_CONFIG_BUTTONS = 0,
+ SCARLETT2_CONFIG_DIM_MUTE = 0,
SCARLETT2_CONFIG_LINE_OUT_VOLUME = 1,
- SCARLETT2_CONFIG_SW_HW_SWITCH = 2,
- SCARLETT2_CONFIG_LEVEL_SWITCH = 3,
- SCARLETT2_CONFIG_PAD_SWITCH = 4,
- SCARLETT2_CONFIG_COUNT = 5
+ SCARLETT2_CONFIG_MUTE_SWITCH = 2,
+ SCARLETT2_CONFIG_SW_HW_SWITCH = 3,
+ SCARLETT2_CONFIG_LEVEL_SWITCH = 4,
+ SCARLETT2_CONFIG_PAD_SWITCH = 5,
+ SCARLETT2_CONFIG_MSD_SWITCH = 6,
+ SCARLETT2_CONFIG_AIR_SWITCH = 7,
+ SCARLETT2_CONFIG_PHANTOM_SWITCH = 8,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE = 9,
+ SCARLETT2_CONFIG_DIRECT_MONITOR = 10,
+ SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH = 11,
+ SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE = 12,
+ SCARLETT2_CONFIG_TALKBACK_MAP = 13,
+ SCARLETT2_CONFIG_COUNT = 14
};
/* Location, size, and activation command number for the configuration
- * parameters
+ * parameters. Size is in bits and may be 1, 8, or 16.
*/
struct scarlett2_config {
u8 offset;
@@ -518,43 +944,73 @@ struct scarlett2_config {
u8 activate;
};
+/* scarlett2_config_items[0] is for devices without a mixer
+ * scarlett2_config_items[1] is for devices with a mixer
+ */
static const struct scarlett2_config
- scarlett2_config_items[SCARLETT2_CONFIG_COUNT] = {
- /* Mute/Dim Buttons */
- {
- .offset = 0x31,
- .size = 1,
- .activate = 2
- },
+ scarlett2_config_items[2][SCARLETT2_CONFIG_COUNT] =
- /* Line Out Volume */
- {
- .offset = 0x34,
- .size = 2,
- .activate = 1
- },
+/* Devices without a mixer (Solo and 2i2 Gen 3) */
+{ {
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x04, .size = 8, .activate = 6 },
- /* SW/HW Volume Switch */
- {
- .offset = 0x66,
- .size = 1,
- .activate = 3
- },
+ [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
+ .offset = 0x05, .size = 8, .activate = 6 },
- /* Level Switch */
- {
- .offset = 0x7c,
- .size = 1,
- .activate = 7
- },
+ [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
+ .offset = 0x06, .size = 8, .activate = 3 },
- /* Pad Switch */
- {
- .offset = 0x84,
- .size = 1,
- .activate = 8
- }
-};
+ [SCARLETT2_CONFIG_DIRECT_MONITOR] = {
+ .offset = 0x07, .size = 8, .activate = 4 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x08, .size = 1, .activate = 7 },
+
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x09, .size = 1, .activate = 8 },
+
+/* Devices with a mixer (Gen 2 and all other Gen 3) */
+}, {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
+
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x8c, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
+ .offset = 0x9c, .size = 1, .activate = 8 },
+
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x9d, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
+ .offset = 0x9e, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH] = {
+ .offset = 0x9f, .size = 1, .activate = 10 },
+
+ [SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE] = {
+ .offset = 0xa0, .size = 1, .activate = 10 },
+
+ [SCARLETT2_CONFIG_TALKBACK_MAP] = {
+ .offset = 0xb0, .size = 16, .activate = 10 },
+} };
/* proprietary request/response format */
struct scarlett2_usb_packet {
@@ -566,9 +1022,7 @@ struct scarlett2_usb_packet {
u8 data[];
};
-#define SCARLETT2_USB_PACKET_LEN (sizeof(struct scarlett2_usb_packet))
-
-static void scarlett2_fill_request_header(struct scarlett2_mixer_data *private,
+static void scarlett2_fill_request_header(struct scarlett2_data *private,
struct scarlett2_usb_packet *req,
u32 cmd, u16 req_size)
{
@@ -582,16 +1036,35 @@ static void scarlett2_fill_request_header(struct scarlett2_mixer_data *private,
req->pad = 0;
}
+static int scarlett2_usb_tx(struct usb_device *dev, int interface,
+ void *buf, u16 size)
+{
+ return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+ SCARLETT2_USB_CMD_REQ,
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+ 0, interface, buf, size);
+}
+
+static int scarlett2_usb_rx(struct usb_device *dev, int interface,
+ u32 usb_req, void *buf, u16 size)
+{
+ return snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
+ usb_req,
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+ 0, interface, buf, size);
+}
+
/* Send a proprietary format request to the Scarlett interface */
static int scarlett2_usb(
struct usb_mixer_interface *mixer, u32 cmd,
void *req_data, u16 req_size, void *resp_data, u16 resp_size)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
+ struct usb_device *dev = mixer->chip->dev;
u16 req_buf_size = sizeof(struct scarlett2_usb_packet) + req_size;
u16 resp_buf_size = sizeof(struct scarlett2_usb_packet) + resp_size;
- struct scarlett2_usb_packet *req = NULL, *resp = NULL;
- int err = 0;
+ struct scarlett2_usb_packet *req, *resp = NULL;
+ int err;
req = kmalloc(req_buf_size, GFP_KERNEL);
if (!req) {
@@ -614,19 +1087,13 @@ static int scarlett2_usb(
if (req_size)
memcpy(req->data, req_data, req_size);
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0),
- SCARLETT2_USB_VENDOR_SPECIFIC_CMD_REQ,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- 0,
- SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE,
- req,
- req_buf_size);
+ err = scarlett2_usb_tx(dev, private->bInterfaceNumber,
+ req, req_buf_size);
if (err != req_buf_size) {
usb_audio_err(
mixer->chip,
- "Scarlett Gen 2 USB request result cmd %x was %d\n",
+ "Scarlett Gen 2/3 USB request result cmd %x was %d\n",
cmd, err);
err = -EINVAL;
goto unlock;
@@ -634,34 +1101,34 @@ static int scarlett2_usb(
/* send a second message to get the response */
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- SCARLETT2_USB_VENDOR_SPECIFIC_CMD_RESP,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- 0,
- SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE,
- resp,
- resp_buf_size);
+ err = scarlett2_usb_rx(dev, private->bInterfaceNumber,
+ SCARLETT2_USB_CMD_RESP,
+ resp, resp_buf_size);
/* validate the response */
if (err != resp_buf_size) {
usb_audio_err(
mixer->chip,
- "Scarlett Gen 2 USB response result cmd %x was %d\n",
- cmd, err);
+ "Scarlett Gen 2/3 USB response result cmd %x was %d "
+ "expected %d\n",
+ cmd, err, resp_buf_size);
err = -EINVAL;
goto unlock;
}
+ /* cmd/seq/size should match except when initialising
+ * seq sent = 1, response = 0
+ */
if (resp->cmd != req->cmd ||
- resp->seq != req->seq ||
+ (resp->seq != req->seq &&
+ (le16_to_cpu(req->seq) != 1 || resp->seq != 0)) ||
resp_size != le16_to_cpu(resp->size) ||
resp->error ||
resp->pad) {
usb_audio_err(
mixer->chip,
- "Scarlett Gen 2 USB invalid response; "
+ "Scarlett Gen 2/3 USB invalid response; "
"cmd tx/rx %d/%d seq %d/%d size %d/%d "
"error %d pad %d\n",
le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd),
@@ -673,7 +1140,7 @@ static int scarlett2_usb(
goto unlock;
}
- if (resp_size > 0)
+ if (resp_data && resp_size > 0)
memcpy(resp_data, resp->data, resp_size);
unlock:
@@ -684,6 +1151,63 @@ error:
return err;
}
+/* Send a USB message to get data; result placed in *buf */
+static int scarlett2_usb_get(
+ struct usb_mixer_interface *mixer,
+ int offset, void *buf, int size)
+{
+ struct {
+ __le32 offset;
+ __le32 size;
+ } __packed req;
+
+ req.offset = cpu_to_le32(offset);
+ req.size = cpu_to_le32(size);
+ return scarlett2_usb(mixer, SCARLETT2_USB_GET_DATA,
+ &req, sizeof(req), buf, size);
+}
+
+/* Send a USB message to get configuration parameters; result placed in *buf */
+static int scarlett2_usb_get_config(
+ struct usb_mixer_interface *mixer,
+ int config_item_num, int count, void *buf)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const struct scarlett2_config *config_item =
+ &scarlett2_config_items[info->has_mixer][config_item_num];
+ int size, err, i;
+ u8 *buf_8;
+ u8 value;
+
+ /* For byte-sized parameters, retrieve directly into buf */
+ if (config_item->size >= 8) {
+ size = config_item->size / 8 * count;
+ err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
+ if (err < 0)
+ return err;
+ if (size == 2) {
+ u16 *buf_16 = buf;
+
+ for (i = 0; i < count; i++, buf_16++)
+ *buf_16 = le16_to_cpu(*(__le16 *)buf_16);
+ }
+ return 0;
+ }
+
+ /* For bit-sized parameters, retrieve into value */
+ err = scarlett2_usb_get(mixer, config_item->offset, &value, 1);
+ if (err < 0)
+ return err;
+
+ /* then unpack from value into buf[] */
+ buf_8 = buf;
+ for (i = 0; i < 8 && i < count; i++, value >>= 1)
+ *buf_8++ = value & 1;
+
+ return 0;
+}
+
/* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
static void scarlett2_config_save(struct usb_mixer_interface *mixer)
{
@@ -697,82 +1221,97 @@ static void scarlett2_config_save(struct usb_mixer_interface *mixer)
/* Delayed work to save config */
static void scarlett2_config_save_work(struct work_struct *work)
{
- struct scarlett2_mixer_data *private =
- container_of(work, struct scarlett2_mixer_data, work.work);
+ struct scarlett2_data *private =
+ container_of(work, struct scarlett2_data, work.work);
scarlett2_config_save(private->mixer);
}
-/* Send a USB message to set a configuration parameter (volume level,
- * sw/hw volume switch, line/inst level switch, or pad switch)
- */
+/* Send a USB message to set a SCARLETT2_CONFIG_* parameter */
static int scarlett2_usb_set_config(
struct usb_mixer_interface *mixer,
int config_item_num, int index, int value)
{
- const struct scarlett2_config config_item =
- scarlett2_config_items[config_item_num];
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const struct scarlett2_config *config_item =
+ &scarlett2_config_items[info->has_mixer][config_item_num];
struct {
__le32 offset;
__le32 bytes;
__le32 value;
} __packed req;
__le32 req2;
+ int offset, size;
int err;
- struct scarlett2_mixer_data *private = mixer->private_data;
/* Cancel any pending NVRAM save */
cancel_delayed_work_sync(&private->work);
+ /* Convert config_item->size in bits to size in bytes and
+ * calculate offset
+ */
+ if (config_item->size >= 8) {
+ size = config_item->size / 8;
+ offset = config_item->offset + index * size;
+
+ /* If updating a bit, retrieve the old value, set/clear the
+ * bit as needed, and update value
+ */
+ } else {
+ u8 tmp;
+
+ size = 1;
+ offset = config_item->offset;
+
+ scarlett2_usb_get(mixer, offset, &tmp, 1);
+ if (value)
+ tmp |= (1 << index);
+ else
+ tmp &= ~(1 << index);
+
+ value = tmp;
+ }
+
/* Send the configuration parameter data */
- req.offset = cpu_to_le32(config_item.offset + index * config_item.size);
- req.bytes = cpu_to_le32(config_item.size);
+ req.offset = cpu_to_le32(offset);
+ req.bytes = cpu_to_le32(size);
req.value = cpu_to_le32(value);
err = scarlett2_usb(mixer, SCARLETT2_USB_SET_DATA,
- &req, sizeof(u32) * 2 + config_item.size,
+ &req, sizeof(u32) * 2 + size,
NULL, 0);
if (err < 0)
return err;
/* Activate the change */
- req2 = cpu_to_le32(config_item.activate);
+ req2 = cpu_to_le32(config_item->activate);
err = scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
&req2, sizeof(req2), NULL, 0);
if (err < 0)
return err;
/* Schedule the change to be written to NVRAM */
- schedule_delayed_work(&private->work, msecs_to_jiffies(2000));
+ if (config_item->activate != SCARLETT2_USB_CONFIG_SAVE)
+ schedule_delayed_work(&private->work, msecs_to_jiffies(2000));
return 0;
}
-/* Send a USB message to get data; result placed in *buf */
-static int scarlett2_usb_get(
+/* Send a USB message to get sync status; result placed in *sync */
+static int scarlett2_usb_get_sync_status(
struct usb_mixer_interface *mixer,
- int offset, void *buf, int size)
+ u8 *sync)
{
- struct {
- __le32 offset;
- __le32 size;
- } __packed req;
-
- req.offset = cpu_to_le32(offset);
- req.size = cpu_to_le32(size);
- return scarlett2_usb(mixer, SCARLETT2_USB_GET_DATA,
- &req, sizeof(req), buf, size);
-}
+ __le32 data;
+ int err;
-/* Send a USB message to get configuration parameters; result placed in *buf */
-static int scarlett2_usb_get_config(
- struct usb_mixer_interface *mixer,
- int config_item_num, int count, void *buf)
-{
- const struct scarlett2_config config_item =
- scarlett2_config_items[config_item_num];
- int size = config_item.size * count;
+ err = scarlett2_usb(mixer, SCARLETT2_USB_GET_SYNC,
+ NULL, 0, &data, sizeof(data));
+ if (err < 0)
+ return err;
- return scarlett2_usb_get(mixer, config_item.offset, buf, size);
+ *sync = !!data;
+ return 0;
}
/* Send a USB message to get volume status; result placed in *buf */
@@ -784,13 +1323,56 @@ static int scarlett2_usb_get_volume_status(
buf, sizeof(*buf));
}
+/* Send a USB message to get the volumes for all inputs of one mix
+ * and put the values into private->mix[]
+ */
+static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
+ int mix_num)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ int num_mixer_in =
+ info->port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+ int err, i, j, k;
+
+ struct {
+ __le16 mix_num;
+ __le16 count;
+ } __packed req;
+
+ __le16 data[SCARLETT2_INPUT_MIX_MAX];
+
+ req.mix_num = cpu_to_le16(mix_num);
+ req.count = cpu_to_le16(num_mixer_in);
+
+ err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MIX,
+ &req, sizeof(req),
+ data, num_mixer_in * sizeof(u16));
+ if (err < 0)
+ return err;
+
+ for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
+ u16 mixer_value = le16_to_cpu(data[i]);
+
+ for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
+ if (scarlett2_mixer_values[k] >= mixer_value)
+ break;
+ if (k == SCARLETT2_MIXER_VALUE_COUNT)
+ k = SCARLETT2_MIXER_MAX_VALUE;
+ private->mix[j] = k;
+ }
+
+ return 0;
+}
+
/* Send a USB message to set the volumes for all inputs of one mix
* (values obtained from private->mix[])
*/
static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
- int mix_num)
+ int mix_num)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
struct {
@@ -800,7 +1382,7 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
int i, j;
int num_mixer_in =
- info->ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
+ info->port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
req.mix_num = cpu_to_le16(mix_num);
@@ -814,40 +1396,120 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
NULL, 0);
}
-/* Convert a port number index (per info->ports) to a hardware ID */
-static u32 scarlett2_mux_src_num_to_id(const struct scarlett2_ports *ports,
- int num)
+/* Convert a port number index (per info->port_count) to a hardware ID */
+static u32 scarlett2_mux_src_num_to_id(
+ const int port_count[][SCARLETT2_PORT_DIRNS], int num)
+{
+ int port_type;
+
+ for (port_type = 0;
+ port_type < SCARLETT2_PORT_TYPE_COUNT;
+ port_type++) {
+ if (num < port_count[port_type][SCARLETT2_PORT_IN])
+ return scarlett2_ports[port_type].id | num;
+ num -= port_count[port_type][SCARLETT2_PORT_IN];
+ }
+
+ /* Oops */
+ return 0;
+}
+
+/* Convert a hardware ID to a port number index */
+static u32 scarlett2_mux_id_to_num(
+ const int port_count[][SCARLETT2_PORT_DIRNS], int direction, u32 id)
{
int port_type;
+ int port_num = 0;
for (port_type = 0;
port_type < SCARLETT2_PORT_TYPE_COUNT;
port_type++) {
- if (num < ports[port_type].num[SCARLETT2_PORT_IN])
- return ports[port_type].id | num;
- num -= ports[port_type].num[SCARLETT2_PORT_IN];
+ int base = scarlett2_ports[port_type].id;
+ int count = port_count[port_type][direction];
+
+ if (id >= base && id < base + count)
+ return port_num + id - base;
+ port_num += count;
}
/* Oops */
+ return -1;
+}
+
+/* Convert one mux entry from the interface and load into private->mux[] */
+static void scarlett2_usb_populate_mux(struct scarlett2_data *private,
+ u32 mux_entry)
+{
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+
+ int dst_idx, src_idx;
+
+ dst_idx = scarlett2_mux_id_to_num(port_count, SCARLETT2_PORT_OUT,
+ mux_entry & 0xFFF);
+ if (dst_idx < 0)
+ return;
+
+ if (dst_idx >= private->num_mux_dsts) {
+ usb_audio_err(private->mixer->chip,
+ "BUG: scarlett2_mux_id_to_num(%06x, OUT): %d >= %d",
+ mux_entry, dst_idx, private->num_mux_dsts);
+ return;
+ }
+
+ src_idx = scarlett2_mux_id_to_num(port_count, SCARLETT2_PORT_IN,
+ mux_entry >> 12);
+ if (src_idx < 0)
+ return;
+
+ if (src_idx >= private->num_mux_srcs) {
+ usb_audio_err(private->mixer->chip,
+ "BUG: scarlett2_mux_id_to_num(%06x, IN): %d >= %d",
+ mux_entry, src_idx, private->num_mux_srcs);
+ return;
+ }
+
+ private->mux[dst_idx] = src_idx;
+}
+
+/* Send USB message to get mux inputs and then populate private->mux[] */
+static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ int count = private->num_mux_dsts;
+ int err, i;
+
+ struct {
+ __le16 num;
+ __le16 count;
+ } __packed req;
+
+ __le32 data[SCARLETT2_MUX_MAX];
+
+ private->mux_updated = 0;
+
+ req.num = 0;
+ req.count = cpu_to_le16(count);
+
+ err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MUX,
+ &req, sizeof(req),
+ data, count * sizeof(u32));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < count; i++)
+ scarlett2_usb_populate_mux(private, le32_to_cpu(data[i]));
+
return 0;
}
/* Send USB messages to set mux inputs */
static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- const struct scarlett2_ports *ports = info->ports;
- int rate, port_dir_rate;
-
- static const int assignment_order[SCARLETT2_PORT_TYPE_COUNT] = {
- SCARLETT2_PORT_TYPE_PCM,
- SCARLETT2_PORT_TYPE_ANALOGUE,
- SCARLETT2_PORT_TYPE_SPDIF,
- SCARLETT2_PORT_TYPE_ADAT,
- SCARLETT2_PORT_TYPE_MIX,
- SCARLETT2_PORT_TYPE_NONE,
- };
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int table;
struct {
__le16 pad;
@@ -857,43 +1519,44 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
req.pad = 0;
- /* mux settings for each rate */
- for (rate = 0, port_dir_rate = SCARLETT2_PORT_OUT_44;
- port_dir_rate <= SCARLETT2_PORT_OUT_176;
- rate++, port_dir_rate++) {
- int order_num, i, err;
-
- req.num = cpu_to_le16(rate);
-
- for (order_num = 0, i = 0;
- order_num < SCARLETT2_PORT_TYPE_COUNT;
- order_num++) {
- int port_type = assignment_order[order_num];
- int j = scarlett2_get_port_start_num(ports,
- SCARLETT2_PORT_OUT,
- port_type);
- int port_id = ports[port_type].id;
- int channel;
-
- for (channel = 0;
- channel < ports[port_type].num[port_dir_rate];
- channel++, i++, j++)
- /* lower 12 bits for the destination and
- * next 12 bits for the source
- */
- req.data[i] = !port_id
- ? 0
- : cpu_to_le32(
- port_id |
- channel |
- scarlett2_mux_src_num_to_id(
- ports, private->mux[j]
- ) << 12
- );
-
- /* skip private->mux[j] entries not output */
- j += ports[port_type].num[SCARLETT2_PORT_OUT] -
- ports[port_type].num[port_dir_rate];
+ /* set mux settings for each rate */
+ for (table = 0; table < SCARLETT2_MUX_TABLES; table++) {
+ const struct scarlett2_mux_entry *entry;
+
+ /* i counts over the output array */
+ int i = 0, err;
+
+ req.num = cpu_to_le16(table);
+
+ /* loop through each entry */
+ for (entry = info->mux_assignment[table];
+ entry->count;
+ entry++) {
+ int j;
+ int port_type = entry->port_type;
+ int port_idx = entry->start;
+ int mux_idx = scarlett2_get_port_start_num(port_count,
+ SCARLETT2_PORT_OUT, port_type) + port_idx;
+ int dst_id = scarlett2_ports[port_type].id + port_idx;
+
+ /* Empty slots */
+ if (!dst_id) {
+ for (j = 0; j < entry->count; j++)
+ req.data[i++] = 0;
+ continue;
+ }
+
+ /* Non-empty mux slots use the lower 12 bits
+ * for the destination and next 12 bits for
+ * the source
+ */
+ for (j = 0; j < entry->count; j++) {
+ int src_id = scarlett2_mux_src_num_to_id(
+ port_count, private->mux[mux_idx++]);
+ req.data[i++] = cpu_to_le32(dst_id |
+ src_id << 12);
+ dst_id++;
+ }
}
err = scarlett2_usb(mixer, SCARLETT2_USB_SET_MUX,
@@ -908,26 +1571,26 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
/* Send USB message to get meter levels */
static int scarlett2_usb_get_meter_levels(struct usb_mixer_interface *mixer,
- u16 *levels)
+ u16 num_meters, u16 *levels)
{
struct {
__le16 pad;
__le16 num_meters;
__le32 magic;
} __packed req;
- u32 resp[SCARLETT2_NUM_METERS];
+ u32 resp[SCARLETT2_MAX_METERS];
int i, err;
req.pad = 0;
- req.num_meters = cpu_to_le16(SCARLETT2_NUM_METERS);
+ req.num_meters = cpu_to_le16(num_meters);
req.magic = cpu_to_le32(SCARLETT2_USB_METER_LEVELS_GET_MAGIC);
- err = scarlett2_usb(mixer, SCARLETT2_USB_GET_METER_LEVELS,
- &req, sizeof(req), resp, sizeof(resp));
+ err = scarlett2_usb(mixer, SCARLETT2_USB_GET_METER,
+ &req, sizeof(req), resp, num_meters * sizeof(u32));
if (err < 0)
return err;
/* copy, convert to u16 */
- for (i = 0; i < SCARLETT2_NUM_METERS; i++)
+ for (i = 0; i < num_meters; i++)
levels[i] = resp[i];
return 0;
@@ -949,10 +1612,15 @@ static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer,
if (!elem)
return -ENOMEM;
+ /* We set USB_MIXER_BESPOKEN type, so that the core USB mixer code
+ * ignores them for resume and other operations.
+ * Also, the head.id field is set to 0, as we don't use this field.
+ */
elem->head.mixer = mixer;
elem->control = index;
- elem->head.id = index;
+ elem->head.id = 0;
elem->channels = channels;
+ elem->val_type = USB_MIXER_BESPOKEN;
kctl = snd_ctl_new1(ncontrol, elem);
if (!kctl) {
@@ -973,6 +1641,64 @@ static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer,
return 0;
}
+/*** Sync Control ***/
+
+/* Update sync control after receiving notification that the status
+ * has changed
+ */
+static int scarlett2_update_sync(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+
+ private->sync_updated = 0;
+ return scarlett2_usb_get_sync_status(mixer, &private->sync);
+}
+
+static int scarlett2_sync_ctl_info(struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static const char *texts[2] = {
+ "Unlocked", "Locked"
+ };
+ return snd_ctl_enum_info(uinfo, 1, 2, texts);
+}
+
+static int scarlett2_sync_ctl_get(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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->sync_updated)
+ scarlett2_update_sync(mixer);
+ ucontrol->value.enumerated.item[0] = private->sync;
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new scarlett2_sync_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .name = "",
+ .info = scarlett2_sync_ctl_info,
+ .get = scarlett2_sync_ctl_get
+};
+
+static int scarlett2_add_sync_ctl(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+
+ /* devices without a mixer also don't support reporting sync status */
+ if (!private->info->has_mixer)
+ return 0;
+
+ return scarlett2_add_new_ctl(mixer, &scarlett2_sync_ctl,
+ 0, 1, "Sync Status", &private->sync_ctl);
+}
+
/*** Analogue Line Out Volume Controls ***/
/* Update hardware volume controls after receiving notification that
@@ -980,12 +1706,14 @@ static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer,
*/
static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
- const struct scarlett2_ports *ports = private->info->ports;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
struct scarlett2_usb_volume_status volume_status;
int num_line_out =
- ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int err, i;
+ int mute;
private->vol_updated = 0;
@@ -997,13 +1725,17 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
volume_status.master_vol + SCARLETT2_VOLUME_BIAS,
0, SCARLETT2_VOLUME_BIAS);
- for (i = 0; i < num_line_out; i++) {
- if (private->vol_sw_hw_switch[i])
- private->vol[i] = private->master_vol;
- }
+ if (info->line_out_hw_vol)
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
+ private->dim_mute[i] = !!volume_status.dim_mute[i];
- for (i = 0; i < private->info->button_count; i++)
- private->buttons[i] = !!volume_status.buttons[i];
+ mute = private->dim_mute[SCARLETT2_BUTTON_MUTE];
+
+ for (i = 0; i < num_line_out; i++)
+ if (private->vol_sw_hw_switch[i]) {
+ private->vol[i] = private->master_vol;
+ private->mute_switch[i] = mute;
+ }
return 0;
}
@@ -1026,31 +1758,38 @@ 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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
- if (private->vol_updated) {
- mutex_lock(&private->data_mutex);
+ mutex_lock(&private->data_mutex);
+ if (private->vol_updated)
scarlett2_update_volumes(mixer);
- mutex_unlock(&private->data_mutex);
- }
+ mutex_unlock(&private->data_mutex);
ucontrol->value.integer.value[0] = private->master_vol;
return 0;
}
+static int line_out_remap(struct scarlett2_data *private, int index)
+{
+ const struct scarlett2_device_info *info = private->info;
+
+ if (!info->line_out_remap_enable)
+ return index;
+ return info->line_out_remap[index];
+}
+
static int scarlett2_volume_ctl_get(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_mixer_data *private = mixer->private_data;
- int index = elem->control;
+ struct scarlett2_data *private = mixer->private_data;
+ int index = line_out_remap(private, elem->control);
- if (private->vol_updated) {
- mutex_lock(&private->data_mutex);
+ mutex_lock(&private->data_mutex);
+ if (private->vol_updated)
scarlett2_update_volumes(mixer);
- mutex_unlock(&private->data_mutex);
- }
+ mutex_unlock(&private->data_mutex);
ucontrol->value.integer.value[0] = private->vol[index];
return 0;
@@ -1061,8 +1800,8 @@ static int scarlett2_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_mixer_data *private = mixer->private_data;
- int index = elem->control;
+ struct scarlett2_data *private = mixer->private_data;
+ int index = line_out_remap(private, elem->control);
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
@@ -1111,8 +1850,71 @@ static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl = {
.tlv = { .p = db_scale_scarlett2_gain }
};
+/*** Mute Switch Controls ***/
+
+static int scarlett2_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;
+ int index = line_out_remap(private, elem->control);
+
+ ucontrol->value.integer.value[0] = private->mute_switch[index];
+ return 0;
+}
+
+static int scarlett2_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 = line_out_remap(private, elem->control);
+ int oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->mute_switch[index];
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_mute_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_mute_ctl_get,
+ .put = scarlett2_mute_ctl_put,
+};
+
/*** HW/SW Volume Switch Controls ***/
+static void scarlett2_sw_hw_ctl_ro(struct scarlett2_data *private, int index)
+{
+ private->sw_hw_ctls[index]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_WRITE;
+}
+
+static void scarlett2_sw_hw_ctl_rw(struct scarlett2_data *private, int index)
+{
+ private->sw_hw_ctls[index]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_WRITE;
+}
+
static int scarlett2_sw_hw_enum_ctl_info(struct snd_kcontrol *kctl,
struct snd_ctl_elem_info *uinfo)
{
@@ -1127,60 +1929,97 @@ static int scarlett2_sw_hw_enum_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
+ struct scarlett2_data *private = elem->head.mixer->private_data;
+ int index = line_out_remap(private, elem->control);
- ucontrol->value.enumerated.item[0] =
- private->vol_sw_hw_switch[elem->control];
+ ucontrol->value.enumerated.item[0] = private->vol_sw_hw_switch[index];
return 0;
}
-static int scarlett2_sw_hw_enum_ctl_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *ucontrol)
+static void scarlett2_vol_ctl_set_writable(struct usb_mixer_interface *mixer,
+ int index, int value)
{
- struct usb_mixer_elem_info *elem = kctl->private_data;
- struct usb_mixer_interface *mixer = elem->head.mixer;
- struct scarlett2_mixer_data *private = mixer->private_data;
-
- int index = elem->control;
- int oval, val, err = 0;
+ struct scarlett2_data *private = mixer->private_data;
+ struct snd_card *card = mixer->chip->card;
- mutex_lock(&private->data_mutex);
+ /* Set/Clear write bits */
+ if (value) {
+ private->vol_ctls[index]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_WRITE;
+ private->mute_ctls[index]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_WRITE;
+ } else {
+ private->vol_ctls[index]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_WRITE;
+ private->mute_ctls[index]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_WRITE;
+ }
- oval = private->vol_sw_hw_switch[index];
- val = !!ucontrol->value.integer.value[0];
+ /* Notify of write bit change */
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
+ &private->vol_ctls[index]->id);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
+ &private->mute_ctls[index]->id);
+}
- if (oval == val)
- goto unlock;
+static int scarlett2_sw_hw_change(struct usb_mixer_interface *mixer,
+ int ctl_index, int val)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ int index = line_out_remap(private, ctl_index);
+ int err;
private->vol_sw_hw_switch[index] = val;
/* Change access mode to RO (hardware controlled volume)
* or RW (software controlled volume)
*/
- if (val)
- private->vol_ctls[index]->vd[0].access &=
- ~SNDRV_CTL_ELEM_ACCESS_WRITE;
- else
- private->vol_ctls[index]->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_WRITE;
+ scarlett2_vol_ctl_set_writable(mixer, ctl_index, !val);
- /* Reset volume to master volume */
+ /* Reset volume/mute to master volume/mute */
private->vol[index] = private->master_vol;
+ private->mute_switch[index] = private->dim_mute[SCARLETT2_BUTTON_MUTE];
/* Set SW volume to current HW volume */
err = scarlett2_usb_set_config(
mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME,
index, private->master_vol - SCARLETT2_VOLUME_BIAS);
if (err < 0)
- goto unlock;
+ return err;
- /* Notify of RO/RW change */
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_INFO,
- &private->vol_ctls[index]->id);
+ /* Set SW mute to current HW mute */
+ err = scarlett2_usb_set_config(
+ mixer, SCARLETT2_CONFIG_MUTE_SWITCH,
+ index, private->dim_mute[SCARLETT2_BUTTON_MUTE]);
+ if (err < 0)
+ return err;
/* Send SW/HW switch change to the device */
- err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
- index, val);
+ return scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
+ index, val);
+}
+
+static int scarlett2_sw_hw_enum_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 ctl_index = elem->control;
+ int index = line_out_remap(private, ctl_index);
+ int oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->vol_sw_hw_switch[index];
+ val = !!ucontrol->value.enumerated.item[0];
+
+ if (oval == val)
+ goto unlock;
+
+ err = scarlett2_sw_hw_change(mixer, ctl_index, val);
+ if (err == 0)
+ err = 1;
unlock:
mutex_unlock(&private->data_mutex);
@@ -1197,6 +2036,55 @@ static const struct snd_kcontrol_new scarlett2_sw_hw_enum_ctl = {
/*** Line Level/Instrument Level Switch Controls ***/
+static int scarlett2_update_input_other(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ private->input_other_updated = 0;
+
+ if (info->level_input_count) {
+ int err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_LEVEL_SWITCH,
+ info->level_input_count + info->level_input_first,
+ private->level_switch);
+ if (err < 0)
+ return err;
+ }
+
+ if (info->pad_input_count) {
+ int err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PAD_SWITCH,
+ info->pad_input_count, private->pad_switch);
+ if (err < 0)
+ return err;
+ }
+
+ if (info->air_input_count) {
+ int err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_AIR_SWITCH,
+ info->air_input_count, private->air_switch);
+ if (err < 0)
+ return err;
+ }
+
+ if (info->phantom_count) {
+ int err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH,
+ info->phantom_count, private->phantom_switch);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
+ 1, &private->phantom_persistence);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
static int scarlett2_level_enum_ctl_info(struct snd_kcontrol *kctl,
struct snd_ctl_elem_info *uinfo)
{
@@ -1211,10 +2099,18 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
+ 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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->input_other_updated)
+ scarlett2_update_input_other(mixer);
+ ucontrol->value.enumerated.item[0] = private->level_switch[index];
+ mutex_unlock(&private->data_mutex);
- ucontrol->value.enumerated.item[0] =
- private->level_switch[elem->control];
return 0;
}
@@ -1223,15 +2119,16 @@ static int scarlett2_level_enum_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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
- int index = elem->control;
+ int index = elem->control + info->level_input_first;
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
oval = private->level_switch[index];
- val = !!ucontrol->value.integer.value[0];
+ val = !!ucontrol->value.enumerated.item[0];
if (oval == val)
goto unlock;
@@ -1241,6 +2138,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);
@@ -1261,10 +2160,16 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = mixer->private_data;
- ucontrol->value.enumerated.item[0] =
+ mutex_lock(&private->data_mutex);
+ if (private->input_other_updated)
+ scarlett2_update_input_other(mixer);
+ ucontrol->value.integer.value[0] =
private->pad_switch[elem->control];
+ mutex_unlock(&private->data_mutex);
+
return 0;
}
@@ -1273,7 +2178,7 @@ 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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
int index = elem->control;
int oval, val, err = 0;
@@ -1291,6 +2196,8 @@ static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl,
/* 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);
@@ -1305,71 +2212,734 @@ static const struct snd_kcontrol_new scarlett2_pad_ctl = {
.put = scarlett2_pad_ctl_put,
};
-/*** Mute/Dim Controls ***/
+/*** Air Switch Controls ***/
-static int scarlett2_button_ctl_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *ucontrol)
+static int scarlett2_air_ctl_get(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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
- if (private->vol_updated) {
- mutex_lock(&private->data_mutex);
- scarlett2_update_volumes(mixer);
- mutex_unlock(&private->data_mutex);
+ mutex_lock(&private->data_mutex);
+ if (private->input_other_updated)
+ scarlett2_update_input_other(mixer);
+ ucontrol->value.integer.value[0] = private->air_switch[elem->control];
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+static int scarlett2_air_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->air_switch[index];
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_air_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_air_ctl_get,
+ .put = scarlett2_air_ctl_put,
+};
+
+/*** Phantom Switch Controls ***/
+
+static int scarlett2_phantom_ctl_get(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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->input_other_updated)
+ scarlett2_update_input_other(mixer);
+ ucontrol->value.integer.value[0] =
+ private->phantom_switch[elem->control];
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+static int scarlett2_phantom_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->phantom_switch[index];
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ private->phantom_switch[index] = val;
+
+ /* Send switch change to the device */
+ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH,
+ index, val);
+ if (err == 0)
+ err = 1;
+
+unlock:
+ mutex_unlock(&private->data_mutex);
+ return err;
+}
+
+static const struct snd_kcontrol_new scarlett2_phantom_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_phantom_ctl_get,
+ .put = scarlett2_phantom_ctl_put,
+};
+
+/*** Phantom Persistence Control ***/
+
+static int scarlett2_phantom_persistence_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->phantom_persistence;
+ return 0;
+}
+
+static int scarlett2_phantom_persistence_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->phantom_persistence;
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_phantom_persistence_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_phantom_persistence_ctl_get,
+ .put = scarlett2_phantom_persistence_ctl_put,
+};
+
+/*** Direct Monitor Control ***/
+
+static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int err;
+
+ /* monitor_other_enable[0] enables speaker switching
+ * monitor_other_enable[1] enables talkback
+ */
+ u8 monitor_other_enable[2];
+
+ /* monitor_other_switch[0] activates the alternate speakers
+ * monitor_other_switch[1] activates talkback
+ */
+ u8 monitor_other_switch[2];
+
+ private->monitor_other_updated = 0;
+
+ if (info->direct_monitor)
+ return scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_DIRECT_MONITOR,
+ 1, &private->direct_monitor_switch);
+
+ /* if it doesn't do speaker switching then it also doesn't do
+ * talkback
+ */
+ if (!info->has_speaker_switching)
+ return 0;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
+ 2, monitor_other_enable);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
+ 2, monitor_other_switch);
+ if (err < 0)
+ return err;
+
+ if (!monitor_other_enable[0])
+ private->speaker_switching_switch = 0;
+ else
+ private->speaker_switching_switch = monitor_other_switch[0] + 1;
+
+ if (info->has_talkback) {
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] =
+ info->port_count;
+ int num_mixes =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
+ u16 bitmap;
+ int i;
+
+ if (!monitor_other_enable[1])
+ private->talkback_switch = 0;
+ else
+ private->talkback_switch = monitor_other_switch[1] + 1;
+
+ err = scarlett2_usb_get_config(mixer,
+ SCARLETT2_CONFIG_TALKBACK_MAP,
+ 1, &bitmap);
+ for (i = 0; i < num_mixes; i++, bitmap >>= 1)
+ private->talkback_map[i] = bitmap & 1;
}
- ucontrol->value.enumerated.item[0] = private->buttons[elem->control];
return 0;
}
-static int scarlett2_button_ctl_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *ucontrol)
+static int scarlett2_direct_monitor_ctl_get(
+ 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 = elem->head.mixer->private_data;
+
+ mutex_lock(&private->data_mutex);
+ if (private->monitor_other_updated)
+ scarlett2_update_monitor_other(mixer);
+ ucontrol->value.enumerated.item[0] = private->direct_monitor_switch;
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+static int scarlett2_direct_monitor_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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
int index = elem->control;
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
- oval = private->buttons[index];
+ oval = private->direct_monitor_switch;
+ val = min(ucontrol->value.enumerated.item[0], 2U);
+
+ if (oval == val)
+ goto unlock;
+
+ 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;
+}
+
+static int scarlett2_direct_monitor_stereo_enum_ctl_info(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ static const char *const values[3] = {
+ "Off", "Mono", "Stereo"
+ };
+
+ return snd_ctl_enum_info(uinfo, 1, 3, values);
+}
+
+/* Direct Monitor for Solo is mono-only and only needs a boolean control
+ * Direct Monitor for 2i2 is selectable between Off/Mono/Stereo
+ */
+static const struct snd_kcontrol_new scarlett2_direct_monitor_ctl[2] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_direct_monitor_ctl_get,
+ .put = scarlett2_direct_monitor_ctl_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = scarlett2_direct_monitor_stereo_enum_ctl_info,
+ .get = scarlett2_direct_monitor_ctl_get,
+ .put = scarlett2_direct_monitor_ctl_put,
+ }
+};
+
+static int scarlett2_add_direct_monitor_ctl(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ if (!info->direct_monitor)
+ return 0;
+
+ return scarlett2_add_new_ctl(
+ mixer, &scarlett2_direct_monitor_ctl[info->direct_monitor - 1],
+ 0, 1, "Direct Monitor Playback Switch",
+ &private->direct_monitor_ctl);
+}
+
+/*** Speaker Switching Control ***/
+
+static int scarlett2_speaker_switch_enum_ctl_info(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ static const char *const values[3] = {
+ "Off", "Main", "Alt"
+ };
+
+ return snd_ctl_enum_info(uinfo, 1, 3, values);
+}
+
+static int scarlett2_speaker_switch_enum_ctl_get(
+ 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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->monitor_other_updated)
+ scarlett2_update_monitor_other(mixer);
+ ucontrol->value.enumerated.item[0] = private->speaker_switching_switch;
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+/* when speaker switching gets enabled, switch the main/alt speakers
+ * to HW volume and disable those controls
+ */
+static int scarlett2_speaker_switch_enable(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ int i, err;
+
+ for (i = 0; i < 4; i++) {
+ int index = line_out_remap(private, i);
+
+ /* switch the main/alt speakers to HW volume */
+ if (!private->vol_sw_hw_switch[index]) {
+ err = scarlett2_sw_hw_change(private->mixer, i, 1);
+ if (err < 0)
+ return err;
+ }
+
+ /* disable the line out SW/HW switch */
+ scarlett2_sw_hw_ctl_ro(private, i);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
+ &private->sw_hw_ctls[i]->id);
+ }
+
+ /* when the next monitor-other notify comes in, update the mux
+ * configuration
+ */
+ private->speaker_switching_switched = 1;
+
+ return 0;
+}
+
+/* when speaker switching gets disabled, reenable the hw/sw controls
+ * and invalidate the routing
+ */
+static void scarlett2_speaker_switch_disable(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ int i;
+
+ /* enable the line out SW/HW switch */
+ for (i = 0; i < 4; i++) {
+ scarlett2_sw_hw_ctl_rw(private, i);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
+ &private->sw_hw_ctls[i]->id);
+ }
+
+ /* when the next monitor-other notify comes in, update the mux
+ * configuration
+ */
+ private->speaker_switching_switched = 1;
+}
+
+static int scarlett2_speaker_switch_enum_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->speaker_switching_switch;
+ val = min(ucontrol->value.enumerated.item[0], 2U);
+
+ if (oval == val)
+ goto unlock;
+
+ private->speaker_switching_switch = val;
+
+ /* enable/disable speaker switching */
+ err = scarlett2_usb_set_config(
+ mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
+ 0, !!val);
+ if (err < 0)
+ goto unlock;
+
+ /* 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;
+
+ /* update controls if speaker switching gets enabled or disabled */
+ if (!oval && val)
+ err = scarlett2_speaker_switch_enable(mixer);
+ else if (oval && !val)
+ scarlett2_speaker_switch_disable(mixer);
+
+ if (err == 0)
+ err = 1;
+
+unlock:
+ mutex_unlock(&private->data_mutex);
+ return err;
+}
+
+static const struct snd_kcontrol_new scarlett2_speaker_switch_enum_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = scarlett2_speaker_switch_enum_ctl_info,
+ .get = scarlett2_speaker_switch_enum_ctl_get,
+ .put = scarlett2_speaker_switch_enum_ctl_put,
+};
+
+static int scarlett2_add_speaker_switch_ctl(
+ struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ if (!info->has_speaker_switching)
+ return 0;
+
+ return scarlett2_add_new_ctl(
+ mixer, &scarlett2_speaker_switch_enum_ctl,
+ 0, 1, "Speaker Switching Playback Enum",
+ &private->speaker_switching_ctl);
+}
+
+/*** Talkback and Talkback Map Controls ***/
+
+static int scarlett2_talkback_enum_ctl_info(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ static const char *const values[3] = {
+ "Disabled", "Off", "On"
+ };
+
+ return snd_ctl_enum_info(uinfo, 1, 3, values);
+}
+
+static int scarlett2_talkback_enum_ctl_get(
+ 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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->monitor_other_updated)
+ scarlett2_update_monitor_other(mixer);
+ ucontrol->value.enumerated.item[0] = private->talkback_switch;
+ mutex_unlock(&private->data_mutex);
+
+ return 0;
+}
+
+static int scarlett2_talkback_enum_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->talkback_switch;
+ val = min(ucontrol->value.enumerated.item[0], 2U);
+
+ if (oval == val)
+ goto unlock;
+
+ private->talkback_switch = val;
+
+ /* enable/disable talkback */
+ err = scarlett2_usb_set_config(
+ mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
+ 1, !!val);
+ if (err < 0)
+ goto unlock;
+
+ /* 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_talkback_enum_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = scarlett2_talkback_enum_ctl_info,
+ .get = scarlett2_talkback_enum_ctl_get,
+ .put = scarlett2_talkback_enum_ctl_put,
+};
+
+static int scarlett2_talkback_map_ctl_get(
+ 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;
+
+ ucontrol->value.integer.value[0] = private->talkback_map[index];
+
+ return 0;
+}
+
+static int scarlett2_talkback_map_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;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] =
+ private->info->port_count;
+ int num_mixes = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
+
+ int index = elem->control;
+ int oval, val, err = 0, i;
+ u16 bitmap = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->talkback_map[index];
val = !!ucontrol->value.integer.value[0];
if (oval == val)
goto unlock;
- private->buttons[index] = val;
+ private->talkback_map[index] = val;
+
+ for (i = 0; i < num_mixes; i++)
+ bitmap |= private->talkback_map[i] << i;
+
+ /* 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_talkback_map_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_talkback_map_ctl_get,
+ .put = scarlett2_talkback_map_ctl_put,
+};
+
+static int scarlett2_add_talkback_ctls(
+ struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int num_mixes = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
+ int err, i;
+ char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+
+ if (!info->has_talkback)
+ return 0;
+
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_talkback_enum_ctl,
+ 0, 1, "Talkback Playback Enum",
+ &private->talkback_ctl);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < num_mixes; i++) {
+ snprintf(s, sizeof(s),
+ "Talkback Mix %c Playback Switch", i + 'A');
+ err = scarlett2_add_new_ctl(mixer, &scarlett2_talkback_map_ctl,
+ i, 1, s, NULL);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+/*** Dim/Mute Controls ***/
+
+static int scarlett2_dim_mute_ctl_get(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;
+
+ mutex_lock(&private->data_mutex);
+ if (private->vol_updated)
+ scarlett2_update_volumes(mixer);
+ mutex_unlock(&private->data_mutex);
+
+ ucontrol->value.integer.value[0] = private->dim_mute[elem->control];
+ return 0;
+}
+
+static int scarlett2_dim_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;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int num_line_out =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
+
+ int index = elem->control;
+ int oval, val, err = 0, i;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->dim_mute[index];
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ private->dim_mute[index] = val;
/* Send switch change to the device */
- err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_BUTTONS,
+ 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 < num_line_out; i++) {
+ int line_index = line_out_remap(private, i);
+
+ if (private->vol_sw_hw_switch[line_index]) {
+ private->mute_switch[line_index] = val;
+ snd_ctl_notify(mixer->chip->card,
+ SNDRV_CTL_EVENT_MASK_INFO,
+ &private->mute_ctls[i]->id);
+ }
+ }
unlock:
mutex_unlock(&private->data_mutex);
return err;
}
-static const struct snd_kcontrol_new scarlett2_button_ctl = {
+static const struct snd_kcontrol_new scarlett2_dim_mute_ctl = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "",
.info = snd_ctl_boolean_mono_info,
- .get = scarlett2_button_ctl_get,
- .put = scarlett2_button_ctl_put
+ .get = scarlett2_dim_mute_ctl_get,
+ .put = scarlett2_dim_mute_ctl_put
};
/*** Create the analogue output controls ***/
static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- const struct scarlett2_ports *ports = info->ports;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int num_line_out =
- ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int err, i;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -1385,6 +2955,7 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
/* Add volume controls */
for (i = 0; i < num_line_out; i++) {
+ int index = line_out_remap(private, i);
/* Fader */
if (info->line_out_descrs[i])
@@ -1401,10 +2972,22 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- /* Make the fader read-only if the SW/HW switch is set to HW */
- if (private->vol_sw_hw_switch[i])
- private->vol_ctls[i]->vd[0].access &=
- ~SNDRV_CTL_ELEM_ACCESS_WRITE;
+ /* Mute Switch */
+ snprintf(s, sizeof(s),
+ "Line %02d Mute Playback Switch",
+ i + 1);
+ err = scarlett2_add_new_ctl(mixer,
+ &scarlett2_mute_ctl,
+ i, 1, s,
+ &private->mute_ctls[i]);
+ if (err < 0)
+ return err;
+
+ /* Make the fader and mute controls read-only if the
+ * SW/HW switch is set to HW
+ */
+ if (private->vol_sw_hw_switch[index])
+ scarlett2_vol_ctl_set_writable(mixer, i, 0);
/* SW/HW Switch */
if (info->line_out_hw_vol) {
@@ -1413,20 +2996,29 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
i + 1);
err = scarlett2_add_new_ctl(mixer,
&scarlett2_sw_hw_enum_ctl,
- i, 1, s, NULL);
+ i, 1, s,
+ &private->sw_hw_ctls[i]);
if (err < 0)
return err;
+
+ /* Make the switch read-only if the line is
+ * involved in speaker switching
+ */
+ if (private->speaker_switching_switch && i < 4)
+ scarlett2_sw_hw_ctl_ro(private, i);
}
}
- /* Add HW button controls */
- for (i = 0; i < private->info->button_count; i++) {
- err = scarlett2_add_new_ctl(mixer, &scarlett2_button_ctl,
- i, 1, scarlett2_button_names[i],
- &private->button_ctls[i]);
- if (err < 0)
- return err;
- }
+ /* Add dim/mute controls */
+ if (info->line_out_hw_vol)
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++) {
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_dim_mute_ctl,
+ i, 1, scarlett2_dim_mute_names[i],
+ &private->dim_mute_ctls[i]);
+ if (err < 0)
+ return err;
+ }
return 0;
}
@@ -1435,25 +3027,70 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
int err, i;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ const char *fmt = "Line In %d %s Capture %s";
+ const char *fmt2 = "Line In %d-%d %s Capture %s";
/* Add input level (line/inst) controls */
for (i = 0; i < info->level_input_count; i++) {
- snprintf(s, sizeof(s), "Line In %d Level Capture Enum", i + 1);
+ snprintf(s, sizeof(s), fmt, i + 1 + info->level_input_first,
+ "Level", "Enum");
err = scarlett2_add_new_ctl(mixer, &scarlett2_level_enum_ctl,
- i, 1, s, NULL);
+ i, 1, s, &private->level_ctls[i]);
if (err < 0)
return err;
}
/* Add input pad controls */
for (i = 0; i < info->pad_input_count; i++) {
- snprintf(s, sizeof(s), "Line In %d Pad Capture Switch", i + 1);
+ snprintf(s, sizeof(s), fmt, i + 1, "Pad", "Switch");
err = scarlett2_add_new_ctl(mixer, &scarlett2_pad_ctl,
- i, 1, s, NULL);
+ i, 1, s, &private->pad_ctls[i]);
+ if (err < 0)
+ return err;
+ }
+
+ /* Add input air controls */
+ for (i = 0; i < info->air_input_count; i++) {
+ snprintf(s, sizeof(s), fmt, i + 1, "Air", "Switch");
+ err = scarlett2_add_new_ctl(mixer, &scarlett2_air_ctl,
+ i, 1, s, &private->air_ctls[i]);
+ if (err < 0)
+ return err;
+ }
+
+ /* Add input phantom controls */
+ if (info->inputs_per_phantom == 1) {
+ for (i = 0; i < info->phantom_count; i++) {
+ snprintf(s, sizeof(s), fmt, i + 1,
+ "Phantom Power", "Switch");
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_phantom_ctl,
+ i, 1, s, &private->phantom_ctls[i]);
+ if (err < 0)
+ return err;
+ }
+ } else if (info->inputs_per_phantom > 1) {
+ for (i = 0; i < info->phantom_count; i++) {
+ int from = i * info->inputs_per_phantom + 1;
+ int to = (i + 1) * info->inputs_per_phantom;
+
+ snprintf(s, sizeof(s), fmt2, from, to,
+ "Phantom Power", "Switch");
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_phantom_ctl,
+ i, 1, s, &private->phantom_ctls[i]);
+ if (err < 0)
+ return err;
+ }
+ }
+ if (info->phantom_count) {
+ err = scarlett2_add_new_ctl(
+ mixer, &scarlett2_phantom_persistence_ctl, 0, 1,
+ "Phantom Power Persistence Capture Switch", NULL);
if (err < 0)
return err;
}
@@ -1480,7 +3117,7 @@ static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
+ struct scarlett2_data *private = elem->head.mixer->private_data;
ucontrol->value.integer.value[0] = private->mix[elem->control];
return 0;
@@ -1491,22 +3128,23 @@ 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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- const struct scarlett2_ports *ports = info->ports;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int oval, val, num_mixer_in, mix_num, err = 0;
+ int index = elem->control;
mutex_lock(&private->data_mutex);
- oval = private->mix[elem->control];
+ oval = private->mix[index];
val = ucontrol->value.integer.value[0];
- num_mixer_in = ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
- mix_num = elem->control / num_mixer_in;
+ num_mixer_in = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+ mix_num = index / num_mixer_in;
if (oval == val)
goto unlock;
- private->mix[elem->control] = val;
+ private->mix[index] = val;
err = scarlett2_usb_set_mix(mixer, mix_num);
if (err == 0)
err = 1;
@@ -1536,16 +3174,19 @@ static const struct snd_kcontrol_new scarlett2_mixer_ctl = {
static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
- const struct scarlett2_ports *ports = private->info->ports;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int err, i, j;
int index;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- int num_inputs = ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
- int num_outputs = ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_IN];
+ int num_inputs =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+ int num_outputs =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
- for (i = 0, index = 0; i < num_outputs; i++) {
+ for (i = 0, index = 0; i < num_outputs; i++)
for (j = 0; j < num_inputs; j++, index++) {
snprintf(s, sizeof(s),
"Mix %c Input %02d Playback Volume",
@@ -1555,7 +3196,6 @@ static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
}
- }
return 0;
}
@@ -1566,8 +3206,9 @@ static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl,
struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
- const struct scarlett2_ports *ports = private->info->ports;
+ struct scarlett2_data *private = elem->head.mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
unsigned int item = uinfo->value.enumerated.item;
int items = private->num_mux_srcs;
int port_type;
@@ -1582,13 +3223,15 @@ static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl,
for (port_type = 0;
port_type < SCARLETT2_PORT_TYPE_COUNT;
port_type++) {
- if (item < ports[port_type].num[SCARLETT2_PORT_IN]) {
+ if (item < port_count[port_type][SCARLETT2_PORT_IN]) {
+ const struct scarlett2_port *port =
+ &scarlett2_ports[port_type];
+
sprintf(uinfo->value.enumerated.name,
- ports[port_type].src_descr,
- item + ports[port_type].src_num_offset);
+ port->src_descr, item + port->src_num_offset);
return 0;
}
- item -= ports[port_type].num[SCARLETT2_PORT_IN];
+ item -= port_count[port_type][SCARLETT2_PORT_IN];
}
return -EINVAL;
@@ -1598,9 +3241,23 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- struct scarlett2_mixer_data *private = elem->head.mixer->private_data;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int line_out_count =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
+ int index = elem->control;
+
+ if (index < line_out_count)
+ index = line_out_remap(private, index);
+
+ mutex_lock(&private->data_mutex);
+ if (private->mux_updated)
+ scarlett2_usb_get_mux(mixer);
+ ucontrol->value.enumerated.item[0] = private->mux[index];
+ mutex_unlock(&private->data_mutex);
- ucontrol->value.enumerated.item[0] = private->mux[elem->control];
return 0;
}
@@ -1609,15 +3266,22 @@ static int scarlett2_mux_src_enum_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_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int line_out_count =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int index = elem->control;
int oval, val, err = 0;
+ if (index < line_out_count)
+ index = line_out_remap(private, index);
+
mutex_lock(&private->data_mutex);
oval = private->mux[index];
- val = clamp(ucontrol->value.integer.value[0],
- 0L, private->num_mux_srcs - 1L);
+ val = min(ucontrol->value.enumerated.item[0],
+ private->num_mux_srcs - 1U);
if (oval == val)
goto unlock;
@@ -1642,26 +3306,29 @@ static const struct snd_kcontrol_new scarlett2_mux_src_enum_ctl = {
static int scarlett2_add_mux_enums(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
- const struct scarlett2_ports *ports = private->info->ports;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int port_type, channel, i;
for (i = 0, port_type = 0;
port_type < SCARLETT2_PORT_TYPE_COUNT;
port_type++) {
for (channel = 0;
- channel < ports[port_type].num[SCARLETT2_PORT_OUT];
+ channel < port_count[port_type][SCARLETT2_PORT_OUT];
channel++, i++) {
int err;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- const char *const descr = ports[port_type].dst_descr;
+ const char *const descr =
+ scarlett2_ports[port_type].dst_descr;
snprintf(s, sizeof(s) - 5, descr, channel + 1);
strcat(s, " Enum");
err = scarlett2_add_new_ctl(mixer,
&scarlett2_mux_src_enum_ctl,
- i, 1, s, NULL);
+ i, 1, s,
+ &private->mux_ctls[i]);
if (err < 0)
return err;
}
@@ -1689,10 +3356,11 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
- u16 meter_levels[SCARLETT2_NUM_METERS];
+ u16 meter_levels[SCARLETT2_MAX_METERS];
int i, err;
- err = scarlett2_usb_get_meter_levels(elem->head.mixer, meter_levels);
+ err = scarlett2_usb_get_meter_levels(elem->head.mixer, elem->channels,
+ meter_levels);
if (err < 0)
return err;
@@ -1712,16 +3380,89 @@ static const struct snd_kcontrol_new scarlett2_meter_ctl = {
static int scarlett2_add_meter_ctl(struct usb_mixer_interface *mixer)
{
+ struct scarlett2_data *private = mixer->private_data;
+
+ /* devices without a mixer also don't support reporting levels */
+ if (!private->info->has_mixer)
+ return 0;
+
return scarlett2_add_new_ctl(mixer, &scarlett2_meter_ctl,
- 0, SCARLETT2_NUM_METERS,
+ 0, private->num_mux_dsts,
"Level Meter", NULL);
}
+/*** MSD Controls ***/
+
+static int scarlett2_msd_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->msd_switch;
+ return 0;
+}
+
+static int scarlett2_msd_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 oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ oval = private->msd_switch;
+ val = !!ucontrol->value.integer.value[0];
+
+ if (oval == val)
+ goto unlock;
+
+ 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;
+}
+
+static const struct snd_kcontrol_new scarlett2_msd_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_msd_ctl_get,
+ .put = scarlett2_msd_ctl_put,
+};
+
+static int scarlett2_add_msd_ctl(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ if (!info->has_msd_mode)
+ return 0;
+
+ /* If MSD mode is off, hide the switch by default */
+ if (!private->msd_switch && !(mixer->chip->setup & SCARLETT2_MSD_ENABLE))
+ return 0;
+
+ /* Add MSD control */
+ return scarlett2_add_new_ctl(mixer, &scarlett2_msd_ctl,
+ 0, 1, "MSD Mode", NULL);
+}
+
/*** Cleanup/Suspend Callbacks ***/
static void scarlett2_private_free(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
cancel_delayed_work_sync(&private->work);
kfree(private);
@@ -1730,7 +3471,7 @@ static void scarlett2_private_free(struct usb_mixer_interface *mixer)
static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
if (cancel_delayed_work_sync(&private->work))
scarlett2_config_save(private->mixer);
@@ -1738,77 +3479,61 @@ static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
/*** Initialisation ***/
-static int scarlett2_count_mux_srcs(const struct scarlett2_ports *ports)
+static void scarlett2_count_mux_io(struct scarlett2_data *private)
{
- int port_type, count = 0;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int port_type, srcs = 0, dsts = 0;
for (port_type = 0;
port_type < SCARLETT2_PORT_TYPE_COUNT;
- port_type++)
- count += ports[port_type].num[SCARLETT2_PORT_IN];
+ port_type++) {
+ srcs += port_count[port_type][SCARLETT2_PORT_IN];
+ dsts += port_count[port_type][SCARLETT2_PORT_OUT];
+ }
- return count;
+ private->num_mux_srcs = srcs;
+ private->num_mux_dsts = dsts;
}
-/* Default routing connects PCM outputs and inputs to Analogue,
- * S/PDIF, then ADAT
+/* Look through the interface descriptors for the Focusrite Control
+ * interface (bInterfaceClass = 255 Vendor Specific Class) and set
+ * bInterfaceNumber, bEndpointAddress, wMaxPacketSize, and bInterval
+ * in private
*/
-static void scarlett2_init_routing(u8 *mux,
- const struct scarlett2_ports *ports)
+static int scarlett2_find_fc_interface(struct usb_device *dev,
+ struct scarlett2_data *private)
{
- int i, input_num, input_count, port_type;
- int output_num, output_count, port_type_connect_num;
+ struct usb_host_config *config = dev->actconfig;
+ int i;
- static const int connect_order[] = {
- SCARLETT2_PORT_TYPE_ANALOGUE,
- SCARLETT2_PORT_TYPE_SPDIF,
- SCARLETT2_PORT_TYPE_ADAT,
- -1
- };
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ struct usb_interface *intf = config->interface[i];
+ struct usb_interface_descriptor *desc =
+ &intf->altsetting[0].desc;
+ struct usb_endpoint_descriptor *epd;
- /* Assign PCM inputs (routing outputs) */
- output_num = scarlett2_get_port_start_num(ports,
- SCARLETT2_PORT_OUT,
- SCARLETT2_PORT_TYPE_PCM);
- output_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_OUT];
-
- for (port_type = connect_order[port_type_connect_num = 0];
- port_type >= 0;
- port_type = connect_order[++port_type_connect_num]) {
- input_num = scarlett2_get_port_start_num(
- ports, SCARLETT2_PORT_IN, port_type);
- input_count = ports[port_type].num[SCARLETT2_PORT_IN];
- for (i = 0;
- i < input_count && output_count;
- i++, output_count--)
- mux[output_num++] = input_num++;
- }
+ if (desc->bInterfaceClass != 255)
+ continue;
- /* Assign PCM outputs (routing inputs) */
- input_num = scarlett2_get_port_start_num(ports,
- SCARLETT2_PORT_IN,
- SCARLETT2_PORT_TYPE_PCM);
- input_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_IN];
-
- for (port_type = connect_order[port_type_connect_num = 0];
- port_type >= 0;
- port_type = connect_order[++port_type_connect_num]) {
- output_num = scarlett2_get_port_start_num(
- ports, SCARLETT2_PORT_OUT, port_type);
- output_count = ports[port_type].num[SCARLETT2_PORT_OUT];
- for (i = 0;
- i < output_count && input_count;
- i++, input_count--)
- mux[output_num++] = input_num++;
+ epd = get_endpoint(intf->altsetting, 0);
+ private->bInterfaceNumber = desc->bInterfaceNumber;
+ private->bEndpointAddress = epd->bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ private->wMaxPacketSize = le16_to_cpu(epd->wMaxPacketSize);
+ private->bInterval = epd->bInterval;
+ return 0;
}
+
+ return -EINVAL;
}
-/* Initialise private data, routing, sequence number */
+/* Initialise private data */
static int scarlett2_init_private(struct usb_mixer_interface *mixer,
const struct scarlett2_device_info *info)
{
- struct scarlett2_mixer_data *private =
- kzalloc(sizeof(struct scarlett2_mixer_data), GFP_KERNEL);
+ struct scarlett2_data *private =
+ kzalloc(sizeof(struct scarlett2_data), GFP_KERNEL);
if (!private)
return -ENOMEM;
@@ -1816,68 +3541,102 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
mutex_init(&private->usb_mutex);
mutex_init(&private->data_mutex);
INIT_DELAYED_WORK(&private->work, scarlett2_config_save_work);
- private->info = info;
- private->num_mux_srcs = scarlett2_count_mux_srcs(info->ports);
- private->scarlett2_seq = 0;
- private->mixer = mixer;
+
mixer->private_data = private;
mixer->private_free = scarlett2_private_free;
mixer->private_suspend = scarlett2_private_suspend;
- /* Setup default routing */
- scarlett2_init_routing(private->mux, info->ports);
+ private->info = info;
+ scarlett2_count_mux_io(private);
+ private->scarlett2_seq = 0;
+ private->mixer = mixer;
- /* Initialise the sequence number used for the proprietary commands */
- return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0);
+ return scarlett2_find_fc_interface(mixer->chip->dev, private);
}
-/* Read line-in config and line-out volume settings on start */
+/* Cargo cult proprietary initialisation sequence */
+static int scarlett2_usb_init(struct usb_mixer_interface *mixer)
+{
+ struct usb_device *dev = mixer->chip->dev;
+ struct scarlett2_data *private = mixer->private_data;
+ u8 buf[24];
+ int err;
+
+ if (usb_pipe_type_check(dev, usb_sndctrlpipe(dev, 0)))
+ return -EINVAL;
+
+ /* step 0 */
+ err = scarlett2_usb_rx(dev, private->bInterfaceNumber,
+ SCARLETT2_USB_CMD_INIT, buf, sizeof(buf));
+ if (err < 0)
+ return err;
+
+ /* step 1 */
+ private->scarlett2_seq = 1;
+ err = scarlett2_usb(mixer, SCARLETT2_USB_INIT_1, NULL, 0, NULL, 0);
+ if (err < 0)
+ return err;
+
+ /* step 2 */
+ private->scarlett2_seq = 1;
+ return scarlett2_usb(mixer, SCARLETT2_USB_INIT_2, NULL, 0, NULL, 84);
+}
+
+/* Read configuration from the interface on start */
static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- const struct scarlett2_ports *ports = info->ports;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int num_line_out =
- ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
- u8 level_switches[SCARLETT2_LEVEL_SWITCH_MAX];
- u8 pad_switches[SCARLETT2_PAD_SWITCH_MAX];
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
+ int num_mixer_out =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
struct scarlett2_usb_volume_status volume_status;
int err, i;
- if (info->level_input_count) {
+ if (info->has_msd_mode) {
err = scarlett2_usb_get_config(
- mixer,
- SCARLETT2_CONFIG_LEVEL_SWITCH,
- info->level_input_count,
- level_switches);
+ mixer, SCARLETT2_CONFIG_MSD_SWITCH,
+ 1, &private->msd_switch);
if (err < 0)
return err;
- for (i = 0; i < info->level_input_count; i++)
- private->level_switch[i] = level_switches[i];
- }
- if (info->pad_input_count) {
- err = scarlett2_usb_get_config(
- mixer,
- SCARLETT2_CONFIG_PAD_SWITCH,
- info->pad_input_count,
- pad_switches);
- if (err < 0)
- return err;
- for (i = 0; i < info->pad_input_count; i++)
- private->pad_switch[i] = pad_switches[i];
+ /* no other controls are created if MSD mode is on */
+ if (private->msd_switch)
+ return 0;
}
+ err = scarlett2_update_input_other(mixer);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_update_monitor_other(mixer);
+ if (err < 0)
+ return err;
+
+ /* the rest of the configuration is for devices with a mixer */
+ if (!info->has_mixer)
+ return 0;
+
+ err = scarlett2_update_sync(mixer);
+ if (err < 0)
+ return err;
+
err = scarlett2_usb_get_volume_status(mixer, &volume_status);
if (err < 0)
return err;
+ if (info->line_out_hw_vol)
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
+ private->dim_mute[i] = !!volume_status.dim_mute[i];
+
private->master_vol = clamp(
volume_status.master_vol + SCARLETT2_VOLUME_BIAS,
0, SCARLETT2_VOLUME_BIAS);
for (i = 0; i < num_line_out; i++) {
- int volume;
+ int volume, mute;
private->vol_sw_hw_switch[i] =
info->line_out_hw_vol
@@ -1889,72 +3648,178 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
volume = clamp(volume + SCARLETT2_VOLUME_BIAS,
0, SCARLETT2_VOLUME_BIAS);
private->vol[i] = volume;
+
+ mute = private->vol_sw_hw_switch[i]
+ ? private->dim_mute[SCARLETT2_BUTTON_MUTE]
+ : volume_status.mute_switch[i];
+ private->mute_switch[i] = mute;
+ }
+
+ for (i = 0; i < num_mixer_out; i++) {
+ err = scarlett2_usb_get_mix(mixer, i);
+ if (err < 0)
+ return err;
}
- for (i = 0; i < info->button_count; i++)
- private->buttons[i] = !!volume_status.buttons[i];
+ return scarlett2_usb_get_mux(mixer);
+}
- return 0;
+/* Notify on sync change */
+static void scarlett2_notify_sync(
+ struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+
+ private->sync_updated = 1;
+
+ snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->sync_ctl->id);
}
-/* Notify on volume change */
-static void scarlett2_mixer_interrupt_vol_change(
+/* Notify on monitor change */
+static void scarlett2_notify_monitor(
struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
- const struct scarlett2_ports *ports = private->info->ports;
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int num_line_out =
- ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int i;
+ /* if line_out_hw_vol is 0, there are no controls to update */
+ if (!info->line_out_hw_vol)
+ return;
+
private->vol_updated = 1;
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->master_vol_ctl->id);
- for (i = 0; i < num_line_out; i++) {
- if (!private->vol_sw_hw_switch[i])
- continue;
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &private->vol_ctls[i]->id);
- }
+ for (i = 0; i < num_line_out; i++)
+ if (private->vol_sw_hw_switch[line_out_remap(private, i)])
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->vol_ctls[i]->id);
}
-/* Notify on button change */
-static void scarlett2_mixer_interrupt_button_change(
+/* Notify on dim/mute change */
+static void scarlett2_notify_dim_mute(
struct usb_mixer_interface *mixer)
{
- struct scarlett2_mixer_data *private = mixer->private_data;
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int num_line_out =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int i;
private->vol_updated = 1;
- for (i = 0; i < private->info->button_count; i++)
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &private->button_ctls[i]->id);
+ if (!info->line_out_hw_vol)
+ return;
+
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->dim_mute_ctls[i]->id);
+
+ for (i = 0; i < num_line_out; i++)
+ if (private->vol_sw_hw_switch[line_out_remap(private, i)])
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->mute_ctls[i]->id);
+}
+
+/* Notify on "input other" change (level/pad/air) */
+static void scarlett2_notify_input_other(
+ struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int i;
+
+ private->input_other_updated = 1;
+
+ for (i = 0; i < info->level_input_count; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->level_ctls[i]->id);
+ for (i = 0; i < info->pad_input_count; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->pad_ctls[i]->id);
+ for (i = 0; i < info->air_input_count; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->air_ctls[i]->id);
+ for (i = 0; i < info->phantom_count; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->phantom_ctls[i]->id);
+}
+
+/* Notify on "monitor other" change (direct monitor, speaker
+ * switching, talkback)
+ */
+static void scarlett2_notify_monitor_other(
+ struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ private->monitor_other_updated = 1;
+
+ if (info->direct_monitor) {
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->direct_monitor_ctl->id);
+ return;
+ }
+
+ if (info->has_speaker_switching)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->speaker_switching_ctl->id);
+
+ if (info->has_talkback)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->talkback_ctl->id);
+
+ /* if speaker switching was recently enabled or disabled,
+ * invalidate the dim/mute and mux enum controls
+ */
+ if (private->speaker_switching_switched) {
+ int i;
+
+ scarlett2_notify_dim_mute(mixer);
+
+ private->speaker_switching_switched = 0;
+ private->mux_updated = 1;
+
+ for (i = 0; i < private->num_mux_dsts; i++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->mux_ctls[i]->id);
+ }
}
/* Interrupt callback */
-static void scarlett2_mixer_interrupt(struct urb *urb)
+static void scarlett2_notify(struct urb *urb)
{
struct usb_mixer_interface *mixer = urb->context;
int len = urb->actual_length;
int ustatus = urb->status;
u32 data;
- if (ustatus != 0)
+ if (ustatus != 0 || len != 8)
goto requeue;
- if (len == 8) {
- data = le32_to_cpu(*(__le32 *)urb->transfer_buffer);
- if (data & SCARLETT2_USB_INTERRUPT_VOL_CHANGE)
- scarlett2_mixer_interrupt_vol_change(mixer);
- if (data & SCARLETT2_USB_INTERRUPT_BUTTON_CHANGE)
- scarlett2_mixer_interrupt_button_change(mixer);
- } else {
- usb_audio_err(mixer->chip,
- "scarlett mixer interrupt length %d\n", len);
- }
+ data = le32_to_cpu(*(__le32 *)urb->transfer_buffer);
+ if (data & SCARLETT2_USB_NOTIFY_SYNC)
+ scarlett2_notify_sync(mixer);
+ if (data & SCARLETT2_USB_NOTIFY_MONITOR)
+ scarlett2_notify_monitor(mixer);
+ if (data & SCARLETT2_USB_NOTIFY_DIM_MUTE)
+ scarlett2_notify_dim_mute(mixer);
+ if (data & SCARLETT2_USB_NOTIFY_INPUT_OTHER)
+ scarlett2_notify_input_other(mixer);
+ if (data & SCARLETT2_USB_NOTIFY_MONITOR_OTHER)
+ scarlett2_notify_monitor_other(mixer);
requeue:
if (ustatus != -ENOENT &&
@@ -1965,11 +3830,11 @@ requeue:
}
}
-static int scarlett2_mixer_status_create(struct usb_mixer_interface *mixer)
+static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
{
struct usb_device *dev = mixer->chip->dev;
- unsigned int pipe = usb_rcvintpipe(dev,
- SCARLETT2_USB_INTERRUPT_ENDPOINT);
+ struct scarlett2_data *private = mixer->private_data;
+ unsigned int pipe = usb_rcvintpipe(dev, private->bEndpointAddress);
void *transfer_buffer;
if (mixer->urb) {
@@ -1985,25 +3850,35 @@ static int scarlett2_mixer_status_create(struct usb_mixer_interface *mixer)
if (!mixer->urb)
return -ENOMEM;
- transfer_buffer = kmalloc(SCARLETT2_USB_INTERRUPT_MAX_DATA, GFP_KERNEL);
+ transfer_buffer = kmalloc(private->wMaxPacketSize, GFP_KERNEL);
if (!transfer_buffer)
return -ENOMEM;
usb_fill_int_urb(mixer->urb, dev, pipe,
- transfer_buffer, SCARLETT2_USB_INTERRUPT_MAX_DATA,
- scarlett2_mixer_interrupt, mixer,
- SCARLETT2_USB_INTERRUPT_INTERVAL);
+ transfer_buffer, private->wMaxPacketSize,
+ scarlett2_notify, mixer, private->bInterval);
return usb_submit_urb(mixer->urb, GFP_KERNEL);
}
-static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
- const struct scarlett2_device_info *info)
+static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
{
+ const struct scarlett2_device_info **info = scarlett2_devices;
int err;
- /* Initialise private data, routing, sequence number */
- err = scarlett2_init_private(mixer, info);
+ /* Find device in scarlett2_devices */
+ while (*info && (*info)->usb_id != mixer->chip->usb_id)
+ info++;
+ if (!*info)
+ return -EINVAL;
+
+ /* Initialise private data */
+ err = scarlett2_init_private(mixer, *info);
+ if (err < 0)
+ return err;
+
+ /* Send proprietary USB initialisation sequence */
+ err = scarlett2_usb_init(mixer);
if (err < 0)
return err;
@@ -2012,6 +3887,15 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
if (err < 0)
return err;
+ /* Create the MSD control */
+ err = scarlett2_add_msd_ctl(mixer);
+ if (err < 0)
+ return err;
+
+ /* If MSD mode is enabled, don't create any other controls */
+ if (((struct scarlett2_data *)mixer->private_data)->msd_switch)
+ return 0;
+
/* Create the analogue output controls */
err = scarlett2_add_line_out_ctls(mixer);
if (err < 0)
@@ -2037,12 +3921,30 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
if (err < 0)
return err;
- /* Set up the interrupt polling if there are hardware buttons */
- if (info->button_count) {
- err = scarlett2_mixer_status_create(mixer);
- if (err < 0)
- return err;
- }
+ /* Create the sync control */
+ err = scarlett2_add_sync_ctl(mixer);
+ if (err < 0)
+ return err;
+
+ /* Create the direct monitor control */
+ err = scarlett2_add_direct_monitor_ctl(mixer);
+ if (err < 0)
+ return err;
+
+ /* Create the speaker switching control */
+ err = scarlett2_add_speaker_switch_ctl(mixer);
+ if (err < 0)
+ return err;
+
+ /* Create the talkback controls */
+ err = scarlett2_add_talkback_ctls(mixer);
+ if (err < 0)
+ return err;
+
+ /* Set up the interrupt polling */
+ err = scarlett2_init_notify(mixer);
+ if (err < 0)
+ return err;
return 0;
}
@@ -2050,30 +3952,15 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
{
struct snd_usb_audio *chip = mixer->chip;
- const struct scarlett2_device_info *info;
int err;
/* only use UAC_VERSION_2 */
if (!mixer->protocol)
return 0;
- switch (chip->usb_id) {
- case USB_ID(0x1235, 0x8203):
- info = &s6i6_gen2_info;
- break;
- case USB_ID(0x1235, 0x8204):
- info = &s18i8_gen2_info;
- break;
- case USB_ID(0x1235, 0x8201):
- info = &s18i20_gen2_info;
- break;
- default: /* device not (yet) supported */
- return -EINVAL;
- }
-
if (!(chip->setup & SCARLETT2_ENABLE)) {
usb_audio_info(chip,
- "Focusrite Scarlett Gen 2 Mixer Driver disabled; "
+ "Focusrite Scarlett Gen 2/3 Mixer Driver disabled; "
"use options snd_usb_audio vid=0x%04x pid=0x%04x "
"device_setup=1 to enable and report any issues "
"to g@b4.vu",
@@ -2083,10 +3970,10 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
}
usb_audio_info(chip,
- "Focusrite Scarlett Gen 2 Mixer Driver enabled pid=0x%04x",
+ "Focusrite Scarlett Gen 2/3 Mixer Driver enabled pid=0x%04x",
USB_ID_PRODUCT(chip->usb_id));
- err = snd_scarlett_gen2_controls_create(mixer, info);
+ err = snd_scarlett_gen2_controls_create(mixer);
if (err < 0)
usb_audio_err(mixer->chip,
"Error initialising Scarlett Mixer Driver: %d",
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index e5311b6bb3f6..4e5031a68064 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -29,15 +29,21 @@
#define SUBSTREAM_FLAG_SYNC_EP_STARTED 1
/* return the estimated delay based on USB frame counters */
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate)
+static snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
+ struct snd_pcm_runtime *runtime)
{
- int current_frame_number;
- int frame_diff;
+ unsigned int current_frame_number;
+ unsigned int frame_diff;
int est_delay;
+ int queued;
- if (!subs->last_delay)
- return 0; /* short path */
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ queued = bytes_to_frames(runtime, subs->inflight_bytes);
+ if (!queued)
+ return 0;
+ } else if (!subs->running) {
+ return 0;
+ }
current_frame_number = usb_get_current_frame_number(subs->dev);
/*
@@ -49,14 +55,14 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
/* Approximation based on number of samples per USB frame (ms),
some truncation for 44.1 but the estimate is good enough */
- est_delay = frame_diff * rate / 1000;
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
- est_delay = subs->last_delay - est_delay;
- else
- est_delay = subs->last_delay + est_delay;
+ est_delay = frame_diff * runtime->rate / 1000;
+
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ est_delay = queued - est_delay;
+ if (est_delay < 0)
+ est_delay = 0;
+ }
- if (est_delay < 0)
- est_delay = 0;
return est_delay;
}
@@ -65,17 +71,17 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
*/
static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
{
- struct snd_usb_substream *subs = substream->runtime->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_usb_substream *subs = runtime->private_data;
unsigned int hwptr_done;
if (atomic_read(&subs->stream->chip->shutdown))
return SNDRV_PCM_POS_XRUN;
spin_lock(&subs->lock);
hwptr_done = subs->hwptr_done;
- substream->runtime->delay = snd_usb_pcm_delay(subs,
- substream->runtime->rate);
+ runtime->delay = snd_usb_pcm_delay(subs, runtime);
spin_unlock(&subs->lock);
- return hwptr_done / (substream->runtime->frame_bits >> 3);
+ return bytes_to_frames(runtime, hwptr_done);
}
/*
@@ -600,17 +606,14 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
goto unlock;
/* reset the pointer */
+ subs->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
+ subs->inflight_bytes = 0;
subs->hwptr_done = 0;
subs->transfer_done = 0;
- subs->last_delay = 0;
subs->last_frame_number = 0;
+ subs->period_elapsed_pending = 0;
runtime->delay = 0;
- /* for playback, submit the URBs now; otherwise, the first hwptr_done
- * updates for all URBs would happen at the same time when starting */
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
- ret = start_endpoints(subs);
-
unlock:
snd_usb_unlock_shutdown(chip);
return ret;
@@ -1147,28 +1150,23 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
spin_lock_irqsave(&subs->lock, flags);
oldptr = subs->hwptr_done;
subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
+ 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;
}
- /* capture delay is by construction limited to one URB,
- * reset delays here
- */
- runtime->delay = subs->last_delay = 0;
/* realign last_frame_number */
subs->last_frame_number = current_frame_number;
- subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
spin_unlock_irqrestore(&subs->lock, flags);
/* copy a data chunk */
- if (oldptr + bytes > runtime->buffer_size * stride) {
- unsigned int bytes1 =
- runtime->buffer_size * stride - oldptr;
+ if (oldptr + bytes > subs->buffer_bytes) {
+ unsigned int bytes1 = subs->buffer_bytes - oldptr;
+
memcpy(runtime->dma_area + oldptr, cp, bytes1);
memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
} else {
@@ -1180,17 +1178,29 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
snd_pcm_period_elapsed(subs->pcm_substream);
}
+static void urb_ctx_queue_advance(struct snd_usb_substream *subs,
+ struct urb *urb, unsigned int bytes)
+{
+ struct snd_urb_ctx *ctx = urb->context;
+
+ ctx->queued += bytes;
+ subs->inflight_bytes += bytes;
+ subs->hwptr_done += bytes;
+ if (subs->hwptr_done >= subs->buffer_bytes)
+ subs->hwptr_done -= subs->buffer_bytes;
+}
+
static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs,
struct urb *urb, unsigned int bytes)
{
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- unsigned int stride = runtime->frame_bits >> 3;
unsigned int dst_idx = 0;
unsigned int src_idx = subs->hwptr_done;
- unsigned int wrap = runtime->buffer_size * stride;
+ unsigned int wrap = subs->buffer_bytes;
u8 *dst = urb->transfer_buffer;
u8 *src = runtime->dma_area;
u8 marker[] = { 0x05, 0xfa };
+ unsigned int queued = 0;
/*
* The DSP DOP format defines a way to transport DSD samples over
@@ -1229,12 +1239,29 @@ static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs,
dst[dst_idx++] = bitrev8(src[idx]);
else
dst[dst_idx++] = src[idx];
-
- subs->hwptr_done++;
+ queued++;
}
}
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
+
+ urb_ctx_queue_advance(subs, urb, queued);
+}
+
+/* copy bit-reversed bytes onto transfer buffer */
+static void fill_playback_urb_dsd_bitrev(struct snd_usb_substream *subs,
+ struct urb *urb, unsigned int bytes)
+{
+ struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+ const u8 *src = runtime->dma_area;
+ u8 *buf = urb->transfer_buffer;
+ int i, ofs = subs->hwptr_done;
+
+ for (i = 0; i < bytes; i++) {
+ *buf++ = bitrev8(src[ofs]);
+ if (++ofs >= subs->buffer_bytes)
+ ofs = 0;
+ }
+
+ urb_ctx_queue_advance(subs, urb, bytes);
}
static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb,
@@ -1242,10 +1269,10 @@ static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb,
{
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
+ if (subs->hwptr_done + bytes > subs->buffer_bytes) {
/* err, the transferred area goes over buffer boundary. */
- unsigned int bytes1 =
- runtime->buffer_size * stride - subs->hwptr_done;
+ unsigned int bytes1 = subs->buffer_bytes - subs->hwptr_done;
+
memcpy(urb->transfer_buffer + offset,
runtime->dma_area + subs->hwptr_done, bytes1);
memcpy(urb->transfer_buffer + offset + bytes1,
@@ -1254,9 +1281,8 @@ static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb,
memcpy(urb->transfer_buffer + offset,
runtime->dma_area + subs->hwptr_done, bytes);
}
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
+
+ urb_ctx_queue_advance(subs, urb, bytes);
}
static unsigned int copy_to_urb_quirk(struct snd_usb_substream *subs,
@@ -1295,17 +1321,18 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
int i, stride, period_elapsed = 0;
unsigned long flags;
- stride = runtime->frame_bits >> 3;
+ stride = ep->stride;
frames = 0;
+ ctx->queued = 0;
urb->number_of_packets = 0;
spin_lock_irqsave(&subs->lock, flags);
subs->frame_limit += ep->max_urb_frames;
for (i = 0; i < ctx->packets; i++) {
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i);
/* set up descriptor */
- urb->iso_frame_desc[i].offset = frames * ep->stride;
- urb->iso_frame_desc[i].length = counts * ep->stride;
+ urb->iso_frame_desc[i].offset = frames * stride;
+ urb->iso_frame_desc[i].length = counts * stride;
frames += counts;
urb->number_of_packets++;
subs->transfer_done += counts;
@@ -1320,14 +1347,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
frames -= subs->transfer_done;
counts -= subs->transfer_done;
urb->iso_frame_desc[i].length =
- counts * ep->stride;
+ counts * stride;
subs->transfer_done = 0;
}
i++;
if (i < ctx->packets) {
/* add a transfer delimiter */
urb->iso_frame_desc[i].offset =
- frames * ep->stride;
+ frames * stride;
urb->iso_frame_desc[i].length = 0;
urb->number_of_packets++;
}
@@ -1340,24 +1367,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
!snd_usb_endpoint_implicit_feedback_sink(ep))
break;
}
- bytes = frames * ep->stride;
+ bytes = frames * stride;
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)) {
- /* bit-reverse the bytes */
- u8 *buf = urb->transfer_buffer;
- for (i = 0; i < bytes; i++) {
- int idx = (subs->hwptr_done + i)
- % (runtime->buffer_size * stride);
- buf[i] = bitrev8(runtime->dma_area[idx]);
- }
-
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
+ fill_playback_urb_dsd_bitrev(subs, urb, bytes);
} else {
/* usual PCM */
if (!subs->tx_length_quirk)
@@ -1367,14 +1384,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
/* bytes is now amount of outgoing data */
}
- /* update delay with exact number of samples queued */
- runtime->delay = subs->last_delay;
- runtime->delay += frames;
- subs->last_delay = runtime->delay;
-
- /* realign last_frame_number */
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
- subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
if (subs->trigger_tstamp_pending_update) {
/* this is the first actual URB submitted,
@@ -1384,6 +1394,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
subs->trigger_tstamp_pending_update = false;
}
+ if (period_elapsed && !subs->running) {
+ subs->period_elapsed_pending = 1;
+ period_elapsed = 0;
+ }
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = bytes;
if (period_elapsed)
@@ -1398,55 +1412,32 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
struct urb *urb)
{
unsigned long flags;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- struct snd_usb_endpoint *ep = subs->data_endpoint;
- int processed = urb->transfer_buffer_length / ep->stride;
- int est_delay;
-
- /* ignore the delay accounting when processed=0 is given, i.e.
- * silent payloads are processed before handling the actual data
- */
- if (!processed)
- return;
+ struct snd_urb_ctx *ctx = urb->context;
+ bool period_elapsed = false;
spin_lock_irqsave(&subs->lock, flags);
- if (!subs->last_delay)
- goto out; /* short path */
-
- est_delay = snd_usb_pcm_delay(subs, runtime->rate);
- /* update delay with exact number of samples played */
- if (processed > subs->last_delay)
- subs->last_delay = 0;
- else
- subs->last_delay -= processed;
- runtime->delay = subs->last_delay;
-
- /*
- * Report when delay estimate is off by more than 2ms.
- * The error should be lower than 2ms since the estimate relies
- * on two reads of a counter updated every ms.
- */
- if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
- dev_dbg_ratelimited(&subs->dev->dev,
- "delay: estimated %d, actual %d\n",
- est_delay, subs->last_delay);
-
- if (!subs->running) {
- /* update last_frame_number for delay counting here since
- * prepare_playback_urb won't be called during pause
- */
- subs->last_frame_number =
- usb_get_current_frame_number(subs->dev) & 0xff;
+ if (ctx->queued) {
+ if (subs->inflight_bytes >= ctx->queued)
+ subs->inflight_bytes -= ctx->queued;
+ else
+ subs->inflight_bytes = 0;
}
- out:
+ 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);
}
static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_usb_substream *subs = substream->runtime->private_data;
+ int err;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -1457,6 +1448,14 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
prepare_playback_urb,
retire_playback_urb,
subs);
+ if (cmd == SNDRV_PCM_TRIGGER_START) {
+ err = start_endpoints(subs);
+ if (err < 0) {
+ snd_usb_endpoint_set_callback(subs->data_endpoint,
+ NULL, NULL, NULL);
+ return err;
+ }
+ }
subs->running = 1;
dev_dbg(&subs->dev->dev, "%d:%d Start Playback PCM\n",
subs->cur_audiofmt->iface,
@@ -1504,6 +1503,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
snd_usb_endpoint_set_callback(subs->data_endpoint,
NULL, retire_capture_urb,
subs);
+ subs->last_frame_number = usb_get_current_frame_number(subs->dev);
subs->running = 1;
dev_dbg(&subs->dev->dev, "%d:%d Start Capture PCM\n",
subs->cur_audiofmt->iface,
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
index 06c586467d3f..493a4e34d78d 100644
--- a/sound/usb/pcm.h
+++ b/sound/usb/pcm.h
@@ -2,9 +2,6 @@
#ifndef __USBAUDIO_PCM_H
#define __USBAUDIO_PCM_H
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate);
-
void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
int snd_usb_pcm_suspend(struct snd_usb_stream *as);
int snd_usb_pcm_resume(struct snd_usb_stream *as);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index bdba37d0faab..19bb499c17da 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -3044,6 +3044,76 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
}
},
+/* Denon DN-X1600 */
+{
+ USB_AUDIO_DEVICE(0x154e, 0x500e),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "Denon",
+ .product_name = "DN-X1600",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]){
+ {
+ .ifnum = 0,
+ .type = QUIRK_IGNORE_INTERFACE,
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 8,
+ .iface = 1,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = 0x0,
+ .endpoint = 0x01,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_ADAPTIVE,
+ .maxpacksize = 0x138,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) {
+ 48000
+ }
+ }
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 8,
+ .iface = 2,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = 0x0,
+ .endpoint = 0x85,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_ADAPTIVE,
+ .maxpacksize = 0x138,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) {
+ 48000
+ }
+ }
+ },
+ {
+ .ifnum = 4,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE,
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
+
/* Microsoft XboxLive Headset/Xbox Communicator */
{
USB_DEVICE(0x045e, 0x0283),
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 6e1bfe894dd5..e558931cce16 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -49,7 +49,7 @@ static int us122l_create_usbmidi(struct snd_card *card)
static const struct snd_usb_audio_quirk quirk = {
.vendor_name = "US122L",
.product_name = NAME_ALLCAPS,
- .ifnum = 1,
+ .ifnum = 1,
.type = QUIRK_MIDI_US122L,
.data = &quirk_data
};
@@ -71,7 +71,7 @@ static int us144_create_usbmidi(struct snd_card *card)
static const struct snd_usb_audio_quirk quirk = {
.vendor_name = "US144",
.product_name = NAME_ALLCAPS,
- .ifnum = 0,
+ .ifnum = 0,
.type = QUIRK_MIDI_US122L,
.data = &quirk_data
};
@@ -95,6 +95,7 @@ static void pt_info_set(struct usb_device *dev, u8 v)
static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
{
struct us122l *us122l = area->vm_private_data;
+
atomic_inc(&us122l->mmap_count);
snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
}
@@ -113,9 +114,9 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
goto unlock;
offset = vmf->pgoff << PAGE_SHIFT;
- if (offset < PAGE_ALIGN(s->read_size))
+ if (offset < PAGE_ALIGN(s->read_size)) {
vaddr = (char *)s + offset;
- else {
+ } else {
offset -= PAGE_ALIGN(s->read_size);
if (offset >= PAGE_ALIGN(s->write_size))
goto unlock;
@@ -138,6 +139,7 @@ unlock:
static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
{
struct us122l *us122l = area->vm_private_data;
+
atomic_dec(&us122l->mmap_count);
snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
}
@@ -148,11 +150,11 @@ static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
.close = usb_stream_hwdep_vm_close,
};
-
static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
{
struct us122l *us122l = hw->private_data;
struct usb_interface *iface;
+
snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
if (hw->used >= 2)
return -EBUSY;
@@ -173,6 +175,7 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
{
struct us122l *us122l = hw->private_data;
struct usb_interface *iface;
+
snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
if (us122l->is_us144) {
@@ -235,7 +238,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
struct file *file, poll_table *wait)
{
struct us122l *us122l = hw->private_data;
- unsigned *polled;
+ unsigned int *polled;
__poll_t mask;
poll_wait(file, &us122l->sk.sleep, wait);
@@ -243,6 +246,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM | EPOLLERR;
if (mutex_trylock(&us122l->mutex)) {
struct usb_stream *s = us122l->sk.s;
+
if (s && s->state == usb_stream_ready) {
if (us122l->first == file)
polled = &s->periods_polled;
@@ -251,8 +255,9 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
if (*polled != s->periods_done) {
*polled = s->periods_done;
mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM;
- } else
+ } else {
mask = 0;
+ }
}
mutex_unlock(&us122l->mutex);
}
@@ -262,6 +267,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
static void us122l_stop(struct us122l *us122l)
{
struct list_head *p;
+
list_for_each(p, &us122l->midi_list)
snd_usbmidi_input_stop(p);
@@ -289,11 +295,11 @@ static int us122l_set_sample_rate(struct usb_device *dev, int rate)
}
static bool us122l_start(struct us122l *us122l,
- unsigned rate, unsigned period_frames)
+ unsigned int rate, unsigned int period_frames)
{
struct list_head *p;
int err;
- unsigned use_packsize = 0;
+ unsigned int use_packsize = 0;
bool success = false;
if (us122l->dev->speed == USB_SPEED_HIGH) {
@@ -320,13 +326,13 @@ static bool us122l_start(struct us122l *us122l,
err = us122l_set_sample_rate(us122l->dev, rate);
if (err < 0) {
us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
+ snd_printk(KERN_ERR "us122l_set_sample_rate error\n");
goto out;
}
err = usb_stream_start(&us122l->sk);
if (err < 0) {
us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_start error %i \n", err);
+ snd_printk(KERN_ERR "%s error %i\n", __func__, err);
goto out;
}
list_for_each(p, &us122l->midi_list)
@@ -337,12 +343,12 @@ out:
}
static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
struct usb_stream_config cfg;
struct us122l *us122l = hw->private_data;
struct usb_stream *s;
- unsigned min_period_frames;
+ unsigned int min_period_frames;
int err = 0;
bool high_speed;
@@ -379,13 +385,13 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
if (cfg.period_frames < min_period_frames)
return -EINVAL;
- snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
+ snd_power_wait(hw->card);
mutex_lock(&us122l->mutex);
s = us122l->sk.s;
- if (!us122l->master)
+ if (!us122l->master) {
us122l->master = file;
- else if (us122l->master != file) {
+ } else if (us122l->master != file) {
if (!s || memcmp(&cfg, &s->cfg, sizeof(cfg))) {
err = -EIO;
goto unlock;
@@ -431,7 +437,6 @@ static int usb_stream_hwdep_new(struct snd_card *card)
return 0;
}
-
static bool us122l_create_card(struct snd_card *card)
{
int err;
@@ -440,13 +445,13 @@ static bool us122l_create_card(struct snd_card *card)
if (us122l->is_us144) {
err = usb_set_interface(us122l->dev, 0, 1);
if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error\n");
return false;
}
}
err = usb_set_interface(us122l->dev, 1, 1);
if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error\n");
return false;
}
@@ -461,13 +466,14 @@ static bool us122l_create_card(struct snd_card *card)
else
err = us122l_create_usbmidi(card);
if (err < 0) {
- snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
+ snd_printk(KERN_ERR "us122l_create_usbmidi error %i\n", err);
goto stop;
}
err = usb_stream_hwdep_new(card);
if (err < 0) {
-/* release the midi resources */
+ /* release the midi resources */
struct list_head *p;
+
list_for_each(p, &us122l->midi_list)
snd_usbmidi_disconnect(p);
@@ -484,7 +490,8 @@ static void snd_us122l_free(struct snd_card *card)
{
struct us122l *us122l = US122L(card);
int index = us122l->card_index;
- if (index >= 0 && index < SNDRV_CARDS)
+
+ if (index >= 0 && index < SNDRV_CARDS)
snd_us122l_card_used[index] = 0;
}
@@ -565,7 +572,7 @@ static int snd_us122l_probe(struct usb_interface *intf,
if (id->driver_info & US122L_FLAG_US144 &&
device->speed == USB_SPEED_HIGH) {
- snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
+ snd_printk(KERN_ERR "disable ehci-hcd to run US-144\n");
return -ENODEV;
}
@@ -601,7 +608,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
us122l_stop(us122l);
mutex_unlock(&us122l->mutex);
-/* release the midi resources */
+ /* release the midi resources */
list_for_each(p, &us122l->midi_list) {
snd_usbmidi_disconnect(p);
}
@@ -661,13 +668,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
if (us122l->is_us144) {
err = usb_set_interface(us122l->dev, 0, 1);
if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error\n");
goto unlock;
}
}
err = usb_set_interface(us122l->dev, 1, 1);
if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error\n");
goto unlock;
}
@@ -677,7 +684,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
err = us122l_set_sample_rate(us122l->dev,
us122l->sk.s->cfg.sample_rate);
if (err < 0) {
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
+ snd_printk(KERN_ERR "us122l_set_sample_rate error\n");
goto unlock;
}
err = usb_stream_start(&us122l->sk);
@@ -717,8 +724,8 @@ static const struct usb_device_id snd_us122l_usb_id_table[] = {
},
{ /* terminator */ }
};
-
MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
+
static struct usb_driver snd_us122l_usb_driver = {
.name = "snd-usb-us122l",
.probe = snd_us122l_probe,
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
index 34bea99d343c..c32ae5e981e9 100644
--- a/sound/usb/usx2y/us122l.h
+++ b/sound/usb/usx2y/us122l.h
@@ -11,7 +11,7 @@ struct us122l {
struct mutex mutex;
struct file *first;
- unsigned second_periods_polled;
+ unsigned int second_periods_polled;
struct file *master;
struct file *slave;
struct list_head midi_list;
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 22412cd69e98..c29da0341bc5 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -21,15 +21,15 @@
static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
{
unsigned long offset;
- struct page * page;
+ struct page *page;
void *vaddr;
snd_printdd("ENTER, start %lXh, pgoff %ld\n",
vmf->vma->vm_start,
vmf->pgoff);
-
+
offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char *)((struct usX2Ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset;
+ vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset;
page = virt_to_page(vaddr);
get_page(page);
vmf->page = page;
@@ -44,30 +44,22 @@ static const struct vm_operations_struct us428ctls_vm_ops = {
.fault = snd_us428ctls_vm_fault,
};
-static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
+static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area)
{
unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *us428 = hw->private_data;
+ struct usx2ydev *us428 = hw->private_data;
// FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs?
// so as long as the device isn't fully initialised yet we return -EBUSY here.
- if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
+ if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
return -EBUSY;
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
- snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem));
- return -EINVAL;
+ /* if userspace tries to mmap beyond end of our buffer, fail */
+ if (size > US428_SHAREDMEM_PAGES) {
+ snd_printd("%lu > %lu\n", size, (unsigned long)US428_SHAREDMEM_PAGES);
+ return -EINVAL;
}
- if (!us428->us428ctls_sharedmem) {
- init_waitqueue_head(&us428->us428ctls_wait_queue_head);
- us428->us428ctls_sharedmem = alloc_pages_exact(sizeof(struct us428ctls_sharedmem), GFP_KERNEL);
- if (!us428->us428ctls_sharedmem)
- return -ENOMEM;
- memset(us428->us428ctls_sharedmem, -1, sizeof(struct us428ctls_sharedmem));
- us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
- }
area->vm_ops = &us428ctls_vm_ops;
area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
@@ -77,21 +69,22 @@ static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct v
static __poll_t snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll_table *wait)
{
__poll_t mask = 0;
- struct usX2Ydev *us428 = hw->private_data;
+ struct usx2ydev *us428 = hw->private_data;
struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem;
+
if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
return EPOLLHUP;
poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
- if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed)
+ if (shm && shm->ctl_snapshot_last != shm->ctl_snapshot_red)
mask |= EPOLLIN;
return mask;
}
-static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
+static int snd_usx2y_hwdep_dsp_status(struct snd_hwdep *hw,
struct snd_hwdep_dsp_status *info)
{
static const char * const type_ids[USX2Y_TYPE_NUMS] = {
@@ -99,7 +92,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
[USX2Y_TYPE_224] = "us224",
[USX2Y_TYPE_428] = "us428",
};
- struct usX2Ydev *us428 = hw->private_data;
+ struct usx2ydev *us428 = hw->private_data;
int id = -1;
switch (le16_to_cpu(us428->dev->descriptor.idProduct)) {
@@ -113,7 +106,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
id = USX2Y_TYPE_428;
break;
}
- if (0 > id)
+ if (id < 0)
return -ENODEV;
strcpy(info->id, type_ids[id]);
info->num_dsps = 2; // 0: Prepad Data, 1: FPGA Code
@@ -123,8 +116,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
return 0;
}
-
-static int usX2Y_create_usbmidi(struct snd_card *card)
+static int usx2y_create_usbmidi(struct snd_card *card)
{
static const struct snd_usb_midi_endpoint_info quirk_data_1 = {
.out_ep = 0x06,
@@ -135,8 +127,8 @@ static int usX2Y_create_usbmidi(struct snd_card *card)
static const struct snd_usb_audio_quirk quirk_1 = {
.vendor_name = "TASCAM",
.product_name = NAME_ALLCAPS,
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .ifnum = 0,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = &quirk_data_1
};
static const struct snd_usb_midi_endpoint_info quirk_data_2 = {
@@ -148,49 +140,50 @@ static int usX2Y_create_usbmidi(struct snd_card *card)
static const struct snd_usb_audio_quirk quirk_2 = {
.vendor_name = "TASCAM",
.product_name = "US428",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .ifnum = 0,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = &quirk_data_2
};
- struct usb_device *dev = usX2Y(card)->dev;
+ struct usb_device *dev = usx2y(card)->dev;
struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
const struct snd_usb_audio_quirk *quirk =
le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
&quirk_2 : &quirk_1;
- snd_printdd("usX2Y_create_usbmidi \n");
- return snd_usbmidi_create(card, iface, &usX2Y(card)->midi_list, quirk);
+ snd_printdd("%s\n", __func__);
+ return snd_usbmidi_create(card, iface, &usx2y(card)->midi_list, quirk);
}
-static int usX2Y_create_alsa_devices(struct snd_card *card)
+static int usx2y_create_alsa_devices(struct snd_card *card)
{
int err;
- do {
- if ((err = usX2Y_create_usbmidi(card)) < 0) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
- break;
- }
- if ((err = usX2Y_audio_create(card)) < 0)
- break;
- if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
- break;
- if ((err = snd_card_register(card)) < 0)
- break;
- } while (0);
-
- return err;
-}
+ err = usx2y_create_usbmidi(card);
+ if (err < 0) {
+ snd_printk(KERN_ERR "%s: usx2y_create_usbmidi error %i\n", __func__, err);
+ return err;
+ }
+ err = usx2y_audio_create(card);
+ if (err < 0)
+ return err;
+ err = usx2y_hwdep_pcm_new(card);
+ if (err < 0)
+ return err;
+ err = snd_card_register(card);
+ if (err < 0)
+ return err;
+ return 0;
+}
-static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
+static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
struct snd_hwdep_dsp_image *dsp)
{
- struct usX2Ydev *priv = hw->private_data;
- struct usb_device* dev = priv->dev;
+ struct usx2ydev *priv = hw->private_data;
+ struct usb_device *dev = priv->dev;
int lret, err;
char *buf;
- snd_printdd( "dsp_load %s\n", dsp->name);
+ snd_printdd("dsp_load %s\n", dsp->name);
buf = memdup_user(dsp->image, dsp->length);
if (IS_ERR(buf))
@@ -198,7 +191,7 @@ static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
err = usb_set_interface(dev, 0, 1);
if (err)
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error\n");
else
err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
kfree(buf);
@@ -206,45 +199,51 @@ static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
return err;
if (dsp->index == 1) {
msleep(250); // give the device some time
- err = usX2Y_AsyncSeq04_init(priv);
+ err = usx2y_async_seq04_init(priv);
if (err) {
- snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
+ snd_printk(KERN_ERR "usx2y_async_seq04_init error\n");
return err;
}
- err = usX2Y_In04_init(priv);
+ err = usx2y_in04_init(priv);
if (err) {
- snd_printk(KERN_ERR "usX2Y_In04_init error \n");
+ snd_printk(KERN_ERR "usx2y_in04_init error\n");
return err;
}
- err = usX2Y_create_alsa_devices(hw->card);
+ err = usx2y_create_alsa_devices(hw->card);
if (err) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
- snd_card_free(hw->card);
+ snd_printk(KERN_ERR "usx2y_create_alsa_devices error %i\n", err);
return err;
}
- priv->chip_status |= USX2Y_STAT_CHIP_INIT;
+ priv->chip_status |= USX2Y_STAT_CHIP_INIT;
snd_printdd("%s: alsa all started\n", hw->name);
}
return err;
}
-
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
+int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device)
{
int err;
struct snd_hwdep *hw;
+ struct usx2ydev *us428 = usx2y(card);
- if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
+ err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw);
+ if (err < 0)
return err;
hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
- hw->private_data = usX2Y(card);
- hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status;
- hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load;
+ hw->private_data = us428;
+ hw->ops.dsp_status = snd_usx2y_hwdep_dsp_status;
+ hw->ops.dsp_load = snd_usx2y_hwdep_dsp_load;
hw->ops.mmap = snd_us428ctls_mmap;
hw->ops.poll = snd_us428ctls_poll;
hw->exclusive = 1;
sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
+
+ us428->us428ctls_sharedmem = alloc_pages_exact(US428_SHAREDMEM_PAGES, GFP_KERNEL);
+ if (!us428->us428ctls_sharedmem)
+ return -ENOMEM;
+ memset(us428->us428ctls_sharedmem, -1, US428_SHAREDMEM_PAGES);
+ us428->us428ctls_sharedmem->ctl_snapshot_last = -2;
+
return 0;
}
-
diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h
index 457199b5ed03..0c9946d9cd99 100644
--- a/sound/usb/usx2y/usX2Yhwdep.h
+++ b/sound/usb/usx2y/usX2Yhwdep.h
@@ -2,6 +2,6 @@
#ifndef USX2YHWDEP_H
#define USX2YHWDEP_H
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device);
+int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device);
#endif
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 091c071b270a..9d0e44793896 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -8,12 +8,12 @@
#include "usb_stream.h"
-
/* setup */
-static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
+static unsigned int usb_stream_next_packet_size(struct usb_stream_kernel *sk)
{
struct usb_stream *s = sk->s;
+
sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
}
@@ -25,6 +25,7 @@ static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
for (pack = 0; pack < sk->n_o_ps; pack++) {
int l = usb_stream_next_packet_size(sk);
+
if (s->idle_outsize + lb + l > s->period_size)
goto check;
@@ -43,9 +44,10 @@ check:
lb, s->period_size);
}
-static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct urb **urbs, char *transfer,
- struct usb_device *dev, int pipe)
+static int init_pipe_urbs(struct usb_stream_kernel *sk,
+ unsigned int use_packsize,
+ struct urb **urbs, char *transfer,
+ struct usb_device *dev, int pipe)
{
int u, p;
int maxpacket = use_packsize ?
@@ -56,6 +58,7 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
++u, transfer += transfer_length) {
struct urb *urb = urbs[u];
struct usb_iso_packet_descriptor *desc;
+
urb->transfer_buffer = transfer;
urb->dev = dev;
urb->pipe = pipe;
@@ -80,13 +83,12 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
return 0;
}
-static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct usb_device *dev, int in_pipe, int out_pipe)
+static int init_urbs(struct usb_stream_kernel *sk, unsigned int use_packsize,
+ struct usb_device *dev, int in_pipe, int out_pipe)
{
struct usb_stream *s = sk->s;
- char *indata = (char *)s + sizeof(*s) +
- sizeof(struct usb_stream_packet) *
- s->inpackets;
+ char *indata =
+ (char *)s + sizeof(*s) + sizeof(struct usb_stream_packet) * s->inpackets;
int u;
for (u = 0; u < USB_STREAM_NURBS; ++u) {
@@ -107,12 +109,11 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
return 0;
}
-
/*
* convert a sampling rate into our full speed format (fs/1000 in Q16.16)
* this will overflow at approx 524 kHz
*/
-static inline unsigned get_usb_full_speed_rate(unsigned rate)
+static inline unsigned int get_usb_full_speed_rate(unsigned int rate)
{
return ((rate << 13) + 62) / 125;
}
@@ -121,7 +122,7 @@ static inline unsigned get_usb_full_speed_rate(unsigned rate)
* convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
* this will overflow at approx 4 MHz
*/
-static inline unsigned get_usb_high_speed_rate(unsigned rate)
+static inline unsigned int get_usb_high_speed_rate(unsigned int rate)
{
return ((rate << 10) + 62) / 125;
}
@@ -129,7 +130,7 @@ static inline unsigned get_usb_high_speed_rate(unsigned rate)
void usb_stream_free(struct usb_stream_kernel *sk)
{
struct usb_stream *s;
- unsigned u;
+ unsigned int u;
for (u = 0; u < USB_STREAM_NURBS; ++u) {
usb_free_urb(sk->inurb[u]);
@@ -142,17 +143,23 @@ void usb_stream_free(struct usb_stream_kernel *sk)
if (!s)
return;
- free_pages_exact(sk->write_page, s->write_size);
- sk->write_page = NULL;
+ if (sk->write_page) {
+ free_pages_exact(sk->write_page, s->write_size);
+ sk->write_page = NULL;
+ }
+
free_pages_exact(s, s->read_size);
sk->s = NULL;
}
struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size)
+ unsigned int in_endpoint,
+ unsigned int out_endpoint,
+ unsigned int sample_rate,
+ unsigned int use_packsize,
+ unsigned int period_frames,
+ unsigned int frame_size)
{
int packets, max_packsize;
int in_pipe, out_pipe;
@@ -231,12 +238,12 @@ out:
return sk->s;
}
-
/* start */
static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
{
bool r;
+
if (unlikely(urb->status)) {
if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
snd_printk(KERN_WARNING "status=%i\n", urb->status);
@@ -267,6 +274,7 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
for (u = 0; u < USB_STREAM_NURBS; u++) {
struct urb *urb = urbs[u];
+
urb->complete = complete;
}
}
@@ -284,6 +292,7 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
struct urb *ii = sk->completed_inurb;
+
id = ii->iso_frame_desc +
ii->number_of_packets + s->sync_packet;
l = id->actual_length;
@@ -351,6 +360,7 @@ static int submit_urbs(struct usb_stream_kernel *sk,
struct urb *inurb, struct urb *outurb)
{
int err;
+
prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
if (err < 0)
@@ -447,6 +457,7 @@ static void stream_idle(struct usb_stream_kernel *sk,
for (p = 0; p < inurb->number_of_packets; ++p) {
struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
+
l = id[p].actual_length;
if (unlikely(l == 0 || id[p].status)) {
snd_printk(KERN_WARNING "underrun, status=%u\n",
@@ -503,6 +514,7 @@ err_out:
static void i_capture_idle(struct urb *urb)
{
struct usb_stream_kernel *sk = urb->context;
+
if (balance_capture(sk, urb))
stream_idle(sk, urb, sk->i_urb);
}
@@ -510,6 +522,7 @@ static void i_capture_idle(struct urb *urb)
static void i_playback_idle(struct urb *urb)
{
struct usb_stream_kernel *sk = urb->context;
+
if (balance_playback(sk, urb))
stream_idle(sk, sk->i_urb, urb);
}
@@ -518,10 +531,12 @@ static void stream_start(struct usb_stream_kernel *sk,
struct urb *inurb, struct urb *outurb)
{
struct usb_stream *s = sk->s;
+
if (s->state >= usb_stream_sync1) {
int l, p, max_diff, max_diff_0;
int urb_size = 0;
- unsigned frames_per_packet, min_frames = 0;
+ unsigned int frames_per_packet, min_frames = 0;
+
frames_per_packet = (s->period_size - s->idle_insize);
frames_per_packet <<= 8;
frames_per_packet /=
@@ -536,6 +551,7 @@ static void stream_start(struct usb_stream_kernel *sk,
max_diff = max_diff_0;
for (p = 0; p < inurb->number_of_packets; ++p) {
int diff;
+
l = inurb->iso_frame_desc[p].actual_length;
urb_size += l;
@@ -561,7 +577,8 @@ static void stream_start(struct usb_stream_kernel *sk,
(s->inpacket_head + 1) % s->inpackets;
s->next_inpacket_split_at = 0;
} else {
- unsigned split = s->inpacket_head;
+ unsigned int split = s->inpacket_head;
+
l = s->idle_insize;
while (l > s->inpacket[split].length) {
l -= s->inpacket[split].length;
@@ -609,6 +626,7 @@ static void i_capture_start(struct urb *urb)
for (p = 0; p < urb->number_of_packets; ++p) {
int l = id[p].actual_length;
+
if (l < s->cfg.frame_size) {
++empty;
if (s->state >= usb_stream_sync0) {
@@ -628,6 +646,7 @@ static void i_capture_start(struct urb *urb)
urb->iso_frame_desc[0].actual_length);
for (pack = 1; pack < urb->number_of_packets; ++pack) {
int l = urb->iso_frame_desc[pack].actual_length;
+
printk(KERN_CONT " %i", l);
}
printk(KERN_CONT "\n");
@@ -643,6 +662,7 @@ static void i_capture_start(struct urb *urb)
static void i_playback_start(struct urb *urb)
{
struct usb_stream_kernel *sk = urb->context;
+
if (balance_playback(sk, urb))
stream_start(sk, sk->i_urb, urb);
}
@@ -671,6 +691,7 @@ dotry:
for (u = 0; u < 2; u++) {
struct urb *inurb = sk->inurb[u];
struct urb *outurb = sk->outurb[u];
+
playback_prep_freqn(sk, outurb);
inurb->number_of_packets = outurb->number_of_packets;
inurb->transfer_buffer_length =
@@ -680,6 +701,7 @@ dotry:
if (u == 0) {
int now;
struct usb_device *dev = inurb->dev;
+
frame = usb_get_current_frame_number(dev);
do {
now = usb_get_current_frame_number(dev);
@@ -688,14 +710,16 @@ dotry:
}
err = usb_submit_urb(inurb, GFP_ATOMIC);
if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
- " returned %i\n", u, err);
+ snd_printk(KERN_ERR
+ "usb_submit_urb(sk->inurb[%i]) returned %i\n",
+ u, err);
return err;
}
err = usb_submit_urb(outurb, GFP_ATOMIC);
if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
- " returned %i\n", u, err);
+ snd_printk(KERN_ERR
+ "usb_submit_urb(sk->outurb[%i]) returned %i\n",
+ u, err);
return err;
}
@@ -716,8 +740,8 @@ check_retry:
snd_printd(KERN_DEBUG "goto dotry;\n");
goto dotry;
}
- snd_printk(KERN_WARNING"couldn't start"
- " all urbs on the same start_frame.\n");
+ snd_printk(KERN_WARNING
+ "couldn't start all urbs on the same start_frame.\n");
return -EFAULT;
}
@@ -729,6 +753,7 @@ check_retry:
/* wait, check */
{
int wait_ms = 3000;
+
while (s->state != usb_stream_ready && wait_ms > 0) {
snd_printdd(KERN_DEBUG "%i\n", s->state);
msleep(200);
@@ -745,6 +770,7 @@ check_retry:
void usb_stream_stop(struct usb_stream_kernel *sk)
{
int u;
+
if (!sk->s)
return;
for (u = 0; u < USB_STREAM_NURBS; ++u) {
diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h
index 851358a8d709..73e57b341adc 100644
--- a/sound/usb/usx2y/usb_stream.h
+++ b/sound/usb/usx2y/usb_stream.h
@@ -12,7 +12,7 @@ struct usb_stream_kernel {
void *write_page;
- unsigned n_o_ps;
+ unsigned int n_o_ps;
struct urb *inurb[USB_STREAM_NURBS];
struct urb *idle_inurb;
@@ -26,18 +26,21 @@ struct usb_stream_kernel {
wait_queue_head_t sleep;
- unsigned out_phase;
- unsigned out_phase_peeked;
- unsigned freqn;
+ unsigned int out_phase;
+ unsigned int out_phase_peeked;
+ unsigned int freqn;
};
struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size);
-void usb_stream_free(struct usb_stream_kernel *);
-int usb_stream_start(struct usb_stream_kernel *);
-void usb_stream_stop(struct usb_stream_kernel *);
+ unsigned int in_endpoint,
+ unsigned int out_endpoint,
+ unsigned int sample_rate,
+ unsigned int use_packsize,
+ unsigned int period_frames,
+ unsigned int frame_size);
+void usb_stream_free(struct usb_stream_kernel *sk);
+int usb_stream_start(struct usb_stream_kernel *sk);
+void usb_stream_stop(struct usb_stream_kernel *sk);
#endif /* __USB_STREAM_H */
diff --git a/sound/usb/usx2y/usbus428ctldefs.h b/sound/usb/usx2y/usbus428ctldefs.h
index 5a7518ea3aeb..9ba15d974e63 100644
--- a/sound/usb/usx2y/usbus428ctldefs.h
+++ b/sound/usb/usx2y/usbus428ctldefs.h
@@ -4,28 +4,28 @@
* Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
*/
-enum E_In84{
- eFader0 = 0,
- eFader1,
- eFader2,
- eFader3,
- eFader4,
- eFader5,
- eFader6,
- eFader7,
- eFaderM,
- eTransport,
- eModifier = 10,
- eFilterSelect,
- eSelect,
- eMute,
+enum E_IN84 {
+ E_FADER_0 = 0,
+ E_FADER_1,
+ E_FADER_2,
+ E_FADER_3,
+ E_FADER_4,
+ E_FADER_5,
+ E_FADER_6,
+ E_FADER_7,
+ E_FADER_M,
+ E_TRANSPORT,
+ E_MODIFIER = 10,
+ E_FILTER_SELECT,
+ E_SELECT,
+ E_MUTE,
- eSwitch = 15,
- eWheelGain,
- eWheelFreq,
- eWheelQ,
- eWheelPan,
- eWheel = 20
+ E_SWITCH = 15,
+ E_WHEEL_GAIN,
+ E_WHEEL_FREQ,
+ E_WHEEL_Q,
+ E_WHEEL_PAN,
+ E_WHEEL = 20
};
#define T_RECORD 1
@@ -39,53 +39,55 @@ enum E_In84{
struct us428_ctls {
- unsigned char Fader[9];
- unsigned char Transport;
- unsigned char Modifier;
- unsigned char FilterSelect;
- unsigned char Select;
- unsigned char Mute;
- unsigned char UNKNOWN;
- unsigned char Switch;
- unsigned char Wheel[5];
+ unsigned char fader[9];
+ unsigned char transport;
+ unsigned char modifier;
+ unsigned char filters_elect;
+ unsigned char select;
+ unsigned char mute;
+ unsigned char unknown;
+ unsigned char wswitch;
+ unsigned char wheel[5];
};
-struct us428_setByte {
- unsigned char Offset,
- Value;
+struct us428_set_byte {
+ unsigned char offset,
+ value;
};
enum {
- eLT_Volume = 0,
- eLT_Light
+ ELT_VOLUME = 0,
+ ELT_LIGHT
};
-struct usX2Y_volume {
- unsigned char Channel,
- LH,
- LL,
- RH,
- RL;
+struct usx2y_volume {
+ unsigned char channel,
+ lh,
+ ll,
+ rh,
+ rl;
};
struct us428_lights {
- struct us428_setByte Light[7];
+ struct us428_set_byte light[7];
};
struct us428_p4out {
char type;
union {
- struct usX2Y_volume vol;
+ struct usx2y_volume vol;
struct us428_lights lights;
} val;
};
-#define N_us428_ctl_BUFS 16
-#define N_us428_p4out_BUFS 16
-struct us428ctls_sharedmem{
- struct us428_ctls CtlSnapShot[N_us428_ctl_BUFS];
- int CtlSnapShotDiffersAt[N_us428_ctl_BUFS];
- int CtlSnapShotLast, CtlSnapShotRed;
- struct us428_p4out p4out[N_us428_p4out_BUFS];
- int p4outLast, p4outSent;
+#define N_US428_CTL_BUFS 16
+#define N_US428_P4OUT_BUFS 16
+struct us428ctls_sharedmem {
+ struct us428_ctls ctl_snapshot[N_US428_CTL_BUFS];
+ int ctl_snapshot_differs_at[N_US428_CTL_BUFS];
+ int ctl_snapshot_last, ctl_snapshot_red;
+ struct us428_p4out p4out[N_US428_P4OUT_BUFS];
+ int p4out_last, p4out_sent;
};
+
+#define US428_SHAREDMEM_PAGES PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 3cd28d24f0a7..099bee662af6 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -17,7 +17,7 @@
2004-10-26 Karsten Wiese
Version 0.8.6:
- wake_up() process waiting in usX2Y_urbs_start() on error.
+ wake_up() process waiting in usx2y_urbs_start() on error.
2004-10-21 Karsten Wiese
Version 0.8.5:
@@ -48,7 +48,7 @@
2004-06-12 Karsten Wiese
Version 0.6.3:
Made it thus the following rule is enforced:
- "All pcm substreams of one usX2Y have to operate at the same rate & format."
+ "All pcm substreams of one usx2y have to operate at the same rate & format."
2004-04-06 Karsten Wiese
Version 0.6.0:
@@ -70,7 +70,7 @@
2003-11-03 Karsten Wiese
Version 0.3:
- 24Bit support.
+ 24Bit support.
"arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works.
2003-08-22 Karsten Wiese
@@ -94,16 +94,15 @@
This helped me much on my slowish PII 400 & PIII 500.
ACPI yet untested but might cause the same bad behaviour.
Use a kernel with lowlatency and preemptiv patches applied.
- To autoload snd-usb-midi append a line
+ To autoload snd-usb-midi append a line
post-install snd-usb-us428 modprobe snd-usb-midi
to /etc/modules.conf.
known problems:
sliders, knobs, lights not yet handled except MASTER Volume slider.
- "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
+ "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
KDE3: "Enable full duplex operation" deadlocks.
-
2002-08-31 Karsten Wiese
Version 0.0.3: audio also simplex;
simplifying: iso urbs only 1 packet, melted structs.
@@ -115,7 +114,7 @@
The firmware has been sniffed from win2k us-428 driver 3.09.
* Copyright (c) 2002 - 2004 Karsten Wiese
-*/
+ */
#include <linux/init.h>
#include <linux/module.h>
@@ -132,14 +131,12 @@
#include "usbusx2y.h"
#include "usX2Yhwdep.h"
-
-
MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
MODULE_LICENSE("GPL");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
@@ -149,305 +146,321 @@ MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
+static int snd_usx2y_card_used[SNDRV_CARDS];
-static int snd_usX2Y_card_used[SNDRV_CARDS];
+static void snd_usx2y_card_private_free(struct snd_card *card);
+static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s);
-static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr);
-static void snd_usX2Y_card_private_free(struct snd_card *card);
-
-/*
- * pipe 4 is used for switching the lamps, setting samplerate, volumes ....
+/*
+ * pipe 4 is used for switching the lamps, setting samplerate, volumes ....
*/
-static void i_usX2Y_Out04Int(struct urb *urb)
+static void i_usx2y_out04_int(struct urb *urb)
{
#ifdef CONFIG_SND_DEBUG
if (urb->status) {
- int i;
- struct usX2Ydev *usX2Y = urb->context;
- for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++);
- snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status);
+ int i;
+ struct usx2ydev *usx2y = urb->context;
+
+ for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++)
+ ;
+ snd_printdd("%s urb %i status=%i\n", __func__, i, urb->status);
}
#endif
}
-static void i_usX2Y_In04Int(struct urb *urb)
+static void i_usx2y_in04_int(struct urb *urb)
{
int err = 0;
- struct usX2Ydev *usX2Y = urb->context;
- struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem;
+ struct usx2ydev *usx2y = urb->context;
+ struct us428ctls_sharedmem *us428ctls = usx2y->us428ctls_sharedmem;
+ struct us428_p4out *p4out;
+ int i, j, n, diff, send;
- usX2Y->In04IntCalls++;
+ usx2y->in04_int_calls++;
if (urb->status) {
snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status);
return;
}
- // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
+ // printk("%i:0x%02X ", 8, (int)((unsigned char*)usx2y->in04_buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
if (us428ctls) {
- int diff = -1;
- if (-2 == us428ctls->CtlSnapShotLast) {
+ diff = -1;
+ if (us428ctls->ctl_snapshot_last == -2) {
diff = 0;
- memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last));
- us428ctls->CtlSnapShotLast = -1;
+ memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
+ us428ctls->ctl_snapshot_last = -1;
} else {
- int i;
for (i = 0; i < 21; i++) {
- if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) {
+ if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {
if (diff < 0)
diff = i;
- usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i];
+ usx2y->in04_last[i] = ((char *)usx2y->in04_buf)[i];
}
}
}
- if (0 <= diff) {
- int n = us428ctls->CtlSnapShotLast + 1;
- if (n >= N_us428_ctl_BUFS || n < 0)
+ if (diff >= 0) {
+ n = us428ctls->ctl_snapshot_last + 1;
+ if (n >= N_US428_CTL_BUFS || n < 0)
n = 0;
- memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0]));
- us428ctls->CtlSnapShotDiffersAt[n] = diff;
- us428ctls->CtlSnapShotLast = n;
- wake_up(&usX2Y->us428ctls_wait_queue_head);
+ memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0]));
+ us428ctls->ctl_snapshot_differs_at[n] = diff;
+ us428ctls->ctl_snapshot_last = n;
+ wake_up(&usx2y->us428ctls_wait_queue_head);
}
}
-
-
- if (usX2Y->US04) {
- if (0 == usX2Y->US04->submitted)
+
+ if (usx2y->us04) {
+ if (!usx2y->us04->submitted) {
do {
- err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC);
- } while (!err && usX2Y->US04->submitted < usX2Y->US04->len);
- } else
- if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) {
- if (us428ctls->p4outLast != us428ctls->p4outSent) {
- int j, send = us428ctls->p4outSent + 1;
- if (send >= N_us428_p4out_BUFS)
+ err = usb_submit_urb(usx2y->us04->urb[usx2y->us04->submitted++], GFP_ATOMIC);
+ } while (!err && usx2y->us04->submitted < usx2y->us04->len);
+ }
+ } else {
+ if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) {
+ if (us428ctls->p4out_last != us428ctls->p4out_sent) {
+ send = us428ctls->p4out_sent + 1;
+ if (send >= N_US428_P4OUT_BUFS)
send = 0;
- for (j = 0; j < URBS_AsyncSeq && !err; ++j)
- if (0 == usX2Y->AS04.urb[j]->status) {
- struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
- usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol,
- p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
- i_usX2Y_Out04Int, usX2Y);
- err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
- us428ctls->p4outSent = send;
+ for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) {
+ if (!usx2y->as04.urb[j]->status) {
+ p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
+ usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev,
+ usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol,
+ p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5,
+ i_usx2y_out04_int, usx2y);
+ err = usb_submit_urb(usx2y->as04.urb[j], GFP_ATOMIC);
+ us428ctls->p4out_sent = send;
break;
}
+ }
}
}
+ }
if (err)
- snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
+ snd_printk(KERN_ERR "in04_int() usb_submit_urb err=%i\n", err);
- urb->dev = usX2Y->dev;
+ urb->dev = usx2y->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
/*
* Prepare some urbs
*/
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
+int usx2y_async_seq04_init(struct usx2ydev *usx2y)
{
- int err = 0,
- i;
+ int err = 0, i;
+
+ if (WARN_ON(usx2y->as04.buffer))
+ return -EBUSY;
- usX2Y->AS04.buffer = kmalloc_array(URBS_AsyncSeq,
- URB_DataLen_AsyncSeq, GFP_KERNEL);
- if (NULL == usX2Y->AS04.buffer) {
+ usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ,
+ URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL);
+ if (!usx2y->as04.buffer) {
err = -ENOMEM;
- } else
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
+ } else {
+ for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
+ usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usx2y->as04.urb[i]) {
err = -ENOMEM;
break;
}
- usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04),
- usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
- i_usX2Y_Out04Int, usX2Y
- );
- err = usb_urb_ep_type_check(usX2Y->AS04.urb[i]);
+ usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev,
+ usb_sndbulkpipe(usx2y->dev, 0x04),
+ usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ * i, 0,
+ i_usx2y_out04_int, usx2y);
+ err = usb_urb_ep_type_check(usx2y->as04.urb[i]);
if (err < 0)
break;
}
+ }
+ if (err)
+ usx2y_unlinkseq(&usx2y->as04);
return err;
}
-int usX2Y_In04_init(struct usX2Ydev *usX2Y)
+int usx2y_in04_init(struct usx2ydev *usx2y)
{
- if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL)))
- return -ENOMEM;
-
- if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL)))
- return -ENOMEM;
-
- init_waitqueue_head(&usX2Y->In04WaitQueue);
- usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4),
- usX2Y->In04Buf, 21,
- i_usX2Y_In04Int, usX2Y,
+ int err;
+
+ if (WARN_ON(usx2y->in04_urb))
+ return -EBUSY;
+
+ usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usx2y->in04_urb) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ usx2y->in04_buf = kmalloc(21, GFP_KERNEL);
+ if (!usx2y->in04_buf) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ init_waitqueue_head(&usx2y->in04_wait_queue);
+ usb_fill_int_urb(usx2y->in04_urb, usx2y->dev, usb_rcvintpipe(usx2y->dev, 0x4),
+ usx2y->in04_buf, 21,
+ i_usx2y_in04_int, usx2y,
10);
- if (usb_urb_ep_type_check(usX2Y->In04urb))
- return -EINVAL;
- return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
+ if (usb_urb_ep_type_check(usx2y->in04_urb)) {
+ err = -EINVAL;
+ goto error;
+ }
+ return usb_submit_urb(usx2y->in04_urb, GFP_KERNEL);
+
+ error:
+ kfree(usx2y->in04_buf);
+ usb_free_urb(usx2y->in04_urb);
+ usx2y->in04_buf = NULL;
+ usx2y->in04_urb = NULL;
+ return err;
}
-static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
+static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s)
{
int i;
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- usb_kill_urb(S->urb[i]);
- usb_free_urb(S->urb[i]);
- S->urb[i] = NULL;
+
+ for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
+ if (!s->urb[i])
+ continue;
+ usb_kill_urb(s->urb[i]);
+ usb_free_urb(s->urb[i]);
+ s->urb[i] = NULL;
}
- kfree(S->buffer);
+ kfree(s->buffer);
+ s->buffer = NULL;
}
-
-static const struct usb_device_id snd_usX2Y_usb_id_table[] = {
+static const struct usb_device_id snd_usx2y_usb_id_table[] = {
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x1604,
- .idProduct = USB_ID_US428
+ .idProduct = USB_ID_US428
},
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x1604,
- .idProduct = USB_ID_US122
+ .idProduct = USB_ID_US122
},
- {
+ {
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x1604,
.idProduct = USB_ID_US224
},
{ /* terminator */ }
};
+MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table);
-static int usX2Y_create_card(struct usb_device *device,
+static int usx2y_create_card(struct usb_device *device,
struct usb_interface *intf,
struct snd_card **cardp)
{
int dev;
- struct snd_card * card;
+ struct snd_card *card;
int err;
for (dev = 0; dev < SNDRV_CARDS; ++dev)
- if (enable[dev] && !snd_usX2Y_card_used[dev])
+ if (enable[dev] && !snd_usx2y_card_used[dev])
break;
if (dev >= SNDRV_CARDS)
return -ENODEV;
err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
- sizeof(struct usX2Ydev), &card);
+ sizeof(struct usx2ydev), &card);
if (err < 0)
return err;
- snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
- card->private_free = snd_usX2Y_card_private_free;
- usX2Y(card)->dev = device;
- init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
- mutex_init(&usX2Y(card)->pcm_mutex);
- INIT_LIST_HEAD(&usX2Y(card)->midi_list);
+ snd_usx2y_card_used[usx2y(card)->card_index = dev] = 1;
+ card->private_free = snd_usx2y_card_private_free;
+ usx2y(card)->dev = device;
+ init_waitqueue_head(&usx2y(card)->prepare_wait_queue);
+ init_waitqueue_head(&usx2y(card)->us428ctls_wait_queue_head);
+ mutex_init(&usx2y(card)->pcm_mutex);
+ INIT_LIST_HEAD(&usx2y(card)->midi_list);
strcpy(card->driver, "USB "NAME_ALLCAPS"");
sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
- card->shortname,
+ card->shortname,
le16_to_cpu(device->descriptor.idVendor),
le16_to_cpu(device->descriptor.idProduct),
0,//us428(card)->usbmidi.ifnum,
- usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum
- );
+ usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum);
*cardp = card;
return 0;
}
-
-static int usX2Y_usb_probe(struct usb_device *device,
- struct usb_interface *intf,
- const struct usb_device_id *device_id,
- struct snd_card **cardp)
+static void snd_usx2y_card_private_free(struct snd_card *card)
{
- int err;
- struct snd_card * card;
+ struct usx2ydev *usx2y = usx2y(card);
+
+ kfree(usx2y->in04_buf);
+ usb_free_urb(usx2y->in04_urb);
+ if (usx2y->us428ctls_sharedmem)
+ free_pages_exact(usx2y->us428ctls_sharedmem,
+ US428_SHAREDMEM_PAGES);
+ if (usx2y->card_index >= 0 && usx2y->card_index < SNDRV_CARDS)
+ snd_usx2y_card_used[usx2y->card_index] = 0;
+}
- *cardp = NULL;
- if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
- (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
- return -EINVAL;
+static void snd_usx2y_disconnect(struct usb_interface *intf)
+{
+ struct snd_card *card;
+ struct usx2ydev *usx2y;
+ struct list_head *p;
- err = usX2Y_create_card(device, intf, &card);
- if (err < 0)
- return err;
- if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
- (err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ card = usb_get_intfdata(intf);
+ if (!card)
+ return;
+ usx2y = usx2y(card);
+ usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
+ usx2y_unlinkseq(&usx2y->as04);
+ usb_kill_urb(usx2y->in04_urb);
+ snd_card_disconnect(card);
+
+ /* release the midi resources */
+ list_for_each(p, &usx2y->midi_list) {
+ snd_usbmidi_disconnect(p);
}
- *cardp = card;
- return 0;
+ if (usx2y->us428ctls_sharedmem)
+ wake_up(&usx2y->us428ctls_wait_queue_head);
+ snd_card_free(card);
}
-/*
- * new 2.5 USB kernel API
- */
-static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int snd_usx2y_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *device = interface_to_usbdev(intf);
struct snd_card *card;
int err;
- err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card);
+ if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
+ (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
+ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
+ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
+ return -EINVAL;
+
+ err = usx2y_create_card(device, intf, &card);
if (err < 0)
return err;
+ err = usx2y_hwdep_new(card, device);
+ if (err < 0)
+ goto error;
+ err = snd_card_register(card);
+ if (err < 0)
+ goto error;
+
dev_set_drvdata(&intf->dev, card);
return 0;
-}
-static void snd_usX2Y_disconnect(struct usb_interface *intf)
-{
- usX2Y_usb_disconnect(interface_to_usbdev(intf),
- usb_get_intfdata(intf));
+ error:
+ snd_card_free(card);
+ return err;
}
-MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
-static struct usb_driver snd_usX2Y_usb_driver = {
+static struct usb_driver snd_usx2y_usb_driver = {
.name = "snd-usb-usx2y",
- .probe = snd_usX2Y_probe,
- .disconnect = snd_usX2Y_disconnect,
- .id_table = snd_usX2Y_usb_id_table,
+ .probe = snd_usx2y_probe,
+ .disconnect = snd_usx2y_disconnect,
+ .id_table = snd_usx2y_usb_id_table,
};
-
-static void snd_usX2Y_card_private_free(struct snd_card *card)
-{
- kfree(usX2Y(card)->In04Buf);
- usb_free_urb(usX2Y(card)->In04urb);
- if (usX2Y(card)->us428ctls_sharedmem)
- free_pages_exact(usX2Y(card)->us428ctls_sharedmem,
- sizeof(*usX2Y(card)->us428ctls_sharedmem));
- if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS)
- snd_usX2Y_card_used[usX2Y(card)->card_index] = 0;
-}
-
-/*
- * Frees the device.
- */
-static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
-{
- if (ptr) {
- struct snd_card *card = ptr;
- struct usX2Ydev *usX2Y = usX2Y(card);
- struct list_head *p;
- usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
- usX2Y_unlinkSeq(&usX2Y->AS04);
- usb_kill_urb(usX2Y->In04urb);
- snd_card_disconnect(card);
- /* release the midi resources */
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_disconnect(p);
- }
- if (usX2Y->us428ctls_sharedmem)
- wake_up(&usX2Y->us428ctls_wait_queue_head);
- snd_card_free(card);
- }
-}
-
-module_usb_driver(snd_usX2Y_usb_driver);
+module_usb_driver(snd_usx2y_usb_driver);
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 144b85f57bd2..8d82f5cc2fe1 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -3,19 +3,19 @@
#define USBUSX2Y_H
#include "../usbaudio.h"
#include "../midi.h"
-#include "usbus428ctldefs.h"
+#include "usbus428ctldefs.h"
-#define NRURBS 2
+#define NRURBS 2
-#define URBS_AsyncSeq 10
-#define URB_DataLen_AsyncSeq 32
-struct snd_usX2Y_AsyncSeq {
- struct urb *urb[URBS_AsyncSeq];
+#define URBS_ASYNC_SEQ 10
+#define URB_DATA_LEN_ASYNC_SEQ 32
+struct snd_usx2y_async_seq {
+ struct urb *urb[URBS_ASYNC_SEQ];
char *buffer;
};
-struct snd_usX2Y_urbSeq {
+struct snd_usx2y_urb_seq {
int submitted;
int len;
struct urb *urb[];
@@ -23,17 +23,17 @@ struct snd_usX2Y_urbSeq {
#include "usx2yhwdeppcm.h"
-struct usX2Ydev {
+struct usx2ydev {
struct usb_device *dev;
int card_index;
int stride;
- struct urb *In04urb;
- void *In04Buf;
- char In04Last[24];
- unsigned In04IntCalls;
- struct snd_usX2Y_urbSeq *US04;
- wait_queue_head_t In04WaitQueue;
- struct snd_usX2Y_AsyncSeq AS04;
+ struct urb *in04_urb;
+ void *in04_buf;
+ char in04_last[24];
+ unsigned int in04_int_calls;
+ struct snd_usx2y_urb_seq *us04;
+ wait_queue_head_t in04_wait_queue;
+ struct snd_usx2y_async_seq as04;
unsigned int rate,
format;
int chip_status;
@@ -41,31 +41,30 @@ struct usX2Ydev {
struct us428ctls_sharedmem *us428ctls_sharedmem;
int wait_iso_frame;
wait_queue_head_t us428ctls_wait_queue_head;
- struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm;
- struct snd_usX2Y_substream *subs[4];
- struct snd_usX2Y_substream * volatile prepare_subs;
+ struct snd_usx2y_hwdep_pcm_shm *hwdep_pcm_shm;
+ struct snd_usx2y_substream *subs[4];
+ struct snd_usx2y_substream * volatile prepare_subs;
wait_queue_head_t prepare_wait_queue;
struct list_head midi_list;
- struct list_head pcm_list;
int pcm_devs;
};
-struct snd_usX2Y_substream {
- struct usX2Ydev *usX2Y;
+struct snd_usx2y_substream {
+ struct usx2ydev *usx2y;
struct snd_pcm_substream *pcm_substream;
- int endpoint;
+ int endpoint;
unsigned int maxpacksize; /* max packet size in bytes */
atomic_t state;
-#define state_STOPPED 0
-#define state_STARTING1 1
-#define state_STARTING2 2
-#define state_STARTING3 3
-#define state_PREPARED 4
-#define state_PRERUNNING 6
-#define state_RUNNING 8
+#define STATE_STOPPED 0
+#define STATE_STARTING1 1
+#define STATE_STARTING2 2
+#define STATE_STARTING3 3
+#define STATE_PREPARED 4
+#define STATE_PRERUNNING 6
+#define STATE_RUNNING 8
int hwptr; /* free frame position in the buffer (only for playback) */
int hwptr_done; /* processed frame position in the buffer */
@@ -77,12 +76,12 @@ struct snd_usX2Y_substream {
};
-#define usX2Y(c) ((struct usX2Ydev *)(c)->private_data)
+#define usx2y(c) ((struct usx2ydev *)(c)->private_data)
-int usX2Y_audio_create(struct snd_card *card);
+int usx2y_audio_create(struct snd_card *card);
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y);
-int usX2Y_In04_init(struct usX2Ydev *usX2Y);
+int usx2y_async_seq04_init(struct usx2ydev *usx2y);
+int usx2y_in04_init(struct usx2ydev *usx2y);
#define NAME_ALLCAPS "US-X2Y"
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index ecaf41265dcd..c39cc6851e2d 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -11,7 +11,7 @@
*
* Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
*
- * Many codes borrowed from audio.c by
+ * Many codes borrowed from audio.c by
* Alan Cox (alan@lxorguk.ukuu.org.uk)
* Thomas Sailer (sailer@ife.ee.ethz.ch)
*/
@@ -28,66 +28,69 @@
#include "usx2y.h"
#include "usbusx2y.h"
-#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb.
- 1 to 4 have been tested ok on uhci.
- To use 3 on ohci, you'd need a patch:
- look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
- "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
- .
- 1, 2 and 4 work out of the box on ohci, if I recall correctly.
- Bigger is safer operation,
- smaller gives lower latencies.
- */
-#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter
- nrpacks set to 1, you might as well comment
- this #define out, and thereby produce smaller, faster code.
- You'd also set USX2Y_NRPACKS to 1 then.
- */
+/* Default value used for nr of packs per urb.
+ * 1 to 4 have been tested ok on uhci.
+ * To use 3 on ohci, you'd need a patch:
+ * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
+ * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
+ *
+ * 1, 2 and 4 work out of the box on ohci, if I recall correctly.
+ * Bigger is safer operation, smaller gives lower latencies.
+ */
+#define USX2Y_NRPACKS 4
+
+/* If your system works ok with this module's parameter
+ * nrpacks set to 1, you might as well comment
+ * this define out, and thereby produce smaller, faster code.
+ * You'd also set USX2Y_NRPACKS to 1 then.
+ */
+#define USX2Y_NRPACKS_VARIABLE 1
#ifdef USX2Y_NRPACKS_VARIABLE
- static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
- #define nr_of_packs() nrpacks
- module_param(nrpacks, int, 0444);
- MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
+static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
+#define nr_of_packs() nrpacks
+module_param(nrpacks, int, 0444);
+MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
#else
- #define nr_of_packs() USX2Y_NRPACKS
+#define nr_of_packs() USX2Y_NRPACKS
#endif
-
-static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
+static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
{
struct urb *urb = subs->completed_urb;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
unsigned char *cp;
- int i, len, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
+ int i, len, lens = 0, hwptr_done = subs->hwptr_done;
+ int cnt, blen;
+ struct usx2ydev *usx2y = subs->usx2y;
for (i = 0; i < nr_of_packs(); i++) {
- cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. "
- "Most probably some hardware problem.\n",
+ snd_printk(KERN_ERR
+ "active frame status %i. Most probably some hardware problem.\n",
urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
- len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
- if (! len) {
+ len = urb->iso_frame_desc[i].actual_length / usx2y->stride;
+ if (!len) {
snd_printd("0 == len ERROR!\n");
continue;
}
/* copy a data chunk */
if ((hwptr_done + len) > runtime->buffer_size) {
- int cnt = runtime->buffer_size - hwptr_done;
- int blen = cnt * usX2Y->stride;
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
- memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
+ cnt = runtime->buffer_size - hwptr_done;
+ blen = cnt * usx2y->stride;
+ memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen);
+ memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen);
} else {
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp,
- len * usX2Y->stride);
+ memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp,
+ len * usx2y->stride);
}
lens += len;
- if ((hwptr_done += len) >= runtime->buffer_size)
+ hwptr_done += len;
+ if (hwptr_done >= runtime->buffer_size)
hwptr_done -= runtime->buffer_size;
}
@@ -100,6 +103,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
}
return 0;
}
+
/*
* prepare urb for playback data pipe
*
@@ -110,18 +114,18 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
* it directly from the buffer. thus the data is once copied to
* a temporary buffer and urb points to that.
*/
-static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
+static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
struct urb *cap_urb,
struct urb *urb)
{
- int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
+ struct usx2ydev *usx2y = subs->usx2y;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+ int count, counts, pack, len;
count = 0;
for (pack = 0; pack < nr_of_packs(); pack++) {
/* calculate the size of a packet */
- counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
+ counts = cap_urb->iso_frame_desc[pack].actual_length / usx2y->stride;
count += counts;
if (counts < 43 || counts > 50) {
snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
@@ -134,29 +138,30 @@ static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
0;
urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
}
- if (atomic_read(&subs->state) >= state_PRERUNNING)
+ if (atomic_read(&subs->state) >= STATE_PRERUNNING) {
if (subs->hwptr + count > runtime->buffer_size) {
/* err, the transferred area goes over buffer boundary.
* copy the data to the temp buffer.
*/
- int len;
len = runtime->buffer_size - subs->hwptr;
urb->transfer_buffer = subs->tmpbuf;
memcpy(subs->tmpbuf, runtime->dma_area +
- subs->hwptr * usX2Y->stride, len * usX2Y->stride);
- memcpy(subs->tmpbuf + len * usX2Y->stride,
- runtime->dma_area, (count - len) * usX2Y->stride);
+ subs->hwptr * usx2y->stride, len * usx2y->stride);
+ memcpy(subs->tmpbuf + len * usx2y->stride,
+ runtime->dma_area, (count - len) * usx2y->stride);
subs->hwptr += count;
subs->hwptr -= runtime->buffer_size;
} else {
/* set the buffer pointer */
- urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
- if ((subs->hwptr += count) >= runtime->buffer_size)
+ urb->transfer_buffer = runtime->dma_area + subs->hwptr * usx2y->stride;
+ subs->hwptr += count;
+ if (subs->hwptr >= runtime->buffer_size)
subs->hwptr -= runtime->buffer_size;
}
- else
+ } else {
urb->transfer_buffer = subs->tmpbuf;
- urb->transfer_buffer_length = count * usX2Y->stride;
+ }
+ urb->transfer_buffer_length = count * usx2y->stride;
return 0;
}
@@ -165,10 +170,10 @@ static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
*
* update the current position and call callback if a period is processed.
*/
-static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *urb)
+static void usx2y_urb_play_retire(struct snd_usx2y_substream *subs, struct urb *urb)
{
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int len = urb->actual_length / subs->usX2Y->stride;
+ int len = urb->actual_length / subs->usx2y->stride;
subs->transfer_done += len;
subs->hwptr_done += len;
@@ -180,181 +185,195 @@ static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *
}
}
-static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, int frame)
+static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, int frame)
{
int err;
+
if (!urb)
return -ENODEV;
- urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
+ urb->start_frame = frame + NRURBS * nr_of_packs(); // let hcd do rollover sanity checks
urb->hcpriv = NULL;
- urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+ urb->dev = subs->usx2y->dev; /* we need to set this at each time */
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
return err;
}
return 0;
}
-static inline int usX2Y_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
+static int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+ struct snd_usx2y_substream *playbacksubs,
+ int frame)
{
int err, state;
struct urb *urb = playbacksubs->completed_urb;
state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
+ if (urb) {
+ if (state == STATE_RUNNING)
+ usx2y_urb_play_retire(playbacksubs, urb);
+ else if (state >= STATE_PRERUNNING)
atomic_inc(&playbacksubs->state);
} else {
switch (state) {
- case state_STARTING1:
+ case STATE_STARTING1:
urb = playbacksubs->urb[0];
atomic_inc(&playbacksubs->state);
break;
- case state_STARTING2:
+ case STATE_STARTING2:
urb = playbacksubs->urb[1];
atomic_inc(&playbacksubs->state);
break;
}
}
if (urb) {
- if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+ err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb);
+ if (err)
+ return err;
+ err = usx2y_urb_submit(playbacksubs, urb, frame);
+ if (err)
return err;
- }
}
playbacksubs->completed_urb = NULL;
state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_urb_capt_retire(capsubs)))
+ if (state >= STATE_PREPARED) {
+ if (state == STATE_RUNNING) {
+ err = usx2y_urb_capt_retire(capsubs);
+ if (err)
return err;
- } else if (state >= state_PRERUNNING)
+ } else if (state >= STATE_PRERUNNING) {
atomic_inc(&capsubs->state);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
+ }
+ err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame);
+ if (err)
return err;
}
capsubs->completed_urb = NULL;
return 0;
}
-
-static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
+static void usx2y_clients_stop(struct usx2ydev *usx2y)
{
+ struct snd_usx2y_substream *subs;
+ struct urb *urb;
int s, u;
for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
+ subs = usx2y->subs[s];
if (subs) {
snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
- atomic_set(&subs->state, state_STOPPED);
+ atomic_set(&subs->state, STATE_STOPPED);
}
}
for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
+ subs = usx2y->subs[s];
if (subs) {
- if (atomic_read(&subs->state) >= state_PRERUNNING)
+ if (atomic_read(&subs->state) >= STATE_PRERUNNING)
snd_pcm_stop_xrun(subs->pcm_substream);
for (u = 0; u < NRURBS; u++) {
- struct urb *urb = subs->urb[u];
- if (NULL != urb)
+ urb = subs->urb[u];
+ if (urb)
snd_printdd("%i status=%i start_frame=%i\n",
u, urb->status, urb->start_frame);
}
}
}
- usX2Y->prepare_subs = NULL;
- wake_up(&usX2Y->prepare_wait_queue);
+ usx2y->prepare_subs = NULL;
+ wake_up(&usx2y->prepare_wait_queue);
}
-static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
+static void usx2y_error_urb_status(struct usx2ydev *usx2y,
+ struct snd_usx2y_substream *subs, struct urb *urb)
{
snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
urb->status = 0;
- usX2Y_clients_stop(usX2Y);
+ usx2y_clients_stop(usx2y);
}
-static void i_usX2Y_urb_complete(struct urb *urb)
+static void i_usx2y_urb_complete(struct urb *urb)
{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
+ struct snd_usx2y_substream *subs = urb->context;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *capsubs, *playbacksubs;
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
+ if (unlikely(atomic_read(&subs->state) < STATE_PREPARED)) {
snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
+ usb_get_current_frame_number(usx2y->dev),
subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
urb->status, urb->start_frame);
return;
}
if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
+ usx2y_error_urb_status(usx2y, subs, urb);
return;
}
subs->completed_urb = urb;
- {
- struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
- *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb &&
- atomic_read(&capsubs->state) >= state_PREPARED &&
- (playbacksubs->completed_urb ||
- atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
- snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
- }
+ capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+
+ if (capsubs->completed_urb &&
+ atomic_read(&capsubs->state) >= STATE_PREPARED &&
+ (playbacksubs->completed_urb ||
+ atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
+ if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
+ usx2y->wait_iso_frame += nr_of_packs();
+ } else {
+ snd_printdd("\n");
+ usx2y_clients_stop(usx2y);
}
}
}
-static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
+static void usx2y_urbs_set_complete(struct usx2ydev *usx2y,
void (*complete)(struct urb *))
{
+ struct snd_usx2y_substream *subs;
+ struct urb *urb;
int s, u;
+
for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (NULL != subs)
+ subs = usx2y->subs[s];
+ if (subs) {
for (u = 0; u < NRURBS; u++) {
- struct urb * urb = subs->urb[u];
- if (NULL != urb)
+ urb = subs->urb[u];
+ if (urb)
urb->complete = complete;
}
+ }
}
}
-static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
+static void usx2y_subs_startup_finish(struct usx2ydev *usx2y)
{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
- usX2Y->prepare_subs = NULL;
+ usx2y_urbs_set_complete(usx2y, i_usx2y_urb_complete);
+ usx2y->prepare_subs = NULL;
}
-static void i_usX2Y_subs_startup(struct urb *urb)
+static void i_usx2y_subs_startup(struct urb *urb)
{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs)
+ struct snd_usx2y_substream *subs = urb->context;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
+
+ if (prepare_subs) {
if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
- usX2Y_subs_startup_finish(usX2Y);
+ usx2y_subs_startup_finish(usx2y);
atomic_inc(&prepare_subs->state);
- wake_up(&usX2Y->prepare_wait_queue);
+ wake_up(&usx2y->prepare_wait_queue);
}
+ }
- i_usX2Y_urb_complete(urb);
+ i_usx2y_urb_complete(urb);
}
-static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
+static void usx2y_subs_prepare(struct snd_usx2y_substream *subs)
{
- snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
+ snd_printdd("usx2y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
subs, subs->endpoint, subs->urb[0], subs->urb[1]);
/* reset the pointer */
subs->hwptr = 0;
@@ -362,8 +381,7 @@ static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
subs->transfer_done = 0;
}
-
-static void usX2Y_urb_release(struct urb **urb, int free_tb)
+static void usx2y_urb_release(struct urb **urb, int free_tb)
{
if (*urb) {
usb_kill_urb(*urb);
@@ -373,29 +391,33 @@ static void usX2Y_urb_release(struct urb **urb, int free_tb)
*urb = NULL;
}
}
+
/*
* release a substreams urbs
*/
-static void usX2Y_urbs_release(struct snd_usX2Y_substream *subs)
+static void usx2y_urbs_release(struct snd_usx2y_substream *subs)
{
int i;
- snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
+
+ snd_printdd("%s %i\n", __func__, subs->endpoint);
for (i = 0; i < NRURBS; i++)
- usX2Y_urb_release(subs->urb + i,
- subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
+ usx2y_urb_release(subs->urb + i,
+ subs != subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
kfree(subs->tmpbuf);
subs->tmpbuf = NULL;
}
+
/*
* initialize a substream's urbs
*/
-static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
+static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
{
int i;
unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
+ int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ struct usb_device *dev = subs->usx2y->dev;
+ struct urb **purb;
pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
usb_rcvisocpipe(dev, subs->endpoint);
@@ -403,21 +425,21 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
if (!subs->maxpacksize)
return -EINVAL;
- if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */
+ if (is_playback && !subs->tmpbuf) { /* allocate a temporary buffer for playback */
subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
if (!subs->tmpbuf)
return -ENOMEM;
}
/* allocate and initialize data urbs */
for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
+ purb = subs->urb + i;
if (*purb) {
usb_kill_urb(*purb);
continue;
}
*purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_urbs_release(subs);
+ if (!*purb) {
+ usx2y_urbs_release(subs);
return -ENOMEM;
}
if (!is_playback && !(*purb)->transfer_buffer) {
@@ -425,8 +447,8 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
(*purb)->transfer_buffer =
kmalloc_array(subs->maxpacksize,
nr_of_packs(), GFP_KERNEL);
- if (NULL == (*purb)->transfer_buffer) {
- usX2Y_urbs_release(subs);
+ if (!(*purb)->transfer_buffer) {
+ usx2y_urbs_release(subs);
return -ENOMEM;
}
}
@@ -435,70 +457,76 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
(*purb)->number_of_packets = nr_of_packs();
(*purb)->context = subs;
(*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_subs_startup;
+ (*purb)->complete = i_usx2y_subs_startup;
}
return 0;
}
-static void usX2Y_subs_startup(struct snd_usX2Y_substream *subs)
+static void usx2y_subs_startup(struct snd_usx2y_substream *subs)
{
- struct usX2Ydev *usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
+ struct usx2ydev *usx2y = subs->usx2y;
+
+ usx2y->prepare_subs = subs;
subs->urb[0]->start_frame = -1;
wmb();
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
+ usx2y_urbs_set_complete(usx2y, i_usx2y_subs_startup);
}
-static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
+static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
{
int i, err;
- struct usX2Ydev *usX2Y = subs->usX2Y;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct urb *urb;
+ unsigned long pack;
- if ((err = usX2Y_urbs_allocate(subs)) < 0)
+ err = usx2y_urbs_allocate(subs);
+ if (err < 0)
return err;
subs->completed_urb = NULL;
for (i = 0; i < 4; i++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[i];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+ struct snd_usx2y_substream *subs = usx2y->subs[i];
+
+ if (subs && atomic_read(&subs->state) >= STATE_PREPARED)
goto start;
}
start:
- usX2Y_subs_startup(subs);
+ usx2y_subs_startup(subs);
for (i = 0; i < NRURBS; i++) {
- struct urb *urb = subs->urb[i];
+ urb = subs->urb[i];
if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == i)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
+ if (!i)
+ atomic_set(&subs->state, STATE_STARTING3);
+ urb->dev = usx2y->dev;
for (pack = 0; pack < nr_of_packs(); pack++) {
urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
urb->iso_frame_desc[pack].length = subs->maxpacksize;
}
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
err = -EPIPE;
goto cleanup;
- } else
- if (i == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
+ } else {
+ if (!i)
+ usx2y->wait_iso_frame = urb->start_frame;
+ }
urb->transfer_flags = 0;
} else {
- atomic_set(&subs->state, state_STARTING1);
+ atomic_set(&subs->state, STATE_STARTING1);
break;
}
}
err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
+ wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs);
+ if (atomic_read(&subs->state) != STATE_PREPARED)
err = -EPIPE;
cleanup:
if (err) {
- usX2Y_subs_startup_finish(usX2Y);
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
+ usx2y_subs_startup_finish(usx2y);
+ usx2y_clients_stop(usx2y); // something is completely wrong > stop everything
}
return err;
}
@@ -506,33 +534,35 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
/*
* return the current pcm pointer. just return the hwptr_done value.
*/
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t snd_usx2y_pcm_pointer(struct snd_pcm_substream *substream)
{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
+ struct snd_usx2y_substream *subs = substream->runtime->private_data;
+
return subs->hwptr_done;
}
+
/*
* start/stop substream
*/
-static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
+ struct snd_usx2y_substream *subs = substream->runtime->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
- if (atomic_read(&subs->state) == state_PREPARED &&
- atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
- atomic_set(&subs->state, state_PRERUNNING);
+ snd_printdd("%s(START)\n", __func__);
+ if (atomic_read(&subs->state) == STATE_PREPARED &&
+ atomic_read(&subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= STATE_PREPARED) {
+ atomic_set(&subs->state, STATE_PRERUNNING);
} else {
snd_printdd("\n");
return -EPIPE;
}
break;
case SNDRV_PCM_TRIGGER_STOP:
- snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
- if (atomic_read(&subs->state) >= state_PRERUNNING)
- atomic_set(&subs->state, state_PREPARED);
+ snd_printdd("%s(STOP)\n", __func__);
+ if (atomic_read(&subs->state) >= STATE_PRERUNNING)
+ atomic_set(&subs->state, STATE_PREPARED);
break;
default:
return -EINVAL;
@@ -540,7 +570,6 @@ static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return 0;
}
-
/*
* allocate a buffer, setup samplerate
*
@@ -549,12 +578,11 @@ static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
* if sg buffer is supported on the later version of alsa, we'll follow
* that.
*/
-static const struct s_c2
-{
+struct s_c2 {
char c1, c2;
-}
- SetRate44100[] =
-{
+};
+
+static const struct s_c2 setrate_44100[] = {
{ 0x14, 0x08}, // this line sets 44100, well actually a little less
{ 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
{ 0x18, 0x42},
@@ -589,8 +617,8 @@ static const struct s_c2
{ 0x18, 0x7C},
{ 0x18, 0x7E}
};
-static const struct s_c2 SetRate48000[] =
-{
+
+static const struct s_c2 setrate_48000[] = {
{ 0x14, 0x09}, // this line sets 48000, well actually a little less
{ 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
{ 0x18, 0x42},
@@ -625,62 +653,65 @@ static const struct s_c2 SetRate48000[] =
{ 0x18, 0x7C},
{ 0x18, 0x7E}
};
-#define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
-static void i_usX2Y_04Int(struct urb *urb)
+#define NOOF_SETRATE_URBS ARRAY_SIZE(setrate_48000)
+
+static void i_usx2y_04int(struct urb *urb)
{
- struct usX2Ydev *usX2Y = urb->context;
-
+ struct usx2ydev *usx2y = urb->context;
+
if (urb->status)
- snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
- if (0 == --usX2Y->US04->len)
- wake_up(&usX2Y->In04WaitQueue);
+ snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status);
+ if (!--usx2y->us04->len)
+ wake_up(&usx2y->in04_wait_queue);
}
-static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
+static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
{
int err = 0, i;
- struct snd_usX2Y_urbSeq *us = NULL;
+ struct snd_usx2y_urb_seq *us = NULL;
int *usbdata = NULL;
- const struct s_c2 *ra = rate == 48000 ? SetRate48000 : SetRate44100;
+ const struct s_c2 *ra = rate == 48000 ? setrate_48000 : setrate_44100;
+ struct urb *urb;
- if (usX2Y->rate != rate) {
- us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == us) {
+ if (usx2y->rate != rate) {
+ us = kzalloc(sizeof(*us) + sizeof(struct urb *) * NOOF_SETRATE_URBS, GFP_KERNEL);
+ if (!us) {
err = -ENOMEM;
goto cleanup;
}
usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int),
GFP_KERNEL);
- if (NULL == usbdata) {
+ if (!usbdata) {
err = -ENOMEM;
goto cleanup;
}
for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
+ us->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (!us->urb[i]) {
err = -ENOMEM;
goto cleanup;
}
- ((char*)(usbdata + i))[0] = ra[i].c1;
- ((char*)(usbdata + i))[1] = ra[i].c2;
- usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
- usbdata + i, 2, i_usX2Y_04Int, usX2Y);
+ ((char *)(usbdata + i))[0] = ra[i].c1;
+ ((char *)(usbdata + i))[1] = ra[i].c2;
+ usb_fill_bulk_urb(us->urb[i], usx2y->dev, usb_sndbulkpipe(usx2y->dev, 4),
+ usbdata + i, 2, i_usx2y_04int, usx2y);
}
err = usb_urb_ep_type_check(us->urb[0]);
if (err < 0)
goto cleanup;
us->submitted = 0;
us->len = NOOF_SETRATE_URBS;
- usX2Y->US04 = us;
- wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
- usX2Y->US04 = NULL;
+ usx2y->us04 = us;
+ wait_event_timeout(usx2y->in04_wait_queue, !us->len, HZ);
+ usx2y->us04 = NULL;
if (us->len)
err = -ENODEV;
cleanup:
if (us) {
us->submitted = 2*NOOF_SETRATE_URBS;
for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- struct urb *urb = us->urb[i];
+ urb = us->urb[i];
if (!urb)
continue;
if (urb->status) {
@@ -690,67 +721,68 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
}
usb_free_urb(urb);
}
- usX2Y->US04 = NULL;
+ usx2y->us04 = NULL;
kfree(usbdata);
kfree(us);
if (!err)
- usX2Y->rate = rate;
+ usx2y->rate = rate;
}
}
return err;
}
-
-static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
+static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
{
int alternate, err;
- struct list_head* p;
+ struct list_head *p;
+
if (format == SNDRV_PCM_FORMAT_S24_3LE) {
alternate = 2;
- usX2Y->stride = 6;
+ usx2y->stride = 6;
} else {
alternate = 1;
- usX2Y->stride = 4;
+ usx2y->stride = 4;
}
- list_for_each(p, &usX2Y->midi_list) {
+ list_for_each(p, &usx2y->midi_list) {
snd_usbmidi_input_stop(p);
}
- usb_kill_urb(usX2Y->In04urb);
- if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
+ usb_kill_urb(usx2y->in04_urb);
+ err = usb_set_interface(usx2y->dev, 0, alternate);
+ if (err) {
+ snd_printk(KERN_ERR "usb_set_interface error\n");
return err;
}
- usX2Y->In04urb->dev = usX2Y->dev;
- err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
- list_for_each(p, &usX2Y->midi_list) {
+ usx2y->in04_urb->dev = usx2y->dev;
+ err = usb_submit_urb(usx2y->in04_urb, GFP_KERNEL);
+ list_for_each(p, &usx2y->midi_list) {
snd_usbmidi_input_start(p);
}
- usX2Y->format = format;
- usX2Y->rate = 0;
+ usx2y->format = format;
+ usx2y->rate = 0;
return err;
}
-static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
+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;
- struct usX2Ydev *dev = usX2Y(card);
+ struct usx2ydev *dev = usx2y(card);
+ struct snd_usx2y_substream *subs;
+ struct snd_pcm_substream *test_substream;
int i;
- mutex_lock(&usX2Y(card)->pcm_mutex);
- snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
- /* all pcm substreams off one usX2Y have to operate at the same
+ mutex_lock(&usx2y(card)->pcm_mutex);
+ snd_printdd("snd_usx2y_hw_params(%p, %p)\n", substream, hw_params);
+ /* all pcm substreams off one usx2y have to operate at the same
* rate & format
*/
for (i = 0; i < dev->pcm_devs * 2; i++) {
- struct snd_usX2Y_substream *subs = dev->subs[i];
- struct snd_pcm_substream *test_substream;
-
+ subs = dev->subs[i];
if (!subs)
continue;
test_substream = subs->pcm_substream;
@@ -767,81 +799,89 @@ static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
}
error:
- mutex_unlock(&usX2Y(card)->pcm_mutex);
+ mutex_unlock(&usx2y(card)->pcm_mutex);
return err;
}
/*
* free the buffer
*/
-static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
+static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- mutex_lock(&subs->usX2Y->pcm_mutex);
- snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
+ struct snd_usx2y_substream *subs = runtime->private_data;
+ struct snd_usx2y_substream *cap_subs, *playback_subs;
+
+ mutex_lock(&subs->usx2y->pcm_mutex);
+ snd_printdd("snd_usx2y_hw_free(%p)\n", substream);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ atomic_set(&subs->state, STATE_STOPPED);
+ usx2y_urbs_release(subs);
if (!cap_subs->pcm_substream ||
!cap_subs->pcm_substream->runtime ||
!cap_subs->pcm_substream->runtime->status ||
cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- usX2Y_urbs_release(cap_subs);
+ atomic_set(&cap_subs->state, STATE_STOPPED);
+ usx2y_urbs_release(cap_subs);
}
} else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
+ playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+ atomic_set(&subs->state, STATE_STOPPED);
+ usx2y_urbs_release(subs);
}
}
- mutex_unlock(&subs->usX2Y->pcm_mutex);
+ mutex_unlock(&subs->usx2y->pcm_mutex);
return 0;
}
+
/*
* prepare callback
*
* set format and initialize urbs
*/
-static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
+static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ struct snd_usx2y_substream *subs = runtime->private_data;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
-
- mutex_lock(&usX2Y->pcm_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
+
+ snd_printdd("%s(%p)\n", __func__, substream);
+
+ mutex_lock(&usx2y->pcm_mutex);
+ usx2y_subs_prepare(subs);
+ // Start hardware streams
+ // SyncStream first....
+ if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+ if (usx2y->format != runtime->format) {
+ err = usx2y_format_set(usx2y, runtime->format);
+ if (err < 0)
goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
+ }
+ if (usx2y->rate != runtime->rate) {
+ err = usx2y_rate_set(usx2y, runtime->rate);
+ if (err < 0)
goto up_prepare_mutex;
+ }
snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
- if (0 > (err = usX2Y_urbs_start(capsubs)))
+ err = usx2y_urbs_start(capsubs);
+ if (err < 0)
goto up_prepare_mutex;
}
- if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
- err = usX2Y_urbs_start(subs);
+ if (subs != capsubs && atomic_read(&subs->state) < STATE_PREPARED)
+ err = usx2y_urbs_start(subs);
up_prepare_mutex:
- mutex_unlock(&usX2Y->pcm_mutex);
+ mutex_unlock(&usx2y->pcm_mutex);
return err;
}
-static const struct snd_pcm_hardware snd_usX2Y_2c =
-{
+static const struct snd_pcm_hardware snd_usx2y_2c = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -860,106 +900,101 @@ static const struct snd_pcm_hardware snd_usX2Y_2c =
.fifo_size = 0
};
-
-
-static int snd_usX2Y_pcm_open(struct snd_pcm_substream *substream)
+static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
+ struct snd_usx2y_substream *subs =
+ ((struct snd_usx2y_substream **)
+ snd_pcm_substream_chip(substream))[substream->stream];
struct snd_pcm_runtime *runtime = substream->runtime;
- if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
+ if (subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
return -EBUSY;
- runtime->hw = snd_usX2Y_2c;
+ runtime->hw = snd_usx2y_2c;
runtime->private_data = subs;
subs->pcm_substream = substream;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
return 0;
}
-
-
-static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream)
+static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
+ struct snd_usx2y_substream *subs = runtime->private_data;
subs->pcm_substream = NULL;
return 0;
}
-
-static const struct snd_pcm_ops snd_usX2Y_pcm_ops =
-{
- .open = snd_usX2Y_pcm_open,
- .close = snd_usX2Y_pcm_close,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_pcm_hw_free,
- .prepare = snd_usX2Y_pcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
+static const struct snd_pcm_ops snd_usx2y_pcm_ops = {
+ .open = snd_usx2y_pcm_open,
+ .close = snd_usx2y_pcm_close,
+ .hw_params = snd_usx2y_pcm_hw_params,
+ .hw_free = snd_usx2y_pcm_hw_free,
+ .prepare = snd_usx2y_pcm_prepare,
+ .trigger = snd_usx2y_pcm_trigger,
+ .pointer = snd_usx2y_pcm_pointer,
};
-
/*
* free a usb stream instance
*/
-static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
+static void usx2y_audio_stream_free(struct snd_usx2y_substream **usx2y_substream)
{
int stream;
for_each_pcm_streams(stream) {
- kfree(usX2Y_substream[stream]);
- usX2Y_substream[stream] = NULL;
+ kfree(usx2y_substream[stream]);
+ usx2y_substream[stream] = NULL;
}
}
-static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)
+static void snd_usx2y_pcm_private_free(struct snd_pcm *pcm)
{
- struct snd_usX2Y_substream **usX2Y_stream = pcm->private_data;
- if (usX2Y_stream)
- usX2Y_audio_stream_free(usX2Y_stream);
+ struct snd_usx2y_substream **usx2y_stream = pcm->private_data;
+
+ if (usx2y_stream)
+ usx2y_audio_stream_free(usx2y_stream);
}
-static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
+static int usx2y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
{
struct snd_pcm *pcm;
int err, i;
- struct snd_usX2Y_substream **usX2Y_substream =
- usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
+ struct snd_usx2y_substream **usx2y_substream =
+ usx2y(card)->subs + 2 * usx2y(card)->pcm_devs;
for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
- usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL);
- if (!usX2Y_substream[i])
+ usx2y_substream[i] = kzalloc(sizeof(struct snd_usx2y_substream), GFP_KERNEL);
+ if (!usx2y_substream[i])
return -ENOMEM;
- usX2Y_substream[i]->usX2Y = usX2Y(card);
+ usx2y_substream[i]->usx2y = usx2y(card);
}
if (playback_endpoint)
- usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
- usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
+ usx2y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
+ usx2y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
- err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
+ err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usx2y(card)->pcm_devs,
playback_endpoint ? 1 : 0, 1,
&pcm);
if (err < 0) {
- usX2Y_audio_stream_free(usX2Y_substream);
+ usx2y_audio_stream_free(usx2y_substream);
return err;
}
if (playback_endpoint)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usx2y_pcm_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usx2y_pcm_ops);
- pcm->private_data = usX2Y_substream;
- pcm->private_free = snd_usX2Y_pcm_private_free;
+ pcm->private_data = usx2y_substream;
+ pcm->private_free = snd_usx2y_pcm_private_free;
pcm->info_flags = 0;
- sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
+ sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usx2y(card)->pcm_devs);
if (playback_endpoint) {
snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
@@ -972,7 +1007,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
SNDRV_DMA_TYPE_CONTINUOUS,
NULL,
64*1024, 128*1024);
- usX2Y(card)->pcm_devs++;
+ usx2y(card)->pcm_devs++;
return 0;
}
@@ -980,18 +1015,19 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
/*
* create a chip instance and set its names.
*/
-int usX2Y_audio_create(struct snd_card *card)
+int usx2y_audio_create(struct snd_card *card)
{
- int err = 0;
-
- INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
+ int err;
- if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
+ err = usx2y_audio_stream_new(card, 0xA, 0x8);
+ if (err < 0)
return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
- if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
- return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
- err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
+ if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) {
+ err = usx2y_audio_stream_new(card, 0, 0xA);
+ if (err < 0)
+ return err;
+ }
+ if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122)
+ err = usx2y_rate_set(usx2y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
return err;
}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 8253669c6a7d..db83522c1b49 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -6,7 +6,7 @@
Its usb's unableness to atomically handle power of 2 period sized data chuncs
at standard samplerates,
- what led to this part of the usx2y module:
+ what led to this part of the usx2y module:
It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
The pair uses a hardware dependent alsa-device for mmaped pcm transport.
Advantage achieved:
@@ -35,7 +35,7 @@
Kernel:
- rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio
devices can use it.
- Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y.
+ Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y.
*/
#include <linux/delay.h>
@@ -46,28 +46,32 @@
#include <sound/hwdep.h>
-
-static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
+static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
{
struct urb *urb = subs->completed_urb;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int i, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- if (0 > usX2Y->hwdep_pcm_shm->capture_iso_start) { //FIXME
- int head = usX2Y->hwdep_pcm_shm->captured_iso_head + 1;
- if (head >= ARRAY_SIZE(usX2Y->hwdep_pcm_shm->captured_iso))
+ int i, lens = 0, hwptr_done = subs->hwptr_done;
+ struct usx2ydev *usx2y = subs->usx2y;
+ int head;
+
+ if (usx2y->hwdep_pcm_shm->capture_iso_start < 0) { //FIXME
+ head = usx2y->hwdep_pcm_shm->captured_iso_head + 1;
+ if (head >= ARRAY_SIZE(usx2y->hwdep_pcm_shm->captured_iso))
head = 0;
- usX2Y->hwdep_pcm_shm->capture_iso_start = head;
+ usx2y->hwdep_pcm_shm->capture_iso_start = head;
snd_printdd("cap start %i\n", head);
}
for (i = 0; i < nr_of_packs(); i++) {
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
+ snd_printk(KERN_ERR
+ "active frame status %i. Most probably some hardware problem.\n",
+ urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
- lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
+ lens += urb->iso_frame_desc[i].actual_length / usx2y->stride;
}
- if ((hwptr_done += lens) >= runtime->buffer_size)
+ hwptr_done += lens;
+ if (hwptr_done >= runtime->buffer_size)
hwptr_done -= runtime->buffer_size;
subs->hwptr_done = hwptr_done;
subs->transfer_done += lens;
@@ -79,10 +83,10 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
return 0;
}
-static inline int usX2Y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
- struct usX2Ydev * usX2Y)
+static int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
+ struct usx2ydev *usx2y)
{
- return (runtime->buffer_size * 1000) / usX2Y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
+ return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
}
/*
@@ -95,18 +99,18 @@ static inline int usX2Y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
* it directly from the buffer. thus the data is once copied to
* a temporary buffer and urb points to that.
*/
-static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
+static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs,
struct urb *urb)
{
int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_hwdep_pcm_shm *shm = usX2Y->hwdep_pcm_shm;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_hwdep_pcm_shm *shm = usx2y->hwdep_pcm_shm;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- if (0 > shm->playback_iso_start) {
+ if (shm->playback_iso_start < 0) {
shm->playback_iso_start = shm->captured_iso_head -
- usX2Y_iso_frames_per_buffer(runtime, usX2Y);
- if (0 > shm->playback_iso_start)
+ usx2y_iso_frames_per_buffer(runtime, usx2y);
+ if (shm->playback_iso_start < 0)
shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
shm->playback_iso_head = shm->playback_iso_start;
}
@@ -114,7 +118,7 @@ static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
count = 0;
for (pack = 0; pack < nr_of_packs(); pack++) {
/* calculate the size of a packet */
- counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
+ counts = shm->captured_iso[shm->playback_iso_head].length / usx2y->stride;
if (counts < 43 || counts > 50) {
snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
return -EPIPE;
@@ -122,27 +126,29 @@ static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
/* set up descriptor */
urb->iso_frame_desc[pack].offset = shm->captured_iso[shm->playback_iso_head].offset;
urb->iso_frame_desc[pack].length = shm->captured_iso[shm->playback_iso_head].length;
- if (atomic_read(&subs->state) != state_RUNNING)
+ if (atomic_read(&subs->state) != STATE_RUNNING)
memset((char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
urb->iso_frame_desc[pack].length);
if (++shm->playback_iso_head >= ARRAY_SIZE(shm->captured_iso))
shm->playback_iso_head = 0;
count += counts;
}
- urb->transfer_buffer_length = count * usX2Y->stride;
+ urb->transfer_buffer_length = count * usx2y->stride;
return 0;
}
-
-static inline void usX2Y_usbpcm_urb_capt_iso_advance(struct snd_usX2Y_substream *subs,
- struct urb *urb)
+static void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs,
+ struct urb *urb)
{
- int pack;
+ struct usb_iso_packet_descriptor *desc;
+ struct snd_usx2y_hwdep_pcm_shm *shm;
+ int pack, head;
+
for (pack = 0; pack < nr_of_packs(); ++pack) {
- struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
- if (NULL != subs) {
- struct snd_usX2Y_hwdep_pcm_shm *shm = subs->usX2Y->hwdep_pcm_shm;
- int head = shm->captured_iso_head + 1;
+ desc = urb->iso_frame_desc + pack;
+ if (subs) {
+ shm = subs->usx2y->hwdep_pcm_shm;
+ head = shm->captured_iso_head + 1;
if (head >= ARRAY_SIZE(shm->captured_iso))
head = 0;
shm->captured_iso[head].frame = urb->start_frame + pack;
@@ -151,106 +157,111 @@ static inline void usX2Y_usbpcm_urb_capt_iso_advance(struct snd_usX2Y_substream
shm->captured_iso_head = head;
shm->captured_iso_frames++;
}
- if ((desc->offset += desc->length * NRURBS*nr_of_packs()) +
- desc->length >= SSS)
+ desc->offset += desc->length * NRURBS * nr_of_packs();
+ if (desc->offset + desc->length >= SSS)
desc->offset -= (SSS - desc->length);
}
}
-static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *capsubs2,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
+static int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *capsubs,
+ struct snd_usx2y_substream *capsubs2,
+ struct snd_usx2y_substream *playbacksubs,
+ int frame)
{
int err, state;
struct urb *urb = playbacksubs->completed_urb;
state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
+ if (urb) {
+ if (state == STATE_RUNNING)
+ usx2y_urb_play_retire(playbacksubs, urb);
+ else if (state >= STATE_PRERUNNING)
atomic_inc(&playbacksubs->state);
} else {
switch (state) {
- case state_STARTING1:
+ case STATE_STARTING1:
urb = playbacksubs->urb[0];
atomic_inc(&playbacksubs->state);
break;
- case state_STARTING2:
+ case STATE_STARTING2:
urb = playbacksubs->urb[1];
atomic_inc(&playbacksubs->state);
break;
}
}
if (urb) {
- if ((err = usX2Y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+ err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb);
+ if (err)
+ return err;
+ err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb);
+ if (err)
return err;
- }
}
-
+
playbacksubs->completed_urb = NULL;
state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
+ if (state >= STATE_PREPARED) {
+ if (state == STATE_RUNNING) {
+ err = usx2y_usbpcm_urb_capt_retire(capsubs);
+ if (err)
return err;
- } else if (state >= state_PRERUNNING)
+ } else if (state >= STATE_PRERUNNING) {
atomic_inc(&capsubs->state);
- usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
- if (NULL != capsubs2)
- usX2Y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
+ }
+ usx2y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
+ if (capsubs2)
+ usx2y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
+ err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame);
+ if (err)
return err;
- if (NULL != capsubs2)
- if ((err = usX2Y_urb_submit(capsubs2, capsubs2->completed_urb, frame)))
+ if (capsubs2) {
+ err = usx2y_urb_submit(capsubs2, capsubs2->completed_urb, frame);
+ if (err)
return err;
+ }
}
capsubs->completed_urb = NULL;
- if (NULL != capsubs2)
+ if (capsubs2)
capsubs2->completed_urb = NULL;
return 0;
}
-
-static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
+static void i_usx2y_usbpcm_urb_complete(struct urb *urb)
{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs, *capsubs2, *playbacksubs;
+ struct snd_usx2y_substream *subs = urb->context;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *capsubs, *capsubs2, *playbacksubs;
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
+ if (unlikely(atomic_read(&subs->state) < STATE_PREPARED)) {
snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
+ usb_get_current_frame_number(usx2y->dev),
subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
urb->status, urb->start_frame);
return;
}
if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
+ usx2y_error_urb_status(usx2y, subs, urb);
return;
}
subs->completed_urb = urb;
- capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
- (NULL == capsubs2 || capsubs2->completed_urb) &&
- (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
+ capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ capsubs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+ playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ if (capsubs->completed_urb && atomic_read(&capsubs->state) >= STATE_PREPARED &&
+ (!capsubs2 || capsubs2->completed_urb) &&
+ (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
+ if (!usx2y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
+ usx2y->wait_iso_frame += nr_of_packs();
+ } else {
snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
+ usx2y_clients_stop(usx2y);
}
}
}
-
-static void usX2Y_hwdep_urb_release(struct urb **urb)
+static void usx2y_hwdep_urb_release(struct urb **urb)
{
usb_kill_urb(*urb);
usb_free_urb(*urb);
@@ -260,49 +271,53 @@ static void usX2Y_hwdep_urb_release(struct urb **urb)
/*
* release a substream
*/
-static void usX2Y_usbpcm_urbs_release(struct snd_usX2Y_substream *subs)
+static void usx2y_usbpcm_urbs_release(struct snd_usx2y_substream *subs)
{
int i;
- snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
+
+ snd_printdd("snd_usx2y_urbs_release() %i\n", subs->endpoint);
for (i = 0; i < NRURBS; i++)
- usX2Y_hwdep_urb_release(subs->urb + i);
+ usx2y_hwdep_urb_release(subs->urb + i);
}
-static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
+static void usx2y_usbpcm_subs_startup_finish(struct usx2ydev *usx2y)
{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
- usX2Y->prepare_subs = NULL;
+ usx2y_urbs_set_complete(usx2y, i_usx2y_usbpcm_urb_complete);
+ usx2y->prepare_subs = NULL;
}
-static void i_usX2Y_usbpcm_subs_startup(struct urb *urb)
+static void i_usx2y_usbpcm_subs_startup(struct urb *urb)
{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs &&
+ struct snd_usx2y_substream *subs = urb->context;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
+ struct snd_usx2y_substream *cap_subs2;
+
+ if (prepare_subs &&
urb->start_frame == prepare_subs->urb[0]->start_frame) {
atomic_inc(&prepare_subs->state);
- if (prepare_subs == usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
- struct snd_usX2Y_substream *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- if (cap_subs2 != NULL)
+ if (prepare_subs == usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
+ cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+ if (cap_subs2)
atomic_inc(&cap_subs2->state);
}
- usX2Y_usbpcm_subs_startup_finish(usX2Y);
- wake_up(&usX2Y->prepare_wait_queue);
+ usx2y_usbpcm_subs_startup_finish(usx2y);
+ wake_up(&usx2y->prepare_wait_queue);
}
- i_usX2Y_usbpcm_urb_complete(urb);
+ i_usx2y_usbpcm_urb_complete(urb);
}
/*
* initialize a substream's urbs
*/
-static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
+static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs)
{
int i;
unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
+ int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ struct usb_device *dev = subs->usx2y->dev;
+ struct urb **purb;
pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
usb_rcvisocpipe(dev, subs->endpoint);
@@ -312,28 +327,28 @@ static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
/* allocate and initialize data urbs */
for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
+ purb = subs->urb + i;
if (*purb) {
usb_kill_urb(*purb);
continue;
}
*purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_usbpcm_urbs_release(subs);
+ if (!*purb) {
+ usx2y_usbpcm_urbs_release(subs);
return -ENOMEM;
}
(*purb)->transfer_buffer = is_playback ?
- subs->usX2Y->hwdep_pcm_shm->playback : (
+ subs->usx2y->hwdep_pcm_shm->playback : (
subs->endpoint == 0x8 ?
- subs->usX2Y->hwdep_pcm_shm->capture0x8 :
- subs->usX2Y->hwdep_pcm_shm->capture0xA);
+ subs->usx2y->hwdep_pcm_shm->capture0x8 :
+ subs->usx2y->hwdep_pcm_shm->capture0xA);
(*purb)->dev = dev;
(*purb)->pipe = pipe;
(*purb)->number_of_packets = nr_of_packs();
(*purb)->context = subs;
(*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_usbpcm_subs_startup;
+ (*purb)->complete = i_usx2y_usbpcm_subs_startup;
}
return 0;
}
@@ -341,195 +356,216 @@ static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
/*
* free the buffer
*/
-static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data,
- *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- mutex_lock(&subs->usX2Y->pcm_mutex);
- snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
+ struct snd_usx2y_substream *subs = runtime->private_data;
+ struct snd_usx2y_substream *cap_subs;
+ struct snd_usx2y_substream *playback_subs;
+ struct snd_usx2y_substream *cap_subs2;
+
+ mutex_lock(&subs->usx2y->pcm_mutex);
+ snd_printdd("%s(%p)\n", __func__, substream);
+
+ cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ atomic_set(&subs->state, STATE_STOPPED);
+ usx2y_usbpcm_urbs_release(subs);
if (!cap_subs->pcm_substream ||
!cap_subs->pcm_substream->runtime ||
!cap_subs->pcm_substream->runtime->status ||
cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(cap_subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
+ atomic_set(&cap_subs->state, STATE_STOPPED);
+ if (cap_subs2)
+ atomic_set(&cap_subs2->state, STATE_STOPPED);
+ usx2y_usbpcm_urbs_release(cap_subs);
+ if (cap_subs2)
+ usx2y_usbpcm_urbs_release(cap_subs2);
}
} else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
+ playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+ atomic_set(&subs->state, STATE_STOPPED);
+ if (cap_subs2)
+ atomic_set(&cap_subs2->state, STATE_STOPPED);
+ usx2y_usbpcm_urbs_release(subs);
+ if (cap_subs2)
+ usx2y_usbpcm_urbs_release(cap_subs2);
}
}
- mutex_unlock(&subs->usX2Y->pcm_mutex);
+ mutex_unlock(&subs->usx2y->pcm_mutex);
return 0;
}
-static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs)
+static void usx2y_usbpcm_subs_startup(struct snd_usx2y_substream *subs)
{
- struct usX2Ydev * usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
+ struct usx2ydev *usx2y = subs->usx2y;
+
+ usx2y->prepare_subs = subs;
subs->urb[0]->start_frame = -1;
- smp_wmb(); // Make sure above modifications are seen by i_usX2Y_subs_startup()
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
+ smp_wmb(); // Make sure above modifications are seen by i_usx2y_subs_startup()
+ usx2y_urbs_set_complete(usx2y, i_usx2y_usbpcm_subs_startup);
}
-static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
+static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
{
- int p, u, err,
- stream = subs->pcm_substream->stream;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if (SNDRV_PCM_STREAM_CAPTURE == stream) {
- usX2Y->hwdep_pcm_shm->captured_iso_head = -1;
- usX2Y->hwdep_pcm_shm->captured_iso_frames = 0;
+ int p, u, err, stream = subs->pcm_substream->stream;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct urb *urb;
+ unsigned long pack;
+
+ if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+ usx2y->hwdep_pcm_shm->captured_iso_head = -1;
+ usx2y->hwdep_pcm_shm->captured_iso_frames = 0;
}
for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
+ struct snd_usx2y_substream *subs = usx2y->subs[stream + p];
+ if (subs) {
+ err = usx2y_usbpcm_urbs_allocate(subs);
+ if (err < 0)
return err;
subs->completed_urb = NULL;
}
}
for (p = 0; p < 4; p++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[p];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+ struct snd_usx2y_substream *subs = usx2y->subs[p];
+
+ if (subs && atomic_read(&subs->state) >= STATE_PREPARED)
goto start;
}
start:
- usX2Y_usbpcm_subs_startup(subs);
+ usx2y_usbpcm_subs_startup(subs);
for (u = 0; u < NRURBS; u++) {
for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- struct urb *urb = subs->urb[u];
- if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == u)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
- snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
- err = -EPIPE;
- goto cleanup;
- } else {
- snd_printdd("%i\n", urb->start_frame);
- if (u == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
- }
- urb->transfer_flags = 0;
- } else {
- atomic_set(&subs->state, state_STARTING1);
- break;
- }
+ struct snd_usx2y_substream *subs = usx2y->subs[stream + p];
+
+ if (!subs)
+ continue;
+ urb = subs->urb[u];
+ if (usb_pipein(urb->pipe)) {
+ if (!u)
+ atomic_set(&subs->state, STATE_STARTING3);
+ urb->dev = usx2y->dev;
+ for (pack = 0; pack < nr_of_packs(); pack++) {
+ urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
+ urb->iso_frame_desc[pack].length = subs->maxpacksize;
+ }
+ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err < 0) {
+ snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
+ err = -EPIPE;
+ goto cleanup;
+ } else {
+ snd_printdd("%i\n", urb->start_frame);
+ if (!u)
+ usx2y->wait_iso_frame = urb->start_frame;
+ }
+ urb->transfer_flags = 0;
+ } else {
+ atomic_set(&subs->state, STATE_STARTING1);
+ break;
}
}
}
err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
+ wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs);
+ if (atomic_read(&subs->state) != STATE_PREPARED)
err = -EPIPE;
-
+
cleanup:
if (err) {
- usX2Y_subs_startup_finish(usX2Y); // Call it now
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
+ usx2y_subs_startup_finish(usx2y); // Call it now
+ usx2y_clients_stop(usx2y); // something is completely wrong > stop everything
}
return err;
}
+#define USX2Y_HWDEP_PCM_PAGES \
+ PAGE_ALIGN(sizeof(struct snd_usx2y_hwdep_pcm_shm))
+
/*
* prepare callback
*
* set format and initialize urbs
*/
-static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
+static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ struct snd_usx2y_substream *subs = runtime->private_data;
+ struct usx2ydev *usx2y = subs->usx2y;
+ struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
- if (NULL == usX2Y->hwdep_pcm_shm) {
- usX2Y->hwdep_pcm_shm = alloc_pages_exact(sizeof(struct snd_usX2Y_hwdep_pcm_shm),
+ snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream);
+
+ mutex_lock(&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)
- return -ENOMEM;
- memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
+ if (!usx2y->hwdep_pcm_shm) {
+ err = -ENOMEM;
+ goto up_prepare_mutex;
+ }
+ memset(usx2y->hwdep_pcm_shm, 0, USX2Y_HWDEP_PCM_PAGES);
}
- mutex_lock(&usX2Y->pcm_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
+ usx2y_subs_prepare(subs);
+ // Start hardware streams
+ // SyncStream first....
+ if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+ if (usx2y->format != runtime->format) {
+ err = usx2y_format_set(usx2y, runtime->format);
+ if (err < 0)
goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
+ }
+ if (usx2y->rate != runtime->rate) {
+ err = usx2y_rate_set(usx2y, runtime->rate);
+ if (err < 0)
goto up_prepare_mutex;
+ }
snd_printdd("starting capture pipe for %s\n", subs == capsubs ?
"self" : "playpipe");
- if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
+ err = usx2y_usbpcm_urbs_start(capsubs);
+ if (err < 0)
goto up_prepare_mutex;
}
if (subs != capsubs) {
- usX2Y->hwdep_pcm_shm->playback_iso_start = -1;
- if (atomic_read(&subs->state) < state_PREPARED) {
- while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) >
- usX2Y->hwdep_pcm_shm->captured_iso_frames) {
- snd_printdd("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);
+ usx2y->hwdep_pcm_shm->playback_iso_start = -1;
+ if (atomic_read(&subs->state) < STATE_PREPARED) {
+ while (usx2y_iso_frames_per_buffer(runtime, usx2y) >
+ usx2y->hwdep_pcm_shm->captured_iso_frames) {
+ snd_printdd("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 (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
+ }
+ err = usx2y_usbpcm_urbs_start(subs);
+ if (err < 0)
goto up_prepare_mutex;
}
snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
- usX2Y_iso_frames_per_buffer(runtime, usX2Y),
- usX2Y->hwdep_pcm_shm->captured_iso_frames);
- } else
- usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
+ usx2y_iso_frames_per_buffer(runtime, usx2y),
+ usx2y->hwdep_pcm_shm->captured_iso_frames);
+ } else {
+ usx2y->hwdep_pcm_shm->capture_iso_start = -1;
+ }
up_prepare_mutex:
- mutex_unlock(&usX2Y->pcm_mutex);
+ mutex_unlock(&usx2y->pcm_mutex);
return err;
}
-static const struct snd_pcm_hardware snd_usX2Y_4c =
-{
+static const struct snd_pcm_hardware snd_usx2y_4c = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -547,55 +583,53 @@ static const struct snd_pcm_hardware snd_usX2Y_4c =
.fifo_size = 0
};
-
-
-static int snd_usX2Y_usbpcm_open(struct snd_pcm_substream *substream)
+static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream)
{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
+ struct snd_usx2y_substream *subs =
+ ((struct snd_usx2y_substream **)
+ snd_pcm_substream_chip(substream))[substream->stream];
struct snd_pcm_runtime *runtime = substream->runtime;
- if (!(subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
+ if (!(subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
return -EBUSY;
- runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usX2Y_2c :
- (subs->usX2Y->subs[3] ? snd_usX2Y_4c : snd_usX2Y_2c);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = snd_usx2y_2c;
+ else
+ runtime->hw = (subs->usx2y->subs[3] ? snd_usx2y_4c : snd_usx2y_2c);
runtime->private_data = subs;
subs->pcm_substream = substream;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
return 0;
}
-
-static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream)
+static int snd_usx2y_usbpcm_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
+ struct snd_usx2y_substream *subs = runtime->private_data;
subs->pcm_substream = NULL;
return 0;
}
-
-static const struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
-{
- .open = snd_usX2Y_usbpcm_open,
- .close = snd_usX2Y_usbpcm_close,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_usbpcm_hw_free,
- .prepare = snd_usX2Y_usbpcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
+static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = {
+ .open = snd_usx2y_usbpcm_open,
+ .close = snd_usx2y_usbpcm_close,
+ .hw_params = snd_usx2y_pcm_hw_params,
+ .hw_free = snd_usx2y_usbpcm_hw_free,
+ .prepare = snd_usx2y_usbpcm_prepare,
+ .trigger = snd_usx2y_pcm_trigger,
+ .pointer = snd_usx2y_pcm_pointer,
};
-
-static int usX2Y_pcms_busy_check(struct snd_card *card)
+static int usx2y_pcms_busy_check(struct snd_card *card)
{
- struct usX2Ydev *dev = usX2Y(card);
+ struct usx2ydev *dev = usx2y(card);
+ struct snd_usx2y_substream *subs;
int i;
for (i = 0; i < dev->pcm_devs * 2; i++) {
- struct snd_usX2Y_substream *subs = dev->subs[i];
+ subs = dev->subs[i];
if (subs && subs->pcm_substream &&
SUBSTREAM_BUSY(subs->pcm_substream))
return -EBUSY;
@@ -603,125 +637,120 @@ static int usX2Y_pcms_busy_check(struct snd_card *card)
return 0;
}
-static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
+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);
- err = usX2Y_pcms_busy_check(card);
+ mutex_lock(&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);
+ usx2y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
+ mutex_unlock(&usx2y(card)->pcm_mutex);
return err;
}
-
-static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
+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);
- err = usX2Y_pcms_busy_check(card);
+ mutex_lock(&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);
+ usx2y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
+ mutex_unlock(&usx2y(card)->pcm_mutex);
return err;
}
-
-static void snd_usX2Y_hwdep_pcm_vm_open(struct vm_area_struct *area)
+static void snd_usx2y_hwdep_pcm_vm_open(struct vm_area_struct *area)
{
}
-
-static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
+static void snd_usx2y_hwdep_pcm_vm_close(struct vm_area_struct *area)
{
}
-
-static vm_fault_t snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
+static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
{
unsigned long offset;
void *vaddr;
offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char *)((struct usX2Ydev *)vmf->vma->vm_private_data)->hwdep_pcm_shm + offset;
+ vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->hwdep_pcm_shm + offset;
vmf->page = virt_to_page(vaddr);
get_page(vmf->page);
return 0;
}
-
-static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
- .open = snd_usX2Y_hwdep_pcm_vm_open,
- .close = snd_usX2Y_hwdep_pcm_vm_close,
- .fault = snd_usX2Y_hwdep_pcm_vm_fault,
+static const struct vm_operations_struct snd_usx2y_hwdep_pcm_vm_ops = {
+ .open = snd_usx2y_hwdep_pcm_vm_open,
+ .close = snd_usx2y_hwdep_pcm_vm_close,
+ .fault = snd_usx2y_hwdep_pcm_vm_fault,
};
-
-static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
+static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area)
{
unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *usX2Y = hw->private_data;
+ struct usx2ydev *usx2y = hw->private_data;
- if (!(usX2Y->chip_status & USX2Y_STAT_CHIP_INIT))
+ if (!(usx2y->chip_status & USX2Y_STAT_CHIP_INIT))
return -EBUSY;
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct snd_usX2Y_hwdep_pcm_shm))) {
- snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usX2Y_hwdep_pcm_shm));
+ /* if userspace tries to mmap beyond end of our buffer, fail */
+ if (size > USX2Y_HWDEP_PCM_PAGES) {
+ snd_printd("%lu > %lu\n", size, (unsigned long)USX2Y_HWDEP_PCM_PAGES);
return -EINVAL;
}
- if (!usX2Y->hwdep_pcm_shm) {
+ if (!usx2y->hwdep_pcm_shm)
return -ENODEV;
- }
- area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
+
+ area->vm_ops = &snd_usx2y_hwdep_pcm_vm_ops;
area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
return 0;
}
-
-static void snd_usX2Y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
+static void snd_usx2y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
{
- struct usX2Ydev *usX2Y = hwdep->private_data;
- if (NULL != usX2Y->hwdep_pcm_shm)
- free_pages_exact(usX2Y->hwdep_pcm_shm, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
-}
+ struct usx2ydev *usx2y = hwdep->private_data;
+ if (usx2y->hwdep_pcm_shm)
+ free_pages_exact(usx2y->hwdep_pcm_shm, USX2Y_HWDEP_PCM_PAGES);
+}
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
+int usx2y_hwdep_pcm_new(struct snd_card *card)
{
int err;
struct snd_hwdep *hw;
struct snd_pcm *pcm;
- struct usb_device *dev = usX2Y(card)->dev;
- if (1 != nr_of_packs())
+ struct usb_device *dev = usx2y(card)->dev;
+
+ if (nr_of_packs() != 1)
return 0;
- if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0)
+ err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw);
+ if (err < 0)
return err;
hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
- hw->private_data = usX2Y(card);
- hw->private_free = snd_usX2Y_hwdep_pcm_private_free;
- hw->ops.open = snd_usX2Y_hwdep_pcm_open;
- hw->ops.release = snd_usX2Y_hwdep_pcm_release;
- hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
+ hw->private_data = usx2y(card);
+ hw->private_free = snd_usx2y_hwdep_pcm_private_free;
+ hw->ops.open = snd_usx2y_hwdep_pcm_open;
+ hw->ops.release = snd_usx2y_hwdep_pcm_release;
+ hw->ops.mmap = snd_usx2y_hwdep_pcm_mmap;
hw->exclusive = 1;
sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
- if (err < 0) {
+ if (err < 0)
return err;
- }
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_usbpcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_usbpcm_ops);
- pcm->private_data = usX2Y(card)->subs;
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usx2y_usbpcm_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usx2y_usbpcm_ops);
+
+ pcm->private_data = usx2y(card)->subs;
pcm->info_flags = 0;
sprintf(pcm->name, NAME_ALLCAPS" hwdep Audio");
@@ -739,7 +768,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
#else
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
+int usx2y_hwdep_pcm_new(struct snd_card *card)
{
return 0;
}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.h b/sound/usb/usx2y/usx2yhwdeppcm.h
index eb5a46466f0e..731b1c5a3474 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.h
+++ b/sound/usb/usx2y/usx2yhwdeppcm.h
@@ -4,7 +4,7 @@
#define MAXSTRIDE 3
#define SSS (((MAXPACK*MAXBUFFERMS*MAXSTRIDE + 4096) / 4096) * 4096)
-struct snd_usX2Y_hwdep_pcm_shm {
+struct snd_usx2y_hwdep_pcm_shm {
char playback[SSS];
char capture0x8[SSS];
char capture0xA[SSS];
@@ -20,4 +20,4 @@ struct snd_usX2Y_hwdep_pcm_shm {
int capture_iso_start;
};
-int usX2Y_hwdep_pcm_new(struct snd_card *card);
+int usx2y_hwdep_pcm_new(struct snd_card *card);
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 33b12aa67cf5..a34d7d9c2a57 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -236,7 +236,7 @@ static void had_write_register(struct snd_intelhad *ctx, u32 reg, u32 val)
* updating AUD_CONFIG register.
* This is because:
* Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2
- * HDMI IP. As a result a read-modify of AUD_CONFIG regiter will always
+ * HDMI IP. As a result a read-modify of AUD_CONFIG register will always
* clear bit6. AUD_CONFIG[6:4] represents the "channels" field of the
* register. This field should be 1xy binary for configuration with 6 or
* more channels. Read-modify of AUD_CONFIG (Eg. for enabling audio)
@@ -342,7 +342,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
/*
* function to initialize audio
- * registers and buffer confgiuration registers
+ * registers and buffer configuration registers
* This function is called in the prepare callback
*/
static int had_init_audio_ctrl(struct snd_pcm_substream *substream,
@@ -1790,7 +1790,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
pcm->private_data = ctx;
pcm->info_flags = 0;
strscpy(pcm->name, card->shortname, strlen(card->shortname));
- /* setup the ops for playabck */
+ /* setup the ops for playback */
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &had_pcm_ops);
/* allocate dma pages;
diff --git a/sound/x86/intel_hdmi_audio.h b/sound/x86/intel_hdmi_audio.h
index 0d91bb5dbab7..bb3853195922 100644
--- a/sound/x86/intel_hdmi_audio.h
+++ b/sound/x86/intel_hdmi_audio.h
@@ -96,7 +96,7 @@ struct pcm_stream_info {
* @had_spinlock: driver lock
* @aes_bits: IEC958 status bits
* @buff_done: id of current buffer done intr
- * @dev: platoform device handle
+ * @dev: platform device handle
* @chmap: holds channel map info
*/
struct snd_intelhad {