aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-03 14:58:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-03 14:58:59 -0400
commit221656e7c4ce342b99c31eca96c1cbb6d1dce45f (patch)
tree1af3655475361f3ec75d8e26bc8d5f4bad8a87b0
parent2f34c1231bfc9f2550f934acb268ac7315fb3837 (diff)
parenta5c3b32a1146e44f6b38fdfdfffc27842953420c (diff)
Merge tag 'sound-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "It was a relatively calm development cycle, and no scaring changes are seen in both core and driver sides. Here are some highlights: ASoC: - A new API for hooking up jacks more generically and easily - Card longname is set based on DMI for a unique UCM profile - Lots of Intel driver fixes: Atom, Broxton, Skylake and newer chips - New drivers for Cirrus CS35L35, DIO DIO2125, Everest ES7132, HiSilicon hi6210, Maxim MAX98927, MT2701 systems with WM8960, Nuvoton NAU8824, Odroid systems, ST STM32 SAI controllers and x86 systems with DA7213 HD-audio: - Many new quirks to support headset for various devices (mostly ASUS ones) as usual - Support for dual codecs on some Gigabyte mobos and Lenovo laptop - Improvement on PCM position reporting for Skylake and newer FireWire: - New drivers for MOTU and RME Fireface series - Updates for Digidesign Digi00x and TASCAM series - Support for tracepoints Others: - USB-audio: improved support for quirk_alias option - Cleanups, constification allover the places" * tag 'sound-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (299 commits) ASoC: codec: wm8960: Relax bit clock computation when using PLL ASoC: codec: wm9860: avoid maybe-uninitialized warning ASoC: nau8824: leave Class D gain at chip default ASoC: nau8824: rename controls to match DAPM controls ASoC: Intel: Skylake: Return negative error code ASoC: Intel: Skylake: Fix unused variable warning ASoC: Intel: Skylake: fix uninitialized pointer use ASoC: sti: Fix error handling if of_clk_get() fails ASoC: cs4271: configure reset GPIO as output ASoC: dwc: Disallow building designware_pcm as a module ALSA: ali5451: fix spelling mistake in "ali_capture_preapre" ASoC: stm32: add SAI driver ASoC: stm32: add bindings for SAI ASoC: Intel: Skylake: Add loadable module support on KBL platform ASoC: Intel: Skylake: Modify load_lib_ipc arguments for a nowait version ASoC: Intel: Skylake: Register dsp_fw_ops for kabylake ASoC: Intel: Skylake: Modify arguments to reuse module transfer function ASoC: Intel: Skylake: Commonize library load ASoC: Intel: Skylake: Move sst common initialization to a helper function ASoC: nau8824: new driver ...
-rw-r--r--Documentation/devicetree/bindings/sound/cs35l35.txt180
-rw-r--r--Documentation/devicetree/bindings/sound/dioo,dio2125.txt12
-rw-r--r--Documentation/devicetree/bindings/sound/everest,es7134.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,ssi.txt34
-rw-r--r--Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt42
-rw-r--r--Documentation/devicetree/bindings/sound/max98925.txt22
-rw-r--r--Documentation/devicetree/bindings/sound/max98926.txt32
-rw-r--r--Documentation/devicetree/bindings/sound/max9892x.txt41
-rw-r--r--Documentation/devicetree/bindings/sound/mt2701-wm8960.txt24
-rw-r--r--Documentation/devicetree/bindings/sound/nau8824.txt88
-rw-r--r--Documentation/devicetree/bindings/sound/rockchip-i2s.txt1
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,odroid.txt57
-rw-r--r--Documentation/devicetree/bindings/sound/sgtl5000.txt9
-rw-r--r--Documentation/devicetree/bindings/sound/st,stm32-sai.txt89
-rw-r--r--Documentation/devicetree/bindings/sound/tas2552.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/wm8903.txt13
-rw-r--r--Documentation/devicetree/bindings/sound/zte,tdm.txt30
-rw-r--r--Documentation/sound/hd-audio/notes.rst2
-rw-r--r--include/sound/cs35l35.h108
-rw-r--r--include/sound/hda_register.h30
-rw-r--r--include/sound/hdaudio.h28
-rw-r--r--include/sound/soc.h14
-rw-r--r--include/uapi/sound/asound.h4
-rw-r--r--include/uapi/sound/firewire.h10
-rw-r--r--sound/core/timer.c19
-rw-r--r--sound/drivers/vx/vx_core.c4
-rw-r--r--sound/firewire/Kconfig20
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/amdtp-stream-trace.h94
-rw-r--r--sound/firewire/amdtp-stream.c158
-rw-r--r--sound/firewire/amdtp-stream.h16
-rw-r--r--sound/firewire/bebob/bebob_command.c30
-rw-r--r--sound/firewire/digi00x/amdtp-dot.c55
-rw-r--r--sound/firewire/digi00x/digi00x-midi.c208
-rw-r--r--sound/firewire/digi00x/digi00x-transaction.c88
-rw-r--r--sound/firewire/digi00x/digi00x.c13
-rw-r--r--sound/firewire/digi00x/digi00x.h7
-rw-r--r--sound/firewire/fcp.c12
-rw-r--r--sound/firewire/fireface/Makefile3
-rw-r--r--sound/firewire/fireface/amdtp-ff.c155
-rw-r--r--sound/firewire/fireface/ff-hwdep.c191
-rw-r--r--sound/firewire/fireface/ff-midi.c131
-rw-r--r--sound/firewire/fireface/ff-pcm.c409
-rw-r--r--sound/firewire/fireface/ff-proc.c63
-rw-r--r--sound/firewire/fireface/ff-protocol-ff400.c371
-rw-r--r--sound/firewire/fireface/ff-stream.c282
-rw-r--r--sound/firewire/fireface/ff-transaction.c295
-rw-r--r--sound/firewire/fireface/ff.c209
-rw-r--r--sound/firewire/fireface/ff.h146
-rw-r--r--sound/firewire/lib.c141
-rw-r--r--sound/firewire/lib.h54
-rw-r--r--sound/firewire/motu/Makefile6
-rw-r--r--sound/firewire/motu/amdtp-motu-trace.h123
-rw-r--r--sound/firewire/motu/amdtp-motu.c427
-rw-r--r--sound/firewire/motu/motu-hwdep.c198
-rw-r--r--sound/firewire/motu/motu-midi.c169
-rw-r--r--sound/firewire/motu/motu-pcm.c398
-rw-r--r--sound/firewire/motu/motu-proc.c118
-rw-r--r--sound/firewire/motu/motu-protocol-v2.c237
-rw-r--r--sound/firewire/motu/motu-protocol-v3.c311
-rw-r--r--sound/firewire/motu/motu-stream.c381
-rw-r--r--sound/firewire/motu/motu-transaction.c137
-rw-r--r--sound/firewire/motu/motu.c264
-rw-r--r--sound/firewire/motu/motu.h161
-rw-r--r--sound/firewire/oxfw/oxfw-command.c12
-rw-r--r--sound/firewire/tascam/tascam-midi.c13
-rw-r--r--sound/firewire/tascam/tascam-transaction.c142
-rw-r--r--sound/firewire/tascam/tascam.h39
-rw-r--r--sound/hda/ext/hdac_ext_controller.c6
-rw-r--r--sound/hda/hdac_controller.c4
-rw-r--r--sound/hda/hdac_stream.c4
-rw-r--r--sound/isa/es1688/es1688_lib.c2
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c2
-rw-r--r--sound/pci/au88x0/au88x0_core.c3
-rw-r--r--sound/pci/au88x0/au88x0_eq.c6
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c2
-rw-r--r--sound/pci/aw2/aw2-alsa.c2
-rw-r--r--sound/pci/bt87x.c6
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c4
-rw-r--r--sound/pci/cmipci.c6
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c26
-rw-r--r--sound/pci/emu10k1/emu10k1x.c6
-rw-r--r--sound/pci/emu10k1/emumixer.c30
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/ens1370.c4
-rw-r--r--sound/pci/hda/hda_auto_parser.c1
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c9
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/hda_intel.c139
-rw-r--r--sound/pci/hda/patch_ca0132.c10
-rw-r--r--sound/pci/hda/patch_conexant.c81
-rw-r--r--sound/pci/hda/patch_hdmi.c29
-rw-r--r--sound/pci/hda/patch_realtek.c221
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/ews.c4
-rw-r--r--sound/pci/ice1712/ice1712.c30
-rw-r--r--sound/pci/ice1712/ice1724.c20
-rw-r--r--sound/pci/lola/lola_mixer.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c2
-rw-r--r--sound/pci/mixart/mixart_mixer.c6
-rw-r--r--sound/pci/oxygen/oxygen.c6
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c6
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c22
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/via82xx.c6
-rw-r--r--sound/pci/vx222/vx222_ops.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c14
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c2
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c2
-rw-r--r--sound/soc/codecs/Kconfig30
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ak4613.c10
-rw-r--r--sound/soc/codecs/cs35l35.c1580
-rw-r--r--sound/soc/codecs/cs35l35.h294
-rw-r--r--sound/soc/codecs/cs4271.c2
-rw-r--r--sound/soc/codecs/cs53l30.c1
-rw-r--r--sound/soc/codecs/da7213.c13
-rw-r--r--sound/soc/codecs/dio2125.c120
-rw-r--r--sound/soc/codecs/es7134.c116
-rw-r--r--sound/soc/codecs/es8328.c51
-rw-r--r--sound/soc/codecs/hdac_hdmi.c4
-rw-r--r--sound/soc/codecs/max9867.c4
-rw-r--r--sound/soc/codecs/max98927.c841
-rw-r--r--sound/soc/codecs/max98927.h272
-rw-r--r--sound/soc/codecs/nau8540.c1224
-rw-r--r--sound/soc/codecs/nau8540.h310
-rw-r--r--sound/soc/codecs/nau8824.c1831
-rw-r--r--sound/soc/codecs/nau8824.h466
-rw-r--r--sound/soc/codecs/rt5514.c36
-rw-r--r--sound/soc/codecs/rt5645.c10
-rw-r--r--sound/soc/codecs/rt5665.c222
-rw-r--r--sound/soc/codecs/rt5665.h2
-rw-r--r--sound/soc/codecs/rt5670.c21
-rw-r--r--sound/soc/codecs/rt5677.c7
-rw-r--r--sound/soc/codecs/sgtl5000.c19
-rw-r--r--sound/soc/codecs/ssm4567.c9
-rw-r--r--sound/soc/codecs/sta529.c7
-rw-r--r--sound/soc/codecs/tas2552.c6
-rw-r--r--sound/soc/codecs/tlv320aic23.c7
-rw-r--r--sound/soc/codecs/twl6040.c8
-rw-r--r--sound/soc/codecs/uda1380.c7
-rw-r--r--sound/soc/codecs/wm5100.c2
-rw-r--r--sound/soc/codecs/wm8903.c31
-rw-r--r--sound/soc/codecs/wm8960.c195
-rw-r--r--sound/soc/codecs/wm8978.c7
-rw-r--r--sound/soc/codecs/wm_adsp.c324
-rw-r--r--sound/soc/codecs/wm_adsp.h24
-rw-r--r--sound/soc/dwc/Kconfig4
-rw-r--r--sound/soc/dwc/Makefile6
-rw-r--r--sound/soc/dwc/dwc-i2s.c (renamed from sound/soc/dwc/designware_i2s.c)0
-rw-r--r--sound/soc/dwc/dwc-pcm.c (renamed from sound/soc/dwc/designware_pcm.c)3
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c2
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c2
-rw-r--r--sound/soc/fsl/fsl_esai.c5
-rw-r--r--sound/soc/fsl/fsl_ssi.c27
-rw-r--r--sound/soc/fsl/imx-mc13783.c2
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c28
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c2
-rw-r--r--sound/soc/fsl/imx-wm8962.c72
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c2
-rw-r--r--sound/soc/fsl/p1022_rdk.c2
-rw-r--r--sound/soc/fsl/phycore-ac97.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c2
-rw-r--r--sound/soc/generic/simple-card.c43
-rw-r--r--sound/soc/generic/simple-scu-card.c37
-rw-r--r--sound/soc/hisilicon/Kconfig5
-rw-r--r--sound/soc/hisilicon/Makefile1
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.c618
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.h276
-rw-r--r--sound/soc/intel/Kconfig24
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c41
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c4
-rw-r--r--sound/soc/intel/boards/Makefile4
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c5
-rw-r--r--sound/soc/intel/boards/broadwell.c3
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c97
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c3
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c283
-rw-r--r--sound/soc/intel/boards/bytcht_nocodec.c208
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c109
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c6
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c118
-rw-r--r--sound/soc/intel/skylake/skl-messages.c16
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c7
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c118
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c26
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.h2
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h40
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c76
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h17
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c140
-rw-r--r--sound/soc/intel/skylake/skl-sst.c175
-rw-r--r--sound/soc/intel/skylake/skl-topology.c247
-rw-r--r--sound/soc/intel/skylake/skl-topology.h17
-rw-r--r--sound/soc/intel/skylake/skl.c2
-rw-r--r--sound/soc/intel/skylake/skl.h22
-rw-r--r--sound/soc/mediatek/Kconfig10
-rw-r--r--sound/soc/mediatek/mt2701/Makefile1
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c16
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-cs42448.c2
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-wm8960.c176
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-max98090.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c2
-rw-r--r--sound/soc/omap/am3517evm.c2
-rw-r--r--sound/soc/omap/n810.c2
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c2
-rw-r--r--sound/soc/omap/omap-twl4030.c2
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/rx51.c7
-rw-r--r--sound/soc/pxa/brownstone.c2
-rw-r--r--sound/soc/pxa/corgi.c2
-rw-r--r--sound/soc/pxa/e750_wm9705.c2
-rw-r--r--sound/soc/pxa/e800_wm9712.c2
-rw-r--r--sound/soc/pxa/em-x270.c2
-rw-r--r--sound/soc/pxa/hx4700.c2
-rw-r--r--sound/soc/pxa/imote2.c2
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c2
-rw-r--r--sound/soc/pxa/mmp-pcm.c1
-rw-r--r--sound/soc/pxa/mmp-sspa.c1
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c15
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c5
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c8
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c2
-rw-r--r--sound/soc/pxa/raumfeld.c8
-rw-r--r--sound/soc/pxa/spitz.c6
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/z2.c6
-rw-r--r--sound/soc/pxa/zylonite.c2
-rw-r--r--sound/soc/qcom/lpass-apq8016.c12
-rw-r--r--sound/soc/qcom/lpass-cpu.c22
-rw-r--r--sound/soc/qcom/lpass-ipq806x.c6
-rw-r--r--sound/soc/qcom/lpass.h2
-rw-r--r--sound/soc/rockchip/rk3288_hdmi_analog.c3
-rw-r--r--sound/soc/samsung/Kconfig8
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/bells.c1
-rw-r--r--sound/soc/samsung/i2s-regs.h2
-rw-r--r--sound/soc/samsung/i2s.c1
-rw-r--r--sound/soc/samsung/odroid.c219
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c1
-rw-r--r--sound/soc/sh/rcar/adg.c75
-rw-r--r--sound/soc/sh/rcar/core.c111
-rw-r--r--sound/soc/sh/rcar/dvc.c24
-rw-r--r--sound/soc/sh/rcar/rsnd.h55
-rw-r--r--sound/soc/sh/rcar/src.c3
-rw-r--r--sound/soc/sh/rcar/ssi.c9
-rw-r--r--sound/soc/sirf/sirf-audio-port.c1
-rw-r--r--sound/soc/sirf/sirf-audio.c1
-rw-r--r--sound/soc/sirf/sirf-usp.c3
-rw-r--r--sound/soc/soc-core.c27
-rw-r--r--sound/soc/soc-jack.c48
-rw-r--r--sound/soc/soc-topology.c5
-rw-r--r--sound/soc/sti/uniperif_player.c2
-rw-r--r--sound/soc/stm/Kconfig8
-rw-r--r--sound/soc/stm/Makefile6
-rw-r--r--sound/soc/stm/stm32_sai.c115
-rw-r--r--sound/soc/stm/stm32_sai.h200
-rw-r--r--sound/soc/stm/stm32_sai_sub.c884
-rw-r--r--sound/soc/sunxi/sun8i-codec-analog.c168
-rw-r--r--sound/soc/sunxi/sun8i-codec.c10
-rw-r--r--sound/soc/tegra/tegra20_ac97.c1
-rw-r--r--sound/soc/tegra/tegra20_das.c2
-rw-r--r--sound/soc/tegra/tegra20_i2s.c1
-rw-r--r--sound/soc/tegra/tegra20_spdif.c5
-rw-r--r--sound/soc/tegra/tegra30_ahub.c5
-rw-r--r--sound/soc/tegra/tegra30_i2s.c1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c4
-rw-r--r--sound/soc/tegra/tegra_max98090.c4
-rw-r--r--sound/soc/tegra/tegra_rt5640.c4
-rw-r--r--sound/soc/tegra/tegra_sgtl5000.c4
-rw-r--r--sound/soc/tegra/tegra_wm8753.c4
-rw-r--r--sound/soc/tegra/tegra_wm8903.c4
-rw-r--r--sound/soc/tegra/tegra_wm9712.c4
-rw-r--r--sound/soc/tegra/trimslice.c4
-rw-r--r--sound/soc/txx9/txx9aclc.c5
-rw-r--r--sound/soc/ux500/mop500.c4
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c4
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c1
-rw-r--r--sound/soc/zte/Kconfig8
-rw-r--r--sound/soc/zte/Makefile1
-rw-r--r--sound/soc/zte/zx-tdm.c461
-rw-r--r--sound/synth/emux/emux_oss.c4
-rw-r--r--sound/usb/card.c6
-rw-r--r--sound/usb/line6/pcm.c2
-rw-r--r--sound/usb/line6/pod.c2
-rw-r--r--sound/usb/line6/toneport.c4
-rw-r--r--sound/usb/midi.c2
-rw-r--r--sound/usb/mixer.c6
-rw-r--r--sound/usb/mixer_scarlett.c12
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
306 files changed, 19287 insertions, 2691 deletions
diff --git a/Documentation/devicetree/bindings/sound/cs35l35.txt b/Documentation/devicetree/bindings/sound/cs35l35.txt
new file mode 100644
index 000000000000..016b768bc722
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs35l35.txt
@@ -0,0 +1,180 @@
1CS35L35 Boosted Speaker Amplifier
2
3Required properties:
4
5 - compatible : "cirrus,cs35l35"
6
7 - reg : the I2C address of the device for I2C
8
9 - VA-supply, VP-supply : power supplies for the device,
10 as covered in
11 Documentation/devicetree/bindings/regulator/regulator.txt.
12
13 - interrupt-parent : Specifies the phandle of the interrupt controller to
14 which the IRQs from CS35L35 are delivered to.
15 - interrupts : IRQ line info CS35L35.
16 (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
17 for further information relating to interrupt properties)
18
19Optional properties:
20 - reset-gpios : gpio used to reset the amplifier
21
22 - cirrus,stereo-config : Boolean to determine if there are 2 AMPs for a
23 Stereo configuration
24
25 - cirrus,audio-channel : Set Location of Audio Signal on Serial Port
26 0 = Data Packet received on Left I2S Channel
27 1 = Data Packet received on Right I2S Channel
28
29 - cirrus,advisory-channel : Set Location of Advisory Signal on Serial Port
30 0 = Data Packet received on Left I2S Channel
31 1 = Data Packet received on Right I2S Channel
32
33 - cirrus,shared-boost : Boolean to enable ClassH tracking of Advisory Signal
34 if 2 Devices share Boost BST_CTL
35
36 - cirrus,external-boost : Boolean to specify the device is using an external
37 boost supply, note that sharing a boost from another cs35l35 would constitute
38 using an external supply for the slave device
39
40 - cirrus,sp-drv-strength : Value for setting the Serial Port drive strength
41 Table 3-10 of the datasheet lists drive-strength specifications
42 0 = 1x (Default)
43 1 = .5x
44 - cirrus,sp-drv-unused : Determines how unused slots should be driven on the
45 Serial Port.
46 0 - Hi-Z
47 2 - Drive 0's (Default)
48 3 - Drive 1's
49
50 - cirrus,bst-pdn-fet-on : Boolean to determine if the Boost PDN control
51 powers down with a rectification FET On or Off. If VSPK is supplied
52 externally then FET is off.
53
54 - cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the boost
55 converter's output voltage in mV. The range is from 2600mV to 9000mV with
56 increments of 100mV.
57 (Default) VP
58
59 - cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA.
60 Configures the peak current by monitoring the current through the boost FET.
61 Range starts at 1680mA and goes to a maximum of 4480mA with increments of
62 110mA.
63 (Default) 2.46 Amps
64
65 - cirrus,amp-gain-zc : Boolean to determine if to use Amplifier gain-change
66 zero-cross
67
68Optional H/G Algorithm sub-node:
69
70 The cs35l35 node can have a single "cirrus,classh-internal-algo" sub-node
71 that will disable automatic control of the internal H/G Algorithm.
72
73 It is strongly recommended that the Datasheet be referenced when adjusting
74 or using these Class H Algorithm controls over the internal Algorithm.
75 Serious damage can occur to the Device and surrounding components.
76
77 - cirrus,classh-internal-algo : Sub-node for the Internal Class H Algorithm
78 See Section 4.3 Internal Class H Algorithm in the Datasheet.
79 If not used, the device manages the ClassH Algorithm internally.
80
81Optional properties for the "cirrus,classh-internal-algo" Sub-node
82
83 Section 7.29 Class H Control
84 - cirrus,classh-bst-overide : Boolean
85 - cirrus,classh-bst-max-limit
86 - cirrus,classh-mem-depth
87
88 Section 7.30 Class H Headroom Control
89 - cirrus,classh-headroom
90
91 Section 7.31 Class H Release Rate
92 - cirrus,classh-release-rate
93
94 Section 7.32 Class H Weak FET Drive Control
95 - cirrus,classh-wk-fet-disable
96 - cirrus,classh-wk-fet-delay
97 - cirrus,classh-wk-fet-thld
98
99 Section 7.34 Class H VP Control
100 - cirrus,classh-vpch-auto
101 - cirrus,classh-vpch-rate
102 - cirrus,classh-vpch-man
103
104Optional Monitor Signal Format sub-node:
105
106 The cs35l35 node can have a single "cirrus,monitor-signal-format" sub-node
107 for adjusting the Depth, Location and Frame of the Monitoring Signals
108 for Algorithms.
109
110 See Sections 4.8.2 through 4.8.4 Serial-Port Control in the Datasheet
111
112 -cirrus,monitor-signal-format : Sub-node for the Monitor Signaling Formating
113 on the I2S Port. Each of the 3 8 bit values in the array contain the settings
114 for depth, location, and frame.
115
116 If not used, the defaults for the 6 monitor signals is used.
117
118 Sections 7.44 - 7.53 lists values for the depth, location, and frame
119 for each monitoring signal.
120
121 - cirrus,imon : 4 8 bit values to set the depth, location, frame and ADC
122 scale of the IMON monitor signal.
123
124 - cirrus,vmon : 3 8 bit values to set the depth, location, and frame
125 of the VMON monitor signal.
126
127 - cirrus,vpmon : 3 8 bit values to set the depth, location, and frame
128 of the VPMON monitor signal.
129
130 - cirrus,vbstmon : 3 8 bit values to set the depth, location, and frame
131 of the VBSTMON monitor signal
132
133 - cirrus,vpbrstat : 3 8 bit values to set the depth, location, and frame
134 of the VPBRSTAT monitor signal
135
136 - cirrus,zerofill : 3 8 bit values to set the depth, location, and frame\
137 of the ZEROFILL packet in the monitor signal
138
139Example:
140
141cs35l35: cs35l35@20 {
142 compatible = "cirrus,cs35l35";
143 reg = <0x20>;
144 VA-supply = <&dummy_vreg>;
145 VP-supply = <&dummy_vreg>;
146 reset-gpios = <&axi_gpio 54 0>;
147 interrupt-parent = <&gpio8>;
148 interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
149 cirrus,boost-ctl-millivolt = <9000>;
150
151 cirrus,stereo-config;
152 cirrus,audio-channel = <0x00>;
153 cirrus,advisory-channel = <0x01>;
154 cirrus,shared-boost;
155
156 cirrus,classh-internal-algo {
157 cirrus,classh-bst-overide;
158 cirrus,classh-bst-max-limit = <0x01>;
159 cirrus,classh-mem-depth = <0x01>;
160 cirrus,classh-release-rate = <0x08>;
161 cirrus,classh-headroom-millivolt = <0x0B>;
162 cirrus,classh-wk-fet-disable = <0x01>;
163 cirrus,classh-wk-fet-delay = <0x04>;
164 cirrus,classh-wk-fet-thld = <0x01>;
165 cirrus,classh-vpch-auto = <0x01>;
166 cirrus,classh-vpch-rate = <0x02>;
167 cirrus,classh-vpch-man = <0x05>;
168 };
169
170 /* Depth, Location, Frame */
171 cirrus,monitor-signal-format {
172 cirrus,imon = /bits/ 8 <0x03 0x00 0x01>;
173 cirrus,vmon = /bits/ 8 <0x03 0x00 0x00>;
174 cirrus,vpmon = /bits/ 8 <0x03 0x04 0x00>;
175 cirrus,vbstmon = /bits/ 8 <0x03 0x04 0x01>;
176 cirrus,vpbrstat = /bits/ 8 <0x00 0x04 0x00>;
177 cirrus,zerofill = /bits/ 8 <0x00 0x00 0x00>;
178 };
179
180};
diff --git a/Documentation/devicetree/bindings/sound/dioo,dio2125.txt b/Documentation/devicetree/bindings/sound/dioo,dio2125.txt
new file mode 100644
index 000000000000..63dbfe0f11d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/dioo,dio2125.txt
@@ -0,0 +1,12 @@
1DIO2125 Audio Driver
2
3Required properties:
4- compatible : "dioo,dio2125"
5- enable-gpios : the gpio connected to the enable pin of the dio2125
6
7Example:
8
9amp: analog-amplifier {
10 compatible = "dioo,dio2125";
11 enable-gpios = <&gpio GPIOH_3 0>;
12};
diff --git a/Documentation/devicetree/bindings/sound/everest,es7134.txt b/Documentation/devicetree/bindings/sound/everest,es7134.txt
new file mode 100644
index 000000000000..5495a3cb8b7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/everest,es7134.txt
@@ -0,0 +1,10 @@
1ES7134 i2s DA converter
2
3Required properties:
4- compatible : "everest,es7134" or "everest,es7144"
5
6Example:
7
8i2s_codec: external-codec {
9 compatible = "everest,es7134";
10};
diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 5b76be45d18b..d415888e1316 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -20,24 +20,8 @@ Required properties:
20 have. 20 have.
21- interrupt-parent: The phandle for the interrupt controller that 21- interrupt-parent: The phandle for the interrupt controller that
22 services interrupts for this device. 22 services interrupts for this device.
23- fsl,playback-dma: Phandle to a node for the DMA channel to use for
24 playback of audio. This is typically dictated by SOC
25 design. See the notes below.
26- fsl,capture-dma: Phandle to a node for the DMA channel to use for
27 capture (recording) of audio. This is typically dictated
28 by SOC design. See the notes below.
29- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs. 23- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs.
30 This number is the maximum allowed value for SFCSR[TFWM0]. 24 This number is the maximum allowed value for SFCSR[TFWM0].
31- fsl,ssi-asynchronous:
32 If specified, the SSI is to be programmed in asynchronous
33 mode. In this mode, pins SRCK, STCK, SRFS, and STFS must
34 all be connected to valid signals. In synchronous mode,
35 SRCK and SRFS are ignored. Asynchronous mode allows
36 playback and capture to use different sample sizes and
37 sample rates. Some drivers may require that SRCK and STCK
38 be connected together, and SRFS and STFS be connected
39 together. This would still allow different sample sizes,
40 but not different sample rates.
41 - clocks: "ipg" - Required clock for the SSI unit 25 - clocks: "ipg" - Required clock for the SSI unit
42 "baud" - Required clock for SSI master mode. Otherwise this 26 "baud" - Required clock for SSI master mode. Otherwise this
43 clock is not used 27 clock is not used
@@ -61,6 +45,24 @@ Optional properties:
61- fsl,mode: The operating mode for the AC97 interface only. 45- fsl,mode: The operating mode for the AC97 interface only.
62 "ac97-slave" - AC97 mode, SSI is clock slave 46 "ac97-slave" - AC97 mode, SSI is clock slave
63 "ac97-master" - AC97 mode, SSI is clock master 47 "ac97-master" - AC97 mode, SSI is clock master
48- fsl,ssi-asynchronous:
49 If specified, the SSI is to be programmed in asynchronous
50 mode. In this mode, pins SRCK, STCK, SRFS, and STFS must
51 all be connected to valid signals. In synchronous mode,
52 SRCK and SRFS are ignored. Asynchronous mode allows
53 playback and capture to use different sample sizes and
54 sample rates. Some drivers may require that SRCK and STCK
55 be connected together, and SRFS and STFS be connected
56 together. This would still allow different sample sizes,
57 but not different sample rates.
58- fsl,playback-dma: Phandle to a node for the DMA channel to use for
59 playback of audio. This is typically dictated by SOC
60 design. See the notes below.
61 Only used on Power Architecture.
62- fsl,capture-dma: Phandle to a node for the DMA channel to use for
63 capture (recording) of audio. This is typically dictated
64 by SOC design. See the notes below.
65 Only used on Power Architecture.
64 66
65Child 'codec' node required properties: 67Child 'codec' node required properties:
66- compatible: Compatible list, contains the name of the codec 68- compatible: Compatible list, contains the name of the codec
diff --git a/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt b/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt
new file mode 100644
index 000000000000..7a296784eb37
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt
@@ -0,0 +1,42 @@
1* Hisilicon 6210 i2s controller
2
3Required properties:
4
5- compatible: should be one of the following:
6 - "hisilicon,hi6210-i2s"
7- reg: physical base address of the i2s controller unit and length of
8 memory mapped region.
9- interrupts: should contain the i2s interrupt.
10- clocks: a list of phandle + clock-specifier pairs, one for each entry
11 in clock-names.
12- clock-names: should contain following:
13 - "dacodec"
14 - "i2s-base"
15- dmas: DMA specifiers for tx dma. See the DMA client binding,
16 Documentation/devicetree/bindings/dma/dma.txt
17- dma-names: should be "tx" and "rx"
18- hisilicon,sysctrl-syscon: phandle to sysctrl syscon
19- #sound-dai-cells: Should be set to 1 (for multi-dai)
20 - The dai cell indexes reference the following interfaces:
21 0: S2 interface
22 (Currently that is the only one available, but more may be
23 supported in the future)
24
25Example for the hi6210 i2s controller:
26
27i2s0: i2s@f7118000{
28 compatible = "hisilicon,hi6210-i2s";
29 reg = <0x0 0xf7118000 0x0 0x8000>; /* i2s unit */
30 interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* 155 "DigACodec_intr"-32 */
31 clocks = <&sys_ctrl HI6220_DACODEC_PCLK>,
32 <&sys_ctrl HI6220_BBPPLL0_DIV>;
33 clock-names = "dacodec", "i2s-base";
34 dmas = <&dma0 15 &dma0 14>;
35 dma-names = "rx", "tx";
36 hisilicon,sysctrl-syscon = <&sys_ctrl>;
37 #sound-dai-cells = <1>;
38};
39
40Then when referencing the i2s controller:
41 sound-dai = <&i2s0 0>; /* index 0 => S2 interface */
42
diff --git a/Documentation/devicetree/bindings/sound/max98925.txt b/Documentation/devicetree/bindings/sound/max98925.txt
deleted file mode 100644
index 27be63e2aa0d..000000000000
--- a/Documentation/devicetree/bindings/sound/max98925.txt
+++ /dev/null
@@ -1,22 +0,0 @@
1max98925 audio CODEC
2
3This device supports I2C.
4
5Required properties:
6
7 - compatible : "maxim,max98925"
8
9 - vmon-slot-no : slot number used to send voltage information
10
11 - imon-slot-no : slot number used to send current information
12
13 - reg : the I2C address of the device for I2C
14
15Example:
16
17codec: max98925@1a {
18 compatible = "maxim,max98925";
19 vmon-slot-no = <0>;
20 imon-slot-no = <2>;
21 reg = <0x1a>;
22};
diff --git a/Documentation/devicetree/bindings/sound/max98926.txt b/Documentation/devicetree/bindings/sound/max98926.txt
deleted file mode 100644
index 0b7f4e4d5f9a..000000000000
--- a/Documentation/devicetree/bindings/sound/max98926.txt
+++ /dev/null
@@ -1,32 +0,0 @@
1max98926 audio CODEC
2
3This device supports I2C.
4
5Required properties:
6
7 - compatible : "maxim,max98926"
8
9 - vmon-slot-no : slot number used to send voltage information
10 or in inteleave mode this will be used as
11 interleave slot.
12
13 - imon-slot-no : slot number used to send current information
14
15 - interleave-mode : When using two MAX98926 in a system it is
16 possible to create ADC data that that will
17 overflow the frame size. Digital Audio Interleave
18 mode provides a means to output VMON and IMON data
19 from two devices on a single DOUT line when running
20 smaller frames sizes such as 32 BCLKS per LRCLK or
21 48 BCLKS per LRCLK.
22
23 - reg : the I2C address of the device for I2C
24
25Example:
26
27codec: max98926@1a {
28 compatible = "maxim,max98926";
29 vmon-slot-no = <0>;
30 imon-slot-no = <2>;
31 reg = <0x1a>;
32};
diff --git a/Documentation/devicetree/bindings/sound/max9892x.txt b/Documentation/devicetree/bindings/sound/max9892x.txt
new file mode 100644
index 000000000000..f6171591ddc6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/max9892x.txt
@@ -0,0 +1,41 @@
1Maxim Integrated MAX98925/MAX98926/MAX98927 Speaker Amplifier
2
3This device supports I2C.
4
5Required properties:
6
7 - compatible : should be one of the following
8 - "maxim,max98925"
9 - "maxim,max98926"
10 - "maxim,max98927"
11
12 - vmon-slot-no : slot number used to send voltage information
13 or in inteleave mode this will be used as
14 interleave slot.
15 MAX98925/MAX98926 slot range : 0 ~ 30, Default : 0
16 MAX98927 slot range : 0 ~ 15, Default : 0
17
18 - imon-slot-no : slot number used to send current information
19 MAX98925/MAX98926 slot range : 0 ~ 30, Default : 0
20 MAX98927 slot range : 0 ~ 15, Default : 0
21
22 - interleave-mode : When using two MAX9892X in a system it is
23 possible to create ADC data that that will
24 overflow the frame size. Digital Audio Interleave
25 mode provides a means to output VMON and IMON data
26 from two devices on a single DOUT line when running
27 smaller frames sizes such as 32 BCLKS per LRCLK or
28 48 BCLKS per LRCLK.
29 Range : 0 (off), 1 (on), Default : 0
30
31 - reg : the I2C address of the device for I2C
32
33Example:
34
35codec: max98927@3a {
36 compatible = "maxim,max98927";
37 vmon-slot-no = <0>;
38 imon-slot-no = <1>;
39 interleave-mode = <0>;
40 reg = <0x3a>;
41};
diff --git a/Documentation/devicetree/bindings/sound/mt2701-wm8960.txt b/Documentation/devicetree/bindings/sound/mt2701-wm8960.txt
new file mode 100644
index 000000000000..809b609ea9d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt2701-wm8960.txt
@@ -0,0 +1,24 @@
1MT2701 with WM8960 CODEC
2
3Required properties:
4- compatible: "mediatek,mt2701-wm8960-machine"
5- mediatek,platform: the phandle of MT2701 ASoC platform
6- audio-routing: a list of the connections between audio
7- mediatek,audio-codec: the phandles of wm8960 codec
8- pinctrl-names: Should contain only one value - "default"
9- pinctrl-0: Should specify pin control groups used for this controller.
10
11Example:
12
13 sound:sound {
14 compatible = "mediatek,mt2701-wm8960-machine";
15 mediatek,platform = <&afe>;
16 audio-routing =
17 "Headphone", "HP_L",
18 "Headphone", "HP_R",
19 "LINPUT1", "AMIC",
20 "RINPUT1", "AMIC";
21 mediatek,audio-codec = <&wm8960>;
22 pinctrl-names = "default";
23 pinctrl-0 = <&aud_pins_default>;
24 };
diff --git a/Documentation/devicetree/bindings/sound/nau8824.txt b/Documentation/devicetree/bindings/sound/nau8824.txt
new file mode 100644
index 000000000000..e0058b97e49a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nau8824.txt
@@ -0,0 +1,88 @@
1Nuvoton NAU8824 audio codec
2
3This device supports I2C only.
4
5Required properties:
6 - compatible : Must be "nuvoton,nau8824"
7
8 - reg : the I2C address of the device. This is either 0x1a (CSB=0) or 0x1b (CSB=1).
9
10Optional properties:
11 - nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
12
13 - nuvoton,vref-impedance: VREF Impedance selection
14 0 - Open
15 1 - 25 kOhm
16 2 - 125 kOhm
17 3 - 2.5 kOhm
18
19 - nuvoton,micbias-voltage: Micbias voltage level.
20 0 - VDDA
21 1 - VDDA
22 2 - VDDA * 1.1
23 3 - VDDA * 1.2
24 4 - VDDA * 1.3
25 5 - VDDA * 1.4
26 6 - VDDA * 1.53
27 7 - VDDA * 1.53
28
29 - nuvoton,sar-threshold-num: Number of buttons supported
30 - nuvoton,sar-threshold: Impedance threshold for each button. Array that contains up to 8 buttons configuration. SAR value is calculated as
31 SAR = 255 * MICBIAS / SAR_VOLTAGE * R / (2000 + R)
32 where MICBIAS is configured by 'nuvoton,micbias-voltage', SAR_VOLTAGE is configured by 'nuvoton,sar-voltage', R - button impedance.
33 Refer datasheet section 10.2 for more information about threshold calculation.
34
35 - nuvoton,sar-hysteresis: Button impedance measurement hysteresis.
36
37 - nuvoton,sar-voltage: Reference voltage for button impedance measurement.
38 0 - VDDA
39 1 - VDDA
40 2 - VDDA * 1.1
41 3 - VDDA * 1.2
42 4 - VDDA * 1.3
43 5 - VDDA * 1.4
44 6 - VDDA * 1.53
45 7 - VDDA * 1.53
46
47 - nuvoton,sar-compare-time: SAR compare time
48 0 - 500 ns
49 1 - 1 us
50 2 - 2 us
51 3 - 4 us
52
53 - nuvoton,sar-sampling-time: SAR sampling time
54 0 - 2 us
55 1 - 4 us
56 2 - 8 us
57 3 - 16 us
58
59 - nuvoton,short-key-debounce: Button short key press debounce time.
60 0 - 30 ms
61 1 - 50 ms
62 2 - 100 ms
63
64 - nuvoton,jack-eject-debounce: Jack ejection debounce time.
65 0 - 0 ms
66 1 - 1 ms
67 2 - 10 ms
68
69
70Example:
71
72 headset: nau8824@1a {
73 compatible = "nuvoton,nau8824";
74 reg = <0x1a>;
75 interrupt-parent = <&gpio>;
76 interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>;
77 nuvoton,vref-impedance = <2>;
78 nuvoton,micbias-voltage = <6>;
79 // Setup 4 buttons impedance according to Android specification
80 nuvoton,sar-threshold-num = <4>;
81 nuvoton,sar-threshold = <0xc 0x1e 0x38 0x60>;
82 nuvoton,sar-hysteresis = <0>;
83 nuvoton,sar-voltage = <6>;
84 nuvoton,sar-compare-time = <1>;
85 nuvoton,sar-sampling-time = <1>;
86 nuvoton,short-key-debounce = <0>;
87 nuvoton,jack-eject-debounce = <1>;
88 };
diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
index a6600f6dea64..206aba1b34bb 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
@@ -9,6 +9,7 @@ Required properties:
9 - "rockchip,rk3066-i2s": for rk3066 9 - "rockchip,rk3066-i2s": for rk3066
10 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 10 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
11 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 11 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288
12 - "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368
12 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 13 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399
13- reg: physical base address of the controller and length of memory mapped 14- reg: physical base address of the controller and length of memory mapped
14 region. 15 region.
diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.txt b/Documentation/devicetree/bindings/sound/samsung,odroid.txt
new file mode 100644
index 000000000000..c1ac70cb0afb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/samsung,odroid.txt
@@ -0,0 +1,57 @@
1Samsung Exynos Odroid XU3/XU4 audio complex with MAX98090 codec
2
3Required properties:
4
5 - compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
6 "samsung,odroidxu4-audio" - for Odroid XU4 board
7 - model - the user-visible name of this sound complex
8 - 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
9 controller
10 - 'codec' subnode with a 'sound-dai' property containing list of phandles
11 to the CODEC nodes, first entry must be corresponding to the MAX98090
12 CODEC and the second entry must be the phandle of the HDMI IP block node
13 - clocks - should contain entries matching clock names in the clock-names
14 property
15 - clock-names - should contain following entries:
16 - "epll" - indicating the EPLL output clock
17 - "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller
18 - samsung,audio-widgets - this property specifies off-codec audio elements
19 like headphones or speakers, for details see widgets.txt
20 - samsung,audio-routing - a list of the connections between audio
21 components; each entry is a pair of strings, the first being the
22 connection's sink, the second being the connection's source;
23 valid names for sources and sinks are the MAX98090's pins (as
24 documented in its binding), and the jacks on the board
25
26 For Odroid X2:
27 "Headphone Jack", "Mic Jack", "DMIC"
28
29 For Odroid U3, XU3:
30 "Headphone Jack", "Speakers"
31
32 For Odroid XU4:
33 no entries
34
35Example:
36
37sound {
38 compatible = "samsung,odroidxu3-audio";
39 samsung,cpu-dai = <&i2s0>;
40 samsung,codec-dai = <&max98090>;
41 model = "Odroid-XU3";
42 samsung,audio-routing =
43 "Headphone Jack", "HPL",
44 "Headphone Jack", "HPR",
45 "IN1", "Mic Jack",
46 "Mic Jack", "MICBIAS";
47
48 clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>;
49 clock-names = "epll", "sclk_i2s";
50
51 cpu {
52 sound-dai = <&i2s0 0>;
53 };
54 codec {
55 sound-dai = <&hdmi>, <&max98090>;
56 };
57};
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
index 5666da7b8605..7a73a9d62015 100644
--- a/Documentation/devicetree/bindings/sound/sgtl5000.txt
+++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
@@ -26,6 +26,15 @@ Optional properties:
26 If this node is not mentioned or the value is unknown, then 26 If this node is not mentioned or the value is unknown, then
27 the value is set to 1.25V. 27 the value is set to 1.25V.
28 28
29- lrclk-strength: the LRCLK pad strength. Possible values are:
300, 1, 2 and 3 as per the table below:
31
32VDDIO 1.8V 2.5V 3.3V
330 = Disable
341 = 1.66 mA 2.87 mA 4.02 mA
352 = 3.33 mA 5.74 mA 8.03 mA
363 = 4.99 mA 8.61 mA 12.05 mA
37
29Example: 38Example:
30 39
31codec: sgtl5000@0a { 40codec: sgtl5000@0a {
diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.txt b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt
new file mode 100644
index 000000000000..c59a3d779e06
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt
@@ -0,0 +1,89 @@
1STMicroelectronics STM32 Serial Audio Interface (SAI).
2
3The SAI interface (Serial Audio Interface) offers a wide set of audio protocols
4as I2S standards, LSB or MSB-justified, PCM/DSP, TDM, and AC'97.
5The SAI contains two independent audio sub-blocks. Each sub-block has
6its own clock generator and I/O lines controller.
7
8Required properties:
9 - compatible: Should be "st,stm32f4-sai"
10 - reg: Base address and size of SAI common register set.
11 - clocks: Must contain phandle and clock specifier pairs for each entry
12 in clock-names.
13 - clock-names: Must contain "x8k" and "x11k"
14 "x8k": SAI parent clock for sampling rates multiple of 8kHz.
15 "x11k": SAI parent clock for sampling rates multiple of 11.025kHz.
16 - interrupts: cpu DAI interrupt line shared by SAI sub-blocks
17
18Optional properties:
19 - resets: Reference to a reset controller asserting the SAI
20
21SAI subnodes:
22Two subnodes corresponding to SAI sub-block instances A et B can be defined.
23Subnode can be omitted for unsused sub-block.
24
25SAI subnodes required properties:
26 - compatible: Should be "st,stm32-sai-sub-a" or "st,stm32-sai-sub-b"
27 for SAI sub-block A or B respectively.
28 - reg: Base address and size of SAI sub-block register set.
29 - clocks: Must contain one phandle and clock specifier pair
30 for sai_ck which feeds the internal clock generator.
31 - clock-names: Must contain "sai_ck".
32 - dmas: see Documentation/devicetree/bindings/dma/stm32-dma.txt
33 - dma-names: identifier string for each DMA request line
34 "tx": if sai sub-block is configured as playback DAI
35 "rx": if sai sub-block is configured as capture DAI
36 - pinctrl-names: should contain only value "default"
37 - pinctrl-0: see Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt
38
39Example:
40sound_card {
41 compatible = "audio-graph-card";
42 dais = <&sai1b_port>;
43};
44
45sai1: sai1@40015800 {
46 compatible = "st,stm32f4-sai";
47 #address-cells = <1>;
48 #size-cells = <1>;
49 ranges;
50 reg = <0x40015800 0x4>;
51 clocks = <&rcc 1 CLK_SAIQ_PDIV>, <&rcc 1 CLK_I2SQ_PDIV>;
52 clock-names = "x8k", "x11k";
53 interrupts = <87>;
54
55 sai1b: audio-controller@40015824 {
56 #sound-dai-cells = <0>;
57 compatible = "st,stm32-sai-sub-b";
58 reg = <0x40015824 0x1C>;
59 clocks = <&rcc 1 CLK_SAI2>;
60 clock-names = "sai_ck";
61 dmas = <&dma2 5 0 0x400 0x0>;
62 dma-names = "tx";
63 pinctrl-names = "default";
64 pinctrl-0 = <&pinctrl_sai1b>;
65
66 ports {
67 #address-cells = <1>;
68 #size-cells = <0>;
69
70 sai1b_port: port@0 {
71 reg = <0>;
72 cpu_endpoint: endpoint {
73 remote-endpoint = <&codec_endpoint>;
74 audio-graph-card,format = "i2s";
75 audio-graph-card,bitclock-master = <&codec_endpoint>;
76 audio-graph-card,frame-master = <&codec_endpoint>;
77 };
78 };
79 };
80 };
81};
82
83audio-codec {
84 codec_port: port {
85 codec_endpoint: endpoint {
86 remote-endpoint = <&cpu_endpoint>;
87 };
88 };
89};
diff --git a/Documentation/devicetree/bindings/sound/tas2552.txt b/Documentation/devicetree/bindings/sound/tas2552.txt
index c49992c0b62a..2d71eb05c1d3 100644
--- a/Documentation/devicetree/bindings/sound/tas2552.txt
+++ b/Documentation/devicetree/bindings/sound/tas2552.txt
@@ -5,7 +5,8 @@ The tas2552 serial control bus communicates through I2C protocols
5Required properties: 5Required properties:
6 - compatible - One of: 6 - compatible - One of:
7 "ti,tas2552" - TAS2552 7 "ti,tas2552" - TAS2552
8 - reg - I2C slave address 8 - reg - I2C slave address: it can be 0x40 if ADDR pin is 0
9 or 0x41 if ADDR pin is 1.
9 - supply-*: Required supply regulators are: 10 - supply-*: Required supply regulators are:
10 "vbat" battery voltage 11 "vbat" battery voltage
11 "iovdd" I/O Voltage 12 "iovdd" I/O Voltage
@@ -14,17 +15,20 @@ Required properties:
14Optional properties: 15Optional properties:
15 - enable-gpio - gpio pin to enable/disable the device 16 - enable-gpio - gpio pin to enable/disable the device
16 17
17tas2552 can receive it's reference clock via MCLK, BCLK, IVCLKIN pin or use the 18tas2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or use the
18internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL, the PDM 19internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL, the PDM
19reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK. 20reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK.
20For system integration the dt-bindings/sound/tas2552.h header file provides 21For system integration the dt-bindings/sound/tas2552.h header file provides
21defined values to selct and configure the PLL and PDM reference clocks. 22defined values to select and configure the PLL and PDM reference clocks.
22 23
23Example: 24Example:
24 25
25tas2552: tas2552@41 { 26tas2552: tas2552@41 {
26 compatible = "ti,tas2552"; 27 compatible = "ti,tas2552";
27 reg = <0x41>; 28 reg = <0x41>;
29 vbat-supply = <&reg_vbat>;
30 iovdd-supply = <&reg_iovdd>;
31 avdd-supply = <&reg_avdd>;
28 enable-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>; 32 enable-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
29}; 33};
30 34
diff --git a/Documentation/devicetree/bindings/sound/wm8903.txt b/Documentation/devicetree/bindings/sound/wm8903.txt
index 94ec32c194bb..afc51caf1137 100644
--- a/Documentation/devicetree/bindings/sound/wm8903.txt
+++ b/Documentation/devicetree/bindings/sound/wm8903.txt
@@ -28,6 +28,14 @@ Optional properties:
28 performed. If any entry has the value 0xffffffff, that GPIO's 28 performed. If any entry has the value 0xffffffff, that GPIO's
29 configuration will not be modified. 29 configuration will not be modified.
30 30
31 - AVDD-supply : Analog power supply regulator on the AVDD pin.
32
33 - CPVDD-supply : Charge pump supply regulator on the CPVDD pin.
34
35 - DBVDD-supply : Digital buffer supply regulator for the DBVDD pin.
36
37 - DCVDD-supply : Digital core supply regulator for the DCVDD pin.
38
31Pins on the device (for linking into audio routes): 39Pins on the device (for linking into audio routes):
32 40
33 * IN1L 41 * IN1L
@@ -54,6 +62,11 @@ codec: wm8903@1a {
54 reg = <0x1a>; 62 reg = <0x1a>;
55 interrupts = < 347 >; 63 interrupts = < 347 >;
56 64
65 AVDD-supply = <&fooreg_a>;
66 CPVDD-supply = <&fooreg_b>;
67 DBVDD-supply = <&fooreg_c>;
68 DCVDC-supply = <&fooreg_d>;
69
57 gpio-controller; 70 gpio-controller;
58 #gpio-cells = <2>; 71 #gpio-cells = <2>;
59 72
diff --git a/Documentation/devicetree/bindings/sound/zte,tdm.txt b/Documentation/devicetree/bindings/sound/zte,tdm.txt
new file mode 100644
index 000000000000..2a07ca655264
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/zte,tdm.txt
@@ -0,0 +1,30 @@
1ZTE TDM DAI driver
2
3Required properties:
4
5- compatible : should be one of the following.
6 * zte,zx296718-tdm
7- reg : physical base address of the controller and length of memory mapped
8 region.
9- clocks : Pairs of phandle and specifier referencing the controller's clocks.
10- clock-names: "wclk" for the wclk.
11 "pclk" for the pclk.
12-#clock-cells: should be 1.
13- zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling
14 the dma. includes:
15 phandle of sysctrl.
16 register offset in sysctrl for control dma.
17 mask of the register that be written to sysctrl.
18
19Example:
20
21 tdm: tdm@1487000 {
22 compatible = "zte,zx296718-tdm";
23 reg = <0x01487000 0x1000>;
24 clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>;
25 clock-names = "wclk", "pclk";
26 #clock-cells = <1>;
27 pinctrl-names = "default";
28 pinctrl-0 = <&tdm_global_pin>;
29 zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>;
30 };
diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst
index 9eeb9b468706..f59c3cdbfaf4 100644
--- a/Documentation/sound/hd-audio/notes.rst
+++ b/Documentation/sound/hd-audio/notes.rst
@@ -494,6 +494,8 @@ add_hp_mic (bool)
494hp_mic_detect (bool) 494hp_mic_detect (bool)
495 enable/disable the hp/mic shared input for a single built-in mic 495 enable/disable the hp/mic shared input for a single built-in mic
496 case; default true 496 case; default true
497vmaster (bool)
498 enable/disable the virtual Master control; default true
497mixer_nid (int) 499mixer_nid (int)
498 specifies the widget NID of the analog-loopback mixer 500 specifies the widget NID of the analog-loopback mixer
499 501
diff --git a/include/sound/cs35l35.h b/include/sound/cs35l35.h
new file mode 100644
index 000000000000..29da899e17e4
--- /dev/null
+++ b/include/sound/cs35l35.h
@@ -0,0 +1,108 @@
1/*
2 * linux/sound/cs35l35.h -- Platform data for CS35l35
3 *
4 * Copyright (c) 2016 Cirrus Logic Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __CS35L35_H
12#define __CS35L35_H
13
14struct classh_cfg {
15 /*
16 * Class H Algorithm Control Variables
17 * You can either have it done
18 * automatically or you can adjust
19 * these variables for tuning
20 *
21 * if you do not enable the internal algorithm
22 * you will get a set of mixer controls for
23 * Class H tuning
24 *
25 * Section 4.3 of the datasheet
26 */
27 bool classh_bst_override;
28 bool classh_algo_enable;
29 int classh_bst_max_limit;
30 int classh_mem_depth;
31 int classh_release_rate;
32 int classh_headroom;
33 int classh_wk_fet_disable;
34 int classh_wk_fet_delay;
35 int classh_wk_fet_thld;
36 int classh_vpch_auto;
37 int classh_vpch_rate;
38 int classh_vpch_man;
39};
40
41struct monitor_cfg {
42 /*
43 * Signal Monitor Data
44 * highly configurable signal monitoring
45 * data positioning and different types of
46 * monitoring data.
47 *
48 * Section 4.8.2 - 4.8.4 of the datasheet
49 */
50 bool is_present;
51 bool imon_specs;
52 bool vmon_specs;
53 bool vpmon_specs;
54 bool vbstmon_specs;
55 bool vpbrstat_specs;
56 bool zerofill_specs;
57 u8 imon_dpth;
58 u8 imon_loc;
59 u8 imon_frm;
60 u8 imon_scale;
61 u8 vmon_dpth;
62 u8 vmon_loc;
63 u8 vmon_frm;
64 u8 vpmon_dpth;
65 u8 vpmon_loc;
66 u8 vpmon_frm;
67 u8 vbstmon_dpth;
68 u8 vbstmon_loc;
69 u8 vbstmon_frm;
70 u8 vpbrstat_dpth;
71 u8 vpbrstat_loc;
72 u8 vpbrstat_frm;
73 u8 zerofill_dpth;
74 u8 zerofill_loc;
75 u8 zerofill_frm;
76};
77
78struct cs35l35_platform_data {
79
80 /* Stereo (2 Device) */
81 bool stereo;
82 /* serial port drive strength */
83 int sp_drv_str;
84 /* serial port drive in unused slots */
85 int sp_drv_unused;
86 /* Boost Power Down with FET */
87 bool bst_pdn_fet_on;
88 /* Boost Voltage : used if ClassH Algo Enabled */
89 int bst_vctl;
90 /* Boost Converter Peak Current CTRL */
91 int bst_ipk;
92 /* Amp Gain Zero Cross */
93 bool gain_zc;
94 /* Audio Input Location */
95 int aud_channel;
96 /* Advisory Input Location */
97 int adv_channel;
98 /* Shared Boost for stereo */
99 bool shared_bst;
100 /* Specifies this amp is using an external boost supply */
101 bool ext_bst;
102 /* ClassH Algorithm */
103 struct classh_cfg classh_algo;
104 /* Monitor Config */
105 struct monitor_cfg mon_cfg;
106};
107
108#endif /* __CS35L35_H */
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index 0013063db7f2..15fc6daf9096 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -106,8 +106,26 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
106#define AZX_REG_HSW_EM4 0x100c 106#define AZX_REG_HSW_EM4 0x100c
107#define AZX_REG_HSW_EM5 0x1010 107#define AZX_REG_HSW_EM5 0x1010
108 108
109/* Skylake/Broxton display HD-A controller Extended Mode registers */ 109/* Skylake/Broxton vendor-specific registers */
110#define AZX_REG_SKL_EM4L 0x1040 110#define AZX_REG_VS_EM1 0x1000
111#define AZX_REG_VS_INRC 0x1004
112#define AZX_REG_VS_OUTRC 0x1008
113#define AZX_REG_VS_FIFOTRK 0x100C
114#define AZX_REG_VS_FIFOTRK2 0x1010
115#define AZX_REG_VS_EM2 0x1030
116#define AZX_REG_VS_EM3L 0x1038
117#define AZX_REG_VS_EM3U 0x103C
118#define AZX_REG_VS_EM4L 0x1040
119#define AZX_REG_VS_EM4U 0x1044
120#define AZX_REG_VS_LTRC 0x1048
121#define AZX_REG_VS_D0I3C 0x104A
122#define AZX_REG_VS_PCE 0x104B
123#define AZX_REG_VS_L2MAGC 0x1050
124#define AZX_REG_VS_L2LAHPT 0x1054
125#define AZX_REG_VS_SDXDPIB_XBASE 0x1084
126#define AZX_REG_VS_SDXDPIB_XINTERVAL 0x20
127#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
128#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
111 129
112/* PCI space */ 130/* PCI space */
113#define AZX_PCIREG_TCSEL 0x44 131#define AZX_PCIREG_TCSEL 0x44
@@ -243,9 +261,11 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
243#define AZX_REG_ML_LOUTPAY 0x20 261#define AZX_REG_ML_LOUTPAY 0x20
244#define AZX_REG_ML_LINPAY 0x30 262#define AZX_REG_ML_LINPAY 0x30
245 263
246#define AZX_MLCTL_SPA (1<<16) 264#define ML_LCTL_SCF_MASK 0xF
247#define AZX_MLCTL_CPA 23 265#define AZX_MLCTL_SPA (0x1 << 16)
248 266#define AZX_MLCTL_CPA (0x1 << 23)
267#define AZX_MLCTL_SPA_SHIFT 16
268#define AZX_MLCTL_CPA_SHIFT 23
249 269
250/* registers for DMA Resume Capability Structure */ 270/* registers for DMA Resume Capability Structure */
251#define AZX_DRSM_CAP_ID 0x5 271#define AZX_DRSM_CAP_ID 0x5
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 56004ec8d441..96546b30e900 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -368,24 +368,32 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
368/* 368/*
369 * macros for easy use 369 * macros for easy use
370 */ 370 */
371#define _snd_hdac_chip_write(type, chip, reg, value) \ 371#define _snd_hdac_chip_writeb(chip, reg, value) \
372 ((chip)->io_ops->reg_write ## type(value, (chip)->remap_addr + (reg))) 372 ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg)))
373#define _snd_hdac_chip_read(type, chip, reg) \ 373#define _snd_hdac_chip_readb(chip, reg) \
374 ((chip)->io_ops->reg_read ## type((chip)->remap_addr + (reg))) 374 ((chip)->io_ops->reg_readb((chip)->remap_addr + (reg)))
375#define _snd_hdac_chip_writew(chip, reg, value) \
376 ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + (reg)))
377#define _snd_hdac_chip_readw(chip, reg) \
378 ((chip)->io_ops->reg_readw((chip)->remap_addr + (reg)))
379#define _snd_hdac_chip_writel(chip, reg, value) \
380 ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + (reg)))
381#define _snd_hdac_chip_readl(chip, reg) \
382 ((chip)->io_ops->reg_readl((chip)->remap_addr + (reg)))
375 383
376/* read/write a register, pass without AZX_REG_ prefix */ 384/* read/write a register, pass without AZX_REG_ prefix */
377#define snd_hdac_chip_writel(chip, reg, value) \ 385#define snd_hdac_chip_writel(chip, reg, value) \
378 _snd_hdac_chip_write(l, chip, AZX_REG_ ## reg, value) 386 _snd_hdac_chip_writel(chip, AZX_REG_ ## reg, value)
379#define snd_hdac_chip_writew(chip, reg, value) \ 387#define snd_hdac_chip_writew(chip, reg, value) \
380 _snd_hdac_chip_write(w, chip, AZX_REG_ ## reg, value) 388 _snd_hdac_chip_writew(chip, AZX_REG_ ## reg, value)
381#define snd_hdac_chip_writeb(chip, reg, value) \ 389#define snd_hdac_chip_writeb(chip, reg, value) \
382 _snd_hdac_chip_write(b, chip, AZX_REG_ ## reg, value) 390 _snd_hdac_chip_writeb(chip, AZX_REG_ ## reg, value)
383#define snd_hdac_chip_readl(chip, reg) \ 391#define snd_hdac_chip_readl(chip, reg) \
384 _snd_hdac_chip_read(l, chip, AZX_REG_ ## reg) 392 _snd_hdac_chip_readl(chip, AZX_REG_ ## reg)
385#define snd_hdac_chip_readw(chip, reg) \ 393#define snd_hdac_chip_readw(chip, reg) \
386 _snd_hdac_chip_read(w, chip, AZX_REG_ ## reg) 394 _snd_hdac_chip_readw(chip, AZX_REG_ ## reg)
387#define snd_hdac_chip_readb(chip, reg) \ 395#define snd_hdac_chip_readb(chip, reg) \
388 _snd_hdac_chip_read(b, chip, AZX_REG_ ## reg) 396 _snd_hdac_chip_readb(chip, AZX_REG_ ## reg)
389 397
390/* update a register, pass without AZX_REG_ prefix */ 398/* update a register, pass without AZX_REG_ prefix */
391#define snd_hdac_chip_updatel(chip, reg, mask, val) \ 399#define snd_hdac_chip_updatel(chip, reg, mask, val) \
diff --git a/include/sound/soc.h b/include/sound/soc.h
index cdfb55f7aede..5170fd81e1fd 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -434,6 +434,8 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
434 int source, unsigned int freq, int dir); 434 int source, unsigned int freq, int dir);
435int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 435int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
436 unsigned int freq_in, unsigned int freq_out); 436 unsigned int freq_in, unsigned int freq_out);
437int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
438 struct snd_soc_jack *jack, void *data);
437 439
438int snd_soc_register_card(struct snd_soc_card *card); 440int snd_soc_register_card(struct snd_soc_card *card);
439int snd_soc_unregister_card(struct snd_soc_card *card); 441int snd_soc_unregister_card(struct snd_soc_card *card);
@@ -497,7 +499,15 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
497int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, 499int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
498 unsigned int dai_fmt); 500 unsigned int dai_fmt);
499 501
502#ifdef CONFIG_DMI
500int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour); 503int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);
504#else
505static inline int snd_soc_set_dmi_name(struct snd_soc_card *card,
506 const char *flavour)
507{
508 return 0;
509}
510#endif
501 511
502/* Utility functions to get clock rates from various things */ 512/* Utility functions to get clock rates from various things */
503int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 513int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -721,6 +731,7 @@ struct snd_soc_jack_gpio {
721 /* private: */ 731 /* private: */
722 struct snd_soc_jack *jack; 732 struct snd_soc_jack *jack;
723 struct delayed_work work; 733 struct delayed_work work;
734 struct notifier_block pm_notifier;
724 struct gpio_desc *desc; 735 struct gpio_desc *desc;
725 736
726 void *data; 737 void *data;
@@ -812,7 +823,6 @@ struct snd_soc_component {
812 823
813 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ 824 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
814 unsigned int registered_as_component:1; 825 unsigned int registered_as_component:1;
815 unsigned int auxiliary:1; /* for auxiliary component of the card */
816 unsigned int suspended:1; /* is in suspend PM state */ 826 unsigned int suspended:1; /* is in suspend PM state */
817 827
818 struct list_head list; 828 struct list_head list;
@@ -913,6 +923,8 @@ struct snd_soc_codec_driver {
913 int clk_id, int source, unsigned int freq, int dir); 923 int clk_id, int source, unsigned int freq, int dir);
914 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, 924 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
915 unsigned int freq_in, unsigned int freq_out); 925 unsigned int freq_in, unsigned int freq_out);
926 int (*set_jack)(struct snd_soc_codec *codec,
927 struct snd_soc_jack *jack, void *data);
916 928
917 /* codec IO */ 929 /* codec IO */
918 struct regmap *(*get_regmap)(struct device *); 930 struct regmap *(*get_regmap)(struct device *);
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index be353a78c303..fd41697cb4d3 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -107,9 +107,11 @@ enum {
107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ 107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */
108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ 108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */
109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ 109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */
110 SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */
111 SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */
110 112
111 /* Don't forget to change the following: */ 113 /* Don't forget to change the following: */
112 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6 114 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
113}; 115};
114 116
115struct snd_hwdep_info { 117struct snd_hwdep_info {
diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index db79a12fcc78..622900488bdc 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -10,6 +10,7 @@
10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e 10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
12#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c 12#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
13#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
13 14
14struct snd_firewire_event_common { 15struct snd_firewire_event_common {
15 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ 16 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
@@ -46,12 +47,18 @@ struct snd_firewire_event_digi00x_message {
46 __u32 message; /* Digi00x-specific message */ 47 __u32 message; /* Digi00x-specific message */
47}; 48};
48 49
50struct snd_firewire_event_motu_notification {
51 unsigned int type;
52 __u32 message; /* MOTU-specific bits. */
53};
54
49union snd_firewire_event { 55union snd_firewire_event {
50 struct snd_firewire_event_common common; 56 struct snd_firewire_event_common common;
51 struct snd_firewire_event_lock_status lock_status; 57 struct snd_firewire_event_lock_status lock_status;
52 struct snd_firewire_event_dice_notification dice_notification; 58 struct snd_firewire_event_dice_notification dice_notification;
53 struct snd_firewire_event_efw_response efw_response; 59 struct snd_firewire_event_efw_response efw_response;
54 struct snd_firewire_event_digi00x_message digi00x_message; 60 struct snd_firewire_event_digi00x_message digi00x_message;
61 struct snd_firewire_event_motu_notification motu_notification;
55}; 62};
56 63
57 64
@@ -65,7 +72,8 @@ union snd_firewire_event {
65#define SNDRV_FIREWIRE_TYPE_OXFW 4 72#define SNDRV_FIREWIRE_TYPE_OXFW 4
66#define SNDRV_FIREWIRE_TYPE_DIGI00X 5 73#define SNDRV_FIREWIRE_TYPE_DIGI00X 5
67#define SNDRV_FIREWIRE_TYPE_TASCAM 6 74#define SNDRV_FIREWIRE_TYPE_TASCAM 6
68/* RME, MOTU, ... */ 75#define SNDRV_FIREWIRE_TYPE_MOTU 7
76#define SNDRV_FIREWIRE_TYPE_FIREFACE 8
69 77
70struct snd_firewire_get_info { 78struct snd_firewire_get_info {
71 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */ 79 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6d4fbc439246..2f836ca09860 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1277,6 +1277,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1277 struct timespec tstamp; 1277 struct timespec tstamp;
1278 int prev, append = 0; 1278 int prev, append = 0;
1279 1279
1280 memset(&r1, 0, sizeof(r1));
1280 memset(&tstamp, 0, sizeof(tstamp)); 1281 memset(&tstamp, 0, sizeof(tstamp));
1281 spin_lock(&tu->qlock); 1282 spin_lock(&tu->qlock);
1282 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | 1283 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
@@ -1292,7 +1293,6 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1292 } 1293 }
1293 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1294 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1294 tu->last_resolution != resolution) { 1295 tu->last_resolution != resolution) {
1295 memset(&r1, 0, sizeof(r1));
1296 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1296 r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
1297 r1.tstamp = tstamp; 1297 r1.tstamp = tstamp;
1298 r1.val = resolution; 1298 r1.val = resolution;
@@ -1430,18 +1430,13 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1430 if (id.card < 0) { 1430 if (id.card < 0) {
1431 id.card = 0; 1431 id.card = 0;
1432 } else { 1432 } else {
1433 if (id.card < 0) { 1433 if (id.device < 0) {
1434 id.card = 0; 1434 id.device = 0;
1435 } else { 1435 } else {
1436 if (id.device < 0) { 1436 if (id.subdevice < 0)
1437 id.device = 0; 1437 id.subdevice = 0;
1438 } else { 1438 else
1439 if (id.subdevice < 0) { 1439 id.subdevice++;
1440 id.subdevice = 0;
1441 } else {
1442 id.subdevice++;
1443 }
1444 }
1445 } 1440 }
1446 } 1441 }
1447 list_for_each(p, &snd_timer_list) { 1442 list_for_each(p, &snd_timer_list) {
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 289f041706cd..f684fffd1397 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -795,10 +795,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
795 return NULL; 795 return NULL;
796 796
797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL); 797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
798 if (! chip) { 798 if (! chip)
799 snd_printk(KERN_ERR "vx_core: no memory\n");
800 return NULL; 799 return NULL;
801 }
802 mutex_init(&chip->lock); 800 mutex_init(&chip->lock);
803 chip->irq = -1; 801 chip->irq = -1;
804 chip->hw = hw; 802 chip->hw = hw;
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 9f00696c4e4a..529d9f405fa9 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -140,4 +140,24 @@ config SND_FIREWIRE_TASCAM
140 To compile this driver as a module, choose M here: the module 140 To compile this driver as a module, choose M here: the module
141 will be called snd-firewire-tascam. 141 will be called snd-firewire-tascam.
142 142
143config SND_FIREWIRE_MOTU
144 tristate "Mark of the unicorn FireWire series support"
145 select SND_FIREWIRE_LIB
146 select SND_HWDEP
147 help
148 Say Y here to enable support for FireWire devices which MOTU produced:
149 * 828mk2
150 * 828mk3
151
152 To compile this driver as a module, choose M here: the module
153 will be called snd-firewire-motu.
154
155config SND_FIREFACE
156 tristate "RME Fireface series support"
157 select SND_FIREWIRE_LIB
158 select SND_HWDEP
159 help
160 Say Y here to include support for RME fireface series.
161 * Fireface 400
162
143endif # SND_FIREWIRE 163endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 0ee1fb115d88..1b98fa3fa3d4 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_SND_FIREWORKS) += fireworks/
13obj-$(CONFIG_SND_BEBOB) += bebob/ 13obj-$(CONFIG_SND_BEBOB) += bebob/
14obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/ 14obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/
15obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/ 15obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/
16obj-$(CONFIG_SND_FIREWIRE_MOTU) += motu/
17obj-$(CONFIG_SND_FIREFACE) += fireface/
diff --git a/sound/firewire/amdtp-stream-trace.h b/sound/firewire/amdtp-stream-trace.h
index 9c04faf206b2..ea0d486652c8 100644
--- a/sound/firewire/amdtp-stream-trace.h
+++ b/sound/firewire/amdtp-stream-trace.h
@@ -14,8 +14,8 @@
14#include <linux/tracepoint.h> 14#include <linux/tracepoint.h>
15 15
16TRACE_EVENT(in_packet, 16TRACE_EVENT(in_packet,
17 TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_quadlets, unsigned int index), 17 TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_length, unsigned int index),
18 TP_ARGS(s, cycles, cip_header, payload_quadlets, index), 18 TP_ARGS(s, cycles, cip_header, payload_length, index),
19 TP_STRUCT__entry( 19 TP_STRUCT__entry(
20 __field(unsigned int, second) 20 __field(unsigned int, second)
21 __field(unsigned int, cycle) 21 __field(unsigned int, cycle)
@@ -37,7 +37,7 @@ TRACE_EVENT(in_packet,
37 __entry->dest = fw_parent_device(s->unit)->card->node_id; 37 __entry->dest = fw_parent_device(s->unit)->card->node_id;
38 __entry->cip_header0 = cip_header[0]; 38 __entry->cip_header0 = cip_header[0];
39 __entry->cip_header1 = cip_header[1]; 39 __entry->cip_header1 = cip_header[1];
40 __entry->payload_quadlets = payload_quadlets; 40 __entry->payload_quadlets = payload_length / 4;
41 __entry->packet_index = s->packet_index; 41 __entry->packet_index = s->packet_index;
42 __entry->irq = !!in_interrupt(); 42 __entry->irq = !!in_interrupt();
43 __entry->index = index; 43 __entry->index = index;
@@ -101,6 +101,94 @@ TRACE_EVENT(out_packet,
101 __entry->index) 101 __entry->index)
102); 102);
103 103
104TRACE_EVENT(in_packet_without_header,
105 TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_quadlets, unsigned int data_blocks, unsigned int index),
106 TP_ARGS(s, cycles, payload_quadlets, data_blocks, index),
107 TP_STRUCT__entry(
108 __field(unsigned int, second)
109 __field(unsigned int, cycle)
110 __field(int, channel)
111 __field(int, src)
112 __field(int, dest)
113 __field(unsigned int, payload_quadlets)
114 __field(unsigned int, data_blocks)
115 __field(unsigned int, data_block_counter)
116 __field(unsigned int, packet_index)
117 __field(unsigned int, irq)
118 __field(unsigned int, index)
119 ),
120 TP_fast_assign(
121 __entry->second = cycles / CYCLES_PER_SECOND;
122 __entry->cycle = cycles % CYCLES_PER_SECOND;
123 __entry->channel = s->context->channel;
124 __entry->src = fw_parent_device(s->unit)->node_id;
125 __entry->dest = fw_parent_device(s->unit)->card->node_id;
126 __entry->payload_quadlets = payload_quadlets;
127 __entry->data_blocks = data_blocks,
128 __entry->data_block_counter = s->data_block_counter,
129 __entry->packet_index = s->packet_index;
130 __entry->irq = !!in_interrupt();
131 __entry->index = index;
132 ),
133 TP_printk(
134 "%02u %04u %04x %04x %02d %03u %3u %3u %02u %01u %02u",
135 __entry->second,
136 __entry->cycle,
137 __entry->src,
138 __entry->dest,
139 __entry->channel,
140 __entry->payload_quadlets,
141 __entry->data_blocks,
142 __entry->data_block_counter,
143 __entry->packet_index,
144 __entry->irq,
145 __entry->index)
146);
147
148TRACE_EVENT(out_packet_without_header,
149 TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_length, unsigned int data_blocks, unsigned int index),
150 TP_ARGS(s, cycles, payload_length, data_blocks, index),
151 TP_STRUCT__entry(
152 __field(unsigned int, second)
153 __field(unsigned int, cycle)
154 __field(int, channel)
155 __field(int, src)
156 __field(int, dest)
157 __field(unsigned int, payload_quadlets)
158 __field(unsigned int, data_blocks)
159 __field(unsigned int, data_block_counter)
160 __field(unsigned int, packet_index)
161 __field(unsigned int, irq)
162 __field(unsigned int, index)
163 ),
164 TP_fast_assign(
165 __entry->second = cycles / CYCLES_PER_SECOND;
166 __entry->cycle = cycles % CYCLES_PER_SECOND;
167 __entry->channel = s->context->channel;
168 __entry->src = fw_parent_device(s->unit)->card->node_id;
169 __entry->dest = fw_parent_device(s->unit)->node_id;
170 __entry->payload_quadlets = payload_length / 4;
171 __entry->data_blocks = data_blocks,
172 __entry->data_blocks = s->data_block_counter,
173 __entry->packet_index = s->packet_index;
174 __entry->irq = !!in_interrupt();
175 __entry->index = index;
176 ),
177 TP_printk(
178 "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u",
179 __entry->second,
180 __entry->cycle,
181 __entry->src,
182 __entry->dest,
183 __entry->channel,
184 __entry->payload_quadlets,
185 __entry->data_blocks,
186 __entry->data_block_counter,
187 __entry->packet_index,
188 __entry->irq,
189 __entry->index)
190);
191
104#endif 192#endif
105 193
106#undef TRACE_INCLUDE_PATH 194#undef TRACE_INCLUDE_PATH
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 00060c4a9deb..9e6f54f8c45d 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -27,6 +27,7 @@
27 27
28/* isochronous header parameters */ 28/* isochronous header parameters */
29#define ISO_DATA_LENGTH_SHIFT 16 29#define ISO_DATA_LENGTH_SHIFT 16
30#define TAG_NO_CIP_HEADER 0
30#define TAG_CIP 1 31#define TAG_CIP 1
31 32
32/* common isochronous packet header parameters */ 33/* common isochronous packet header parameters */
@@ -37,6 +38,8 @@
37#define CIP_SID_MASK 0x3f000000 38#define CIP_SID_MASK 0x3f000000
38#define CIP_DBS_MASK 0x00ff0000 39#define CIP_DBS_MASK 0x00ff0000
39#define CIP_DBS_SHIFT 16 40#define CIP_DBS_SHIFT 16
41#define CIP_SPH_MASK 0x00000400
42#define CIP_SPH_SHIFT 10
40#define CIP_DBC_MASK 0x000000ff 43#define CIP_DBC_MASK 0x000000ff
41#define CIP_FMT_SHIFT 24 44#define CIP_FMT_SHIFT 24
42#define CIP_FMT_MASK 0x3f000000 45#define CIP_FMT_MASK 0x3f000000
@@ -232,11 +235,15 @@ EXPORT_SYMBOL(amdtp_stream_set_parameters);
232unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 235unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
233{ 236{
234 unsigned int multiplier = 1; 237 unsigned int multiplier = 1;
238 unsigned int header_size = 0;
235 239
236 if (s->flags & CIP_JUMBO_PAYLOAD) 240 if (s->flags & CIP_JUMBO_PAYLOAD)
237 multiplier = 5; 241 multiplier = 5;
242 if (!(s->flags & CIP_NO_HEADER))
243 header_size = 8;
238 244
239 return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier; 245 return header_size +
246 s->syt_interval * s->data_block_quadlets * 4 * multiplier;
240} 247}
241EXPORT_SYMBOL(amdtp_stream_get_max_payload); 248EXPORT_SYMBOL(amdtp_stream_get_max_payload);
242 249
@@ -378,7 +385,7 @@ static int queue_packet(struct amdtp_stream *s, unsigned int header_length,
378 goto end; 385 goto end;
379 386
380 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); 387 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);
381 p.tag = TAG_CIP; 388 p.tag = s->tag;
382 p.header_length = header_length; 389 p.header_length = header_length;
383 if (payload_length > 0) 390 if (payload_length > 0)
384 p.payload_length = payload_length; 391 p.payload_length = payload_length;
@@ -405,17 +412,16 @@ static inline int queue_out_packet(struct amdtp_stream *s,
405 412
406static inline int queue_in_packet(struct amdtp_stream *s) 413static inline int queue_in_packet(struct amdtp_stream *s)
407{ 414{
408 return queue_packet(s, IN_PACKET_HEADER_SIZE, 415 return queue_packet(s, IN_PACKET_HEADER_SIZE, s->max_payload_length);
409 amdtp_stream_get_max_payload(s));
410} 416}
411 417
412static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle, 418static int handle_out_packet(struct amdtp_stream *s,
419 unsigned int payload_length, unsigned int cycle,
413 unsigned int index) 420 unsigned int index)
414{ 421{
415 __be32 *buffer; 422 __be32 *buffer;
416 unsigned int syt; 423 unsigned int syt;
417 unsigned int data_blocks; 424 unsigned int data_blocks;
418 unsigned int payload_length;
419 unsigned int pcm_frames; 425 unsigned int pcm_frames;
420 struct snd_pcm_substream *pcm; 426 struct snd_pcm_substream *pcm;
421 427
@@ -424,15 +430,22 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,
424 data_blocks = calculate_data_blocks(s, syt); 430 data_blocks = calculate_data_blocks(s, syt);
425 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt); 431 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);
426 432
433 if (s->flags & CIP_DBC_IS_END_EVENT)
434 s->data_block_counter =
435 (s->data_block_counter + data_blocks) & 0xff;
436
427 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | 437 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
428 (s->data_block_quadlets << CIP_DBS_SHIFT) | 438 (s->data_block_quadlets << CIP_DBS_SHIFT) |
439 ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) |
429 s->data_block_counter); 440 s->data_block_counter);
430 buffer[1] = cpu_to_be32(CIP_EOH | 441 buffer[1] = cpu_to_be32(CIP_EOH |
431 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | 442 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
432 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | 443 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
433 (syt & CIP_SYT_MASK)); 444 (syt & CIP_SYT_MASK));
434 445
435 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; 446 if (!(s->flags & CIP_DBC_IS_END_EVENT))
447 s->data_block_counter =
448 (s->data_block_counter + data_blocks) & 0xff;
436 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; 449 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
437 450
438 trace_out_packet(s, cycle, buffer, payload_length, index); 451 trace_out_packet(s, cycle, buffer, payload_length, index);
@@ -448,13 +461,45 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,
448 return 0; 461 return 0;
449} 462}
450 463
464static int handle_out_packet_without_header(struct amdtp_stream *s,
465 unsigned int payload_length, unsigned int cycle,
466 unsigned int index)
467{
468 __be32 *buffer;
469 unsigned int syt;
470 unsigned int data_blocks;
471 unsigned int pcm_frames;
472 struct snd_pcm_substream *pcm;
473
474 buffer = s->buffer.packets[s->packet_index].buffer;
475 syt = calculate_syt(s, cycle);
476 data_blocks = calculate_data_blocks(s, syt);
477 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt);
478 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
479
480 payload_length = data_blocks * 4 * s->data_block_quadlets;
481
482 trace_out_packet_without_header(s, cycle, payload_length, data_blocks,
483 index);
484
485 if (queue_out_packet(s, payload_length) < 0)
486 return -EIO;
487
488 pcm = ACCESS_ONCE(s->pcm);
489 if (pcm && pcm_frames > 0)
490 update_pcm_pointers(s, pcm, pcm_frames);
491
492 /* No need to return the number of handled data blocks. */
493 return 0;
494}
495
451static int handle_in_packet(struct amdtp_stream *s, 496static int handle_in_packet(struct amdtp_stream *s,
452 unsigned int payload_quadlets, unsigned int cycle, 497 unsigned int payload_length, unsigned int cycle,
453 unsigned int index) 498 unsigned int index)
454{ 499{
455 __be32 *buffer; 500 __be32 *buffer;
456 u32 cip_header[2]; 501 u32 cip_header[2];
457 unsigned int fmt, fdf, syt; 502 unsigned int sph, fmt, fdf, syt;
458 unsigned int data_block_quadlets, data_block_counter, dbc_interval; 503 unsigned int data_block_quadlets, data_block_counter, dbc_interval;
459 unsigned int data_blocks; 504 unsigned int data_blocks;
460 struct snd_pcm_substream *pcm; 505 struct snd_pcm_substream *pcm;
@@ -465,14 +510,15 @@ static int handle_in_packet(struct amdtp_stream *s,
465 cip_header[0] = be32_to_cpu(buffer[0]); 510 cip_header[0] = be32_to_cpu(buffer[0]);
466 cip_header[1] = be32_to_cpu(buffer[1]); 511 cip_header[1] = be32_to_cpu(buffer[1]);
467 512
468 trace_in_packet(s, cycle, cip_header, payload_quadlets, index); 513 trace_in_packet(s, cycle, cip_header, payload_length, index);
469 514
470 /* 515 /*
471 * This module supports 'Two-quadlet CIP header with SYT field'. 516 * This module supports 'Two-quadlet CIP header with SYT field'.
472 * For convenience, also check FMT field is AM824 or not. 517 * For convenience, also check FMT field is AM824 or not.
473 */ 518 */
474 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 519 if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||
475 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) { 520 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) &&
521 (!(s->flags & CIP_HEADER_WITHOUT_EOH))) {
476 dev_info_ratelimited(&s->unit->device, 522 dev_info_ratelimited(&s->unit->device,
477 "Invalid CIP header for AMDTP: %08X:%08X\n", 523 "Invalid CIP header for AMDTP: %08X:%08X\n",
478 cip_header[0], cip_header[1]); 524 cip_header[0], cip_header[1]);
@@ -482,8 +528,9 @@ static int handle_in_packet(struct amdtp_stream *s,
482 } 528 }
483 529
484 /* Check valid protocol or not. */ 530 /* Check valid protocol or not. */
531 sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT;
485 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT; 532 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;
486 if (fmt != s->fmt) { 533 if (sph != s->sph || fmt != s->fmt) {
487 dev_info_ratelimited(&s->unit->device, 534 dev_info_ratelimited(&s->unit->device,
488 "Detect unexpected protocol: %08x %08x\n", 535 "Detect unexpected protocol: %08x %08x\n",
489 cip_header[0], cip_header[1]); 536 cip_header[0], cip_header[1]);
@@ -494,7 +541,7 @@ static int handle_in_packet(struct amdtp_stream *s,
494 541
495 /* Calculate data blocks */ 542 /* Calculate data blocks */
496 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT; 543 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;
497 if (payload_quadlets < 3 || 544 if (payload_length < 12 ||
498 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) { 545 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
499 data_blocks = 0; 546 data_blocks = 0;
500 } else { 547 } else {
@@ -510,7 +557,8 @@ static int handle_in_packet(struct amdtp_stream *s,
510 if (s->flags & CIP_WRONG_DBS) 557 if (s->flags & CIP_WRONG_DBS)
511 data_block_quadlets = s->data_block_quadlets; 558 data_block_quadlets = s->data_block_quadlets;
512 559
513 data_blocks = (payload_quadlets - 2) / data_block_quadlets; 560 data_blocks = (payload_length / 4 - 2) /
561 data_block_quadlets;
514 } 562 }
515 563
516 /* Check data block counter continuity */ 564 /* Check data block counter continuity */
@@ -561,6 +609,34 @@ end:
561 return 0; 609 return 0;
562} 610}
563 611
612static int handle_in_packet_without_header(struct amdtp_stream *s,
613 unsigned int payload_quadlets, unsigned int cycle,
614 unsigned int index)
615{
616 __be32 *buffer;
617 unsigned int data_blocks;
618 struct snd_pcm_substream *pcm;
619 unsigned int pcm_frames;
620
621 buffer = s->buffer.packets[s->packet_index].buffer;
622 data_blocks = payload_quadlets / s->data_block_quadlets;
623
624 trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks,
625 index);
626
627 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, NULL);
628 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
629
630 if (queue_in_packet(s) < 0)
631 return -EIO;
632
633 pcm = ACCESS_ONCE(s->pcm);
634 if (pcm && pcm_frames > 0)
635 update_pcm_pointers(s, pcm, pcm_frames);
636
637 return 0;
638}
639
564/* 640/*
565 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On 641 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On
566 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent 642 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent
@@ -604,7 +680,7 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
604 680
605 for (i = 0; i < packets; ++i) { 681 for (i = 0; i < packets; ++i) {
606 cycle = increment_cycle_count(cycle, 1); 682 cycle = increment_cycle_count(cycle, 1);
607 if (handle_out_packet(s, cycle, i) < 0) { 683 if (s->handle_packet(s, 0, cycle, i) < 0) {
608 s->packet_index = -1; 684 s->packet_index = -1;
609 amdtp_stream_pcm_abort(s); 685 amdtp_stream_pcm_abort(s);
610 return; 686 return;
@@ -620,7 +696,7 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
620{ 696{
621 struct amdtp_stream *s = private_data; 697 struct amdtp_stream *s = private_data;
622 unsigned int i, packets; 698 unsigned int i, packets;
623 unsigned int payload_quadlets, max_payload_quadlets; 699 unsigned int payload_length, max_payload_length;
624 __be32 *headers = header; 700 __be32 *headers = header;
625 u32 cycle; 701 u32 cycle;
626 702
@@ -636,22 +712,22 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
636 cycle = decrement_cycle_count(cycle, packets); 712 cycle = decrement_cycle_count(cycle, packets);
637 713
638 /* For buffer-over-run prevention. */ 714 /* For buffer-over-run prevention. */
639 max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4; 715 max_payload_length = s->max_payload_length;
640 716
641 for (i = 0; i < packets; i++) { 717 for (i = 0; i < packets; i++) {
642 cycle = increment_cycle_count(cycle, 1); 718 cycle = increment_cycle_count(cycle, 1);
643 719
644 /* The number of quadlets in this packet */ 720 /* The number of bytes in this packet */
645 payload_quadlets = 721 payload_length =
646 (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT) / 4; 722 (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT);
647 if (payload_quadlets > max_payload_quadlets) { 723 if (payload_length > max_payload_length) {
648 dev_err(&s->unit->device, 724 dev_err(&s->unit->device,
649 "Detect jumbo payload: %02x %02x\n", 725 "Detect jumbo payload: %04x %04x\n",
650 payload_quadlets, max_payload_quadlets); 726 payload_length, max_payload_length);
651 break; 727 break;
652 } 728 }
653 729
654 if (handle_in_packet(s, payload_quadlets, cycle, i) < 0) 730 if (s->handle_packet(s, payload_length, cycle, i) < 0)
655 break; 731 break;
656 } 732 }
657 733
@@ -671,6 +747,10 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
671 void *header, void *private_data) 747 void *header, void *private_data)
672{ 748{
673 struct amdtp_stream *s = private_data; 749 struct amdtp_stream *s = private_data;
750 u32 cycle;
751 unsigned int packets;
752
753 s->max_payload_length = amdtp_stream_get_max_payload(s);
674 754
675 /* 755 /*
676 * For in-stream, first packet has come. 756 * For in-stream, first packet has come.
@@ -679,10 +759,27 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
679 s->callbacked = true; 759 s->callbacked = true;
680 wake_up(&s->callback_wait); 760 wake_up(&s->callback_wait);
681 761
682 if (s->direction == AMDTP_IN_STREAM) 762 cycle = compute_cycle_count(tstamp);
763
764 if (s->direction == AMDTP_IN_STREAM) {
765 packets = header_length / IN_PACKET_HEADER_SIZE;
766 cycle = decrement_cycle_count(cycle, packets);
683 context->callback.sc = in_stream_callback; 767 context->callback.sc = in_stream_callback;
684 else 768 if (s->flags & CIP_NO_HEADER)
769 s->handle_packet = handle_in_packet_without_header;
770 else
771 s->handle_packet = handle_in_packet;
772 } else {
773 packets = header_length / 4;
774 cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets);
685 context->callback.sc = out_stream_callback; 775 context->callback.sc = out_stream_callback;
776 if (s->flags & CIP_NO_HEADER)
777 s->handle_packet = handle_out_packet_without_header;
778 else
779 s->handle_packet = handle_out_packet;
780 }
781
782 s->start_cycle = cycle;
686 783
687 context->callback.sc(context, tstamp, header_length, header, s); 784 context->callback.sc(context, tstamp, header_length, header, s);
688} 785}
@@ -759,6 +856,11 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
759 856
760 amdtp_stream_update(s); 857 amdtp_stream_update(s);
761 858
859 if (s->flags & CIP_NO_HEADER)
860 s->tag = TAG_NO_CIP_HEADER;
861 else
862 s->tag = TAG_CIP;
863
762 s->packet_index = 0; 864 s->packet_index = 0;
763 do { 865 do {
764 if (s->direction == AMDTP_IN_STREAM) 866 if (s->direction == AMDTP_IN_STREAM)
@@ -771,7 +873,7 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
771 873
772 /* NOTE: TAG1 matches CIP. This just affects in stream. */ 874 /* NOTE: TAG1 matches CIP. This just affects in stream. */
773 tag = FW_ISO_CONTEXT_MATCH_TAG1; 875 tag = FW_ISO_CONTEXT_MATCH_TAG1;
774 if (s->flags & CIP_EMPTY_WITH_TAG0) 876 if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))
775 tag |= FW_ISO_CONTEXT_MATCH_TAG0; 877 tag |= FW_ISO_CONTEXT_MATCH_TAG0;
776 878
777 s->callbacked = false; 879 s->callbacked = false;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index c1bc7fad056e..7e8831722821 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -18,8 +18,8 @@
18 * SYT_INTERVAL samples, with these two types alternating so that 18 * SYT_INTERVAL samples, with these two types alternating so that
19 * the overall sample rate comes out right. 19 * the overall sample rate comes out right.
20 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. 20 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.
21 * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet 21 * @CIP_DBC_IS_END_EVENT: The value of dbc in an packet corresponds to the end
22 * corresponds to the end of event in the packet. Out of IEC 61883. 22 * of event in the packet. Out of IEC 61883.
23 * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. 23 * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets.
24 * The value of data_block_quadlets is used instead of reported value. 24 * The value of data_block_quadlets is used instead of reported value.
25 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is 25 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is
@@ -29,6 +29,9 @@
29 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an 29 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an
30 * packet is larger than IEC 61883-6 defines. Current implementation 30 * packet is larger than IEC 61883-6 defines. Current implementation
31 * allows 5 times as large as IEC 61883-6 defines. 31 * allows 5 times as large as IEC 61883-6 defines.
32 * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include
33 * valid EOH.
34 * @CIP_NO_HEADERS: a lack of headers in packets
32 */ 35 */
33enum cip_flags { 36enum cip_flags {
34 CIP_NONBLOCKING = 0x00, 37 CIP_NONBLOCKING = 0x00,
@@ -39,6 +42,8 @@ enum cip_flags {
39 CIP_SKIP_DBC_ZERO_CHECK = 0x10, 42 CIP_SKIP_DBC_ZERO_CHECK = 0x10,
40 CIP_EMPTY_HAS_WRONG_DBC = 0x20, 43 CIP_EMPTY_HAS_WRONG_DBC = 0x20,
41 CIP_JUMBO_PAYLOAD = 0x40, 44 CIP_JUMBO_PAYLOAD = 0x40,
45 CIP_HEADER_WITHOUT_EOH = 0x80,
46 CIP_NO_HEADER = 0x100,
42}; 47};
43 48
44/** 49/**
@@ -101,11 +106,17 @@ struct amdtp_stream {
101 struct fw_iso_context *context; 106 struct fw_iso_context *context;
102 struct iso_packets_buffer buffer; 107 struct iso_packets_buffer buffer;
103 int packet_index; 108 int packet_index;
109 int tag;
110 int (*handle_packet)(struct amdtp_stream *s,
111 unsigned int payload_quadlets, unsigned int cycle,
112 unsigned int index);
113 unsigned int max_payload_length;
104 114
105 /* For CIP headers. */ 115 /* For CIP headers. */
106 unsigned int source_node_id_field; 116 unsigned int source_node_id_field;
107 unsigned int data_block_quadlets; 117 unsigned int data_block_quadlets;
108 unsigned int data_block_counter; 118 unsigned int data_block_counter;
119 unsigned int sph;
109 unsigned int fmt; 120 unsigned int fmt;
110 unsigned int fdf; 121 unsigned int fdf;
111 /* quirk: fixed interval of dbc between previos/current packets. */ 122 /* quirk: fixed interval of dbc between previos/current packets. */
@@ -130,6 +141,7 @@ struct amdtp_stream {
130 /* To wait for first packet. */ 141 /* To wait for first packet. */
131 bool callbacked; 142 bool callbacked;
132 wait_queue_head_t callback_wait; 143 wait_queue_head_t callback_wait;
144 u32 start_cycle;
133 145
134 /* For backends to process data blocks. */ 146 /* For backends to process data blocks. */
135 void *protocol; 147 void *protocol;
diff --git a/sound/firewire/bebob/bebob_command.c b/sound/firewire/bebob/bebob_command.c
index 9402cc15dbc1..f9b4225dd86f 100644
--- a/sound/firewire/bebob/bebob_command.c
+++ b/sound/firewire/bebob/bebob_command.c
@@ -31,13 +31,15 @@ int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
31 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 31 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
33 BIT(6) | BIT(7) | BIT(8)); 33 BIT(6) | BIT(7) | BIT(8));
34 if (err > 0 && err < 9) 34 if (err < 0)
35 ;
36 else if (err < 9)
35 err = -EIO; 37 err = -EIO;
36 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 38 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
37 err = -ENOSYS; 39 err = -ENOSYS;
38 else if (buf[0] == 0x0a) /* REJECTED */ 40 else if (buf[0] == 0x0a) /* REJECTED */
39 err = -EINVAL; 41 err = -EINVAL;
40 else if (err > 0) 42 else
41 err = 0; 43 err = 0;
42 44
43 kfree(buf); 45 kfree(buf);
@@ -67,7 +69,9 @@ int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
67 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 69 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
68 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 70 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
69 BIT(6) | BIT(8)); 71 BIT(6) | BIT(8));
70 if (err > 0 && err < 9) 72 if (err < 0)
73 ;
74 else if (err < 9)
71 err = -EIO; 75 err = -EIO;
72 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 76 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
73 err = -ENOSYS; 77 err = -ENOSYS;
@@ -120,7 +124,9 @@ int avc_bridgeco_get_plug_type(struct fw_unit *unit,
120 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 124 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
121 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 125 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
122 BIT(6) | BIT(7) | BIT(9)); 126 BIT(6) | BIT(7) | BIT(9));
123 if ((err >= 0) && (err < 8)) 127 if (err < 0)
128 ;
129 else if (err < 11)
124 err = -EIO; 130 err = -EIO;
125 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 131 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
126 err = -ENOSYS; 132 err = -ENOSYS;
@@ -150,7 +156,9 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
150 err = fcp_avc_transaction(unit, buf, 12, buf, 256, 156 err = fcp_avc_transaction(unit, buf, 12, buf, 256,
151 BIT(1) | BIT(2) | BIT(3) | BIT(4) | 157 BIT(1) | BIT(2) | BIT(3) | BIT(4) |
152 BIT(5) | BIT(6) | BIT(7) | BIT(9)); 158 BIT(5) | BIT(6) | BIT(7) | BIT(9));
153 if ((err >= 0) && (err < 8)) 159 if (err < 0)
160 ;
161 else if (err < 11)
154 err = -EIO; 162 err = -EIO;
155 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 163 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
156 err = -ENOSYS; 164 err = -ENOSYS;
@@ -187,7 +195,9 @@ int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
187 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 195 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
188 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 196 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
189 BIT(6) | BIT(7) | BIT(9) | BIT(10)); 197 BIT(6) | BIT(7) | BIT(9) | BIT(10));
190 if ((err >= 0) && (err < 8)) 198 if (err < 0)
199 ;
200 else if (err < 12)
191 err = -EIO; 201 err = -EIO;
192 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 202 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
193 err = -ENOSYS; 203 err = -ENOSYS;
@@ -221,7 +231,9 @@ int avc_bridgeco_get_plug_input(struct fw_unit *unit,
221 err = fcp_avc_transaction(unit, buf, 16, buf, 16, 231 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
222 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 232 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
223 BIT(6) | BIT(7)); 233 BIT(6) | BIT(7));
224 if ((err >= 0) && (err < 8)) 234 if (err < 0)
235 ;
236 else if (err < 16)
225 err = -EIO; 237 err = -EIO;
226 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 238 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
227 err = -ENOSYS; 239 err = -ENOSYS;
@@ -260,7 +272,9 @@ int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
260 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 272 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
261 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 273 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
262 BIT(6) | BIT(7) | BIT(10)); 274 BIT(6) | BIT(7) | BIT(10));
263 if ((err >= 0) && (err < 12)) 275 if (err < 0)
276 ;
277 else if (err < 12)
264 err = -EIO; 278 err = -EIO;
265 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 279 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
266 err = -ENOSYS; 280 err = -ENOSYS;
diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c
index b3cffd01a19f..a4688545339c 100644
--- a/sound/firewire/digi00x/amdtp-dot.c
+++ b/sound/firewire/digi00x/amdtp-dot.c
@@ -28,6 +28,9 @@
28 */ 28 */
29#define MAX_MIDI_RX_BLOCKS 8 29#define MAX_MIDI_RX_BLOCKS 8
30 30
31/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */
32#define MAX_MIDI_PORTS 3
33
31/* 34/*
32 * The double-oh-three algorithm was discovered by Robin Gareus and Damien 35 * The double-oh-three algorithm was discovered by Robin Gareus and Damien
33 * Zammit in 2012, with reverse-engineering for Digi 003 Rack. 36 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.
@@ -42,10 +45,8 @@ struct amdtp_dot {
42 unsigned int pcm_channels; 45 unsigned int pcm_channels;
43 struct dot_state state; 46 struct dot_state state;
44 47
45 unsigned int midi_ports; 48 struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];
46 /* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */ 49 int midi_fifo_used[MAX_MIDI_PORTS];
47 struct snd_rawmidi_substream *midi[2];
48 int midi_fifo_used[2];
49 int midi_fifo_limit; 50 int midi_fifo_limit;
50 51
51 void (*transfer_samples)(struct amdtp_stream *s, 52 void (*transfer_samples)(struct amdtp_stream *s,
@@ -124,8 +125,8 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
124 return -EBUSY; 125 return -EBUSY;
125 126
126 /* 127 /*
127 * A first data channel is for MIDI conformant data channel, the rest is 128 * A first data channel is for MIDI messages, the rest is Multi Bit
128 * Multi Bit Linear Audio data channel. 129 * Linear Audio data channel.
129 */ 130 */
130 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1); 131 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);
131 if (err < 0) 132 if (err < 0)
@@ -135,11 +136,6 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
135 136
136 p->pcm_channels = pcm_channels; 137 p->pcm_channels = pcm_channels;
137 138
138 if (s->direction == AMDTP_IN_STREAM)
139 p->midi_ports = DOT_MIDI_IN_PORTS;
140 else
141 p->midi_ports = DOT_MIDI_OUT_PORTS;
142
143 /* 139 /*
144 * We do not know the actual MIDI FIFO size of most devices. Just 140 * We do not know the actual MIDI FIFO size of most devices. Just
145 * assume two bytes, i.e., one byte can be received over the bus while 141 * assume two bytes, i.e., one byte can be received over the bus while
@@ -281,13 +277,25 @@ static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
281 b = (u8 *)&buffer[0]; 277 b = (u8 *)&buffer[0];
282 278
283 len = 0; 279 len = 0;
284 if (port < p->midi_ports && 280 if (port < MAX_MIDI_PORTS &&
285 midi_ratelimit_per_packet(s, port) && 281 midi_ratelimit_per_packet(s, port) &&
286 p->midi[port] != NULL) 282 p->midi[port] != NULL)
287 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2); 283 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
288 284
289 if (len > 0) { 285 if (len > 0) {
290 b[3] = (0x10 << port) | len; 286 /*
287 * Upper 4 bits of LSB represent port number.
288 * - 0000b: physical MIDI port 1.
289 * - 0010b: physical MIDI port 2.
290 * - 1110b: console MIDI port.
291 */
292 if (port == 2)
293 b[3] = 0xe0;
294 else if (port == 1)
295 b[3] = 0x20;
296 else
297 b[3] = 0x00;
298 b[3] |= len;
291 midi_use_bytes(s, port, len); 299 midi_use_bytes(s, port, len);
292 } else { 300 } else {
293 b[1] = 0; 301 b[1] = 0;
@@ -309,11 +317,22 @@ static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
309 317
310 for (f = 0; f < data_blocks; f++) { 318 for (f = 0; f < data_blocks; f++) {
311 b = (u8 *)&buffer[0]; 319 b = (u8 *)&buffer[0];
312 port = b[3] >> 4;
313 len = b[3] & 0x0f;
314 320
315 if (port < p->midi_ports && p->midi[port] && len > 0) 321 len = b[3] & 0x0f;
316 snd_rawmidi_receive(p->midi[port], b + 1, len); 322 if (len > 0) {
323 /*
324 * Upper 4 bits of LSB represent port number.
325 * - 0000b: physical MIDI port 1. Use port 0.
326 * - 1110b: console MIDI port. Use port 2.
327 */
328 if (b[3] >> 4 > 0)
329 port = 2;
330 else
331 port = 0;
332
333 if (port < MAX_MIDI_PORTS && p->midi[port])
334 snd_rawmidi_receive(p->midi[port], b + 1, len);
335 }
317 336
318 buffer += s->data_block_quadlets; 337 buffer += s->data_block_quadlets;
319 } 338 }
@@ -364,7 +383,7 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
364{ 383{
365 struct amdtp_dot *p = s->protocol; 384 struct amdtp_dot *p = s->protocol;
366 385
367 if (port < p->midi_ports) 386 if (port < MAX_MIDI_PORTS)
368 ACCESS_ONCE(p->midi[port]) = midi; 387 ACCESS_ONCE(p->midi[port]) = midi;
369} 388}
370 389
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c
index 915d2a21223e..7ab3d0810f6b 100644
--- a/sound/firewire/digi00x/digi00x-midi.c
+++ b/sound/firewire/digi00x/digi00x-midi.c
@@ -8,7 +8,7 @@
8 8
9#include "digi00x.h" 9#include "digi00x.h"
10 10
11static int midi_phys_open(struct snd_rawmidi_substream *substream) 11static int midi_open(struct snd_rawmidi_substream *substream)
12{ 12{
13 struct snd_dg00x *dg00x = substream->rmidi->private_data; 13 struct snd_dg00x *dg00x = substream->rmidi->private_data;
14 int err; 14 int err;
@@ -27,7 +27,7 @@ static int midi_phys_open(struct snd_rawmidi_substream *substream)
27 return err; 27 return err;
28} 28}
29 29
30static int midi_phys_close(struct snd_rawmidi_substream *substream) 30static int midi_close(struct snd_rawmidi_substream *substream)
31{ 31{
32 struct snd_dg00x *dg00x = substream->rmidi->private_data; 32 struct snd_dg00x *dg00x = substream->rmidi->private_data;
33 33
@@ -40,180 +40,130 @@ static int midi_phys_close(struct snd_rawmidi_substream *substream)
40 return 0; 40 return 0;
41} 41}
42 42
43static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, 43static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
44 int up) 44 int up)
45{ 45{
46 struct snd_dg00x *dg00x = substream->rmidi->private_data; 46 struct snd_dg00x *dg00x = substream->rmidi->private_data;
47 unsigned int port;
47 unsigned long flags; 48 unsigned long flags;
48 49
49 spin_lock_irqsave(&dg00x->lock, flags); 50 if (substream->rmidi->device == 0)
50 51 port = substream->number;
51 if (up)
52 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
53 substream);
54 else 52 else
55 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, 53 port = 2;
56 NULL);
57
58 spin_unlock_irqrestore(&dg00x->lock, flags);
59}
60
61static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream,
62 int up)
63{
64 struct snd_dg00x *dg00x = substream->rmidi->private_data;
65 unsigned long flags;
66 54
67 spin_lock_irqsave(&dg00x->lock, flags); 55 spin_lock_irqsave(&dg00x->lock, flags);
68 56
69 if (up) 57 if (up)
70 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 58 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
71 substream);
72 else 59 else
73 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 60 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
74 NULL);
75 61
76 spin_unlock_irqrestore(&dg00x->lock, flags); 62 spin_unlock_irqrestore(&dg00x->lock, flags);
77} 63}
78 64
79static int midi_ctl_open(struct snd_rawmidi_substream *substream) 65static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
80{ 66 int up)
81 /* Do nothing. */
82 return 0;
83}
84
85static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream)
86{
87 /* Do nothing. */
88 return 0;
89}
90
91static int midi_ctl_playback_close(struct snd_rawmidi_substream *substream)
92{
93 struct snd_dg00x *dg00x = substream->rmidi->private_data;
94
95 snd_fw_async_midi_port_finish(&dg00x->out_control);
96
97 return 0;
98}
99
100static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream,
101 int up)
102{ 67{
103 struct snd_dg00x *dg00x = substream->rmidi->private_data; 68 struct snd_dg00x *dg00x = substream->rmidi->private_data;
69 unsigned int port;
104 unsigned long flags; 70 unsigned long flags;
105 71
106 spin_lock_irqsave(&dg00x->lock, flags); 72 if (substream->rmidi->device == 0)
107 73 port = substream->number;
108 if (up)
109 dg00x->in_control = substream;
110 else 74 else
111 dg00x->in_control = NULL; 75 port = 2;
112
113 spin_unlock_irqrestore(&dg00x->lock, flags);
114}
115
116static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream,
117 int up)
118{
119 struct snd_dg00x *dg00x = substream->rmidi->private_data;
120 unsigned long flags;
121 76
122 spin_lock_irqsave(&dg00x->lock, flags); 77 spin_lock_irqsave(&dg00x->lock, flags);
123 78
124 if (up) 79 if (up)
125 snd_fw_async_midi_port_run(&dg00x->out_control, substream); 80 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
81 else
82 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
126 83
127 spin_unlock_irqrestore(&dg00x->lock, flags); 84 spin_unlock_irqrestore(&dg00x->lock, flags);
128} 85}
129 86
130static void set_midi_substream_names(struct snd_dg00x *dg00x, 87static void set_substream_names(struct snd_dg00x *dg00x,
131 struct snd_rawmidi_str *str, 88 struct snd_rawmidi *rmidi, bool is_console)
132 bool is_ctl)
133{ 89{
134 struct snd_rawmidi_substream *subs; 90 struct snd_rawmidi_substream *subs;
135 91 struct snd_rawmidi_str *str;
136 list_for_each_entry(subs, &str->substreams, list) { 92 int i;
137 if (!is_ctl) 93
138 snprintf(subs->name, sizeof(subs->name), 94 for (i = 0; i < 2; ++i) {
139 "%s MIDI %d", 95 str = &rmidi->streams[i];
140 dg00x->card->shortname, subs->number + 1); 96
141 else 97 list_for_each_entry(subs, &str->substreams, list) {
142 /* This port is for asynchronous transaction. */ 98 if (!is_console) {
143 snprintf(subs->name, sizeof(subs->name), 99 snprintf(subs->name, sizeof(subs->name),
144 "%s control", 100 "%s MIDI %d",
145 dg00x->card->shortname); 101 dg00x->card->shortname,
102 subs->number + 1);
103 } else {
104 snprintf(subs->name, sizeof(subs->name),
105 "%s control",
106 dg00x->card->shortname);
107 }
108 }
146 } 109 }
147} 110}
148 111
149int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) 112static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,
113 unsigned int in_ports, bool is_console)
150{ 114{
151 static const struct snd_rawmidi_ops phys_capture_ops = { 115 static const struct snd_rawmidi_ops capture_ops = {
152 .open = midi_phys_open, 116 .open = midi_open,
153 .close = midi_phys_close, 117 .close = midi_close,
154 .trigger = midi_phys_capture_trigger, 118 .trigger = midi_capture_trigger,
155 };
156 static const struct snd_rawmidi_ops phys_playback_ops = {
157 .open = midi_phys_open,
158 .close = midi_phys_close,
159 .trigger = midi_phys_playback_trigger,
160 }; 119 };
161 static const struct snd_rawmidi_ops ctl_capture_ops = { 120 static const struct snd_rawmidi_ops playback_ops = {
162 .open = midi_ctl_open, 121 .open = midi_open,
163 .close = midi_ctl_capture_close, 122 .close = midi_close,
164 .trigger = midi_ctl_capture_trigger, 123 .trigger = midi_playback_trigger,
165 }; 124 };
166 static const struct snd_rawmidi_ops ctl_playback_ops = { 125 const char *label;
167 .open = midi_ctl_open, 126 struct snd_rawmidi *rmidi;
168 .close = midi_ctl_playback_close,
169 .trigger = midi_ctl_playback_trigger,
170 };
171 struct snd_rawmidi *rmidi[2];
172 struct snd_rawmidi_str *str;
173 unsigned int i;
174 int err; 127 int err;
175 128
176 /* Add physical midi ports. */ 129 /* Add physical midi ports. */
177 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, 130 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,
178 DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]); 131 out_ports, in_ports, &rmidi);
179 if (err < 0) 132 if (err < 0)
180 return err; 133 return err;
134 rmidi->private_data = dg00x;
181 135
182 snprintf(rmidi[0]->name, sizeof(rmidi[0]->name), 136 if (!is_console)
183 "%s MIDI", dg00x->card->shortname); 137 label = "%s control";
184 138 else
185 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT, 139 label = "%s MIDI";
186 &phys_capture_ops); 140 snprintf(rmidi->name, sizeof(rmidi->name), label,
187 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT, 141 dg00x->card->shortname);
188 &phys_playback_ops);
189 142
190 /* Add a pair of control midi ports. */ 143 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);
191 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1, 144 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);
192 1, 1, &rmidi[1]);
193 if (err < 0)
194 return err;
195 145
196 snprintf(rmidi[1]->name, sizeof(rmidi[1]->name), 146 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
197 "%s control", dg00x->card->shortname); 147 SNDRV_RAWMIDI_INFO_OUTPUT |
148 SNDRV_RAWMIDI_INFO_DUPLEX;
198 149
199 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT, 150 set_substream_names(dg00x, rmidi, is_console);
200 &ctl_capture_ops);
201 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT,
202 &ctl_playback_ops);
203 151
204 for (i = 0; i < ARRAY_SIZE(rmidi); i++) { 152 return 0;
205 rmidi[i]->private_data = dg00x; 153}
206 154
207 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 155int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
208 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT]; 156{
209 set_midi_substream_names(dg00x, str, i); 157 int err;
210 158
211 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 159 /* Add physical midi ports. */
212 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; 160 err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,
213 set_midi_substream_names(dg00x, str, i); 161 false);
162 if (err < 0)
163 return err;
214 164
215 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 165 if (dg00x->is_console)
216 } 166 err = add_substream_pair(dg00x, 1, 1, true);
217 167
218 return 0; 168 return err;
219} 169}
diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
index 735d35640807..af9bc8504781 100644
--- a/sound/firewire/digi00x/digi00x-transaction.c
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -9,40 +9,6 @@
9#include <sound/asound.h> 9#include <sound/asound.h>
10#include "digi00x.h" 10#include "digi00x.h"
11 11
12static int fill_midi_message(struct snd_rawmidi_substream *substream, u8 *buf)
13{
14 int bytes;
15
16 buf[0] = 0x80;
17 bytes = snd_rawmidi_transmit_peek(substream, buf + 1, 2);
18 if (bytes >= 0)
19 buf[3] = 0xc0 | bytes;
20
21 return bytes;
22}
23
24static void handle_midi_control(struct snd_dg00x *dg00x, __be32 *buf,
25 unsigned int length)
26{
27 struct snd_rawmidi_substream *substream;
28 unsigned int i;
29 unsigned int len;
30 u8 *b;
31
32 substream = ACCESS_ONCE(dg00x->in_control);
33 if (substream == NULL)
34 return;
35
36 length /= 4;
37
38 for (i = 0; i < length; i++) {
39 b = (u8 *)&buf[i];
40 len = b[3] & 0xf;
41 if (len > 0)
42 snd_rawmidi_receive(dg00x->in_control, b + 1, len);
43 }
44}
45
46static void handle_unknown_message(struct snd_dg00x *dg00x, 12static void handle_unknown_message(struct snd_dg00x *dg00x,
47 unsigned long long offset, __be32 *buf) 13 unsigned long long offset, __be32 *buf)
48{ 14{
@@ -63,39 +29,36 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
63 struct snd_dg00x *dg00x = callback_data; 29 struct snd_dg00x *dg00x = callback_data;
64 __be32 *buf = (__be32 *)data; 30 __be32 *buf = (__be32 *)data;
65 31
32 fw_send_response(card, request, RCODE_COMPLETE);
33
66 if (offset == dg00x->async_handler.offset) 34 if (offset == dg00x->async_handler.offset)
67 handle_unknown_message(dg00x, offset, buf); 35 handle_unknown_message(dg00x, offset, buf);
68 else if (offset == dg00x->async_handler.offset + 4)
69 handle_midi_control(dg00x, buf, length);
70
71 fw_send_response(card, request, RCODE_COMPLETE);
72} 36}
73 37
74int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x) 38int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x)
75{ 39{
76 struct fw_device *device = fw_parent_device(dg00x->unit); 40 struct fw_device *device = fw_parent_device(dg00x->unit);
77 __be32 data[2]; 41 __be32 data[2];
78 int err;
79 42
80 /* Unknown. 4bytes. */ 43 /* Unknown. 4bytes. */
81 data[0] = cpu_to_be32((device->card->node_id << 16) | 44 data[0] = cpu_to_be32((device->card->node_id << 16) |
82 (dg00x->async_handler.offset >> 32)); 45 (dg00x->async_handler.offset >> 32));
83 data[1] = cpu_to_be32(dg00x->async_handler.offset); 46 data[1] = cpu_to_be32(dg00x->async_handler.offset);
84 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
85 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
86 &data, sizeof(data), 0);
87 if (err < 0)
88 return err;
89
90 /* Asynchronous transactions for MIDI control message. */
91 data[0] = cpu_to_be32((device->card->node_id << 16) |
92 (dg00x->async_handler.offset >> 32));
93 data[1] = cpu_to_be32(dg00x->async_handler.offset + 4);
94 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST, 47 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
95 DG00X_ADDR_BASE + DG00X_OFFSET_MIDI_CTL_ADDR, 48 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
96 &data, sizeof(data), 0); 49 &data, sizeof(data), 0);
97} 50}
98 51
52void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
53{
54 if (dg00x->async_handler.callback_data == NULL)
55 return;
56
57 fw_core_remove_address_handler(&dg00x->async_handler);
58
59 dg00x->async_handler.callback_data = NULL;
60}
61
99int snd_dg00x_transaction_register(struct snd_dg00x *dg00x) 62int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
100{ 63{
101 static const struct fw_address_region resp_register_region = { 64 static const struct fw_address_region resp_register_region = {
@@ -104,7 +67,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
104 }; 67 };
105 int err; 68 int err;
106 69
107 dg00x->async_handler.length = 12; 70 dg00x->async_handler.length = 4;
108 dg00x->async_handler.address_callback = handle_message; 71 dg00x->async_handler.address_callback = handle_message;
109 dg00x->async_handler.callback_data = dg00x; 72 dg00x->async_handler.callback_data = dg00x;
110 73
@@ -115,28 +78,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
115 78
116 err = snd_dg00x_transaction_reregister(dg00x); 79 err = snd_dg00x_transaction_reregister(dg00x);
117 if (err < 0) 80 if (err < 0)
118 goto error; 81 snd_dg00x_transaction_unregister(dg00x);
119
120 err = snd_fw_async_midi_port_init(&dg00x->out_control, dg00x->unit,
121 DG00X_ADDR_BASE + DG00X_OFFSET_MMC,
122 4, fill_midi_message);
123 if (err < 0)
124 goto error;
125 82
126 return err; 83 return err;
127error:
128 fw_core_remove_address_handler(&dg00x->async_handler);
129 dg00x->async_handler.callback_data = NULL;
130 return err;
131}
132
133void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
134{
135 if (dg00x->async_handler.callback_data == NULL)
136 return;
137
138 snd_fw_async_midi_port_destroy(&dg00x->out_control);
139 fw_core_remove_address_handler(&dg00x->async_handler);
140
141 dg00x->async_handler.callback_data = NULL;
142} 84}
diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
index cc4776c6ded3..1f5e1d23f31a 100644
--- a/sound/firewire/digi00x/digi00x.c
+++ b/sound/firewire/digi00x/digi00x.c
@@ -13,7 +13,8 @@ MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
13MODULE_LICENSE("GPL v2"); 13MODULE_LICENSE("GPL v2");
14 14
15#define VENDOR_DIGIDESIGN 0x00a07e 15#define VENDOR_DIGIDESIGN 0x00a07e
16#define MODEL_DIGI00X 0x000002 16#define MODEL_CONSOLE 0x000001
17#define MODEL_RACK 0x000002
17 18
18static int name_card(struct snd_dg00x *dg00x) 19static int name_card(struct snd_dg00x *dg00x)
19{ 20{
@@ -129,6 +130,8 @@ static int snd_dg00x_probe(struct fw_unit *unit,
129 spin_lock_init(&dg00x->lock); 130 spin_lock_init(&dg00x->lock);
130 init_waitqueue_head(&dg00x->hwdep_wait); 131 init_waitqueue_head(&dg00x->hwdep_wait);
131 132
133 dg00x->is_console = entry->model_id == MODEL_CONSOLE;
134
132 /* Allocate and register this sound card later. */ 135 /* Allocate and register this sound card later. */
133 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); 136 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration);
134 snd_fw_schedule_registration(unit, &dg00x->dwork); 137 snd_fw_schedule_registration(unit, &dg00x->dwork);
@@ -183,7 +186,13 @@ static const struct ieee1394_device_id snd_dg00x_id_table[] = {
183 .match_flags = IEEE1394_MATCH_VENDOR_ID | 186 .match_flags = IEEE1394_MATCH_VENDOR_ID |
184 IEEE1394_MATCH_MODEL_ID, 187 IEEE1394_MATCH_MODEL_ID,
185 .vendor_id = VENDOR_DIGIDESIGN, 188 .vendor_id = VENDOR_DIGIDESIGN,
186 .model_id = MODEL_DIGI00X, 189 .model_id = MODEL_CONSOLE,
190 },
191 {
192 .match_flags = IEEE1394_MATCH_VENDOR_ID |
193 IEEE1394_MATCH_MODEL_ID,
194 .vendor_id = VENDOR_DIGIDESIGN,
195 .model_id = MODEL_RACK,
187 }, 196 },
188 {} 197 {}
189}; 198};
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
index 9dc761bdacca..1275a50956c0 100644
--- a/sound/firewire/digi00x/digi00x.h
+++ b/sound/firewire/digi00x/digi00x.h
@@ -58,16 +58,15 @@ struct snd_dg00x {
58 struct fw_address_handler async_handler; 58 struct fw_address_handler async_handler;
59 u32 msg; 59 u32 msg;
60 60
61 /* For asynchronous MIDI controls. */ 61 /* Console models have additional MIDI ports for control surface. */
62 struct snd_rawmidi_substream *in_control; 62 bool is_console;
63 struct snd_fw_async_midi_port out_control;
64}; 63};
65 64
66#define DG00X_ADDR_BASE 0xffffe0000000ull 65#define DG00X_ADDR_BASE 0xffffe0000000ull
67 66
68#define DG00X_OFFSET_STREAMING_STATE 0x0000 67#define DG00X_OFFSET_STREAMING_STATE 0x0000
69#define DG00X_OFFSET_STREAMING_SET 0x0004 68#define DG00X_OFFSET_STREAMING_SET 0x0004
70#define DG00X_OFFSET_MIDI_CTL_ADDR 0x0008 69/* unknown but address in host space 0x0008 */
71/* For LSB of the address 0x000c */ 70/* For LSB of the address 0x000c */
72/* unknown 0x0010 */ 71/* unknown 0x0010 */
73#define DG00X_OFFSET_MESSAGE_ADDR 0x0014 72#define DG00X_OFFSET_MESSAGE_ADDR 0x0014
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
index cce19768f43d..61dda828f767 100644
--- a/sound/firewire/fcp.c
+++ b/sound/firewire/fcp.c
@@ -63,7 +63,9 @@ int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate,
63 /* do transaction and check buf[1-5] are the same against command */ 63 /* do transaction and check buf[1-5] are the same against command */
64 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 64 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
66 if (err >= 0 && err < 8) 66 if (err < 0)
67 ;
68 else if (err < 8)
67 err = -EIO; 69 err = -EIO;
68 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 70 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
69 err = -ENOSYS; 71 err = -ENOSYS;
@@ -106,7 +108,9 @@ int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate,
106 /* do transaction and check buf[1-4] are the same against command */ 108 /* do transaction and check buf[1-4] are the same against command */
107 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 109 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
108 BIT(1) | BIT(2) | BIT(3) | BIT(4)); 110 BIT(1) | BIT(2) | BIT(3) | BIT(4));
109 if (err >= 0 && err < 8) 111 if (err < 0)
112 ;
113 else if (err < 8)
110 err = -EIO; 114 err = -EIO;
111 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 115 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
112 err = -ENOSYS; 116 err = -ENOSYS;
@@ -154,7 +158,9 @@ int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type,
154 buf[3] = 0xff & subfunction; 158 buf[3] = 0xff & subfunction;
155 159
156 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); 160 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));
157 if (err >= 0 && err < 8) 161 if (err < 0)
162 ;
163 else if (err < 8)
158 err = -EIO; 164 err = -EIO;
159 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 165 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
160 err = -ENOSYS; 166 err = -ENOSYS;
diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile
new file mode 100644
index 000000000000..8f807284ba54
--- /dev/null
+++ b/sound/firewire/fireface/Makefile
@@ -0,0 +1,3 @@
1snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \
2 ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o
3obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o
diff --git a/sound/firewire/fireface/amdtp-ff.c b/sound/firewire/fireface/amdtp-ff.c
new file mode 100644
index 000000000000..780da9deb2f0
--- /dev/null
+++ b/sound/firewire/fireface/amdtp-ff.c
@@ -0,0 +1,155 @@
1/*
2 * amdtp-ff.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <sound/pcm.h>
10#include "ff.h"
11
12struct amdtp_ff {
13 unsigned int pcm_channels;
14};
15
16int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,
17 unsigned int pcm_channels)
18{
19 struct amdtp_ff *p = s->protocol;
20 unsigned int data_channels;
21
22 if (amdtp_stream_running(s))
23 return -EBUSY;
24
25 p->pcm_channels = pcm_channels;
26 data_channels = pcm_channels;
27
28 return amdtp_stream_set_parameters(s, rate, data_channels);
29}
30
31static void write_pcm_s32(struct amdtp_stream *s,
32 struct snd_pcm_substream *pcm,
33 __le32 *buffer, unsigned int frames)
34{
35 struct amdtp_ff *p = s->protocol;
36 struct snd_pcm_runtime *runtime = pcm->runtime;
37 unsigned int channels, remaining_frames, i, c;
38 const u32 *src;
39
40 channels = p->pcm_channels;
41 src = (void *)runtime->dma_area +
42 frames_to_bytes(runtime, s->pcm_buffer_pointer);
43 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
44
45 for (i = 0; i < frames; ++i) {
46 for (c = 0; c < channels; ++c) {
47 buffer[c] = cpu_to_le32(*src);
48 src++;
49 }
50 buffer += s->data_block_quadlets;
51 if (--remaining_frames == 0)
52 src = (void *)runtime->dma_area;
53 }
54}
55
56static void read_pcm_s32(struct amdtp_stream *s,
57 struct snd_pcm_substream *pcm,
58 __le32 *buffer, unsigned int frames)
59{
60 struct amdtp_ff *p = s->protocol;
61 struct snd_pcm_runtime *runtime = pcm->runtime;
62 unsigned int channels, remaining_frames, i, c;
63 u32 *dst;
64
65 channels = p->pcm_channels;
66 dst = (void *)runtime->dma_area +
67 frames_to_bytes(runtime, s->pcm_buffer_pointer);
68 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
69
70 for (i = 0; i < frames; ++i) {
71 for (c = 0; c < channels; ++c) {
72 *dst = le32_to_cpu(buffer[c]) & 0xffffff00;
73 dst++;
74 }
75 buffer += s->data_block_quadlets;
76 if (--remaining_frames == 0)
77 dst = (void *)runtime->dma_area;
78 }
79}
80
81static void write_pcm_silence(struct amdtp_stream *s,
82 __le32 *buffer, unsigned int frames)
83{
84 struct amdtp_ff *p = s->protocol;
85 unsigned int i, c, channels = p->pcm_channels;
86
87 for (i = 0; i < frames; ++i) {
88 for (c = 0; c < channels; ++c)
89 buffer[c] = cpu_to_le32(0x00000000);
90 buffer += s->data_block_quadlets;
91 }
92}
93
94int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
95 struct snd_pcm_runtime *runtime)
96{
97 int err;
98
99 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
100 if (err < 0)
101 return err;
102
103 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
104}
105
106static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
107 __be32 *buffer,
108 unsigned int data_blocks,
109 unsigned int *syt)
110{
111 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
112 unsigned int pcm_frames;
113
114 if (pcm) {
115 write_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks);
116 pcm_frames = data_blocks;
117 } else {
118 write_pcm_silence(s, (__le32 *)buffer, data_blocks);
119 pcm_frames = 0;
120 }
121
122 return pcm_frames;
123}
124
125static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
126 __be32 *buffer,
127 unsigned int data_blocks,
128 unsigned int *syt)
129{
130 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
131 unsigned int pcm_frames;
132
133 if (pcm) {
134 read_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks);
135 pcm_frames = data_blocks;
136 } else {
137 pcm_frames = 0;
138 }
139
140 return pcm_frames;
141}
142
143int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
144 enum amdtp_stream_direction dir)
145{
146 amdtp_stream_process_data_blocks_t process_data_blocks;
147
148 if (dir == AMDTP_IN_STREAM)
149 process_data_blocks = process_tx_data_blocks;
150 else
151 process_data_blocks = process_rx_data_blocks;
152
153 return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0,
154 process_data_blocks, sizeof(struct amdtp_ff));
155}
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c
new file mode 100644
index 000000000000..3ee04b054585
--- /dev/null
+++ b/sound/firewire/fireface/ff-hwdep.c
@@ -0,0 +1,191 @@
1/*
2 * ff-hwdep.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9/*
10 * This codes give three functionality.
11 *
12 * 1.get firewire node information
13 * 2.get notification about starting/stopping stream
14 * 3.lock/unlock stream
15 */
16
17#include "ff.h"
18
19static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
20 loff_t *offset)
21{
22 struct snd_ff *ff = hwdep->private_data;
23 DEFINE_WAIT(wait);
24 union snd_firewire_event event;
25
26 spin_lock_irq(&ff->lock);
27
28 while (!ff->dev_lock_changed) {
29 prepare_to_wait(&ff->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
30 spin_unlock_irq(&ff->lock);
31 schedule();
32 finish_wait(&ff->hwdep_wait, &wait);
33 if (signal_pending(current))
34 return -ERESTARTSYS;
35 spin_lock_irq(&ff->lock);
36 }
37
38 memset(&event, 0, sizeof(event));
39 if (ff->dev_lock_changed) {
40 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
41 event.lock_status.status = (ff->dev_lock_count > 0);
42 ff->dev_lock_changed = false;
43
44 count = min_t(long, count, sizeof(event.lock_status));
45 }
46
47 spin_unlock_irq(&ff->lock);
48
49 if (copy_to_user(buf, &event, count))
50 return -EFAULT;
51
52 return count;
53}
54
55static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
56 poll_table *wait)
57{
58 struct snd_ff *ff = hwdep->private_data;
59 unsigned int events;
60
61 poll_wait(file, &ff->hwdep_wait, wait);
62
63 spin_lock_irq(&ff->lock);
64 if (ff->dev_lock_changed)
65 events = POLLIN | POLLRDNORM;
66 else
67 events = 0;
68 spin_unlock_irq(&ff->lock);
69
70 return events;
71}
72
73static int hwdep_get_info(struct snd_ff *ff, void __user *arg)
74{
75 struct fw_device *dev = fw_parent_device(ff->unit);
76 struct snd_firewire_get_info info;
77
78 memset(&info, 0, sizeof(info));
79 info.type = SNDRV_FIREWIRE_TYPE_FIREFACE;
80 info.card = dev->card->index;
81 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
82 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
83 strlcpy(info.device_name, dev_name(&dev->device),
84 sizeof(info.device_name));
85
86 if (copy_to_user(arg, &info, sizeof(info)))
87 return -EFAULT;
88
89 return 0;
90}
91
92static int hwdep_lock(struct snd_ff *ff)
93{
94 int err;
95
96 spin_lock_irq(&ff->lock);
97
98 if (ff->dev_lock_count == 0) {
99 ff->dev_lock_count = -1;
100 err = 0;
101 } else {
102 err = -EBUSY;
103 }
104
105 spin_unlock_irq(&ff->lock);
106
107 return err;
108}
109
110static int hwdep_unlock(struct snd_ff *ff)
111{
112 int err;
113
114 spin_lock_irq(&ff->lock);
115
116 if (ff->dev_lock_count == -1) {
117 ff->dev_lock_count = 0;
118 err = 0;
119 } else {
120 err = -EBADFD;
121 }
122
123 spin_unlock_irq(&ff->lock);
124
125 return err;
126}
127
128static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
129{
130 struct snd_ff *ff = hwdep->private_data;
131
132 spin_lock_irq(&ff->lock);
133 if (ff->dev_lock_count == -1)
134 ff->dev_lock_count = 0;
135 spin_unlock_irq(&ff->lock);
136
137 return 0;
138}
139
140static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
141 unsigned int cmd, unsigned long arg)
142{
143 struct snd_ff *ff = hwdep->private_data;
144
145 switch (cmd) {
146 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
147 return hwdep_get_info(ff, (void __user *)arg);
148 case SNDRV_FIREWIRE_IOCTL_LOCK:
149 return hwdep_lock(ff);
150 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
151 return hwdep_unlock(ff);
152 default:
153 return -ENOIOCTLCMD;
154 }
155}
156
157#ifdef CONFIG_COMPAT
158static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
159 unsigned int cmd, unsigned long arg)
160{
161 return hwdep_ioctl(hwdep, file, cmd,
162 (unsigned long)compat_ptr(arg));
163}
164#else
165#define hwdep_compat_ioctl NULL
166#endif
167
168int snd_ff_create_hwdep_devices(struct snd_ff *ff)
169{
170 static const struct snd_hwdep_ops hwdep_ops = {
171 .read = hwdep_read,
172 .release = hwdep_release,
173 .poll = hwdep_poll,
174 .ioctl = hwdep_ioctl,
175 .ioctl_compat = hwdep_compat_ioctl,
176 };
177 struct snd_hwdep *hwdep;
178 int err;
179
180 err = snd_hwdep_new(ff->card, ff->card->driver, 0, &hwdep);
181 if (err < 0)
182 return err;
183
184 strcpy(hwdep->name, ff->card->driver);
185 hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREFACE;
186 hwdep->ops = hwdep_ops;
187 hwdep->private_data = ff;
188 hwdep->exclusive = true;
189
190 return 0;
191}
diff --git a/sound/firewire/fireface/ff-midi.c b/sound/firewire/fireface/ff-midi.c
new file mode 100644
index 000000000000..29ee0a7365c3
--- /dev/null
+++ b/sound/firewire/fireface/ff-midi.c
@@ -0,0 +1,131 @@
1/*
2 * ff-midi.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "ff.h"
10
11static int midi_capture_open(struct snd_rawmidi_substream *substream)
12{
13 /* Do nothing. */
14 return 0;
15}
16
17static int midi_playback_open(struct snd_rawmidi_substream *substream)
18{
19 struct snd_ff *ff = substream->rmidi->private_data;
20
21 /* Initialize internal status. */
22 ff->running_status[substream->number] = 0;
23 ff->rx_midi_error[substream->number] = false;
24
25 ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = substream;
26
27 return 0;
28}
29
30static int midi_capture_close(struct snd_rawmidi_substream *substream)
31{
32 /* Do nothing. */
33 return 0;
34}
35
36static int midi_playback_close(struct snd_rawmidi_substream *substream)
37{
38 struct snd_ff *ff = substream->rmidi->private_data;
39
40 cancel_work_sync(&ff->rx_midi_work[substream->number]);
41 ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = NULL;
42
43 return 0;
44}
45
46static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
47 int up)
48{
49 struct snd_ff *ff = substream->rmidi->private_data;
50 unsigned long flags;
51
52 spin_lock_irqsave(&ff->lock, flags);
53
54 if (up)
55 ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) =
56 substream;
57 else
58 ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) = NULL;
59
60 spin_unlock_irqrestore(&ff->lock, flags);
61}
62
63static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
64 int up)
65{
66 struct snd_ff *ff = substream->rmidi->private_data;
67 unsigned long flags;
68
69 spin_lock_irqsave(&ff->lock, flags);
70
71 if (up || !ff->rx_midi_error[substream->number])
72 schedule_work(&ff->rx_midi_work[substream->number]);
73
74 spin_unlock_irqrestore(&ff->lock, flags);
75}
76
77static struct snd_rawmidi_ops midi_capture_ops = {
78 .open = midi_capture_open,
79 .close = midi_capture_close,
80 .trigger = midi_capture_trigger,
81};
82
83static struct snd_rawmidi_ops midi_playback_ops = {
84 .open = midi_playback_open,
85 .close = midi_playback_close,
86 .trigger = midi_playback_trigger,
87};
88
89static void set_midi_substream_names(struct snd_rawmidi_str *stream,
90 const char *const name)
91{
92 struct snd_rawmidi_substream *substream;
93
94 list_for_each_entry(substream, &stream->substreams, list) {
95 snprintf(substream->name, sizeof(substream->name),
96 "%s MIDI %d", name, substream->number + 1);
97 }
98}
99
100int snd_ff_create_midi_devices(struct snd_ff *ff)
101{
102 struct snd_rawmidi *rmidi;
103 struct snd_rawmidi_str *stream;
104 int err;
105
106 err = snd_rawmidi_new(ff->card, ff->card->driver, 0,
107 ff->spec->midi_out_ports, ff->spec->midi_in_ports,
108 &rmidi);
109 if (err < 0)
110 return err;
111
112 snprintf(rmidi->name, sizeof(rmidi->name),
113 "%s MIDI", ff->card->shortname);
114 rmidi->private_data = ff;
115
116 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
117 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
118 &midi_capture_ops);
119 stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
120 set_midi_substream_names(stream, ff->card->shortname);
121
122 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
123 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
124 &midi_playback_ops);
125 stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
126 set_midi_substream_names(stream, ff->card->shortname);
127
128 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
129
130 return 0;
131}
diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c
new file mode 100644
index 000000000000..93cee1978e8e
--- /dev/null
+++ b/sound/firewire/fireface/ff-pcm.c
@@ -0,0 +1,409 @@
1/*
2 * ff-pcm.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "ff.h"
10
11static inline unsigned int get_multiplier_mode_with_index(unsigned int index)
12{
13 return ((int)index - 1) / 2;
14}
15
16static int hw_rule_rate(struct snd_pcm_hw_params *params,
17 struct snd_pcm_hw_rule *rule)
18{
19 const unsigned int *pcm_channels = rule->private;
20 struct snd_interval *r =
21 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
22 const struct snd_interval *c =
23 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
24 struct snd_interval t = {
25 .min = UINT_MAX, .max = 0, .integer = 1
26 };
27 unsigned int i, mode;
28
29 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
30 mode = get_multiplier_mode_with_index(i);
31 if (!snd_interval_test(c, pcm_channels[mode]))
32 continue;
33
34 t.min = min(t.min, amdtp_rate_table[i]);
35 t.max = max(t.max, amdtp_rate_table[i]);
36 }
37
38 return snd_interval_refine(r, &t);
39}
40
41static int hw_rule_channels(struct snd_pcm_hw_params *params,
42 struct snd_pcm_hw_rule *rule)
43{
44 const unsigned int *pcm_channels = rule->private;
45 struct snd_interval *c =
46 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
47 const struct snd_interval *r =
48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
49 struct snd_interval t = {
50 .min = UINT_MAX, .max = 0, .integer = 1
51 };
52 unsigned int i, mode;
53
54 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
55 mode = get_multiplier_mode_with_index(i);
56 if (!snd_interval_test(r, amdtp_rate_table[i]))
57 continue;
58
59 t.min = min(t.min, pcm_channels[mode]);
60 t.max = max(t.max, pcm_channels[mode]);
61 }
62
63 return snd_interval_refine(c, &t);
64}
65
66static void limit_channels_and_rates(struct snd_pcm_hardware *hw,
67 const unsigned int *pcm_channels)
68{
69 unsigned int mode;
70 unsigned int rate, channels;
71 int i;
72
73 hw->channels_min = UINT_MAX;
74 hw->channels_max = 0;
75 hw->rate_min = UINT_MAX;
76 hw->rate_max = 0;
77
78 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
79 mode = get_multiplier_mode_with_index(i);
80
81 channels = pcm_channels[mode];
82 if (pcm_channels[mode] == 0)
83 continue;
84 hw->channels_min = min(hw->channels_min, channels);
85 hw->channels_max = max(hw->channels_max, channels);
86
87 rate = amdtp_rate_table[i];
88 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
89 hw->rate_min = min(hw->rate_min, rate);
90 hw->rate_max = max(hw->rate_max, rate);
91 }
92}
93
94static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
95{
96 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */
97 hw->periods_max = UINT_MAX;
98
99 hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */
100
101 /* Just to prevent from allocating much pages. */
102 hw->period_bytes_max = hw->period_bytes_min * 2048;
103 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
104}
105
106static int pcm_init_hw_params(struct snd_ff *ff,
107 struct snd_pcm_substream *substream)
108{
109 struct snd_pcm_runtime *runtime = substream->runtime;
110 struct amdtp_stream *s;
111 const unsigned int *pcm_channels;
112 int err;
113
114 runtime->hw.info = SNDRV_PCM_INFO_BATCH |
115 SNDRV_PCM_INFO_BLOCK_TRANSFER |
116 SNDRV_PCM_INFO_INTERLEAVED |
117 SNDRV_PCM_INFO_JOINT_DUPLEX |
118 SNDRV_PCM_INFO_MMAP |
119 SNDRV_PCM_INFO_MMAP_VALID;
120
121 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
122 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
123 s = &ff->tx_stream;
124 pcm_channels = ff->spec->pcm_capture_channels;
125 } else {
126 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
127 s = &ff->rx_stream;
128 pcm_channels = ff->spec->pcm_playback_channels;
129 }
130
131 /* limit rates */
132 limit_channels_and_rates(&runtime->hw, pcm_channels);
133 limit_period_and_buffer(&runtime->hw);
134
135 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
136 hw_rule_channels, (void *)pcm_channels,
137 SNDRV_PCM_HW_PARAM_RATE, -1);
138 if (err < 0)
139 return err;
140
141 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
142 hw_rule_rate, (void *)pcm_channels,
143 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
144 if (err < 0)
145 return err;
146
147 return amdtp_ff_add_pcm_hw_constraints(s, runtime);
148}
149
150static int pcm_open(struct snd_pcm_substream *substream)
151{
152 struct snd_ff *ff = substream->private_data;
153 unsigned int rate;
154 enum snd_ff_clock_src src;
155 int i, err;
156
157 err = snd_ff_stream_lock_try(ff);
158 if (err < 0)
159 return err;
160
161 err = pcm_init_hw_params(ff, substream);
162 if (err < 0) {
163 snd_ff_stream_lock_release(ff);
164 return err;
165 }
166
167 err = ff->spec->protocol->get_clock(ff, &rate, &src);
168 if (err < 0) {
169 snd_ff_stream_lock_release(ff);
170 return err;
171 }
172
173 if (src != SND_FF_CLOCK_SRC_INTERNAL) {
174 for (i = 0; i < CIP_SFC_COUNT; ++i) {
175 if (amdtp_rate_table[i] == rate)
176 break;
177 }
178 /*
179 * The unit is configured at sampling frequency which packet
180 * streaming engine can't support.
181 */
182 if (i >= CIP_SFC_COUNT) {
183 snd_ff_stream_lock_release(ff);
184 return -EIO;
185 }
186
187 substream->runtime->hw.rate_min = rate;
188 substream->runtime->hw.rate_max = rate;
189 } else {
190 if (amdtp_stream_pcm_running(&ff->rx_stream) ||
191 amdtp_stream_pcm_running(&ff->tx_stream)) {
192 rate = amdtp_rate_table[ff->rx_stream.sfc];
193 substream->runtime->hw.rate_min = rate;
194 substream->runtime->hw.rate_max = rate;
195 }
196 }
197
198 snd_pcm_set_sync(substream);
199
200 return 0;
201}
202
203static int pcm_close(struct snd_pcm_substream *substream)
204{
205 struct snd_ff *ff = substream->private_data;
206
207 snd_ff_stream_lock_release(ff);
208
209 return 0;
210}
211
212static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
213 struct snd_pcm_hw_params *hw_params)
214{
215 struct snd_ff *ff = substream->private_data;
216 int err;
217
218 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
219 params_buffer_bytes(hw_params));
220 if (err < 0)
221 return err;
222
223 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
224 mutex_lock(&ff->mutex);
225 ff->substreams_counter++;
226 mutex_unlock(&ff->mutex);
227 }
228
229 return 0;
230}
231
232static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *hw_params)
234{
235 struct snd_ff *ff = substream->private_data;
236 int err;
237
238 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
239 params_buffer_bytes(hw_params));
240 if (err < 0)
241 return err;
242
243 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
244 mutex_lock(&ff->mutex);
245 ff->substreams_counter++;
246 mutex_unlock(&ff->mutex);
247 }
248
249 return 0;
250}
251
252static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
253{
254 struct snd_ff *ff = substream->private_data;
255
256 mutex_lock(&ff->mutex);
257
258 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
259 ff->substreams_counter--;
260
261 snd_ff_stream_stop_duplex(ff);
262
263 mutex_unlock(&ff->mutex);
264
265 return snd_pcm_lib_free_vmalloc_buffer(substream);
266}
267
268static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
269{
270 struct snd_ff *ff = substream->private_data;
271
272 mutex_lock(&ff->mutex);
273
274 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
275 ff->substreams_counter--;
276
277 snd_ff_stream_stop_duplex(ff);
278
279 mutex_unlock(&ff->mutex);
280
281 return snd_pcm_lib_free_vmalloc_buffer(substream);
282}
283
284static int pcm_capture_prepare(struct snd_pcm_substream *substream)
285{
286 struct snd_ff *ff = substream->private_data;
287 struct snd_pcm_runtime *runtime = substream->runtime;
288 int err;
289
290 mutex_lock(&ff->mutex);
291
292 err = snd_ff_stream_start_duplex(ff, runtime->rate);
293 if (err >= 0)
294 amdtp_stream_pcm_prepare(&ff->tx_stream);
295
296 mutex_unlock(&ff->mutex);
297
298 return err;
299}
300
301static int pcm_playback_prepare(struct snd_pcm_substream *substream)
302{
303 struct snd_ff *ff = substream->private_data;
304 struct snd_pcm_runtime *runtime = substream->runtime;
305 int err;
306
307 mutex_lock(&ff->mutex);
308
309 err = snd_ff_stream_start_duplex(ff, runtime->rate);
310 if (err >= 0)
311 amdtp_stream_pcm_prepare(&ff->rx_stream);
312
313 mutex_unlock(&ff->mutex);
314
315 return err;
316}
317
318static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
319{
320 struct snd_ff *ff = substream->private_data;
321
322 switch (cmd) {
323 case SNDRV_PCM_TRIGGER_START:
324 amdtp_stream_pcm_trigger(&ff->tx_stream, substream);
325 break;
326 case SNDRV_PCM_TRIGGER_STOP:
327 amdtp_stream_pcm_trigger(&ff->tx_stream, NULL);
328 break;
329 default:
330 return -EINVAL;
331 }
332
333 return 0;
334}
335
336static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
337{
338 struct snd_ff *ff = substream->private_data;
339
340 switch (cmd) {
341 case SNDRV_PCM_TRIGGER_START:
342 amdtp_stream_pcm_trigger(&ff->rx_stream, substream);
343 break;
344 case SNDRV_PCM_TRIGGER_STOP:
345 amdtp_stream_pcm_trigger(&ff->rx_stream, NULL);
346 break;
347 default:
348 return -EINVAL;
349 }
350
351 return 0;
352}
353
354static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
355{
356 struct snd_ff *ff = sbstrm->private_data;
357
358 return amdtp_stream_pcm_pointer(&ff->tx_stream);
359}
360
361static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
362{
363 struct snd_ff *ff = sbstrm->private_data;
364
365 return amdtp_stream_pcm_pointer(&ff->rx_stream);
366}
367
368static struct snd_pcm_ops pcm_capture_ops = {
369 .open = pcm_open,
370 .close = pcm_close,
371 .ioctl = snd_pcm_lib_ioctl,
372 .hw_params = pcm_capture_hw_params,
373 .hw_free = pcm_capture_hw_free,
374 .prepare = pcm_capture_prepare,
375 .trigger = pcm_capture_trigger,
376 .pointer = pcm_capture_pointer,
377 .page = snd_pcm_lib_get_vmalloc_page,
378};
379
380static struct snd_pcm_ops pcm_playback_ops = {
381 .open = pcm_open,
382 .close = pcm_close,
383 .ioctl = snd_pcm_lib_ioctl,
384 .hw_params = pcm_playback_hw_params,
385 .hw_free = pcm_playback_hw_free,
386 .prepare = pcm_playback_prepare,
387 .trigger = pcm_playback_trigger,
388 .pointer = pcm_playback_pointer,
389 .page = snd_pcm_lib_get_vmalloc_page,
390 .mmap = snd_pcm_lib_mmap_vmalloc,
391};
392
393int snd_ff_create_pcm_devices(struct snd_ff *ff)
394{
395 struct snd_pcm *pcm;
396 int err;
397
398 err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm);
399 if (err < 0)
400 return err;
401
402 pcm->private_data = ff;
403 snprintf(pcm->name, sizeof(pcm->name),
404 "%s PCM", ff->card->shortname);
405 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
406 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
407
408 return 0;
409}
diff --git a/sound/firewire/fireface/ff-proc.c b/sound/firewire/fireface/ff-proc.c
new file mode 100644
index 000000000000..69441d121f71
--- /dev/null
+++ b/sound/firewire/fireface/ff-proc.c
@@ -0,0 +1,63 @@
1/*
2 * ff-proc.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "./ff.h"
10
11static void proc_dump_clock_config(struct snd_info_entry *entry,
12 struct snd_info_buffer *buffer)
13{
14 struct snd_ff *ff = entry->private_data;
15
16 ff->spec->protocol->dump_clock_config(ff, buffer);
17}
18
19static void proc_dump_sync_status(struct snd_info_entry *entry,
20 struct snd_info_buffer *buffer)
21{
22 struct snd_ff *ff = entry->private_data;
23
24 ff->spec->protocol->dump_sync_status(ff, buffer);
25}
26
27static void add_node(struct snd_ff *ff, struct snd_info_entry *root,
28 const char *name,
29 void (*op)(struct snd_info_entry *e,
30 struct snd_info_buffer *b))
31{
32 struct snd_info_entry *entry;
33
34 entry = snd_info_create_card_entry(ff->card, name, root);
35 if (entry == NULL)
36 return;
37
38 snd_info_set_text_ops(entry, ff, op);
39 if (snd_info_register(entry) < 0)
40 snd_info_free_entry(entry);
41}
42
43void snd_ff_proc_init(struct snd_ff *ff)
44{
45 struct snd_info_entry *root;
46
47 /*
48 * All nodes are automatically removed at snd_card_disconnect(),
49 * by following to link list.
50 */
51 root = snd_info_create_card_entry(ff->card, "firewire",
52 ff->card->proc_root);
53 if (root == NULL)
54 return;
55 root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
56 if (snd_info_register(root) < 0) {
57 snd_info_free_entry(root);
58 return;
59 }
60
61 add_node(ff, root, "clock-config", proc_dump_clock_config);
62 add_node(ff, root, "sync-status", proc_dump_sync_status);
63}
diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c
new file mode 100644
index 000000000000..fcec6de80eeb
--- /dev/null
+++ b/sound/firewire/fireface/ff-protocol-ff400.c
@@ -0,0 +1,371 @@
1/*
2 * ff-protocol-ff400.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/delay.h>
10#include "ff.h"
11
12#define FF400_STF 0x000080100500ull
13#define FF400_RX_PACKET_FORMAT 0x000080100504ull
14#define FF400_ISOC_COMM_START 0x000080100508ull
15#define FF400_TX_PACKET_FORMAT 0x00008010050cull
16#define FF400_ISOC_COMM_STOP 0x000080100510ull
17#define FF400_SYNC_STATUS 0x0000801c0000ull
18#define FF400_FETCH_PCM_FRAMES 0x0000801c0000ull /* For block request. */
19#define FF400_CLOCK_CONFIG 0x0000801c0004ull
20
21#define FF400_MIDI_HIGH_ADDR 0x0000801003f4ull
22#define FF400_MIDI_RX_PORT_0 0x000080180000ull
23#define FF400_MIDI_RX_PORT_1 0x000080190000ull
24
25static int ff400_get_clock(struct snd_ff *ff, unsigned int *rate,
26 enum snd_ff_clock_src *src)
27{
28 __le32 reg;
29 u32 data;
30 int err;
31
32 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
33 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
34 if (err < 0)
35 return err;
36 data = le32_to_cpu(reg);
37
38 /* Calculate sampling rate. */
39 switch ((data >> 1) & 0x03) {
40 case 0x01:
41 *rate = 32000;
42 break;
43 case 0x00:
44 *rate = 44100;
45 break;
46 case 0x03:
47 *rate = 48000;
48 break;
49 case 0x02:
50 default:
51 return -EIO;
52 }
53
54 if (data & 0x08)
55 *rate *= 2;
56 else if (data & 0x10)
57 *rate *= 4;
58
59 /* Calculate source of clock. */
60 if (data & 0x01) {
61 *src = SND_FF_CLOCK_SRC_INTERNAL;
62 } else {
63 /* TODO: 0x00, 0x01, 0x02, 0x06, 0x07? */
64 switch ((data >> 10) & 0x07) {
65 case 0x03:
66 *src = SND_FF_CLOCK_SRC_SPDIF;
67 break;
68 case 0x04:
69 *src = SND_FF_CLOCK_SRC_WORD;
70 break;
71 case 0x05:
72 *src = SND_FF_CLOCK_SRC_LTC;
73 break;
74 case 0x00:
75 default:
76 *src = SND_FF_CLOCK_SRC_ADAT;
77 break;
78 }
79 }
80
81 return 0;
82}
83
84static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
85{
86 __le32 reg;
87 int i, err;
88
89 /* Check whether the given value is supported or not. */
90 for (i = 0; i < CIP_SFC_COUNT; i++) {
91 if (amdtp_rate_table[i] == rate)
92 break;
93 }
94 if (i == CIP_SFC_COUNT)
95 return -EINVAL;
96
97 /* Set the number of data blocks transferred in a second. */
98 reg = cpu_to_le32(rate);
99 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
100 FF400_STF, &reg, sizeof(reg), 0);
101 if (err < 0)
102 return err;
103
104 msleep(100);
105
106 /*
107 * Set isochronous channel and the number of quadlets of received
108 * packets.
109 */
110 reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) |
111 ff->rx_resources.channel);
112 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
113 FF400_RX_PACKET_FORMAT, &reg, sizeof(reg), 0);
114 if (err < 0)
115 return err;
116
117 /*
118 * Set isochronous channel and the number of quadlets of transmitted
119 * packet.
120 */
121 /* TODO: investigate the purpose of this 0x80. */
122 reg = cpu_to_le32((0x80 << 24) |
123 (ff->tx_resources.channel << 5) |
124 (ff->tx_stream.data_block_quadlets));
125 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
126 FF400_TX_PACKET_FORMAT, &reg, sizeof(reg), 0);
127 if (err < 0)
128 return err;
129
130 /* Allow to transmit packets. */
131 reg = cpu_to_le32(0x00000001);
132 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
133 FF400_ISOC_COMM_START, &reg, sizeof(reg), 0);
134}
135
136static void ff400_finish_session(struct snd_ff *ff)
137{
138 __le32 reg;
139
140 reg = cpu_to_le32(0x80000000);
141 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
142 FF400_ISOC_COMM_STOP, &reg, sizeof(reg), 0);
143}
144
145static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
146{
147 __le32 *reg;
148 int i;
149
150 reg = kzalloc(sizeof(__le32) * 18, GFP_KERNEL);
151 if (reg == NULL)
152 return -ENOMEM;
153
154 if (enable) {
155 /*
156 * Each quadlet is corresponding to data channels in a data
157 * blocks in reverse order. Precisely, quadlets for available
158 * data channels should be enabled. Here, I take second best
159 * to fetch PCM frames from all of data channels regardless of
160 * stf.
161 */
162 for (i = 0; i < 18; ++i)
163 reg[i] = cpu_to_le32(0x00000001);
164 }
165
166 return snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
167 FF400_FETCH_PCM_FRAMES, reg,
168 sizeof(__le32) * 18, 0);
169}
170
171static void ff400_dump_sync_status(struct snd_ff *ff,
172 struct snd_info_buffer *buffer)
173{
174 __le32 reg;
175 u32 data;
176 int err;
177
178 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
179 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
180 if (err < 0)
181 return;
182
183 data = le32_to_cpu(reg);
184
185 snd_iprintf(buffer, "External source detection:\n");
186
187 snd_iprintf(buffer, "Word Clock:");
188 if ((data >> 24) & 0x20) {
189 if ((data >> 24) & 0x40)
190 snd_iprintf(buffer, "sync\n");
191 else
192 snd_iprintf(buffer, "lock\n");
193 } else {
194 snd_iprintf(buffer, "none\n");
195 }
196
197 snd_iprintf(buffer, "S/PDIF:");
198 if ((data >> 16) & 0x10) {
199 if ((data >> 16) & 0x04)
200 snd_iprintf(buffer, "sync\n");
201 else
202 snd_iprintf(buffer, "lock\n");
203 } else {
204 snd_iprintf(buffer, "none\n");
205 }
206
207 snd_iprintf(buffer, "ADAT:");
208 if ((data >> 8) & 0x04) {
209 if ((data >> 8) & 0x10)
210 snd_iprintf(buffer, "sync\n");
211 else
212 snd_iprintf(buffer, "lock\n");
213 } else {
214 snd_iprintf(buffer, "none\n");
215 }
216
217 snd_iprintf(buffer, "\nUsed external source:\n");
218
219 if (((data >> 22) & 0x07) == 0x07) {
220 snd_iprintf(buffer, "None\n");
221 } else {
222 switch ((data >> 22) & 0x07) {
223 case 0x00:
224 snd_iprintf(buffer, "ADAT:");
225 break;
226 case 0x03:
227 snd_iprintf(buffer, "S/PDIF:");
228 break;
229 case 0x04:
230 snd_iprintf(buffer, "Word:");
231 break;
232 case 0x07:
233 snd_iprintf(buffer, "Nothing:");
234 break;
235 case 0x01:
236 case 0x02:
237 case 0x05:
238 case 0x06:
239 default:
240 snd_iprintf(buffer, "unknown:");
241 break;
242 }
243
244 if ((data >> 25) & 0x07) {
245 switch ((data >> 25) & 0x07) {
246 case 0x01:
247 snd_iprintf(buffer, "32000\n");
248 break;
249 case 0x02:
250 snd_iprintf(buffer, "44100\n");
251 break;
252 case 0x03:
253 snd_iprintf(buffer, "48000\n");
254 break;
255 case 0x04:
256 snd_iprintf(buffer, "64000\n");
257 break;
258 case 0x05:
259 snd_iprintf(buffer, "88200\n");
260 break;
261 case 0x06:
262 snd_iprintf(buffer, "96000\n");
263 break;
264 case 0x07:
265 snd_iprintf(buffer, "128000\n");
266 break;
267 case 0x08:
268 snd_iprintf(buffer, "176400\n");
269 break;
270 case 0x09:
271 snd_iprintf(buffer, "192000\n");
272 break;
273 case 0x00:
274 snd_iprintf(buffer, "unknown\n");
275 break;
276 }
277 }
278 }
279
280 snd_iprintf(buffer, "Multiplied:");
281 snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);
282}
283
284static void ff400_dump_clock_config(struct snd_ff *ff,
285 struct snd_info_buffer *buffer)
286{
287 __le32 reg;
288 u32 data;
289 unsigned int rate;
290 const char *src;
291 int err;
292
293 err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
294 FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0);
295 if (err < 0)
296 return;
297
298 data = le32_to_cpu(reg);
299
300 snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
301 (data & 0x20) ? "Professional" : "Consumer",
302 (data & 0x40) ? "on" : "off");
303
304 snd_iprintf(buffer, "Optical output interface format: %s\n",
305 ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");
306
307 snd_iprintf(buffer, "Word output single speed: %s\n",
308 ((data >> 8) & 0x20) ? "on" : "off");
309
310 snd_iprintf(buffer, "S/PDIF input interface: %s\n",
311 ((data >> 8) & 0x02) ? "Optical" : "Coaxial");
312
313 switch ((data >> 1) & 0x03) {
314 case 0x01:
315 rate = 32000;
316 break;
317 case 0x00:
318 rate = 44100;
319 break;
320 case 0x03:
321 rate = 48000;
322 break;
323 case 0x02:
324 default:
325 return;
326 }
327
328 if (data & 0x08)
329 rate *= 2;
330 else if (data & 0x10)
331 rate *= 4;
332
333 snd_iprintf(buffer, "Sampling rate: %d\n", rate);
334
335 if (data & 0x01) {
336 src = "Internal";
337 } else {
338 switch ((data >> 10) & 0x07) {
339 case 0x00:
340 src = "ADAT";
341 break;
342 case 0x03:
343 src = "S/PDIF";
344 break;
345 case 0x04:
346 src = "Word";
347 break;
348 case 0x05:
349 src = "LTC";
350 break;
351 default:
352 return;
353 }
354 }
355
356 snd_iprintf(buffer, "Sync to clock source: %s\n", src);
357}
358
359struct snd_ff_protocol snd_ff_protocol_ff400 = {
360 .get_clock = ff400_get_clock,
361 .begin_session = ff400_begin_session,
362 .finish_session = ff400_finish_session,
363 .switch_fetching_mode = ff400_switch_fetching_mode,
364
365 .dump_sync_status = ff400_dump_sync_status,
366 .dump_clock_config = ff400_dump_clock_config,
367
368 .midi_high_addr_reg = FF400_MIDI_HIGH_ADDR,
369 .midi_rx_port_0_reg = FF400_MIDI_RX_PORT_0,
370 .midi_rx_port_1_reg = FF400_MIDI_RX_PORT_1,
371};
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
new file mode 100644
index 000000000000..78880922120e
--- /dev/null
+++ b/sound/firewire/fireface/ff-stream.c
@@ -0,0 +1,282 @@
1/*
2 * ff-stream.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "ff.h"
10
11#define CALLBACK_TIMEOUT_MS 200
12
13static int get_rate_mode(unsigned int rate, unsigned int *mode)
14{
15 int i;
16
17 for (i = 0; i < CIP_SFC_COUNT; i++) {
18 if (amdtp_rate_table[i] == rate)
19 break;
20 }
21
22 if (i == CIP_SFC_COUNT)
23 return -EINVAL;
24
25 *mode = ((int)i - 1) / 2;
26
27 return 0;
28}
29
30/*
31 * Fireface 400 manages isochronous channel number in 3 bit field. Therefore,
32 * we can allocate between 0 and 7 channel.
33 */
34static int keep_resources(struct snd_ff *ff, unsigned int rate)
35{
36 int mode;
37 int err;
38
39 err = get_rate_mode(rate, &mode);
40 if (err < 0)
41 return err;
42
43 /* Keep resources for in-stream. */
44 err = amdtp_ff_set_parameters(&ff->tx_stream, rate,
45 ff->spec->pcm_capture_channels[mode]);
46 if (err < 0)
47 return err;
48 ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
49 err = fw_iso_resources_allocate(&ff->tx_resources,
50 amdtp_stream_get_max_payload(&ff->tx_stream),
51 fw_parent_device(ff->unit)->max_speed);
52 if (err < 0)
53 return err;
54
55 /* Keep resources for out-stream. */
56 err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
57 ff->spec->pcm_playback_channels[mode]);
58 if (err < 0)
59 return err;
60 ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
61 err = fw_iso_resources_allocate(&ff->rx_resources,
62 amdtp_stream_get_max_payload(&ff->rx_stream),
63 fw_parent_device(ff->unit)->max_speed);
64 if (err < 0)
65 fw_iso_resources_free(&ff->tx_resources);
66
67 return err;
68}
69
70static void release_resources(struct snd_ff *ff)
71{
72 fw_iso_resources_free(&ff->tx_resources);
73 fw_iso_resources_free(&ff->rx_resources);
74}
75
76static inline void finish_session(struct snd_ff *ff)
77{
78 ff->spec->protocol->finish_session(ff);
79 ff->spec->protocol->switch_fetching_mode(ff, false);
80}
81
82static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
83{
84 int err;
85 struct fw_iso_resources *resources;
86 struct amdtp_stream *stream;
87
88 if (dir == AMDTP_IN_STREAM) {
89 resources = &ff->tx_resources;
90 stream = &ff->tx_stream;
91 } else {
92 resources = &ff->rx_resources;
93 stream = &ff->rx_stream;
94 }
95
96 err = fw_iso_resources_init(resources, ff->unit);
97 if (err < 0)
98 return err;
99
100 err = amdtp_ff_init(stream, ff->unit, dir);
101 if (err < 0)
102 fw_iso_resources_destroy(resources);
103
104 return err;
105}
106
107static void destroy_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
108{
109 if (dir == AMDTP_IN_STREAM) {
110 amdtp_stream_destroy(&ff->tx_stream);
111 fw_iso_resources_destroy(&ff->tx_resources);
112 } else {
113 amdtp_stream_destroy(&ff->rx_stream);
114 fw_iso_resources_destroy(&ff->rx_resources);
115 }
116}
117
118int snd_ff_stream_init_duplex(struct snd_ff *ff)
119{
120 int err;
121
122 err = init_stream(ff, AMDTP_OUT_STREAM);
123 if (err < 0)
124 goto end;
125
126 err = init_stream(ff, AMDTP_IN_STREAM);
127 if (err < 0)
128 destroy_stream(ff, AMDTP_OUT_STREAM);
129end:
130 return err;
131}
132
133/*
134 * This function should be called before starting streams or after stopping
135 * streams.
136 */
137void snd_ff_stream_destroy_duplex(struct snd_ff *ff)
138{
139 destroy_stream(ff, AMDTP_IN_STREAM);
140 destroy_stream(ff, AMDTP_OUT_STREAM);
141}
142
143int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
144{
145 unsigned int curr_rate;
146 enum snd_ff_clock_src src;
147 int err;
148
149 if (ff->substreams_counter == 0)
150 return 0;
151
152 err = ff->spec->protocol->get_clock(ff, &curr_rate, &src);
153 if (err < 0)
154 return err;
155 if (curr_rate != rate ||
156 amdtp_streaming_error(&ff->tx_stream) ||
157 amdtp_streaming_error(&ff->rx_stream)) {
158 finish_session(ff);
159
160 amdtp_stream_stop(&ff->tx_stream);
161 amdtp_stream_stop(&ff->rx_stream);
162
163 release_resources(ff);
164 }
165
166 /*
167 * Regardless of current source of clock signal, drivers transfer some
168 * packets. Then, the device transfers packets.
169 */
170 if (!amdtp_stream_running(&ff->rx_stream)) {
171 err = keep_resources(ff, rate);
172 if (err < 0)
173 goto error;
174
175 err = ff->spec->protocol->begin_session(ff, rate);
176 if (err < 0)
177 goto error;
178
179 err = amdtp_stream_start(&ff->rx_stream,
180 ff->rx_resources.channel,
181 fw_parent_device(ff->unit)->max_speed);
182 if (err < 0)
183 goto error;
184
185 if (!amdtp_stream_wait_callback(&ff->rx_stream,
186 CALLBACK_TIMEOUT_MS)) {
187 err = -ETIMEDOUT;
188 goto error;
189 }
190
191 err = ff->spec->protocol->switch_fetching_mode(ff, true);
192 if (err < 0)
193 goto error;
194 }
195
196 if (!amdtp_stream_running(&ff->tx_stream)) {
197 err = amdtp_stream_start(&ff->tx_stream,
198 ff->tx_resources.channel,
199 fw_parent_device(ff->unit)->max_speed);
200 if (err < 0)
201 goto error;
202
203 if (!amdtp_stream_wait_callback(&ff->tx_stream,
204 CALLBACK_TIMEOUT_MS)) {
205 err = -ETIMEDOUT;
206 goto error;
207 }
208 }
209
210 return 0;
211error:
212 amdtp_stream_stop(&ff->tx_stream);
213 amdtp_stream_stop(&ff->rx_stream);
214
215 finish_session(ff);
216 release_resources(ff);
217
218 return err;
219}
220
221void snd_ff_stream_stop_duplex(struct snd_ff *ff)
222{
223 if (ff->substreams_counter > 0)
224 return;
225
226 amdtp_stream_stop(&ff->tx_stream);
227 amdtp_stream_stop(&ff->rx_stream);
228 finish_session(ff);
229 release_resources(ff);
230}
231
232void snd_ff_stream_update_duplex(struct snd_ff *ff)
233{
234 /* The device discontinue to transfer packets. */
235 amdtp_stream_pcm_abort(&ff->tx_stream);
236 amdtp_stream_stop(&ff->tx_stream);
237
238 amdtp_stream_pcm_abort(&ff->rx_stream);
239 amdtp_stream_stop(&ff->rx_stream);
240
241 fw_iso_resources_update(&ff->tx_resources);
242 fw_iso_resources_update(&ff->rx_resources);
243}
244
245void snd_ff_stream_lock_changed(struct snd_ff *ff)
246{
247 ff->dev_lock_changed = true;
248 wake_up(&ff->hwdep_wait);
249}
250
251int snd_ff_stream_lock_try(struct snd_ff *ff)
252{
253 int err;
254
255 spin_lock_irq(&ff->lock);
256
257 /* user land lock this */
258 if (ff->dev_lock_count < 0) {
259 err = -EBUSY;
260 goto end;
261 }
262
263 /* this is the first time */
264 if (ff->dev_lock_count++ == 0)
265 snd_ff_stream_lock_changed(ff);
266 err = 0;
267end:
268 spin_unlock_irq(&ff->lock);
269 return err;
270}
271
272void snd_ff_stream_lock_release(struct snd_ff *ff)
273{
274 spin_lock_irq(&ff->lock);
275
276 if (WARN_ON(ff->dev_lock_count <= 0))
277 goto end;
278 if (--ff->dev_lock_count == 0)
279 snd_ff_stream_lock_changed(ff);
280end:
281 spin_unlock_irq(&ff->lock);
282}
diff --git a/sound/firewire/fireface/ff-transaction.c b/sound/firewire/fireface/ff-transaction.c
new file mode 100644
index 000000000000..dd6c8e839647
--- /dev/null
+++ b/sound/firewire/fireface/ff-transaction.c
@@ -0,0 +1,295 @@
1/*
2 * ff-transaction.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "ff.h"
10
11static void finish_transmit_midi_msg(struct snd_ff *ff, unsigned int port,
12 int rcode)
13{
14 struct snd_rawmidi_substream *substream =
15 ACCESS_ONCE(ff->rx_midi_substreams[port]);
16
17 if (rcode_is_permanent_error(rcode)) {
18 ff->rx_midi_error[port] = true;
19 return;
20 }
21
22 if (rcode != RCODE_COMPLETE) {
23 /* Transfer the message again, immediately. */
24 ff->next_ktime[port] = 0;
25 schedule_work(&ff->rx_midi_work[port]);
26 return;
27 }
28
29 snd_rawmidi_transmit_ack(substream, ff->rx_bytes[port]);
30 ff->rx_bytes[port] = 0;
31
32 if (!snd_rawmidi_transmit_empty(substream))
33 schedule_work(&ff->rx_midi_work[port]);
34}
35
36static void finish_transmit_midi0_msg(struct fw_card *card, int rcode,
37 void *data, size_t length,
38 void *callback_data)
39{
40 struct snd_ff *ff =
41 container_of(callback_data, struct snd_ff, transactions[0]);
42 finish_transmit_midi_msg(ff, 0, rcode);
43}
44
45static void finish_transmit_midi1_msg(struct fw_card *card, int rcode,
46 void *data, size_t length,
47 void *callback_data)
48{
49 struct snd_ff *ff =
50 container_of(callback_data, struct snd_ff, transactions[1]);
51 finish_transmit_midi_msg(ff, 1, rcode);
52}
53
54static inline void fill_midi_buf(struct snd_ff *ff, unsigned int port,
55 unsigned int index, u8 byte)
56{
57 ff->msg_buf[port][index] = cpu_to_le32(byte);
58}
59
60static void transmit_midi_msg(struct snd_ff *ff, unsigned int port)
61{
62 struct snd_rawmidi_substream *substream =
63 ACCESS_ONCE(ff->rx_midi_substreams[port]);
64 u8 *buf = (u8 *)ff->msg_buf[port];
65 int i, len;
66
67 struct fw_device *fw_dev = fw_parent_device(ff->unit);
68 unsigned long long addr;
69 int generation;
70 fw_transaction_callback_t callback;
71
72 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
73 return;
74
75 if (ff->rx_bytes[port] > 0 || ff->rx_midi_error[port])
76 return;
77
78 /* Do it in next chance. */
79 if (ktime_after(ff->next_ktime[port], ktime_get())) {
80 schedule_work(&ff->rx_midi_work[port]);
81 return;
82 }
83
84 len = snd_rawmidi_transmit_peek(substream, buf,
85 SND_FF_MAXIMIM_MIDI_QUADS);
86 if (len <= 0)
87 return;
88
89 for (i = len - 1; i >= 0; i--)
90 fill_midi_buf(ff, port, i, buf[i]);
91
92 if (port == 0) {
93 addr = ff->spec->protocol->midi_rx_port_0_reg;
94 callback = finish_transmit_midi0_msg;
95 } else {
96 addr = ff->spec->protocol->midi_rx_port_1_reg;
97 callback = finish_transmit_midi1_msg;
98 }
99
100 /* Set interval to next transaction. */
101 ff->next_ktime[port] = ktime_add_ns(ktime_get(),
102 len * 8 * NSEC_PER_SEC / 31250);
103 ff->rx_bytes[port] = len;
104
105 /*
106 * In Linux FireWire core, when generation is updated with memory
107 * barrier, node id has already been updated. In this module, After
108 * this smp_rmb(), load/store instructions to memory are completed.
109 * Thus, both of generation and node id are available with recent
110 * values. This is a light-serialization solution to handle bus reset
111 * events on IEEE 1394 bus.
112 */
113 generation = fw_dev->generation;
114 smp_rmb();
115 fw_send_request(fw_dev->card, &ff->transactions[port],
116 TCODE_WRITE_BLOCK_REQUEST,
117 fw_dev->node_id, generation, fw_dev->max_speed,
118 addr, &ff->msg_buf[port], len * 4,
119 callback, &ff->transactions[port]);
120}
121
122static void transmit_midi0_msg(struct work_struct *work)
123{
124 struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[0]);
125
126 transmit_midi_msg(ff, 0);
127}
128
129static void transmit_midi1_msg(struct work_struct *work)
130{
131 struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[1]);
132
133 transmit_midi_msg(ff, 1);
134}
135
136static void handle_midi_msg(struct fw_card *card, struct fw_request *request,
137 int tcode, int destination, int source,
138 int generation, unsigned long long offset,
139 void *data, size_t length, void *callback_data)
140{
141 struct snd_ff *ff = callback_data;
142 __le32 *buf = data;
143 u32 quad;
144 u8 byte;
145 unsigned int index;
146 struct snd_rawmidi_substream *substream;
147 int i;
148
149 fw_send_response(card, request, RCODE_COMPLETE);
150
151 for (i = 0; i < length / 4; i++) {
152 quad = le32_to_cpu(buf[i]);
153
154 /* Message in first port. */
155 /*
156 * This value may represent the index of this unit when the same
157 * units are on the same IEEE 1394 bus. This driver doesn't use
158 * it.
159 */
160 index = (quad >> 8) & 0xff;
161 if (index > 0) {
162 substream = ACCESS_ONCE(ff->tx_midi_substreams[0]);
163 if (substream != NULL) {
164 byte = quad & 0xff;
165 snd_rawmidi_receive(substream, &byte, 1);
166 }
167 }
168
169 /* Message in second port. */
170 index = (quad >> 24) & 0xff;
171 if (index > 0) {
172 substream = ACCESS_ONCE(ff->tx_midi_substreams[1]);
173 if (substream != NULL) {
174 byte = (quad >> 16) & 0xff;
175 snd_rawmidi_receive(substream, &byte, 1);
176 }
177 }
178 }
179}
180
181static int allocate_own_address(struct snd_ff *ff, int i)
182{
183 struct fw_address_region midi_msg_region;
184 int err;
185
186 ff->async_handler.length = SND_FF_MAXIMIM_MIDI_QUADS * 4;
187 ff->async_handler.address_callback = handle_midi_msg;
188 ff->async_handler.callback_data = ff;
189
190 midi_msg_region.start = 0x000100000000ull * i;
191 midi_msg_region.end = midi_msg_region.start + ff->async_handler.length;
192
193 err = fw_core_add_address_handler(&ff->async_handler, &midi_msg_region);
194 if (err >= 0) {
195 /* Controllers are allowed to register this region. */
196 if (ff->async_handler.offset & 0x0000ffffffff) {
197 fw_core_remove_address_handler(&ff->async_handler);
198 err = -EAGAIN;
199 }
200 }
201
202 return err;
203}
204
205/*
206 * The configuration to start asynchronous transactions for MIDI messages is in
207 * 0x'0000'8010'051c. This register includes the other options, thus this driver
208 * doesn't touch it and leaves the decision to userspace. The userspace MUST add
209 * 0x04000000 to write transactions to the register to receive any MIDI
210 * messages.
211 *
212 * Here, I just describe MIDI-related offsets of the register, in little-endian
213 * order.
214 *
215 * Controllers are allowed to register higher 4 bytes of address to receive
216 * the transactions. The register is 0x'0000'8010'03f4. On the other hand, the
217 * controllers are not allowed to register lower 4 bytes of the address. They
218 * are forced to select from 4 options by writing corresponding bits to
219 * 0x'0000'8010'051c.
220 *
221 * The 3rd-6th bits in MSB of this register are used to indicate lower 4 bytes
222 * of address to which the device transferrs the transactions.
223 * - 6th: 0x'....'....'0000'0180
224 * - 5th: 0x'....'....'0000'0100
225 * - 4th: 0x'....'....'0000'0080
226 * - 3rd: 0x'....'....'0000'0000
227 *
228 * This driver configure 0x'....'....'0000'0000 for units to receive MIDI
229 * messages. 3rd bit of the register should be configured, however this driver
230 * deligates this task to user space applications due to a restriction that
231 * this register is write-only and the other bits have own effects.
232 *
233 * The 1st and 2nd bits in LSB of this register are used to cancel transferring
234 * asynchronous transactions. These two bits have the same effect.
235 * - 1st/2nd: cancel transferring
236 */
237int snd_ff_transaction_reregister(struct snd_ff *ff)
238{
239 struct fw_card *fw_card = fw_parent_device(ff->unit)->card;
240 u32 addr;
241 __le32 reg;
242
243 /*
244 * Controllers are allowed to register its node ID and upper 2 byte of
245 * local address to listen asynchronous transactions.
246 */
247 addr = (fw_card->node_id << 16) | (ff->async_handler.offset >> 32);
248 reg = cpu_to_le32(addr);
249 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
250 ff->spec->protocol->midi_high_addr_reg,
251 &reg, sizeof(reg), 0);
252}
253
254int snd_ff_transaction_register(struct snd_ff *ff)
255{
256 int i, err;
257
258 /*
259 * Allocate in Memory Space of IEC 13213, but lower 4 byte in LSB should
260 * be zero due to device specification.
261 */
262 for (i = 0; i < 0xffff; i++) {
263 err = allocate_own_address(ff, i);
264 if (err != -EBUSY && err != -EAGAIN)
265 break;
266 }
267 if (err < 0)
268 return err;
269
270 err = snd_ff_transaction_reregister(ff);
271 if (err < 0)
272 return err;
273
274 INIT_WORK(&ff->rx_midi_work[0], transmit_midi0_msg);
275 INIT_WORK(&ff->rx_midi_work[1], transmit_midi1_msg);
276
277 return 0;
278}
279
280void snd_ff_transaction_unregister(struct snd_ff *ff)
281{
282 __le32 reg;
283
284 if (ff->async_handler.callback_data == NULL)
285 return;
286 ff->async_handler.callback_data = NULL;
287
288 /* Release higher 4 bytes of address. */
289 reg = cpu_to_le32(0x00000000);
290 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
291 ff->spec->protocol->midi_high_addr_reg,
292 &reg, sizeof(reg), 0);
293
294 fw_core_remove_address_handler(&ff->async_handler);
295}
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
new file mode 100644
index 000000000000..eee7c8eac7a6
--- /dev/null
+++ b/sound/firewire/fireface/ff.c
@@ -0,0 +1,209 @@
1/*
2 * ff.c - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "ff.h"
10
11#define OUI_RME 0x000a35
12
13MODULE_DESCRIPTION("RME Fireface series Driver");
14MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
15MODULE_LICENSE("GPL v2");
16
17static void name_card(struct snd_ff *ff)
18{
19 struct fw_device *fw_dev = fw_parent_device(ff->unit);
20
21 strcpy(ff->card->driver, "Fireface");
22 strcpy(ff->card->shortname, ff->spec->name);
23 strcpy(ff->card->mixername, ff->spec->name);
24 snprintf(ff->card->longname, sizeof(ff->card->longname),
25 "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name,
26 fw_dev->config_rom[3], fw_dev->config_rom[4],
27 dev_name(&ff->unit->device), 100 << fw_dev->max_speed);
28}
29
30static void ff_free(struct snd_ff *ff)
31{
32 snd_ff_stream_destroy_duplex(ff);
33 snd_ff_transaction_unregister(ff);
34
35 fw_unit_put(ff->unit);
36
37 mutex_destroy(&ff->mutex);
38 kfree(ff);
39}
40
41static void ff_card_free(struct snd_card *card)
42{
43 ff_free(card->private_data);
44}
45
46static void do_registration(struct work_struct *work)
47{
48 struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work);
49 int err;
50
51 if (ff->registered)
52 return;
53
54 err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0,
55 &ff->card);
56 if (err < 0)
57 return;
58
59 err = snd_ff_transaction_register(ff);
60 if (err < 0)
61 goto error;
62
63 name_card(ff);
64
65 err = snd_ff_stream_init_duplex(ff);
66 if (err < 0)
67 goto error;
68
69 snd_ff_proc_init(ff);
70
71 err = snd_ff_create_midi_devices(ff);
72 if (err < 0)
73 goto error;
74
75 err = snd_ff_create_pcm_devices(ff);
76 if (err < 0)
77 goto error;
78
79 err = snd_ff_create_hwdep_devices(ff);
80 if (err < 0)
81 goto error;
82
83 err = snd_card_register(ff->card);
84 if (err < 0)
85 goto error;
86
87 ff->card->private_free = ff_card_free;
88 ff->card->private_data = ff;
89 ff->registered = true;
90
91 return;
92error:
93 snd_ff_transaction_unregister(ff);
94 snd_ff_stream_destroy_duplex(ff);
95 snd_card_free(ff->card);
96 dev_info(&ff->unit->device,
97 "Sound card registration failed: %d\n", err);
98}
99
100static int snd_ff_probe(struct fw_unit *unit,
101 const struct ieee1394_device_id *entry)
102{
103 struct snd_ff *ff;
104
105 ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL);
106 if (ff == NULL)
107 return -ENOMEM;
108
109 /* initialize myself */
110 ff->unit = fw_unit_get(unit);
111 dev_set_drvdata(&unit->device, ff);
112
113 mutex_init(&ff->mutex);
114 spin_lock_init(&ff->lock);
115 init_waitqueue_head(&ff->hwdep_wait);
116
117 ff->spec = (const struct snd_ff_spec *)entry->driver_data;
118
119 /* Register this sound card later. */
120 INIT_DEFERRABLE_WORK(&ff->dwork, do_registration);
121 snd_fw_schedule_registration(unit, &ff->dwork);
122
123 return 0;
124}
125
126static void snd_ff_update(struct fw_unit *unit)
127{
128 struct snd_ff *ff = dev_get_drvdata(&unit->device);
129
130 /* Postpone a workqueue for deferred registration. */
131 if (!ff->registered)
132 snd_fw_schedule_registration(unit, &ff->dwork);
133
134 snd_ff_transaction_reregister(ff);
135
136 if (ff->registered)
137 snd_ff_stream_update_duplex(ff);
138}
139
140static void snd_ff_remove(struct fw_unit *unit)
141{
142 struct snd_ff *ff = dev_get_drvdata(&unit->device);
143
144 /*
145 * Confirm to stop the work for registration before the sound card is
146 * going to be released. The work is not scheduled again because bus
147 * reset handler is not called anymore.
148 */
149 cancel_work_sync(&ff->dwork.work);
150
151 if (ff->registered) {
152 /* No need to wait for releasing card object in this context. */
153 snd_card_free_when_closed(ff->card);
154 } else {
155 /* Don't forget this case. */
156 ff_free(ff);
157 }
158}
159
160static struct snd_ff_spec spec_ff400 = {
161 .name = "Fireface400",
162 .pcm_capture_channels = {18, 14, 10},
163 .pcm_playback_channels = {18, 14, 10},
164 .midi_in_ports = 2,
165 .midi_out_ports = 2,
166 .protocol = &snd_ff_protocol_ff400,
167};
168
169static const struct ieee1394_device_id snd_ff_id_table[] = {
170 /* Fireface 400 */
171 {
172 .match_flags = IEEE1394_MATCH_VENDOR_ID |
173 IEEE1394_MATCH_SPECIFIER_ID |
174 IEEE1394_MATCH_VERSION |
175 IEEE1394_MATCH_MODEL_ID,
176 .vendor_id = OUI_RME,
177 .specifier_id = 0x000a35,
178 .version = 0x000002,
179 .model_id = 0x101800,
180 .driver_data = (kernel_ulong_t)&spec_ff400,
181 },
182 {}
183};
184MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
185
186static struct fw_driver ff_driver = {
187 .driver = {
188 .owner = THIS_MODULE,
189 .name = "snd-fireface",
190 .bus = &fw_bus_type,
191 },
192 .probe = snd_ff_probe,
193 .update = snd_ff_update,
194 .remove = snd_ff_remove,
195 .id_table = snd_ff_id_table,
196};
197
198static int __init snd_ff_init(void)
199{
200 return driver_register(&ff_driver.driver);
201}
202
203static void __exit snd_ff_exit(void)
204{
205 driver_unregister(&ff_driver.driver);
206}
207
208module_init(snd_ff_init);
209module_exit(snd_ff_exit);
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
new file mode 100644
index 000000000000..3cb812a50030
--- /dev/null
+++ b/sound/firewire/fireface/ff.h
@@ -0,0 +1,146 @@
1/*
2 * ff.h - a part of driver for RME Fireface series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#ifndef SOUND_FIREFACE_H_INCLUDED
10#define SOUND_FIREFACE_H_INCLUDED
11
12#include <linux/device.h>
13#include <linux/firewire.h>
14#include <linux/firewire-constants.h>
15#include <linux/module.h>
16#include <linux/mod_devicetable.h>
17#include <linux/mutex.h>
18#include <linux/slab.h>
19#include <linux/compat.h>
20#include <linux/sched/signal.h>
21
22#include <sound/core.h>
23#include <sound/info.h>
24#include <sound/rawmidi.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/hwdep.h>
28#include <sound/firewire.h>
29
30#include "../lib.h"
31#include "../amdtp-stream.h"
32#include "../iso-resources.h"
33
34#define SND_FF_STREAM_MODES 3
35
36#define SND_FF_MAXIMIM_MIDI_QUADS 9
37#define SND_FF_IN_MIDI_PORTS 2
38#define SND_FF_OUT_MIDI_PORTS 2
39
40struct snd_ff_protocol;
41struct snd_ff_spec {
42 const char *const name;
43
44 const unsigned int pcm_capture_channels[SND_FF_STREAM_MODES];
45 const unsigned int pcm_playback_channels[SND_FF_STREAM_MODES];
46
47 unsigned int midi_in_ports;
48 unsigned int midi_out_ports;
49
50 struct snd_ff_protocol *protocol;
51};
52
53struct snd_ff {
54 struct snd_card *card;
55 struct fw_unit *unit;
56 struct mutex mutex;
57 spinlock_t lock;
58
59 bool registered;
60 struct delayed_work dwork;
61
62 const struct snd_ff_spec *spec;
63
64 /* To handle MIDI tx. */
65 struct snd_rawmidi_substream *tx_midi_substreams[SND_FF_IN_MIDI_PORTS];
66 struct fw_address_handler async_handler;
67
68 /* TO handle MIDI rx. */
69 struct snd_rawmidi_substream *rx_midi_substreams[SND_FF_OUT_MIDI_PORTS];
70 u8 running_status[SND_FF_OUT_MIDI_PORTS];
71 __le32 msg_buf[SND_FF_OUT_MIDI_PORTS][SND_FF_MAXIMIM_MIDI_QUADS];
72 struct work_struct rx_midi_work[SND_FF_OUT_MIDI_PORTS];
73 struct fw_transaction transactions[SND_FF_OUT_MIDI_PORTS];
74 ktime_t next_ktime[SND_FF_OUT_MIDI_PORTS];
75 bool rx_midi_error[SND_FF_OUT_MIDI_PORTS];
76 unsigned int rx_bytes[SND_FF_OUT_MIDI_PORTS];
77
78 unsigned int substreams_counter;
79 struct amdtp_stream tx_stream;
80 struct amdtp_stream rx_stream;
81 struct fw_iso_resources tx_resources;
82 struct fw_iso_resources rx_resources;
83
84 int dev_lock_count;
85 bool dev_lock_changed;
86 wait_queue_head_t hwdep_wait;
87};
88
89enum snd_ff_clock_src {
90 SND_FF_CLOCK_SRC_INTERNAL,
91 SND_FF_CLOCK_SRC_SPDIF,
92 SND_FF_CLOCK_SRC_ADAT,
93 SND_FF_CLOCK_SRC_WORD,
94 SND_FF_CLOCK_SRC_LTC,
95 /* TODO: perhaps ADAT2 and TCO exists. */
96};
97
98struct snd_ff_protocol {
99 int (*get_clock)(struct snd_ff *ff, unsigned int *rate,
100 enum snd_ff_clock_src *src);
101 int (*begin_session)(struct snd_ff *ff, unsigned int rate);
102 void (*finish_session)(struct snd_ff *ff);
103 int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);
104
105 void (*dump_sync_status)(struct snd_ff *ff,
106 struct snd_info_buffer *buffer);
107 void (*dump_clock_config)(struct snd_ff *ff,
108 struct snd_info_buffer *buffer);
109
110 u64 midi_high_addr_reg;
111 u64 midi_rx_port_0_reg;
112 u64 midi_rx_port_1_reg;
113};
114
115extern struct snd_ff_protocol snd_ff_protocol_ff400;
116
117int snd_ff_transaction_register(struct snd_ff *ff);
118int snd_ff_transaction_reregister(struct snd_ff *ff);
119void snd_ff_transaction_unregister(struct snd_ff *ff);
120
121int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,
122 unsigned int pcm_channels);
123int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
124 struct snd_pcm_runtime *runtime);
125int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
126 enum amdtp_stream_direction dir);
127
128int snd_ff_stream_init_duplex(struct snd_ff *ff);
129void snd_ff_stream_destroy_duplex(struct snd_ff *ff);
130int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate);
131void snd_ff_stream_stop_duplex(struct snd_ff *ff);
132void snd_ff_stream_update_duplex(struct snd_ff *ff);
133
134void snd_ff_stream_lock_changed(struct snd_ff *ff);
135int snd_ff_stream_lock_try(struct snd_ff *ff);
136void snd_ff_stream_lock_release(struct snd_ff *ff);
137
138void snd_ff_proc_init(struct snd_ff *ff);
139
140int snd_ff_create_midi_devices(struct snd_ff *ff);
141
142int snd_ff_create_pcm_devices(struct snd_ff *ff);
143
144int snd_ff_create_hwdep_devices(struct snd_ff *ff);
145
146#endif
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index 7683238283b6..39dfa74906ef 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -99,147 +99,6 @@ void snd_fw_schedule_registration(struct fw_unit *unit,
99} 99}
100EXPORT_SYMBOL(snd_fw_schedule_registration); 100EXPORT_SYMBOL(snd_fw_schedule_registration);
101 101
102static void async_midi_port_callback(struct fw_card *card, int rcode,
103 void *data, size_t length,
104 void *callback_data)
105{
106 struct snd_fw_async_midi_port *port = callback_data;
107 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
108
109 /* This port is closed. */
110 if (substream == NULL)
111 return;
112
113 if (rcode == RCODE_COMPLETE)
114 snd_rawmidi_transmit_ack(substream, port->consume_bytes);
115 else if (!rcode_is_permanent_error(rcode))
116 /* To start next transaction immediately for recovery. */
117 port->next_ktime = 0;
118 else
119 /* Don't continue processing. */
120 port->error = true;
121
122 port->idling = true;
123
124 if (!snd_rawmidi_transmit_empty(substream))
125 schedule_work(&port->work);
126}
127
128static void midi_port_work(struct work_struct *work)
129{
130 struct snd_fw_async_midi_port *port =
131 container_of(work, struct snd_fw_async_midi_port, work);
132 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
133 int generation;
134 int type;
135
136 /* Under transacting or error state. */
137 if (!port->idling || port->error)
138 return;
139
140 /* Nothing to do. */
141 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
142 return;
143
144 /* Do it in next chance. */
145 if (ktime_after(port->next_ktime, ktime_get())) {
146 schedule_work(&port->work);
147 return;
148 }
149
150 /*
151 * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().
152 * Later, snd_rawmidi_transmit_ack() is called.
153 */
154 memset(port->buf, 0, port->len);
155 port->consume_bytes = port->fill(substream, port->buf);
156 if (port->consume_bytes <= 0) {
157 /* Do it in next chance, immediately. */
158 if (port->consume_bytes == 0) {
159 port->next_ktime = 0;
160 schedule_work(&port->work);
161 } else {
162 /* Fatal error. */
163 port->error = true;
164 }
165 return;
166 }
167
168 /* Calculate type of transaction. */
169 if (port->len == 4)
170 type = TCODE_WRITE_QUADLET_REQUEST;
171 else
172 type = TCODE_WRITE_BLOCK_REQUEST;
173
174 /* Set interval to next transaction. */
175 port->next_ktime = ktime_add_ns(ktime_get(),
176 port->consume_bytes * 8 * NSEC_PER_SEC / 31250);
177
178 /* Start this transaction. */
179 port->idling = false;
180
181 /*
182 * In Linux FireWire core, when generation is updated with memory
183 * barrier, node id has already been updated. In this module, After
184 * this smp_rmb(), load/store instructions to memory are completed.
185 * Thus, both of generation and node id are available with recent
186 * values. This is a light-serialization solution to handle bus reset
187 * events on IEEE 1394 bus.
188 */
189 generation = port->parent->generation;
190 smp_rmb();
191
192 fw_send_request(port->parent->card, &port->transaction, type,
193 port->parent->node_id, generation,
194 port->parent->max_speed, port->addr,
195 port->buf, port->len, async_midi_port_callback,
196 port);
197}
198
199/**
200 * snd_fw_async_midi_port_init - initialize asynchronous MIDI port structure
201 * @port: the asynchronous MIDI port to initialize
202 * @unit: the target of the asynchronous transaction
203 * @addr: the address to which transactions are transferred
204 * @len: the length of transaction
205 * @fill: the callback function to fill given buffer, and returns the
206 * number of consumed bytes for MIDI message.
207 *
208 */
209int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
210 struct fw_unit *unit, u64 addr, unsigned int len,
211 snd_fw_async_midi_port_fill fill)
212{
213 port->len = DIV_ROUND_UP(len, 4) * 4;
214 port->buf = kzalloc(port->len, GFP_KERNEL);
215 if (port->buf == NULL)
216 return -ENOMEM;
217
218 port->parent = fw_parent_device(unit);
219 port->addr = addr;
220 port->fill = fill;
221 port->idling = true;
222 port->next_ktime = 0;
223 port->error = false;
224
225 INIT_WORK(&port->work, midi_port_work);
226
227 return 0;
228}
229EXPORT_SYMBOL(snd_fw_async_midi_port_init);
230
231/**
232 * snd_fw_async_midi_port_destroy - free asynchronous MIDI port structure
233 * @port: the asynchronous MIDI port structure
234 */
235void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port)
236{
237 snd_fw_async_midi_port_finish(port);
238 cancel_work_sync(&port->work);
239 kfree(port->buf);
240}
241EXPORT_SYMBOL(snd_fw_async_midi_port_destroy);
242
243MODULE_DESCRIPTION("FireWire audio helper functions"); 102MODULE_DESCRIPTION("FireWire audio helper functions");
244MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 103MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
245MODULE_LICENSE("GPL v2"); 104MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index c3768cd494a5..eef70922ed89 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -25,58 +25,4 @@ static inline bool rcode_is_permanent_error(int rcode)
25void snd_fw_schedule_registration(struct fw_unit *unit, 25void snd_fw_schedule_registration(struct fw_unit *unit,
26 struct delayed_work *dwork); 26 struct delayed_work *dwork);
27 27
28struct snd_fw_async_midi_port;
29typedef int (*snd_fw_async_midi_port_fill)(
30 struct snd_rawmidi_substream *substream,
31 u8 *buf);
32
33struct snd_fw_async_midi_port {
34 struct fw_device *parent;
35 struct work_struct work;
36 bool idling;
37 ktime_t next_ktime;
38 bool error;
39
40 u64 addr;
41 struct fw_transaction transaction;
42
43 u8 *buf;
44 unsigned int len;
45
46 struct snd_rawmidi_substream *substream;
47 snd_fw_async_midi_port_fill fill;
48 int consume_bytes;
49};
50
51int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
52 struct fw_unit *unit, u64 addr, unsigned int len,
53 snd_fw_async_midi_port_fill fill);
54void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port);
55
56/**
57 * snd_fw_async_midi_port_run - run transactions for the async MIDI port
58 * @port: the asynchronous MIDI port
59 * @substream: the MIDI substream
60 */
61static inline void
62snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
63 struct snd_rawmidi_substream *substream)
64{
65 if (!port->error) {
66 port->substream = substream;
67 schedule_work(&port->work);
68 }
69}
70
71/**
72 * snd_fw_async_midi_port_finish - finish the asynchronous MIDI port
73 * @port: the asynchronous MIDI port
74 */
75static inline void
76snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
77{
78 port->substream = NULL;
79 port->error = false;
80}
81
82#endif 28#endif
diff --git a/sound/firewire/motu/Makefile b/sound/firewire/motu/Makefile
new file mode 100644
index 000000000000..728f586e754b
--- /dev/null
+++ b/sound/firewire/motu/Makefile
@@ -0,0 +1,6 @@
1CFLAGS_amdtp-motu.o := -I$(src)
2
3snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \
4 motu-proc.o motu-pcm.o motu-midi.o motu-hwdep.o \
5 motu-protocol-v2.o motu-protocol-v3.o
6obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
diff --git a/sound/firewire/motu/amdtp-motu-trace.h b/sound/firewire/motu/amdtp-motu-trace.h
new file mode 100644
index 000000000000..cd0cbfa9f96f
--- /dev/null
+++ b/sound/firewire/motu/amdtp-motu-trace.h
@@ -0,0 +1,123 @@
1/*
2 * amdtp-motu-trace.h - tracepoint definitions to dump a part of packet data
3 *
4 * Copyright (c) 2017 Takashi Sakamoto
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#undef TRACE_SYSTEM
9#define TRACE_SYSTEM snd_firewire_motu
10
11#if !defined(_SND_FIREWIRE_MOTU_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
12#define _SND_FIREWIRE_MOTU_TRACE_H
13
14#include <linux/tracepoint.h>
15
16static void copy_sph(u32 *frame, __be32 *buffer, unsigned int data_blocks,
17 unsigned int data_block_quadlets);
18static void copy_message(u64 *frames, __be32 *buffer, unsigned int data_blocks,
19 unsigned int data_block_quadlets);
20
21TRACE_EVENT(in_data_block_sph,
22 TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer),
23 TP_ARGS(s, data_blocks, buffer),
24 TP_STRUCT__entry(
25 __field(int, src)
26 __field(int, dst)
27 __field(unsigned int, data_blocks)
28 __dynamic_array(u32, tstamps, data_blocks)
29 ),
30 TP_fast_assign(
31 __entry->src = fw_parent_device(s->unit)->node_id;
32 __entry->dst = fw_parent_device(s->unit)->card->node_id;
33 __entry->data_blocks = data_blocks;
34 copy_sph(__get_dynamic_array(tstamps), buffer, data_blocks, s->data_block_quadlets);
35 ),
36 TP_printk(
37 "%04x %04x %u %s",
38 __entry->src,
39 __entry->dst,
40 __entry->data_blocks,
41 __print_array(__get_dynamic_array(tstamps), __entry->data_blocks, 4)
42 )
43);
44
45TRACE_EVENT(out_data_block_sph,
46 TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer),
47 TP_ARGS(s, data_blocks, buffer),
48 TP_STRUCT__entry(
49 __field(int, src)
50 __field(int, dst)
51 __field(unsigned int, data_blocks)
52 __dynamic_array(u32, tstamps, data_blocks)
53 ),
54 TP_fast_assign(
55 __entry->src = fw_parent_device(s->unit)->card->node_id;
56 __entry->dst = fw_parent_device(s->unit)->node_id;
57 __entry->data_blocks = data_blocks;
58 copy_sph(__get_dynamic_array(tstamps), buffer, data_blocks, s->data_block_quadlets);
59 ),
60 TP_printk(
61 "%04x %04x %u %s",
62 __entry->src,
63 __entry->dst,
64 __entry->data_blocks,
65 __print_array(__get_dynamic_array(tstamps), __entry->data_blocks, 4)
66 )
67);
68
69TRACE_EVENT(in_data_block_message,
70 TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer),
71 TP_ARGS(s, data_blocks, buffer),
72 TP_STRUCT__entry(
73 __field(int, src)
74 __field(int, dst)
75 __field(unsigned int, data_blocks)
76 __dynamic_array(u64, messages, data_blocks)
77 ),
78 TP_fast_assign(
79 __entry->src = fw_parent_device(s->unit)->node_id;
80 __entry->dst = fw_parent_device(s->unit)->card->node_id;
81 __entry->data_blocks = data_blocks;
82 copy_message(__get_dynamic_array(messages), buffer, data_blocks, s->data_block_quadlets);
83 ),
84 TP_printk(
85 "%04x %04x %u %s",
86 __entry->src,
87 __entry->dst,
88 __entry->data_blocks,
89 __print_array(__get_dynamic_array(messages), __entry->data_blocks, 8)
90 )
91);
92
93TRACE_EVENT(out_data_block_message,
94 TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer),
95 TP_ARGS(s, data_blocks, buffer),
96 TP_STRUCT__entry(
97 __field(int, src)
98 __field(int, dst)
99 __field(unsigned int, data_blocks)
100 __dynamic_array(u64, messages, data_blocks)
101 ),
102 TP_fast_assign(
103 __entry->src = fw_parent_device(s->unit)->card->node_id;
104 __entry->dst = fw_parent_device(s->unit)->node_id;
105 __entry->data_blocks = data_blocks;
106 copy_message(__get_dynamic_array(messages), buffer, data_blocks, s->data_block_quadlets);
107 ),
108 TP_printk(
109 "%04x %04x %u %s",
110 __entry->src,
111 __entry->dst,
112 __entry->data_blocks,
113 __print_array(__get_dynamic_array(messages), __entry->data_blocks, 8)
114 )
115);
116
117#endif
118
119#undef TRACE_INCLUDE_PATH
120#define TRACE_INCLUDE_PATH .
121#undef TRACE_INCLUDE_FILE
122#define TRACE_INCLUDE_FILE amdtp-motu-trace
123#include <trace/define_trace.h>
diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c
new file mode 100644
index 000000000000..96f0091144bb
--- /dev/null
+++ b/sound/firewire/motu/amdtp-motu.c
@@ -0,0 +1,427 @@
1/*
2 * amdtp-motu.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/slab.h>
10#include <sound/pcm.h>
11#include "motu.h"
12
13#define CREATE_TRACE_POINTS
14#include "amdtp-motu-trace.h"
15
16#define CIP_FMT_MOTU 0x02
17#define CIP_FMT_MOTU_TX_V3 0x22
18#define MOTU_FDF_AM824 0x22
19
20/*
21 * Nominally 3125 bytes/second, but the MIDI port's clock might be
22 * 1% too slow, and the bus clock 100 ppm too fast.
23 */
24#define MIDI_BYTES_PER_SECOND 3093
25
26struct amdtp_motu {
27 /* For timestamp processing. */
28 unsigned int quotient_ticks_per_event;
29 unsigned int remainder_ticks_per_event;
30 unsigned int next_ticks;
31 unsigned int next_accumulated;
32 unsigned int next_cycles;
33 unsigned int next_seconds;
34
35 unsigned int pcm_chunks;
36 unsigned int pcm_byte_offset;
37
38 struct snd_rawmidi_substream *midi;
39 unsigned int midi_ports;
40 unsigned int midi_flag_offset;
41 unsigned int midi_byte_offset;
42
43 int midi_db_count;
44 unsigned int midi_db_interval;
45};
46
47int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
48 unsigned int midi_ports,
49 struct snd_motu_packet_format *formats)
50{
51 static const struct {
52 unsigned int quotient_ticks_per_event;
53 unsigned int remainder_ticks_per_event;
54 } params[] = {
55 [CIP_SFC_44100] = { 557, 123 },
56 [CIP_SFC_48000] = { 512, 0 },
57 [CIP_SFC_88200] = { 278, 282 },
58 [CIP_SFC_96000] = { 256, 0 },
59 [CIP_SFC_176400] = { 139, 141 },
60 [CIP_SFC_192000] = { 128, 0 },
61 };
62 struct amdtp_motu *p = s->protocol;
63 unsigned int pcm_chunks, data_chunks, data_block_quadlets;
64 unsigned int delay;
65 unsigned int mode;
66 int i, err;
67
68 if (amdtp_stream_running(s))
69 return -EBUSY;
70
71 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
72 if (snd_motu_clock_rates[i] == rate) {
73 mode = i >> 1;
74 break;
75 }
76 }
77 if (i == ARRAY_SIZE(snd_motu_clock_rates))
78 return -EINVAL;
79
80 pcm_chunks = formats->fixed_part_pcm_chunks[mode] +
81 formats->differed_part_pcm_chunks[mode];
82 data_chunks = formats->msg_chunks + pcm_chunks;
83
84 /*
85 * Each data block includes SPH in its head. Data chunks follow with
86 * 3 byte alignment. Padding follows with zero to conform to quadlet
87 * alignment.
88 */
89 data_block_quadlets = 1 + DIV_ROUND_UP(data_chunks * 3, 4);
90
91 err = amdtp_stream_set_parameters(s, rate, data_block_quadlets);
92 if (err < 0)
93 return err;
94
95 p->pcm_chunks = pcm_chunks;
96 p->pcm_byte_offset = formats->pcm_byte_offset;
97
98 p->midi_ports = midi_ports;
99 p->midi_flag_offset = formats->midi_flag_offset;
100 p->midi_byte_offset = formats->midi_byte_offset;
101
102 p->midi_db_count = 0;
103 p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND;
104
105 /* IEEE 1394 bus requires. */
106 delay = 0x2e00;
107
108 /* For no-data or empty packets to adjust PCM sampling frequency. */
109 delay += 8000 * 3072 * s->syt_interval / rate;
110
111 p->next_seconds = 0;
112 p->next_cycles = delay / 3072;
113 p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event;
114 p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event;
115 p->next_ticks = delay % 3072;
116 p->next_accumulated = 0;
117
118 return 0;
119}
120
121static void read_pcm_s32(struct amdtp_stream *s,
122 struct snd_pcm_runtime *runtime,
123 __be32 *buffer, unsigned int data_blocks)
124{
125 struct amdtp_motu *p = s->protocol;
126 unsigned int channels, remaining_frames, i, c;
127 u8 *byte;
128 u32 *dst;
129
130 channels = p->pcm_chunks;
131 dst = (void *)runtime->dma_area +
132 frames_to_bytes(runtime, s->pcm_buffer_pointer);
133 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
134
135 for (i = 0; i < data_blocks; ++i) {
136 byte = (u8 *)buffer + p->pcm_byte_offset;
137
138 for (c = 0; c < channels; ++c) {
139 *dst = (byte[0] << 24) | (byte[1] << 16) | byte[2];
140 byte += 3;
141 dst++;
142 }
143 buffer += s->data_block_quadlets;
144 if (--remaining_frames == 0)
145 dst = (void *)runtime->dma_area;
146 }
147}
148
149static void write_pcm_s32(struct amdtp_stream *s,
150 struct snd_pcm_runtime *runtime,
151 __be32 *buffer, unsigned int data_blocks)
152{
153 struct amdtp_motu *p = s->protocol;
154 unsigned int channels, remaining_frames, i, c;
155 u8 *byte;
156 const u32 *src;
157
158 channels = p->pcm_chunks;
159 src = (void *)runtime->dma_area +
160 frames_to_bytes(runtime, s->pcm_buffer_pointer);
161 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
162
163 for (i = 0; i < data_blocks; ++i) {
164 byte = (u8 *)buffer + p->pcm_byte_offset;
165
166 for (c = 0; c < channels; ++c) {
167 byte[0] = (*src >> 24) & 0xff;
168 byte[1] = (*src >> 16) & 0xff;
169 byte[2] = (*src >> 8) & 0xff;
170 byte += 3;
171 src++;
172 }
173
174 buffer += s->data_block_quadlets;
175 if (--remaining_frames == 0)
176 src = (void *)runtime->dma_area;
177 }
178}
179
180static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
181 unsigned int data_blocks)
182{
183 struct amdtp_motu *p = s->protocol;
184 unsigned int channels, i, c;
185 u8 *byte;
186
187 channels = p->pcm_chunks;
188
189 for (i = 0; i < data_blocks; ++i) {
190 byte = (u8 *)buffer + p->pcm_byte_offset;
191
192 for (c = 0; c < channels; ++c) {
193 byte[0] = 0;
194 byte[1] = 0;
195 byte[2] = 0;
196 byte += 3;
197 }
198
199 buffer += s->data_block_quadlets;
200 }
201}
202
203int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
204 struct snd_pcm_runtime *runtime)
205{
206 int err;
207
208 /* TODO: how to set an constraint for exactly 24bit PCM sample? */
209 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
210 if (err < 0)
211 return err;
212
213 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
214}
215
216void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
217 struct snd_rawmidi_substream *midi)
218{
219 struct amdtp_motu *p = s->protocol;
220
221 if (port < p->midi_ports)
222 WRITE_ONCE(p->midi, midi);
223}
224
225static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
226 unsigned int data_blocks)
227{
228 struct amdtp_motu *p = s->protocol;
229 struct snd_rawmidi_substream *midi = READ_ONCE(p->midi);
230 u8 *b;
231 int i;
232
233 for (i = 0; i < data_blocks; i++) {
234 b = (u8 *)buffer;
235
236 if (midi && p->midi_db_count == 0 &&
237 snd_rawmidi_transmit(midi, b + p->midi_byte_offset, 1) == 1) {
238 b[p->midi_flag_offset] = 0x01;
239 } else {
240 b[p->midi_byte_offset] = 0x00;
241 b[p->midi_flag_offset] = 0x00;
242 }
243
244 buffer += s->data_block_quadlets;
245
246 if (--p->midi_db_count < 0)
247 p->midi_db_count = p->midi_db_interval;
248 }
249}
250
251static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
252 unsigned int data_blocks)
253{
254 struct amdtp_motu *p = s->protocol;
255 struct snd_rawmidi_substream *midi;
256 u8 *b;
257 int i;
258
259 for (i = 0; i < data_blocks; i++) {
260 b = (u8 *)buffer;
261 midi = READ_ONCE(p->midi);
262
263 if (midi && (b[p->midi_flag_offset] & 0x01))
264 snd_rawmidi_receive(midi, b + p->midi_byte_offset, 1);
265
266 buffer += s->data_block_quadlets;
267 }
268}
269
270/* For tracepoints. */
271static void __maybe_unused copy_sph(u32 *frames, __be32 *buffer,
272 unsigned int data_blocks,
273 unsigned int data_block_quadlets)
274{
275 unsigned int i;
276
277 for (i = 0; i < data_blocks; ++i) {
278 *frames = be32_to_cpu(*buffer);
279 buffer += data_block_quadlets;
280 frames++;
281 }
282}
283
284/* For tracepoints. */
285static void __maybe_unused copy_message(u64 *frames, __be32 *buffer,
286 unsigned int data_blocks,
287 unsigned int data_block_quadlets)
288{
289 unsigned int i;
290
291 /* This is just for v2/v3 protocol. */
292 for (i = 0; i < data_blocks; ++i) {
293 *frames = (be32_to_cpu(buffer[1]) << 16) |
294 (be32_to_cpu(buffer[2]) >> 16);
295 buffer += data_block_quadlets;
296 frames++;
297 }
298}
299
300static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
301 __be32 *buffer, unsigned int data_blocks,
302 unsigned int *syt)
303{
304 struct amdtp_motu *p = s->protocol;
305 struct snd_pcm_substream *pcm;
306
307 trace_in_data_block_sph(s, data_blocks, buffer);
308 trace_in_data_block_message(s, data_blocks, buffer);
309
310 if (p->midi_ports)
311 read_midi_messages(s, buffer, data_blocks);
312
313 pcm = ACCESS_ONCE(s->pcm);
314 if (data_blocks > 0 && pcm)
315 read_pcm_s32(s, pcm->runtime, buffer, data_blocks);
316
317 return data_blocks;
318}
319
320static inline void compute_next_elapse_from_start(struct amdtp_motu *p)
321{
322 p->next_accumulated += p->remainder_ticks_per_event;
323 if (p->next_accumulated >= 441) {
324 p->next_accumulated -= 441;
325 p->next_ticks++;
326 }
327
328 p->next_ticks += p->quotient_ticks_per_event;
329 if (p->next_ticks >= 3072) {
330 p->next_ticks -= 3072;
331 p->next_cycles++;
332 }
333
334 if (p->next_cycles >= 8000) {
335 p->next_cycles -= 8000;
336 p->next_seconds++;
337 }
338
339 if (p->next_seconds >= 128)
340 p->next_seconds -= 128;
341}
342
343static void write_sph(struct amdtp_stream *s, __be32 *buffer,
344 unsigned int data_blocks)
345{
346 struct amdtp_motu *p = s->protocol;
347 unsigned int next_cycles;
348 unsigned int i;
349 u32 sph;
350
351 for (i = 0; i < data_blocks; i++) {
352 next_cycles = (s->start_cycle + p->next_cycles) % 8000;
353 sph = ((next_cycles << 12) | p->next_ticks) & 0x01ffffff;
354 *buffer = cpu_to_be32(sph);
355
356 compute_next_elapse_from_start(p);
357
358 buffer += s->data_block_quadlets;
359 }
360}
361
362static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
363 __be32 *buffer, unsigned int data_blocks,
364 unsigned int *syt)
365{
366 struct amdtp_motu *p = (struct amdtp_motu *)s->protocol;
367 struct snd_pcm_substream *pcm;
368
369 /* Not used. */
370 *syt = 0xffff;
371
372 /* TODO: how to interact control messages between userspace? */
373
374 if (p->midi_ports)
375 write_midi_messages(s, buffer, data_blocks);
376
377 pcm = ACCESS_ONCE(s->pcm);
378 if (pcm)
379 write_pcm_s32(s, pcm->runtime, buffer, data_blocks);
380 else
381 write_pcm_silence(s, buffer, data_blocks);
382
383 write_sph(s, buffer, data_blocks);
384
385 trace_out_data_block_sph(s, data_blocks, buffer);
386 trace_out_data_block_message(s, data_blocks, buffer);
387
388 return data_blocks;
389}
390
391int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
392 enum amdtp_stream_direction dir,
393 const struct snd_motu_protocol *const protocol)
394{
395 amdtp_stream_process_data_blocks_t process_data_blocks;
396 int fmt = CIP_FMT_MOTU;
397 int flags = CIP_BLOCKING;
398 int err;
399
400 if (dir == AMDTP_IN_STREAM) {
401 process_data_blocks = process_tx_data_blocks;
402
403 /*
404 * Units of version 3 transmits packets with invalid CIP header
405 * against IEC 61883-1.
406 */
407 if (protocol == &snd_motu_protocol_v3) {
408 flags |= CIP_WRONG_DBS |
409 CIP_SKIP_DBC_ZERO_CHECK |
410 CIP_HEADER_WITHOUT_EOH;
411 fmt = CIP_FMT_MOTU_TX_V3;
412 }
413 } else {
414 process_data_blocks = process_rx_data_blocks;
415 flags |= CIP_DBC_IS_END_EVENT;
416 }
417
418 err = amdtp_stream_init(s, unit, dir, flags, fmt, process_data_blocks,
419 sizeof(struct amdtp_motu));
420 if (err < 0)
421 return err;
422
423 s->sph = 1;
424 s->fdf = MOTU_FDF_AM824;
425
426 return 0;
427}
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
new file mode 100644
index 000000000000..b87ccb69d597
--- /dev/null
+++ b/sound/firewire/motu/motu-hwdep.c
@@ -0,0 +1,198 @@
1/*
2 * motu-hwdep.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9/*
10 * This codes have five functionalities.
11 *
12 * 1.get information about firewire node
13 * 2.get notification about starting/stopping stream
14 * 3.lock/unlock streaming
15 *
16 */
17
18#include "motu.h"
19
20static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
21 loff_t *offset)
22{
23 struct snd_motu *motu = hwdep->private_data;
24 DEFINE_WAIT(wait);
25 union snd_firewire_event event;
26
27 spin_lock_irq(&motu->lock);
28
29 while (!motu->dev_lock_changed && motu->msg == 0) {
30 prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
31 spin_unlock_irq(&motu->lock);
32 schedule();
33 finish_wait(&motu->hwdep_wait, &wait);
34 if (signal_pending(current))
35 return -ERESTARTSYS;
36 spin_lock_irq(&motu->lock);
37 }
38
39 memset(&event, 0, sizeof(event));
40 if (motu->dev_lock_changed) {
41 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
42 event.lock_status.status = (motu->dev_lock_count > 0);
43 motu->dev_lock_changed = false;
44
45 count = min_t(long, count, sizeof(event.lock_status));
46 } else {
47 event.motu_notification.type = SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION;
48 event.motu_notification.message = motu->msg;
49 motu->msg = 0;
50
51 count = min_t(long, count, sizeof(event.motu_notification));
52 }
53
54 spin_unlock_irq(&motu->lock);
55
56 if (copy_to_user(buf, &event, count))
57 return -EFAULT;
58
59 return count;
60}
61
62static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
63 poll_table *wait)
64{
65 struct snd_motu *motu = hwdep->private_data;
66 unsigned int events;
67
68 poll_wait(file, &motu->hwdep_wait, wait);
69
70 spin_lock_irq(&motu->lock);
71 if (motu->dev_lock_changed || motu->msg)
72 events = POLLIN | POLLRDNORM;
73 else
74 events = 0;
75 spin_unlock_irq(&motu->lock);
76
77 return events | POLLOUT;
78}
79
80static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
81{
82 struct fw_device *dev = fw_parent_device(motu->unit);
83 struct snd_firewire_get_info info;
84
85 memset(&info, 0, sizeof(info));
86 info.type = SNDRV_FIREWIRE_TYPE_MOTU;
87 info.card = dev->card->index;
88 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
89 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
90 strlcpy(info.device_name, dev_name(&dev->device),
91 sizeof(info.device_name));
92
93 if (copy_to_user(arg, &info, sizeof(info)))
94 return -EFAULT;
95
96 return 0;
97}
98
99static int hwdep_lock(struct snd_motu *motu)
100{
101 int err;
102
103 spin_lock_irq(&motu->lock);
104
105 if (motu->dev_lock_count == 0) {
106 motu->dev_lock_count = -1;
107 err = 0;
108 } else {
109 err = -EBUSY;
110 }
111
112 spin_unlock_irq(&motu->lock);
113
114 return err;
115}
116
117static int hwdep_unlock(struct snd_motu *motu)
118{
119 int err;
120
121 spin_lock_irq(&motu->lock);
122
123 if (motu->dev_lock_count == -1) {
124 motu->dev_lock_count = 0;
125 err = 0;
126 } else {
127 err = -EBADFD;
128 }
129
130 spin_unlock_irq(&motu->lock);
131
132 return err;
133}
134
135static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
136{
137 struct snd_motu *motu = hwdep->private_data;
138
139 spin_lock_irq(&motu->lock);
140 if (motu->dev_lock_count == -1)
141 motu->dev_lock_count = 0;
142 spin_unlock_irq(&motu->lock);
143
144 return 0;
145}
146
147static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
148 unsigned int cmd, unsigned long arg)
149{
150 struct snd_motu *motu = hwdep->private_data;
151
152 switch (cmd) {
153 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
154 return hwdep_get_info(motu, (void __user *)arg);
155 case SNDRV_FIREWIRE_IOCTL_LOCK:
156 return hwdep_lock(motu);
157 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
158 return hwdep_unlock(motu);
159 default:
160 return -ENOIOCTLCMD;
161 }
162}
163
164#ifdef CONFIG_COMPAT
165static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
166 unsigned int cmd, unsigned long arg)
167{
168 return hwdep_ioctl(hwdep, file, cmd,
169 (unsigned long)compat_ptr(arg));
170}
171#else
172#define hwdep_compat_ioctl NULL
173#endif
174
175int snd_motu_create_hwdep_device(struct snd_motu *motu)
176{
177 static const struct snd_hwdep_ops ops = {
178 .read = hwdep_read,
179 .release = hwdep_release,
180 .poll = hwdep_poll,
181 .ioctl = hwdep_ioctl,
182 .ioctl_compat = hwdep_compat_ioctl,
183 };
184 struct snd_hwdep *hwdep;
185 int err;
186
187 err = snd_hwdep_new(motu->card, motu->card->driver, 0, &hwdep);
188 if (err < 0)
189 return err;
190
191 strcpy(hwdep->name, "MOTU");
192 hwdep->iface = SNDRV_HWDEP_IFACE_FW_MOTU;
193 hwdep->ops = ops;
194 hwdep->private_data = motu;
195 hwdep->exclusive = true;
196
197 return 0;
198}
diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c
new file mode 100644
index 000000000000..e3acfcc53f4e
--- /dev/null
+++ b/sound/firewire/motu/motu-midi.c
@@ -0,0 +1,169 @@
1/*
2 * motu-midi.h - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8#include "motu.h"
9
10static int midi_capture_open(struct snd_rawmidi_substream *substream)
11{
12 struct snd_motu *motu = substream->rmidi->private_data;
13 int err;
14
15 err = snd_motu_stream_lock_try(motu);
16 if (err < 0)
17 return err;
18
19 mutex_lock(&motu->mutex);
20
21 motu->capture_substreams++;
22 err = snd_motu_stream_start_duplex(motu, 0);
23
24 mutex_unlock(&motu->mutex);
25
26 if (err < 0)
27 snd_motu_stream_lock_release(motu);
28
29 return err;
30}
31
32static int midi_playback_open(struct snd_rawmidi_substream *substream)
33{
34 struct snd_motu *motu = substream->rmidi->private_data;
35 int err;
36
37 err = snd_motu_stream_lock_try(motu);
38 if (err < 0)
39 return err;
40
41 mutex_lock(&motu->mutex);
42
43 motu->playback_substreams++;
44 err = snd_motu_stream_start_duplex(motu, 0);
45
46 mutex_unlock(&motu->mutex);
47
48 if (err < 0)
49 snd_motu_stream_lock_release(motu);
50
51 return err;
52}
53
54static int midi_capture_close(struct snd_rawmidi_substream *substream)
55{
56 struct snd_motu *motu = substream->rmidi->private_data;
57
58 mutex_lock(&motu->mutex);
59
60 motu->capture_substreams--;
61 snd_motu_stream_stop_duplex(motu);
62
63 mutex_unlock(&motu->mutex);
64
65 snd_motu_stream_lock_release(motu);
66 return 0;
67}
68
69static int midi_playback_close(struct snd_rawmidi_substream *substream)
70{
71 struct snd_motu *motu = substream->rmidi->private_data;
72
73 mutex_lock(&motu->mutex);
74
75 motu->playback_substreams--;
76 snd_motu_stream_stop_duplex(motu);
77
78 mutex_unlock(&motu->mutex);
79
80 snd_motu_stream_lock_release(motu);
81 return 0;
82}
83
84static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
85{
86 struct snd_motu *motu = substrm->rmidi->private_data;
87 unsigned long flags;
88
89 spin_lock_irqsave(&motu->lock, flags);
90
91 if (up)
92 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
93 substrm);
94 else
95 amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number,
96 NULL);
97
98 spin_unlock_irqrestore(&motu->lock, flags);
99}
100
101static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
102{
103 struct snd_motu *motu = substrm->rmidi->private_data;
104 unsigned long flags;
105
106 spin_lock_irqsave(&motu->lock, flags);
107
108 if (up)
109 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
110 substrm);
111 else
112 amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number,
113 NULL);
114
115 spin_unlock_irqrestore(&motu->lock, flags);
116}
117
118static void set_midi_substream_names(struct snd_motu *motu,
119 struct snd_rawmidi_str *str)
120{
121 struct snd_rawmidi_substream *subs;
122
123 list_for_each_entry(subs, &str->substreams, list) {
124 snprintf(subs->name, sizeof(subs->name),
125 "%s MIDI %d", motu->card->shortname, subs->number + 1);
126 }
127}
128
129int snd_motu_create_midi_devices(struct snd_motu *motu)
130{
131 static struct snd_rawmidi_ops capture_ops = {
132 .open = midi_capture_open,
133 .close = midi_capture_close,
134 .trigger = midi_capture_trigger,
135 };
136 static struct snd_rawmidi_ops playback_ops = {
137 .open = midi_playback_open,
138 .close = midi_playback_close,
139 .trigger = midi_playback_trigger,
140 };
141 struct snd_rawmidi *rmidi;
142 struct snd_rawmidi_str *str;
143 int err;
144
145 /* create midi ports */
146 err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi);
147 if (err < 0)
148 return err;
149
150 snprintf(rmidi->name, sizeof(rmidi->name),
151 "%s MIDI", motu->card->shortname);
152 rmidi->private_data = motu;
153
154 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
155 SNDRV_RAWMIDI_INFO_OUTPUT |
156 SNDRV_RAWMIDI_INFO_DUPLEX;
157
158 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
159 &capture_ops);
160 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
161 set_midi_substream_names(motu, str);
162
163 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
164 &playback_ops);
165 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
166 set_midi_substream_names(motu, str);
167
168 return 0;
169}
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c
new file mode 100644
index 000000000000..94558f3d218b
--- /dev/null
+++ b/sound/firewire/motu/motu-pcm.c
@@ -0,0 +1,398 @@
1/*
2 * motu-pcm.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <sound/pcm_params.h>
10#include "motu.h"
11
12static int motu_rate_constraint(struct snd_pcm_hw_params *params,
13 struct snd_pcm_hw_rule *rule)
14{
15 struct snd_motu_packet_format *formats = rule->private;
16
17 const struct snd_interval *c =
18 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
19 struct snd_interval *r =
20 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
21 struct snd_interval rates = {
22 .min = UINT_MAX, .max = 0, .integer = 1
23 };
24 unsigned int i, pcm_channels, rate, mode;
25
26 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
27 rate = snd_motu_clock_rates[i];
28 mode = i / 2;
29
30 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
31 formats->differed_part_pcm_chunks[mode];
32 if (!snd_interval_test(c, pcm_channels))
33 continue;
34
35 rates.min = min(rates.min, rate);
36 rates.max = max(rates.max, rate);
37 }
38
39 return snd_interval_refine(r, &rates);
40}
41
42static int motu_channels_constraint(struct snd_pcm_hw_params *params,
43 struct snd_pcm_hw_rule *rule)
44{
45 struct snd_motu_packet_format *formats = rule->private;
46
47 const struct snd_interval *r =
48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
49 struct snd_interval *c =
50 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
51 struct snd_interval channels = {
52 .min = UINT_MAX, .max = 0, .integer = 1
53 };
54 unsigned int i, pcm_channels, rate, mode;
55
56 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
57 rate = snd_motu_clock_rates[i];
58 mode = i / 2;
59
60 if (!snd_interval_test(r, rate))
61 continue;
62
63 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
64 formats->differed_part_pcm_chunks[mode];
65 channels.min = min(channels.min, pcm_channels);
66 channels.max = max(channels.max, pcm_channels);
67 }
68
69 return snd_interval_refine(c, &channels);
70}
71
72static void limit_channels_and_rates(struct snd_motu *motu,
73 struct snd_pcm_runtime *runtime,
74 struct snd_motu_packet_format *formats)
75{
76 struct snd_pcm_hardware *hw = &runtime->hw;
77 unsigned int i, pcm_channels, rate, mode;
78
79 hw->channels_min = UINT_MAX;
80 hw->channels_max = 0;
81
82 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
83 rate = snd_motu_clock_rates[i];
84 mode = i / 2;
85
86 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
87 formats->differed_part_pcm_chunks[mode];
88 if (pcm_channels == 0)
89 continue;
90
91 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
92 hw->channels_min = min(hw->channels_min, pcm_channels);
93 hw->channels_max = max(hw->channels_max, pcm_channels);
94 }
95
96 snd_pcm_limit_hw_rates(runtime);
97}
98
99static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
100{
101 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */
102 hw->periods_max = UINT_MAX;
103
104 hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */
105
106 /* Just to prevent from allocating much pages. */
107 hw->period_bytes_max = hw->period_bytes_min * 2048;
108 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
109}
110
111static int init_hw_info(struct snd_motu *motu,
112 struct snd_pcm_substream *substream)
113{
114 struct snd_pcm_runtime *runtime = substream->runtime;
115 struct snd_pcm_hardware *hw = &runtime->hw;
116 struct amdtp_stream *stream;
117 struct snd_motu_packet_format *formats;
118 int err;
119
120 hw->info = SNDRV_PCM_INFO_MMAP |
121 SNDRV_PCM_INFO_MMAP_VALID |
122 SNDRV_PCM_INFO_BATCH |
123 SNDRV_PCM_INFO_INTERLEAVED |
124 SNDRV_PCM_INFO_JOINT_DUPLEX |
125 SNDRV_PCM_INFO_BLOCK_TRANSFER;
126
127 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
128 hw->formats = SNDRV_PCM_FMTBIT_S32;
129 stream = &motu->tx_stream;
130 formats = &motu->tx_packet_formats;
131 } else {
132 hw->formats = SNDRV_PCM_FMTBIT_S32;
133 stream = &motu->rx_stream;
134 formats = &motu->rx_packet_formats;
135 }
136
137 limit_channels_and_rates(motu, runtime, formats);
138 limit_period_and_buffer(hw);
139
140 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
141 motu_rate_constraint, formats,
142 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
143 if (err < 0)
144 return err;
145 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
146 motu_channels_constraint, formats,
147 SNDRV_PCM_HW_PARAM_RATE, -1);
148 if (err < 0)
149 return err;
150
151 return amdtp_motu_add_pcm_hw_constraints(stream, runtime);
152}
153
154static int pcm_open(struct snd_pcm_substream *substream)
155{
156 struct snd_motu *motu = substream->private_data;
157 const struct snd_motu_protocol *const protocol = motu->spec->protocol;
158 enum snd_motu_clock_source src;
159 unsigned int rate;
160 int err;
161
162 err = snd_motu_stream_lock_try(motu);
163 if (err < 0)
164 return err;
165
166 mutex_lock(&motu->mutex);
167
168 err = protocol->cache_packet_formats(motu);
169 if (err < 0)
170 goto err_locked;
171
172 err = init_hw_info(motu, substream);
173 if (err < 0)
174 goto err_locked;
175
176 /*
177 * When source of clock is not internal or any PCM streams are running,
178 * available sampling rate is limited at current sampling rate.
179 */
180 err = protocol->get_clock_source(motu, &src);
181 if (err < 0)
182 goto err_locked;
183 if (src != SND_MOTU_CLOCK_SOURCE_INTERNAL ||
184 amdtp_stream_pcm_running(&motu->tx_stream) ||
185 amdtp_stream_pcm_running(&motu->rx_stream)) {
186 err = protocol->get_clock_rate(motu, &rate);
187 if (err < 0)
188 goto err_locked;
189 substream->runtime->hw.rate_min = rate;
190 substream->runtime->hw.rate_max = rate;
191 }
192
193 snd_pcm_set_sync(substream);
194
195 mutex_unlock(&motu->mutex);
196
197 return err;
198err_locked:
199 mutex_unlock(&motu->mutex);
200 snd_motu_stream_lock_release(motu);
201 return err;
202}
203
204static int pcm_close(struct snd_pcm_substream *substream)
205{
206 struct snd_motu *motu = substream->private_data;
207
208 snd_motu_stream_lock_release(motu);
209
210 return 0;
211}
212
213static int capture_hw_params(struct snd_pcm_substream *substream,
214 struct snd_pcm_hw_params *hw_params)
215{
216 struct snd_motu *motu = substream->private_data;
217 int err;
218
219 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
220 params_buffer_bytes(hw_params));
221 if (err < 0)
222 return err;
223
224 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
225 mutex_lock(&motu->mutex);
226 motu->capture_substreams++;
227 mutex_unlock(&motu->mutex);
228 }
229
230 return 0;
231}
232static int playback_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *hw_params)
234{
235 struct snd_motu *motu = substream->private_data;
236 int err;
237
238 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
239 params_buffer_bytes(hw_params));
240 if (err < 0)
241 return err;
242
243 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
244 mutex_lock(&motu->mutex);
245 motu->playback_substreams++;
246 mutex_unlock(&motu->mutex);
247 }
248
249 return 0;
250}
251
252static int capture_hw_free(struct snd_pcm_substream *substream)
253{
254 struct snd_motu *motu = substream->private_data;
255
256 mutex_lock(&motu->mutex);
257
258 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
259 motu->capture_substreams--;
260
261 snd_motu_stream_stop_duplex(motu);
262
263 mutex_unlock(&motu->mutex);
264
265 return snd_pcm_lib_free_vmalloc_buffer(substream);
266}
267
268static int playback_hw_free(struct snd_pcm_substream *substream)
269{
270 struct snd_motu *motu = substream->private_data;
271
272 mutex_lock(&motu->mutex);
273
274 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
275 motu->playback_substreams--;
276
277 snd_motu_stream_stop_duplex(motu);
278
279 mutex_unlock(&motu->mutex);
280
281 return snd_pcm_lib_free_vmalloc_buffer(substream);
282}
283
284static int capture_prepare(struct snd_pcm_substream *substream)
285{
286 struct snd_motu *motu = substream->private_data;
287 int err;
288
289 mutex_lock(&motu->mutex);
290 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
291 mutex_unlock(&motu->mutex);
292 if (err >= 0)
293 amdtp_stream_pcm_prepare(&motu->tx_stream);
294
295 return 0;
296}
297static int playback_prepare(struct snd_pcm_substream *substream)
298{
299 struct snd_motu *motu = substream->private_data;
300 int err;
301
302 mutex_lock(&motu->mutex);
303 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
304 mutex_unlock(&motu->mutex);
305 if (err >= 0)
306 amdtp_stream_pcm_prepare(&motu->rx_stream);
307
308 return err;
309}
310
311static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
312{
313 struct snd_motu *motu = substream->private_data;
314
315 switch (cmd) {
316 case SNDRV_PCM_TRIGGER_START:
317 amdtp_stream_pcm_trigger(&motu->tx_stream, substream);
318 break;
319 case SNDRV_PCM_TRIGGER_STOP:
320 amdtp_stream_pcm_trigger(&motu->tx_stream, NULL);
321 break;
322 default:
323 return -EINVAL;
324 }
325
326 return 0;
327}
328static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
329{
330 struct snd_motu *motu = substream->private_data;
331
332 switch (cmd) {
333 case SNDRV_PCM_TRIGGER_START:
334 amdtp_stream_pcm_trigger(&motu->rx_stream, substream);
335 break;
336 case SNDRV_PCM_TRIGGER_STOP:
337 amdtp_stream_pcm_trigger(&motu->rx_stream, NULL);
338 break;
339 default:
340 return -EINVAL;
341 }
342
343 return 0;
344}
345
346static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
347{
348 struct snd_motu *motu = substream->private_data;
349
350 return amdtp_stream_pcm_pointer(&motu->tx_stream);
351}
352static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
353{
354 struct snd_motu *motu = substream->private_data;
355
356 return amdtp_stream_pcm_pointer(&motu->rx_stream);
357}
358
359int snd_motu_create_pcm_devices(struct snd_motu *motu)
360{
361 static struct snd_pcm_ops capture_ops = {
362 .open = pcm_open,
363 .close = pcm_close,
364 .ioctl = snd_pcm_lib_ioctl,
365 .hw_params = capture_hw_params,
366 .hw_free = capture_hw_free,
367 .prepare = capture_prepare,
368 .trigger = capture_trigger,
369 .pointer = capture_pointer,
370 .page = snd_pcm_lib_get_vmalloc_page,
371 .mmap = snd_pcm_lib_mmap_vmalloc,
372 };
373 static struct snd_pcm_ops playback_ops = {
374 .open = pcm_open,
375 .close = pcm_close,
376 .ioctl = snd_pcm_lib_ioctl,
377 .hw_params = playback_hw_params,
378 .hw_free = playback_hw_free,
379 .prepare = playback_prepare,
380 .trigger = playback_trigger,
381 .pointer = playback_pointer,
382 .page = snd_pcm_lib_get_vmalloc_page,
383 .mmap = snd_pcm_lib_mmap_vmalloc,
384 };
385 struct snd_pcm *pcm;
386 int err;
387
388 err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm);
389 if (err < 0)
390 return err;
391 pcm->private_data = motu;
392 strcpy(pcm->name, motu->card->shortname);
393
394 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
395 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
396
397 return 0;
398}
diff --git a/sound/firewire/motu/motu-proc.c b/sound/firewire/motu/motu-proc.c
new file mode 100644
index 000000000000..4edc064999ed
--- /dev/null
+++ b/sound/firewire/motu/motu-proc.c
@@ -0,0 +1,118 @@
1/*
2 * motu-proc.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "./motu.h"
10
11static const char *const clock_names[] = {
12 [SND_MOTU_CLOCK_SOURCE_INTERNAL] = "Internal",
13 [SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB] = "ADAT on Dsub-9pin interface",
14 [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT] = "ADAT on optical interface",
15 [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A] = "ADAT on optical interface A",
16 [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B] = "ADAT on optical interface B",
17 [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT] = "S/PDIF on optical interface",
18 [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A] = "S/PDIF on optical interface A",
19 [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B] = "S/PDIF on optical interface B",
20 [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX] = "S/PCIF on coaxial interface",
21 [SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR] = "AESEBU on XLR interface",
22 [SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC] = "Word clock on BNC interface",
23};
24
25static void proc_read_clock(struct snd_info_entry *entry,
26 struct snd_info_buffer *buffer)
27{
28
29 struct snd_motu *motu = entry->private_data;
30 const struct snd_motu_protocol *const protocol = motu->spec->protocol;
31 unsigned int rate;
32 enum snd_motu_clock_source source;
33
34 if (protocol->get_clock_rate(motu, &rate) < 0)
35 return;
36 if (protocol->get_clock_source(motu, &source) < 0)
37 return;
38
39 snd_iprintf(buffer, "Rate:\t%d\n", rate);
40 snd_iprintf(buffer, "Source:\t%s\n", clock_names[source]);
41}
42
43static void proc_read_format(struct snd_info_entry *entry,
44 struct snd_info_buffer *buffer)
45{
46 struct snd_motu *motu = entry->private_data;
47 const struct snd_motu_protocol *const protocol = motu->spec->protocol;
48 unsigned int mode;
49 struct snd_motu_packet_format *formats;
50 int i;
51
52 if (protocol->cache_packet_formats(motu) < 0)
53 return;
54
55 snd_iprintf(buffer, "tx:\tmsg\tfixed\tdiffered\n");
56 for (i = 0; i < SND_MOTU_CLOCK_RATE_COUNT; ++i) {
57 mode = i >> 1;
58
59 formats = &motu->tx_packet_formats;
60 snd_iprintf(buffer,
61 "%u:\t%u\t%u\t%u\n",
62 snd_motu_clock_rates[i],
63 formats->msg_chunks,
64 formats->fixed_part_pcm_chunks[mode],
65 formats->differed_part_pcm_chunks[mode]);
66 }
67
68 snd_iprintf(buffer, "rx:\tmsg\tfixed\tdiffered\n");
69 for (i = 0; i < SND_MOTU_CLOCK_RATE_COUNT; ++i) {
70 mode = i >> 1;
71
72 formats = &motu->rx_packet_formats;
73 snd_iprintf(buffer,
74 "%u:\t%u\t%u\t%u\n",
75 snd_motu_clock_rates[i],
76 formats->msg_chunks,
77 formats->fixed_part_pcm_chunks[mode],
78 formats->differed_part_pcm_chunks[mode]);
79 }
80}
81
82static void add_node(struct snd_motu *motu, struct snd_info_entry *root,
83 const char *name,
84 void (*op)(struct snd_info_entry *e,
85 struct snd_info_buffer *b))
86{
87 struct snd_info_entry *entry;
88
89 entry = snd_info_create_card_entry(motu->card, name, root);
90 if (entry == NULL)
91 return;
92
93 snd_info_set_text_ops(entry, motu, op);
94 if (snd_info_register(entry) < 0)
95 snd_info_free_entry(entry);
96}
97
98void snd_motu_proc_init(struct snd_motu *motu)
99{
100 struct snd_info_entry *root;
101
102 /*
103 * All nodes are automatically removed at snd_card_disconnect(),
104 * by following to link list.
105 */
106 root = snd_info_create_card_entry(motu->card, "firewire",
107 motu->card->proc_root);
108 if (root == NULL)
109 return;
110 root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
111 if (snd_info_register(root) < 0) {
112 snd_info_free_entry(root);
113 return;
114 }
115
116 add_node(motu, root, "clock", proc_read_clock);
117 add_node(motu, root, "format", proc_read_format);
118}
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c
new file mode 100644
index 000000000000..05b5d287c2f3
--- /dev/null
+++ b/sound/firewire/motu/motu-protocol-v2.c
@@ -0,0 +1,237 @@
1/*
2 * motu-protocol-v2.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "motu.h"
10
11#define V2_CLOCK_STATUS_OFFSET 0x0b14
12#define V2_CLOCK_RATE_MASK 0x00000038
13#define V2_CLOCK_RATE_SHIFT 3
14#define V2_CLOCK_SRC_MASK 0x00000007
15#define V2_CLOCK_SRC_SHIFT 0
16
17#define V2_IN_OUT_CONF_OFFSET 0x0c04
18#define V2_OPT_OUT_IFACE_MASK 0x00000c00
19#define V2_OPT_OUT_IFACE_SHIFT 10
20#define V2_OPT_IN_IFACE_MASK 0x00000300
21#define V2_OPT_IN_IFACE_SHIFT 8
22#define V2_OPT_IFACE_MODE_NONE 0
23#define V2_OPT_IFACE_MODE_ADAT 1
24#define V2_OPT_IFACE_MODE_SPDIF 2
25
26static int v2_get_clock_rate(struct snd_motu *motu, unsigned int *rate)
27{
28 __be32 reg;
29 unsigned int index;
30 int err;
31
32 err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg,
33 sizeof(reg));
34 if (err < 0)
35 return err;
36
37 index = (be32_to_cpu(reg) & V2_CLOCK_RATE_MASK) >> V2_CLOCK_RATE_SHIFT;
38 if (index >= ARRAY_SIZE(snd_motu_clock_rates))
39 return -EIO;
40
41 *rate = snd_motu_clock_rates[index];
42
43 return 0;
44}
45
46static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate)
47{
48 __be32 reg;
49 u32 data;
50 int i;
51 int err;
52
53 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
54 if (snd_motu_clock_rates[i] == rate)
55 break;
56 }
57 if (i == ARRAY_SIZE(snd_motu_clock_rates))
58 return -EINVAL;
59
60 err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg,
61 sizeof(reg));
62 if (err < 0)
63 return err;
64 data = be32_to_cpu(reg);
65
66 data &= ~V2_CLOCK_RATE_MASK;
67 data |= i << V2_CLOCK_RATE_SHIFT;
68
69 reg = cpu_to_be32(data);
70 return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, &reg,
71 sizeof(reg));
72}
73
74static int v2_get_clock_source(struct snd_motu *motu,
75 enum snd_motu_clock_source *src)
76{
77 __be32 reg;
78 unsigned int index;
79 int err;
80
81 err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg,
82 sizeof(reg));
83 if (err < 0)
84 return err;
85
86 index = be32_to_cpu(reg) & V2_CLOCK_SRC_MASK;
87 if (index > 5)
88 return -EIO;
89
90 /* To check the configuration of optical interface. */
91 err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg,
92 sizeof(reg));
93 if (err < 0)
94 return err;
95
96 switch (index) {
97 case 0:
98 *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
99 break;
100 case 1:
101 if (be32_to_cpu(reg) & 0x00000200)
102 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
103 else
104 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
105 break;
106 case 2:
107 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
108 break;
109 case 4:
110 *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
111 break;
112 case 5:
113 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
114 break;
115 default:
116 return -EIO;
117 }
118
119 return 0;
120}
121
122static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable)
123{
124 /* V2 protocol doesn't have this feature. */
125 return 0;
126}
127
128static void calculate_fixed_part(struct snd_motu_packet_format *formats,
129 enum amdtp_stream_direction dir,
130 enum snd_motu_spec_flags flags,
131 unsigned char analog_ports)
132{
133 unsigned char pcm_chunks[3] = {0, 0, 0};
134
135 formats->msg_chunks = 2;
136
137 pcm_chunks[0] = analog_ports;
138 pcm_chunks[1] = analog_ports;
139 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
140 pcm_chunks[2] = analog_ports;
141
142 if (dir == AMDTP_IN_STREAM) {
143 if (flags & SND_MOTU_SPEC_TX_MICINST_CHUNK) {
144 pcm_chunks[0] += 2;
145 pcm_chunks[1] += 2;
146 }
147 if (flags & SND_MOTU_SPEC_TX_RETURN_CHUNK) {
148 pcm_chunks[0] += 2;
149 pcm_chunks[1] += 2;
150 }
151 } else {
152 /*
153 * Packets to v2 units transfer main-out-1/2 and phone-out-1/2.
154 */
155 pcm_chunks[0] += 4;
156 pcm_chunks[1] += 4;
157 }
158
159 /*
160 * All of v2 models have a pair of coaxial interfaces for digital in/out
161 * port. At 44.1/48.0/88.2/96.0 kHz, packets includes PCM from these
162 * ports.
163 */
164 pcm_chunks[0] += 2;
165 pcm_chunks[1] += 2;
166
167 /* This part should be multiples of 4. */
168 formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2;
169 formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2;
170 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
171 formats->fixed_part_pcm_chunks[2] =
172 round_up(2 + pcm_chunks[2], 4) - 2;
173}
174
175static void calculate_differed_part(struct snd_motu_packet_format *formats,
176 enum snd_motu_spec_flags flags,
177 u32 data, u32 mask, u32 shift)
178{
179 unsigned char pcm_chunks[3] = {0, 0};
180
181 /*
182 * When optical interfaces are configured for S/PDIF (TOSLINK),
183 * the above PCM frames come from them, instead of coaxial
184 * interfaces.
185 */
186 data = (data & mask) >> shift;
187 if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_A) &&
188 data == V2_OPT_IFACE_MODE_ADAT) {
189 pcm_chunks[0] += 8;
190 pcm_chunks[1] += 4;
191 }
192
193 /* At mode x4, no data chunks are supported in this part. */
194 formats->differed_part_pcm_chunks[0] = pcm_chunks[0];
195 formats->differed_part_pcm_chunks[1] = pcm_chunks[1];
196}
197
198static int v2_cache_packet_formats(struct snd_motu *motu)
199{
200 __be32 reg;
201 u32 data;
202 int err;
203
204 err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg,
205 sizeof(reg));
206 if (err < 0)
207 return err;
208 data = be32_to_cpu(reg);
209
210 calculate_fixed_part(&motu->tx_packet_formats, AMDTP_IN_STREAM,
211 motu->spec->flags, motu->spec->analog_in_ports);
212 calculate_differed_part(&motu->tx_packet_formats, motu->spec->flags,
213 data, V2_OPT_IN_IFACE_MASK, V2_OPT_IN_IFACE_SHIFT);
214
215 calculate_fixed_part(&motu->rx_packet_formats, AMDTP_OUT_STREAM,
216 motu->spec->flags, motu->spec->analog_out_ports);
217 calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags,
218 data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT);
219
220 motu->tx_packet_formats.midi_flag_offset = 4;
221 motu->tx_packet_formats.midi_byte_offset = 6;
222 motu->tx_packet_formats.pcm_byte_offset = 10;
223
224 motu->rx_packet_formats.midi_flag_offset = 4;
225 motu->rx_packet_formats.midi_byte_offset = 6;
226 motu->rx_packet_formats.pcm_byte_offset = 10;
227
228 return 0;
229}
230
231const struct snd_motu_protocol snd_motu_protocol_v2 = {
232 .get_clock_rate = v2_get_clock_rate,
233 .set_clock_rate = v2_set_clock_rate,
234 .get_clock_source = v2_get_clock_source,
235 .switch_fetching_mode = v2_switch_fetching_mode,
236 .cache_packet_formats = v2_cache_packet_formats,
237};
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c
new file mode 100644
index 000000000000..ddb647254ed2
--- /dev/null
+++ b/sound/firewire/motu/motu-protocol-v3.c
@@ -0,0 +1,311 @@
1/*
2 * motu-protocol-v3.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/delay.h>
10#include "motu.h"
11
12#define V3_CLOCK_STATUS_OFFSET 0x0b14
13#define V3_FETCH_PCM_FRAMES 0x02000000
14#define V3_CLOCK_RATE_MASK 0x0000ff00
15#define V3_CLOCK_RATE_SHIFT 8
16#define V3_CLOCK_SOURCE_MASK 0x000000ff
17
18#define V3_OPT_IFACE_MODE_OFFSET 0x0c94
19#define V3_ENABLE_OPT_IN_IFACE_A 0x00000001
20#define V3_ENABLE_OPT_IN_IFACE_B 0x00000002
21#define V3_ENABLE_OPT_OUT_IFACE_A 0x00000100
22#define V3_ENABLE_OPT_OUT_IFACE_B 0x00000200
23#define V3_NO_ADAT_OPT_IN_IFACE_A 0x00010000
24#define V3_NO_ADAT_OPT_IN_IFACE_B 0x00100000
25#define V3_NO_ADAT_OPT_OUT_IFACE_A 0x00040000
26#define V3_NO_ADAT_OPT_OUT_IFACE_B 0x00400000
27
28static int v3_get_clock_rate(struct snd_motu *motu, unsigned int *rate)
29{
30 __be32 reg;
31 u32 data;
32 int err;
33
34 err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
35 sizeof(reg));
36 if (err < 0)
37 return err;
38 data = be32_to_cpu(reg);
39
40 data = (data & V3_CLOCK_RATE_MASK) >> V3_CLOCK_RATE_SHIFT;
41 if (data >= ARRAY_SIZE(snd_motu_clock_rates))
42 return -EIO;
43
44 *rate = snd_motu_clock_rates[data];
45
46 return 0;
47}
48
49static int v3_set_clock_rate(struct snd_motu *motu, unsigned int rate)
50{
51 __be32 reg;
52 u32 data;
53 bool need_to_wait;
54 int i, err;
55
56 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
57 if (snd_motu_clock_rates[i] == rate)
58 break;
59 }
60 if (i == ARRAY_SIZE(snd_motu_clock_rates))
61 return -EINVAL;
62
63 err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
64 sizeof(reg));
65 if (err < 0)
66 return err;
67 data = be32_to_cpu(reg);
68
69 data &= ~(V3_CLOCK_RATE_MASK | V3_FETCH_PCM_FRAMES);
70 data |= i << V3_CLOCK_RATE_SHIFT;
71
72 need_to_wait = data != be32_to_cpu(reg);
73
74 reg = cpu_to_be32(data);
75 err = snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg,
76 sizeof(reg));
77 if (err < 0)
78 return err;
79
80 if (need_to_wait) {
81 /* Cost expensive. */
82 if (msleep_interruptible(4000) > 0)
83 return -EINTR;
84 }
85
86 return 0;
87}
88
89static int v3_get_clock_source(struct snd_motu *motu,
90 enum snd_motu_clock_source *src)
91{
92 __be32 reg;
93 u32 data;
94 unsigned int val;
95 int err;
96
97 err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
98 sizeof(reg));
99 if (err < 0)
100 return err;
101 data = be32_to_cpu(reg);
102
103 val = data & V3_CLOCK_SOURCE_MASK;
104 if (val == 0x00) {
105 *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
106 } else if (val == 0x01) {
107 *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
108 } else if (val == 0x10) {
109 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
110 } else if (val == 0x18 || val == 0x19) {
111 err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET,
112 &reg, sizeof(reg));
113 if (err < 0)
114 return err;
115 data = be32_to_cpu(reg);
116
117 if (val == 0x18) {
118 if (data & V3_NO_ADAT_OPT_IN_IFACE_A)
119 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A;
120 else
121 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A;
122 } else {
123 if (data & V3_NO_ADAT_OPT_IN_IFACE_B)
124 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B;
125 else
126 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B;
127 }
128 } else {
129 *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
130 }
131
132 return 0;
133}
134
135static int v3_switch_fetching_mode(struct snd_motu *motu, bool enable)
136{
137 __be32 reg;
138 u32 data;
139 int err;
140
141 err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
142 sizeof(reg));
143 if (err < 0)
144 return 0;
145 data = be32_to_cpu(reg);
146
147 if (enable)
148 data |= V3_FETCH_PCM_FRAMES;
149 else
150 data &= ~V3_FETCH_PCM_FRAMES;
151
152 reg = cpu_to_be32(data);
153 return snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg,
154 sizeof(reg));
155}
156
157static void calculate_fixed_part(struct snd_motu_packet_format *formats,
158 enum amdtp_stream_direction dir,
159 enum snd_motu_spec_flags flags,
160 unsigned char analog_ports)
161{
162 unsigned char pcm_chunks[3] = {0, 0, 0};
163
164 formats->msg_chunks = 2;
165
166 pcm_chunks[0] = analog_ports;
167 pcm_chunks[1] = analog_ports;
168 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
169 pcm_chunks[2] = analog_ports;
170
171 if (dir == AMDTP_IN_STREAM) {
172 if (flags & SND_MOTU_SPEC_TX_MICINST_CHUNK) {
173 pcm_chunks[0] += 2;
174 pcm_chunks[1] += 2;
175 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
176 pcm_chunks[2] += 2;
177 }
178
179 if (flags & SND_MOTU_SPEC_TX_RETURN_CHUNK) {
180 pcm_chunks[0] += 2;
181 pcm_chunks[1] += 2;
182 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
183 pcm_chunks[2] += 2;
184 }
185
186 if (flags & SND_MOTU_SPEC_TX_REVERB_CHUNK) {
187 pcm_chunks[0] += 2;
188 pcm_chunks[1] += 2;
189 }
190 } else {
191 /*
192 * Packets to v2 units transfer main-out-1/2 and phone-out-1/2.
193 */
194 pcm_chunks[0] += 4;
195 pcm_chunks[1] += 4;
196 }
197
198 /*
199 * At least, packets have two data chunks for S/PDIF on coaxial
200 * interface.
201 */
202 pcm_chunks[0] += 2;
203 pcm_chunks[1] += 2;
204
205 /*
206 * Fixed part consists of PCM chunks multiple of 4, with msg chunks. As
207 * a result, this part can includes empty data chunks.
208 */
209 formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2;
210 formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2;
211 if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
212 formats->fixed_part_pcm_chunks[2] =
213 round_up(2 + pcm_chunks[2], 4) - 2;
214}
215
216static void calculate_differed_part(struct snd_motu_packet_format *formats,
217 enum snd_motu_spec_flags flags, u32 data,
218 u32 a_enable_mask, u32 a_no_adat_mask,
219 u32 b_enable_mask, u32 b_no_adat_mask)
220{
221 unsigned char pcm_chunks[3] = {0, 0, 0};
222 int i;
223
224 if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_A) && (data & a_enable_mask)) {
225 if (data & a_no_adat_mask) {
226 /*
227 * Additional two data chunks for S/PDIF on optical
228 * interface A. This includes empty data chunks.
229 */
230 pcm_chunks[0] += 4;
231 pcm_chunks[1] += 4;
232 } else {
233 /*
234 * Additional data chunks for ADAT on optical interface
235 * A.
236 */
237 pcm_chunks[0] += 8;
238 pcm_chunks[1] += 4;
239 }
240 }
241
242 if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_B) && (data & b_enable_mask)) {
243 if (data & b_no_adat_mask) {
244 /*
245 * Additional two data chunks for S/PDIF on optical
246 * interface B. This includes empty data chunks.
247 */
248 pcm_chunks[0] += 4;
249 pcm_chunks[1] += 4;
250 } else {
251 /*
252 * Additional data chunks for ADAT on optical interface
253 * B.
254 */
255 pcm_chunks[0] += 8;
256 pcm_chunks[1] += 4;
257 }
258 }
259
260 for (i = 0; i < 3; ++i) {
261 if (pcm_chunks[i] > 0)
262 pcm_chunks[i] = round_up(pcm_chunks[i], 4);
263
264 formats->differed_part_pcm_chunks[i] = pcm_chunks[i];
265 }
266}
267
268static int v3_cache_packet_formats(struct snd_motu *motu)
269{
270 __be32 reg;
271 u32 data;
272 int err;
273
274 err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET, &reg,
275 sizeof(reg));
276 if (err < 0)
277 return err;
278 data = be32_to_cpu(reg);
279
280 calculate_fixed_part(&motu->tx_packet_formats, AMDTP_IN_STREAM,
281 motu->spec->flags, motu->spec->analog_in_ports);
282 calculate_differed_part(&motu->tx_packet_formats,
283 motu->spec->flags, data,
284 V3_ENABLE_OPT_IN_IFACE_A, V3_NO_ADAT_OPT_IN_IFACE_A,
285 V3_ENABLE_OPT_IN_IFACE_B, V3_NO_ADAT_OPT_IN_IFACE_B);
286
287 calculate_fixed_part(&motu->rx_packet_formats, AMDTP_OUT_STREAM,
288 motu->spec->flags, motu->spec->analog_out_ports);
289 calculate_differed_part(&motu->rx_packet_formats,
290 motu->spec->flags, data,
291 V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A,
292 V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B);
293
294 motu->tx_packet_formats.midi_flag_offset = 8;
295 motu->tx_packet_formats.midi_byte_offset = 7;
296 motu->tx_packet_formats.pcm_byte_offset = 10;
297
298 motu->rx_packet_formats.midi_flag_offset = 8;
299 motu->rx_packet_formats.midi_byte_offset = 7;
300 motu->rx_packet_formats.pcm_byte_offset = 10;
301
302 return 0;
303}
304
305const struct snd_motu_protocol snd_motu_protocol_v3 = {
306 .get_clock_rate = v3_get_clock_rate,
307 .set_clock_rate = v3_set_clock_rate,
308 .get_clock_source = v3_get_clock_source,
309 .switch_fetching_mode = v3_switch_fetching_mode,
310 .cache_packet_formats = v3_cache_packet_formats,
311};
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
new file mode 100644
index 000000000000..bd458029099e
--- /dev/null
+++ b/sound/firewire/motu/motu-stream.c
@@ -0,0 +1,381 @@
1/*
2 * motu-stream.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "motu.h"
10
11#define CALLBACK_TIMEOUT 200
12
13#define ISOC_COMM_CONTROL_OFFSET 0x0b00
14#define ISOC_COMM_CONTROL_MASK 0xffff0000
15#define CHANGE_RX_ISOC_COMM_STATE 0x80000000
16#define RX_ISOC_COMM_IS_ACTIVATED 0x40000000
17#define RX_ISOC_COMM_CHANNEL_MASK 0x3f000000
18#define RX_ISOC_COMM_CHANNEL_SHIFT 24
19#define CHANGE_TX_ISOC_COMM_STATE 0x00800000
20#define TX_ISOC_COMM_IS_ACTIVATED 0x00400000
21#define TX_ISOC_COMM_CHANNEL_MASK 0x003f0000
22#define TX_ISOC_COMM_CHANNEL_SHIFT 16
23
24#define PACKET_FORMAT_OFFSET 0x0b10
25#define TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000080
26#define RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000040
27#define TX_PACKET_TRANSMISSION_SPEED_MASK 0x0000000f
28
29static int start_both_streams(struct snd_motu *motu, unsigned int rate)
30{
31 unsigned int midi_ports = 0;
32 __be32 reg;
33 u32 data;
34 int err;
35
36 if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI)
37 midi_ports = 1;
38
39 /* Set packet formation to our packet streaming engine. */
40 err = amdtp_motu_set_parameters(&motu->rx_stream, rate, midi_ports,
41 &motu->rx_packet_formats);
42 if (err < 0)
43 return err;
44
45 err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports,
46 &motu->tx_packet_formats);
47 if (err < 0)
48 return err;
49
50 /* Get isochronous resources on the bus. */
51 err = fw_iso_resources_allocate(&motu->rx_resources,
52 amdtp_stream_get_max_payload(&motu->rx_stream),
53 fw_parent_device(motu->unit)->max_speed);
54 if (err < 0)
55 return err;
56
57 err = fw_iso_resources_allocate(&motu->tx_resources,
58 amdtp_stream_get_max_payload(&motu->tx_stream),
59 fw_parent_device(motu->unit)->max_speed);
60 if (err < 0)
61 return err;
62
63 /* Configure the unit to start isochronous communication. */
64 err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
65 sizeof(reg));
66 if (err < 0)
67 return err;
68 data = be32_to_cpu(reg) & ~ISOC_COMM_CONTROL_MASK;
69
70 data |= CHANGE_RX_ISOC_COMM_STATE | RX_ISOC_COMM_IS_ACTIVATED |
71 (motu->rx_resources.channel << RX_ISOC_COMM_CHANNEL_SHIFT) |
72 CHANGE_TX_ISOC_COMM_STATE | TX_ISOC_COMM_IS_ACTIVATED |
73 (motu->tx_resources.channel << TX_ISOC_COMM_CHANNEL_SHIFT);
74
75 reg = cpu_to_be32(data);
76 return snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
77 sizeof(reg));
78}
79
80static void stop_both_streams(struct snd_motu *motu)
81{
82 __be32 reg;
83 u32 data;
84 int err;
85
86 err = motu->spec->protocol->switch_fetching_mode(motu, false);
87 if (err < 0)
88 return;
89
90 err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
91 sizeof(reg));
92 if (err < 0)
93 return;
94 data = be32_to_cpu(reg);
95
96 data &= ~(RX_ISOC_COMM_IS_ACTIVATED | TX_ISOC_COMM_IS_ACTIVATED);
97 data |= CHANGE_RX_ISOC_COMM_STATE | CHANGE_TX_ISOC_COMM_STATE;
98
99 reg = cpu_to_be32(data);
100 snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
101 sizeof(reg));
102
103 fw_iso_resources_free(&motu->tx_resources);
104 fw_iso_resources_free(&motu->rx_resources);
105}
106
107static int start_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
108{
109 struct fw_iso_resources *resources;
110 int err;
111
112 if (stream == &motu->rx_stream)
113 resources = &motu->rx_resources;
114 else
115 resources = &motu->tx_resources;
116
117 err = amdtp_stream_start(stream, resources->channel,
118 fw_parent_device(motu->unit)->max_speed);
119 if (err < 0)
120 return err;
121
122 if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
123 amdtp_stream_stop(stream);
124 fw_iso_resources_free(resources);
125 return -ETIMEDOUT;
126 }
127
128 return 0;
129}
130
131static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
132{
133 struct fw_iso_resources *resources;
134
135 if (stream == &motu->rx_stream)
136 resources = &motu->rx_resources;
137 else
138 resources = &motu->tx_resources;
139
140 amdtp_stream_stop(stream);
141 fw_iso_resources_free(resources);
142}
143
144static int ensure_packet_formats(struct snd_motu *motu)
145{
146 __be32 reg;
147 u32 data;
148 int err;
149
150 err = snd_motu_transaction_read(motu, PACKET_FORMAT_OFFSET, &reg,
151 sizeof(reg));
152 if (err < 0)
153 return err;
154 data = be32_to_cpu(reg);
155
156 data &= ~(TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS |
157 RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS|
158 TX_PACKET_TRANSMISSION_SPEED_MASK);
159 if (motu->tx_packet_formats.differed_part_pcm_chunks[0] == 0)
160 data |= TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
161 if (motu->rx_packet_formats.differed_part_pcm_chunks[0] == 0)
162 data |= RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
163 data |= fw_parent_device(motu->unit)->max_speed;
164
165 reg = cpu_to_be32(data);
166 return snd_motu_transaction_write(motu, PACKET_FORMAT_OFFSET, &reg,
167 sizeof(reg));
168}
169
170int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate)
171{
172 const struct snd_motu_protocol *protocol = motu->spec->protocol;
173 unsigned int curr_rate;
174 int err = 0;
175
176 if (motu->capture_substreams == 0 && motu->playback_substreams == 0)
177 return 0;
178
179 /* Some packet queueing errors. */
180 if (amdtp_streaming_error(&motu->rx_stream) ||
181 amdtp_streaming_error(&motu->tx_stream)) {
182 amdtp_stream_stop(&motu->rx_stream);
183 amdtp_stream_stop(&motu->tx_stream);
184 stop_both_streams(motu);
185 }
186
187 err = protocol->cache_packet_formats(motu);
188 if (err < 0)
189 return err;
190
191 /* Stop stream if rate is different. */
192 err = protocol->get_clock_rate(motu, &curr_rate);
193 if (err < 0) {
194 dev_err(&motu->unit->device,
195 "fail to get sampling rate: %d\n", err);
196 return err;
197 }
198 if (rate == 0)
199 rate = curr_rate;
200 if (rate != curr_rate) {
201 amdtp_stream_stop(&motu->rx_stream);
202 amdtp_stream_stop(&motu->tx_stream);
203 stop_both_streams(motu);
204 }
205
206 if (!amdtp_stream_running(&motu->rx_stream)) {
207 err = protocol->set_clock_rate(motu, rate);
208 if (err < 0) {
209 dev_err(&motu->unit->device,
210 "fail to set sampling rate: %d\n", err);
211 return err;
212 }
213
214 err = ensure_packet_formats(motu);
215 if (err < 0)
216 return err;
217
218 err = start_both_streams(motu, rate);
219 if (err < 0) {
220 dev_err(&motu->unit->device,
221 "fail to start isochronous comm: %d\n", err);
222 stop_both_streams(motu);
223 return err;
224 }
225
226 err = start_isoc_ctx(motu, &motu->rx_stream);
227 if (err < 0) {
228 dev_err(&motu->unit->device,
229 "fail to start IT context: %d\n", err);
230 stop_both_streams(motu);
231 return err;
232 }
233
234 err = protocol->switch_fetching_mode(motu, true);
235 if (err < 0) {
236 dev_err(&motu->unit->device,
237 "fail to enable frame fetching: %d\n", err);
238 stop_both_streams(motu);
239 return err;
240 }
241 }
242
243 if (!amdtp_stream_running(&motu->tx_stream) &&
244 motu->capture_substreams > 0) {
245 err = start_isoc_ctx(motu, &motu->tx_stream);
246 if (err < 0) {
247 dev_err(&motu->unit->device,
248 "fail to start IR context: %d", err);
249 amdtp_stream_stop(&motu->rx_stream);
250 stop_both_streams(motu);
251 return err;
252 }
253 }
254
255 return 0;
256}
257
258void snd_motu_stream_stop_duplex(struct snd_motu *motu)
259{
260 if (motu->capture_substreams == 0) {
261 if (amdtp_stream_running(&motu->tx_stream))
262 stop_isoc_ctx(motu, &motu->tx_stream);
263
264 if (motu->playback_substreams == 0) {
265 if (amdtp_stream_running(&motu->rx_stream))
266 stop_isoc_ctx(motu, &motu->rx_stream);
267 stop_both_streams(motu);
268 }
269 }
270}
271
272static int init_stream(struct snd_motu *motu, enum amdtp_stream_direction dir)
273{
274 int err;
275 struct amdtp_stream *stream;
276 struct fw_iso_resources *resources;
277
278 if (dir == AMDTP_IN_STREAM) {
279 stream = &motu->tx_stream;
280 resources = &motu->tx_resources;
281 } else {
282 stream = &motu->rx_stream;
283 resources = &motu->rx_resources;
284 }
285
286 err = fw_iso_resources_init(resources, motu->unit);
287 if (err < 0)
288 return err;
289
290 err = amdtp_motu_init(stream, motu->unit, dir, motu->spec->protocol);
291 if (err < 0) {
292 amdtp_stream_destroy(stream);
293 fw_iso_resources_destroy(resources);
294 }
295
296 return err;
297}
298
299static void destroy_stream(struct snd_motu *motu,
300 enum amdtp_stream_direction dir)
301{
302 struct amdtp_stream *stream;
303 struct fw_iso_resources *resources;
304
305 if (dir == AMDTP_IN_STREAM) {
306 stream = &motu->tx_stream;
307 resources = &motu->tx_resources;
308 } else {
309 stream = &motu->rx_stream;
310 resources = &motu->rx_resources;
311 }
312
313 amdtp_stream_destroy(stream);
314 fw_iso_resources_free(resources);
315}
316
317int snd_motu_stream_init_duplex(struct snd_motu *motu)
318{
319 int err;
320
321 err = init_stream(motu, AMDTP_IN_STREAM);
322 if (err < 0)
323 return err;
324
325 err = init_stream(motu, AMDTP_OUT_STREAM);
326 if (err < 0)
327 destroy_stream(motu, AMDTP_IN_STREAM);
328
329 return err;
330}
331
332/*
333 * This function should be called before starting streams or after stopping
334 * streams.
335 */
336void snd_motu_stream_destroy_duplex(struct snd_motu *motu)
337{
338 destroy_stream(motu, AMDTP_IN_STREAM);
339 destroy_stream(motu, AMDTP_OUT_STREAM);
340
341 motu->playback_substreams = 0;
342 motu->capture_substreams = 0;
343}
344
345static void motu_lock_changed(struct snd_motu *motu)
346{
347 motu->dev_lock_changed = true;
348 wake_up(&motu->hwdep_wait);
349}
350
351int snd_motu_stream_lock_try(struct snd_motu *motu)
352{
353 int err;
354
355 spin_lock_irq(&motu->lock);
356
357 if (motu->dev_lock_count < 0) {
358 err = -EBUSY;
359 goto out;
360 }
361
362 if (motu->dev_lock_count++ == 0)
363 motu_lock_changed(motu);
364 err = 0;
365out:
366 spin_unlock_irq(&motu->lock);
367 return err;
368}
369
370void snd_motu_stream_lock_release(struct snd_motu *motu)
371{
372 spin_lock_irq(&motu->lock);
373
374 if (WARN_ON(motu->dev_lock_count <= 0))
375 goto out;
376
377 if (--motu->dev_lock_count == 0)
378 motu_lock_changed(motu);
379out:
380 spin_unlock_irq(&motu->lock);
381}
diff --git a/sound/firewire/motu/motu-transaction.c b/sound/firewire/motu/motu-transaction.c
new file mode 100644
index 000000000000..7fc30091e0de
--- /dev/null
+++ b/sound/firewire/motu/motu-transaction.c
@@ -0,0 +1,137 @@
1/*
2 * motu-transaction.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9
10#include "motu.h"
11
12#define SND_MOTU_ADDR_BASE 0xfffff0000000ULL
13#define ASYNC_ADDR_HI 0x0b04
14#define ASYNC_ADDR_LO 0x0b08
15
16int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
17 size_t size)
18{
19 int tcode;
20
21 if (size % sizeof(__be32) > 0 || size <= 0)
22 return -EINVAL;
23 if (size == sizeof(__be32))
24 tcode = TCODE_READ_QUADLET_REQUEST;
25 else
26 tcode = TCODE_READ_BLOCK_REQUEST;
27
28 return snd_fw_transaction(motu->unit, tcode,
29 SND_MOTU_ADDR_BASE + offset, reg, size, 0);
30}
31
32int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
33 size_t size)
34{
35 int tcode;
36
37 if (size % sizeof(__be32) > 0 || size <= 0)
38 return -EINVAL;
39 if (size == sizeof(__be32))
40 tcode = TCODE_WRITE_QUADLET_REQUEST;
41 else
42 tcode = TCODE_WRITE_BLOCK_REQUEST;
43
44 return snd_fw_transaction(motu->unit, tcode,
45 SND_MOTU_ADDR_BASE + offset, reg, size, 0);
46}
47
48static void handle_message(struct fw_card *card, struct fw_request *request,
49 int tcode, int destination, int source,
50 int generation, unsigned long long offset,
51 void *data, size_t length, void *callback_data)
52{
53 struct snd_motu *motu = callback_data;
54 __be32 *buf = (__be32 *)data;
55 unsigned long flags;
56
57 if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
58 fw_send_response(card, request, RCODE_COMPLETE);
59 return;
60 }
61
62 if (offset != motu->async_handler.offset || length != 4) {
63 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
64 return;
65 }
66
67 spin_lock_irqsave(&motu->lock, flags);
68 motu->msg = be32_to_cpu(*buf);
69 spin_unlock_irqrestore(&motu->lock, flags);
70
71 fw_send_response(card, request, RCODE_COMPLETE);
72
73 wake_up(&motu->hwdep_wait);
74}
75
76int snd_motu_transaction_reregister(struct snd_motu *motu)
77{
78 struct fw_device *device = fw_parent_device(motu->unit);
79 __be32 data;
80 int err;
81
82 if (motu->async_handler.callback_data == NULL)
83 return -EINVAL;
84
85 /* Register messaging address. Block transaction is not allowed. */
86 data = cpu_to_be32((device->card->node_id << 16) |
87 (motu->async_handler.offset >> 32));
88 err = snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data,
89 sizeof(data));
90 if (err < 0)
91 return err;
92
93 data = cpu_to_be32(motu->async_handler.offset);
94 return snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data,
95 sizeof(data));
96}
97
98int snd_motu_transaction_register(struct snd_motu *motu)
99{
100 static const struct fw_address_region resp_register_region = {
101 .start = 0xffffe0000000ull,
102 .end = 0xffffe000ffffull,
103 };
104 int err;
105
106 /* Perhaps, 4 byte messages are transferred. */
107 motu->async_handler.length = 4;
108 motu->async_handler.address_callback = handle_message;
109 motu->async_handler.callback_data = motu;
110
111 err = fw_core_add_address_handler(&motu->async_handler,
112 &resp_register_region);
113 if (err < 0)
114 return err;
115
116 err = snd_motu_transaction_reregister(motu);
117 if (err < 0) {
118 fw_core_remove_address_handler(&motu->async_handler);
119 motu->async_handler.address_callback = NULL;
120 }
121
122 return err;
123}
124
125void snd_motu_transaction_unregister(struct snd_motu *motu)
126{
127 __be32 data;
128
129 if (motu->async_handler.address_callback != NULL)
130 fw_core_remove_address_handler(&motu->async_handler);
131 motu->async_handler.address_callback = NULL;
132
133 /* Unregister the address. */
134 data = cpu_to_be32(0x00000000);
135 snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data, sizeof(data));
136 snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data, sizeof(data));
137}
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c
new file mode 100644
index 000000000000..bf779cfeef0d
--- /dev/null
+++ b/sound/firewire/motu/motu.c
@@ -0,0 +1,264 @@
1/*
2 * motu.c - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "motu.h"
10
11#define OUI_MOTU 0x0001f2
12
13MODULE_DESCRIPTION("MOTU FireWire driver");
14MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
15MODULE_LICENSE("GPL v2");
16
17const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT] = {
18 /* mode 0 */
19 [0] = 44100,
20 [1] = 48000,
21 /* mode 1 */
22 [2] = 88200,
23 [3] = 96000,
24 /* mode 2 */
25 [4] = 176400,
26 [5] = 192000,
27};
28
29static void name_card(struct snd_motu *motu)
30{
31 struct fw_device *fw_dev = fw_parent_device(motu->unit);
32 struct fw_csr_iterator it;
33 int key, val;
34 u32 version = 0;
35
36 fw_csr_iterator_init(&it, motu->unit->directory);
37 while (fw_csr_iterator_next(&it, &key, &val)) {
38 switch (key) {
39 case CSR_VERSION:
40 version = val;
41 break;
42 }
43 }
44
45 strcpy(motu->card->driver, "FW-MOTU");
46 strcpy(motu->card->shortname, motu->spec->name);
47 strcpy(motu->card->mixername, motu->spec->name);
48 snprintf(motu->card->longname, sizeof(motu->card->longname),
49 "MOTU %s (version:%d), GUID %08x%08x at %s, S%d",
50 motu->spec->name, version,
51 fw_dev->config_rom[3], fw_dev->config_rom[4],
52 dev_name(&motu->unit->device), 100 << fw_dev->max_speed);
53}
54
55static void motu_free(struct snd_motu *motu)
56{
57 snd_motu_transaction_unregister(motu);
58
59 snd_motu_stream_destroy_duplex(motu);
60 fw_unit_put(motu->unit);
61
62 mutex_destroy(&motu->mutex);
63 kfree(motu);
64}
65
66/*
67 * This module releases the FireWire unit data after all ALSA character devices
68 * are released by applications. This is for releasing stream data or finishing
69 * transactions safely. Thus at returning from .remove(), this module still keep
70 * references for the unit.
71 */
72static void motu_card_free(struct snd_card *card)
73{
74 motu_free(card->private_data);
75}
76
77static void do_registration(struct work_struct *work)
78{
79 struct snd_motu *motu = container_of(work, struct snd_motu, dwork.work);
80 int err;
81
82 if (motu->registered)
83 return;
84
85 err = snd_card_new(&motu->unit->device, -1, NULL, THIS_MODULE, 0,
86 &motu->card);
87 if (err < 0)
88 return;
89
90 name_card(motu);
91
92 err = snd_motu_transaction_register(motu);
93 if (err < 0)
94 goto error;
95
96 err = snd_motu_stream_init_duplex(motu);
97 if (err < 0)
98 goto error;
99
100 snd_motu_proc_init(motu);
101
102 err = snd_motu_create_pcm_devices(motu);
103 if (err < 0)
104 goto error;
105
106 if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) {
107 err = snd_motu_create_midi_devices(motu);
108 if (err < 0)
109 goto error;
110 }
111
112 err = snd_motu_create_hwdep_device(motu);
113 if (err < 0)
114 goto error;
115
116 err = snd_card_register(motu->card);
117 if (err < 0)
118 goto error;
119
120 /*
121 * After registered, motu instance can be released corresponding to
122 * releasing the sound card instance.
123 */
124 motu->card->private_free = motu_card_free;
125 motu->card->private_data = motu;
126 motu->registered = true;
127
128 return;
129error:
130 snd_motu_transaction_unregister(motu);
131 snd_card_free(motu->card);
132 dev_info(&motu->unit->device,
133 "Sound card registration failed: %d\n", err);
134}
135
136static int motu_probe(struct fw_unit *unit,
137 const struct ieee1394_device_id *entry)
138{
139 struct snd_motu *motu;
140
141 /* Allocate this independently of sound card instance. */
142 motu = kzalloc(sizeof(struct snd_motu), GFP_KERNEL);
143 if (motu == NULL)
144 return -ENOMEM;
145
146 motu->spec = (const struct snd_motu_spec *)entry->driver_data;
147 motu->unit = fw_unit_get(unit);
148 dev_set_drvdata(&unit->device, motu);
149
150 mutex_init(&motu->mutex);
151 spin_lock_init(&motu->lock);
152 init_waitqueue_head(&motu->hwdep_wait);
153
154 /* Allocate and register this sound card later. */
155 INIT_DEFERRABLE_WORK(&motu->dwork, do_registration);
156 snd_fw_schedule_registration(unit, &motu->dwork);
157
158 return 0;
159}
160
161static void motu_remove(struct fw_unit *unit)
162{
163 struct snd_motu *motu = dev_get_drvdata(&unit->device);
164
165 /*
166 * Confirm to stop the work for registration before the sound card is
167 * going to be released. The work is not scheduled again because bus
168 * reset handler is not called anymore.
169 */
170 cancel_delayed_work_sync(&motu->dwork);
171
172 if (motu->registered) {
173 /* No need to wait for releasing card object in this context. */
174 snd_card_free_when_closed(motu->card);
175 } else {
176 /* Don't forget this case. */
177 motu_free(motu);
178 }
179}
180
181static void motu_bus_update(struct fw_unit *unit)
182{
183 struct snd_motu *motu = dev_get_drvdata(&unit->device);
184
185 /* Postpone a workqueue for deferred registration. */
186 if (!motu->registered)
187 snd_fw_schedule_registration(unit, &motu->dwork);
188
189 /* The handler address register becomes initialized. */
190 snd_motu_transaction_reregister(motu);
191}
192
193static struct snd_motu_spec motu_828mk2 = {
194 .name = "828mk2",
195 .protocol = &snd_motu_protocol_v2,
196 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
197 SND_MOTU_SPEC_TX_MICINST_CHUNK |
198 SND_MOTU_SPEC_TX_RETURN_CHUNK |
199 SND_MOTU_SPEC_HAS_OPT_IFACE_A |
200 SND_MOTU_SPEC_HAS_MIDI,
201
202 .analog_in_ports = 8,
203 .analog_out_ports = 8,
204};
205
206static struct snd_motu_spec motu_828mk3 = {
207 .name = "828mk3",
208 .protocol = &snd_motu_protocol_v3,
209 .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
210 SND_MOTU_SPEC_SUPPORT_CLOCK_X4 |
211 SND_MOTU_SPEC_TX_MICINST_CHUNK |
212 SND_MOTU_SPEC_TX_RETURN_CHUNK |
213 SND_MOTU_SPEC_TX_REVERB_CHUNK |
214 SND_MOTU_SPEC_HAS_OPT_IFACE_A |
215 SND_MOTU_SPEC_HAS_OPT_IFACE_B |
216 SND_MOTU_SPEC_HAS_MIDI,
217
218 .analog_in_ports = 8,
219 .analog_out_ports = 8,
220};
221
222#define SND_MOTU_DEV_ENTRY(model, data) \
223{ \
224 .match_flags = IEEE1394_MATCH_VENDOR_ID | \
225 IEEE1394_MATCH_MODEL_ID | \
226 IEEE1394_MATCH_SPECIFIER_ID, \
227 .vendor_id = OUI_MOTU, \
228 .model_id = model, \
229 .specifier_id = OUI_MOTU, \
230 .driver_data = (kernel_ulong_t)data, \
231}
232
233static const struct ieee1394_device_id motu_id_table[] = {
234 SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2),
235 SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */
236 SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */
237 { }
238};
239MODULE_DEVICE_TABLE(ieee1394, motu_id_table);
240
241static struct fw_driver motu_driver = {
242 .driver = {
243 .owner = THIS_MODULE,
244 .name = KBUILD_MODNAME,
245 .bus = &fw_bus_type,
246 },
247 .probe = motu_probe,
248 .update = motu_bus_update,
249 .remove = motu_remove,
250 .id_table = motu_id_table,
251};
252
253static int __init alsa_motu_init(void)
254{
255 return driver_register(&motu_driver.driver);
256}
257
258static void __exit alsa_motu_exit(void)
259{
260 driver_unregister(&motu_driver.driver);
261}
262
263module_init(alsa_motu_init);
264module_exit(alsa_motu_exit);
diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h
new file mode 100644
index 000000000000..8d6a4a3af9cc
--- /dev/null
+++ b/sound/firewire/motu/motu.h
@@ -0,0 +1,161 @@
1/*
2 * motu.h - a part of driver for MOTU FireWire series
3 *
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED
10#define SOUND_FIREWIRE_MOTU_H_INCLUDED
11
12#include <linux/device.h>
13#include <linux/firewire.h>
14#include <linux/firewire-constants.h>
15#include <linux/module.h>
16#include <linux/mod_devicetable.h>
17#include <linux/mutex.h>
18#include <linux/slab.h>
19#include <linux/compat.h>
20#include <linux/sched/signal.h>
21
22#include <sound/control.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/info.h>
26#include <sound/rawmidi.h>
27#include <sound/firewire.h>
28#include <sound/hwdep.h>
29
30#include "../lib.h"
31#include "../amdtp-stream.h"
32#include "../iso-resources.h"
33
34struct snd_motu_packet_format {
35 unsigned char midi_flag_offset;
36 unsigned char midi_byte_offset;
37 unsigned char pcm_byte_offset;
38
39 unsigned char msg_chunks;
40 unsigned char fixed_part_pcm_chunks[3];
41 unsigned char differed_part_pcm_chunks[3];
42};
43
44struct snd_motu {
45 struct snd_card *card;
46 struct fw_unit *unit;
47 struct mutex mutex;
48 spinlock_t lock;
49
50 bool registered;
51 struct delayed_work dwork;
52
53 /* Model dependent information. */
54 const struct snd_motu_spec *spec;
55
56 /* For packet streaming */
57 struct snd_motu_packet_format tx_packet_formats;
58 struct snd_motu_packet_format rx_packet_formats;
59 struct amdtp_stream tx_stream;
60 struct amdtp_stream rx_stream;
61 struct fw_iso_resources tx_resources;
62 struct fw_iso_resources rx_resources;
63 unsigned int capture_substreams;
64 unsigned int playback_substreams;
65
66 /* For notification. */
67 struct fw_address_handler async_handler;
68 u32 msg;
69
70 /* For uapi */
71 int dev_lock_count;
72 bool dev_lock_changed;
73 wait_queue_head_t hwdep_wait;
74};
75
76enum snd_motu_spec_flags {
77 SND_MOTU_SPEC_SUPPORT_CLOCK_X2 = 0x0001,
78 SND_MOTU_SPEC_SUPPORT_CLOCK_X4 = 0x0002,
79 SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004,
80 SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008,
81 SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010,
82 SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020,
83 SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040,
84 SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080,
85 SND_MOTU_SPEC_HAS_MIDI = 0x0100,
86};
87
88#define SND_MOTU_CLOCK_RATE_COUNT 6
89extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT];
90
91enum snd_motu_clock_source {
92 SND_MOTU_CLOCK_SOURCE_INTERNAL,
93 SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB,
94 SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT,
95 SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A,
96 SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B,
97 SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT,
98 SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A,
99 SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B,
100 SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX,
101 SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR,
102 SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC,
103 SND_MOTU_CLOCK_SOURCE_UNKNOWN,
104};
105
106struct snd_motu_protocol {
107 int (*get_clock_rate)(struct snd_motu *motu, unsigned int *rate);
108 int (*set_clock_rate)(struct snd_motu *motu, unsigned int rate);
109 int (*get_clock_source)(struct snd_motu *motu,
110 enum snd_motu_clock_source *source);
111 int (*switch_fetching_mode)(struct snd_motu *motu, bool enable);
112 int (*cache_packet_formats)(struct snd_motu *motu);
113};
114
115struct snd_motu_spec {
116 const char *const name;
117 enum snd_motu_spec_flags flags;
118
119 unsigned char analog_in_ports;
120 unsigned char analog_out_ports;
121
122 const struct snd_motu_protocol *const protocol;
123};
124
125extern const struct snd_motu_protocol snd_motu_protocol_v2;
126extern const struct snd_motu_protocol snd_motu_protocol_v3;
127
128int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
129 enum amdtp_stream_direction dir,
130 const struct snd_motu_protocol *const protocol);
131int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
132 unsigned int midi_ports,
133 struct snd_motu_packet_format *formats);
134int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
135 struct snd_pcm_runtime *runtime);
136void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
137 struct snd_rawmidi_substream *midi);
138
139int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
140 size_t size);
141int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
142 size_t size);
143int snd_motu_transaction_register(struct snd_motu *motu);
144int snd_motu_transaction_reregister(struct snd_motu *motu);
145void snd_motu_transaction_unregister(struct snd_motu *motu);
146
147int snd_motu_stream_init_duplex(struct snd_motu *motu);
148void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
149int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate);
150void snd_motu_stream_stop_duplex(struct snd_motu *motu);
151int snd_motu_stream_lock_try(struct snd_motu *motu);
152void snd_motu_stream_lock_release(struct snd_motu *motu);
153
154void snd_motu_proc_init(struct snd_motu *motu);
155
156int snd_motu_create_pcm_devices(struct snd_motu *motu);
157
158int snd_motu_create_midi_devices(struct snd_motu *motu);
159
160int snd_motu_create_hwdep_device(struct snd_motu *motu);
161#endif
diff --git a/sound/firewire/oxfw/oxfw-command.c b/sound/firewire/oxfw/oxfw-command.c
index 12ef3253bc89..ac3e2e301666 100644
--- a/sound/firewire/oxfw/oxfw-command.c
+++ b/sound/firewire/oxfw/oxfw-command.c
@@ -34,7 +34,9 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, 34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10,
35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
36 BIT(6) | BIT(7) | BIT(8)); 36 BIT(6) | BIT(7) | BIT(8));
37 if ((err > 0) && (err < len + 10)) 37 if (err < 0)
38 ;
39 else if (err < len + 10)
38 err = -EIO; 40 err = -EIO;
39 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 41 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
40 err = -ENOSYS; 42 err = -ENOSYS;
@@ -77,7 +79,9 @@ int avc_stream_get_format(struct fw_unit *unit,
77 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 79 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
78 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 80 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
79 BIT(6) | BIT(7)); 81 BIT(6) | BIT(7));
80 if ((err > 0) && (err < 10)) 82 if (err < 0)
83 ;
84 else if (err < 12)
81 err = -EIO; 85 err = -EIO;
82 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 86 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
83 err = -ENOSYS; 87 err = -ENOSYS;
@@ -139,7 +143,9 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
139 /* do transaction and check buf[1-5] are the same against command */ 143 /* do transaction and check buf[1-5] are the same against command */
140 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 144 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
141 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 145 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
142 if ((err > 0) && (err < 8)) 146 if (err < 0)
147 ;
148 else if (err < 8)
143 err = -EIO; 149 err = -EIO;
144 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 150 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
145 err = -ENOSYS; 151 err = -ENOSYS;
diff --git a/sound/firewire/tascam/tascam-midi.c b/sound/firewire/tascam/tascam-midi.c
index df4f95d65925..4a741570d536 100644
--- a/sound/firewire/tascam/tascam-midi.c
+++ b/sound/firewire/tascam/tascam-midi.c
@@ -18,9 +18,8 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)
18{ 18{
19 struct snd_tscm *tscm = substream->rmidi->private_data; 19 struct snd_tscm *tscm = substream->rmidi->private_data;
20 20
21 /* Initialize internal status. */ 21 snd_fw_async_midi_port_init(&tscm->out_ports[substream->number]);
22 tscm->running_status[substream->number] = 0; 22
23 tscm->on_sysex[substream->number] = 0;
24 return 0; 23 return 0;
25} 24}
26 25
@@ -32,11 +31,14 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream)
32 31
33static int midi_playback_close(struct snd_rawmidi_substream *substream) 32static int midi_playback_close(struct snd_rawmidi_substream *substream)
34{ 33{
34 return 0;
35}
36
37static void midi_playback_drain(struct snd_rawmidi_substream *substream)
38{
35 struct snd_tscm *tscm = substream->rmidi->private_data; 39 struct snd_tscm *tscm = substream->rmidi->private_data;
36 40
37 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]); 41 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]);
38
39 return 0;
40} 42}
41 43
42static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) 44static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
@@ -78,6 +80,7 @@ int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
78 static const struct snd_rawmidi_ops playback_ops = { 80 static const struct snd_rawmidi_ops playback_ops = {
79 .open = midi_playback_open, 81 .open = midi_playback_open,
80 .close = midi_playback_close, 82 .close = midi_playback_close,
83 .drain = midi_playback_drain,
81 .trigger = midi_playback_trigger, 84 .trigger = midi_playback_trigger,
82 }; 85 };
83 struct snd_rawmidi *rmidi; 86 struct snd_rawmidi *rmidi;
diff --git a/sound/firewire/tascam/tascam-transaction.c b/sound/firewire/tascam/tascam-transaction.c
index 040a96d1ba8e..8967c52f5032 100644
--- a/sound/firewire/tascam/tascam-transaction.c
+++ b/sound/firewire/tascam/tascam-transaction.c
@@ -58,39 +58,38 @@ static inline int calculate_message_bytes(u8 status)
58 return -EINVAL; 58 return -EINVAL;
59} 59}
60 60
61static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf) 61static int fill_message(struct snd_fw_async_midi_port *port,
62 struct snd_rawmidi_substream *substream)
62{ 63{
63 struct snd_tscm *tscm = substream->rmidi->private_data;
64 unsigned int port = substream->number;
65 int i, len, consume; 64 int i, len, consume;
66 u8 *label, *msg; 65 u8 *label, *msg;
67 u8 status; 66 u8 status;
68 67
69 /* The first byte is used for label, the rest for MIDI bytes. */ 68 /* The first byte is used for label, the rest for MIDI bytes. */
70 label = buf; 69 label = port->buf;
71 msg = buf + 1; 70 msg = port->buf + 1;
72 71
73 consume = snd_rawmidi_transmit_peek(substream, msg, 3); 72 consume = snd_rawmidi_transmit_peek(substream, msg, 3);
74 if (consume == 0) 73 if (consume == 0)
75 return 0; 74 return 0;
76 75
77 /* On exclusive message. */ 76 /* On exclusive message. */
78 if (tscm->on_sysex[port]) { 77 if (port->on_sysex) {
79 /* Seek the end of exclusives. */ 78 /* Seek the end of exclusives. */
80 for (i = 0; i < consume; ++i) { 79 for (i = 0; i < consume; ++i) {
81 if (msg[i] == 0xf7) { 80 if (msg[i] == 0xf7) {
82 tscm->on_sysex[port] = false; 81 port->on_sysex = false;
83 break; 82 break;
84 } 83 }
85 } 84 }
86 85
87 /* At the end of exclusive message, use label 0x07. */ 86 /* At the end of exclusive message, use label 0x07. */
88 if (!tscm->on_sysex[port]) { 87 if (!port->on_sysex) {
89 consume = i + 1; 88 consume = i + 1;
90 *label = (port << 4) | 0x07; 89 *label = (substream->number << 4) | 0x07;
91 /* During exclusive message, use label 0x04. */ 90 /* During exclusive message, use label 0x04. */
92 } else if (consume == 3) { 91 } else if (consume == 3) {
93 *label = (port << 4) | 0x04; 92 *label = (substream->number << 4) | 0x04;
94 /* We need to fill whole 3 bytes. Go to next change. */ 93 /* We need to fill whole 3 bytes. Go to next change. */
95 } else { 94 } else {
96 return 0; 95 return 0;
@@ -101,12 +100,12 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
101 /* The beginning of exclusives. */ 100 /* The beginning of exclusives. */
102 if (msg[0] == 0xf0) { 101 if (msg[0] == 0xf0) {
103 /* Transfer it in next chance in another condition. */ 102 /* Transfer it in next chance in another condition. */
104 tscm->on_sysex[port] = true; 103 port->on_sysex = true;
105 return 0; 104 return 0;
106 } else { 105 } else {
107 /* On running-status. */ 106 /* On running-status. */
108 if ((msg[0] & 0x80) != 0x80) 107 if ((msg[0] & 0x80) != 0x80)
109 status = tscm->running_status[port]; 108 status = port->running_status;
110 else 109 else
111 status = msg[0]; 110 status = msg[0];
112 111
@@ -124,18 +123,18 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
124 123
125 msg[2] = msg[1]; 124 msg[2] = msg[1];
126 msg[1] = msg[0]; 125 msg[1] = msg[0];
127 msg[0] = tscm->running_status[port]; 126 msg[0] = port->running_status;
128 } else { 127 } else {
129 /* Enough MIDI bytes were not retrieved. */ 128 /* Enough MIDI bytes were not retrieved. */
130 if (consume < len) 129 if (consume < len)
131 return 0; 130 return 0;
132 consume = len; 131 consume = len;
133 132
134 tscm->running_status[port] = msg[0]; 133 port->running_status = msg[0];
135 } 134 }
136 } 135 }
137 136
138 *label = (port << 4) | (msg[0] >> 4); 137 *label = (substream->number << 4) | (msg[0] >> 4);
139 } 138 }
140 139
141 if (len > 0 && len < 3) 140 if (len > 0 && len < 3)
@@ -144,6 +143,106 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
144 return consume; 143 return consume;
145} 144}
146 145
146static void async_midi_port_callback(struct fw_card *card, int rcode,
147 void *data, size_t length,
148 void *callback_data)
149{
150 struct snd_fw_async_midi_port *port = callback_data;
151 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
152
153 /* This port is closed. */
154 if (substream == NULL)
155 return;
156
157 if (rcode == RCODE_COMPLETE)
158 snd_rawmidi_transmit_ack(substream, port->consume_bytes);
159 else if (!rcode_is_permanent_error(rcode))
160 /* To start next transaction immediately for recovery. */
161 port->next_ktime = 0;
162 else
163 /* Don't continue processing. */
164 port->error = true;
165
166 port->idling = true;
167
168 if (!snd_rawmidi_transmit_empty(substream))
169 schedule_work(&port->work);
170}
171
172static void midi_port_work(struct work_struct *work)
173{
174 struct snd_fw_async_midi_port *port =
175 container_of(work, struct snd_fw_async_midi_port, work);
176 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
177 int generation;
178
179 /* Under transacting or error state. */
180 if (!port->idling || port->error)
181 return;
182
183 /* Nothing to do. */
184 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
185 return;
186
187 /* Do it in next chance. */
188 if (ktime_after(port->next_ktime, ktime_get())) {
189 schedule_work(&port->work);
190 return;
191 }
192
193 /*
194 * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().
195 * Later, snd_rawmidi_transmit_ack() is called.
196 */
197 memset(port->buf, 0, 4);
198 port->consume_bytes = fill_message(port, substream);
199 if (port->consume_bytes <= 0) {
200 /* Do it in next chance, immediately. */
201 if (port->consume_bytes == 0) {
202 port->next_ktime = 0;
203 schedule_work(&port->work);
204 } else {
205 /* Fatal error. */
206 port->error = true;
207 }
208 return;
209 }
210
211 /* Set interval to next transaction. */
212 port->next_ktime = ktime_add_ns(ktime_get(),
213 port->consume_bytes * 8 * NSEC_PER_SEC / 31250);
214
215 /* Start this transaction. */
216 port->idling = false;
217
218 /*
219 * In Linux FireWire core, when generation is updated with memory
220 * barrier, node id has already been updated. In this module, After
221 * this smp_rmb(), load/store instructions to memory are completed.
222 * Thus, both of generation and node id are available with recent
223 * values. This is a light-serialization solution to handle bus reset
224 * events on IEEE 1394 bus.
225 */
226 generation = port->parent->generation;
227 smp_rmb();
228
229 fw_send_request(port->parent->card, &port->transaction,
230 TCODE_WRITE_QUADLET_REQUEST,
231 port->parent->node_id, generation,
232 port->parent->max_speed,
233 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD,
234 port->buf, 4, async_midi_port_callback,
235 port);
236}
237
238void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port)
239{
240 port->idling = true;
241 port->error = false;
242 port->running_status = 0;
243 port->on_sysex = false;
244}
245
147static void handle_midi_tx(struct fw_card *card, struct fw_request *request, 246static void handle_midi_tx(struct fw_card *card, struct fw_request *request,
148 int tcode, int destination, int source, 247 int tcode, int destination, int source,
149 int generation, unsigned long long offset, 248 int generation, unsigned long long offset,
@@ -219,12 +318,9 @@ int snd_tscm_transaction_register(struct snd_tscm *tscm)
219 goto error; 318 goto error;
220 319
221 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) { 320 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) {
222 err = snd_fw_async_midi_port_init( 321 tscm->out_ports[i].parent = fw_parent_device(tscm->unit);
223 &tscm->out_ports[i], tscm->unit, 322 tscm->out_ports[i].next_ktime = 0;
224 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD, 323 INIT_WORK(&tscm->out_ports[i].work, midi_port_work);
225 4, fill_message);
226 if (err < 0)
227 goto error;
228 } 324 }
229 325
230 return err; 326 return err;
@@ -275,7 +371,6 @@ int snd_tscm_transaction_reregister(struct snd_tscm *tscm)
275void snd_tscm_transaction_unregister(struct snd_tscm *tscm) 371void snd_tscm_transaction_unregister(struct snd_tscm *tscm)
276{ 372{
277 __be32 reg; 373 __be32 reg;
278 unsigned int i;
279 374
280 if (tscm->async_handler.callback_data == NULL) 375 if (tscm->async_handler.callback_data == NULL)
281 return; 376 return;
@@ -302,7 +397,4 @@ void snd_tscm_transaction_unregister(struct snd_tscm *tscm)
302 397
303 fw_core_remove_address_handler(&tscm->async_handler); 398 fw_core_remove_address_handler(&tscm->async_handler);
304 tscm->async_handler.callback_data = NULL; 399 tscm->async_handler.callback_data = NULL;
305
306 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++)
307 snd_fw_async_midi_port_destroy(&tscm->out_ports[i]);
308} 400}
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index d3cd4065722b..08ecfae5c584 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -45,6 +45,23 @@ struct snd_tscm_spec {
45#define TSCM_MIDI_IN_PORT_MAX 4 45#define TSCM_MIDI_IN_PORT_MAX 4
46#define TSCM_MIDI_OUT_PORT_MAX 4 46#define TSCM_MIDI_OUT_PORT_MAX 4
47 47
48struct snd_fw_async_midi_port {
49 struct fw_device *parent;
50 struct work_struct work;
51 bool idling;
52 ktime_t next_ktime;
53 bool error;
54
55 struct fw_transaction transaction;
56
57 u8 buf[4];
58 u8 running_status;
59 bool on_sysex;
60
61 struct snd_rawmidi_substream *substream;
62 int consume_bytes;
63};
64
48struct snd_tscm { 65struct snd_tscm {
49 struct snd_card *card; 66 struct snd_card *card;
50 struct fw_unit *unit; 67 struct fw_unit *unit;
@@ -72,8 +89,6 @@ struct snd_tscm {
72 89
73 /* For MIDI message outgoing transactions. */ 90 /* For MIDI message outgoing transactions. */
74 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX]; 91 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX];
75 u8 running_status[TSCM_MIDI_OUT_PORT_MAX];
76 bool on_sysex[TSCM_MIDI_OUT_PORT_MAX];
77}; 92};
78 93
79#define TSCM_ADDR_BASE 0xffff00000000ull 94#define TSCM_ADDR_BASE 0xffff00000000ull
@@ -131,6 +146,26 @@ void snd_tscm_stream_lock_changed(struct snd_tscm *tscm);
131int snd_tscm_stream_lock_try(struct snd_tscm *tscm); 146int snd_tscm_stream_lock_try(struct snd_tscm *tscm);
132void snd_tscm_stream_lock_release(struct snd_tscm *tscm); 147void snd_tscm_stream_lock_release(struct snd_tscm *tscm);
133 148
149void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port);
150
151static inline void
152snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
153 struct snd_rawmidi_substream *substream)
154{
155 if (!port->error) {
156 port->substream = substream;
157 schedule_work(&port->work);
158 }
159}
160
161static inline void
162snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
163{
164 port->substream = NULL;
165 cancel_work_sync(&port->work);
166 port->error = false;
167}
168
134int snd_tscm_transaction_register(struct snd_tscm *tscm); 169int snd_tscm_transaction_register(struct snd_tscm *tscm);
135int snd_tscm_transaction_reregister(struct snd_tscm *tscm); 170int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
136void snd_tscm_transaction_unregister(struct snd_tscm *tscm); 171void snd_tscm_transaction_unregister(struct snd_tscm *tscm);
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 261469188566..84f3b8168716 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -171,7 +171,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
171{ 171{
172 int timeout; 172 int timeout;
173 u32 val; 173 u32 val;
174 int mask = (1 << AZX_MLCTL_CPA); 174 int mask = (1 << AZX_MLCTL_CPA_SHIFT);
175 175
176 udelay(3); 176 udelay(3);
177 timeout = 150; 177 timeout = 150;
@@ -179,10 +179,10 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
179 do { 179 do {
180 val = readl(link->ml_addr + AZX_REG_ML_LCTL); 180 val = readl(link->ml_addr + AZX_REG_ML_LCTL);
181 if (enable) { 181 if (enable) {
182 if (((val & mask) >> AZX_MLCTL_CPA)) 182 if (((val & mask) >> AZX_MLCTL_CPA_SHIFT))
183 return 0; 183 return 0;
184 } else { 184 } else {
185 if (!((val & mask) >> AZX_MLCTL_CPA)) 185 if (!((val & mask) >> AZX_MLCTL_CPA_SHIFT))
186 return 0; 186 return 0;
187 } 187 }
188 udelay(3); 188 udelay(3);
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 043065867656..ee08c389b4d6 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -268,11 +268,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
268 unsigned int offset; 268 unsigned int offset;
269 unsigned int counter = 0; 269 unsigned int counter = 0;
270 270
271 offset = snd_hdac_chip_readl(bus, LLCH); 271 offset = snd_hdac_chip_readw(bus, LLCH);
272 272
273 /* Lets walk the linked capabilities list */ 273 /* Lets walk the linked capabilities list */
274 do { 274 do {
275 cur_cap = _snd_hdac_chip_read(l, bus, offset); 275 cur_cap = _snd_hdac_chip_readl(bus, offset);
276 276
277 dev_dbg(bus->dev, "Capability version: 0x%x\n", 277 dev_dbg(bus->dev, "Capability version: 0x%x\n",
278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF); 278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index c6994ebb4567..e1472c7ab6c1 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -555,12 +555,12 @@ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
555 555
556 if (!reg) 556 if (!reg)
557 reg = AZX_REG_SSYNC; 557 reg = AZX_REG_SSYNC;
558 val = _snd_hdac_chip_read(l, bus, reg); 558 val = _snd_hdac_chip_readl(bus, reg);
559 if (set) 559 if (set)
560 val |= streams; 560 val |= streams;
561 else 561 else
562 val &= ~streams; 562 val &= ~streams;
563 _snd_hdac_chip_write(l, bus, reg, val); 563 _snd_hdac_chip_writel(bus, reg, val);
564} 564}
565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger); 565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);
566 566
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index e2cf508841b1..81cf26fa28d6 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -742,7 +742,7 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device)
742 742
743 pcm->private_data = chip; 743 pcm->private_data = chip;
744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
745 sprintf(pcm->name, snd_es1688_chip_id(chip)); 745 strcpy(pcm->name, snd_es1688_chip_id(chip));
746 chip->pcm = pcm; 746 chip->pcm = pcm;
747 747
748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 92b819e4f729..34bbc2e730a6 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1339,7 +1339,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
1339 rate = snd_ali_get_spdif_in_rate(codec); 1339 rate = snd_ali_get_spdif_in_rate(codec);
1340 if (rate == 0) { 1340 if (rate == 0) {
1341 dev_warn(codec->card->dev, 1341 dev_warn(codec->card->dev,
1342 "ali_capture_preapre: spdif rate detect err!\n"); 1342 "ali_capture_prepare: spdif rate detect err!\n");
1343 rate = 48000; 1343 rate = 48000;
1344 } 1344 }
1345 spin_lock_irq(&codec->reg_lock); 1345 spin_lock_irq(&codec->reg_lock);
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index ab0f87312911..7a4558a70fb9 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -846,7 +846,7 @@ snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
846 return changed; 846 return changed;
847} 847}
848 848
849static struct snd_kcontrol_new vortex_a3d_kcontrol = { 849static const struct snd_kcontrol_new vortex_a3d_kcontrol = {
850 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 850 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
851 .name = "Playback PCM advanced processing", 851 .name = "Playback PCM advanced processing",
852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index e1af24f87566..c308a4f70550 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2279,6 +2279,9 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2279 } else { 2279 } else {
2280 int src[2], mix[2]; 2280 int src[2], mix[2];
2281 2281
2282 if (nr_ch < 1)
2283 return -EINVAL;
2284
2282 /* Get SRC and MIXER hardware resources. */ 2285 /* Get SRC and MIXER hardware resources. */
2283 for (i = 0; i < nr_ch; i++) { 2286 for (i = 0; i < nr_ch; i++) {
2284 if ((mix[i] = 2287 if ((mix[i] =
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 9585c5c63b96..b566b44e4da7 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -757,7 +757,7 @@ snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol,
757 return 1; /* Allways changes */ 757 return 1; /* Allways changes */
758} 758}
759 759
760static struct snd_kcontrol_new vortex_eqtoggle_kcontrol = { 760static const struct snd_kcontrol_new vortex_eqtoggle_kcontrol = {
761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
762 .name = "EQ Enable", 762 .name = "EQ Enable",
763 .index = 0, 763 .index = 0,
@@ -815,7 +815,7 @@ snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon
815 return changed; 815 return changed;
816} 816}
817 817
818static struct snd_kcontrol_new vortex_eq_kcontrol = { 818static const struct snd_kcontrol_new vortex_eq_kcontrol = {
819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
820 .name = " .", 820 .name = " .",
821 .index = 0, 821 .index = 0,
@@ -855,7 +855,7 @@ snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
855 return 0; 855 return 0;
856} 856}
857 857
858static struct snd_kcontrol_new vortex_levels_kcontrol = { 858static const struct snd_kcontrol_new vortex_levels_kcontrol = {
859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
860 .name = "EQ Peaks", 860 .name = "EQ Peaks",
861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index df5741a78fd2..335979a753fe 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -601,7 +601,7 @@ static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
601 601
602static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); 602static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
603 603
604static struct snd_kcontrol_new snd_vortex_pcm_vol = { 604static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
606 .name = "PCM Playback Volume", 606 .name = "PCM Playback Volume",
607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 57bbb87d0c62..8356180bfe0e 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -202,7 +202,7 @@ static const struct snd_pcm_ops snd_aw2_capture_ops = {
202 .pointer = snd_aw2_pcm_pointer_capture, 202 .pointer = snd_aw2_pcm_pointer_capture,
203}; 203};
204 204
205static struct snd_kcontrol_new aw2_control = { 205static const struct snd_kcontrol_new aw2_control = {
206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
207 .name = "PCM Capture Route", 207 .name = "PCM Capture Route",
208 .index = 0, 208 .index = 0,
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index f2c0709d7441..099efb046b1c 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -598,7 +598,7 @@ static int snd_bt87x_capture_volume_put(struct snd_kcontrol *kcontrol,
598 return changed; 598 return changed;
599} 599}
600 600
601static struct snd_kcontrol_new snd_bt87x_capture_volume = { 601static const struct snd_kcontrol_new snd_bt87x_capture_volume = {
602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
603 .name = "Capture Volume", 603 .name = "Capture Volume",
604 .info = snd_bt87x_capture_volume_info, 604 .info = snd_bt87x_capture_volume_info,
@@ -634,7 +634,7 @@ static int snd_bt87x_capture_boost_put(struct snd_kcontrol *kcontrol,
634 return changed; 634 return changed;
635} 635}
636 636
637static struct snd_kcontrol_new snd_bt87x_capture_boost = { 637static const struct snd_kcontrol_new snd_bt87x_capture_boost = {
638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
639 .name = "Capture Boost", 639 .name = "Capture Boost",
640 .info = snd_bt87x_capture_boost_info, 640 .info = snd_bt87x_capture_boost_info,
@@ -676,7 +676,7 @@ static int snd_bt87x_capture_source_put(struct snd_kcontrol *kcontrol,
676 return changed; 676 return changed;
677} 677}
678 678
679static struct snd_kcontrol_new snd_bt87x_capture_source = { 679static const struct snd_kcontrol_new snd_bt87x_capture_source = {
680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
681 .name = "Capture Source", 681 .name = "Capture Source",
682 .info = snd_bt87x_capture_source_info, 682 .info = snd_bt87x_capture_source_info,
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 025805cba779..b4d3415331f6 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -301,7 +301,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
301 return change; 301 return change;
302} 302}
303 303
304static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in = 304static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
305{ 305{
306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 .name = "Shared Mic/Line in Capture Switch", 307 .name = "Shared Mic/Line in Capture Switch",
@@ -310,7 +310,7 @@ static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
310 .put = snd_ca0106_capture_mic_line_in_put 310 .put = snd_ca0106_capture_mic_line_in_put
311}; 311};
312 312
313static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out = 313static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
314{ 314{
315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
316 .name = "Shared Line in/Side out Capture Switch", 316 .name = "Shared Line in/Side out Capture Switch",
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index aeedc270ed9b..227c9d3802b8 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1045,7 +1045,7 @@ static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
1045 return change; 1045 return change;
1046} 1046}
1047 1047
1048static struct snd_kcontrol_new snd_cmipci_spdif_default = 1048static const struct snd_kcontrol_new snd_cmipci_spdif_default =
1049{ 1049{
1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1072,7 +1072,7 @@ static int snd_cmipci_spdif_mask_get(struct snd_kcontrol *kcontrol,
1072 return 0; 1072 return 0;
1073} 1073}
1074 1074
1075static struct snd_kcontrol_new snd_cmipci_spdif_mask = 1075static const struct snd_kcontrol_new snd_cmipci_spdif_mask =
1076{ 1076{
1077 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1077 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1119,7 +1119,7 @@ static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
1119 return change; 1119 return change;
1120} 1120}
1121 1121
1122static struct snd_kcontrol_new snd_cmipci_spdif_stream = 1122static const struct snd_kcontrol_new snd_cmipci_spdif_stream =
1123{ 1123{
1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index fa7c51684dd2..f870697aca67 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1055,7 +1055,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
1055 1055
1056static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); 1056static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0);
1057 1057
1058static struct snd_kcontrol_new snd_cs4281_fm_vol = 1058static const struct snd_kcontrol_new snd_cs4281_fm_vol =
1059{ 1059{
1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1061 .name = "Synth Playback Volume", 1061 .name = "Synth Playback Volume",
@@ -1066,7 +1066,7 @@ static struct snd_kcontrol_new snd_cs4281_fm_vol =
1066 .tlv = { .p = db_scale_dsp }, 1066 .tlv = { .p = db_scale_dsp },
1067}; 1067};
1068 1068
1069static struct snd_kcontrol_new snd_cs4281_pcm_vol = 1069static const struct snd_kcontrol_new snd_cs4281_pcm_vol =
1070{ 1070{
1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1072 .name = "PCM Stream Playback Volume", 1072 .name = "PCM Stream Playback Volume",
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 937071760bc4..d15ecf9febbf 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1039,7 +1039,7 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
1039 1039
1040#ifdef ECHOCARD_HAS_LINE_OUT_GAIN 1040#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
1041/* On the Mia this one controls the line-out volume */ 1041/* On the Mia this one controls the line-out volume */
1042static struct snd_kcontrol_new snd_echo_line_output_gain = { 1042static const struct snd_kcontrol_new snd_echo_line_output_gain = {
1043 .name = "Line Playback Volume", 1043 .name = "Line Playback Volume",
1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1050,7 +1050,7 @@ static struct snd_kcontrol_new snd_echo_line_output_gain = {
1050 .tlv = {.p = db_scale_output_gain}, 1050 .tlv = {.p = db_scale_output_gain},
1051}; 1051};
1052#else 1052#else
1053static struct snd_kcontrol_new snd_echo_pcm_output_gain = { 1053static const struct snd_kcontrol_new snd_echo_pcm_output_gain = {
1054 .name = "PCM Playback Volume", 1054 .name = "PCM Playback Volume",
1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1120,7 +1120,7 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
1120 1120
1121static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); 1121static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
1122 1122
1123static struct snd_kcontrol_new snd_echo_line_input_gain = { 1123static const struct snd_kcontrol_new snd_echo_line_input_gain = {
1124 .name = "Line Capture Volume", 1124 .name = "Line Capture Volume",
1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1184,7 +1184,7 @@ static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
1184 return changed; 1184 return changed;
1185} 1185}
1186 1186
1187static struct snd_kcontrol_new snd_echo_output_nominal_level = { 1187static const struct snd_kcontrol_new snd_echo_output_nominal_level = {
1188 .name = "Line Playback Switch (-10dBV)", 1188 .name = "Line Playback Switch (-10dBV)",
1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1190 .info = snd_echo_output_nominal_info, 1190 .info = snd_echo_output_nominal_info,
@@ -1250,7 +1250,7 @@ static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
1250 return changed; 1250 return changed;
1251} 1251}
1252 1252
1253static struct snd_kcontrol_new snd_echo_intput_nominal_level = { 1253static const struct snd_kcontrol_new snd_echo_intput_nominal_level = {
1254 .name = "Line Capture Switch (-10dBV)", 1254 .name = "Line Capture Switch (-10dBV)",
1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1256 .info = snd_echo_input_nominal_info, 1256 .info = snd_echo_input_nominal_info,
@@ -1477,7 +1477,7 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
1477 return changed; 1477 return changed;
1478} 1478}
1479 1479
1480static struct snd_kcontrol_new snd_echo_digital_mode_switch = { 1480static const struct snd_kcontrol_new snd_echo_digital_mode_switch = {
1481 .name = "Digital mode Switch", 1481 .name = "Digital mode Switch",
1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1483 .info = snd_echo_digital_mode_info, 1483 .info = snd_echo_digital_mode_info,
@@ -1527,7 +1527,7 @@ static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
1527 return 0; 1527 return 0;
1528} 1528}
1529 1529
1530static struct snd_kcontrol_new snd_echo_spdif_mode_switch = { 1530static const struct snd_kcontrol_new snd_echo_spdif_mode_switch = {
1531 .name = "S/PDIF mode Switch", 1531 .name = "S/PDIF mode Switch",
1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1533 .info = snd_echo_spdif_mode_info, 1533 .info = snd_echo_spdif_mode_info,
@@ -1600,7 +1600,7 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
1600 return changed; 1600 return changed;
1601} 1601}
1602 1602
1603static struct snd_kcontrol_new snd_echo_clock_source_switch = { 1603static const struct snd_kcontrol_new snd_echo_clock_source_switch = {
1604 .name = "Sample Clock Source", 1604 .name = "Sample Clock Source",
1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1606 .info = snd_echo_clock_source_info, 1606 .info = snd_echo_clock_source_info,
@@ -1643,7 +1643,7 @@ static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
1643 return changed; 1643 return changed;
1644} 1644}
1645 1645
1646static struct snd_kcontrol_new snd_echo_phantom_power_switch = { 1646static const struct snd_kcontrol_new snd_echo_phantom_power_switch = {
1647 .name = "Phantom power Switch", 1647 .name = "Phantom power Switch",
1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1649 .info = snd_echo_phantom_power_info, 1649 .info = snd_echo_phantom_power_info,
@@ -1686,7 +1686,7 @@ static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
1686 return changed; 1686 return changed;
1687} 1687}
1688 1688
1689static struct snd_kcontrol_new snd_echo_automute_switch = { 1689static const struct snd_kcontrol_new snd_echo_automute_switch = {
1690 .name = "Digital Capture Switch (automute)", 1690 .name = "Digital Capture Switch (automute)",
1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1692 .info = snd_echo_automute_info, 1692 .info = snd_echo_automute_info,
@@ -1713,7 +1713,7 @@ static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
1713 return 1; 1713 return 1;
1714} 1714}
1715 1715
1716static struct snd_kcontrol_new snd_echo_vumeters_switch = { 1716static const struct snd_kcontrol_new snd_echo_vumeters_switch = {
1717 .name = "VU-meters Switch", 1717 .name = "VU-meters Switch",
1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE, 1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
@@ -1751,7 +1751,7 @@ static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
1751 return 0; 1751 return 0;
1752} 1752}
1753 1753
1754static struct snd_kcontrol_new snd_echo_vumeters = { 1754static const struct snd_kcontrol_new snd_echo_vumeters = {
1755 .name = "VU-meters", 1755 .name = "VU-meters",
1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1757 .access = SNDRV_CTL_ELEM_ACCESS_READ | 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ |
@@ -1804,7 +1804,7 @@ static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol,
1804 return 0; 1804 return 0;
1805} 1805}
1806 1806
1807static struct snd_kcontrol_new snd_echo_channels_info = { 1807static const struct snd_kcontrol_new snd_echo_channels_info = {
1808 .name = "Channels info", 1808 .name = "Channels info",
1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, 1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 32842734ada6..77a4413f4564 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1112,7 +1112,7 @@ static int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
1112 return change; 1112 return change;
1113} 1113}
1114 1114
1115static struct snd_kcontrol_new snd_emu10k1x_shared_spdif = 1115static const struct snd_kcontrol_new snd_emu10k1x_shared_spdif =
1116{ 1116{
1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1118 .name = "Analog/Digital Output Jack", 1118 .name = "Analog/Digital Output Jack",
@@ -1171,7 +1171,7 @@ static int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
1171 return change; 1171 return change;
1172} 1172}
1173 1173
1174static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control = 1174static const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
1175{ 1175{
1176 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1176 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1181,7 +1181,7 @@ static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
1181 .get = snd_emu10k1x_spdif_get_mask 1181 .get = snd_emu10k1x_spdif_get_mask
1182}; 1182};
1183 1183
1184static struct snd_kcontrol_new snd_emu10k1x_spdif_control = 1184static const struct snd_kcontrol_new snd_emu10k1x_spdif_control =
1185{ 1185{
1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 076b117009c5..b2219a73c17c 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -795,7 +795,7 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
795 return change; 795 return change;
796} 796}
797 797
798static struct snd_kcontrol_new snd_emu1010_internal_clock = 798static const struct snd_kcontrol_new snd_emu1010_internal_clock =
799{ 799{
800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -847,7 +847,7 @@ static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol,
847 return change; 847 return change;
848} 848}
849 849
850static struct snd_kcontrol_new snd_emu1010_optical_out = { 850static const struct snd_kcontrol_new snd_emu1010_optical_out = {
851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
853 .name = "Optical Output Mode", 853 .name = "Optical Output Mode",
@@ -898,7 +898,7 @@ static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol,
898 return change; 898 return change;
899} 899}
900 900
901static struct snd_kcontrol_new snd_emu1010_optical_in = { 901static const struct snd_kcontrol_new snd_emu1010_optical_in = {
902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "Optical Input Mode", 904 .name = "Optical Input Mode",
@@ -978,7 +978,7 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
978 return change; 978 return change;
979} 979}
980 980
981static struct snd_kcontrol_new snd_audigy_i2c_capture_source = 981static const struct snd_kcontrol_new snd_audigy_i2c_capture_source =
982{ 982{
983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
984 .name = "Capture Source", 984 .name = "Capture Source",
@@ -1177,7 +1177,7 @@ static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
1177 return change; 1177 return change;
1178} 1178}
1179 1179
1180static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = 1180static const struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
1181{ 1181{
1182 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1182 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1187,7 +1187,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
1187 .get = snd_emu10k1_spdif_get_mask 1187 .get = snd_emu10k1_spdif_get_mask
1188}; 1188};
1189 1189
1190static struct snd_kcontrol_new snd_emu10k1_spdif_control = 1190static const struct snd_kcontrol_new snd_emu10k1_spdif_control =
1191{ 1191{
1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1293,7 +1293,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
1293 return change; 1293 return change;
1294} 1294}
1295 1295
1296static struct snd_kcontrol_new snd_emu10k1_send_routing_control = 1296static const struct snd_kcontrol_new snd_emu10k1_send_routing_control =
1297{ 1297{
1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1364,7 +1364,7 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
1364 return change; 1364 return change;
1365} 1365}
1366 1366
1367static struct snd_kcontrol_new snd_emu10k1_send_volume_control = 1367static const struct snd_kcontrol_new snd_emu10k1_send_volume_control =
1368{ 1368{
1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1429,7 +1429,7 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
1429 return change; 1429 return change;
1430} 1430}
1431 1431
1432static struct snd_kcontrol_new snd_emu10k1_attn_control = 1432static const struct snd_kcontrol_new snd_emu10k1_attn_control =
1433{ 1433{
1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1501,7 +1501,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
1501 return change; 1501 return change;
1502} 1502}
1503 1503
1504static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control = 1504static const struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
1505{ 1505{
1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1568,7 +1568,7 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
1568} 1568}
1569 1569
1570 1570
1571static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control = 1571static const struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
1572{ 1572{
1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1626,7 +1626,7 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
1626 return change; 1626 return change;
1627} 1627}
1628 1628
1629static struct snd_kcontrol_new snd_emu10k1_efx_attn_control = 1629static const struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
1630{ 1630{
1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1691,7 +1691,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1691 return change; 1691 return change;
1692} 1692}
1693 1693
1694static struct snd_kcontrol_new snd_emu10k1_shared_spdif = 1694static const struct snd_kcontrol_new snd_emu10k1_shared_spdif =
1695{ 1695{
1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1697 .name = "SB Live Analog/Digital Output Jack", 1697 .name = "SB Live Analog/Digital Output Jack",
@@ -1700,7 +1700,7 @@ static struct snd_kcontrol_new snd_emu10k1_shared_spdif =
1700 .put = snd_emu10k1_shared_spdif_put 1700 .put = snd_emu10k1_shared_spdif_put
1701}; 1701};
1702 1702
1703static struct snd_kcontrol_new snd_audigy_shared_spdif = 1703static const struct snd_kcontrol_new snd_audigy_shared_spdif =
1704{ 1704{
1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1706 .name = "Audigy Analog/Digital Output Jack", 1706 .name = "Audigy Analog/Digital Output Jack",
@@ -1738,7 +1738,7 @@ static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val); 1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
1739} 1739}
1740 1740
1741static struct snd_kcontrol_new snd_audigy_capture_boost = 1741static const struct snd_kcontrol_new snd_audigy_capture_boost =
1742{ 1742{
1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1744 .name = "Mic Extra Boost", 1744 .name = "Mic Extra Boost",
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 37be1e14d756..ef1cf530c929 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1542,7 +1542,7 @@ static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, st
1542 return change; 1542 return change;
1543} 1543}
1544 1544
1545static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = { 1545static const struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = {
1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1547 .name = "Captured FX8010 Outputs", 1547 .name = "Captured FX8010 Outputs",
1548 .info = snd_emu10k1_pcm_efx_voices_mask_info, 1548 .info = snd_emu10k1_pcm_efx_voices_mask_info,
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 164adad91650..5d10349d11ce 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1530,7 +1530,7 @@ static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
1530 return change; 1530 return change;
1531} 1531}
1532 1532
1533static struct snd_kcontrol_new snd_ens1373_rear = 1533static const struct snd_kcontrol_new snd_ens1373_rear =
1534{ 1534{
1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1536 .name = "AC97 2ch->4ch Copy Switch", 1536 .name = "AC97 2ch->4ch Copy Switch",
@@ -1575,7 +1575,7 @@ static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
1575 return changed; 1575 return changed;
1576} 1576}
1577 1577
1578static struct snd_kcontrol_new snd_ens1373_line = 1578static const struct snd_kcontrol_new snd_ens1373_line =
1579{ 1579{
1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1581 .name = "Line In->Rear Out Switch", 1581 .name = "Line In->Rear Out Switch",
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index a03cf68d0bcd..d3ea73171a3d 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
580 has_multiple_pins = 1; 580 has_multiple_pins = 1;
581 if (has_multiple_pins && type == AUTO_PIN_MIC) 581 if (has_multiple_pins && type == AUTO_PIN_MIC)
582 has_multiple_pins &= check_mic_location_need(codec, cfg, input); 582 has_multiple_pins &= check_mic_location_need(codec, cfg, input);
583 has_multiple_pins |= codec->force_pin_prefix;
583 return hda_get_input_pin_label(codec, &cfg->inputs[input], 584 return hda_get_input_pin_label(codec, &cfg->inputs[input],
584 cfg->inputs[input].pin, 585 cfg->inputs[input].pin,
585 has_multiple_pins); 586 has_multiple_pins);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8fd745cb3f36..70bb365a08d2 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1965,7 +1965,7 @@ static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
1965 return 1; 1965 return 1;
1966} 1966}
1967 1967
1968static struct snd_kcontrol_new vmaster_mute_mode = { 1968static const struct snd_kcontrol_new vmaster_mute_mode = {
1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1970 .name = "Mute-LED Mode", 1970 .name = "Mute-LED Mode",
1971 .info = vmaster_mute_mode_info, 1971 .info = vmaster_mute_mode_info,
@@ -2705,7 +2705,7 @@ static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
2705 return 0; 2705 return 0;
2706} 2706}
2707 2707
2708static struct snd_kcontrol_new spdif_share_sw = { 2708static const struct snd_kcontrol_new spdif_share_sw = {
2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2710 .name = "IEC958 Default PCM Playback Switch", 2710 .name = "IEC958 Default PCM Playback Switch",
2711 .info = snd_ctl_boolean_mono_info, 2711 .info = snd_ctl_boolean_mono_info,
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f17f25245e52..d6fb2d5d01a7 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -256,6 +256,7 @@ struct hda_codec {
256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ 256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
257 unsigned int power_save_node:1; /* advanced PM for each widget */ 257 unsigned int power_save_node:1; /* advanced PM for each widget */
258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */ 258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
259 unsigned int force_pin_prefix:1; /* Add location prefix */
259#ifdef CONFIG_PM 260#ifdef CONFIG_PM
260 unsigned long power_on_acct; 261 unsigned long power_on_acct;
261 unsigned long power_off_acct; 262 unsigned long power_off_acct;
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index e7c8f4f076d5..2842c82363c0 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect"); 196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
197 if (val >= 0) 197 if (val >= 0)
198 spec->suppress_hp_mic_detect = !val; 198 spec->suppress_hp_mic_detect = !val;
199 val = snd_hda_get_bool_hint(codec, "vmaster");
200 if (val >= 0)
201 spec->suppress_vmaster = !val;
199 202
200 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) 203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
201 spec->mixer_nid = val; 204 spec->mixer_nid = val;
@@ -1125,6 +1128,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1125 1128
1126 *index = 0; 1129 *index = 0;
1127 if (cfg->line_outs == 1 && !spec->multi_ios && 1130 if (cfg->line_outs == 1 && !spec->multi_ios &&
1131 !codec->force_pin_prefix &&
1128 !cfg->hp_outs && !cfg->speaker_outs) 1132 !cfg->hp_outs && !cfg->speaker_outs)
1129 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1133 return spec->vmaster_mute.hook ? "PCM" : "Master";
1130 1134
@@ -1132,6 +1136,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1132 * use it master (or "PCM" if a vmaster hook is present) 1136 * use it master (or "PCM" if a vmaster hook is present)
1133 */ 1137 */
1134 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid && 1138 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
1139 !codec->force_pin_prefix &&
1135 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) 1140 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
1136 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1141 return spec->vmaster_mute.hook ? "PCM" : "Master";
1137 1142
@@ -5031,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5031 } 5036 }
5032 5037
5033 /* if we have no master control, let's create it */ 5038 /* if we have no master control, let's create it */
5034 if (!spec->no_analog && 5039 if (!spec->no_analog && !spec->suppress_vmaster &&
5035 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 5040 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
5036 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 5041 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
5037 spec->vmaster_tlv, slave_pfxs, 5042 spec->vmaster_tlv, slave_pfxs,
@@ -5039,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5039 if (err < 0) 5044 if (err < 0)
5040 return err; 5045 return err;
5041 } 5046 }
5042 if (!spec->no_analog && 5047 if (!spec->no_analog && !spec->suppress_vmaster &&
5043 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 5048 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
5044 err = __snd_hda_add_vmaster(codec, "Master Playback Switch", 5049 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
5045 NULL, slave_pfxs, 5050 NULL, slave_pfxs,
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index f66fc7e25e07..61772317de46 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -229,6 +229,7 @@ struct hda_gen_spec {
229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */ 229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
230 unsigned int power_down_unused:1; /* power down unused widgets */ 230 unsigned int power_down_unused:1; /* power down unused widgets */
231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */ 231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */
232 unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
232 233
233 /* other internal flags */ 234 /* other internal flags */
234 unsigned int no_analog:1; /* digital I/O only */ 235 unsigned int no_analog:1; /* digital I/O only */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c8256a89375a..b786fbab029f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -77,6 +77,7 @@ enum {
77 POS_FIX_POSBUF, 77 POS_FIX_POSBUF,
78 POS_FIX_VIACOMBO, 78 POS_FIX_VIACOMBO,
79 POS_FIX_COMBO, 79 POS_FIX_COMBO,
80 POS_FIX_SKL,
80}; 81};
81 82
82/* Defines for ATI HD Audio support in SB450 south bridge */ 83/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -148,7 +149,7 @@ module_param_array(model, charp, NULL, 0444);
148MODULE_PARM_DESC(model, "Use the given board model."); 149MODULE_PARM_DESC(model, "Use the given board model.");
149module_param_array(position_fix, int, NULL, 0444); 150module_param_array(position_fix, int, NULL, 0444);
150MODULE_PARM_DESC(position_fix, "DMA pointer read method." 151MODULE_PARM_DESC(position_fix, "DMA pointer read method."
151 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO)."); 152 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+).");
152module_param_array(bdl_pos_adj, int, NULL, 0644); 153module_param_array(bdl_pos_adj, int, NULL, 0644);
153MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 154MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
154module_param_array(probe_mask, int, NULL, 0444); 155module_param_array(probe_mask, int, NULL, 0444);
@@ -369,8 +370,10 @@ enum {
369#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71) 370#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
370#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0) 371#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
371#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) 372#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
373#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
372#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \ 374#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
373 IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) 375 IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \
376 IS_GLK(pci)
374 377
375static char *driver_short_names[] = { 378static char *driver_short_names[] = {
376 [AZX_DRIVER_ICH] = "HDA Intel", 379 [AZX_DRIVER_ICH] = "HDA Intel",
@@ -534,9 +537,101 @@ static void bxt_reduce_dma_latency(struct azx *chip)
534{ 537{
535 u32 val; 538 u32 val;
536 539
537 val = azx_readl(chip, SKL_EM4L); 540 val = azx_readl(chip, VS_EM4L);
538 val &= (0x3 << 20); 541 val &= (0x3 << 20);
539 azx_writel(chip, SKL_EM4L, val); 542 azx_writel(chip, VS_EM4L, val);
543}
544
545/*
546 * ML_LCAP bits:
547 * bit 0: 6 MHz Supported
548 * bit 1: 12 MHz Supported
549 * bit 2: 24 MHz Supported
550 * bit 3: 48 MHz Supported
551 * bit 4: 96 MHz Supported
552 * bit 5: 192 MHz Supported
553 */
554static int intel_get_lctl_scf(struct azx *chip)
555{
556 struct hdac_bus *bus = azx_bus(chip);
557 static int preferred_bits[] = { 2, 3, 1, 4, 5 };
558 u32 val, t;
559 int i;
560
561 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);
562
563 for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {
564 t = preferred_bits[i];
565 if (val & (1 << t))
566 return t;
567 }
568
569 dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");
570 return 0;
571}
572
573static int intel_ml_lctl_set_power(struct azx *chip, int state)
574{
575 struct hdac_bus *bus = azx_bus(chip);
576 u32 val;
577 int timeout;
578
579 /*
580 * the codecs are sharing the first link setting by default
581 * If other links are enabled for stream, they need similar fix
582 */
583 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
584 val &= ~AZX_MLCTL_SPA;
585 val |= state << AZX_MLCTL_SPA_SHIFT;
586 writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
587 /* wait for CPA */
588 timeout = 50;
589 while (timeout) {
590 if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &
591 AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))
592 return 0;
593 timeout--;
594 udelay(10);
595 }
596
597 return -1;
598}
599
600static void intel_init_lctl(struct azx *chip)
601{
602 struct hdac_bus *bus = azx_bus(chip);
603 u32 val;
604 int ret;
605
606 /* 0. check lctl register value is correct or not */
607 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
608 /* if SCF is already set, let's use it */
609 if ((val & ML_LCTL_SCF_MASK) != 0)
610 return;
611
612 /*
613 * Before operating on SPA, CPA must match SPA.
614 * Any deviation may result in undefined behavior.
615 */
616 if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=
617 ((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))
618 return;
619
620 /* 1. turn link down: set SPA to 0 and wait CPA to 0 */
621 ret = intel_ml_lctl_set_power(chip, 0);
622 udelay(100);
623 if (ret)
624 goto set_spa;
625
626 /* 2. update SCF to select a properly audio clock*/
627 val &= ~ML_LCTL_SCF_MASK;
628 val |= intel_get_lctl_scf(chip);
629 writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
630
631set_spa:
632 /* 4. turn link up: set SPA to 1 and wait CPA to 1 */
633 intel_ml_lctl_set_power(chip, 1);
634 udelay(100);
540} 635}
541 636
542static void hda_intel_init_chip(struct azx *chip, bool full_reset) 637static void hda_intel_init_chip(struct azx *chip, bool full_reset)
@@ -564,6 +659,9 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
564 /* reduce dma latency to avoid noise */ 659 /* reduce dma latency to avoid noise */
565 if (IS_BXT(pci)) 660 if (IS_BXT(pci))
566 bxt_reduce_dma_latency(chip); 661 bxt_reduce_dma_latency(chip);
662
663 if (bus->mlcap != NULL)
664 intel_init_lctl(chip);
567} 665}
568 666
569/* calculate runtime delay from LPIB */ 667/* calculate runtime delay from LPIB */
@@ -815,6 +913,31 @@ static unsigned int azx_via_get_position(struct azx *chip,
815 return bound_pos + mod_dma_pos; 913 return bound_pos + mod_dma_pos;
816} 914}
817 915
916static unsigned int azx_skl_get_dpib_pos(struct azx *chip,
917 struct azx_dev *azx_dev)
918{
919 return _snd_hdac_chip_readl(azx_bus(chip),
920 AZX_REG_VS_SDXDPIB_XBASE +
921 (AZX_REG_VS_SDXDPIB_XINTERVAL *
922 azx_dev->core.index));
923}
924
925/* get the current DMA position with correction on SKL+ chips */
926static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev)
927{
928 /* DPIB register gives a more accurate position for playback */
929 if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
930 return azx_skl_get_dpib_pos(chip, azx_dev);
931
932 /* For capture, we need to read posbuf, but it requires a delay
933 * for the possible boundary overlap; the read of DPIB fetches the
934 * actual posbuf
935 */
936 udelay(20);
937 azx_skl_get_dpib_pos(chip, azx_dev);
938 return azx_get_pos_posbuf(chip, azx_dev);
939}
940
818#ifdef CONFIG_PM 941#ifdef CONFIG_PM
819static DEFINE_MUTEX(card_list_lock); 942static DEFINE_MUTEX(card_list_lock);
820static LIST_HEAD(card_list); 943static LIST_HEAD(card_list);
@@ -1351,6 +1474,7 @@ static int check_position_fix(struct azx *chip, int fix)
1351 case POS_FIX_POSBUF: 1474 case POS_FIX_POSBUF:
1352 case POS_FIX_VIACOMBO: 1475 case POS_FIX_VIACOMBO:
1353 case POS_FIX_COMBO: 1476 case POS_FIX_COMBO:
1477 case POS_FIX_SKL:
1354 return fix; 1478 return fix;
1355 } 1479 }
1356 1480
@@ -1371,6 +1495,10 @@ static int check_position_fix(struct azx *chip, int fix)
1371 dev_dbg(chip->card->dev, "Using LPIB position fix\n"); 1495 dev_dbg(chip->card->dev, "Using LPIB position fix\n");
1372 return POS_FIX_LPIB; 1496 return POS_FIX_LPIB;
1373 } 1497 }
1498 if (IS_SKL_PLUS(chip->pci)) {
1499 dev_dbg(chip->card->dev, "Using SKL position fix\n");
1500 return POS_FIX_SKL;
1501 }
1374 return POS_FIX_AUTO; 1502 return POS_FIX_AUTO;
1375} 1503}
1376 1504
@@ -1382,6 +1510,7 @@ static void assign_position_fix(struct azx *chip, int fix)
1382 [POS_FIX_POSBUF] = azx_get_pos_posbuf, 1510 [POS_FIX_POSBUF] = azx_get_pos_posbuf,
1383 [POS_FIX_VIACOMBO] = azx_via_get_position, 1511 [POS_FIX_VIACOMBO] = azx_via_get_position,
1384 [POS_FIX_COMBO] = azx_get_pos_lpib, 1512 [POS_FIX_COMBO] = azx_get_pos_lpib,
1513 [POS_FIX_SKL] = azx_get_pos_skl,
1385 }; 1514 };
1386 1515
1387 chip->get_position[0] = chip->get_position[1] = callbacks[fix]; 1516 chip->get_position[0] = chip->get_position[1] = callbacks[fix];
@@ -1390,7 +1519,7 @@ static void assign_position_fix(struct azx *chip, int fix)
1390 if (fix == POS_FIX_COMBO) 1519 if (fix == POS_FIX_COMBO)
1391 chip->get_position[1] = NULL; 1520 chip->get_position[1] = NULL;
1392 1521
1393 if (fix == POS_FIX_POSBUF && 1522 if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&
1394 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { 1523 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
1395 chip->get_delay[0] = chip->get_delay[1] = 1524 chip->get_delay[0] = chip->get_delay[1] =
1396 azx_get_delay_from_lpib; 1525 azx_get_delay_from_lpib;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 07a9deb17477..a148176c16a9 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -857,7 +857,7 @@ static int chipio_write_address(struct hda_codec *codec,
857 chip_addx >> 16); 857 chip_addx >> 16);
858 } 858 }
859 859
860 spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx; 860 spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx;
861 861
862 return res; 862 return res;
863} 863}
@@ -882,7 +882,7 @@ static int chipio_write_data(struct hda_codec *codec, unsigned int data)
882 /*If no error encountered, automatically increment the address 882 /*If no error encountered, automatically increment the address
883 as per chip behaviour*/ 883 as per chip behaviour*/
884 spec->curr_chip_addx = (res != -EIO) ? 884 spec->curr_chip_addx = (res != -EIO) ?
885 (spec->curr_chip_addx + 4) : ~0UL; 885 (spec->curr_chip_addx + 4) : ~0U;
886 return res; 886 return res;
887} 887}
888 888
@@ -933,7 +933,7 @@ static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
933 /*If no error encountered, automatically increment the address 933 /*If no error encountered, automatically increment the address
934 as per chip behaviour*/ 934 as per chip behaviour*/
935 spec->curr_chip_addx = (res != -EIO) ? 935 spec->curr_chip_addx = (res != -EIO) ?
936 (spec->curr_chip_addx + 4) : ~0UL; 936 (spec->curr_chip_addx + 4) : ~0U;
937 return res; 937 return res;
938} 938}
939 939
@@ -1168,7 +1168,7 @@ static int dspio_write_multiple(struct hda_codec *codec,
1168 int status = 0; 1168 int status = 0;
1169 unsigned int count; 1169 unsigned int count;
1170 1170
1171 if ((buffer == NULL)) 1171 if (buffer == NULL)
1172 return -EINVAL; 1172 return -EINVAL;
1173 1173
1174 count = 0; 1174 count = 0;
@@ -1210,7 +1210,7 @@ static int dspio_read_multiple(struct hda_codec *codec, unsigned int *buffer,
1210 unsigned int skip_count; 1210 unsigned int skip_count;
1211 unsigned int dummy; 1211 unsigned int dummy;
1212 1212
1213 if ((buffer == NULL)) 1213 if (buffer == NULL)
1214 return -1; 1214 return -1;
1215 1215
1216 count = 0; 1216 count = 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 69266b8ea2ad..e8253737c47a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -52,6 +52,12 @@ struct conexant_spec {
52 bool dc_enable; 52 bool dc_enable;
53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ 53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */
54 struct nid_path *dc_mode_path; 54 struct nid_path *dc_mode_path;
55
56 int mute_led_polarity;
57 unsigned int gpio_led;
58 unsigned int gpio_mute_led_mask;
59 unsigned int gpio_mic_led_mask;
60
55}; 61};
56 62
57 63
@@ -264,6 +270,7 @@ enum {
264 CXT_FIXUP_HP_DOCK, 270 CXT_FIXUP_HP_DOCK,
265 CXT_FIXUP_HP_SPECTRE, 271 CXT_FIXUP_HP_SPECTRE,
266 CXT_FIXUP_HP_GATE_MIC, 272 CXT_FIXUP_HP_GATE_MIC,
273 CXT_FIXUP_MUTE_LED_GPIO,
267}; 274};
268 275
269/* for hda_fixup_thinkpad_acpi() */ 276/* for hda_fixup_thinkpad_acpi() */
@@ -646,6 +653,74 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,
646 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); 653 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16);
647} 654}
648 655
656/* update LED status via GPIO */
657static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask,
658 bool enabled)
659{
660 struct conexant_spec *spec = codec->spec;
661 unsigned int oldval = spec->gpio_led;
662
663 if (spec->mute_led_polarity)
664 enabled = !enabled;
665
666 if (enabled)
667 spec->gpio_led &= ~mask;
668 else
669 spec->gpio_led |= mask;
670 if (spec->gpio_led != oldval)
671 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
672 spec->gpio_led);
673}
674
675/* turn on/off mute LED via GPIO per vmaster hook */
676static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled)
677{
678 struct hda_codec *codec = private_data;
679 struct conexant_spec *spec = codec->spec;
680
681 cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
682}
683
684/* turn on/off mic-mute LED via GPIO per capture hook */
685static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
686 struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
688{
689 struct conexant_spec *spec = codec->spec;
690
691 if (ucontrol)
692 cxt_update_gpio_led(codec, spec->gpio_mic_led_mask,
693 ucontrol->value.integer.value[0] ||
694 ucontrol->value.integer.value[1]);
695}
696
697
698static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
699 const struct hda_fixup *fix, int action)
700{
701 struct conexant_spec *spec = codec->spec;
702 static const struct hda_verb gpio_init[] = {
703 { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 },
704 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
705 {}
706 };
707 codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led);
708
709 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
710 spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook;
711 spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook;
712 spec->gpio_led = 0;
713 spec->mute_led_polarity = 0;
714 spec->gpio_mute_led_mask = 0x01;
715 spec->gpio_mic_led_mask = 0x02;
716 }
717 snd_hda_add_verbs(codec, gpio_init);
718 if (spec->gpio_led)
719 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
720 spec->gpio_led);
721}
722
723
649/* ThinkPad X200 & co with cxt5051 */ 724/* ThinkPad X200 & co with cxt5051 */
650static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 725static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
651 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 726 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -799,6 +874,10 @@ static const struct hda_fixup cxt_fixups[] = {
799 .type = HDA_FIXUP_FUNC, 874 .type = HDA_FIXUP_FUNC,
800 .v.func = cxt_fixup_hp_gate_mic_jack, 875 .v.func = cxt_fixup_hp_gate_mic_jack,
801 }, 876 },
877 [CXT_FIXUP_MUTE_LED_GPIO] = {
878 .type = HDA_FIXUP_FUNC,
879 .v.func = cxt_fixup_mute_led_gpio,
880 },
802}; 881};
803 882
804static const struct snd_pci_quirk cxt5045_fixups[] = { 883static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -851,6 +930,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
851 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), 930 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
852 SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), 931 SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
853 SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), 932 SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
933 SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
854 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 934 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
855 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 935 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
856 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 936 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
@@ -882,6 +962,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
882 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, 962 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" },
883 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, 963 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
884 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, 964 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" },
965 { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
885 {} 966 {}
886}; 967};
887 968
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1461ef8eb749..90e4ff87445e 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -177,6 +177,7 @@ struct hdmi_spec {
177 bool i915_bound; /* was i915 bound in this driver? */ 177 bool i915_bound; /* was i915 bound in this driver? */
178 178
179 struct hdac_chmap chmap; 179 struct hdac_chmap chmap;
180 hda_nid_t vendor_nid;
180}; 181};
181 182
182#ifdef CONFIG_SND_HDA_I915 183#ifdef CONFIG_SND_HDA_I915
@@ -383,7 +384,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
383 return 0; 384 return 0;
384} 385}
385 386
386static struct snd_kcontrol_new eld_bytes_ctl = { 387static const struct snd_kcontrol_new eld_bytes_ctl = {
387 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 388 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
388 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 389 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
389 .name = "ELD", 390 .name = "ELD",
@@ -2372,6 +2373,7 @@ static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
2372} 2373}
2373 2374
2374#define INTEL_VENDOR_NID 0x08 2375#define INTEL_VENDOR_NID 0x08
2376#define INTEL_GLK_VENDOR_NID 0x0B
2375#define INTEL_GET_VENDOR_VERB 0xf81 2377#define INTEL_GET_VENDOR_VERB 0xf81
2376#define INTEL_SET_VENDOR_VERB 0x781 2378#define INTEL_SET_VENDOR_VERB 0x781
2377#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ 2379#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
@@ -2381,14 +2383,15 @@ static void intel_haswell_enable_all_pins(struct hda_codec *codec,
2381 bool update_tree) 2383 bool update_tree)
2382{ 2384{
2383 unsigned int vendor_param; 2385 unsigned int vendor_param;
2386 struct hdmi_spec *spec = codec->spec;
2384 2387
2385 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2388 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2386 INTEL_GET_VENDOR_VERB, 0); 2389 INTEL_GET_VENDOR_VERB, 0);
2387 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) 2390 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
2388 return; 2391 return;
2389 2392
2390 vendor_param |= INTEL_EN_ALL_PIN_CVTS; 2393 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
2391 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2394 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2392 INTEL_SET_VENDOR_VERB, vendor_param); 2395 INTEL_SET_VENDOR_VERB, vendor_param);
2393 if (vendor_param == -1) 2396 if (vendor_param == -1)
2394 return; 2397 return;
@@ -2400,8 +2403,9 @@ static void intel_haswell_enable_all_pins(struct hda_codec *codec,
2400static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec) 2403static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2401{ 2404{
2402 unsigned int vendor_param; 2405 unsigned int vendor_param;
2406 struct hdmi_spec *spec = codec->spec;
2403 2407
2404 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2408 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2405 INTEL_GET_VENDOR_VERB, 0); 2409 INTEL_GET_VENDOR_VERB, 0);
2406 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) 2410 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
2407 return; 2411 return;
@@ -2409,7 +2413,7 @@ static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2409 /* enable DP1.2 mode */ 2413 /* enable DP1.2 mode */
2410 vendor_param |= INTEL_EN_DP12; 2414 vendor_param |= INTEL_EN_DP12;
2411 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB); 2415 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB);
2412 snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0, 2416 snd_hda_codec_write_cache(codec, spec->vendor_nid, 0,
2413 INTEL_SET_VENDOR_VERB, vendor_param); 2417 INTEL_SET_VENDOR_VERB, vendor_param);
2414} 2418}
2415 2419
@@ -2503,7 +2507,7 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
2503} 2507}
2504 2508
2505/* Intel Haswell and onwards; audio component with eld notifier */ 2509/* Intel Haswell and onwards; audio component with eld notifier */
2506static int patch_i915_hsw_hdmi(struct hda_codec *codec) 2510static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid)
2507{ 2511{
2508 struct hdmi_spec *spec; 2512 struct hdmi_spec *spec;
2509 int err; 2513 int err;
@@ -2520,6 +2524,7 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2520 spec = codec->spec; 2524 spec = codec->spec;
2521 codec->dp_mst = true; 2525 codec->dp_mst = true;
2522 spec->dyn_pcm_assign = true; 2526 spec->dyn_pcm_assign = true;
2527 spec->vendor_nid = vendor_nid;
2523 2528
2524 intel_haswell_enable_all_pins(codec, true); 2529 intel_haswell_enable_all_pins(codec, true);
2525 intel_haswell_fixup_enable_dp12(codec); 2530 intel_haswell_fixup_enable_dp12(codec);
@@ -2548,6 +2553,16 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2548 return 0; 2553 return 0;
2549} 2554}
2550 2555
2556static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2557{
2558 return intel_hsw_common_init(codec, INTEL_VENDOR_NID);
2559}
2560
2561static int patch_i915_glk_hdmi(struct hda_codec *codec)
2562{
2563 return intel_hsw_common_init(codec, INTEL_GLK_VENDOR_NID);
2564}
2565
2551/* Intel Baytrail and Braswell; with eld notifier */ 2566/* Intel Baytrail and Braswell; with eld notifier */
2552static int patch_i915_byt_hdmi(struct hda_codec *codec) 2567static int patch_i915_byt_hdmi(struct hda_codec *codec)
2553{ 2568{
@@ -3800,7 +3815,7 @@ HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi),
3800HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), 3815HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi),
3801HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), 3816HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi),
3802HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), 3817HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi),
3803HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_hsw_hdmi), 3818HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
3804HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), 3819HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
3805HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), 3820HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
3806HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), 3821HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 299835d1fbaa..58df440013c5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1800,6 +1800,7 @@ enum {
1800 ALC882_FIXUP_NO_PRIMARY_HP, 1800 ALC882_FIXUP_NO_PRIMARY_HP,
1801 ALC887_FIXUP_ASUS_BASS, 1801 ALC887_FIXUP_ASUS_BASS,
1802 ALC887_FIXUP_BASS_CHMAP, 1802 ALC887_FIXUP_BASS_CHMAP,
1803 ALC1220_FIXUP_GB_DUAL_CODECS,
1803}; 1804};
1804 1805
1805static void alc889_fixup_coef(struct hda_codec *codec, 1806static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1962static void alc_fixup_bass_chmap(struct hda_codec *codec, 1963static void alc_fixup_bass_chmap(struct hda_codec *codec,
1963 const struct hda_fixup *fix, int action); 1964 const struct hda_fixup *fix, int action);
1964 1965
1966/* For dual-codec configuration, we need to disable some features to avoid
1967 * conflicts of kctls and PCM streams
1968 */
1969static void alc_fixup_dual_codecs(struct hda_codec *codec,
1970 const struct hda_fixup *fix, int action)
1971{
1972 struct alc_spec *spec = codec->spec;
1973
1974 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1975 return;
1976 /* disable vmaster */
1977 spec->gen.suppress_vmaster = 1;
1978 /* auto-mute and auto-mic switch don't work with multiple codecs */
1979 spec->gen.suppress_auto_mute = 1;
1980 spec->gen.suppress_auto_mic = 1;
1981 /* disable aamix as well */
1982 spec->gen.mixer_nid = 0;
1983 /* add location prefix to avoid conflicts */
1984 codec->force_pin_prefix = 1;
1985}
1986
1987static void rename_ctl(struct hda_codec *codec, const char *oldname,
1988 const char *newname)
1989{
1990 struct snd_kcontrol *kctl;
1991
1992 kctl = snd_hda_find_mixer_ctl(codec, oldname);
1993 if (kctl)
1994 strcpy(kctl->id.name, newname);
1995}
1996
1997static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
1998 const struct hda_fixup *fix,
1999 int action)
2000{
2001 alc_fixup_dual_codecs(codec, fix, action);
2002 switch (action) {
2003 case HDA_FIXUP_ACT_PRE_PROBE:
2004 /* override card longname to provide a unique UCM profile */
2005 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2006 break;
2007 case HDA_FIXUP_ACT_BUILD:
2008 /* rename Capture controls depending on the codec */
2009 rename_ctl(codec, "Capture Volume",
2010 codec->addr == 0 ?
2011 "Rear-Panel Capture Volume" :
2012 "Front-Panel Capture Volume");
2013 rename_ctl(codec, "Capture Switch",
2014 codec->addr == 0 ?
2015 "Rear-Panel Capture Switch" :
2016 "Front-Panel Capture Switch");
2017 break;
2018 }
2019}
2020
1965static const struct hda_fixup alc882_fixups[] = { 2021static const struct hda_fixup alc882_fixups[] = {
1966 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 2022 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1967 .type = HDA_FIXUP_PINS, 2023 .type = HDA_FIXUP_PINS,
@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
2198 .type = HDA_FIXUP_FUNC, 2254 .type = HDA_FIXUP_FUNC,
2199 .v.func = alc_fixup_bass_chmap, 2255 .v.func = alc_fixup_bass_chmap,
2200 }, 2256 },
2257 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2258 .type = HDA_FIXUP_FUNC,
2259 .v.func = alc1220_fixup_gb_dual_codecs,
2260 },
2201}; 2261};
2202 2262
2203static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2263static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2267 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2327 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2268 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2328 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2269 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), 2329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2330 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2270 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2331 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2271 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2332 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2272 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2333 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -4663,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4663 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4724 { 0x1b, 0x21114000 }, /* dock speaker pin */
4664 {} 4725 {}
4665 }; 4726 };
4666 struct snd_kcontrol *kctl;
4667 4727
4668 switch (action) { 4728 switch (action) {
4669 case HDA_FIXUP_ACT_PRE_PROBE: 4729 case HDA_FIXUP_ACT_PRE_PROBE:
@@ -4678,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4678 /* this is a bit tricky; give more sane names for the main 4738 /* this is a bit tricky; give more sane names for the main
4679 * (tablet) speaker and the dock speaker, respectively 4739 * (tablet) speaker and the dock speaker, respectively
4680 */ 4740 */
4681 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); 4741 rename_ctl(codec, "Speaker Playback Switch",
4682 if (kctl) 4742 "Dock Speaker Playback Switch");
4683 strcpy(kctl->id.name, "Dock Speaker Playback Switch"); 4743 rename_ctl(codec, "Bass Speaker Playback Switch",
4684 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); 4744 "Speaker Playback Switch");
4685 if (kctl)
4686 strcpy(kctl->id.name, "Speaker Playback Switch");
4687 break; 4745 break;
4688 } 4746 }
4689} 4747}
@@ -4766,6 +4824,30 @@ static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4766 } 4824 }
4767} 4825}
4768 4826
4827static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
4828 const struct hda_fixup *fix,
4829 int action)
4830{
4831 alc_fixup_dual_codecs(codec, fix, action);
4832 switch (action) {
4833 case HDA_FIXUP_ACT_PRE_PROBE:
4834 /* override card longname to provide a unique UCM profile */
4835 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
4836 break;
4837 case HDA_FIXUP_ACT_BUILD:
4838 /* rename Capture controls depending on the codec */
4839 rename_ctl(codec, "Capture Volume",
4840 codec->addr == 0 ?
4841 "Rear-Panel Capture Volume" :
4842 "Front-Panel Capture Volume");
4843 rename_ctl(codec, "Capture Switch",
4844 codec->addr == 0 ?
4845 "Rear-Panel Capture Switch" :
4846 "Front-Panel Capture Switch");
4847 break;
4848 }
4849}
4850
4769/* for hda_fixup_thinkpad_acpi() */ 4851/* for hda_fixup_thinkpad_acpi() */
4770#include "thinkpad_helper.c" 4852#include "thinkpad_helper.c"
4771 4853
@@ -4833,6 +4915,8 @@ enum {
4833 ALC290_FIXUP_SUBWOOFER_HSJACK, 4915 ALC290_FIXUP_SUBWOOFER_HSJACK,
4834 ALC269_FIXUP_THINKPAD_ACPI, 4916 ALC269_FIXUP_THINKPAD_ACPI,
4835 ALC269_FIXUP_DMIC_THINKPAD_ACPI, 4917 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4918 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
4919 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
4836 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4920 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4837 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4921 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4838 ALC255_FIXUP_HEADSET_MODE, 4922 ALC255_FIXUP_HEADSET_MODE,
@@ -4872,6 +4956,12 @@ enum {
4872 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, 4956 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
4873 ALC269_FIXUP_ATIV_BOOK_8, 4957 ALC269_FIXUP_ATIV_BOOK_8,
4874 ALC221_FIXUP_HP_MIC_NO_PRESENCE, 4958 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
4959 ALC256_FIXUP_ASUS_HEADSET_MODE,
4960 ALC256_FIXUP_ASUS_MIC,
4961 ALC256_FIXUP_ASUS_AIO_GPIO2,
4962 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
4963 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
4964 ALC233_FIXUP_LENOVO_MULTI_CODECS,
4875}; 4965};
4876 4966
4877static const struct hda_fixup alc269_fixups[] = { 4967static const struct hda_fixup alc269_fixups[] = {
@@ -5289,6 +5379,24 @@ static const struct hda_fixup alc269_fixups[] = {
5289 .chained = true, 5379 .chained = true,
5290 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5380 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5291 }, 5381 },
5382 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
5383 .type = HDA_FIXUP_PINS,
5384 .v.pins = (const struct hda_pintbl[]) {
5385 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5386 { }
5387 },
5388 .chained = true,
5389 .chain_id = ALC255_FIXUP_HEADSET_MODE
5390 },
5391 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5392 .type = HDA_FIXUP_PINS,
5393 .v.pins = (const struct hda_pintbl[]) {
5394 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5395 { }
5396 },
5397 .chained = true,
5398 .chain_id = ALC255_FIXUP_HEADSET_MODE
5399 },
5292 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5400 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5293 .type = HDA_FIXUP_PINS, 5401 .type = HDA_FIXUP_PINS,
5294 .v.pins = (const struct hda_pintbl[]) { 5402 .v.pins = (const struct hda_pintbl[]) {
@@ -5579,6 +5687,54 @@ static const struct hda_fixup alc269_fixups[] = {
5579 .chained = true, 5687 .chained = true,
5580 .chain_id = ALC269_FIXUP_HEADSET_MODE 5688 .chain_id = ALC269_FIXUP_HEADSET_MODE
5581 }, 5689 },
5690 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
5691 .type = HDA_FIXUP_FUNC,
5692 .v.func = alc_fixup_headset_mode,
5693 },
5694 [ALC256_FIXUP_ASUS_MIC] = {
5695 .type = HDA_FIXUP_PINS,
5696 .v.pins = (const struct hda_pintbl[]) {
5697 { 0x13, 0x90a60160 }, /* use as internal mic */
5698 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
5699 { }
5700 },
5701 .chained = true,
5702 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
5703 },
5704 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
5705 .type = HDA_FIXUP_VERBS,
5706 .v.verbs = (const struct hda_verb[]) {
5707 /* Set up GPIO2 for the speaker amp */
5708 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
5709 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
5710 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
5711 {}
5712 },
5713 },
5714 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5715 .type = HDA_FIXUP_PINS,
5716 .v.pins = (const struct hda_pintbl[]) {
5717 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5718 { }
5719 },
5720 .chained = true,
5721 .chain_id = ALC269_FIXUP_HEADSET_MIC
5722 },
5723 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
5724 .type = HDA_FIXUP_VERBS,
5725 .v.verbs = (const struct hda_verb[]) {
5726 /* Enables internal speaker */
5727 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
5728 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
5729 {}
5730 },
5731 .chained = true,
5732 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
5733 },
5734 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
5735 .type = HDA_FIXUP_FUNC,
5736 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
5737 },
5582}; 5738};
5583 5739
5584static const struct snd_pci_quirk alc269_fixup_tbl[] = { 5740static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5692,15 +5848,27 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5692 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 5848 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
5693 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5849 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
5694 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5850 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
5851 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
5695 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 5852 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5696 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5853 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5854 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
5697 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5855 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5856 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
5857 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
5858 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
5698 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), 5859 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5699 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), 5860 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5700 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 5861 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5701 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 5862 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5702 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 5863 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5703 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5864 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5865 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5866 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5867 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5868 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
5869 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
5870 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
5871 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
5704 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 5872 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5705 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 5873 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5706 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 5874 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
@@ -5721,6 +5889,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5721 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), 5889 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
5722 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), 5890 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
5723 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), 5891 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
5892 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
5724 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 5893 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5725 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 5894 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5726 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 5895 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
@@ -5875,6 +6044,18 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
5875 {0x21, 0x03211020} 6044 {0x21, 0x03211020}
5876 6045
5877static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 6046static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
6047 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
6048 {0x12, 0x90a601c0},
6049 {0x14, 0x90171120},
6050 {0x21, 0x02211030}),
6051 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6052 {0x14, 0x90170110},
6053 {0x1b, 0x90a70130},
6054 {0x21, 0x03211020}),
6055 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6056 {0x1a, 0x90a70130},
6057 {0x1b, 0x90170110},
6058 {0x21, 0x03211020}),
5878 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 6059 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5879 ALC225_STANDARD_PINS, 6060 ALC225_STANDARD_PINS,
5880 {0x12, 0xb7a60130}, 6061 {0x12, 0xb7a60130},
@@ -5995,6 +6176,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5995 {0x21, 0x02211020}), 6176 {0x21, 0x02211020}),
5996 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 6177 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5997 ALC256_STANDARD_PINS), 6178 ALC256_STANDARD_PINS),
6179 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6180 {0x14, 0x90170110},
6181 {0x1b, 0x90a70130},
6182 {0x21, 0x04211020}),
6183 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6184 {0x14, 0x90170110},
6185 {0x1b, 0x90a70130},
6186 {0x21, 0x03211020}),
5998 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 6187 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5999 {0x12, 0x90a60130}, 6188 {0x12, 0x90a60130},
6000 {0x14, 0x90170110}, 6189 {0x14, 0x90170110},
@@ -6714,6 +6903,7 @@ enum {
6714 ALC668_FIXUP_DELL_DISABLE_AAMIX, 6903 ALC668_FIXUP_DELL_DISABLE_AAMIX,
6715 ALC668_FIXUP_DELL_XPS13, 6904 ALC668_FIXUP_DELL_XPS13,
6716 ALC662_FIXUP_ASUS_Nx50, 6905 ALC662_FIXUP_ASUS_Nx50,
6906 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
6717 ALC668_FIXUP_ASUS_Nx51, 6907 ALC668_FIXUP_ASUS_Nx51,
6718 ALC891_FIXUP_HEADSET_MODE, 6908 ALC891_FIXUP_HEADSET_MODE,
6719 ALC891_FIXUP_DELL_MIC_NO_PRESENCE, 6909 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
@@ -6721,6 +6911,7 @@ enum {
6721 ALC892_FIXUP_ASROCK_MOBO, 6911 ALC892_FIXUP_ASROCK_MOBO,
6722 ALC662_FIXUP_USI_FUNC, 6912 ALC662_FIXUP_USI_FUNC,
6723 ALC662_FIXUP_USI_HEADSET_MODE, 6913 ALC662_FIXUP_USI_HEADSET_MODE,
6914 ALC662_FIXUP_LENOVO_MULTI_CODECS,
6724}; 6915};
6725 6916
6726static const struct hda_fixup alc662_fixups[] = { 6917static const struct hda_fixup alc662_fixups[] = {
@@ -6967,14 +7158,21 @@ static const struct hda_fixup alc662_fixups[] = {
6967 .chained = true, 7158 .chained = true,
6968 .chain_id = ALC662_FIXUP_BASS_1A 7159 .chain_id = ALC662_FIXUP_BASS_1A
6969 }, 7160 },
7161 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7162 .type = HDA_FIXUP_FUNC,
7163 .v.func = alc_fixup_headset_mode_alc668,
7164 .chain_id = ALC662_FIXUP_BASS_CHMAP
7165 },
6970 [ALC668_FIXUP_ASUS_Nx51] = { 7166 [ALC668_FIXUP_ASUS_Nx51] = {
6971 .type = HDA_FIXUP_PINS, 7167 .type = HDA_FIXUP_PINS,
6972 .v.pins = (const struct hda_pintbl[]) { 7168 .v.pins = (const struct hda_pintbl[]) {
6973 {0x1a, 0x90170151}, /* bass speaker */ 7169 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7170 { 0x1a, 0x90170151 }, /* bass speaker */
7171 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6974 {} 7172 {}
6975 }, 7173 },
6976 .chained = true, 7174 .chained = true,
6977 .chain_id = ALC662_FIXUP_BASS_CHMAP, 7175 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
6978 }, 7176 },
6979 [ALC891_FIXUP_HEADSET_MODE] = { 7177 [ALC891_FIXUP_HEADSET_MODE] = {
6980 .type = HDA_FIXUP_FUNC, 7178 .type = HDA_FIXUP_FUNC,
@@ -7019,6 +7217,10 @@ static const struct hda_fixup alc662_fixups[] = {
7019 .chained = true, 7217 .chained = true,
7020 .chain_id = ALC662_FIXUP_USI_FUNC 7218 .chain_id = ALC662_FIXUP_USI_FUNC
7021 }, 7219 },
7220 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
7221 .type = HDA_FIXUP_FUNC,
7222 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
7223 },
7022}; 7224};
7023 7225
7024static const struct snd_pci_quirk alc662_fixup_tbl[] = { 7226static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -7056,6 +7258,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
7056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 7258 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
7057 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 7259 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
7058 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 7260 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
7261 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
7059 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 7262 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
7060 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 7263 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
7061 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), 7264 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 3bfdc78cbc5f..da5f37b7fdd0 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -432,7 +432,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
432 return 0; 432 return 0;
433} 433}
434 434
435static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = 435static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =
436{ 436{
437 .access = (SNDRV_CTL_ELEM_ACCESS_READ), 437 .access = (SNDRV_CTL_ELEM_ACCESS_READ),
438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 5cb587cf360e..ec07136fc288 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -719,7 +719,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
719 return ndata != data; 719 return ndata != data;
720} 720}
721 721
722static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = { 722static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {
723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
724 .name = "Input Sensitivity Switch", 724 .name = "Input Sensitivity Switch",
725 .info = snd_ice1712_ewx_io_sense_info, 725 .info = snd_ice1712_ewx_io_sense_info,
@@ -728,7 +728,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {
728 .count = 8, 728 .count = 8,
729}; 729};
730 730
731static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = { 731static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = {
732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
733 .name = "Output Sensitivity Switch", 733 .name = "Output Sensitivity Switch",
734 .info = snd_ice1712_ewx_io_sense_info, 734 .info = snd_ice1712_ewx_io_sense_info,
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index b4aa4c1370a8..1d8612cabb9e 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -279,7 +279,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
279 return val != nval; 279 return val != nval;
280} 280}
281 281
282static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = { 282static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = {
283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
284 .name = "Digital Mixer To AC97", 284 .name = "Digital Mixer To AC97",
285 .info = snd_ice1712_digmix_route_ac97_info, 285 .info = snd_ice1712_digmix_route_ac97_info,
@@ -1410,7 +1410,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = {
1410 .private_value = 10, 1410 .private_value = 10,
1411}; 1411};
1412 1412
1413static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = { 1413static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = {
1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), 1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
1416 .info = snd_ice1712_pro_mixer_switch_info, 1416 .info = snd_ice1712_pro_mixer_switch_info,
@@ -1432,7 +1432,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = {
1432 .tlv = { .p = db_scale_playback } 1432 .tlv = { .p = db_scale_playback }
1433}; 1433};
1434 1434
1435static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = { 1435static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = {
1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), 1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
1438 .info = snd_ice1712_pro_mixer_volume_info, 1438 .info = snd_ice1712_pro_mixer_volume_info,
@@ -1630,7 +1630,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
1630 return 0; 1630 return 0;
1631} 1631}
1632 1632
1633static struct snd_kcontrol_new snd_ice1712_eeprom = { 1633static const struct snd_kcontrol_new snd_ice1712_eeprom = {
1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1635 .name = "ICE1712 EEPROM", 1635 .name = "ICE1712 EEPROM",
1636 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1636 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1666,7 +1666,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
1666 return 0; 1666 return 0;
1667} 1667}
1668 1668
1669static struct snd_kcontrol_new snd_ice1712_spdif_default = 1669static const struct snd_kcontrol_new snd_ice1712_spdif_default =
1670{ 1670{
1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1717,7 +1717,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1717 return 0; 1717 return 0;
1718} 1718}
1719 1719
1720static struct snd_kcontrol_new snd_ice1712_spdif_maskc = 1720static const struct snd_kcontrol_new snd_ice1712_spdif_maskc =
1721{ 1721{
1722 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1722 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1726,7 +1726,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc =
1726 .get = snd_ice1712_spdif_maskc_get, 1726 .get = snd_ice1712_spdif_maskc_get,
1727}; 1727};
1728 1728
1729static struct snd_kcontrol_new snd_ice1712_spdif_maskp = 1729static const struct snd_kcontrol_new snd_ice1712_spdif_maskp =
1730{ 1730{
1731 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1731 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1753,7 +1753,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
1753 return 0; 1753 return 0;
1754} 1754}
1755 1755
1756static struct snd_kcontrol_new snd_ice1712_spdif_stream = 1756static const struct snd_kcontrol_new snd_ice1712_spdif_stream =
1757{ 1757{
1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE), 1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1878,7 +1878,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1878 return change; 1878 return change;
1879} 1879}
1880 1880
1881static struct snd_kcontrol_new snd_ice1712_pro_internal_clock = { 1881static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock = {
1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1883 .name = "Multi Track Internal Clock", 1883 .name = "Multi Track Internal Clock",
1884 .info = snd_ice1712_pro_internal_clock_info, 1884 .info = snd_ice1712_pro_internal_clock_info,
@@ -1943,7 +1943,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont
1943 return change; 1943 return change;
1944} 1944}
1945 1945
1946static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = { 1946static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = {
1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1948 .name = "Multi Track Internal Clock Default", 1948 .name = "Multi Track Internal Clock Default",
1949 .info = snd_ice1712_pro_internal_clock_default_info, 1949 .info = snd_ice1712_pro_internal_clock_default_info,
@@ -1974,7 +1974,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
1974 return change; 1974 return change;
1975} 1975}
1976 1976
1977static struct snd_kcontrol_new snd_ice1712_pro_rate_locking = { 1977static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking = {
1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1979 .name = "Multi Track Rate Locking", 1979 .name = "Multi Track Rate Locking",
1980 .info = snd_ice1712_pro_rate_locking_info, 1980 .info = snd_ice1712_pro_rate_locking_info,
@@ -2005,7 +2005,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
2005 return change; 2005 return change;
2006} 2006}
2007 2007
2008static struct snd_kcontrol_new snd_ice1712_pro_rate_reset = { 2008static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset = {
2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2010 .name = "Multi Track Rate Reset", 2010 .name = "Multi Track Rate Reset",
2011 .info = snd_ice1712_pro_rate_reset_info, 2011 .info = snd_ice1712_pro_rate_reset_info,
@@ -2173,7 +2173,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = {
2173 .put = snd_ice1712_pro_route_analog_put, 2173 .put = snd_ice1712_pro_route_analog_put,
2174}; 2174};
2175 2175
2176static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = { 2176static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = {
2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2179 .info = snd_ice1712_pro_route_info, 2179 .info = snd_ice1712_pro_route_info,
@@ -2215,7 +2215,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
2215 return change; 2215 return change;
2216} 2216}
2217 2217
2218static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = { 2218static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = {
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2220 .name = "Multi Track Volume Rate", 2220 .name = "Multi Track Volume Rate",
2221 .info = snd_ice1712_pro_volume_rate_info, 2221 .info = snd_ice1712_pro_volume_rate_info,
@@ -2248,7 +2248,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
2248 return 0; 2248 return 0;
2249} 2249}
2250 2250
2251static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = { 2251static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = {
2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2253 .name = "Multi Track Peak", 2253 .name = "Multi Track Peak",
2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 842744e7a139..9cd6e55c0642 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1598,7 +1598,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
1598 return 0; 1598 return 0;
1599} 1599}
1600 1600
1601static struct snd_kcontrol_new snd_vt1724_eeprom = { 1601static const struct snd_kcontrol_new snd_vt1724_eeprom = {
1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1603 .name = "ICE1724 EEPROM", 1603 .name = "ICE1724 EEPROM",
1604 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1604 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1711,7 +1711,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
1711 return val != old; 1711 return val != old;
1712} 1712}
1713 1713
1714static struct snd_kcontrol_new snd_vt1724_spdif_default = 1714static const struct snd_kcontrol_new snd_vt1724_spdif_default =
1715{ 1715{
1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1743,7 +1743,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1743 return 0; 1743 return 0;
1744} 1744}
1745 1745
1746static struct snd_kcontrol_new snd_vt1724_spdif_maskc = 1746static const struct snd_kcontrol_new snd_vt1724_spdif_maskc =
1747{ 1747{
1748 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1748 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1752,7 +1752,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc =
1752 .get = snd_vt1724_spdif_maskc_get, 1752 .get = snd_vt1724_spdif_maskc_get,
1753}; 1753};
1754 1754
1755static struct snd_kcontrol_new snd_vt1724_spdif_maskp = 1755static const struct snd_kcontrol_new snd_vt1724_spdif_maskp =
1756{ 1756{
1757 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1789,7 +1789,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
1789 return old != val; 1789 return old != val;
1790} 1790}
1791 1791
1792static struct snd_kcontrol_new snd_vt1724_spdif_switch = 1792static const struct snd_kcontrol_new snd_vt1724_spdif_switch =
1793{ 1793{
1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1795 /* FIXME: the following conflict with IEC958 Playback Route */ 1795 /* FIXME: the following conflict with IEC958 Playback Route */
@@ -1964,7 +1964,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1964 return old_rate != new_rate; 1964 return old_rate != new_rate;
1965} 1965}
1966 1966
1967static struct snd_kcontrol_new snd_vt1724_pro_internal_clock = { 1967static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock = {
1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1969 .name = "Multi Track Internal Clock", 1969 .name = "Multi Track Internal Clock",
1970 .info = snd_vt1724_pro_internal_clock_info, 1970 .info = snd_vt1724_pro_internal_clock_info,
@@ -1995,7 +1995,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
1995 return change; 1995 return change;
1996} 1996}
1997 1997
1998static struct snd_kcontrol_new snd_vt1724_pro_rate_locking = { 1998static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking = {
1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2000 .name = "Multi Track Rate Locking", 2000 .name = "Multi Track Rate Locking",
2001 .info = snd_vt1724_pro_rate_locking_info, 2001 .info = snd_vt1724_pro_rate_locking_info,
@@ -2026,7 +2026,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
2026 return change; 2026 return change;
2027} 2027}
2028 2028
2029static struct snd_kcontrol_new snd_vt1724_pro_rate_reset = { 2029static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset = {
2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2031 .name = "Multi Track Rate Reset", 2031 .name = "Multi Track Rate Reset",
2032 .info = snd_vt1724_pro_rate_reset_info, 2032 .info = snd_vt1724_pro_rate_reset_info,
@@ -2151,7 +2151,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route =
2151 .put = snd_vt1724_pro_route_analog_put, 2151 .put = snd_vt1724_pro_route_analog_put,
2152}; 2152};
2153 2153
2154static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = { 2154static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = {
2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2157 .info = snd_vt1724_pro_route_info, 2157 .info = snd_vt1724_pro_route_info,
@@ -2187,7 +2187,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
2187 return 0; 2187 return 0;
2188} 2188}
2189 2189
2190static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = { 2190static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = {
2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2192 .name = "Multi Track Peak", 2192 .name = "Multi Track Peak",
2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index e7fe15dd5a90..cb25acf7bc49 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -645,7 +645,7 @@ static int lola_input_src_put(struct snd_kcontrol *kcontrol,
645 return lola_set_src_config(chip, mask, true); 645 return lola_set_src_config(chip, mask, true);
646} 646}
647 647
648static struct snd_kcontrol_new lola_input_src_mixer = { 648static const struct snd_kcontrol_new lola_input_src_mixer = {
649 .name = "Digital SRC Capture Switch", 649 .name = "Digital SRC Capture Switch",
650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
651 .info = lola_input_src_info, 651 .info = lola_input_src_info,
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index c0f0c349c3ec..f9c3e86d55d5 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -899,7 +899,7 @@ static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
899 return changed; 899 return changed;
900} 900}
901 901
902static struct snd_kcontrol_new lx_control_playback_switch = { 902static const struct snd_kcontrol_new lx_control_playback_switch = {
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "PCM Playback Switch", 904 .name = "PCM Playback Switch",
905 .index = 0, 905 .index = 0,
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 51e53497f0ad..4a4616aac787 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -448,7 +448,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
448 return changed; 448 return changed;
449} 449}
450 450
451static struct snd_kcontrol_new mixart_control_output_switch = { 451static const struct snd_kcontrol_new mixart_control_output_switch = {
452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
453 .name = "Master Playback Switch", 453 .name = "Master Playback Switch",
454 .info = mixart_sw_info, /* shared */ 454 .info = mixart_sw_info, /* shared */
@@ -1024,7 +1024,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1024 return changed; 1024 return changed;
1025} 1025}
1026 1026
1027static struct snd_kcontrol_new mixart_control_monitor_vol = { 1027static const struct snd_kcontrol_new mixart_control_monitor_vol = {
1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1091,7 +1091,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1091 return (changed != 0); 1091 return (changed != 0);
1092} 1092}
1093 1093
1094static struct snd_kcontrol_new mixart_control_monitor_sw = { 1094static const struct snd_kcontrol_new mixart_control_monitor_sw = {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Monitoring Switch", 1096 .name = "Monitoring Switch",
1097 .info = mixart_sw_info, /* shared */ 1097 .info = mixart_sw_info, /* shared */
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 74afb6b75976..e36ed8af55ad 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -767,6 +767,8 @@ static int get_oxygen_model(struct oxygen *chip,
767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia", 767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
768 [MODEL_SERENADE] = "TempoTec HiFier Serenade", 768 [MODEL_SERENADE] = "TempoTec HiFier Serenade",
769 [MODEL_HG2PCI] = "CMI8787-HG2PCI", 769 [MODEL_HG2PCI] = "CMI8787-HG2PCI",
770 [MODEL_XONAR_DG] = "Xonar DG",
771 [MODEL_XONAR_DGX] = "Xonar DGX",
770 }; 772 };
771 773
772 chip->model = model_generic; 774 chip->model = model_generic;
@@ -829,12 +831,8 @@ static int get_oxygen_model(struct oxygen *chip,
829 chip->model.dac_channels_mixer = 2; 831 chip->model.dac_channels_mixer = 2;
830 break; 832 break;
831 case MODEL_XONAR_DG: 833 case MODEL_XONAR_DG:
832 chip->model = model_xonar_dg;
833 chip->model.shortname = "Xonar DG";
834 break;
835 case MODEL_XONAR_DGX: 834 case MODEL_XONAR_DGX:
836 chip->model = model_xonar_dg; 835 chip->model = model_xonar_dg;
837 chip->model.shortname = "Xonar DGX";
838 break; 836 break;
839 } 837 }
840 if (id->driver_data == MODEL_MERIDIAN || 838 if (id->driver_data == MODEL_MERIDIAN ||
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
index 6a56e5306a65..8b4d0282efb8 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.c
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -744,7 +744,7 @@ static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
744 return changed; 744 return changed;
745} 745}
746 746
747static struct snd_kcontrol_new hr222_control_mic_level = { 747static const struct snd_kcontrol_new hr222_control_mic_level = {
748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
750 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 750 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -794,7 +794,7 @@ static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
794 return changed; 794 return changed;
795} 795}
796 796
797static struct snd_kcontrol_new hr222_control_mic_boost = { 797static const struct snd_kcontrol_new hr222_control_mic_boost = {
798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
800 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 800 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -836,7 +836,7 @@ static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
836 return changed; 836 return changed;
837} 837}
838 838
839static struct snd_kcontrol_new hr222_phantom_power_switch = { 839static const struct snd_kcontrol_new hr222_phantom_power_switch = {
840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
841 .name = "Phantom Power Switch", 841 .name = "Phantom Power Switch",
842 .info = hr222_phantom_power_info, 842 .info = hr222_phantom_power_info,
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index 63136c4f3f3d..36875df30dbf 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -235,7 +235,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
235 return changed; 235 return changed;
236} 236}
237 237
238static struct snd_kcontrol_new pcxhr_control_output_switch = { 238static const struct snd_kcontrol_new pcxhr_control_output_switch = {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch", 240 .name = "Master Playback Switch",
241 .info = pcxhr_sw_info, /* shared */ 241 .info = pcxhr_sw_info, /* shared */
@@ -460,7 +460,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
460 return changed; 460 return changed;
461} 461}
462 462
463static struct snd_kcontrol_new pcxhr_control_pcm_switch = { 463static const struct snd_kcontrol_new pcxhr_control_pcm_switch = {
464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
465 .name = "PCM Playback Switch", 465 .name = "PCM Playback Switch",
466 .count = PCXHR_PLAYBACK_STREAMS, 466 .count = PCXHR_PLAYBACK_STREAMS,
@@ -509,7 +509,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
509 return changed; 509 return changed;
510} 510}
511 511
512static struct snd_kcontrol_new pcxhr_control_monitor_vol = { 512static const struct snd_kcontrol_new pcxhr_control_monitor_vol = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
515 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 515 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -562,7 +562,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
562 return (changed != 0); 562 return (changed != 0);
563} 563}
564 564
565static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 565static const struct snd_kcontrol_new pcxhr_control_monitor_sw = {
566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
567 .name = "Monitoring Playback Switch", 567 .name = "Monitoring Playback Switch",
568 .info = pcxhr_sw_info, /* shared */ 568 .info = pcxhr_sw_info, /* shared */
@@ -697,7 +697,7 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
697 return ret; 697 return ret;
698} 698}
699 699
700static struct snd_kcontrol_new pcxhr_control_audio_src = { 700static const struct snd_kcontrol_new pcxhr_control_audio_src = {
701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
702 .name = "Capture Source", 702 .name = "Capture Source",
703 .info = pcxhr_audio_src_info, 703 .info = pcxhr_audio_src_info,
@@ -798,7 +798,7 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
798 return ret; 798 return ret;
799} 799}
800 800
801static struct snd_kcontrol_new pcxhr_control_clock_type = { 801static const struct snd_kcontrol_new pcxhr_control_clock_type = {
802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
803 .name = "Clock Mode", 803 .name = "Clock Mode",
804 .info = pcxhr_clock_type_info, 804 .info = pcxhr_clock_type_info,
@@ -842,7 +842,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
842 return 0; 842 return 0;
843} 843}
844 844
845static struct snd_kcontrol_new pcxhr_control_clock_rate = { 845static const struct snd_kcontrol_new pcxhr_control_clock_rate = {
846 .access = SNDRV_CTL_ELEM_ACCESS_READ, 846 .access = SNDRV_CTL_ELEM_ACCESS_READ,
847 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 847 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
848 .name = "Clock Rates", 848 .name = "Clock Rates",
@@ -1017,14 +1017,14 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
1017 return changed; 1017 return changed;
1018} 1018}
1019 1019
1020static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = { 1020static const struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
1021 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1021 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1024 .info = pcxhr_iec958_info, 1024 .info = pcxhr_iec958_info,
1025 .get = pcxhr_iec958_mask_get 1025 .get = pcxhr_iec958_mask_get
1026}; 1026};
1027static struct snd_kcontrol_new pcxhr_control_playback_iec958 = { 1027static const struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1030 .info = pcxhr_iec958_info, 1030 .info = pcxhr_iec958_info,
@@ -1033,14 +1033,14 @@ static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
1033 .private_value = 0 /* playback */ 1033 .private_value = 0 /* playback */
1034}; 1034};
1035 1035
1036static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = { 1036static const struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
1037 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1037 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1040 .info = pcxhr_iec958_info, 1040 .info = pcxhr_iec958_info,
1041 .get = pcxhr_iec958_mask_get 1041 .get = pcxhr_iec958_mask_get
1042}; 1042};
1043static struct snd_kcontrol_new pcxhr_control_capture_iec958 = { 1043static const struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
1044 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1044 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 92ad2d7a6bf8..64d3b8eba4bb 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2356,7 +2356,7 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
2356 return change; 2356 return change;
2357} 2357}
2358 2358
2359static struct snd_kcontrol_new snd_trident_spdif_control = 2359static const struct snd_kcontrol_new snd_trident_spdif_control =
2360{ 2360{
2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
@@ -2419,7 +2419,7 @@ static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
2419 return change; 2419 return change;
2420} 2420}
2421 2421
2422static struct snd_kcontrol_new snd_trident_spdif_default = 2422static const struct snd_kcontrol_new snd_trident_spdif_default =
2423{ 2423{
2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2452,7 +2452,7 @@ static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
2452 return 0; 2452 return 0;
2453} 2453}
2454 2454
2455static struct snd_kcontrol_new snd_trident_spdif_mask = 2455static const struct snd_kcontrol_new snd_trident_spdif_mask =
2456{ 2456{
2457 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2457 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2514,7 +2514,7 @@ static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
2514 return change; 2514 return change;
2515} 2515}
2516 2516
2517static struct snd_kcontrol_new snd_trident_spdif_stream = 2517static const struct snd_kcontrol_new snd_trident_spdif_stream =
2518{ 2518{
2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2564,7 +2564,7 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
2564 return change; 2564 return change;
2565} 2565}
2566 2566
2567static struct snd_kcontrol_new snd_trident_ac97_rear_control = 2567static const struct snd_kcontrol_new snd_trident_ac97_rear_control =
2568{ 2568{
2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2570 .name = "Rear Path", 2570 .name = "Rear Path",
@@ -2622,7 +2622,7 @@ static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
2622 return change; 2622 return change;
2623} 2623}
2624 2624
2625static struct snd_kcontrol_new snd_trident_vol_music_control = 2625static const struct snd_kcontrol_new snd_trident_vol_music_control =
2626{ 2626{
2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2628 .name = "Music Playback Volume", 2628 .name = "Music Playback Volume",
@@ -2633,7 +2633,7 @@ static struct snd_kcontrol_new snd_trident_vol_music_control =
2633 .tlv = { .p = db_scale_gvol }, 2633 .tlv = { .p = db_scale_gvol },
2634}; 2634};
2635 2635
2636static struct snd_kcontrol_new snd_trident_vol_wave_control = 2636static const struct snd_kcontrol_new snd_trident_vol_wave_control =
2637{ 2637{
2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2639 .name = "Wave Playback Volume", 2639 .name = "Wave Playback Volume",
@@ -2700,7 +2700,7 @@ static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
2700 return change; 2700 return change;
2701} 2701}
2702 2702
2703static struct snd_kcontrol_new snd_trident_pcm_vol_control = 2703static const struct snd_kcontrol_new snd_trident_pcm_vol_control =
2704{ 2704{
2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2706 .name = "PCM Front Playback Volume", 2706 .name = "PCM Front Playback Volume",
@@ -2764,7 +2764,7 @@ static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
2764 return change; 2764 return change;
2765} 2765}
2766 2766
2767static struct snd_kcontrol_new snd_trident_pcm_pan_control = 2767static const struct snd_kcontrol_new snd_trident_pcm_pan_control =
2768{ 2768{
2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2770 .name = "PCM Pan Playback Control", 2770 .name = "PCM Pan Playback Control",
@@ -2821,7 +2821,7 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
2821 2821
2822static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); 2822static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
2823 2823
2824static struct snd_kcontrol_new snd_trident_pcm_rvol_control = 2824static const struct snd_kcontrol_new snd_trident_pcm_rvol_control =
2825{ 2825{
2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2827 .name = "PCM Reverb Playback Volume", 2827 .name = "PCM Reverb Playback Volume",
@@ -2877,7 +2877,7 @@ static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
2877 return change; 2877 return change;
2878} 2878}
2879 2879
2880static struct snd_kcontrol_new snd_trident_pcm_cvol_control = 2880static const struct snd_kcontrol_new snd_trident_pcm_cvol_control =
2881{ 2881{
2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2883 .name = "PCM Chorus Playback Volume", 2883 .name = "PCM Chorus Playback Volume",
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 2d8c14e3f8d2..d078e86414c2 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1683,7 +1683,7 @@ static int snd_via8233_dxs3_spdif_put(struct snd_kcontrol *kcontrol,
1683 return 0; 1683 return 0;
1684} 1684}
1685 1685
1686static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = { 1686static const struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = {
1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1689 .info = snd_via8233_dxs3_spdif_info, 1689 .info = snd_via8233_dxs3_spdif_info,
@@ -1772,7 +1772,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
1772 1772
1773static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1); 1773static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
1774 1774
1775static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = { 1775static const struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
1776 .name = "PCM Playback Volume", 1776 .name = "PCM Playback Volume",
1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1783,7 +1783,7 @@ static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
1783 .tlv = { .p = db_scale_dxs } 1783 .tlv = { .p = db_scale_dxs }
1784}; 1784};
1785 1785
1786static struct snd_kcontrol_new snd_via8233_dxs_volume_control = { 1786static const struct snd_kcontrol_new snd_via8233_dxs_volume_control = {
1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1788 .device = 0, 1788 .device = 0,
1789 /* .subdevice set later */ 1789 /* .subdevice set later */
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 8e457ea27f89..7df1663ea510 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -945,7 +945,7 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
945 return 0; 945 return 0;
946} 946}
947 947
948static struct snd_kcontrol_new vx_control_input_level = { 948static const struct snd_kcontrol_new vx_control_input_level = {
949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
951 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 951 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -956,7 +956,7 @@ static struct snd_kcontrol_new vx_control_input_level = {
956 .tlv = { .p = db_scale_mic }, 956 .tlv = { .p = db_scale_mic },
957}; 957};
958 958
959static struct snd_kcontrol_new vx_control_mic_level = { 959static const struct snd_kcontrol_new vx_control_mic_level = {
960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
962 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 962 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index ffee284898b3..fe4ba463b57c 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1316,7 +1316,7 @@ static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,
1316 return change; 1316 return change;
1317} 1317}
1318 1318
1319static struct snd_kcontrol_new snd_ymfpci_spdif_default = 1319static const struct snd_kcontrol_new snd_ymfpci_spdif_default =
1320{ 1320{
1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1344,7 +1344,7 @@ static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,
1344 return 0; 1344 return 0;
1345} 1345}
1346 1346
1347static struct snd_kcontrol_new snd_ymfpci_spdif_mask = 1347static const struct snd_kcontrol_new snd_ymfpci_spdif_mask =
1348{ 1348{
1349 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1349 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1391,7 +1391,7 @@ static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,
1391 return change; 1391 return change;
1392} 1392}
1393 1393
1394static struct snd_kcontrol_new snd_ymfpci_spdif_stream = 1394static const struct snd_kcontrol_new snd_ymfpci_spdif_stream =
1395{ 1395{
1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1439,7 +1439,7 @@ static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_
1439 return reg != old_reg; 1439 return reg != old_reg;
1440} 1440}
1441 1441
1442static struct snd_kcontrol_new snd_ymfpci_drec_source = { 1442static const struct snd_kcontrol_new snd_ymfpci_drec_source = {
1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1445 .name = "Direct Recording Source", 1445 .name = "Direct Recording Source",
@@ -1609,7 +1609,7 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1609 return change; 1609 return change;
1610} 1610}
1611 1611
1612static struct snd_kcontrol_new snd_ymfpci_dup4ch = { 1612static const struct snd_kcontrol_new snd_ymfpci_dup4ch = {
1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1614 .name = "4ch Duplication", 1614 .name = "4ch Duplication",
1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -1712,7 +1712,7 @@ static int snd_ymfpci_gpio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1712 return 0; 1712 return 0;
1713} 1713}
1714 1714
1715static struct snd_kcontrol_new snd_ymfpci_rear_shared = { 1715static const struct snd_kcontrol_new snd_ymfpci_rear_shared = {
1716 .name = "Shared Rear/Line-In Switch", 1716 .name = "Shared Rear/Line-In Switch",
1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1718 .info = snd_ymfpci_gpio_sw_info, 1718 .info = snd_ymfpci_gpio_sw_info,
@@ -1776,7 +1776,7 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
1776 return 0; 1776 return 0;
1777} 1777}
1778 1778
1779static struct snd_kcontrol_new snd_ymfpci_pcm_volume = { 1779static const struct snd_kcontrol_new snd_ymfpci_pcm_volume = {
1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1781 .name = "PCM Playback Volume", 1781 .name = "PCM Playback Volume",
1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 182d92efc7c8..c0abad2067e1 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/cirrus/Kconfig"
47source "sound/soc/davinci/Kconfig" 47source "sound/soc/davinci/Kconfig"
48source "sound/soc/dwc/Kconfig" 48source "sound/soc/dwc/Kconfig"
49source "sound/soc/fsl/Kconfig" 49source "sound/soc/fsl/Kconfig"
50source "sound/soc/hisilicon/Kconfig"
50source "sound/soc/jz4740/Kconfig" 51source "sound/soc/jz4740/Kconfig"
51source "sound/soc/nuc900/Kconfig" 52source "sound/soc/nuc900/Kconfig"
52source "sound/soc/omap/Kconfig" 53source "sound/soc/omap/Kconfig"
@@ -63,6 +64,7 @@ source "sound/soc/sh/Kconfig"
63source "sound/soc/sirf/Kconfig" 64source "sound/soc/sirf/Kconfig"
64source "sound/soc/spear/Kconfig" 65source "sound/soc/spear/Kconfig"
65source "sound/soc/sti/Kconfig" 66source "sound/soc/sti/Kconfig"
67source "sound/soc/stm/Kconfig"
66source "sound/soc/sunxi/Kconfig" 68source "sound/soc/sunxi/Kconfig"
67source "sound/soc/tegra/Kconfig" 69source "sound/soc/tegra/Kconfig"
68source "sound/soc/txx9/Kconfig" 70source "sound/soc/txx9/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9a30f21d16ee..39c27a58158d 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC) += cirrus/
27obj-$(CONFIG_SND_SOC) += davinci/ 27obj-$(CONFIG_SND_SOC) += davinci/
28obj-$(CONFIG_SND_SOC) += dwc/ 28obj-$(CONFIG_SND_SOC) += dwc/
29obj-$(CONFIG_SND_SOC) += fsl/ 29obj-$(CONFIG_SND_SOC) += fsl/
30obj-$(CONFIG_SND_SOC) += hisilicon/
30obj-$(CONFIG_SND_SOC) += jz4740/ 31obj-$(CONFIG_SND_SOC) += jz4740/
31obj-$(CONFIG_SND_SOC) += img/ 32obj-$(CONFIG_SND_SOC) += img/
32obj-$(CONFIG_SND_SOC) += intel/ 33obj-$(CONFIG_SND_SOC) += intel/
@@ -43,6 +44,7 @@ obj-$(CONFIG_SND_SOC) += sh/
43obj-$(CONFIG_SND_SOC) += sirf/ 44obj-$(CONFIG_SND_SOC) += sirf/
44obj-$(CONFIG_SND_SOC) += spear/ 45obj-$(CONFIG_SND_SOC) += spear/
45obj-$(CONFIG_SND_SOC) += sti/ 46obj-$(CONFIG_SND_SOC) += sti/
47obj-$(CONFIG_SND_SOC) += stm/
46obj-$(CONFIG_SND_SOC) += sunxi/ 48obj-$(CONFIG_SND_SOC) += sunxi/
47obj-$(CONFIG_SND_SOC) += tegra/ 49obj-$(CONFIG_SND_SOC) += tegra/
48obj-$(CONFIG_SND_SOC) += txx9/ 50obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 72ac78988426..64b88fdc1f6c 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -119,7 +119,7 @@ static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
119 119
120 return ret; 120 return ret;
121} 121}
122static struct snd_soc_ops bfin_eval_adau1373_ops = { 122static const struct snd_soc_ops bfin_eval_adau1373_ops = {
123 .hw_params = bfin_eval_adau1373_hw_params, 123 .hw_params = bfin_eval_adau1373_hw_params,
124}; 124};
125 125
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 1037477d10b2..99e5ecabdcda 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -64,7 +64,7 @@ static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
64 return 0; 64 return 0;
65} 65}
66 66
67static struct snd_soc_ops bfin_eval_adav80x_ops = { 67static const struct snd_soc_ops bfin_eval_adav80x_ops = {
68 .hw_params = bfin_eval_adav80x_hw_params, 68 .hw_params = bfin_eval_adav80x_hw_params,
69}; 69};
70 70
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e49e9da7f1f6..883ed4c8a551 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -49,6 +49,7 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_CS35L32 if I2C 49 select SND_SOC_CS35L32 if I2C
50 select SND_SOC_CS35L33 if I2C 50 select SND_SOC_CS35L33 if I2C
51 select SND_SOC_CS35L34 if I2C 51 select SND_SOC_CS35L34 if I2C
52 select SND_SOC_CS35L35 if I2C
52 select SND_SOC_CS42L42 if I2C 53 select SND_SOC_CS42L42 if I2C
53 select SND_SOC_CS42L51_I2C if I2C 54 select SND_SOC_CS42L51_I2C if I2C
54 select SND_SOC_CS42L52 if I2C && INPUT 55 select SND_SOC_CS42L52 if I2C && INPUT
@@ -69,9 +70,11 @@ config SND_SOC_ALL_CODECS
69 select SND_SOC_DA7219 if I2C 70 select SND_SOC_DA7219 if I2C
70 select SND_SOC_DA732X if I2C 71 select SND_SOC_DA732X if I2C
71 select SND_SOC_DA9055 if I2C 72 select SND_SOC_DA9055 if I2C
73 select SND_SOC_DIO2125
72 select SND_SOC_DMIC 74 select SND_SOC_DMIC
73 select SND_SOC_ES8328_SPI if SPI_MASTER 75 select SND_SOC_ES8328_SPI if SPI_MASTER
74 select SND_SOC_ES8328_I2C if I2C 76 select SND_SOC_ES8328_I2C if I2C
77 select SND_SOC_ES7134
75 select SND_SOC_GTM601 78 select SND_SOC_GTM601
76 select SND_SOC_HDAC_HDMI 79 select SND_SOC_HDAC_HDMI
77 select SND_SOC_ICS43432 80 select SND_SOC_ICS43432
@@ -89,6 +92,7 @@ config SND_SOC_ALL_CODECS
89 select SND_SOC_MAX9867 if I2C 92 select SND_SOC_MAX9867 if I2C
90 select SND_SOC_MAX98925 if I2C 93 select SND_SOC_MAX98925 if I2C
91 select SND_SOC_MAX98926 if I2C 94 select SND_SOC_MAX98926 if I2C
95 select SND_SOC_MAX98927 if I2C
92 select SND_SOC_MAX9850 if I2C 96 select SND_SOC_MAX9850 if I2C
93 select SND_SOC_MAX9860 if I2C 97 select SND_SOC_MAX9860 if I2C
94 select SND_SOC_MAX9768 if I2C 98 select SND_SOC_MAX9768 if I2C
@@ -97,6 +101,7 @@ config SND_SOC_ALL_CODECS
97 select SND_SOC_ML26124 if I2C 101 select SND_SOC_ML26124 if I2C
98 select SND_SOC_NAU8540 if I2C 102 select SND_SOC_NAU8540 if I2C
99 select SND_SOC_NAU8810 if I2C 103 select SND_SOC_NAU8810 if I2C
104 select SND_SOC_NAU8824 if I2C
100 select SND_SOC_NAU8825 if I2C 105 select SND_SOC_NAU8825 if I2C
101 select SND_SOC_HDMI_CODEC 106 select SND_SOC_HDMI_CODEC
102 select SND_SOC_PCM1681 if I2C 107 select SND_SOC_PCM1681 if I2C
@@ -303,12 +308,14 @@ config SND_SOC_ADAU1761
303 select SND_SOC_ADAU17X1 308 select SND_SOC_ADAU17X1
304 309
305config SND_SOC_ADAU1761_I2C 310config SND_SOC_ADAU1761_I2C
306 tristate 311 tristate "Analog Devices AU1761 CODEC - I2C"
312 depends on I2C
307 select SND_SOC_ADAU1761 313 select SND_SOC_ADAU1761
308 select REGMAP_I2C 314 select REGMAP_I2C
309 315
310config SND_SOC_ADAU1761_SPI 316config SND_SOC_ADAU1761_SPI
311 tristate 317 tristate "Analog Devices AU1761 CODEC - SPI"
318 depends on SPI
312 select SND_SOC_ADAU1761 319 select SND_SOC_ADAU1761
313 select REGMAP_SPI 320 select REGMAP_SPI
314 321
@@ -408,6 +415,10 @@ config SND_SOC_CS35L34
408 tristate "Cirrus Logic CS35L34 CODEC" 415 tristate "Cirrus Logic CS35L34 CODEC"
409 depends on I2C 416 depends on I2C
410 417
418config SND_SOC_CS35L35
419 tristate "Cirrus Logic CS35L35 CODEC"
420 depends on I2C
421
411config SND_SOC_CS42L42 422config SND_SOC_CS42L42
412 tristate "Cirrus Logic CS42L42 CODEC" 423 tristate "Cirrus Logic CS42L42 CODEC"
413 depends on I2C 424 depends on I2C
@@ -516,6 +527,10 @@ config SND_SOC_DA732X
516config SND_SOC_DA9055 527config SND_SOC_DA9055
517 tristate 528 tristate
518 529
530config SND_SOC_DIO2125
531 tristate "Dioo DIO2125 Amplifier"
532 select GPIOLIB
533
519config SND_SOC_DMIC 534config SND_SOC_DMIC
520 tristate 535 tristate
521 536
@@ -525,6 +540,9 @@ config SND_SOC_HDMI_CODEC
525 select SND_PCM_IEC958 540 select SND_PCM_IEC958
526 select HDMI 541 select HDMI
527 542
543config SND_SOC_ES7134
544 tristate "Everest Semi ES7134 CODEC"
545
528config SND_SOC_ES8328 546config SND_SOC_ES8328
529 tristate 547 tristate
530 548
@@ -588,6 +606,10 @@ config SND_SOC_MAX98925
588config SND_SOC_MAX98926 606config SND_SOC_MAX98926
589 tristate 607 tristate
590 608
609config SND_SOC_MAX98927
610 tristate "Maxim Integrated MAX98927 Speaker Amplifier"
611 depends on I2C
612
591config SND_SOC_MAX9850 613config SND_SOC_MAX9850
592 tristate 614 tristate
593 615
@@ -1116,6 +1138,10 @@ config SND_SOC_NAU8810
1116 tristate "Nuvoton Technology Corporation NAU88C10 CODEC" 1138 tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
1117 depends on I2C 1139 depends on I2C
1118 1140
1141config SND_SOC_NAU8824
1142 tristate "Nuvoton Technology Corporation NAU88L24 CODEC"
1143 depends on I2C
1144
1119config SND_SOC_NAU8825 1145config SND_SOC_NAU8825
1120 tristate 1146 tristate
1121 1147
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1796cb987e71..28a63fdaf982 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -39,6 +39,7 @@ snd-soc-cq93vc-objs := cq93vc.o
39snd-soc-cs35l32-objs := cs35l32.o 39snd-soc-cs35l32-objs := cs35l32.o
40snd-soc-cs35l33-objs := cs35l33.o 40snd-soc-cs35l33-objs := cs35l33.o
41snd-soc-cs35l34-objs := cs35l34.o 41snd-soc-cs35l34-objs := cs35l34.o
42snd-soc-cs35l35-objs := cs35l35.o
42snd-soc-cs42l42-objs := cs42l42.o 43snd-soc-cs42l42-objs := cs42l42.o
43snd-soc-cs42l51-objs := cs42l51.o 44snd-soc-cs42l51-objs := cs42l51.o
44snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o 45snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
@@ -63,6 +64,7 @@ snd-soc-da7219-objs := da7219.o da7219-aad.o
63snd-soc-da732x-objs := da732x.o 64snd-soc-da732x-objs := da732x.o
64snd-soc-da9055-objs := da9055.o 65snd-soc-da9055-objs := da9055.o
65snd-soc-dmic-objs := dmic.o 66snd-soc-dmic-objs := dmic.o
67snd-soc-es7134-objs := es7134.o
66snd-soc-es8328-objs := es8328.o 68snd-soc-es8328-objs := es8328.o
67snd-soc-es8328-i2c-objs := es8328-i2c.o 69snd-soc-es8328-i2c-objs := es8328-i2c.o
68snd-soc-es8328-spi-objs := es8328-spi.o 70snd-soc-es8328-spi-objs := es8328-spi.o
@@ -84,6 +86,7 @@ snd-soc-max98371-objs := max98371.o
84snd-soc-max9867-objs := max9867.o 86snd-soc-max9867-objs := max9867.o
85snd-soc-max98925-objs := max98925.o 87snd-soc-max98925-objs := max98925.o
86snd-soc-max98926-objs := max98926.o 88snd-soc-max98926-objs := max98926.o
89snd-soc-max98927-objs := max98927.o
87snd-soc-max9850-objs := max9850.o 90snd-soc-max9850-objs := max9850.o
88snd-soc-max9860-objs := max9860.o 91snd-soc-max9860-objs := max9860.o
89snd-soc-mc13783-objs := mc13783.o 92snd-soc-mc13783-objs := mc13783.o
@@ -92,6 +95,7 @@ snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
92snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o 95snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
93snd-soc-nau8540-objs := nau8540.o 96snd-soc-nau8540-objs := nau8540.o
94snd-soc-nau8810-objs := nau8810.o 97snd-soc-nau8810-objs := nau8810.o
98snd-soc-nau8824-objs := nau8824.o
95snd-soc-nau8825-objs := nau8825.o 99snd-soc-nau8825-objs := nau8825.o
96snd-soc-hdmi-codec-objs := hdmi-codec.o 100snd-soc-hdmi-codec-objs := hdmi-codec.o
97snd-soc-pcm1681-objs := pcm1681.o 101snd-soc-pcm1681-objs := pcm1681.o
@@ -221,6 +225,7 @@ snd-soc-wm9712-objs := wm9712.o
221snd-soc-wm9713-objs := wm9713.o 225snd-soc-wm9713-objs := wm9713.o
222snd-soc-wm-hubs-objs := wm_hubs.o 226snd-soc-wm-hubs-objs := wm_hubs.o
223# Amp 227# Amp
228snd-soc-dio2125-objs := dio2125.o
224snd-soc-max9877-objs := max9877.o 229snd-soc-max9877-objs := max9877.o
225snd-soc-max98504-objs := max98504.o 230snd-soc-max98504-objs := max98504.o
226snd-soc-tpa6130a2-objs := tpa6130a2.o 231snd-soc-tpa6130a2-objs := tpa6130a2.o
@@ -269,6 +274,7 @@ obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
269obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o 274obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
270obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o 275obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
271obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o 276obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o
277obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o
272obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o 278obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o
273obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 279obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
274obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o 280obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
@@ -293,6 +299,7 @@ obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
293obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 299obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
294obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 300obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
295obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 301obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
302obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o
296obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o 303obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
297obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o 304obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
298obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o 305obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
@@ -313,6 +320,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
313obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o 320obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
314obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o 321obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
315obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o 322obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
323obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
316obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 324obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
317obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o 325obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
318obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 326obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
@@ -321,6 +329,7 @@ obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
321obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o 329obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
322obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o 330obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
323obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o 331obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
332obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o
324obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 333obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
325obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 334obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
326obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 335obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
@@ -448,6 +457,7 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
448obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 457obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
449 458
450# Amp 459# Amp
460obj-$(CONFIG_SND_SOC_DIO2125) += snd-soc-dio2125.o
451obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 461obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
452obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o 462obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
453obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 463obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index e819dd8c82fd..b2dfddead227 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -75,6 +75,12 @@
75#define DFS_DOUBLE_SPEED (1 << 2) 75#define DFS_DOUBLE_SPEED (1 << 2)
76#define DFS_QUAD_SPEED (2 << 2) 76#define DFS_QUAD_SPEED (2 << 2)
77 77
78/* ICTRL */
79#define ICTRL_MASK (0x3)
80
81/* OCTRL */
82#define OCTRL_MASK (0x3F)
83
78struct ak4613_formats { 84struct ak4613_formats {
79 unsigned int width; 85 unsigned int width;
80 unsigned int fmt; 86 unsigned int fmt;
@@ -365,8 +371,8 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
365 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); 371 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
366 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2); 372 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
367 373
368 snd_soc_write(codec, ICTRL, priv->ic); 374 snd_soc_update_bits(codec, ICTRL, ICTRL_MASK, priv->ic);
369 snd_soc_write(codec, OCTRL, priv->oc); 375 snd_soc_update_bits(codec, OCTRL, OCTRL_MASK, priv->oc);
370 376
371hw_params_end: 377hw_params_end:
372 if (ret < 0) 378 if (ret < 0)
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
new file mode 100644
index 000000000000..f8aef5869b03
--- /dev/null
+++ b/sound/soc/codecs/cs35l35.c
@@ -0,0 +1,1580 @@
1/*
2 * cs35l35.c -- CS35L35 ALSA SoC audio driver
3 *
4 * Copyright 2017 Cirrus Logic, Inc.
5 *
6 * Author: Brian Austin <brian.austin@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/gpio/consumer.h>
25#include <linux/of_device.h>
26#include <linux/of_gpio.h>
27#include <linux/regmap.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <linux/gpio.h>
34#include <sound/initval.h>
35#include <sound/tlv.h>
36#include <sound/cs35l35.h>
37#include <linux/of_irq.h>
38#include <linux/completion.h>
39
40#include "cs35l35.h"
41
42/*
43 * Some fields take zero as a valid value so use a high bit flag that won't
44 * get written to the device to mark those.
45 */
46#define CS35L35_VALID_PDATA 0x80000000
47
48static const struct reg_default cs35l35_reg[] = {
49 {CS35L35_PWRCTL1, 0x01},
50 {CS35L35_PWRCTL2, 0x11},
51 {CS35L35_PWRCTL3, 0x00},
52 {CS35L35_CLK_CTL1, 0x04},
53 {CS35L35_CLK_CTL2, 0x12},
54 {CS35L35_CLK_CTL3, 0xCF},
55 {CS35L35_SP_FMT_CTL1, 0x20},
56 {CS35L35_SP_FMT_CTL2, 0x00},
57 {CS35L35_SP_FMT_CTL3, 0x02},
58 {CS35L35_MAG_COMP_CTL, 0x00},
59 {CS35L35_AMP_INP_DRV_CTL, 0x01},
60 {CS35L35_AMP_DIG_VOL_CTL, 0x12},
61 {CS35L35_AMP_DIG_VOL, 0x00},
62 {CS35L35_ADV_DIG_VOL, 0x00},
63 {CS35L35_PROTECT_CTL, 0x06},
64 {CS35L35_AMP_GAIN_AUD_CTL, 0x13},
65 {CS35L35_AMP_GAIN_PDM_CTL, 0x00},
66 {CS35L35_AMP_GAIN_ADV_CTL, 0x00},
67 {CS35L35_GPI_CTL, 0x00},
68 {CS35L35_BST_CVTR_V_CTL, 0x00},
69 {CS35L35_BST_PEAK_I, 0x07},
70 {CS35L35_BST_RAMP_CTL, 0x85},
71 {CS35L35_BST_CONV_COEF_1, 0x24},
72 {CS35L35_BST_CONV_COEF_2, 0x24},
73 {CS35L35_BST_CONV_SLOPE_COMP, 0x4E},
74 {CS35L35_BST_CONV_SW_FREQ, 0x04},
75 {CS35L35_CLASS_H_CTL, 0x0B},
76 {CS35L35_CLASS_H_HEADRM_CTL, 0x0B},
77 {CS35L35_CLASS_H_RELEASE_RATE, 0x08},
78 {CS35L35_CLASS_H_FET_DRIVE_CTL, 0x41},
79 {CS35L35_CLASS_H_VP_CTL, 0xC5},
80 {CS35L35_VPBR_CTL, 0x0A},
81 {CS35L35_VPBR_VOL_CTL, 0x90},
82 {CS35L35_VPBR_TIMING_CTL, 0x6A},
83 {CS35L35_VPBR_MODE_VOL_CTL, 0x00},
84 {CS35L35_SPKR_MON_CTL, 0xC0},
85 {CS35L35_IMON_SCALE_CTL, 0x30},
86 {CS35L35_AUDIN_RXLOC_CTL, 0x00},
87 {CS35L35_ADVIN_RXLOC_CTL, 0x80},
88 {CS35L35_VMON_TXLOC_CTL, 0x00},
89 {CS35L35_IMON_TXLOC_CTL, 0x80},
90 {CS35L35_VPMON_TXLOC_CTL, 0x04},
91 {CS35L35_VBSTMON_TXLOC_CTL, 0x84},
92 {CS35L35_VPBR_STATUS_TXLOC_CTL, 0x04},
93 {CS35L35_ZERO_FILL_LOC_CTL, 0x00},
94 {CS35L35_AUDIN_DEPTH_CTL, 0x0F},
95 {CS35L35_SPKMON_DEPTH_CTL, 0x0F},
96 {CS35L35_SUPMON_DEPTH_CTL, 0x0F},
97 {CS35L35_ZEROFILL_DEPTH_CTL, 0x00},
98 {CS35L35_MULT_DEV_SYNCH1, 0x02},
99 {CS35L35_MULT_DEV_SYNCH2, 0x80},
100 {CS35L35_PROT_RELEASE_CTL, 0x00},
101 {CS35L35_DIAG_MODE_REG_LOCK, 0x00},
102 {CS35L35_DIAG_MODE_CTL_1, 0x40},
103 {CS35L35_DIAG_MODE_CTL_2, 0x00},
104 {CS35L35_INT_MASK_1, 0xFF},
105 {CS35L35_INT_MASK_2, 0xFF},
106 {CS35L35_INT_MASK_3, 0xFF},
107 {CS35L35_INT_MASK_4, 0xFF},
108
109};
110
111static bool cs35l35_volatile_register(struct device *dev, unsigned int reg)
112{
113 switch (reg) {
114 case CS35L35_INT_STATUS_1:
115 case CS35L35_INT_STATUS_2:
116 case CS35L35_INT_STATUS_3:
117 case CS35L35_INT_STATUS_4:
118 case CS35L35_PLL_STATUS:
119 case CS35L35_OTP_TRIM_STATUS:
120 return true;
121 default:
122 return false;
123 }
124}
125
126static bool cs35l35_readable_register(struct device *dev, unsigned int reg)
127{
128 switch (reg) {
129 case CS35L35_DEVID_AB ... CS35L35_PWRCTL3:
130 case CS35L35_CLK_CTL1 ... CS35L35_SP_FMT_CTL3:
131 case CS35L35_MAG_COMP_CTL ... CS35L35_AMP_GAIN_AUD_CTL:
132 case CS35L35_AMP_GAIN_PDM_CTL ... CS35L35_BST_PEAK_I:
133 case CS35L35_BST_RAMP_CTL ... CS35L35_BST_CONV_SW_FREQ:
134 case CS35L35_CLASS_H_CTL ... CS35L35_CLASS_H_VP_CTL:
135 case CS35L35_CLASS_H_STATUS:
136 case CS35L35_VPBR_CTL ... CS35L35_VPBR_MODE_VOL_CTL:
137 case CS35L35_VPBR_ATTEN_STATUS:
138 case CS35L35_SPKR_MON_CTL:
139 case CS35L35_IMON_SCALE_CTL ... CS35L35_ZEROFILL_DEPTH_CTL:
140 case CS35L35_MULT_DEV_SYNCH1 ... CS35L35_PROT_RELEASE_CTL:
141 case CS35L35_DIAG_MODE_REG_LOCK ... CS35L35_DIAG_MODE_CTL_2:
142 case CS35L35_INT_MASK_1 ... CS35L35_PLL_STATUS:
143 case CS35L35_OTP_TRIM_STATUS:
144 return true;
145 default:
146 return false;
147 }
148}
149
150static bool cs35l35_precious_register(struct device *dev, unsigned int reg)
151{
152 switch (reg) {
153 case CS35L35_INT_STATUS_1:
154 case CS35L35_INT_STATUS_2:
155 case CS35L35_INT_STATUS_3:
156 case CS35L35_INT_STATUS_4:
157 case CS35L35_PLL_STATUS:
158 case CS35L35_OTP_TRIM_STATUS:
159 return true;
160 default:
161 return false;
162 }
163}
164
165static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
166{
167 int ret;
168
169 if (cs35l35->pdata.ext_bst) {
170 usleep_range(5000, 5500);
171 return 0;
172 }
173
174 reinit_completion(&cs35l35->pdn_done);
175
176 ret = wait_for_completion_timeout(&cs35l35->pdn_done,
177 msecs_to_jiffies(100));
178 if (ret == 0) {
179 dev_err(cs35l35->dev, "PDN_DONE did not complete\n");
180 return -ETIMEDOUT;
181 }
182
183 return 0;
184}
185
186static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
187 struct snd_kcontrol *kcontrol, int event)
188{
189 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
190 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
191 int ret = 0;
192
193 switch (event) {
194 case SND_SOC_DAPM_PRE_PMU:
195 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
196 CS35L35_MCLK_DIS_MASK,
197 0 << CS35L35_MCLK_DIS_SHIFT);
198 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
199 CS35L35_DISCHG_FILT_MASK,
200 0 << CS35L35_DISCHG_FILT_SHIFT);
201 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
202 CS35L35_PDN_ALL_MASK, 0);
203 break;
204 case SND_SOC_DAPM_POST_PMD:
205 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
206 CS35L35_DISCHG_FILT_MASK,
207 1 << CS35L35_DISCHG_FILT_SHIFT);
208 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
209 CS35L35_PDN_ALL_MASK, 1);
210
211 /* Already muted, so disable volume ramp for faster shutdown */
212 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
213 CS35L35_AMP_DIGSFT_MASK, 0);
214
215 ret = cs35l35_wait_for_pdn(cs35l35);
216
217 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
218 CS35L35_MCLK_DIS_MASK,
219 1 << CS35L35_MCLK_DIS_SHIFT);
220
221 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
222 CS35L35_AMP_DIGSFT_MASK,
223 1 << CS35L35_AMP_DIGSFT_SHIFT);
224 break;
225 default:
226 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
227 ret = -EINVAL;
228 }
229 return ret;
230}
231
232static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
233 struct snd_kcontrol *kcontrol, int event)
234{
235 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
236 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
237 unsigned int reg[4];
238 int i;
239
240 switch (event) {
241 case SND_SOC_DAPM_PRE_PMU:
242 if (cs35l35->pdata.bst_pdn_fet_on)
243 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
244 CS35L35_PDN_BST_MASK,
245 0 << CS35L35_PDN_BST_FETON_SHIFT);
246 else
247 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
248 CS35L35_PDN_BST_MASK,
249 0 << CS35L35_PDN_BST_FETOFF_SHIFT);
250 break;
251 case SND_SOC_DAPM_POST_PMU:
252 usleep_range(5000, 5100);
253 /* If in PDM mode we must use VP for Voltage control */
254 if (cs35l35->pdm_mode)
255 regmap_update_bits(cs35l35->regmap,
256 CS35L35_BST_CVTR_V_CTL,
257 CS35L35_BST_CTL_MASK,
258 0 << CS35L35_BST_CTL_SHIFT);
259
260 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
261 CS35L35_AMP_MUTE_MASK, 0);
262
263 for (i = 0; i < 2; i++)
264 regmap_bulk_read(cs35l35->regmap, CS35L35_INT_STATUS_1,
265 &reg, ARRAY_SIZE(reg));
266
267 break;
268 case SND_SOC_DAPM_PRE_PMD:
269 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
270 CS35L35_AMP_MUTE_MASK,
271 1 << CS35L35_AMP_MUTE_SHIFT);
272 if (cs35l35->pdata.bst_pdn_fet_on)
273 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
274 CS35L35_PDN_BST_MASK,
275 1 << CS35L35_PDN_BST_FETON_SHIFT);
276 else
277 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
278 CS35L35_PDN_BST_MASK,
279 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
280 break;
281 case SND_SOC_DAPM_POST_PMD:
282 usleep_range(5000, 5100);
283 /*
284 * If PDM mode we should switch back to pdata value
285 * for Voltage control when we go down
286 */
287 if (cs35l35->pdm_mode)
288 regmap_update_bits(cs35l35->regmap,
289 CS35L35_BST_CVTR_V_CTL,
290 CS35L35_BST_CTL_MASK,
291 cs35l35->pdata.bst_vctl
292 << CS35L35_BST_CTL_SHIFT);
293
294 break;
295 default:
296 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
297 }
298 return 0;
299}
300
301static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
302static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
303
304static const struct snd_kcontrol_new cs35l35_aud_controls[] = {
305 SOC_SINGLE_SX_TLV("Digital Audio Volume", CS35L35_AMP_DIG_VOL,
306 0, 0x34, 0xE4, dig_vol_tlv),
307 SOC_SINGLE_TLV("Analog Audio Volume", CS35L35_AMP_GAIN_AUD_CTL, 0, 19, 0,
308 amp_gain_tlv),
309 SOC_SINGLE_TLV("PDM Volume", CS35L35_AMP_GAIN_PDM_CTL, 0, 19, 0,
310 amp_gain_tlv),
311};
312
313static const struct snd_kcontrol_new cs35l35_adv_controls[] = {
314 SOC_SINGLE_SX_TLV("Digital Advisory Volume", CS35L35_ADV_DIG_VOL,
315 0, 0x34, 0xE4, dig_vol_tlv),
316 SOC_SINGLE_TLV("Analog Advisory Volume", CS35L35_AMP_GAIN_ADV_CTL, 0, 19, 0,
317 amp_gain_tlv),
318};
319
320static const struct snd_soc_dapm_widget cs35l35_dapm_widgets[] = {
321 SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L35_PWRCTL3, 1, 1,
322 cs35l35_sdin_event, SND_SOC_DAPM_PRE_PMU |
323 SND_SOC_DAPM_POST_PMD),
324 SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L35_PWRCTL3, 2, 1),
325
326 SND_SOC_DAPM_OUTPUT("SPK"),
327
328 SND_SOC_DAPM_INPUT("VP"),
329 SND_SOC_DAPM_INPUT("VBST"),
330 SND_SOC_DAPM_INPUT("ISENSE"),
331 SND_SOC_DAPM_INPUT("VSENSE"),
332
333 SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L35_PWRCTL2, 7, 1),
334 SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L35_PWRCTL2, 6, 1),
335 SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L35_PWRCTL3, 3, 1),
336 SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L35_PWRCTL3, 4, 1),
337 SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L35_PWRCTL2, 5, 1),
338
339 SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L35_PWRCTL2, 0, 1, NULL, 0,
340 cs35l35_main_amp_event, SND_SOC_DAPM_PRE_PMU |
341 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU |
342 SND_SOC_DAPM_PRE_PMD),
343};
344
345static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
346 {"VPMON ADC", NULL, "VP"},
347 {"VBSTMON ADC", NULL, "VBST"},
348 {"IMON ADC", NULL, "ISENSE"},
349 {"VMON ADC", NULL, "VSENSE"},
350 {"SDOUT", NULL, "IMON ADC"},
351 {"SDOUT", NULL, "VMON ADC"},
352 {"SDOUT", NULL, "VBSTMON ADC"},
353 {"SDOUT", NULL, "VPMON ADC"},
354 {"AMP Capture", NULL, "SDOUT"},
355
356 {"SDIN", NULL, "AMP Playback"},
357 {"CLASS H", NULL, "SDIN"},
358 {"Main AMP", NULL, "CLASS H"},
359 {"SPK", NULL, "Main AMP"},
360};
361
362static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
363{
364 struct snd_soc_codec *codec = codec_dai->codec;
365 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
366
367 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
368 case SND_SOC_DAIFMT_CBM_CFM:
369 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
370 CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);
371 cs35l35->slave_mode = false;
372 break;
373 case SND_SOC_DAIFMT_CBS_CFS:
374 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
375 CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);
376 cs35l35->slave_mode = true;
377 break;
378 default:
379 return -EINVAL;
380 }
381
382 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
383 case SND_SOC_DAIFMT_I2S:
384 cs35l35->i2s_mode = true;
385 cs35l35->pdm_mode = false;
386 break;
387 case SND_SOC_DAIFMT_PDM:
388 cs35l35->pdm_mode = true;
389 cs35l35->i2s_mode = false;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398struct cs35l35_sysclk_config {
399 int sysclk;
400 int srate;
401 u8 clk_cfg;
402};
403
404static struct cs35l35_sysclk_config cs35l35_clk_ctl[] = {
405
406 /* SYSCLK, Sample Rate, Serial Port Cfg */
407 {5644800, 44100, 0x00},
408 {5644800, 88200, 0x40},
409 {6144000, 48000, 0x10},
410 {6144000, 96000, 0x50},
411 {11289600, 44100, 0x01},
412 {11289600, 88200, 0x41},
413 {11289600, 176400, 0x81},
414 {12000000, 44100, 0x03},
415 {12000000, 48000, 0x13},
416 {12000000, 88200, 0x43},
417 {12000000, 96000, 0x53},
418 {12000000, 176400, 0x83},
419 {12000000, 192000, 0x93},
420 {12288000, 48000, 0x11},
421 {12288000, 96000, 0x51},
422 {12288000, 192000, 0x91},
423 {13000000, 44100, 0x07},
424 {13000000, 48000, 0x17},
425 {13000000, 88200, 0x47},
426 {13000000, 96000, 0x57},
427 {13000000, 176400, 0x87},
428 {13000000, 192000, 0x97},
429 {22579200, 44100, 0x02},
430 {22579200, 88200, 0x42},
431 {22579200, 176400, 0x82},
432 {24000000, 44100, 0x0B},
433 {24000000, 48000, 0x1B},
434 {24000000, 88200, 0x4B},
435 {24000000, 96000, 0x5B},
436 {24000000, 176400, 0x8B},
437 {24000000, 192000, 0x9B},
438 {24576000, 48000, 0x12},
439 {24576000, 96000, 0x52},
440 {24576000, 192000, 0x92},
441 {26000000, 44100, 0x0F},
442 {26000000, 48000, 0x1F},
443 {26000000, 88200, 0x4F},
444 {26000000, 96000, 0x5F},
445 {26000000, 176400, 0x8F},
446 {26000000, 192000, 0x9F},
447};
448
449static int cs35l35_get_clk_config(int sysclk, int srate)
450{
451 int i;
452
453 for (i = 0; i < ARRAY_SIZE(cs35l35_clk_ctl); i++) {
454 if (cs35l35_clk_ctl[i].sysclk == sysclk &&
455 cs35l35_clk_ctl[i].srate == srate)
456 return cs35l35_clk_ctl[i].clk_cfg;
457 }
458 return -EINVAL;
459}
460
461static int cs35l35_hw_params(struct snd_pcm_substream *substream,
462 struct snd_pcm_hw_params *params,
463 struct snd_soc_dai *dai)
464{
465 struct snd_soc_codec *codec = dai->codec;
466 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
467 struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
468 int srate = params_rate(params);
469 int ret = 0;
470 u8 sp_sclks;
471 int audin_format;
472 int errata_chk;
473
474 int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
475
476 if (clk_ctl < 0) {
477 dev_err(codec->dev, "Invalid CLK:Rate %d:%d\n",
478 cs35l35->sysclk, srate);
479 return -EINVAL;
480 }
481
482 ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
483 CS35L35_CLK_CTL2_MASK, clk_ctl);
484 if (ret != 0) {
485 dev_err(codec->dev, "Failed to set port config %d\n", ret);
486 return ret;
487 }
488
489 /*
490 * Rev A0 Errata
491 * When configured for the weak-drive detection path (CH_WKFET_DIS = 0)
492 * the Class H algorithm does not enable weak-drive operation for
493 * nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10
494 */
495 errata_chk = clk_ctl & CS35L35_SP_RATE_MASK;
496
497 if (classh->classh_wk_fet_disable == 0x00 &&
498 (errata_chk == 0x01 || errata_chk == 0x03)) {
499 ret = regmap_update_bits(cs35l35->regmap,
500 CS35L35_CLASS_H_FET_DRIVE_CTL,
501 CS35L35_CH_WKFET_DEL_MASK,
502 0 << CS35L35_CH_WKFET_DEL_SHIFT);
503 if (ret != 0) {
504 dev_err(codec->dev, "Failed to set fet config %d\n",
505 ret);
506 return ret;
507 }
508 }
509
510 /*
511 * You can pull more Monitor data from the SDOUT pin than going to SDIN
512 * Just make sure your SCLK is fast enough to fill the frame
513 */
514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
515 switch (params_width(params)) {
516 case 8:
517 audin_format = CS35L35_SDIN_DEPTH_8;
518 break;
519 case 16:
520 audin_format = CS35L35_SDIN_DEPTH_16;
521 break;
522 case 24:
523 audin_format = CS35L35_SDIN_DEPTH_24;
524 break;
525 default:
526 dev_err(codec->dev, "Unsupported Width %d\n",
527 params_width(params));
528 return -EINVAL;
529 }
530 regmap_update_bits(cs35l35->regmap,
531 CS35L35_AUDIN_DEPTH_CTL,
532 CS35L35_AUDIN_DEPTH_MASK,
533 audin_format <<
534 CS35L35_AUDIN_DEPTH_SHIFT);
535 if (cs35l35->pdata.stereo) {
536 regmap_update_bits(cs35l35->regmap,
537 CS35L35_AUDIN_DEPTH_CTL,
538 CS35L35_ADVIN_DEPTH_MASK,
539 audin_format <<
540 CS35L35_ADVIN_DEPTH_SHIFT);
541 }
542 }
543
544 if (cs35l35->i2s_mode) {
545 /* We have to take the SCLK to derive num sclks
546 * to configure the CLOCK_CTL3 register correctly
547 */
548 if ((cs35l35->sclk / srate) % 4) {
549 dev_err(codec->dev, "Unsupported sclk/fs ratio %d:%d\n",
550 cs35l35->sclk, srate);
551 return -EINVAL;
552 }
553 sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;
554
555 /* Only certain ratios are supported in I2S Slave Mode */
556 if (cs35l35->slave_mode) {
557 switch (sp_sclks) {
558 case CS35L35_SP_SCLKS_32FS:
559 case CS35L35_SP_SCLKS_48FS:
560 case CS35L35_SP_SCLKS_64FS:
561 break;
562 default:
563 dev_err(codec->dev, "ratio not supported\n");
564 return -EINVAL;
565 }
566 } else {
567 /* Only certain ratios supported in I2S MASTER Mode */
568 switch (sp_sclks) {
569 case CS35L35_SP_SCLKS_32FS:
570 case CS35L35_SP_SCLKS_64FS:
571 break;
572 default:
573 dev_err(codec->dev, "ratio not supported\n");
574 return -EINVAL;
575 }
576 }
577 ret = regmap_update_bits(cs35l35->regmap,
578 CS35L35_CLK_CTL3,
579 CS35L35_SP_SCLKS_MASK, sp_sclks <<
580 CS35L35_SP_SCLKS_SHIFT);
581 if (ret != 0) {
582 dev_err(codec->dev, "Failed to set fsclk %d\n", ret);
583 return ret;
584 }
585 }
586
587 return ret;
588}
589
590static const unsigned int cs35l35_src_rates[] = {
591 44100, 48000, 88200, 96000, 176400, 192000
592};
593
594static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
595 .count = ARRAY_SIZE(cs35l35_src_rates),
596 .list = cs35l35_src_rates,
597};
598
599static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
600 struct snd_soc_dai *dai)
601{
602 struct snd_soc_codec *codec = dai->codec;
603 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
604
605 if (!substream->runtime)
606 return 0;
607
608 snd_pcm_hw_constraint_list(substream->runtime, 0,
609 SNDRV_PCM_HW_PARAM_RATE, &cs35l35_constraints);
610
611 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
612 CS35L35_PDM_MODE_MASK,
613 0 << CS35L35_PDM_MODE_SHIFT);
614
615 return 0;
616}
617
618static const unsigned int cs35l35_pdm_rates[] = {
619 44100, 48000, 88200, 96000
620};
621
622static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
623 .count = ARRAY_SIZE(cs35l35_pdm_rates),
624 .list = cs35l35_pdm_rates,
625};
626
627static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
628 struct snd_soc_dai *dai)
629{
630 struct snd_soc_codec *codec = dai->codec;
631 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
632
633 if (!substream->runtime)
634 return 0;
635
636 snd_pcm_hw_constraint_list(substream->runtime, 0,
637 SNDRV_PCM_HW_PARAM_RATE,
638 &cs35l35_pdm_constraints);
639
640 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
641 CS35L35_PDM_MODE_MASK,
642 1 << CS35L35_PDM_MODE_SHIFT);
643
644 return 0;
645}
646
647static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
648 int clk_id, unsigned int freq, int dir)
649{
650 struct snd_soc_codec *codec = dai->codec;
651 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
652
653 /* Need the SCLK Frequency regardless of sysclk source for I2S */
654 cs35l35->sclk = freq;
655
656 return 0;
657}
658
659static const struct snd_soc_dai_ops cs35l35_ops = {
660 .startup = cs35l35_pcm_startup,
661 .set_fmt = cs35l35_set_dai_fmt,
662 .hw_params = cs35l35_hw_params,
663 .set_sysclk = cs35l35_dai_set_sysclk,
664};
665
666static const struct snd_soc_dai_ops cs35l35_pdm_ops = {
667 .startup = cs35l35_pdm_startup,
668 .set_fmt = cs35l35_set_dai_fmt,
669 .hw_params = cs35l35_hw_params,
670};
671
672static struct snd_soc_dai_driver cs35l35_dai[] = {
673 {
674 .name = "cs35l35-pcm",
675 .id = 0,
676 .playback = {
677 .stream_name = "AMP Playback",
678 .channels_min = 1,
679 .channels_max = 8,
680 .rates = SNDRV_PCM_RATE_KNOT,
681 .formats = CS35L35_FORMATS,
682 },
683 .capture = {
684 .stream_name = "AMP Capture",
685 .channels_min = 1,
686 .channels_max = 8,
687 .rates = SNDRV_PCM_RATE_KNOT,
688 .formats = CS35L35_FORMATS,
689 },
690 .ops = &cs35l35_ops,
691 .symmetric_rates = 1,
692 },
693 {
694 .name = "cs35l35-pdm",
695 .id = 1,
696 .playback = {
697 .stream_name = "PDM Playback",
698 .channels_min = 1,
699 .channels_max = 2,
700 .rates = SNDRV_PCM_RATE_KNOT,
701 .formats = CS35L35_FORMATS,
702 },
703 .ops = &cs35l35_pdm_ops,
704 },
705};
706
707static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
708 int clk_id, int source, unsigned int freq,
709 int dir)
710{
711 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
712 int clksrc;
713 int ret = 0;
714
715 switch (clk_id) {
716 case 0:
717 clksrc = CS35L35_CLK_SOURCE_MCLK;
718 break;
719 case 1:
720 clksrc = CS35L35_CLK_SOURCE_SCLK;
721 break;
722 case 2:
723 clksrc = CS35L35_CLK_SOURCE_PDM;
724 break;
725 default:
726 dev_err(codec->dev, "Invalid CLK Source\n");
727 return -EINVAL;
728 }
729
730 switch (freq) {
731 case 5644800:
732 case 6144000:
733 case 11289600:
734 case 12000000:
735 case 12288000:
736 case 13000000:
737 case 22579200:
738 case 24000000:
739 case 24576000:
740 case 26000000:
741 cs35l35->sysclk = freq;
742 break;
743 default:
744 dev_err(codec->dev, "Invalid CLK Frequency Input : %d\n", freq);
745 return -EINVAL;
746 }
747
748 ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
749 CS35L35_CLK_SOURCE_MASK,
750 clksrc << CS35L35_CLK_SOURCE_SHIFT);
751 if (ret != 0) {
752 dev_err(codec->dev, "Failed to set sysclk %d\n", ret);
753 return ret;
754 }
755
756 return ret;
757}
758
759static int cs35l35_codec_probe(struct snd_soc_codec *codec)
760{
761 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
762 struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
763 struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
764 int ret;
765
766 /* Set Platform Data */
767 if (cs35l35->pdata.bst_vctl)
768 regmap_update_bits(cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,
769 CS35L35_BST_CTL_MASK,
770 cs35l35->pdata.bst_vctl);
771
772 if (cs35l35->pdata.bst_ipk)
773 regmap_update_bits(cs35l35->regmap, CS35L35_BST_PEAK_I,
774 CS35L35_BST_IPK_MASK,
775 cs35l35->pdata.bst_ipk <<
776 CS35L35_BST_IPK_SHIFT);
777
778 if (cs35l35->pdata.gain_zc)
779 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
780 CS35L35_AMP_GAIN_ZC_MASK,
781 cs35l35->pdata.gain_zc <<
782 CS35L35_AMP_GAIN_ZC_SHIFT);
783
784 if (cs35l35->pdata.aud_channel)
785 regmap_update_bits(cs35l35->regmap,
786 CS35L35_AUDIN_RXLOC_CTL,
787 CS35L35_AUD_IN_LR_MASK,
788 cs35l35->pdata.aud_channel <<
789 CS35L35_AUD_IN_LR_SHIFT);
790
791 if (cs35l35->pdata.stereo) {
792 regmap_update_bits(cs35l35->regmap,
793 CS35L35_ADVIN_RXLOC_CTL,
794 CS35L35_ADV_IN_LR_MASK,
795 cs35l35->pdata.adv_channel <<
796 CS35L35_ADV_IN_LR_SHIFT);
797 if (cs35l35->pdata.shared_bst)
798 regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
799 CS35L35_CH_STEREO_MASK,
800 1 << CS35L35_CH_STEREO_SHIFT);
801 ret = snd_soc_add_codec_controls(codec, cs35l35_adv_controls,
802 ARRAY_SIZE(cs35l35_adv_controls));
803 if (ret)
804 return ret;
805 }
806
807 if (cs35l35->pdata.sp_drv_str)
808 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
809 CS35L35_SP_DRV_MASK,
810 cs35l35->pdata.sp_drv_str <<
811 CS35L35_SP_DRV_SHIFT);
812 if (cs35l35->pdata.sp_drv_unused)
813 regmap_update_bits(cs35l35->regmap, CS35L35_SP_FMT_CTL3,
814 CS35L35_SP_I2S_DRV_MASK,
815 cs35l35->pdata.sp_drv_unused <<
816 CS35L35_SP_I2S_DRV_SHIFT);
817
818 if (classh->classh_algo_enable) {
819 if (classh->classh_bst_override)
820 regmap_update_bits(cs35l35->regmap,
821 CS35L35_CLASS_H_CTL,
822 CS35L35_CH_BST_OVR_MASK,
823 classh->classh_bst_override <<
824 CS35L35_CH_BST_OVR_SHIFT);
825 if (classh->classh_bst_max_limit)
826 regmap_update_bits(cs35l35->regmap,
827 CS35L35_CLASS_H_CTL,
828 CS35L35_CH_BST_LIM_MASK,
829 classh->classh_bst_max_limit <<
830 CS35L35_CH_BST_LIM_SHIFT);
831 if (classh->classh_mem_depth)
832 regmap_update_bits(cs35l35->regmap,
833 CS35L35_CLASS_H_CTL,
834 CS35L35_CH_MEM_DEPTH_MASK,
835 classh->classh_mem_depth <<
836 CS35L35_CH_MEM_DEPTH_SHIFT);
837 if (classh->classh_headroom)
838 regmap_update_bits(cs35l35->regmap,
839 CS35L35_CLASS_H_HEADRM_CTL,
840 CS35L35_CH_HDRM_CTL_MASK,
841 classh->classh_headroom <<
842 CS35L35_CH_HDRM_CTL_SHIFT);
843 if (classh->classh_release_rate)
844 regmap_update_bits(cs35l35->regmap,
845 CS35L35_CLASS_H_RELEASE_RATE,
846 CS35L35_CH_REL_RATE_MASK,
847 classh->classh_release_rate <<
848 CS35L35_CH_REL_RATE_SHIFT);
849 if (classh->classh_wk_fet_disable)
850 regmap_update_bits(cs35l35->regmap,
851 CS35L35_CLASS_H_FET_DRIVE_CTL,
852 CS35L35_CH_WKFET_DIS_MASK,
853 classh->classh_wk_fet_disable <<
854 CS35L35_CH_WKFET_DIS_SHIFT);
855 if (classh->classh_wk_fet_delay)
856 regmap_update_bits(cs35l35->regmap,
857 CS35L35_CLASS_H_FET_DRIVE_CTL,
858 CS35L35_CH_WKFET_DEL_MASK,
859 classh->classh_wk_fet_delay <<
860 CS35L35_CH_WKFET_DEL_SHIFT);
861 if (classh->classh_wk_fet_thld)
862 regmap_update_bits(cs35l35->regmap,
863 CS35L35_CLASS_H_FET_DRIVE_CTL,
864 CS35L35_CH_WKFET_THLD_MASK,
865 classh->classh_wk_fet_thld <<
866 CS35L35_CH_WKFET_THLD_SHIFT);
867 if (classh->classh_vpch_auto)
868 regmap_update_bits(cs35l35->regmap,
869 CS35L35_CLASS_H_VP_CTL,
870 CS35L35_CH_VP_AUTO_MASK,
871 classh->classh_vpch_auto <<
872 CS35L35_CH_VP_AUTO_SHIFT);
873 if (classh->classh_vpch_rate)
874 regmap_update_bits(cs35l35->regmap,
875 CS35L35_CLASS_H_VP_CTL,
876 CS35L35_CH_VP_RATE_MASK,
877 classh->classh_vpch_rate <<
878 CS35L35_CH_VP_RATE_SHIFT);
879 if (classh->classh_vpch_man)
880 regmap_update_bits(cs35l35->regmap,
881 CS35L35_CLASS_H_VP_CTL,
882 CS35L35_CH_VP_MAN_MASK,
883 classh->classh_vpch_man <<
884 CS35L35_CH_VP_MAN_SHIFT);
885 }
886
887 if (monitor_config->is_present) {
888 if (monitor_config->vmon_specs) {
889 regmap_update_bits(cs35l35->regmap,
890 CS35L35_SPKMON_DEPTH_CTL,
891 CS35L35_VMON_DEPTH_MASK,
892 monitor_config->vmon_dpth <<
893 CS35L35_VMON_DEPTH_SHIFT);
894 regmap_update_bits(cs35l35->regmap,
895 CS35L35_VMON_TXLOC_CTL,
896 CS35L35_MON_TXLOC_MASK,
897 monitor_config->vmon_loc <<
898 CS35L35_MON_TXLOC_SHIFT);
899 regmap_update_bits(cs35l35->regmap,
900 CS35L35_VMON_TXLOC_CTL,
901 CS35L35_MON_FRM_MASK,
902 monitor_config->vmon_frm <<
903 CS35L35_MON_FRM_SHIFT);
904 }
905 if (monitor_config->imon_specs) {
906 regmap_update_bits(cs35l35->regmap,
907 CS35L35_SPKMON_DEPTH_CTL,
908 CS35L35_IMON_DEPTH_MASK,
909 monitor_config->imon_dpth <<
910 CS35L35_IMON_DEPTH_SHIFT);
911 regmap_update_bits(cs35l35->regmap,
912 CS35L35_IMON_TXLOC_CTL,
913 CS35L35_MON_TXLOC_MASK,
914 monitor_config->imon_loc <<
915 CS35L35_MON_TXLOC_SHIFT);
916 regmap_update_bits(cs35l35->regmap,
917 CS35L35_IMON_TXLOC_CTL,
918 CS35L35_MON_FRM_MASK,
919 monitor_config->imon_frm <<
920 CS35L35_MON_FRM_SHIFT);
921 regmap_update_bits(cs35l35->regmap,
922 CS35L35_IMON_SCALE_CTL,
923 CS35L35_IMON_SCALE_MASK,
924 monitor_config->imon_scale <<
925 CS35L35_IMON_SCALE_SHIFT);
926 }
927 if (monitor_config->vpmon_specs) {
928 regmap_update_bits(cs35l35->regmap,
929 CS35L35_SUPMON_DEPTH_CTL,
930 CS35L35_VPMON_DEPTH_MASK,
931 monitor_config->vpmon_dpth <<
932 CS35L35_VPMON_DEPTH_SHIFT);
933 regmap_update_bits(cs35l35->regmap,
934 CS35L35_VPMON_TXLOC_CTL,
935 CS35L35_MON_TXLOC_MASK,
936 monitor_config->vpmon_loc <<
937 CS35L35_MON_TXLOC_SHIFT);
938 regmap_update_bits(cs35l35->regmap,
939 CS35L35_VPMON_TXLOC_CTL,
940 CS35L35_MON_FRM_MASK,
941 monitor_config->vpmon_frm <<
942 CS35L35_MON_FRM_SHIFT);
943 }
944 if (monitor_config->vbstmon_specs) {
945 regmap_update_bits(cs35l35->regmap,
946 CS35L35_SUPMON_DEPTH_CTL,
947 CS35L35_VBSTMON_DEPTH_MASK,
948 monitor_config->vpmon_dpth <<
949 CS35L35_VBSTMON_DEPTH_SHIFT);
950 regmap_update_bits(cs35l35->regmap,
951 CS35L35_VBSTMON_TXLOC_CTL,
952 CS35L35_MON_TXLOC_MASK,
953 monitor_config->vbstmon_loc <<
954 CS35L35_MON_TXLOC_SHIFT);
955 regmap_update_bits(cs35l35->regmap,
956 CS35L35_VBSTMON_TXLOC_CTL,
957 CS35L35_MON_FRM_MASK,
958 monitor_config->vbstmon_frm <<
959 CS35L35_MON_FRM_SHIFT);
960 }
961 if (monitor_config->vpbrstat_specs) {
962 regmap_update_bits(cs35l35->regmap,
963 CS35L35_SUPMON_DEPTH_CTL,
964 CS35L35_VPBRSTAT_DEPTH_MASK,
965 monitor_config->vpbrstat_dpth <<
966 CS35L35_VPBRSTAT_DEPTH_SHIFT);
967 regmap_update_bits(cs35l35->regmap,
968 CS35L35_VPBR_STATUS_TXLOC_CTL,
969 CS35L35_MON_TXLOC_MASK,
970 monitor_config->vpbrstat_loc <<
971 CS35L35_MON_TXLOC_SHIFT);
972 regmap_update_bits(cs35l35->regmap,
973 CS35L35_VPBR_STATUS_TXLOC_CTL,
974 CS35L35_MON_FRM_MASK,
975 monitor_config->vpbrstat_frm <<
976 CS35L35_MON_FRM_SHIFT);
977 }
978 if (monitor_config->zerofill_specs) {
979 regmap_update_bits(cs35l35->regmap,
980 CS35L35_SUPMON_DEPTH_CTL,
981 CS35L35_ZEROFILL_DEPTH_MASK,
982 monitor_config->zerofill_dpth <<
983 CS35L35_ZEROFILL_DEPTH_SHIFT);
984 regmap_update_bits(cs35l35->regmap,
985 CS35L35_ZERO_FILL_LOC_CTL,
986 CS35L35_MON_TXLOC_MASK,
987 monitor_config->zerofill_loc <<
988 CS35L35_MON_TXLOC_SHIFT);
989 regmap_update_bits(cs35l35->regmap,
990 CS35L35_ZERO_FILL_LOC_CTL,
991 CS35L35_MON_FRM_MASK,
992 monitor_config->zerofill_frm <<
993 CS35L35_MON_FRM_SHIFT);
994 }
995 }
996
997 return 0;
998}
999
1000static struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
1001 .probe = cs35l35_codec_probe,
1002 .set_sysclk = cs35l35_codec_set_sysclk,
1003 .component_driver = {
1004 .dapm_widgets = cs35l35_dapm_widgets,
1005 .num_dapm_widgets = ARRAY_SIZE(cs35l35_dapm_widgets),
1006
1007 .dapm_routes = cs35l35_audio_map,
1008 .num_dapm_routes = ARRAY_SIZE(cs35l35_audio_map),
1009
1010 .controls = cs35l35_aud_controls,
1011 .num_controls = ARRAY_SIZE(cs35l35_aud_controls),
1012 },
1013
1014};
1015
1016static struct regmap_config cs35l35_regmap = {
1017 .reg_bits = 8,
1018 .val_bits = 8,
1019
1020 .max_register = CS35L35_MAX_REGISTER,
1021 .reg_defaults = cs35l35_reg,
1022 .num_reg_defaults = ARRAY_SIZE(cs35l35_reg),
1023 .volatile_reg = cs35l35_volatile_register,
1024 .readable_reg = cs35l35_readable_register,
1025 .precious_reg = cs35l35_precious_register,
1026 .cache_type = REGCACHE_RBTREE,
1027};
1028
1029static irqreturn_t cs35l35_irq(int irq, void *data)
1030{
1031 struct cs35l35_private *cs35l35 = data;
1032 unsigned int sticky1, sticky2, sticky3, sticky4;
1033 unsigned int mask1, mask2, mask3, mask4, current1;
1034
1035 /* ack the irq by reading all status registers */
1036 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_4, &sticky4);
1037 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_3, &sticky3);
1038 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_2, &sticky2);
1039 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &sticky1);
1040
1041 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_4, &mask4);
1042 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_3, &mask3);
1043 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_2, &mask2);
1044 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_1, &mask1);
1045
1046 /* Check to see if unmasked bits are active */
1047 if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)
1048 && !(sticky4 & ~mask4))
1049 return IRQ_NONE;
1050
1051 if (sticky2 & CS35L35_PDN_DONE)
1052 complete(&cs35l35->pdn_done);
1053
1054 /* read the current values */
1055 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &current1);
1056
1057 /* handle the interrupts */
1058 if (sticky1 & CS35L35_CAL_ERR) {
1059 dev_crit(cs35l35->dev, "Calibration Error\n");
1060
1061 /* error is no longer asserted; safe to reset */
1062 if (!(current1 & CS35L35_CAL_ERR)) {
1063 pr_debug("%s : Cal error release\n", __func__);
1064 regmap_update_bits(cs35l35->regmap,
1065 CS35L35_PROT_RELEASE_CTL,
1066 CS35L35_CAL_ERR_RLS, 0);
1067 regmap_update_bits(cs35l35->regmap,
1068 CS35L35_PROT_RELEASE_CTL,
1069 CS35L35_CAL_ERR_RLS,
1070 CS35L35_CAL_ERR_RLS);
1071 regmap_update_bits(cs35l35->regmap,
1072 CS35L35_PROT_RELEASE_CTL,
1073 CS35L35_CAL_ERR_RLS, 0);
1074 }
1075 }
1076
1077 if (sticky1 & CS35L35_AMP_SHORT) {
1078 dev_crit(cs35l35->dev, "AMP Short Error\n");
1079 /* error is no longer asserted; safe to reset */
1080 if (!(current1 & CS35L35_AMP_SHORT)) {
1081 dev_dbg(cs35l35->dev, "Amp short error release\n");
1082 regmap_update_bits(cs35l35->regmap,
1083 CS35L35_PROT_RELEASE_CTL,
1084 CS35L35_SHORT_RLS, 0);
1085 regmap_update_bits(cs35l35->regmap,
1086 CS35L35_PROT_RELEASE_CTL,
1087 CS35L35_SHORT_RLS,
1088 CS35L35_SHORT_RLS);
1089 regmap_update_bits(cs35l35->regmap,
1090 CS35L35_PROT_RELEASE_CTL,
1091 CS35L35_SHORT_RLS, 0);
1092 }
1093 }
1094
1095 if (sticky1 & CS35L35_OTW) {
1096 dev_warn(cs35l35->dev, "Over temperature warning\n");
1097
1098 /* error is no longer asserted; safe to reset */
1099 if (!(current1 & CS35L35_OTW)) {
1100 dev_dbg(cs35l35->dev, "Over temperature warn release\n");
1101 regmap_update_bits(cs35l35->regmap,
1102 CS35L35_PROT_RELEASE_CTL,
1103 CS35L35_OTW_RLS, 0);
1104 regmap_update_bits(cs35l35->regmap,
1105 CS35L35_PROT_RELEASE_CTL,
1106 CS35L35_OTW_RLS,
1107 CS35L35_OTW_RLS);
1108 regmap_update_bits(cs35l35->regmap,
1109 CS35L35_PROT_RELEASE_CTL,
1110 CS35L35_OTW_RLS, 0);
1111 }
1112 }
1113
1114 if (sticky1 & CS35L35_OTE) {
1115 dev_crit(cs35l35->dev, "Over temperature error\n");
1116 /* error is no longer asserted; safe to reset */
1117 if (!(current1 & CS35L35_OTE)) {
1118 dev_dbg(cs35l35->dev, "Over temperature error release\n");
1119 regmap_update_bits(cs35l35->regmap,
1120 CS35L35_PROT_RELEASE_CTL,
1121 CS35L35_OTE_RLS, 0);
1122 regmap_update_bits(cs35l35->regmap,
1123 CS35L35_PROT_RELEASE_CTL,
1124 CS35L35_OTE_RLS,
1125 CS35L35_OTE_RLS);
1126 regmap_update_bits(cs35l35->regmap,
1127 CS35L35_PROT_RELEASE_CTL,
1128 CS35L35_OTE_RLS, 0);
1129 }
1130 }
1131
1132 if (sticky3 & CS35L35_BST_HIGH) {
1133 dev_crit(cs35l35->dev, "VBST error: powering off!\n");
1134 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1135 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1136 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1137 CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1138 }
1139
1140 if (sticky3 & CS35L35_LBST_SHORT) {
1141 dev_crit(cs35l35->dev, "LBST error: powering off!\n");
1142 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1143 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1144 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1145 CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1146 }
1147
1148 if (sticky2 & CS35L35_VPBR_ERR)
1149 dev_dbg(cs35l35->dev, "Error: Reactive Brownout\n");
1150
1151 if (sticky4 & CS35L35_VMON_OVFL)
1152 dev_dbg(cs35l35->dev, "Error: VMON overflow\n");
1153
1154 if (sticky4 & CS35L35_IMON_OVFL)
1155 dev_dbg(cs35l35->dev, "Error: IMON overflow\n");
1156
1157 return IRQ_HANDLED;
1158}
1159
1160
1161static int cs35l35_handle_of_data(struct i2c_client *i2c_client,
1162 struct cs35l35_platform_data *pdata)
1163{
1164 struct device_node *np = i2c_client->dev.of_node;
1165 struct device_node *classh, *signal_format;
1166 struct classh_cfg *classh_config = &pdata->classh_algo;
1167 struct monitor_cfg *monitor_config = &pdata->mon_cfg;
1168 unsigned int val32 = 0;
1169 u8 monitor_array[4];
1170 const int imon_array_size = ARRAY_SIZE(monitor_array);
1171 const int mon_array_size = imon_array_size - 1;
1172 int ret = 0;
1173
1174 if (!np)
1175 return 0;
1176
1177 pdata->bst_pdn_fet_on = of_property_read_bool(np,
1178 "cirrus,boost-pdn-fet-on");
1179
1180 ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val32);
1181 if (ret >= 0) {
1182 if (val32 < 2600 || val32 > 9000) {
1183 dev_err(&i2c_client->dev,
1184 "Invalid Boost Voltage %d mV\n", val32);
1185 return -EINVAL;
1186 }
1187 pdata->bst_vctl = ((val32 - 2600) / 100) + 1;
1188 }
1189
1190 ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val32);
1191 if (ret >= 0) {
1192 if (val32 < 1680 || val32 > 4480) {
1193 dev_err(&i2c_client->dev,
1194 "Invalid Boost Peak Current %u mA\n", val32);
1195 return -EINVAL;
1196 }
1197
1198 pdata->bst_ipk = (val32 - 1680) / 110;
1199 }
1200
1201 if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)
1202 pdata->sp_drv_str = val32;
1203 if (of_property_read_u32(np, "cirrus,sp-drv-unused", &val32) >= 0)
1204 pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;
1205
1206 pdata->stereo = of_property_read_bool(np, "cirrus,stereo-config");
1207
1208 if (pdata->stereo) {
1209 ret = of_property_read_u32(np, "cirrus,audio-channel", &val32);
1210 if (ret >= 0)
1211 pdata->aud_channel = val32;
1212
1213 ret = of_property_read_u32(np, "cirrus,advisory-channel",
1214 &val32);
1215 if (ret >= 0)
1216 pdata->adv_channel = val32;
1217
1218 pdata->shared_bst = of_property_read_bool(np,
1219 "cirrus,shared-boost");
1220 }
1221
1222 pdata->ext_bst = of_property_read_bool(np, "cirrus,external-boost");
1223
1224 pdata->gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc");
1225
1226 classh = of_get_child_by_name(np, "cirrus,classh-internal-algo");
1227 classh_config->classh_algo_enable = classh ? true : false;
1228
1229 if (classh_config->classh_algo_enable) {
1230 classh_config->classh_bst_override =
1231 of_property_read_bool(np, "cirrus,classh-bst-overide");
1232
1233 ret = of_property_read_u32(classh,
1234 "cirrus,classh-bst-max-limit",
1235 &val32);
1236 if (ret >= 0) {
1237 val32 |= CS35L35_VALID_PDATA;
1238 classh_config->classh_bst_max_limit = val32;
1239 }
1240
1241 ret = of_property_read_u32(classh,
1242 "cirrus,classh-bst-max-limit",
1243 &val32);
1244 if (ret >= 0) {
1245 val32 |= CS35L35_VALID_PDATA;
1246 classh_config->classh_bst_max_limit = val32;
1247 }
1248
1249 ret = of_property_read_u32(classh, "cirrus,classh-mem-depth",
1250 &val32);
1251 if (ret >= 0) {
1252 val32 |= CS35L35_VALID_PDATA;
1253 classh_config->classh_mem_depth = val32;
1254 }
1255
1256 ret = of_property_read_u32(classh, "cirrus,classh-release-rate",
1257 &val32);
1258 if (ret >= 0)
1259 classh_config->classh_release_rate = val32;
1260
1261 ret = of_property_read_u32(classh, "cirrus,classh-headroom",
1262 &val32);
1263 if (ret >= 0) {
1264 val32 |= CS35L35_VALID_PDATA;
1265 classh_config->classh_headroom = val32;
1266 }
1267
1268 ret = of_property_read_u32(classh,
1269 "cirrus,classh-wk-fet-disable",
1270 &val32);
1271 if (ret >= 0)
1272 classh_config->classh_wk_fet_disable = val32;
1273
1274 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-delay",
1275 &val32);
1276 if (ret >= 0) {
1277 val32 |= CS35L35_VALID_PDATA;
1278 classh_config->classh_wk_fet_delay = val32;
1279 }
1280
1281 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-thld",
1282 &val32);
1283 if (ret >= 0)
1284 classh_config->classh_wk_fet_thld = val32;
1285
1286 ret = of_property_read_u32(classh, "cirrus,classh-vpch-auto",
1287 &val32);
1288 if (ret >= 0) {
1289 val32 |= CS35L35_VALID_PDATA;
1290 classh_config->classh_vpch_auto = val32;
1291 }
1292
1293 ret = of_property_read_u32(classh, "cirrus,classh-vpch-rate",
1294 &val32);
1295 if (ret >= 0) {
1296 val32 |= CS35L35_VALID_PDATA;
1297 classh_config->classh_vpch_rate = val32;
1298 }
1299
1300 ret = of_property_read_u32(classh, "cirrus,classh-vpch-man",
1301 &val32);
1302 if (ret >= 0)
1303 classh_config->classh_vpch_man = val32;
1304 }
1305 of_node_put(classh);
1306
1307 /* frame depth location */
1308 signal_format = of_get_child_by_name(np, "cirrus,monitor-signal-format");
1309 monitor_config->is_present = signal_format ? true : false;
1310 if (monitor_config->is_present) {
1311 ret = of_property_read_u8_array(signal_format, "cirrus,imon",
1312 monitor_array, imon_array_size);
1313 if (!ret) {
1314 monitor_config->imon_specs = true;
1315 monitor_config->imon_dpth = monitor_array[0];
1316 monitor_config->imon_loc = monitor_array[1];
1317 monitor_config->imon_frm = monitor_array[2];
1318 monitor_config->imon_scale = monitor_array[3];
1319 }
1320 ret = of_property_read_u8_array(signal_format, "cirrus,vmon",
1321 monitor_array, mon_array_size);
1322 if (!ret) {
1323 monitor_config->vmon_specs = true;
1324 monitor_config->vmon_dpth = monitor_array[0];
1325 monitor_config->vmon_loc = monitor_array[1];
1326 monitor_config->vmon_frm = monitor_array[2];
1327 }
1328 ret = of_property_read_u8_array(signal_format, "cirrus,vpmon",
1329 monitor_array, mon_array_size);
1330 if (!ret) {
1331 monitor_config->vpmon_specs = true;
1332 monitor_config->vpmon_dpth = monitor_array[0];
1333 monitor_config->vpmon_loc = monitor_array[1];
1334 monitor_config->vpmon_frm = monitor_array[2];
1335 }
1336 ret = of_property_read_u8_array(signal_format, "cirrus,vbstmon",
1337 monitor_array, mon_array_size);
1338 if (!ret) {
1339 monitor_config->vbstmon_specs = true;
1340 monitor_config->vbstmon_dpth = monitor_array[0];
1341 monitor_config->vbstmon_loc = monitor_array[1];
1342 monitor_config->vbstmon_frm = monitor_array[2];
1343 }
1344 ret = of_property_read_u8_array(signal_format, "cirrus,vpbrstat",
1345 monitor_array, mon_array_size);
1346 if (!ret) {
1347 monitor_config->vpbrstat_specs = true;
1348 monitor_config->vpbrstat_dpth = monitor_array[0];
1349 monitor_config->vpbrstat_loc = monitor_array[1];
1350 monitor_config->vpbrstat_frm = monitor_array[2];
1351 }
1352 ret = of_property_read_u8_array(signal_format, "cirrus,zerofill",
1353 monitor_array, mon_array_size);
1354 if (!ret) {
1355 monitor_config->zerofill_specs = true;
1356 monitor_config->zerofill_dpth = monitor_array[0];
1357 monitor_config->zerofill_loc = monitor_array[1];
1358 monitor_config->zerofill_frm = monitor_array[2];
1359 }
1360 }
1361 of_node_put(signal_format);
1362
1363 return 0;
1364}
1365
1366/* Errata Rev A0 */
1367static const struct reg_sequence cs35l35_errata_patch[] = {
1368
1369 { 0x7F, 0x99 },
1370 { 0x00, 0x99 },
1371 { 0x52, 0x22 },
1372 { 0x04, 0x14 },
1373 { 0x6D, 0x44 },
1374 { 0x24, 0x10 },
1375 { 0x58, 0xC4 },
1376 { 0x00, 0x98 },
1377 { 0x18, 0x08 },
1378 { 0x00, 0x00 },
1379 { 0x7F, 0x00 },
1380};
1381
1382static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
1383 const struct i2c_device_id *id)
1384{
1385 struct cs35l35_private *cs35l35;
1386 struct device *dev = &i2c_client->dev;
1387 struct cs35l35_platform_data *pdata = dev_get_platdata(dev);
1388 int i;
1389 int ret;
1390 unsigned int devid = 0;
1391 unsigned int reg;
1392
1393 cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);
1394 if (!cs35l35)
1395 return -ENOMEM;
1396
1397 cs35l35->dev = dev;
1398
1399 i2c_set_clientdata(i2c_client, cs35l35);
1400 cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);
1401 if (IS_ERR(cs35l35->regmap)) {
1402 ret = PTR_ERR(cs35l35->regmap);
1403 dev_err(dev, "regmap_init() failed: %d\n", ret);
1404 goto err;
1405 }
1406
1407 for (i = 0; i < ARRAY_SIZE(cs35l35_supplies); i++)
1408 cs35l35->supplies[i].supply = cs35l35_supplies[i];
1409
1410 cs35l35->num_supplies = ARRAY_SIZE(cs35l35_supplies);
1411
1412 ret = devm_regulator_bulk_get(dev, cs35l35->num_supplies,
1413 cs35l35->supplies);
1414 if (ret != 0) {
1415 dev_err(dev, "Failed to request core supplies: %d\n", ret);
1416 return ret;
1417 }
1418
1419 if (pdata) {
1420 cs35l35->pdata = *pdata;
1421 } else {
1422 pdata = devm_kzalloc(dev, sizeof(struct cs35l35_platform_data),
1423 GFP_KERNEL);
1424 if (!pdata)
1425 return -ENOMEM;
1426 if (i2c_client->dev.of_node) {
1427 ret = cs35l35_handle_of_data(i2c_client, pdata);
1428 if (ret != 0)
1429 return ret;
1430
1431 }
1432 cs35l35->pdata = *pdata;
1433 }
1434
1435 ret = regulator_bulk_enable(cs35l35->num_supplies,
1436 cs35l35->supplies);
1437 if (ret != 0) {
1438 dev_err(dev, "Failed to enable core supplies: %d\n", ret);
1439 return ret;
1440 }
1441
1442 /* returning NULL can be valid if in stereo mode */
1443 cs35l35->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1444 GPIOD_OUT_LOW);
1445 if (IS_ERR(cs35l35->reset_gpio)) {
1446 ret = PTR_ERR(cs35l35->reset_gpio);
1447 cs35l35->reset_gpio = NULL;
1448 if (ret == -EBUSY) {
1449 dev_info(dev,
1450 "Reset line busy, assuming shared reset\n");
1451 } else {
1452 dev_err(dev, "Failed to get reset GPIO: %d\n", ret);
1453 goto err;
1454 }
1455 }
1456
1457 gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);
1458
1459 init_completion(&cs35l35->pdn_done);
1460
1461 ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l35_irq,
1462 IRQF_ONESHOT | IRQF_TRIGGER_LOW |
1463 IRQF_SHARED, "cs35l35", cs35l35);
1464 if (ret != 0) {
1465 dev_err(dev, "Failed to request IRQ: %d\n", ret);
1466 goto err;
1467 }
1468 /* initialize codec */
1469 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_AB, &reg);
1470
1471 devid = (reg & 0xFF) << 12;
1472 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_CD, &reg);
1473 devid |= (reg & 0xFF) << 4;
1474 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_E, &reg);
1475 devid |= (reg & 0xF0) >> 4;
1476
1477 if (devid != CS35L35_CHIP_ID) {
1478 dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",
1479 devid, CS35L35_CHIP_ID);
1480 ret = -ENODEV;
1481 goto err;
1482 }
1483
1484 ret = regmap_read(cs35l35->regmap, CS35L35_REV_ID, &reg);
1485 if (ret < 0) {
1486 dev_err(dev, "Get Revision ID failed: %d\n", ret);
1487 goto err;
1488 }
1489
1490 ret = regmap_register_patch(cs35l35->regmap, cs35l35_errata_patch,
1491 ARRAY_SIZE(cs35l35_errata_patch));
1492 if (ret < 0) {
1493 dev_err(dev, "Failed to apply errata patch: %d\n", ret);
1494 goto err;
1495 }
1496
1497 dev_info(dev, "Cirrus Logic CS35L35 (%x), Revision: %02X\n",
1498 devid, reg & 0xFF);
1499
1500 /* Set the INT Masks for critical errors */
1501 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_1,
1502 CS35L35_INT1_CRIT_MASK);
1503 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_2,
1504 CS35L35_INT2_CRIT_MASK);
1505 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_3,
1506 CS35L35_INT3_CRIT_MASK);
1507 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_4,
1508 CS35L35_INT4_CRIT_MASK);
1509
1510 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1511 CS35L35_PWR2_PDN_MASK,
1512 CS35L35_PWR2_PDN_MASK);
1513
1514 if (cs35l35->pdata.bst_pdn_fet_on)
1515 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1516 CS35L35_PDN_BST_MASK,
1517 1 << CS35L35_PDN_BST_FETON_SHIFT);
1518 else
1519 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1520 CS35L35_PDN_BST_MASK,
1521 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
1522
1523 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL3,
1524 CS35L35_PWR3_PDN_MASK,
1525 CS35L35_PWR3_PDN_MASK);
1526
1527 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
1528 CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
1529
1530 ret = snd_soc_register_codec(dev, &soc_codec_dev_cs35l35, cs35l35_dai,
1531 ARRAY_SIZE(cs35l35_dai));
1532 if (ret < 0) {
1533 dev_err(dev, "Failed to register codec: %d\n", ret);
1534 goto err;
1535 }
1536
1537 return 0;
1538
1539err:
1540 regulator_bulk_disable(cs35l35->num_supplies,
1541 cs35l35->supplies);
1542 gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
1543
1544 return ret;
1545}
1546
1547static int cs35l35_i2c_remove(struct i2c_client *client)
1548{
1549 snd_soc_unregister_codec(&client->dev);
1550 return 0;
1551}
1552
1553static const struct of_device_id cs35l35_of_match[] = {
1554 {.compatible = "cirrus,cs35l35"},
1555 {},
1556};
1557MODULE_DEVICE_TABLE(of, cs35l35_of_match);
1558
1559static const struct i2c_device_id cs35l35_id[] = {
1560 {"cs35l35", 0},
1561 {}
1562};
1563
1564MODULE_DEVICE_TABLE(i2c, cs35l35_id);
1565
1566static struct i2c_driver cs35l35_i2c_driver = {
1567 .driver = {
1568 .name = "cs35l35",
1569 .of_match_table = cs35l35_of_match,
1570 },
1571 .id_table = cs35l35_id,
1572 .probe = cs35l35_i2c_probe,
1573 .remove = cs35l35_i2c_remove,
1574};
1575
1576module_i2c_driver(cs35l35_i2c_driver);
1577
1578MODULE_DESCRIPTION("ASoC CS35L35 driver");
1579MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1580MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l35.h b/sound/soc/codecs/cs35l35.h
new file mode 100644
index 000000000000..5a6e43a87c4d
--- /dev/null
+++ b/sound/soc/codecs/cs35l35.h
@@ -0,0 +1,294 @@
1/*
2 * cs35l35.h -- CS35L35 ALSA SoC audio driver
3 *
4 * Copyright 2016 Cirrus Logic, Inc.
5 *
6 * Author: Brian Austin <brian.austin@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#ifndef __CS35L35_H__
15#define __CS35L35_H__
16
17#define CS35L35_FIRSTREG 0x01
18#define CS35L35_LASTREG 0x7E
19#define CS35L35_CHIP_ID 0x00035A35
20#define CS35L35_DEVID_AB 0x01 /* Device ID A & B [RO] */
21#define CS35L35_DEVID_CD 0x02 /* Device ID C & D [RO] */
22#define CS35L35_DEVID_E 0x03 /* Device ID E [RO] */
23#define CS35L35_FAB_ID 0x04 /* Fab ID [RO] */
24#define CS35L35_REV_ID 0x05 /* Revision ID [RO] */
25#define CS35L35_PWRCTL1 0x06 /* Power Ctl 1 */
26#define CS35L35_PWRCTL2 0x07 /* Power Ctl 2 */
27#define CS35L35_PWRCTL3 0x08 /* Power Ctl 3 */
28#define CS35L35_CLK_CTL1 0x0A /* Clocking Ctl 1 */
29#define CS35L35_CLK_CTL2 0x0B /* Clocking Ctl 2 */
30#define CS35L35_CLK_CTL3 0x0C /* Clocking Ctl 3 */
31#define CS35L35_SP_FMT_CTL1 0x0D /* Serial Port Format CTL1 */
32#define CS35L35_SP_FMT_CTL2 0x0E /* Serial Port Format CTL2 */
33#define CS35L35_SP_FMT_CTL3 0x0F /* Serial Port Format CTL3 */
34#define CS35L35_MAG_COMP_CTL 0x13 /* Magnitude Comp CTL */
35#define CS35L35_AMP_INP_DRV_CTL 0x14 /* Amp Input Drive Ctl */
36#define CS35L35_AMP_DIG_VOL_CTL 0x15 /* Amplifier Dig Volume Ctl */
37#define CS35L35_AMP_DIG_VOL 0x16 /* Amplifier Dig Volume */
38#define CS35L35_ADV_DIG_VOL 0x17 /* Advisory Digital Volume */
39#define CS35L35_PROTECT_CTL 0x18 /* Amp Gain - Prot Ctl Param */
40#define CS35L35_AMP_GAIN_AUD_CTL 0x19 /* Amp Serial Port Gain Ctl */
41#define CS35L35_AMP_GAIN_PDM_CTL 0x1A /* Amplifier Gain PDM Ctl */
42#define CS35L35_AMP_GAIN_ADV_CTL 0x1B /* Amplifier Gain Ctl */
43#define CS35L35_GPI_CTL 0x1C /* GPI Ctl */
44#define CS35L35_BST_CVTR_V_CTL 0x1D /* Boost Conv Voltage Ctl */
45#define CS35L35_BST_PEAK_I 0x1E /* Boost Conv Peak Current */
46#define CS35L35_BST_RAMP_CTL 0x20 /* Boost Conv Soft Ramp Ctl */
47#define CS35L35_BST_CONV_COEF_1 0x21 /* Boost Conv Coefficients 1 */
48#define CS35L35_BST_CONV_COEF_2 0x22 /* Boost Conv Coefficients 2 */
49#define CS35L35_BST_CONV_SLOPE_COMP 0x23 /* Boost Conv Slope Comp */
50#define CS35L35_BST_CONV_SW_FREQ 0x24 /* Boost Conv L BST SW Freq */
51#define CS35L35_CLASS_H_CTL 0x30 /* CLS H Control */
52#define CS35L35_CLASS_H_HEADRM_CTL 0x31 /* CLS H Headroom Ctl */
53#define CS35L35_CLASS_H_RELEASE_RATE 0x32 /* CLS H Release Rate */
54#define CS35L35_CLASS_H_FET_DRIVE_CTL 0x33 /* CLS H Weak FET Drive Ctl */
55#define CS35L35_CLASS_H_VP_CTL 0x34 /* CLS H VP Ctl */
56#define CS35L35_CLASS_H_STATUS 0x38 /* CLS H Status */
57#define CS35L35_VPBR_CTL 0x3A /* VPBR Ctl */
58#define CS35L35_VPBR_VOL_CTL 0x3B /* VPBR Volume Ctl */
59#define CS35L35_VPBR_TIMING_CTL 0x3C /* VPBR Timing Ctl */
60#define CS35L35_VPBR_MODE_VOL_CTL 0x3D /* VPBR Mode/Attack Vol Ctl */
61#define CS35L35_VPBR_ATTEN_STATUS 0x4B /* VPBR Attenuation Status */
62#define CS35L35_SPKR_MON_CTL 0x4E /* Speaker Monitoring Ctl */
63#define CS35L35_IMON_SCALE_CTL 0x51 /* IMON Scale Ctl */
64#define CS35L35_AUDIN_RXLOC_CTL 0x52 /* Audio Input RX Loc Ctl */
65#define CS35L35_ADVIN_RXLOC_CTL 0x53 /* Advisory Input RX Loc Ctl */
66#define CS35L35_VMON_TXLOC_CTL 0x54 /* VMON TX Loc Ctl */
67#define CS35L35_IMON_TXLOC_CTL 0x55 /* IMON TX Loc Ctl */
68#define CS35L35_VPMON_TXLOC_CTL 0x56 /* VPMON TX Loc Ctl */
69#define CS35L35_VBSTMON_TXLOC_CTL 0x57 /* VBSTMON TX Loc Ctl */
70#define CS35L35_VPBR_STATUS_TXLOC_CTL 0x58 /* VPBR Status TX Loc Ctl */
71#define CS35L35_ZERO_FILL_LOC_CTL 0x59 /* Zero Fill Loc Ctl */
72#define CS35L35_AUDIN_DEPTH_CTL 0x5A /* Audio Input Depth Ctl */
73#define CS35L35_SPKMON_DEPTH_CTL 0x5B /* SPK Mon Output Depth Ctl */
74#define CS35L35_SUPMON_DEPTH_CTL 0x5C /* Supply Mon Out Depth Ctl */
75#define CS35L35_ZEROFILL_DEPTH_CTL 0x5D /* Zero Fill Mon Output Ctl */
76#define CS35L35_MULT_DEV_SYNCH1 0x62 /* Multidevice Synch */
77#define CS35L35_MULT_DEV_SYNCH2 0x63 /* Multidevice Synch 2 */
78#define CS35L35_PROT_RELEASE_CTL 0x64 /* Protection Release Ctl */
79#define CS35L35_DIAG_MODE_REG_LOCK 0x68 /* Diagnostic Mode Reg Lock */
80#define CS35L35_DIAG_MODE_CTL_1 0x69 /* Diagnostic Mode Ctl 1 */
81#define CS35L35_DIAG_MODE_CTL_2 0x6A /* Diagnostic Mode Ctl 2 */
82#define CS35L35_INT_MASK_1 0x70 /* Interrupt Mask 1 */
83#define CS35L35_INT_MASK_2 0x71 /* Interrupt Mask 2 */
84#define CS35L35_INT_MASK_3 0x72 /* Interrupt Mask 3 */
85#define CS35L35_INT_MASK_4 0x73 /* Interrupt Mask 4 */
86#define CS35L35_INT_STATUS_1 0x74 /* Interrupt Status 1 */
87#define CS35L35_INT_STATUS_2 0x75 /* Interrupt Status 2 */
88#define CS35L35_INT_STATUS_3 0x76 /* Interrupt Status 3 */
89#define CS35L35_INT_STATUS_4 0x77 /* Interrupt Status 4 */
90#define CS35L35_PLL_STATUS 0x78 /* PLL Status */
91#define CS35L35_OTP_TRIM_STATUS 0x7E /* OTP Trim Status */
92
93#define CS35L35_MAX_REGISTER 0x7F
94
95/* CS35L35_PWRCTL1 */
96#define CS35L35_SFT_RST 0x80
97#define CS35L35_DISCHG_FLT 0x02
98#define CS35L35_PDN_ALL 0x01
99
100/* CS35L35_PWRCTL2 */
101#define CS35L35_PDN_VMON 0x80
102#define CS35L35_PDN_IMON 0x40
103#define CS35L35_PDN_CLASSH 0x20
104#define CS35L35_PDN_VPBR 0x10
105#define CS35L35_PDN_BST 0x04
106#define CS35L35_PDN_AMP 0x01
107
108/* CS35L35_PWRCTL3 */
109#define CS35L35_PDN_VBSTMON_OUT 0x10
110#define CS35L35_PDN_VMON_OUT 0x08
111
112#define CS35L35_AUDIN_DEPTH_MASK 0x03
113#define CS35L35_AUDIN_DEPTH_SHIFT 0
114#define CS35L35_ADVIN_DEPTH_MASK 0x0C
115#define CS35L35_ADVIN_DEPTH_SHIFT 2
116#define CS35L35_SDIN_DEPTH_8 0x01
117#define CS35L35_SDIN_DEPTH_16 0x02
118#define CS35L35_SDIN_DEPTH_24 0x03
119
120#define CS35L35_SDOUT_DEPTH_8 0x01
121#define CS35L35_SDOUT_DEPTH_12 0x02
122#define CS35L35_SDOUT_DEPTH_16 0x03
123
124#define CS35L35_AUD_IN_LR_MASK 0x80
125#define CS35L35_AUD_IN_LR_SHIFT 7
126#define CS35L35_ADV_IN_LR_MASK 0x80
127#define CS35L35_ADV_IN_LR_SHIFT 7
128#define CS35L35_AUD_IN_LOC_MASK 0x0F
129#define CS35L35_AUD_IN_LOC_SHIFT 0
130#define CS35L35_ADV_IN_LOC_MASK 0x0F
131#define CS35L35_ADV_IN_LOC_SHIFT 0
132
133#define CS35L35_IMON_DEPTH_MASK 0x03
134#define CS35L35_IMON_DEPTH_SHIFT 0
135#define CS35L35_VMON_DEPTH_MASK 0x0C
136#define CS35L35_VMON_DEPTH_SHIFT 2
137#define CS35L35_VBSTMON_DEPTH_MASK 0x03
138#define CS35L35_VBSTMON_DEPTH_SHIFT 0
139#define CS35L35_VPMON_DEPTH_MASK 0x0C
140#define CS35L35_VPMON_DEPTH_SHIFT 2
141#define CS35L35_VPBRSTAT_DEPTH_MASK 0x30
142#define CS35L35_VPBRSTAT_DEPTH_SHIFT 4
143#define CS35L35_ZEROFILL_DEPTH_MASK 0x03
144#define CS35L35_ZEROFILL_DEPTH_SHIFT 0x00
145
146#define CS35L35_MON_TXLOC_MASK 0x3F
147#define CS35L35_MON_TXLOC_SHIFT 0
148#define CS35L35_MON_FRM_MASK 0x80
149#define CS35L35_MON_FRM_SHIFT 7
150
151#define CS35L35_IMON_SCALE_MASK 0xF8
152#define CS35L35_IMON_SCALE_SHIFT 3
153
154#define CS35L35_MS_MASK 0x80
155#define CS35L35_MS_SHIFT 7
156#define CS35L35_SPMODE_MASK 0x40
157#define CS35L35_SP_DRV_MASK 0x10
158#define CS35L35_SP_DRV_SHIFT 4
159#define CS35L35_CLK_CTL2_MASK 0xFF
160#define CS35L35_PDM_MODE_MASK 0x40
161#define CS35L35_PDM_MODE_SHIFT 6
162#define CS35L35_CLK_SOURCE_MASK 0x03
163#define CS35L35_CLK_SOURCE_SHIFT 0
164#define CS35L35_CLK_SOURCE_MCLK 0
165#define CS35L35_CLK_SOURCE_SCLK 1
166#define CS35L35_CLK_SOURCE_PDM 2
167
168#define CS35L35_SP_SCLKS_MASK 0x0F
169#define CS35L35_SP_SCLKS_SHIFT 0x00
170#define CS35L35_SP_SCLKS_16FS 0x03
171#define CS35L35_SP_SCLKS_32FS 0x07
172#define CS35L35_SP_SCLKS_48FS 0x0B
173#define CS35L35_SP_SCLKS_64FS 0x0F
174#define CS35L35_SP_RATE_MASK 0xC0
175
176#define CS35L35_PDN_BST_MASK 0x06
177#define CS35L35_PDN_BST_FETON_SHIFT 1
178#define CS35L35_PDN_BST_FETOFF_SHIFT 2
179#define CS35L35_PWR2_PDN_MASK 0xE0
180#define CS35L35_PWR3_PDN_MASK 0x1E
181#define CS35L35_PDN_ALL_MASK 0x01
182#define CS35L35_DISCHG_FILT_MASK 0x02
183#define CS35L35_DISCHG_FILT_SHIFT 1
184#define CS35L35_MCLK_DIS_MASK 0x04
185#define CS35L35_MCLK_DIS_SHIFT 2
186
187#define CS35L35_BST_CTL_MASK 0x7F
188#define CS35L35_BST_CTL_SHIFT 0
189#define CS35L35_BST_IPK_MASK 0x1F
190#define CS35L35_BST_IPK_SHIFT 0
191#define CS35L35_AMP_MUTE_MASK 0x20
192#define CS35L35_AMP_MUTE_SHIFT 5
193#define CS35L35_AMP_GAIN_ZC_MASK 0x10
194#define CS35L35_AMP_GAIN_ZC_SHIFT 4
195
196#define CS35L35_AMP_DIGSFT_MASK 0x02
197#define CS35L35_AMP_DIGSFT_SHIFT 1
198
199/* CS35L35_SP_FMT_CTL3 */
200#define CS35L35_SP_I2S_DRV_MASK 0x03
201#define CS35L35_SP_I2S_DRV_SHIFT 0
202
203/* Class H Algorithm Control */
204#define CS35L35_CH_STEREO_MASK 0x40
205#define CS35L35_CH_STEREO_SHIFT 6
206#define CS35L35_CH_BST_OVR_MASK 0x04
207#define CS35L35_CH_BST_OVR_SHIFT 2
208#define CS35L35_CH_BST_LIM_MASK 0x08
209#define CS35L35_CH_BST_LIM_SHIFT 3
210#define CS35L35_CH_MEM_DEPTH_MASK 0x01
211#define CS35L35_CH_MEM_DEPTH_SHIFT 0
212#define CS35L35_CH_HDRM_CTL_MASK 0x3F
213#define CS35L35_CH_HDRM_CTL_SHIFT 0
214#define CS35L35_CH_REL_RATE_MASK 0xFF
215#define CS35L35_CH_REL_RATE_SHIFT 0
216#define CS35L35_CH_WKFET_DIS_MASK 0x80
217#define CS35L35_CH_WKFET_DIS_SHIFT 7
218#define CS35L35_CH_WKFET_DEL_MASK 0x70
219#define CS35L35_CH_WKFET_DEL_SHIFT 4
220#define CS35L35_CH_WKFET_THLD_MASK 0x0F
221#define CS35L35_CH_WKFET_THLD_SHIFT 0
222#define CS35L35_CH_VP_AUTO_MASK 0x80
223#define CS35L35_CH_VP_AUTO_SHIFT 7
224#define CS35L35_CH_VP_RATE_MASK 0x60
225#define CS35L35_CH_VP_RATE_SHIFT 5
226#define CS35L35_CH_VP_MAN_MASK 0x1F
227#define CS35L35_CH_VP_MAN_SHIFT 0
228
229/* CS35L35_PROT_RELEASE_CTL */
230#define CS35L35_CAL_ERR_RLS 0x80
231#define CS35L35_SHORT_RLS 0x04
232#define CS35L35_OTW_RLS 0x02
233#define CS35L35_OTE_RLS 0x01
234
235/* INT Mask Registers */
236#define CS35L35_INT1_CRIT_MASK 0x38
237#define CS35L35_INT2_CRIT_MASK 0xEF
238#define CS35L35_INT3_CRIT_MASK 0xEE
239#define CS35L35_INT4_CRIT_MASK 0xFF
240
241/* PDN DONE Masks */
242#define CS35L35_M_PDN_DONE_SHIFT 4
243#define CS35L35_M_PDN_DONE_MASK 0x10
244
245/* CS35L35_INT_1 */
246#define CS35L35_CAL_ERR 0x80
247#define CS35L35_OTP_ERR 0x40
248#define CS35L35_LRCLK_ERR 0x20
249#define CS35L35_SPCLK_ERR 0x10
250#define CS35L35_MCLK_ERR 0x08
251#define CS35L35_AMP_SHORT 0x04
252#define CS35L35_OTW 0x02
253#define CS35L35_OTE 0x01
254
255/* CS35L35_INT_2 */
256#define CS35L35_PDN_DONE 0x10
257#define CS35L35_VPBR_ERR 0x02
258#define CS35L35_VPBR_CLR 0x01
259
260/* CS35L35_INT_3 */
261#define CS35L35_BST_HIGH 0x10
262#define CS35L35_BST_HIGH_FLAG 0x08
263#define CS35L35_BST_IPK_FLAG 0x04
264#define CS35L35_LBST_SHORT 0x01
265
266/* CS35L35_INT_4 */
267#define CS35L35_VMON_OVFL 0x08
268#define CS35L35_IMON_OVFL 0x04
269
270#define CS35L35_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | \
271 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
272
273struct cs35l35_private {
274 struct device *dev;
275 struct cs35l35_platform_data pdata;
276 struct regmap *regmap;
277 struct regulator_bulk_data supplies[2];
278 int num_supplies;
279 int sysclk;
280 int sclk;
281 bool pdm_mode;
282 bool i2s_mode;
283 bool slave_mode;
284 /* GPIO for /RST */
285 struct gpio_desc *reset_gpio;
286 struct completion pdn_done;
287};
288
289static const char * const cs35l35_supplies[] = {
290 "VA",
291 "VP",
292};
293
294#endif
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 8c0f3b89b5bc..e78b5f055f25 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -498,7 +498,7 @@ static int cs4271_reset(struct snd_soc_codec *codec)
498 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 498 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
499 499
500 if (gpio_is_valid(cs4271->gpio_nreset)) { 500 if (gpio_is_valid(cs4271->gpio_nreset)) {
501 gpio_set_value(cs4271->gpio_nreset, 0); 501 gpio_direction_output(cs4271->gpio_nreset, 0);
502 mdelay(1); 502 mdelay(1);
503 gpio_set_value(cs4271->gpio_nreset, 1); 503 gpio_set_value(cs4271->gpio_nreset, 1);
504 mdelay(1); 504 mdelay(1);
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index cb47fb595ff4..1e0d5973b758 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -1130,6 +1130,7 @@ MODULE_DEVICE_TABLE(i2c, cs53l30_id);
1130static struct i2c_driver cs53l30_i2c_driver = { 1130static struct i2c_driver cs53l30_i2c_driver = {
1131 .driver = { 1131 .driver = {
1132 .name = "cs53l30", 1132 .name = "cs53l30",
1133 .of_match_table = cs53l30_of_match,
1133 .pm = &cs53l30_runtime_pm, 1134 .pm = &cs53l30_runtime_pm,
1134 }, 1135 },
1135 .id_table = cs53l30_id, 1136 .id_table = cs53l30_id,
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 12da55882c06..6dd7578f0bb8 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -12,6 +12,7 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/acpi.h>
15#include <linux/clk.h> 16#include <linux/clk.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
@@ -1528,12 +1529,23 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1528 return 0; 1529 return 0;
1529} 1530}
1530 1531
1532#if defined(CONFIG_OF)
1531/* DT */ 1533/* DT */
1532static const struct of_device_id da7213_of_match[] = { 1534static const struct of_device_id da7213_of_match[] = {
1533 { .compatible = "dlg,da7213", }, 1535 { .compatible = "dlg,da7213", },
1534 { } 1536 { }
1535}; 1537};
1536MODULE_DEVICE_TABLE(of, da7213_of_match); 1538MODULE_DEVICE_TABLE(of, da7213_of_match);
1539#endif
1540
1541#ifdef CONFIG_ACPI
1542static const struct acpi_device_id da7213_acpi_match[] = {
1543 { "DLGS7212", 0},
1544 { "DLGS7213", 0},
1545 { },
1546};
1547MODULE_DEVICE_TABLE(acpi, da7213_acpi_match);
1548#endif
1537 1549
1538static enum da7213_micbias_voltage 1550static enum da7213_micbias_voltage
1539 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1551 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
@@ -1844,6 +1856,7 @@ static struct i2c_driver da7213_i2c_driver = {
1844 .driver = { 1856 .driver = {
1845 .name = "da7213", 1857 .name = "da7213",
1846 .of_match_table = of_match_ptr(da7213_of_match), 1858 .of_match_table = of_match_ptr(da7213_of_match),
1859 .acpi_match_table = ACPI_PTR(da7213_acpi_match),
1847 }, 1860 },
1848 .probe = da7213_i2c_probe, 1861 .probe = da7213_i2c_probe,
1849 .remove = da7213_remove, 1862 .remove = da7213_remove,
diff --git a/sound/soc/codecs/dio2125.c b/sound/soc/codecs/dio2125.c
new file mode 100644
index 000000000000..09451cd44f9b
--- /dev/null
+++ b/sound/soc/codecs/dio2125.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Jerome Brunet <jbrunet@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * The full GNU General Public License is included in this distribution
17 * in the file called COPYING.
18 */
19
20#include <linux/gpio/consumer.h>
21#include <linux/module.h>
22#include <sound/soc.h>
23
24#define DRV_NAME "dio2125"
25
26struct dio2125 {
27 struct gpio_desc *gpiod_enable;
28};
29
30static int drv_event(struct snd_soc_dapm_widget *w,
31 struct snd_kcontrol *control, int event)
32{
33 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
34 struct dio2125 *priv = snd_soc_component_get_drvdata(c);
35 int val;
36
37 switch (event) {
38 case SND_SOC_DAPM_POST_PMU:
39 val = 1;
40 break;
41 case SND_SOC_DAPM_PRE_PMD:
42 val = 0;
43 break;
44 default:
45 WARN(1, "Unexpected event");
46 return -EINVAL;
47 }
48
49 gpiod_set_value_cansleep(priv->gpiod_enable, val);
50
51 return 0;
52}
53
54static const struct snd_soc_dapm_widget dio2125_dapm_widgets[] = {
55 SND_SOC_DAPM_INPUT("INL"),
56 SND_SOC_DAPM_INPUT("INR"),
57 SND_SOC_DAPM_OUT_DRV_E("DRV", SND_SOC_NOPM, 0, 0, NULL, 0, drv_event,
58 (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
59 SND_SOC_DAPM_OUTPUT("OUTL"),
60 SND_SOC_DAPM_OUTPUT("OUTR"),
61};
62
63static const struct snd_soc_dapm_route dio2125_dapm_routes[] = {
64 { "DRV", NULL, "INL" },
65 { "DRV", NULL, "INR" },
66 { "OUTL", NULL, "DRV" },
67 { "OUTR", NULL, "DRV" },
68};
69
70static const struct snd_soc_component_driver dio2125_component_driver = {
71 .dapm_widgets = dio2125_dapm_widgets,
72 .num_dapm_widgets = ARRAY_SIZE(dio2125_dapm_widgets),
73 .dapm_routes = dio2125_dapm_routes,
74 .num_dapm_routes = ARRAY_SIZE(dio2125_dapm_routes),
75};
76
77static int dio2125_probe(struct platform_device *pdev)
78{
79 struct device *dev = &pdev->dev;
80 struct dio2125 *priv;
81 int err;
82
83 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
84 if (priv == NULL)
85 return -ENOMEM;
86 platform_set_drvdata(pdev, priv);
87
88 priv->gpiod_enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
89 if (IS_ERR(priv->gpiod_enable)) {
90 err = PTR_ERR(priv->gpiod_enable);
91 if (err != -EPROBE_DEFER)
92 dev_err(dev, "Failed to get 'enable' gpio: %d", err);
93 return err;
94 }
95
96 return devm_snd_soc_register_component(dev, &dio2125_component_driver,
97 NULL, 0);
98}
99
100#ifdef CONFIG_OF
101static const struct of_device_id dio2125_ids[] = {
102 { .compatible = "dioo,dio2125", },
103 { }
104};
105MODULE_DEVICE_TABLE(of, dio2125_ids);
106#endif
107
108static struct platform_driver dio2125_driver = {
109 .driver = {
110 .name = DRV_NAME,
111 .of_match_table = of_match_ptr(dio2125_ids),
112 },
113 .probe = dio2125_probe,
114};
115
116module_platform_driver(dio2125_driver);
117
118MODULE_DESCRIPTION("ASoC DIO2125 output driver");
119MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
120MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c
new file mode 100644
index 000000000000..25ede825d349
--- /dev/null
+++ b/sound/soc/codecs/es7134.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Jerome Brunet <jbrunet@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * The full GNU General Public License is included in this distribution
17 * in the file called COPYING.
18 */
19
20#include <linux/module.h>
21#include <sound/soc.h>
22
23/*
24 * The everest 7134 is a very simple DA converter with no register
25 */
26
27static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
28{
29 fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK |
30 SND_SOC_DAIFMT_MASTER_MASK);
31
32 if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
33 SND_SOC_DAIFMT_CBS_CFS)) {
34 dev_err(codec_dai->dev, "Invalid DAI format\n");
35 return -EINVAL;
36 }
37
38 return 0;
39}
40
41static const struct snd_soc_dai_ops es7134_dai_ops = {
42 .set_fmt = es7134_set_fmt,
43};
44
45static struct snd_soc_dai_driver es7134_dai = {
46 .name = "es7134-hifi",
47 .playback = {
48 .stream_name = "Playback",
49 .channels_min = 2,
50 .channels_max = 2,
51 .rates = SNDRV_PCM_RATE_8000_192000,
52 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
53 SNDRV_PCM_FMTBIT_S18_3LE |
54 SNDRV_PCM_FMTBIT_S20_3LE |
55 SNDRV_PCM_FMTBIT_S24_3LE |
56 SNDRV_PCM_FMTBIT_S24_LE),
57 },
58 .ops = &es7134_dai_ops,
59};
60
61static const struct snd_soc_dapm_widget es7134_dapm_widgets[] = {
62 SND_SOC_DAPM_OUTPUT("AOUTL"),
63 SND_SOC_DAPM_OUTPUT("AOUTR"),
64 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
65};
66
67static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
68 { "AOUTL", NULL, "DAC" },
69 { "AOUTR", NULL, "DAC" },
70};
71
72static struct snd_soc_codec_driver es7134_codec_driver = {
73 .component_driver = {
74 .dapm_widgets = es7134_dapm_widgets,
75 .num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets),
76 .dapm_routes = es7134_dapm_routes,
77 .num_dapm_routes = ARRAY_SIZE(es7134_dapm_routes),
78 },
79};
80
81static int es7134_probe(struct platform_device *pdev)
82{
83 return snd_soc_register_codec(&pdev->dev,
84 &es7134_codec_driver,
85 &es7134_dai, 1);
86}
87
88static int es7134_remove(struct platform_device *pdev)
89{
90 snd_soc_unregister_codec(&pdev->dev);
91 return 0;
92}
93
94#ifdef CONFIG_OF
95static const struct of_device_id es7134_ids[] = {
96 { .compatible = "everest,es7134", },
97 { .compatible = "everest,es7144", },
98 { }
99};
100MODULE_DEVICE_TABLE(of, es7134_ids);
101#endif
102
103static struct platform_driver es7134_driver = {
104 .driver = {
105 .name = "es7134",
106 .of_match_table = of_match_ptr(es7134_ids),
107 },
108 .probe = es7134_probe,
109 .remove = es7134_remove,
110};
111
112module_platform_driver(es7134_driver);
113
114MODULE_DESCRIPTION("ASoC ES7134 audio codec driver");
115MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
116MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 3f84fbd071e2..ed7cc42d1ee2 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -69,14 +69,10 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = {
69 "HPVDD", 69 "HPVDD",
70}; 70};
71 71
72#define ES8328_RATES (SNDRV_PCM_RATE_96000 | \ 72#define ES8328_RATES (SNDRV_PCM_RATE_192000 | \
73 SNDRV_PCM_RATE_48000 | \ 73 SNDRV_PCM_RATE_96000 | \
74 SNDRV_PCM_RATE_44100 | \ 74 SNDRV_PCM_RATE_88200 | \
75 SNDRV_PCM_RATE_32000 | \ 75 SNDRV_PCM_RATE_8000_48000)
76 SNDRV_PCM_RATE_22050 | \
77 SNDRV_PCM_RATE_16000 | \
78 SNDRV_PCM_RATE_11025 | \
79 SNDRV_PCM_RATE_8000)
80#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 76#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
81 SNDRV_PCM_FMTBIT_S18_3LE | \ 77 SNDRV_PCM_FMTBIT_S18_3LE | \
82 SNDRV_PCM_FMTBIT_S20_3LE | \ 78 SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -91,6 +87,7 @@ struct es8328_priv {
91 int mclkdiv2; 87 int mclkdiv2;
92 const struct snd_pcm_hw_constraint_list *sysclk_constraints; 88 const struct snd_pcm_hw_constraint_list *sysclk_constraints;
93 const int *mclk_ratios; 89 const int *mclk_ratios;
90 bool master;
94 struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; 91 struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM];
95}; 92};
96 93
@@ -469,7 +466,7 @@ static int es8328_startup(struct snd_pcm_substream *substream,
469 struct snd_soc_codec *codec = dai->codec; 466 struct snd_soc_codec *codec = dai->codec;
470 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 467 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
471 468
472 if (es8328->sysclk_constraints) 469 if (es8328->master && es8328->sysclk_constraints)
473 snd_pcm_hw_constraint_list(substream->runtime, 0, 470 snd_pcm_hw_constraint_list(substream->runtime, 0,
474 SNDRV_PCM_HW_PARAM_RATE, 471 SNDRV_PCM_HW_PARAM_RATE,
475 es8328->sysclk_constraints); 472 es8328->sysclk_constraints);
@@ -488,27 +485,34 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
488 int wl; 485 int wl;
489 int ratio; 486 int ratio;
490 487
491 if (!es8328->sysclk_constraints) {
492 dev_err(codec->dev, "No MCLK configured\n");
493 return -EINVAL;
494 }
495
496 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 488 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
497 reg = ES8328_DACCONTROL2; 489 reg = ES8328_DACCONTROL2;
498 else 490 else
499 reg = ES8328_ADCCONTROL5; 491 reg = ES8328_ADCCONTROL5;
500 492
501 for (i = 0; i < es8328->sysclk_constraints->count; i++) 493 if (es8328->master) {
502 if (es8328->sysclk_constraints->list[i] == params_rate(params)) 494 if (!es8328->sysclk_constraints) {
503 break; 495 dev_err(codec->dev, "No MCLK configured\n");
496 return -EINVAL;
497 }
504 498
505 if (i == es8328->sysclk_constraints->count) { 499 for (i = 0; i < es8328->sysclk_constraints->count; i++)
506 dev_err(codec->dev, "LRCLK %d unsupported with current clock\n", 500 if (es8328->sysclk_constraints->list[i] ==
507 params_rate(params)); 501 params_rate(params))
508 return -EINVAL; 502 break;
503
504 if (i == es8328->sysclk_constraints->count) {
505 dev_err(codec->dev,
506 "LRCLK %d unsupported with current clock\n",
507 params_rate(params));
508 return -EINVAL;
509 }
510 ratio = es8328->mclk_ratios[i];
511 } else {
512 ratio = 0;
513 es8328->mclkdiv2 = 0;
509 } 514 }
510 515
511 ratio = es8328->mclk_ratios[i];
512 snd_soc_update_bits(codec, ES8328_MASTERMODE, 516 snd_soc_update_bits(codec, ES8328_MASTERMODE,
513 ES8328_MASTERMODE_MCLKDIV2, 517 ES8328_MASTERMODE_MCLKDIV2,
514 es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0); 518 es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);
@@ -586,6 +590,7 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
586 unsigned int fmt) 590 unsigned int fmt)
587{ 591{
588 struct snd_soc_codec *codec = codec_dai->codec; 592 struct snd_soc_codec *codec = codec_dai->codec;
593 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
589 u8 dac_mode = 0; 594 u8 dac_mode = 0;
590 u8 adc_mode = 0; 595 u8 adc_mode = 0;
591 596
@@ -595,11 +600,13 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
595 snd_soc_update_bits(codec, ES8328_MASTERMODE, 600 snd_soc_update_bits(codec, ES8328_MASTERMODE,
596 ES8328_MASTERMODE_MSC, 601 ES8328_MASTERMODE_MSC,
597 ES8328_MASTERMODE_MSC); 602 ES8328_MASTERMODE_MSC);
603 es8328->master = true;
598 break; 604 break;
599 case SND_SOC_DAIFMT_CBS_CFS: 605 case SND_SOC_DAIFMT_CBS_CFS:
600 /* Slave serial port mode */ 606 /* Slave serial port mode */
601 snd_soc_update_bits(codec, ES8328_MASTERMODE, 607 snd_soc_update_bits(codec, ES8328_MASTERMODE,
602 ES8328_MASTERMODE_MSC, 0); 608 ES8328_MASTERMODE_MSC, 0);
609 es8328->master = false;
603 break; 610 break;
604 default: 611 default:
605 return -EINVAL; 612 return -EINVAL;
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index fd272a40485b..bc2e74ff3b2d 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -469,7 +469,7 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
469 469
470 format = snd_hdac_calc_stream_format(params_rate(hparams), 470 format = snd_hdac_calc_stream_format(params_rate(hparams),
471 params_channels(hparams), params_format(hparams), 471 params_channels(hparams), params_format(hparams),
472 24, 0); 472 dai->driver->playback.sig_bits, 0);
473 473
474 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt); 474 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
475 if (!pcm) 475 if (!pcm)
@@ -1419,8 +1419,8 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
1419 hdmi_dais[i].playback.rate_min = rate_min; 1419 hdmi_dais[i].playback.rate_min = rate_min;
1420 hdmi_dais[i].playback.channels_min = 2; 1420 hdmi_dais[i].playback.channels_min = 2;
1421 hdmi_dais[i].playback.channels_max = 2; 1421 hdmi_dais[i].playback.channels_max = 2;
1422 hdmi_dais[i].playback.sig_bits = bps;
1422 hdmi_dais[i].ops = &hdmi_dai_ops; 1423 hdmi_dais[i].ops = &hdmi_dai_ops;
1423
1424 i++; 1424 i++;
1425 } 1425 }
1426 1426
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 6cdf15ab46de..0247edc9c84e 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -516,13 +516,13 @@ static const struct i2c_device_id max9867_i2c_id[] = {
516 { "max9867", 0 }, 516 { "max9867", 0 },
517 { } 517 { }
518}; 518};
519MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
519 520
520static const struct of_device_id max9867_of_match[] = { 521static const struct of_device_id max9867_of_match[] = {
521 { .compatible = "maxim,max9867", }, 522 { .compatible = "maxim,max9867", },
522 { } 523 { }
523}; 524};
524 525MODULE_DEVICE_TABLE(of, max9867_of_match);
525MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
526 526
527static const struct dev_pm_ops max9867_pm_ops = { 527static const struct dev_pm_ops max9867_pm_ops = {
528 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume) 528 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume)
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
new file mode 100644
index 000000000000..b5ee29499e16
--- /dev/null
+++ b/sound/soc/codecs/max98927.c
@@ -0,0 +1,841 @@
1/*
2 * max98927.c -- MAX98927 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2016 Maxim Integrated Products
5 * Author: Ryan Lee <ryans.lee@maximintegrated.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/acpi.h>
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/cdev.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <linux/gpio.h>
23#include <linux/of_gpio.h>
24#include <sound/tlv.h>
25#include "max98927.h"
26
27static struct reg_default max98927_reg[] = {
28 {MAX98927_R0001_INT_RAW1, 0x00},
29 {MAX98927_R0002_INT_RAW2, 0x00},
30 {MAX98927_R0003_INT_RAW3, 0x00},
31 {MAX98927_R0004_INT_STATE1, 0x00},
32 {MAX98927_R0005_INT_STATE2, 0x00},
33 {MAX98927_R0006_INT_STATE3, 0x00},
34 {MAX98927_R0007_INT_FLAG1, 0x00},
35 {MAX98927_R0008_INT_FLAG2, 0x00},
36 {MAX98927_R0009_INT_FLAG3, 0x00},
37 {MAX98927_R000A_INT_EN1, 0x00},
38 {MAX98927_R000B_INT_EN2, 0x00},
39 {MAX98927_R000C_INT_EN3, 0x00},
40 {MAX98927_R000D_INT_FLAG_CLR1, 0x00},
41 {MAX98927_R000E_INT_FLAG_CLR2, 0x00},
42 {MAX98927_R000F_INT_FLAG_CLR3, 0x00},
43 {MAX98927_R0010_IRQ_CTRL, 0x00},
44 {MAX98927_R0011_CLK_MON, 0x00},
45 {MAX98927_R0012_WDOG_CTRL, 0x00},
46 {MAX98927_R0013_WDOG_RST, 0x00},
47 {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00},
48 {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00},
49 {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00},
50 {MAX98927_R0017_PIN_CFG, 0x55},
51 {MAX98927_R0018_PCM_RX_EN_A, 0x00},
52 {MAX98927_R0019_PCM_RX_EN_B, 0x00},
53 {MAX98927_R001A_PCM_TX_EN_A, 0x00},
54 {MAX98927_R001B_PCM_TX_EN_B, 0x00},
55 {MAX98927_R001C_PCM_TX_HIZ_CTRL_A, 0x00},
56 {MAX98927_R001D_PCM_TX_HIZ_CTRL_B, 0x00},
57 {MAX98927_R001E_PCM_TX_CH_SRC_A, 0x00},
58 {MAX98927_R001F_PCM_TX_CH_SRC_B, 0x00},
59 {MAX98927_R0020_PCM_MODE_CFG, 0x40},
60 {MAX98927_R0021_PCM_MASTER_MODE, 0x00},
61 {MAX98927_R0022_PCM_CLK_SETUP, 0x22},
62 {MAX98927_R0023_PCM_SR_SETUP1, 0x00},
63 {MAX98927_R0024_PCM_SR_SETUP2, 0x00},
64 {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A, 0x00},
65 {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B, 0x00},
66 {MAX98927_R0027_ICC_RX_EN_A, 0x00},
67 {MAX98927_R0028_ICC_RX_EN_B, 0x00},
68 {MAX98927_R002B_ICC_TX_EN_A, 0x00},
69 {MAX98927_R002C_ICC_TX_EN_B, 0x00},
70 {MAX98927_R002E_ICC_HIZ_MANUAL_MODE, 0x00},
71 {MAX98927_R002F_ICC_TX_HIZ_EN_A, 0x00},
72 {MAX98927_R0030_ICC_TX_HIZ_EN_B, 0x00},
73 {MAX98927_R0031_ICC_LNK_EN, 0x00},
74 {MAX98927_R0032_PDM_TX_EN, 0x00},
75 {MAX98927_R0033_PDM_TX_HIZ_CTRL, 0x00},
76 {MAX98927_R0034_PDM_TX_CTRL, 0x00},
77 {MAX98927_R0035_PDM_RX_CTRL, 0x00},
78 {MAX98927_R0036_AMP_VOL_CTRL, 0x00},
79 {MAX98927_R0037_AMP_DSP_CFG, 0x02},
80 {MAX98927_R0038_TONE_GEN_DC_CFG, 0x00},
81 {MAX98927_R0039_DRE_CTRL, 0x01},
82 {MAX98927_R003A_AMP_EN, 0x00},
83 {MAX98927_R003B_SPK_SRC_SEL, 0x00},
84 {MAX98927_R003C_SPK_GAIN, 0x00},
85 {MAX98927_R003D_SSM_CFG, 0x01},
86 {MAX98927_R003E_MEAS_EN, 0x00},
87 {MAX98927_R003F_MEAS_DSP_CFG, 0x04},
88 {MAX98927_R0040_BOOST_CTRL0, 0x00},
89 {MAX98927_R0041_BOOST_CTRL3, 0x00},
90 {MAX98927_R0042_BOOST_CTRL1, 0x00},
91 {MAX98927_R0043_MEAS_ADC_CFG, 0x00},
92 {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00},
93 {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00},
94 {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00},
95 {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00},
96 {MAX98927_R0048_ADC_CH2_DIVIDE, 0x00},
97 {MAX98927_R0049_ADC_CH0_FILT_CFG, 0x00},
98 {MAX98927_R004A_ADC_CH1_FILT_CFG, 0x00},
99 {MAX98927_R004B_ADC_CH2_FILT_CFG, 0x00},
100 {MAX98927_R004C_MEAS_ADC_CH0_READ, 0x00},
101 {MAX98927_R004D_MEAS_ADC_CH1_READ, 0x00},
102 {MAX98927_R004E_MEAS_ADC_CH2_READ, 0x00},
103 {MAX98927_R0051_BROWNOUT_STATUS, 0x00},
104 {MAX98927_R0052_BROWNOUT_EN, 0x00},
105 {MAX98927_R0053_BROWNOUT_INFINITE_HOLD, 0x00},
106 {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR, 0x00},
107 {MAX98927_R0055_BROWNOUT_LVL_HOLD, 0x00},
108 {MAX98927_R005A_BROWNOUT_LVL1_THRESH, 0x00},
109 {MAX98927_R005B_BROWNOUT_LVL2_THRESH, 0x00},
110 {MAX98927_R005C_BROWNOUT_LVL3_THRESH, 0x00},
111 {MAX98927_R005D_BROWNOUT_LVL4_THRESH, 0x00},
112 {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS, 0x00},
113 {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL, 0x00},
114 {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL, 0x00},
115 {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE, 0x00},
116 {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT, 0x00},
117 {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1, 0x00},
118 {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2, 0x00},
119 {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3, 0x00},
120 {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT, 0x00},
121 {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1, 0x00},
122 {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2, 0x00},
123 {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3, 0x00},
124 {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT, 0x00},
125 {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1, 0x00},
126 {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2, 0x00},
127 {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3, 0x00},
128 {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT, 0x00},
129 {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1, 0x00},
130 {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2, 0x00},
131 {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3, 0x00},
132 {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0x00},
133 {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY, 0x00},
134 {MAX98927_R0084_ENV_TRACK_REL_RATE, 0x00},
135 {MAX98927_R0085_ENV_TRACK_HOLD_RATE, 0x00},
136 {MAX98927_R0086_ENV_TRACK_CTRL, 0x00},
137 {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ, 0x00},
138 {MAX98927_R00FF_GLOBAL_SHDN, 0x00},
139 {MAX98927_R0100_SOFT_RESET, 0x00},
140 {MAX98927_R01FF_REV_ID, 0x40},
141};
142
143static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
144{
145 struct snd_soc_codec *codec = codec_dai->codec;
146 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
147 unsigned int mode = 0;
148 unsigned int format = 0;
149 unsigned int invert = 0;
150
151 dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
152
153 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
154 case SND_SOC_DAIFMT_CBS_CFS:
155 mode = MAX98927_PCM_MASTER_MODE_SLAVE;
156 break;
157 case SND_SOC_DAIFMT_CBM_CFM:
158 max98927->master = true;
159 mode = MAX98927_PCM_MASTER_MODE_MASTER;
160 break;
161 default:
162 dev_err(codec->dev, "DAI clock mode unsupported");
163 return -EINVAL;
164 }
165
166 regmap_update_bits(max98927->regmap,
167 MAX98927_R0021_PCM_MASTER_MODE,
168 MAX98927_PCM_MASTER_MODE_MASK,
169 mode);
170
171 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
172 case SND_SOC_DAIFMT_NB_NF:
173 break;
174 case SND_SOC_DAIFMT_IB_NF:
175 invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
176 break;
177 default:
178 dev_err(codec->dev, "DAI invert mode unsupported");
179 return -EINVAL;
180 }
181
182 regmap_update_bits(max98927->regmap,
183 MAX98927_R0020_PCM_MODE_CFG,
184 MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
185 invert);
186
187 /* interface format */
188 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
189 case SND_SOC_DAIFMT_I2S:
190 max98927->iface |= SND_SOC_DAIFMT_I2S;
191 format = MAX98927_PCM_FORMAT_I2S;
192 break;
193 case SND_SOC_DAIFMT_LEFT_J:
194 max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
195 format = MAX98927_PCM_FORMAT_LJ;
196 break;
197 case SND_SOC_DAIFMT_PDM:
198 max98927->iface |= SND_SOC_DAIFMT_PDM;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 /* pcm channel configuration */
205 if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
206 regmap_update_bits(max98927->regmap,
207 MAX98927_R0018_PCM_RX_EN_A,
208 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
209 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
210
211 regmap_update_bits(max98927->regmap,
212 MAX98927_R0020_PCM_MODE_CFG,
213 MAX98927_PCM_MODE_CFG_FORMAT_MASK,
214 format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
215
216 regmap_update_bits(max98927->regmap,
217 MAX98927_R003B_SPK_SRC_SEL,
218 MAX98927_SPK_SRC_MASK, 0);
219
220 } else
221 regmap_update_bits(max98927->regmap,
222 MAX98927_R0018_PCM_RX_EN_A,
223 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
224
225 /* pdm channel configuration */
226 if (max98927->iface & SND_SOC_DAIFMT_PDM) {
227 regmap_update_bits(max98927->regmap,
228 MAX98927_R0035_PDM_RX_CTRL,
229 MAX98927_PDM_RX_EN_MASK, 1);
230
231 regmap_update_bits(max98927->regmap,
232 MAX98927_R003B_SPK_SRC_SEL,
233 MAX98927_SPK_SRC_MASK, 3);
234 } else
235 regmap_update_bits(max98927->regmap,
236 MAX98927_R0035_PDM_RX_CTRL,
237 MAX98927_PDM_RX_EN_MASK, 0);
238 return 0;
239}
240
241/* codec MCLK rate in master mode */
242static const int rate_table[] = {
243 5644800, 6000000, 6144000, 6500000,
244 9600000, 11289600, 12000000, 12288000,
245 13000000, 19200000,
246};
247
248static int max98927_set_clock(struct max98927_priv *max98927,
249 struct snd_pcm_hw_params *params)
250{
251 struct snd_soc_codec *codec = max98927->codec;
252 /* BCLK/LRCLK ratio calculation */
253 int blr_clk_ratio = params_channels(params) * max98927->ch_size;
254 int value;
255
256 if (max98927->master) {
257 int i;
258 /* match rate to closest value */
259 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
260 if (rate_table[i] >= max98927->sysclk)
261 break;
262 }
263 if (i == ARRAY_SIZE(rate_table)) {
264 dev_err(codec->dev, "failed to find proper clock rate.\n");
265 return -EINVAL;
266 }
267 regmap_update_bits(max98927->regmap,
268 MAX98927_R0021_PCM_MASTER_MODE,
269 MAX98927_PCM_MASTER_MODE_MCLK_MASK,
270 i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
271 }
272
273 switch (blr_clk_ratio) {
274 case 32:
275 value = 2;
276 break;
277 case 48:
278 value = 3;
279 break;
280 case 64:
281 value = 4;
282 break;
283 default:
284 return -EINVAL;
285 }
286 regmap_update_bits(max98927->regmap,
287 MAX98927_R0022_PCM_CLK_SETUP,
288 MAX98927_PCM_CLK_SETUP_BSEL_MASK,
289 value);
290 return 0;
291}
292
293static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
294 struct snd_pcm_hw_params *params,
295 struct snd_soc_dai *dai)
296{
297 struct snd_soc_codec *codec = dai->codec;
298 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
299 unsigned int sampling_rate = 0;
300 unsigned int chan_sz = 0;
301
302 /* pcm mode configuration */
303 switch (snd_pcm_format_width(params_format(params))) {
304 case 16:
305 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
306 break;
307 case 24:
308 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
309 break;
310 case 32:
311 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
312 break;
313 default:
314 dev_err(codec->dev, "format unsupported %d",
315 params_format(params));
316 goto err;
317 }
318
319 max98927->ch_size = snd_pcm_format_width(params_format(params));
320
321 regmap_update_bits(max98927->regmap,
322 MAX98927_R0020_PCM_MODE_CFG,
323 MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
324
325 dev_dbg(codec->dev, "format supported %d",
326 params_format(params));
327
328 /* sampling rate configuration */
329 switch (params_rate(params)) {
330 case 8000:
331 sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
332 break;
333 case 11025:
334 sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
335 break;
336 case 12000:
337 sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
338 break;
339 case 16000:
340 sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
341 break;
342 case 22050:
343 sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
344 break;
345 case 24000:
346 sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
347 break;
348 case 32000:
349 sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
350 break;
351 case 44100:
352 sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
353 break;
354 case 48000:
355 sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
356 break;
357 default:
358 dev_err(codec->dev, "rate %d not supported\n",
359 params_rate(params));
360 goto err;
361 }
362 /* set DAI_SR to correct LRCLK frequency */
363 regmap_update_bits(max98927->regmap,
364 MAX98927_R0023_PCM_SR_SETUP1,
365 MAX98927_PCM_SR_SET1_SR_MASK,
366 sampling_rate);
367 regmap_update_bits(max98927->regmap,
368 MAX98927_R0024_PCM_SR_SETUP2,
369 MAX98927_PCM_SR_SET2_SR_MASK,
370 sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
371
372 /* set sampling rate of IV */
373 if (max98927->interleave_mode &&
374 sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
375 regmap_update_bits(max98927->regmap,
376 MAX98927_R0024_PCM_SR_SETUP2,
377 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
378 sampling_rate - 3);
379 else
380 regmap_update_bits(max98927->regmap,
381 MAX98927_R0024_PCM_SR_SETUP2,
382 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
383 sampling_rate);
384 return max98927_set_clock(max98927, params);
385err:
386 return -EINVAL;
387}
388
389#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
390
391#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
392 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
393
394static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
395 int clk_id, unsigned int freq, int dir)
396{
397 struct snd_soc_codec *codec = dai->codec;
398 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
399
400 max98927->sysclk = freq;
401 return 0;
402}
403
404static const struct snd_soc_dai_ops max98927_dai_ops = {
405 .set_sysclk = max98927_dai_set_sysclk,
406 .set_fmt = max98927_dai_set_fmt,
407 .hw_params = max98927_dai_hw_params,
408};
409
410static int max98927_dac_event(struct snd_soc_dapm_widget *w,
411 struct snd_kcontrol *kcontrol, int event)
412{
413 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
414 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
415
416 switch (event) {
417 case SND_SOC_DAPM_POST_PMU:
418 regmap_update_bits(max98927->regmap,
419 MAX98927_R003A_AMP_EN,
420 MAX98927_AMP_EN_MASK, 1);
421 /* enable VMON and IMON */
422 regmap_update_bits(max98927->regmap,
423 MAX98927_R003E_MEAS_EN,
424 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
425 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
426 regmap_update_bits(max98927->regmap,
427 MAX98927_R00FF_GLOBAL_SHDN,
428 MAX98927_GLOBAL_EN_MASK, 1);
429 break;
430 case SND_SOC_DAPM_POST_PMD:
431 regmap_update_bits(max98927->regmap,
432 MAX98927_R00FF_GLOBAL_SHDN,
433 MAX98927_GLOBAL_EN_MASK, 0);
434 regmap_update_bits(max98927->regmap,
435 MAX98927_R003A_AMP_EN,
436 MAX98927_AMP_EN_MASK, 0);
437 /* disable VMON and IMON */
438 regmap_update_bits(max98927->regmap,
439 MAX98927_R003E_MEAS_EN,
440 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
441 break;
442 default:
443 return 0;
444 }
445 return 0;
446}
447
448static const char * const max98927_switch_text[] = {
449 "Left", "Right", "LeftRight"};
450
451static const struct soc_enum dai_sel_enum =
452 SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
453 MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
454 3, max98927_switch_text);
455
456static const struct snd_kcontrol_new max98927_dai_controls =
457 SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
458
459static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
460 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
461 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
462 0, 0, max98927_dac_event,
463 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
464 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
465 &max98927_dai_controls),
466 SND_SOC_DAPM_OUTPUT("BE_OUT"),
467};
468
469static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
470static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
471
472static bool max98927_readable_register(struct device *dev, unsigned int reg)
473{
474 switch (reg) {
475 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
476 case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
477 case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
478 ... MAX98927_R004E_MEAS_ADC_CH2_READ:
479 case MAX98927_R0051_BROWNOUT_STATUS
480 ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
481 case MAX98927_R005A_BROWNOUT_LVL1_THRESH
482 ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
483 case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
484 ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
485 case MAX98927_R00FF_GLOBAL_SHDN:
486 case MAX98927_R0100_SOFT_RESET:
487 case MAX98927_R01FF_REV_ID:
488 return true;
489 default:
490 return false;
491 }
492};
493
494static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
495{
496 switch (reg) {
497 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
498 return true;
499 default:
500 return false;
501 }
502}
503
504static const char * const max98927_boost_voltage_text[] = {
505 "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
506 "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
507 "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
508 "9.5V", "9.625V", "9.75V", "9.875V", "10V"
509};
510
511static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
512 MAX98927_R0040_BOOST_CTRL0, 0,
513 max98927_boost_voltage_text);
514
515static const char * const max98927_current_limit_text[] = {
516 "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
517 "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
518 "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
519 "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
520};
521
522static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
523 MAX98927_R0042_BOOST_CTRL1, 1,
524 max98927_current_limit_text);
525
526static const struct snd_kcontrol_new max98927_snd_controls[] = {
527 SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
528 0, 6, 0,
529 max98927_spk_tlv),
530 SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
531 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
532 max98927_digital_tlv),
533 SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
534 MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
535 SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
536 MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
537 SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
538 MAX98927_DRE_EN_SHIFT, 1, 0),
539 SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
540 MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
541 SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
542 SOC_ENUM("Current Limit", max98927_current_limit),
543};
544
545static const struct snd_soc_dapm_route max98927_audio_map[] = {
546 {"Amp Enable", NULL, "DAI_OUT"},
547 {"DAI Sel Mux", "Left", "Amp Enable"},
548 {"DAI Sel Mux", "Right", "Amp Enable"},
549 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
550 {"BE_OUT", NULL, "DAI Sel Mux"},
551};
552
553static struct snd_soc_dai_driver max98927_dai[] = {
554 {
555 .name = "max98927-aif1",
556 .playback = {
557 .stream_name = "HiFi Playback",
558 .channels_min = 1,
559 .channels_max = 2,
560 .rates = MAX98927_RATES,
561 .formats = MAX98927_FORMATS,
562 },
563 .capture = {
564 .stream_name = "HiFi Capture",
565 .channels_min = 1,
566 .channels_max = 2,
567 .rates = MAX98927_RATES,
568 .formats = MAX98927_FORMATS,
569 },
570 .ops = &max98927_dai_ops,
571 }
572};
573
574static int max98927_probe(struct snd_soc_codec *codec)
575{
576 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
577
578 max98927->codec = codec;
579 codec->control_data = max98927->regmap;
580 codec->cache_bypass = 1;
581
582 /* Software Reset */
583 regmap_write(max98927->regmap,
584 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
585
586 /* IV default slot configuration */
587 regmap_write(max98927->regmap,
588 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
589 0xFF);
590 regmap_write(max98927->regmap,
591 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
592 0xFF);
593 regmap_write(max98927->regmap,
594 MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
595 0x80);
596 regmap_write(max98927->regmap,
597 MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
598 0x1);
599 /* Set inital volume (+13dB) */
600 regmap_write(max98927->regmap,
601 MAX98927_R0036_AMP_VOL_CTRL,
602 0x38);
603 regmap_write(max98927->regmap,
604 MAX98927_R003C_SPK_GAIN,
605 0x05);
606 /* Enable DC blocker */
607 regmap_write(max98927->regmap,
608 MAX98927_R0037_AMP_DSP_CFG,
609 0x03);
610 /* Enable IMON VMON DC blocker */
611 regmap_write(max98927->regmap,
612 MAX98927_R003F_MEAS_DSP_CFG,
613 0xF7);
614 /* Boost Output Voltage & Current limit */
615 regmap_write(max98927->regmap,
616 MAX98927_R0040_BOOST_CTRL0,
617 0x1C);
618 regmap_write(max98927->regmap,
619 MAX98927_R0042_BOOST_CTRL1,
620 0x3E);
621 /* Measurement ADC config */
622 regmap_write(max98927->regmap,
623 MAX98927_R0043_MEAS_ADC_CFG,
624 0x04);
625 regmap_write(max98927->regmap,
626 MAX98927_R0044_MEAS_ADC_BASE_MSB,
627 0x00);
628 regmap_write(max98927->regmap,
629 MAX98927_R0045_MEAS_ADC_BASE_LSB,
630 0x24);
631 /* Brownout Level */
632 regmap_write(max98927->regmap,
633 MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
634 0x06);
635 /* Envelope Tracking configuration */
636 regmap_write(max98927->regmap,
637 MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
638 0x08);
639 regmap_write(max98927->regmap,
640 MAX98927_R0086_ENV_TRACK_CTRL,
641 0x01);
642 regmap_write(max98927->regmap,
643 MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
644 0x10);
645
646 /* voltage, current slot configuration */
647 regmap_write(max98927->regmap,
648 MAX98927_R001E_PCM_TX_CH_SRC_A,
649 (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
650 max98927->v_l_slot)&0xFF);
651
652 if (max98927->v_l_slot < 8) {
653 regmap_update_bits(max98927->regmap,
654 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
655 1 << max98927->v_l_slot, 0);
656 regmap_update_bits(max98927->regmap,
657 MAX98927_R001A_PCM_TX_EN_A,
658 1 << max98927->v_l_slot,
659 1 << max98927->v_l_slot);
660 } else {
661 regmap_update_bits(max98927->regmap,
662 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
663 1 << (max98927->v_l_slot - 8), 0);
664 regmap_update_bits(max98927->regmap,
665 MAX98927_R001B_PCM_TX_EN_B,
666 1 << (max98927->v_l_slot - 8),
667 1 << (max98927->v_l_slot - 8));
668 }
669
670 if (max98927->i_l_slot < 8) {
671 regmap_update_bits(max98927->regmap,
672 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
673 1 << max98927->i_l_slot, 0);
674 regmap_update_bits(max98927->regmap,
675 MAX98927_R001A_PCM_TX_EN_A,
676 1 << max98927->i_l_slot,
677 1 << max98927->i_l_slot);
678 } else {
679 regmap_update_bits(max98927->regmap,
680 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
681 1 << (max98927->i_l_slot - 8), 0);
682 regmap_update_bits(max98927->regmap,
683 MAX98927_R001B_PCM_TX_EN_B,
684 1 << (max98927->i_l_slot - 8),
685 1 << (max98927->i_l_slot - 8));
686 }
687
688 /* Set interleave mode */
689 if (max98927->interleave_mode)
690 regmap_update_bits(max98927->regmap,
691 MAX98927_R001F_PCM_TX_CH_SRC_B,
692 MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
693 MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
694 return 0;
695}
696
697static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
698 .probe = max98927_probe,
699 .component_driver = {
700 .controls = max98927_snd_controls,
701 .num_controls = ARRAY_SIZE(max98927_snd_controls),
702 .dapm_widgets = max98927_dapm_widgets,
703 .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
704 .dapm_routes = max98927_audio_map,
705 .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
706 },
707};
708
709static const struct regmap_config max98927_regmap = {
710 .reg_bits = 16,
711 .val_bits = 8,
712 .max_register = MAX98927_R01FF_REV_ID,
713 .reg_defaults = max98927_reg,
714 .num_reg_defaults = ARRAY_SIZE(max98927_reg),
715 .readable_reg = max98927_readable_register,
716 .volatile_reg = max98927_volatile_reg,
717 .cache_type = REGCACHE_RBTREE,
718};
719
720static void max98927_slot_config(struct i2c_client *i2c,
721 struct max98927_priv *max98927)
722{
723 int value;
724
725 if (!of_property_read_u32(i2c->dev.of_node,
726 "vmon-slot-no", &value))
727 max98927->v_l_slot = value & 0xF;
728 else
729 max98927->v_l_slot = 0;
730 if (!of_property_read_u32(i2c->dev.of_node,
731 "imon-slot-no", &value))
732 max98927->i_l_slot = value & 0xF;
733 else
734 max98927->i_l_slot = 1;
735}
736
737static int max98927_i2c_probe(struct i2c_client *i2c,
738 const struct i2c_device_id *id)
739{
740
741 int ret = 0, value;
742 int reg = 0;
743 struct max98927_priv *max98927 = NULL;
744
745 max98927 = devm_kzalloc(&i2c->dev,
746 sizeof(*max98927), GFP_KERNEL);
747
748 if (!max98927) {
749 ret = -ENOMEM;
750 return ret;
751 }
752 i2c_set_clientdata(i2c, max98927);
753
754 /* update interleave mode info */
755 if (!of_property_read_u32(i2c->dev.of_node,
756 "interleave_mode", &value)) {
757 if (value > 0)
758 max98927->interleave_mode = 1;
759 else
760 max98927->interleave_mode = 0;
761 } else
762 max98927->interleave_mode = 0;
763
764 /* regmap initialization */
765 max98927->regmap
766 = devm_regmap_init_i2c(i2c, &max98927_regmap);
767 if (IS_ERR(max98927->regmap)) {
768 ret = PTR_ERR(max98927->regmap);
769 dev_err(&i2c->dev,
770 "Failed to allocate regmap: %d\n", ret);
771 return ret;
772 }
773
774 /* Check Revision ID */
775 ret = regmap_read(max98927->regmap,
776 MAX98927_R01FF_REV_ID, &reg);
777 if (ret < 0) {
778 dev_err(&i2c->dev,
779 "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
780 return ret;
781 }
782 dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
783
784 /* voltage/current slot configuration */
785 max98927_slot_config(i2c, max98927);
786
787 /* codec registeration */
788 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
789 max98927_dai, ARRAY_SIZE(max98927_dai));
790 if (ret < 0)
791 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
792
793 return ret;
794}
795
796static int max98927_i2c_remove(struct i2c_client *client)
797{
798 snd_soc_unregister_codec(&client->dev);
799 return 0;
800}
801
802static const struct i2c_device_id max98927_i2c_id[] = {
803 { "max98927", 0},
804 { },
805};
806
807MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
808
809#if defined(CONFIG_OF)
810static const struct of_device_id max98927_of_match[] = {
811 { .compatible = "maxim,max98927", },
812 { }
813};
814MODULE_DEVICE_TABLE(of, max98927_of_match);
815#endif
816
817#ifdef CONFIG_ACPI
818static const struct acpi_device_id max98927_acpi_match[] = {
819 { "MX98927", 0 },
820 {},
821};
822MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
823#endif
824
825static struct i2c_driver max98927_i2c_driver = {
826 .driver = {
827 .name = "max98927",
828 .of_match_table = of_match_ptr(max98927_of_match),
829 .acpi_match_table = ACPI_PTR(max98927_acpi_match),
830 .pm = NULL,
831 },
832 .probe = max98927_i2c_probe,
833 .remove = max98927_i2c_remove,
834 .id_table = max98927_i2c_id,
835};
836
837module_i2c_driver(max98927_i2c_driver)
838
839MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
840MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
841MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
new file mode 100644
index 000000000000..ece6a608cbe1
--- /dev/null
+++ b/sound/soc/codecs/max98927.h
@@ -0,0 +1,272 @@
1/*
2 * max98927.h -- MAX98927 ALSA Soc Audio driver
3 *
4 * Copyright 2013-15 Maxim Integrated Products
5 * Author: Ryan Lee <ryans.lee@maximintegrated.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifndef _MAX98927_H
14#define _MAX98927_H
15
16/* Register Values */
17#define MAX98927_R0001_INT_RAW1 0x0001
18#define MAX98927_R0002_INT_RAW2 0x0002
19#define MAX98927_R0003_INT_RAW3 0x0003
20#define MAX98927_R0004_INT_STATE1 0x0004
21#define MAX98927_R0005_INT_STATE2 0x0005
22#define MAX98927_R0006_INT_STATE3 0x0006
23#define MAX98927_R0007_INT_FLAG1 0x0007
24#define MAX98927_R0008_INT_FLAG2 0x0008
25#define MAX98927_R0009_INT_FLAG3 0x0009
26#define MAX98927_R000A_INT_EN1 0x000A
27#define MAX98927_R000B_INT_EN2 0x000B
28#define MAX98927_R000C_INT_EN3 0x000C
29#define MAX98927_R000D_INT_FLAG_CLR1 0x000D
30#define MAX98927_R000E_INT_FLAG_CLR2 0x000E
31#define MAX98927_R000F_INT_FLAG_CLR3 0x000F
32#define MAX98927_R0010_IRQ_CTRL 0x0010
33#define MAX98927_R0011_CLK_MON 0x0011
34#define MAX98927_R0012_WDOG_CTRL 0x0012
35#define MAX98927_R0013_WDOG_RST 0x0013
36#define MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH 0x0014
37#define MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH 0x0015
38#define MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS 0x0016
39#define MAX98927_R0017_PIN_CFG 0x0017
40#define MAX98927_R0018_PCM_RX_EN_A 0x0018
41#define MAX98927_R0019_PCM_RX_EN_B 0x0019
42#define MAX98927_R001A_PCM_TX_EN_A 0x001A
43#define MAX98927_R001B_PCM_TX_EN_B 0x001B
44#define MAX98927_R001C_PCM_TX_HIZ_CTRL_A 0x001C
45#define MAX98927_R001D_PCM_TX_HIZ_CTRL_B 0x001D
46#define MAX98927_R001E_PCM_TX_CH_SRC_A 0x001E
47#define MAX98927_R001F_PCM_TX_CH_SRC_B 0x001F
48#define MAX98927_R0020_PCM_MODE_CFG 0x0020
49#define MAX98927_R0021_PCM_MASTER_MODE 0x0021
50#define MAX98927_R0022_PCM_CLK_SETUP 0x0022
51#define MAX98927_R0023_PCM_SR_SETUP1 0x0023
52#define MAX98927_R0024_PCM_SR_SETUP2 0x0024
53#define MAX98927_R0025_PCM_TO_SPK_MONOMIX_A 0x0025
54#define MAX98927_R0026_PCM_TO_SPK_MONOMIX_B 0x0026
55#define MAX98927_R0027_ICC_RX_EN_A 0x0027
56#define MAX98927_R0028_ICC_RX_EN_B 0x0028
57#define MAX98927_R002B_ICC_TX_EN_A 0x002B
58#define MAX98927_R002C_ICC_TX_EN_B 0x002C
59#define MAX98927_R002E_ICC_HIZ_MANUAL_MODE 0x002E
60#define MAX98927_R002F_ICC_TX_HIZ_EN_A 0x002F
61#define MAX98927_R0030_ICC_TX_HIZ_EN_B 0x0030
62#define MAX98927_R0031_ICC_LNK_EN 0x0031
63#define MAX98927_R0032_PDM_TX_EN 0x0032
64#define MAX98927_R0033_PDM_TX_HIZ_CTRL 0x0033
65#define MAX98927_R0034_PDM_TX_CTRL 0x0034
66#define MAX98927_R0035_PDM_RX_CTRL 0x0035
67#define MAX98927_R0036_AMP_VOL_CTRL 0x0036
68#define MAX98927_R0037_AMP_DSP_CFG 0x0037
69#define MAX98927_R0038_TONE_GEN_DC_CFG 0x0038
70#define MAX98927_R0039_DRE_CTRL 0x0039
71#define MAX98927_R003A_AMP_EN 0x003A
72#define MAX98927_R003B_SPK_SRC_SEL 0x003B
73#define MAX98927_R003C_SPK_GAIN 0x003C
74#define MAX98927_R003D_SSM_CFG 0x003D
75#define MAX98927_R003E_MEAS_EN 0x003E
76#define MAX98927_R003F_MEAS_DSP_CFG 0x003F
77#define MAX98927_R0040_BOOST_CTRL0 0x0040
78#define MAX98927_R0041_BOOST_CTRL3 0x0041
79#define MAX98927_R0042_BOOST_CTRL1 0x0042
80#define MAX98927_R0043_MEAS_ADC_CFG 0x0043
81#define MAX98927_R0044_MEAS_ADC_BASE_MSB 0x0044
82#define MAX98927_R0045_MEAS_ADC_BASE_LSB 0x0045
83#define MAX98927_R0046_ADC_CH0_DIVIDE 0x0046
84#define MAX98927_R0047_ADC_CH1_DIVIDE 0x0047
85#define MAX98927_R0048_ADC_CH2_DIVIDE 0x0048
86#define MAX98927_R0049_ADC_CH0_FILT_CFG 0x0049
87#define MAX98927_R004A_ADC_CH1_FILT_CFG 0x004A
88#define MAX98927_R004B_ADC_CH2_FILT_CFG 0x004B
89#define MAX98927_R004C_MEAS_ADC_CH0_READ 0x004C
90#define MAX98927_R004D_MEAS_ADC_CH1_READ 0x004D
91#define MAX98927_R004E_MEAS_ADC_CH2_READ 0x004E
92#define MAX98927_R0051_BROWNOUT_STATUS 0x0051
93#define MAX98927_R0052_BROWNOUT_EN 0x0052
94#define MAX98927_R0053_BROWNOUT_INFINITE_HOLD 0x0053
95#define MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR 0x0054
96#define MAX98927_R0055_BROWNOUT_LVL_HOLD 0x0055
97#define MAX98927_R005A_BROWNOUT_LVL1_THRESH 0x005A
98#define MAX98927_R005B_BROWNOUT_LVL2_THRESH 0x005B
99#define MAX98927_R005C_BROWNOUT_LVL3_THRESH 0x005C
100#define MAX98927_R005D_BROWNOUT_LVL4_THRESH 0x005D
101#define MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS 0x005E
102#define MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL 0x005F
103#define MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL 0x0060
104#define MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE 0x0061
105#define MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT 0x0072
106#define MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1 0x0073
107#define MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2 0x0074
108#define MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3 0x0075
109#define MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT 0x0076
110#define MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1 0x0077
111#define MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2 0x0078
112#define MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3 0x0079
113#define MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT 0x007A
114#define MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1 0x007B
115#define MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2 0x007C
116#define MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3 0x007D
117#define MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT 0x007E
118#define MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1 0x007F
119#define MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2 0x0080
120#define MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3 0x0081
121#define MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM 0x0082
122#define MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY 0x0083
123#define MAX98927_R0084_ENV_TRACK_REL_RATE 0x0084
124#define MAX98927_R0085_ENV_TRACK_HOLD_RATE 0x0085
125#define MAX98927_R0086_ENV_TRACK_CTRL 0x0086
126#define MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ 0x0087
127#define MAX98927_R00FF_GLOBAL_SHDN 0x00FF
128#define MAX98927_R0100_SOFT_RESET 0x0100
129#define MAX98927_R01FF_REV_ID 0x01FF
130
131/* MAX98927_R0018_PCM_RX_EN_A */
132#define MAX98927_PCM_RX_CH0_EN (0x1 << 0)
133#define MAX98927_PCM_RX_CH1_EN (0x1 << 1)
134#define MAX98927_PCM_RX_CH2_EN (0x1 << 2)
135#define MAX98927_PCM_RX_CH3_EN (0x1 << 3)
136#define MAX98927_PCM_RX_CH4_EN (0x1 << 4)
137#define MAX98927_PCM_RX_CH5_EN (0x1 << 5)
138#define MAX98927_PCM_RX_CH6_EN (0x1 << 6)
139#define MAX98927_PCM_RX_CH7_EN (0x1 << 7)
140
141/* MAX98927_R001A_PCM_TX_EN_A */
142#define MAX98927_PCM_TX_CH0_EN (0x1 << 0)
143#define MAX98927_PCM_TX_CH1_EN (0x1 << 1)
144#define MAX98927_PCM_TX_CH2_EN (0x1 << 2)
145#define MAX98927_PCM_TX_CH3_EN (0x1 << 3)
146#define MAX98927_PCM_TX_CH4_EN (0x1 << 4)
147#define MAX98927_PCM_TX_CH5_EN (0x1 << 5)
148#define MAX98927_PCM_TX_CH6_EN (0x1 << 6)
149#define MAX98927_PCM_TX_CH7_EN (0x1 << 7)
150
151/* MAX98927_R001E_PCM_TX_CH_SRC_A */
152#define MAX98927_PCM_TX_CH_SRC_A_V_SHIFT (0)
153#define MAX98927_PCM_TX_CH_SRC_A_I_SHIFT (4)
154
155/* MAX98927_R001F_PCM_TX_CH_SRC_B */
156#define MAX98927_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 5)
157
158/* MAX98927_R0020_PCM_MODE_CFG */
159#define MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 2)
160#define MAX98927_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3)
161#define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
162#define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
163#define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
164
165#define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
166#define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
167#define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
168#define MAX98927_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6)
169
170/* MAX98927_R0021_PCM_MASTER_MODE */
171#define MAX98927_PCM_MASTER_MODE_MASK (0x3 << 0)
172#define MAX98927_PCM_MASTER_MODE_SLAVE (0x0 << 0)
173#define MAX98927_PCM_MASTER_MODE_MASTER (0x3 << 0)
174
175#define MAX98927_PCM_MASTER_MODE_MCLK_MASK (0xF << 2)
176#define MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT (2)
177
178/* MAX98927_R0022_PCM_CLK_SETUP */
179#define MAX98927_PCM_CLK_SETUP_BSEL_MASK (0xF << 0)
180
181/* MAX98927_R0023_PCM_SR_SETUP1 */
182#define MAX98927_PCM_SR_SET1_SR_MASK (0xF << 0)
183
184#define MAX98927_PCM_SR_SET1_SR_8000 (0x0 << 0)
185#define MAX98927_PCM_SR_SET1_SR_11025 (0x1 << 0)
186#define MAX98927_PCM_SR_SET1_SR_12000 (0x2 << 0)
187#define MAX98927_PCM_SR_SET1_SR_16000 (0x3 << 0)
188#define MAX98927_PCM_SR_SET1_SR_22050 (0x4 << 0)
189#define MAX98927_PCM_SR_SET1_SR_24000 (0x5 << 0)
190#define MAX98927_PCM_SR_SET1_SR_32000 (0x6 << 0)
191#define MAX98927_PCM_SR_SET1_SR_44100 (0x7 << 0)
192#define MAX98927_PCM_SR_SET1_SR_48000 (0x8 << 0)
193
194/* MAX98927_R0024_PCM_SR_SETUP2 */
195#define MAX98927_PCM_SR_SET2_SR_MASK (0xF << 4)
196#define MAX98927_PCM_SR_SET2_SR_SHIFT (4)
197#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xf << 0)
198
199/* MAX98927_R0025_PCM_TO_SPK_MONOMIX_A */
200#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6)
201#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6)
202
203/* MAX98927_R0035_PDM_RX_CTRL */
204#define MAX98927_PDM_RX_EN_MASK (0x1 << 0)
205
206/* MAX98927_R0036_AMP_VOL_CTRL */
207#define MAX98927_AMP_VOL_SEL (0x1 << 7)
208#define MAX98927_AMP_VOL_SEL_WIDTH (1)
209#define MAX98927_AMP_VOL_SEL_SHIFT (7)
210#define MAX98927_AMP_VOL_MASK (0x7f << 0)
211#define MAX98927_AMP_VOL_WIDTH (7)
212#define MAX98927_AMP_VOL_SHIFT (0)
213
214/* MAX98927_R0037_AMP_DSP_CFG */
215#define MAX98927_AMP_DSP_CFG_DCBLK_EN (0x1 << 0)
216#define MAX98927_AMP_DSP_CFG_DITH_EN (0x1 << 1)
217#define MAX98927_AMP_DSP_CFG_RMP_BYPASS (0x1 << 4)
218#define MAX98927_AMP_DSP_CFG_DAC_INV (0x1 << 5)
219#define MAX98927_AMP_DSP_CFG_RMP_SHIFT (4)
220
221/* MAX98927_R0039_DRE_CTRL */
222#define MAX98927_DRE_CTRL_DRE_EN (0x1 << 0)
223#define MAX98927_DRE_EN_SHIFT 0x1
224
225/* MAX98927_R003A_AMP_EN */
226#define MAX98927_AMP_EN_MASK (0x1 << 0)
227
228/* MAX98927_R003B_SPK_SRC_SEL */
229#define MAX98927_SPK_SRC_MASK (0x3 << 0)
230
231/* MAX98927_R003C_SPK_GAIN */
232#define MAX98927_SPK_PCM_GAIN_MASK (0x7 << 0)
233#define MAX98927_SPK_PDM_GAIN_MASK (0x7 << 4)
234#define MAX98927_SPK_GAIN_WIDTH (3)
235
236/* MAX98927_R003E_MEAS_EN */
237#define MAX98927_MEAS_V_EN (0x1 << 0)
238#define MAX98927_MEAS_I_EN (0x1 << 1)
239
240/* MAX98927_R0040_BOOST_CTRL0 */
241#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1f << 0)
242#define MAX98927_BOOST_CTRL0_PVDD_MASK (0x1 << 7)
243#define MAX98927_BOOST_CTRL0_PVDD_EN_SHIFT (7)
244
245/* MAX98927_R0052_BROWNOUT_EN */
246#define MAX98927_BROWNOUT_BDE_EN (0x1 << 0)
247#define MAX98927_BROWNOUT_AMP_EN (0x1 << 1)
248#define MAX98927_BROWNOUT_DSP_EN (0x1 << 2)
249#define MAX98927_BROWNOUT_DSP_SHIFT (2)
250
251/* MAX98927_R0100_SOFT_RESET */
252#define MAX98927_SOFT_RESET (0x1 << 0)
253
254/* MAX98927_R00FF_GLOBAL_SHDN */
255#define MAX98927_GLOBAL_EN_MASK (0x1 << 0)
256
257struct max98927_priv {
258 struct regmap *regmap;
259 struct snd_soc_codec *codec;
260 struct max98927_pdata *pdata;
261 unsigned int spk_gain;
262 unsigned int sysclk;
263 unsigned int v_l_slot;
264 unsigned int i_l_slot;
265 bool interleave_mode;
266 unsigned int ch_size;
267 unsigned int rate;
268 unsigned int iface;
269 unsigned int master;
270 unsigned int digital_gain;
271};
272#endif
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c
index 9e8f0f4aa51a..c8bcb1db966d 100644
--- a/sound/soc/codecs/nau8540.c
+++ b/sound/soc/codecs/nau8540.c
@@ -39,147 +39,147 @@
39 39
40/* scaling for mclk from sysclk_src output */ 40/* scaling for mclk from sysclk_src output */
41static const struct nau8540_fll_attr mclk_src_scaling[] = { 41static const struct nau8540_fll_attr mclk_src_scaling[] = {
42 { 1, 0x0 }, 42 { 1, 0x0 },
43 { 2, 0x2 }, 43 { 2, 0x2 },
44 { 4, 0x3 }, 44 { 4, 0x3 },
45 { 8, 0x4 }, 45 { 8, 0x4 },
46 { 16, 0x5 }, 46 { 16, 0x5 },
47 { 32, 0x6 }, 47 { 32, 0x6 },
48 { 3, 0x7 }, 48 { 3, 0x7 },
49 { 6, 0xa }, 49 { 6, 0xa },
50 { 12, 0xb }, 50 { 12, 0xb },
51 { 24, 0xc }, 51 { 24, 0xc },
52}; 52};
53 53
54/* ratio for input clk freq */ 54/* ratio for input clk freq */
55static const struct nau8540_fll_attr fll_ratio[] = { 55static const struct nau8540_fll_attr fll_ratio[] = {
56 { 512000, 0x01 }, 56 { 512000, 0x01 },
57 { 256000, 0x02 }, 57 { 256000, 0x02 },
58 { 128000, 0x04 }, 58 { 128000, 0x04 },
59 { 64000, 0x08 }, 59 { 64000, 0x08 },
60 { 32000, 0x10 }, 60 { 32000, 0x10 },
61 { 8000, 0x20 }, 61 { 8000, 0x20 },
62 { 4000, 0x40 }, 62 { 4000, 0x40 },
63}; 63};
64 64
65static const struct nau8540_fll_attr fll_pre_scalar[] = { 65static const struct nau8540_fll_attr fll_pre_scalar[] = {
66 { 1, 0x0 }, 66 { 1, 0x0 },
67 { 2, 0x1 }, 67 { 2, 0x1 },
68 { 4, 0x2 }, 68 { 4, 0x2 },
69 { 8, 0x3 }, 69 { 8, 0x3 },
70}; 70};
71 71
72/* over sampling rate */ 72/* over sampling rate */
73static const struct nau8540_osr_attr osr_adc_sel[] = { 73static const struct nau8540_osr_attr osr_adc_sel[] = {
74 { 32, 3 }, /* OSR 32, SRC 1/8 */ 74 { 32, 3 }, /* OSR 32, SRC 1/8 */
75 { 64, 2 }, /* OSR 64, SRC 1/4 */ 75 { 64, 2 }, /* OSR 64, SRC 1/4 */
76 { 128, 1 }, /* OSR 128, SRC 1/2 */ 76 { 128, 1 }, /* OSR 128, SRC 1/2 */
77 { 256, 0 }, /* OSR 256, SRC 1 */ 77 { 256, 0 }, /* OSR 256, SRC 1 */
78}; 78};
79 79
80static const struct reg_default nau8540_reg_defaults[] = { 80static const struct reg_default nau8540_reg_defaults[] = {
81 {NAU8540_REG_POWER_MANAGEMENT, 0x0000}, 81 {NAU8540_REG_POWER_MANAGEMENT, 0x0000},
82 {NAU8540_REG_CLOCK_CTRL, 0x0000}, 82 {NAU8540_REG_CLOCK_CTRL, 0x0000},
83 {NAU8540_REG_CLOCK_SRC, 0x0000}, 83 {NAU8540_REG_CLOCK_SRC, 0x0000},
84 {NAU8540_REG_FLL1, 0x0001}, 84 {NAU8540_REG_FLL1, 0x0001},
85 {NAU8540_REG_FLL2, 0x3126}, 85 {NAU8540_REG_FLL2, 0x3126},
86 {NAU8540_REG_FLL3, 0x0008}, 86 {NAU8540_REG_FLL3, 0x0008},
87 {NAU8540_REG_FLL4, 0x0010}, 87 {NAU8540_REG_FLL4, 0x0010},
88 {NAU8540_REG_FLL5, 0xC000}, 88 {NAU8540_REG_FLL5, 0xC000},
89 {NAU8540_REG_FLL6, 0x6000}, 89 {NAU8540_REG_FLL6, 0x6000},
90 {NAU8540_REG_FLL_VCO_RSV, 0xF13C}, 90 {NAU8540_REG_FLL_VCO_RSV, 0xF13C},
91 {NAU8540_REG_PCM_CTRL0, 0x000B}, 91 {NAU8540_REG_PCM_CTRL0, 0x000B},
92 {NAU8540_REG_PCM_CTRL1, 0x3010}, 92 {NAU8540_REG_PCM_CTRL1, 0x3010},
93 {NAU8540_REG_PCM_CTRL2, 0x0800}, 93 {NAU8540_REG_PCM_CTRL2, 0x0800},
94 {NAU8540_REG_PCM_CTRL3, 0x0000}, 94 {NAU8540_REG_PCM_CTRL3, 0x0000},
95 {NAU8540_REG_PCM_CTRL4, 0x000F}, 95 {NAU8540_REG_PCM_CTRL4, 0x000F},
96 {NAU8540_REG_ALC_CONTROL_1, 0x0000}, 96 {NAU8540_REG_ALC_CONTROL_1, 0x0000},
97 {NAU8540_REG_ALC_CONTROL_2, 0x700B}, 97 {NAU8540_REG_ALC_CONTROL_2, 0x700B},
98 {NAU8540_REG_ALC_CONTROL_3, 0x0022}, 98 {NAU8540_REG_ALC_CONTROL_3, 0x0022},
99 {NAU8540_REG_ALC_CONTROL_4, 0x1010}, 99 {NAU8540_REG_ALC_CONTROL_4, 0x1010},
100 {NAU8540_REG_ALC_CONTROL_5, 0x1010}, 100 {NAU8540_REG_ALC_CONTROL_5, 0x1010},
101 {NAU8540_REG_NOTCH_FIL1_CH1, 0x0000}, 101 {NAU8540_REG_NOTCH_FIL1_CH1, 0x0000},
102 {NAU8540_REG_NOTCH_FIL2_CH1, 0x0000}, 102 {NAU8540_REG_NOTCH_FIL2_CH1, 0x0000},
103 {NAU8540_REG_NOTCH_FIL1_CH2, 0x0000}, 103 {NAU8540_REG_NOTCH_FIL1_CH2, 0x0000},
104 {NAU8540_REG_NOTCH_FIL2_CH2, 0x0000}, 104 {NAU8540_REG_NOTCH_FIL2_CH2, 0x0000},
105 {NAU8540_REG_NOTCH_FIL1_CH3, 0x0000}, 105 {NAU8540_REG_NOTCH_FIL1_CH3, 0x0000},
106 {NAU8540_REG_NOTCH_FIL2_CH3, 0x0000}, 106 {NAU8540_REG_NOTCH_FIL2_CH3, 0x0000},
107 {NAU8540_REG_NOTCH_FIL1_CH4, 0x0000}, 107 {NAU8540_REG_NOTCH_FIL1_CH4, 0x0000},
108 {NAU8540_REG_NOTCH_FIL2_CH4, 0x0000}, 108 {NAU8540_REG_NOTCH_FIL2_CH4, 0x0000},
109 {NAU8540_REG_HPF_FILTER_CH12, 0x0000}, 109 {NAU8540_REG_HPF_FILTER_CH12, 0x0000},
110 {NAU8540_REG_HPF_FILTER_CH34, 0x0000}, 110 {NAU8540_REG_HPF_FILTER_CH34, 0x0000},
111 {NAU8540_REG_ADC_SAMPLE_RATE, 0x0002}, 111 {NAU8540_REG_ADC_SAMPLE_RATE, 0x0002},
112 {NAU8540_REG_DIGITAL_GAIN_CH1, 0x0400}, 112 {NAU8540_REG_DIGITAL_GAIN_CH1, 0x0400},
113 {NAU8540_REG_DIGITAL_GAIN_CH2, 0x0400}, 113 {NAU8540_REG_DIGITAL_GAIN_CH2, 0x0400},
114 {NAU8540_REG_DIGITAL_GAIN_CH3, 0x0400}, 114 {NAU8540_REG_DIGITAL_GAIN_CH3, 0x0400},
115 {NAU8540_REG_DIGITAL_GAIN_CH4, 0x0400}, 115 {NAU8540_REG_DIGITAL_GAIN_CH4, 0x0400},
116 {NAU8540_REG_DIGITAL_MUX, 0x00E4}, 116 {NAU8540_REG_DIGITAL_MUX, 0x00E4},
117 {NAU8540_REG_GPIO_CTRL, 0x0000}, 117 {NAU8540_REG_GPIO_CTRL, 0x0000},
118 {NAU8540_REG_MISC_CTRL, 0x0000}, 118 {NAU8540_REG_MISC_CTRL, 0x0000},
119 {NAU8540_REG_I2C_CTRL, 0xEFFF}, 119 {NAU8540_REG_I2C_CTRL, 0xEFFF},
120 {NAU8540_REG_VMID_CTRL, 0x0000}, 120 {NAU8540_REG_VMID_CTRL, 0x0000},
121 {NAU8540_REG_MUTE, 0x0000}, 121 {NAU8540_REG_MUTE, 0x0000},
122 {NAU8540_REG_ANALOG_ADC1, 0x0011}, 122 {NAU8540_REG_ANALOG_ADC1, 0x0011},
123 {NAU8540_REG_ANALOG_ADC2, 0x0020}, 123 {NAU8540_REG_ANALOG_ADC2, 0x0020},
124 {NAU8540_REG_ANALOG_PWR, 0x0000}, 124 {NAU8540_REG_ANALOG_PWR, 0x0000},
125 {NAU8540_REG_MIC_BIAS, 0x0004}, 125 {NAU8540_REG_MIC_BIAS, 0x0004},
126 {NAU8540_REG_REFERENCE, 0x0000}, 126 {NAU8540_REG_REFERENCE, 0x0000},
127 {NAU8540_REG_FEPGA1, 0x0000}, 127 {NAU8540_REG_FEPGA1, 0x0000},
128 {NAU8540_REG_FEPGA2, 0x0000}, 128 {NAU8540_REG_FEPGA2, 0x0000},
129 {NAU8540_REG_FEPGA3, 0x0101}, 129 {NAU8540_REG_FEPGA3, 0x0101},
130 {NAU8540_REG_FEPGA4, 0x0101}, 130 {NAU8540_REG_FEPGA4, 0x0101},
131 {NAU8540_REG_PWR, 0x0000}, 131 {NAU8540_REG_PWR, 0x0000},
132}; 132};
133 133
134static bool nau8540_readable_reg(struct device *dev, unsigned int reg) 134static bool nau8540_readable_reg(struct device *dev, unsigned int reg)
135{ 135{
136 switch (reg) { 136 switch (reg) {
137 case NAU8540_REG_POWER_MANAGEMENT ... NAU8540_REG_FLL_VCO_RSV: 137 case NAU8540_REG_POWER_MANAGEMENT ... NAU8540_REG_FLL_VCO_RSV:
138 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4: 138 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:
139 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5: 139 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:
140 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ADC_SAMPLE_RATE: 140 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ADC_SAMPLE_RATE:
141 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX: 141 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:
142 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_I2C_CTRL: 142 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_I2C_CTRL:
143 case NAU8540_REG_I2C_DEVICE_ID: 143 case NAU8540_REG_I2C_DEVICE_ID:
144 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE: 144 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:
145 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR: 145 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:
146 return true; 146 return true;
147 default: 147 default:
148 return false; 148 return false;
149 } 149 }
150 150
151} 151}
152 152
153static bool nau8540_writeable_reg(struct device *dev, unsigned int reg) 153static bool nau8540_writeable_reg(struct device *dev, unsigned int reg)
154{ 154{
155 switch (reg) { 155 switch (reg) {
156 case NAU8540_REG_SW_RESET ... NAU8540_REG_FLL_VCO_RSV: 156 case NAU8540_REG_SW_RESET ... NAU8540_REG_FLL_VCO_RSV:
157 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4: 157 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:
158 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5: 158 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:
159 case NAU8540_REG_NOTCH_FIL1_CH1 ... NAU8540_REG_ADC_SAMPLE_RATE: 159 case NAU8540_REG_NOTCH_FIL1_CH1 ... NAU8540_REG_ADC_SAMPLE_RATE:
160 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX: 160 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:
161 case NAU8540_REG_GPIO_CTRL ... NAU8540_REG_I2C_CTRL: 161 case NAU8540_REG_GPIO_CTRL ... NAU8540_REG_I2C_CTRL:
162 case NAU8540_REG_RST: 162 case NAU8540_REG_RST:
163 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE: 163 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:
164 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR: 164 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:
165 return true; 165 return true;
166 default: 166 default:
167 return false; 167 return false;
168 } 168 }
169} 169}
170 170
171static bool nau8540_volatile_reg(struct device *dev, unsigned int reg) 171static bool nau8540_volatile_reg(struct device *dev, unsigned int reg)
172{ 172{
173 switch (reg) { 173 switch (reg) {
174 case NAU8540_REG_SW_RESET: 174 case NAU8540_REG_SW_RESET:
175 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ALC_STATUS: 175 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ALC_STATUS:
176 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_PEAK_CH4: 176 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_PEAK_CH4:
177 case NAU8540_REG_I2C_DEVICE_ID: 177 case NAU8540_REG_I2C_DEVICE_ID:
178 case NAU8540_REG_RST: 178 case NAU8540_REG_RST:
179 return true; 179 return true;
180 default: 180 default:
181 return false; 181 return false;
182 } 182 }
183} 183}
184 184
185 185
@@ -187,255 +187,255 @@ static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -12800, 3600);
187static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600); 187static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600);
188 188
189static const struct snd_kcontrol_new nau8540_snd_controls[] = { 189static const struct snd_kcontrol_new nau8540_snd_controls[] = {
190 SOC_SINGLE_TLV("Mic1 Volume", NAU8540_REG_DIGITAL_GAIN_CH1, 190 SOC_SINGLE_TLV("Mic1 Volume", NAU8540_REG_DIGITAL_GAIN_CH1,
191 0, 0x520, 0, adc_vol_tlv), 191 0, 0x520, 0, adc_vol_tlv),
192 SOC_SINGLE_TLV("Mic2 Volume", NAU8540_REG_DIGITAL_GAIN_CH2, 192 SOC_SINGLE_TLV("Mic2 Volume", NAU8540_REG_DIGITAL_GAIN_CH2,
193 0, 0x520, 0, adc_vol_tlv), 193 0, 0x520, 0, adc_vol_tlv),
194 SOC_SINGLE_TLV("Mic3 Volume", NAU8540_REG_DIGITAL_GAIN_CH3, 194 SOC_SINGLE_TLV("Mic3 Volume", NAU8540_REG_DIGITAL_GAIN_CH3,
195 0, 0x520, 0, adc_vol_tlv), 195 0, 0x520, 0, adc_vol_tlv),
196 SOC_SINGLE_TLV("Mic4 Volume", NAU8540_REG_DIGITAL_GAIN_CH4, 196 SOC_SINGLE_TLV("Mic4 Volume", NAU8540_REG_DIGITAL_GAIN_CH4,
197 0, 0x520, 0, adc_vol_tlv), 197 0, 0x520, 0, adc_vol_tlv),
198 198
199 SOC_SINGLE_TLV("Frontend PGA1 Volume", NAU8540_REG_FEPGA3, 199 SOC_SINGLE_TLV("Frontend PGA1 Volume", NAU8540_REG_FEPGA3,
200 0, 0x25, 0, fepga_gain_tlv), 200 0, 0x25, 0, fepga_gain_tlv),
201 SOC_SINGLE_TLV("Frontend PGA2 Volume", NAU8540_REG_FEPGA3, 201 SOC_SINGLE_TLV("Frontend PGA2 Volume", NAU8540_REG_FEPGA3,
202 8, 0x25, 0, fepga_gain_tlv), 202 8, 0x25, 0, fepga_gain_tlv),
203 SOC_SINGLE_TLV("Frontend PGA3 Volume", NAU8540_REG_FEPGA4, 203 SOC_SINGLE_TLV("Frontend PGA3 Volume", NAU8540_REG_FEPGA4,
204 0, 0x25, 0, fepga_gain_tlv), 204 0, 0x25, 0, fepga_gain_tlv),
205 SOC_SINGLE_TLV("Frontend PGA4 Volume", NAU8540_REG_FEPGA4, 205 SOC_SINGLE_TLV("Frontend PGA4 Volume", NAU8540_REG_FEPGA4,
206 8, 0x25, 0, fepga_gain_tlv), 206 8, 0x25, 0, fepga_gain_tlv),
207}; 207};
208 208
209static const char * const adc_channel[] = { 209static const char * const adc_channel[] = {
210 "ADC channel 1", "ADC channel 2", "ADC channel 3", "ADC channel 4" 210 "ADC channel 1", "ADC channel 2", "ADC channel 3", "ADC channel 4"
211}; 211};
212static SOC_ENUM_SINGLE_DECL( 212static SOC_ENUM_SINGLE_DECL(
213 digital_ch4_enum, NAU8540_REG_DIGITAL_MUX, 6, adc_channel); 213 digital_ch4_enum, NAU8540_REG_DIGITAL_MUX, 6, adc_channel);
214 214
215static const struct snd_kcontrol_new digital_ch4_mux = 215static const struct snd_kcontrol_new digital_ch4_mux =
216 SOC_DAPM_ENUM("Digital CH4 Select", digital_ch4_enum); 216 SOC_DAPM_ENUM("Digital CH4 Select", digital_ch4_enum);
217 217
218static SOC_ENUM_SINGLE_DECL( 218static SOC_ENUM_SINGLE_DECL(
219 digital_ch3_enum, NAU8540_REG_DIGITAL_MUX, 4, adc_channel); 219 digital_ch3_enum, NAU8540_REG_DIGITAL_MUX, 4, adc_channel);
220 220
221static const struct snd_kcontrol_new digital_ch3_mux = 221static const struct snd_kcontrol_new digital_ch3_mux =
222 SOC_DAPM_ENUM("Digital CH3 Select", digital_ch3_enum); 222 SOC_DAPM_ENUM("Digital CH3 Select", digital_ch3_enum);
223 223
224static SOC_ENUM_SINGLE_DECL( 224static SOC_ENUM_SINGLE_DECL(
225 digital_ch2_enum, NAU8540_REG_DIGITAL_MUX, 2, adc_channel); 225 digital_ch2_enum, NAU8540_REG_DIGITAL_MUX, 2, adc_channel);
226 226
227static const struct snd_kcontrol_new digital_ch2_mux = 227static const struct snd_kcontrol_new digital_ch2_mux =
228 SOC_DAPM_ENUM("Digital CH2 Select", digital_ch2_enum); 228 SOC_DAPM_ENUM("Digital CH2 Select", digital_ch2_enum);
229 229
230static SOC_ENUM_SINGLE_DECL( 230static SOC_ENUM_SINGLE_DECL(
231 digital_ch1_enum, NAU8540_REG_DIGITAL_MUX, 0, adc_channel); 231 digital_ch1_enum, NAU8540_REG_DIGITAL_MUX, 0, adc_channel);
232 232
233static const struct snd_kcontrol_new digital_ch1_mux = 233static const struct snd_kcontrol_new digital_ch1_mux =
234 SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); 234 SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum);
235 235
236static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { 236static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = {
237 SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0), 237 SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0),
238 SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0), 238 SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0),
239 239
240 SND_SOC_DAPM_INPUT("MIC1"), 240 SND_SOC_DAPM_INPUT("MIC1"),
241 SND_SOC_DAPM_INPUT("MIC2"), 241 SND_SOC_DAPM_INPUT("MIC2"),
242 SND_SOC_DAPM_INPUT("MIC3"), 242 SND_SOC_DAPM_INPUT("MIC3"),
243 SND_SOC_DAPM_INPUT("MIC4"), 243 SND_SOC_DAPM_INPUT("MIC4"),
244 244
245 SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0), 245 SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0),
246 SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0), 246 SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0),
247 SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), 247 SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0),
248 SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), 248 SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0),
249 249
250 SND_SOC_DAPM_ADC("ADC1", NULL, 250 SND_SOC_DAPM_ADC("ADC1", NULL,
251 NAU8540_REG_POWER_MANAGEMENT, 0, 0), 251 NAU8540_REG_POWER_MANAGEMENT, 0, 0),
252 SND_SOC_DAPM_ADC("ADC2", NULL, 252 SND_SOC_DAPM_ADC("ADC2", NULL,
253 NAU8540_REG_POWER_MANAGEMENT, 1, 0), 253 NAU8540_REG_POWER_MANAGEMENT, 1, 0),
254 SND_SOC_DAPM_ADC("ADC3", NULL, 254 SND_SOC_DAPM_ADC("ADC3", NULL,
255 NAU8540_REG_POWER_MANAGEMENT, 2, 0), 255 NAU8540_REG_POWER_MANAGEMENT, 2, 0),
256 SND_SOC_DAPM_ADC("ADC4", NULL, 256 SND_SOC_DAPM_ADC("ADC4", NULL,
257 NAU8540_REG_POWER_MANAGEMENT, 3, 0), 257 NAU8540_REG_POWER_MANAGEMENT, 3, 0),
258 258
259 SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), 259 SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0),
260 SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), 260 SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0),
261 SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0), 261 SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0),
262 SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0), 262 SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0),
263 263
264 SND_SOC_DAPM_MUX("Digital CH4 Mux", 264 SND_SOC_DAPM_MUX("Digital CH4 Mux",
265 SND_SOC_NOPM, 0, 0, &digital_ch4_mux), 265 SND_SOC_NOPM, 0, 0, &digital_ch4_mux),
266 SND_SOC_DAPM_MUX("Digital CH3 Mux", 266 SND_SOC_DAPM_MUX("Digital CH3 Mux",
267 SND_SOC_NOPM, 0, 0, &digital_ch3_mux), 267 SND_SOC_NOPM, 0, 0, &digital_ch3_mux),
268 SND_SOC_DAPM_MUX("Digital CH2 Mux", 268 SND_SOC_DAPM_MUX("Digital CH2 Mux",
269 SND_SOC_NOPM, 0, 0, &digital_ch2_mux), 269 SND_SOC_NOPM, 0, 0, &digital_ch2_mux),
270 SND_SOC_DAPM_MUX("Digital CH1 Mux", 270 SND_SOC_DAPM_MUX("Digital CH1 Mux",
271 SND_SOC_NOPM, 0, 0, &digital_ch1_mux), 271 SND_SOC_NOPM, 0, 0, &digital_ch1_mux),
272 272
273 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), 273 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0),
274}; 274};
275 275
276static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { 276static const struct snd_soc_dapm_route nau8540_dapm_routes[] = {
277 {"Frontend PGA1", NULL, "MIC1"}, 277 {"Frontend PGA1", NULL, "MIC1"},
278 {"Frontend PGA2", NULL, "MIC2"}, 278 {"Frontend PGA2", NULL, "MIC2"},
279 {"Frontend PGA3", NULL, "MIC3"}, 279 {"Frontend PGA3", NULL, "MIC3"},
280 {"Frontend PGA4", NULL, "MIC4"}, 280 {"Frontend PGA4", NULL, "MIC4"},
281 281
282 {"ADC1", NULL, "Frontend PGA1"}, 282 {"ADC1", NULL, "Frontend PGA1"},
283 {"ADC2", NULL, "Frontend PGA2"}, 283 {"ADC2", NULL, "Frontend PGA2"},
284 {"ADC3", NULL, "Frontend PGA3"}, 284 {"ADC3", NULL, "Frontend PGA3"},
285 {"ADC4", NULL, "Frontend PGA4"}, 285 {"ADC4", NULL, "Frontend PGA4"},
286 286
287 {"ADC CH1", NULL, "ADC1"}, 287 {"ADC CH1", NULL, "ADC1"},
288 {"ADC CH2", NULL, "ADC2"}, 288 {"ADC CH2", NULL, "ADC2"},
289 {"ADC CH3", NULL, "ADC3"}, 289 {"ADC CH3", NULL, "ADC3"},
290 {"ADC CH4", NULL, "ADC4"}, 290 {"ADC CH4", NULL, "ADC4"},
291 291
292 {"ADC1", NULL, "MICBIAS1"}, 292 {"ADC1", NULL, "MICBIAS1"},
293 {"ADC2", NULL, "MICBIAS1"}, 293 {"ADC2", NULL, "MICBIAS1"},
294 {"ADC3", NULL, "MICBIAS2"}, 294 {"ADC3", NULL, "MICBIAS2"},
295 {"ADC4", NULL, "MICBIAS2"}, 295 {"ADC4", NULL, "MICBIAS2"},
296 296
297 {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"}, 297 {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"},
298 {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"}, 298 {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"},
299 {"Digital CH1 Mux", "ADC channel 3", "ADC CH3"}, 299 {"Digital CH1 Mux", "ADC channel 3", "ADC CH3"},
300 {"Digital CH1 Mux", "ADC channel 4", "ADC CH4"}, 300 {"Digital CH1 Mux", "ADC channel 4", "ADC CH4"},
301 301
302 {"Digital CH2 Mux", "ADC channel 1", "ADC CH1"}, 302 {"Digital CH2 Mux", "ADC channel 1", "ADC CH1"},
303 {"Digital CH2 Mux", "ADC channel 2", "ADC CH2"}, 303 {"Digital CH2 Mux", "ADC channel 2", "ADC CH2"},
304 {"Digital CH2 Mux", "ADC channel 3", "ADC CH3"}, 304 {"Digital CH2 Mux", "ADC channel 3", "ADC CH3"},
305 {"Digital CH2 Mux", "ADC channel 4", "ADC CH4"}, 305 {"Digital CH2 Mux", "ADC channel 4", "ADC CH4"},
306 306
307 {"Digital CH3 Mux", "ADC channel 1", "ADC CH1"}, 307 {"Digital CH3 Mux", "ADC channel 1", "ADC CH1"},
308 {"Digital CH3 Mux", "ADC channel 2", "ADC CH2"}, 308 {"Digital CH3 Mux", "ADC channel 2", "ADC CH2"},
309 {"Digital CH3 Mux", "ADC channel 3", "ADC CH3"}, 309 {"Digital CH3 Mux", "ADC channel 3", "ADC CH3"},
310 {"Digital CH3 Mux", "ADC channel 4", "ADC CH4"}, 310 {"Digital CH3 Mux", "ADC channel 4", "ADC CH4"},
311 311
312 {"Digital CH4 Mux", "ADC channel 1", "ADC CH1"}, 312 {"Digital CH4 Mux", "ADC channel 1", "ADC CH1"},
313 {"Digital CH4 Mux", "ADC channel 2", "ADC CH2"}, 313 {"Digital CH4 Mux", "ADC channel 2", "ADC CH2"},
314 {"Digital CH4 Mux", "ADC channel 3", "ADC CH3"}, 314 {"Digital CH4 Mux", "ADC channel 3", "ADC CH3"},
315 {"Digital CH4 Mux", "ADC channel 4", "ADC CH4"}, 315 {"Digital CH4 Mux", "ADC channel 4", "ADC CH4"},
316 316
317 {"AIFTX", NULL, "Digital CH1 Mux"}, 317 {"AIFTX", NULL, "Digital CH1 Mux"},
318 {"AIFTX", NULL, "Digital CH2 Mux"}, 318 {"AIFTX", NULL, "Digital CH2 Mux"},
319 {"AIFTX", NULL, "Digital CH3 Mux"}, 319 {"AIFTX", NULL, "Digital CH3 Mux"},
320 {"AIFTX", NULL, "Digital CH4 Mux"}, 320 {"AIFTX", NULL, "Digital CH4 Mux"},
321}; 321};
322 322
323static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr) 323static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr)
324{ 324{
325 int osrate; 325 int osrate;
326 326
327 if (osr >= ARRAY_SIZE(osr_adc_sel)) 327 if (osr >= ARRAY_SIZE(osr_adc_sel))
328 return -EINVAL; 328 return -EINVAL;
329 osrate = osr_adc_sel[osr].osr; 329 osrate = osr_adc_sel[osr].osr;
330 330
331 if (rate * osr > CLK_ADC_MAX) { 331 if (rate * osr > CLK_ADC_MAX) {
332 dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n"); 332 dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n");
333 return -EINVAL; 333 return -EINVAL;
334 } 334 }
335 335
336 return 0; 336 return 0;
337} 337}
338 338
339static int nau8540_hw_params(struct snd_pcm_substream *substream, 339static int nau8540_hw_params(struct snd_pcm_substream *substream,
340 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 340 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
341{ 341{
342 struct snd_soc_codec *codec = dai->codec; 342 struct snd_soc_codec *codec = dai->codec;
343 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 343 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
344 unsigned int val_len = 0, osr; 344 unsigned int val_len = 0, osr;
345 345
346 /* CLK_ADC = OSR * FS 346 /* CLK_ADC = OSR * FS
347 * ADC clock frequency is defined as Over Sampling Rate (OSR) 347 * ADC clock frequency is defined as Over Sampling Rate (OSR)
348 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs 348 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs
349 * values must be selected such that the maximum frequency is less 349 * values must be selected such that the maximum frequency is less
350 * than 6.144 MHz. 350 * than 6.144 MHz.
351 */ 351 */
352 regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); 352 regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);
353 osr &= NAU8540_ADC_OSR_MASK; 353 osr &= NAU8540_ADC_OSR_MASK;
354 if (nau8540_clock_check(nau8540, params_rate(params), osr)) 354 if (nau8540_clock_check(nau8540, params_rate(params), osr))
355 return -EINVAL; 355 return -EINVAL;
356 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 356 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
357 NAU8540_CLK_ADC_SRC_MASK, 357 NAU8540_CLK_ADC_SRC_MASK,
358 osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT); 358 osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT);
359 359
360 switch (params_width(params)) { 360 switch (params_width(params)) {
361 case 16: 361 case 16:
362 val_len |= NAU8540_I2S_DL_16; 362 val_len |= NAU8540_I2S_DL_16;
363 break; 363 break;
364 case 20: 364 case 20:
365 val_len |= NAU8540_I2S_DL_20; 365 val_len |= NAU8540_I2S_DL_20;
366 break; 366 break;
367 case 24: 367 case 24:
368 val_len |= NAU8540_I2S_DL_24; 368 val_len |= NAU8540_I2S_DL_24;
369 break; 369 break;
370 case 32: 370 case 32:
371 val_len |= NAU8540_I2S_DL_32; 371 val_len |= NAU8540_I2S_DL_32;
372 break; 372 break;
373 default: 373 default:
374 return -EINVAL; 374 return -EINVAL;
375 } 375 }
376 376
377 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0, 377 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,
378 NAU8540_I2S_DL_MASK, val_len); 378 NAU8540_I2S_DL_MASK, val_len);
379 379
380 return 0; 380 return 0;
381} 381}
382 382
383static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 383static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
384{ 384{
385 struct snd_soc_codec *codec = dai->codec; 385 struct snd_soc_codec *codec = dai->codec;
386 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 386 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
387 unsigned int ctrl1_val = 0, ctrl2_val = 0; 387 unsigned int ctrl1_val = 0, ctrl2_val = 0;
388 388
389 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 389 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
390 case SND_SOC_DAIFMT_CBM_CFM: 390 case SND_SOC_DAIFMT_CBM_CFM:
391 ctrl2_val |= NAU8540_I2S_MS_MASTER; 391 ctrl2_val |= NAU8540_I2S_MS_MASTER;
392 break; 392 break;
393 case SND_SOC_DAIFMT_CBS_CFS: 393 case SND_SOC_DAIFMT_CBS_CFS:
394 break; 394 break;
395 default: 395 default:
396 return -EINVAL; 396 return -EINVAL;
397 } 397 }
398 398
399 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 399 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
400 case SND_SOC_DAIFMT_NB_NF: 400 case SND_SOC_DAIFMT_NB_NF:
401 break; 401 break;
402 case SND_SOC_DAIFMT_IB_NF: 402 case SND_SOC_DAIFMT_IB_NF:
403 ctrl1_val |= NAU8540_I2S_BP_INV; 403 ctrl1_val |= NAU8540_I2S_BP_INV;
404 break; 404 break;
405 default: 405 default:
406 return -EINVAL; 406 return -EINVAL;
407 } 407 }
408 408
409 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 409 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
410 case SND_SOC_DAIFMT_I2S: 410 case SND_SOC_DAIFMT_I2S:
411 ctrl1_val |= NAU8540_I2S_DF_I2S; 411 ctrl1_val |= NAU8540_I2S_DF_I2S;
412 break; 412 break;
413 case SND_SOC_DAIFMT_LEFT_J: 413 case SND_SOC_DAIFMT_LEFT_J:
414 ctrl1_val |= NAU8540_I2S_DF_LEFT; 414 ctrl1_val |= NAU8540_I2S_DF_LEFT;
415 break; 415 break;
416 case SND_SOC_DAIFMT_RIGHT_J: 416 case SND_SOC_DAIFMT_RIGHT_J:
417 ctrl1_val |= NAU8540_I2S_DF_RIGTH; 417 ctrl1_val |= NAU8540_I2S_DF_RIGTH;
418 break; 418 break;
419 case SND_SOC_DAIFMT_DSP_A: 419 case SND_SOC_DAIFMT_DSP_A:
420 ctrl1_val |= NAU8540_I2S_DF_PCM_AB; 420 ctrl1_val |= NAU8540_I2S_DF_PCM_AB;
421 break; 421 break;
422 case SND_SOC_DAIFMT_DSP_B: 422 case SND_SOC_DAIFMT_DSP_B:
423 ctrl1_val |= NAU8540_I2S_DF_PCM_AB; 423 ctrl1_val |= NAU8540_I2S_DF_PCM_AB;
424 ctrl1_val |= NAU8540_I2S_PCMB_EN; 424 ctrl1_val |= NAU8540_I2S_PCMB_EN;
425 break; 425 break;
426 default: 426 default:
427 return -EINVAL; 427 return -EINVAL;
428 } 428 }
429 429
430 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0, 430 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,
431 NAU8540_I2S_DL_MASK | NAU8540_I2S_DF_MASK | 431 NAU8540_I2S_DL_MASK | NAU8540_I2S_DF_MASK |
432 NAU8540_I2S_BP_INV | NAU8540_I2S_PCMB_EN, ctrl1_val); 432 NAU8540_I2S_BP_INV | NAU8540_I2S_PCMB_EN, ctrl1_val);
433 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, 433 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,
434 NAU8540_I2S_MS_MASK | NAU8540_I2S_DO12_OE, ctrl2_val); 434 NAU8540_I2S_MS_MASK | NAU8540_I2S_DO12_OE, ctrl2_val);
435 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, 435 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,
436 NAU8540_I2S_DO34_OE, 0); 436 NAU8540_I2S_DO34_OE, 0);
437 437
438 return 0; 438 return 0;
439} 439}
440 440
441/** 441/**
@@ -451,55 +451,55 @@ static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
451 * Configures a DAI for TDM operation. Only support 4 slots TDM. 451 * Configures a DAI for TDM operation. Only support 4 slots TDM.
452 */ 452 */
453static int nau8540_set_tdm_slot(struct snd_soc_dai *dai, 453static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
454 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 454 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
455{ 455{
456 struct snd_soc_codec *codec = dai->codec; 456 struct snd_soc_codec *codec = dai->codec;
457 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 457 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
458 unsigned int ctrl2_val = 0, ctrl4_val = 0; 458 unsigned int ctrl2_val = 0, ctrl4_val = 0;
459 459
460 if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf))) 460 if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)))
461 return -EINVAL; 461 return -EINVAL;
462 462
463 ctrl4_val |= (NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN); 463 ctrl4_val |= (NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN);
464 if (tx_mask & 0xf0) { 464 if (tx_mask & 0xf0) {
465 ctrl2_val = 4 * slot_width; 465 ctrl2_val = 4 * slot_width;
466 ctrl4_val |= (tx_mask >> 4); 466 ctrl4_val |= (tx_mask >> 4);
467 } else { 467 } else {
468 ctrl4_val |= tx_mask; 468 ctrl4_val |= tx_mask;
469 } 469 }
470 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL4, 470 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL4,
471 NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN | 471 NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN |
472 NAU8540_TDM_TX_MASK, ctrl4_val); 472 NAU8540_TDM_TX_MASK, ctrl4_val);
473 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, 473 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,
474 NAU8540_I2S_DO12_OE, NAU8540_I2S_DO12_OE); 474 NAU8540_I2S_DO12_OE, NAU8540_I2S_DO12_OE);
475 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, 475 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,
476 NAU8540_I2S_DO34_OE | NAU8540_I2S_TSLOT_L_MASK, 476 NAU8540_I2S_DO34_OE | NAU8540_I2S_TSLOT_L_MASK,
477 NAU8540_I2S_DO34_OE | ctrl2_val); 477 NAU8540_I2S_DO34_OE | ctrl2_val);
478 478
479 return 0; 479 return 0;
480} 480}
481 481
482 482
483static const struct snd_soc_dai_ops nau8540_dai_ops = { 483static const struct snd_soc_dai_ops nau8540_dai_ops = {
484 .hw_params = nau8540_hw_params, 484 .hw_params = nau8540_hw_params,
485 .set_fmt = nau8540_set_fmt, 485 .set_fmt = nau8540_set_fmt,
486 .set_tdm_slot = nau8540_set_tdm_slot, 486 .set_tdm_slot = nau8540_set_tdm_slot,
487}; 487};
488 488
489#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000 489#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000
490#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ 490#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
491 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 491 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
492 492
493static struct snd_soc_dai_driver nau8540_dai = { 493static struct snd_soc_dai_driver nau8540_dai = {
494 .name = "nau8540-hifi", 494 .name = "nau8540-hifi",
495 .capture = { 495 .capture = {
496 .stream_name = "Capture", 496 .stream_name = "Capture",
497 .channels_min = 1, 497 .channels_min = 1,
498 .channels_max = 4, 498 .channels_max = 4,
499 .rates = NAU8540_RATES, 499 .rates = NAU8540_RATES,
500 .formats = NAU8540_FORMATS, 500 .formats = NAU8540_FORMATS,
501 }, 501 },
502 .ops = &nau8540_dai_ops, 502 .ops = &nau8540_dai_ops,
503}; 503};
504 504
505/** 505/**
@@ -513,320 +513,320 @@ static struct snd_soc_dai_driver nau8540_dai = {
513 * Returns 0 for success or negative error code. 513 * Returns 0 for success or negative error code.
514 */ 514 */
515static int nau8540_calc_fll_param(unsigned int fll_in, 515static int nau8540_calc_fll_param(unsigned int fll_in,
516 unsigned int fs, struct nau8540_fll *fll_param) 516 unsigned int fs, struct nau8540_fll *fll_param)
517{ 517{
518 u64 fvco, fvco_max; 518 u64 fvco, fvco_max;
519 unsigned int fref, i, fvco_sel; 519 unsigned int fref, i, fvco_sel;
520 520
521 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing 521 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
522 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar. 522 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
523 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK 523 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK
524 */ 524 */
525 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) { 525 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
526 fref = fll_in / fll_pre_scalar[i].param; 526 fref = fll_in / fll_pre_scalar[i].param;
527 if (fref <= NAU_FREF_MAX) 527 if (fref <= NAU_FREF_MAX)
528 break; 528 break;
529 } 529 }
530 if (i == ARRAY_SIZE(fll_pre_scalar)) 530 if (i == ARRAY_SIZE(fll_pre_scalar))
531 return -EINVAL; 531 return -EINVAL;
532 fll_param->clk_ref_div = fll_pre_scalar[i].val; 532 fll_param->clk_ref_div = fll_pre_scalar[i].val;
533 533
534 /* Choose the FLL ratio based on FREF */ 534 /* Choose the FLL ratio based on FREF */
535 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) { 535 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
536 if (fref >= fll_ratio[i].param) 536 if (fref >= fll_ratio[i].param)
537 break; 537 break;
538 } 538 }
539 if (i == ARRAY_SIZE(fll_ratio)) 539 if (i == ARRAY_SIZE(fll_ratio))
540 return -EINVAL; 540 return -EINVAL;
541 fll_param->ratio = fll_ratio[i].val; 541 fll_param->ratio = fll_ratio[i].val;
542 542
543 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. 543 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
544 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be 544 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
545 * guaranteed across the full range of operation. 545 * guaranteed across the full range of operation.
546 * FDCO = freq_out * 2 * mclk_src_scaling 546 * FDCO = freq_out * 2 * mclk_src_scaling
547 */ 547 */
548 fvco_max = 0; 548 fvco_max = 0;
549 fvco_sel = ARRAY_SIZE(mclk_src_scaling); 549 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
550 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 550 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
551 fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 551 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
552 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX && 552 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
553 fvco_max < fvco) { 553 fvco_max < fvco) {
554 fvco_max = fvco; 554 fvco_max = fvco;
555 fvco_sel = i; 555 fvco_sel = i;
556 } 556 }
557 } 557 }
558 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel) 558 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
559 return -EINVAL; 559 return -EINVAL;
560 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val; 560 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
561 561
562 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 562 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
563 * input based on FDCO, FREF and FLL ratio. 563 * input based on FDCO, FREF and FLL ratio.
564 */ 564 */
565 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); 565 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
566 fll_param->fll_int = (fvco >> 16) & 0x3FF; 566 fll_param->fll_int = (fvco >> 16) & 0x3FF;
567 fll_param->fll_frac = fvco & 0xFFFF; 567 fll_param->fll_frac = fvco & 0xFFFF;
568 return 0; 568 return 0;
569} 569}
570 570
571static void nau8540_fll_apply(struct regmap *regmap, 571static void nau8540_fll_apply(struct regmap *regmap,
572 struct nau8540_fll *fll_param) 572 struct nau8540_fll *fll_param)
573{ 573{
574 regmap_update_bits(regmap, NAU8540_REG_CLOCK_SRC, 574 regmap_update_bits(regmap, NAU8540_REG_CLOCK_SRC,
575 NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK, 575 NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK,
576 NAU8540_CLK_SRC_MCLK | fll_param->mclk_src); 576 NAU8540_CLK_SRC_MCLK | fll_param->mclk_src);
577 regmap_update_bits(regmap, NAU8540_REG_FLL1, 577 regmap_update_bits(regmap, NAU8540_REG_FLL1,
578 NAU8540_FLL_RATIO_MASK, fll_param->ratio); 578 NAU8540_FLL_RATIO_MASK, fll_param->ratio);
579 /* FLL 16-bit fractional input */ 579 /* FLL 16-bit fractional input */
580 regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac); 580 regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac);
581 /* FLL 10-bit integer input */ 581 /* FLL 10-bit integer input */
582 regmap_update_bits(regmap, NAU8540_REG_FLL3, 582 regmap_update_bits(regmap, NAU8540_REG_FLL3,
583 NAU8540_FLL_INTEGER_MASK, fll_param->fll_int); 583 NAU8540_FLL_INTEGER_MASK, fll_param->fll_int);
584 /* FLL pre-scaler */ 584 /* FLL pre-scaler */
585 regmap_update_bits(regmap, NAU8540_REG_FLL4, 585 regmap_update_bits(regmap, NAU8540_REG_FLL4,
586 NAU8540_FLL_REF_DIV_MASK, 586 NAU8540_FLL_REF_DIV_MASK,
587 fll_param->clk_ref_div << NAU8540_FLL_REF_DIV_SFT); 587 fll_param->clk_ref_div << NAU8540_FLL_REF_DIV_SFT);
588 regmap_update_bits(regmap, NAU8540_REG_FLL5, 588 regmap_update_bits(regmap, NAU8540_REG_FLL5,
589 NAU8540_FLL_CLK_SW_MASK, NAU8540_FLL_CLK_SW_REF); 589 NAU8540_FLL_CLK_SW_MASK, NAU8540_FLL_CLK_SW_REF);
590 regmap_update_bits(regmap, 590 regmap_update_bits(regmap,
591 NAU8540_REG_FLL6, NAU8540_DCO_EN, 0); 591 NAU8540_REG_FLL6, NAU8540_DCO_EN, 0);
592 if (fll_param->fll_frac) { 592 if (fll_param->fll_frac) {
593 regmap_update_bits(regmap, NAU8540_REG_FLL5, 593 regmap_update_bits(regmap, NAU8540_REG_FLL5,
594 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 594 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
595 NAU8540_FLL_FTR_SW_MASK, 595 NAU8540_FLL_FTR_SW_MASK,
596 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 596 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
597 NAU8540_FLL_FTR_SW_FILTER); 597 NAU8540_FLL_FTR_SW_FILTER);
598 regmap_update_bits(regmap, NAU8540_REG_FLL6, 598 regmap_update_bits(regmap, NAU8540_REG_FLL6,
599 NAU8540_SDM_EN, NAU8540_SDM_EN); 599 NAU8540_SDM_EN, NAU8540_SDM_EN);
600 } else { 600 } else {
601 regmap_update_bits(regmap, NAU8540_REG_FLL5, 601 regmap_update_bits(regmap, NAU8540_REG_FLL5,
602 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 602 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
603 NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU); 603 NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU);
604 regmap_update_bits(regmap, 604 regmap_update_bits(regmap,
605 NAU8540_REG_FLL6, NAU8540_SDM_EN, 0); 605 NAU8540_REG_FLL6, NAU8540_SDM_EN, 0);
606 } 606 }
607} 607}
608 608
609/* freq_out must be 256*Fs in order to achieve the best performance */ 609/* freq_out must be 256*Fs in order to achieve the best performance */
610static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 610static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
611 unsigned int freq_in, unsigned int freq_out) 611 unsigned int freq_in, unsigned int freq_out)
612{ 612{
613 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 613 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
614 struct nau8540_fll fll_param; 614 struct nau8540_fll fll_param;
615 int ret, fs; 615 int ret, fs;
616 616
617 switch (pll_id) { 617 switch (pll_id) {
618 case NAU8540_CLK_FLL_MCLK: 618 case NAU8540_CLK_FLL_MCLK:
619 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 619 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
620 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_MCLK); 620 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_MCLK);
621 break; 621 break;
622 622
623 case NAU8540_CLK_FLL_BLK: 623 case NAU8540_CLK_FLL_BLK:
624 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 624 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
625 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_BLK); 625 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_BLK);
626 break; 626 break;
627 627
628 case NAU8540_CLK_FLL_FS: 628 case NAU8540_CLK_FLL_FS:
629 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 629 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
630 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_FS); 630 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_FS);
631 break; 631 break;
632 632
633 default: 633 default:
634 dev_err(nau8540->dev, "Invalid clock id (%d)\n", pll_id); 634 dev_err(nau8540->dev, "Invalid clock id (%d)\n", pll_id);
635 return -EINVAL; 635 return -EINVAL;
636 } 636 }
637 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n", 637 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",
638 freq_out, pll_id); 638 freq_out, pll_id);
639 639
640 fs = freq_out / 256; 640 fs = freq_out / 256;
641 ret = nau8540_calc_fll_param(freq_in, fs, &fll_param); 641 ret = nau8540_calc_fll_param(freq_in, fs, &fll_param);
642 if (ret < 0) { 642 if (ret < 0) {
643 dev_err(nau8540->dev, "Unsupported input clock %d\n", freq_in); 643 dev_err(nau8540->dev, "Unsupported input clock %d\n", freq_in);
644 return ret; 644 return ret;
645 } 645 }
646 dev_dbg(nau8540->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n", 646 dev_dbg(nau8540->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
647 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac, 647 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
648 fll_param.fll_int, fll_param.clk_ref_div); 648 fll_param.fll_int, fll_param.clk_ref_div);
649 649
650 nau8540_fll_apply(nau8540->regmap, &fll_param); 650 nau8540_fll_apply(nau8540->regmap, &fll_param);
651 mdelay(2); 651 mdelay(2);
652 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 652 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
653 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO); 653 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);
654 654
655 return 0; 655 return 0;
656} 656}
657 657
658static int nau8540_set_sysclk(struct snd_soc_codec *codec, 658static int nau8540_set_sysclk(struct snd_soc_codec *codec,
659 int clk_id, int source, unsigned int freq, int dir) 659 int clk_id, int source, unsigned int freq, int dir)
660{ 660{
661 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 661 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
662 662
663 switch (clk_id) { 663 switch (clk_id) {
664 case NAU8540_CLK_DIS: 664 case NAU8540_CLK_DIS:
665 case NAU8540_CLK_MCLK: 665 case NAU8540_CLK_MCLK:
666 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 666 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
667 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_MCLK); 667 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_MCLK);
668 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6, 668 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,
669 NAU8540_DCO_EN, 0); 669 NAU8540_DCO_EN, 0);
670 break; 670 break;
671 671
672 case NAU8540_CLK_INTERNAL: 672 case NAU8540_CLK_INTERNAL:
673 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6, 673 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,
674 NAU8540_DCO_EN, NAU8540_DCO_EN); 674 NAU8540_DCO_EN, NAU8540_DCO_EN);
675 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 675 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
676 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO); 676 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);
677 break; 677 break;
678 678
679 default: 679 default:
680 dev_err(nau8540->dev, "Invalid clock id (%d)\n", clk_id); 680 dev_err(nau8540->dev, "Invalid clock id (%d)\n", clk_id);
681 return -EINVAL; 681 return -EINVAL;
682 } 682 }
683 683
684 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n", 684 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",
685 freq, clk_id); 685 freq, clk_id);
686 686
687 return 0; 687 return 0;
688} 688}
689 689
690static void nau8540_reset_chip(struct regmap *regmap) 690static void nau8540_reset_chip(struct regmap *regmap)
691{ 691{
692 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00); 692 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);
693 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00); 693 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);
694} 694}
695 695
696static void nau8540_init_regs(struct nau8540 *nau8540) 696static void nau8540_init_regs(struct nau8540 *nau8540)
697{ 697{
698 struct regmap *regmap = nau8540->regmap; 698 struct regmap *regmap = nau8540->regmap;
699 699
700 /* Enable Bias/VMID/VMID Tieoff */ 700 /* Enable Bias/VMID/VMID Tieoff */
701 regmap_update_bits(regmap, NAU8540_REG_VMID_CTRL, 701 regmap_update_bits(regmap, NAU8540_REG_VMID_CTRL,
702 NAU8540_VMID_EN | NAU8540_VMID_SEL_MASK, 702 NAU8540_VMID_EN | NAU8540_VMID_SEL_MASK,
703 NAU8540_VMID_EN | (0x2 << NAU8540_VMID_SEL_SFT)); 703 NAU8540_VMID_EN | (0x2 << NAU8540_VMID_SEL_SFT));
704 regmap_update_bits(regmap, NAU8540_REG_REFERENCE, 704 regmap_update_bits(regmap, NAU8540_REG_REFERENCE,
705 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN, 705 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN,
706 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN); 706 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN);
707 mdelay(2); 707 mdelay(2);
708 regmap_update_bits(regmap, NAU8540_REG_MIC_BIAS, 708 regmap_update_bits(regmap, NAU8540_REG_MIC_BIAS,
709 NAU8540_PU_PRE, NAU8540_PU_PRE); 709 NAU8540_PU_PRE, NAU8540_PU_PRE);
710 regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, 710 regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,
711 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN, 711 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN,
712 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN); 712 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN);
713 /* ADC OSR selection, CLK_ADC = Fs * OSR */ 713 /* ADC OSR selection, CLK_ADC = Fs * OSR */
714 regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE, 714 regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE,
715 NAU8540_ADC_OSR_MASK, NAU8540_ADC_OSR_64); 715 NAU8540_ADC_OSR_MASK, NAU8540_ADC_OSR_64);
716} 716}
717 717
718static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec) 718static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
719{ 719{
720 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 720 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
721 721
722 regcache_cache_only(nau8540->regmap, true); 722 regcache_cache_only(nau8540->regmap, true);
723 regcache_mark_dirty(nau8540->regmap); 723 regcache_mark_dirty(nau8540->regmap);
724 724
725 return 0; 725 return 0;
726} 726}
727 727
728static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec) 728static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
729{ 729{
730 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 730 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
731 731
732 regcache_cache_only(nau8540->regmap, false); 732 regcache_cache_only(nau8540->regmap, false);
733 regcache_sync(nau8540->regmap); 733 regcache_sync(nau8540->regmap);
734 734
735 return 0; 735 return 0;
736} 736}
737 737
738static struct snd_soc_codec_driver nau8540_codec_driver = { 738static struct snd_soc_codec_driver nau8540_codec_driver = {
739 .set_sysclk = nau8540_set_sysclk, 739 .set_sysclk = nau8540_set_sysclk,
740 .set_pll = nau8540_set_pll, 740 .set_pll = nau8540_set_pll,
741 .suspend = nau8540_suspend, 741 .suspend = nau8540_suspend,
742 .resume = nau8540_resume, 742 .resume = nau8540_resume,
743 .suspend_bias_off = true, 743 .suspend_bias_off = true,
744 744
745 .component_driver = { 745 .component_driver = {
746 .controls = nau8540_snd_controls, 746 .controls = nau8540_snd_controls,
747 .num_controls = ARRAY_SIZE(nau8540_snd_controls), 747 .num_controls = ARRAY_SIZE(nau8540_snd_controls),
748 .dapm_widgets = nau8540_dapm_widgets, 748 .dapm_widgets = nau8540_dapm_widgets,
749 .num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets), 749 .num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets),
750 .dapm_routes = nau8540_dapm_routes, 750 .dapm_routes = nau8540_dapm_routes,
751 .num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes), 751 .num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes),
752 }, 752 },
753}; 753};
754 754
755static const struct regmap_config nau8540_regmap_config = { 755static const struct regmap_config nau8540_regmap_config = {
756 .val_bits = 16, 756 .val_bits = 16,
757 .reg_bits = 16, 757 .reg_bits = 16,
758 758
759 .max_register = NAU8540_REG_MAX, 759 .max_register = NAU8540_REG_MAX,
760 .readable_reg = nau8540_readable_reg, 760 .readable_reg = nau8540_readable_reg,
761 .writeable_reg = nau8540_writeable_reg, 761 .writeable_reg = nau8540_writeable_reg,
762 .volatile_reg = nau8540_volatile_reg, 762 .volatile_reg = nau8540_volatile_reg,
763 763
764 .cache_type = REGCACHE_RBTREE, 764 .cache_type = REGCACHE_RBTREE,
765 .reg_defaults = nau8540_reg_defaults, 765 .reg_defaults = nau8540_reg_defaults,
766 .num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults), 766 .num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults),
767}; 767};
768 768
769static int nau8540_i2c_probe(struct i2c_client *i2c, 769static int nau8540_i2c_probe(struct i2c_client *i2c,
770 const struct i2c_device_id *id) 770 const struct i2c_device_id *id)
771{ 771{
772 struct device *dev = &i2c->dev; 772 struct device *dev = &i2c->dev;
773 struct nau8540 *nau8540 = dev_get_platdata(dev); 773 struct nau8540 *nau8540 = dev_get_platdata(dev);
774 int ret, value; 774 int ret, value;
775 775
776 if (!nau8540) { 776 if (!nau8540) {
777 nau8540 = devm_kzalloc(dev, sizeof(*nau8540), GFP_KERNEL); 777 nau8540 = devm_kzalloc(dev, sizeof(*nau8540), GFP_KERNEL);
778 if (!nau8540) 778 if (!nau8540)
779 return -ENOMEM; 779 return -ENOMEM;
780 } 780 }
781 i2c_set_clientdata(i2c, nau8540); 781 i2c_set_clientdata(i2c, nau8540);
782 782
783 nau8540->regmap = devm_regmap_init_i2c(i2c, &nau8540_regmap_config); 783 nau8540->regmap = devm_regmap_init_i2c(i2c, &nau8540_regmap_config);
784 if (IS_ERR(nau8540->regmap)) 784 if (IS_ERR(nau8540->regmap))
785 return PTR_ERR(nau8540->regmap); 785 return PTR_ERR(nau8540->regmap);
786 ret = regmap_read(nau8540->regmap, NAU8540_REG_I2C_DEVICE_ID, &value); 786 ret = regmap_read(nau8540->regmap, NAU8540_REG_I2C_DEVICE_ID, &value);
787 if (ret < 0) { 787 if (ret < 0) {
788 dev_err(dev, "Failed to read device id from the NAU85L40: %d\n", 788 dev_err(dev, "Failed to read device id from the NAU85L40: %d\n",
789 ret); 789 ret);
790 return ret; 790 return ret;
791 } 791 }
792 792
793 nau8540->dev = dev; 793 nau8540->dev = dev;
794 nau8540_reset_chip(nau8540->regmap); 794 nau8540_reset_chip(nau8540->regmap);
795 nau8540_init_regs(nau8540); 795 nau8540_init_regs(nau8540);
796 796
797 return snd_soc_register_codec(dev, 797 return snd_soc_register_codec(dev,
798 &nau8540_codec_driver, &nau8540_dai, 1); 798 &nau8540_codec_driver, &nau8540_dai, 1);
799} 799}
800 800
801static int nau8540_i2c_remove(struct i2c_client *client) 801static int nau8540_i2c_remove(struct i2c_client *client)
802{ 802{
803 snd_soc_unregister_codec(&client->dev); 803 snd_soc_unregister_codec(&client->dev);
804 return 0; 804 return 0;
805} 805}
806 806
807 807
808static const struct i2c_device_id nau8540_i2c_ids[] = { 808static const struct i2c_device_id nau8540_i2c_ids[] = {
809 { "nau8540", 0 }, 809 { "nau8540", 0 },
810 { } 810 { }
811}; 811};
812MODULE_DEVICE_TABLE(i2c, nau8540_i2c_ids); 812MODULE_DEVICE_TABLE(i2c, nau8540_i2c_ids);
813 813
814#ifdef CONFIG_OF 814#ifdef CONFIG_OF
815static const struct of_device_id nau8540_of_ids[] = { 815static const struct of_device_id nau8540_of_ids[] = {
816 { .compatible = "nuvoton,nau8540", }, 816 { .compatible = "nuvoton,nau8540", },
817 {} 817 {}
818}; 818};
819MODULE_DEVICE_TABLE(of, nau8540_of_ids); 819MODULE_DEVICE_TABLE(of, nau8540_of_ids);
820#endif 820#endif
821 821
822static struct i2c_driver nau8540_i2c_driver = { 822static struct i2c_driver nau8540_i2c_driver = {
823 .driver = { 823 .driver = {
824 .name = "nau8540", 824 .name = "nau8540",
825 .of_match_table = of_match_ptr(nau8540_of_ids), 825 .of_match_table = of_match_ptr(nau8540_of_ids),
826 }, 826 },
827 .probe = nau8540_i2c_probe, 827 .probe = nau8540_i2c_probe,
828 .remove = nau8540_i2c_remove, 828 .remove = nau8540_i2c_remove,
829 .id_table = nau8540_i2c_ids, 829 .id_table = nau8540_i2c_ids,
830}; 830};
831module_i2c_driver(nau8540_i2c_driver); 831module_i2c_driver(nau8540_i2c_driver);
832 832
diff --git a/sound/soc/codecs/nau8540.h b/sound/soc/codecs/nau8540.h
index d06e65188cd5..5db5b224944d 100644
--- a/sound/soc/codecs/nau8540.h
+++ b/sound/soc/codecs/nau8540.h
@@ -12,211 +12,211 @@
12#ifndef __NAU8540_H__ 12#ifndef __NAU8540_H__
13#define __NAU8540_H__ 13#define __NAU8540_H__
14 14
15#define NAU8540_REG_SW_RESET 0x00 15#define NAU8540_REG_SW_RESET 0x00
16#define NAU8540_REG_POWER_MANAGEMENT 0x01 16#define NAU8540_REG_POWER_MANAGEMENT 0x01
17#define NAU8540_REG_CLOCK_CTRL 0x02 17#define NAU8540_REG_CLOCK_CTRL 0x02
18#define NAU8540_REG_CLOCK_SRC 0x03 18#define NAU8540_REG_CLOCK_SRC 0x03
19#define NAU8540_REG_FLL1 0x04 19#define NAU8540_REG_FLL1 0x04
20#define NAU8540_REG_FLL2 0x05 20#define NAU8540_REG_FLL2 0x05
21#define NAU8540_REG_FLL3 0x06 21#define NAU8540_REG_FLL3 0x06
22#define NAU8540_REG_FLL4 0x07 22#define NAU8540_REG_FLL4 0x07
23#define NAU8540_REG_FLL5 0x08 23#define NAU8540_REG_FLL5 0x08
24#define NAU8540_REG_FLL6 0x09 24#define NAU8540_REG_FLL6 0x09
25#define NAU8540_REG_FLL_VCO_RSV 0x0A 25#define NAU8540_REG_FLL_VCO_RSV 0x0A
26#define NAU8540_REG_PCM_CTRL0 0x10 26#define NAU8540_REG_PCM_CTRL0 0x10
27#define NAU8540_REG_PCM_CTRL1 0x11 27#define NAU8540_REG_PCM_CTRL1 0x11
28#define NAU8540_REG_PCM_CTRL2 0x12 28#define NAU8540_REG_PCM_CTRL2 0x12
29#define NAU8540_REG_PCM_CTRL3 0x13 29#define NAU8540_REG_PCM_CTRL3 0x13
30#define NAU8540_REG_PCM_CTRL4 0x14 30#define NAU8540_REG_PCM_CTRL4 0x14
31#define NAU8540_REG_ALC_CONTROL_1 0x20 31#define NAU8540_REG_ALC_CONTROL_1 0x20
32#define NAU8540_REG_ALC_CONTROL_2 0x21 32#define NAU8540_REG_ALC_CONTROL_2 0x21
33#define NAU8540_REG_ALC_CONTROL_3 0x22 33#define NAU8540_REG_ALC_CONTROL_3 0x22
34#define NAU8540_REG_ALC_CONTROL_4 0x23 34#define NAU8540_REG_ALC_CONTROL_4 0x23
35#define NAU8540_REG_ALC_CONTROL_5 0x24 35#define NAU8540_REG_ALC_CONTROL_5 0x24
36#define NAU8540_REG_ALC_GAIN_CH12 0x2D 36#define NAU8540_REG_ALC_GAIN_CH12 0x2D
37#define NAU8540_REG_ALC_GAIN_CH34 0x2E 37#define NAU8540_REG_ALC_GAIN_CH34 0x2E
38#define NAU8540_REG_ALC_STATUS 0x2F 38#define NAU8540_REG_ALC_STATUS 0x2F
39#define NAU8540_REG_NOTCH_FIL1_CH1 0x30 39#define NAU8540_REG_NOTCH_FIL1_CH1 0x30
40#define NAU8540_REG_NOTCH_FIL2_CH1 0x31 40#define NAU8540_REG_NOTCH_FIL2_CH1 0x31
41#define NAU8540_REG_NOTCH_FIL1_CH2 0x32 41#define NAU8540_REG_NOTCH_FIL1_CH2 0x32
42#define NAU8540_REG_NOTCH_FIL2_CH2 0x33 42#define NAU8540_REG_NOTCH_FIL2_CH2 0x33
43#define NAU8540_REG_NOTCH_FIL1_CH3 0x34 43#define NAU8540_REG_NOTCH_FIL1_CH3 0x34
44#define NAU8540_REG_NOTCH_FIL2_CH3 0x35 44#define NAU8540_REG_NOTCH_FIL2_CH3 0x35
45#define NAU8540_REG_NOTCH_FIL1_CH4 0x36 45#define NAU8540_REG_NOTCH_FIL1_CH4 0x36
46#define NAU8540_REG_NOTCH_FIL2_CH4 0x37 46#define NAU8540_REG_NOTCH_FIL2_CH4 0x37
47#define NAU8540_REG_HPF_FILTER_CH12 0x38 47#define NAU8540_REG_HPF_FILTER_CH12 0x38
48#define NAU8540_REG_HPF_FILTER_CH34 0x39 48#define NAU8540_REG_HPF_FILTER_CH34 0x39
49#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A 49#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A
50#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40 50#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40
51#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41 51#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41
52#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42 52#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42
53#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43 53#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43
54#define NAU8540_REG_DIGITAL_MUX 0x44 54#define NAU8540_REG_DIGITAL_MUX 0x44
55#define NAU8540_REG_P2P_CH1 0x48 55#define NAU8540_REG_P2P_CH1 0x48
56#define NAU8540_REG_P2P_CH2 0x49 56#define NAU8540_REG_P2P_CH2 0x49
57#define NAU8540_REG_P2P_CH3 0x4A 57#define NAU8540_REG_P2P_CH3 0x4A
58#define NAU8540_REG_P2P_CH4 0x4B 58#define NAU8540_REG_P2P_CH4 0x4B
59#define NAU8540_REG_PEAK_CH1 0x4C 59#define NAU8540_REG_PEAK_CH1 0x4C
60#define NAU8540_REG_PEAK_CH2 0x4D 60#define NAU8540_REG_PEAK_CH2 0x4D
61#define NAU8540_REG_PEAK_CH3 0x4E 61#define NAU8540_REG_PEAK_CH3 0x4E
62#define NAU8540_REG_PEAK_CH4 0x4F 62#define NAU8540_REG_PEAK_CH4 0x4F
63#define NAU8540_REG_GPIO_CTRL 0x50 63#define NAU8540_REG_GPIO_CTRL 0x50
64#define NAU8540_REG_MISC_CTRL 0x51 64#define NAU8540_REG_MISC_CTRL 0x51
65#define NAU8540_REG_I2C_CTRL 0x52 65#define NAU8540_REG_I2C_CTRL 0x52
66#define NAU8540_REG_I2C_DEVICE_ID 0x58 66#define NAU8540_REG_I2C_DEVICE_ID 0x58
67#define NAU8540_REG_RST 0x5A 67#define NAU8540_REG_RST 0x5A
68#define NAU8540_REG_VMID_CTRL 0x60 68#define NAU8540_REG_VMID_CTRL 0x60
69#define NAU8540_REG_MUTE 0x61 69#define NAU8540_REG_MUTE 0x61
70#define NAU8540_REG_ANALOG_ADC1 0x64 70#define NAU8540_REG_ANALOG_ADC1 0x64
71#define NAU8540_REG_ANALOG_ADC2 0x65 71#define NAU8540_REG_ANALOG_ADC2 0x65
72#define NAU8540_REG_ANALOG_PWR 0x66 72#define NAU8540_REG_ANALOG_PWR 0x66
73#define NAU8540_REG_MIC_BIAS 0x67 73#define NAU8540_REG_MIC_BIAS 0x67
74#define NAU8540_REG_REFERENCE 0x68 74#define NAU8540_REG_REFERENCE 0x68
75#define NAU8540_REG_FEPGA1 0x69 75#define NAU8540_REG_FEPGA1 0x69
76#define NAU8540_REG_FEPGA2 0x6A 76#define NAU8540_REG_FEPGA2 0x6A
77#define NAU8540_REG_FEPGA3 0x6B 77#define NAU8540_REG_FEPGA3 0x6B
78#define NAU8540_REG_FEPGA4 0x6C 78#define NAU8540_REG_FEPGA4 0x6C
79#define NAU8540_REG_PWR 0x6D 79#define NAU8540_REG_PWR 0x6D
80#define NAU8540_REG_MAX NAU8540_REG_PWR 80#define NAU8540_REG_MAX NAU8540_REG_PWR
81 81
82 82
83/* POWER_MANAGEMENT (0x01) */ 83/* POWER_MANAGEMENT (0x01) */
84#define NAU8540_ADC4_EN (0x1 << 3) 84#define NAU8540_ADC4_EN (0x1 << 3)
85#define NAU8540_ADC3_EN (0x1 << 2) 85#define NAU8540_ADC3_EN (0x1 << 2)
86#define NAU8540_ADC2_EN (0x1 << 1) 86#define NAU8540_ADC2_EN (0x1 << 1)
87#define NAU8540_ADC1_EN 0x1 87#define NAU8540_ADC1_EN 0x1
88 88
89/* CLOCK_CTRL (0x02) */ 89/* CLOCK_CTRL (0x02) */
90#define NAU8540_CLK_ADC_EN (0x1 << 15) 90#define NAU8540_CLK_ADC_EN (0x1 << 15)
91#define NAU8540_CLK_I2S_EN (0x1 << 1) 91#define NAU8540_CLK_I2S_EN (0x1 << 1)
92 92
93/* CLOCK_SRC (0x03) */ 93/* CLOCK_SRC (0x03) */
94#define NAU8540_CLK_SRC_SFT 15 94#define NAU8540_CLK_SRC_SFT 15
95#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT) 95#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT)
96#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT) 96#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT)
97#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT) 97#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT)
98#define NAU8540_CLK_ADC_SRC_SFT 6 98#define NAU8540_CLK_ADC_SRC_SFT 6
99#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT) 99#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT)
100#define NAU8540_CLK_MCLK_SRC_MASK 0xf 100#define NAU8540_CLK_MCLK_SRC_MASK 0xf
101 101
102/* FLL1 (0x04) */ 102/* FLL1 (0x04) */
103#define NAU8540_FLL_RATIO_MASK 0x7f 103#define NAU8540_FLL_RATIO_MASK 0x7f
104 104
105/* FLL3 (0x06) */ 105/* FLL3 (0x06) */
106#define NAU8540_FLL_CLK_SRC_SFT 10 106#define NAU8540_FLL_CLK_SRC_SFT 10
107#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT) 107#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT)
108#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT) 108#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT)
109#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT) 109#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT)
110#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT) 110#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT)
111#define NAU8540_FLL_INTEGER_MASK 0x3ff 111#define NAU8540_FLL_INTEGER_MASK 0x3ff
112 112
113/* FLL4 (0x07) */ 113/* FLL4 (0x07) */
114#define NAU8540_FLL_REF_DIV_SFT 10 114#define NAU8540_FLL_REF_DIV_SFT 10
115#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT) 115#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT)
116 116
117/* FLL5 (0x08) */ 117/* FLL5 (0x08) */
118#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15) 118#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15)
119#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14) 119#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14)
120#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13) 120#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13)
121#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13) 121#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13)
122#define NAU8540_FLL_CLK_SW_REF (0x0 << 13) 122#define NAU8540_FLL_CLK_SW_REF (0x0 << 13)
123#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12) 123#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12)
124#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12) 124#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12)
125#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12) 125#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12)
126 126
127/* FLL6 (0x9) */ 127/* FLL6 (0x9) */
128#define NAU8540_DCO_EN (0x1 << 15) 128#define NAU8540_DCO_EN (0x1 << 15)
129#define NAU8540_SDM_EN (0x1 << 14) 129#define NAU8540_SDM_EN (0x1 << 14)
130 130
131/* PCM_CTRL0 (0x10) */ 131/* PCM_CTRL0 (0x10) */
132#define NAU8540_I2S_BP_SFT 7 132#define NAU8540_I2S_BP_SFT 7
133#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT) 133#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT)
134#define NAU8540_I2S_PCMB_SFT 6 134#define NAU8540_I2S_PCMB_SFT 6
135#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT) 135#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT)
136#define NAU8540_I2S_DL_SFT 2 136#define NAU8540_I2S_DL_SFT 2
137#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT) 137#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT)
138#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT) 138#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT)
139#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT) 139#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT)
140#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT) 140#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT)
141#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT) 141#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT)
142#define NAU8540_I2S_DF_MASK 0x3 142#define NAU8540_I2S_DF_MASK 0x3
143#define NAU8540_I2S_DF_RIGTH 0 143#define NAU8540_I2S_DF_RIGTH 0
144#define NAU8540_I2S_DF_LEFT 0x1 144#define NAU8540_I2S_DF_LEFT 0x1
145#define NAU8540_I2S_DF_I2S 0x2 145#define NAU8540_I2S_DF_I2S 0x2
146#define NAU8540_I2S_DF_PCM_AB 0x3 146#define NAU8540_I2S_DF_PCM_AB 0x3
147 147
148/* PCM_CTRL1 (0x11) */ 148/* PCM_CTRL1 (0x11) */
149#define NAU8540_I2S_LRC_DIV_SFT 12 149#define NAU8540_I2S_LRC_DIV_SFT 12
150#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT) 150#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT)
151#define NAU8540_I2S_DO12_OE (0x1 << 4) 151#define NAU8540_I2S_DO12_OE (0x1 << 4)
152#define NAU8540_I2S_MS_SFT 3 152#define NAU8540_I2S_MS_SFT 3
153#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT) 153#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT)
154#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT) 154#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT)
155#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT) 155#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT)
156#define NAU8540_I2S_BLK_DIV_MASK 0x7 156#define NAU8540_I2S_BLK_DIV_MASK 0x7
157 157
158/* PCM_CTRL1 (0x12) */ 158/* PCM_CTRL1 (0x12) */
159#define NAU8540_I2S_DO34_OE (0x1 << 11) 159#define NAU8540_I2S_DO34_OE (0x1 << 11)
160#define NAU8540_I2S_TSLOT_L_MASK 0x3ff 160#define NAU8540_I2S_TSLOT_L_MASK 0x3ff
161 161
162/* PCM_CTRL4 (0x14) */ 162/* PCM_CTRL4 (0x14) */
163#define NAU8540_TDM_MODE (0x1 << 15) 163#define NAU8540_TDM_MODE (0x1 << 15)
164#define NAU8540_TDM_OFFSET_EN (0x1 << 14) 164#define NAU8540_TDM_OFFSET_EN (0x1 << 14)
165#define NAU8540_TDM_TX_MASK 0xf 165#define NAU8540_TDM_TX_MASK 0xf
166 166
167/* ADC_SAMPLE_RATE (0x3A) */ 167/* ADC_SAMPLE_RATE (0x3A) */
168#define NAU8540_ADC_OSR_MASK 0x3 168#define NAU8540_ADC_OSR_MASK 0x3
169#define NAU8540_ADC_OSR_256 0x3 169#define NAU8540_ADC_OSR_256 0x3
170#define NAU8540_ADC_OSR_128 0x2 170#define NAU8540_ADC_OSR_128 0x2
171#define NAU8540_ADC_OSR_64 0x1 171#define NAU8540_ADC_OSR_64 0x1
172#define NAU8540_ADC_OSR_32 0x0 172#define NAU8540_ADC_OSR_32 0x0
173 173
174/* VMID_CTRL (0x60) */ 174/* VMID_CTRL (0x60) */
175#define NAU8540_VMID_EN (1 << 6) 175#define NAU8540_VMID_EN (1 << 6)
176#define NAU8540_VMID_SEL_SFT 4 176#define NAU8540_VMID_SEL_SFT 4
177#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT) 177#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
178 178
179/* MIC_BIAS (0x67) */ 179/* MIC_BIAS (0x67) */
180#define NAU8540_PU_PRE (0x1 << 8) 180#define NAU8540_PU_PRE (0x1 << 8)
181 181
182/* REFERENCE (0x68) */ 182/* REFERENCE (0x68) */
183#define NAU8540_PRECHARGE_DIS (0x1 << 13) 183#define NAU8540_PRECHARGE_DIS (0x1 << 13)
184#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) 184#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12)
185 185
186 186
187/* System Clock Source */ 187/* System Clock Source */
188enum { 188enum {
189 NAU8540_CLK_DIS, 189 NAU8540_CLK_DIS,
190 NAU8540_CLK_MCLK, 190 NAU8540_CLK_MCLK,
191 NAU8540_CLK_INTERNAL, 191 NAU8540_CLK_INTERNAL,
192 NAU8540_CLK_FLL_MCLK, 192 NAU8540_CLK_FLL_MCLK,
193 NAU8540_CLK_FLL_BLK, 193 NAU8540_CLK_FLL_BLK,
194 NAU8540_CLK_FLL_FS, 194 NAU8540_CLK_FLL_FS,
195}; 195};
196 196
197struct nau8540 { 197struct nau8540 {
198 struct device *dev; 198 struct device *dev;
199 struct regmap *regmap; 199 struct regmap *regmap;
200}; 200};
201 201
202struct nau8540_fll { 202struct nau8540_fll {
203 int mclk_src; 203 int mclk_src;
204 int ratio; 204 int ratio;
205 int fll_frac; 205 int fll_frac;
206 int fll_int; 206 int fll_int;
207 int clk_ref_div; 207 int clk_ref_div;
208}; 208};
209 209
210struct nau8540_fll_attr { 210struct nau8540_fll_attr {
211 unsigned int param; 211 unsigned int param;
212 unsigned int val; 212 unsigned int val;
213}; 213};
214 214
215/* over sampling rate */ 215/* over sampling rate */
216struct nau8540_osr_attr { 216struct nau8540_osr_attr {
217 unsigned int osr; 217 unsigned int osr;
218 unsigned int clk_src; 218 unsigned int clk_src;
219}; 219};
220 220
221 221
222#endif /* __NAU8540_H__ */ 222#endif /* __NAU8540_H__ */
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c
new file mode 100644
index 000000000000..cca974d26136
--- /dev/null
+++ b/sound/soc/codecs/nau8824.c
@@ -0,0 +1,1831 @@
1/*
2 * NAU88L24 ALSA SoC audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 * Author: John Hsu <KCHSU0@nuvoton.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/clk.h>
19#include <linux/acpi.h>
20#include <linux/math64.h>
21#include <linux/semaphore.h>
22
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30
31#include "nau8824.h"
32
33
34static int nau8824_config_sysclk(struct nau8824 *nau8824,
35 int clk_id, unsigned int freq);
36static bool nau8824_is_jack_inserted(struct nau8824 *nau8824);
37
38/* the ADC threshold of headset */
39#define DMIC_CLK 3072000
40
41/* the ADC threshold of headset */
42#define HEADSET_SARADC_THD 0x80
43
44/* the parameter threshold of FLL */
45#define NAU_FREF_MAX 13500000
46#define NAU_FVCO_MAX 124000000
47#define NAU_FVCO_MIN 90000000
48
49/* scaling for mclk from sysclk_src output */
50static const struct nau8824_fll_attr mclk_src_scaling[] = {
51 { 1, 0x0 },
52 { 2, 0x2 },
53 { 4, 0x3 },
54 { 8, 0x4 },
55 { 16, 0x5 },
56 { 32, 0x6 },
57 { 3, 0x7 },
58 { 6, 0xa },
59 { 12, 0xb },
60 { 24, 0xc },
61};
62
63/* ratio for input clk freq */
64static const struct nau8824_fll_attr fll_ratio[] = {
65 { 512000, 0x01 },
66 { 256000, 0x02 },
67 { 128000, 0x04 },
68 { 64000, 0x08 },
69 { 32000, 0x10 },
70 { 8000, 0x20 },
71 { 4000, 0x40 },
72};
73
74static const struct nau8824_fll_attr fll_pre_scalar[] = {
75 { 1, 0x0 },
76 { 2, 0x1 },
77 { 4, 0x2 },
78 { 8, 0x3 },
79};
80
81/* the maximum frequency of CLK_ADC and CLK_DAC */
82#define CLK_DA_AD_MAX 6144000
83
84/* over sampling rate */
85static const struct nau8824_osr_attr osr_dac_sel[] = {
86 { 64, 2 }, /* OSR 64, SRC 1/4 */
87 { 256, 0 }, /* OSR 256, SRC 1 */
88 { 128, 1 }, /* OSR 128, SRC 1/2 */
89 { 0, 0 },
90 { 32, 3 }, /* OSR 32, SRC 1/8 */
91};
92
93static const struct nau8824_osr_attr osr_adc_sel[] = {
94 { 32, 3 }, /* OSR 32, SRC 1/8 */
95 { 64, 2 }, /* OSR 64, SRC 1/4 */
96 { 128, 1 }, /* OSR 128, SRC 1/2 */
97 { 256, 0 }, /* OSR 256, SRC 1 */
98};
99
100static const struct reg_default nau8824_reg_defaults[] = {
101 { NAU8824_REG_ENA_CTRL, 0x0000 },
102 { NAU8824_REG_CLK_GATING_ENA, 0x0000 },
103 { NAU8824_REG_CLK_DIVIDER, 0x0000 },
104 { NAU8824_REG_FLL1, 0x0000 },
105 { NAU8824_REG_FLL2, 0x3126 },
106 { NAU8824_REG_FLL3, 0x0008 },
107 { NAU8824_REG_FLL4, 0x0010 },
108 { NAU8824_REG_FLL5, 0xC000 },
109 { NAU8824_REG_FLL6, 0x6000 },
110 { NAU8824_REG_FLL_VCO_RSV, 0xF13C },
111 { NAU8824_REG_JACK_DET_CTRL, 0x0000 },
112 { NAU8824_REG_INTERRUPT_SETTING_1, 0x0000 },
113 { NAU8824_REG_IRQ, 0x0000 },
114 { NAU8824_REG_CLEAR_INT_REG, 0x0000 },
115 { NAU8824_REG_INTERRUPT_SETTING, 0x1000 },
116 { NAU8824_REG_SAR_ADC, 0x0015 },
117 { NAU8824_REG_VDET_COEFFICIENT, 0x0110 },
118 { NAU8824_REG_VDET_THRESHOLD_1, 0x0000 },
119 { NAU8824_REG_VDET_THRESHOLD_2, 0x0000 },
120 { NAU8824_REG_VDET_THRESHOLD_3, 0x0000 },
121 { NAU8824_REG_VDET_THRESHOLD_4, 0x0000 },
122 { NAU8824_REG_GPIO_SEL, 0x0000 },
123 { NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 0x000B },
124 { NAU8824_REG_PORT0_I2S_PCM_CTRL_2, 0x0010 },
125 { NAU8824_REG_PORT0_LEFT_TIME_SLOT, 0x0000 },
126 { NAU8824_REG_PORT0_RIGHT_TIME_SLOT, 0x0000 },
127 { NAU8824_REG_TDM_CTRL, 0x0000 },
128 { NAU8824_REG_ADC_HPF_FILTER, 0x0000 },
129 { NAU8824_REG_ADC_FILTER_CTRL, 0x0002 },
130 { NAU8824_REG_DAC_FILTER_CTRL_1, 0x0000 },
131 { NAU8824_REG_DAC_FILTER_CTRL_2, 0x0000 },
132 { NAU8824_REG_NOTCH_FILTER_1, 0x0000 },
133 { NAU8824_REG_NOTCH_FILTER_2, 0x0000 },
134 { NAU8824_REG_EQ1_LOW, 0x112C },
135 { NAU8824_REG_EQ2_EQ3, 0x2C2C },
136 { NAU8824_REG_EQ4_EQ5, 0x2C2C },
137 { NAU8824_REG_ADC_CH0_DGAIN_CTRL, 0x0100 },
138 { NAU8824_REG_ADC_CH1_DGAIN_CTRL, 0x0100 },
139 { NAU8824_REG_ADC_CH2_DGAIN_CTRL, 0x0100 },
140 { NAU8824_REG_ADC_CH3_DGAIN_CTRL, 0x0100 },
141 { NAU8824_REG_DAC_MUTE_CTRL, 0x0000 },
142 { NAU8824_REG_DAC_CH0_DGAIN_CTRL, 0x0100 },
143 { NAU8824_REG_DAC_CH1_DGAIN_CTRL, 0x0100 },
144 { NAU8824_REG_ADC_TO_DAC_ST, 0x0000 },
145 { NAU8824_REG_DRC_KNEE_IP12_ADC_CH01, 0x1486 },
146 { NAU8824_REG_DRC_KNEE_IP34_ADC_CH01, 0x0F12 },
147 { NAU8824_REG_DRC_SLOPE_ADC_CH01, 0x25FF },
148 { NAU8824_REG_DRC_ATKDCY_ADC_CH01, 0x3457 },
149 { NAU8824_REG_DRC_KNEE_IP12_ADC_CH23, 0x1486 },
150 { NAU8824_REG_DRC_KNEE_IP34_ADC_CH23, 0x0F12 },
151 { NAU8824_REG_DRC_SLOPE_ADC_CH23, 0x25FF },
152 { NAU8824_REG_DRC_ATKDCY_ADC_CH23, 0x3457 },
153 { NAU8824_REG_DRC_GAINL_ADC0, 0x0200 },
154 { NAU8824_REG_DRC_GAINL_ADC1, 0x0200 },
155 { NAU8824_REG_DRC_GAINL_ADC2, 0x0200 },
156 { NAU8824_REG_DRC_GAINL_ADC3, 0x0200 },
157 { NAU8824_REG_DRC_KNEE_IP12_DAC, 0x1486 },
158 { NAU8824_REG_DRC_KNEE_IP34_DAC, 0x0F12 },
159 { NAU8824_REG_DRC_SLOPE_DAC, 0x25F9 },
160 { NAU8824_REG_DRC_ATKDCY_DAC, 0x3457 },
161 { NAU8824_REG_DRC_GAIN_DAC_CH0, 0x0200 },
162 { NAU8824_REG_DRC_GAIN_DAC_CH1, 0x0200 },
163 { NAU8824_REG_MODE, 0x0000 },
164 { NAU8824_REG_MODE1, 0x0000 },
165 { NAU8824_REG_MODE2, 0x0000 },
166 { NAU8824_REG_CLASSG, 0x0000 },
167 { NAU8824_REG_OTP_EFUSE, 0x0000 },
168 { NAU8824_REG_OTPDOUT_1, 0x0000 },
169 { NAU8824_REG_OTPDOUT_2, 0x0000 },
170 { NAU8824_REG_MISC_CTRL, 0x0000 },
171 { NAU8824_REG_I2C_TIMEOUT, 0xEFFF },
172 { NAU8824_REG_TEST_MODE, 0x0000 },
173 { NAU8824_REG_I2C_DEVICE_ID, 0x1AF1 },
174 { NAU8824_REG_SAR_ADC_DATA_OUT, 0x00FF },
175 { NAU8824_REG_BIAS_ADJ, 0x0000 },
176 { NAU8824_REG_PGA_GAIN, 0x0000 },
177 { NAU8824_REG_TRIM_SETTINGS, 0x0000 },
178 { NAU8824_REG_ANALOG_CONTROL_1, 0x0000 },
179 { NAU8824_REG_ANALOG_CONTROL_2, 0x0000 },
180 { NAU8824_REG_ENABLE_LO, 0x0000 },
181 { NAU8824_REG_GAIN_LO, 0x0000 },
182 { NAU8824_REG_CLASSD_GAIN_1, 0x0000 },
183 { NAU8824_REG_CLASSD_GAIN_2, 0x0000 },
184 { NAU8824_REG_ANALOG_ADC_1, 0x0011 },
185 { NAU8824_REG_ANALOG_ADC_2, 0x0020 },
186 { NAU8824_REG_RDAC, 0x0008 },
187 { NAU8824_REG_MIC_BIAS, 0x0006 },
188 { NAU8824_REG_HS_VOLUME_CONTROL, 0x0000 },
189 { NAU8824_REG_BOOST, 0x0000 },
190 { NAU8824_REG_FEPGA, 0x0000 },
191 { NAU8824_REG_FEPGA_II, 0x0000 },
192 { NAU8824_REG_FEPGA_SE, 0x0000 },
193 { NAU8824_REG_FEPGA_ATTENUATION, 0x0000 },
194 { NAU8824_REG_ATT_PORT0, 0x0000 },
195 { NAU8824_REG_ATT_PORT1, 0x0000 },
196 { NAU8824_REG_POWER_UP_CONTROL, 0x0000 },
197 { NAU8824_REG_CHARGE_PUMP_CONTROL, 0x0300 },
198 { NAU8824_REG_CHARGE_PUMP_INPUT, 0x0013 },
199};
200
201static int nau8824_sema_acquire(struct nau8824 *nau8824, long timeout)
202{
203 int ret;
204
205 if (timeout) {
206 ret = down_timeout(&nau8824->jd_sem, timeout);
207 if (ret < 0)
208 dev_warn(nau8824->dev, "Acquire semaphone timeout\n");
209 } else {
210 ret = down_interruptible(&nau8824->jd_sem);
211 if (ret < 0)
212 dev_warn(nau8824->dev, "Acquire semaphone fail\n");
213 }
214
215 return ret;
216}
217
218static inline void nau8824_sema_release(struct nau8824 *nau8824)
219{
220 up(&nau8824->jd_sem);
221}
222
223static bool nau8824_readable_reg(struct device *dev, unsigned int reg)
224{
225 switch (reg) {
226 case NAU8824_REG_ENA_CTRL ... NAU8824_REG_FLL_VCO_RSV:
227 case NAU8824_REG_JACK_DET_CTRL:
228 case NAU8824_REG_INTERRUPT_SETTING_1:
229 case NAU8824_REG_IRQ:
230 case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4:
231 case NAU8824_REG_GPIO_SEL:
232 case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL:
233 case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5:
234 case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST:
235 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 ... NAU8824_REG_DRC_GAINL_ADC3:
236 case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_GAIN_DAC_CH1:
237 case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE:
238 case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2:
239 case NAU8824_REG_I2C_TIMEOUT:
240 case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT:
241 case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2:
242 case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1:
243 case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_INPUT:
244 return true;
245 default:
246 return false;
247 }
248
249}
250
251static bool nau8824_writeable_reg(struct device *dev, unsigned int reg)
252{
253 switch (reg) {
254 case NAU8824_REG_RESET ... NAU8824_REG_FLL_VCO_RSV:
255 case NAU8824_REG_JACK_DET_CTRL:
256 case NAU8824_REG_INTERRUPT_SETTING_1:
257 case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4:
258 case NAU8824_REG_GPIO_SEL:
259 case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL:
260 case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5:
261 case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST:
262 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01:
263 case NAU8824_REG_DRC_KNEE_IP34_ADC_CH01:
264 case NAU8824_REG_DRC_SLOPE_ADC_CH01:
265 case NAU8824_REG_DRC_ATKDCY_ADC_CH01:
266 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH23:
267 case NAU8824_REG_DRC_KNEE_IP34_ADC_CH23:
268 case NAU8824_REG_DRC_SLOPE_ADC_CH23:
269 case NAU8824_REG_DRC_ATKDCY_ADC_CH23:
270 case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_ATKDCY_DAC:
271 case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE:
272 case NAU8824_REG_I2C_TIMEOUT:
273 case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2:
274 case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1:
275 case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_CONTROL:
276 return true;
277 default:
278 return false;
279 }
280}
281
282static bool nau8824_volatile_reg(struct device *dev, unsigned int reg)
283{
284 switch (reg) {
285 case NAU8824_REG_RESET:
286 case NAU8824_REG_IRQ ... NAU8824_REG_CLEAR_INT_REG:
287 case NAU8824_REG_DRC_GAINL_ADC0 ... NAU8824_REG_DRC_GAINL_ADC3:
288 case NAU8824_REG_DRC_GAIN_DAC_CH0 ... NAU8824_REG_DRC_GAIN_DAC_CH1:
289 case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2:
290 case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT:
291 case NAU8824_REG_CHARGE_PUMP_INPUT:
292 return true;
293 default:
294 return false;
295 }
296}
297
298static const char * const nau8824_companding[] = {
299 "Off", "NC", "u-law", "A-law" };
300
301static const struct soc_enum nau8824_companding_adc_enum =
302 SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 12,
303 ARRAY_SIZE(nau8824_companding), nau8824_companding);
304
305static const struct soc_enum nau8824_companding_dac_enum =
306 SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 14,
307 ARRAY_SIZE(nau8824_companding), nau8824_companding);
308
309static const char * const nau8824_adc_decimation[] = {
310 "32", "64", "128", "256" };
311
312static const struct soc_enum nau8824_adc_decimation_enum =
313 SOC_ENUM_SINGLE(NAU8824_REG_ADC_FILTER_CTRL, 0,
314 ARRAY_SIZE(nau8824_adc_decimation), nau8824_adc_decimation);
315
316static const char * const nau8824_dac_oversampl[] = {
317 "64", "256", "128", "", "32" };
318
319static const struct soc_enum nau8824_dac_oversampl_enum =
320 SOC_ENUM_SINGLE(NAU8824_REG_DAC_FILTER_CTRL_1, 0,
321 ARRAY_SIZE(nau8824_dac_oversampl), nau8824_dac_oversampl);
322
323static const char * const nau8824_input_channel[] = {
324 "Input CH0", "Input CH1", "Input CH2", "Input CH3" };
325
326static const struct soc_enum nau8824_adc_ch0_enum =
327 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH0_DGAIN_CTRL, 9,
328 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
329
330static const struct soc_enum nau8824_adc_ch1_enum =
331 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH1_DGAIN_CTRL, 9,
332 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
333
334static const struct soc_enum nau8824_adc_ch2_enum =
335 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH2_DGAIN_CTRL, 9,
336 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
337
338static const struct soc_enum nau8824_adc_ch3_enum =
339 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH3_DGAIN_CTRL, 9,
340 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
341
342static const char * const nau8824_tdm_slot[] = {
343 "Slot 0", "Slot 1", "Slot 2", "Slot 3" };
344
345static const struct soc_enum nau8824_dac_left_sel_enum =
346 SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 6,
347 ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot);
348
349static const struct soc_enum nau8824_dac_right_sel_enum =
350 SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 4,
351 ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot);
352
353static const DECLARE_TLV_DB_MINMAX_MUTE(spk_vol_tlv, 0, 2400);
354static const DECLARE_TLV_DB_MINMAX(hp_vol_tlv, -3000, 0);
355static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 200, 0);
356static const DECLARE_TLV_DB_SCALE(dmic_vol_tlv, -12800, 50, 0);
357
358static const struct snd_kcontrol_new nau8824_snd_controls[] = {
359 SOC_ENUM("ADC Companding", nau8824_companding_adc_enum),
360 SOC_ENUM("DAC Companding", nau8824_companding_dac_enum),
361
362 SOC_ENUM("ADC Decimation Rate", nau8824_adc_decimation_enum),
363 SOC_ENUM("DAC Oversampling Rate", nau8824_dac_oversampl_enum),
364
365 SOC_SINGLE_TLV("Speaker Right DACR Volume",
366 NAU8824_REG_CLASSD_GAIN_1, 8, 0x1f, 0, spk_vol_tlv),
367 SOC_SINGLE_TLV("Speaker Left DACL Volume",
368 NAU8824_REG_CLASSD_GAIN_2, 0, 0x1f, 0, spk_vol_tlv),
369 SOC_SINGLE_TLV("Speaker Left DACR Volume",
370 NAU8824_REG_CLASSD_GAIN_1, 0, 0x1f, 0, spk_vol_tlv),
371 SOC_SINGLE_TLV("Speaker Right DACL Volume",
372 NAU8824_REG_CLASSD_GAIN_2, 8, 0x1f, 0, spk_vol_tlv),
373
374 SOC_SINGLE_TLV("Headphone Right DACR Volume",
375 NAU8824_REG_ATT_PORT0, 8, 0x1f, 0, hp_vol_tlv),
376 SOC_SINGLE_TLV("Headphone Left DACL Volume",
377 NAU8824_REG_ATT_PORT0, 0, 0x1f, 0, hp_vol_tlv),
378 SOC_SINGLE_TLV("Headphone Right DACL Volume",
379 NAU8824_REG_ATT_PORT1, 8, 0x1f, 0, hp_vol_tlv),
380 SOC_SINGLE_TLV("Headphone Left DACR Volume",
381 NAU8824_REG_ATT_PORT1, 0, 0x1f, 0, hp_vol_tlv),
382
383 SOC_SINGLE_TLV("MIC1 Volume", NAU8824_REG_FEPGA_II,
384 NAU8824_FEPGA_GAINL_SFT, 0x12, 0, mic_vol_tlv),
385 SOC_SINGLE_TLV("MIC2 Volume", NAU8824_REG_FEPGA_II,
386 NAU8824_FEPGA_GAINR_SFT, 0x12, 0, mic_vol_tlv),
387
388 SOC_SINGLE_TLV("DMIC1 Volume", NAU8824_REG_ADC_CH0_DGAIN_CTRL,
389 0, 0x164, 0, dmic_vol_tlv),
390 SOC_SINGLE_TLV("DMIC2 Volume", NAU8824_REG_ADC_CH1_DGAIN_CTRL,
391 0, 0x164, 0, dmic_vol_tlv),
392 SOC_SINGLE_TLV("DMIC3 Volume", NAU8824_REG_ADC_CH2_DGAIN_CTRL,
393 0, 0x164, 0, dmic_vol_tlv),
394 SOC_SINGLE_TLV("DMIC4 Volume", NAU8824_REG_ADC_CH3_DGAIN_CTRL,
395 0, 0x164, 0, dmic_vol_tlv),
396
397 SOC_ENUM("ADC CH0 Select", nau8824_adc_ch0_enum),
398 SOC_ENUM("ADC CH1 Select", nau8824_adc_ch1_enum),
399 SOC_ENUM("ADC CH2 Select", nau8824_adc_ch2_enum),
400 SOC_ENUM("ADC CH3 Select", nau8824_adc_ch3_enum),
401
402 SOC_SINGLE("ADC CH0 TX Switch", NAU8824_REG_TDM_CTRL, 0, 1, 0),
403 SOC_SINGLE("ADC CH1 TX Switch", NAU8824_REG_TDM_CTRL, 1, 1, 0),
404 SOC_SINGLE("ADC CH2 TX Switch", NAU8824_REG_TDM_CTRL, 2, 1, 0),
405 SOC_SINGLE("ADC CH3 TX Switch", NAU8824_REG_TDM_CTRL, 3, 1, 0),
406
407 SOC_ENUM("DACL Channel Source", nau8824_dac_left_sel_enum),
408 SOC_ENUM("DACR Channel Source", nau8824_dac_right_sel_enum),
409
410 SOC_SINGLE("DACL LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 0, 1, 0),
411 SOC_SINGLE("DACR LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 1, 1, 0),
412};
413
414static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
415 struct snd_kcontrol *kcontrol, int event)
416{
417 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
418 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
419
420 switch (event) {
421 case SND_SOC_DAPM_PRE_PMU:
422 /* Disables the TESTDAC to let DAC signal pass through. */
423 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO,
424 NAU8824_TEST_DAC_EN, 0);
425 break;
426 case SND_SOC_DAPM_POST_PMD:
427 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO,
428 NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN);
429 break;
430 default:
431 return -EINVAL;
432 }
433
434 return 0;
435}
436
437static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
438 struct snd_kcontrol *kcontrol, int event)
439{
440 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
441 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
442
443 switch (event) {
444 case SND_SOC_DAPM_PRE_PMU:
445 regmap_update_bits(nau8824->regmap,
446 NAU8824_REG_ANALOG_CONTROL_2,
447 NAU8824_CLASSD_CLAMP_DIS, NAU8824_CLASSD_CLAMP_DIS);
448 break;
449 case SND_SOC_DAPM_POST_PMD:
450 regmap_update_bits(nau8824->regmap,
451 NAU8824_REG_ANALOG_CONTROL_2,
452 NAU8824_CLASSD_CLAMP_DIS, 0);
453 break;
454 default:
455 return -EINVAL;
456 }
457
458 return 0;
459}
460
461static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
462 struct snd_kcontrol *kcontrol, int event)
463{
464 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
465 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
466
467 switch (event) {
468 case SND_SOC_DAPM_POST_PMU:
469 /* Prevent startup click by letting charge pump to ramp up */
470 msleep(10);
471 regmap_update_bits(nau8824->regmap,
472 NAU8824_REG_CHARGE_PUMP_CONTROL,
473 NAU8824_JAMNODCLOW, NAU8824_JAMNODCLOW);
474 break;
475 case SND_SOC_DAPM_PRE_PMD:
476 regmap_update_bits(nau8824->regmap,
477 NAU8824_REG_CHARGE_PUMP_CONTROL,
478 NAU8824_JAMNODCLOW, 0);
479 break;
480 default:
481 return -EINVAL;
482 }
483
484 return 0;
485}
486
487static int system_clock_control(struct snd_soc_dapm_widget *w,
488 struct snd_kcontrol *k, int event)
489{
490 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
491 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
492
493 if (SND_SOC_DAPM_EVENT_OFF(event)) {
494 /* Set clock source to disable or internal clock before the
495 * playback or capture end. Codec needs clock for Jack
496 * detection and button press if jack inserted; otherwise,
497 * the clock should be closed.
498 */
499 if (nau8824_is_jack_inserted(nau8824)) {
500 nau8824_config_sysclk(nau8824,
501 NAU8824_CLK_INTERNAL, 0);
502 } else {
503 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
504 }
505 }
506 return 0;
507}
508
509static int dmic_clock_control(struct snd_soc_dapm_widget *w,
510 struct snd_kcontrol *k, int event)
511{
512 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
513 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
514 int src;
515
516 /* The DMIC clock is gotten from system clock (256fs) divided by
517 * DMIC_SRC (1, 2, 4, 8, 16, 32). The clock has to be equal or
518 * less than 3.072 MHz.
519 */
520 for (src = 0; src < 5; src++) {
521 if ((0x1 << (8 - src)) * nau8824->fs <= DMIC_CLK)
522 break;
523 }
524 dev_dbg(nau8824->dev, "dmic src %d for mclk %d\n", src, nau8824->fs * 256);
525 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
526 NAU8824_CLK_DMIC_SRC_MASK, (src << NAU8824_CLK_DMIC_SRC_SFT));
527
528 return 0;
529}
530
531static const struct snd_kcontrol_new nau8824_adc_ch0_dmic =
532 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
533 NAU8824_ADC_CH0_DMIC_SFT, 1, 0);
534
535static const struct snd_kcontrol_new nau8824_adc_ch1_dmic =
536 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
537 NAU8824_ADC_CH1_DMIC_SFT, 1, 0);
538
539static const struct snd_kcontrol_new nau8824_adc_ch2_dmic =
540 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
541 NAU8824_ADC_CH2_DMIC_SFT, 1, 0);
542
543static const struct snd_kcontrol_new nau8824_adc_ch3_dmic =
544 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
545 NAU8824_ADC_CH3_DMIC_SFT, 1, 0);
546
547static const struct snd_kcontrol_new nau8824_adc_left_mixer[] = {
548 SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA,
549 NAU8824_FEPGA_MODEL_MIC1_SFT, 1, 0),
550 SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA,
551 NAU8824_FEPGA_MODEL_HSMIC_SFT, 1, 0),
552};
553
554static const struct snd_kcontrol_new nau8824_adc_right_mixer[] = {
555 SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA,
556 NAU8824_FEPGA_MODER_MIC2_SFT, 1, 0),
557 SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA,
558 NAU8824_FEPGA_MODER_HSMIC_SFT, 1, 0),
559};
560
561static const struct snd_kcontrol_new nau8824_hp_left_mixer[] = {
562 SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO,
563 NAU8824_DACR_HPL_EN_SFT, 1, 0),
564 SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO,
565 NAU8824_DACL_HPL_EN_SFT, 1, 0),
566};
567
568static const struct snd_kcontrol_new nau8824_hp_right_mixer[] = {
569 SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO,
570 NAU8824_DACL_HPR_EN_SFT, 1, 0),
571 SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO,
572 NAU8824_DACR_HPR_EN_SFT, 1, 0),
573};
574
575static const char * const nau8824_dac_src[] = { "DACL", "DACR" };
576
577static SOC_ENUM_SINGLE_DECL(
578 nau8824_dacl_enum, NAU8824_REG_DAC_CH0_DGAIN_CTRL,
579 NAU8824_DAC_CH0_SEL_SFT, nau8824_dac_src);
580
581static SOC_ENUM_SINGLE_DECL(
582 nau8824_dacr_enum, NAU8824_REG_DAC_CH1_DGAIN_CTRL,
583 NAU8824_DAC_CH1_SEL_SFT, nau8824_dac_src);
584
585static const struct snd_kcontrol_new nau8824_dacl_mux =
586 SOC_DAPM_ENUM("DACL Source", nau8824_dacl_enum);
587
588static const struct snd_kcontrol_new nau8824_dacr_mux =
589 SOC_DAPM_ENUM("DACR Source", nau8824_dacr_enum);
590
591
592static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = {
593 SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0,
594 system_clock_control, SND_SOC_DAPM_POST_PMD),
595
596 SND_SOC_DAPM_INPUT("HSMIC1"),
597 SND_SOC_DAPM_INPUT("HSMIC2"),
598 SND_SOC_DAPM_INPUT("MIC1"),
599 SND_SOC_DAPM_INPUT("MIC2"),
600 SND_SOC_DAPM_INPUT("DMIC1"),
601 SND_SOC_DAPM_INPUT("DMIC2"),
602 SND_SOC_DAPM_INPUT("DMIC3"),
603 SND_SOC_DAPM_INPUT("DMIC4"),
604
605 SND_SOC_DAPM_SUPPLY("SAR", NAU8824_REG_SAR_ADC,
606 NAU8824_SAR_ADC_EN_SFT, 0, NULL, 0),
607 SND_SOC_DAPM_SUPPLY("MICBIAS", NAU8824_REG_MIC_BIAS,
608 NAU8824_MICBIAS_POWERUP_SFT, 0, NULL, 0),
609 SND_SOC_DAPM_SUPPLY("DMIC12 Power", NAU8824_REG_BIAS_ADJ,
610 NAU8824_DMIC1_EN_SFT, 0, NULL, 0),
611 SND_SOC_DAPM_SUPPLY("DMIC34 Power", NAU8824_REG_BIAS_ADJ,
612 NAU8824_DMIC2_EN_SFT, 0, NULL, 0),
613 SND_SOC_DAPM_SUPPLY("DMIC Clock", SND_SOC_NOPM, 0, 0,
614 dmic_clock_control, SND_SOC_DAPM_POST_PMU),
615
616 SND_SOC_DAPM_SWITCH("DMIC1 Enable", SND_SOC_NOPM,
617 0, 0, &nau8824_adc_ch0_dmic),
618 SND_SOC_DAPM_SWITCH("DMIC2 Enable", SND_SOC_NOPM,
619 0, 0, &nau8824_adc_ch1_dmic),
620 SND_SOC_DAPM_SWITCH("DMIC3 Enable", SND_SOC_NOPM,
621 0, 0, &nau8824_adc_ch2_dmic),
622 SND_SOC_DAPM_SWITCH("DMIC4 Enable", SND_SOC_NOPM,
623 0, 0, &nau8824_adc_ch3_dmic),
624
625 SND_SOC_DAPM_MIXER("Left ADC", NAU8824_REG_POWER_UP_CONTROL,
626 12, 0, nau8824_adc_left_mixer,
627 ARRAY_SIZE(nau8824_adc_left_mixer)),
628 SND_SOC_DAPM_MIXER("Right ADC", NAU8824_REG_POWER_UP_CONTROL,
629 13, 0, nau8824_adc_right_mixer,
630 ARRAY_SIZE(nau8824_adc_right_mixer)),
631
632 SND_SOC_DAPM_ADC("ADCL", NULL, NAU8824_REG_ANALOG_ADC_2,
633 NAU8824_ADCL_EN_SFT, 0),
634 SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2,
635 NAU8824_ADCR_EN_SFT, 0),
636
637 SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
638 SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
639
640 SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC,
641 NAU8824_DACL_EN_SFT, 0),
642 SND_SOC_DAPM_SUPPLY("DACL Clock", NAU8824_REG_RDAC,
643 NAU8824_DACL_CLK_SFT, 0, NULL, 0),
644 SND_SOC_DAPM_DAC("DACR", NULL, NAU8824_REG_RDAC,
645 NAU8824_DACR_EN_SFT, 0),
646 SND_SOC_DAPM_SUPPLY("DACR Clock", NAU8824_REG_RDAC,
647 NAU8824_DACR_CLK_SFT, 0, NULL, 0),
648
649 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacl_mux),
650 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacr_mux),
651
652 SND_SOC_DAPM_PGA_S("Output DACL", 0, NAU8824_REG_CHARGE_PUMP_CONTROL,
653 8, 1, nau8824_output_dac_event,
654 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
655 SND_SOC_DAPM_PGA_S("Output DACR", 0, NAU8824_REG_CHARGE_PUMP_CONTROL,
656 9, 1, nau8824_output_dac_event,
657 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
658
659 SND_SOC_DAPM_PGA_S("ClassD", 0, NAU8824_REG_CLASSD_GAIN_1,
660 NAU8824_CLASSD_EN_SFT, 0, nau8824_spk_event,
661 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
662
663 SND_SOC_DAPM_MIXER("Left Headphone", NAU8824_REG_CLASSG,
664 NAU8824_CLASSG_LDAC_EN_SFT, 0, nau8824_hp_left_mixer,
665 ARRAY_SIZE(nau8824_hp_left_mixer)),
666 SND_SOC_DAPM_MIXER("Right Headphone", NAU8824_REG_CLASSG,
667 NAU8824_CLASSG_RDAC_EN_SFT, 0, nau8824_hp_right_mixer,
668 ARRAY_SIZE(nau8824_hp_right_mixer)),
669 SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8824_REG_CHARGE_PUMP_CONTROL,
670 NAU8824_CHARGE_PUMP_EN_SFT, 0, nau8824_pump_event,
671 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
672 SND_SOC_DAPM_PGA("Output Driver L",
673 NAU8824_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
674 SND_SOC_DAPM_PGA("Output Driver R",
675 NAU8824_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
676 SND_SOC_DAPM_PGA("Main Driver L",
677 NAU8824_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
678 SND_SOC_DAPM_PGA("Main Driver R",
679 NAU8824_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
680 SND_SOC_DAPM_PGA("HP Boost Driver", NAU8824_REG_BOOST,
681 NAU8824_HP_BOOST_DIS_SFT, 1, NULL, 0),
682 SND_SOC_DAPM_PGA("Class G", NAU8824_REG_CLASSG,
683 NAU8824_CLASSG_EN_SFT, 0, NULL, 0),
684
685 SND_SOC_DAPM_OUTPUT("SPKOUTL"),
686 SND_SOC_DAPM_OUTPUT("SPKOUTR"),
687 SND_SOC_DAPM_OUTPUT("HPOL"),
688 SND_SOC_DAPM_OUTPUT("HPOR"),
689};
690
691static const struct snd_soc_dapm_route nau8824_dapm_routes[] = {
692 {"DMIC1 Enable", "Switch", "DMIC1"},
693 {"DMIC2 Enable", "Switch", "DMIC2"},
694 {"DMIC3 Enable", "Switch", "DMIC3"},
695 {"DMIC4 Enable", "Switch", "DMIC4"},
696
697 {"DMIC1", NULL, "DMIC12 Power"},
698 {"DMIC2", NULL, "DMIC12 Power"},
699 {"DMIC3", NULL, "DMIC34 Power"},
700 {"DMIC4", NULL, "DMIC34 Power"},
701 {"DMIC12 Power", NULL, "DMIC Clock"},
702 {"DMIC34 Power", NULL, "DMIC Clock"},
703
704 {"Left ADC", "MIC Switch", "MIC1"},
705 {"Left ADC", "HSMIC Switch", "HSMIC1"},
706 {"Right ADC", "MIC Switch", "MIC2"},
707 {"Right ADC", "HSMIC Switch", "HSMIC2"},
708
709 {"ADCL", NULL, "Left ADC"},
710 {"ADCR", NULL, "Right ADC"},
711
712 {"AIFTX", NULL, "MICBIAS"},
713 {"AIFTX", NULL, "ADCL"},
714 {"AIFTX", NULL, "ADCR"},
715 {"AIFTX", NULL, "DMIC1 Enable"},
716 {"AIFTX", NULL, "DMIC2 Enable"},
717 {"AIFTX", NULL, "DMIC3 Enable"},
718 {"AIFTX", NULL, "DMIC4 Enable"},
719
720 {"AIFTX", NULL, "System Clock"},
721 {"AIFRX", NULL, "System Clock"},
722
723 {"DACL", NULL, "AIFRX"},
724 {"DACL", NULL, "DACL Clock"},
725 {"DACR", NULL, "AIFRX"},
726 {"DACR", NULL, "DACR Clock"},
727
728 {"DACL Mux", "DACL", "DACL"},
729 {"DACL Mux", "DACR", "DACR"},
730 {"DACR Mux", "DACL", "DACL"},
731 {"DACR Mux", "DACR", "DACR"},
732
733 {"Output DACL", NULL, "DACL Mux"},
734 {"Output DACR", NULL, "DACR Mux"},
735
736 {"ClassD", NULL, "Output DACL"},
737 {"ClassD", NULL, "Output DACR"},
738
739 {"Left Headphone", "DAC Left Switch", "Output DACL"},
740 {"Left Headphone", "DAC Right Switch", "Output DACR"},
741 {"Right Headphone", "DAC Left Switch", "Output DACL"},
742 {"Right Headphone", "DAC Right Switch", "Output DACR"},
743
744 {"Charge Pump", NULL, "Left Headphone"},
745 {"Charge Pump", NULL, "Right Headphone"},
746 {"Output Driver L", NULL, "Charge Pump"},
747 {"Output Driver R", NULL, "Charge Pump"},
748 {"Main Driver L", NULL, "Output Driver L"},
749 {"Main Driver R", NULL, "Output Driver R"},
750 {"Class G", NULL, "Main Driver L"},
751 {"Class G", NULL, "Main Driver R"},
752 {"HP Boost Driver", NULL, "Class G"},
753
754 {"SPKOUTL", NULL, "ClassD"},
755 {"SPKOUTR", NULL, "ClassD"},
756 {"HPOL", NULL, "HP Boost Driver"},
757 {"HPOR", NULL, "HP Boost Driver"},
758};
759
760static bool nau8824_is_jack_inserted(struct nau8824 *nau8824)
761{
762 struct snd_soc_jack *jack = nau8824->jack;
763 bool insert = FALSE;
764
765 if (nau8824->irq && jack)
766 insert = jack->status & SND_JACK_HEADPHONE;
767
768 return insert;
769}
770
771static void nau8824_int_status_clear_all(struct regmap *regmap)
772{
773 int active_irq, clear_irq, i;
774
775 /* Reset the intrruption status from rightmost bit if the corres-
776 * ponding irq event occurs.
777 */
778 regmap_read(regmap, NAU8824_REG_IRQ, &active_irq);
779 for (i = 0; i < NAU8824_REG_DATA_LEN; i++) {
780 clear_irq = (0x1 << i);
781 if (active_irq & clear_irq)
782 regmap_write(regmap,
783 NAU8824_REG_CLEAR_INT_REG, clear_irq);
784 }
785}
786
787static void nau8824_eject_jack(struct nau8824 *nau8824)
788{
789 struct snd_soc_dapm_context *dapm = nau8824->dapm;
790 struct regmap *regmap = nau8824->regmap;
791
792 /* Clear all interruption status */
793 nau8824_int_status_clear_all(regmap);
794
795 snd_soc_dapm_disable_pin(dapm, "SAR");
796 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
797 snd_soc_dapm_sync(dapm);
798
799 /* Enable the insertion interruption, disable the ejection
800 * interruption, and then bypass de-bounce circuit.
801 */
802 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING,
803 NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS |
804 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS,
805 NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS |
806 NAU8824_IRQ_EJECT_DIS);
807 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1,
808 NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN,
809 NAU8824_IRQ_INSERT_EN);
810 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
811 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
812
813 /* Close clock for jack type detection at manual mode */
814 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
815}
816
817static void nau8824_jdet_work(struct work_struct *work)
818{
819 struct nau8824 *nau8824 = container_of(
820 work, struct nau8824, jdet_work);
821 struct snd_soc_dapm_context *dapm = nau8824->dapm;
822 struct regmap *regmap = nau8824->regmap;
823 int adc_value, event = 0, event_mask = 0;
824
825 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
826 snd_soc_dapm_force_enable_pin(dapm, "SAR");
827 snd_soc_dapm_sync(dapm);
828
829 msleep(100);
830
831 regmap_read(regmap, NAU8824_REG_SAR_ADC_DATA_OUT, &adc_value);
832 adc_value = adc_value & NAU8824_SAR_ADC_DATA_MASK;
833 dev_dbg(nau8824->dev, "SAR ADC data 0x%02x\n", adc_value);
834 if (adc_value < HEADSET_SARADC_THD) {
835 event |= SND_JACK_HEADPHONE;
836
837 snd_soc_dapm_disable_pin(dapm, "SAR");
838 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
839 snd_soc_dapm_sync(dapm);
840 } else {
841 event |= SND_JACK_HEADSET;
842 }
843 event_mask |= SND_JACK_HEADSET;
844 snd_soc_jack_report(nau8824->jack, event, event_mask);
845
846 nau8824_sema_release(nau8824);
847}
848
849static void nau8824_setup_auto_irq(struct nau8824 *nau8824)
850{
851 struct regmap *regmap = nau8824->regmap;
852
853 /* Enable jack ejection, short key press and release interruption. */
854 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1,
855 NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN,
856 NAU8824_IRQ_EJECT_EN);
857 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING,
858 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_KEY_RELEASE_DIS |
859 NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0);
860 /* Enable internal VCO needed for interruptions */
861 nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0);
862 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
863 NAU8824_JD_SLEEP_MODE, 0);
864}
865
866static int nau8824_button_decode(int value)
867{
868 int buttons = 0;
869
870 /* The chip supports up to 8 buttons, but ALSA defines
871 * only 6 buttons.
872 */
873 if (value & BIT(0))
874 buttons |= SND_JACK_BTN_0;
875 if (value & BIT(1))
876 buttons |= SND_JACK_BTN_1;
877 if (value & BIT(2))
878 buttons |= SND_JACK_BTN_2;
879 if (value & BIT(3))
880 buttons |= SND_JACK_BTN_3;
881 if (value & BIT(4))
882 buttons |= SND_JACK_BTN_4;
883 if (value & BIT(5))
884 buttons |= SND_JACK_BTN_5;
885
886 return buttons;
887}
888
889#define NAU8824_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
890 SND_JACK_BTN_2 | SND_JACK_BTN_3)
891
892static irqreturn_t nau8824_interrupt(int irq, void *data)
893{
894 struct nau8824 *nau8824 = (struct nau8824 *)data;
895 struct regmap *regmap = nau8824->regmap;
896 int active_irq, clear_irq = 0, event = 0, event_mask = 0;
897
898 if (regmap_read(regmap, NAU8824_REG_IRQ, &active_irq)) {
899 dev_err(nau8824->dev, "failed to read irq status\n");
900 return IRQ_NONE;
901 }
902 dev_dbg(nau8824->dev, "IRQ %x\n", active_irq);
903
904 if (active_irq & NAU8824_JACK_EJECTION_DETECTED) {
905 nau8824_eject_jack(nau8824);
906 event_mask |= SND_JACK_HEADSET;
907 clear_irq = NAU8824_JACK_EJECTION_DETECTED;
908 /* release semaphore held after resume,
909 * and cancel jack detection
910 */
911 nau8824_sema_release(nau8824);
912 cancel_work_sync(&nau8824->jdet_work);
913 } else if (active_irq & NAU8824_KEY_SHORT_PRESS_IRQ) {
914 int key_status, button_pressed;
915
916 regmap_read(regmap, NAU8824_REG_CLEAR_INT_REG,
917 &key_status);
918
919 /* lower 8 bits of the register are for pressed keys */
920 button_pressed = nau8824_button_decode(key_status);
921
922 event |= button_pressed;
923 dev_dbg(nau8824->dev, "button %x pressed\n", event);
924 event_mask |= NAU8824_BUTTONS;
925 clear_irq = NAU8824_KEY_SHORT_PRESS_IRQ;
926 } else if (active_irq & NAU8824_KEY_RELEASE_IRQ) {
927 event_mask = NAU8824_BUTTONS;
928 clear_irq = NAU8824_KEY_RELEASE_IRQ;
929 } else if (active_irq & NAU8824_JACK_INSERTION_DETECTED) {
930 /* Turn off insertion interruption at manual mode */
931 regmap_update_bits(regmap,
932 NAU8824_REG_INTERRUPT_SETTING,
933 NAU8824_IRQ_INSERT_DIS,
934 NAU8824_IRQ_INSERT_DIS);
935 regmap_update_bits(regmap,
936 NAU8824_REG_INTERRUPT_SETTING_1,
937 NAU8824_IRQ_INSERT_EN, 0);
938 /* detect microphone and jack type */
939 cancel_work_sync(&nau8824->jdet_work);
940 schedule_work(&nau8824->jdet_work);
941
942 /* Enable interruption for jack type detection at audo
943 * mode which can detect microphone and jack type.
944 */
945 nau8824_setup_auto_irq(nau8824);
946 }
947
948 if (!clear_irq)
949 clear_irq = active_irq;
950 /* clears the rightmost interruption */
951 regmap_write(regmap, NAU8824_REG_CLEAR_INT_REG, clear_irq);
952
953 if (event_mask)
954 snd_soc_jack_report(nau8824->jack, event, event_mask);
955
956 return IRQ_HANDLED;
957}
958
959static int nau8824_clock_check(struct nau8824 *nau8824,
960 int stream, int rate, int osr)
961{
962 int osrate;
963
964 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
965 if (osr >= ARRAY_SIZE(osr_dac_sel))
966 return -EINVAL;
967 osrate = osr_dac_sel[osr].osr;
968 } else {
969 if (osr >= ARRAY_SIZE(osr_adc_sel))
970 return -EINVAL;
971 osrate = osr_adc_sel[osr].osr;
972 }
973
974 if (!osrate || rate * osr > CLK_DA_AD_MAX) {
975 dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n");
976 return -EINVAL;
977 }
978
979 return 0;
980}
981
982static int nau8824_hw_params(struct snd_pcm_substream *substream,
983 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
984{
985 struct snd_soc_codec *codec = dai->codec;
986 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
987 unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
988
989 nau8824_sema_acquire(nau8824, HZ);
990
991 /* CLK_DAC or CLK_ADC = OSR * FS
992 * DAC or ADC clock frequency is defined as Over Sampling Rate (OSR)
993 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs
994 * values must be selected such that the maximum frequency is less
995 * than 6.144 MHz.
996 */
997 nau8824->fs = params_rate(params);
998 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
999 regmap_read(nau8824->regmap,
1000 NAU8824_REG_DAC_FILTER_CTRL_1, &osr);
1001 osr &= NAU8824_DAC_OVERSAMPLE_MASK;
1002 if (nau8824_clock_check(nau8824, substream->stream,
1003 nau8824->fs, osr))
1004 return -EINVAL;
1005 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1006 NAU8824_CLK_DAC_SRC_MASK,
1007 osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT);
1008 } else {
1009 regmap_read(nau8824->regmap,
1010 NAU8824_REG_ADC_FILTER_CTRL, &osr);
1011 osr &= NAU8824_ADC_SYNC_DOWN_MASK;
1012 if (nau8824_clock_check(nau8824, substream->stream,
1013 nau8824->fs, osr))
1014 return -EINVAL;
1015 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1016 NAU8824_CLK_ADC_SRC_MASK,
1017 osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT);
1018 }
1019
1020 /* make BCLK and LRC divde configuration if the codec as master. */
1021 regmap_read(nau8824->regmap,
1022 NAU8824_REG_PORT0_I2S_PCM_CTRL_2, &ctrl_val);
1023 if (ctrl_val & NAU8824_I2S_MS_MASTER) {
1024 /* get the bclk and fs ratio */
1025 bclk_fs = snd_soc_params_to_bclk(params) / nau8824->fs;
1026 if (bclk_fs <= 32)
1027 bclk_div = 0x3;
1028 else if (bclk_fs <= 64)
1029 bclk_div = 0x2;
1030 else if (bclk_fs <= 128)
1031 bclk_div = 0x1;
1032 else if (bclk_fs <= 256)
1033 bclk_div = 0;
1034 else
1035 return -EINVAL;
1036 regmap_update_bits(nau8824->regmap,
1037 NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
1038 NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK,
1039 (bclk_div << NAU8824_I2S_LRC_DIV_SFT) | bclk_div);
1040 }
1041
1042 switch (params_width(params)) {
1043 case 16:
1044 val_len |= NAU8824_I2S_DL_16;
1045 break;
1046 case 20:
1047 val_len |= NAU8824_I2S_DL_20;
1048 break;
1049 case 24:
1050 val_len |= NAU8824_I2S_DL_24;
1051 break;
1052 case 32:
1053 val_len |= NAU8824_I2S_DL_32;
1054 break;
1055 default:
1056 return -EINVAL;
1057 }
1058
1059 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
1060 NAU8824_I2S_DL_MASK, val_len);
1061
1062 nau8824_sema_release(nau8824);
1063
1064 return 0;
1065}
1066
1067static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1068{
1069 struct snd_soc_codec *codec = dai->codec;
1070 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1071 unsigned int ctrl1_val = 0, ctrl2_val = 0;
1072
1073 nau8824_sema_acquire(nau8824, HZ);
1074
1075 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1076 case SND_SOC_DAIFMT_CBM_CFM:
1077 ctrl2_val |= NAU8824_I2S_MS_MASTER;
1078 break;
1079 case SND_SOC_DAIFMT_CBS_CFS:
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1086 case SND_SOC_DAIFMT_NB_NF:
1087 break;
1088 case SND_SOC_DAIFMT_IB_NF:
1089 ctrl1_val |= NAU8824_I2S_BP_INV;
1090 break;
1091 default:
1092 return -EINVAL;
1093 }
1094
1095 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1096 case SND_SOC_DAIFMT_I2S:
1097 ctrl1_val |= NAU8824_I2S_DF_I2S;
1098 break;
1099 case SND_SOC_DAIFMT_LEFT_J:
1100 ctrl1_val |= NAU8824_I2S_DF_LEFT;
1101 break;
1102 case SND_SOC_DAIFMT_RIGHT_J:
1103 ctrl1_val |= NAU8824_I2S_DF_RIGTH;
1104 break;
1105 case SND_SOC_DAIFMT_DSP_A:
1106 ctrl1_val |= NAU8824_I2S_DF_PCM_AB;
1107 break;
1108 case SND_SOC_DAIFMT_DSP_B:
1109 ctrl1_val |= NAU8824_I2S_DF_PCM_AB;
1110 ctrl1_val |= NAU8824_I2S_PCMB_EN;
1111 break;
1112 default:
1113 return -EINVAL;
1114 }
1115
1116 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
1117 NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
1118 NAU8824_I2S_PCMB_EN, ctrl1_val);
1119 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
1120 NAU8824_I2S_MS_MASK, ctrl2_val);
1121
1122 nau8824_sema_release(nau8824);
1123
1124 return 0;
1125}
1126
1127/**
1128 * nau8824_calc_fll_param - Calculate FLL parameters.
1129 * @fll_in: external clock provided to codec.
1130 * @fs: sampling rate.
1131 * @fll_param: Pointer to structure of FLL parameters.
1132 *
1133 * Calculate FLL parameters to configure codec.
1134 *
1135 * Returns 0 for success or negative error code.
1136 */
1137static int nau8824_calc_fll_param(unsigned int fll_in,
1138 unsigned int fs, struct nau8824_fll *fll_param)
1139{
1140 u64 fvco, fvco_max;
1141 unsigned int fref, i, fvco_sel;
1142
1143 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
1144 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
1145 * FREF = freq_in / NAU8824_FLL_REF_DIV_MASK
1146 */
1147 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
1148 fref = fll_in / fll_pre_scalar[i].param;
1149 if (fref <= NAU_FREF_MAX)
1150 break;
1151 }
1152 if (i == ARRAY_SIZE(fll_pre_scalar))
1153 return -EINVAL;
1154 fll_param->clk_ref_div = fll_pre_scalar[i].val;
1155
1156 /* Choose the FLL ratio based on FREF */
1157 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
1158 if (fref >= fll_ratio[i].param)
1159 break;
1160 }
1161 if (i == ARRAY_SIZE(fll_ratio))
1162 return -EINVAL;
1163 fll_param->ratio = fll_ratio[i].val;
1164
1165 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
1166 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
1167 * guaranteed across the full range of operation.
1168 * FDCO = freq_out * 2 * mclk_src_scaling
1169 */
1170 fvco_max = 0;
1171 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
1172 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
1173 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
1174 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
1175 fvco_max < fvco) {
1176 fvco_max = fvco;
1177 fvco_sel = i;
1178 }
1179 }
1180 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
1181 return -EINVAL;
1182 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
1183
1184 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
1185 * input based on FDCO, FREF and FLL ratio.
1186 */
1187 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
1188 fll_param->fll_int = (fvco >> 16) & 0x3FF;
1189 fll_param->fll_frac = fvco & 0xFFFF;
1190 return 0;
1191}
1192
1193static void nau8824_fll_apply(struct regmap *regmap,
1194 struct nau8824_fll *fll_param)
1195{
1196 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1197 NAU8824_CLK_SRC_MASK | NAU8824_CLK_MCLK_SRC_MASK,
1198 NAU8824_CLK_SRC_MCLK | fll_param->mclk_src);
1199 regmap_update_bits(regmap, NAU8824_REG_FLL1,
1200 NAU8824_FLL_RATIO_MASK, fll_param->ratio);
1201 /* FLL 16-bit fractional input */
1202 regmap_write(regmap, NAU8824_REG_FLL2, fll_param->fll_frac);
1203 /* FLL 10-bit integer input */
1204 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1205 NAU8824_FLL_INTEGER_MASK, fll_param->fll_int);
1206 /* FLL pre-scaler */
1207 regmap_update_bits(regmap, NAU8824_REG_FLL4,
1208 NAU8824_FLL_REF_DIV_MASK,
1209 fll_param->clk_ref_div << NAU8824_FLL_REF_DIV_SFT);
1210 /* select divided VCO input */
1211 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1212 NAU8824_FLL_CLK_SW_MASK, NAU8824_FLL_CLK_SW_REF);
1213 /* Disable free-running mode */
1214 regmap_update_bits(regmap,
1215 NAU8824_REG_FLL6, NAU8824_DCO_EN, 0);
1216 if (fll_param->fll_frac) {
1217 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1218 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1219 NAU8824_FLL_FTR_SW_MASK,
1220 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1221 NAU8824_FLL_FTR_SW_FILTER);
1222 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1223 NAU8824_SDM_EN, NAU8824_SDM_EN);
1224 } else {
1225 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1226 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1227 NAU8824_FLL_FTR_SW_MASK, NAU8824_FLL_FTR_SW_ACCU);
1228 regmap_update_bits(regmap,
1229 NAU8824_REG_FLL6, NAU8824_SDM_EN, 0);
1230 }
1231}
1232
1233/* freq_out must be 256*Fs in order to achieve the best performance */
1234static int nau8824_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
1235 unsigned int freq_in, unsigned int freq_out)
1236{
1237 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1238 struct nau8824_fll fll_param;
1239 int ret, fs;
1240
1241 fs = freq_out / 256;
1242 ret = nau8824_calc_fll_param(freq_in, fs, &fll_param);
1243 if (ret < 0) {
1244 dev_err(nau8824->dev, "Unsupported input clock %d\n", freq_in);
1245 return ret;
1246 }
1247 dev_dbg(nau8824->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
1248 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
1249 fll_param.fll_int, fll_param.clk_ref_div);
1250
1251 nau8824_fll_apply(nau8824->regmap, &fll_param);
1252 mdelay(2);
1253 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1254 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO);
1255
1256 return 0;
1257}
1258
1259static int nau8824_config_sysclk(struct nau8824 *nau8824,
1260 int clk_id, unsigned int freq)
1261{
1262 struct regmap *regmap = nau8824->regmap;
1263
1264 switch (clk_id) {
1265 case NAU8824_CLK_DIS:
1266 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1267 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK);
1268 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1269 NAU8824_DCO_EN, 0);
1270 break;
1271
1272 case NAU8824_CLK_MCLK:
1273 nau8824_sema_acquire(nau8824, HZ);
1274 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1275 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK);
1276 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1277 NAU8824_DCO_EN, 0);
1278 nau8824_sema_release(nau8824);
1279 break;
1280
1281 case NAU8824_CLK_INTERNAL:
1282 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1283 NAU8824_DCO_EN, NAU8824_DCO_EN);
1284 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1285 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO);
1286 break;
1287
1288 case NAU8824_CLK_FLL_MCLK:
1289 nau8824_sema_acquire(nau8824, HZ);
1290 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1291 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_MCLK);
1292 nau8824_sema_release(nau8824);
1293 break;
1294
1295 case NAU8824_CLK_FLL_BLK:
1296 nau8824_sema_acquire(nau8824, HZ);
1297 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1298 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_BLK);
1299 nau8824_sema_release(nau8824);
1300 break;
1301
1302 case NAU8824_CLK_FLL_FS:
1303 nau8824_sema_acquire(nau8824, HZ);
1304 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1305 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_FS);
1306 nau8824_sema_release(nau8824);
1307 break;
1308
1309 default:
1310 dev_err(nau8824->dev, "Invalid clock id (%d)\n", clk_id);
1311 return -EINVAL;
1312 }
1313
1314 dev_dbg(nau8824->dev, "Sysclk is %dHz and clock id is %d\n", freq,
1315 clk_id);
1316
1317 return 0;
1318}
1319
1320static int nau8824_set_sysclk(struct snd_soc_codec *codec,
1321 int clk_id, int source, unsigned int freq, int dir)
1322{
1323 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1324
1325 return nau8824_config_sysclk(nau8824, clk_id, freq);
1326}
1327
1328static void nau8824_resume_setup(struct nau8824 *nau8824)
1329{
1330 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
1331 if (nau8824->irq) {
1332 /* Clear all interruption status */
1333 nau8824_int_status_clear_all(nau8824->regmap);
1334 /* Enable jack detection at sleep mode, insertion detection,
1335 * and ejection detection.
1336 */
1337 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL,
1338 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
1339 regmap_update_bits(nau8824->regmap,
1340 NAU8824_REG_INTERRUPT_SETTING_1,
1341 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN,
1342 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN);
1343 regmap_update_bits(nau8824->regmap,
1344 NAU8824_REG_INTERRUPT_SETTING,
1345 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS, 0);
1346 }
1347}
1348
1349static int nau8824_set_bias_level(struct snd_soc_codec *codec,
1350 enum snd_soc_bias_level level)
1351{
1352 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1353
1354 switch (level) {
1355 case SND_SOC_BIAS_ON:
1356 break;
1357
1358 case SND_SOC_BIAS_PREPARE:
1359 break;
1360
1361 case SND_SOC_BIAS_STANDBY:
1362 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1363 /* Setup codec configuration after resume */
1364 nau8824_resume_setup(nau8824);
1365 }
1366 break;
1367
1368 case SND_SOC_BIAS_OFF:
1369 regmap_update_bits(nau8824->regmap,
1370 NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff);
1371 regmap_update_bits(nau8824->regmap,
1372 NAU8824_REG_INTERRUPT_SETTING_1,
1373 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0);
1374 break;
1375 }
1376
1377 return 0;
1378}
1379
1380static int nau8824_codec_probe(struct snd_soc_codec *codec)
1381{
1382 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1383 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1384
1385 nau8824->dapm = dapm;
1386
1387 return 0;
1388}
1389
1390static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
1391{
1392 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1393
1394 if (nau8824->irq) {
1395 disable_irq(nau8824->irq);
1396 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1397 }
1398 regcache_cache_only(nau8824->regmap, true);
1399 regcache_mark_dirty(nau8824->regmap);
1400
1401 return 0;
1402}
1403
1404static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
1405{
1406 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1407
1408 regcache_cache_only(nau8824->regmap, false);
1409 regcache_sync(nau8824->regmap);
1410 if (nau8824->irq) {
1411 /* Hold semaphore to postpone playback happening
1412 * until jack detection done.
1413 */
1414 nau8824_sema_acquire(nau8824, 0);
1415 enable_irq(nau8824->irq);
1416 }
1417
1418 return 0;
1419}
1420
1421static struct snd_soc_codec_driver nau8824_codec_driver = {
1422 .probe = nau8824_codec_probe,
1423 .set_sysclk = nau8824_set_sysclk,
1424 .set_pll = nau8824_set_pll,
1425 .set_bias_level = nau8824_set_bias_level,
1426 .suspend = nau8824_suspend,
1427 .resume = nau8824_resume,
1428 .suspend_bias_off = true,
1429
1430 .component_driver = {
1431 .controls = nau8824_snd_controls,
1432 .num_controls = ARRAY_SIZE(nau8824_snd_controls),
1433 .dapm_widgets = nau8824_dapm_widgets,
1434 .num_dapm_widgets = ARRAY_SIZE(nau8824_dapm_widgets),
1435 .dapm_routes = nau8824_dapm_routes,
1436 .num_dapm_routes = ARRAY_SIZE(nau8824_dapm_routes),
1437 },
1438};
1439
1440static const struct snd_soc_dai_ops nau8824_dai_ops = {
1441 .hw_params = nau8824_hw_params,
1442 .set_fmt = nau8824_set_fmt,
1443};
1444
1445#define NAU8824_RATES SNDRV_PCM_RATE_8000_192000
1446#define NAU8824_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
1447 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
1448
1449static struct snd_soc_dai_driver nau8824_dai = {
1450 .name = NAU8824_CODEC_DAI,
1451 .playback = {
1452 .stream_name = "Playback",
1453 .channels_min = 1,
1454 .channels_max = 2,
1455 .rates = NAU8824_RATES,
1456 .formats = NAU8824_FORMATS,
1457 },
1458 .capture = {
1459 .stream_name = "Capture",
1460 .channels_min = 1,
1461 .channels_max = 2,
1462 .rates = NAU8824_RATES,
1463 .formats = NAU8824_FORMATS,
1464 },
1465 .ops = &nau8824_dai_ops,
1466};
1467
1468static const struct regmap_config nau8824_regmap_config = {
1469 .val_bits = NAU8824_REG_ADDR_LEN,
1470 .reg_bits = NAU8824_REG_DATA_LEN,
1471
1472 .max_register = NAU8824_REG_MAX,
1473 .readable_reg = nau8824_readable_reg,
1474 .writeable_reg = nau8824_writeable_reg,
1475 .volatile_reg = nau8824_volatile_reg,
1476
1477 .cache_type = REGCACHE_RBTREE,
1478 .reg_defaults = nau8824_reg_defaults,
1479 .num_reg_defaults = ARRAY_SIZE(nau8824_reg_defaults),
1480};
1481
1482/**
1483 * nau8824_enable_jack_detect - Specify a jack for event reporting
1484 *
1485 * @component: component to register the jack with
1486 * @jack: jack to use to report headset and button events on
1487 *
1488 * After this function has been called the headset insert/remove and button
1489 * events will be routed to the given jack. Jack can be null to stop
1490 * reporting.
1491 */
1492int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
1493 struct snd_soc_jack *jack)
1494{
1495 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1496 int ret;
1497
1498 nau8824->jack = jack;
1499 /* Initiate jack detection work queue */
1500 INIT_WORK(&nau8824->jdet_work, nau8824_jdet_work);
1501 ret = devm_request_threaded_irq(nau8824->dev, nau8824->irq, NULL,
1502 nau8824_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1503 "nau8824", nau8824);
1504 if (ret) {
1505 dev_err(nau8824->dev, "Cannot request irq %d (%d)\n",
1506 nau8824->irq, ret);
1507 }
1508
1509 return ret;
1510}
1511EXPORT_SYMBOL_GPL(nau8824_enable_jack_detect);
1512
1513static void nau8824_reset_chip(struct regmap *regmap)
1514{
1515 regmap_write(regmap, NAU8824_REG_RESET, 0x00);
1516 regmap_write(regmap, NAU8824_REG_RESET, 0x00);
1517}
1518
1519static void nau8824_setup_buttons(struct nau8824 *nau8824)
1520{
1521 struct regmap *regmap = nau8824->regmap;
1522
1523 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1524 NAU8824_SAR_TRACKING_GAIN_MASK,
1525 nau8824->sar_voltage << NAU8824_SAR_TRACKING_GAIN_SFT);
1526 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1527 NAU8824_SAR_COMPARE_TIME_MASK,
1528 nau8824->sar_compare_time << NAU8824_SAR_COMPARE_TIME_SFT);
1529 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1530 NAU8824_SAR_SAMPLING_TIME_MASK,
1531 nau8824->sar_sampling_time << NAU8824_SAR_SAMPLING_TIME_SFT);
1532
1533 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1534 NAU8824_LEVELS_NR_MASK,
1535 (nau8824->sar_threshold_num - 1) << NAU8824_LEVELS_NR_SFT);
1536 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1537 NAU8824_HYSTERESIS_MASK,
1538 nau8824->sar_hysteresis << NAU8824_HYSTERESIS_SFT);
1539 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1540 NAU8824_SHORTKEY_DEBOUNCE_MASK,
1541 nau8824->key_debounce << NAU8824_SHORTKEY_DEBOUNCE_SFT);
1542
1543 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_1,
1544 (nau8824->sar_threshold[0] << 8) | nau8824->sar_threshold[1]);
1545 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_2,
1546 (nau8824->sar_threshold[2] << 8) | nau8824->sar_threshold[3]);
1547 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_3,
1548 (nau8824->sar_threshold[4] << 8) | nau8824->sar_threshold[5]);
1549 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_4,
1550 (nau8824->sar_threshold[6] << 8) | nau8824->sar_threshold[7]);
1551}
1552
1553static void nau8824_init_regs(struct nau8824 *nau8824)
1554{
1555 struct regmap *regmap = nau8824->regmap;
1556
1557 /* Enable Bias/VMID/VMID Tieoff */
1558 regmap_update_bits(regmap, NAU8824_REG_BIAS_ADJ,
1559 NAU8824_VMID | NAU8824_VMID_SEL_MASK, NAU8824_VMID |
1560 (nau8824->vref_impedance << NAU8824_VMID_SEL_SFT));
1561 regmap_update_bits(regmap, NAU8824_REG_BOOST,
1562 NAU8824_GLOBAL_BIAS_EN, NAU8824_GLOBAL_BIAS_EN);
1563 mdelay(2);
1564 regmap_update_bits(regmap, NAU8824_REG_MIC_BIAS,
1565 NAU8824_MICBIAS_VOLTAGE_MASK, nau8824->micbias_voltage);
1566 /* Disable Boost Driver, Automatic Short circuit protection enable */
1567 regmap_update_bits(regmap, NAU8824_REG_BOOST,
1568 NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS |
1569 NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN,
1570 NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS |
1571 NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN);
1572 /* Scaling for ADC and DAC clock */
1573 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1574 NAU8824_CLK_ADC_SRC_MASK | NAU8824_CLK_DAC_SRC_MASK,
1575 (0x1 << NAU8824_CLK_ADC_SRC_SFT) |
1576 (0x1 << NAU8824_CLK_DAC_SRC_SFT));
1577 regmap_update_bits(regmap, NAU8824_REG_DAC_MUTE_CTRL,
1578 NAU8824_DAC_ZC_EN, NAU8824_DAC_ZC_EN);
1579 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
1580 NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN |
1581 NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN |
1582 NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN,
1583 NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN |
1584 NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN |
1585 NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN);
1586 regmap_update_bits(regmap, NAU8824_REG_CLK_GATING_ENA,
1587 NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN |
1588 NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN |
1589 NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN |
1590 NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN,
1591 NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN |
1592 NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN |
1593 NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN |
1594 NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN);
1595 /* Class G timer 64ms */
1596 regmap_update_bits(regmap, NAU8824_REG_CLASSG,
1597 NAU8824_CLASSG_TIMER_MASK,
1598 0x20 << NAU8824_CLASSG_TIMER_SFT);
1599 regmap_update_bits(regmap, NAU8824_REG_TRIM_SETTINGS,
1600 NAU8824_DRV_CURR_INC, NAU8824_DRV_CURR_INC);
1601 /* Disable DACR/L power */
1602 regmap_update_bits(regmap, NAU8824_REG_CHARGE_PUMP_CONTROL,
1603 NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN |
1604 NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL,
1605 NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN |
1606 NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL);
1607 /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input
1608 * signal to avoid any glitches due to power up transients in both
1609 * the analog and digital DAC circuit.
1610 */
1611 regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO,
1612 NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN);
1613 /* Config L/R channel */
1614 regmap_update_bits(regmap, NAU8824_REG_DAC_CH0_DGAIN_CTRL,
1615 NAU8824_DAC_CH0_SEL_MASK, NAU8824_DAC_CH0_SEL_I2S0);
1616 regmap_update_bits(regmap, NAU8824_REG_DAC_CH1_DGAIN_CTRL,
1617 NAU8824_DAC_CH1_SEL_MASK, NAU8824_DAC_CH1_SEL_I2S1);
1618 regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO,
1619 NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN,
1620 NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN);
1621 /* Default oversampling/decimations settings are unusable
1622 * (audible hiss). Set it to something better.
1623 */
1624 regmap_update_bits(regmap, NAU8824_REG_ADC_FILTER_CTRL,
1625 NAU8824_ADC_SYNC_DOWN_MASK, NAU8824_ADC_SYNC_DOWN_64);
1626 regmap_update_bits(regmap, NAU8824_REG_DAC_FILTER_CTRL_1,
1627 NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_MASK,
1628 NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_64);
1629 /* DAC clock delay 2ns, VREF */
1630 regmap_update_bits(regmap, NAU8824_REG_RDAC,
1631 NAU8824_RDAC_CLK_DELAY_MASK | NAU8824_RDAC_VREF_MASK,
1632 (0x2 << NAU8824_RDAC_CLK_DELAY_SFT) |
1633 (0x3 << NAU8824_RDAC_VREF_SFT));
1634 /* PGA input mode selection */
1635 regmap_update_bits(regmap, NAU8824_REG_FEPGA,
1636 NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN,
1637 NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN);
1638 /* Digital microphone control */
1639 regmap_update_bits(regmap, NAU8824_REG_ANALOG_CONTROL_1,
1640 NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST,
1641 NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST);
1642 regmap_update_bits(regmap, NAU8824_REG_JACK_DET_CTRL,
1643 NAU8824_JACK_LOGIC,
1644 /* jkdet_polarity - 1 is for active-low */
1645 nau8824->jkdet_polarity ? 0 : NAU8824_JACK_LOGIC);
1646 regmap_update_bits(regmap,
1647 NAU8824_REG_JACK_DET_CTRL, NAU8824_JACK_EJECT_DT_MASK,
1648 (nau8824->jack_eject_debounce << NAU8824_JACK_EJECT_DT_SFT));
1649 if (nau8824->sar_threshold_num)
1650 nau8824_setup_buttons(nau8824);
1651}
1652
1653static int nau8824_setup_irq(struct nau8824 *nau8824)
1654{
1655 /* Disable interruption before codec initiation done */
1656 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL,
1657 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
1658 regmap_update_bits(nau8824->regmap,
1659 NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff);
1660 regmap_update_bits(nau8824->regmap, NAU8824_REG_INTERRUPT_SETTING_1,
1661 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0);
1662
1663 return 0;
1664}
1665
1666static void nau8824_print_device_properties(struct nau8824 *nau8824)
1667{
1668 struct device *dev = nau8824->dev;
1669 int i;
1670
1671 dev_dbg(dev, "jkdet-polarity: %d\n", nau8824->jkdet_polarity);
1672 dev_dbg(dev, "micbias-voltage: %d\n", nau8824->micbias_voltage);
1673 dev_dbg(dev, "vref-impedance: %d\n", nau8824->vref_impedance);
1674
1675 dev_dbg(dev, "sar-threshold-num: %d\n", nau8824->sar_threshold_num);
1676 for (i = 0; i < nau8824->sar_threshold_num; i++)
1677 dev_dbg(dev, "sar-threshold[%d]=%x\n", i,
1678 nau8824->sar_threshold[i]);
1679
1680 dev_dbg(dev, "sar-hysteresis: %d\n", nau8824->sar_hysteresis);
1681 dev_dbg(dev, "sar-voltage: %d\n", nau8824->sar_voltage);
1682 dev_dbg(dev, "sar-compare-time: %d\n", nau8824->sar_compare_time);
1683 dev_dbg(dev, "sar-sampling-time: %d\n", nau8824->sar_sampling_time);
1684 dev_dbg(dev, "short-key-debounce: %d\n", nau8824->key_debounce);
1685 dev_dbg(dev, "jack-eject-debounce: %d\n",
1686 nau8824->jack_eject_debounce);
1687}
1688
1689static int nau8824_read_device_properties(struct device *dev,
1690 struct nau8824 *nau8824) {
1691 int ret;
1692
1693 ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
1694 &nau8824->jkdet_polarity);
1695 if (ret)
1696 nau8824->jkdet_polarity = 1;
1697 ret = device_property_read_u32(dev, "nuvoton,micbias-voltage",
1698 &nau8824->micbias_voltage);
1699 if (ret)
1700 nau8824->micbias_voltage = 6;
1701 ret = device_property_read_u32(dev, "nuvoton,vref-impedance",
1702 &nau8824->vref_impedance);
1703 if (ret)
1704 nau8824->vref_impedance = 2;
1705 ret = device_property_read_u32(dev, "nuvoton,sar-threshold-num",
1706 &nau8824->sar_threshold_num);
1707 if (ret)
1708 nau8824->sar_threshold_num = 4;
1709 ret = device_property_read_u32_array(dev, "nuvoton,sar-threshold",
1710 nau8824->sar_threshold, nau8824->sar_threshold_num);
1711 if (ret) {
1712 nau8824->sar_threshold[0] = 0x0a;
1713 nau8824->sar_threshold[1] = 0x14;
1714 nau8824->sar_threshold[2] = 0x26;
1715 nau8824->sar_threshold[3] = 0x73;
1716 }
1717 ret = device_property_read_u32(dev, "nuvoton,sar-hysteresis",
1718 &nau8824->sar_hysteresis);
1719 if (ret)
1720 nau8824->sar_hysteresis = 0;
1721 ret = device_property_read_u32(dev, "nuvoton,sar-voltage",
1722 &nau8824->sar_voltage);
1723 if (ret)
1724 nau8824->sar_voltage = 6;
1725 ret = device_property_read_u32(dev, "nuvoton,sar-compare-time",
1726 &nau8824->sar_compare_time);
1727 if (ret)
1728 nau8824->sar_compare_time = 1;
1729 ret = device_property_read_u32(dev, "nuvoton,sar-sampling-time",
1730 &nau8824->sar_sampling_time);
1731 if (ret)
1732 nau8824->sar_sampling_time = 1;
1733 ret = device_property_read_u32(dev, "nuvoton,short-key-debounce",
1734 &nau8824->key_debounce);
1735 if (ret)
1736 nau8824->key_debounce = 0;
1737 ret = device_property_read_u32(dev, "nuvoton,jack-eject-debounce",
1738 &nau8824->jack_eject_debounce);
1739 if (ret)
1740 nau8824->jack_eject_debounce = 1;
1741
1742 return 0;
1743}
1744
1745static int nau8824_i2c_probe(struct i2c_client *i2c,
1746 const struct i2c_device_id *id)
1747{
1748 struct device *dev = &i2c->dev;
1749 struct nau8824 *nau8824 = dev_get_platdata(dev);
1750 int ret, value;
1751
1752 if (!nau8824) {
1753 nau8824 = devm_kzalloc(dev, sizeof(*nau8824), GFP_KERNEL);
1754 if (!nau8824)
1755 return -ENOMEM;
1756 ret = nau8824_read_device_properties(dev, nau8824);
1757 if (ret)
1758 return ret;
1759 }
1760 i2c_set_clientdata(i2c, nau8824);
1761
1762 nau8824->regmap = devm_regmap_init_i2c(i2c, &nau8824_regmap_config);
1763 if (IS_ERR(nau8824->regmap))
1764 return PTR_ERR(nau8824->regmap);
1765 nau8824->dev = dev;
1766 nau8824->irq = i2c->irq;
1767 sema_init(&nau8824->jd_sem, 1);
1768
1769 nau8824_print_device_properties(nau8824);
1770
1771 ret = regmap_read(nau8824->regmap, NAU8824_REG_I2C_DEVICE_ID, &value);
1772 if (ret < 0) {
1773 dev_err(dev, "Failed to read device id from the NAU8824: %d\n",
1774 ret);
1775 return ret;
1776 }
1777 nau8824_reset_chip(nau8824->regmap);
1778 nau8824_init_regs(nau8824);
1779
1780 if (i2c->irq)
1781 nau8824_setup_irq(nau8824);
1782
1783 return snd_soc_register_codec(dev,
1784 &nau8824_codec_driver, &nau8824_dai, 1);
1785}
1786
1787
1788static int nau8824_i2c_remove(struct i2c_client *client)
1789{
1790 snd_soc_unregister_codec(&client->dev);
1791 return 0;
1792}
1793
1794static const struct i2c_device_id nau8824_i2c_ids[] = {
1795 { "nau8824", 0 },
1796 { }
1797};
1798MODULE_DEVICE_TABLE(i2c, nau8824_i2c_ids);
1799
1800#ifdef CONFIG_OF
1801static const struct of_device_id nau8824_of_ids[] = {
1802 { .compatible = "nuvoton,nau8824", },
1803 {}
1804};
1805MODULE_DEVICE_TABLE(of, nau8824_of_ids);
1806#endif
1807
1808#ifdef CONFIG_ACPI
1809static const struct acpi_device_id nau8824_acpi_match[] = {
1810 { "10508824", 0 },
1811 {},
1812};
1813MODULE_DEVICE_TABLE(acpi, nau8824_acpi_match);
1814#endif
1815
1816static struct i2c_driver nau8824_i2c_driver = {
1817 .driver = {
1818 .name = "nau8824",
1819 .of_match_table = of_match_ptr(nau8824_of_ids),
1820 .acpi_match_table = ACPI_PTR(nau8824_acpi_match),
1821 },
1822 .probe = nau8824_i2c_probe,
1823 .remove = nau8824_i2c_remove,
1824 .id_table = nau8824_i2c_ids,
1825};
1826module_i2c_driver(nau8824_i2c_driver);
1827
1828
1829MODULE_DESCRIPTION("ASoC NAU88L24 driver");
1830MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");
1831MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/nau8824.h b/sound/soc/codecs/nau8824.h
new file mode 100644
index 000000000000..87ac9a382aed
--- /dev/null
+++ b/sound/soc/codecs/nau8824.h
@@ -0,0 +1,466 @@
1/*
2 * NAU88L24 ALSA SoC audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 * Author: John Hsu <KCHSU0@nuvoton.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __NAU8824_H__
13#define __NAU8824_H__
14
15#define NAU8824_REG_RESET 0x00
16#define NAU8824_REG_ENA_CTRL 0x01
17#define NAU8824_REG_CLK_GATING_ENA 0x02
18#define NAU8824_REG_CLK_DIVIDER 0x03
19#define NAU8824_REG_FLL1 0x04
20#define NAU8824_REG_FLL2 0x05
21#define NAU8824_REG_FLL3 0x06
22#define NAU8824_REG_FLL4 0x07
23#define NAU8824_REG_FLL5 0x08
24#define NAU8824_REG_FLL6 0x09
25#define NAU8824_REG_FLL_VCO_RSV 0x0A
26#define NAU8824_REG_JACK_DET_CTRL 0x0D
27#define NAU8824_REG_INTERRUPT_SETTING_1 0x0F
28#define NAU8824_REG_IRQ 0x10
29#define NAU8824_REG_CLEAR_INT_REG 0x11
30#define NAU8824_REG_INTERRUPT_SETTING 0x12
31#define NAU8824_REG_SAR_ADC 0x13
32#define NAU8824_REG_VDET_COEFFICIENT 0x14
33#define NAU8824_REG_VDET_THRESHOLD_1 0x15
34#define NAU8824_REG_VDET_THRESHOLD_2 0x16
35#define NAU8824_REG_VDET_THRESHOLD_3 0x17
36#define NAU8824_REG_VDET_THRESHOLD_4 0x18
37#define NAU8824_REG_GPIO_SEL 0x1A
38#define NAU8824_REG_PORT0_I2S_PCM_CTRL_1 0x1C
39#define NAU8824_REG_PORT0_I2S_PCM_CTRL_2 0x1D
40#define NAU8824_REG_PORT0_LEFT_TIME_SLOT 0x1E
41#define NAU8824_REG_PORT0_RIGHT_TIME_SLOT 0x1F
42#define NAU8824_REG_TDM_CTRL 0x20
43#define NAU8824_REG_ADC_HPF_FILTER 0x23
44#define NAU8824_REG_ADC_FILTER_CTRL 0x24
45#define NAU8824_REG_DAC_FILTER_CTRL_1 0x25
46#define NAU8824_REG_DAC_FILTER_CTRL_2 0x26
47#define NAU8824_REG_NOTCH_FILTER_1 0x27
48#define NAU8824_REG_NOTCH_FILTER_2 0x28
49#define NAU8824_REG_EQ1_LOW 0x29
50#define NAU8824_REG_EQ2_EQ3 0x2A
51#define NAU8824_REG_EQ4_EQ5 0x2B
52#define NAU8824_REG_ADC_CH0_DGAIN_CTRL 0x2D
53#define NAU8824_REG_ADC_CH1_DGAIN_CTRL 0x2E
54#define NAU8824_REG_ADC_CH2_DGAIN_CTRL 0x2F
55#define NAU8824_REG_ADC_CH3_DGAIN_CTRL 0x30
56#define NAU8824_REG_DAC_MUTE_CTRL 0x31
57#define NAU8824_REG_DAC_CH0_DGAIN_CTRL 0x32
58#define NAU8824_REG_DAC_CH1_DGAIN_CTRL 0x33
59#define NAU8824_REG_ADC_TO_DAC_ST 0x34
60#define NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 0x38
61#define NAU8824_REG_DRC_KNEE_IP34_ADC_CH01 0x39
62#define NAU8824_REG_DRC_SLOPE_ADC_CH01 0x3A
63#define NAU8824_REG_DRC_ATKDCY_ADC_CH01 0x3B
64#define NAU8824_REG_DRC_KNEE_IP12_ADC_CH23 0x3C
65#define NAU8824_REG_DRC_KNEE_IP34_ADC_CH23 0x3D
66#define NAU8824_REG_DRC_SLOPE_ADC_CH23 0x3E
67#define NAU8824_REG_DRC_ATKDCY_ADC_CH23 0x3F
68#define NAU8824_REG_DRC_GAINL_ADC0 0x40
69#define NAU8824_REG_DRC_GAINL_ADC1 0x41
70#define NAU8824_REG_DRC_GAINL_ADC2 0x42
71#define NAU8824_REG_DRC_GAINL_ADC3 0x43
72#define NAU8824_REG_DRC_KNEE_IP12_DAC 0x45
73#define NAU8824_REG_DRC_KNEE_IP34_DAC 0x46
74#define NAU8824_REG_DRC_SLOPE_DAC 0x47
75#define NAU8824_REG_DRC_ATKDCY_DAC 0x48
76#define NAU8824_REG_DRC_GAIN_DAC_CH0 0x49
77#define NAU8824_REG_DRC_GAIN_DAC_CH1 0x4A
78#define NAU8824_REG_MODE 0x4C
79#define NAU8824_REG_MODE1 0x4D
80#define NAU8824_REG_MODE2 0x4E
81#define NAU8824_REG_CLASSG 0x50
82#define NAU8824_REG_OTP_EFUSE 0x51
83#define NAU8824_REG_OTPDOUT_1 0x53
84#define NAU8824_REG_OTPDOUT_2 0x54
85#define NAU8824_REG_MISC_CTRL 0x55
86#define NAU8824_REG_I2C_TIMEOUT 0x56
87#define NAU8824_REG_TEST_MODE 0x57
88#define NAU8824_REG_I2C_DEVICE_ID 0x58
89#define NAU8824_REG_SAR_ADC_DATA_OUT 0x59
90#define NAU8824_REG_BIAS_ADJ 0x66
91#define NAU8824_REG_PGA_GAIN 0x67
92#define NAU8824_REG_TRIM_SETTINGS 0x68
93#define NAU8824_REG_ANALOG_CONTROL_1 0x69
94#define NAU8824_REG_ANALOG_CONTROL_2 0x6A
95#define NAU8824_REG_ENABLE_LO 0x6B
96#define NAU8824_REG_GAIN_LO 0x6C
97#define NAU8824_REG_CLASSD_GAIN_1 0x6D
98#define NAU8824_REG_CLASSD_GAIN_2 0x6E
99#define NAU8824_REG_ANALOG_ADC_1 0x71
100#define NAU8824_REG_ANALOG_ADC_2 0x72
101#define NAU8824_REG_RDAC 0x73
102#define NAU8824_REG_MIC_BIAS 0x74
103#define NAU8824_REG_HS_VOLUME_CONTROL 0x75
104#define NAU8824_REG_BOOST 0x76
105#define NAU8824_REG_FEPGA 0x77
106#define NAU8824_REG_FEPGA_II 0x78
107#define NAU8824_REG_FEPGA_SE 0x79
108#define NAU8824_REG_FEPGA_ATTENUATION 0x7A
109#define NAU8824_REG_ATT_PORT0 0x7B
110#define NAU8824_REG_ATT_PORT1 0x7C
111#define NAU8824_REG_POWER_UP_CONTROL 0x7F
112#define NAU8824_REG_CHARGE_PUMP_CONTROL 0x80
113#define NAU8824_REG_CHARGE_PUMP_INPUT 0x81
114#define NAU8824_REG_MAX NAU8824_REG_CHARGE_PUMP_INPUT
115/* 16-bit control register address, and 16-bits control register data */
116#define NAU8824_REG_ADDR_LEN 16
117#define NAU8824_REG_DATA_LEN 16
118
119
120/* ENA_CTRL (0x1) */
121#define NAU8824_DMIC_LCH_EDGE_CH23 (0x1 << 12)
122#define NAU8824_DMIC_LCH_EDGE_CH01 (0x1 << 11)
123#define NAU8824_JD_SLEEP_MODE (0x1 << 10)
124#define NAU8824_ADC_CH3_DMIC_SFT 9
125#define NAU8824_ADC_CH3_DMIC_EN (0x1 << NAU8824_ADC_CH3_DMIC_SFT)
126#define NAU8824_ADC_CH2_DMIC_SFT 8
127#define NAU8824_ADC_CH2_DMIC_EN (0x1 << NAU8824_ADC_CH2_DMIC_SFT)
128#define NAU8824_ADC_CH1_DMIC_SFT 7
129#define NAU8824_ADC_CH1_DMIC_EN (0x1 << NAU8824_ADC_CH1_DMIC_SFT)
130#define NAU8824_ADC_CH0_DMIC_SFT 6
131#define NAU8824_ADC_CH0_DMIC_EN (0x1 << NAU8824_ADC_CH0_DMIC_SFT)
132#define NAU8824_DAC_CH1_EN (0x1 << 5)
133#define NAU8824_DAC_CH0_EN (0x1 << 4)
134#define NAU8824_ADC_CH3_EN (0x1 << 3)
135#define NAU8824_ADC_CH2_EN (0x1 << 2)
136#define NAU8824_ADC_CH1_EN (0x1 << 1)
137#define NAU8824_ADC_CH0_EN 0x1
138
139/* CLK_GATING_ENA (0x02) */
140#define NAU8824_CLK_ADC_CH23_EN (0x1 << 15)
141#define NAU8824_CLK_ADC_CH01_EN (0x1 << 14)
142#define NAU8824_CLK_DAC_CH1_EN (0x1 << 13)
143#define NAU8824_CLK_DAC_CH0_EN (0x1 << 12)
144#define NAU8824_CLK_I2S_EN (0x1 << 7)
145#define NAU8824_CLK_GAIN_EN (0x1 << 5)
146#define NAU8824_CLK_SAR_EN (0x1 << 3)
147#define NAU8824_CLK_DMIC_CH23_EN (0x1 << 1)
148
149/* CLK_DIVIDER (0x3) */
150#define NAU8824_CLK_SRC_SFT 15
151#define NAU8824_CLK_SRC_MASK (1 << NAU8824_CLK_SRC_SFT)
152#define NAU8824_CLK_SRC_VCO (1 << NAU8824_CLK_SRC_SFT)
153#define NAU8824_CLK_SRC_MCLK (0 << NAU8824_CLK_SRC_SFT)
154#define NAU8824_CLK_MCLK_SRC_MASK (0xf << 0)
155#define NAU8824_CLK_DMIC_SRC_SFT 10
156#define NAU8824_CLK_DMIC_SRC_MASK (0x7 << NAU8824_CLK_DMIC_SRC_SFT)
157#define NAU8824_CLK_ADC_SRC_SFT 6
158#define NAU8824_CLK_ADC_SRC_MASK (0x3 << NAU8824_CLK_ADC_SRC_SFT)
159#define NAU8824_CLK_DAC_SRC_SFT 4
160#define NAU8824_CLK_DAC_SRC_MASK (0x3 << NAU8824_CLK_DAC_SRC_SFT)
161
162/* FLL1 (0x04) */
163#define NAU8824_FLL_RATIO_MASK (0x7f << 0)
164
165/* FLL3 (0x06) */
166#define NAU8824_FLL_INTEGER_MASK (0x3ff << 0)
167#define NAU8824_FLL_CLK_SRC_SFT 10
168#define NAU8824_FLL_CLK_SRC_MASK (0x3 << NAU8824_FLL_CLK_SRC_SFT)
169#define NAU8824_FLL_CLK_SRC_MCLK (0 << NAU8824_FLL_CLK_SRC_SFT)
170#define NAU8824_FLL_CLK_SRC_BLK (0x2 << NAU8824_FLL_CLK_SRC_SFT)
171#define NAU8824_FLL_CLK_SRC_FS (0x3 << NAU8824_FLL_CLK_SRC_SFT)
172
173/* FLL4 (0x07) */
174#define NAU8824_FLL_REF_DIV_SFT 10
175#define NAU8824_FLL_REF_DIV_MASK (0x3 << NAU8824_FLL_REF_DIV_SFT)
176
177/* FLL5 (0x08) */
178#define NAU8824_FLL_PDB_DAC_EN (0x1 << 15)
179#define NAU8824_FLL_LOOP_FTR_EN (0x1 << 14)
180#define NAU8824_FLL_CLK_SW_MASK (0x1 << 13)
181#define NAU8824_FLL_CLK_SW_N2 (0x1 << 13)
182#define NAU8824_FLL_CLK_SW_REF (0x0 << 13)
183#define NAU8824_FLL_FTR_SW_MASK (0x1 << 12)
184#define NAU8824_FLL_FTR_SW_ACCU (0x1 << 12)
185#define NAU8824_FLL_FTR_SW_FILTER (0x0 << 12)
186
187/* FLL6 (0x9) */
188#define NAU8824_DCO_EN (0x1 << 15)
189#define NAU8824_SDM_EN (0x1 << 14)
190
191/* IRQ (0x10) */
192#define NAU8824_SHORT_CIRCUIT_IRQ (0x1 << 7)
193#define NAU8824_IMPEDANCE_MEAS_IRQ (0x1 << 6)
194#define NAU8824_KEY_RELEASE_IRQ (0x1 << 5)
195#define NAU8824_KEY_LONG_PRESS_IRQ (0x1 << 4)
196#define NAU8824_KEY_SHORT_PRESS_IRQ (0x1 << 3)
197#define NAU8824_JACK_EJECTION_DETECTED (0x1 << 1)
198#define NAU8824_JACK_INSERTION_DETECTED 0x1
199
200/* JACK_DET_CTRL (0x0D) */
201#define NAU8824_JACK_EJECT_DT_SFT 2
202#define NAU8824_JACK_EJECT_DT_MASK (0x3 << NAU8824_JACK_EJECT_DT_SFT)
203#define NAU8824_JACK_LOGIC 0x1
204
205
206/* INTERRUPT_SETTING_1 (0x0F) */
207#define NAU8824_IRQ_EJECT_EN (0x1 << 9)
208#define NAU8824_IRQ_INSERT_EN (0x1 << 8)
209
210/* INTERRUPT_SETTING (0x12) */
211#define NAU8824_IRQ_KEY_RELEASE_DIS (0x1 << 5)
212#define NAU8824_IRQ_KEY_SHORT_PRESS_DIS (0x1 << 3)
213#define NAU8824_IRQ_EJECT_DIS (0x1 << 1)
214#define NAU8824_IRQ_INSERT_DIS 0x1
215
216/* SAR_ADC (0x13) */
217#define NAU8824_SAR_ADC_EN_SFT 12
218#define NAU8824_SAR_TRACKING_GAIN_SFT 8
219#define NAU8824_SAR_TRACKING_GAIN_MASK (0x7 << NAU8824_SAR_TRACKING_GAIN_SFT)
220#define NAU8824_SAR_COMPARE_TIME_SFT 2
221#define NAU8824_SAR_COMPARE_TIME_MASK (3 << 2)
222#define NAU8824_SAR_SAMPLING_TIME_SFT 0
223#define NAU8824_SAR_SAMPLING_TIME_MASK (3 << 0)
224
225/* VDET_COEFFICIENT (0x14) */
226#define NAU8824_SHORTKEY_DEBOUNCE_SFT 12
227#define NAU8824_SHORTKEY_DEBOUNCE_MASK (0x3 << NAU8824_SHORTKEY_DEBOUNCE_SFT)
228#define NAU8824_LEVELS_NR_SFT 8
229#define NAU8824_LEVELS_NR_MASK (0x7 << 8)
230#define NAU8824_HYSTERESIS_SFT 0
231#define NAU8824_HYSTERESIS_MASK 0xf
232
233/* PORT0_I2S_PCM_CTRL_1 (0x1C) */
234#define NAU8824_I2S_BP_SFT 7
235#define NAU8824_I2S_BP_MASK (1 << NAU8824_I2S_BP_SFT)
236#define NAU8824_I2S_BP_INV (1 << NAU8824_I2S_BP_SFT)
237#define NAU8824_I2S_PCMB_SFT 6
238#define NAU8824_I2S_PCMB_EN (1 << NAU8824_I2S_PCMB_SFT)
239#define NAU8824_I2S_DL_SFT 2
240#define NAU8824_I2S_DL_MASK (0x3 << NAU8824_I2S_DL_SFT)
241#define NAU8824_I2S_DL_16 (0 << NAU8824_I2S_DL_SFT)
242#define NAU8824_I2S_DL_20 (1 << NAU8824_I2S_DL_SFT)
243#define NAU8824_I2S_DL_24 (2 << NAU8824_I2S_DL_SFT)
244#define NAU8824_I2S_DL_32 (3 << NAU8824_I2S_DL_SFT)
245#define NAU8824_I2S_DF_MASK 0x3
246#define NAU8824_I2S_DF_RIGTH 0
247#define NAU8824_I2S_DF_LEFT 1
248#define NAU8824_I2S_DF_I2S 2
249#define NAU8824_I2S_DF_PCM_AB 3
250
251
252/* PORT0_I2S_PCM_CTRL_2 (0x1D) */
253#define NAU8824_I2S_LRC_DIV_SFT 12
254#define NAU8824_I2S_LRC_DIV_MASK (0x3 << NAU8824_I2S_LRC_DIV_SFT)
255#define NAU8824_I2S_MS_SFT 3
256#define NAU8824_I2S_MS_MASK (1 << NAU8824_I2S_MS_SFT)
257#define NAU8824_I2S_MS_MASTER (1 << NAU8824_I2S_MS_SFT)
258#define NAU8824_I2S_MS_SLAVE (0 << NAU8824_I2S_MS_SFT)
259#define NAU8824_I2S_BLK_DIV_MASK 0x7
260
261/* ADC_FILTER_CTRL (0x24) */
262#define NAU8824_ADC_SYNC_DOWN_MASK 0x3
263#define NAU8824_ADC_SYNC_DOWN_32 0
264#define NAU8824_ADC_SYNC_DOWN_64 1
265#define NAU8824_ADC_SYNC_DOWN_128 2
266#define NAU8824_ADC_SYNC_DOWN_256 3
267
268/* DAC_FILTER_CTRL_1 (0x25) */
269#define NAU8824_DAC_CICCLP_OFF (0x1 << 7)
270#define NAU8824_DAC_OVERSAMPLE_MASK 0x7
271#define NAU8824_DAC_OVERSAMPLE_64 0
272#define NAU8824_DAC_OVERSAMPLE_256 1
273#define NAU8824_DAC_OVERSAMPLE_128 2
274#define NAU8824_DAC_OVERSAMPLE_32 4
275
276/* DAC_MUTE_CTRL (0x31) */
277#define NAU8824_DAC_CH01_MIX 0x3
278#define NAU8824_DAC_ZC_EN (0x1 << 11)
279
280/* DAC_CH0_DGAIN_CTRL (0x32) */
281#define NAU8824_DAC_CH0_SEL_SFT 9
282#define NAU8824_DAC_CH0_SEL_MASK (0x1 << NAU8824_DAC_CH0_SEL_SFT)
283#define NAU8824_DAC_CH0_SEL_I2S0 (0x0 << NAU8824_DAC_CH0_SEL_SFT)
284#define NAU8824_DAC_CH0_SEL_I2S1 (0x1 << NAU8824_DAC_CH0_SEL_SFT)
285#define NAU8824_DAC_CH0_VOL_MASK 0x1ff
286
287/* DAC_CH1_DGAIN_CTRL (0x33) */
288#define NAU8824_DAC_CH1_SEL_SFT 9
289#define NAU8824_DAC_CH1_SEL_MASK (0x1 << NAU8824_DAC_CH1_SEL_SFT)
290#define NAU8824_DAC_CH1_SEL_I2S0 (0x0 << NAU8824_DAC_CH1_SEL_SFT)
291#define NAU8824_DAC_CH1_SEL_I2S1 (0x1 << NAU8824_DAC_CH1_SEL_SFT)
292#define NAU8824_DAC_CH1_VOL_MASK 0x1ff
293
294/* CLASSG (0x50) */
295#define NAU8824_CLASSG_TIMER_SFT 8
296#define NAU8824_CLASSG_TIMER_MASK (0x3f << NAU8824_CLASSG_TIMER_SFT)
297#define NAU8824_CLASSG_LDAC_EN_SFT 2
298#define NAU8824_CLASSG_RDAC_EN_SFT 1
299#define NAU8824_CLASSG_EN_SFT 0
300
301/* SAR_ADC_DATA_OUT (0x59) */
302#define NAU8824_SAR_ADC_DATA_MASK 0xff
303
304/* BIAS_ADJ (0x66) */
305#define NAU8824_VMID (1 << 6)
306#define NAU8824_VMID_SEL_SFT 4
307#define NAU8824_VMID_SEL_MASK (3 << NAU8824_VMID_SEL_SFT)
308#define NAU8824_DMIC2_EN_SFT 3
309#define NAU8824_DMIC1_EN_SFT 2
310
311/* TRIM_SETTINGS (0x68) */
312#define NAU8824_DRV_CURR_INC (1 << 15)
313
314/* ANALOG_CONTROL_1 (0x69) */
315#define NAU8824_DMIC_CLK_DRV_STRG (1 << 3)
316#define NAU8824_DMIC_CLK_SLEW_FAST (0x7)
317
318/* ANALOG_CONTROL_2 (0x6A) */
319#define NAU8824_CLASSD_CLAMP_DIS_SFT 3
320#define NAU8824_CLASSD_CLAMP_DIS (0x1 << NAU8824_CLASSD_CLAMP_DIS_SFT)
321
322/* ENABLE_LO (0x6B) */
323#define NAU8824_TEST_DAC_SFT 14
324#define NAU8824_TEST_DAC_EN (0x3 << NAU8824_TEST_DAC_SFT)
325#define NAU8824_DACL_HPR_EN_SFT 3
326#define NAU8824_DACL_HPR_EN (0x1 << NAU8824_DACL_HPR_EN_SFT)
327#define NAU8824_DACR_HPR_EN_SFT 2
328#define NAU8824_DACR_HPR_EN (0x1 << NAU8824_DACR_HPR_EN_SFT)
329#define NAU8824_DACR_HPL_EN_SFT 1
330#define NAU8824_DACR_HPL_EN (0x1 << NAU8824_DACR_HPL_EN_SFT)
331#define NAU8824_DACL_HPL_EN_SFT 0
332#define NAU8824_DACL_HPL_EN 0x1
333
334/* CLASSD_GAIN_1 (0x6D) */
335#define NAU8824_CLASSD_GAIN_1R_SFT 8
336#define NAU8824_CLASSD_GAIN_1R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT)
337#define NAU8824_CLASSD_EN_SFT 7
338#define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT)
339#define NAU8824_CLASSD_GAIN_1L_MASK 0x1f
340
341/* CLASSD_GAIN_2 (0x6E) */
342#define NAU8824_CLASSD_GAIN_2R_SFT 8
343#define NAU8824_CLASSD_GAIN_2R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT)
344#define NAU8824_CLASSD_EN_SFT 7
345#define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT)
346#define NAU8824_CLASSD_GAIN_2L_MASK 0x1f
347
348/* ANALOG_ADC_2 (0x72) */
349#define NAU8824_ADCR_EN_SFT 7
350#define NAU8824_ADCL_EN_SFT 6
351
352/* RDAC (0x73) */
353#define NAU8824_DACR_EN_SFT 13
354#define NAU8824_DACL_EN_SFT 12
355#define NAU8824_DACR_CLK_SFT 9
356#define NAU8824_DACL_CLK_SFT 8
357#define NAU8824_RDAC_CLK_DELAY_SFT 4
358#define NAU8824_RDAC_CLK_DELAY_MASK (0x7 << NAU8824_RDAC_CLK_DELAY_SFT)
359#define NAU8824_RDAC_VREF_SFT 2
360#define NAU8824_RDAC_VREF_MASK (0x3 << NAU8824_RDAC_VREF_SFT)
361
362/* MIC_BIAS (0x74) */
363#define NAU8824_MICBIAS_JKSLV (1 << 14)
364#define NAU8824_MICBIAS_JKR2 (1 << 12)
365#define NAU8824_MICBIAS_POWERUP_SFT 8
366#define NAU8824_MICBIAS_VOLTAGE_SFT 0
367#define NAU8824_MICBIAS_VOLTAGE_MASK 0x7
368
369/* BOOST (0x76) */
370#define NAU8824_PRECHARGE_DIS (0x1 << 13)
371#define NAU8824_GLOBAL_BIAS_EN (0x1 << 12)
372#define NAU8824_HP_BOOST_DIS_SFT 9
373#define NAU8824_HP_BOOST_DIS (0x1 << NAU8824_HP_BOOST_DIS_SFT)
374#define NAU8824_HP_BOOST_G_DIS_SFT 8
375#define NAU8824_HP_BOOST_G_DIS (0x1 << NAU8824_HP_BOOST_G_DIS_SFT)
376#define NAU8824_SHORT_SHUTDOWN_DIG_EN (1 << 7)
377#define NAU8824_SHORT_SHUTDOWN_EN (1 << 6)
378
379/* FEPGA (0x77) */
380#define NAU8824_FEPGA_MODER_SHORT_SFT 7
381#define NAU8824_FEPGA_MODER_SHORT_EN (0x1 << NAU8824_FEPGA_MODER_SHORT_SFT)
382#define NAU8824_FEPGA_MODER_MIC2_SFT 5
383#define NAU8824_FEPGA_MODER_MIC2_EN (0x1 << NAU8824_FEPGA_MODER_MIC2_SFT)
384#define NAU8824_FEPGA_MODER_HSMIC_SFT 4
385#define NAU8824_FEPGA_MODER_HSMIC_EN (0x1 << NAU8824_FEPGA_MODER_HSMIC_SFT)
386#define NAU8824_FEPGA_MODEL_SHORT_SFT 3
387#define NAU8824_FEPGA_MODEL_SHORT_EN (0x1 << NAU8824_FEPGA_MODEL_SHORT_SFT)
388#define NAU8824_FEPGA_MODEL_MIC1_SFT 1
389#define NAU8824_FEPGA_MODEL_MIC1_EN (0x1 << NAU8824_FEPGA_MODEL_MIC1_SFT)
390#define NAU8824_FEPGA_MODEL_HSMIC_SFT 0
391#define NAU8824_FEPGA_MODEL_HSMIC_EN (0x1 << NAU8824_FEPGA_MODEL_HSMIC_SFT)
392
393/* FEPGA_II (0x78) */
394#define NAU8824_FEPGA_GAINR_SFT 5
395#define NAU8824_FEPGA_GAINR_MASK (0x1f << NAU8824_FEPGA_GAINR_SFT)
396#define NAU8824_FEPGA_GAINL_SFT 0
397#define NAU8824_FEPGA_GAINL_MASK 0x1f
398
399/* CHARGE_PUMP_CONTROL (0x80) */
400#define NAU8824_JAMNODCLOW (0x1 << 15)
401#define NAU8824_SPKR_PULL_DOWN (0x1 << 13)
402#define NAU8824_SPKL_PULL_DOWN (0x1 << 12)
403#define NAU8824_POWER_DOWN_DACR (0x1 << 9)
404#define NAU8824_POWER_DOWN_DACL (0x1 << 8)
405#define NAU8824_CHARGE_PUMP_EN_SFT 5
406#define NAU8824_CHARGE_PUMP_EN (0x1 << NAU8824_CHARGE_PUMP_EN_SFT)
407
408
409#define NAU8824_CODEC_DAI "nau8824-hifi"
410
411/* System Clock Source */
412enum {
413 NAU8824_CLK_DIS,
414 NAU8824_CLK_MCLK,
415 NAU8824_CLK_INTERNAL,
416 NAU8824_CLK_FLL_MCLK,
417 NAU8824_CLK_FLL_BLK,
418 NAU8824_CLK_FLL_FS,
419};
420
421struct nau8824 {
422 struct device *dev;
423 struct regmap *regmap;
424 struct snd_soc_dapm_context *dapm;
425 struct snd_soc_jack *jack;
426 struct work_struct jdet_work;
427 struct semaphore jd_sem;
428 int fs;
429 int irq;
430 int micbias_voltage;
431 int vref_impedance;
432 int jkdet_polarity;
433 int sar_threshold_num;
434 int sar_threshold[8];
435 int sar_hysteresis;
436 int sar_voltage;
437 int sar_compare_time;
438 int sar_sampling_time;
439 int key_debounce;
440 int jack_eject_debounce;
441};
442
443struct nau8824_fll {
444 int mclk_src;
445 int ratio;
446 int fll_frac;
447 int fll_int;
448 int clk_ref_div;
449};
450
451struct nau8824_fll_attr {
452 unsigned int param;
453 unsigned int val;
454};
455
456struct nau8824_osr_attr {
457 unsigned int osr;
458 unsigned int clk_src;
459};
460
461
462int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
463 struct snd_soc_jack *jack);
464
465#endif /* _NAU8824_H */
466
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index b281a46d769d..f91221b1ddf0 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -1084,13 +1084,28 @@ static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev)
1084 return 0; 1084 return 0;
1085} 1085}
1086 1086
1087static __maybe_unused int rt5514_i2c_resume(struct device *dev)
1088{
1089 struct rt5514_priv *rt5514 = dev_get_drvdata(dev);
1090 unsigned int val;
1091
1092 /*
1093 * Add a bogus read to avoid rt5514's confusion after s2r in case it
1094 * saw glitches on the i2c lines and thought the other side sent a
1095 * start bit.
1096 */
1097 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1098
1099 return 0;
1100}
1101
1087static int rt5514_i2c_probe(struct i2c_client *i2c, 1102static int rt5514_i2c_probe(struct i2c_client *i2c,
1088 const struct i2c_device_id *id) 1103 const struct i2c_device_id *id)
1089{ 1104{
1090 struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev); 1105 struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev);
1091 struct rt5514_priv *rt5514; 1106 struct rt5514_priv *rt5514;
1092 int ret; 1107 int ret;
1093 unsigned int val; 1108 unsigned int val = ~0;
1094 1109
1095 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv), 1110 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv),
1096 GFP_KERNEL); 1111 GFP_KERNEL);
@@ -1120,8 +1135,16 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
1120 return ret; 1135 return ret;
1121 } 1136 }
1122 1137
1123 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); 1138 /*
1124 if (val != RT5514_DEVICE_ID) { 1139 * The rt5514 can get confused if the i2c lines glitch together, as
1140 * can happen at bootup as regulators are turned off and on. If it's
1141 * in this glitched state the first i2c read will fail, so we'll give
1142 * it one change to retry.
1143 */
1144 ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1145 if (ret || val != RT5514_DEVICE_ID)
1146 ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1147 if (ret || val != RT5514_DEVICE_ID) {
1125 dev_err(&i2c->dev, 1148 dev_err(&i2c->dev,
1126 "Device with ID register %x is not rt5514\n", val); 1149 "Device with ID register %x is not rt5514\n", val);
1127 return -ENODEV; 1150 return -ENODEV;
@@ -1149,10 +1172,15 @@ static int rt5514_i2c_remove(struct i2c_client *i2c)
1149 return 0; 1172 return 0;
1150} 1173}
1151 1174
1152struct i2c_driver rt5514_i2c_driver = { 1175static const struct dev_pm_ops rt5514_i2_pm_ops = {
1176 SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume)
1177};
1178
1179static struct i2c_driver rt5514_i2c_driver = {
1153 .driver = { 1180 .driver = {
1154 .name = "rt5514", 1181 .name = "rt5514",
1155 .of_match_table = of_match_ptr(rt5514_of_match), 1182 .of_match_table = of_match_ptr(rt5514_of_match),
1183 .pm = &rt5514_i2_pm_ops,
1156 }, 1184 },
1157 .probe = rt5514_i2c_probe, 1185 .probe = rt5514_i2c_probe,
1158 .remove = rt5514_i2c_remove, 1186 .remove = rt5514_i2c_remove,
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index e149f3ce5401..87844a45886a 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3542,6 +3542,15 @@ static const struct i2c_device_id rt5645_i2c_id[] = {
3542}; 3542};
3543MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); 3543MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
3544 3544
3545#ifdef CONFIG_OF
3546static const struct of_device_id rt5645_of_match[] = {
3547 { .compatible = "realtek,rt5645", },
3548 { .compatible = "realtek,rt5650", },
3549 { }
3550};
3551MODULE_DEVICE_TABLE(of, rt5645_of_match);
3552#endif
3553
3545#ifdef CONFIG_ACPI 3554#ifdef CONFIG_ACPI
3546static const struct acpi_device_id rt5645_acpi_match[] = { 3555static const struct acpi_device_id rt5645_acpi_match[] = {
3547 { "10EC5645", 0 }, 3556 { "10EC5645", 0 },
@@ -3912,6 +3921,7 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
3912static struct i2c_driver rt5645_i2c_driver = { 3921static struct i2c_driver rt5645_i2c_driver = {
3913 .driver = { 3922 .driver = {
3914 .name = "rt5645", 3923 .name = "rt5645",
3924 .of_match_table = of_match_ptr(rt5645_of_match),
3915 .acpi_match_table = ACPI_PTR(rt5645_acpi_match), 3925 .acpi_match_table = ACPI_PTR(rt5645_acpi_match),
3916 }, 3926 },
3917 .probe = rt5645_i2c_probe, 3927 .probe = rt5645_i2c_probe,
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
index 476135ec5726..8cd22307f5b6 100644
--- a/sound/soc/codecs/rt5665.c
+++ b/sound/soc/codecs/rt5665.c
@@ -1139,7 +1139,8 @@ static void rt5665_enable_push_button_irq(struct snd_soc_codec *codec,
1139 bool enable) 1139 bool enable)
1140{ 1140{
1141 if (enable) { 1141 if (enable) {
1142 snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x000b); 1142 snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003);
1143 snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
1143 snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048); 1144 snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048);
1144 snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2, 1145 snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
1145 RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK, 1146 RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK,
@@ -1192,10 +1193,13 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
1192 } 1193 }
1193 1194
1194 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, 1195 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
1195 0x180, 0x180); 1196 0x1a0, 0x120);
1196 regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424); 1197 regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424);
1198 regmap_write(rt5665->regmap, RT5665_IL_CMD_1, 0x0048);
1197 regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291); 1199 regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291);
1198 1200
1201 usleep_range(10000, 15000);
1202
1199 rt5665->sar_adc_value = snd_soc_read(rt5665->codec, 1203 rt5665->sar_adc_value = snd_soc_read(rt5665->codec,
1200 RT5665_SAR_IL_CMD_4) & 0x7ff; 1204 RT5665_SAR_IL_CMD_4) & 0x7ff;
1201 1205
@@ -1256,8 +1260,8 @@ static void rt5665_jd_check_handler(struct work_struct *work)
1256 } 1260 }
1257} 1261}
1258 1262
1259int rt5665_set_jack_detect(struct snd_soc_codec *codec, 1263static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1260 struct snd_soc_jack *hs_jack) 1264 struct snd_soc_jack *hs_jack, void *data)
1261{ 1265{
1262 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 1266 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
1263 1267
@@ -1284,7 +1288,6 @@ int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1284 1288
1285 return 0; 1289 return 0;
1286} 1290}
1287EXPORT_SYMBOL_GPL(rt5665_set_jack_detect);
1288 1291
1289static void rt5665_jack_detect_handler(struct work_struct *work) 1292static void rt5665_jack_detect_handler(struct work_struct *work)
1290{ 1293{
@@ -2600,6 +2603,55 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
2600 return 0; 2603 return 0;
2601} 2604}
2602 2605
2606static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
2607 struct snd_kcontrol *kcontrol, int event)
2608{
2609 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2610 unsigned int val1, val2, mask1, mask2 = 0;
2611
2612 switch (w->shift) {
2613 case RT5665_PWR_I2S2_1_BIT:
2614 mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
2615 RT5665_GP4_PIN_MASK | RT5665_GP5_PIN_MASK;
2616 val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
2617 RT5665_GP4_PIN_DACDAT2_1 | RT5665_GP5_PIN_ADCDAT2_1;
2618 break;
2619 case RT5665_PWR_I2S2_2_BIT:
2620 mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
2621 RT5665_GP8_PIN_MASK;
2622 val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
2623 RT5665_GP8_PIN_DACDAT2_2;
2624 mask2 = RT5665_GP9_PIN_MASK;
2625 val2 = RT5665_GP9_PIN_ADCDAT2_2;
2626 break;
2627 case RT5665_PWR_I2S3_BIT:
2628 mask1 = RT5665_GP6_PIN_MASK | RT5665_GP7_PIN_MASK |
2629 RT5665_GP8_PIN_MASK;
2630 val1 = RT5665_GP6_PIN_BCLK3 | RT5665_GP7_PIN_LRCK3 |
2631 RT5665_GP8_PIN_DACDAT3;
2632 mask2 = RT5665_GP9_PIN_MASK;
2633 val2 = RT5665_GP9_PIN_ADCDAT3;
2634 break;
2635 }
2636 switch (event) {
2637 case SND_SOC_DAPM_PRE_PMU:
2638 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, val1);
2639 if (mask2)
2640 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
2641 mask2, val2);
2642 break;
2643 case SND_SOC_DAPM_POST_PMD:
2644 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, 0);
2645 if (mask2)
2646 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
2647 mask2, 0);
2648 break;
2649 default:
2650 return 0;
2651 }
2652
2653 return 0;
2654}
2603 2655
2604static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { 2656static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
2605 SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0, 2657 SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0,
@@ -2852,11 +2904,14 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
2852 SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT, 2904 SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT,
2853 0, NULL, 0), 2905 0, NULL, 0),
2854 SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT, 2906 SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT,
2855 0, NULL, 0), 2907 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2908 SND_SOC_DAPM_POST_PMD),
2856 SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT, 2909 SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT,
2857 0, NULL, 0), 2910 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2911 SND_SOC_DAPM_POST_PMD),
2858 SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT, 2912 SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT,
2859 0, NULL, 0), 2913 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2914 SND_SOC_DAPM_POST_PMD),
2860 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), 2915 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2861 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), 2916 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2862 SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0), 2917 SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -3963,12 +4018,68 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
3963 {"PDMR", NULL, "PDM R Playback"}, 4018 {"PDMR", NULL, "PDM R Playback"},
3964}; 4019};
3965 4020
4021static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
4022 unsigned int rx_mask, int slots, int slot_width)
4023{
4024 struct snd_soc_codec *codec = dai->codec;
4025 unsigned int val = 0;
4026
4027 if (rx_mask || tx_mask)
4028 val |= RT5665_I2S1_MODE_TDM;
4029
4030 switch (slots) {
4031 case 4:
4032 val |= RT5665_TDM_IN_CH_4;
4033 val |= RT5665_TDM_OUT_CH_4;
4034 break;
4035 case 6:
4036 val |= RT5665_TDM_IN_CH_6;
4037 val |= RT5665_TDM_OUT_CH_6;
4038 break;
4039 case 8:
4040 val |= RT5665_TDM_IN_CH_8;
4041 val |= RT5665_TDM_OUT_CH_8;
4042 break;
4043 case 2:
4044 break;
4045 default:
4046 return -EINVAL;
4047 }
4048
4049 switch (slot_width) {
4050 case 20:
4051 val |= RT5665_TDM_IN_LEN_20;
4052 val |= RT5665_TDM_OUT_LEN_20;
4053 break;
4054 case 24:
4055 val |= RT5665_TDM_IN_LEN_24;
4056 val |= RT5665_TDM_OUT_LEN_24;
4057 break;
4058 case 32:
4059 val |= RT5665_TDM_IN_LEN_32;
4060 val |= RT5665_TDM_OUT_LEN_32;
4061 break;
4062 case 16:
4063 break;
4064 default:
4065 return -EINVAL;
4066 }
4067
4068 snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
4069 RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
4070 RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
4071 RT5665_TDM_OUT_LEN_MASK, val);
4072
4073 return 0;
4074}
4075
4076
3966static int rt5665_hw_params(struct snd_pcm_substream *substream, 4077static int rt5665_hw_params(struct snd_pcm_substream *substream,
3967 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 4078 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
3968{ 4079{
3969 struct snd_soc_codec *codec = dai->codec; 4080 struct snd_soc_codec *codec = dai->codec;
3970 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4081 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
3971 unsigned int val_len = 0, val_clk, mask_clk, val_bits = 0x0100; 4082 unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100;
3972 int pre_div, frame_size; 4083 int pre_div, frame_size;
3973 4084
3974 rt5665->lrck[dai->id] = params_rate(params); 4085 rt5665->lrck[dai->id] = params_rate(params);
@@ -4009,6 +4120,10 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4009 switch (dai->id) { 4120 switch (dai->id) {
4010 case RT5665_AIF1_1: 4121 case RT5665_AIF1_1:
4011 case RT5665_AIF1_2: 4122 case RT5665_AIF1_2:
4123 if (params_channels(params) > 2)
4124 rt5665_set_tdm_slot(dai, 0xf, 0xf,
4125 params_channels(params), params_width(params));
4126 reg_clk = RT5665_ADDA_CLK_1;
4012 mask_clk = RT5665_I2S_PD1_MASK; 4127 mask_clk = RT5665_I2S_PD1_MASK;
4013 val_clk = pre_div << RT5665_I2S_PD1_SFT; 4128 val_clk = pre_div << RT5665_I2S_PD1_SFT;
4014 snd_soc_update_bits(codec, RT5665_I2S1_SDP, 4129 snd_soc_update_bits(codec, RT5665_I2S1_SDP,
@@ -4016,12 +4131,14 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4016 break; 4131 break;
4017 case RT5665_AIF2_1: 4132 case RT5665_AIF2_1:
4018 case RT5665_AIF2_2: 4133 case RT5665_AIF2_2:
4134 reg_clk = RT5665_ADDA_CLK_2;
4019 mask_clk = RT5665_I2S_PD2_MASK; 4135 mask_clk = RT5665_I2S_PD2_MASK;
4020 val_clk = pre_div << RT5665_I2S_PD2_SFT; 4136 val_clk = pre_div << RT5665_I2S_PD2_SFT;
4021 snd_soc_update_bits(codec, RT5665_I2S2_SDP, 4137 snd_soc_update_bits(codec, RT5665_I2S2_SDP,
4022 RT5665_I2S_DL_MASK, val_len); 4138 RT5665_I2S_DL_MASK, val_len);
4023 break; 4139 break;
4024 case RT5665_AIF3: 4140 case RT5665_AIF3:
4141 reg_clk = RT5665_ADDA_CLK_2;
4025 mask_clk = RT5665_I2S_PD3_MASK; 4142 mask_clk = RT5665_I2S_PD3_MASK;
4026 val_clk = pre_div << RT5665_I2S_PD3_SFT; 4143 val_clk = pre_div << RT5665_I2S_PD3_SFT;
4027 snd_soc_update_bits(codec, RT5665_I2S3_SDP, 4144 snd_soc_update_bits(codec, RT5665_I2S3_SDP,
@@ -4032,7 +4149,7 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4032 return -EINVAL; 4149 return -EINVAL;
4033 } 4150 }
4034 4151
4035 snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, mask_clk, val_clk); 4152 snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk);
4036 snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits); 4153 snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
4037 4154
4038 switch (rt5665->lrck[dai->id]) { 4155 switch (rt5665->lrck[dai->id]) {
@@ -4125,10 +4242,9 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4125 return 0; 4242 return 0;
4126} 4243}
4127 4244
4128static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai, 4245static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
4129 int clk_id, unsigned int freq, int dir) 4246 int source, unsigned int freq, int dir)
4130{ 4247{
4131 struct snd_soc_codec *codec = dai->codec;
4132 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4248 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
4133 unsigned int reg_val = 0; 4249 unsigned int reg_val = 0;
4134 4250
@@ -4154,20 +4270,20 @@ static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai,
4154 rt5665->sysclk = freq; 4270 rt5665->sysclk = freq;
4155 rt5665->sysclk_src = clk_id; 4271 rt5665->sysclk_src = clk_id;
4156 4272
4157 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 4273 dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
4158 4274
4159 return 0; 4275 return 0;
4160} 4276}
4161 4277
4162static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, 4278static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
4163 unsigned int freq_in, unsigned int freq_out) 4279 int source, unsigned int freq_in,
4280 unsigned int freq_out)
4164{ 4281{
4165 struct snd_soc_codec *codec = dai->codec;
4166 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4282 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
4167 struct rl6231_pll_code pll_code; 4283 struct rl6231_pll_code pll_code;
4168 int ret; 4284 int ret;
4169 4285
4170 if (Source == rt5665->pll_src && freq_in == rt5665->pll_in && 4286 if (source == rt5665->pll_src && freq_in == rt5665->pll_in &&
4171 freq_out == rt5665->pll_out) 4287 freq_out == rt5665->pll_out)
4172 return 0; 4288 return 0;
4173 4289
@@ -4181,7 +4297,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4181 return 0; 4297 return 0;
4182 } 4298 }
4183 4299
4184 switch (Source) { 4300 switch (source) {
4185 case RT5665_PLL1_S_MCLK: 4301 case RT5665_PLL1_S_MCLK:
4186 snd_soc_update_bits(codec, RT5665_GLB_CLK, 4302 snd_soc_update_bits(codec, RT5665_GLB_CLK,
4187 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK); 4303 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK);
@@ -4199,7 +4315,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4199 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3); 4315 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3);
4200 break; 4316 break;
4201 default: 4317 default:
4202 dev_err(codec->dev, "Unknown PLL Source %d\n", Source); 4318 dev_err(codec->dev, "Unknown PLL Source %d\n", source);
4203 return -EINVAL; 4319 return -EINVAL;
4204 } 4320 }
4205 4321
@@ -4221,62 +4337,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4221 4337
4222 rt5665->pll_in = freq_in; 4338 rt5665->pll_in = freq_in;
4223 rt5665->pll_out = freq_out; 4339 rt5665->pll_out = freq_out;
4224 rt5665->pll_src = Source; 4340 rt5665->pll_src = source;
4225
4226 return 0;
4227}
4228
4229static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
4230 unsigned int rx_mask, int slots, int slot_width)
4231{
4232 struct snd_soc_codec *codec = dai->codec;
4233 unsigned int val = 0;
4234
4235 if (rx_mask || tx_mask)
4236 val |= RT5665_I2S1_MODE_TDM;
4237
4238 switch (slots) {
4239 case 4:
4240 val |= RT5665_TDM_IN_CH_4;
4241 val |= RT5665_TDM_OUT_CH_4;
4242 break;
4243 case 6:
4244 val |= RT5665_TDM_IN_CH_6;
4245 val |= RT5665_TDM_OUT_CH_6;
4246 break;
4247 case 8:
4248 val |= RT5665_TDM_IN_CH_8;
4249 val |= RT5665_TDM_OUT_CH_8;
4250 break;
4251 case 2:
4252 break;
4253 default:
4254 return -EINVAL;
4255 }
4256
4257 switch (slot_width) {
4258 case 20:
4259 val |= RT5665_TDM_IN_LEN_20;
4260 val |= RT5665_TDM_OUT_LEN_20;
4261 break;
4262 case 24:
4263 val |= RT5665_TDM_IN_LEN_24;
4264 val |= RT5665_TDM_OUT_LEN_24;
4265 break;
4266 case 32:
4267 val |= RT5665_TDM_IN_LEN_32;
4268 val |= RT5665_TDM_OUT_LEN_32;
4269 break;
4270 case 16:
4271 break;
4272 default:
4273 return -EINVAL;
4274 }
4275
4276 snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
4277 RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
4278 RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
4279 RT5665_TDM_OUT_LEN_MASK, val);
4280 4341
4281 return 0; 4342 return 0;
4282} 4343}
@@ -4393,9 +4454,7 @@ static int rt5665_resume(struct snd_soc_codec *codec)
4393static const struct snd_soc_dai_ops rt5665_aif_dai_ops = { 4454static const struct snd_soc_dai_ops rt5665_aif_dai_ops = {
4394 .hw_params = rt5665_hw_params, 4455 .hw_params = rt5665_hw_params,
4395 .set_fmt = rt5665_set_dai_fmt, 4456 .set_fmt = rt5665_set_dai_fmt,
4396 .set_sysclk = rt5665_set_dai_sysclk,
4397 .set_tdm_slot = rt5665_set_tdm_slot, 4457 .set_tdm_slot = rt5665_set_tdm_slot,
4398 .set_pll = rt5665_set_dai_pll,
4399 .set_bclk_ratio = rt5665_set_bclk_ratio, 4458 .set_bclk_ratio = rt5665_set_bclk_ratio,
4400}; 4459};
4401 4460
@@ -4504,7 +4563,10 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5665 = {
4504 .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets), 4563 .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets),
4505 .dapm_routes = rt5665_dapm_routes, 4564 .dapm_routes = rt5665_dapm_routes,
4506 .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes), 4565 .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes),
4507 } 4566 },
4567 .set_sysclk = rt5665_set_codec_sysclk,
4568 .set_pll = rt5665_set_codec_pll,
4569 .set_jack = rt5665_set_jack_detect,
4508}; 4570};
4509 4571
4510 4572
@@ -4783,7 +4845,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
4783 4845
4784 regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002); 4846 regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002);
4785 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, 4847 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
4786 0xf000 | RT5665_VREF_POW_MASK, 0xd000 | RT5665_VREF_POW_REG); 4848 0xf000 | RT5665_VREF_POW_MASK, 0xe000 | RT5665_VREF_POW_REG);
4787 /* Work around for pow_pump */ 4849 /* Work around for pow_pump */
4788 regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET, 4850 regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET,
4789 RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS); 4851 RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS);
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h
index a30f5e6d0628..1db5c6a62a8e 100644
--- a/sound/soc/codecs/rt5665.h
+++ b/sound/soc/codecs/rt5665.h
@@ -1984,7 +1984,5 @@ enum {
1984 1984
1985int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec, 1985int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
1986 unsigned int filter_mask, unsigned int clk_src); 1986 unsigned int filter_mask, unsigned int clk_src);
1987int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1988 struct snd_soc_jack *hs_jack);
1989 1987
1990#endif /* __RT5665_H__ */ 1988#endif /* __RT5665_H__ */
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 17d20b99f041..e27c5a4a0a15 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -2835,6 +2835,27 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
2835 DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"), 2835 DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"),
2836 }, 2836 },
2837 }, 2837 },
2838 {
2839 .ident = "Lenovo Thinkpad Tablet 10",
2840 .matches = {
2841 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2842 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
2843 },
2844 },
2845 {
2846 .ident = "Lenovo Thinkpad Tablet 10",
2847 .matches = {
2848 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2849 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
2850 },
2851 },
2852 {
2853 .ident = "Lenovo Thinkpad Tablet 10",
2854 .matches = {
2855 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2856 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
2857 },
2858 },
2838 {} 2859 {}
2839}; 2860};
2840 2861
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index abc802a5a479..65ac4518ad06 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -5035,6 +5035,12 @@ static const struct i2c_device_id rt5677_i2c_id[] = {
5035}; 5035};
5036MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); 5036MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
5037 5037
5038static const struct of_device_id rt5677_of_match[] = {
5039 { .compatible = "realtek,rt5677", },
5040 { }
5041};
5042MODULE_DEVICE_TABLE(of, rt5677_of_match);
5043
5038static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false }; 5044static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false };
5039static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false }; 5045static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false };
5040static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false }; 5046static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false };
@@ -5294,6 +5300,7 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
5294static struct i2c_driver rt5677_i2c_driver = { 5300static struct i2c_driver rt5677_i2c_driver = {
5295 .driver = { 5301 .driver = {
5296 .name = "rt5677", 5302 .name = "rt5677",
5303 .of_match_table = rt5677_of_match,
5297 }, 5304 },
5298 .probe = rt5677_i2c_probe, 5305 .probe = rt5677_i2c_probe,
5299 .remove = rt5677_i2c_remove, 5306 .remove = rt5677_i2c_remove,
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 1589325855bc..5a2702edeb77 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -99,6 +99,13 @@ enum sgtl5000_micbias_resistor {
99 SGTL5000_MICBIAS_8K = 8, 99 SGTL5000_MICBIAS_8K = 8,
100}; 100};
101 101
102enum {
103 I2S_LRCLK_STRENGTH_DISABLE,
104 I2S_LRCLK_STRENGTH_LOW,
105 I2S_LRCLK_STRENGTH_MEDIUM,
106 I2S_LRCLK_STRENGTH_HIGH,
107};
108
102/* sgtl5000 private structure in codec */ 109/* sgtl5000 private structure in codec */
103struct sgtl5000_priv { 110struct sgtl5000_priv {
104 int sysclk; /* sysclk rate */ 111 int sysclk; /* sysclk rate */
@@ -111,6 +118,7 @@ struct sgtl5000_priv {
111 int revision; 118 int revision;
112 u8 micbias_resistor; 119 u8 micbias_resistor;
113 u8 micbias_voltage; 120 u8 micbias_voltage;
121 u8 lrclk_strength;
114}; 122};
115 123
116/* 124/*
@@ -1089,6 +1097,7 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
1089static int sgtl5000_probe(struct snd_soc_codec *codec) 1097static int sgtl5000_probe(struct snd_soc_codec *codec)
1090{ 1098{
1091 int ret; 1099 int ret;
1100 u16 reg;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1101 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093 1102
1094 /* power up sgtl5000 */ 1103 /* power up sgtl5000 */
@@ -1118,7 +1127,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1118 SGTL5000_DAC_MUTE_RIGHT | 1127 SGTL5000_DAC_MUTE_RIGHT |
1119 SGTL5000_DAC_MUTE_LEFT); 1128 SGTL5000_DAC_MUTE_LEFT);
1120 1129
1121 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f); 1130 reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
1131 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
1122 1132
1123 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL, 1133 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1124 SGTL5000_HP_ZCD_EN | 1134 SGTL5000_HP_ZCD_EN |
@@ -1347,6 +1357,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1347 } 1357 }
1348 } 1358 }
1349 1359
1360 sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
1361 if (!of_property_read_u32(np, "lrclk-strength", &value)) {
1362 if (value > I2S_LRCLK_STRENGTH_HIGH)
1363 value = I2S_LRCLK_STRENGTH_LOW;
1364 sgtl5000->lrclk_strength = value;
1365 }
1366
1350 /* Ensure sgtl5000 will start with sane register values */ 1367 /* Ensure sgtl5000 will start with sane register values */
1351 sgtl5000_fill_defaults(client); 1368 sgtl5000_fill_defaults(client);
1352 1369
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c
index 2bb5a11c9ba1..a622623e8558 100644
--- a/sound/soc/codecs/ssm4567.c
+++ b/sound/soc/codecs/ssm4567.c
@@ -485,6 +485,14 @@ static const struct i2c_device_id ssm4567_i2c_ids[] = {
485}; 485};
486MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids); 486MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids);
487 487
488#ifdef CONFIG_OF
489static const struct of_device_id ssm4567_of_match[] = {
490 { .compatible = "adi,ssm4567", },
491 { }
492};
493MODULE_DEVICE_TABLE(of, ssm4567_of_match);
494#endif
495
488#ifdef CONFIG_ACPI 496#ifdef CONFIG_ACPI
489 497
490static const struct acpi_device_id ssm4567_acpi_match[] = { 498static const struct acpi_device_id ssm4567_acpi_match[] = {
@@ -498,6 +506,7 @@ MODULE_DEVICE_TABLE(acpi, ssm4567_acpi_match);
498static struct i2c_driver ssm4567_driver = { 506static struct i2c_driver ssm4567_driver = {
499 .driver = { 507 .driver = {
500 .name = "ssm4567", 508 .name = "ssm4567",
509 .of_match_table = of_match_ptr(ssm4567_of_match),
501 .acpi_match_table = ACPI_PTR(ssm4567_acpi_match), 510 .acpi_match_table = ACPI_PTR(ssm4567_acpi_match),
502 }, 511 },
503 .probe = ssm4567_i2c_probe, 512 .probe = ssm4567_i2c_probe,
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index d4b384e4b266..660734359bf3 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -375,9 +375,16 @@ static const struct i2c_device_id sta529_i2c_id[] = {
375}; 375};
376MODULE_DEVICE_TABLE(i2c, sta529_i2c_id); 376MODULE_DEVICE_TABLE(i2c, sta529_i2c_id);
377 377
378static const struct of_device_id sta529_of_match[] = {
379 { .compatible = "st,sta529", },
380 { }
381};
382MODULE_DEVICE_TABLE(of, sta529_of_match);
383
378static struct i2c_driver sta529_i2c_driver = { 384static struct i2c_driver sta529_i2c_driver = {
379 .driver = { 385 .driver = {
380 .name = "sta529", 386 .name = "sta529",
387 .of_match_table = sta529_of_match,
381 }, 388 },
382 .probe = sta529_i2c_probe, 389 .probe = sta529_i2c_probe,
383 .remove = sta529_i2c_remove, 390 .remove = sta529_i2c_remove,
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index baf455e8c2f7..8840f72f3c4a 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -611,7 +611,7 @@ probe_fail:
611 611
612 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies), 612 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
613 tas2552->supplies); 613 tas2552->supplies);
614 return -EIO; 614 return ret;
615} 615}
616 616
617static int tas2552_codec_remove(struct snd_soc_codec *codec) 617static int tas2552_codec_remove(struct snd_soc_codec *codec)
@@ -637,7 +637,7 @@ static int tas2552_suspend(struct snd_soc_codec *codec)
637 if (ret != 0) 637 if (ret != 0)
638 dev_err(codec->dev, "Failed to disable supplies: %d\n", 638 dev_err(codec->dev, "Failed to disable supplies: %d\n",
639 ret); 639 ret);
640 return 0; 640 return ret;
641} 641}
642 642
643static int tas2552_resume(struct snd_soc_codec *codec) 643static int tas2552_resume(struct snd_soc_codec *codec)
@@ -653,7 +653,7 @@ static int tas2552_resume(struct snd_soc_codec *codec)
653 ret); 653 ret);
654 } 654 }
655 655
656 return 0; 656 return ret;
657} 657}
658#else 658#else
659#define tas2552_suspend NULL 659#define tas2552_suspend NULL
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 410cae0f2060..628a8eeaab68 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -174,10 +174,9 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
174 {"ROUT", NULL, "Output Mixer"}, 174 {"ROUT", NULL, "Output Mixer"},
175 175
176 /* Inputs */ 176 /* Inputs */
177 {"Line Input", "NULL", "LLINEIN"}, 177 {"Line Input", NULL, "LLINEIN"},
178 {"Line Input", "NULL", "RLINEIN"}, 178 {"Line Input", NULL, "RLINEIN"},
179 179 {"Mic Input", NULL, "MICIN"},
180 {"Mic Input", "NULL", "MICIN"},
181 180
182 /* input mux */ 181 /* input mux */
183 {"Capture Source", "Line", "Line Input"}, 182 {"Capture Source", "Line", "Line Input"},
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 748036e851ea..2b6ad09e0886 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -606,6 +606,14 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
606 twl6040_headset_power_get_enum, 606 twl6040_headset_power_get_enum,
607 twl6040_headset_power_put_enum), 607 twl6040_headset_power_put_enum),
608 608
609 /* Left HS PDM data routed to Right HSDAC */
610 SOC_SINGLE("Headset Mono to Stereo Playback Switch",
611 TWL6040_REG_HSRCTL, 7, 1, 0),
612
613 /* Left HF PDM data routed to Right HFDAC */
614 SOC_SINGLE("Handsfree Mono to Stereo Playback Switch",
615 TWL6040_REG_HFRCTL, 5, 1, 0),
616
609 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum, 617 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
610 twl6040_pll_get_enum, twl6040_pll_put_enum), 618 twl6040_pll_get_enum, twl6040_pll_put_enum),
611}; 619};
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2918fdb95e58..61cdc79840e7 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -791,9 +791,16 @@ static const struct i2c_device_id uda1380_i2c_id[] = {
791}; 791};
792MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); 792MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
793 793
794static const struct of_device_id uda1380_of_match[] = {
795 { .compatible = "nxp,uda1380", },
796 { }
797};
798MODULE_DEVICE_TABLE(of, uda1380_of_match);
799
794static struct i2c_driver uda1380_i2c_driver = { 800static struct i2c_driver uda1380_i2c_driver = {
795 .driver = { 801 .driver = {
796 .name = "uda1380-codec", 802 .name = "uda1380-codec",
803 .of_match_table = uda1380_of_match,
797 }, 804 },
798 .probe = uda1380_i2c_probe, 805 .probe = uda1380_i2c_probe,
799 .remove = uda1380_i2c_remove, 806 .remove = uda1380_i2c_remove,
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 560575000cc5..138a84efdd54 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2014,7 +2014,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2014 2014
2015 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val); 2015 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
2016 if (ret != 0) { 2016 if (ret != 0) {
2017 dev_err(wm5100->dev, "Failed to read micropone status: %d\n", 2017 dev_err(wm5100->dev, "Failed to read microphone status: %d\n",
2018 ret); 2018 ret);
2019 return; 2019 return;
2020 } 2020 }
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 6e887c2c42b1..237eeb9a8b97 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -24,6 +24,7 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/regulator/consumer.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <linux/irq.h> 29#include <linux/irq.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
@@ -115,10 +116,19 @@ static const struct reg_default wm8903_reg_defaults[] = {
115 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */ 116 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
116}; 117};
117 118
119#define WM8903_NUM_SUPPLIES 4
120static const char *wm8903_supply_names[WM8903_NUM_SUPPLIES] = {
121 "AVDD",
122 "CPVDD",
123 "DBVDD",
124 "DCVDD",
125};
126
118struct wm8903_priv { 127struct wm8903_priv {
119 struct wm8903_platform_data *pdata; 128 struct wm8903_platform_data *pdata;
120 struct device *dev; 129 struct device *dev;
121 struct regmap *regmap; 130 struct regmap *regmap;
131 struct regulator_bulk_data supplies[WM8903_NUM_SUPPLIES];
122 132
123 int sysclk; 133 int sysclk;
124 int irq; 134 int irq;
@@ -2030,6 +2040,23 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2030 2040
2031 pdata = wm8903->pdata; 2041 pdata = wm8903->pdata;
2032 2042
2043 for (i = 0; i < ARRAY_SIZE(wm8903->supplies); i++)
2044 wm8903->supplies[i].supply = wm8903_supply_names[i];
2045
2046 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8903->supplies),
2047 wm8903->supplies);
2048 if (ret != 0) {
2049 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2050 return ret;
2051 }
2052
2053 ret = regulator_bulk_enable(ARRAY_SIZE(wm8903->supplies),
2054 wm8903->supplies);
2055 if (ret != 0) {
2056 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2057 return ret;
2058 }
2059
2033 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); 2060 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
2034 if (ret != 0) { 2061 if (ret != 0) {
2035 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); 2062 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
@@ -2160,6 +2187,8 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2160 2187
2161 return 0; 2188 return 0;
2162err: 2189err:
2190 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2191 wm8903->supplies);
2163 return ret; 2192 return ret;
2164} 2193}
2165 2194
@@ -2167,6 +2196,8 @@ static int wm8903_i2c_remove(struct i2c_client *client)
2167{ 2196{
2168 struct wm8903_priv *wm8903 = i2c_get_clientdata(client); 2197 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2169 2198
2199 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2200 wm8903->supplies);
2170 if (client->irq) 2201 if (client->irq)
2171 free_irq(client->irq, wm8903); 2202 free_irq(client->irq, wm8903);
2172 wm8903_free_gpio(wm8903); 2203 wm8903_free_gpio(wm8903);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 3bf081a7e450..9ed455700954 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -604,12 +604,150 @@ static const int bclk_divs[] = {
604 120, 160, 220, 240, 320, 320, 320 604 120, 160, 220, 240, 320, 320, 320
605}; 605};
606 606
607/**
608 * wm8960_configure_sysclk - checks if there is a sysclk frequency available
609 * The sysclk must be chosen such that:
610 * - sysclk = MCLK / sysclk_divs
611 * - lrclk = sysclk / dac_divs
612 * - 10 * bclk = sysclk / bclk_divs
613 *
614 * If we cannot find an exact match for (sysclk, lrclk, bclk)
615 * triplet, we relax the bclk such that bclk is chosen as the
616 * closest available frequency greater than expected bclk.
617 *
618 * @wm8960_priv: wm8960 codec private data
619 * @mclk: MCLK used to derive sysclk
620 * @sysclk_idx: sysclk_divs index for found sysclk
621 * @dac_idx: dac_divs index for found lrclk
622 * @bclk_idx: bclk_divs index for found bclk
623 *
624 * Returns:
625 * -1, in case no sysclk frequency available found
626 * >=0, in case we could derive bclk and lrclk from sysclk using
627 * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
628 */
629static
630int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
631 int *sysclk_idx, int *dac_idx, int *bclk_idx)
632{
633 int sysclk, bclk, lrclk;
634 int i, j, k;
635 int diff, closest = mclk;
636
637 /* marker for no match */
638 *bclk_idx = -1;
639
640 bclk = wm8960->bclk;
641 lrclk = wm8960->lrclk;
642
643 /* check if the sysclk frequency is available. */
644 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
645 if (sysclk_divs[i] == -1)
646 continue;
647 sysclk = mclk / sysclk_divs[i];
648 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
649 if (sysclk != dac_divs[j] * lrclk)
650 continue;
651 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
652 diff = sysclk - bclk * bclk_divs[k] / 10;
653 if (diff == 0) {
654 *sysclk_idx = i;
655 *dac_idx = j;
656 *bclk_idx = k;
657 break;
658 }
659 if (diff > 0 && closest > diff) {
660 *sysclk_idx = i;
661 *dac_idx = j;
662 *bclk_idx = k;
663 closest = diff;
664 }
665 }
666 if (k != ARRAY_SIZE(bclk_divs))
667 break;
668 }
669 if (j != ARRAY_SIZE(dac_divs))
670 break;
671 }
672 return *bclk_idx;
673}
674
675/**
676 * wm8960_configure_pll - checks if there is a PLL out frequency available
677 * The PLL out frequency must be chosen such that:
678 * - sysclk = lrclk * dac_divs
679 * - freq_out = sysclk * sysclk_divs
680 * - 10 * sysclk = bclk * bclk_divs
681 *
682 * If we cannot find an exact match for (sysclk, lrclk, bclk)
683 * triplet, we relax the bclk such that bclk is chosen as the
684 * closest available frequency greater than expected bclk.
685 *
686 * @codec: codec structure
687 * @freq_in: input frequency used to derive freq out via PLL
688 * @sysclk_idx: sysclk_divs index for found sysclk
689 * @dac_idx: dac_divs index for found lrclk
690 * @bclk_idx: bclk_divs index for found bclk
691 *
692 * Returns:
693 * < 0, in case no PLL frequency out available was found
694 * >=0, in case we could derive bclk, lrclk, sysclk from PLL out using
695 * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
696 */
697static
698int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
699 int *sysclk_idx, int *dac_idx, int *bclk_idx)
700{
701 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
702 int sysclk, bclk, lrclk, freq_out;
703 int diff, closest, best_freq_out;
704 int i, j, k;
705
706 bclk = wm8960->bclk;
707 lrclk = wm8960->lrclk;
708 closest = freq_in;
709
710 best_freq_out = -EINVAL;
711 *sysclk_idx = *dac_idx = *bclk_idx = -1;
712
713 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
714 if (sysclk_divs[i] == -1)
715 continue;
716 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
717 sysclk = lrclk * dac_divs[j];
718 freq_out = sysclk * sysclk_divs[i];
719
720 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
721 if (!is_pll_freq_available(freq_in, freq_out))
722 continue;
723
724 diff = sysclk - bclk * bclk_divs[k] / 10;
725 if (diff == 0) {
726 *sysclk_idx = i;
727 *dac_idx = j;
728 *bclk_idx = k;
729 return freq_out;
730 }
731 if (diff > 0 && closest > diff) {
732 *sysclk_idx = i;
733 *dac_idx = j;
734 *bclk_idx = k;
735 closest = diff;
736 best_freq_out = freq_out;
737 }
738 }
739 }
740 }
741
742 return best_freq_out;
743}
607static int wm8960_configure_clocking(struct snd_soc_codec *codec) 744static int wm8960_configure_clocking(struct snd_soc_codec *codec)
608{ 745{
609 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 746 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
610 int sysclk, bclk, lrclk, freq_out, freq_in; 747 int freq_out, freq_in;
611 u16 iface1 = snd_soc_read(codec, WM8960_IFACE1); 748 u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
612 int i, j, k; 749 int i, j, k;
750 int ret;
613 751
614 if (!(iface1 & (1<<6))) { 752 if (!(iface1 & (1<<6))) {
615 dev_dbg(codec->dev, 753 dev_dbg(codec->dev,
@@ -623,8 +761,6 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
623 } 761 }
624 762
625 freq_in = wm8960->freq_in; 763 freq_in = wm8960->freq_in;
626 bclk = wm8960->bclk;
627 lrclk = wm8960->lrclk;
628 /* 764 /*
629 * If it's sysclk auto mode, check if the MCLK can provide sysclk or 765 * If it's sysclk auto mode, check if the MCLK can provide sysclk or
630 * not. If MCLK can provide sysclk, using MCLK to provide sysclk 766 * not. If MCLK can provide sysclk, using MCLK to provide sysclk
@@ -643,60 +779,21 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
643 } 779 }
644 780
645 if (wm8960->clk_id != WM8960_SYSCLK_PLL) { 781 if (wm8960->clk_id != WM8960_SYSCLK_PLL) {
646 /* check if the sysclk frequency is available. */ 782 ret = wm8960_configure_sysclk(wm8960, freq_out, &i, &j, &k);
647 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { 783 if (ret >= 0) {
648 if (sysclk_divs[i] == -1)
649 continue;
650 sysclk = freq_out / sysclk_divs[i];
651 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
652 if (sysclk != dac_divs[j] * lrclk)
653 continue;
654 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k)
655 if (sysclk == bclk * bclk_divs[k] / 10)
656 break;
657 if (k != ARRAY_SIZE(bclk_divs))
658 break;
659 }
660 if (j != ARRAY_SIZE(dac_divs))
661 break;
662 }
663
664 if (i != ARRAY_SIZE(sysclk_divs)) {
665 goto configure_clock; 784 goto configure_clock;
666 } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { 785 } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
667 dev_err(codec->dev, "failed to configure clock\n"); 786 dev_err(codec->dev, "failed to configure clock\n");
668 return -EINVAL; 787 return -EINVAL;
669 } 788 }
670 } 789 }
671 /* get a available pll out frequency and set pll */
672 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
673 if (sysclk_divs[i] == -1)
674 continue;
675 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
676 sysclk = lrclk * dac_divs[j];
677 freq_out = sysclk * sysclk_divs[i];
678 790
679 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) { 791 freq_out = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
680 if (sysclk == bclk * bclk_divs[k] / 10 && 792 if (freq_out < 0) {
681 is_pll_freq_available(freq_in, freq_out)) { 793 dev_err(codec->dev, "failed to configure clock via PLL\n");
682 wm8960_set_pll(codec, 794 return freq_out;
683 freq_in, freq_out);
684 break;
685 } else {
686 continue;
687 }
688 }
689 if (k != ARRAY_SIZE(bclk_divs))
690 break;
691 }
692 if (j != ARRAY_SIZE(dac_divs))
693 break;
694 }
695
696 if (i == ARRAY_SIZE(sysclk_divs)) {
697 dev_err(codec->dev, "failed to configure clock\n");
698 return -EINVAL;
699 } 795 }
796 wm8960_set_pll(codec, freq_in, freq_out);
700 797
701configure_clock: 798configure_clock:
702 /* configure sysclk clock */ 799 /* configure sysclk clock */
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 90b2d418ef60..cf761e2d7546 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1071,9 +1071,16 @@ static const struct i2c_device_id wm8978_i2c_id[] = {
1071}; 1071};
1072MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id); 1072MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1073 1073
1074static const struct of_device_id wm8978_of_match[] = {
1075 { .compatible = "wlf,wm8978", },
1076 { }
1077};
1078MODULE_DEVICE_TABLE(of, wm8978_of_match);
1079
1074static struct i2c_driver wm8978_i2c_driver = { 1080static struct i2c_driver wm8978_i2c_driver = {
1075 .driver = { 1081 .driver = {
1076 .name = "wm8978", 1082 .name = "wm8978",
1083 .of_match_table = wm8978_of_match,
1077 }, 1084 },
1078 .probe = wm8978_i2c_probe, 1085 .probe = wm8978_i2c_probe,
1079 .remove = wm8978_i2c_remove, 1086 .remove = wm8978_i2c_remove,
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index bbdb72f73df1..20695b691aff 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -112,17 +112,22 @@
112#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 112#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */
113#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 113#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
114 114
115#define ADSP2_CONTROL 0x0 115#define ADSP2_CONTROL 0x0
116#define ADSP2_CLOCKING 0x1 116#define ADSP2_CLOCKING 0x1
117#define ADSP2_STATUS1 0x4 117#define ADSP2V2_CLOCKING 0x2
118#define ADSP2_WDMA_CONFIG_1 0x30 118#define ADSP2_STATUS1 0x4
119#define ADSP2_WDMA_CONFIG_2 0x31 119#define ADSP2_WDMA_CONFIG_1 0x30
120#define ADSP2_RDMA_CONFIG_1 0x34 120#define ADSP2_WDMA_CONFIG_2 0x31
121 121#define ADSP2V2_WDMA_CONFIG_2 0x32
122#define ADSP2_SCRATCH0 0x40 122#define ADSP2_RDMA_CONFIG_1 0x34
123#define ADSP2_SCRATCH1 0x41 123
124#define ADSP2_SCRATCH2 0x42 124#define ADSP2_SCRATCH0 0x40
125#define ADSP2_SCRATCH3 0x43 125#define ADSP2_SCRATCH1 0x41
126#define ADSP2_SCRATCH2 0x42
127#define ADSP2_SCRATCH3 0x43
128
129#define ADSP2V2_SCRATCH0_1 0x40
130#define ADSP2V2_SCRATCH2_3 0x42
126 131
127/* 132/*
128 * ADSP2 Control 133 * ADSP2 Control
@@ -153,6 +158,17 @@
153#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 158#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
154 159
155/* 160/*
161 * ADSP2V2 clocking
162 */
163#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */
164#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */
165#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
166
167#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */
168#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */
169#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */
170
171/*
156 * ADSP2 Status 1 172 * ADSP2 Status 1
157 */ 173 */
158#define ADSP2_RAM_RDY 0x0001 174#define ADSP2_RAM_RDY 0x0001
@@ -160,6 +176,37 @@
160#define ADSP2_RAM_RDY_SHIFT 0 176#define ADSP2_RAM_RDY_SHIFT 0
161#define ADSP2_RAM_RDY_WIDTH 1 177#define ADSP2_RAM_RDY_WIDTH 1
162 178
179/*
180 * ADSP2 Lock support
181 */
182#define ADSP2_LOCK_CODE_0 0x5555
183#define ADSP2_LOCK_CODE_1 0xAAAA
184
185#define ADSP2_WATCHDOG 0x0A
186#define ADSP2_BUS_ERR_ADDR 0x52
187#define ADSP2_REGION_LOCK_STATUS 0x64
188#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66
189#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68
190#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A
191#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C
192#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E
193#define ADSP2_LOCK_REGION_CTRL 0x7A
194#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C
195
196#define ADSP2_REGION_LOCK_ERR_MASK 0x8000
197#define ADSP2_SLAVE_ERR_MASK 0x4000
198#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000
199#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002
200#define ADSP2_CTRL_ERR_EINT 0x0001
201
202#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF
203#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF
204#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000
205#define ADSP2_PMEM_ERR_ADDR_SHIFT 16
206#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD
207
208#define ADSP2_LOCK_REGION_SHIFT 16
209
163#define ADSP_MAX_STD_CTRL_SIZE 512 210#define ADSP_MAX_STD_CTRL_SIZE 512
164 211
165#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 212#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100
@@ -683,6 +730,9 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
683 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 730 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
684 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 731 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
685 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 732 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
733 SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
734 SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
735 SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
686}; 736};
687 737
688const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 738const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
@@ -694,6 +744,12 @@ const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
694 wm_adsp_fw_get, wm_adsp_fw_put), 744 wm_adsp_fw_get, wm_adsp_fw_put),
695 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 745 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
696 wm_adsp_fw_get, wm_adsp_fw_put), 746 wm_adsp_fw_get, wm_adsp_fw_put),
747 SOC_ENUM_EXT("DSP5 Firmware", wm_adsp_fw_enum[4],
748 wm_adsp_fw_get, wm_adsp_fw_put),
749 SOC_ENUM_EXT("DSP6 Firmware", wm_adsp_fw_enum[5],
750 wm_adsp_fw_get, wm_adsp_fw_put),
751 SOC_ENUM_EXT("DSP7 Firmware", wm_adsp_fw_enum[6],
752 wm_adsp_fw_get, wm_adsp_fw_put),
697}; 753};
698EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 754EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
699 755
@@ -750,6 +806,29 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
750 be16_to_cpu(scratch[3])); 806 be16_to_cpu(scratch[3]));
751} 807}
752 808
809static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
810{
811 u32 scratch[2];
812 int ret;
813
814 ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
815 scratch, sizeof(scratch));
816
817 if (ret) {
818 adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
819 return;
820 }
821
822 scratch[0] = be32_to_cpu(scratch[0]);
823 scratch[1] = be32_to_cpu(scratch[1]);
824
825 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
826 scratch[0] & 0xFFFF,
827 scratch[0] >> 16,
828 scratch[1] & 0xFFFF,
829 scratch[1] >> 16);
830}
831
753static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) 832static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext)
754{ 833{
755 return container_of(ext, struct wm_coeff_ctl, bytes_ext); 834 return container_of(ext, struct wm_coeff_ctl, bytes_ext);
@@ -2435,10 +2514,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
2435 unsigned int val; 2514 unsigned int val;
2436 int ret, count; 2515 int ret, count;
2437 2516
2438 ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, 2517 switch (dsp->rev) {
2439 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 2518 case 0:
2440 if (ret != 0) 2519 ret = regmap_update_bits_async(dsp->regmap,
2441 return ret; 2520 dsp->base + ADSP2_CONTROL,
2521 ADSP2_SYS_ENA, ADSP2_SYS_ENA);
2522 if (ret != 0)
2523 return ret;
2524 break;
2525 default:
2526 break;
2527 }
2442 2528
2443 /* Wait for the RAM to start, should be near instantaneous */ 2529 /* Wait for the RAM to start, should be near instantaneous */
2444 for (count = 0; count < 10; ++count) { 2530 for (count = 0; count < 10; ++count) {
@@ -2497,11 +2583,17 @@ static void wm_adsp2_boot_work(struct work_struct *work)
2497 if (ret != 0) 2583 if (ret != 0)
2498 goto err_ena; 2584 goto err_ena;
2499 2585
2500 /* Turn DSP back off until we are ready to run */ 2586 switch (dsp->rev) {
2501 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2587 case 0:
2502 ADSP2_SYS_ENA, 0); 2588 /* Turn DSP back off until we are ready to run */
2503 if (ret != 0) 2589 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2504 goto err_ena; 2590 ADSP2_SYS_ENA, 0);
2591 if (ret != 0)
2592 goto err_ena;
2593 break;
2594 default:
2595 break;
2596 }
2505 2597
2506 dsp->booted = true; 2598 dsp->booted = true;
2507 2599
@@ -2523,12 +2615,21 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
2523{ 2615{
2524 int ret; 2616 int ret;
2525 2617
2526 ret = regmap_update_bits_async(dsp->regmap, 2618 switch (dsp->rev) {
2527 dsp->base + ADSP2_CLOCKING, 2619 case 0:
2528 ADSP2_CLK_SEL_MASK, 2620 ret = regmap_update_bits_async(dsp->regmap,
2529 freq << ADSP2_CLK_SEL_SHIFT); 2621 dsp->base + ADSP2_CLOCKING,
2530 if (ret != 0) 2622 ADSP2_CLK_SEL_MASK,
2531 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2623 freq << ADSP2_CLK_SEL_SHIFT);
2624 if (ret) {
2625 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
2626 return;
2627 }
2628 break;
2629 default:
2630 /* clock is handled by parent codec driver */
2631 break;
2632 }
2532} 2633}
2533 2634
2534int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, 2635int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
@@ -2568,6 +2669,18 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
2568} 2669}
2569EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); 2670EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
2570 2671
2672static void wm_adsp_stop_watchdog(struct wm_adsp *dsp)
2673{
2674 switch (dsp->rev) {
2675 case 0:
2676 case 1:
2677 return;
2678 default:
2679 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG,
2680 ADSP2_WDT_ENA_MASK, 0);
2681 }
2682}
2683
2571int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2684int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2572 struct snd_kcontrol *kcontrol, int event, 2685 struct snd_kcontrol *kcontrol, int event,
2573 unsigned int freq) 2686 unsigned int freq)
@@ -2640,6 +2753,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2640 if (ret != 0) 2753 if (ret != 0)
2641 goto err; 2754 goto err;
2642 2755
2756 wm_adsp2_lock(dsp, dsp->lock_regions);
2757
2643 ret = regmap_update_bits(dsp->regmap, 2758 ret = regmap_update_bits(dsp->regmap,
2644 dsp->base + ADSP2_CONTROL, 2759 dsp->base + ADSP2_CONTROL,
2645 ADSP2_CORE_ENA | ADSP2_START, 2760 ADSP2_CORE_ENA | ADSP2_START,
@@ -2663,23 +2778,49 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2663 /* Tell the firmware to cleanup */ 2778 /* Tell the firmware to cleanup */
2664 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); 2779 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN);
2665 2780
2781 wm_adsp_stop_watchdog(dsp);
2782
2666 /* Log firmware state, it can be useful for analysis */ 2783 /* Log firmware state, it can be useful for analysis */
2667 wm_adsp2_show_fw_status(dsp); 2784 switch (dsp->rev) {
2785 case 0:
2786 wm_adsp2_show_fw_status(dsp);
2787 break;
2788 default:
2789 wm_adsp2v2_show_fw_status(dsp);
2790 break;
2791 }
2668 2792
2669 mutex_lock(&dsp->pwr_lock); 2793 mutex_lock(&dsp->pwr_lock);
2670 2794
2671 dsp->running = false; 2795 dsp->running = false;
2672 2796
2673 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2797 regmap_update_bits(dsp->regmap,
2798 dsp->base + ADSP2_CONTROL,
2674 ADSP2_CORE_ENA | ADSP2_START, 0); 2799 ADSP2_CORE_ENA | ADSP2_START, 0);
2675 2800
2676 /* Make sure DMAs are quiesced */ 2801 /* Make sure DMAs are quiesced */
2677 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2802 switch (dsp->rev) {
2678 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2803 case 0:
2679 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 2804 regmap_write(dsp->regmap,
2680 2805 dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2681 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2806 regmap_write(dsp->regmap,
2682 ADSP2_SYS_ENA, 0); 2807 dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2808 regmap_write(dsp->regmap,
2809 dsp->base + ADSP2_WDMA_CONFIG_2, 0);
2810
2811 regmap_update_bits(dsp->regmap,
2812 dsp->base + ADSP2_CONTROL,
2813 ADSP2_SYS_ENA, 0);
2814 break;
2815 default:
2816 regmap_write(dsp->regmap,
2817 dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2818 regmap_write(dsp->regmap,
2819 dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2820 regmap_write(dsp->regmap,
2821 dsp->base + ADSP2V2_WDMA_CONFIG_2, 0);
2822 break;
2823 }
2683 2824
2684 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2825 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2685 wm_adsp_buffer_free(dsp); 2826 wm_adsp_buffer_free(dsp);
@@ -2732,15 +2873,22 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2732{ 2873{
2733 int ret; 2874 int ret;
2734 2875
2735 /* 2876 switch (dsp->rev) {
2736 * Disable the DSP memory by default when in reset for a small 2877 case 0:
2737 * power saving. 2878 /*
2738 */ 2879 * Disable the DSP memory by default when in reset for a small
2739 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2880 * power saving.
2740 ADSP2_MEM_ENA, 0); 2881 */
2741 if (ret != 0) { 2882 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2742 adsp_err(dsp, "Failed to clear memory retention: %d\n", ret); 2883 ADSP2_MEM_ENA, 0);
2743 return ret; 2884 if (ret) {
2885 adsp_err(dsp,
2886 "Failed to clear memory retention: %d\n", ret);
2887 return ret;
2888 }
2889 break;
2890 default:
2891 break;
2744 } 2892 }
2745 2893
2746 INIT_LIST_HEAD(&dsp->alg_regions); 2894 INIT_LIST_HEAD(&dsp->alg_regions);
@@ -3523,4 +3671,94 @@ int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf,
3523} 3671}
3524EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); 3672EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
3525 3673
3674int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions)
3675{
3676 struct regmap *regmap = dsp->regmap;
3677 unsigned int code0, code1, lock_reg;
3678
3679 if (!(lock_regions & WM_ADSP2_REGION_ALL))
3680 return 0;
3681
3682 lock_regions &= WM_ADSP2_REGION_ALL;
3683 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0;
3684
3685 while (lock_regions) {
3686 code0 = code1 = 0;
3687 if (lock_regions & BIT(0)) {
3688 code0 = ADSP2_LOCK_CODE_0;
3689 code1 = ADSP2_LOCK_CODE_1;
3690 }
3691 if (lock_regions & BIT(1)) {
3692 code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT;
3693 code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT;
3694 }
3695 regmap_write(regmap, lock_reg, code0);
3696 regmap_write(regmap, lock_reg, code1);
3697 lock_regions >>= 2;
3698 lock_reg += 2;
3699 }
3700
3701 return 0;
3702}
3703EXPORT_SYMBOL_GPL(wm_adsp2_lock);
3704
3705irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
3706{
3707 unsigned int val;
3708 struct regmap *regmap = dsp->regmap;
3709 int ret = 0;
3710
3711 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
3712 if (ret) {
3713 adsp_err(dsp,
3714 "Failed to read Region Lock Ctrl register: %d\n", ret);
3715 return IRQ_HANDLED;
3716 }
3717
3718 if (val & ADSP2_WDT_TIMEOUT_STS_MASK) {
3719 adsp_err(dsp, "watchdog timeout error\n");
3720 wm_adsp_stop_watchdog(dsp);
3721 }
3722
3723 if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) {
3724 if (val & ADSP2_SLAVE_ERR_MASK)
3725 adsp_err(dsp, "bus error: slave error\n");
3726 else
3727 adsp_err(dsp, "bus error: region lock error\n");
3728
3729 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val);
3730 if (ret) {
3731 adsp_err(dsp,
3732 "Failed to read Bus Err Addr register: %d\n",
3733 ret);
3734 return IRQ_HANDLED;
3735 }
3736
3737 adsp_err(dsp, "bus error address = 0x%x\n",
3738 val & ADSP2_BUS_ERR_ADDR_MASK);
3739
3740 ret = regmap_read(regmap,
3741 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR,
3742 &val);
3743 if (ret) {
3744 adsp_err(dsp,
3745 "Failed to read Pmem Xmem Err Addr register: %d\n",
3746 ret);
3747 return IRQ_HANDLED;
3748 }
3749
3750 adsp_err(dsp, "xmem error address = 0x%x\n",
3751 val & ADSP2_XMEM_ERR_ADDR_MASK);
3752 adsp_err(dsp, "pmem error address = 0x%x\n",
3753 (val & ADSP2_PMEM_ERR_ADDR_MASK) >>
3754 ADSP2_PMEM_ERR_ADDR_SHIFT);
3755 }
3756
3757 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
3758 ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT);
3759
3760 return IRQ_HANDLED;
3761}
3762EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
3763
3526MODULE_LICENSE("GPL v2"); 3764MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 3706b11053a3..41cc11c19b83 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -23,6 +23,23 @@
23#define WM_ADSP_COMPR_OK 0 23#define WM_ADSP_COMPR_OK 0
24#define WM_ADSP_COMPR_VOICE_TRIGGER 1 24#define WM_ADSP_COMPR_VOICE_TRIGGER 1
25 25
26#define WM_ADSP2_REGION_0 BIT(0)
27#define WM_ADSP2_REGION_1 BIT(1)
28#define WM_ADSP2_REGION_2 BIT(2)
29#define WM_ADSP2_REGION_3 BIT(3)
30#define WM_ADSP2_REGION_4 BIT(4)
31#define WM_ADSP2_REGION_5 BIT(5)
32#define WM_ADSP2_REGION_6 BIT(6)
33#define WM_ADSP2_REGION_7 BIT(7)
34#define WM_ADSP2_REGION_8 BIT(8)
35#define WM_ADSP2_REGION_9 BIT(9)
36#define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \
37 WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \
38 WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \
39 WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \
40 WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9)
41#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9)
42
26struct wm_adsp_region { 43struct wm_adsp_region {
27 int type; 44 int type;
28 unsigned int base; 45 unsigned int base;
@@ -40,6 +57,7 @@ struct wm_adsp_compr_buf;
40 57
41struct wm_adsp { 58struct wm_adsp {
42 const char *part; 59 const char *part;
60 int rev;
43 int num; 61 int num;
44 int type; 62 int type;
45 struct device *dev; 63 struct device *dev;
@@ -75,6 +93,8 @@ struct wm_adsp {
75 93
76 struct mutex pwr_lock; 94 struct mutex pwr_lock;
77 95
96 unsigned int lock_regions;
97
78#ifdef CONFIG_DEBUG_FS 98#ifdef CONFIG_DEBUG_FS
79 struct dentry *debugfs_root; 99 struct dentry *debugfs_root;
80 char *wmfw_file_name; 100 char *wmfw_file_name;
@@ -113,6 +133,10 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
113int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 133int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *kcontrol, int event, 134 struct snd_kcontrol *kcontrol, int event,
115 unsigned int freq); 135 unsigned int freq);
136
137int wm_adsp2_lock(struct wm_adsp *adsp, unsigned int regions);
138irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp);
139
116int wm_adsp2_event(struct snd_soc_dapm_widget *w, 140int wm_adsp2_event(struct snd_soc_dapm_widget *w,
117 struct snd_kcontrol *kcontrol, int event); 141 struct snd_kcontrol *kcontrol, int event);
118 142
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index c297efe43861..c6fd95fa5ca6 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -8,10 +8,10 @@ config SND_DESIGNWARE_I2S
8 maximum of 8 channels each for play and record. 8 maximum of 8 channels each for play and record.
9 9
10config SND_DESIGNWARE_PCM 10config SND_DESIGNWARE_PCM
11 tristate "PCM PIO extension for I2S driver" 11 bool "PCM PIO extension for I2S driver"
12 depends on SND_DESIGNWARE_I2S 12 depends on SND_DESIGNWARE_I2S
13 help 13 help
14 Say Y, M or N if you want to add a custom ALSA extension that registers 14 Say Y or N if you want to add a custom ALSA extension that registers
15 a PCM and uses PIO to transfer data. 15 a PCM and uses PIO to transfer data.
16 16
17 This functionality is specially suited for I2S devices that don't have 17 This functionality is specially suited for I2S devices that don't have
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
index 38f1ca31c5fa..3e24c0ff95fb 100644
--- a/sound/soc/dwc/Makefile
+++ b/sound/soc/dwc/Makefile
@@ -1,5 +1,5 @@
1# SYNOPSYS Platform Support 1# SYNOPSYS Platform Support
2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o 2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
3ifdef CONFIG_SND_DESIGNWARE_PCM 3
4obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_pcm.o 4designware_i2s-y := dwc-i2s.o
5endif 5designware_i2s-$(CONFIG_SND_DESIGNWARE_PCM) += dwc-pcm.o
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/dwc-i2s.c
index 9c46e4112026..9c46e4112026 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
diff --git a/sound/soc/dwc/designware_pcm.c b/sound/soc/dwc/dwc-pcm.c
index 459ec861e6b6..406fd867117b 100644
--- a/sound/soc/dwc/designware_pcm.c
+++ b/sound/soc/dwc/dwc-pcm.c
@@ -129,13 +129,11 @@ void dw_pcm_push_tx(struct dw_i2s_dev *dev)
129{ 129{
130 dw_pcm_transfer(dev, true); 130 dw_pcm_transfer(dev, true);
131} 131}
132EXPORT_SYMBOL_GPL(dw_pcm_push_tx);
133 132
134void dw_pcm_pop_rx(struct dw_i2s_dev *dev) 133void dw_pcm_pop_rx(struct dw_i2s_dev *dev)
135{ 134{
136 dw_pcm_transfer(dev, false); 135 dw_pcm_transfer(dev, false);
137} 136}
138EXPORT_SYMBOL_GPL(dw_pcm_pop_rx);
139 137
140static int dw_pcm_open(struct snd_pcm_substream *substream) 138static int dw_pcm_open(struct snd_pcm_substream *substream)
141{ 139{
@@ -281,4 +279,3 @@ int dw_pcm_register(struct platform_device *pdev)
281{ 279{
282 return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform); 280 return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
283} 281}
284EXPORT_SYMBOL_GPL(dw_pcm_register);
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 883087f2b092..84ef6385736c 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -64,7 +64,7 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
64 return 0; 64 return 0;
65} 65}
66 66
67static struct snd_soc_ops eukrea_tlv320_snd_ops = { 67static const struct snd_soc_ops eukrea_tlv320_snd_ops = {
68 .hw_params = eukrea_tlv320_hw_params, 68 .hw_params = eukrea_tlv320_hw_params,
69}; 69};
70 70
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index dc30d780f874..282d841840b1 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -76,7 +76,7 @@ static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
76 pair->dma_chan[!dir], runtime->dma_addr, 76 pair->dma_chan[!dir], runtime->dma_addr,
77 snd_pcm_lib_buffer_bytes(substream), 77 snd_pcm_lib_buffer_bytes(substream),
78 snd_pcm_lib_period_bytes(substream), 78 snd_pcm_lib_period_bytes(substream),
79 dir == OUT ? DMA_TO_DEVICE : DMA_FROM_DEVICE, flags); 79 dir == OUT ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, flags);
80 if (!pair->desc[!dir]) { 80 if (!pair->desc[!dir]) {
81 dev_err(dev, "failed to prepare slave DMA for Front-End\n"); 81 dev_err(dev, "failed to prepare slave DMA for Front-End\n");
82 return -ENOMEM; 82 return -ENOMEM;
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 38bfd46f4ad8..809a069d490b 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -19,7 +19,6 @@
19#include "fsl_esai.h" 19#include "fsl_esai.h"
20#include "imx-pcm.h" 20#include "imx-pcm.h"
21 21
22#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
23#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 22#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
24 SNDRV_PCM_FMTBIT_S16_LE | \ 23 SNDRV_PCM_FMTBIT_S16_LE | \
25 SNDRV_PCM_FMTBIT_S20_3LE | \ 24 SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -647,14 +646,14 @@ static struct snd_soc_dai_driver fsl_esai_dai = {
647 .stream_name = "CPU-Playback", 646 .stream_name = "CPU-Playback",
648 .channels_min = 1, 647 .channels_min = 1,
649 .channels_max = 12, 648 .channels_max = 12,
650 .rates = FSL_ESAI_RATES, 649 .rates = SNDRV_PCM_RATE_8000_192000,
651 .formats = FSL_ESAI_FORMATS, 650 .formats = FSL_ESAI_FORMATS,
652 }, 651 },
653 .capture = { 652 .capture = {
654 .stream_name = "CPU-Capture", 653 .stream_name = "CPU-Capture",
655 .channels_min = 1, 654 .channels_min = 1,
656 .channels_max = 8, 655 .channels_max = 8,
657 .rates = FSL_ESAI_RATES, 656 .rates = SNDRV_PCM_RATE_8000_192000,
658 .formats = FSL_ESAI_FORMATS, 657 .formats = FSL_ESAI_FORMATS,
659 }, 658 },
660 .ops = &fsl_esai_dai_ops, 659 .ops = &fsl_esai_dai_ops,
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fde08660b63b..173cb8496641 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/clk.h> 37#include <linux/clk.h>
38#include <linux/ctype.h>
38#include <linux/device.h> 39#include <linux/device.h>
39#include <linux/delay.h> 40#include <linux/delay.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
@@ -55,16 +56,6 @@
55#include "imx-pcm.h" 56#include "imx-pcm.h"
56 57
57/** 58/**
58 * FSLSSI_I2S_RATES: sample rates supported by the I2S
59 *
60 * This driver currently only supports the SSI running in I2S slave mode,
61 * which means the codec determines the sample rate. Therefore, we tell
62 * ALSA that we support all rates and let the codec driver decide what rates
63 * are really supported.
64 */
65#define FSLSSI_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
66
67/**
68 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI 59 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
69 * 60 *
70 * The SSI has a limitation in that the samples must be in the same byte 61 * The SSI has a limitation in that the samples must be in the same byte
@@ -1212,14 +1203,14 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = {
1212 .stream_name = "CPU-Playback", 1203 .stream_name = "CPU-Playback",
1213 .channels_min = 1, 1204 .channels_min = 1,
1214 .channels_max = 32, 1205 .channels_max = 32,
1215 .rates = FSLSSI_I2S_RATES, 1206 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1216 .formats = FSLSSI_I2S_FORMATS, 1207 .formats = FSLSSI_I2S_FORMATS,
1217 }, 1208 },
1218 .capture = { 1209 .capture = {
1219 .stream_name = "CPU-Capture", 1210 .stream_name = "CPU-Capture",
1220 .channels_min = 1, 1211 .channels_min = 1,
1221 .channels_max = 32, 1212 .channels_max = 32,
1222 .rates = FSLSSI_I2S_RATES, 1213 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1223 .formats = FSLSSI_I2S_FORMATS, 1214 .formats = FSLSSI_I2S_FORMATS,
1224 }, 1215 },
1225 .ops = &fsl_ssi_dai_ops, 1216 .ops = &fsl_ssi_dai_ops,
@@ -1325,14 +1316,10 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
1325 */ 1316 */
1326static void make_lowercase(char *s) 1317static void make_lowercase(char *s)
1327{ 1318{
1328 char *p = s; 1319 if (!s)
1329 char c; 1320 return;
1330 1321 for (; *s; s++)
1331 while ((c = *p)) { 1322 *s = tolower(*s);
1332 if ((c >= 'A') && (c <= 'Z'))
1333 *p = c + ('a' - 'A');
1334 p++;
1335 }
1336} 1323}
1337 1324
1338static int fsl_ssi_imx_probe(struct platform_device *pdev, 1325static int fsl_ssi_imx_probe(struct platform_device *pdev,
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index bb0459018b45..9d19b808f634 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -48,7 +48,7 @@ static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream,
48 return snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16); 48 return snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16);
49} 49}
50 50
51static struct snd_soc_ops imx_mc13783_hifi_ops = { 51static const struct snd_soc_ops imx_mc13783_hifi_ops = {
52 .hw_params = imx_mc13783_hifi_hw_params, 52 .hw_params = imx_mc13783_hifi_hw_params,
53}; 53};
54 54
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index f3d3d1ffa84e..314814ddd2b0 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -33,48 +33,20 @@ static bool filter(struct dma_chan *chan, void *param)
33 return true; 33 return true;
34} 34}
35 35
36static const struct snd_pcm_hardware imx_pcm_hardware = {
37 .info = SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_BLOCK_TRANSFER |
39 SNDRV_PCM_INFO_MMAP |
40 SNDRV_PCM_INFO_MMAP_VALID |
41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME,
43 .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
44 .period_bytes_min = 128,
45 .period_bytes_max = 65535, /* Limited by SDMA engine */
46 .periods_min = 2,
47 .periods_max = 255,
48 .fifo_size = 0,
49};
50
51static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = { 36static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
52 .pcm_hardware = &imx_pcm_hardware,
53 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 37 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
54 .compat_filter_fn = filter, 38 .compat_filter_fn = filter,
55 .prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE,
56}; 39};
57 40
58int imx_pcm_dma_init(struct platform_device *pdev, size_t size) 41int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
59{ 42{
60 struct snd_dmaengine_pcm_config *config; 43 struct snd_dmaengine_pcm_config *config;
61 struct snd_pcm_hardware *pcm_hardware;
62 44
63 config = devm_kzalloc(&pdev->dev, 45 config = devm_kzalloc(&pdev->dev,
64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL); 46 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
65 if (!config) 47 if (!config)
66 return -ENOMEM; 48 return -ENOMEM;
67 *config = imx_dmaengine_pcm_config; 49 *config = imx_dmaengine_pcm_config;
68 if (size)
69 config->prealloc_buffer_size = size;
70
71 pcm_hardware = devm_kzalloc(&pdev->dev,
72 sizeof(struct snd_pcm_hardware), GFP_KERNEL);
73 *pcm_hardware = imx_pcm_hardware;
74 if (size)
75 pcm_hardware->buffer_bytes_max = size;
76
77 config->pcm_hardware = pcm_hardware;
78 50
79 return devm_snd_dmaengine_pcm_register(&pdev->dev, 51 return devm_snd_dmaengine_pcm_register(&pdev->dev,
80 config, 52 config,
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index dac6688540dc..92410f7ca1fa 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -282,7 +282,7 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
282 return 0; 282 return 0;
283} 283}
284 284
285static int ssi_irq = 0; 285static int ssi_irq;
286 286
287static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) 287static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
288{ 288{
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 1b60958e2080..206b898e554c 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -33,14 +33,14 @@ struct imx_wm8962_data {
33 struct snd_soc_card card; 33 struct snd_soc_card card;
34 char codec_dai_name[DAI_NAME_SIZE]; 34 char codec_dai_name[DAI_NAME_SIZE];
35 char platform_name[DAI_NAME_SIZE]; 35 char platform_name[DAI_NAME_SIZE];
36 struct clk *codec_clk;
37 unsigned int clk_frequency; 36 unsigned int clk_frequency;
38}; 37};
39 38
40struct imx_priv { 39struct imx_priv {
41 struct platform_device *pdev; 40 struct platform_device *pdev;
41 int sample_rate;
42 snd_pcm_format_t sample_format;
42}; 43};
43static struct imx_priv card_priv;
44 44
45static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = { 45static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
46 SND_SOC_DAPM_HP("Headphone Jack", NULL), 46 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -49,14 +49,14 @@ static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
49 SND_SOC_DAPM_MIC("DMIC", NULL), 49 SND_SOC_DAPM_MIC("DMIC", NULL),
50}; 50};
51 51
52static int sample_rate = 44100;
53static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
54
55static int imx_hifi_hw_params(struct snd_pcm_substream *substream, 52static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params) 53 struct snd_pcm_hw_params *params)
57{ 54{
58 sample_rate = params_rate(params); 55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 sample_format = params_format(params); 56 struct imx_priv *priv = snd_soc_card_get_drvdata(rtd->card);
57
58 priv->sample_rate = params_rate(params);
59 priv->sample_format = params_format(params);
60 60
61 return 0; 61 return 0;
62} 62}
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
71{ 71{
72 struct snd_soc_pcm_runtime *rtd; 72 struct snd_soc_pcm_runtime *rtd;
73 struct snd_soc_dai *codec_dai; 73 struct snd_soc_dai *codec_dai;
74 struct imx_priv *priv = &card_priv; 74 struct imx_priv *priv = snd_soc_card_get_drvdata(card);
75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
76 struct device *dev = &priv->pdev->dev; 76 struct device *dev = &priv->pdev->dev;
77 unsigned int pll_out; 77 unsigned int pll_out;
@@ -85,10 +85,10 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
85 switch (level) { 85 switch (level) {
86 case SND_SOC_BIAS_PREPARE: 86 case SND_SOC_BIAS_PREPARE:
87 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 87 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
88 if (sample_format == SNDRV_PCM_FORMAT_S24_LE) 88 if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
89 pll_out = sample_rate * 384; 89 pll_out = priv->sample_rate * 384;
90 else 90 else
91 pll_out = sample_rate * 256; 91 pll_out = priv->sample_rate * 256;
92 92
93 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 93 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
94 WM8962_FLL_MCLK, data->clk_frequency, 94 WM8962_FLL_MCLK, data->clk_frequency,
@@ -140,7 +140,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
140{ 140{
141 struct snd_soc_pcm_runtime *rtd; 141 struct snd_soc_pcm_runtime *rtd;
142 struct snd_soc_dai *codec_dai; 142 struct snd_soc_dai *codec_dai;
143 struct imx_priv *priv = &card_priv; 143 struct imx_priv *priv = snd_soc_card_get_drvdata(card);
144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
145 struct device *dev = &priv->pdev->dev; 145 struct device *dev = &priv->pdev->dev;
146 int ret; 146 int ret;
@@ -160,13 +160,20 @@ static int imx_wm8962_probe(struct platform_device *pdev)
160 struct device_node *np = pdev->dev.of_node; 160 struct device_node *np = pdev->dev.of_node;
161 struct device_node *ssi_np, *codec_np; 161 struct device_node *ssi_np, *codec_np;
162 struct platform_device *ssi_pdev; 162 struct platform_device *ssi_pdev;
163 struct imx_priv *priv = &card_priv;
164 struct i2c_client *codec_dev; 163 struct i2c_client *codec_dev;
165 struct imx_wm8962_data *data; 164 struct imx_wm8962_data *data;
165 struct imx_priv *priv;
166 struct clk *codec_clk;
166 int int_port, ext_port; 167 int int_port, ext_port;
167 int ret; 168 int ret;
168 169
170 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
171 if (!priv)
172 return -ENOMEM;
173
169 priv->pdev = pdev; 174 priv->pdev = pdev;
175 priv->sample_rate = 44100;
176 priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
170 177
171 ret = of_property_read_u32(np, "mux-int-port", &int_port); 178 ret = of_property_read_u32(np, "mux-int-port", &int_port);
172 if (ret) { 179 if (ret) {
@@ -231,19 +238,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
231 goto fail; 238 goto fail;
232 } 239 }
233 240
234 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL); 241 codec_clk = clk_get(&codec_dev->dev, NULL);
235 if (IS_ERR(data->codec_clk)) { 242 if (IS_ERR(codec_clk)) {
236 ret = PTR_ERR(data->codec_clk); 243 ret = PTR_ERR(codec_clk);
237 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret); 244 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
238 goto fail; 245 goto fail;
239 } 246 }
240 247
241 data->clk_frequency = clk_get_rate(data->codec_clk); 248 data->clk_frequency = clk_get_rate(codec_clk);
242 ret = clk_prepare_enable(data->codec_clk); 249 clk_put(codec_clk);
243 if (ret) {
244 dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
245 goto fail;
246 }
247 250
248 data->dai.name = "HiFi"; 251 data->dai.name = "HiFi";
249 data->dai.stream_name = "HiFi"; 252 data->dai.stream_name = "HiFi";
@@ -258,10 +261,10 @@ static int imx_wm8962_probe(struct platform_device *pdev)
258 data->card.dev = &pdev->dev; 261 data->card.dev = &pdev->dev;
259 ret = snd_soc_of_parse_card_name(&data->card, "model"); 262 ret = snd_soc_of_parse_card_name(&data->card, "model");
260 if (ret) 263 if (ret)
261 goto clk_fail; 264 goto fail;
262 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); 265 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
263 if (ret) 266 if (ret)
264 goto clk_fail; 267 goto fail;
265 data->card.num_links = 1; 268 data->card.num_links = 1;
266 data->card.owner = THIS_MODULE; 269 data->card.owner = THIS_MODULE;
267 data->card.dai_link = &data->dai; 270 data->card.dai_link = &data->dai;
@@ -277,16 +280,9 @@ static int imx_wm8962_probe(struct platform_device *pdev)
277 ret = devm_snd_soc_register_card(&pdev->dev, &data->card); 280 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
278 if (ret) { 281 if (ret) {
279 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 282 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
280 goto clk_fail; 283 goto fail;
281 } 284 }
282 285
283 of_node_put(ssi_np);
284 of_node_put(codec_np);
285
286 return 0;
287
288clk_fail:
289 clk_disable_unprepare(data->codec_clk);
290fail: 286fail:
291 of_node_put(ssi_np); 287 of_node_put(ssi_np);
292 of_node_put(codec_np); 288 of_node_put(codec_np);
@@ -294,17 +290,6 @@ fail:
294 return ret; 290 return ret;
295} 291}
296 292
297static int imx_wm8962_remove(struct platform_device *pdev)
298{
299 struct snd_soc_card *card = platform_get_drvdata(pdev);
300 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
301
302 if (!IS_ERR(data->codec_clk))
303 clk_disable_unprepare(data->codec_clk);
304
305 return 0;
306}
307
308static const struct of_device_id imx_wm8962_dt_ids[] = { 293static const struct of_device_id imx_wm8962_dt_ids[] = {
309 { .compatible = "fsl,imx-audio-wm8962", }, 294 { .compatible = "fsl,imx-audio-wm8962", },
310 { /* sentinel */ } 295 { /* sentinel */ }
@@ -318,7 +303,6 @@ static struct platform_driver imx_wm8962_driver = {
318 .of_match_table = imx_wm8962_dt_ids, 303 .of_match_table = imx_wm8962_dt_ids,
319 }, 304 },
320 .probe = imx_wm8962_probe, 305 .probe = imx_wm8962_probe,
321 .remove = imx_wm8962_remove,
322}; 306};
323module_platform_driver(imx_wm8962_driver); 307module_platform_driver(imx_wm8962_driver);
324 308
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ddf49f30b23f..a639b52c16f6 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -174,7 +174,7 @@ static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
174/** 174/**
175 * mpc8610_hpcd_ops: ASoC machine driver operations 175 * mpc8610_hpcd_ops: ASoC machine driver operations
176 */ 176 */
177static struct snd_soc_ops mpc8610_hpcd_ops = { 177static const struct snd_soc_ops mpc8610_hpcd_ops = {
178 .startup = mpc8610_hpcd_startup, 178 .startup = mpc8610_hpcd_startup,
179}; 179};
180 180
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index 198eeb3f3f7a..d7ec3d20065c 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -73,7 +73,7 @@ static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
73 return 0; 73 return 0;
74} 74}
75 75
76static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { 76static const struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
77 .hw_params = mx27vis_aic32x4_hw_params, 77 .hw_params = mx27vis_aic32x4_hw_params,
78}; 78};
79 79
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index a1f780ecadf5..41c623c55c16 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -184,7 +184,7 @@ static int p1022_ds_machine_remove(struct snd_soc_card *card)
184/** 184/**
185 * p1022_ds_ops: ASoC machine driver operations 185 * p1022_ds_ops: ASoC machine driver operations
186 */ 186 */
187static struct snd_soc_ops p1022_ds_ops = { 187static const struct snd_soc_ops p1022_ds_ops = {
188 .startup = p1022_ds_startup, 188 .startup = p1022_ds_startup,
189}; 189};
190 190
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index d4d88a8cb9c0..4afbdd610bfa 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -188,7 +188,7 @@ static int p1022_rdk_machine_remove(struct snd_soc_card *card)
188/** 188/**
189 * p1022_rdk_ops: ASoC machine driver operations 189 * p1022_rdk_ops: ASoC machine driver operations
190 */ 190 */
191static struct snd_soc_ops p1022_rdk_ops = { 191static const struct snd_soc_ops p1022_rdk_ops = {
192 .startup = p1022_rdk_startup, 192 .startup = p1022_rdk_startup,
193}; 193};
194 194
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index ae403c29688f..66fb6c4614d2 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -23,7 +23,7 @@
23 23
24static struct snd_soc_card imx_phycore; 24static struct snd_soc_card imx_phycore;
25 25
26static struct snd_soc_ops imx_phycore_hifi_ops = { 26static const struct snd_soc_ops imx_phycore_hifi_ops = {
27}; 27};
28 28
29static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { 29static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index b454972dce35..cdaf16367b47 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -139,7 +139,7 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
139 return 0; 139 return 0;
140} 140}
141 141
142static struct snd_soc_ops wm1133_ev1_ops = { 142static const struct snd_soc_ops wm1133_ev1_ops = {
143 .hw_params = wm1133_ev1_hw_params, 143 .hw_params = wm1133_ev1_hw_params,
144}; 144};
145 145
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 85b4f1806514..2c9dedab5184 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -40,9 +40,10 @@ struct simple_card_data {
40 struct snd_soc_dai_link *dai_link; 40 struct snd_soc_dai_link *dai_link;
41}; 41};
42 42
43#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) 43#define simple_priv_to_card(priv) (&(priv)->snd_card)
44#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
45#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) 44#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
45#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
46#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
46 47
47#define DAI "sound-dai" 48#define DAI "sound-dai"
48#define CELL "#sound-dai-cells" 49#define CELL "#sound-dai-cells"
@@ -323,6 +324,7 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
323{ 324{
324 struct device *dev = simple_priv_to_dev(priv); 325 struct device *dev = simple_priv_to_dev(priv);
325 struct device_node *aux_node; 326 struct device_node *aux_node;
327 struct snd_soc_card *card = simple_priv_to_card(priv);
326 int i, n, len; 328 int i, n, len;
327 329
328 if (!of_find_property(node, PREFIX "aux-devs", &len)) 330 if (!of_find_property(node, PREFIX "aux-devs", &len))
@@ -332,19 +334,19 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
332 if (n <= 0) 334 if (n <= 0)
333 return -EINVAL; 335 return -EINVAL;
334 336
335 priv->snd_card.aux_dev = devm_kzalloc(dev, 337 card->aux_dev = devm_kzalloc(dev,
336 n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL); 338 n * sizeof(*card->aux_dev), GFP_KERNEL);
337 if (!priv->snd_card.aux_dev) 339 if (!card->aux_dev)
338 return -ENOMEM; 340 return -ENOMEM;
339 341
340 for (i = 0; i < n; i++) { 342 for (i = 0; i < n; i++) {
341 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); 343 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
342 if (!aux_node) 344 if (!aux_node)
343 return -EINVAL; 345 return -EINVAL;
344 priv->snd_card.aux_dev[i].codec_of_node = aux_node; 346 card->aux_dev[i].codec_of_node = aux_node;
345 } 347 }
346 348
347 priv->snd_card.num_aux_devs = n; 349 card->num_aux_devs = n;
348 return 0; 350 return 0;
349} 351}
350 352
@@ -352,6 +354,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
352 struct simple_card_data *priv) 354 struct simple_card_data *priv)
353{ 355{
354 struct device *dev = simple_priv_to_dev(priv); 356 struct device *dev = simple_priv_to_dev(priv);
357 struct snd_soc_card *card = simple_priv_to_card(priv);
355 struct device_node *dai_link; 358 struct device_node *dai_link;
356 int ret; 359 int ret;
357 360
@@ -362,7 +365,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
362 365
363 /* The off-codec widgets */ 366 /* The off-codec widgets */
364 if (of_property_read_bool(node, PREFIX "widgets")) { 367 if (of_property_read_bool(node, PREFIX "widgets")) {
365 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 368 ret = snd_soc_of_parse_audio_simple_widgets(card,
366 PREFIX "widgets"); 369 PREFIX "widgets");
367 if (ret) 370 if (ret)
368 goto card_parse_end; 371 goto card_parse_end;
@@ -370,7 +373,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
370 373
371 /* DAPM routes */ 374 /* DAPM routes */
372 if (of_property_read_bool(node, PREFIX "routing")) { 375 if (of_property_read_bool(node, PREFIX "routing")) {
373 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, 376 ret = snd_soc_of_parse_audio_routing(card,
374 PREFIX "routing"); 377 PREFIX "routing");
375 if (ret) 378 if (ret)
376 goto card_parse_end; 379 goto card_parse_end;
@@ -401,7 +404,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
401 goto card_parse_end; 404 goto card_parse_end;
402 } 405 }
403 406
404 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); 407 ret = asoc_simple_card_parse_card_name(card, PREFIX);
405 if (ret < 0) 408 if (ret < 0)
406 goto card_parse_end; 409 goto card_parse_end;
407 410
@@ -418,8 +421,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
418 struct simple_card_data *priv; 421 struct simple_card_data *priv;
419 struct snd_soc_dai_link *dai_link; 422 struct snd_soc_dai_link *dai_link;
420 struct simple_dai_props *dai_props; 423 struct simple_dai_props *dai_props;
421 struct device_node *np = pdev->dev.of_node;
422 struct device *dev = &pdev->dev; 424 struct device *dev = &pdev->dev;
425 struct device_node *np = dev->of_node;
426 struct snd_soc_card *card;
423 int num, ret; 427 int num, ret;
424 428
425 /* Get the number of DAI links */ 429 /* Get the number of DAI links */
@@ -442,10 +446,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
442 priv->dai_link = dai_link; 446 priv->dai_link = dai_link;
443 447
444 /* Init snd_soc_card */ 448 /* Init snd_soc_card */
445 priv->snd_card.owner = THIS_MODULE; 449 card = simple_priv_to_card(priv);
446 priv->snd_card.dev = dev; 450 card->owner = THIS_MODULE;
447 priv->snd_card.dai_link = priv->dai_link; 451 card->dev = dev;
448 priv->snd_card.num_links = num; 452 card->dai_link = priv->dai_link;
453 card->num_links = num;
449 454
450 if (np && of_device_is_available(np)) { 455 if (np && of_device_is_available(np)) {
451 456
@@ -474,7 +479,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
474 return -EINVAL; 479 return -EINVAL;
475 } 480 }
476 481
477 priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name; 482 card->name = (cinfo->card) ? cinfo->card : cinfo->name;
478 dai_link->name = cinfo->name; 483 dai_link->name = cinfo->name;
479 dai_link->stream_name = cinfo->name; 484 dai_link->stream_name = cinfo->name;
480 dai_link->platform_name = cinfo->platform; 485 dai_link->platform_name = cinfo->platform;
@@ -489,13 +494,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
489 sizeof(priv->dai_props->codec_dai)); 494 sizeof(priv->dai_props->codec_dai));
490 } 495 }
491 496
492 snd_soc_card_set_drvdata(&priv->snd_card, priv); 497 snd_soc_card_set_drvdata(card, priv);
493 498
494 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 499 ret = devm_snd_soc_register_card(dev, card);
495 if (ret >= 0) 500 if (ret >= 0)
496 return ret; 501 return ret;
497err: 502err:
498 asoc_simple_card_clean_reference(&priv->snd_card); 503 asoc_simple_card_clean_reference(card);
499 504
500 return ret; 505 return ret;
501} 506}
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index 308ff4c11a8d..dcbcab230d1b 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -31,9 +31,10 @@ struct simple_card_data {
31 u32 convert_channels; 31 u32 convert_channels;
32}; 32};
33 33
34#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) 34#define simple_priv_to_card(priv) (&(priv)->snd_card)
35#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
36#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) 35#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
36#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
37#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
37 38
38#define DAI "sound-dai" 39#define DAI "sound-dai"
39#define CELL "#sound-dai-cells" 40#define CELL "#sound-dai-cells"
@@ -109,6 +110,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
109 struct device *dev = simple_priv_to_dev(priv); 110 struct device *dev = simple_priv_to_dev(priv);
110 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 111 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
111 struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx); 112 struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
113 struct snd_soc_card *card = simple_priv_to_card(priv);
112 int ret; 114 int ret;
113 115
114 if (is_fe) { 116 if (is_fe) {
@@ -163,7 +165,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
163 if (ret < 0) 165 if (ret < 0)
164 return ret; 166 return ret;
165 167
166 snd_soc_of_parse_audio_prefix(&priv->snd_card, 168 snd_soc_of_parse_audio_prefix(card,
167 &priv->codec_conf, 169 &priv->codec_conf,
168 dai_link->codec_of_node, 170 dai_link->codec_of_node,
169 PREFIX "prefix"); 171 PREFIX "prefix");
@@ -201,6 +203,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
201{ 203{
202 struct device *dev = simple_priv_to_dev(priv); 204 struct device *dev = simple_priv_to_dev(priv);
203 struct device_node *np; 205 struct device_node *np;
206 struct snd_soc_card *card = simple_priv_to_card(priv);
204 unsigned int daifmt = 0; 207 unsigned int daifmt = 0;
205 bool is_fe; 208 bool is_fe;
206 int ret, i; 209 int ret, i;
@@ -208,7 +211,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
208 if (!node) 211 if (!node)
209 return -EINVAL; 212 return -EINVAL;
210 213
211 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing"); 214 ret = snd_soc_of_parse_audio_routing(card, PREFIX "routing");
212 if (ret < 0) 215 if (ret < 0)
213 return ret; 216 return ret;
214 217
@@ -239,12 +242,12 @@ static int asoc_simple_card_parse_of(struct device_node *node,
239 i++; 242 i++;
240 } 243 }
241 244
242 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); 245 ret = asoc_simple_card_parse_card_name(card, PREFIX);
243 if (ret < 0) 246 if (ret < 0)
244 return ret; 247 return ret;
245 248
246 dev_dbg(dev, "New card: %s\n", 249 dev_dbg(dev, "New card: %s\n",
247 priv->snd_card.name ? priv->snd_card.name : ""); 250 card->name ? card->name : "");
248 dev_dbg(dev, "convert_rate %d\n", priv->convert_rate); 251 dev_dbg(dev, "convert_rate %d\n", priv->convert_rate);
249 dev_dbg(dev, "convert_channels %d\n", priv->convert_channels); 252 dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
250 253
@@ -256,8 +259,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
256 struct simple_card_data *priv; 259 struct simple_card_data *priv;
257 struct snd_soc_dai_link *dai_link; 260 struct snd_soc_dai_link *dai_link;
258 struct asoc_simple_dai *dai_props; 261 struct asoc_simple_dai *dai_props;
262 struct snd_soc_card *card;
259 struct device *dev = &pdev->dev; 263 struct device *dev = &pdev->dev;
260 struct device_node *np = pdev->dev.of_node; 264 struct device_node *np = dev->of_node;
261 int num, ret; 265 int num, ret;
262 266
263 /* Allocate the private data */ 267 /* Allocate the private data */
@@ -276,12 +280,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
276 priv->dai_link = dai_link; 280 priv->dai_link = dai_link;
277 281
278 /* Init snd_soc_card */ 282 /* Init snd_soc_card */
279 priv->snd_card.owner = THIS_MODULE; 283 card = simple_priv_to_card(priv);
280 priv->snd_card.dev = dev; 284 card->owner = THIS_MODULE;
281 priv->snd_card.dai_link = priv->dai_link; 285 card->dev = dev;
282 priv->snd_card.num_links = num; 286 card->dai_link = priv->dai_link;
283 priv->snd_card.codec_conf = &priv->codec_conf; 287 card->num_links = num;
284 priv->snd_card.num_configs = 1; 288 card->codec_conf = &priv->codec_conf;
289 card->num_configs = 1;
285 290
286 ret = asoc_simple_card_parse_of(np, priv); 291 ret = asoc_simple_card_parse_of(np, priv);
287 if (ret < 0) { 292 if (ret < 0) {
@@ -290,13 +295,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
290 goto err; 295 goto err;
291 } 296 }
292 297
293 snd_soc_card_set_drvdata(&priv->snd_card, priv); 298 snd_soc_card_set_drvdata(card, priv);
294 299
295 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 300 ret = devm_snd_soc_register_card(dev, card);
296 if (ret >= 0) 301 if (ret >= 0)
297 return ret; 302 return ret;
298err: 303err:
299 asoc_simple_card_clean_reference(&priv->snd_card); 304 asoc_simple_card_clean_reference(card);
300 305
301 return ret; 306 return ret;
302} 307}
diff --git a/sound/soc/hisilicon/Kconfig b/sound/soc/hisilicon/Kconfig
new file mode 100644
index 000000000000..4356d5a1d338
--- /dev/null
+++ b/sound/soc/hisilicon/Kconfig
@@ -0,0 +1,5 @@
1config SND_I2S_HI6210_I2S
2 tristate "Hisilicon I2S controller"
3 select SND_SOC_GENERIC_DMAENGINE_PCM
4 help
5 Hisilicon I2S
diff --git a/sound/soc/hisilicon/Makefile b/sound/soc/hisilicon/Makefile
new file mode 100644
index 000000000000..e8095e2af91a
--- /dev/null
+++ b/sound/soc/hisilicon/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SND_I2S_HI6210_I2S) += hi6210-i2s.o
diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c
new file mode 100644
index 000000000000..45163e5202f5
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.c
@@ -0,0 +1,618 @@
1/*
2 * linux/sound/soc/m8m/hi6210_i2s.c - I2S IP driver
3 *
4 * Copyright (C) 2015 Linaro, Ltd
5 * Author: Andy Green <andy.green@linaro.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver only deals with S2 interface (BT)
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/jiffies.h>
25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/dmaengine_pcm.h>
31#include <sound/initval.h>
32#include <sound/soc.h>
33#include <linux/interrupt.h>
34#include <linux/reset.h>
35#include <linux/of_address.h>
36#include <linux/of_irq.h>
37#include <linux/mfd/syscon.h>
38#include <linux/reset-controller.h>
39#include <linux/clk.h>
40
41#include "hi6210-i2s.h"
42
43struct hi6210_i2s {
44 struct device *dev;
45 struct reset_control *rc;
46 struct clk *clk[8];
47 int clocks;
48 struct snd_soc_dai_driver dai;
49 void __iomem *base;
50 struct regmap *sysctrl;
51 phys_addr_t base_phys;
52 struct snd_dmaengine_dai_dma_data dma_data[2];
53 int clk_rate;
54 spinlock_t lock;
55 int rate;
56 int format;
57 u8 bits;
58 u8 channels;
59 u8 id;
60 u8 channel_length;
61 u8 use;
62 u32 master:1;
63 u32 status:1;
64};
65
66#define SC_PERIPH_CLKEN1 0x210
67#define SC_PERIPH_CLKDIS1 0x214
68
69#define SC_PERIPH_CLKEN3 0x230
70#define SC_PERIPH_CLKDIS3 0x234
71
72#define SC_PERIPH_CLKEN12 0x270
73#define SC_PERIPH_CLKDIS12 0x274
74
75#define SC_PERIPH_RSTEN1 0x310
76#define SC_PERIPH_RSTDIS1 0x314
77#define SC_PERIPH_RSTSTAT1 0x318
78
79#define SC_PERIPH_RSTEN2 0x320
80#define SC_PERIPH_RSTDIS2 0x324
81#define SC_PERIPH_RSTSTAT2 0x328
82
83#define SOC_PMCTRL_BBPPLLALIAS 0x48
84
85enum {
86 CLK_DACODEC,
87 CLK_I2S_BASE,
88};
89
90static inline void hi6210_write_reg(struct hi6210_i2s *i2s, int reg, u32 val)
91{
92 writel(val, i2s->base + reg);
93}
94
95static inline u32 hi6210_read_reg(struct hi6210_i2s *i2s, int reg)
96{
97 return readl(i2s->base + reg);
98}
99
100int hi6210_i2s_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *cpu_dai)
102{
103 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
104 int ret, n;
105 u32 val;
106
107 /* deassert reset on ABB */
108 regmap_read(i2s->sysctrl, SC_PERIPH_RSTSTAT2, &val);
109 if (val & BIT(4))
110 regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS2, BIT(4));
111
112 for (n = 0; n < i2s->clocks; n++) {
113 ret = clk_prepare_enable(i2s->clk[n]);
114 if (ret) {
115 while (n--)
116 clk_disable_unprepare(i2s->clk[n]);
117 return ret;
118 }
119 }
120
121 ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
122 if (ret) {
123 dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
124 __func__, ret);
125 return ret;
126 }
127
128 /* enable clock before frequency division */
129 regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN12, BIT(9));
130
131 /* enable codec working clock / == "codec bus clock" */
132 regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN1, BIT(5));
133
134 /* deassert reset on codec / interface clock / working clock */
135 regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
136 regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS1, BIT(5));
137
138 /* not interested in i2s irqs */
139 val = hi6210_read_reg(i2s, HII2S_CODEC_IRQ_MASK);
140 val |= 0x3f;
141 hi6210_write_reg(i2s, HII2S_CODEC_IRQ_MASK, val);
142
143
144 /* reset the stereo downlink fifo */
145 val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
146 val |= (BIT(5) | BIT(4));
147 hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
148
149 val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
150 val &= ~(BIT(5) | BIT(4));
151 hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
152
153
154 val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
155 val &= ~(HII2S_SW_RST_N__ST_DL_WORDLEN_MASK <<
156 HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
157 val |= (HII2S_BITS_16 << HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
158 hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
159
160 val = hi6210_read_reg(i2s, HII2S_MISC_CFG);
161 /* mux 11/12 = APB not i2s */
162 val &= ~HII2S_MISC_CFG__ST_DL_TEST_SEL;
163 /* BT R ch 0 = mixer op of DACR ch */
164 val &= ~HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
165 val &= ~HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
166
167 val |= HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
168 /* BT L ch = 1 = mux 7 = "mixer output of DACL */
169 val |= HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
170 hi6210_write_reg(i2s, HII2S_MISC_CFG, val);
171
172 val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
173 val |= HII2S_SW_RST_N__SW_RST_N;
174 hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
175
176 return 0;
177}
178void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
179 struct snd_soc_dai *cpu_dai)
180{
181 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
182 int n;
183
184 for (n = 0; n < i2s->clocks; n++)
185 clk_disable_unprepare(i2s->clk[n]);
186
187 regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
188}
189
190static void hi6210_i2s_txctrl(struct snd_soc_dai *cpu_dai, int on)
191{
192 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
193 u32 val;
194
195 spin_lock(&i2s->lock);
196 if (on) {
197 /* enable S2 TX */
198 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
199 val |= HII2S_I2S_CFG__S2_IF_TX_EN;
200 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
201 } else {
202 /* disable S2 TX */
203 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
204 val &= ~HII2S_I2S_CFG__S2_IF_TX_EN;
205 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
206 }
207 spin_unlock(&i2s->lock);
208}
209
210static void hi6210_i2s_rxctrl(struct snd_soc_dai *cpu_dai, int on)
211{
212 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
213 u32 val;
214
215 spin_lock(&i2s->lock);
216 if (on) {
217 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
218 val |= HII2S_I2S_CFG__S2_IF_RX_EN;
219 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
220 } else {
221 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
222 val &= ~HII2S_I2S_CFG__S2_IF_RX_EN;
223 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
224 }
225 spin_unlock(&i2s->lock);
226}
227
228static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
229{
230 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
231
232 /*
233 * We don't actually set the hardware until the hw_params
234 * call, but we need to validate the user input here.
235 */
236 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
237 case SND_SOC_DAIFMT_CBM_CFM:
238 case SND_SOC_DAIFMT_CBS_CFS:
239 break;
240 default:
241 return -EINVAL;
242 }
243
244 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
245 case SND_SOC_DAIFMT_I2S:
246 case SND_SOC_DAIFMT_LEFT_J:
247 case SND_SOC_DAIFMT_RIGHT_J:
248 break;
249 default:
250 return -EINVAL;
251 }
252
253 i2s->format = fmt;
254 i2s->master = (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) ==
255 SND_SOC_DAIFMT_CBS_CFS;
256
257 return 0;
258}
259
260static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream,
261 struct snd_pcm_hw_params *params,
262 struct snd_soc_dai *cpu_dai)
263{
264 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
265 u32 bits = 0, rate = 0, signed_data = 0, fmt = 0;
266 u32 val;
267 struct snd_dmaengine_dai_dma_data *dma_data;
268
269 switch (params_format(params)) {
270 case SNDRV_PCM_FORMAT_U16_LE:
271 signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
272 /* fallthru */
273 case SNDRV_PCM_FORMAT_S16_LE:
274 bits = HII2S_BITS_16;
275 break;
276 case SNDRV_PCM_FORMAT_U24_LE:
277 signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
278 /* fallthru */
279 case SNDRV_PCM_FORMAT_S24_LE:
280 bits = HII2S_BITS_24;
281 break;
282 default:
283 dev_err(cpu_dai->dev, "Bad format\n");
284 return -EINVAL;
285 }
286
287
288 switch (params_rate(params)) {
289 case 8000:
290 rate = HII2S_FS_RATE_8KHZ;
291 break;
292 case 16000:
293 rate = HII2S_FS_RATE_16KHZ;
294 break;
295 case 32000:
296 rate = HII2S_FS_RATE_32KHZ;
297 break;
298 case 48000:
299 rate = HII2S_FS_RATE_48KHZ;
300 break;
301 case 96000:
302 rate = HII2S_FS_RATE_96KHZ;
303 break;
304 case 192000:
305 rate = HII2S_FS_RATE_192KHZ;
306 break;
307 default:
308 dev_err(cpu_dai->dev, "Bad rate: %d\n", params_rate(params));
309 return -EINVAL;
310 }
311
312 if (!(params_channels(params))) {
313 dev_err(cpu_dai->dev, "Bad channels\n");
314 return -EINVAL;
315 }
316
317 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
318
319 switch (bits) {
320 case HII2S_BITS_24:
321 i2s->bits = 32;
322 dma_data->addr_width = 3;
323 break;
324 default:
325 i2s->bits = 16;
326 dma_data->addr_width = 2;
327 break;
328 }
329 i2s->rate = params_rate(params);
330 i2s->channels = params_channels(params);
331 i2s->channel_length = i2s->channels * i2s->bits;
332
333 val = hi6210_read_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG);
334 val &= ~((HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK <<
335 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
336 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK <<
337 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
338 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK <<
339 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
340 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK <<
341 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
342 val |= ((16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
343 (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
344 (16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
345 (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
346 hi6210_write_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG, val);
347
348
349 val = hi6210_read_reg(i2s, HII2S_IF_CLK_EN_CFG);
350 val |= (BIT(19) | BIT(18) | BIT(17) |
351 HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN |
352 HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN |
353 HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN |
354 HII2S_IF_CLK_EN_CFG__ST_DL_R_EN |
355 HII2S_IF_CLK_EN_CFG__ST_DL_L_EN);
356 hi6210_write_reg(i2s, HII2S_IF_CLK_EN_CFG, val);
357
358
359 val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG);
360 val &= ~(HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN |
361 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN |
362 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN |
363 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN |
364 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN |
365 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN);
366 val |= (HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN |
367 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN);
368 hi6210_write_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG, val);
369
370
371 val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG);
372 val &= ~(HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE |
373 HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE);
374 hi6210_write_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG, val);
375
376 val = hi6210_read_reg(i2s, HII2S_MUX_TOP_MODULE_CFG);
377 val &= ~(HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE |
378 HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE |
379 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE |
380 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE);
381 hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val);
382
383
384 switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) {
385 case SND_SOC_DAIFMT_CBM_CFM:
386 i2s->master = false;
387 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
388 val |= HII2S_I2S_CFG__S2_MST_SLV;
389 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 i2s->master = true;
393 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
394 val &= ~HII2S_I2S_CFG__S2_MST_SLV;
395 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
396 break;
397 default:
398 WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n");
399 return -EINVAL;
400 }
401
402 switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
403 case SND_SOC_DAIFMT_I2S:
404 fmt = HII2S_FORMAT_I2S;
405 break;
406 case SND_SOC_DAIFMT_LEFT_J:
407 fmt = HII2S_FORMAT_LEFT_JUST;
408 break;
409 case SND_SOC_DAIFMT_RIGHT_J:
410 fmt = HII2S_FORMAT_RIGHT_JUST;
411 break;
412 default:
413 WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
414 return -EINVAL;
415 }
416
417 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
418 val &= ~(HII2S_I2S_CFG__S2_FUNC_MODE_MASK <<
419 HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT);
420 val |= fmt << HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT;
421 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
422
423
424 val = hi6210_read_reg(i2s, HII2S_CLK_SEL);
425 val &= ~(HII2S_CLK_SEL__I2S_BT_FM_SEL | /* BT gets the I2S */
426 HII2S_CLK_SEL__EXT_12_288MHZ_SEL);
427 hi6210_write_reg(i2s, HII2S_CLK_SEL, val);
428
429 dma_data->maxburst = 2;
430
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
432 dma_data->addr = i2s->base_phys + HII2S_ST_DL_CHANNEL;
433 else
434 dma_data->addr = i2s->base_phys + HII2S_STEREO_UPLINK_CHANNEL;
435
436 switch (i2s->channels) {
437 case 1:
438 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
439 val |= HII2S_I2S_CFG__S2_FRAME_MODE;
440 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
441 break;
442 default:
443 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
444 val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
445 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
446 break;
447 }
448
449 /* clear loopback, set signed type and word length */
450 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
451 val &= ~HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
452 val &= ~(HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK <<
453 HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
454 val &= ~(HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK <<
455 HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT);
456 val |= signed_data;
457 val |= (bits << HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
458 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
459
460
461 if (!i2s->master)
462 return 0;
463
464 /* set DAC and related units to correct rate */
465 val = hi6210_read_reg(i2s, HII2S_FS_CFG);
466 val &= ~(HII2S_FS_CFG__FS_S2_MASK << HII2S_FS_CFG__FS_S2_SHIFT);
467 val &= ~(HII2S_FS_CFG__FS_DACLR_MASK << HII2S_FS_CFG__FS_DACLR_SHIFT);
468 val &= ~(HII2S_FS_CFG__FS_ST_DL_R_MASK <<
469 HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
470 val &= ~(HII2S_FS_CFG__FS_ST_DL_L_MASK <<
471 HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
472 val |= (rate << HII2S_FS_CFG__FS_S2_SHIFT);
473 val |= (rate << HII2S_FS_CFG__FS_DACLR_SHIFT);
474 val |= (rate << HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
475 val |= (rate << HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
476 hi6210_write_reg(i2s, HII2S_FS_CFG, val);
477
478 return 0;
479}
480
481static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
482 struct snd_soc_dai *cpu_dai)
483{
484 pr_debug("%s\n", __func__);
485 switch (cmd) {
486 case SNDRV_PCM_TRIGGER_START:
487 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
488 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
489 hi6210_i2s_rxctrl(cpu_dai, 1);
490 else
491 hi6210_i2s_txctrl(cpu_dai, 1);
492 break;
493 case SNDRV_PCM_TRIGGER_STOP:
494 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
495 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
496 hi6210_i2s_rxctrl(cpu_dai, 0);
497 else
498 hi6210_i2s_txctrl(cpu_dai, 0);
499 break;
500 default:
501 dev_err(cpu_dai->dev, "uknown cmd\n");
502 return -EINVAL;
503 }
504 return 0;
505}
506
507static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai)
508{
509 struct hi6210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
510
511 snd_soc_dai_init_dma_data(dai,
512 &i2s->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
513 &i2s->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
514
515 return 0;
516}
517
518
519static struct snd_soc_dai_ops hi6210_i2s_dai_ops = {
520 .trigger = hi6210_i2s_trigger,
521 .hw_params = hi6210_i2s_hw_params,
522 .set_fmt = hi6210_i2s_set_fmt,
523 .startup = hi6210_i2s_startup,
524 .shutdown = hi6210_i2s_shutdown,
525};
526
527struct snd_soc_dai_driver hi6210_i2s_dai_init = {
528 .probe = hi6210_i2s_dai_probe,
529 .playback = {
530 .channels_min = 2,
531 .channels_max = 2,
532 .formats = SNDRV_PCM_FMTBIT_S16_LE |
533 SNDRV_PCM_FMTBIT_U16_LE,
534 .rates = SNDRV_PCM_RATE_48000,
535 },
536 .capture = {
537 .channels_min = 2,
538 .channels_max = 2,
539 .formats = SNDRV_PCM_FMTBIT_S16_LE |
540 SNDRV_PCM_FMTBIT_U16_LE,
541 .rates = SNDRV_PCM_RATE_48000,
542 },
543 .ops = &hi6210_i2s_dai_ops,
544};
545
546static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = {
547 .name = "hi6210_i2s-i2s",
548};
549
550static int hi6210_i2s_probe(struct platform_device *pdev)
551{
552 struct device_node *node = pdev->dev.of_node;
553 struct device *dev = &pdev->dev;
554 struct hi6210_i2s *i2s;
555 struct resource *res;
556 int ret;
557
558 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
559 if (!i2s)
560 return -ENOMEM;
561
562 i2s->dev = dev;
563 spin_lock_init(&i2s->lock);
564
565 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
566 i2s->base = devm_ioremap_resource(dev, res);
567 if (IS_ERR(i2s->base))
568 return PTR_ERR(i2s->base);
569
570 i2s->base_phys = (phys_addr_t)res->start;
571 i2s->dai = hi6210_i2s_dai_init;
572
573 dev_set_drvdata(&pdev->dev, i2s);
574
575 i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
576 "hisilicon,sysctrl-syscon");
577 if (IS_ERR(i2s->sysctrl))
578 return PTR_ERR(i2s->sysctrl);
579
580 i2s->clk[CLK_DACODEC] = devm_clk_get(&pdev->dev, "dacodec");
581 if (IS_ERR_OR_NULL(i2s->clk[CLK_DACODEC]))
582 return PTR_ERR(i2s->clk[CLK_DACODEC]);
583 i2s->clocks++;
584
585 i2s->clk[CLK_I2S_BASE] = devm_clk_get(&pdev->dev, "i2s-base");
586 if (IS_ERR_OR_NULL(i2s->clk[CLK_I2S_BASE]))
587 return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
588 i2s->clocks++;
589
590 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
591 if (ret)
592 return ret;
593
594 ret = devm_snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
595 &i2s->dai, 1);
596 return ret;
597}
598
599static const struct of_device_id hi6210_i2s_dt_ids[] = {
600 { .compatible = "hisilicon,hi6210-i2s" },
601 { /* sentinel */ }
602};
603
604MODULE_DEVICE_TABLE(of, hi6210_i2s_dt_ids);
605
606static struct platform_driver hi6210_i2s_driver = {
607 .probe = hi6210_i2s_probe,
608 .driver = {
609 .name = "hi6210_i2s",
610 .of_match_table = hi6210_i2s_dt_ids,
611 },
612};
613
614module_platform_driver(hi6210_i2s_driver);
615
616MODULE_DESCRIPTION("Hisilicon HI6210 I2S driver");
617MODULE_AUTHOR("Andy Green <andy.green@linaro.org>");
618MODULE_LICENSE("GPL");
diff --git a/sound/soc/hisilicon/hi6210-i2s.h b/sound/soc/hisilicon/hi6210-i2s.h
new file mode 100644
index 000000000000..85cecc4939a0
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.h
@@ -0,0 +1,276 @@
1/*
2 * linux/sound/soc/hisilicon/hi6210-i2s.h
3 *
4 * Copyright (C) 2015 Linaro, Ltd
5 * Author: Andy Green <andy.green@linaro.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Note at least on 6220, S2 == BT, S1 == Digital FM Radio IF
20 */
21
22#ifndef _HI6210_I2S_H
23#define _HI6210_I2S_H
24
25#define HII2S_SW_RST_N 0
26
27#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_SHIFT 28
28#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_MASK 3
29#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_SHIFT 26
30#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_MASK 3
31#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_SHIFT 24
32#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_MASK 3
33#define HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT 20
34#define HII2S_SW_RST_N__ST_DL_WORDLEN_MASK 3
35#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_SHIFT 18
36#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_MASK 3
37#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_SHIFT 16
38#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_MASK 3
39
40#define HII2S_SW_RST_N__SW_RST_N BIT(0)
41
42enum hi6210_bits {
43 HII2S_BITS_16,
44 HII2S_BITS_18,
45 HII2S_BITS_20,
46 HII2S_BITS_24,
47};
48
49
50#define HII2S_IF_CLK_EN_CFG 4
51
52#define HII2S_IF_CLK_EN_CFG__THIRDMD_UPLINK_EN BIT(25)
53#define HII2S_IF_CLK_EN_CFG__THIRDMD_DLINK_EN BIT(24)
54#define HII2S_IF_CLK_EN_CFG__S3_IF_CLK_EN BIT(20)
55#define HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN BIT(16)
56#define HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN BIT(15)
57#define HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN BIT(14)
58#define HII2S_IF_CLK_EN_CFG__S2_IR_PGA_EN BIT(13)
59#define HII2S_IF_CLK_EN_CFG__S2_IL_PGA_EN BIT(12)
60#define HII2S_IF_CLK_EN_CFG__S1_IR_PGA_EN BIT(10)
61#define HII2S_IF_CLK_EN_CFG__S1_IL_PGA_EN BIT(9)
62#define HII2S_IF_CLK_EN_CFG__S1_IF_CLK_EN BIT(8)
63#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_SRC_EN BIT(7)
64#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_EN BIT(6)
65#define HII2S_IF_CLK_EN_CFG__ST_DL_R_EN BIT(5)
66#define HII2S_IF_CLK_EN_CFG__ST_DL_L_EN BIT(4)
67#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_R_EN BIT(3)
68#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_L_EN BIT(2)
69#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_R_EN BIT(1)
70#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_L_EN BIT(0)
71
72#define HII2S_DIG_FILTER_CLK_EN_CFG 8
73#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN BIT(30)
74#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN BIT(28)
75#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN BIT(25)
76#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN BIT(24)
77#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN BIT(22)
78#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN BIT(20)
79#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN BIT(17)
80#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN BIT(16)
81
82#define HII2S_FS_CFG 0xc
83
84#define HII2S_FS_CFG__FS_S2_SHIFT 28
85#define HII2S_FS_CFG__FS_S2_MASK 7
86#define HII2S_FS_CFG__FS_S1_SHIFT 24
87#define HII2S_FS_CFG__FS_S1_MASK 7
88#define HII2S_FS_CFG__FS_ADCLR_SHIFT 20
89#define HII2S_FS_CFG__FS_ADCLR_MASK 7
90#define HII2S_FS_CFG__FS_DACLR_SHIFT 16
91#define HII2S_FS_CFG__FS_DACLR_MASK 7
92#define HII2S_FS_CFG__FS_ST_DL_R_SHIFT 8
93#define HII2S_FS_CFG__FS_ST_DL_R_MASK 7
94#define HII2S_FS_CFG__FS_ST_DL_L_SHIFT 4
95#define HII2S_FS_CFG__FS_ST_DL_L_MASK 7
96#define HII2S_FS_CFG__FS_VOICE_DLINK_SHIFT 0
97#define HII2S_FS_CFG__FS_VOICE_DLINK_MASK 7
98
99enum hi6210_i2s_rates {
100 HII2S_FS_RATE_8KHZ = 0,
101 HII2S_FS_RATE_16KHZ = 1,
102 HII2S_FS_RATE_32KHZ = 2,
103 HII2S_FS_RATE_48KHZ = 4,
104 HII2S_FS_RATE_96KHZ = 5,
105 HII2S_FS_RATE_192KHZ = 6,
106};
107
108#define HII2S_I2S_CFG 0x10
109
110#define HII2S_I2S_CFG__S2_IF_TX_EN BIT(31)
111#define HII2S_I2S_CFG__S2_IF_RX_EN BIT(30)
112#define HII2S_I2S_CFG__S2_FRAME_MODE BIT(29)
113#define HII2S_I2S_CFG__S2_MST_SLV BIT(28)
114#define HII2S_I2S_CFG__S2_LRCK_MODE BIT(27)
115#define HII2S_I2S_CFG__S2_CHNNL_MODE BIT(26)
116#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT 24
117#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK 3
118#define HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT 22
119#define HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK 3
120#define HII2S_I2S_CFG__S2_TX_CLK_SEL BIT(21)
121#define HII2S_I2S_CFG__S2_RX_CLK_SEL BIT(20)
122#define HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT BIT(19)
123#define HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT 16
124#define HII2S_I2S_CFG__S2_FUNC_MODE_MASK 7
125#define HII2S_I2S_CFG__S1_IF_TX_EN BIT(15)
126#define HII2S_I2S_CFG__S1_IF_RX_EN BIT(14)
127#define HII2S_I2S_CFG__S1_FRAME_MODE BIT(13)
128#define HII2S_I2S_CFG__S1_MST_SLV BIT(12)
129#define HII2S_I2S_CFG__S1_LRCK_MODE BIT(11)
130#define HII2S_I2S_CFG__S1_CHNNL_MODE BIT(10)
131#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_SHIFT 8
132#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_MASK 3
133#define HII2S_I2S_CFG__S1_DIRECT_LOOP_SHIFT 6
134#define HII2S_I2S_CFG__S1_DIRECT_LOOP_MASK 3
135#define HII2S_I2S_CFG__S1_TX_CLK_SEL BIT(5)
136#define HII2S_I2S_CFG__S1_RX_CLK_SEL BIT(4)
137#define HII2S_I2S_CFG__S1_CODEC_DATA_FORMAT BIT(3)
138#define HII2S_I2S_CFG__S1_FUNC_MODE_SHIFT 0
139#define HII2S_I2S_CFG__S1_FUNC_MODE_MASK 7
140
141enum hi6210_i2s_formats {
142 HII2S_FORMAT_I2S,
143 HII2S_FORMAT_PCM_STD,
144 HII2S_FORMAT_PCM_USER,
145 HII2S_FORMAT_LEFT_JUST,
146 HII2S_FORMAT_RIGHT_JUST,
147};
148
149#define HII2S_DIG_FILTER_MODULE_CFG 0x14
150
151#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_SHIFT 28
152#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_MASK 3
153#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN4_MUTE BIT(27)
154#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN3_MUTE BIT(26)
155#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE BIT(25)
156#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN1_MUTE BIT(24)
157#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_SHIFT 20
158#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_MASK 3
159#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN4_MUTE BIT(19)
160#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN3_MUTE BIT(18)
161#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE BIT(17)
162#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN1_MUTE BIT(16)
163#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACR_SDM_DITHER BIT(9)
164#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACL_SDM_DITHER BIT(8)
165#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_SHIFT 4
166#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_MASK 7
167#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_SHIFT 0
168#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_MASK 7
169
170enum hi6210_gains {
171 HII2S_GAIN_100PC,
172 HII2S_GAIN_50PC,
173 HII2S_GAIN_25PC,
174};
175
176#define HII2S_MUX_TOP_MODULE_CFG 0x18
177
178#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_SHIFT 14
179#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_MASK 3
180#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE BIT(13)
181#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE BIT(12)
182#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_SHIFT 10
183#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_MASK 3
184#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE BIT(9)
185#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE BIT(8)
186#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_RDY BIT(6)
187#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_SHIFT 4
188#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_MASK 3
189#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_RDY BIT(3)
190#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_SHIFT 0
191#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_MASK 7
192
193enum hi6210_s2_src_mode {
194 HII2S_S2_SRC_MODE_3,
195 HII2S_S2_SRC_MODE_12,
196 HII2S_S2_SRC_MODE_6,
197 HII2S_S2_SRC_MODE_2,
198};
199
200enum hi6210_voice_dlink_src_mode {
201 HII2S_VOICE_DL_SRC_MODE_12 = 1,
202 HII2S_VOICE_DL_SRC_MODE_6,
203 HII2S_VOICE_DL_SRC_MODE_2,
204 HII2S_VOICE_DL_SRC_MODE_3,
205};
206
207#define HII2S_ADC_PGA_CFG 0x1c
208#define HII2S_S1_INPUT_PGA_CFG 0x20
209#define HII2S_S2_INPUT_PGA_CFG 0x24
210#define HII2S_ST_DL_PGA_CFG 0x28
211#define HII2S_VOICE_SIDETONE_DLINK_PGA_CFG 0x2c
212#define HII2S_APB_AFIFO_CFG_1 0x30
213#define HII2S_APB_AFIFO_CFG_2 0x34
214#define HII2S_ST_DL_FIFO_TH_CFG 0x38
215
216#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT 24
217#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK 0x1f
218#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT 16
219#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK 0x1f
220#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT 8
221#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK 0x1f
222#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT 0
223#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK 0x1f
224
225#define HII2S_STEREO_UPLINK_FIFO_TH_CFG 0x3c
226#define HII2S_VOICE_UPLINK_FIFO_TH_CFG 0x40
227#define HII2S_CODEC_IRQ_MASK 0x44
228#define HII2S_CODEC_IRQ 0x48
229#define HII2S_DACL_AGC_CFG_1 0x4c
230#define HII2S_DACL_AGC_CFG_2 0x50
231#define HII2S_DACR_AGC_CFG_1 0x54
232#define HII2S_DACR_AGC_CFG_2 0x58
233#define HII2S_DMIC_SIF_CFG 0x5c
234#define HII2S_MISC_CFG 0x60
235
236#define HII2S_MISC_CFG__THIRDMD_DLINK_TEST_SEL BIT(17)
237#define HII2S_MISC_CFG__THIRDMD_DLINK_DIN_SEL BIT(16)
238#define HII2S_MISC_CFG__S3_DOUT_RIGHT_SEL BIT(14)
239#define HII2S_MISC_CFG__S3_DOUT_LEFT_SEL BIT(13)
240#define HII2S_MISC_CFG__S3_DIN_TEST_SEL BIT(12)
241#define HII2S_MISC_CFG__VOICE_DLINK_SRC_UP_DOUT_VLD_SEL BIT(8)
242#define HII2S_MISC_CFG__VOICE_DLINK_TEST_SEL BIT(7)
243#define HII2S_MISC_CFG__VOICE_DLINK_DIN_SEL BIT(6)
244#define HII2S_MISC_CFG__ST_DL_TEST_SEL BIT(4)
245#define HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL BIT(3)
246#define HII2S_MISC_CFG__S2_DOUT_TEST_SEL BIT(2)
247#define HII2S_MISC_CFG__S1_DOUT_TEST_SEL BIT(1)
248#define HII2S_MISC_CFG__S2_DOUT_LEFT_SEL BIT(0)
249
250#define HII2S_S2_SRC_CFG 0x64
251#define HII2S_MEM_CFG 0x68
252#define HII2S_THIRDMD_PCM_PGA_CFG 0x6c
253#define HII2S_THIRD_MODEM_FIFO_TH 0x70
254#define HII2S_S3_ANTI_FREQ_JITTER_TX_INC_CNT 0x74
255#define HII2S_S3_ANTI_FREQ_JITTER_TX_DEC_CNT 0x78
256#define HII2S_S3_ANTI_FREQ_JITTER_RX_INC_CNT 0x7c
257#define HII2S_S3_ANTI_FREQ_JITTER_RX_DEC_CNT 0x80
258#define HII2S_ANTI_FREQ_JITTER_EN 0x84
259#define HII2S_CLK_SEL 0x88
260
261/* 0 = BT owns the i2s */
262#define HII2S_CLK_SEL__I2S_BT_FM_SEL BIT(0)
263/* 0 = internal source, 1 = ext */
264#define HII2S_CLK_SEL__EXT_12_288MHZ_SEL BIT(1)
265
266
267#define HII2S_THIRDMD_DLINK_CHANNEL 0xe8
268#define HII2S_THIRDMD_ULINK_CHANNEL 0xec
269#define HII2S_VOICE_DLINK_CHANNEL 0xf0
270
271/* shovel data in here for playback */
272#define HII2S_ST_DL_CHANNEL 0xf4
273#define HII2S_STEREO_UPLINK_CHANNEL 0xf8
274#define HII2S_VOICE_UPLINK_CHANNEL 0xfc
275
276#endif/* _HI6210_I2S_H */
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 526855ad479e..67968ef3bbda 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -202,6 +202,30 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
202 platforms with MAX98090 audio codec it also can support TI jack chip as aux device. 202 platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
203 If unsure select "N". 203 If unsure select "N".
204 204
205config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
206 tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
207 depends on X86_INTEL_LPSS && I2C && ACPI
208 select SND_SOC_DA7213
209 select SND_SST_ATOM_HIFI2_PLATFORM
210 select SND_SST_IPC_ACPI
211 select SND_SOC_INTEL_SST_MATCH if ACPI
212 help
213 This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
214 platforms with DA7212/7213 audio codec.
215 If unsure select "N".
216
217config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
218 tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
219 depends on X86_INTEL_LPSS && I2C && ACPI
220 select SND_SST_ATOM_HIFI2_PLATFORM
221 select SND_SST_IPC_ACPI
222 select SND_SOC_INTEL_SST_MATCH if ACPI
223 help
224 This adds support for ASoC machine driver for the MinnowBoard Max or
225 Up boards and provides access to I2S signals on the Low-Speed
226 connector
227 If unsure select "N".
228
205config SND_SOC_INTEL_SKYLAKE 229config SND_SOC_INTEL_SKYLAKE
206 tristate 230 tristate
207 select SND_HDA_EXT_CORE 231 select SND_HDA_EXT_CORE
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 747c0f393d2d..dd250b8b26f2 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -420,7 +420,21 @@ static const struct dmi_system_id byt_table[] = {
420 .callback = byt_thinkpad10_quirk_cb, 420 .callback = byt_thinkpad10_quirk_cb,
421 .matches = { 421 .matches = {
422 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 422 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
423 DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), 423 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
424 },
425 },
426 {
427 .callback = byt_thinkpad10_quirk_cb,
428 .matches = {
429 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
430 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
431 },
432 },
433 {
434 .callback = byt_thinkpad10_quirk_cb,
435 .matches = {
436 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
437 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
424 }, 438 },
425 }, 439 },
426 { } 440 { }
@@ -480,12 +494,23 @@ static struct sst_acpi_mach sst_acpi_bytcr[] = {
480 &byt_rvp_platform_data }, 494 &byt_rvp_platform_data },
481 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_0f28.bin", "bytcr_rt5651", NULL, 495 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_0f28.bin", "bytcr_rt5651", NULL,
482 &byt_rvp_platform_data }, 496 &byt_rvp_platform_data },
497 {"DLGS7212", "bytcht_da7213", "intel/fw_sst_0f28.bin", "bytcht_da7213", NULL,
498 &byt_rvp_platform_data },
499 {"DLGS7213", "bytcht_da7213", "intel/fw_sst_0f28.bin", "bytcht_da7213", NULL,
500 &byt_rvp_platform_data },
483 /* some Baytrail platforms rely on RT5645, use CHT machine driver */ 501 /* some Baytrail platforms rely on RT5645, use CHT machine driver */
484 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, 502 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL,
485 &byt_rvp_platform_data }, 503 &byt_rvp_platform_data },
486 {"10EC5648", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, 504 {"10EC5648", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL,
487 &byt_rvp_platform_data }, 505 &byt_rvp_platform_data },
488 506#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
507 /*
508 * This is always last in the table so that it is selected only when
509 * enabled explicitly and there is no codec-related information in SSDT
510 */
511 {"80860F28", "bytcht_nocodec", "intel/fw_sst_0f28.bin", "bytcht_nocodec", NULL,
512 &byt_rvp_platform_data },
513#endif
489 {}, 514 {},
490}; 515};
491 516
@@ -504,6 +529,10 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
504 529
505 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, 530 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
506 &chv_platform_data }, 531 &chv_platform_data },
532 {"DLGS7212", "bytcht_da7213", "intel/fw_sst_22a8.bin", "bytcht_da7213", NULL,
533 &chv_platform_data },
534 {"DLGS7213", "bytcht_da7213", "intel/fw_sst_22a8.bin", "bytcht_da7213", NULL,
535 &chv_platform_data },
507 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */ 536 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
508 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", cht_quirk, 537 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", cht_quirk,
509 &chv_platform_data }, 538 &chv_platform_data },
@@ -512,6 +541,14 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
512 /* some CHT-T platforms rely on RT5651, use Baytrail machine driver */ 541 /* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
513 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_22a8.bin", "bytcr_rt5651", NULL, 542 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_22a8.bin", "bytcr_rt5651", NULL,
514 &chv_platform_data }, 543 &chv_platform_data },
544#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
545 /*
546 * This is always last in the table so that it is selected only when
547 * enabled explicitly and there is no codec-related information in SSDT
548 */
549 {"808622A8", "bytcht_nocodec", "intel/fw_sst_22a8.bin", "bytcht_nocodec", NULL,
550 &chv_platform_data },
551#endif
515 {}, 552 {},
516}; 553};
517 554
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index 14c2d9d18180..20b01e02ed8f 100644
--- a/sound/soc/intel/atom/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -236,7 +236,9 @@ static void process_fw_init(struct intel_sst_drv *sst_drv_ctx,
236 retval = init->result; 236 retval = init->result;
237 goto ret; 237 goto ret;
238 } 238 }
239 dev_info(sst_drv_ctx->dev, "FW Version %02x.%02x.%02x.%02x\n", 239 if (memcmp(&sst_drv_ctx->fw_version, &init->fw_version,
240 sizeof(init->fw_version)))
241 dev_info(sst_drv_ctx->dev, "FW Version %02x.%02x.%02x.%02x\n",
240 init->fw_version.type, init->fw_version.major, 242 init->fw_version.type, init->fw_version.major,
241 init->fw_version.minor, init->fw_version.build); 243 init->fw_version.minor, init->fw_version.build);
242 dev_dbg(sst_drv_ctx->dev, "Build date %s Time %s\n", 244 dev_dbg(sst_drv_ctx->dev, "Build date %s Time %s\n",
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 5639f10774e6..56896e09445d 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -10,6 +10,8 @@ snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
10snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 10snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
11snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 11snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
12snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 12snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
13snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
14snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
13snd-soc-skl_rt286-objs := skl_rt286.o 15snd-soc-skl_rt286-objs := skl_rt286.o
14snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o 16snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
15snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o 17snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
@@ -26,6 +28,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
26obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 28obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
27obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 29obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
28obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 30obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
31obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
32obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
29obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o 33obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
30obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o 34obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
31obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o 35obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index 53c6b4cbb1e1..14d9693c1641 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -193,13 +193,12 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
193 RT5677_CLK_SEL_I2S1_ASRC); 193 RT5677_CLK_SEL_I2S1_ASRC);
194 194
195 /* Request rt5677 GPIO for headphone amp control */ 195 /* Request rt5677 GPIO for headphone amp control */
196 bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev, 196 bdw_rt5677->gpio_hp_en = devm_gpiod_get(codec->dev, "headphone-enable",
197 "headphone-enable", 0, 0); 197 GPIOD_OUT_LOW);
198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) { 198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n"); 199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
200 return PTR_ERR(bdw_rt5677->gpio_hp_en); 200 return PTR_ERR(bdw_rt5677->gpio_hp_en);
201 } 201 }
202 gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);
203 202
204 /* Create and initialize headphone jack */ 203 /* Create and initialize headphone jack */
205 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack", 204 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index faf865bb1765..6dcbbcefc25b 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -269,9 +269,6 @@ static struct snd_soc_card broadwell_rt286 = {
269static int broadwell_audio_probe(struct platform_device *pdev) 269static int broadwell_audio_probe(struct platform_device *pdev)
270{ 270{
271 broadwell_rt286.dev = &pdev->dev; 271 broadwell_rt286.dev = &pdev->dev;
272
273 snd_soc_set_dmi_name(&broadwell_rt286, NULL);
274
275 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286); 272 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286);
276} 273}
277 274
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 2cda06cde4d1..3a8c4d954a91 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -55,6 +55,54 @@ enum {
55 BXT_DPCM_AUDIO_HDMI3_PB, 55 BXT_DPCM_AUDIO_HDMI3_PB,
56}; 56};
57 57
58static inline struct snd_soc_dai *bxt_get_codec_dai(struct snd_soc_card *card)
59{
60 struct snd_soc_pcm_runtime *rtd;
61
62 list_for_each_entry(rtd, &card->rtd_list, list) {
63
64 if (!strncmp(rtd->codec_dai->name, BXT_DIALOG_CODEC_DAI,
65 strlen(BXT_DIALOG_CODEC_DAI)))
66 return rtd->codec_dai;
67 }
68
69 return NULL;
70}
71
72static int platform_clock_control(struct snd_soc_dapm_widget *w,
73 struct snd_kcontrol *k, int event)
74{
75 int ret = 0;
76 struct snd_soc_dapm_context *dapm = w->dapm;
77 struct snd_soc_card *card = dapm->card;
78 struct snd_soc_dai *codec_dai;
79
80 codec_dai = bxt_get_codec_dai(card);
81 if (!codec_dai) {
82 dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
83 return -EIO;
84 }
85
86 if (SND_SOC_DAPM_EVENT_OFF(event)) {
87 ret = snd_soc_dai_set_pll(codec_dai, 0,
88 DA7219_SYSCLK_MCLK, 0, 0);
89 if (ret)
90 dev_err(card->dev, "failed to stop PLL: %d\n", ret);
91 } else if(SND_SOC_DAPM_EVENT_ON(event)) {
92 ret = snd_soc_dai_set_sysclk(codec_dai,
93 DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN);
94 if (ret)
95 dev_err(card->dev, "can't set codec sysclk configuration\n");
96
97 ret = snd_soc_dai_set_pll(codec_dai, 0,
98 DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
99 if (ret)
100 dev_err(card->dev, "failed to start PLL: %d\n", ret);
101 }
102
103 return ret;
104}
105
58static const struct snd_kcontrol_new broxton_controls[] = { 106static const struct snd_kcontrol_new broxton_controls[] = {
59 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 107 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
60 SOC_DAPM_PIN_SWITCH("Headset Mic"), 108 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -69,6 +117,8 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = {
69 SND_SOC_DAPM_SPK("HDMI1", NULL), 117 SND_SOC_DAPM_SPK("HDMI1", NULL),
70 SND_SOC_DAPM_SPK("HDMI2", NULL), 118 SND_SOC_DAPM_SPK("HDMI2", NULL),
71 SND_SOC_DAPM_SPK("HDMI3", NULL), 119 SND_SOC_DAPM_SPK("HDMI3", NULL),
120 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
121 platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
72}; 122};
73 123
74static const struct snd_soc_dapm_route broxton_map[] = { 124static const struct snd_soc_dapm_route broxton_map[] = {
@@ -109,6 +159,9 @@ static const struct snd_soc_dapm_route broxton_map[] = {
109 /* DMIC */ 159 /* DMIC */
110 {"dmic01_hifi", NULL, "DMIC01 Rx"}, 160 {"dmic01_hifi", NULL, "DMIC01 Rx"},
111 {"DMIC01 Rx", NULL, "DMIC AIF"}, 161 {"DMIC01 Rx", NULL, "DMIC AIF"},
162
163 { "Headphone Jack", NULL, "Platform Clock" },
164 { "Headset Mic", NULL, "Platform Clock" },
112}; 165};
113 166
114static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, 167static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
@@ -243,49 +296,6 @@ static const struct snd_soc_ops broxton_da7219_fe_ops = {
243 .startup = bxt_fe_startup, 296 .startup = bxt_fe_startup,
244}; 297};
245 298
246static int broxton_da7219_hw_params(struct snd_pcm_substream *substream,
247 struct snd_pcm_hw_params *params)
248{
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250 struct snd_soc_dai *codec_dai = rtd->codec_dai;
251 int ret;
252
253 ret = snd_soc_dai_set_sysclk(codec_dai,
254 DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN);
255 if (ret < 0)
256 dev_err(codec_dai->dev, "can't set codec sysclk configuration\n");
257
258 ret = snd_soc_dai_set_pll(codec_dai, 0,
259 DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
260 if (ret < 0) {
261 dev_err(codec_dai->dev, "failed to start PLL: %d\n", ret);
262 return -EIO;
263 }
264
265 return ret;
266}
267
268static int broxton_da7219_hw_free(struct snd_pcm_substream *substream)
269{
270 struct snd_soc_pcm_runtime *rtd = substream->private_data;
271 struct snd_soc_dai *codec_dai = rtd->codec_dai;
272 int ret;
273
274 ret = snd_soc_dai_set_pll(codec_dai, 0,
275 DA7219_SYSCLK_MCLK, 0, 0);
276 if (ret < 0) {
277 dev_err(codec_dai->dev, "failed to stop PLL: %d\n", ret);
278 return -EIO;
279 }
280
281 return ret;
282}
283
284static const struct snd_soc_ops broxton_da7219_ops = {
285 .hw_params = broxton_da7219_hw_params,
286 .hw_free = broxton_da7219_hw_free,
287};
288
289static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 299static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
290 struct snd_pcm_hw_params *params) 300 struct snd_pcm_hw_params *params)
291{ 301{
@@ -467,7 +477,6 @@ static struct snd_soc_dai_link broxton_dais[] = {
467 SND_SOC_DAIFMT_CBS_CFS, 477 SND_SOC_DAIFMT_CBS_CFS,
468 .ignore_pmdown_time = 1, 478 .ignore_pmdown_time = 1,
469 .be_hw_params_fixup = broxton_ssp_fixup, 479 .be_hw_params_fixup = broxton_ssp_fixup,
470 .ops = &broxton_da7219_ops,
471 .dpcm_playback = 1, 480 .dpcm_playback = 1,
472 .dpcm_capture = 1, 481 .dpcm_capture = 1,
473 }, 482 },
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 176c080a9818..1a68d043c803 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -274,12 +274,15 @@ static int bxt_fe_startup(struct snd_pcm_substream *substream)
274 * on this platform for PCM device we support: 274 * on this platform for PCM device we support:
275 * 48Khz 275 * 48Khz
276 * stereo 276 * stereo
277 * 16-bit audio
277 */ 278 */
278 279
279 runtime->hw.channels_max = 2; 280 runtime->hw.channels_max = 2;
280 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 281 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
281 &constraints_channels); 282 &constraints_channels);
282 283
284 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
285 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
283 snd_pcm_hw_constraint_list(runtime, 0, 286 snd_pcm_hw_constraint_list(runtime, 0,
284 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 287 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
285 288
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c
new file mode 100644
index 000000000000..18873e23f404
--- /dev/null
+++ b/sound/soc/intel/boards/bytcht_da7213.c
@@ -0,0 +1,283 @@
1/*
2 * bytcht-da7213.c - ASoc Machine driver for Intel Baytrail and
3 * Cherrytrail-based platforms, with Dialog DA7213 codec
4 *
5 * Copyright (C) 2017 Intel Corporation
6 * Author: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21
22#include <linux/module.h>
23#include <linux/acpi.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <asm/platform_sst_audio.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include "../../codecs/da7213.h"
31#include "../atom/sst-atom-controls.h"
32#include "../common/sst-acpi.h"
33
34static const struct snd_kcontrol_new controls[] = {
35 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
36 SOC_DAPM_PIN_SWITCH("Headset Mic"),
37 SOC_DAPM_PIN_SWITCH("Mic"),
38 SOC_DAPM_PIN_SWITCH("Aux In"),
39};
40
41static const struct snd_soc_dapm_widget dapm_widgets[] = {
42 SND_SOC_DAPM_HP("Headphone Jack", NULL),
43 SND_SOC_DAPM_MIC("Headset Mic", NULL),
44 SND_SOC_DAPM_MIC("Mic", NULL),
45 SND_SOC_DAPM_LINE("Aux In", NULL),
46};
47
48static const struct snd_soc_dapm_route audio_map[] = {
49 {"Headphone Jack", NULL, "HPL"},
50 {"Headphone Jack", NULL, "HPR"},
51
52 {"AUXL", NULL, "Aux In"},
53 {"AUXR", NULL, "Aux In"},
54
55 /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */
56 {"MIC1", NULL, "Headset Mic"},
57 {"MIC2", NULL, "Mic"},
58
59 /* SOC-codec link */
60 {"ssp2 Tx", NULL, "codec_out0"},
61 {"ssp2 Tx", NULL, "codec_out1"},
62 {"codec_in0", NULL, "ssp2 Rx"},
63 {"codec_in1", NULL, "ssp2 Rx"},
64
65 {"Playback", NULL, "ssp2 Tx"},
66 {"ssp2 Rx", NULL, "Capture"},
67};
68
69static int codec_fixup(struct snd_soc_pcm_runtime *rtd,
70 struct snd_pcm_hw_params *params)
71{
72 int ret;
73 struct snd_interval *rate = hw_param_interval(params,
74 SNDRV_PCM_HW_PARAM_RATE);
75 struct snd_interval *channels = hw_param_interval(params,
76 SNDRV_PCM_HW_PARAM_CHANNELS);
77
78 /* The DSP will convert the FE rate to 48k, stereo, 24bits */
79 rate->min = rate->max = 48000;
80 channels->min = channels->max = 2;
81
82 /* set SSP2 to 24-bit */
83 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
84
85 /*
86 * Default mode for SSP configuration is TDM 4 slot, override config
87 * with explicit setting to I2S 2ch 24-bit. The word length is set with
88 * dai_set_tdm_slot() since there is no other API exposed
89 */
90 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
91 SND_SOC_DAIFMT_I2S |
92 SND_SOC_DAIFMT_NB_NF |
93 SND_SOC_DAIFMT_CBS_CFS);
94 if (ret < 0) {
95 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
96 return ret;
97 }
98
99 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
100 if (ret < 0) {
101 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
102 return ret;
103 }
104
105 return 0;
106}
107
108static int aif1_startup(struct snd_pcm_substream *substream)
109{
110 return snd_pcm_hw_constraint_single(substream->runtime,
111 SNDRV_PCM_HW_PARAM_RATE, 48000);
112}
113
114static int aif1_hw_params(struct snd_pcm_substream *substream,
115 struct snd_pcm_hw_params *params)
116{
117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
118 struct snd_soc_dai *codec_dai = rtd->codec_dai;
119 int ret;
120
121 ret = snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK,
122 19200000, SND_SOC_CLOCK_IN);
123 if (ret < 0)
124 dev_err(codec_dai->dev, "can't set codec sysclk configuration\n");
125
126 ret = snd_soc_dai_set_pll(codec_dai, 0,
127 DA7213_SYSCLK_PLL_SRM, 0, DA7213_PLL_FREQ_OUT_98304000);
128 if (ret < 0) {
129 dev_err(codec_dai->dev, "failed to start PLL: %d\n", ret);
130 return -EIO;
131 }
132
133 return ret;
134}
135
136static int aif1_hw_free(struct snd_pcm_substream *substream)
137{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct snd_soc_dai *codec_dai = rtd->codec_dai;
140 int ret;
141
142 ret = snd_soc_dai_set_pll(codec_dai, 0,
143 DA7213_SYSCLK_MCLK, 0, 0);
144 if (ret < 0) {
145 dev_err(codec_dai->dev, "failed to stop PLL: %d\n", ret);
146 return -EIO;
147 }
148
149 return ret;
150}
151
152static const struct snd_soc_ops aif1_ops = {
153 .startup = aif1_startup,
154};
155
156static const struct snd_soc_ops ssp2_ops = {
157 .hw_params = aif1_hw_params,
158 .hw_free = aif1_hw_free,
159
160};
161
162static struct snd_soc_dai_link dailink[] = {
163 [MERR_DPCM_AUDIO] = {
164 .name = "Audio Port",
165 .stream_name = "Audio",
166 .cpu_dai_name = "media-cpu-dai",
167 .codec_dai_name = "snd-soc-dummy-dai",
168 .codec_name = "snd-soc-dummy",
169 .platform_name = "sst-mfld-platform",
170 .nonatomic = true,
171 .dynamic = 1,
172 .dpcm_playback = 1,
173 .dpcm_capture = 1,
174 .ops = &aif1_ops,
175 },
176 [MERR_DPCM_DEEP_BUFFER] = {
177 .name = "Deep-Buffer Audio Port",
178 .stream_name = "Deep-Buffer Audio",
179 .cpu_dai_name = "deepbuffer-cpu-dai",
180 .codec_dai_name = "snd-soc-dummy-dai",
181 .codec_name = "snd-soc-dummy",
182 .platform_name = "sst-mfld-platform",
183 .nonatomic = true,
184 .dynamic = 1,
185 .dpcm_playback = 1,
186 .ops = &aif1_ops,
187 },
188 [MERR_DPCM_COMPR] = {
189 .name = "Compressed Port",
190 .stream_name = "Compress",
191 .cpu_dai_name = "compress-cpu-dai",
192 .codec_dai_name = "snd-soc-dummy-dai",
193 .codec_name = "snd-soc-dummy",
194 .platform_name = "sst-mfld-platform",
195 },
196 /* CODEC<->CODEC link */
197 /* back ends */
198 {
199 .name = "SSP2-Codec",
200 .id = 1,
201 .cpu_dai_name = "ssp2-port",
202 .platform_name = "sst-mfld-platform",
203 .no_pcm = 1,
204 .codec_dai_name = "da7213-hifi",
205 .codec_name = "i2c-DLGS7213:00",
206 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
207 | SND_SOC_DAIFMT_CBS_CFS,
208 .be_hw_params_fixup = codec_fixup,
209 .nonatomic = true,
210 .dpcm_playback = 1,
211 .dpcm_capture = 1,
212 .ops = &ssp2_ops,
213 },
214};
215
216/* SoC card */
217static struct snd_soc_card bytcht_da7213_card = {
218 .name = "bytcht-da7213",
219 .owner = THIS_MODULE,
220 .dai_link = dailink,
221 .num_links = ARRAY_SIZE(dailink),
222 .controls = controls,
223 .num_controls = ARRAY_SIZE(controls),
224 .dapm_widgets = dapm_widgets,
225 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
226 .dapm_routes = audio_map,
227 .num_dapm_routes = ARRAY_SIZE(audio_map),
228};
229
230static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
231
232static int bytcht_da7213_probe(struct platform_device *pdev)
233{
234 int ret_val = 0;
235 int i;
236 struct snd_soc_card *card;
237 struct sst_acpi_mach *mach;
238 const char *i2c_name = NULL;
239 int dai_index = 0;
240
241 mach = (&pdev->dev)->platform_data;
242 card = &bytcht_da7213_card;
243 card->dev = &pdev->dev;
244
245 /* fix index of codec dai */
246 dai_index = MERR_DPCM_COMPR + 1;
247 for (i = 0; i < ARRAY_SIZE(dailink); i++) {
248 if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) {
249 dai_index = i;
250 break;
251 }
252 }
253
254 /* fixup codec name based on HID */
255 i2c_name = sst_acpi_find_name_from_hid(mach->id);
256 if (i2c_name != NULL) {
257 snprintf(codec_name, sizeof(codec_name),
258 "%s%s", "i2c-", i2c_name);
259 dailink[dai_index].codec_name = codec_name;
260 }
261
262 ret_val = devm_snd_soc_register_card(&pdev->dev, card);
263 if (ret_val) {
264 dev_err(&pdev->dev,
265 "snd_soc_register_card failed %d\n", ret_val);
266 return ret_val;
267 }
268 platform_set_drvdata(pdev, card);
269 return ret_val;
270}
271
272static struct platform_driver bytcht_da7213_driver = {
273 .driver = {
274 .name = "bytcht_da7213",
275 },
276 .probe = bytcht_da7213_probe,
277};
278module_platform_driver(bytcht_da7213_driver);
279
280MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail+DA7213 Machine driver");
281MODULE_AUTHOR("Pierre-Louis Bossart");
282MODULE_LICENSE("GPL v2");
283MODULE_ALIAS("platform:bytcht_da7213");
diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c
new file mode 100644
index 000000000000..89853eeaaf9d
--- /dev/null
+++ b/sound/soc/intel/boards/bytcht_nocodec.c
@@ -0,0 +1,208 @@
1/*
2 * bytcht_nocodec.c - ASoc Machine driver for MinnowBoard Max and Up
3 * to make I2S signals observable on the Low-Speed connector. Audio codec
4 * is not managed by ASoC/DAPM
5 *
6 * Copyright (C) 2015-2017 Intel Corp
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21
22#include <linux/module.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include "../atom/sst-atom-controls.h"
27
28static const struct snd_soc_dapm_widget widgets[] = {
29 SND_SOC_DAPM_MIC("Mic", NULL),
30 SND_SOC_DAPM_SPK("Speaker", NULL),
31};
32
33static const struct snd_kcontrol_new controls[] = {
34 SOC_DAPM_PIN_SWITCH("Mic"),
35 SOC_DAPM_PIN_SWITCH("Speaker"),
36};
37
38static const struct snd_soc_dapm_route audio_map[] = {
39 {"ssp2 Tx", NULL, "codec_out0"},
40 {"ssp2 Tx", NULL, "codec_out1"},
41 {"codec_in0", NULL, "ssp2 Rx"},
42 {"codec_in1", NULL, "ssp2 Rx"},
43
44 {"ssp2 Rx", NULL, "Mic"},
45 {"Speaker", NULL, "ssp2 Tx"},
46};
47
48static int codec_fixup(struct snd_soc_pcm_runtime *rtd,
49 struct snd_pcm_hw_params *params)
50{
51 struct snd_interval *rate = hw_param_interval(params,
52 SNDRV_PCM_HW_PARAM_RATE);
53 struct snd_interval *channels = hw_param_interval(params,
54 SNDRV_PCM_HW_PARAM_CHANNELS);
55 int ret;
56
57 /* The DSP will convert the FE rate to 48k, stereo, 24bits */
58 rate->min = rate->max = 48000;
59 channels->min = channels->max = 2;
60
61 /* set SSP2 to 24-bit */
62 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
63
64 /*
65 * Default mode for SSP configuration is TDM 4 slot, override config
66 * with explicit setting to I2S 2ch 24-bit. The word length is set with
67 * dai_set_tdm_slot() since there is no other API exposed
68 */
69 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
70 SND_SOC_DAIFMT_I2S |
71 SND_SOC_DAIFMT_NB_NF |
72 SND_SOC_DAIFMT_CBS_CFS);
73
74 if (ret < 0) {
75 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
76 return ret;
77 }
78
79 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
80 if (ret < 0) {
81 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
82 return ret;
83 }
84
85 return 0;
86}
87
88static unsigned int rates_48000[] = {
89 48000,
90};
91
92static struct snd_pcm_hw_constraint_list constraints_48000 = {
93 .count = ARRAY_SIZE(rates_48000),
94 .list = rates_48000,
95};
96
97static int aif1_startup(struct snd_pcm_substream *substream)
98{
99 return snd_pcm_hw_constraint_list(substream->runtime, 0,
100 SNDRV_PCM_HW_PARAM_RATE,
101 &constraints_48000);
102}
103
104static struct snd_soc_ops aif1_ops = {
105 .startup = aif1_startup,
106};
107
108static struct snd_soc_dai_link dais[] = {
109 [MERR_DPCM_AUDIO] = {
110 .name = "Audio Port",
111 .stream_name = "Audio",
112 .cpu_dai_name = "media-cpu-dai",
113 .codec_dai_name = "snd-soc-dummy-dai",
114 .codec_name = "snd-soc-dummy",
115 .platform_name = "sst-mfld-platform",
116 .ignore_suspend = 1,
117 .nonatomic = true,
118 .dynamic = 1,
119 .dpcm_playback = 1,
120 .dpcm_capture = 1,
121 .ops = &aif1_ops,
122 },
123 [MERR_DPCM_DEEP_BUFFER] = {
124 .name = "Deep-Buffer Audio Port",
125 .stream_name = "Deep-Buffer Audio",
126 .cpu_dai_name = "deepbuffer-cpu-dai",
127 .codec_dai_name = "snd-soc-dummy-dai",
128 .codec_name = "snd-soc-dummy",
129 .platform_name = "sst-mfld-platform",
130 .ignore_suspend = 1,
131 .nonatomic = true,
132 .dynamic = 1,
133 .dpcm_playback = 1,
134 .ops = &aif1_ops,
135 },
136 [MERR_DPCM_COMPR] = {
137 .name = "Compressed Port",
138 .stream_name = "Compress",
139 .cpu_dai_name = "compress-cpu-dai",
140 .codec_dai_name = "snd-soc-dummy-dai",
141 .codec_name = "snd-soc-dummy",
142 .platform_name = "sst-mfld-platform",
143 },
144 /* CODEC<->CODEC link */
145 /* back ends */
146 {
147 .name = "SSP2-LowSpeed Connector",
148 .id = 1,
149 .cpu_dai_name = "ssp2-port",
150 .platform_name = "sst-mfld-platform",
151 .no_pcm = 1,
152 .codec_dai_name = "snd-soc-dummy-dai",
153 .codec_name = "snd-soc-dummy",
154 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
155 | SND_SOC_DAIFMT_CBS_CFS,
156 .be_hw_params_fixup = codec_fixup,
157 .ignore_suspend = 1,
158 .nonatomic = true,
159 .dpcm_playback = 1,
160 .dpcm_capture = 1,
161 },
162};
163
164/* SoC card */
165static struct snd_soc_card bytcht_nocodec_card = {
166 .name = "bytcht-nocodec",
167 .owner = THIS_MODULE,
168 .dai_link = dais,
169 .num_links = ARRAY_SIZE(dais),
170 .dapm_widgets = widgets,
171 .num_dapm_widgets = ARRAY_SIZE(widgets),
172 .dapm_routes = audio_map,
173 .num_dapm_routes = ARRAY_SIZE(audio_map),
174 .controls = controls,
175 .num_controls = ARRAY_SIZE(controls),
176 .fully_routed = true,
177};
178
179static int snd_bytcht_nocodec_mc_probe(struct platform_device *pdev)
180{
181 int ret_val = 0;
182
183 /* register the soc card */
184 bytcht_nocodec_card.dev = &pdev->dev;
185
186 ret_val = devm_snd_soc_register_card(&pdev->dev, &bytcht_nocodec_card);
187
188 if (ret_val) {
189 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
190 ret_val);
191 return ret_val;
192 }
193 platform_set_drvdata(pdev, &bytcht_nocodec_card);
194 return ret_val;
195}
196
197static struct platform_driver snd_bytcht_nocodec_mc_driver = {
198 .driver = {
199 .name = "bytcht_nocodec",
200 },
201 .probe = snd_bytcht_nocodec_mc_probe,
202};
203module_platform_driver(snd_bytcht_nocodec_mc_driver);
204
205MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail Nocodec Machine driver");
206MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>");
207MODULE_LICENSE("GPL v2");
208MODULE_ALIAS("platform:bytcht_nocodec");
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 9e2a3404a836..4a76b099a508 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/moduleparam.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/acpi.h> 24#include <linux/acpi.h>
24#include <linux/device.h> 25#include <linux/device.h>
@@ -56,35 +57,88 @@ enum {
56struct byt_rt5640_private { 57struct byt_rt5640_private {
57 struct clk *mclk; 58 struct clk *mclk;
58}; 59};
60static bool is_bytcr;
59 61
60static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; 62static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
63static unsigned int quirk_override;
64module_param_named(quirk, quirk_override, uint, 0444);
65MODULE_PARM_DESC(quirk, "Board-specific quirk override");
61 66
62static void log_quirks(struct device *dev) 67static void log_quirks(struct device *dev)
63{ 68{
64 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP) 69 int map;
65 dev_info(dev, "quirk DMIC1_MAP enabled"); 70 bool has_dmic = false;
66 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP) 71 bool has_mclk = false;
67 dev_info(dev, "quirk DMIC2_MAP enabled"); 72 bool has_ssp0 = false;
68 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP) 73 bool has_ssp0_aif1 = false;
69 dev_info(dev, "quirk IN1_MAP enabled"); 74 bool has_ssp0_aif2 = false;
70 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP) 75 bool has_ssp2_aif2 = false;
71 dev_info(dev, "quirk IN3_MAP enabled"); 76
72 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) 77 map = BYT_RT5640_MAP(byt_rt5640_quirk);
73 dev_info(dev, "quirk DMIC enabled"); 78 switch (map) {
79 case BYT_RT5640_DMIC1_MAP:
80 dev_info(dev, "quirk DMIC1_MAP enabled\n");
81 has_dmic = true;
82 break;
83 case BYT_RT5640_DMIC2_MAP:
84 dev_info(dev, "quirk DMIC2_MAP enabled\n");
85 has_dmic = true;
86 break;
87 case BYT_RT5640_IN1_MAP:
88 dev_info(dev, "quirk IN1_MAP enabled\n");
89 break;
90 case BYT_RT5640_IN3_MAP:
91 dev_info(dev, "quirk IN3_MAP enabled\n");
92 break;
93 default:
94 dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
95 break;
96 }
97 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
98 if (has_dmic)
99 dev_info(dev, "quirk DMIC enabled\n");
100 else
101 dev_err(dev, "quirk DMIC enabled but no DMIC input set, will be ignored\n");
102 }
74 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) 103 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
75 dev_info(dev, "quirk MONO_SPEAKER enabled"); 104 dev_info(dev, "quirk MONO_SPEAKER enabled\n");
76 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) 105 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
77 dev_info(dev, "quirk DIFF_MIC enabled"); 106 if (!has_dmic)
78 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) 107 dev_info(dev, "quirk DIFF_MIC enabled\n");
79 dev_info(dev, "quirk SSP2_AIF2 enabled"); 108 else
80 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) 109 dev_info(dev, "quirk DIFF_MIC enabled but DMIC input selected, will be ignored\n");
81 dev_info(dev, "quirk SSP0_AIF1 enabled"); 110 }
82 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) 111 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
83 dev_info(dev, "quirk SSP0_AIF2 enabled"); 112 dev_info(dev, "quirk SSP0_AIF1 enabled\n");
84 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) 113 has_ssp0 = true;
85 dev_info(dev, "quirk MCLK_EN enabled"); 114 has_ssp0_aif1 = true;
86 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) 115 }
87 dev_info(dev, "quirk MCLK_25MHZ enabled"); 116 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
117 dev_info(dev, "quirk SSP0_AIF2 enabled\n");
118 has_ssp0 = true;
119 has_ssp0_aif2 = true;
120 }
121 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
122 dev_info(dev, "quirk SSP2_AIF2 enabled\n");
123 has_ssp2_aif2 = true;
124 }
125 if (is_bytcr && !has_ssp0)
126 dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
127 if (has_ssp0_aif1 && has_ssp0_aif2)
128 dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
129 if (has_ssp0 && has_ssp2_aif2)
130 dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
131
132 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
133 dev_info(dev, "quirk MCLK_EN enabled\n");
134 has_mclk = true;
135 }
136 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
137 if (has_mclk)
138 dev_info(dev, "quirk MCLK_25MHZ enabled\n");
139 else
140 dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
141 }
88} 142}
89 143
90 144
@@ -128,7 +182,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
128 ret = clk_prepare_enable(priv->mclk); 182 ret = clk_prepare_enable(priv->mclk);
129 if (ret < 0) { 183 if (ret < 0) {
130 dev_err(card->dev, 184 dev_err(card->dev,
131 "could not configure MCLK state"); 185 "could not configure MCLK state\n");
132 return ret; 186 return ret;
133 } 187 }
134 } 188 }
@@ -710,8 +764,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
710 int i; 764 int i;
711 int dai_index; 765 int dai_index;
712 struct byt_rt5640_private *priv; 766 struct byt_rt5640_private *priv;
713 bool is_bytcr = false;
714 767
768 is_bytcr = false;
715 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 769 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
716 if (!priv) 770 if (!priv)
717 return -ENOMEM; 771 return -ENOMEM;
@@ -806,6 +860,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
806 860
807 /* check quirks before creating card */ 861 /* check quirks before creating card */
808 dmi_check_system(byt_rt5640_quirk_table); 862 dmi_check_system(byt_rt5640_quirk_table);
863 if (quirk_override) {
864 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
865 (unsigned int)byt_rt5640_quirk, quirk_override);
866 byt_rt5640_quirk = quirk_override;
867 }
809 log_quirks(&pdev->dev); 868 log_quirks(&pdev->dev);
810 869
811 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || 870 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index a3459d1682a6..d33bdaf92c57 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -2000,10 +2000,8 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2000 u32 param_size, char *param) 2000 u32 param_size, char *param)
2001{ 2001{
2002 int ret; 2002 int ret;
2003 unsigned char *data = NULL;
2004 u32 header = 0; 2003 u32 header = 0;
2005 u32 payload_size = 0, transfer_parameter_size = 0; 2004 u32 payload_size = 0, transfer_parameter_size = 0;
2006 dma_addr_t dma_addr = 0;
2007 struct sst_hsw_transfer_parameter *parameter; 2005 struct sst_hsw_transfer_parameter *parameter;
2008 struct device *dev = hsw->dev; 2006 struct device *dev = hsw->dev;
2009 2007
@@ -2047,10 +2045,6 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2047 2045
2048 kfree(parameter); 2046 kfree(parameter);
2049 2047
2050 if (data)
2051 dma_free_coherent(hsw->dsp->dma_dev,
2052 param_size, (void *)data, dma_addr);
2053
2054 return ret; 2048 return ret;
2055} 2049}
2056 2050
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 15a063a403cc..f5e7dbb1ba39 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -25,7 +25,8 @@
25#include "skl-sst-ipc.h" 25#include "skl-sst-ipc.h"
26 26
27#define BXT_BASEFW_TIMEOUT 3000 27#define BXT_BASEFW_TIMEOUT 3000
28#define BXT_INIT_TIMEOUT 500 28#define BXT_INIT_TIMEOUT 300
29#define BXT_ROM_INIT_TIMEOUT 70
29#define BXT_IPC_PURGE_FW 0x01004000 30#define BXT_IPC_PURGE_FW 0x01004000
30 31
31#define BXT_ROM_INIT 0x5 32#define BXT_ROM_INIT 0x5
@@ -45,6 +46,8 @@
45/* Delay before scheduling D0i3 entry */ 46/* Delay before scheduling D0i3 entry */
46#define BXT_D0I3_DELAY 5000 47#define BXT_D0I3_DELAY 5000
47 48
49#define BXT_FW_ROM_INIT_RETRY 3
50
48static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 51static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
49{ 52{
50 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 53 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
@@ -55,29 +58,15 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
55{ 58{
56 struct snd_dma_buffer dmab; 59 struct snd_dma_buffer dmab;
57 struct skl_sst *skl = ctx->thread_context; 60 struct skl_sst *skl = ctx->thread_context;
58 const struct firmware *fw = NULL;
59 struct firmware stripped_fw; 61 struct firmware stripped_fw;
60 int ret = 0, i, dma_id, stream_tag; 62 int ret = 0, i, dma_id, stream_tag;
61 63
62 /* library indices start from 1 to N. 0 represents base FW */ 64 /* library indices start from 1 to N. 0 represents base FW */
63 for (i = 1; i < lib_count; i++) { 65 for (i = 1; i < lib_count; i++) {
64 ret = request_firmware(&fw, linfo[i].name, ctx->dev); 66 ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
65 if (ret < 0) {
66 dev_err(ctx->dev, "Request lib %s failed:%d\n",
67 linfo[i].name, ret);
68 return ret;
69 }
70
71 if (skl->is_first_boot) {
72 ret = snd_skl_parse_uuids(ctx, fw,
73 BXT_ADSP_FW_BIN_HDR_OFFSET, i); 67 BXT_ADSP_FW_BIN_HDR_OFFSET, i);
74 if (ret < 0) 68 if (ret < 0)
75 goto load_library_failed; 69 goto load_library_failed;
76 }
77
78 stripped_fw.data = fw->data;
79 stripped_fw.size = fw->size;
80 skl_dsp_strip_extended_manifest(&stripped_fw);
81 70
82 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, 71 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
83 stripped_fw.size, &dmab); 72 stripped_fw.size, &dmab);
@@ -92,21 +81,19 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
92 memcpy(dmab.area, stripped_fw.data, stripped_fw.size); 81 memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
93 82
94 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); 83 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
95 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i); 84 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true);
96 if (ret < 0) 85 if (ret < 0)
97 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", 86 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
98 linfo[i].name, ret); 87 linfo[i].name, ret);
99 88
100 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); 89 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
101 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); 90 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
102 release_firmware(fw);
103 fw = NULL;
104 } 91 }
105 92
106 return ret; 93 return ret;
107 94
108load_library_failed: 95load_library_failed:
109 release_firmware(fw); 96 skl_release_library(linfo, lib_count);
110 return ret; 97 return ret;
111} 98}
112 99
@@ -156,7 +143,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
156 SKL_ADSP_REG_HIPCIE_DONE, 143 SKL_ADSP_REG_HIPCIE_DONE,
157 BXT_INIT_TIMEOUT, "HIPCIE Done"); 144 BXT_INIT_TIMEOUT, "HIPCIE Done");
158 if (ret < 0) { 145 if (ret < 0) {
159 dev_err(ctx->dev, "Timout for Purge Request%d\n", ret); 146 dev_err(ctx->dev, "Timeout for Purge Request%d\n", ret);
160 goto base_fw_load_failed; 147 goto base_fw_load_failed;
161 } 148 }
162 149
@@ -173,7 +160,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
173 160
174 /* Step 7: Wait for ROM init */ 161 /* Step 7: Wait for ROM init */
175 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK, 162 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
176 SKL_FW_INIT, BXT_INIT_TIMEOUT, "ROM Load"); 163 SKL_FW_INIT, BXT_ROM_INIT_TIMEOUT, "ROM Load");
177 if (ret < 0) { 164 if (ret < 0) {
178 dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret); 165 dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret);
179 goto base_fw_load_failed; 166 goto base_fw_load_failed;
@@ -206,18 +193,16 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
206{ 193{
207 struct firmware stripped_fw; 194 struct firmware stripped_fw;
208 struct skl_sst *skl = ctx->thread_context; 195 struct skl_sst *skl = ctx->thread_context;
209 int ret; 196 int ret, i;
210 197
211 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); 198 if (ctx->fw == NULL) {
212 if (ret < 0) { 199 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
213 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 200 if (ret < 0) {
214 goto sst_load_base_firmware_failed; 201 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
202 return ret;
203 }
215 } 204 }
216 205
217 /* check for extended manifest */
218 if (ctx->fw == NULL)
219 goto sst_load_base_firmware_failed;
220
221 /* prase uuids on first boot */ 206 /* prase uuids on first boot */
222 if (skl->is_first_boot) { 207 if (skl->is_first_boot) {
223 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); 208 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
@@ -229,18 +214,20 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
229 stripped_fw.size = ctx->fw->size; 214 stripped_fw.size = ctx->fw->size;
230 skl_dsp_strip_extended_manifest(&stripped_fw); 215 skl_dsp_strip_extended_manifest(&stripped_fw);
231 216
232 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 217
233 /* Retry Enabling core and ROM load. Retry seemed to help */ 218 for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) {
234 if (ret < 0) {
235 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 219 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
236 if (ret < 0) { 220 if (ret == 0)
237 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 221 break;
222 }
223
224 if (ret < 0) {
225 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
238 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 226 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
239 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 227 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
240 228
241 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret); 229 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret);
242 goto sst_load_base_firmware_failed; 230 goto sst_load_base_firmware_failed;
243 }
244 } 231 }
245 232
246 ret = sst_transfer_fw_host_dma(ctx); 233 ret = sst_transfer_fw_host_dma(ctx);
@@ -265,8 +252,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
265 } 252 }
266 } 253 }
267 254
255 return ret;
256
268sst_load_base_firmware_failed: 257sst_load_base_firmware_failed:
269 release_firmware(ctx->fw); 258 release_firmware(ctx->fw);
259 ctx->fw = NULL;
270 return ret; 260 return ret;
271} 261}
272 262
@@ -428,6 +418,7 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
428 return ret; 418 return ret;
429 } 419 }
430 } 420 }
421 skl->cores.state[core_id] = SKL_DSP_RUNNING;
431 return ret; 422 return ret;
432 } 423 }
433 424
@@ -514,11 +505,22 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
514 505
515 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID, 506 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
516 BXT_BASE_FW_MODULE_ID, &dx); 507 BXT_BASE_FW_MODULE_ID, &dx);
517 if (ret < 0) 508 if (ret < 0) {
518 dev_err(ctx->dev, 509 dev_err(ctx->dev,
519 "Failed to set DSP to D3:core id = %d;Continue reset\n", 510 "Failed to set DSP to D3:core id = %d;Continue reset\n",
520 core_id); 511 core_id);
512 /*
513 * In case of D3 failure, re-download the firmware, so set
514 * fw_loaded to false.
515 */
516 skl->fw_loaded = false;
517 }
521 518
519 if (core_id == SKL_DSP_CORE0_ID) {
520 /* disable Interrupt */
521 skl_ipc_op_int_disable(ctx);
522 skl_ipc_int_disable(ctx);
523 }
522 ret = skl_dsp_disable_core(ctx, core_mask); 524 ret = skl_dsp_disable_core(ctx, core_mask);
523 if (ret < 0) { 525 if (ret < 0) {
524 dev_err(ctx->dev, "Failed to disable core %d\n", ret); 526 dev_err(ctx->dev, "Failed to disable core %d\n", ret);
@@ -560,23 +562,14 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
560 struct sst_dsp *sst; 562 struct sst_dsp *sst;
561 int ret; 563 int ret;
562 564
563 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); 565 ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
564 if (skl == NULL) 566 if (ret < 0) {
565 return -ENOMEM; 567 dev_err(dev, "%s: no device\n", __func__);
566 568 return ret;
567 skl->dev = dev;
568 skl_dev.thread_context = skl;
569 INIT_LIST_HEAD(&skl->uuid_list);
570
571 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
572 if (!skl->dsp) {
573 dev_err(skl->dev, "skl_dsp_ctx_init failed\n");
574 return -ENODEV;
575 } 569 }
576 570
571 skl = *dsp;
577 sst = skl->dsp; 572 sst = skl->dsp;
578 sst->fw_name = fw_name;
579 sst->dsp_ops = dsp_ops;
580 sst->fw_ops = bxt_fw_ops; 573 sst->fw_ops = bxt_fw_ops;
581 sst->addr.lpe = mmio_base; 574 sst->addr.lpe = mmio_base;
582 sst->addr.shim = mmio_base; 575 sst->addr.shim = mmio_base;
@@ -584,24 +577,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
584 sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 577 sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
585 SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 578 SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
586 579
587 INIT_LIST_HEAD(&sst->module_list);
588 ret = skl_ipc_init(dev, skl);
589 if (ret)
590 return ret;
591
592 /* set the D0i3 check */ 580 /* set the D0i3 check */
593 skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; 581 skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
594 582
595 skl->cores.count = 2; 583 skl->cores.count = 2;
596 skl->boot_complete = false; 584 skl->boot_complete = false;
597 init_waitqueue_head(&skl->boot_wait); 585 init_waitqueue_head(&skl->boot_wait);
598 skl->is_first_boot = true;
599 INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); 586 INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
600 skl->d0i3.state = SKL_DSP_D0I3_NONE; 587 skl->d0i3.state = SKL_DSP_D0I3_NONE;
601 588
602 if (dsp)
603 *dsp = skl;
604
605 return 0; 589 return 0;
606} 590}
607EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 591EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
@@ -635,6 +619,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
635 619
636void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 620void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
637{ 621{
622
623 skl_release_library(ctx->lib_info, ctx->lib_count);
624 if (ctx->dsp->fw)
625 release_firmware(ctx->dsp->fw);
638 skl_freeup_uuid_list(ctx); 626 skl_freeup_uuid_list(ctx);
639 skl_ipc_free(&ctx->ipc); 627 skl_ipc_free(&ctx->ipc);
640 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); 628 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index e66870474f10..ab1adc0c9cc3 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -58,7 +58,7 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
58#define NOTIFICATION_MASK 0xf 58#define NOTIFICATION_MASK 0xf
59 59
60/* disable notfication for underruns/overruns from firmware module */ 60/* disable notfication for underruns/overruns from firmware module */
61static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) 61void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
62{ 62{
63 struct notification_mask mask; 63 struct notification_mask mask;
64 struct skl_ipc_large_config_msg msg = {0}; 64 struct skl_ipc_large_config_msg msg = {0};
@@ -209,7 +209,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
209 { 209 {
210 .id = 0x9d71, 210 .id = 0x9d71,
211 .loader_ops = skl_get_loader_ops, 211 .loader_ops = skl_get_loader_ops,
212 .init = skl_sst_dsp_init, 212 .init = kbl_sst_dsp_init,
213 .init_fw = skl_sst_init_fw, 213 .init_fw = skl_sst_init_fw,
214 .cleanup = skl_sst_dsp_cleanup 214 .cleanup = skl_sst_dsp_cleanup
215 }, 215 },
@@ -274,6 +274,7 @@ int skl_init_dsp(struct skl *skl)
274 if (ret < 0) 274 if (ret < 0)
275 return ret; 275 return ret;
276 276
277 skl->skl_sst->dsp_ops = ops;
277 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 278 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
278 279
279 return ret; 280 return ret;
@@ -284,16 +285,11 @@ int skl_free_dsp(struct skl *skl)
284 struct hdac_ext_bus *ebus = &skl->ebus; 285 struct hdac_ext_bus *ebus = &skl->ebus;
285 struct hdac_bus *bus = ebus_to_hbus(ebus); 286 struct hdac_bus *bus = ebus_to_hbus(ebus);
286 struct skl_sst *ctx = skl->skl_sst; 287 struct skl_sst *ctx = skl->skl_sst;
287 const struct skl_dsp_ops *ops;
288 288
289 /* disable ppcap interrupt */ 289 /* disable ppcap interrupt */
290 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 290 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
291 291
292 ops = skl_get_dsp_ops(skl->pci->device); 292 ctx->dsp_ops->cleanup(bus->dev, ctx);
293 if (!ops)
294 return -EIO;
295
296 ops->cleanup(bus->dev, ctx);
297 293
298 if (ctx->dsp->addr.lpe) 294 if (ctx->dsp->addr.lpe)
299 iounmap(ctx->dsp->addr.lpe); 295 iounmap(ctx->dsp->addr.lpe);
@@ -866,7 +862,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
866 } 862 }
867 863
868 if (!found) 864 if (!found)
869 mcfg->m_state = SKL_MODULE_UNINIT; 865 mcfg->m_state = SKL_MODULE_INIT_DONE;
870 return; 866 return;
871} 867}
872 868
@@ -1098,7 +1094,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1098 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1094 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1099 1095
1100 /* If pipe is started, do stop the pipe in FW. */ 1096 /* If pipe is started, do stop the pipe in FW. */
1101 if (pipe->state > SKL_PIPE_STARTED) { 1097 if (pipe->state >= SKL_PIPE_STARTED) {
1102 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1098 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
1103 if (ret < 0) { 1099 if (ret < 0) {
1104 dev_err(ctx->dev, "Failed to stop pipeline\n"); 1100 dev_err(ctx->dev, "Failed to stop pipeline\n");
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 7eb9c419dc7f..e3f06672fd6d 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -24,8 +24,6 @@
24static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45, 24static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45,
25 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53}; 25 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53};
26 26
27#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS"
28
29struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) 27struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
30{ 28{
31 acpi_handle handle; 29 acpi_handle handle;
@@ -33,8 +31,9 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
33 struct nhlt_resource_desc *nhlt_ptr = NULL; 31 struct nhlt_resource_desc *nhlt_ptr = NULL;
34 struct nhlt_acpi_table *nhlt_table = NULL; 32 struct nhlt_acpi_table *nhlt_table = NULL;
35 33
36 if (ACPI_FAILURE(acpi_get_handle(NULL, DSDT_NHLT_PATH, &handle))) { 34 handle = ACPI_HANDLE(dev);
37 dev_err(dev, "Requested NHLT device not found\n"); 35 if (!handle) {
36 dev_err(dev, "Didn't find ACPI_HANDLE\n");
38 return NULL; 37 return NULL;
39 } 38 }
40 39
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index e12520e142ff..e91bbcffc856 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/delay.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
25#include <sound/soc.h> 26#include <sound/soc.h>
26#include "skl.h" 27#include "skl.h"
@@ -155,7 +156,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
155 snd_hdac_ext_stream_decouple(ebus, stream, true); 156 snd_hdac_ext_stream_decouple(ebus, stream, true);
156 157
157 format_val = snd_hdac_calc_stream_format(params->s_freq, 158 format_val = snd_hdac_calc_stream_format(params->s_freq,
158 params->ch, params->format, 32, 0); 159 params->ch, params->format, params->host_bps, 0);
159 160
160 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", 161 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
161 format_val, params->s_freq, params->ch, params->format); 162 format_val, params->s_freq, params->ch, params->format);
@@ -190,8 +191,8 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
190 191
191 stream = stream_to_hdac_ext_stream(hstream); 192 stream = stream_to_hdac_ext_stream(hstream);
192 snd_hdac_ext_stream_decouple(ebus, stream, true); 193 snd_hdac_ext_stream_decouple(ebus, stream, true);
193 format_val = snd_hdac_calc_stream_format(params->s_freq, 194 format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
194 params->ch, params->format, 24, 0); 195 params->format, params->link_bps, 0);
195 196
196 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", 197 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
197 format_val, params->s_freq, params->ch, params->format); 198 format_val, params->s_freq, params->ch, params->format);
@@ -262,23 +263,6 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
262 return 0; 263 return 0;
263} 264}
264 265
265static int skl_be_prepare(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai)
267{
268 struct skl *skl = get_skl_ctx(dai->dev);
269 struct skl_sst *ctx = skl->skl_sst;
270 struct skl_module_cfg *mconfig;
271
272 if (dai->playback_widget->power || dai->capture_widget->power)
273 return 0;
274
275 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
276 if (mconfig == NULL)
277 return -EINVAL;
278
279 return skl_dsp_set_dma_control(ctx, mconfig);
280}
281
282static int skl_pcm_prepare(struct snd_pcm_substream *substream, 266static int skl_pcm_prepare(struct snd_pcm_substream *substream,
283 struct snd_soc_dai *dai) 267 struct snd_soc_dai *dai)
284{ 268{
@@ -326,6 +310,11 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
326 p_params.host_dma_id = dma_id; 310 p_params.host_dma_id = dma_id;
327 p_params.stream = substream->stream; 311 p_params.stream = substream->stream;
328 p_params.format = params_format(params); 312 p_params.format = params_format(params);
313 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
314 p_params.host_bps = dai->driver->playback.sig_bits;
315 else
316 p_params.host_bps = dai->driver->capture.sig_bits;
317
329 318
330 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream); 319 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
331 if (m_cfg) 320 if (m_cfg)
@@ -564,6 +553,11 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
564 p_params.link_index = link->index; 553 p_params.link_index = link->index;
565 p_params.format = params_format(params); 554 p_params.format = params_format(params);
566 555
556 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
557 p_params.link_bps = codec_dai->driver->playback.sig_bits;
558 else
559 p_params.link_bps = codec_dai->driver->capture.sig_bits;
560
567 return skl_tplg_be_update_params(dai, &p_params); 561 return skl_tplg_be_update_params(dai, &p_params);
568} 562}
569 563
@@ -649,7 +643,6 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = {
649 643
650static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { 644static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
651 .hw_params = skl_be_hw_params, 645 .hw_params = skl_be_hw_params,
652 .prepare = skl_be_prepare,
653}; 646};
654 647
655static struct snd_soc_dai_ops skl_link_dai_ops = { 648static struct snd_soc_dai_ops skl_link_dai_ops = {
@@ -670,6 +663,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
670 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, 663 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
671 .formats = SNDRV_PCM_FMTBIT_S16_LE | 664 .formats = SNDRV_PCM_FMTBIT_S16_LE |
672 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, 665 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
666 .sig_bits = 32,
673 }, 667 },
674 .capture = { 668 .capture = {
675 .stream_name = "System Capture", 669 .stream_name = "System Capture",
@@ -677,6 +671,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
677 .channels_max = HDA_STEREO, 671 .channels_max = HDA_STEREO,
678 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 672 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
679 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 673 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
674 .sig_bits = 32,
680 }, 675 },
681}, 676},
682{ 677{
@@ -688,6 +683,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
688 .channels_max = HDA_QUAD, 683 .channels_max = HDA_QUAD,
689 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 684 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
690 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 685 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
686 .sig_bits = 32,
691 }, 687 },
692}, 688},
693{ 689{
@@ -699,6 +695,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
699 .channels_max = HDA_STEREO, 695 .channels_max = HDA_STEREO,
700 .rates = SNDRV_PCM_RATE_48000, 696 .rates = SNDRV_PCM_RATE_48000,
701 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 697 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
698 .sig_bits = 32,
702 }, 699 },
703}, 700},
704{ 701{
@@ -710,6 +707,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
710 .channels_max = HDA_STEREO, 707 .channels_max = HDA_STEREO,
711 .rates = SNDRV_PCM_RATE_48000, 708 .rates = SNDRV_PCM_RATE_48000,
712 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 709 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
710 .sig_bits = 32,
713 }, 711 },
714}, 712},
715{ 713{
@@ -721,6 +719,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
721 .channels_max = HDA_QUAD, 719 .channels_max = HDA_QUAD,
722 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 720 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
723 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 721 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
722 .sig_bits = 32,
724 }, 723 },
725}, 724},
726{ 725{
@@ -736,6 +735,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
736 SNDRV_PCM_RATE_192000, 735 SNDRV_PCM_RATE_192000,
737 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 736 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
738 SNDRV_PCM_FMTBIT_S32_LE, 737 SNDRV_PCM_FMTBIT_S32_LE,
738 .sig_bits = 32,
739 }, 739 },
740}, 740},
741{ 741{
@@ -751,6 +751,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
751 SNDRV_PCM_RATE_192000, 751 SNDRV_PCM_RATE_192000,
752 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 752 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
753 SNDRV_PCM_FMTBIT_S32_LE, 753 SNDRV_PCM_FMTBIT_S32_LE,
754 .sig_bits = 32,
754 }, 755 },
755}, 756},
756{ 757{
@@ -766,6 +767,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
766 SNDRV_PCM_RATE_192000, 767 SNDRV_PCM_RATE_192000,
767 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 768 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
768 SNDRV_PCM_FMTBIT_S32_LE, 769 SNDRV_PCM_FMTBIT_S32_LE,
770 .sig_bits = 32,
769 }, 771 },
770}, 772},
771 773
@@ -949,14 +951,12 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
949 951
950static int skl_platform_open(struct snd_pcm_substream *substream) 952static int skl_platform_open(struct snd_pcm_substream *substream)
951{ 953{
952 struct snd_pcm_runtime *runtime;
953 struct snd_soc_pcm_runtime *rtd = substream->private_data; 954 struct snd_soc_pcm_runtime *rtd = substream->private_data;
954 struct snd_soc_dai_link *dai_link = rtd->dai_link; 955 struct snd_soc_dai_link *dai_link = rtd->dai_link;
955 956
956 dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__, 957 dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__,
957 dai_link->cpu_dai_name); 958 dai_link->cpu_dai_name);
958 959
959 runtime = substream->runtime;
960 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw); 960 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw);
961 961
962 return 0; 962 return 0;
@@ -1062,13 +1062,31 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer
1062 * HAD space reflects the actual data that is transferred. 1062 * HAD space reflects the actual data that is transferred.
1063 * Use the position buffer for capture, as DPIB write gets 1063 * Use the position buffer for capture, as DPIB write gets
1064 * completed earlier than the actual data written to the DDR. 1064 * completed earlier than the actual data written to the DDR.
1065 *
1066 * For capture stream following workaround is required to fix the
1067 * incorrect position reporting.
1068 *
1069 * 1. Wait for 20us before reading the DMA position in buffer once
1070 * the interrupt is generated for stream completion as update happens
1071 * on the HDA frame boundary i.e. 20.833uSec.
1072 * 2. Read DPIB register to flush the DMA position value. This dummy
1073 * read is required to flush DMA position value.
1074 * 3. Read the DMA Position-in-Buffer. This value now will be equal to
1075 * or greater than period boundary.
1065 */ 1076 */
1066 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1077
1078 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1067 pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE + 1079 pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1068 (AZX_REG_VS_SDXDPIB_XINTERVAL * 1080 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1069 hdac_stream(hstream)->index)); 1081 hdac_stream(hstream)->index));
1070 else 1082 } else {
1083 udelay(20);
1084 readl(ebus->bus.remap_addr +
1085 AZX_REG_VS_SDXDPIB_XBASE +
1086 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1087 hdac_stream(hstream)->index));
1071 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream)); 1088 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
1089 }
1072 1090
1073 if (pos >= hdac_stream(hstream)->bufsize) 1091 if (pos >= hdac_stream(hstream)->bufsize)
1074 pos = 0; 1092 pos = 0;
@@ -1165,7 +1183,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1165 snd_dma_pci_data(skl->pci), 1183 snd_dma_pci_data(skl->pci),
1166 size, MAX_PREALLOC_SIZE); 1184 size, MAX_PREALLOC_SIZE);
1167 if (retval) { 1185 if (retval) {
1168 dev_err(dai->dev, "dma buffer allocationf fail\n"); 1186 dev_err(dai->dev, "dma buffer allocation fail\n");
1169 return retval; 1187 return retval;
1170 } 1188 }
1171 } 1189 }
@@ -1173,29 +1191,52 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1173 return retval; 1191 return retval;
1174} 1192}
1175 1193
1194static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1195{
1196 struct skl_sst *ctx = skl->skl_sst;
1197 struct uuid_module *module;
1198 uuid_le *uuid_mod;
1199
1200 uuid_mod = (uuid_le *)mconfig->guid;
1201
1202 if (list_empty(&ctx->uuid_list)) {
1203 dev_err(ctx->dev, "Module list is empty\n");
1204 return -EIO;
1205 }
1206
1207 list_for_each_entry(module, &ctx->uuid_list, list) {
1208 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
1209 mconfig->id.module_id = module->id;
1210 mconfig->is_loadable = module->is_loadable;
1211 return 0;
1212 }
1213 }
1214
1215 return -EIO;
1216}
1217
1176static int skl_populate_modules(struct skl *skl) 1218static int skl_populate_modules(struct skl *skl)
1177{ 1219{
1178 struct skl_pipeline *p; 1220 struct skl_pipeline *p;
1179 struct skl_pipe_module *m; 1221 struct skl_pipe_module *m;
1180 struct snd_soc_dapm_widget *w; 1222 struct snd_soc_dapm_widget *w;
1181 struct skl_module_cfg *mconfig; 1223 struct skl_module_cfg *mconfig;
1182 int ret; 1224 int ret = 0;
1183 1225
1184 list_for_each_entry(p, &skl->ppl_list, node) { 1226 list_for_each_entry(p, &skl->ppl_list, node) {
1185 list_for_each_entry(m, &p->pipe->w_list, node) { 1227 list_for_each_entry(m, &p->pipe->w_list, node) {
1186
1187 w = m->w; 1228 w = m->w;
1188 mconfig = w->priv; 1229 mconfig = w->priv;
1189 1230
1190 ret = snd_skl_get_module_info(skl->skl_sst, mconfig); 1231 ret = skl_get_module_info(skl, mconfig);
1191 if (ret < 0) { 1232 if (ret < 0) {
1192 dev_err(skl->skl_sst->dev, 1233 dev_err(skl->skl_sst->dev,
1193 "query module info failed:%d\n", ret); 1234 "query module info failed\n");
1194 goto err; 1235 return ret;
1195 } 1236 }
1196 } 1237 }
1197 } 1238 }
1198err: 1239
1199 return ret; 1240 return ret;
1200} 1241}
1201 1242
@@ -1232,6 +1273,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1232 } 1273 }
1233 skl_populate_modules(skl); 1274 skl_populate_modules(skl);
1234 skl->skl_sst->update_d0i3c = skl_update_d0i3c; 1275 skl->skl_sst->update_d0i3c = skl_update_d0i3c;
1276 skl_dsp_enable_notification(skl->skl_sst, false);
1235 } 1277 }
1236 pm_runtime_mark_last_busy(platform->dev); 1278 pm_runtime_mark_last_busy(platform->dev);
1237 pm_runtime_put_autosuspend(platform->dev); 1279 pm_runtime_put_autosuspend(platform->dev);
@@ -1256,6 +1298,7 @@ int skl_platform_register(struct device *dev)
1256 struct skl *skl = ebus_to_skl(ebus); 1298 struct skl *skl = ebus_to_skl(ebus);
1257 1299
1258 INIT_LIST_HEAD(&skl->ppl_list); 1300 INIT_LIST_HEAD(&skl->ppl_list);
1301 INIT_LIST_HEAD(&skl->bind_list);
1259 1302
1260 ret = snd_soc_register_platform(dev, &skl_platform_drv); 1303 ret = snd_soc_register_platform(dev, &skl_platform_drv);
1261 if (ret) { 1304 if (ret) {
@@ -1276,6 +1319,17 @@ int skl_platform_register(struct device *dev)
1276 1319
1277int skl_platform_unregister(struct device *dev) 1320int skl_platform_unregister(struct device *dev)
1278{ 1321{
1322 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
1323 struct skl *skl = ebus_to_skl(ebus);
1324 struct skl_module_deferred_bind *modules, *tmp;
1325
1326 if (!list_empty(&skl->bind_list)) {
1327 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
1328 list_del(&modules->node);
1329 kfree(modules);
1330 }
1331 }
1332
1279 snd_soc_unregister_component(dev); 1333 snd_soc_unregister_component(dev);
1280 snd_soc_unregister_platform(dev); 1334 snd_soc_unregister_platform(dev);
1281 return 0; 1335 return 0;
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index c9f6d87381db..d2b1d60fec02 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -164,7 +164,7 @@ static void skl_cldma_cleanup(struct sst_dsp *ctx)
164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl); 164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl);
165} 165}
166 166
167static int skl_cldma_wait_interruptible(struct sst_dsp *ctx) 167int skl_cldma_wait_interruptible(struct sst_dsp *ctx)
168{ 168{
169 int ret = 0; 169 int ret = 0;
170 170
@@ -243,9 +243,14 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
243 * 2. Polling on fw register to identify if data left to transferred doesn't 243 * 2. Polling on fw register to identify if data left to transferred doesn't
244 * fill the ring buffer. Caller takes care of polling the required status 244 * fill the ring buffer. Caller takes care of polling the required status
245 * register to identify the transfer status. 245 * register to identify the transfer status.
246 * 3. if wait flag is set, waits for DBL interrupt to copy the next chunk till
247 * bytes_left is 0.
248 * if wait flag is not set, doesn't wait for BDL interrupt. after ccopying
249 * the first chunk return the no of bytes_left to be copied.
246 */ 250 */
247static int 251static int
248skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size) 252skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin,
253 u32 total_size, bool wait)
249{ 254{
250 int ret = 0; 255 int ret = 0;
251 bool start = true; 256 bool start = true;
@@ -272,13 +277,14 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
272 size = ctx->cl_dev.bufsize; 277 size = ctx->cl_dev.bufsize;
273 skl_cldma_fill_buffer(ctx, size, curr_pos, true, start); 278 skl_cldma_fill_buffer(ctx, size, curr_pos, true, start);
274 279
275 start = false; 280 if (wait) {
276 ret = skl_cldma_wait_interruptible(ctx); 281 start = false;
277 if (ret < 0) { 282 ret = skl_cldma_wait_interruptible(ctx);
278 skl_cldma_stop(ctx); 283 if (ret < 0) {
279 return ret; 284 skl_cldma_stop(ctx);
285 return ret;
286 }
280 } 287 }
281
282 } else { 288 } else {
283 skl_cldma_int_disable(ctx); 289 skl_cldma_int_disable(ctx);
284 290
@@ -298,9 +304,11 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
298 } 304 }
299 bytes_left -= size; 305 bytes_left -= size;
300 curr_pos = curr_pos + size; 306 curr_pos = curr_pos + size;
307 if (!wait)
308 return bytes_left;
301 } 309 }
302 310
303 return ret; 311 return bytes_left;
304} 312}
305 313
306void skl_cldma_process_intr(struct sst_dsp *ctx) 314void skl_cldma_process_intr(struct sst_dsp *ctx)
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.h b/sound/soc/intel/skylake/skl-sst-cldma.h
index 99e4c86b6358..5b730a1a0ae4 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.h
+++ b/sound/soc/intel/skylake/skl-sst-cldma.h
@@ -213,7 +213,7 @@ struct skl_cl_dev_ops {
213 void (*cl_trigger)(struct sst_dsp *ctx, bool enable); 213 void (*cl_trigger)(struct sst_dsp *ctx, bool enable);
214 void (*cl_cleanup_controller)(struct sst_dsp *ctx); 214 void (*cl_cleanup_controller)(struct sst_dsp *ctx);
215 int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx, 215 int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
216 const void *bin, u32 size); 216 const void *bin, u32 size, bool wait);
217 void (*cl_stop_dma)(struct sst_dsp *ctx); 217 void (*cl_stop_dma)(struct sst_dsp *ctx);
218}; 218};
219 219
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index c3deefab65d6..08332723c700 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -355,12 +355,13 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
355 ret = ctx->fw_ops.set_state_D0(ctx, core_id); 355 ret = ctx->fw_ops.set_state_D0(ctx, core_id);
356 if (ret < 0) { 356 if (ret < 0) {
357 dev_err(ctx->dev, "unable to get core%d\n", core_id); 357 dev_err(ctx->dev, "unable to get core%d\n", core_id);
358 return ret; 358 goto out;
359 } 359 }
360 } 360 }
361 361
362 skl->cores.usage_count[core_id]++; 362 skl->cores.usage_count[core_id]++;
363 363
364out:
364 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", 365 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
365 core_id, skl->cores.state[core_id], 366 core_id, skl->cores.state[core_id],
366 skl->cores.usage_count[core_id]); 367 skl->cores.usage_count[core_id]);
@@ -379,7 +380,8 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
379 return -EINVAL; 380 return -EINVAL;
380 } 381 }
381 382
382 if (--skl->cores.usage_count[core_id] == 0) { 383 if ((--skl->cores.usage_count[core_id] == 0) &&
384 (skl->cores.state[core_id] != SKL_DSP_RESET)) {
383 ret = ctx->fw_ops.set_state_D3(ctx, core_id); 385 ret = ctx->fw_ops.set_state_D3(ctx, core_id);
384 if (ret < 0) { 386 if (ret < 0) {
385 dev_err(ctx->dev, "unable to put core %d: %d\n", 387 dev_err(ctx->dev, "unable to put core %d: %d\n",
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 849410d0823e..eba20d37ba8c 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -17,13 +17,15 @@
17#define __SKL_SST_DSP_H__ 17#define __SKL_SST_DSP_H__
18 18
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/uuid.h>
21#include <linux/firmware.h>
20#include <sound/memalloc.h> 22#include <sound/memalloc.h>
21#include "skl-sst-cldma.h" 23#include "skl-sst-cldma.h"
22#include "skl-topology.h"
23 24
24struct sst_dsp; 25struct sst_dsp;
25struct skl_sst; 26struct skl_sst;
26struct sst_dsp_device; 27struct sst_dsp_device;
28struct skl_lib_info;
27 29
28/* Intel HD Audio General DSP Registers */ 30/* Intel HD Audio General DSP Registers */
29#define SKL_ADSP_GEN_BASE 0x0 31#define SKL_ADSP_GEN_BASE 0x0
@@ -144,7 +146,7 @@ struct skl_dsp_fw_ops {
144 int (*load_fw)(struct sst_dsp *ctx); 146 int (*load_fw)(struct sst_dsp *ctx);
145 /* FW module parser/loader */ 147 /* FW module parser/loader */
146 int (*load_library)(struct sst_dsp *ctx, 148 int (*load_library)(struct sst_dsp *ctx,
147 struct skl_lib_info *linfo, int count); 149 struct skl_lib_info *linfo, int lib_count);
148 int (*parse_fw)(struct sst_dsp *ctx); 150 int (*parse_fw)(struct sst_dsp *ctx);
149 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); 151 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
150 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); 152 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
@@ -172,6 +174,19 @@ struct skl_dsp_loader_ops {
172 int stream_tag); 174 int stream_tag);
173}; 175};
174 176
177#define MAX_INSTANCE_BUFF 2
178
179struct uuid_module {
180 uuid_le uuid;
181 int id;
182 int is_loadable;
183 int max_instance;
184 u64 pvt_id[MAX_INSTANCE_BUFF];
185 int *instance_id;
186
187 struct list_head list;
188};
189
175struct skl_load_module_info { 190struct skl_load_module_info {
176 u16 mod_id; 191 u16 mod_id;
177 const struct firmware *fw; 192 const struct firmware *fw;
@@ -186,6 +201,7 @@ struct skl_module_table {
186void skl_cldma_process_intr(struct sst_dsp *ctx); 201void skl_cldma_process_intr(struct sst_dsp *ctx);
187void skl_cldma_int_disable(struct sst_dsp *ctx); 202void skl_cldma_int_disable(struct sst_dsp *ctx);
188int skl_cldma_prepare(struct sst_dsp *ctx); 203int skl_cldma_prepare(struct sst_dsp *ctx);
204int skl_cldma_wait_interruptible(struct sst_dsp *ctx);
189 205
190void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); 206void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
191struct sst_dsp *skl_dsp_ctx_init(struct device *dev, 207struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
@@ -214,6 +230,9 @@ int skl_dsp_boot(struct sst_dsp *ctx);
214int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 230int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
215 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 231 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
216 struct skl_sst **dsp); 232 struct skl_sst **dsp);
233int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
234 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
235 struct skl_sst **dsp);
217int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 236int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
218 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 237 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
219 struct skl_sst **dsp); 238 struct skl_sst **dsp);
@@ -222,17 +241,22 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
222void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 241void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
223void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 242void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
224 243
225int snd_skl_get_module_info(struct skl_sst *ctx,
226 struct skl_module_cfg *mconfig);
227int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, 244int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
228 unsigned int offset, int index); 245 unsigned int offset, int index);
229int skl_get_pvt_id(struct skl_sst *ctx, 246int skl_get_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int instance_id);
230 struct skl_module_cfg *mconfig); 247int skl_put_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int *pvt_id);
231int skl_put_pvt_id(struct skl_sst *ctx,
232 struct skl_module_cfg *mconfig);
233int skl_get_pvt_instance_id_map(struct skl_sst *ctx, 248int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
234 int module_id, int instance_id); 249 int module_id, int instance_id);
235void skl_freeup_uuid_list(struct skl_sst *ctx); 250void skl_freeup_uuid_list(struct skl_sst *ctx);
236 251
237int skl_dsp_strip_extended_manifest(struct firmware *fw); 252int skl_dsp_strip_extended_manifest(struct firmware *fw);
253void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable);
254int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
255 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
256 struct sst_dsp_device *skl_dev);
257int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
258 struct firmware *stripped_fw,
259 unsigned int hdr_offset, int index);
260void skl_release_library(struct skl_lib_info *linfo, int lib_count);
261
238#endif /*__SKL_SST_DSP_H__*/ 262#endif /*__SKL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index e1391dfbc9e9..58c525096a7c 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -34,6 +34,11 @@
34#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1) 34#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
35#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT) 35#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT)
36 36
37#define IPC_GLB_REPLY_TYPE_SHIFT 29
38#define IPC_GLB_REPLY_TYPE_MASK 0x1F
39#define IPC_GLB_REPLY_TYPE(x) (((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
40 & IPC_GLB_RPLY_TYPE_MASK)
41
37#define IPC_TIMEOUT_MSECS 3000 42#define IPC_TIMEOUT_MSECS 3000
38 43
39#define IPC_EMPTY_LIST_SIZE 8 44#define IPC_EMPTY_LIST_SIZE 8
@@ -387,12 +392,27 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
387 return 0; 392 return 0;
388} 393}
389 394
395static int skl_ipc_set_reply_error_code(u32 reply)
396{
397 switch (reply) {
398 case IPC_GLB_REPLY_OUT_OF_MEMORY:
399 return -ENOMEM;
400
401 case IPC_GLB_REPLY_BUSY:
402 return -EBUSY;
403
404 default:
405 return -EINVAL;
406 }
407}
408
390static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, 409static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
391 struct skl_ipc_header header) 410 struct skl_ipc_header header)
392{ 411{
393 struct ipc_message *msg; 412 struct ipc_message *msg;
394 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; 413 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
395 u64 *ipc_header = (u64 *)(&header); 414 u64 *ipc_header = (u64 *)(&header);
415 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
396 416
397 msg = skl_ipc_reply_get_msg(ipc, *ipc_header); 417 msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
398 if (msg == NULL) { 418 if (msg == NULL) {
@@ -401,33 +421,39 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
401 } 421 }
402 422
403 /* first process the header */ 423 /* first process the header */
404 switch (reply) { 424 if (reply == IPC_GLB_REPLY_SUCCESS) {
405 case IPC_GLB_REPLY_SUCCESS:
406 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); 425 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
407 /* copy the rx data from the mailbox */ 426 /* copy the rx data from the mailbox */
408 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); 427 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
409 break; 428 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
410 429 case IPC_GLB_LOAD_MULTIPLE_MODS:
411 case IPC_GLB_REPLY_OUT_OF_MEMORY: 430 case IPC_GLB_LOAD_LIBRARY:
412 dev_err(ipc->dev, "ipc fw reply: %x: no memory\n", header.primary); 431 skl->mod_load_complete = true;
413 msg->errno = -ENOMEM; 432 skl->mod_load_status = true;
414 break; 433 wake_up(&skl->mod_load_wait);
415 434 break;
416 case IPC_GLB_REPLY_BUSY:
417 dev_err(ipc->dev, "ipc fw reply: %x: Busy\n", header.primary);
418 msg->errno = -EBUSY;
419 break;
420 435
421 default: 436 default:
422 dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply); 437 break;
423 msg->errno = -EINVAL;
424 break;
425 }
426 438
427 if (reply != IPC_GLB_REPLY_SUCCESS) { 439 }
440 } else {
441 msg->errno = skl_ipc_set_reply_error_code(reply);
428 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply); 442 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
429 dev_err(ipc->dev, "FW Error Code: %u\n", 443 dev_err(ipc->dev, "FW Error Code: %u\n",
430 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); 444 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
445 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
446 case IPC_GLB_LOAD_MULTIPLE_MODS:
447 case IPC_GLB_LOAD_LIBRARY:
448 skl->mod_load_complete = true;
449 skl->mod_load_status = false;
450 wake_up(&skl->mod_load_wait);
451 break;
452
453 default:
454 break;
455
456 }
431 } 457 }
432 458
433 list_del(&msg->list); 459 list_del(&msg->list);
@@ -811,8 +837,8 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
811 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); 837 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
812 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); 838 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
813 839
814 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, 840 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data,
815 (sizeof(u16) * module_cnt), NULL, 0); 841 (sizeof(u16) * module_cnt));
816 if (ret < 0) 842 if (ret < 0)
817 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); 843 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
818 844
@@ -947,7 +973,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
947EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); 973EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
948 974
949int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, 975int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
950 u8 dma_id, u8 table_id) 976 u8 dma_id, u8 table_id, bool wait)
951{ 977{
952 struct skl_ipc_header header = {0}; 978 struct skl_ipc_header header = {0};
953 u64 *ipc_header = (u64 *)(&header); 979 u64 *ipc_header = (u64 *)(&header);
@@ -959,7 +985,11 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
959 header.primary |= IPC_MOD_INSTANCE_ID(table_id); 985 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
960 header.primary |= IPC_MOD_ID(dma_id); 986 header.primary |= IPC_MOD_ID(dma_id);
961 987
962 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 988 if (wait)
989 ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
990 NULL, 0, NULL, 0);
991 else
992 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
963 993
964 if (ret < 0) 994 if (ret < 0)
965 dev_err(ipc->dev, "ipc: load lib failed\n"); 995 dev_err(ipc->dev, "ipc: load lib failed\n");
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9660ace379ab..e057da2713c6 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -69,6 +69,14 @@ struct skl_d0i3_data {
69 struct delayed_work work; 69 struct delayed_work work;
70}; 70};
71 71
72#define SKL_LIB_NAME_LENGTH 128
73#define SKL_MAX_LIB 16
74
75struct skl_lib_info {
76 char name[SKL_LIB_NAME_LENGTH];
77 const struct firmware *fw;
78};
79
72struct skl_sst { 80struct skl_sst {
73 struct device *dev; 81 struct device *dev;
74 struct sst_dsp *dsp; 82 struct sst_dsp *dsp;
@@ -77,6 +85,11 @@ struct skl_sst {
77 wait_queue_head_t boot_wait; 85 wait_queue_head_t boot_wait;
78 bool boot_complete; 86 bool boot_complete;
79 87
88 /* module load */
89 wait_queue_head_t mod_load_wait;
90 bool mod_load_complete;
91 bool mod_load_status;
92
80 /* IPC messaging */ 93 /* IPC messaging */
81 struct sst_generic_ipc ipc; 94 struct sst_generic_ipc ipc;
82 95
@@ -105,6 +118,8 @@ struct skl_sst {
105 void (*update_d0i3c)(struct device *dev, bool enable); 118 void (*update_d0i3c)(struct device *dev, bool enable);
106 119
107 struct skl_d0i3_data d0i3; 120 struct skl_d0i3_data d0i3;
121
122 const struct skl_dsp_ops *dsp_ops;
108}; 123};
109 124
110struct skl_ipc_init_instance_msg { 125struct skl_ipc_init_instance_msg {
@@ -182,7 +197,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
182 struct skl_ipc_large_config_msg *msg, u32 *param); 197 struct skl_ipc_large_config_msg *msg, u32 *param);
183 198
184int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, 199int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
185 u8 dma_id, u8 table_id); 200 u8 dma_id, u8 table_id, bool wait);
186 201
187int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, 202int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc,
188 struct skl_ipc_d0ix_msg *msg); 203 struct skl_ipc_d0ix_msg *msg);
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index ea162fbf68e5..81ee251881b4 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -94,19 +94,6 @@ struct adsp_fw_hdr {
94 u32 load_offset; 94 u32 load_offset;
95} __packed; 95} __packed;
96 96
97#define MAX_INSTANCE_BUFF 2
98
99struct uuid_module {
100 uuid_le uuid;
101 int id;
102 int is_loadable;
103 int max_instance;
104 u64 pvt_id[MAX_INSTANCE_BUFF];
105 int *instance_id;
106
107 struct list_head list;
108};
109
110struct skl_ext_manifest_hdr { 97struct skl_ext_manifest_hdr {
111 u32 id; 98 u32 id;
112 u32 len; 99 u32 len;
@@ -115,32 +102,6 @@ struct skl_ext_manifest_hdr {
115 u32 entries; 102 u32 entries;
116}; 103};
117 104
118int snd_skl_get_module_info(struct skl_sst *ctx,
119 struct skl_module_cfg *mconfig)
120{
121 struct uuid_module *module;
122 uuid_le *uuid_mod;
123
124 uuid_mod = (uuid_le *)mconfig->guid;
125
126 if (list_empty(&ctx->uuid_list)) {
127 dev_err(ctx->dev, "Module list is empty\n");
128 return -EINVAL;
129 }
130
131 list_for_each_entry(module, &ctx->uuid_list, list) {
132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
133 mconfig->id.module_id = module->id;
134 mconfig->is_loadable = module->is_loadable;
135
136 return 0;
137 }
138 }
139
140 return -EINVAL;
141}
142EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
143
144static int skl_get_pvtid_map(struct uuid_module *module, int instance_id) 105static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
145{ 106{
146 int pvt_id; 107 int pvt_id;
@@ -222,21 +183,18 @@ static inline int skl_pvtid_128(struct uuid_module *module)
222 * This generates a 128 bit private unique id for a module TYPE so that 183 * This generates a 128 bit private unique id for a module TYPE so that
223 * module instance is unique 184 * module instance is unique
224 */ 185 */
225int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 186int skl_get_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int instance_id)
226{ 187{
227 struct uuid_module *module; 188 struct uuid_module *module;
228 uuid_le *uuid_mod;
229 int pvt_id; 189 int pvt_id;
230 190
231 uuid_mod = (uuid_le *)mconfig->guid;
232
233 list_for_each_entry(module, &ctx->uuid_list, list) { 191 list_for_each_entry(module, &ctx->uuid_list, list) {
234 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 192 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
235 193
236 pvt_id = skl_pvtid_128(module); 194 pvt_id = skl_pvtid_128(module);
237 if (pvt_id >= 0) { 195 if (pvt_id >= 0) {
238 module->instance_id[pvt_id] = 196 module->instance_id[pvt_id] = instance_id;
239 mconfig->id.instance_id; 197
240 return pvt_id; 198 return pvt_id;
241 } 199 }
242 } 200 }
@@ -254,23 +212,21 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
254 * 212 *
255 * This frees a 128 bit private unique id previously generated 213 * This frees a 128 bit private unique id previously generated
256 */ 214 */
257int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 215int skl_put_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int *pvt_id)
258{ 216{
259 int i; 217 int i;
260 uuid_le *uuid_mod;
261 struct uuid_module *module; 218 struct uuid_module *module;
262 219
263 uuid_mod = (uuid_le *)mconfig->guid;
264 list_for_each_entry(module, &ctx->uuid_list, list) { 220 list_for_each_entry(module, &ctx->uuid_list, list) {
265 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 221 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
266 222
267 if (mconfig->id.pvt_id != 0) 223 if (*pvt_id != 0)
268 i = (mconfig->id.pvt_id) / 64; 224 i = (*pvt_id) / 64;
269 else 225 else
270 i = 0; 226 i = 0;
271 227
272 module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id)); 228 module->pvt_id[i] &= ~(1 << (*pvt_id));
273 mconfig->id.pvt_id = -1; 229 *pvt_id = -1;
274 return 0; 230 return 0;
275 } 231 }
276 } 232 }
@@ -405,3 +361,83 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
405 361
406 return 0; 362 return 0;
407} 363}
364
365int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
366 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
367 struct sst_dsp_device *skl_dev)
368{
369 struct skl_sst *skl;
370 struct sst_dsp *sst;
371 int ret;
372
373 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
374 if (skl == NULL)
375 return -ENOMEM;
376
377 skl->dev = dev;
378 skl_dev->thread_context = skl;
379 INIT_LIST_HEAD(&skl->uuid_list);
380 skl->dsp = skl_dsp_ctx_init(dev, skl_dev, irq);
381 if (!skl->dsp) {
382 dev_err(skl->dev, "%s: no device\n", __func__);
383 return -ENODEV;
384 }
385
386 sst = skl->dsp;
387 sst->fw_name = fw_name;
388 sst->dsp_ops = dsp_ops;
389 init_waitqueue_head(&skl->mod_load_wait);
390 INIT_LIST_HEAD(&sst->module_list);
391 ret = skl_ipc_init(dev, skl);
392 if (ret)
393 return ret;
394
395 skl->is_first_boot = true;
396 if (dsp)
397 *dsp = skl;
398
399 return ret;
400}
401
402int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
403 struct firmware *stripped_fw,
404 unsigned int hdr_offset, int index)
405{
406 int ret;
407 struct sst_dsp *dsp = skl->dsp;
408
409 if (linfo->fw == NULL) {
410 ret = request_firmware(&linfo->fw, linfo->name,
411 skl->dev);
412 if (ret < 0) {
413 dev_err(skl->dev, "Request lib %s failed:%d\n",
414 linfo->name, ret);
415 return ret;
416 }
417 }
418
419 if (skl->is_first_boot) {
420 ret = snd_skl_parse_uuids(dsp, linfo->fw, hdr_offset, index);
421 if (ret < 0)
422 return ret;
423 }
424
425 stripped_fw->data = linfo->fw->data;
426 stripped_fw->size = linfo->fw->size;
427 skl_dsp_strip_extended_manifest(stripped_fw);
428
429 return 0;
430}
431
432void skl_release_library(struct skl_lib_info *linfo, int lib_count)
433{
434 int i;
435
436 /* library indices start from 1 to N. 0 represents base FW */
437 for (i = 1; i < lib_count; i++) {
438 if (linfo[i].fw) {
439 release_firmware(linfo[i].fw);
440 linfo[i].fw = NULL;
441 }
442 }
443}
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index b30bd384c8d3..155e456b7a3a 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -52,7 +52,8 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
52{ 52{
53 int ret = 0; 53 int ret = 0;
54 54
55 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, basefw, base_fw_size); 55 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, basefw, base_fw_size,
56 true);
56 if (ret < 0) 57 if (ret < 0)
57 return ret; 58 return ret;
58 59
@@ -178,6 +179,18 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
178 dev_err(ctx->dev, "unable to load firmware\n"); 179 dev_err(ctx->dev, "unable to load firmware\n");
179 return ret; 180 return ret;
180 } 181 }
182
183 /* load libs as they are also lost on D3 */
184 if (skl->lib_count > 1) {
185 ret = ctx->fw_ops.load_library(ctx, skl->lib_info,
186 skl->lib_count);
187 if (ret < 0) {
188 dev_err(ctx->dev, "reload libs failed: %d\n",
189 ret);
190 return ret;
191 }
192
193 }
181 } 194 }
182 195
183 /* 196 /*
@@ -203,7 +216,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
203 216
204 skl->cores.state[core_id] = SKL_DSP_RUNNING; 217 skl->cores.state[core_id] = SKL_DSP_RUNNING;
205 218
206 return ret; 219 return 0;
207} 220}
208 221
209static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) 222static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
@@ -323,27 +336,85 @@ static struct skl_module_table *skl_module_get_from_id(
323 return NULL; 336 return NULL;
324} 337}
325 338
326static int skl_transfer_module(struct sst_dsp *ctx, 339static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
327 struct skl_load_module_info *module) 340 u32 size, u16 mod_id, u8 table_id, bool is_module)
328{ 341{
329 int ret; 342 int ret, bytes_left, curr_pos;
330 struct skl_sst *skl = ctx->thread_context; 343 struct skl_sst *skl = ctx->thread_context;
344 skl->mod_load_complete = false;
331 345
332 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, module->fw->data, 346 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false);
333 module->fw->size); 347 if (bytes_left < 0)
334 if (ret < 0) 348 return bytes_left;
335 return ret;
336 349
337 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, 350 /* check is_module flag to load module or library */
338 (void *)&module->mod_id); 351 if (is_module)
339 if (ret < 0) 352 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id);
340 dev_err(ctx->dev, "Failed to Load module: %d\n", ret); 353 else
354 ret = skl_sst_ipc_load_library(&skl->ipc, 0, table_id, false);
355
356 if (ret < 0) {
357 dev_err(ctx->dev, "Failed to Load %s with err %d\n",
358 is_module ? "module" : "lib", ret);
359 goto out;
360 }
361
362 /*
363 * if bytes_left > 0 then wait for BDL complete interrupt and
364 * copy the next chunk till bytes_left is 0. if bytes_left is
365 * is zero, then wait for load module IPC reply
366 */
367 while (bytes_left > 0) {
368 curr_pos = size - bytes_left;
369
370 ret = skl_cldma_wait_interruptible(ctx);
371 if (ret < 0)
372 goto out;
373
374 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx,
375 data + curr_pos,
376 bytes_left, false);
377 }
341 378
379 ret = wait_event_timeout(skl->mod_load_wait, skl->mod_load_complete,
380 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
381 if (ret == 0 || !skl->mod_load_status) {
382 dev_err(ctx->dev, "Module Load failed\n");
383 ret = -EIO;
384 }
385
386out:
342 ctx->cl_dev.ops.cl_stop_dma(ctx); 387 ctx->cl_dev.ops.cl_stop_dma(ctx);
343 388
344 return ret; 389 return ret;
345} 390}
346 391
392static int
393kbl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
394{
395 struct skl_sst *skl = ctx->thread_context;
396 struct firmware stripped_fw;
397 int ret, i;
398
399 /* library indices start from 1 to N. 0 represents base FW */
400 for (i = 1; i < lib_count; i++) {
401 ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
402 SKL_ADSP_FW_BIN_HDR_OFFSET, i);
403 if (ret < 0)
404 goto load_library_failed;
405 ret = skl_transfer_module(ctx, stripped_fw.data,
406 stripped_fw.size, 0, i, false);
407 if (ret < 0)
408 goto load_library_failed;
409 }
410
411 return 0;
412
413load_library_failed:
414 skl_release_library(linfo, lib_count);
415 return ret;
416}
417
347static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) 418static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
348{ 419{
349 struct skl_module_table *module_entry = NULL; 420 struct skl_module_table *module_entry = NULL;
@@ -365,7 +436,9 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
365 } 436 }
366 437
367 if (!module_entry->usage_cnt) { 438 if (!module_entry->usage_cnt) {
368 ret = skl_transfer_module(ctx, module_entry->mod_info); 439 ret = skl_transfer_module(ctx, module_entry->mod_info->fw->data,
440 module_entry->mod_info->fw->size,
441 mod_id, 0, true);
369 if (ret < 0) { 442 if (ret < 0) {
370 dev_err(ctx->dev, "Failed to Load module\n"); 443 dev_err(ctx->dev, "Failed to Load module\n");
371 return ret; 444 return ret;
@@ -388,6 +461,11 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
388 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt); 461 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt);
389 return -EIO; 462 return -EIO;
390 } 463 }
464
465 /* if module is used by others return, no need to unload */
466 if (usage_cnt > 0)
467 return 0;
468
391 ret = skl_ipc_unload_modules(&skl->ipc, 469 ret = skl_ipc_unload_modules(&skl->ipc,
392 SKL_NUM_MODULES, &mod_id); 470 SKL_NUM_MODULES, &mod_id);
393 if (ret < 0) { 471 if (ret < 0) {
@@ -434,6 +512,16 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
434 .unload_mod = skl_unload_module, 512 .unload_mod = skl_unload_module,
435}; 513};
436 514
515static struct skl_dsp_fw_ops kbl_fw_ops = {
516 .set_state_D0 = skl_set_dsp_D0,
517 .set_state_D3 = skl_set_dsp_D3,
518 .load_fw = skl_load_base_firmware,
519 .get_fw_errcode = skl_get_errorcode,
520 .load_library = kbl_load_library,
521 .load_mod = skl_load_module,
522 .unload_mod = skl_unload_module,
523};
524
437static struct sst_ops skl_ops = { 525static struct sst_ops skl_ops = {
438 .irq_handler = skl_dsp_sst_interrupt, 526 .irq_handler = skl_dsp_sst_interrupt,
439 .write = sst_shim32_write, 527 .write = sst_shim32_write,
@@ -455,45 +543,47 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
455 struct sst_dsp *sst; 543 struct sst_dsp *sst;
456 int ret; 544 int ret;
457 545
458 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); 546 ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
459 if (skl == NULL) 547 if (ret < 0) {
460 return -ENOMEM; 548 dev_err(dev, "%s: no device\n", __func__);
461 549 return ret;
462 skl->dev = dev;
463 skl_dev.thread_context = skl;
464 INIT_LIST_HEAD(&skl->uuid_list);
465
466 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
467 if (!skl->dsp) {
468 dev_err(skl->dev, "%s: no device\n", __func__);
469 return -ENODEV;
470 } 550 }
471 551
552 skl = *dsp;
472 sst = skl->dsp; 553 sst = skl->dsp;
473
474 sst->fw_name = fw_name;
475 sst->addr.lpe = mmio_base; 554 sst->addr.lpe = mmio_base;
476 sst->addr.shim = mmio_base; 555 sst->addr.shim = mmio_base;
477 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 556 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
478 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 557 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
479 558
480 INIT_LIST_HEAD(&sst->module_list);
481 sst->dsp_ops = dsp_ops;
482 sst->fw_ops = skl_fw_ops; 559 sst->fw_ops = skl_fw_ops;
483 560
484 ret = skl_ipc_init(dev, skl); 561 skl->cores.count = 2;
485 if (ret) 562
563 return 0;
564}
565EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
566
567int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
568 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
569 struct skl_sst **dsp)
570{
571 struct sst_dsp *sst;
572 int ret;
573
574 ret = skl_sst_dsp_init(dev, mmio_base, irq, fw_name, dsp_ops, dsp);
575 if (ret < 0) {
576 dev_err(dev, "%s: Init failed %d\n", __func__, ret);
486 return ret; 577 return ret;
578 }
487 579
488 skl->cores.count = 2; 580 sst = (*dsp)->dsp;
489 skl->is_first_boot = true; 581 sst->fw_ops = kbl_fw_ops;
490 582
491 if (dsp) 583 return 0;
492 *dsp = skl;
493 584
494 return ret;
495} 585}
496EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 586EXPORT_SYMBOL_GPL(kbl_sst_dsp_init);
497 587
498int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) 588int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
499{ 589{
@@ -507,6 +597,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
507 } 597 }
508 598
509 skl_dsp_init_core_state(sst); 599 skl_dsp_init_core_state(sst);
600
601 if (ctx->lib_count > 1) {
602 ret = sst->fw_ops.load_library(sst, ctx->lib_info,
603 ctx->lib_count);
604 if (ret < 0) {
605 dev_err(dev, "Load Library failed : %x\n", ret);
606 return ret;
607 }
608 }
510 ctx->is_first_boot = false; 609 ctx->is_first_boot = false;
511 610
512 return 0; 611 return 0;
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 2dbfb1b24ef4..3a99712e44a8 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -299,8 +299,6 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
299{ 299{
300 int multiplier = 1; 300 int multiplier = 1;
301 struct skl_module_fmt *in_fmt, *out_fmt; 301 struct skl_module_fmt *in_fmt, *out_fmt;
302 int in_rate, out_rate;
303
304 302
305 /* Since fixups is applied to pin 0 only, ibs, obs needs 303 /* Since fixups is applied to pin 0 only, ibs, obs needs
306 * change for pin 0 only 304 * change for pin 0 only
@@ -311,22 +309,12 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
311 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) 309 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
312 multiplier = 5; 310 multiplier = 5;
313 311
314 if (in_fmt->s_freq % 1000) 312 mcfg->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) *
315 in_rate = (in_fmt->s_freq / 1000) + 1; 313 in_fmt->channels * (in_fmt->bit_depth >> 3) *
316 else
317 in_rate = (in_fmt->s_freq / 1000);
318
319 mcfg->ibs = in_rate * (mcfg->in_fmt->channels) *
320 (mcfg->in_fmt->bit_depth >> 3) *
321 multiplier; 314 multiplier;
322 315
323 if (mcfg->out_fmt->s_freq % 1000) 316 mcfg->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) *
324 out_rate = (mcfg->out_fmt->s_freq / 1000) + 1; 317 out_fmt->channels * (out_fmt->bit_depth >> 3) *
325 else
326 out_rate = (mcfg->out_fmt->s_freq / 1000);
327
328 mcfg->obs = out_rate * (mcfg->out_fmt->channels) *
329 (mcfg->out_fmt->bit_depth >> 3) *
330 multiplier; 318 multiplier;
331} 319}
332 320
@@ -551,6 +539,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
551 int ret = 0; 539 int ret = 0;
552 540
553 list_for_each_entry(w_module, &pipe->w_list, node) { 541 list_for_each_entry(w_module, &pipe->w_list, node) {
542 uuid_le *uuid_mod;
554 w = w_module->w; 543 w = w_module->w;
555 mconfig = w->priv; 544 mconfig = w->priv;
556 545
@@ -588,13 +577,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
588 * FE/BE params 577 * FE/BE params
589 */ 578 */
590 skl_tplg_update_module_params(w, ctx); 579 skl_tplg_update_module_params(w, ctx);
591 mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig); 580 uuid_mod = (uuid_le *)mconfig->guid;
581 mconfig->id.pvt_id = skl_get_pvt_id(ctx, uuid_mod,
582 mconfig->id.instance_id);
592 if (mconfig->id.pvt_id < 0) 583 if (mconfig->id.pvt_id < 0)
593 return ret; 584 return ret;
594 skl_tplg_set_module_init_data(w); 585 skl_tplg_set_module_init_data(w);
595 ret = skl_init_module(ctx, mconfig); 586 ret = skl_init_module(ctx, mconfig);
596 if (ret < 0) { 587 if (ret < 0) {
597 skl_put_pvt_id(ctx, mconfig); 588 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
598 return ret; 589 return ret;
599 } 590 }
600 skl_tplg_alloc_pipe_mcps(skl, mconfig); 591 skl_tplg_alloc_pipe_mcps(skl, mconfig);
@@ -614,7 +605,9 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
614 struct skl_module_cfg *mconfig = NULL; 605 struct skl_module_cfg *mconfig = NULL;
615 606
616 list_for_each_entry(w_module, &pipe->w_list, node) { 607 list_for_each_entry(w_module, &pipe->w_list, node) {
608 uuid_le *uuid_mod;
617 mconfig = w_module->w->priv; 609 mconfig = w_module->w->priv;
610 uuid_mod = (uuid_le *)mconfig->guid;
618 611
619 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && 612 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
620 mconfig->m_state > SKL_MODULE_UNINIT) { 613 mconfig->m_state > SKL_MODULE_UNINIT) {
@@ -623,7 +616,7 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
623 if (ret < 0) 616 if (ret < 0)
624 return -EIO; 617 return -EIO;
625 } 618 }
626 skl_put_pvt_id(ctx, mconfig); 619 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
627 } 620 }
628 621
629 /* no modules to unload in this path, so return */ 622 /* no modules to unload in this path, so return */
@@ -645,8 +638,9 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
645 struct skl_module_cfg *mconfig = w->priv; 638 struct skl_module_cfg *mconfig = w->priv;
646 struct skl_pipe_module *w_module; 639 struct skl_pipe_module *w_module;
647 struct skl_pipe *s_pipe = mconfig->pipe; 640 struct skl_pipe *s_pipe = mconfig->pipe;
648 struct skl_module_cfg *src_module = NULL, *dst_module; 641 struct skl_module_cfg *src_module = NULL, *dst_module, *module;
649 struct skl_sst *ctx = skl->skl_sst; 642 struct skl_sst *ctx = skl->skl_sst;
643 struct skl_module_deferred_bind *modules;
650 644
651 /* check resource available */ 645 /* check resource available */
652 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 646 if (!skl_is_pipe_mcps_avail(skl, mconfig))
@@ -687,29 +681,48 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
687 src_module = dst_module; 681 src_module = dst_module;
688 } 682 }
689 683
684 /*
685 * When the destination module is initialized, check for these modules
686 * in deferred bind list. If found, bind them.
687 */
688 list_for_each_entry(w_module, &s_pipe->w_list, node) {
689 if (list_empty(&skl->bind_list))
690 break;
691
692 list_for_each_entry(modules, &skl->bind_list, node) {
693 module = w_module->w->priv;
694 if (modules->dst == module)
695 skl_bind_modules(ctx, modules->src,
696 modules->dst);
697 }
698 }
699
690 return 0; 700 return 0;
691} 701}
692 702
693static int skl_fill_sink_instance_id(struct skl_sst *ctx, 703static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
694 struct skl_algo_data *alg_data) 704 int size, struct skl_module_cfg *mcfg)
695{ 705{
696 struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params;
697 struct skl_mod_inst_map *inst;
698 int i, pvt_id; 706 int i, pvt_id;
699 707
700 inst = params->map; 708 if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
709 struct skl_kpb_params *kpb_params =
710 (struct skl_kpb_params *)params;
711 struct skl_mod_inst_map *inst = kpb_params->map;
701 712
702 for (i = 0; i < params->num_modules; i++) { 713 for (i = 0; i < kpb_params->num_modules; i++) {
703 pvt_id = skl_get_pvt_instance_id_map(ctx, 714 pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
704 inst->mod_id, inst->inst_id); 715 inst->inst_id);
705 if (pvt_id < 0) 716 if (pvt_id < 0)
706 return -EINVAL; 717 return -EINVAL;
707 inst->inst_id = pvt_id; 718
708 inst++; 719 inst->inst_id = pvt_id;
720 inst++;
721 }
709 } 722 }
723
710 return 0; 724 return 0;
711} 725}
712
713/* 726/*
714 * Some modules require params to be set after the module is bound to 727 * Some modules require params to be set after the module is bound to
715 * all pins connected. 728 * all pins connected.
@@ -726,6 +739,7 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
726 struct soc_bytes_ext *sb; 739 struct soc_bytes_ext *sb;
727 struct skl_algo_data *bc; 740 struct skl_algo_data *bc;
728 struct skl_specific_cfg *sp_cfg; 741 struct skl_specific_cfg *sp_cfg;
742 u32 *params;
729 743
730 /* 744 /*
731 * check all out/in pins are in bind state. 745 * check all out/in pins are in bind state.
@@ -758,11 +772,18 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
758 bc = (struct skl_algo_data *)sb->dobj.private; 772 bc = (struct skl_algo_data *)sb->dobj.private;
759 773
760 if (bc->set_params == SKL_PARAM_BIND) { 774 if (bc->set_params == SKL_PARAM_BIND) {
761 if (mconfig->m_type == SKL_MODULE_TYPE_KPB) 775 params = kzalloc(bc->max, GFP_KERNEL);
762 skl_fill_sink_instance_id(ctx, bc); 776 if (!params)
763 ret = skl_set_module_params(ctx, 777 return -ENOMEM;
764 (u32 *)bc->params, bc->max, 778
765 bc->param_id, mconfig); 779 memcpy(params, bc->params, bc->max);
780 skl_fill_sink_instance_id(ctx, params, bc->max,
781 mconfig);
782
783 ret = skl_set_module_params(ctx, params,
784 bc->max, bc->param_id, mconfig);
785 kfree(params);
786
766 if (ret < 0) 787 if (ret < 0)
767 return ret; 788 return ret;
768 } 789 }
@@ -772,6 +793,44 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
772 return 0; 793 return 0;
773} 794}
774 795
796
797static int skl_tplg_module_add_deferred_bind(struct skl *skl,
798 struct skl_module_cfg *src, struct skl_module_cfg *dst)
799{
800 struct skl_module_deferred_bind *m_list, *modules;
801 int i;
802
803 /* only supported for module with static pin connection */
804 for (i = 0; i < dst->max_in_queue; i++) {
805 struct skl_module_pin *pin = &dst->m_in_pin[i];
806
807 if (pin->is_dynamic)
808 continue;
809
810 if ((pin->id.module_id == src->id.module_id) &&
811 (pin->id.instance_id == src->id.instance_id)) {
812
813 if (!list_empty(&skl->bind_list)) {
814 list_for_each_entry(modules, &skl->bind_list, node) {
815 if (modules->src == src && modules->dst == dst)
816 return 0;
817 }
818 }
819
820 m_list = kzalloc(sizeof(*m_list), GFP_KERNEL);
821 if (!m_list)
822 return -ENOMEM;
823
824 m_list->src = src;
825 m_list->dst = dst;
826
827 list_add(&m_list->node, &skl->bind_list);
828 }
829 }
830
831 return 0;
832}
833
775static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, 834static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
776 struct skl *skl, 835 struct skl *skl,
777 struct snd_soc_dapm_widget *src_w, 836 struct snd_soc_dapm_widget *src_w,
@@ -806,6 +865,28 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
806 sink = p->sink; 865 sink = p->sink;
807 sink_mconfig = sink->priv; 866 sink_mconfig = sink->priv;
808 867
868 /*
869 * Modules other than PGA leaf can be connected
870 * directly or via switch to a module in another
871 * pipeline. EX: reference path
872 * when the path is enabled, the dst module that needs
873 * to be bound may not be initialized. if the module is
874 * not initialized, add these modules in the deferred
875 * bind list and when the dst module is initialised,
876 * bind this module to the dst_module in deferred list.
877 */
878 if (((src_mconfig->m_state == SKL_MODULE_INIT_DONE)
879 && (sink_mconfig->m_state == SKL_MODULE_UNINIT))) {
880
881 ret = skl_tplg_module_add_deferred_bind(skl,
882 src_mconfig, sink_mconfig);
883
884 if (ret < 0)
885 return ret;
886
887 }
888
889
809 if (src_mconfig->m_state == SKL_MODULE_UNINIT || 890 if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
810 sink_mconfig->m_state == SKL_MODULE_UNINIT) 891 sink_mconfig->m_state == SKL_MODULE_UNINIT)
811 continue; 892 continue;
@@ -985,15 +1066,6 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
985 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; 1066 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
986 if (!src_mconfig) 1067 if (!src_mconfig)
987 continue; 1068 continue;
988 /*
989 * If path_found == 1, that means pmd for source
990 * pipe has not occurred, source is connected to
991 * some other sink. so its responsibility of sink
992 * to unbind itself from source.
993 */
994 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
995 if (ret < 0)
996 return ret;
997 1069
998 ret = skl_unbind_modules(ctx, 1070 ret = skl_unbind_modules(ctx,
999 src_mconfig, sink_mconfig); 1071 src_mconfig, sink_mconfig);
@@ -1019,6 +1091,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1019 struct skl_module_cfg *src_module = NULL, *dst_module; 1091 struct skl_module_cfg *src_module = NULL, *dst_module;
1020 struct skl_sst *ctx = skl->skl_sst; 1092 struct skl_sst *ctx = skl->skl_sst;
1021 struct skl_pipe *s_pipe = mconfig->pipe; 1093 struct skl_pipe *s_pipe = mconfig->pipe;
1094 struct skl_module_deferred_bind *modules, *tmp;
1022 1095
1023 if (s_pipe->state == SKL_PIPE_INVALID) 1096 if (s_pipe->state == SKL_PIPE_INVALID)
1024 return -EINVAL; 1097 return -EINVAL;
@@ -1027,6 +1100,35 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1027 skl_tplg_free_pipe_mem(skl, mconfig); 1100 skl_tplg_free_pipe_mem(skl, mconfig);
1028 1101
1029 list_for_each_entry(w_module, &s_pipe->w_list, node) { 1102 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1103 if (list_empty(&skl->bind_list))
1104 break;
1105
1106 src_module = w_module->w->priv;
1107
1108 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
1109 /*
1110 * When the destination module is deleted, Unbind the
1111 * modules from deferred bind list.
1112 */
1113 if (modules->dst == src_module) {
1114 skl_unbind_modules(ctx, modules->src,
1115 modules->dst);
1116 }
1117
1118 /*
1119 * When the source module is deleted, remove this entry
1120 * from the deferred bind list.
1121 */
1122 if (modules->src == src_module) {
1123 list_del(&modules->node);
1124 modules->src = NULL;
1125 modules->dst = NULL;
1126 kfree(modules);
1127 }
1128 }
1129 }
1130
1131 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1030 dst_module = w_module->w->priv; 1132 dst_module = w_module->w->priv;
1031 1133
1032 if (mconfig->m_state >= SKL_MODULE_INIT_DONE) 1134 if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
@@ -1042,6 +1144,11 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1042 1144
1043 skl_delete_pipe(ctx, mconfig->pipe); 1145 skl_delete_pipe(ctx, mconfig->pipe);
1044 1146
1147 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1148 src_module = w_module->w->priv;
1149 src_module->m_state = SKL_MODULE_UNINIT;
1150 }
1151
1045 return skl_tplg_unload_pipe_modules(ctx, s_pipe); 1152 return skl_tplg_unload_pipe_modules(ctx, s_pipe);
1046} 1153}
1047 1154
@@ -1083,36 +1190,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1083} 1190}
1084 1191
1085/* 1192/*
1086 * In modelling, we assume there will be ONLY one mixer in a pipeline. If
1087 * mixer is not required then it is treated as static mixer aka vmixer with
1088 * a hard path to source module
1089 * So we don't need to check if source is started or not as hard path puts
1090 * dependency on each other
1091 */
1092static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
1093 struct snd_kcontrol *k, int event)
1094{
1095 struct snd_soc_dapm_context *dapm = w->dapm;
1096 struct skl *skl = get_skl_ctx(dapm->dev);
1097
1098 switch (event) {
1099 case SND_SOC_DAPM_PRE_PMU:
1100 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
1101
1102 case SND_SOC_DAPM_POST_PMU:
1103 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
1104
1105 case SND_SOC_DAPM_PRE_PMD:
1106 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
1107
1108 case SND_SOC_DAPM_POST_PMD:
1109 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
1110 }
1111
1112 return 0;
1113}
1114
1115/*
1116 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a 1193 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
1117 * second one is required that is created as another pipe entity. 1194 * second one is required that is created as another pipe entity.
1118 * The mixer is responsible for pipe management and represent a pipeline 1195 * The mixer is responsible for pipe management and represent a pipeline
@@ -1252,10 +1329,12 @@ static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg,
1252 case SKL_DEVICE_HDALINK: 1329 case SKL_DEVICE_HDALINK:
1253 pipe->p_params->link_dma_id = params->link_dma_id; 1330 pipe->p_params->link_dma_id = params->link_dma_id;
1254 pipe->p_params->link_index = params->link_index; 1331 pipe->p_params->link_index = params->link_index;
1332 pipe->p_params->link_bps = params->link_bps;
1255 break; 1333 break;
1256 1334
1257 case SKL_DEVICE_HDAHOST: 1335 case SKL_DEVICE_HDAHOST:
1258 pipe->p_params->host_dma_id = params->host_dma_id; 1336 pipe->p_params->host_dma_id = params->host_dma_id;
1337 pipe->p_params->host_bps = params->host_bps;
1259 break; 1338 break;
1260 1339
1261 default: 1340 default:
@@ -1578,7 +1657,7 @@ int skl_tplg_be_update_params(struct snd_soc_dai *dai,
1578 1657
1579static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = { 1658static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1580 {SKL_MIXER_EVENT, skl_tplg_mixer_event}, 1659 {SKL_MIXER_EVENT, skl_tplg_mixer_event},
1581 {SKL_VMIXER_EVENT, skl_tplg_vmixer_event}, 1660 {SKL_VMIXER_EVENT, skl_tplg_mixer_event},
1582 {SKL_PGA_EVENT, skl_tplg_pga_event}, 1661 {SKL_PGA_EVENT, skl_tplg_pga_event},
1583}; 1662};
1584 1663
@@ -1632,7 +1711,7 @@ static int skl_tplg_add_pipe(struct device *dev,
1632 list_for_each_entry(ppl, &skl->ppl_list, node) { 1711 list_for_each_entry(ppl, &skl->ppl_list, node) {
1633 if (ppl->pipe->ppl_id == tkn_elem->value) { 1712 if (ppl->pipe->ppl_id == tkn_elem->value) {
1634 mconfig->pipe = ppl->pipe; 1713 mconfig->pipe = ppl->pipe;
1635 return EEXIST; 1714 return -EEXIST;
1636 } 1715 }
1637 } 1716 }
1638 1717
@@ -1924,11 +2003,13 @@ static int skl_tplg_get_token(struct device *dev,
1924 ret = skl_tplg_add_pipe(dev, 2003 ret = skl_tplg_add_pipe(dev,
1925 mconfig, skl, tkn_elem); 2004 mconfig, skl, tkn_elem);
1926 2005
1927 if (ret < 0) 2006 if (ret < 0) {
2007 if (ret == -EEXIST) {
2008 is_pipe_exists = 1;
2009 break;
2010 }
1928 return is_pipe_exists; 2011 return is_pipe_exists;
1929 2012 }
1930 if (ret == EEXIST)
1931 is_pipe_exists = 1;
1932 2013
1933 break; 2014 break;
1934 2015
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index fefab0e99a3b..cc64d6bdb4f6 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -257,6 +257,8 @@ struct skl_pipe_params {
257 snd_pcm_format_t format; 257 snd_pcm_format_t format;
258 int link_index; 258 int link_index;
259 int stream; 259 int stream;
260 unsigned int host_bps;
261 unsigned int link_bps;
260}; 262};
261 263
262struct skl_pipe { 264struct skl_pipe {
@@ -334,17 +336,10 @@ struct skl_pipeline {
334 struct list_head node; 336 struct list_head node;
335}; 337};
336 338
337#define SKL_LIB_NAME_LENGTH 128 339struct skl_module_deferred_bind {
338#define SKL_MAX_LIB 16 340 struct skl_module_cfg *src;
339 341 struct skl_module_cfg *dst;
340struct skl_lib_info { 342 struct list_head node;
341 char name[SKL_LIB_NAME_LENGTH];
342 const struct firmware *fw;
343};
344
345struct skl_manifest {
346 u32 lib_count;
347 struct skl_lib_info lib[SKL_MAX_LIB];
348}; 343};
349 344
350static inline struct skl *get_skl_ctx(struct device *dev) 345static inline struct skl *get_skl_ctx(struct device *dev)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 0c57d4eaae3a..6df3b317a476 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -512,7 +512,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
512 struct hdac_bus *bus = ebus_to_hbus(ebus); 512 struct hdac_bus *bus = ebus_to_hbus(ebus);
513 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | 513 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
514 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; 514 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
515 unsigned int res; 515 unsigned int res = -1;
516 516
517 mutex_lock(&bus->cmd_mutex); 517 mutex_lock(&bus->cmd_mutex);
518 snd_hdac_bus_send_cmd(bus, cmd); 518 snd_hdac_bus_send_cmd(bus, cmd);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index bbef77d2b917..a454f6035f3e 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -27,27 +27,6 @@
27 27
28#define SKL_SUSPEND_DELAY 2000 28#define SKL_SUSPEND_DELAY 2000
29 29
30/* Vendor Specific Registers */
31#define AZX_REG_VS_EM1 0x1000
32#define AZX_REG_VS_INRC 0x1004
33#define AZX_REG_VS_OUTRC 0x1008
34#define AZX_REG_VS_FIFOTRK 0x100C
35#define AZX_REG_VS_FIFOTRK2 0x1010
36#define AZX_REG_VS_EM2 0x1030
37#define AZX_REG_VS_EM3L 0x1038
38#define AZX_REG_VS_EM3U 0x103C
39#define AZX_REG_VS_EM4L 0x1040
40#define AZX_REG_VS_EM4U 0x1044
41#define AZX_REG_VS_LTRC 0x1048
42#define AZX_REG_VS_D0I3C 0x104A
43#define AZX_REG_VS_PCE 0x104B
44#define AZX_REG_VS_L2MAGC 0x1050
45#define AZX_REG_VS_L2LAHPT 0x1054
46#define AZX_REG_VS_SDXDPIB_XBASE 0x1084
47#define AZX_REG_VS_SDXDPIB_XINTERVAL 0x20
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50
51#define AZX_PCIREG_PGCTL 0x44 30#define AZX_PCIREG_PGCTL 0x44
52#define AZX_PGCTL_LSRMD_MASK (1 << 4) 31#define AZX_PGCTL_LSRMD_MASK (1 << 4)
53#define AZX_PCIREG_CGCTL 0x48 32#define AZX_PCIREG_CGCTL 0x48
@@ -77,6 +56,7 @@ struct skl {
77 56
78 struct skl_dsp_resource resource; 57 struct skl_dsp_resource resource;
79 struct list_head ppl_list; 58 struct list_head ppl_list;
59 struct list_head bind_list;
80 60
81 const char *fw_name; 61 const char *fw_name;
82 char tplg_name[64]; 62 char tplg_name[64];
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index d7013bde6f45..5c68797f36c4 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -22,6 +22,16 @@ config SND_SOC_MT2701_CS42448
22 Select Y if you have such device. 22 Select Y if you have such device.
23 If unsure select "N". 23 If unsure select "N".
24 24
25config SND_SOC_MT2701_WM8960
26 tristate "ASoc Audio driver for MT2701 with WM8960 codec"
27 depends on SND_SOC_MT2701 && I2C
28 select SND_SOC_WM8960
29 help
30 This adds ASoC driver for Mediatek MT2701 boards
31 with the WM8960 codecs.
32 Select Y if you have such device.
33 If unsure select "N".
34
25config SND_SOC_MT8173 35config SND_SOC_MT8173
26 tristate "ASoC support for Mediatek MT8173 chip" 36 tristate "ASoC support for Mediatek MT8173 chip"
27 depends on ARCH_MEDIATEK 37 depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/mt2701/Makefile b/sound/soc/mediatek/mt2701/Makefile
index 31c3d04d4942..c91deb6aca21 100644
--- a/sound/soc/mediatek/mt2701/Makefile
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
17 17
18# machine driver 18# machine driver
19obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o 19obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
20obj-$(CONFIG_SND_SOC_MT2701_WM8960) += mt2701-wm8960.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index c7fa3e663463..bc5d4db94de6 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -604,6 +604,22 @@ static struct snd_soc_dai_ops mt2701_btmrg_ops = {
604static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { 604static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
605 /* FE DAIs: memory intefaces to CPU */ 605 /* FE DAIs: memory intefaces to CPU */
606 { 606 {
607 .name = "PCMO0",
608 .id = MT2701_MEMIF_DL1,
609 .suspend = mtk_afe_dai_suspend,
610 .resume = mtk_afe_dai_resume,
611 .playback = {
612 .stream_name = "DL1",
613 .channels_min = 1,
614 .channels_max = 2,
615 .rates = SNDRV_PCM_RATE_8000_192000,
616 .formats = (SNDRV_PCM_FMTBIT_S16_LE
617 | SNDRV_PCM_FMTBIT_S24_LE
618 | SNDRV_PCM_FMTBIT_S32_LE)
619 },
620 .ops = &mt2701_single_memif_dai_ops,
621 },
622 {
607 .name = "PCM_multi", 623 .name = "PCM_multi",
608 .id = MT2701_MEMIF_DLM, 624 .id = MT2701_MEMIF_DLM,
609 .suspend = mtk_afe_dai_suspend, 625 .suspend = mtk_afe_dai_suspend,
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
index 1e7e8d43fd8a..aa5b31b121e3 100644
--- a/sound/soc/mediatek/mt2701/mt2701-cs42448.c
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -129,7 +129,7 @@ static int mt2701_cs42448_fe_ops_startup(struct snd_pcm_substream *substream)
129 return 0; 129 return 0;
130} 130}
131 131
132static struct snd_soc_ops mt2701_cs42448_48k_fe_ops = { 132static const struct snd_soc_ops mt2701_cs42448_48k_fe_ops = {
133 .startup = mt2701_cs42448_fe_ops_startup, 133 .startup = mt2701_cs42448_fe_ops_startup,
134}; 134};
135 135
diff --git a/sound/soc/mediatek/mt2701/mt2701-wm8960.c b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
new file mode 100644
index 000000000000..a08ce2323bdc
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
@@ -0,0 +1,176 @@
1/*
2 * mt2701-wm8960.c -- MT2701 WM8960 ALSA SoC machine driver
3 *
4 * Copyright (c) 2017 MediaTek Inc.
5 * Author: Ryder Lee <ryder.lee@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <sound/soc.h>
19
20#include "mt2701-afe-common.h"
21
22static const struct snd_soc_dapm_widget mt2701_wm8960_widgets[] = {
23 SND_SOC_DAPM_HP("Headphone", NULL),
24 SND_SOC_DAPM_MIC("AMIC", NULL),
25};
26
27static const struct snd_kcontrol_new mt2701_wm8960_controls[] = {
28 SOC_DAPM_PIN_SWITCH("Headphone"),
29 SOC_DAPM_PIN_SWITCH("AMIC"),
30};
31
32static int mt2701_wm8960_be_ops_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params)
34{
35 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
38 unsigned int mclk_rate;
39 unsigned int rate = params_rate(params);
40 unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
41 unsigned int div_bck_over_lrck = 64;
42
43 mclk_rate = rate * div_bck_over_lrck * div_mclk_over_bck;
44
45 snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate, SND_SOC_CLOCK_OUT);
46 snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate, SND_SOC_CLOCK_IN);
47
48 return 0;
49}
50
51static struct snd_soc_ops mt2701_wm8960_be_ops = {
52 .hw_params = mt2701_wm8960_be_ops_hw_params
53};
54
55static struct snd_soc_dai_link mt2701_wm8960_dai_links[] = {
56 /* FE */
57 {
58 .name = "wm8960-playback",
59 .stream_name = "wm8960-playback",
60 .cpu_dai_name = "PCMO0",
61 .codec_name = "snd-soc-dummy",
62 .codec_dai_name = "snd-soc-dummy-dai",
63 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
64 SND_SOC_DPCM_TRIGGER_POST},
65 .dynamic = 1,
66 .dpcm_playback = 1,
67 },
68 {
69 .name = "wm8960-capture",
70 .stream_name = "wm8960-capture",
71 .cpu_dai_name = "PCM0",
72 .codec_name = "snd-soc-dummy",
73 .codec_dai_name = "snd-soc-dummy-dai",
74 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
75 SND_SOC_DPCM_TRIGGER_POST},
76 .dynamic = 1,
77 .dpcm_capture = 1,
78 },
79 /* BE */
80 {
81 .name = "wm8960-codec",
82 .cpu_dai_name = "I2S0",
83 .no_pcm = 1,
84 .codec_dai_name = "wm8960-hifi",
85 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
86 | SND_SOC_DAIFMT_GATED,
87 .ops = &mt2701_wm8960_be_ops,
88 .dpcm_playback = 1,
89 .dpcm_capture = 1,
90 },
91};
92
93static struct snd_soc_card mt2701_wm8960_card = {
94 .name = "mt2701-wm8960",
95 .owner = THIS_MODULE,
96 .dai_link = mt2701_wm8960_dai_links,
97 .num_links = ARRAY_SIZE(mt2701_wm8960_dai_links),
98 .controls = mt2701_wm8960_controls,
99 .num_controls = ARRAY_SIZE(mt2701_wm8960_controls),
100 .dapm_widgets = mt2701_wm8960_widgets,
101 .num_dapm_widgets = ARRAY_SIZE(mt2701_wm8960_widgets),
102};
103
104static int mt2701_wm8960_machine_probe(struct platform_device *pdev)
105{
106 struct snd_soc_card *card = &mt2701_wm8960_card;
107 struct device_node *platform_node, *codec_node;
108 int ret, i;
109
110 platform_node = of_parse_phandle(pdev->dev.of_node,
111 "mediatek,platform", 0);
112 if (!platform_node) {
113 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
114 return -EINVAL;
115 }
116 for (i = 0; i < card->num_links; i++) {
117 if (mt2701_wm8960_dai_links[i].platform_name)
118 continue;
119 mt2701_wm8960_dai_links[i].platform_of_node = platform_node;
120 }
121
122 card->dev = &pdev->dev;
123
124 codec_node = of_parse_phandle(pdev->dev.of_node,
125 "mediatek,audio-codec", 0);
126 if (!codec_node) {
127 dev_err(&pdev->dev,
128 "Property 'audio-codec' missing or invalid\n");
129 return -EINVAL;
130 }
131 for (i = 0; i < card->num_links; i++) {
132 if (mt2701_wm8960_dai_links[i].codec_name)
133 continue;
134 mt2701_wm8960_dai_links[i].codec_of_node = codec_node;
135 }
136
137 ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
138 if (ret) {
139 dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
140 return ret;
141 }
142
143 ret = devm_snd_soc_register_card(&pdev->dev, card);
144 if (ret)
145 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
146 __func__, ret);
147
148 return ret;
149}
150
151#ifdef CONFIG_OF
152static const struct of_device_id mt2701_wm8960_machine_dt_match[] = {
153 {.compatible = "mediatek,mt2701-wm8960-machine",},
154 {}
155};
156#endif
157
158static struct platform_driver mt2701_wm8960_machine = {
159 .driver = {
160 .name = "mt2701-wm8960",
161 .owner = THIS_MODULE,
162#ifdef CONFIG_OF
163 .of_match_table = mt2701_wm8960_machine_dt_match,
164#endif
165 },
166 .probe = mt2701_wm8960_machine_probe,
167};
168
169module_platform_driver(mt2701_wm8960_machine);
170
171/* Module information */
172MODULE_DESCRIPTION("MT2701 WM8960 ALSA SoC machine driver");
173MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
174MODULE_LICENSE("GPL v2");
175MODULE_ALIAS("mt2701 wm8960 soc card");
176
diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 46c8e6ae00b4..e0c2b23ec711 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -67,7 +67,7 @@ static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream,
67 SND_SOC_CLOCK_IN); 67 SND_SOC_CLOCK_IN);
68} 68}
69 69
70static struct snd_soc_ops mt8173_max98090_ops = { 70static const struct snd_soc_ops mt8173_max98090_ops = {
71 .hw_params = mt8173_max98090_hw_params, 71 .hw_params = mt8173_max98090_hw_params,
72}; 72};
73 73
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 467f7049a288..5e383eb456a4 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -75,7 +75,7 @@ static int mt8173_rt5650_rt5514_hw_params(struct snd_pcm_substream *substream,
75 return 0; 75 return 0;
76} 76}
77 77
78static struct snd_soc_ops mt8173_rt5650_rt5514_ops = { 78static const struct snd_soc_ops mt8173_rt5650_rt5514_ops = {
79 .hw_params = mt8173_rt5650_rt5514_hw_params, 79 .hw_params = mt8173_rt5650_rt5514_hw_params,
80}; 80};
81 81
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 1b8b2a778845..fed1f15a39c2 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -79,7 +79,7 @@ static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream,
79 return 0; 79 return 0;
80} 80}
81 81
82static struct snd_soc_ops mt8173_rt5650_rt5676_ops = { 82static const struct snd_soc_ops mt8173_rt5650_rt5676_ops = {
83 .hw_params = mt8173_rt5650_rt5676_hw_params, 83 .hw_params = mt8173_rt5650_rt5676_hw_params,
84}; 84};
85 85
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index ba65f4157a7e..a78470839b65 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -105,7 +105,7 @@ static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
105 return 0; 105 return 0;
106} 106}
107 107
108static struct snd_soc_ops mt8173_rt5650_ops = { 108static const struct snd_soc_ops mt8173_rt5650_ops = {
109 .hw_params = mt8173_rt5650_hw_params, 109 .hw_params = mt8173_rt5650_hw_params,
110}; 110};
111 111
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 25a33e9d417a..d5651026ec10 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -49,7 +49,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
49 return ret; 49 return ret;
50} 50}
51 51
52static struct snd_soc_ops am3517evm_ops = { 52static const struct snd_soc_ops am3517evm_ops = {
53 .hw_params = am3517evm_hw_params, 53 .hw_params = am3517evm_hw_params,
54}; 54};
55 55
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index fdecb7043174..71e5f31fa306 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -124,7 +124,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
124 return err; 124 return err;
125} 125}
126 126
127static struct snd_soc_ops n810_ops = { 127static const struct snd_soc_ops n810_ops = {
128 .startup = n810_startup, 128 .startup = n810_startup,
129 .hw_params = n810_hw_params, 129 .hw_params = n810_hw_params,
130 .shutdown = n810_shutdown, 130 .shutdown = n810_shutdown,
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 89fe95e877db..614b18d2f631 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -70,7 +70,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
70 return ret; 70 return ret;
71} 71}
72 72
73static struct snd_soc_ops omap_abe_ops = { 73static const struct snd_soc_ops omap_abe_ops = {
74 .hw_params = omap_abe_hw_params, 74 .hw_params = omap_abe_hw_params,
75}; 75};
76 76
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index 743131473056..a24b0dedabb9 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -73,7 +73,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
73 return snd_soc_runtime_set_dai_fmt(rtd, fmt); 73 return snd_soc_runtime_set_dai_fmt(rtd, fmt);
74} 74}
75 75
76static struct snd_soc_ops omap_twl4030_ops = { 76static const struct snd_soc_ops omap_twl4030_ops = {
77 .hw_params = omap_twl4030_hw_params, 77 .hw_params = omap_twl4030_hw_params,
78}; 78};
79 79
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 732e749a1f8e..4e3de712159c 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -184,7 +184,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
184 return 0; 184 return 0;
185} 185}
186 186
187static struct snd_soc_ops omap3pandora_ops = { 187static const struct snd_soc_ops omap3pandora_ops = {
188 .hw_params = omap3pandora_hw_params, 188 .hw_params = omap3pandora_hw_params,
189}; 189};
190 190
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index aa4053bf6710..e4096779ca05 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -68,7 +68,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
68 return err; 68 return err;
69} 69}
70 70
71static struct snd_soc_ops osk_ops = { 71static const struct snd_soc_ops osk_ops = {
72 .startup = osk_startup, 72 .startup = osk_startup,
73 .hw_params = osk_hw_params, 73 .hw_params = osk_hw_params,
74 .shutdown = osk_shutdown, 74 .shutdown = osk_shutdown,
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index a76845748a10..3aeb65feaea1 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -123,7 +123,7 @@ static int rx51_hw_params(struct snd_pcm_substream *substream,
123 SND_SOC_CLOCK_IN); 123 SND_SOC_CLOCK_IN);
124} 124}
125 125
126static struct snd_soc_ops rx51_ops = { 126static const struct snd_soc_ops rx51_ops = {
127 .startup = rx51_startup, 127 .startup = rx51_startup,
128 .hw_params = rx51_hw_params, 128 .hw_params = rx51_hw_params,
129}; 129};
@@ -433,10 +433,9 @@ static int rx51_soc_probe(struct platform_device *pdev)
433 } 433 }
434 434
435 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 435 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
436 if (pdata == NULL) { 436 if (pdata == NULL)
437 dev_err(card->dev, "failed to create private data\n");
438 return -ENOMEM; 437 return -ENOMEM;
439 } 438
440 snd_soc_card_set_drvdata(card, pdata); 439 snd_soc_card_set_drvdata(card, pdata);
441 440
442 pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, 441 pdata->tvout_selection_gpio = devm_gpiod_get(card->dev,
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index b6cb9950f05d..9a3f5b799720 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -74,7 +74,7 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
74} 74}
75 75
76/* machine stream operations */ 76/* machine stream operations */
77static struct snd_soc_ops brownstone_ops = { 77static const struct snd_soc_ops brownstone_ops = {
78 .hw_params = brownstone_wm8994_hw_params, 78 .hw_params = brownstone_wm8994_hw_params,
79}; 79};
80 80
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 311774e9ca46..054e0d65db9d 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -154,7 +154,7 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
154 return 0; 154 return 0;
155} 155}
156 156
157static struct snd_soc_ops corgi_ops = { 157static const struct snd_soc_ops corgi_ops = {
158 .startup = corgi_startup, 158 .startup = corgi_startup,
159 .hw_params = corgi_hw_params, 159 .hw_params = corgi_hw_params,
160 .shutdown = corgi_shutdown, 160 .shutdown = corgi_shutdown,
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index fdcd94adee7c..82bcbbb1841b 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -81,7 +81,7 @@ static struct snd_soc_dai_link e750_dai[] = {
81 .name = "AC97 Aux", 81 .name = "AC97 Aux",
82 .stream_name = "AC97 Aux", 82 .stream_name = "AC97 Aux",
83 .cpu_dai_name = "pxa2xx-ac97-aux", 83 .cpu_dai_name = "pxa2xx-ac97-aux",
84 .codec_dai_name ="wm9705-aux", 84 .codec_dai_name = "wm9705-aux",
85 .platform_name = "pxa-pcm-audio", 85 .platform_name = "pxa-pcm-audio",
86 .codec_name = "wm9705-codec", 86 .codec_name = "wm9705-codec",
87 }, 87 },
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 2df714f70ec0..1ed8aa2348f1 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -81,7 +81,7 @@ static struct snd_soc_dai_link e800_dai[] = {
81 .name = "AC97 Aux", 81 .name = "AC97 Aux",
82 .stream_name = "AC97 Aux", 82 .stream_name = "AC97 Aux",
83 .cpu_dai_name = "pxa2xx-ac97-aux", 83 .cpu_dai_name = "pxa2xx-ac97-aux",
84 .codec_dai_name ="wm9712-aux", 84 .codec_dai_name = "wm9712-aux",
85 .platform_name = "pxa-pcm-audio", 85 .platform_name = "pxa-pcm-audio",
86 .codec_name = "wm9712-codec", 86 .codec_name = "wm9712-codec",
87 }, 87 },
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index 6f2020f6c8d3..e046770ce70e 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -43,7 +43,7 @@ static struct snd_soc_dai_link em_x270_dai[] = {
43 .name = "AC97 Aux", 43 .name = "AC97 Aux",
44 .stream_name = "AC97 Aux", 44 .stream_name = "AC97 Aux",
45 .cpu_dai_name = "pxa2xx-ac97-aux", 45 .cpu_dai_name = "pxa2xx-ac97-aux",
46 .codec_dai_name ="wm9712-aux", 46 .codec_dai_name = "wm9712-aux",
47 .platform_name = "pxa-pcm-audio", 47 .platform_name = "pxa-pcm-audio",
48 .codec_name = "wm9712-codec", 48 .codec_name = "wm9712-codec",
49 }, 49 },
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 85483049b916..a9ac881c2e14 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -79,7 +79,7 @@ static int hx4700_hw_params(struct snd_pcm_substream *substream,
79 return 0; 79 return 0;
80} 80}
81 81
82static struct snd_soc_ops hx4700_ops = { 82static const struct snd_soc_ops hx4700_ops = {
83 .hw_params = hx4700_hw_params, 83 .hw_params = hx4700_hw_params,
84}; 84};
85 85
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 9d0e40771ef5..78475376f971 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -42,7 +42,7 @@ static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
42 return ret; 42 return ret;
43} 43}
44 44
45static struct snd_soc_ops imote2_asoc_ops = { 45static const struct snd_soc_ops imote2_asoc_ops = {
46 .hw_params = imote2_asoc_hw_params, 46 .hw_params = imote2_asoc_hw_params,
47}; 47};
48 48
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 2d4d4455fe87..2fc012b06c43 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -255,12 +255,12 @@ static int magician_capture_hw_params(struct snd_pcm_substream *substream,
255 return 0; 255 return 0;
256} 256}
257 257
258static struct snd_soc_ops magician_capture_ops = { 258static const struct snd_soc_ops magician_capture_ops = {
259 .startup = magician_startup, 259 .startup = magician_startup,
260 .hw_params = magician_capture_hw_params, 260 .hw_params = magician_capture_hw_params,
261}; 261};
262 262
263static struct snd_soc_ops magician_playback_ops = { 263static const struct snd_soc_ops magician_playback_ops = {
264 .startup = magician_startup, 264 .startup = magician_startup,
265 .hw_params = magician_playback_hw_params, 265 .hw_params = magician_playback_hw_params,
266}; 266};
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 8760a6687885..c4c6fbedc723 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -157,7 +157,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
157 .name = "AC97 Aux", 157 .name = "AC97 Aux",
158 .stream_name = "AC97 Aux", 158 .stream_name = "AC97 Aux",
159 .cpu_dai_name = "pxa2xx-ac97-aux", 159 .cpu_dai_name = "pxa2xx-ac97-aux",
160 .codec_dai_name ="wm9713-aux", 160 .codec_dai_name = "wm9713-aux",
161 .codec_name = "wm9713-codec", 161 .codec_name = "wm9713-codec",
162 .platform_name = "pxa-pcm-audio", 162 .platform_name = "pxa-pcm-audio",
163 .ops = &mioa701_ops, 163 .ops = &mioa701_ops,
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 96df9b2d8fc4..5b5f1a442891 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -166,7 +166,6 @@ static void mmp_pcm_free_dma_buffers(struct snd_pcm *pcm)
166 buf->area = NULL; 166 buf->area = NULL;
167 } 167 }
168 168
169 return;
170} 169}
171 170
172static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream, 171static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index ca8b23f8c525..9cc35012e6e5 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -119,7 +119,6 @@ static void mmp_sspa_shutdown(struct snd_pcm_substream *substream,
119 clk_disable(priv->sspa->clk); 119 clk_disable(priv->sspa->clk);
120 clk_disable(priv->sysclk); 120 clk_disable(priv->sysclk);
121 121
122 return;
123} 122}
124 123
125/* 124/*
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a879aba0691f..b6693f32fc02 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -129,7 +129,7 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
129 return 0; 129 return 0;
130} 130}
131 131
132static struct snd_soc_ops poodle_ops = { 132static const struct snd_soc_ops poodle_ops = {
133 .startup = poodle_startup, 133 .startup = poodle_startup,
134 .hw_params = poodle_hw_params, 134 .hw_params = poodle_hw_params,
135 .shutdown = poodle_shutdown, 135 .shutdown = poodle_shutdown,
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3cad990dad2c..0291c7cb64eb 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -354,6 +354,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
354 if (ssp->type == PXA3xx_SSP) { 354 if (ssp->type == PXA3xx_SSP) {
355 u32 val; 355 u32 val;
356 u64 tmp = 19968; 356 u64 tmp = 19968;
357
357 tmp *= 1000000; 358 tmp *= 1000000;
358 do_div(tmp, freq_out); 359 do_div(tmp, freq_out);
359 val = tmp; 360 val = tmp;
@@ -590,13 +591,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
590 591
591 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) { 592 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
592 /* This is a special case where the bitclk is 64fs 593 /* This is a special case where the bitclk is 64fs
593 * and we're not dealing with 2*32 bits of audio 594 * and we're not dealing with 2*32 bits of audio
594 * samples. 595 * samples.
595 * 596 *
596 * The SSP values used for that are all found out by 597 * The SSP values used for that are all found out by
597 * trying and failing a lot; some of the registers 598 * trying and failing a lot; some of the registers
598 * needed for that mode are only available on PXA3xx. 599 * needed for that mode are only available on PXA3xx.
599 */ 600 */
600 if (ssp->type != PXA3xx_SSP) 601 if (ssp->type != PXA3xx_SSP)
601 return -EINVAL; 602 return -EINVAL;
602 603
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 2e2fb1838ec2..f49bf02e5ec2 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -140,9 +140,8 @@ static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
140{ 140{
141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
142 return -ENODEV; 142 return -ENODEV;
143 else 143 snd_soc_dai_set_dma_data(cpu_dai, substream,
144 snd_soc_dai_set_dma_data(cpu_dai, substream, 144 &pxa2xx_ac97_pcm_mic_mono_in);
145 &pxa2xx_ac97_pcm_mic_mono_in);
146 145
147 return 0; 146 return 0;
148} 147}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 0389cf7b4b1e..3fb60baf6eab 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -46,10 +46,10 @@
46#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ 46#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
47#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ 47#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
48#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ 48#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
49#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ 49#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
50#define SACR0_ENB (1 << 0) /* Enable I2S Link */ 50#define SACR0_ENB (1 << 0) /* Enable I2S Link */
51#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ 51#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
52#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ 52#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
53#define SACR1_DREC (1 << 3) /* Disable Recording Function */ 53#define SACR1_DREC (1 << 3) /* Disable Recording Function */
54#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ 54#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
55 55
@@ -60,7 +60,7 @@
60#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ 60#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
61#define SASR0_BSY (1 << 2) /* I2S Busy */ 61#define SASR0_BSY (1 << 2) /* I2S Busy */
62#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ 62#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
63#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ 63#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
64 64
65#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ 65#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
66#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ 66#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
@@ -119,7 +119,7 @@ static int pxa_i2s_wait(void)
119 int i; 119 int i;
120 120
121 /* flush the Rx FIFO */ 121 /* flush the Rx FIFO */
122 for(i = 0; i < 16; i++) 122 for (i = 0; i < 16; i++)
123 SADR; 123 SADR;
124 return 0; 124 return 0;
125} 125}
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 410d48b93031..b51d7a0755d5 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -85,7 +85,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
85} 85}
86 86
87static struct snd_soc_platform_driver pxa2xx_soc_platform = { 87static struct snd_soc_platform_driver pxa2xx_soc_platform = {
88 .ops = &pxa2xx_pcm_ops, 88 .ops = &pxa2xx_pcm_ops,
89 .pcm_new = pxa2xx_soc_pcm_new, 89 .pcm_new = pxa2xx_soc_pcm_new,
90 .pcm_free = pxa2xx_pcm_free_dma_buffers, 90 .pcm_free = pxa2xx_pcm_free_dma_buffers,
91}; 91};
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 552b763005ed..111a907c4eb9 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -132,7 +132,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct snd_soc_ops raumfeld_cs4270_ops = { 135static const struct snd_soc_ops raumfeld_cs4270_ops = {
136 .startup = raumfeld_cs4270_startup, 136 .startup = raumfeld_cs4270_startup,
137 .shutdown = raumfeld_cs4270_shutdown, 137 .shutdown = raumfeld_cs4270_shutdown,
138 .hw_params = raumfeld_cs4270_hw_params, 138 .hw_params = raumfeld_cs4270_hw_params,
@@ -228,14 +228,12 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
228 .codec_name = "spi0.0", \ 228 .codec_name = "spi0.0", \
229} 229}
230 230
231static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = 231static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = {
232{
233 DAI_LINK_CS4270, 232 DAI_LINK_CS4270,
234 DAI_LINK_AK4104, 233 DAI_LINK_AK4104,
235}; 234};
236 235
237static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = 236static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = {
238{
239 DAI_LINK_CS4270, 237 DAI_LINK_CS4270,
240}; 238};
241 239
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 07d77cddac60..1671da648e95 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -156,7 +156,7 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
156 return 0; 156 return 0;
157} 157}
158 158
159static struct snd_soc_ops spitz_ops = { 159static const struct snd_soc_ops spitz_ops = {
160 .startup = spitz_startup, 160 .startup = spitz_startup,
161 .hw_params = spitz_hw_params, 161 .hw_params = spitz_hw_params,
162}; 162};
@@ -230,8 +230,8 @@ static const struct snd_soc_dapm_route spitz_audio_map[] = {
230 {"Headset Jack", NULL, "ROUT1"}, 230 {"Headset Jack", NULL, "ROUT1"},
231 231
232 /* ext speaker connected to LOUT2, ROUT2 */ 232 /* ext speaker connected to LOUT2, ROUT2 */
233 {"Ext Spk", NULL , "ROUT2"}, 233 {"Ext Spk", NULL, "ROUT2"},
234 {"Ext Spk", NULL , "LOUT2"}, 234 {"Ext Spk", NULL, "LOUT2"},
235 235
236 /* mic is connected to input 1 - with bias */ 236 /* mic is connected to input 1 - with bias */
237 {"LINPUT1", NULL, "Mic Bias"}, 237 {"LINPUT1", NULL, "Mic Bias"},
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index e022b2a777f6..ae9c12e1ea2a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -85,7 +85,7 @@ static int tosa_startup(struct snd_pcm_substream *substream)
85 return 0; 85 return 0;
86} 86}
87 87
88static struct snd_soc_ops tosa_ops = { 88static const struct snd_soc_ops tosa_ops = {
89 .startup = tosa_startup, 89 .startup = tosa_startup,
90}; 90};
91 91
@@ -133,7 +133,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
133static int tosa_hp_event(struct snd_soc_dapm_widget *w, 133static int tosa_hp_event(struct snd_soc_dapm_widget *w,
134 struct snd_kcontrol *k, int event) 134 struct snd_kcontrol *k, int event)
135{ 135{
136 gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0); 136 gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
137 return 0; 137 return 0;
138} 138}
139 139
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 990b1aa6d7f6..5b0eccd2b4dd 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -119,8 +119,8 @@ static const struct snd_soc_dapm_route z2_audio_map[] = {
119 {"Headphone Jack", NULL, "ROUT1"}, 119 {"Headphone Jack", NULL, "ROUT1"},
120 120
121 /* ext speaker connected to LOUT2, ROUT2 */ 121 /* ext speaker connected to LOUT2, ROUT2 */
122 {"Ext Spk", NULL , "ROUT2"}, 122 {"Ext Spk", NULL, "ROUT2"},
123 {"Ext Spk", NULL , "LOUT2"}, 123 {"Ext Spk", NULL, "LOUT2"},
124 124
125 /* mic is connected to R input 2 - with bias */ 125 /* mic is connected to R input 2 - with bias */
126 {"RINPUT2", NULL, "Mic Bias"}, 126 {"RINPUT2", NULL, "Mic Bias"},
@@ -152,7 +152,7 @@ err:
152 return ret; 152 return ret;
153} 153}
154 154
155static struct snd_soc_ops z2_ops = { 155static const struct snd_soc_ops z2_ops = {
156 .hw_params = z2_hw_params, 156 .hw_params = z2_hw_params,
157}; 157};
158 158
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 6fbcdf02c88d..ba468e560dd2 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -132,7 +132,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct snd_soc_ops zylonite_voice_ops = { 135static const struct snd_soc_ops zylonite_voice_ops = {
136 .hw_params = zylonite_voice_hw_params, 136 .hw_params = zylonite_voice_hw_params,
137}; 137};
138 138
diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
index 8aed72be3224..8a74844d99e2 100644
--- a/sound/soc/qcom/lpass-apq8016.c
+++ b/sound/soc/qcom/lpass-apq8016.c
@@ -231,6 +231,18 @@ static struct lpass_variant apq8016_data = {
231 .wrdma_channels = 2, 231 .wrdma_channels = 2,
232 .dai_driver = apq8016_lpass_cpu_dai_driver, 232 .dai_driver = apq8016_lpass_cpu_dai_driver,
233 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver), 233 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
234 .dai_osr_clk_names = (const char *[]) {
235 "mi2s-osr-clk0",
236 "mi2s-osr-clk1",
237 "mi2s-osr-clk2",
238 "mi2s-osr-clk3",
239 },
240 .dai_bit_clk_names = (const char *[]) {
241 "mi2s-bit-clk0",
242 "mi2s-bit-clk1",
243 "mi2s-bit-clk2",
244 "mi2s-bit-clk3",
245 },
234 .init = apq8016_lpass_init, 246 .init = apq8016_lpass_init,
235 .exit = apq8016_lpass_exit, 247 .exit = apq8016_lpass_exit,
236 .alloc_dma_channel = apq8016_lpass_alloc_dma_channel, 248 .alloc_dma_channel = apq8016_lpass_alloc_dma_channel,
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 5202a584e0c6..292b103abada 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -429,7 +429,6 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
429 struct lpass_variant *variant; 429 struct lpass_variant *variant;
430 struct device *dev = &pdev->dev; 430 struct device *dev = &pdev->dev;
431 const struct of_device_id *match; 431 const struct of_device_id *match;
432 char clk_name[16];
433 int ret, i, dai_id; 432 int ret, i, dai_id;
434 433
435 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0); 434 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
@@ -477,31 +476,24 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
477 476
478 for (i = 0; i < variant->num_dai; i++) { 477 for (i = 0; i < variant->num_dai; i++) {
479 dai_id = variant->dai_driver[i].id; 478 dai_id = variant->dai_driver[i].id;
480 if (variant->num_dai > 1)
481 sprintf(clk_name, "mi2s-osr-clk%d", i);
482 else
483 sprintf(clk_name, "mi2s-osr-clk");
484
485 drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev, 479 drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev,
486 clk_name); 480 variant->dai_osr_clk_names[i]);
487 if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) { 481 if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {
488 dev_warn(&pdev->dev, 482 dev_warn(&pdev->dev,
489 "error getting optional mi2s-osr-clk: %ld\n", 483 "%s() error getting optional %s: %ld\n",
484 __func__,
485 variant->dai_osr_clk_names[i],
490 PTR_ERR(drvdata->mi2s_osr_clk[dai_id])); 486 PTR_ERR(drvdata->mi2s_osr_clk[dai_id]));
491 487
492 drvdata->mi2s_osr_clk[dai_id] = NULL; 488 drvdata->mi2s_osr_clk[dai_id] = NULL;
493 } 489 }
494 490
495 if (variant->num_dai > 1)
496 sprintf(clk_name, "mi2s-bit-clk%d", i);
497 else
498 sprintf(clk_name, "mi2s-bit-clk");
499
500 drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev, 491 drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev,
501 clk_name); 492 variant->dai_bit_clk_names[i]);
502 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { 493 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
503 dev_err(&pdev->dev, 494 dev_err(&pdev->dev,
504 "error getting mi2s-bit-clk: %ld\n", 495 "error getting %s: %ld\n",
496 variant->dai_bit_clk_names[i],
505 PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); 497 PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
506 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); 498 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
507 } 499 }
diff --git a/sound/soc/qcom/lpass-ipq806x.c b/sound/soc/qcom/lpass-ipq806x.c
index 608c1a92af8a..ca1e1f2d2787 100644
--- a/sound/soc/qcom/lpass-ipq806x.c
+++ b/sound/soc/qcom/lpass-ipq806x.c
@@ -92,6 +92,12 @@ static struct lpass_variant ipq806x_data = {
92 .wrdma_channels = 4, 92 .wrdma_channels = 4,
93 .dai_driver = &ipq806x_lpass_cpu_dai_driver, 93 .dai_driver = &ipq806x_lpass_cpu_dai_driver,
94 .num_dai = 1, 94 .num_dai = 1,
95 .dai_osr_clk_names = (const char *[]) {
96 "mi2s-osr-clk",
97 },
98 .dai_bit_clk_names = (const char *[]) {
99 "mi2s-bit-clk",
100 },
95 .alloc_dma_channel = ipq806x_lpass_alloc_dma_channel, 101 .alloc_dma_channel = ipq806x_lpass_alloc_dma_channel,
96 .free_dma_channel = ipq806x_lpass_free_dma_channel, 102 .free_dma_channel = ipq806x_lpass_free_dma_channel,
97}; 103};
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 9b031352ea3c..b848db2d6c3d 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -91,6 +91,8 @@ struct lpass_variant {
91 /* SOC specific dais */ 91 /* SOC specific dais */
92 struct snd_soc_dai_driver *dai_driver; 92 struct snd_soc_dai_driver *dai_driver;
93 int num_dai; 93 int num_dai;
94 const char * const *dai_osr_clk_names;
95 const char * const *dai_bit_clk_names;
94}; 96};
95 97
96/* register the platform driver from the CPU DAI driver */ 98/* register the platform driver from the CPU DAI driver */
diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c
index b60abf322ce1..dbc53e48c52c 100644
--- a/sound/soc/rockchip/rk3288_hdmi_analog.c
+++ b/sound/soc/rockchip/rk3288_hdmi_analog.c
@@ -93,6 +93,9 @@ static int rk_hw_params(struct snd_pcm_substream *substream,
93 case 96000: 93 case 96000:
94 mclk = 12288000; 94 mclk = 12288000;
95 break; 95 break;
96 case 192000:
97 mclk = 24576000;
98 break;
96 case 11025: 99 case 11025:
97 case 22050: 100 case 22050:
98 case 44100: 101 case 44100:
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index f1f1d7959a1b..0520f5afd7cc 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -185,6 +185,14 @@ config SND_SOC_SNOW
185 Say Y if you want to add audio support for various Snow 185 Say Y if you want to add audio support for various Snow
186 boards based on Exynos5 series of SoCs. 186 boards based on Exynos5 series of SoCs.
187 187
188config SND_SOC_ODROID
189 tristate "Audio support for Odroid XU3/XU4"
190 depends on SND_SOC_SAMSUNG && I2C
191 select SND_SOC_MAX98090
192 select SND_SAMSUNG_I2S
193 help
194 Say Y here to enable audio support for the Odroid XU3/XU4.
195
188config SND_SOC_ARNDALE_RT5631_ALC5631 196config SND_SOC_ARNDALE_RT5631_ALC5631
189 tristate "Audio support for RT5631(ALC5631) on Arndale Board" 197 tristate "Audio support for RT5631(ALC5631) on Arndale Board"
190 depends on I2C 198 depends on I2C
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index b5df5e2e3d94..b6c2ee358333 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -40,6 +40,7 @@ snd-soc-tobermory-objs := tobermory.o
40snd-soc-lowland-objs := lowland.o 40snd-soc-lowland-objs := lowland.o
41snd-soc-littlemill-objs := littlemill.o 41snd-soc-littlemill-objs := littlemill.o
42snd-soc-bells-objs := bells.o 42snd-soc-bells-objs := bells.o
43snd-soc-odroid-objs := odroid.o
43snd-soc-arndale-rt5631-objs := arndale_rt5631.o 44snd-soc-arndale-rt5631-objs := arndale_rt5631.o
44snd-soc-tm2-wm5110-objs := tm2_wm5110.o 45snd-soc-tm2-wm5110-objs := tm2_wm5110.o
45 46
@@ -62,5 +63,6 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
62obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o 63obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
63obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o 64obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
64obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o 65obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
66obj-$(CONFIG_SND_SOC_ODROID) += snd-soc-odroid.o
65obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o 67obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o
66obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) += snd-soc-tm2-wm5110.o 68obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) += snd-soc-tm2-wm5110.o
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index 3dd246fa0059..34deba461ae1 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -446,7 +446,6 @@ static struct snd_soc_card bells_cards[] = {
446 }, 446 },
447}; 447};
448 448
449
450static int bells_probe(struct platform_device *pdev) 449static int bells_probe(struct platform_device *pdev)
451{ 450{
452 int ret; 451 int ret;
diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h
index 9170c311d66e..fe6914005494 100644
--- a/sound/soc/samsung/i2s-regs.h
+++ b/sound/soc/samsung/i2s-regs.h
@@ -160,5 +160,3 @@
160#define I2SSIZE_SHIFT (16) 160#define I2SSIZE_SHIFT (16)
161 161
162#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */ 162#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */
163
164
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 52a47ed292a4..af3ba4d4ccc5 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1242,7 +1242,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1242 i2s_dai_data = (struct samsung_i2s_dai_data *) 1242 i2s_dai_data = (struct samsung_i2s_dai_data *)
1243 platform_get_device_id(pdev)->driver_data; 1243 platform_get_device_id(pdev)->driver_data;
1244 1244
1245
1246 pri_dai = i2s_alloc_dai(pdev, false); 1245 pri_dai = i2s_alloc_dai(pdev, false);
1247 if (!pri_dai) { 1246 if (!pri_dai) {
1248 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); 1247 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
new file mode 100644
index 000000000000..0c0b00e40646
--- /dev/null
+++ b/sound/soc/samsung/odroid.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2017 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
10#include <linux/of.h>
11#include <linux/of_device.h>
12#include <linux/module.h>
13#include <sound/soc.h>
14#include <sound/pcm_params.h>
15#include "i2s.h"
16#include "i2s-regs.h"
17
18struct odroid_priv {
19 struct snd_soc_card card;
20 struct snd_soc_dai_link dai_link;
21
22 struct clk *pll;
23 struct clk *rclk;
24};
25
26static int odroid_card_startup(struct snd_pcm_substream *substream)
27{
28 struct snd_pcm_runtime *runtime = substream->runtime;
29
30 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
31 return 0;
32}
33
34static int odroid_card_hw_params(struct snd_pcm_substream *substream,
35 struct snd_pcm_hw_params *params)
36{
37 struct snd_soc_pcm_runtime *rtd = substream->private_data;
38 struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card);
39 unsigned int pll_freq, rclk_freq;
40 int ret;
41
42 switch (params_rate(params)) {
43 case 32000:
44 case 64000:
45 pll_freq = 131072000U;
46 break;
47 case 44100:
48 case 88200:
49 case 176400:
50 pll_freq = 180633600U;
51 break;
52 case 48000:
53 case 96000:
54 case 192000:
55 pll_freq = 196608000U;
56 break;
57 default:
58 return -EINVAL;
59 }
60
61 ret = clk_set_rate(priv->pll, pll_freq + 1);
62 if (ret < 0)
63 return ret;
64
65 rclk_freq = params_rate(params) * 256 * 4;
66
67 ret = clk_set_rate(priv->rclk, rclk_freq);
68 if (ret < 0)
69 return ret;
70
71 if (rtd->num_codecs > 1) {
72 struct snd_soc_dai *codec_dai = rtd->codec_dais[1];
73
74 ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq,
75 SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78 }
79
80 return 0;
81}
82
83static const struct snd_soc_ops odroid_card_ops = {
84 .startup = odroid_card_startup,
85 .hw_params = odroid_card_hw_params,
86};
87
88static void odroid_put_codec_of_nodes(struct snd_soc_dai_link *link)
89{
90 struct snd_soc_dai_link_component *component = link->codecs;
91 int i;
92
93 for (i = 0; i < link->num_codecs; i++, component++) {
94 if (!component->of_node)
95 break;
96 of_node_put(component->of_node);
97 }
98}
99
100static int odroid_audio_probe(struct platform_device *pdev)
101{
102 struct device *dev = &pdev->dev;
103 struct device_node *cpu, *codec;
104 struct odroid_priv *priv;
105 struct snd_soc_dai_link *link;
106 struct snd_soc_card *card;
107 int ret;
108
109 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
110 if (!priv)
111 return -ENOMEM;
112
113 card = &priv->card;
114 card->dev = dev;
115
116 card->owner = THIS_MODULE;
117 card->fully_routed = true;
118
119 snd_soc_card_set_drvdata(card, priv);
120
121 priv->pll = devm_clk_get(dev, "epll");
122 if (IS_ERR(priv->pll))
123 return PTR_ERR(priv->pll);
124
125 priv->rclk = devm_clk_get(dev, "i2s_rclk");
126 if (IS_ERR(priv->rclk))
127 return PTR_ERR(priv->rclk);
128
129 ret = snd_soc_of_parse_card_name(card, "model");
130 if (ret < 0)
131 return ret;
132
133 if (of_property_read_bool(dev->of_node, "samsung,audio-widgets")) {
134 ret = snd_soc_of_parse_audio_simple_widgets(card,
135 "samsung,audio-widgets");
136 if (ret < 0)
137 return ret;
138 }
139
140 if (of_property_read_bool(dev->of_node, "samsung,audio-routing")) {
141 ret = snd_soc_of_parse_audio_routing(card,
142 "samsung,audio-routing");
143 if (ret < 0)
144 return ret;
145 }
146
147 link = &priv->dai_link;
148
149 link->ops = &odroid_card_ops;
150 link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
151 SND_SOC_DAIFMT_CBS_CFS;
152
153 card->dai_link = &priv->dai_link;
154 card->num_links = 1;
155
156 cpu = of_get_child_by_name(dev->of_node, "cpu");
157 codec = of_get_child_by_name(dev->of_node, "codec");
158
159 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
160 if (!link->cpu_of_node) {
161 dev_err(dev, "Failed parsing cpu/sound-dai property\n");
162 return -EINVAL;
163 }
164
165 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
166 if (ret < 0)
167 goto err_put_codec_n;
168
169 link->platform_of_node = link->cpu_of_node;
170
171 link->name = "Primary";
172 link->stream_name = link->name;
173
174 ret = devm_snd_soc_register_card(dev, card);
175 if (ret < 0) {
176 dev_err(dev, "snd_soc_register_card() failed: %d\n", ret);
177 goto err_put_i2s_n;
178 }
179
180 return 0;
181
182err_put_i2s_n:
183 of_node_put(link->cpu_of_node);
184err_put_codec_n:
185 odroid_put_codec_of_nodes(link);
186 return ret;
187}
188
189static int odroid_audio_remove(struct platform_device *pdev)
190{
191 struct odroid_priv *priv = platform_get_drvdata(pdev);
192
193 of_node_put(priv->dai_link.cpu_of_node);
194 odroid_put_codec_of_nodes(&priv->dai_link);
195
196 return 0;
197}
198
199static const struct of_device_id odroid_audio_of_match[] = {
200 { .compatible = "samsung,odroid-xu3-audio" },
201 { .compatible = "samsung,odroid-xu4-audio"},
202 { },
203};
204MODULE_DEVICE_TABLE(of, odroid_audio_of_match);
205
206static struct platform_driver odroid_audio_driver = {
207 .driver = {
208 .name = "odroid-audio",
209 .of_match_table = odroid_audio_of_match,
210 .pm = &snd_soc_pm_ops,
211 },
212 .probe = odroid_audio_probe,
213 .remove = odroid_audio_remove,
214};
215module_platform_driver(odroid_audio_driver);
216
217MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
218MODULE_DESCRIPTION("Odroid XU3/XU4 audio support");
219MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 644f186fd35c..8f42deaa184b 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -72,7 +72,6 @@ static inline void dbg_showcon(const char *fn, u32 con)
72} 72}
73#endif 73#endif
74 74
75
76/* Turn on or off the transmission path. */ 75/* Turn on or off the transmission path. */
77static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) 76static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
78{ 77{
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 85a33ac0a5c4..66203d107a11 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -43,6 +43,7 @@ struct rsnd_adg {
43}; 43};
44 44
45#define LRCLK_ASYNC (1 << 0) 45#define LRCLK_ASYNC (1 << 0)
46#define AUDIO_OUT_48 (1 << 1)
46#define adg_mode_flags(adg) (adg->flags) 47#define adg_mode_flags(adg) (adg->flags)
47 48
48#define for_each_rsnd_clk(pos, adg, i) \ 49#define for_each_rsnd_clk(pos, adg, i) \
@@ -364,7 +365,10 @@ found_clock:
364 365
365 rsnd_adg_set_ssi_clk(ssi_mod, data); 366 rsnd_adg_set_ssi_clk(ssi_mod, data);
366 367
367 if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) { 368 if (adg_mode_flags(adg) & LRCLK_ASYNC) {
369 if (adg_mode_flags(adg) & AUDIO_OUT_48)
370 ckr = 0x80000000;
371 } else {
368 if (0 == (rate % 8000)) 372 if (0 == (rate % 8000))
369 ckr = 0x80000000; 373 ckr = 0x80000000;
370 } 374 }
@@ -427,11 +431,14 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
427 struct clk *clk; 431 struct clk *clk;
428 struct device *dev = rsnd_priv_to_dev(priv); 432 struct device *dev = rsnd_priv_to_dev(priv);
429 struct device_node *np = dev->of_node; 433 struct device_node *np = dev->of_node;
434 struct property *prop;
430 u32 ckr, rbgx, rbga, rbgb; 435 u32 ckr, rbgx, rbga, rbgb;
431 u32 rate, req_rate = 0, div; 436 u32 rate, div;
437#define REQ_SIZE 2
438 u32 req_rate[REQ_SIZE] = {};
432 uint32_t count = 0; 439 uint32_t count = 0;
433 unsigned long req_48kHz_rate, req_441kHz_rate; 440 unsigned long req_48kHz_rate, req_441kHz_rate;
434 int i; 441 int i, req_size;
435 const char *parent_clk_name = NULL; 442 const char *parent_clk_name = NULL;
436 static const char * const clkout_name[] = { 443 static const char * const clkout_name[] = {
437 [CLKOUT] = "audio_clkout", 444 [CLKOUT] = "audio_clkout",
@@ -446,19 +453,32 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
446 [CLKI] = 0x2, 453 [CLKI] = 0x2,
447 }; 454 };
448 455
449 of_property_read_u32(np, "#clock-cells", &count); 456 ckr = 0;
457 rbga = 2; /* default 1/6 */
458 rbgb = 2; /* default 1/6 */
450 459
451 /* 460 /*
452 * ADG supports BRRA/BRRB output only 461 * ADG supports BRRA/BRRB output only
453 * this means all clkout0/1/2/3 will be same rate 462 * this means all clkout0/1/2/3 will be same rate
454 */ 463 */
455 of_property_read_u32(np, "clock-frequency", &req_rate); 464 prop = of_find_property(np, "clock-frequency", NULL);
465 if (!prop)
466 goto rsnd_adg_get_clkout_end;
467
468 req_size = prop->length / sizeof(u32);
469
470 of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
456 req_48kHz_rate = 0; 471 req_48kHz_rate = 0;
457 req_441kHz_rate = 0; 472 req_441kHz_rate = 0;
458 if (0 == (req_rate % 44100)) 473 for (i = 0; i < req_size; i++) {
459 req_441kHz_rate = req_rate; 474 if (0 == (req_rate[i] % 44100))
460 if (0 == (req_rate % 48000)) 475 req_441kHz_rate = req_rate[i];
461 req_48kHz_rate = req_rate; 476 if (0 == (req_rate[i] % 48000))
477 req_48kHz_rate = req_rate[i];
478 }
479
480 if (req_rate[0] % 48000 == 0)
481 adg->flags = AUDIO_OUT_48;
462 482
463 /* 483 /*
464 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC 484 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
@@ -469,9 +489,6 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
469 * rsnd_adg_ssi_clk_try_start() 489 * rsnd_adg_ssi_clk_try_start()
470 * rsnd_ssi_master_clk_start() 490 * rsnd_ssi_master_clk_start()
471 */ 491 */
472 ckr = 0;
473 rbga = 2; /* default 1/6 */
474 rbgb = 2; /* default 1/6 */
475 adg->rbga_rate_for_441khz = 0; 492 adg->rbga_rate_for_441khz = 0;
476 adg->rbgb_rate_for_48khz = 0; 493 adg->rbgb_rate_for_48khz = 0;
477 for_each_rsnd_clk(clk, adg, i) { 494 for_each_rsnd_clk(clk, adg, i) {
@@ -505,10 +522,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
505 rbgb = rbgx; 522 rbgb = rbgx;
506 adg->rbgb_rate_for_48khz = rate / div; 523 adg->rbgb_rate_for_48khz = rate / div;
507 ckr |= brg_table[i] << 16; 524 ckr |= brg_table[i] << 16;
508 if (req_48kHz_rate) { 525 if (req_48kHz_rate)
509 parent_clk_name = __clk_get_name(clk); 526 parent_clk_name = __clk_get_name(clk);
510 ckr |= 0x80000000;
511 }
512 } 527 }
513 } 528 }
514 } 529 }
@@ -518,12 +533,13 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
518 * this means all clkout0/1/2/3 will be * same rate 533 * this means all clkout0/1/2/3 will be * same rate
519 */ 534 */
520 535
536 of_property_read_u32(np, "#clock-cells", &count);
521 /* 537 /*
522 * for clkout 538 * for clkout
523 */ 539 */
524 if (!count) { 540 if (!count) {
525 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], 541 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
526 parent_clk_name, 0, req_rate); 542 parent_clk_name, 0, req_rate[0]);
527 if (!IS_ERR(clk)) { 543 if (!IS_ERR(clk)) {
528 adg->clkout[CLKOUT] = clk; 544 adg->clkout[CLKOUT] = clk;
529 of_clk_add_provider(np, of_clk_src_simple_get, clk); 545 of_clk_add_provider(np, of_clk_src_simple_get, clk);
@@ -536,19 +552,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
536 for (i = 0; i < CLKOUTMAX; i++) { 552 for (i = 0; i < CLKOUTMAX; i++) {
537 clk = clk_register_fixed_rate(dev, clkout_name[i], 553 clk = clk_register_fixed_rate(dev, clkout_name[i],
538 parent_clk_name, 0, 554 parent_clk_name, 0,
539 req_rate); 555 req_rate[0]);
540 if (!IS_ERR(clk)) { 556 adg->clkout[i] = ERR_PTR(-ENOENT);
541 adg->onecell.clks = adg->clkout; 557 if (!IS_ERR(clk))
542 adg->onecell.clk_num = CLKOUTMAX;
543
544 adg->clkout[i] = clk; 558 adg->clkout[i] = clk;
545
546 of_clk_add_provider(np, of_clk_src_onecell_get,
547 &adg->onecell);
548 }
549 } 559 }
560 adg->onecell.clks = adg->clkout;
561 adg->onecell.clk_num = CLKOUTMAX;
562 of_clk_add_provider(np, of_clk_src_onecell_get,
563 &adg->onecell);
550 } 564 }
551 565
566rsnd_adg_get_clkout_end:
552 adg->ckr = ckr; 567 adg->ckr = ckr;
553 adg->rbga = rbga; 568 adg->rbga = rbga;
554 adg->rbgb = rbgb; 569 adg->rbgb = rbgb;
@@ -564,6 +579,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
564 struct rsnd_adg *adg; 579 struct rsnd_adg *adg;
565 struct device *dev = rsnd_priv_to_dev(priv); 580 struct device *dev = rsnd_priv_to_dev(priv);
566 struct device_node *np = dev->of_node; 581 struct device_node *np = dev->of_node;
582 int ret;
567 583
568 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 584 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
569 if (!adg) { 585 if (!adg) {
@@ -571,8 +587,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
571 return -ENOMEM; 587 return -ENOMEM;
572 } 588 }
573 589
574 rsnd_mod_init(priv, &adg->mod, &adg_ops, 590 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
575 NULL, NULL, 0, 0); 591 NULL, NULL, 0, 0);
592 if (ret)
593 return ret;
576 594
577 rsnd_adg_get_clkin(priv, adg); 595 rsnd_adg_get_clkin(priv, adg);
578 rsnd_adg_get_clkout(priv, adg); 596 rsnd_adg_get_clkout(priv, adg);
@@ -589,5 +607,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
589 607
590void rsnd_adg_remove(struct rsnd_priv *priv) 608void rsnd_adg_remove(struct rsnd_priv *priv)
591{ 609{
610 struct device *dev = rsnd_priv_to_dev(priv);
611 struct device_node *np = dev->of_node;
612
613 of_clk_del_provider(np);
614
592 rsnd_adg_clk_disable(priv); 615 rsnd_adg_clk_disable(priv);
593} 616}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 47b370cb2d3b..1744015408c3 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -96,7 +96,7 @@
96#include <linux/pm_runtime.h> 96#include <linux/pm_runtime.h>
97#include "rsnd.h" 97#include "rsnd.h"
98 98
99#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_192000
100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
101 101
102static const struct of_device_id rsnd_of_match[] = { 102static const struct of_device_id rsnd_of_match[] = {
@@ -110,7 +110,6 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
110/* 110/*
111 * rsnd_mod functions 111 * rsnd_mod functions
112 */ 112 */
113#ifdef DEBUG
114void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) 113void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
115{ 114{
116 if (mod->type != type) { 115 if (mod->type != type) {
@@ -121,7 +120,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
121 rsnd_mod_name(mod), rsnd_mod_id(mod)); 120 rsnd_mod_name(mod), rsnd_mod_id(mod));
122 } 121 }
123} 122}
124#endif
125 123
126char *rsnd_mod_name(struct rsnd_mod *mod) 124char *rsnd_mod_name(struct rsnd_mod *mod)
127{ 125{
@@ -674,12 +672,10 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
674 /* set clock inversion */ 672 /* set clock inversion */
675 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 673 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
676 case SND_SOC_DAIFMT_NB_IF: 674 case SND_SOC_DAIFMT_NB_IF:
677 rdai->bit_clk_inv = rdai->bit_clk_inv;
678 rdai->frm_clk_inv = !rdai->frm_clk_inv; 675 rdai->frm_clk_inv = !rdai->frm_clk_inv;
679 break; 676 break;
680 case SND_SOC_DAIFMT_IB_NF: 677 case SND_SOC_DAIFMT_IB_NF:
681 rdai->bit_clk_inv = !rdai->bit_clk_inv; 678 rdai->bit_clk_inv = !rdai->bit_clk_inv;
682 rdai->frm_clk_inv = rdai->frm_clk_inv;
683 break; 679 break;
684 case SND_SOC_DAIFMT_IB_IF: 680 case SND_SOC_DAIFMT_IB_IF:
685 rdai->bit_clk_inv = !rdai->bit_clk_inv; 681 rdai->bit_clk_inv = !rdai->bit_clk_inv;
@@ -1002,13 +998,30 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
1002 return change; 998 return change;
1003} 999}
1004 1000
1005static int __rsnd_kctrl_new(struct rsnd_mod *mod, 1001struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg)
1006 struct rsnd_dai_stream *io, 1002{
1007 struct snd_soc_pcm_runtime *rtd, 1003 cfg->cfg.val = cfg->val;
1008 const unsigned char *name, 1004
1009 struct rsnd_kctrl_cfg *cfg, 1005 return &cfg->cfg;
1010 void (*update)(struct rsnd_dai_stream *io, 1006}
1011 struct rsnd_mod *mod)) 1007
1008struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg)
1009{
1010 cfg->cfg.val = &cfg->val;
1011
1012 return &cfg->cfg;
1013}
1014
1015int rsnd_kctrl_new(struct rsnd_mod *mod,
1016 struct rsnd_dai_stream *io,
1017 struct snd_soc_pcm_runtime *rtd,
1018 const unsigned char *name,
1019 void (*update)(struct rsnd_dai_stream *io,
1020 struct rsnd_mod *mod),
1021 struct rsnd_kctrl_cfg *cfg,
1022 const char * const *texts,
1023 int size,
1024 u32 max)
1012{ 1025{
1013 struct snd_card *card = rtd->card->snd_card; 1026 struct snd_card *card = rtd->card->snd_card;
1014 struct snd_kcontrol *kctrl; 1027 struct snd_kcontrol *kctrl;
@@ -1023,6 +1036,9 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1023 }; 1036 };
1024 int ret; 1037 int ret;
1025 1038
1039 if (size > RSND_MAX_CHANNELS)
1040 return -EINVAL;
1041
1026 kctrl = snd_ctl_new1(&knew, mod); 1042 kctrl = snd_ctl_new1(&knew, mod);
1027 if (!kctrl) 1043 if (!kctrl)
1028 return -ENOMEM; 1044 return -ENOMEM;
@@ -1031,74 +1047,17 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1031 if (ret < 0) 1047 if (ret < 0)
1032 return ret; 1048 return ret;
1033 1049
1034 cfg->update = update; 1050 cfg->texts = texts;
1035 cfg->card = card; 1051 cfg->max = max;
1036 cfg->kctrl = kctrl; 1052 cfg->size = size;
1037 cfg->io = io; 1053 cfg->update = update;
1054 cfg->card = card;
1055 cfg->kctrl = kctrl;
1056 cfg->io = io;
1038 1057
1039 return 0; 1058 return 0;
1040} 1059}
1041 1060
1042void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg)
1043{
1044 if (cfg->card && cfg->kctrl)
1045 snd_ctl_remove(cfg->card, cfg->kctrl);
1046
1047 cfg->card = NULL;
1048 cfg->kctrl = NULL;
1049}
1050
1051int rsnd_kctrl_new_m(struct rsnd_mod *mod,
1052 struct rsnd_dai_stream *io,
1053 struct snd_soc_pcm_runtime *rtd,
1054 const unsigned char *name,
1055 void (*update)(struct rsnd_dai_stream *io,
1056 struct rsnd_mod *mod),
1057 struct rsnd_kctrl_cfg_m *_cfg,
1058 int ch_size,
1059 u32 max)
1060{
1061 if (ch_size > RSND_MAX_CHANNELS)
1062 return -EINVAL;
1063
1064 _cfg->cfg.max = max;
1065 _cfg->cfg.size = ch_size;
1066 _cfg->cfg.val = _cfg->val;
1067 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1068}
1069
1070int rsnd_kctrl_new_s(struct rsnd_mod *mod,
1071 struct rsnd_dai_stream *io,
1072 struct snd_soc_pcm_runtime *rtd,
1073 const unsigned char *name,
1074 void (*update)(struct rsnd_dai_stream *io,
1075 struct rsnd_mod *mod),
1076 struct rsnd_kctrl_cfg_s *_cfg,
1077 u32 max)
1078{
1079 _cfg->cfg.max = max;
1080 _cfg->cfg.size = 1;
1081 _cfg->cfg.val = &_cfg->val;
1082 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1083}
1084
1085int rsnd_kctrl_new_e(struct rsnd_mod *mod,
1086 struct rsnd_dai_stream *io,
1087 struct snd_soc_pcm_runtime *rtd,
1088 const unsigned char *name,
1089 struct rsnd_kctrl_cfg_s *_cfg,
1090 void (*update)(struct rsnd_dai_stream *io,
1091 struct rsnd_mod *mod),
1092 const char * const *texts,
1093 u32 max)
1094{
1095 _cfg->cfg.max = max;
1096 _cfg->cfg.size = 1;
1097 _cfg->cfg.val = &_cfg->val;
1098 _cfg->cfg.texts = texts;
1099 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1100}
1101
1102/* 1061/*
1103 * snd_soc_platform 1062 * snd_soc_platform
1104 */ 1063 */
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index cf8f59cdd8d7..463de8360985 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -218,21 +218,6 @@ static int rsnd_dvc_probe_(struct rsnd_mod *mod,
218 return rsnd_cmd_attach(io, rsnd_mod_id(mod)); 218 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
219} 219}
220 220
221static int rsnd_dvc_remove_(struct rsnd_mod *mod,
222 struct rsnd_dai_stream *io,
223 struct rsnd_priv *priv)
224{
225 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
226
227 rsnd_kctrl_remove(dvc->volume);
228 rsnd_kctrl_remove(dvc->mute);
229 rsnd_kctrl_remove(dvc->ren);
230 rsnd_kctrl_remove(dvc->rup);
231 rsnd_kctrl_remove(dvc->rdown);
232
233 return 0;
234}
235
236static int rsnd_dvc_init(struct rsnd_mod *mod, 221static int rsnd_dvc_init(struct rsnd_mod *mod,
237 struct rsnd_dai_stream *io, 222 struct rsnd_dai_stream *io,
238 struct rsnd_priv *priv) 223 struct rsnd_priv *priv)
@@ -300,18 +285,18 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
300 ret = rsnd_kctrl_new_e(mod, io, rtd, 285 ret = rsnd_kctrl_new_e(mod, io, rtd,
301 is_play ? 286 is_play ?
302 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", 287 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
303 &dvc->rup,
304 rsnd_dvc_volume_update, 288 rsnd_dvc_volume_update,
305 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 289 &dvc->rup,
290 dvc_ramp_rate);
306 if (ret < 0) 291 if (ret < 0)
307 return ret; 292 return ret;
308 293
309 ret = rsnd_kctrl_new_e(mod, io, rtd, 294 ret = rsnd_kctrl_new_e(mod, io, rtd,
310 is_play ? 295 is_play ?
311 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", 296 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
312 &dvc->rdown,
313 rsnd_dvc_volume_update, 297 rsnd_dvc_volume_update,
314 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 298 &dvc->rdown,
299 dvc_ramp_rate);
315 300
316 if (ret < 0) 301 if (ret < 0)
317 return ret; 302 return ret;
@@ -332,7 +317,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
332 .name = DVC_NAME, 317 .name = DVC_NAME,
333 .dma_req = rsnd_dvc_dma_req, 318 .dma_req = rsnd_dvc_dma_req,
334 .probe = rsnd_dvc_probe_, 319 .probe = rsnd_dvc_probe_,
335 .remove = rsnd_dvc_remove_,
336 .init = rsnd_dvc_init, 320 .init = rsnd_dvc_init,
337 .quit = rsnd_dvc_quit, 321 .quit = rsnd_dvc_quit,
338 .pcm_new = rsnd_dvc_pcm_new, 322 .pcm_new = rsnd_dvc_pcm_new,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 7410ec0174db..dbf4163427e8 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -611,35 +611,30 @@ struct rsnd_kctrl_cfg_s {
611 u32 val; 611 u32 val;
612}; 612};
613 613
614void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); 614struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg);
615#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) 615struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg);
616 616int rsnd_kctrl_new(struct rsnd_mod *mod,
617int rsnd_kctrl_new_m(struct rsnd_mod *mod, 617 struct rsnd_dai_stream *io,
618 struct rsnd_dai_stream *io, 618 struct snd_soc_pcm_runtime *rtd,
619 struct snd_soc_pcm_runtime *rtd, 619 const unsigned char *name,
620 const unsigned char *name, 620 void (*update)(struct rsnd_dai_stream *io,
621 void (*update)(struct rsnd_dai_stream *io, 621 struct rsnd_mod *mod),
622 struct rsnd_mod *mod), 622 struct rsnd_kctrl_cfg *cfg,
623 struct rsnd_kctrl_cfg_m *_cfg, 623 const char * const *texts,
624 int ch_size, 624 int size,
625 u32 max); 625 u32 max);
626int rsnd_kctrl_new_s(struct rsnd_mod *mod, 626
627 struct rsnd_dai_stream *io, 627#define rsnd_kctrl_new_m(mod, io, rtd, name, update, cfg, size, max) \
628 struct snd_soc_pcm_runtime *rtd, 628 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_m(cfg), \
629 const unsigned char *name, 629 NULL, size, max)
630 void (*update)(struct rsnd_dai_stream *io, 630
631 struct rsnd_mod *mod), 631#define rsnd_kctrl_new_s(mod, io, rtd, name, update, cfg, max) \
632 struct rsnd_kctrl_cfg_s *_cfg, 632 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \
633 u32 max); 633 NULL, 1, max)
634int rsnd_kctrl_new_e(struct rsnd_mod *mod, 634
635 struct rsnd_dai_stream *io, 635#define rsnd_kctrl_new_e(mod, io, rtd, name, update, cfg, texts) \
636 struct snd_soc_pcm_runtime *rtd, 636 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \
637 const unsigned char *name, 637 texts, 1, ARRAY_SIZE(texts))
638 struct rsnd_kctrl_cfg_s *_cfg,
639 void (*update)(struct rsnd_dai_stream *io,
640 struct rsnd_mod *mod),
641 const char * const *texts,
642 u32 max);
643 638
644/* 639/*
645 * R-Car SSI 640 * R-Car SSI
@@ -732,8 +727,8 @@ void rsnd_cmd_remove(struct rsnd_priv *priv);
732int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); 727int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
733struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); 728struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id);
734 729
735#ifdef DEBUG
736void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 730void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
731#ifdef DEBUG
737#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) 732#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
738#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC) 733#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
739#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC) 734#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 42db48db09ba..20b5b2ec625e 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -167,6 +167,7 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
167 * dpcm_fe_dai_hw_params() 167 * dpcm_fe_dai_hw_params()
168 * dpcm_be_dai_hw_params() 168 * dpcm_be_dai_hw_params()
169 */ 169 */
170 src->convert_rate = 0;
170 if (fe->dai_link->dynamic) { 171 if (fe->dai_link->dynamic) {
171 int stream = substream->stream; 172 int stream = substream->stream;
172 struct snd_soc_dpcm *dpcm; 173 struct snd_soc_dpcm *dpcm;
@@ -414,8 +415,6 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
414 415
415 rsnd_mod_power_off(mod); 416 rsnd_mod_power_off(mod);
416 417
417 src->convert_rate = 0;
418
419 /* reset sync convert_rate */ 418 /* reset sync convert_rate */
420 src->sync.val = 0; 419 src->sync.val = 0;
421 420
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 411bda2387ad..135c5669f796 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -228,6 +228,15 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
228 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { 228 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
229 229
230 /* 230 /*
231 * It will set SSIWSR.CONT here, but SSICR.CKDV = 000
232 * with it is not allowed. (SSIWSR.WS_MODE with
233 * SSICR.CKDV = 000 is not allowed either).
234 * Skip it. See SSICR.CKDV
235 */
236 if (j == 0)
237 continue;
238
239 /*
231 * this driver is assuming that 240 * this driver is assuming that
232 * system word is 32bit x chan 241 * system word is 32bit x chan
233 * see rsnd_ssi_init() 242 * see rsnd_ssi_init()
diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c
index 3f2cce03275c..be066de74aaa 100644
--- a/sound/soc/sirf/sirf-audio-port.c
+++ b/sound/soc/sirf/sirf-audio-port.c
@@ -19,6 +19,7 @@ struct sirf_audio_port {
19static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) 19static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
20{ 20{
21 struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); 21 struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai);
22
22 snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, 23 snd_soc_dai_init_dma_data(dai, &port->playback_dma_data,
23 &port->capture_dma_data); 24 &port->capture_dma_data);
24 return 0; 25 return 0;
diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c
index 94ea152e0362..f2bc50790f76 100644
--- a/sound/soc/sirf/sirf-audio.c
+++ b/sound/soc/sirf/sirf-audio.c
@@ -27,6 +27,7 @@ static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w,
27 struct snd_soc_card *card = dapm->card; 27 struct snd_soc_card *card = dapm->card;
28 struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); 28 struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
29 int on = !SND_SOC_DAPM_EVENT_OFF(event); 29 int on = !SND_SOC_DAPM_EVENT_OFF(event);
30
30 if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) 31 if (gpio_is_valid(sirf_audio_card->gpio_hp_pa))
31 gpio_set_value(sirf_audio_card->gpio_hp_pa, on); 32 gpio_set_value(sirf_audio_card->gpio_hp_pa, on);
32 return 0; 33 return 0;
diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 45fc06c0e0e5..77e7dcf969d0 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -71,6 +71,7 @@ static void sirf_usp_rx_disable(struct sirf_usp *usp)
71static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) 71static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai)
72{ 72{
73 struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 73 struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai);
74
74 snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, 75 snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data,
75 &usp->capture_dma_data); 76 &usp->capture_dma_data);
76 return 0; 77 return 0;
@@ -294,6 +295,7 @@ static struct snd_soc_dai_driver sirf_usp_pcm_dai = {
294static int sirf_usp_pcm_runtime_suspend(struct device *dev) 295static int sirf_usp_pcm_runtime_suspend(struct device *dev)
295{ 296{
296 struct sirf_usp *usp = dev_get_drvdata(dev); 297 struct sirf_usp *usp = dev_get_drvdata(dev);
298
297 clk_disable_unprepare(usp->clk); 299 clk_disable_unprepare(usp->clk);
298 return 0; 300 return 0;
299} 301}
@@ -302,6 +304,7 @@ static int sirf_usp_pcm_runtime_resume(struct device *dev)
302{ 304{
303 struct sirf_usp *usp = dev_get_drvdata(dev); 305 struct sirf_usp *usp = dev_get_drvdata(dev);
304 int ret; 306 int ret;
307
305 ret = clk_prepare_enable(usp->clk); 308 ret = clk_prepare_enable(usp->clk);
306 if (ret) { 309 if (ret) {
307 dev_err(dev, "clk_enable failed: %d\n", ret); 310 dev_err(dev, "clk_enable failed: %d\n", ret);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2722bb0c5573..525f2f397b4c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1776,7 +1776,6 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1776 } 1776 }
1777 1777
1778 component->init = aux_dev->init; 1778 component->init = aux_dev->init;
1779 component->auxiliary = 1;
1780 list_add(&component->card_aux_list, &card->aux_comp_list); 1779 list_add(&component->card_aux_list, &card->aux_comp_list);
1781 1780
1782 return 0; 1781 return 0;
@@ -1788,14 +1787,13 @@ err_defer:
1788 1787
1789static int soc_probe_aux_devices(struct snd_soc_card *card) 1788static int soc_probe_aux_devices(struct snd_soc_card *card)
1790{ 1789{
1791 struct snd_soc_component *comp, *tmp; 1790 struct snd_soc_component *comp;
1792 int order; 1791 int order;
1793 int ret; 1792 int ret;
1794 1793
1795 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1794 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1796 order++) { 1795 order++) {
1797 list_for_each_entry_safe(comp, tmp, &card->aux_comp_list, 1796 list_for_each_entry(comp, &card->aux_comp_list, card_aux_list) {
1798 card_aux_list) {
1799 if (comp->driver->probe_order == order) { 1797 if (comp->driver->probe_order == order) {
1800 ret = soc_probe_component(card, comp); 1798 ret = soc_probe_component(card, comp);
1801 if (ret < 0) { 1799 if (ret < 0) {
@@ -1804,7 +1802,6 @@ static int soc_probe_aux_devices(struct snd_soc_card *card)
1804 comp->name, ret); 1802 comp->name, ret);
1805 return ret; 1803 return ret;
1806 } 1804 }
1807 list_del(&comp->card_aux_list);
1808 } 1805 }
1809 } 1806 }
1810 } 1807 }
@@ -1820,14 +1817,12 @@ static void soc_remove_aux_devices(struct snd_soc_card *card)
1820 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1817 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1821 order++) { 1818 order++) {
1822 list_for_each_entry_safe(comp, _comp, 1819 list_for_each_entry_safe(comp, _comp,
1823 &card->component_dev_list, card_list) { 1820 &card->aux_comp_list, card_aux_list) {
1824
1825 if (!comp->auxiliary)
1826 continue;
1827 1821
1828 if (comp->driver->remove_order == order) { 1822 if (comp->driver->remove_order == order) {
1829 soc_remove_component(comp); 1823 soc_remove_component(comp);
1830 comp->auxiliary = 0; 1824 /* remove it from the card's aux_comp_list */
1825 list_del(&comp->card_aux_list);
1831 } 1826 }
1832 } 1827 }
1833 } 1828 }
@@ -1918,6 +1913,7 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
1918EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt); 1913EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
1919 1914
1920 1915
1916#ifdef CONFIG_DMI
1921/* Trim special characters, and replace '-' with '_' since '-' is used to 1917/* Trim special characters, and replace '-' with '_' since '-' is used to
1922 * separate different DMI fields in the card long name. Only number and 1918 * separate different DMI fields in the card long name. Only number and
1923 * alphabet characters and a few separator characters are kept. 1919 * alphabet characters and a few separator characters are kept.
@@ -2049,6 +2045,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
2049 return 0; 2045 return 0;
2050} 2046}
2051EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name); 2047EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
2048#endif /* CONFIG_DMI */
2052 2049
2053static int snd_soc_instantiate_card(struct snd_soc_card *card) 2050static int snd_soc_instantiate_card(struct snd_soc_card *card)
2054{ 2051{
@@ -2190,6 +2187,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2190 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 2187 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
2191 card->num_of_dapm_routes); 2188 card->num_of_dapm_routes);
2192 2189
2190 /* try to set some sane longname if DMI is available */
2191 snd_soc_set_dmi_name(card, NULL);
2192
2193 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 2193 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
2194 "%s", card->name); 2194 "%s", card->name);
2195 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 2195 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -3139,7 +3139,7 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
3139 component->suspend = component->driver->suspend; 3139 component->suspend = component->driver->suspend;
3140 component->resume = component->driver->resume; 3140 component->resume = component->driver->resume;
3141 component->pcm_new = component->driver->pcm_new; 3141 component->pcm_new = component->driver->pcm_new;
3142 component->pcm_free= component->driver->pcm_free; 3142 component->pcm_free = component->driver->pcm_free;
3143 3143
3144 dapm = &component->dapm; 3144 dapm = &component->dapm;
3145 dapm->dev = dev; 3145 dapm->dev = dev;
@@ -3240,6 +3240,11 @@ static void snd_soc_component_cleanup(struct snd_soc_component *component)
3240 3240
3241static void snd_soc_component_del_unlocked(struct snd_soc_component *component) 3241static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
3242{ 3242{
3243 struct snd_soc_card *card = component->card;
3244
3245 if (card)
3246 snd_soc_unregister_card(card);
3247
3243 list_del(&component->list); 3248 list_del(&component->list);
3244} 3249}
3245 3250
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fbaa1bb41102..7daf21fee355 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -19,9 +19,28 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/suspend.h>
22#include <trace/events/asoc.h> 23#include <trace/events/asoc.h>
23 24
24/** 25/**
26 * snd_soc_codec_set_jack - configure codec jack.
27 * @codec: CODEC
28 * @jack: structure to use for the jack
29 * @data: can be used if codec driver need extra data for configuring jack
30 *
31 * Configures and enables jack detection function.
32 */
33int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
34 struct snd_soc_jack *jack, void *data)
35{
36 if (codec->driver->set_jack)
37 return codec->driver->set_jack(codec, jack, data);
38 else
39 return -EINVAL;
40}
41EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack);
42
43/**
25 * snd_soc_card_jack_new - Create a new jack 44 * snd_soc_card_jack_new - Create a new jack
26 * @card: ASoC card 45 * @card: ASoC card
27 * @id: an identifying string for this jack 46 * @id: an identifying string for this jack
@@ -293,6 +312,27 @@ static void gpio_work(struct work_struct *work)
293 snd_soc_jack_gpio_detect(gpio); 312 snd_soc_jack_gpio_detect(gpio);
294} 313}
295 314
315static int snd_soc_jack_pm_notifier(struct notifier_block *nb,
316 unsigned long action, void *data)
317{
318 struct snd_soc_jack_gpio *gpio =
319 container_of(nb, struct snd_soc_jack_gpio, pm_notifier);
320
321 switch (action) {
322 case PM_POST_SUSPEND:
323 case PM_POST_HIBERNATION:
324 case PM_POST_RESTORE:
325 /*
326 * Use workqueue so we do not have to care about running
327 * concurrently with work triggered by the interrupt handler.
328 */
329 queue_delayed_work(system_power_efficient_wq, &gpio->work, 0);
330 break;
331 }
332
333 return NOTIFY_DONE;
334}
335
296/** 336/**
297 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack 337 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
298 * 338 *
@@ -369,6 +409,13 @@ got_gpio:
369 i, ret); 409 i, ret);
370 } 410 }
371 411
412 /*
413 * Register PM notifier so we do not miss state transitions
414 * happening while system is asleep.
415 */
416 gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier;
417 register_pm_notifier(&gpios[i].pm_notifier);
418
372 /* Expose GPIO value over sysfs for diagnostic purposes */ 419 /* Expose GPIO value over sysfs for diagnostic purposes */
373 gpiod_export(gpios[i].desc, false); 420 gpiod_export(gpios[i].desc, false);
374 421
@@ -428,6 +475,7 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
428 475
429 for (i = 0; i < count; i++) { 476 for (i = 0; i < count; i++) {
430 gpiod_unexport(gpios[i].desc); 477 gpiod_unexport(gpios[i].desc);
478 unregister_pm_notifier(&gpios[i].pm_notifier);
431 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); 479 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
432 cancel_delayed_work_sync(&gpios[i].work); 480 cancel_delayed_work_sync(&gpios[i].work);
433 gpiod_put(gpios[i].desc); 481 gpiod_put(gpios[i].desc);
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 058bc99c6c34..002772e3ba2c 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -495,12 +495,13 @@ static void remove_widget(struct snd_soc_component *comp,
495 struct snd_kcontrol *kcontrol = w->kcontrols[i]; 495 struct snd_kcontrol *kcontrol = w->kcontrols[i];
496 struct soc_enum *se = 496 struct soc_enum *se =
497 (struct soc_enum *)kcontrol->private_value; 497 (struct soc_enum *)kcontrol->private_value;
498 int j;
498 499
499 snd_ctl_remove(card, kcontrol); 500 snd_ctl_remove(card, kcontrol);
500 501
501 kfree(se->dobj.control.dvalues); 502 kfree(se->dobj.control.dvalues);
502 for (i = 0; i < se->items; i++) 503 for (j = 0; j < se->items; j++)
503 kfree(se->dobj.control.dtexts[i]); 504 kfree(se->dobj.control.dtexts[j]);
504 505
505 kfree(se); 506 kfree(se);
506 } 507 }
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index d7e8dd46d2cc..d8b6936e544e 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -1074,7 +1074,7 @@ int uni_player_init(struct platform_device *pdev,
1074 player->clk = of_clk_get(pdev->dev.of_node, 0); 1074 player->clk = of_clk_get(pdev->dev.of_node, 0);
1075 if (IS_ERR(player->clk)) { 1075 if (IS_ERR(player->clk)) {
1076 dev_err(player->dev, "Failed to get clock\n"); 1076 dev_err(player->dev, "Failed to get clock\n");
1077 ret = PTR_ERR(player->clk); 1077 return PTR_ERR(player->clk);
1078 } 1078 }
1079 1079
1080 /* Select the frequency synthesizer clock */ 1080 /* Select the frequency synthesizer clock */
diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
new file mode 100644
index 000000000000..972970f0890a
--- /dev/null
+++ b/sound/soc/stm/Kconfig
@@ -0,0 +1,8 @@
1menuconfig SND_SOC_STM32
2 tristate "STMicroelectronics STM32 SOC audio support"
3 depends on ARCH_STM32 || COMPILE_TEST
4 depends on SND_SOC
5 select SND_SOC_GENERIC_DMAENGINE_PCM
6 select REGMAP_MMIO
7 help
8 Say Y if you want to enable ASoC-support for STM32
diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile
new file mode 100644
index 000000000000..e466a4759698
--- /dev/null
+++ b/sound/soc/stm/Makefile
@@ -0,0 +1,6 @@
1# SAI
2snd-soc-stm32-sai-sub-objs := stm32_sai_sub.o
3obj-$(CONFIG_SND_SOC_STM32) += snd-soc-stm32-sai-sub.o
4
5snd-soc-stm32-sai-objs := stm32_sai.o
6obj-$(CONFIG_SND_SOC_STM32) += snd-soc-stm32-sai.o
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
new file mode 100644
index 000000000000..2a27a26bf7a1
--- /dev/null
+++ b/sound/soc/stm/stm32_sai.c
@@ -0,0 +1,115 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19#include <linux/clk.h>
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/of_platform.h>
23#include <linux/reset.h>
24
25#include <sound/dmaengine_pcm.h>
26#include <sound/core.h>
27
28#include "stm32_sai.h"
29
30static const struct of_device_id stm32_sai_ids[] = {
31 { .compatible = "st,stm32f4-sai", .data = (void *)SAI_STM32F4 },
32 {}
33};
34
35static int stm32_sai_probe(struct platform_device *pdev)
36{
37 struct device_node *np = pdev->dev.of_node;
38 struct stm32_sai_data *sai;
39 struct reset_control *rst;
40 struct resource *res;
41 void __iomem *base;
42 const struct of_device_id *of_id;
43
44 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
45 if (!sai)
46 return -ENOMEM;
47
48 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
49 base = devm_ioremap_resource(&pdev->dev, res);
50 if (IS_ERR(base))
51 return PTR_ERR(base);
52
53 of_id = of_match_device(stm32_sai_ids, &pdev->dev);
54 if (of_id)
55 sai->version = (enum stm32_sai_version)of_id->data;
56 else
57 return -EINVAL;
58
59 sai->clk_x8k = devm_clk_get(&pdev->dev, "x8k");
60 if (IS_ERR(sai->clk_x8k)) {
61 dev_err(&pdev->dev, "missing x8k parent clock\n");
62 return PTR_ERR(sai->clk_x8k);
63 }
64
65 sai->clk_x11k = devm_clk_get(&pdev->dev, "x11k");
66 if (IS_ERR(sai->clk_x11k)) {
67 dev_err(&pdev->dev, "missing x11k parent clock\n");
68 return PTR_ERR(sai->clk_x11k);
69 }
70
71 /* init irqs */
72 sai->irq = platform_get_irq(pdev, 0);
73 if (sai->irq < 0) {
74 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
75 return sai->irq;
76 }
77
78 /* reset */
79 rst = reset_control_get(&pdev->dev, NULL);
80 if (!IS_ERR(rst)) {
81 reset_control_assert(rst);
82 udelay(2);
83 reset_control_deassert(rst);
84 }
85
86 sai->pdev = pdev;
87 platform_set_drvdata(pdev, sai);
88
89 return of_platform_populate(np, NULL, NULL, &pdev->dev);
90}
91
92static int stm32_sai_remove(struct platform_device *pdev)
93{
94 of_platform_depopulate(&pdev->dev);
95
96 return 0;
97}
98
99MODULE_DEVICE_TABLE(of, stm32_sai_ids);
100
101static struct platform_driver stm32_sai_driver = {
102 .driver = {
103 .name = "st,stm32-sai",
104 .of_match_table = stm32_sai_ids,
105 },
106 .probe = stm32_sai_probe,
107 .remove = stm32_sai_remove,
108};
109
110module_platform_driver(stm32_sai_driver);
111
112MODULE_DESCRIPTION("STM32 Soc SAI Interface");
113MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>");
114MODULE_ALIAS("platform:st,stm32-sai");
115MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/stm/stm32_sai.h b/sound/soc/stm/stm32_sai.h
new file mode 100644
index 000000000000..a801fda5066f
--- /dev/null
+++ b/sound/soc/stm/stm32_sai.h
@@ -0,0 +1,200 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19/******************** SAI Register Map **************************************/
20
21/* common register */
22#define STM_SAI_GCR 0x00
23
24/* Sub-block A&B registers offsets, relative to A&B sub-block addresses */
25#define STM_SAI_CR1_REGX 0x00 /* A offset: 0x04. B offset: 0x24 */
26#define STM_SAI_CR2_REGX 0x04
27#define STM_SAI_FRCR_REGX 0x08
28#define STM_SAI_SLOTR_REGX 0x0C
29#define STM_SAI_IMR_REGX 0x10
30#define STM_SAI_SR_REGX 0x14
31#define STM_SAI_CLRFR_REGX 0x18
32#define STM_SAI_DR_REGX 0x1C
33
34/******************** Bit definition for SAI_GCR register *******************/
35#define SAI_GCR_SYNCIN_SHIFT 0
36#define SAI_GCR_SYNCIN_MASK GENMASK(1, SAI_GCR_SYNCIN_SHIFT)
37#define SAI_GCR_SYNCIN_SET(x) ((x) << SAI_GCR_SYNCIN_SHIFT)
38
39#define SAI_GCR_SYNCOUT_SHIFT 4
40#define SAI_GCR_SYNCOUT_MASK GENMASK(5, SAI_GCR_SYNCOUT_SHIFT)
41#define SAI_GCR_SYNCOUT_SET(x) ((x) << SAI_GCR_SYNCOUT_SHIFT)
42
43/******************* Bit definition for SAI_XCR1 register *******************/
44#define SAI_XCR1_RX_TX_SHIFT 0
45#define SAI_XCR1_RX_TX BIT(SAI_XCR1_RX_TX_SHIFT)
46#define SAI_XCR1_SLAVE_SHIFT 1
47#define SAI_XCR1_SLAVE BIT(SAI_XCR1_SLAVE_SHIFT)
48
49#define SAI_XCR1_PRTCFG_SHIFT 2
50#define SAI_XCR1_PRTCFG_MASK GENMASK(3, SAI_XCR1_PRTCFG_SHIFT)
51#define SAI_XCR1_PRTCFG_SET(x) ((x) << SAI_XCR1_PRTCFG_SHIFT)
52
53#define SAI_XCR1_DS_SHIFT 5
54#define SAI_XCR1_DS_MASK GENMASK(7, SAI_XCR1_DS_SHIFT)
55#define SAI_XCR1_DS_SET(x) ((x) << SAI_XCR1_DS_SHIFT)
56
57#define SAI_XCR1_LSBFIRST_SHIFT 8
58#define SAI_XCR1_LSBFIRST BIT(SAI_XCR1_LSBFIRST_SHIFT)
59#define SAI_XCR1_CKSTR_SHIFT 9
60#define SAI_XCR1_CKSTR BIT(SAI_XCR1_CKSTR_SHIFT)
61
62#define SAI_XCR1_SYNCEN_SHIFT 10
63#define SAI_XCR1_SYNCEN_MASK GENMASK(11, SAI_XCR1_SYNCEN_SHIFT)
64#define SAI_XCR1_SYNCEN_SET(x) ((x) << SAI_XCR1_SYNCEN_SHIFT)
65
66#define SAI_XCR1_MONO_SHIFT 12
67#define SAI_XCR1_MONO BIT(SAI_XCR1_MONO_SHIFT)
68#define SAI_XCR1_OUTDRIV_SHIFT 13
69#define SAI_XCR1_OUTDRIV BIT(SAI_XCR1_OUTDRIV_SHIFT)
70#define SAI_XCR1_SAIEN_SHIFT 16
71#define SAI_XCR1_SAIEN BIT(SAI_XCR1_SAIEN_SHIFT)
72#define SAI_XCR1_DMAEN_SHIFT 17
73#define SAI_XCR1_DMAEN BIT(SAI_XCR1_DMAEN_SHIFT)
74#define SAI_XCR1_NODIV_SHIFT 19
75#define SAI_XCR1_NODIV BIT(SAI_XCR1_NODIV_SHIFT)
76
77#define SAI_XCR1_MCKDIV_SHIFT 20
78#define SAI_XCR1_MCKDIV_WIDTH 4
79#define SAI_XCR1_MCKDIV_MASK GENMASK(24, SAI_XCR1_MCKDIV_SHIFT)
80#define SAI_XCR1_MCKDIV_SET(x) ((x) << SAI_XCR1_MCKDIV_SHIFT)
81#define SAI_XCR1_MCKDIV_MAX ((1 << SAI_XCR1_MCKDIV_WIDTH) - 1)
82
83#define SAI_XCR1_OSR_SHIFT 26
84#define SAI_XCR1_OSR BIT(SAI_XCR1_OSR_SHIFT)
85
86/******************* Bit definition for SAI_XCR2 register *******************/
87#define SAI_XCR2_FTH_SHIFT 0
88#define SAI_XCR2_FTH_MASK GENMASK(2, SAI_XCR2_FTH_SHIFT)
89#define SAI_XCR2_FTH_SET(x) ((x) << SAI_XCR2_FTH_SHIFT)
90
91#define SAI_XCR2_FFLUSH_SHIFT 3
92#define SAI_XCR2_FFLUSH BIT(SAI_XCR2_FFLUSH_SHIFT)
93#define SAI_XCR2_TRIS_SHIFT 4
94#define SAI_XCR2_TRIS BIT(SAI_XCR2_TRIS_SHIFT)
95#define SAI_XCR2_MUTE_SHIFT 5
96#define SAI_XCR2_MUTE BIT(SAI_XCR2_MUTE_SHIFT)
97#define SAI_XCR2_MUTEVAL_SHIFT 6
98#define SAI_XCR2_MUTEVAL BIT(SAI_XCR2_MUTEVAL_SHIFT)
99
100#define SAI_XCR2_MUTECNT_SHIFT 7
101#define SAI_XCR2_MUTECNT_MASK GENMASK(12, SAI_XCR2_MUTECNT_SHIFT)
102#define SAI_XCR2_MUTECNT_SET(x) ((x) << SAI_XCR2_MUTECNT_SHIFT)
103
104#define SAI_XCR2_CPL_SHIFT 13
105#define SAI_XCR2_CPL BIT(SAI_XCR2_CPL_SHIFT)
106
107#define SAI_XCR2_COMP_SHIFT 14
108#define SAI_XCR2_COMP_MASK GENMASK(15, SAI_XCR2_COMP_SHIFT)
109#define SAI_XCR2_COMP_SET(x) ((x) << SAI_XCR2_COMP_SHIFT)
110
111/****************** Bit definition for SAI_XFRCR register *******************/
112#define SAI_XFRCR_FRL_SHIFT 0
113#define SAI_XFRCR_FRL_MASK GENMASK(7, SAI_XFRCR_FRL_SHIFT)
114#define SAI_XFRCR_FRL_SET(x) ((x) << SAI_XFRCR_FRL_SHIFT)
115
116#define SAI_XFRCR_FSALL_SHIFT 8
117#define SAI_XFRCR_FSALL_MASK GENMASK(14, SAI_XFRCR_FSALL_SHIFT)
118#define SAI_XFRCR_FSALL_SET(x) ((x) << SAI_XFRCR_FSALL_SHIFT)
119
120#define SAI_XFRCR_FSDEF_SHIFT 16
121#define SAI_XFRCR_FSDEF BIT(SAI_XFRCR_FSDEF_SHIFT)
122#define SAI_XFRCR_FSPOL_SHIFT 17
123#define SAI_XFRCR_FSPOL BIT(SAI_XFRCR_FSPOL_SHIFT)
124#define SAI_XFRCR_FSOFF_SHIFT 18
125#define SAI_XFRCR_FSOFF BIT(SAI_XFRCR_FSOFF_SHIFT)
126
127/****************** Bit definition for SAI_XSLOTR register ******************/
128
129#define SAI_XSLOTR_FBOFF_SHIFT 0
130#define SAI_XSLOTR_FBOFF_MASK GENMASK(4, SAI_XSLOTR_FBOFF_SHIFT)
131#define SAI_XSLOTR_FBOFF_SET(x) ((x) << SAI_XSLOTR_FBOFF_SHIFT)
132
133#define SAI_XSLOTR_SLOTSZ_SHIFT 6
134#define SAI_XSLOTR_SLOTSZ_MASK GENMASK(7, SAI_XSLOTR_SLOTSZ_SHIFT)
135#define SAI_XSLOTR_SLOTSZ_SET(x) ((x) << SAI_XSLOTR_SLOTSZ_SHIFT)
136
137#define SAI_XSLOTR_NBSLOT_SHIFT 8
138#define SAI_XSLOTR_NBSLOT_MASK GENMASK(11, SAI_XSLOTR_NBSLOT_SHIFT)
139#define SAI_XSLOTR_NBSLOT_SET(x) ((x) << SAI_XSLOTR_NBSLOT_SHIFT)
140
141#define SAI_XSLOTR_SLOTEN_SHIFT 16
142#define SAI_XSLOTR_SLOTEN_WIDTH 16
143#define SAI_XSLOTR_SLOTEN_MASK GENMASK(31, SAI_XSLOTR_SLOTEN_SHIFT)
144#define SAI_XSLOTR_SLOTEN_SET(x) ((x) << SAI_XSLOTR_SLOTEN_SHIFT)
145
146/******************* Bit definition for SAI_XIMR register *******************/
147#define SAI_XIMR_OVRUDRIE BIT(0)
148#define SAI_XIMR_MUTEDETIE BIT(1)
149#define SAI_XIMR_WCKCFGIE BIT(2)
150#define SAI_XIMR_FREQIE BIT(3)
151#define SAI_XIMR_CNRDYIE BIT(4)
152#define SAI_XIMR_AFSDETIE BIT(5)
153#define SAI_XIMR_LFSDETIE BIT(6)
154
155#define SAI_XIMR_SHIFT 0
156#define SAI_XIMR_MASK GENMASK(6, SAI_XIMR_SHIFT)
157
158/******************** Bit definition for SAI_XSR register *******************/
159#define SAI_XSR_OVRUDR BIT(0)
160#define SAI_XSR_MUTEDET BIT(1)
161#define SAI_XSR_WCKCFG BIT(2)
162#define SAI_XSR_FREQ BIT(3)
163#define SAI_XSR_CNRDY BIT(4)
164#define SAI_XSR_AFSDET BIT(5)
165#define SAI_XSR_LFSDET BIT(6)
166
167#define SAI_XSR_SHIFT 0
168#define SAI_XSR_MASK GENMASK(6, SAI_XSR_SHIFT)
169
170/****************** Bit definition for SAI_XCLRFR register ******************/
171#define SAI_XCLRFR_COVRUDR BIT(0)
172#define SAI_XCLRFR_CMUTEDET BIT(1)
173#define SAI_XCLRFR_CWCKCFG BIT(2)
174#define SAI_XCLRFR_CFREQ BIT(3)
175#define SAI_XCLRFR_CCNRDY BIT(4)
176#define SAI_XCLRFR_CAFSDET BIT(5)
177#define SAI_XCLRFR_CLFSDET BIT(6)
178
179#define SAI_XCLRFR_SHIFT 0
180#define SAI_XCLRFR_MASK GENMASK(6, SAI_XCLRFR_SHIFT)
181
182enum stm32_sai_version {
183 SAI_STM32F4
184};
185
186/**
187 * struct stm32_sai_data - private data of SAI instance driver
188 * @pdev: device data pointer
189 * @clk_x8k: SAI parent clock for sampling frequencies multiple of 8kHz
190 * @clk_x11k: SAI parent clock for sampling frequencies multiple of 11kHz
191 * @version: SOC version
192 * @irq: SAI interrupt line
193 */
194struct stm32_sai_data {
195 struct platform_device *pdev;
196 struct clk *clk_x8k;
197 struct clk *clk_x11k;
198 int version;
199 int irq;
200};
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
new file mode 100644
index 000000000000..ae4706ca265b
--- /dev/null
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -0,0 +1,884 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of_irq.h>
23#include <linux/of_platform.h>
24#include <linux/regmap.h>
25
26#include <sound/core.h>
27#include <sound/dmaengine_pcm.h>
28#include <sound/pcm_params.h>
29
30#include "stm32_sai.h"
31
32#define SAI_FREE_PROTOCOL 0x0
33
34#define SAI_SLOT_SIZE_AUTO 0x0
35#define SAI_SLOT_SIZE_16 0x1
36#define SAI_SLOT_SIZE_32 0x2
37
38#define SAI_DATASIZE_8 0x2
39#define SAI_DATASIZE_10 0x3
40#define SAI_DATASIZE_16 0x4
41#define SAI_DATASIZE_20 0x5
42#define SAI_DATASIZE_24 0x6
43#define SAI_DATASIZE_32 0x7
44
45#define STM_SAI_FIFO_SIZE 8
46#define STM_SAI_DAI_NAME_SIZE 15
47
48#define STM_SAI_IS_PLAYBACK(ip) ((ip)->dir == SNDRV_PCM_STREAM_PLAYBACK)
49#define STM_SAI_IS_CAPTURE(ip) ((ip)->dir == SNDRV_PCM_STREAM_CAPTURE)
50
51#define STM_SAI_A_ID 0x0
52#define STM_SAI_B_ID 0x1
53
54#define STM_SAI_BLOCK_NAME(x) (((x)->id == STM_SAI_A_ID) ? "A" : "B")
55
56/**
57 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
58 * @pdev: device data pointer
59 * @regmap: SAI register map pointer
60 * @dma_params: dma configuration data for rx or tx channel
61 * @cpu_dai_drv: DAI driver data pointer
62 * @cpu_dai: DAI runtime data pointer
63 * @substream: PCM substream data pointer
64 * @pdata: SAI block parent data pointer
65 * @sai_ck: kernel clock feeding the SAI clock generator
66 * @phys_addr: SAI registers physical base address
67 * @mclk_rate: SAI block master clock frequency (Hz). set at init
68 * @id: SAI sub block id corresponding to sub-block A or B
69 * @dir: SAI block direction (playback or capture). set at init
70 * @master: SAI block mode flag. (true=master, false=slave) set at init
71 * @fmt: SAI block format. relevant only for custom protocols. set at init
72 * @sync: SAI block synchronization mode. (none, internal or external)
73 * @fs_length: frame synchronization length. depends on protocol settings
74 * @slots: rx or tx slot number
75 * @slot_width: rx or tx slot width in bits
76 * @slot_mask: rx or tx active slots mask. set at init or at runtime
77 * @data_size: PCM data width. corresponds to PCM substream width.
78 */
79struct stm32_sai_sub_data {
80 struct platform_device *pdev;
81 struct regmap *regmap;
82 struct snd_dmaengine_dai_dma_data dma_params;
83 struct snd_soc_dai_driver *cpu_dai_drv;
84 struct snd_soc_dai *cpu_dai;
85 struct snd_pcm_substream *substream;
86 struct stm32_sai_data *pdata;
87 struct clk *sai_ck;
88 dma_addr_t phys_addr;
89 unsigned int mclk_rate;
90 unsigned int id;
91 int dir;
92 bool master;
93 int fmt;
94 int sync;
95 int fs_length;
96 int slots;
97 int slot_width;
98 int slot_mask;
99 int data_size;
100};
101
102enum stm32_sai_fifo_th {
103 STM_SAI_FIFO_TH_EMPTY,
104 STM_SAI_FIFO_TH_QUARTER,
105 STM_SAI_FIFO_TH_HALF,
106 STM_SAI_FIFO_TH_3_QUARTER,
107 STM_SAI_FIFO_TH_FULL,
108};
109
110static bool stm32_sai_sub_readable_reg(struct device *dev, unsigned int reg)
111{
112 switch (reg) {
113 case STM_SAI_CR1_REGX:
114 case STM_SAI_CR2_REGX:
115 case STM_SAI_FRCR_REGX:
116 case STM_SAI_SLOTR_REGX:
117 case STM_SAI_IMR_REGX:
118 case STM_SAI_SR_REGX:
119 case STM_SAI_CLRFR_REGX:
120 case STM_SAI_DR_REGX:
121 return true;
122 default:
123 return false;
124 }
125}
126
127static bool stm32_sai_sub_volatile_reg(struct device *dev, unsigned int reg)
128{
129 switch (reg) {
130 case STM_SAI_DR_REGX:
131 return true;
132 default:
133 return false;
134 }
135}
136
137static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
138{
139 switch (reg) {
140 case STM_SAI_CR1_REGX:
141 case STM_SAI_CR2_REGX:
142 case STM_SAI_FRCR_REGX:
143 case STM_SAI_SLOTR_REGX:
144 case STM_SAI_IMR_REGX:
145 case STM_SAI_SR_REGX:
146 case STM_SAI_CLRFR_REGX:
147 case STM_SAI_DR_REGX:
148 return true;
149 default:
150 return false;
151 }
152}
153
154static const struct regmap_config stm32_sai_sub_regmap_config = {
155 .reg_bits = 32,
156 .reg_stride = 4,
157 .val_bits = 32,
158 .max_register = STM_SAI_DR_REGX,
159 .readable_reg = stm32_sai_sub_readable_reg,
160 .volatile_reg = stm32_sai_sub_volatile_reg,
161 .writeable_reg = stm32_sai_sub_writeable_reg,
162 .fast_io = true,
163};
164
165static irqreturn_t stm32_sai_isr(int irq, void *devid)
166{
167 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
168 struct snd_pcm_substream *substream = sai->substream;
169 struct platform_device *pdev = sai->pdev;
170 unsigned int sr, imr, flags;
171 snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
172
173 regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr);
174 regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr);
175
176 flags = sr & imr;
177 if (!flags)
178 return IRQ_NONE;
179
180 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
181 SAI_XCLRFR_MASK);
182
183 if (flags & SAI_XIMR_OVRUDRIE) {
184 dev_err(&pdev->dev, "IT %s\n",
185 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
186 status = SNDRV_PCM_STATE_XRUN;
187 }
188
189 if (flags & SAI_XIMR_MUTEDETIE)
190 dev_dbg(&pdev->dev, "IT mute detected\n");
191
192 if (flags & SAI_XIMR_WCKCFGIE) {
193 dev_err(&pdev->dev, "IT wrong clock configuration\n");
194 status = SNDRV_PCM_STATE_DISCONNECTED;
195 }
196
197 if (flags & SAI_XIMR_CNRDYIE)
198 dev_warn(&pdev->dev, "IT Codec not ready\n");
199
200 if (flags & SAI_XIMR_AFSDETIE) {
201 dev_warn(&pdev->dev, "IT Anticipated frame synchro\n");
202 status = SNDRV_PCM_STATE_XRUN;
203 }
204
205 if (flags & SAI_XIMR_LFSDETIE) {
206 dev_warn(&pdev->dev, "IT Late frame synchro\n");
207 status = SNDRV_PCM_STATE_XRUN;
208 }
209
210 if (status != SNDRV_PCM_STATE_RUNNING) {
211 snd_pcm_stream_lock(substream);
212 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
213 snd_pcm_stream_unlock(substream);
214 }
215
216 return IRQ_HANDLED;
217}
218
219static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
220 int clk_id, unsigned int freq, int dir)
221{
222 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
223
224 if ((dir == SND_SOC_CLOCK_OUT) && sai->master) {
225 sai->mclk_rate = freq;
226 dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
227 }
228
229 return 0;
230}
231
232static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
233 u32 rx_mask, int slots, int slot_width)
234{
235 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
236 int slotr, slotr_mask, slot_size;
237
238 dev_dbg(cpu_dai->dev, "masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
239 tx_mask, rx_mask, slots, slot_width);
240
241 switch (slot_width) {
242 case 16:
243 slot_size = SAI_SLOT_SIZE_16;
244 break;
245 case 32:
246 slot_size = SAI_SLOT_SIZE_32;
247 break;
248 default:
249 slot_size = SAI_SLOT_SIZE_AUTO;
250 break;
251 }
252
253 slotr = SAI_XSLOTR_SLOTSZ_SET(slot_size) |
254 SAI_XSLOTR_NBSLOT_SET(slots - 1);
255 slotr_mask = SAI_XSLOTR_SLOTSZ_MASK | SAI_XSLOTR_NBSLOT_MASK;
256
257 /* tx/rx mask set in machine init, if slot number defined in DT */
258 if (STM_SAI_IS_PLAYBACK(sai)) {
259 sai->slot_mask = tx_mask;
260 slotr |= SAI_XSLOTR_SLOTEN_SET(tx_mask);
261 }
262
263 if (STM_SAI_IS_CAPTURE(sai)) {
264 sai->slot_mask = rx_mask;
265 slotr |= SAI_XSLOTR_SLOTEN_SET(rx_mask);
266 }
267
268 slotr_mask |= SAI_XSLOTR_SLOTEN_MASK;
269
270 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
271
272 sai->slot_width = slot_width;
273 sai->slots = slots;
274
275 return 0;
276}
277
278static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
279{
280 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
281 int cr1 = 0, frcr = 0;
282 int cr1_mask = 0, frcr_mask = 0;
283 int ret;
284
285 dev_dbg(cpu_dai->dev, "fmt %x\n", fmt);
286
287 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
288 /* SCK active high for all protocols */
289 case SND_SOC_DAIFMT_I2S:
290 cr1 |= SAI_XCR1_CKSTR;
291 frcr |= SAI_XFRCR_FSOFF | SAI_XFRCR_FSDEF;
292 break;
293 /* Left justified */
294 case SND_SOC_DAIFMT_MSB:
295 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
296 break;
297 /* Right justified */
298 case SND_SOC_DAIFMT_LSB:
299 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
300 break;
301 case SND_SOC_DAIFMT_DSP_A:
302 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
303 break;
304 case SND_SOC_DAIFMT_DSP_B:
305 frcr |= SAI_XFRCR_FSPOL;
306 break;
307 default:
308 dev_err(cpu_dai->dev, "Unsupported protocol %#x\n",
309 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
310 return -EINVAL;
311 }
312
313 cr1_mask |= SAI_XCR1_PRTCFG_MASK | SAI_XCR1_CKSTR;
314 frcr_mask |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF |
315 SAI_XFRCR_FSDEF;
316
317 /* DAI clock strobing. Invert setting previously set */
318 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
319 case SND_SOC_DAIFMT_NB_NF:
320 break;
321 case SND_SOC_DAIFMT_IB_NF:
322 cr1 ^= SAI_XCR1_CKSTR;
323 break;
324 case SND_SOC_DAIFMT_NB_IF:
325 frcr ^= SAI_XFRCR_FSPOL;
326 break;
327 case SND_SOC_DAIFMT_IB_IF:
328 /* Invert fs & sck */
329 cr1 ^= SAI_XCR1_CKSTR;
330 frcr ^= SAI_XFRCR_FSPOL;
331 break;
332 default:
333 dev_err(cpu_dai->dev, "Unsupported strobing %#x\n",
334 fmt & SND_SOC_DAIFMT_INV_MASK);
335 return -EINVAL;
336 }
337 cr1_mask |= SAI_XCR1_CKSTR;
338 frcr_mask |= SAI_XFRCR_FSPOL;
339
340 regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
341
342 /* DAI clock master masks */
343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344 case SND_SOC_DAIFMT_CBM_CFM:
345 /* codec is master */
346 cr1 |= SAI_XCR1_SLAVE;
347 sai->master = false;
348 break;
349 case SND_SOC_DAIFMT_CBS_CFS:
350 sai->master = true;
351 break;
352 default:
353 dev_err(cpu_dai->dev, "Unsupported mode %#x\n",
354 fmt & SND_SOC_DAIFMT_MASTER_MASK);
355 return -EINVAL;
356 }
357 cr1_mask |= SAI_XCR1_SLAVE;
358
359 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
360 if (ret < 0) {
361 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
362 return ret;
363 }
364
365 sai->fmt = fmt;
366
367 return 0;
368}
369
370static int stm32_sai_startup(struct snd_pcm_substream *substream,
371 struct snd_soc_dai *cpu_dai)
372{
373 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
374 int imr, cr2, ret;
375
376 sai->substream = substream;
377
378 ret = clk_prepare_enable(sai->sai_ck);
379 if (ret < 0) {
380 dev_err(cpu_dai->dev, "failed to enable clock: %d\n", ret);
381 return ret;
382 }
383
384 /* Enable ITs */
385 regmap_update_bits(sai->regmap, STM_SAI_SR_REGX,
386 SAI_XSR_MASK, (unsigned int)~SAI_XSR_MASK);
387
388 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX,
389 SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
390
391 imr = SAI_XIMR_OVRUDRIE;
392 if (STM_SAI_IS_CAPTURE(sai)) {
393 regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2);
394 if (cr2 & SAI_XCR2_MUTECNT_MASK)
395 imr |= SAI_XIMR_MUTEDETIE;
396 }
397
398 if (sai->master)
399 imr |= SAI_XIMR_WCKCFGIE;
400 else
401 imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE;
402
403 regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
404 SAI_XIMR_MASK, imr);
405
406 return 0;
407}
408
409static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
410 struct snd_pcm_substream *substream,
411 struct snd_pcm_hw_params *params)
412{
413 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
414 int cr1, cr1_mask, ret;
415 int fth = STM_SAI_FIFO_TH_HALF;
416
417 /* FIFO config */
418 regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
419 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
420 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));
421
422 /* Mode, data format and channel config */
423 cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
424 switch (params_format(params)) {
425 case SNDRV_PCM_FORMAT_S8:
426 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_8);
427 break;
428 case SNDRV_PCM_FORMAT_S16_LE:
429 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_16);
430 break;
431 case SNDRV_PCM_FORMAT_S32_LE:
432 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_32);
433 break;
434 default:
435 dev_err(cpu_dai->dev, "Data format not supported");
436 return -EINVAL;
437 }
438 cr1_mask = SAI_XCR1_DS_MASK | SAI_XCR1_PRTCFG_MASK;
439
440 cr1_mask |= SAI_XCR1_RX_TX;
441 if (STM_SAI_IS_CAPTURE(sai))
442 cr1 |= SAI_XCR1_RX_TX;
443
444 cr1_mask |= SAI_XCR1_MONO;
445 if ((sai->slots == 2) && (params_channels(params) == 1))
446 cr1 |= SAI_XCR1_MONO;
447
448 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
449 if (ret < 0) {
450 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
451 return ret;
452 }
453
454 /* DMA config */
455 sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
456 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
457
458 return 0;
459}
460
461static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai)
462{
463 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
464 int slotr, slot_sz;
465
466 regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr);
467
468 /*
469 * If SLOTSZ is set to auto in SLOTR, align slot width on data size
470 * By default slot width = data size, if not forced from DT
471 */
472 slot_sz = slotr & SAI_XSLOTR_SLOTSZ_MASK;
473 if (slot_sz == SAI_XSLOTR_SLOTSZ_SET(SAI_SLOT_SIZE_AUTO))
474 sai->slot_width = sai->data_size;
475
476 if (sai->slot_width < sai->data_size) {
477 dev_err(cpu_dai->dev,
478 "Data size %d larger than slot width\n",
479 sai->data_size);
480 return -EINVAL;
481 }
482
483 /* Slot number is set to 2, if not specified in DT */
484 if (!sai->slots)
485 sai->slots = 2;
486
487 /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/
488 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
489 SAI_XSLOTR_NBSLOT_MASK,
490 SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
491
492 /* Set default slots mask if not already set from DT */
493 if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) {
494 sai->slot_mask = (1 << sai->slots) - 1;
495 regmap_update_bits(sai->regmap,
496 STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
497 SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
498 }
499
500 dev_dbg(cpu_dai->dev, "slots %d, slot width %d\n",
501 sai->slots, sai->slot_width);
502
503 return 0;
504}
505
506static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai)
507{
508 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
509 int fs_active, offset, format;
510 int frcr, frcr_mask;
511
512 format = sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
513 sai->fs_length = sai->slot_width * sai->slots;
514
515 fs_active = sai->fs_length / 2;
516 if ((format == SND_SOC_DAIFMT_DSP_A) ||
517 (format == SND_SOC_DAIFMT_DSP_B))
518 fs_active = 1;
519
520 frcr = SAI_XFRCR_FRL_SET((sai->fs_length - 1));
521 frcr |= SAI_XFRCR_FSALL_SET((fs_active - 1));
522 frcr_mask = SAI_XFRCR_FRL_MASK | SAI_XFRCR_FSALL_MASK;
523
524 dev_dbg(cpu_dai->dev, "frame length %d, frame active %d\n",
525 sai->fs_length, fs_active);
526
527 regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
528
529 if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
530 offset = sai->slot_width - sai->data_size;
531
532 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
533 SAI_XSLOTR_FBOFF_MASK,
534 SAI_XSLOTR_FBOFF_SET(offset));
535 }
536}
537
538static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
539 struct snd_pcm_hw_params *params)
540{
541 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
542 int cr1, mask, div = 0;
543 int sai_clk_rate, ret;
544
545 if (!sai->mclk_rate) {
546 dev_err(cpu_dai->dev, "Mclk rate is null\n");
547 return -EINVAL;
548 }
549
550 if (!(params_rate(params) % 11025))
551 clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
552 else
553 clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
554 sai_clk_rate = clk_get_rate(sai->sai_ck);
555
556 /*
557 * mclk_rate = 256 * fs
558 * MCKDIV = 0 if sai_ck < 3/2 * mclk_rate
559 * MCKDIV = sai_ck / (2 * mclk_rate) otherwise
560 */
561 if (2 * sai_clk_rate >= 3 * sai->mclk_rate)
562 div = DIV_ROUND_CLOSEST(sai_clk_rate, 2 * sai->mclk_rate);
563
564 if (div > SAI_XCR1_MCKDIV_MAX) {
565 dev_err(cpu_dai->dev, "Divider %d out of range\n", div);
566 return -EINVAL;
567 }
568 dev_dbg(cpu_dai->dev, "SAI clock %d, divider %d\n", sai_clk_rate, div);
569
570 mask = SAI_XCR1_MCKDIV_MASK;
571 cr1 = SAI_XCR1_MCKDIV_SET(div);
572 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1);
573 if (ret < 0) {
574 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
575 return ret;
576 }
577
578 return 0;
579}
580
581static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
582 struct snd_pcm_hw_params *params,
583 struct snd_soc_dai *cpu_dai)
584{
585 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
586 int ret;
587
588 sai->data_size = params_width(params);
589
590 ret = stm32_sai_set_slots(cpu_dai);
591 if (ret < 0)
592 return ret;
593 stm32_sai_set_frame(cpu_dai);
594
595 ret = stm32_sai_set_config(cpu_dai, substream, params);
596 if (ret)
597 return ret;
598
599 if (sai->master)
600 ret = stm32_sai_configure_clock(cpu_dai, params);
601
602 return ret;
603}
604
605static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
606 struct snd_soc_dai *cpu_dai)
607{
608 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
609 int ret;
610
611 switch (cmd) {
612 case SNDRV_PCM_TRIGGER_START:
613 case SNDRV_PCM_TRIGGER_RESUME:
614 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
615 dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n");
616
617 regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
618 SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
619
620 /* Enable SAI */
621 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
622 SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
623 if (ret < 0)
624 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
625 break;
626 case SNDRV_PCM_TRIGGER_SUSPEND:
627 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
628 case SNDRV_PCM_TRIGGER_STOP:
629 dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n");
630
631 regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
632 SAI_XCR1_DMAEN,
633 (unsigned int)~SAI_XCR1_DMAEN);
634
635 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
636 SAI_XCR1_SAIEN,
637 (unsigned int)~SAI_XCR1_SAIEN);
638 if (ret < 0)
639 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
640 break;
641 default:
642 return -EINVAL;
643 }
644
645 return ret;
646}
647
648static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
649 struct snd_soc_dai *cpu_dai)
650{
651 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
652
653 regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
654
655 clk_disable_unprepare(sai->sai_ck);
656 sai->substream = NULL;
657}
658
659static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
660{
661 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
662
663 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
664 sai->dma_params.maxburst = 1;
665 /* Buswidth will be set by framework at runtime */
666 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
667
668 if (STM_SAI_IS_PLAYBACK(sai))
669 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params, NULL);
670 else
671 snd_soc_dai_init_dma_data(cpu_dai, NULL, &sai->dma_params);
672
673 return 0;
674}
675
676static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
677 .set_sysclk = stm32_sai_set_sysclk,
678 .set_fmt = stm32_sai_set_dai_fmt,
679 .set_tdm_slot = stm32_sai_set_dai_tdm_slot,
680 .startup = stm32_sai_startup,
681 .hw_params = stm32_sai_hw_params,
682 .trigger = stm32_sai_trigger,
683 .shutdown = stm32_sai_shutdown,
684};
685
686static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
687 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
688 .buffer_bytes_max = 8 * PAGE_SIZE,
689 .period_bytes_min = 1024, /* 5ms at 48kHz */
690 .period_bytes_max = PAGE_SIZE,
691 .periods_min = 2,
692 .periods_max = 8,
693};
694
695static struct snd_soc_dai_driver stm32_sai_playback_dai[] = {
696{
697 .probe = stm32_sai_dai_probe,
698 .id = 1, /* avoid call to fmt_single_name() */
699 .playback = {
700 .channels_min = 1,
701 .channels_max = 2,
702 .rate_min = 8000,
703 .rate_max = 192000,
704 .rates = SNDRV_PCM_RATE_CONTINUOUS,
705 /* DMA does not support 24 bits transfers */
706 .formats =
707 SNDRV_PCM_FMTBIT_S8 |
708 SNDRV_PCM_FMTBIT_S16_LE |
709 SNDRV_PCM_FMTBIT_S32_LE,
710 },
711 .ops = &stm32_sai_pcm_dai_ops,
712 }
713};
714
715static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
716{
717 .probe = stm32_sai_dai_probe,
718 .id = 1, /* avoid call to fmt_single_name() */
719 .capture = {
720 .channels_min = 1,
721 .channels_max = 2,
722 .rate_min = 8000,
723 .rate_max = 192000,
724 .rates = SNDRV_PCM_RATE_CONTINUOUS,
725 /* DMA does not support 24 bits transfers */
726 .formats =
727 SNDRV_PCM_FMTBIT_S8 |
728 SNDRV_PCM_FMTBIT_S16_LE |
729 SNDRV_PCM_FMTBIT_S32_LE,
730 },
731 .ops = &stm32_sai_pcm_dai_ops,
732 }
733};
734
735static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
736 .pcm_hardware = &stm32_sai_pcm_hw,
737 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
738};
739
740static const struct snd_soc_component_driver stm32_component = {
741 .name = "stm32-sai",
742};
743
744static const struct of_device_id stm32_sai_sub_ids[] = {
745 { .compatible = "st,stm32-sai-sub-a",
746 .data = (void *)STM_SAI_A_ID},
747 { .compatible = "st,stm32-sai-sub-b",
748 .data = (void *)STM_SAI_B_ID},
749 {}
750};
751MODULE_DEVICE_TABLE(of, stm32_sai_sub_ids);
752
753static int stm32_sai_sub_parse_of(struct platform_device *pdev,
754 struct stm32_sai_sub_data *sai)
755{
756 struct device_node *np = pdev->dev.of_node;
757 struct resource *res;
758 void __iomem *base;
759
760 if (!np)
761 return -ENODEV;
762
763 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
764
765 dev_err(&pdev->dev, "res %pr\n", res);
766
767 base = devm_ioremap_resource(&pdev->dev, res);
768 if (IS_ERR(base))
769 return PTR_ERR(base);
770
771 sai->phys_addr = res->start;
772 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
773 &stm32_sai_sub_regmap_config);
774
775 /* Get direction property */
776 if (of_property_match_string(np, "dma-names", "tx") >= 0) {
777 sai->dir = SNDRV_PCM_STREAM_PLAYBACK;
778 } else if (of_property_match_string(np, "dma-names", "rx") >= 0) {
779 sai->dir = SNDRV_PCM_STREAM_CAPTURE;
780 } else {
781 dev_err(&pdev->dev, "Unsupported direction\n");
782 return -EINVAL;
783 }
784
785 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
786 if (IS_ERR(sai->sai_ck)) {
787 dev_err(&pdev->dev, "missing kernel clock sai_ck\n");
788 return PTR_ERR(sai->sai_ck);
789 }
790
791 return 0;
792}
793
794static int stm32_sai_sub_dais_init(struct platform_device *pdev,
795 struct stm32_sai_sub_data *sai)
796{
797 sai->cpu_dai_drv = devm_kzalloc(&pdev->dev,
798 sizeof(struct snd_soc_dai_driver),
799 GFP_KERNEL);
800 if (!sai->cpu_dai_drv)
801 return -ENOMEM;
802
803 sai->cpu_dai_drv->name = dev_name(&pdev->dev);
804 if (STM_SAI_IS_PLAYBACK(sai)) {
805 memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai,
806 sizeof(stm32_sai_playback_dai));
807 sai->cpu_dai_drv->playback.stream_name = sai->cpu_dai_drv->name;
808 } else {
809 memcpy(sai->cpu_dai_drv, &stm32_sai_capture_dai,
810 sizeof(stm32_sai_capture_dai));
811 sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name;
812 }
813
814 return 0;
815}
816
817static int stm32_sai_sub_probe(struct platform_device *pdev)
818{
819 struct stm32_sai_sub_data *sai;
820 const struct of_device_id *of_id;
821 int ret;
822
823 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
824 if (!sai)
825 return -ENOMEM;
826
827 of_id = of_match_device(stm32_sai_sub_ids, &pdev->dev);
828 if (!of_id)
829 return -EINVAL;
830 sai->id = (uintptr_t)of_id->data;
831
832 sai->pdev = pdev;
833 platform_set_drvdata(pdev, sai);
834
835 sai->pdata = dev_get_drvdata(pdev->dev.parent);
836 if (!sai->pdata) {
837 dev_err(&pdev->dev, "Parent device data not available\n");
838 return -EINVAL;
839 }
840
841 ret = stm32_sai_sub_parse_of(pdev, sai);
842 if (ret)
843 return ret;
844
845 ret = stm32_sai_sub_dais_init(pdev, sai);
846 if (ret)
847 return ret;
848
849 ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
850 IRQF_SHARED, dev_name(&pdev->dev), sai);
851 if (ret) {
852 dev_err(&pdev->dev, "irq request returned %d\n", ret);
853 return ret;
854 }
855
856 ret = devm_snd_soc_register_component(&pdev->dev, &stm32_component,
857 sai->cpu_dai_drv, 1);
858 if (ret)
859 return ret;
860
861 ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
862 &stm32_sai_pcm_config, 0);
863 if (ret) {
864 dev_err(&pdev->dev, "could not register pcm dma\n");
865 return ret;
866 }
867
868 return 0;
869}
870
871static struct platform_driver stm32_sai_sub_driver = {
872 .driver = {
873 .name = "st,stm32-sai-sub",
874 .of_match_table = stm32_sai_sub_ids,
875 },
876 .probe = stm32_sai_sub_probe,
877};
878
879module_platform_driver(stm32_sai_sub_driver);
880
881MODULE_DESCRIPTION("STM32 Soc SAI sub-block Interface");
882MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>");
883MODULE_ALIAS("platform:st,stm32-sai-sub");
884MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
index 72331332b72e..6c17c99c2c8d 100644
--- a/sound/soc/sunxi/sun8i-codec-analog.c
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -252,24 +252,15 @@ static const DECLARE_TLV_DB_RANGE(sun8i_codec_mic_gain_scale,
252); 252);
253 253
254static const struct snd_kcontrol_new sun8i_codec_common_controls[] = { 254static const struct snd_kcontrol_new sun8i_codec_common_controls[] = {
255 /* Mixer pre-gains */ 255 /* Mixer pre-gain */
256 SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
257 SUN8I_ADDA_LINEIN_GCTRL_LINEING,
258 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
259 SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL, 256 SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL,
260 SUN8I_ADDA_MICIN_GCTRL_MIC1G, 257 SUN8I_ADDA_MICIN_GCTRL_MIC1G,
261 0x7, 0, sun8i_codec_out_mixer_pregain_scale), 258 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
262 SOC_SINGLE_TLV("Mic2 Playback Volume",
263 SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
264 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
265 259
266 /* Microphone Amp boost gains */ 260 /* Microphone Amp boost gain */
267 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 261 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
268 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0, 262 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0,
269 sun8i_codec_mic_gain_scale), 263 sun8i_codec_mic_gain_scale),
270 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
271 SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
272 sun8i_codec_mic_gain_scale),
273 264
274 /* ADC */ 265 /* ADC */
275 SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN, 266 SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN,
@@ -295,12 +286,8 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
295 * stream widgets at the card level. 286 * stream widgets at the card level.
296 */ 287 */
297 288
298 /* Line In */ 289 /* Microphone input */
299 SND_SOC_DAPM_INPUT("LINEIN"),
300
301 /* Microphone inputs */
302 SND_SOC_DAPM_INPUT("MIC1"), 290 SND_SOC_DAPM_INPUT("MIC1"),
303 SND_SOC_DAPM_INPUT("MIC2"),
304 291
305 /* Microphone Bias */ 292 /* Microphone Bias */
306 SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 293 SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
@@ -310,8 +297,6 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
310 /* Mic input path */ 297 /* Mic input path */
311 SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 298 SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
312 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0), 299 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0),
313 SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
314 SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
315 300
316 /* Mixers */ 301 /* Mixers */
317 SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC, 302 SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
@@ -335,35 +320,26 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
335static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = { 320static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = {
336 /* Microphone Routes */ 321 /* Microphone Routes */
337 { "Mic1 Amplifier", NULL, "MIC1"}, 322 { "Mic1 Amplifier", NULL, "MIC1"},
338 { "Mic2 Amplifier", NULL, "MIC2"},
339 323
340 /* Left Mixer Routes */ 324 /* Left Mixer Routes */
341 { "Left Mixer", "DAC Playback Switch", "Left DAC" }, 325 { "Left Mixer", "DAC Playback Switch", "Left DAC" },
342 { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, 326 { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
343 { "Left Mixer", "Line In Playback Switch", "LINEIN" },
344 { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 327 { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
345 { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
346 328
347 /* Right Mixer Routes */ 329 /* Right Mixer Routes */
348 { "Right Mixer", "DAC Playback Switch", "Right DAC" }, 330 { "Right Mixer", "DAC Playback Switch", "Right DAC" },
349 { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, 331 { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
350 { "Right Mixer", "Line In Playback Switch", "LINEIN" },
351 { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 332 { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
352 { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
353 333
354 /* Left ADC Mixer Routes */ 334 /* Left ADC Mixer Routes */
355 { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, 335 { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
356 { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, 336 { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
357 { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
358 { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 337 { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
359 { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
360 338
361 /* Right ADC Mixer Routes */ 339 /* Right ADC Mixer Routes */
362 { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, 340 { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
363 { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, 341 { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
364 { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
365 { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 342 { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
366 { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
367 343
368 /* ADC Routes */ 344 /* ADC Routes */
369 { "Left ADC", NULL, "Left ADC Mixer" }, 345 { "Left ADC", NULL, "Left ADC Mixer" },
@@ -498,6 +474,61 @@ static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt)
498 return ret; 474 return ret;
499} 475}
500 476
477/* line in specific controls, widgets and rines */
478static const struct snd_kcontrol_new sun8i_codec_linein_controls[] = {
479 /* Mixer pre-gain */
480 SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
481 SUN8I_ADDA_LINEIN_GCTRL_LINEING,
482 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
483};
484
485static const struct snd_soc_dapm_widget sun8i_codec_linein_widgets[] = {
486 /* Line input */
487 SND_SOC_DAPM_INPUT("LINEIN"),
488};
489
490static const struct snd_soc_dapm_route sun8i_codec_linein_routes[] = {
491 { "Left Mixer", "Line In Playback Switch", "LINEIN" },
492
493 { "Right Mixer", "Line In Playback Switch", "LINEIN" },
494
495 { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
496
497 { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
498};
499
500static int sun8i_codec_add_linein(struct snd_soc_component *cmpnt)
501{
502 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
503 struct device *dev = cmpnt->dev;
504 int ret;
505
506 ret = snd_soc_add_component_controls(cmpnt,
507 sun8i_codec_linein_controls,
508 ARRAY_SIZE(sun8i_codec_linein_controls));
509 if (ret) {
510 dev_err(dev, "Failed to add Line In controls: %d\n", ret);
511 return ret;
512 }
513
514 ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_linein_widgets,
515 ARRAY_SIZE(sun8i_codec_linein_widgets));
516 if (ret) {
517 dev_err(dev, "Failed to add Line In DAPM widgets: %d\n", ret);
518 return ret;
519 }
520
521 ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_linein_routes,
522 ARRAY_SIZE(sun8i_codec_linein_routes));
523 if (ret) {
524 dev_err(dev, "Failed to add Line In DAPM routes: %d\n", ret);
525 return ret;
526 }
527
528 return 0;
529}
530
531
501/* line out specific controls, widgets and routes */ 532/* line out specific controls, widgets and routes */
502static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale, 533static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale,
503 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 534 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
@@ -578,19 +609,90 @@ static int sun8i_codec_add_lineout(struct snd_soc_component *cmpnt)
578 return 0; 609 return 0;
579} 610}
580 611
612/* mic2 specific controls, widgets and routes */
613static const struct snd_kcontrol_new sun8i_codec_mic2_controls[] = {
614 /* Mixer pre-gain */
615 SOC_SINGLE_TLV("Mic2 Playback Volume",
616 SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
617 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
618
619 /* Microphone Amp boost gain */
620 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
621 SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
622 sun8i_codec_mic_gain_scale),
623};
624
625static const struct snd_soc_dapm_widget sun8i_codec_mic2_widgets[] = {
626 /* Microphone input */
627 SND_SOC_DAPM_INPUT("MIC2"),
628
629 /* Mic input path */
630 SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
631 SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
632};
633
634static const struct snd_soc_dapm_route sun8i_codec_mic2_routes[] = {
635 { "Mic2 Amplifier", NULL, "MIC2"},
636
637 { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
638
639 { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
640
641 { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
642
643 { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
644};
645
646static int sun8i_codec_add_mic2(struct snd_soc_component *cmpnt)
647{
648 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
649 struct device *dev = cmpnt->dev;
650 int ret;
651
652 ret = snd_soc_add_component_controls(cmpnt,
653 sun8i_codec_mic2_controls,
654 ARRAY_SIZE(sun8i_codec_mic2_controls));
655 if (ret) {
656 dev_err(dev, "Failed to add MIC2 controls: %d\n", ret);
657 return ret;
658 }
659
660 ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_mic2_widgets,
661 ARRAY_SIZE(sun8i_codec_mic2_widgets));
662 if (ret) {
663 dev_err(dev, "Failed to add MIC2 DAPM widgets: %d\n", ret);
664 return ret;
665 }
666
667 ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_mic2_routes,
668 ARRAY_SIZE(sun8i_codec_mic2_routes));
669 if (ret) {
670 dev_err(dev, "Failed to add MIC2 DAPM routes: %d\n", ret);
671 return ret;
672 }
673
674 return 0;
675}
676
581struct sun8i_codec_analog_quirks { 677struct sun8i_codec_analog_quirks {
582 bool has_headphone; 678 bool has_headphone;
583 bool has_hmic; 679 bool has_hmic;
680 bool has_linein;
584 bool has_lineout; 681 bool has_lineout;
682 bool has_mic2;
585}; 683};
586 684
587static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = { 685static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = {
588 .has_headphone = true, 686 .has_headphone = true,
589 .has_hmic = true, 687 .has_hmic = true,
688 .has_linein = true,
689 .has_mic2 = true,
590}; 690};
591 691
592static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = { 692static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = {
693 .has_linein = true,
593 .has_lineout = true, 694 .has_lineout = true,
695 .has_mic2 = true,
594}; 696};
595 697
596static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt) 698static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
@@ -620,12 +722,24 @@ static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
620 return ret; 722 return ret;
621 } 723 }
622 724
725 if (quirks->has_linein) {
726 ret = sun8i_codec_add_linein(cmpnt);
727 if (ret)
728 return ret;
729 }
730
623 if (quirks->has_lineout) { 731 if (quirks->has_lineout) {
624 ret = sun8i_codec_add_lineout(cmpnt); 732 ret = sun8i_codec_add_lineout(cmpnt);
625 if (ret) 733 if (ret)
626 return ret; 734 return ret;
627 } 735 }
628 736
737 if (quirks->has_mic2) {
738 ret = sun8i_codec_add_mic2(cmpnt);
739 if (ret)
740 return ret;
741 }
742
629 return 0; 743 return 0;
630} 744}
631 745
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7527ba29a5a0..5723c3404f6b 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -290,12 +290,10 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
290 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0), 290 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
291 291
292 /* DAC Mixers */ 292 /* DAC Mixers */
293 SND_SOC_DAPM_MIXER("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0, 293 SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
294 sun8i_dac_mixer_controls, 294 sun8i_dac_mixer_controls),
295 ARRAY_SIZE(sun8i_dac_mixer_controls)), 295 SOC_MIXER_ARRAY("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
296 SND_SOC_DAPM_MIXER("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0, 296 sun8i_dac_mixer_controls),
297 sun8i_dac_mixer_controls,
298 ARRAY_SIZE(sun8i_dac_mixer_controls)),
299 297
300 /* Clocks */ 298 /* Clocks */
301 SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA, 299 SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index a68368edab9c..affad46bf188 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -318,7 +318,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
318 ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97), 318 ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97),
319 GFP_KERNEL); 319 GFP_KERNEL);
320 if (!ac97) { 320 if (!ac97) {
321 dev_err(&pdev->dev, "Can't allocate tegra20_ac97\n");
322 ret = -ENOMEM; 321 ret = -ENOMEM;
323 goto err; 322 goto err;
324 } 323 }
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index 89add13c31cf..4024e3abbeed 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -41,6 +41,7 @@ static inline void tegra20_das_write(u32 reg, u32 val)
41static inline u32 tegra20_das_read(u32 reg) 41static inline u32 tegra20_das_read(u32 reg)
42{ 42{
43 u32 val; 43 u32 val;
44
44 regmap_read(das->regmap, reg, &val); 45 regmap_read(das->regmap, reg, &val);
45 return val; 46 return val;
46} 47}
@@ -142,7 +143,6 @@ static int tegra20_das_probe(struct platform_device *pdev)
142 143
143 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL); 144 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL);
144 if (!das) { 145 if (!das) {
145 dev_err(&pdev->dev, "Can't allocate tegra20_das\n");
146 ret = -ENOMEM; 146 ret = -ENOMEM;
147 goto err; 147 goto err;
148 } 148 }
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 14106fa82bca..26253c2849e7 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -345,7 +345,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
345 345
346 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL); 346 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
347 if (!i2s) { 347 if (!i2s) {
348 dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
349 ret = -ENOMEM; 348 ret = -ENOMEM;
350 goto err; 349 goto err;
351 } 350 }
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index a0c3640572b9..767c0491e11a 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -271,10 +271,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
271 271
272 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif), 272 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
273 GFP_KERNEL); 273 GFP_KERNEL);
274 if (!spdif) { 274 if (!spdif)
275 dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
276 return -ENOMEM; 275 return -ENOMEM;
277 } 276
278 dev_set_drvdata(&pdev->dev, spdif); 277 dev_set_drvdata(&pdev->dev, spdif);
279 278
280 spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "spdif_out"); 279 spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "spdif_out");
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index fef3b9a21a66..8c10ae7982ba 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -41,6 +41,7 @@ static inline void tegra30_apbif_write(u32 reg, u32 val)
41static inline u32 tegra30_apbif_read(u32 reg) 41static inline u32 tegra30_apbif_read(u32 reg)
42{ 42{
43 u32 val; 43 u32 val;
44
44 regmap_read(ahub->regmap_apbif, reg, &val); 45 regmap_read(ahub->regmap_apbif, reg, &val);
45 return val; 46 return val;
46} 47}
@@ -560,10 +561,8 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
560 561
561 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), 562 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
562 GFP_KERNEL); 563 GFP_KERNEL);
563 if (!ahub) { 564 if (!ahub)
564 dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n");
565 return -ENOMEM; 565 return -ENOMEM;
566 }
567 dev_set_drvdata(&pdev->dev, ahub); 566 dev_set_drvdata(&pdev->dev, ahub);
568 567
569 ahub->soc_data = soc_data; 568 ahub->soc_data = soc_data;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 8e55583aa104..b2b279c96029 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -385,7 +385,6 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
385 385
386 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); 386 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
387 if (!i2s) { 387 if (!i2s) {
388 dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
389 ret = -ENOMEM; 388 ret = -ENOMEM;
390 goto err; 389 goto err;
391 } 390 }
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index eead6e7f205b..0509902512cc 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -169,10 +169,8 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
169 169
170 alc5632 = devm_kzalloc(&pdev->dev, 170 alc5632 = devm_kzalloc(&pdev->dev,
171 sizeof(struct tegra_alc5632), GFP_KERNEL); 171 sizeof(struct tegra_alc5632), GFP_KERNEL);
172 if (!alc5632) { 172 if (!alc5632)
173 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
174 return -ENOMEM; 173 return -ENOMEM;
175 }
176 174
177 card->dev = &pdev->dev; 175 card->dev = &pdev->dev;
178 platform_set_drvdata(pdev, card); 176 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c
index a403db6d563e..c34a54d6e812 100644
--- a/sound/soc/tegra/tegra_max98090.c
+++ b/sound/soc/tegra/tegra_max98090.c
@@ -225,10 +225,8 @@ static int tegra_max98090_probe(struct platform_device *pdev)
225 225
226 machine = devm_kzalloc(&pdev->dev, 226 machine = devm_kzalloc(&pdev->dev,
227 sizeof(struct tegra_max98090), GFP_KERNEL); 227 sizeof(struct tegra_max98090), GFP_KERNEL);
228 if (!machine) { 228 if (!machine)
229 dev_err(&pdev->dev, "Can't allocate tegra_max98090\n");
230 return -ENOMEM; 229 return -ENOMEM;
231 }
232 230
233 card->dev = &pdev->dev; 231 card->dev = &pdev->dev;
234 platform_set_drvdata(pdev, card); 232 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 25b9fc03ba62..93a356802345 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -170,10 +170,8 @@ static int tegra_rt5640_probe(struct platform_device *pdev)
170 170
171 machine = devm_kzalloc(&pdev->dev, 171 machine = devm_kzalloc(&pdev->dev,
172 sizeof(struct tegra_rt5640), GFP_KERNEL); 172 sizeof(struct tegra_rt5640), GFP_KERNEL);
173 if (!machine) { 173 if (!machine)
174 dev_err(&pdev->dev, "Can't allocate tegra_rt5640\n");
175 return -ENOMEM; 174 return -ENOMEM;
176 }
177 175
178 card->dev = &pdev->dev; 176 card->dev = &pdev->dev;
179 platform_set_drvdata(pdev, card); 177 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c
index 4bbab098f50b..6dda01f69983 100644
--- a/sound/soc/tegra/tegra_sgtl5000.c
+++ b/sound/soc/tegra/tegra_sgtl5000.c
@@ -120,10 +120,8 @@ static int tegra_sgtl5000_driver_probe(struct platform_device *pdev)
120 120
121 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000), 121 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000),
122 GFP_KERNEL); 122 GFP_KERNEL);
123 if (!machine) { 123 if (!machine)
124 dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n");
125 return -ENOMEM; 124 return -ENOMEM;
126 }
127 125
128 card->dev = &pdev->dev; 126 card->dev = &pdev->dev;
129 platform_set_drvdata(pdev, card); 127 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index bdedd1028569..d0ab0026a4cd 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -128,10 +128,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
128 128
129 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753), 129 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753),
130 GFP_KERNEL); 130 GFP_KERNEL);
131 if (!machine) { 131 if (!machine)
132 dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
133 return -ENOMEM; 132 return -ENOMEM;
134 }
135 133
136 card->dev = &pdev->dev; 134 card->dev = &pdev->dev;
137 platform_set_drvdata(pdev, card); 135 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 2013e9c4bba0..dbfb49298ae8 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -248,10 +248,8 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
248 248
249 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), 249 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
250 GFP_KERNEL); 250 GFP_KERNEL);
251 if (!machine) { 251 if (!machine)
252 dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
253 return -ENOMEM; 252 return -ENOMEM;
254 }
255 253
256 card->dev = &pdev->dev; 254 card->dev = &pdev->dev;
257 platform_set_drvdata(pdev, card); 255 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 6492f8143ff1..c9cd22432627 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -77,10 +77,8 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev)
77 77
78 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712), 78 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
79 GFP_KERNEL); 79 GFP_KERNEL);
80 if (!machine) { 80 if (!machine)
81 dev_err(&pdev->dev, "Can't allocate tegra_wm9712 struct\n");
82 return -ENOMEM; 81 return -ENOMEM;
83 }
84 82
85 card->dev = &pdev->dev; 83 card->dev = &pdev->dev;
86 platform_set_drvdata(pdev, card); 84 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 870f84ab5005..c9dcad9bb931 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -123,10 +123,8 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev)
123 123
124 trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice), 124 trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice),
125 GFP_KERNEL); 125 GFP_KERNEL);
126 if (!trimslice) { 126 if (!trimslice)
127 dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
128 return -ENOMEM; 127 return -ENOMEM;
129 }
130 128
131 card->dev = &pdev->dev; 129 card->dev = &pdev->dev;
132 platform_set_drvdata(pdev, card); 130 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index a8f705bb60dc..7912bf09dc4d 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -206,7 +206,7 @@ static void txx9aclc_dma_tasklet(unsigned long data)
206static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 206static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
207{ 207{
208 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; 208 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
209 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; 209 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
210 void __iomem *base = drvdata->base; 210 void __iomem *base = drvdata->base;
211 unsigned long flags; 211 unsigned long flags;
212 int ret = 0; 212 int ret = 0;
@@ -340,7 +340,7 @@ static bool filter(struct dma_chan *chan, void *param)
340static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, 340static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
341 struct txx9aclc_dmadata *dmadata) 341 struct txx9aclc_dmadata *dmadata)
342{ 342{
343 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; 343 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
344 struct txx9dmac_slave *ds = &dmadata->dma_slave; 344 struct txx9dmac_slave *ds = &dmadata->dma_slave;
345 dma_cap_mask_t mask; 345 dma_cap_mask_t mask;
346 346
@@ -392,6 +392,7 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
392 for (i = 0; i < 2; i++) { 392 for (i = 0; i < 2; i++) {
393 struct txx9aclc_dmadata *dmadata = &dev->dmadata[i]; 393 struct txx9aclc_dmadata *dmadata = &dev->dmadata[i];
394 struct dma_chan *chan = dmadata->dma_chan; 394 struct dma_chan *chan = dmadata->dma_chan;
395
395 if (chan) { 396 if (chan) {
396 dmadata->frag_count = -1; 397 dmadata->frag_count = -1;
397 dmaengine_terminate_all(chan); 398 dmaengine_terminate_all(chan);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index ba9fc099cf67..b50f68a439ce 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -33,7 +33,6 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
33 .stream_name = "ab8500_0", 33 .stream_name = "ab8500_0",
34 .cpu_dai_name = "ux500-msp-i2s.1", 34 .cpu_dai_name = "ux500-msp-i2s.1",
35 .codec_dai_name = "ab8500-codec-dai.0", 35 .codec_dai_name = "ab8500-codec-dai.0",
36 .platform_name = "ux500-msp-i2s.1",
37 .codec_name = "ab8500-codec.0", 36 .codec_name = "ab8500-codec.0",
38 .init = mop500_ab8500_machine_init, 37 .init = mop500_ab8500_machine_init,
39 .ops = mop500_ab8500_ops, 38 .ops = mop500_ab8500_ops,
@@ -43,7 +42,6 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
43 .stream_name = "ab8500_1", 42 .stream_name = "ab8500_1",
44 .cpu_dai_name = "ux500-msp-i2s.3", 43 .cpu_dai_name = "ux500-msp-i2s.3",
45 .codec_dai_name = "ab8500-codec-dai.1", 44 .codec_dai_name = "ab8500-codec-dai.1",
46 .platform_name = "ux500-msp-i2s.3",
47 .codec_name = "ab8500-codec.0", 45 .codec_name = "ab8500-codec.0",
48 .init = NULL, 46 .init = NULL,
49 .ops = mop500_ab8500_ops, 47 .ops = mop500_ab8500_ops,
@@ -87,8 +85,6 @@ static int mop500_of_probe(struct platform_device *pdev,
87 for (i = 0; i < 2; i++) { 85 for (i = 0; i < 2; i++) {
88 mop500_dai_links[i].cpu_of_node = msp_np[i]; 86 mop500_dai_links[i].cpu_of_node = msp_np[i];
89 mop500_dai_links[i].cpu_dai_name = NULL; 87 mop500_dai_links[i].cpu_dai_name = NULL;
90 mop500_dai_links[i].platform_of_node = msp_np[i];
91 mop500_dai_links[i].platform_name = NULL;
92 mop500_dai_links[i].codec_of_node = codec_np; 88 mop500_dai_links[i].codec_of_node = codec_np;
93 mop500_dai_links[i].codec_name = NULL; 89 mop500_dai_links[i].codec_name = NULL;
94 } 90 }
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index b343efd9be5b..ec5152aa3f6e 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -133,6 +133,7 @@ static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
133 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 133 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
134 134
135 u32 frame_length = MSP_FRAME_LEN_1; 135 u32 frame_length = MSP_FRAME_LEN_1;
136
136 prot_desc->frame_width = 0; 137 prot_desc->frame_width = 0;
137 138
138 switch (drvdata->slots) { 139 switch (drvdata->slots) {
@@ -482,7 +483,8 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
482 if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) && 483 if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) &&
483 (drvdata->msp->f_bitclk > 19200000)) { 484 (drvdata->msp->f_bitclk > 19200000)) {
484 /* If the bit-clock is higher than 19.2MHz, Vape should be 485 /* If the bit-clock is higher than 19.2MHz, Vape should be
485 * run in 100% OPP. Only when bit-clock is used (MSP master) */ 486 * run in 100% OPP. Only when bit-clock is used (MSP master)
487 */
486 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, 488 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
487 "ux500-msp-i2s", 100); 489 "ux500-msp-i2s", 100);
488 drvdata->vape_opp_constraint = 1; 490 drvdata->vape_opp_constraint = 1;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 959d7b4edf56..bd5266aca0f1 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -604,7 +604,6 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
604 break; 604 break;
605 default: 605 default:
606 return -EINVAL; 606 return -EINVAL;
607 break;
608 } 607 }
609 608
610 return 0; 609 return 0;
diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig
index 6d8a90d36315..75f67a5d23ea 100644
--- a/sound/soc/zte/Kconfig
+++ b/sound/soc/zte/Kconfig
@@ -15,3 +15,11 @@ config ZX_I2S
15 help 15 help
16 Say Y or M if you want to add support for codecs attached to the 16 Say Y or M if you want to add support for codecs attached to the
17 ZTE ZX I2S interface 17 ZTE ZX I2S interface
18
19config ZX_TDM
20 tristate "ZTE ZX TDM Driver Support"
21 depends on COMMON_CLK
22 select SND_SOC_GENERIC_DMAENGINE_PCM
23 help
24 Say Y or M if you want to add support for codecs attached to the
25 ZTE ZX TDM interface
diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile
index 77768f5fd10c..1fc841acdfdd 100644
--- a/sound/soc/zte/Makefile
+++ b/sound/soc/zte/Makefile
@@ -1,2 +1,3 @@
1obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o 1obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o
2obj-$(CONFIG_ZX_I2S) += zx-i2s.o 2obj-$(CONFIG_ZX_I2S) += zx-i2s.o
3obj-$(CONFIG_ZX_TDM) += zx-tdm.o
diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c
new file mode 100644
index 000000000000..bd632cc503b3
--- /dev/null
+++ b/sound/soc/zte/zx-tdm.c
@@ -0,0 +1,461 @@
1/*
2 * ZTE's TDM driver
3 *
4 * Copyright (C) 2017 ZTE Ltd
5 *
6 * Author: Baoyou Xie <baoyou.xie@linaro.org>
7 *
8 * License terms: GNU General Public License (GPL) version 2
9 */
10
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <sound/dmaengine_pcm.h>
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18#include <sound/soc-dai.h>
19
20#define REG_TIMING_CTRL 0x04
21#define REG_TX_FIFO_CTRL 0x0C
22#define REG_RX_FIFO_CTRL 0x10
23#define REG_INT_EN 0x1C
24#define REG_INT_STATUS 0x20
25#define REG_DATABUF 0x24
26#define REG_TS_MASK0 0x44
27#define REG_PROCESS_CTRL 0x54
28
29#define FIFO_CTRL_TX_RST BIT(0)
30#define FIFO_CTRL_RX_RST BIT(0)
31#define DEAGULT_FIFO_THRES GENMASK(4, 2)
32
33#define FIFO_CTRL_TX_DMA_EN BIT(1)
34#define FIFO_CTRL_RX_DMA_EN BIT(1)
35
36#define TX_FIFO_RST_MASK BIT(0)
37#define RX_FIFO_RST_MASK BIT(0)
38
39#define FIFOCTRL_TX_FIFO_RST BIT(0)
40#define FIFOCTRL_RX_FIFO_RST BIT(0)
41
42#define TXTH_MASK GENMASK(5, 2)
43#define RXTH_MASK GENMASK(5, 2)
44
45#define FIFOCTRL_THRESHOLD(x) ((x) << 2)
46
47#define TIMING_MS_MASK BIT(1)
48/*
49 * 00: 8 clk cycles every timeslot
50 * 01: 16 clk cycles every timeslot
51 * 10: 32 clk cycles every timeslot
52 */
53#define TIMING_SYNC_WIDTH_MASK GENMASK(6, 5)
54#define TIMING_WIDTH_SHIFT 5
55#define TIMING_DEFAULT_WIDTH 0
56#define TIMING_TS_WIDTH(x) ((x) << TIMING_WIDTH_SHIFT)
57#define TIMING_WIDTH_FACTOR 8
58
59#define TIMING_MASTER_MODE BIT(21)
60#define TIMING_LSB_FIRST BIT(20)
61#define TIMING_TS_NUM(x) (((x) - 1) << 7)
62#define TIMING_CLK_SEL_MASK GENMASK(2, 0)
63#define TIMING_CLK_SEL_DEF BIT(2)
64
65#define PROCESS_TX_EN BIT(0)
66#define PROCESS_RX_EN BIT(1)
67#define PROCESS_TDM_EN BIT(2)
68#define PROCESS_DISABLE_ALL 0
69
70#define INT_DISABLE_ALL 0
71#define INT_STATUS_MASK GENMASK(6, 0)
72
73struct zx_tdm_info {
74 struct snd_dmaengine_dai_dma_data dma_playback;
75 struct snd_dmaengine_dai_dma_data dma_capture;
76 resource_size_t phy_addr;
77 void __iomem *regbase;
78 struct clk *dai_wclk;
79 struct clk *dai_pclk;
80 int master;
81 struct device *dev;
82};
83
84static inline u32 zx_tdm_readl(struct zx_tdm_info *tdm, u16 reg)
85{
86 return readl_relaxed(tdm->regbase + reg);
87}
88
89static inline void zx_tdm_writel(struct zx_tdm_info *tdm, u16 reg, u32 val)
90{
91 writel_relaxed(val, tdm->regbase + reg);
92}
93
94static void zx_tdm_tx_en(struct zx_tdm_info *tdm, bool on)
95{
96 unsigned long val;
97
98 val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
99 if (on)
100 val |= PROCESS_TX_EN | PROCESS_TDM_EN;
101 else
102 val &= ~(PROCESS_TX_EN | PROCESS_TDM_EN);
103 zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
104}
105
106static void zx_tdm_rx_en(struct zx_tdm_info *tdm, bool on)
107{
108 unsigned long val;
109
110 val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
111 if (on)
112 val |= PROCESS_RX_EN | PROCESS_TDM_EN;
113 else
114 val &= ~(PROCESS_RX_EN | PROCESS_TDM_EN);
115 zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
116}
117
118static void zx_tdm_tx_dma_en(struct zx_tdm_info *tdm, bool on)
119{
120 unsigned long val;
121
122 val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
123 val |= FIFO_CTRL_TX_RST | DEAGULT_FIFO_THRES;
124 if (on)
125 val |= FIFO_CTRL_TX_DMA_EN;
126 else
127 val &= ~FIFO_CTRL_TX_DMA_EN;
128 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
129}
130
131static void zx_tdm_rx_dma_en(struct zx_tdm_info *tdm, bool on)
132{
133 unsigned long val;
134
135 val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
136 val |= FIFO_CTRL_RX_RST | DEAGULT_FIFO_THRES;
137 if (on)
138 val |= FIFO_CTRL_RX_DMA_EN;
139 else
140 val &= ~FIFO_CTRL_RX_DMA_EN;
141 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
142}
143
144#define ZX_TDM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
145
146#define ZX_TDM_FMTBIT \
147 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_MU_LAW | \
148 SNDRV_PCM_FORMAT_A_LAW)
149
150static int zx_tdm_dai_probe(struct snd_soc_dai *dai)
151{
152 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
153
154 snd_soc_dai_set_drvdata(dai, zx_tdm);
155 zx_tdm->dma_playback.addr = zx_tdm->phy_addr + REG_DATABUF;
156 zx_tdm->dma_playback.maxburst = 16;
157 zx_tdm->dma_capture.addr = zx_tdm->phy_addr + REG_DATABUF;
158 zx_tdm->dma_capture.maxburst = 16;
159 snd_soc_dai_init_dma_data(dai, &zx_tdm->dma_playback,
160 &zx_tdm->dma_capture);
161 return 0;
162}
163
164static int zx_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
165{
166 struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(cpu_dai);
167 unsigned long val;
168
169 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
170 val &= ~(TIMING_SYNC_WIDTH_MASK | TIMING_MS_MASK);
171 val |= TIMING_DEFAULT_WIDTH << TIMING_WIDTH_SHIFT;
172
173 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
174 case SND_SOC_DAIFMT_CBM_CFM:
175 tdm->master = 1;
176 val |= TIMING_MASTER_MODE;
177 break;
178 case SND_SOC_DAIFMT_CBS_CFS:
179 tdm->master = 0;
180 val &= ~TIMING_MASTER_MODE;
181 break;
182 default:
183 dev_err(cpu_dai->dev, "Unknown master/slave format\n");
184 return -EINVAL;
185 }
186
187
188 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
189
190 return 0;
191}
192
193static int zx_tdm_hw_params(struct snd_pcm_substream *substream,
194 struct snd_pcm_hw_params *params,
195 struct snd_soc_dai *socdai)
196{
197 struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(socdai);
198 struct snd_dmaengine_dai_dma_data *dma_data;
199 unsigned int ts_width = TIMING_DEFAULT_WIDTH;
200 unsigned int ch_num = 32;
201 unsigned int mask = 0;
202 unsigned int ret = 0;
203 unsigned long val;
204
205 dma_data = snd_soc_dai_get_dma_data(socdai, substream);
206 dma_data->addr_width = ch_num >> 3;
207
208 switch (params_format(params)) {
209 case SNDRV_PCM_FORMAT_MU_LAW:
210 case SNDRV_PCM_FORMAT_A_LAW:
211 case SNDRV_PCM_FORMAT_S16_LE:
212 ts_width = 1;
213 break;
214 default:
215 ts_width = 0;
216 dev_err(socdai->dev, "Unknown data format\n");
217 return -EINVAL;
218 }
219
220 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
221 val |= TIMING_TS_WIDTH(ts_width) | TIMING_TS_NUM(1);
222 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
223 zx_tdm_writel(tdm, REG_TS_MASK0, mask);
224
225 if (tdm->master)
226 ret = clk_set_rate(tdm->dai_wclk,
227 params_rate(params) * TIMING_WIDTH_FACTOR * ch_num);
228
229 return ret;
230}
231
232static int zx_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
233 struct snd_soc_dai *dai)
234{
235 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
236 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
237 unsigned int val;
238 int ret = 0;
239
240 switch (cmd) {
241 case SNDRV_PCM_TRIGGER_START:
242 if (capture) {
243 val = zx_tdm_readl(zx_tdm, REG_RX_FIFO_CTRL);
244 val |= FIFOCTRL_RX_FIFO_RST;
245 zx_tdm_writel(zx_tdm, REG_RX_FIFO_CTRL, val);
246
247 zx_tdm_rx_dma_en(zx_tdm, true);
248 } else {
249 val = zx_tdm_readl(zx_tdm, REG_TX_FIFO_CTRL);
250 val |= FIFOCTRL_TX_FIFO_RST;
251 zx_tdm_writel(zx_tdm, REG_TX_FIFO_CTRL, val);
252
253 zx_tdm_tx_dma_en(zx_tdm, true);
254 }
255 break;
256 case SNDRV_PCM_TRIGGER_RESUME:
257 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
258 if (capture)
259 zx_tdm_rx_en(zx_tdm, true);
260 else
261 zx_tdm_tx_en(zx_tdm, true);
262 break;
263 case SNDRV_PCM_TRIGGER_STOP:
264 if (capture)
265 zx_tdm_rx_dma_en(zx_tdm, false);
266 else
267 zx_tdm_tx_dma_en(zx_tdm, false);
268 break;
269 case SNDRV_PCM_TRIGGER_SUSPEND:
270 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
271 if (capture)
272 zx_tdm_rx_en(zx_tdm, false);
273 else
274 zx_tdm_tx_en(zx_tdm, false);
275 break;
276 default:
277 ret = -EINVAL;
278 break;
279 }
280
281 return ret;
282}
283
284static int zx_tdm_startup(struct snd_pcm_substream *substream,
285 struct snd_soc_dai *dai)
286{
287 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
288 int ret;
289
290 ret = clk_prepare_enable(zx_tdm->dai_wclk);
291 if (ret)
292 return ret;
293
294 ret = clk_prepare_enable(zx_tdm->dai_pclk);
295 if (ret) {
296 clk_disable_unprepare(zx_tdm->dai_wclk);
297 return ret;
298 }
299
300 return 0;
301}
302
303static void zx_tdm_shutdown(struct snd_pcm_substream *substream,
304 struct snd_soc_dai *dai)
305{
306 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
307
308 clk_disable_unprepare(zx_tdm->dai_pclk);
309 clk_disable_unprepare(zx_tdm->dai_wclk);
310}
311
312static struct snd_soc_dai_ops zx_tdm_dai_ops = {
313 .trigger = zx_tdm_trigger,
314 .hw_params = zx_tdm_hw_params,
315 .set_fmt = zx_tdm_set_fmt,
316 .startup = zx_tdm_startup,
317 .shutdown = zx_tdm_shutdown,
318};
319
320static const struct snd_soc_component_driver zx_tdm_component = {
321 .name = "zx-tdm",
322};
323
324static void zx_tdm_init_state(struct zx_tdm_info *tdm)
325{
326 unsigned int val;
327
328 zx_tdm_writel(tdm, REG_PROCESS_CTRL, PROCESS_DISABLE_ALL);
329
330 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
331 val |= TIMING_LSB_FIRST;
332 val &= ~TIMING_CLK_SEL_MASK;
333 val |= TIMING_CLK_SEL_DEF;
334 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
335
336 zx_tdm_writel(tdm, REG_INT_EN, INT_DISABLE_ALL);
337 /*
338 * write INT_STATUS register to clear it.
339 */
340 zx_tdm_writel(tdm, REG_INT_STATUS, INT_STATUS_MASK);
341 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, FIFOCTRL_RX_FIFO_RST);
342 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, FIFOCTRL_TX_FIFO_RST);
343
344 val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
345 val &= ~(RXTH_MASK | RX_FIFO_RST_MASK);
346 val |= FIFOCTRL_THRESHOLD(8);
347 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
348
349 val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
350 val &= ~(TXTH_MASK | TX_FIFO_RST_MASK);
351 val |= FIFOCTRL_THRESHOLD(8);
352 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
353}
354
355static struct snd_soc_dai_driver zx_tdm_dai = {
356 .name = "zx-tdm-dai",
357 .id = 0,
358 .probe = zx_tdm_dai_probe,
359 .playback = {
360 .channels_min = 1,
361 .channels_max = 4,
362 .rates = ZX_TDM_RATES,
363 .formats = ZX_TDM_FMTBIT,
364 },
365 .capture = {
366 .channels_min = 1,
367 .channels_max = 4,
368 .rates = ZX_TDM_RATES,
369 .formats = ZX_TDM_FMTBIT,
370 },
371 .ops = &zx_tdm_dai_ops,
372};
373
374static int zx_tdm_probe(struct platform_device *pdev)
375{
376 struct device *dev = &pdev->dev;
377 struct of_phandle_args out_args;
378 unsigned int dma_reg_offset;
379 struct zx_tdm_info *zx_tdm;
380 unsigned int dma_mask;
381 struct resource *res;
382 struct regmap *regmap_sysctrl;
383 int ret;
384
385 zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL);
386 if (!zx_tdm)
387 return -ENOMEM;
388
389 zx_tdm->dev = dev;
390
391 zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk");
392 if (IS_ERR(zx_tdm->dai_wclk)) {
393 dev_err(&pdev->dev, "Fail to get wclk\n");
394 return PTR_ERR(zx_tdm->dai_wclk);
395 }
396
397 zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk");
398 if (IS_ERR(zx_tdm->dai_pclk)) {
399 dev_err(&pdev->dev, "Fail to get pclk\n");
400 return PTR_ERR(zx_tdm->dai_pclk);
401 }
402
403 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
404 zx_tdm->phy_addr = res->start;
405 zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res);
406 if (IS_ERR(zx_tdm->regbase))
407 return PTR_ERR(zx_tdm->regbase);
408
409 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
410 "zte,tdm-dma-sysctrl", 2, 0, &out_args);
411 if (ret) {
412 dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n");
413 return ret;
414 }
415
416 dma_reg_offset = out_args.args[0];
417 dma_mask = out_args.args[1];
418 regmap_sysctrl = syscon_node_to_regmap(out_args.np);
419 if (IS_ERR(regmap_sysctrl)) {
420 of_node_put(out_args.np);
421 return PTR_ERR(regmap_sysctrl);
422 }
423
424 regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask);
425 of_node_put(out_args.np);
426
427 zx_tdm_init_state(zx_tdm);
428 platform_set_drvdata(pdev, zx_tdm);
429
430 ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component,
431 &zx_tdm_dai, 1);
432 if (ret) {
433 dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
434 return ret;
435 }
436
437 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
438 if (ret)
439 dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
440
441 return ret;
442}
443
444static const struct of_device_id zx_tdm_dt_ids[] = {
445 { .compatible = "zte,zx296718-tdm", },
446 {}
447};
448MODULE_DEVICE_TABLE(of, zx_tdm_dt_ids);
449
450static struct platform_driver tdm_driver = {
451 .probe = zx_tdm_probe,
452 .driver = {
453 .name = "zx-tdm",
454 .of_match_table = zx_tdm_dt_ids,
455 },
456};
457module_platform_driver(tdm_driver);
458
459MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
460MODULE_DESCRIPTION("ZTE TDM DAI driver");
461MODULE_LICENSE("GPL v2");
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index ac75816ada7c..850fab4a8f3b 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -225,9 +225,9 @@ snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { 225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
226 struct soundfont_patch_info patch; 226 struct soundfont_patch_info patch;
227 if (count < (int)sizeof(patch)) 227 if (count < (int)sizeof(patch))
228 rc = -EINVAL; 228 return -EINVAL;
229 if (copy_from_user(&patch, buf, sizeof(patch))) 229 if (copy_from_user(&patch, buf, sizeof(patch)))
230 rc = -EFAULT; 230 return -EFAULT;
231 if (patch.type >= SNDRV_SFNT_LOAD_INFO && 231 if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
232 patch.type <= SNDRV_SFNT_PROBE_DATA) 232 patch.type <= SNDRV_SFNT_PROBE_DATA)
233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port)); 233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
diff --git a/sound/usb/card.c b/sound/usb/card.c
index f36cb068dad3..6640277a725b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -332,6 +332,7 @@ static int snd_usb_audio_dev_free(struct snd_device *device)
332static int snd_usb_audio_create(struct usb_interface *intf, 332static int snd_usb_audio_create(struct usb_interface *intf,
333 struct usb_device *dev, int idx, 333 struct usb_device *dev, int idx,
334 const struct snd_usb_audio_quirk *quirk, 334 const struct snd_usb_audio_quirk *quirk,
335 unsigned int usb_id,
335 struct snd_usb_audio **rchip) 336 struct snd_usb_audio **rchip)
336{ 337{
337 struct snd_card *card; 338 struct snd_card *card;
@@ -381,8 +382,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
381 atomic_set(&chip->usage_count, 0); 382 atomic_set(&chip->usage_count, 0);
382 atomic_set(&chip->shutdown, 0); 383 atomic_set(&chip->shutdown, 0);
383 384
384 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 385 chip->usb_id = usb_id;
385 le16_to_cpu(dev->descriptor.idProduct));
386 INIT_LIST_HEAD(&chip->pcm_list); 386 INIT_LIST_HEAD(&chip->pcm_list);
387 INIT_LIST_HEAD(&chip->ep_list); 387 INIT_LIST_HEAD(&chip->ep_list);
388 INIT_LIST_HEAD(&chip->midi_list); 388 INIT_LIST_HEAD(&chip->midi_list);
@@ -569,7 +569,7 @@ static int usb_audio_probe(struct usb_interface *intf,
569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && 569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { 570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
571 err = snd_usb_audio_create(intf, dev, i, quirk, 571 err = snd_usb_audio_create(intf, dev, i, quirk,
572 &chip); 572 id, &chip);
573 if (err < 0) 573 if (err < 0)
574 goto __error; 574 goto __error;
575 chip->pm_intf = intf; 575 chip->pm_intf = intf;
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index fab53f58d447..b3854f8c0c67 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -430,7 +430,7 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
430} 430}
431 431
432/* control definition */ 432/* control definition */
433static struct snd_kcontrol_new line6_controls[] = { 433static const struct snd_kcontrol_new line6_controls[] = {
434 { 434 {
435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
436 .name = "PCM Playback Volume", 436 .name = "PCM Playback Volume",
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index 17aa616e61f5..358224cc5638 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -380,7 +380,7 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
380} 380}
381 381
382/* control definition */ 382/* control definition */
383static struct snd_kcontrol_new pod_control_monitor = { 383static const struct snd_kcontrol_new pod_control_monitor = {
384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 .name = "Monitor Playback Volume", 385 .name = "Monitor Playback Volume",
386 .index = 0, 386 .index = 0,
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 8e22f430d700..ba7975c0d03d 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -250,7 +250,7 @@ static void toneport_start_pcm(unsigned long arg)
250} 250}
251 251
252/* control definition */ 252/* control definition */
253static struct snd_kcontrol_new toneport_control_monitor = { 253static const struct snd_kcontrol_new toneport_control_monitor = {
254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
255 .name = "Monitor Playback Volume", 255 .name = "Monitor Playback Volume",
256 .index = 0, 256 .index = 0,
@@ -261,7 +261,7 @@ static struct snd_kcontrol_new toneport_control_monitor = {
261}; 261};
262 262
263/* source selector definition */ 263/* source selector definition */
264static struct snd_kcontrol_new toneport_control_source = { 264static const struct snd_kcontrol_new toneport_control_source = {
265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
266 .name = "PCM Capture Source", 266 .name = "PCM Capture Source",
267 .index = 0, 267 .index = 0,
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 6e763bc8d7db..a35f41467237 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1922,7 +1922,7 @@ static int roland_load_put(struct snd_kcontrol *kcontrol,
1922 return changed; 1922 return changed;
1923} 1923}
1924 1924
1925static struct snd_kcontrol_new roland_load_ctl = { 1925static const struct snd_kcontrol_new roland_load_ctl = {
1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1927 .name = "MIDI Input Mode", 1927 .name = "MIDI Input Mode",
1928 .info = roland_load_info, 1928 .info = roland_load_info,
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4703caea56b2..082736c539bc 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1172,7 +1172,7 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
1172}; 1172};
1173 1173
1174/* the read-only variant */ 1174/* the read-only variant */
1175static struct snd_kcontrol_new usb_feature_unit_ctl_ro = { 1175static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1177 .name = "", /* will be filled later manually */ 1177 .name = "", /* will be filled later manually */
1178 .info = mixer_ctl_feature_info, 1178 .info = mixer_ctl_feature_info,
@@ -1745,7 +1745,7 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
1745} 1745}
1746 1746
1747/* alsa control interface for processing/extension unit */ 1747/* alsa control interface for processing/extension unit */
1748static struct snd_kcontrol_new mixer_procunit_ctl = { 1748static const struct snd_kcontrol_new mixer_procunit_ctl = {
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "", /* will be filled later */ 1750 .name = "", /* will be filled later */
1751 .info = mixer_ctl_feature_info, 1751 .info = mixer_ctl_feature_info,
@@ -2033,7 +2033,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
2033} 2033}
2034 2034
2035/* alsa control interface for selector unit */ 2035/* alsa control interface for selector unit */
2036static struct snd_kcontrol_new mixer_selectunit_ctl = { 2036static const struct snd_kcontrol_new mixer_selectunit_ctl = {
2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2038 .name = "", /* will be filled later */ 2038 .name = "", /* will be filled later */
2039 .info = mixer_ctl_selector_info, 2039 .info = mixer_ctl_selector_info,
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c
index 7438e7c4a842..c33e2378089d 100644
--- a/sound/usb/mixer_scarlett.c
+++ b/sound/usb/mixer_scarlett.c
@@ -477,7 +477,7 @@ static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
477 return 0; 477 return 0;
478} 478}
479 479
480static struct snd_kcontrol_new usb_scarlett_ctl_switch = { 480static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "", 482 .name = "",
483 .info = scarlett_ctl_switch_info, 483 .info = scarlett_ctl_switch_info,
@@ -487,7 +487,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_switch = {
487 487
488static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0); 488static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
489 489
490static struct snd_kcontrol_new usb_scarlett_ctl = { 490static const struct snd_kcontrol_new usb_scarlett_ctl = {
491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
493 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 493 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -499,7 +499,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl = {
499 .tlv = { .p = db_scale_scarlett_gain } 499 .tlv = { .p = db_scale_scarlett_gain }
500}; 500};
501 501
502static struct snd_kcontrol_new usb_scarlett_ctl_master = { 502static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
505 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 505 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -511,7 +511,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_master = {
511 .tlv = { .p = db_scale_scarlett_gain } 511 .tlv = { .p = db_scale_scarlett_gain }
512}; 512};
513 513
514static struct snd_kcontrol_new usb_scarlett_ctl_enum = { 514static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
516 .name = "", 516 .name = "",
517 .info = scarlett_ctl_enum_info, 517 .info = scarlett_ctl_enum_info,
@@ -519,7 +519,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_enum = {
519 .put = scarlett_ctl_enum_put, 519 .put = scarlett_ctl_enum_put,
520}; 520};
521 521
522static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = { 522static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
524 .name = "", 524 .name = "",
525 .info = scarlett_ctl_enum_dynamic_info, 525 .info = scarlett_ctl_enum_dynamic_info,
@@ -527,7 +527,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
527 .put = scarlett_ctl_enum_put, 527 .put = scarlett_ctl_enum_put,
528}; 528};
529 529
530static struct snd_kcontrol_new usb_scarlett_ctl_sync = { 530static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
533 .name = "", 533 .name = "",
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index cf45bf1f7ee0..e118bdca983d 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -472,7 +472,7 @@ static int usb_stream_hwdep_new(struct snd_card *card)
472 hw->ops.mmap = usb_stream_hwdep_mmap; 472 hw->ops.mmap = usb_stream_hwdep_mmap;
473 hw->ops.poll = usb_stream_hwdep_poll; 473 hw->ops.poll = usb_stream_hwdep_poll;
474 474
475 sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", 475 sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm",
476 dev->bus->busnum, dev->devnum); 476 dev->bus->busnum, dev->devnum);
477 return 0; 477 return 0;
478} 478}
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 605e1047c01d..f4b3cda412fc 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -258,7 +258,7 @@ int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
258 hw->ops.mmap = snd_us428ctls_mmap; 258 hw->ops.mmap = snd_us428ctls_mmap;
259 hw->ops.poll = snd_us428ctls_poll; 259 hw->ops.poll = snd_us428ctls_poll;
260 hw->exclusive = 1; 260 hw->exclusive = 1;
261 sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); 261 sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
262 return 0; 262 return 0;
263} 263}
264 264
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index f95164b91152..d51c7fd7835b 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -723,7 +723,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
723 hw->ops.release = snd_usX2Y_hwdep_pcm_release; 723 hw->ops.release = snd_usX2Y_hwdep_pcm_release;
724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap; 724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
725 hw->exclusive = 1; 725 hw->exclusive = 1;
726 sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum); 726 sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
727 727
728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm); 728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
729 if (err < 0) { 729 if (err < 0) {