Merge branch 'topic/drm_audio_component' of https://git.kernel.org/pub/scm/linux...
authorMark Brown <broonie@kernel.org>
Wed, 1 Aug 2018 09:32:05 +0000 (10:32 +0100)
committerMark Brown <broonie@kernel.org>
Wed, 1 Aug 2018 09:32:05 +0000 (10:32 +0100)
250 files changed:
Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/amlogic,axg-sound-card.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/amlogic,axg-tdm-iface.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/atmel-i2s.txt
Documentation/devicetree/bindings/sound/audio-graph-card.txt
Documentation/devicetree/bindings/sound/dioo,dio2125.txt [deleted file]
Documentation/devicetree/bindings/sound/everest,es7134.txt
Documentation/devicetree/bindings/sound/everest,es7241.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/marvell,pxa2xx-ac97.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt
Documentation/devicetree/bindings/sound/mrvl,pxa2xx-pcm.txt [deleted file]
Documentation/devicetree/bindings/sound/name-prefix.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,q6adm.txt
Documentation/devicetree/bindings/sound/qcom,q6afe.txt
Documentation/devicetree/bindings/sound/qcom,q6asm.txt
Documentation/devicetree/bindings/sound/qcom,wcd9335.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
Documentation/devicetree/bindings/sound/rockchip-i2s.txt
Documentation/devicetree/bindings/sound/rt5682.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/devicetree/bindings/sound/simple-amplifier.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/tas571x.txt
Documentation/sound/soc/dpcm.rst
MAINTAINERS
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/devices.h
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/plat-pxa/ssp.c
drivers/ata/pata_pxa.c
drivers/dma/pxa_dma.c
drivers/media/platform/pxa_camera.c
drivers/mmc/host/pxamci.c
drivers/mtd/nand/raw/marvell_nand.c
include/linux/dma/pxa-dma.h
include/linux/platform_data/mmp_dma.h
include/linux/pxa2xx_ssp.h
include/sound/ac97/codec.h
include/sound/ac97/compat.h
include/sound/ac97/controller.h
include/sound/ac97/regs.h
include/sound/ac97_codec.h
include/sound/compress_driver.h
include/sound/dmaengine_pcm.h
include/sound/memalloc.h
include/sound/pcm_params.h
include/sound/pxa2xx-lib.h
include/sound/rt5682.h [new file with mode: 0644]
include/sound/simple_card.h
include/sound/simple_card_utils.h
include/sound/soc-acpi-intel-match.h
include/sound/soc-acpi.h
include/sound/soc-dai.h
include/sound/soc-dapm.h
include/sound/soc-dpcm.h
include/sound/soc-topology.h
include/sound/soc.h
sound/arm/Kconfig
sound/arm/Makefile
sound/arm/pxa2xx-ac97-lib.c
sound/arm/pxa2xx-ac97.c
sound/arm/pxa2xx-pcm-lib.c
sound/arm/pxa2xx-pcm.c [deleted file]
sound/arm/pxa2xx-pcm.h [deleted file]
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/amd/Kconfig
sound/soc/amd/acp-da7219-max98357a.c
sound/soc/amd/acp-pcm-dma.c
sound/soc/amd/acp.h
sound/soc/atmel/atmel-i2s.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/adau17x1.c
sound/soc/codecs/ak4458.c
sound/soc/codecs/ak4554.c
sound/soc/codecs/ak4613.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak5558.c
sound/soc/codecs/cs47l24.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/es7134.c
sound/soc/codecs/es7241.c [new file with mode: 0644]
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/nau8824.c
sound/soc/codecs/nau8825.c
sound/soc/codecs/pcm1789.c
sound/soc/codecs/pcm186x.c
sound/soc/codecs/rt1305.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/rt5651.c
sound/soc/codecs/rt5651.h
sound/soc/codecs/rt5682.c [new file with mode: 0644]
sound/soc/codecs/rt5682.h [new file with mode: 0644]
sound/soc/codecs/simple-amplifier.c [moved from sound/soc/codecs/dio2125.c with 68% similarity]
sound/soc/codecs/tas571x.c
sound/soc/codecs/tas571x.h
sound/soc/codecs/tscs42xx.c
sound/soc/codecs/tscs42xx.h
sound/soc/codecs/wcd-clsh.c [new file with mode: 0644]
sound/soc/codecs/wcd-clsh.h [new file with mode: 0644]
sound/soc/codecs/wcd9335.c [new file with mode: 0644]
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm_adsp.c
sound/soc/codecs/wmfw.h
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/fsl-asoc-card.c
sound/soc/fsl/fsl_asrc.c
sound/soc/fsl/fsl_asrc.h
sound/soc/fsl/fsl_asrc_dma.c
sound/soc/fsl/fsl_spdif.c
sound/soc/fsl/fsl_utils.c
sound/soc/fsl/fsl_utils.h
sound/soc/fsl/imx-sgtl5000.c
sound/soc/generic/audio-graph-card.c
sound/soc/generic/audio-graph-scu-card.c
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card.c
sound/soc/generic/simple-scu-card.c
sound/soc/intel/atom/sst/sst_drv_interface.c
sound/soc/intel/atom/sst/sst_loader.c
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/bdw-rt5677.c
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/bytcr_rt5651.c
sound/soc/intel/boards/glk_rt5682_max98357a.c [new file with mode: 0644]
sound/soc/intel/boards/kbl_da7219_max98357a.c
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/boards/skl_rt286.c
sound/soc/intel/common/Makefile
sound/soc/intel/common/soc-acpi-intel-bxt-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-byt-match.c
sound/soc/intel/common/soc-acpi-intel-cht-match.c
sound/soc/intel/common/soc-acpi-intel-cnl-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-glk-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c
sound/soc/intel/common/soc-acpi-intel-kbl-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-skl-match.c [new file with mode: 0644]
sound/soc/intel/common/sst-firmware.c
sound/soc/intel/haswell/sst-haswell-dsp.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-sst-cldma.c
sound/soc/intel/skylake/skl-sst-cldma.h
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl.c
sound/soc/mediatek/common/mtk-afe-platform-driver.c
sound/soc/mediatek/common/mtk-base-afe.h
sound/soc/mediatek/mt6797/mt6797-afe-common.h
sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
sound/soc/mediatek/mt6797/mt6797-dai-adda.c
sound/soc/mediatek/mt6797/mt6797-dai-hostless.c
sound/soc/mediatek/mt6797/mt6797-dai-pcm.c
sound/soc/meson/Kconfig [new file with mode: 0644]
sound/soc/meson/Makefile [new file with mode: 0644]
sound/soc/meson/axg-card.c [new file with mode: 0644]
sound/soc/meson/axg-fifo.c [new file with mode: 0644]
sound/soc/meson/axg-fifo.h [new file with mode: 0644]
sound/soc/meson/axg-frddr.c [new file with mode: 0644]
sound/soc/meson/axg-spdifout.c [new file with mode: 0644]
sound/soc/meson/axg-tdm-formatter.c [new file with mode: 0644]
sound/soc/meson/axg-tdm-formatter.h [new file with mode: 0644]
sound/soc/meson/axg-tdm-interface.c [new file with mode: 0644]
sound/soc/meson/axg-tdm.h [new file with mode: 0644]
sound/soc/meson/axg-tdmin.c [new file with mode: 0644]
sound/soc/meson/axg-tdmout.c [new file with mode: 0644]
sound/soc/meson/axg-toddr.c [new file with mode: 0644]
sound/soc/omap/omap-abe-twl6040.c
sound/soc/pxa/Kconfig
sound/soc/pxa/magician.c
sound/soc/pxa/pxa-ssp.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/pxa/zylonite.c
sound/soc/qcom/apq8096.c
sound/soc/qcom/lpass-platform.c
sound/soc/qcom/qdsp6/q6adm.c
sound/soc/qcom/qdsp6/q6afe-dai.c
sound/soc/qcom/qdsp6/q6afe.c
sound/soc/qcom/qdsp6/q6asm-dai.c
sound/soc/qcom/qdsp6/q6asm.c
sound/soc/qcom/qdsp6/q6routing.c
sound/soc/rockchip/Makefile
sound/soc/rockchip/rockchip_i2s.c
sound/soc/rockchip/rockchip_pcm.c [new file with mode: 0644]
sound/soc/rockchip/rockchip_pcm.h [new file with mode: 0644]
sound/soc/rockchip/rockchip_rt5645.c
sound/soc/sh/Kconfig
sound/soc/sh/dma-sh7760.c
sound/soc/sh/fsi.c
sound/soc/sh/hac.c
sound/soc/sh/migor.c
sound/soc/sh/rcar/Makefile
sound/soc/sh/rcar/adg.c
sound/soc/sh/rcar/cmd.c
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/ctu.c
sound/soc/sh/rcar/dma.c
sound/soc/sh/rcar/dvc.c
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/mix.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/ssi.c
sound/soc/sh/rcar/ssiu.c
sound/soc/sh/sh7760-ac97.c
sound/soc/sh/siu.h
sound/soc/sh/siu_dai.c
sound/soc/sh/siu_pcm.c
sound/soc/sh/ssi.c
sound/soc/sirf/sirf-usp.c
sound/soc/soc-ac97.c
sound/soc/soc-acpi.c
sound/soc/soc-compress.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-devres.c
sound/soc/soc-generic-dmaengine-pcm.c
sound/soc/soc-io.c
sound/soc/soc-jack.c
sound/soc/soc-ops.c
sound/soc/soc-pcm.c
sound/soc/soc-topology.c
sound/soc/soc-utils.c
sound/soc/sti/uniperif_player.c
sound/soc/sti/uniperif_reader.c
sound/soc/stm/Kconfig
sound/soc/stm/stm32_adfsdm.c
sound/soc/stm/stm32_sai_sub.c
sound/soc/tegra/tegra20_ac97.c
sound/soc/tegra/tegra_alc5632.c
sound/soc/tegra/tegra_rt5677.c
sound/soc/uniphier/aio-core.c
sound/soc/uniphier/aio-cpu.c
sound/soc/uniphier/aio-ld11.c
sound/soc/uniphier/aio-reg.h
sound/soc/uniphier/aio.h
sound/soc/zte/zx-tdm.c

diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
new file mode 100644 (file)
index 0000000..3dfc251
--- /dev/null
@@ -0,0 +1,23 @@
+* Amlogic Audio FIFO controllers
+
+Required properties:
+- compatible: 'amlogic,axg-toddr' or
+             'amlogic,axg-frddr'
+- reg: physical base address of the controller and length of memory
+       mapped region.
+- interrupts: interrupt specifier for the fifo.
+- clocks: phandle to the fifo peripheral clock provided by the audio
+         clock controller.
+- resets: phandle to memory ARB line provided by the arb reset controller.
+- #sound-dai-cells: must be 0.
+
+Example of FRDDR A on the A113 SoC:
+
+frddr_a: audio-controller@1c0 {
+       compatible = "amlogic,axg-frddr";
+       reg = <0x0 0x1c0 0x0 0x1c>;
+       #sound-dai-cells = <0>;
+       interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
+       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+       resets = <&arb AXG_ARB_FRDDR_A>;
+};
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-sound-card.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-sound-card.txt
new file mode 100644 (file)
index 0000000..80b4112
--- /dev/null
@@ -0,0 +1,124 @@
+Amlogic AXG sound card:
+
+Required properties:
+
+- compatible: "amlogic,axg-sound-card"
+- model : User specified audio sound card name, one string
+
+Optional properties:
+
+- audio-aux-devs : List of phandles pointing to auxiliary devices
+- audio-widgets : Please refer to widgets.txt.
+- audio-routing : A list of the connections between audio components.
+
+Subnodes:
+
+- dai-link: Container for dai-link level properties and the CODEC
+           sub-nodes. There should be at least one (and probably more)
+           subnode of this type.
+
+Required dai-link properties:
+
+- sound-dai: phandle and port of the CPU DAI.
+
+Required TDM Backend dai-link properties:
+- dai-format : CPU/CODEC common audio format
+
+Optional TDM Backend dai-link properties:
+- dai-tdm-slot-rx-mask-{0,1,2,3}: Receive direction slot masks
+- dai-tdm-slot-tx-mask-{0,1,2,3}: Transmit direction slot masks
+                                 When omitted, mask is assumed to have to no
+                                 slots. A valid must have at one slot, so at
+                                 least one these mask should be provided with
+                                 an enabled slot.
+- dai-tdm-slot-num : Please refer to tdm-slot.txt.
+                    If omitted, slot number is set to accommodate the largest
+                    mask provided.
+- dai-tdm-slot-width : Please refer to tdm-slot.txt. default to 32 if omitted.
+- mclk-fs : Multiplication factor between stream rate and mclk
+
+Backend dai-link subnodes:
+
+- codec: dai-link representing backend links should have at least one subnode.
+        One subnode for each codec of the dai-link.
+        dai-link representing frontend links have no codec, therefore have no
+        subnodes
+
+Required codec subnodes properties:
+
+- sound-dai: phandle and port of the CODEC DAI.
+
+Optional codec subnodes properties:
+
+- dai-tdm-slot-tx-mask : Please refer to tdm-slot.txt.
+- dai-tdm-slot-rx-mask : Please refer to tdm-slot.txt.
+
+Example:
+
+sound {
+       compatible = "amlogic,axg-sound-card";
+       model = "AXG-S420";
+       audio-aux-devs = <&tdmin_a>, <&tdmout_c>;
+       audio-widgets = "Line", "Lineout",
+                       "Line", "Linein",
+                       "Speaker", "Speaker1 Left",
+                       "Speaker", "Speaker1 Right";
+                       "Speaker", "Speaker2 Left",
+                       "Speaker", "Speaker2 Right";
+       audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+                       "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+                       "TDM_C Playback", "TDMOUT_C OUT",
+                       "TDMIN_A IN 2", "TDM_C Capture",
+                       "TDMIN_A IN 5", "TDM_C Loopback",
+                       "TODDR_A IN 0", "TDMIN_A OUT",
+                       "Lineout", "Lineout AOUTL",
+                       "Lineout", "Lineout AOUTR",
+                       "Speaker1 Left", "SPK1 OUT_A",
+                       "Speaker2 Left", "SPK2 OUT_A",
+                       "Speaker1 Right", "SPK1 OUT_B",
+                       "Speaker2 Right", "SPK2 OUT_B",
+                       "Linein AINL", "Linein",
+                       "Linein AINR", "Linein";
+
+       dai-link@0 {
+               sound-dai = <&frddr_a>;
+       };
+
+       dai-link@1 {
+               sound-dai = <&toddr_a>;
+       };
+
+       dai-link@2 {
+               sound-dai = <&tdmif_c>;
+               dai-format = "i2s";
+               dai-tdm-slot-tx-mask-2 = <1 1>;
+               dai-tdm-slot-tx-mask-3 = <1 1>;
+               dai-tdm-slot-rx-mask-1 = <1 1>;
+               mclk-fs = <256>;
+
+               codec@0 {
+                       sound-dai = <&lineout>;
+               };
+
+               codec@1 {
+                       sound-dai = <&speaker_amp1>;
+               };
+
+               codec@2 {
+                       sound-dai = <&speaker_amp2>;
+               };
+
+               codec@3 {
+                       sound-dai = <&linein>;
+               };
+
+       };
+
+       dai-link@3 {
+               sound-dai = <&spdifout>;
+
+               codec {
+                       sound-dai = <&spdif_dit>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt
new file mode 100644 (file)
index 0000000..521c38a
--- /dev/null
@@ -0,0 +1,20 @@
+* Amlogic Audio SPDIF Output
+
+Required properties:
+- compatible: 'amlogic,axg-spdifout'
+- clocks: list of clock phandle, one for each entry clock-names.
+- clock-names: should contain the following:
+  * "pclk" : peripheral clock.
+  * "mclk" : master clock
+- #sound-dai-cells: must be 0.
+
+Example on the A113 SoC:
+
+spdifout: audio-controller@480 {
+       compatible = "amlogic,axg-spdifout";
+       reg = <0x0 0x480 0x0 0x50>;
+       #sound-dai-cells = <0>;
+       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+                <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+       clock-names = "pclk", "mclk";
+};
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt
new file mode 100644 (file)
index 0000000..1c1b749
--- /dev/null
@@ -0,0 +1,28 @@
+* Amlogic Audio TDM formatters
+
+Required properties:
+- compatible: 'amlogic,axg-tdmin' or
+             'amlogic,axg-tdmout'
+- reg: physical base address of the controller and length of memory
+       mapped region.
+- clocks: list of clock phandle, one for each entry clock-names.
+- clock-names: should contain the following:
+  * "pclk"     : peripheral clock.
+  * "sclk"     : bit clock.
+  * "sclk_sel" : bit clock input multiplexer.
+  * "lrclk"    : sample clock
+  * "lrclk_sel": sample clock input multiplexer
+
+Example of TDMOUT_A on the A113 SoC:
+
+tdmout_a: audio-controller@500 {
+       compatible = "amlogic,axg-tdmout";
+       reg = <0x0 0x500 0x0 0x40>;
+       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+       clock-names = "pclk", "sclk", "sclk_sel",
+                     "lrclk", "lrclk_sel";
+};
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-iface.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-iface.txt
new file mode 100644 (file)
index 0000000..cabfb26
--- /dev/null
@@ -0,0 +1,22 @@
+* Amlogic Audio TDM Interfaces
+
+Required properties:
+- compatible: 'amlogic,axg-tdm-iface'
+- clocks: list of clock phandle, one for each entry clock-names.
+- clock-names: should contain the following:
+  * "sclk" : bit clock.
+  * "lrclk": sample clock
+  * "mclk" : master clock
+            -> optional if the interface is in clock slave mode.
+- #sound-dai-cells: must be 0.
+
+Example of TDM_A on the A113 SoC:
+
+tdmif_a: audio-controller@0 {
+       compatible = "amlogic,axg-tdm-iface";
+       #sound-dai-cells = <0>;
+       clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+                <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+       clock-names = "mclk", "sclk", "lrclk";
+};
index 735368b8a73fe5149fbb13f03741fecf6dad4094..40549f496a81ccdfb59d49da32682ab8cba2107f 100644 (file)
@@ -15,7 +15,6 @@ Required properties:
 - clock-names:    Should be one of each entry matching the clocks phandles list:
                   - "pclk" (peripheral clock) Required.
                   - "gclk" (generated clock) Optional (1).
-                  - "aclk" (Audio PLL clock) Optional (1).
                   - "muxclk" (I2S mux clock) Optional (1).
 
 Optional properties:
@@ -23,9 +22,9 @@ Optional properties:
 - princtrl-names: Should contain only one value - "default".
 
 
-(1) : Only the peripheral clock is required. The generated clock, the Audio
-      PLL clock adn the I2S mux clock are optional and should only be set
-      together, when Master Mode is required.
+(1) : Only the peripheral clock is required. The generated clock and the I2S
+      mux clock are optional and should only be set together, when Master Mode
+      is required.
 
 Example:
 
@@ -40,8 +39,8 @@ Example:
                        (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
                         AT91_XDMAC_DT_PERID(32))>;
                dma-names = "tx", "rx";
-               clocks = <&i2s0_clk>, <&i2s0_gclk>, <&audio_pll_pmc>, <&i2s0muxck>;
-               clock-names = "pclk", "gclk", "aclk", "muxclk";
+               clocks = <&i2s0_clk>, <&i2s0_gclk>, <&i2s0muxck>;
+               clock-names = "pclk", "gclk", "muxclk";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_i2s0_default>;
        };
index d04ea3b1a1dd5d7710da9c25b76372a8aadb6347..7e63e53a901c65db905b4ded8b46462de43a5267 100644 (file)
@@ -18,6 +18,8 @@ Below are same as Simple-Card.
 - bitclock-inversion
 - frame-inversion
 - mclk-fs
+- hp-det-gpio
+- mic-det-gpio
 - dai-tdm-slot-num
 - dai-tdm-slot-width
 - clocks / system-clock-frequency
diff --git a/Documentation/devicetree/bindings/sound/dioo,dio2125.txt b/Documentation/devicetree/bindings/sound/dioo,dio2125.txt
deleted file mode 100644 (file)
index 63dbfe0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-DIO2125 Audio Driver
-
-Required properties:
-- compatible : "dioo,dio2125"
-- enable-gpios : the gpio connected to the enable pin of the dio2125
-
-Example:
-
-amp: analog-amplifier {
-       compatible = "dioo,dio2125";
-       enable-gpios = <&gpio GPIOH_3 0>;
-};
index 5495a3cb8b7bc2b2e6fe7925038caa9b86040ede..091666069bde1e6d885a05346499fc0e651c7d34 100644 (file)
@@ -1,10 +1,15 @@
 ES7134 i2s DA converter
 
 Required properties:
-- compatible : "everest,es7134" or "everest,es7144"
+- compatible : "everest,es7134" or
+               "everest,es7144" or
+              "everest,es7154"
+- VDD-supply : regulator phandle for the VDD supply
+- PVDD-supply: regulator phandle for the PVDD supply for the es7154
 
 Example:
 
 i2s_codec: external-codec {
        compatible = "everest,es7134";
+       VDD-supply = <&vcc_5v>;
 };
diff --git a/Documentation/devicetree/bindings/sound/everest,es7241.txt b/Documentation/devicetree/bindings/sound/everest,es7241.txt
new file mode 100644 (file)
index 0000000..28f82cf
--- /dev/null
@@ -0,0 +1,28 @@
+ES7241 i2s AD converter
+
+Required properties:
+- compatible : "everest,es7241"
+- VDDP-supply: regulator phandle for the VDDA supply
+- VDDA-supply: regulator phandle for the VDDP supply
+- VDDD-supply: regulator phandle for the VDDD supply
+
+Optional properties:
+- reset-gpios: gpio connected to the reset pin
+- m0-gpios   : gpio connected to the m0 pin
+- m1-gpios   : gpio connected to the m1 pin
+- everest,sdout-pull-down:
+   Format used by the serial interface is controlled by pulling
+   the sdout. If the sdout is pulled down, leftj format is used.
+   If this property is not provided, sdout is assumed to pulled
+   up and i2s format is used
+
+Example:
+
+linein: audio-codec@2 {
+       #sound-dai-cells = <0>;
+       compatible = "everest,es7241";
+       VDDA-supply = <&vcc_3v3>;
+       VDDP-supply = <&vcc_3v3>;
+       VDDD-supply = <&vcc_3v3>;
+       reset-gpios = <&gpio GPIOH_42>;
+};
diff --git a/Documentation/devicetree/bindings/sound/marvell,pxa2xx-ac97.txt b/Documentation/devicetree/bindings/sound/marvell,pxa2xx-ac97.txt
new file mode 100644 (file)
index 0000000..2ea85d5
--- /dev/null
@@ -0,0 +1,27 @@
+Marvell PXA2xx audio complex
+
+This descriptions matches the AC97 controller found in pxa2xx and pxa3xx series.
+
+Required properties:
+  - compatible: should be one of the following:
+    "marvell,pxa250-ac97"
+    "marvell,pxa270-ac97"
+    "marvell,pxa300-ac97"
+  - reg: device MMIO address space
+  - interrupts: single interrupt generated by AC97 IP
+  - clocks: input clock of the AC97 IP, refer to clock-bindings.txt
+
+Optional properties:
+  - pinctrl-names, pinctrl-0: refer to pinctrl-bindings.txt
+  - reset-gpios: gpio used for AC97 reset, refer to gpio.txt
+
+Example:
+       ac97: sound@40500000 {
+               compatible = "marvell,pxa250-ac97";
+               reg = < 0x40500000 0x1000 >;
+               interrupts = <14>;
+               reset-gpios = <&gpio 113 GPIO_ACTIVE_HIGH>;
+               #sound-dai-cells = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = < &pmux_ac97_default >;
+       };
index 74c9ba6c2823d9d1dc0704bc7338f8b3414e2eca..93b982e9419fd9c6bdadd361c9266efb24f95422 100644 (file)
@@ -5,6 +5,14 @@ Required properties:
        compatible      Must be "mrvl,pxa-ssp-dai"
        port            A phandle reference to a PXA ssp upstream device
 
+Optional properties:
+
+       clock-names
+       clocks          Through "clock-names" and "clocks", external clocks
+                       can be configured. If a clock names "extclk" exists,
+                       it will be set to the mclk rate of the audio stream
+                       and be used as clock provider of the DAI.
+
 Example:
 
        /* upstream device */
diff --git a/Documentation/devicetree/bindings/sound/mrvl,pxa2xx-pcm.txt b/Documentation/devicetree/bindings/sound/mrvl,pxa2xx-pcm.txt
deleted file mode 100644 (file)
index 551fbb8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-DT bindings for ARM PXA2xx PCM platform driver
-
-This is just a dummy driver that registers the PXA ASoC platform driver.
-It does not have any resources assigned.
-
-Required properties:
-
-       - compatible            'mrvl,pxa-pcm-audio'
-
-Example:
-
-       pxa_pcm_audio: snd_soc_pxa_audio {
-               compatible = "mrvl,pxa-pcm-audio";
-       };
-
diff --git a/Documentation/devicetree/bindings/sound/name-prefix.txt b/Documentation/devicetree/bindings/sound/name-prefix.txt
new file mode 100644 (file)
index 0000000..6457759
--- /dev/null
@@ -0,0 +1,24 @@
+Name prefix:
+
+Card implementing the routing property define the connection between
+audio components as list of string pair. Component using the same
+sink/source names may use the name prefix property to prepend the
+name of their sinks/sources with the provided string.
+
+Optional name prefix property:
+- sound-name-prefix : string using as prefix for the sink/source names of
+                     the component.
+
+Example: Two instances of the same component.
+
+amp0: analog-amplifier@0 {
+       compatible = "simple-audio-amplifier";
+       enable-gpios = <&gpio GPIOH_3 0>;
+       sound-name-prefix = "FRONT";
+};
+
+amp1: analog-amplifier@1 {
+       compatible = "simple-audio-amplifier";
+       enable-gpios = <&gpio GPIOH_4 0>;
+       sound-name-prefix = "BACK";
+};
index cb709e5dbc44fb0238c143acf14acdb87169b05b..bbae426cdfb19d67f573b2dd4502f8e9480a1e05 100644 (file)
@@ -18,6 +18,11 @@ used by the apr service device.
 = ADM routing
 "routing" subnode of the ADM node represents adm routing specific configuration
 
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6adm-routing".
+
 - #sound-dai-cells
        Usage: required
        Value type: <u32>
@@ -28,6 +33,7 @@ q6adm@8 {
        compatible = "qcom,q6adm";
        reg = <APR_SVC_ADM>;
        q6routing: routing {
+               compatible = "qcom,q6adm-routing";
                #sound-dai-cells = <0>;
        };
 };
index bdbf87df8c0be3933604ff177607b3ee314c3d70..a8179409c1945a58bebe84ee86ab858a1d927386 100644 (file)
@@ -17,6 +17,11 @@ used by all apr services. Must contain the following properties.
 subnode of "dais" representing board specific dai setup.
 "dais" node should have following properties followed by dai children.
 
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6afe-dais"
+
 - #sound-dai-cells
        Usage: required
        Value type: <u32>
@@ -100,6 +105,7 @@ q6afe@4 {
        reg = <APR_SVC_AFE>;
 
        dais {
+               compatible = "qcom,q6afe-dais";
                #sound-dai-cells = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
index 2178eb91146f84a8ade34294f535df5240c6b6c5..f9c7bd8c1bc0fa8f3bb61cbe95ec09639d66122d 100644 (file)
@@ -17,6 +17,11 @@ used by the apr service device.
 = ASM DAIs (Digial Audio Interface)
 "dais" subnode of the ASM node represents dai specific configuration
 
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6asm-dais".
+
 - #sound-dai-cells
        Usage: required
        Value type: <u32>
@@ -28,6 +33,7 @@ q6asm@7 {
        compatible = "qcom,q6asm";
        reg = <APR_SVC_ASM>;
        q6asmdai: dais {
+               compatible = "qcom,q6asm-dais";
                #sound-dai-cells = <1>;
        };
 };
diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
new file mode 100644 (file)
index 0000000..1d8d49e
--- /dev/null
@@ -0,0 +1,123 @@
+QCOM WCD9335 Codec
+
+Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC, supports
+Qualcomm Technologies, Inc. (QTI) multimedia solutions, including
+the MSM8996, MSM8976, and MSM8956 chipsets. It has in-built
+Soundwire controller, interrupt mux. It supports both I2S/I2C and
+SLIMbus audio interfaces.
+
+Required properties with SLIMbus Interface:
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: For SLIMbus interface it should be "slimMID,PID",
+                   textual representation of Manufacturer ID, Product Code,
+                   shall be in lower case hexadecimal with leading zeroes
+                   suppressed.  Refer to slimbus/bus.txt for details.
+                   Should be:
+                   "slim217,1a0" for MSM8996 and APQ8096 SoCs with SLIMbus.
+
+- reg
+       Usage: required
+       Value type: <u32 u32>
+       Definition: Should be ('Device index', 'Instance ID')
+
+- interrupts
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: Interrupts via WCD INTR1 and INTR2 pins
+
+- interrupt-names:
+       Usage: required
+       Value type: <String array>
+       Definition: Interrupt names of WCD INTR1 and INTR2
+       Should be: "intr1", "intr2"
+
+- reset-gpio:
+       Usage: required
+       Value type: <String Array>
+       Definition: Reset gpio line
+
+- qcom,ifd:
+       Usage: required
+       Value type: <phandle>
+       Definition: SLIM interface device
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: See clock-bindings.txt section "consumers". List of
+                three clock specifiers for mclk, mclk2 and slimbus clock.
+
+- clock-names:
+       Usage: required
+       Value type: <string>
+       Definition: Must contain "mclk", "mclk2" and "slimbus" strings.
+
+- vdd-buck-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the 1.8V buck supply
+
+- vdd-buck-sido-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the 1.8V SIDO buck supply
+
+- vdd-rx-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the 1.8V rx supply
+
+- vdd-tx-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the 1.8V tx supply
+
+- vdd-vbat-supply:
+       Usage: Optional
+       Value type: <phandle>
+       Definition: Should contain a reference to the vbat supply
+
+- vdd-micbias-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the micbias supply
+
+- vdd-io-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: Should contain a reference to the 1.8V io supply
+
+- interrupt-controller:
+       Usage: required
+       Definition: Indicating that this is a interrupt controller
+
+- #interrupt-cells:
+       Usage: required
+       Value type: <int>
+       Definition: should be 1
+
+#sound-dai-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 1
+
+codec@1{
+       compatible = "slim217,1a0";
+       reg  = <1 0>;
+       interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
+       interrupt-names = "intr2"
+       reset-gpio = <&msmgpio 64 0>;
+       qcom,ifd  = <&wc9335_ifd>;
+       clock-names = "mclk", "native";
+       clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
+                <&rpmcc RPM_SMD_BB_CLK1>;
+       vdd-buck-supply = <&pm8994_s4>;
+       vdd-rx-supply = <&pm8994_s4>;
+       vdd-buck-sido-supply = <&pm8994_s4>;
+       vdd-tx-supply = <&pm8994_s4>;
+       vdd-io-supply = <&pm8994_s4>;
+       #sound-dai-cells = <1>;
+}
index b86d790f630ff79a390f6ef004c7fe595acf44e9..9e764270c36b869768429950b6fabcb88a3e6f7d 100644 (file)
@@ -352,6 +352,7 @@ Required properties:
                                    - "renesas,rcar_sound-r8a7794" (R-Car E2)
                                    - "renesas,rcar_sound-r8a7795" (R-Car H3)
                                    - "renesas,rcar_sound-r8a7796" (R-Car M3-W)
+                                   - "renesas,rcar_sound-r8a77965" (R-Car M3-N)
 - reg                          : Should contain the register physical address.
                                  required register is
                                   SRU/ADG/SSI      if generation1
index b208a752576c1173669d2d408b60101d05b361ac..54aefab71f2cb1b3c4e276ff905a4fed8d8ab568 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
 
 - compatible: should be one of the following:
    - "rockchip,rk3066-i2s": for rk3066
+   - "rockchip,px30-i2s", "rockchip,rk3066-i2s": for px30
    - "rockchip,rk3036-i2s", "rockchip,rk3066-i2s": for rk3036
    - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
    - "rockchip,rk3228-i2s", "rockchip,rk3066-i2s": for rk3228
diff --git a/Documentation/devicetree/bindings/sound/rt5682.txt b/Documentation/devicetree/bindings/sound/rt5682.txt
new file mode 100644 (file)
index 0000000..312e9a1
--- /dev/null
@@ -0,0 +1,50 @@
+RT5682 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "realtek,rt5682" or "realtek,rt5682i"
+
+- reg : The I2C address of the device.
+
+Optional properties:
+
+- interrupts : The CODEC's interrupt output.
+
+- realtek,dmic1-data-pin
+  0: dmic1 is not used
+  1: using GPIO2 pin as dmic1 data pin
+  2: using GPIO5 pin as dmic1 data pin
+
+- realtek,dmic1-clk-pin
+  0: using GPIO1 pin as dmic1 clock pin
+  1: using GPIO3 pin as dmic1 clock pin
+
+- realtek,jd-src
+  0: No JD is used
+  1: using JD1 as JD source
+
+- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
+
+Pins on the device (for linking into audio routes) for RT5682:
+
+  * DMIC L1
+  * DMIC R1
+  * IN1P
+  * HPOL
+  * HPOR
+
+Example:
+
+rt5682 {
+       compatible = "realtek,rt5682i";
+       reg = <0x1a>;
+       interrupt-parent = <&gpio>;
+       interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
+       realtek,ldo1-en-gpios =
+               <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+       realtek,dmic1-data-pin = <1>;
+       realtek,dmic1-clk-pin = <1>;
+       realtek,jd-src = <1>;
+};
index 0f214457476f2aa399925720ee8b42c934b89568..9c58f724396ab0881e851eaef1ed3a5902c14115 100644 (file)
@@ -17,7 +17,7 @@ Optional properties:
 
 - VDDD-supply : the regulator provider of VDDD
 
-- micbias-resistor-k-ohms : the bias resistor to be used in kOmhs
+- micbias-resistor-k-ohms : the bias resistor to be used in kOhms
        The resistor can take values of 2k, 4k or 8k.
        If set to 0 it will be off.
        If this node is not mentioned or if the value is unknown, then
diff --git a/Documentation/devicetree/bindings/sound/simple-amplifier.txt b/Documentation/devicetree/bindings/sound/simple-amplifier.txt
new file mode 100644 (file)
index 0000000..8647eda
--- /dev/null
@@ -0,0 +1,12 @@
+Simple Amplifier Audio Driver
+
+Required properties:
+- compatible : "dioo,dio2125" or "simple-audio-amplifier"
+- enable-gpios : the gpio connected to the enable pin of the simple amplifier
+
+Example:
+
+amp: analog-amplifier {
+       compatible = "simple-audio-amplifier";
+       enable-gpios = <&gpio GPIOH_3 0>;
+};
index b4959f10b74b0c7f05f1511dbc88ef183d2f2599..7c8fd37c2f9e9da14740f78ae8801a01d086ec46 100644 (file)
@@ -7,6 +7,7 @@ powerdown (optional).
 Required properties:
 
 - compatible: should be one of the following:
+  - "ti,tas5707"
   - "ti,tas5711",
   - "ti,tas5717",
   - "ti,tas5719",
index 395e5a5162820e709c7d01e81b06010adc6acf4f..fe61e02277f801058da3166b5c58d69872598ccd 100644 (file)
@@ -254,9 +254,7 @@ configuration.
        channels->min = channels->max = 2;
 
        /* set DAI0 to 16 bit */
-       snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
-                                   SNDRV_PCM_HW_PARAM_FIRST_MASK],
-                                   SNDRV_PCM_FORMAT_S16_LE);
+       params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
        return 0;
   }
 
index 9d5eeff51b5fd32979f64d288375b6489ff25712..fc711d23dc8394fabf25600d12421ce7eb4137ca 100644 (file)
@@ -13557,6 +13557,13 @@ L:     linux-block@vger.kernel.org
 S:     Maintained
 F:     drivers/block/skd*[ch]
 
+STI AUDIO (ASoC) DRIVERS
+M:     Arnaud Pouliquen <arnaud.pouliquen@st.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
+F:     sound/soc/sti/
+
 STI CEC DRIVER
 M:     Benjamin Gaignard <benjamin.gaignard@linaro.org>
 S:     Maintained
@@ -13570,6 +13577,14 @@ T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/stk1160/
 
+STM32 AUDIO (ASoC) DRIVERS
+M:     Olivier Moysan <olivier.moysan@st.com>
+M:     Arnaud Pouliquen <arnaud.pouliquen@st.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/sound/st,stm32-*.txt
+F:     sound/soc/stm/
+
 STM32 TIMER/LPTIMER DRIVERS
 M:     Fabrice Gasnier <fabrice.gasnier@st.com>
 S:     Maintained
index d7c9a8476d5717950f893f2d1e419083e8b7da18..5a16ea74e28a00820e6d3b92b0c2c3c73ebaa784 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/platform_data/i2c-pxa.h>
 
@@ -59,16 +60,6 @@ static struct resource pxamci_resources[] = {
                .end    = IRQ_MMC,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               .start  = 21,
-               .end    = 21,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start  = 22,
-               .end    = 22,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 static u64 pxamci_dmamask = 0xffffffffUL;
@@ -406,16 +397,6 @@ static struct resource pxa_ir_resources[] = {
                .end    = 0x40700023,
                .flags  = IORESOURCE_MEM,
        },
-       [5] = {
-               .start  = 17,
-               .end    = 17,
-               .flags  = IORESOURCE_DMA,
-       },
-       [6] = {
-               .start  = 18,
-               .end    = 18,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa_device_ficp = {
@@ -544,18 +525,6 @@ static struct resource pxa25x_resource_ssp[] = {
                .end    = IRQ_SSP,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 13,
-               .end    = 13,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 14,
-               .end    = 14,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa25x_device_ssp = {
@@ -582,18 +551,6 @@ static struct resource pxa25x_resource_nssp[] = {
                .end    = IRQ_NSSP,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 15,
-               .end    = 15,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 16,
-               .end    = 16,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa25x_device_nssp = {
@@ -620,18 +577,6 @@ static struct resource pxa25x_resource_assp[] = {
                .end    = IRQ_ASSP,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 23,
-               .end    = 23,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 24,
-               .end    = 24,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa25x_device_assp = {
@@ -750,18 +695,6 @@ static struct resource pxa27x_resource_ssp1[] = {
                .end    = IRQ_SSP,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 13,
-               .end    = 13,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 14,
-               .end    = 14,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa27x_device_ssp1 = {
@@ -788,18 +721,6 @@ static struct resource pxa27x_resource_ssp2[] = {
                .end    = IRQ_SSP2,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 15,
-               .end    = 15,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 16,
-               .end    = 16,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa27x_device_ssp2 = {
@@ -826,18 +747,6 @@ static struct resource pxa27x_resource_ssp3[] = {
                .end    = IRQ_SSP3,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 66,
-               .end    = 66,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 67,
-               .end    = 67,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa27x_device_ssp3 = {
@@ -894,16 +803,6 @@ static struct resource pxa3xx_resources_mci2[] = {
                .end    = IRQ_MMC2,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               .start  = 93,
-               .end    = 93,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start  = 94,
-               .end    = 94,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa3xx_device_mci2 = {
@@ -933,16 +832,6 @@ static struct resource pxa3xx_resources_mci3[] = {
                .end    = IRQ_MMC3,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               .start  = 100,
-               .end    = 100,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start  = 101,
-               .end    = 101,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 struct platform_device pxa3xx_device_mci3 = {
@@ -1020,18 +909,6 @@ static struct resource pxa3xx_resources_nand[] = {
                .end    = IRQ_NAND,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for Data DMA */
-               .start  = 97,
-               .end    = 97,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for Command DMA */
-               .start  = 99,
-               .end    = 99,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
@@ -1065,18 +942,6 @@ static struct resource pxa3xx_resource_ssp4[] = {
                .end    = IRQ_SSP4,
                .flags  = IORESOURCE_IRQ,
        },
-       [2] = {
-               /* DRCMR for RX */
-               .start  = 2,
-               .end    = 2,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               /* DRCMR for TX */
-               .start  = 3,
-               .end    = 3,
-               .flags  = IORESOURCE_DMA,
-       },
 };
 
 /*
@@ -1202,11 +1067,6 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
        platform_device_add(pd);
 }
 
-static struct mmp_dma_platdata pxa_dma_pdata = {
-       .dma_channels   = 0,
-       .nb_requestors  = 0,
-};
-
 static struct resource pxa_dma_resource[] = {
        [0] = {
                .start  = 0x40000000,
@@ -1233,9 +1093,7 @@ static struct platform_device pxa2xx_pxa_dma = {
        .resource       = pxa_dma_resource,
 };
 
-void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors)
+void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata)
 {
-       pxa_dma_pdata.dma_channels = nb_channels;
-       pxa_dma_pdata.nb_requestors = nb_requestors;
-       pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata);
+       pxa_register_device(&pxa2xx_pxa_dma, dma_pdata);
 }
index 11263f7c455bae2bbcd192dfcb3e3c444c632c1b..498b07bc6a3ea6323d0afb87e71ef6bb6cfd2472 100644 (file)
@@ -1,4 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#define PDMA_FILTER_PARAM(_prio, _requestor) (&(struct pxad_param) { \
+       .prio = PXAD_PRIO_##_prio, .drcmr = _requestor })
+struct mmp_dma_platdata;
+
 extern struct platform_device pxa_device_pmu;
 extern struct platform_device pxa_device_mci;
 extern struct platform_device pxa3xx_device_mci2;
@@ -55,7 +59,7 @@ extern struct platform_device pxa3xx_device_gpio;
 extern struct platform_device pxa93x_device_gpio;
 
 void __init pxa_register_device(struct platform_device *dev, void *data);
-void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors);
+void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata);
 
 struct i2c_pxa_platform_data;
 extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
index ba431fad5c47fd4456871083c5f81092da6814da..ab8808ce7e219cd5d5fd16963aa5e81f3498fe1d 100644 (file)
@@ -16,6 +16,8 @@
  * initialization stuff for PXA machines which can be overridden later if
  * need be.
  */
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/gpio-pxa.h>
 #include <linux/module.h>
@@ -26,6 +28,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
+#include <linux/platform_data/mmp_dma.h>
 
 #include <asm/mach/map.h>
 #include <asm/suspend.h>
@@ -201,6 +204,39 @@ static struct platform_device *pxa25x_devices[] __initdata = {
        &pxa_device_asoc_platform,
 };
 
+static const struct dma_slave_map pxa25x_slave_map[] = {
+       /* PXA25x, PXA27x and PXA3xx common entries */
+       { "pxa2xx-ac97", "pcm_pcm_mic_mono", PDMA_FILTER_PARAM(LOWEST, 8) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_in", PDMA_FILTER_PARAM(LOWEST, 9) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_out",
+         PDMA_FILTER_PARAM(LOWEST, 10) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_in", PDMA_FILTER_PARAM(LOWEST, 11) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_out", PDMA_FILTER_PARAM(LOWEST, 12) },
+       { "pxa-ssp-dai.1", "rx", PDMA_FILTER_PARAM(LOWEST, 13) },
+       { "pxa-ssp-dai.1", "tx", PDMA_FILTER_PARAM(LOWEST, 14) },
+       { "pxa-ssp-dai.2", "rx", PDMA_FILTER_PARAM(LOWEST, 15) },
+       { "pxa-ssp-dai.2", "tx", PDMA_FILTER_PARAM(LOWEST, 16) },
+       { "pxa2xx-ir", "rx", PDMA_FILTER_PARAM(LOWEST, 17) },
+       { "pxa2xx-ir", "tx", PDMA_FILTER_PARAM(LOWEST, 18) },
+       { "pxa2xx-mci.0", "rx", PDMA_FILTER_PARAM(LOWEST, 21) },
+       { "pxa2xx-mci.0", "tx", PDMA_FILTER_PARAM(LOWEST, 22) },
+
+       /* PXA25x specific map */
+       { "pxa25x-ssp.0", "rx", PDMA_FILTER_PARAM(LOWEST, 13) },
+       { "pxa25x-ssp.0", "tx", PDMA_FILTER_PARAM(LOWEST, 14) },
+       { "pxa25x-nssp.1", "rx", PDMA_FILTER_PARAM(LOWEST, 15) },
+       { "pxa25x-nssp.1", "tx", PDMA_FILTER_PARAM(LOWEST, 16) },
+       { "pxa25x-nssp.2", "rx", PDMA_FILTER_PARAM(LOWEST, 23) },
+       { "pxa25x-nssp.2", "tx", PDMA_FILTER_PARAM(LOWEST, 24) },
+};
+
+static struct mmp_dma_platdata pxa25x_dma_pdata = {
+       .dma_channels   = 16,
+       .nb_requestors  = 40,
+       .slave_map      = pxa25x_slave_map,
+       .slave_map_cnt  = ARRAY_SIZE(pxa25x_slave_map),
+};
+
 static int __init pxa25x_init(void)
 {
        int ret = 0;
@@ -215,7 +251,7 @@ static int __init pxa25x_init(void)
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
 
                if (!of_have_populated_dt()) {
-                       pxa2xx_set_dmac_info(16, 40);
+                       pxa2xx_set_dmac_info(&pxa25x_dma_pdata);
                        pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
                        ret = platform_add_devices(pxa25x_devices,
                                                   ARRAY_SIZE(pxa25x_devices));
index 0c06f383ad52afa0ac977b48944cedd9c996c942..5a8990a9313d193fc98baba0d46e5b37d8b87f32 100644 (file)
@@ -11,6 +11,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/gpio-pxa.h>
 #include <linux/module.h>
@@ -23,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/platform_data/i2c-pxa.h>
+#include <linux/platform_data/mmp_dma.h>
 
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
@@ -297,6 +300,40 @@ static struct platform_device *devices[] __initdata = {
        &pxa27x_device_pwm1,
 };
 
+static const struct dma_slave_map pxa27x_slave_map[] = {
+       /* PXA25x, PXA27x and PXA3xx common entries */
+       { "pxa2xx-ac97", "pcm_pcm_mic_mono", PDMA_FILTER_PARAM(LOWEST, 8) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_in", PDMA_FILTER_PARAM(LOWEST, 9) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_out",
+         PDMA_FILTER_PARAM(LOWEST, 10) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_in", PDMA_FILTER_PARAM(LOWEST, 11) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_out", PDMA_FILTER_PARAM(LOWEST, 12) },
+       { "pxa-ssp-dai.0", "rx", PDMA_FILTER_PARAM(LOWEST, 13) },
+       { "pxa-ssp-dai.0", "tx", PDMA_FILTER_PARAM(LOWEST, 14) },
+       { "pxa-ssp-dai.1", "rx", PDMA_FILTER_PARAM(LOWEST, 15) },
+       { "pxa-ssp-dai.1", "tx", PDMA_FILTER_PARAM(LOWEST, 16) },
+       { "pxa2xx-ir", "rx", PDMA_FILTER_PARAM(LOWEST, 17) },
+       { "pxa2xx-ir", "tx", PDMA_FILTER_PARAM(LOWEST, 18) },
+       { "pxa2xx-mci.0", "rx", PDMA_FILTER_PARAM(LOWEST, 21) },
+       { "pxa2xx-mci.0", "tx", PDMA_FILTER_PARAM(LOWEST, 22) },
+       { "pxa-ssp-dai.2", "rx", PDMA_FILTER_PARAM(LOWEST, 66) },
+       { "pxa-ssp-dai.2", "tx", PDMA_FILTER_PARAM(LOWEST, 67) },
+
+       /* PXA27x specific map */
+       { "pxa2xx-i2s", "rx", PDMA_FILTER_PARAM(LOWEST, 2) },
+       { "pxa2xx-i2s", "tx", PDMA_FILTER_PARAM(LOWEST, 3) },
+       { "pxa27x-camera.0", "CI_Y", PDMA_FILTER_PARAM(HIGHEST, 68) },
+       { "pxa27x-camera.0", "CI_U", PDMA_FILTER_PARAM(HIGHEST, 69) },
+       { "pxa27x-camera.0", "CI_V", PDMA_FILTER_PARAM(HIGHEST, 70) },
+};
+
+static struct mmp_dma_platdata pxa27x_dma_pdata = {
+       .dma_channels   = 32,
+       .nb_requestors  = 75,
+       .slave_map      = pxa27x_slave_map,
+       .slave_map_cnt  = ARRAY_SIZE(pxa27x_slave_map),
+};
+
 static int __init pxa27x_init(void)
 {
        int ret = 0;
@@ -313,7 +350,7 @@ static int __init pxa27x_init(void)
                if (!of_have_populated_dt()) {
                        pxa_register_device(&pxa27x_device_gpio,
                                            &pxa27x_gpio_info);
-                       pxa2xx_set_dmac_info(32, 75);
+                       pxa2xx_set_dmac_info(&pxa27x_dma_pdata);
                        ret = platform_add_devices(devices,
                                                   ARRAY_SIZE(devices));
                }
index 8c64f93b669b9539dc691e325195740aac4d86d2..df9c8970adcf4a1edf98cc0f1856df9c2575ec67 100644 (file)
@@ -12,6 +12,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -24,6 +26,7 @@
 #include <linux/of.h>
 #include <linux/syscore_ops.h>
 #include <linux/platform_data/i2c-pxa.h>
+#include <linux/platform_data/mmp_dma.h>
 
 #include <asm/mach/map.h>
 #include <asm/suspend.h>
@@ -421,6 +424,42 @@ static struct platform_device *devices[] __initdata = {
        &pxa27x_device_pwm1,
 };
 
+static const struct dma_slave_map pxa3xx_slave_map[] = {
+       /* PXA25x, PXA27x and PXA3xx common entries */
+       { "pxa2xx-ac97", "pcm_pcm_mic_mono", PDMA_FILTER_PARAM(LOWEST, 8) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_in", PDMA_FILTER_PARAM(LOWEST, 9) },
+       { "pxa2xx-ac97", "pcm_pcm_aux_mono_out",
+         PDMA_FILTER_PARAM(LOWEST, 10) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_in", PDMA_FILTER_PARAM(LOWEST, 11) },
+       { "pxa2xx-ac97", "pcm_pcm_stereo_out", PDMA_FILTER_PARAM(LOWEST, 12) },
+       { "pxa-ssp-dai.0", "rx", PDMA_FILTER_PARAM(LOWEST, 13) },
+       { "pxa-ssp-dai.0", "tx", PDMA_FILTER_PARAM(LOWEST, 14) },
+       { "pxa-ssp-dai.1", "rx", PDMA_FILTER_PARAM(LOWEST, 15) },
+       { "pxa-ssp-dai.1", "tx", PDMA_FILTER_PARAM(LOWEST, 16) },
+       { "pxa2xx-ir", "rx", PDMA_FILTER_PARAM(LOWEST, 17) },
+       { "pxa2xx-ir", "tx", PDMA_FILTER_PARAM(LOWEST, 18) },
+       { "pxa2xx-mci.0", "rx", PDMA_FILTER_PARAM(LOWEST, 21) },
+       { "pxa2xx-mci.0", "tx", PDMA_FILTER_PARAM(LOWEST, 22) },
+       { "pxa-ssp-dai.2", "rx", PDMA_FILTER_PARAM(LOWEST, 66) },
+       { "pxa-ssp-dai.2", "tx", PDMA_FILTER_PARAM(LOWEST, 67) },
+
+       /* PXA3xx specific map */
+       { "pxa-ssp-dai.3", "rx", PDMA_FILTER_PARAM(LOWEST, 2) },
+       { "pxa-ssp-dai.3", "tx", PDMA_FILTER_PARAM(LOWEST, 3) },
+       { "pxa2xx-mci.1", "rx", PDMA_FILTER_PARAM(LOWEST, 93) },
+       { "pxa2xx-mci.1", "tx", PDMA_FILTER_PARAM(LOWEST, 94) },
+       { "pxa3xx-nand", "data", PDMA_FILTER_PARAM(LOWEST, 97) },
+       { "pxa2xx-mci.2", "rx", PDMA_FILTER_PARAM(LOWEST, 100) },
+       { "pxa2xx-mci.2", "tx", PDMA_FILTER_PARAM(LOWEST, 101) },
+};
+
+static struct mmp_dma_platdata pxa3xx_dma_pdata = {
+       .dma_channels   = 32,
+       .nb_requestors  = 100,
+       .slave_map      = pxa3xx_slave_map,
+       .slave_map_cnt  = ARRAY_SIZE(pxa3xx_slave_map),
+};
+
 static int __init pxa3xx_init(void)
 {
        int ret = 0;
@@ -456,7 +495,7 @@ static int __init pxa3xx_init(void)
                if (of_have_populated_dt())
                        return 0;
 
-               pxa2xx_set_dmac_info(32, 100);
+               pxa2xx_set_dmac_info(&pxa3xx_dma_pdata);
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
                if (ret)
                        return ret;
index ba13f793fbce45734b149e861481c0a33f996ac4..ed36dcab80f1e7fb1a89cb41bc05ed71a1afd66f 100644 (file)
@@ -127,53 +127,6 @@ static int pxa_ssp_probe(struct platform_device *pdev)
        if (IS_ERR(ssp->clk))
                return PTR_ERR(ssp->clk);
 
-       if (dev->of_node) {
-               struct of_phandle_args dma_spec;
-               struct device_node *np = dev->of_node;
-               int ret;
-
-               /*
-                * FIXME: we should allocate the DMA channel from this
-                * context and pass the channel down to the ssp users.
-                * For now, we lookup the rx and tx indices manually
-                */
-
-               /* rx */
-               ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells",
-                                                0, &dma_spec);
-
-               if (ret) {
-                       dev_err(dev, "Can't parse dmas property\n");
-                       return -ENODEV;
-               }
-               ssp->drcmr_rx = dma_spec.args[0];
-               of_node_put(dma_spec.np);
-
-               /* tx */
-               ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells",
-                                                1, &dma_spec);
-               if (ret) {
-                       dev_err(dev, "Can't parse dmas property\n");
-                       return -ENODEV;
-               }
-               ssp->drcmr_tx = dma_spec.args[0];
-               of_node_put(dma_spec.np);
-       } else {
-               res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-               if (res == NULL) {
-                       dev_err(dev, "no SSP RX DRCMR defined\n");
-                       return -ENODEV;
-               }
-               ssp->drcmr_rx = res->start;
-
-               res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-               if (res == NULL) {
-                       dev_err(dev, "no SSP TX DRCMR defined\n");
-                       return -ENODEV;
-               }
-               ssp->drcmr_tx = res->start;
-       }
-
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
                dev_err(dev, "no memory resource defined\n");
index f6c46e9a4dc0f1425ae99b7fbf5dfa71d6a86eeb..e8b6a2e464c988e5eb5f586fa38fc426419b1678 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/libata.h>
 #include <linux/platform_device.h>
 #include <linux/dmaengine.h>
-#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
@@ -180,8 +179,6 @@ static int pxa_ata_probe(struct platform_device *pdev)
        struct resource *irq_res;
        struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
        struct dma_slave_config config;
-       dma_cap_mask_t mask;
-       struct pxad_param param;
        int ret = 0;
 
        /*
@@ -278,10 +275,6 @@ static int pxa_ata_probe(struct platform_device *pdev)
 
        ap->private_data = data;
 
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       param.prio = PXAD_PRIO_LOWEST;
-       param.drcmr = pdata->dma_dreq;
        memset(&config, 0, sizeof(config));
        config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
        config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
@@ -294,8 +287,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
         * Request the DMA channel
         */
        data->dma_chan =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param, &pdev->dev, "data");
+               dma_request_slave_channel(&pdev->dev, "data");
        if (!data->dma_chan)
                return -EBUSY;
        ret = dmaengine_slave_config(data->dma_chan, &config);
index b53fb618bbf6b5a44043d470fe5ae3a55ddb4147..b31c28b67ad3ec6aef3babf5402defaac504f680 100644 (file)
@@ -179,6 +179,8 @@ static unsigned int pxad_drcmr(unsigned int line)
        return 0x1000 + line * 4;
 }
 
+bool pxad_filter_fn(struct dma_chan *chan, void *param);
+
 /*
  * Debug fs
  */
@@ -760,6 +762,8 @@ static void pxad_free_chan_resources(struct dma_chan *dchan)
        dma_pool_destroy(chan->desc_pool);
        chan->desc_pool = NULL;
 
+       chan->drcmr = U32_MAX;
+       chan->prio = PXAD_PRIO_LOWEST;
 }
 
 static void pxad_free_desc(struct virt_dma_desc *vd)
@@ -1384,6 +1388,9 @@ static int pxad_init_dmadev(struct platform_device *op,
                c = devm_kzalloc(&op->dev, sizeof(*c), GFP_KERNEL);
                if (!c)
                        return -ENOMEM;
+
+               c->drcmr = U32_MAX;
+               c->prio = PXAD_PRIO_LOWEST;
                c->vc.desc_free = pxad_free_desc;
                vchan_init(&c->vc, &pdev->slave);
                init_waitqueue_head(&c->wq_state);
@@ -1396,9 +1403,10 @@ static int pxad_probe(struct platform_device *op)
 {
        struct pxad_device *pdev;
        const struct of_device_id *of_id;
+       const struct dma_slave_map *slave_map = NULL;
        struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
        struct resource *iores;
-       int ret, dma_channels = 0, nb_requestors = 0;
+       int ret, dma_channels = 0, nb_requestors = 0, slave_map_cnt = 0;
        const enum dma_slave_buswidth widths =
                DMA_SLAVE_BUSWIDTH_1_BYTE   | DMA_SLAVE_BUSWIDTH_2_BYTES |
                DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -1429,6 +1437,8 @@ static int pxad_probe(struct platform_device *op)
        } else if (pdata && pdata->dma_channels) {
                dma_channels = pdata->dma_channels;
                nb_requestors = pdata->nb_requestors;
+               slave_map = pdata->slave_map;
+               slave_map_cnt = pdata->slave_map_cnt;
        } else {
                dma_channels = 32;      /* default 32 channel */
        }
@@ -1440,6 +1450,9 @@ static int pxad_probe(struct platform_device *op)
        pdev->slave.device_prep_dma_memcpy = pxad_prep_memcpy;
        pdev->slave.device_prep_slave_sg = pxad_prep_slave_sg;
        pdev->slave.device_prep_dma_cyclic = pxad_prep_dma_cyclic;
+       pdev->slave.filter.map = slave_map;
+       pdev->slave.filter.mapcnt = slave_map_cnt;
+       pdev->slave.filter.fn = pxad_filter_fn;
 
        pdev->slave.copy_align = PDMA_ALIGNMENT;
        pdev->slave.src_addr_widths = widths;
index d85ffbfb7c1fde9271f1e42ec28a31b205206a78..b6e9e93bde7a8ad635a32eab35fc4658610d571a 100644 (file)
@@ -2375,8 +2375,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
                .src_maxburst = 8,
                .direction = DMA_DEV_TO_MEM,
        };
-       dma_cap_mask_t mask;
-       struct pxad_param params;
        char clk_name[V4L2_CLK_NAME_SIZE];
        int irq;
        int err = 0, i;
@@ -2450,34 +2448,20 @@ static int pxa_camera_probe(struct platform_device *pdev)
        pcdev->base = base;
 
        /* request dma */
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       dma_cap_set(DMA_PRIVATE, mask);
-
-       params.prio = 0;
-       params.drcmr = 68;
-       pcdev->dma_chans[0] =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &params, &pdev->dev, "CI_Y");
+       pcdev->dma_chans[0] = dma_request_slave_channel(&pdev->dev, "CI_Y");
        if (!pcdev->dma_chans[0]) {
                dev_err(&pdev->dev, "Can't request DMA for Y\n");
                return -ENODEV;
        }
 
-       params.drcmr = 69;
-       pcdev->dma_chans[1] =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &params, &pdev->dev, "CI_U");
+       pcdev->dma_chans[1] = dma_request_slave_channel(&pdev->dev, "CI_U");
        if (!pcdev->dma_chans[1]) {
                dev_err(&pdev->dev, "Can't request DMA for Y\n");
                err = -ENODEV;
                goto exit_free_dma_y;
        }
 
-       params.drcmr = 70;
-       pcdev->dma_chans[2] =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &params, &pdev->dev, "CI_V");
+       pcdev->dma_chans[2] = dma_request_slave_channel(&pdev->dev, "CI_V");
        if (!pcdev->dma_chans[2]) {
                dev_err(&pdev->dev, "Can't request DMA for V\n");
                err = -ENODEV;
index c763b404510f3a29d3864290297b22f596701cc3..6c94474e36f461eefac935c794879c297a62c94a 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma/pxa-dma.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/mmc/host.h>
@@ -637,10 +636,8 @@ static int pxamci_probe(struct platform_device *pdev)
 {
        struct mmc_host *mmc;
        struct pxamci_host *host = NULL;
-       struct resource *r, *dmarx, *dmatx;
-       struct pxad_param param_rx, param_tx;
+       struct resource *r;
        int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
-       dma_cap_mask_t mask;
 
        ret = pxamci_of_init(pdev);
        if (ret)
@@ -739,34 +736,14 @@ static int pxamci_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, mmc);
 
-       if (!pdev->dev.of_node) {
-               dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-               dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-               if (!dmarx || !dmatx) {
-                       ret = -ENXIO;
-                       goto out;
-               }
-               param_rx.prio = PXAD_PRIO_LOWEST;
-               param_rx.drcmr = dmarx->start;
-               param_tx.prio = PXAD_PRIO_LOWEST;
-               param_tx.drcmr = dmatx->start;
-       }
-
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-
-       host->dma_chan_rx =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param_rx, &pdev->dev, "rx");
+       host->dma_chan_rx = dma_request_slave_channel(&pdev->dev, "rx");
        if (host->dma_chan_rx == NULL) {
                dev_err(&pdev->dev, "unable to request rx dma channel\n");
                ret = -ENODEV;
                goto out;
        }
 
-       host->dma_chan_tx =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param_tx,  &pdev->dev, "tx");
+       host->dma_chan_tx = dma_request_slave_channel(&pdev->dev, "tx");
        if (host->dma_chan_tx == NULL) {
                dev_err(&pdev->dev, "unable to request tx dma channel\n");
                ret = -ENODEV;
index ebb1d141b90000c069b0634fe0a3c4d5d5f842d4..00d9f29bbdb6148a1584d4d4c7d449c0066beee9 100644 (file)
@@ -2612,8 +2612,6 @@ static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
                                                    dev);
        struct dma_slave_config config = {};
        struct resource *r;
-       dma_cap_mask_t mask;
-       struct pxad_param param;
        int ret;
 
        if (!IS_ENABLED(CONFIG_PXA_DMA)) {
@@ -2626,20 +2624,7 @@ static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
        if (ret)
                return ret;
 
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!r) {
-               dev_err(nfc->dev, "No resource defined for data DMA\n");
-               return -ENXIO;
-       }
-
-       param.drcmr = r->start;
-       param.prio = PXAD_PRIO_LOWEST;
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       nfc->dma_chan =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param, nfc->dev,
-                                                "data");
+       nfc->dma_chan = dma_request_slave_channel(nfc->dev, "data");
        if (!nfc->dma_chan) {
                dev_err(nfc->dev,
                        "Unable to request data DMA channel\n");
index e56ec7af4fd7ca1054dba37f0a1800c079d21d27..9fc594f69eff3e693cf4297fe33a1dd249048c94 100644 (file)
@@ -9,6 +9,15 @@ enum pxad_chan_prio {
        PXAD_PRIO_LOWEST,
 };
 
+/**
+ * struct pxad_param - dma channel request parameters
+ * @drcmr: requestor line number
+ * @prio: minimal mandatory priority of the channel
+ *
+ * If a requested channel is granted, its priority will be at least @prio,
+ * ie. if PXAD_PRIO_LOW is required, the requested channel will be either
+ * PXAD_PRIO_LOW, PXAD_PRIO_NORMAL or PXAD_PRIO_HIGHEST.
+ */
 struct pxad_param {
        unsigned int drcmr;
        enum pxad_chan_prio prio;
index d1397c8ed94eef8768fe096d1ef00cdf3d42e95e..6397b9c8149ae8d110e7c374a0257499914a3b2c 100644 (file)
 #ifndef MMP_DMA_H
 #define MMP_DMA_H
 
+struct dma_slave_map;
+
 struct mmp_dma_platdata {
        int dma_channels;
        int nb_requestors;
+       int slave_map_cnt;
+       const struct dma_slave_map *slave_map;
 };
 
 #endif /* MMP_DMA_H */
index 8461b18e4608f206b8982192e07760aadb739f42..13b4244d44c1f8ebf052a8f31f36671ca53a667d 100644 (file)
 #define SSACD_SCDB             (1 << 3)        /* SSPSYSCLK Divider Bypass */
 #define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
 #define SSACD_ACDS(x)          ((x) << 0)      /* Audio clock divider select */
+#define SSACD_ACDS_1           (0)
+#define SSACD_ACDS_2           (1)
+#define SSACD_ACDS_4           (2)
+#define SSACD_ACDS_8           (3)
+#define SSACD_ACDS_16          (4)
+#define SSACD_ACDS_32          (5)
+#define SSACD_SCDB_4X          (0)
+#define SSACD_SCDB_1X          (1)
 #define SSACD_SCDX8            (1 << 7)        /* SYSCLK division ratio select */
 
 /* LPSS SSP */
@@ -212,8 +220,6 @@ struct ssp_device {
        int             type;
        int             use_count;
        int             irq;
-       int             drcmr_rx;
-       int             drcmr_tx;
 
        struct device_node      *of_node;
 };
index ec04be9ab119281b0b1f8f1dfdb9eedf6132448d..9792d25fa36928b8470bfd6891dbb98ebf401733 100644 (file)
@@ -1,10 +1,8 @@
-/*
- *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+/* SPDX-License-Identifier: GPL-2.0
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
  */
+
 #ifndef __SOUND_AC97_CODEC2_H
 #define __SOUND_AC97_CODEC2_H
 
index 1351cba40048e577ccfb19b7a7ee072b5690cd6f..57e19afa31ab5c63ab810ca94c6ec8627cfc911f 100644 (file)
@@ -1,14 +1,11 @@
-/*
- *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+/* SPDX-License-Identifier: GPL-2.0
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
  *
  * This file is for backward compatibility with snd_ac97 structure and its
  * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
- *
  */
+
 #ifndef AC97_COMPAT_H
 #define AC97_COMPAT_H
 
index b36ecdd64f14aca196dbb9a8791b751229c21ac9..06b5afb7fa6b9fedfd997a1e87634012470ce9c4 100644 (file)
@@ -1,10 +1,8 @@
-/*
- *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+/* SPDX-License-Identifier: GPL-2.0
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
  */
+
 #ifndef AC97_CONTROLLER_H
 #define AC97_CONTROLLER_H
 
index 9a4fa0c3264aac22ca794751e7144052e1fe0c35..843f73f3705aec45de3d007cf6ca449923e17274 100644 (file)
@@ -1,27 +1,11 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *  Universal interface for Audio Codec '97
  *
  *  For more details look to AC '97 component specification revision 2.1
  *  by Intel Corporation (http://developer.intel.com).
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
-
 /*
  *  AC'97 codec registers
  */
index 89d311a503d34802223b98dbb4e80c924afee0b8..cc383991c0fe59c774020c4bb4d487ca2e75bee8 100644 (file)
@@ -1,30 +1,15 @@
-#ifndef __SOUND_AC97_CODEC_H
-#define __SOUND_AC97_CODEC_H
-
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *  Universal interface for Audio Codec '97
  *
  *  For more details look to AC '97 component specification revision 2.1
  *  by Intel Corporation (http://developer.intel.com).
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
+#ifndef __SOUND_AC97_CODEC_H
+#define __SOUND_AC97_CODEC_H
+
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
index 9924bc9cbc7c26ea3cdb82478f66bad6ab45be18..ea8c93bbb0e05490b023fdf402e8aa1d2f76ceeb 100644 (file)
@@ -1,27 +1,12 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  *  compress_driver.h - compress offload driver definations
  *
  *  Copyright (C) 2011 Intel Corporation
  *  Authors:   Vinod Koul <vinod.koul@linux.intel.com>
  *             Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
  */
+
 #ifndef __COMPRESS_DRIVER_H
 #define __COMPRESS_DRIVER_H
 
index e3481eebdd98d860cebc21d462bdcd303fd4fdfc..2c4cfaa135a62eae880e7d7fd78eb611055a7bb5 100644 (file)
@@ -1,17 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  *  Copyright (C) 2012, Analog Devices Inc.
  *     Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
+
 #ifndef __SOUND_DMAENGINE_PCM_H__
 #define __SOUND_DMAENGINE_PCM_H__
 
index 9c3db3dce32b4a5e3f0bd4a14d65eaa4556341bf..67561b9979150833b4b433a38a59aedc101df573 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef __SOUND_MEMALLOC_H
 #define __SOUND_MEMALLOC_H
 
+#include <asm/page.h>
+
 struct device;
 
 /*
@@ -67,6 +69,14 @@ struct snd_dma_buffer {
        void *private_data;     /* private for allocator; don't touch */
 };
 
+/*
+ * return the pages matching with the given byte size
+ */
+static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
+{
+       return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
 #ifdef CONFIG_SND_DMA_SGBUF
 /*
  * Scatter-Gather generic device pages
@@ -90,14 +100,6 @@ struct snd_sg_buf {
        struct device *dev;
 };
 
-/*
- * return the pages matching with the given byte size
- */
-static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
-{
-       return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-}
-
 /*
  * return the physical address at the corresponding offset
  */
index c704357775fc4ef077ef52fb27cfb97c75b378ee..2dd37cada7c088d7bd6c8b4bd35f18c28c63cc86 100644 (file)
@@ -87,6 +87,13 @@ static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
        mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
 }
 
+/* Most of drivers need only this one */
+static inline void snd_mask_set_format(struct snd_mask *mask,
+                                      snd_pcm_format_t format)
+{
+       snd_mask_set(mask, (__force unsigned int)format);
+}
+
 static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
 {
        mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
@@ -369,8 +376,7 @@ static inline int params_physical_width(const struct snd_pcm_hw_params *p)
 static inline void
 params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
 {
-       snd_mask_set(hw_param_mask(p, SNDRV_PCM_HW_PARAM_FORMAT),
-               (__force int)fmt);
+       snd_mask_set_format(hw_param_mask(p, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
 }
 
 #endif /* __SOUND_PCM_PARAMS_H */
index 63f75450d3dbb9f09eb9c11a1984c6a1c8e8fea2..6758fc12fa84b4ada446868964ddc26ec77f3110 100644 (file)
@@ -8,20 +8,23 @@
 /* PCM */
 struct snd_pcm_substream;
 struct snd_pcm_hw_params;
+struct snd_soc_pcm_runtime;
 struct snd_pcm;
 
-extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
+extern int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params);
-extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
 extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
 extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
-extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
-extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream);
-extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_open(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_close(struct snd_pcm_substream *substream);
 extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
        struct vm_area_struct *vma);
 extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream);
 extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
+extern int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd);
+extern const struct snd_pcm_ops pxa2xx_pcm_ops;
 
 /* AC97 */
 
diff --git a/include/sound/rt5682.h b/include/sound/rt5682.h
new file mode 100644 (file)
index 0000000..0251797
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * linux/sound/rt5682.h -- Platform data for RT5682
+ *
+ * Copyright 2018 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5682_H
+#define __LINUX_SND_RT5682_H
+
+enum rt5682_dmic1_data_pin {
+       RT5682_DMIC1_NULL,
+       RT5682_DMIC1_DATA_GPIO2,
+       RT5682_DMIC1_DATA_GPIO5,
+};
+
+enum rt5682_dmic1_clk_pin {
+       RT5682_DMIC1_CLK_GPIO1,
+       RT5682_DMIC1_CLK_GPIO3,
+};
+
+enum rt5682_jd_src {
+       RT5682_JD_NULL,
+       RT5682_JD1,
+};
+
+struct rt5682_platform_data {
+
+       int ldo1_en; /* GPIO for LDO1_EN */
+
+       enum rt5682_dmic1_data_pin dmic1_data_pin;
+       enum rt5682_dmic1_clk_pin dmic1_clk_pin;
+       enum rt5682_jd_src jd_src;
+};
+
+#endif
+
index a6a2e1547092a8e232c27bf5a8778b4eaa63a1bb..d264e5463f22dfd62ac4add4a64f5a747e9d7729 100644 (file)
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * ASoC simple sound card support
  *
  * Copyright (C) 2012 Renesas Solutions Corp.
  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef __SIMPLE_CARD_H
index 7e25afce6566fe315496979c9da9f6176d3fae20..8bc5e2d8b13c47e0512cc42fe8637735d06ef315 100644 (file)
@@ -1,17 +1,20 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * simple_card_utils.h
  *
  * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
+
 #ifndef __SIMPLE_CARD_UTILS_H
 #define __SIMPLE_CARD_UTILS_H
 
 #include <sound/soc.h>
 
+#define asoc_simple_card_init_hp(card, sjack, prefix) \
+       asoc_simple_card_init_jack(card, sjack, 1, prefix)
+#define asoc_simple_card_init_mic(card, sjack, prefix) \
+       asoc_simple_card_init_jack(card, sjack, 0, prefix)
+
 struct asoc_simple_dai {
        const char *name;
        unsigned int sysclk;
@@ -28,6 +31,12 @@ struct asoc_simple_card_data {
        u32 convert_channels;
 };
 
+struct asoc_simple_jack {
+       struct snd_soc_jack jack;
+       struct snd_soc_jack_pin pin;
+       struct snd_soc_jack_gpio gpio;
+};
+
 int asoc_simple_card_parse_daifmt(struct device *dev,
                                  struct device_node *node,
                                  struct device_node *codec,
@@ -107,4 +116,8 @@ int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
 int asoc_simple_card_of_parse_widgets(struct snd_soc_card *card,
                                      char *prefix);
 
+int asoc_simple_card_init_jack(struct snd_soc_card *card,
+                              struct asoc_simple_jack *sjack,
+                              int is_hp, char *prefix);
+
 #endif /* __SIMPLE_CARD_UTILS_H */
index 9da6388c20a1cc6a5ab509b9800139583a495912..bb1d24b703fb05a09b751c1fa7d36177553250b8 100644 (file)
@@ -1,16 +1,6 @@
-
-/*
- * Copyright (C) 2017, Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+/* SPDX-License-Identifier: GPL-2.0
  *
+ * Copyright (C) 2017, Intel Corporation. All rights reserved.
  */
 
 #ifndef __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
@@ -29,5 +19,10 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
 extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
 extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
 extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[];
 
 #endif
index 082224275f5232256819f4f4316886e0965c5a79..e45b2330d16a458b638f08dcdcdd87a4f87f76b0 100644 (file)
@@ -1,15 +1,6 @@
-/*
- * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+/* SPDX-License-Identifier: GPL-2.0
  *
+ * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
  */
 
 #ifndef __LINUX_SND_SOC_ACPI_H
index e6f8c40ed43c3f1615aaad20af4e467a3bc937e5..f5d70041108f75d45098ca21b1a3c1ee9610ff98 100644 (file)
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * linux/sound/soc-dai.h -- ALSA SoC Layer
  *
  * Copyright:  2005-2008 Wolfson Microelectronics. PLC.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Digital Audio Interface (DAI) API.
  */
 
@@ -141,6 +138,11 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
 int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
                             int direction);
 
+
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+               unsigned int *tx_num, unsigned int *tx_slot,
+               unsigned int *rx_num, unsigned int *rx_slot);
+
 int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
 
 struct snd_soc_dai_ops {
@@ -168,6 +170,9 @@ struct snd_soc_dai_ops {
        int (*set_channel_map)(struct snd_soc_dai *dai,
                unsigned int tx_num, unsigned int *tx_slot,
                unsigned int rx_num, unsigned int *rx_slot);
+       int (*get_channel_map)(struct snd_soc_dai *dai,
+                       unsigned int *tx_num, unsigned int *tx_slot,
+                       unsigned int *rx_num, unsigned int *rx_slot);
        int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
 
        int (*set_sdw_stream)(struct snd_soc_dai *dai,
index a6ce2de4e20a837c79745c79cc7559a517a157fb..af9ef16cc34d36f6fd314cc2522997a4b2dbc12f 100644 (file)
@@ -1,13 +1,10 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * linux/sound/soc-dapm.h -- ALSA SoC Dynamic Audio Power Management
  *
- * Author:             Liam Girdwood
- * Created:            Aug 11th 2005
+ * Author:     Liam Girdwood
+ * Created:    Aug 11th 2005
  * Copyright:  Wolfson Microelectronics. PLC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_SND_SOC_DAPM_H
index 806059052bfcca4aa9d46ff3b0f061442136e84f..9bb92f187af87a3f8d7196c7580320792af35137 100644 (file)
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * linux/sound/soc-dpcm.h -- ALSA SoC Dynamic PCM Support
  *
  * Author:             Liam Girdwood <lrg@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_SND_SOC_DPCM_H
index f552c3f56368c48a524e8889f5dabbc09f45d509..fa4b8413d2e222dd51e884f69e563c010b854980 100644 (file)
@@ -1,13 +1,10 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * linux/sound/soc-topology.h -- ALSA SoC Firmware Controls and DAPM
  *
  * Copyright (C) 2012 Texas Instruments Inc.
  * Copyright (C) 2015 Intel Corporation.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
  * algorithms, equalisers, DAIs, widgets, FE caps, BE caps, codec link caps etc.
  */
@@ -30,6 +27,9 @@ struct snd_soc_dapm_context;
 struct snd_soc_card;
 struct snd_kcontrol_new;
 struct snd_soc_dai_link;
+struct snd_soc_dai_driver;
+struct snd_soc_dai;
+struct snd_soc_dapm_route;
 
 /* object scan be loaded and unloaded in groups with identfying indexes */
 #define SND_SOC_TPLG_INDEX_ALL 0       /* ID that matches all FW objects */
@@ -109,35 +109,44 @@ struct snd_soc_tplg_widget_events {
 struct snd_soc_tplg_ops {
 
        /* external kcontrol init - used for any driver specific init */
-       int (*control_load)(struct snd_soc_component *,
+       int (*control_load)(struct snd_soc_component *, int index,
                struct snd_kcontrol_new *, struct snd_soc_tplg_ctl_hdr *);
        int (*control_unload)(struct snd_soc_component *,
                struct snd_soc_dobj *);
 
+       /* DAPM graph route element loading and unloading */
+       int (*dapm_route_load)(struct snd_soc_component *, int index,
+               struct snd_soc_dapm_route *route);
+       int (*dapm_route_unload)(struct snd_soc_component *,
+               struct snd_soc_dobj *);
+
        /* external widget init - used for any driver specific init */
-       int (*widget_load)(struct snd_soc_component *,
+       int (*widget_load)(struct snd_soc_component *, int index,
                struct snd_soc_dapm_widget *,
                struct snd_soc_tplg_dapm_widget *);
-       int (*widget_ready)(struct snd_soc_component *,
+       int (*widget_ready)(struct snd_soc_component *, int index,
                struct snd_soc_dapm_widget *,
                struct snd_soc_tplg_dapm_widget *);
        int (*widget_unload)(struct snd_soc_component *,
                struct snd_soc_dobj *);
 
        /* FE DAI - used for any driver specific init */
-       int (*dai_load)(struct snd_soc_component *,
-               struct snd_soc_dai_driver *dai_drv);
+       int (*dai_load)(struct snd_soc_component *, int index,
+               struct snd_soc_dai_driver *dai_drv,
+               struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai);
+
        int (*dai_unload)(struct snd_soc_component *,
                struct snd_soc_dobj *);
 
        /* DAI link - used for any driver specific init */
-       int (*link_load)(struct snd_soc_component *,
-               struct snd_soc_dai_link *link);
+       int (*link_load)(struct snd_soc_component *, int index,
+               struct snd_soc_dai_link *link,
+               struct snd_soc_tplg_link_config *cfg);
        int (*link_unload)(struct snd_soc_component *,
                struct snd_soc_dobj *);
 
        /* callback to handle vendor bespoke data */
-       int (*vendor_load)(struct snd_soc_component *,
+       int (*vendor_load)(struct snd_soc_component *, int index,
                struct snd_soc_tplg_hdr *);
        int (*vendor_unload)(struct snd_soc_component *,
                struct snd_soc_tplg_hdr *);
@@ -146,7 +155,7 @@ struct snd_soc_tplg_ops {
        void (*complete)(struct snd_soc_component *);
 
        /* manifest - optional to inform component of manifest */
-       int (*manifest)(struct snd_soc_component *,
+       int (*manifest)(struct snd_soc_component *, int index,
                struct snd_soc_tplg_manifest *);
 
        /* vendor specific kcontrol handlers available for binding */
index 1378dcd2128aa34f9fdbf9197817760bb98e96df..ace474e8649e6d7b64575e7031efe713465d2ffe 100644 (file)
@@ -1,13 +1,10 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * linux/sound/soc.h -- ALSA SoC Layer
  *
- * Author:             Liam Girdwood
- * Created:            Aug 11th 2005
+ * Author:     Liam Girdwood
+ * Created:    Aug 11th 2005
  * Copyright:  Wolfson Microelectronics. PLC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_SND_SOC_H
@@ -20,6 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/component.h>
 #include <linux/regmap.h>
 #include <linux/log2.h>
 #include <sound/core.h>
@@ -806,6 +804,14 @@ struct snd_soc_component_driver {
        unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
        unsigned int endianness:1;
        unsigned int non_legacy_dai_naming:1;
+
+       /* this component uses topology and ignore machine driver FEs */
+       const char *ignore_machine;
+       const char *topology_name_prefix;
+       int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+                                 struct snd_pcm_hw_params *params);
+       bool use_dai_pcm_id;    /* use the DAI link PCM ID as PCM device number */
+       int be_pcm_base;        /* base device ID for all BE PCMs */
 };
 
 struct snd_soc_component {
@@ -957,10 +963,17 @@ struct snd_soc_dai_link {
 
        /* DPCM used FE & BE merged format */
        unsigned int dpcm_merged_format:1;
+       /* DPCM used FE & BE merged channel */
+       unsigned int dpcm_merged_chan:1;
+       /* DPCM used FE & BE merged rate */
+       unsigned int dpcm_merged_rate:1;
 
        /* pmdown_time is ignored at stop */
        unsigned int ignore_pmdown_time:1;
 
+       /* Do not create a PCM for this DAI link (Backend link) */
+       unsigned int ignore:1;
+
        struct list_head list; /* DAI link list of the soc card */
        struct snd_soc_dobj dobj; /* For topology */
 };
@@ -1000,6 +1013,7 @@ struct snd_soc_card {
        const char *long_name;
        const char *driver_name;
        char dmi_longname[80];
+       char topology_shortname[32];
 
        struct device *dev;
        struct snd_card *snd_card;
@@ -1009,6 +1023,7 @@ struct snd_soc_card {
        struct mutex dapm_mutex;
 
        bool instantiated;
+       bool topology_shortname_created;
 
        int (*probe)(struct snd_soc_card *card);
        int (*late_probe)(struct snd_soc_card *card);
@@ -1076,6 +1091,12 @@ struct snd_soc_card {
 
        struct work_struct deferred_resume_work;
 
+       /* component framework related */
+       bool components_added;
+       /* set in machine driver to enable/disable auto re-binding */
+       bool auto_bind;
+       struct component_match *match;
+
        /* lists of probed devices belonging to this card */
        struct list_head component_dev_list;
 
@@ -1412,6 +1433,9 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
                               const char *propname);
 int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
                                          const char *propname);
+int snd_soc_of_get_slot_mask(struct device_node *np,
+                            const char *prop_name,
+                            unsigned int *mask);
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
                              unsigned int *tx_mask,
                              unsigned int *rx_mask,
index 65171f6657a2984ccc14ce907a4c7c87d77d196b..5fbd47a9177ee250a5f05eb6211e5a4424ad69fc 100644 (file)
@@ -17,14 +17,9 @@ config SND_ARMAACI
        select SND_PCM
        select SND_AC97_CODEC
 
-config SND_PXA2XX_PCM
-       tristate
-       select SND_PCM
-
 config SND_PXA2XX_AC97
        tristate "AC97 driver for the Intel PXA2xx chip"
        depends on ARCH_PXA
-       select SND_PXA2XX_PCM
        select SND_AC97_CODEC
        select SND_PXA2XX_LIB
        select SND_PXA2XX_LIB_AC97
index e10d5b1695658085ca50ed09b8763d8103bf337f..34c7694898779581e7ffeee20aaeef95eba6cea9 100644 (file)
@@ -6,9 +6,6 @@
 obj-$(CONFIG_SND_ARMAACI)      += snd-aaci.o
 snd-aaci-objs                  := aaci.o
 
-obj-$(CONFIG_SND_PXA2XX_PCM)   += snd-pxa2xx-pcm.o
-snd-pxa2xx-pcm-objs            := pxa2xx-pcm.o
-
 obj-$(CONFIG_SND_PXA2XX_LIB)   += snd-pxa2xx-lib.o
 snd-pxa2xx-lib-y               := pxa2xx-pcm-lib.o
 snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_AC97)   += pxa2xx-ac97-lib.o
index 5950a9e218d962294b4e46f36e795e0af37b0250..8eafd3d3dff67324899cd5433cce91d6cbc28a23 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <sound/pxa2xx-lib.h>
 
@@ -337,6 +338,17 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
                        dev_err(&dev->dev, "Invalid reset GPIO %d\n",
                                pdata->reset_gpio);
                }
+       } else if (!pdata && dev->dev.of_node) {
+               pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+               pdata->reset_gpio = of_get_named_gpio(dev->dev.of_node,
+                                                     "reset-gpios", 0);
+               if (pdata->reset_gpio == -ENOENT)
+                       pdata->reset_gpio = -1;
+               else if (pdata->reset_gpio < 0)
+                       return pdata->reset_gpio;
+               reset_gpio = pdata->reset_gpio;
        } else {
                if (cpu_is_pxa27x())
                        reset_gpio = 113;
index 4bc244c40f80b45c223b8f186c7e694030734650..1f72672262d06406d21ea4fc00c400fac24fd94b 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/dmaengine.h>
-#include <linux/dma/pxa-dma.h>
+#include <linux/dma-mapping.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -27,8 +27,6 @@
 #include <mach/regs-ac97.h>
 #include <mach/audio.h>
 
-#include "pxa2xx-pcm.h"
-
 static void pxa2xx_ac97_legacy_reset(struct snd_ac97 *ac97)
 {
        if (!pxa2xx_ac97_try_cold_reset())
@@ -63,61 +61,46 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
        .reset  = pxa2xx_ac97_legacy_reset,
 };
 
-static struct pxad_param pxa2xx_ac97_pcm_out_req = {
-       .prio = PXAD_PRIO_LOWEST,
-       .drcmr = 12,
-};
-
-static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
-       .addr           = __PREG(PCDR),
-       .addr_width     = DMA_SLAVE_BUSWIDTH_4_BYTES,
-       .maxburst       = 32,
-       .filter_data    = &pxa2xx_ac97_pcm_out_req,
-};
-
-static struct pxad_param pxa2xx_ac97_pcm_in_req = {
-       .prio = PXAD_PRIO_LOWEST,
-       .drcmr = 11,
-};
-
-static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
-       .addr           = __PREG(PCDR),
-       .addr_width     = DMA_SLAVE_BUSWIDTH_4_BYTES,
-       .maxburst       = 32,
-       .filter_data    = &pxa2xx_ac97_pcm_in_req,
-};
-
 static struct snd_pcm *pxa2xx_ac97_pcm;
 static struct snd_ac97 *pxa2xx_ac97_ac97;
 
-static int pxa2xx_ac97_pcm_startup(struct snd_pcm_substream *substream)
+static int pxa2xx_ac97_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        pxa2xx_audio_ops_t *platform_ops;
-       int r;
+       int ret, i;
+
+       ret = pxa2xx_pcm_open(substream);
+       if (ret)
+               return ret;
 
        runtime->hw.channels_min = 2;
        runtime->hw.channels_max = 2;
 
-       r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
-           AC97_RATES_FRONT_DAC : AC97_RATES_ADC;
-       runtime->hw.rates = pxa2xx_ac97_ac97->rates[r];
+       i = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+               AC97_RATES_FRONT_DAC : AC97_RATES_ADC;
+       runtime->hw.rates = pxa2xx_ac97_ac97->rates[i];
        snd_pcm_limit_hw_rates(runtime);
 
-               platform_ops = substream->pcm->card->dev->platform_data;
-       if (platform_ops && platform_ops->startup)
-               return platform_ops->startup(substream, platform_ops->priv);
-       else
-               return 0;
+       platform_ops = substream->pcm->card->dev->platform_data;
+       if (platform_ops && platform_ops->startup) {
+               ret = platform_ops->startup(substream, platform_ops->priv);
+               if (ret < 0)
+                       pxa2xx_pcm_close(substream);
+       }
+
+       return ret;
 }
 
-static void pxa2xx_ac97_pcm_shutdown(struct snd_pcm_substream *substream)
+static int pxa2xx_ac97_pcm_close(struct snd_pcm_substream *substream)
 {
        pxa2xx_audio_ops_t *platform_ops;
 
-               platform_ops = substream->pcm->card->dev->platform_data;
+       platform_ops = substream->pcm->card->dev->platform_data;
        if (platform_ops && platform_ops->shutdown)
                platform_ops->shutdown(substream, platform_ops->priv);
+
+       return 0;
 }
 
 static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream)
@@ -125,17 +108,15 @@ static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
                  AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
+       int ret;
+
+       ret = pxa2xx_pcm_prepare(substream);
+       if (ret < 0)
+               return ret;
+
        return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate);
 }
 
-static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
-       .playback_params        = &pxa2xx_ac97_pcm_out,
-       .capture_params         = &pxa2xx_ac97_pcm_in,
-       .startup                = pxa2xx_ac97_pcm_startup,
-       .shutdown               = pxa2xx_ac97_pcm_shutdown,
-       .prepare                = pxa2xx_ac97_pcm_prepare,
-};
-
 #ifdef CONFIG_PM_SLEEP
 
 static int pxa2xx_ac97_do_suspend(struct snd_card *card)
@@ -193,6 +174,53 @@ static int pxa2xx_ac97_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
 #endif
 
+static const struct snd_pcm_ops pxa2xx_ac97_pcm_ops = {
+       .open           = pxa2xx_ac97_pcm_open,
+       .close          = pxa2xx_ac97_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = pxa2xx_pcm_hw_params,
+       .hw_free        = pxa2xx_pcm_hw_free,
+       .prepare        = pxa2xx_ac97_pcm_prepare,
+       .trigger        = pxa2xx_pcm_trigger,
+       .pointer        = pxa2xx_pcm_pointer,
+       .mmap           = pxa2xx_pcm_mmap,
+};
+
+
+static int pxa2xx_ac97_pcm_new(struct snd_card *card)
+{
+       struct snd_pcm *pcm;
+       int stream, ret;
+
+       ret = snd_pcm_new(card, "PXA2xx-PCM", 0, 1, 1, &pcm);
+       if (ret)
+               goto out;
+
+       pcm->private_free = pxa2xx_pcm_free_dma_buffers;
+
+       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
+       if (ret)
+               goto out;
+
+       stream = SNDRV_PCM_STREAM_PLAYBACK;
+       snd_pcm_set_ops(pcm, stream, &pxa2xx_ac97_pcm_ops);
+       ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
+       if (ret)
+               goto out;
+
+       stream = SNDRV_PCM_STREAM_CAPTURE;
+       snd_pcm_set_ops(pcm, stream, &pxa2xx_ac97_pcm_ops);
+       ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
+       if (ret)
+               goto out;
+
+       pxa2xx_ac97_pcm = pcm;
+       ret = 0;
+
+ out:
+       return ret;
+}
+
 static int pxa2xx_ac97_probe(struct platform_device *dev)
 {
        struct snd_card *card;
@@ -214,7 +242,7 @@ static int pxa2xx_ac97_probe(struct platform_device *dev)
 
        strlcpy(card->driver, dev->dev.driver->name, sizeof(card->driver));
 
-       ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm);
+       ret = pxa2xx_ac97_pcm_new(card);
        if (ret)
                goto err;
 
index e8da3b8ee7213352426023029fcff04e87659d50..7931789d4a9f588fb5f1a29e6f4d1aa929cfd380 100644 (file)
@@ -16,8 +16,6 @@
 #include <sound/pxa2xx-lib.h>
 #include <sound/dmaengine_pcm.h>
 
-#include "pxa2xx-pcm.h"
-
 static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
        .info                   = SNDRV_PCM_INFO_MMAP |
                                  SNDRV_PCM_INFO_MMAP_VALID |
@@ -25,8 +23,8 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
                                  SNDRV_PCM_INFO_PAUSE |
                                  SNDRV_PCM_INFO_RESUME,
        .formats                = SNDRV_PCM_FMTBIT_S16_LE |
-                                       SNDRV_PCM_FMTBIT_S24_LE |
-                                       SNDRV_PCM_FMTBIT_S32_LE,
+                                 SNDRV_PCM_FMTBIT_S24_LE |
+                                 SNDRV_PCM_FMTBIT_S32_LE,
        .period_bytes_min       = 32,
        .period_bytes_max       = 8192 - 32,
        .periods_min            = 1,
@@ -35,8 +33,8 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
        .fifo_size              = 32,
 };
 
-int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
+                        struct snd_pcm_hw_params *params)
 {
        struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -64,14 +62,14 @@ int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
 
        return 0;
 }
-EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
+EXPORT_SYMBOL(pxa2xx_pcm_hw_params);
 
-int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
+int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
        snd_pcm_set_runtime_buffer(substream, NULL);
        return 0;
 }
-EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
+EXPORT_SYMBOL(pxa2xx_pcm_hw_free);
 
 int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
@@ -86,13 +84,13 @@ pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
 }
 EXPORT_SYMBOL(pxa2xx_pcm_pointer);
 
-int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
+int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
 {
        return 0;
 }
-EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
+EXPORT_SYMBOL(pxa2xx_pcm_prepare);
 
-int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
+int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
@@ -125,17 +123,17 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
        if (ret < 0)
                return ret;
 
-       return snd_dmaengine_pcm_open_request_chan(substream,
-                                       pxad_filter_fn,
-                                       dma_params->filter_data);
+       return snd_dmaengine_pcm_open(
+               substream, dma_request_slave_channel(rtd->cpu_dai->dev,
+                                                    dma_params->chan_name));
 }
-EXPORT_SYMBOL(__pxa2xx_pcm_open);
+EXPORT_SYMBOL(pxa2xx_pcm_open);
 
-int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
+int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
 {
        return snd_dmaengine_pcm_close_release_chan(substream);
 }
-EXPORT_SYMBOL(__pxa2xx_pcm_close);
+EXPORT_SYMBOL(pxa2xx_pcm_close);
 
 int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
        struct vm_area_struct *vma)
@@ -181,6 +179,47 @@ void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
 }
 EXPORT_SYMBOL(pxa2xx_pcm_free_dma_buffers);
 
+int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_card *card = rtd->card->snd_card;
+       struct snd_pcm *pcm = rtd->pcm;
+       int ret;
+
+       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
+       if (ret)
+               return ret;
+
+       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+               ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+               ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+ out:
+       return ret;
+}
+EXPORT_SYMBOL(pxa2xx_soc_pcm_new);
+
+const struct snd_pcm_ops pxa2xx_pcm_ops = {
+       .open           = pxa2xx_pcm_open,
+       .close          = pxa2xx_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = pxa2xx_pcm_hw_params,
+       .hw_free        = pxa2xx_pcm_hw_free,
+       .prepare        = pxa2xx_pcm_prepare,
+       .trigger        = pxa2xx_pcm_trigger,
+       .pointer        = pxa2xx_pcm_pointer,
+       .mmap           = pxa2xx_pcm_mmap,
+};
+EXPORT_SYMBOL(pxa2xx_pcm_ops);
+
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("Intel PXA2xx sound library");
 MODULE_LICENSE("GPL");
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
deleted file mode 100644 (file)
index 1c6f4b4..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author:     Nicolas Pitre
- * Created:    Nov 30, 2004
- * Copyright:  (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/dmaengine.h>
-
-#include <mach/dma.h>
-
-#include <sound/core.h>
-#include <sound/pxa2xx-lib.h>
-#include <sound/dmaengine_pcm.h>
-
-#include "pxa2xx-pcm.h"
-
-static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct pxa2xx_pcm_client *client = substream->private_data;
-
-       __pxa2xx_pcm_prepare(substream);
-
-       return client->prepare(substream);
-}
-
-static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct pxa2xx_pcm_client *client = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct pxa2xx_runtime_data *rtd;
-       int ret;
-
-       ret = __pxa2xx_pcm_open(substream);
-       if (ret)
-               goto out;
-
-       rtd = runtime->private_data;
-
-       rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
-                     client->playback_params : client->capture_params;
-
-       ret = client->startup(substream);
-       if (!ret)
-               goto err2;
-
-       return 0;
-
- err2:
-       __pxa2xx_pcm_close(substream);
- out:
-       return ret;
-}
-
-static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
-{
-       struct pxa2xx_pcm_client *client = substream->private_data;
-
-       client->shutdown(substream);
-
-       return __pxa2xx_pcm_close(substream);
-}
-
-static const struct snd_pcm_ops pxa2xx_pcm_ops = {
-       .open           = pxa2xx_pcm_open,
-       .close          = pxa2xx_pcm_close,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = __pxa2xx_pcm_hw_params,
-       .hw_free        = __pxa2xx_pcm_hw_free,
-       .prepare        = pxa2xx_pcm_prepare,
-       .trigger        = pxa2xx_pcm_trigger,
-       .pointer        = pxa2xx_pcm_pointer,
-       .mmap           = pxa2xx_pcm_mmap,
-};
-
-int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
-                  struct snd_pcm **rpcm)
-{
-       struct snd_pcm *pcm;
-       int play = client->playback_params ? 1 : 0;
-       int capt = client->capture_params ? 1 : 0;
-       int ret;
-
-       ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm);
-       if (ret)
-               goto out;
-
-       pcm->private_data = client;
-       pcm->private_free = pxa2xx_pcm_free_dma_buffers;
-
-       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-       if (ret)
-               goto out;
-
-       if (play) {
-               int stream = SNDRV_PCM_STREAM_PLAYBACK;
-               snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
-               ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
-               if (ret)
-                       goto out;
-       }
-       if (capt) {
-               int stream = SNDRV_PCM_STREAM_CAPTURE;
-               snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
-               ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
-               if (ret)
-                       goto out;
-       }
-
-       if (rpcm)
-               *rpcm = pcm;
-       ret = 0;
-
- out:
-       return ret;
-}
-
-EXPORT_SYMBOL(pxa2xx_pcm_new);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
deleted file mode 100644 (file)
index 8fa2b7c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author:     Nicolas Pitre
- * Created:    Nov 30, 2004
- * Copyright:  MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-struct pxa2xx_runtime_data {
-       int dma_ch;
-       struct snd_dmaengine_dai_dma_data *params;
-};
-
-struct pxa2xx_pcm_client {
-       struct snd_dmaengine_dai_dma_data *playback_params;
-       struct snd_dmaengine_dai_dma_data *capture_params;
-       int (*startup)(struct snd_pcm_substream *);
-       void (*shutdown)(struct snd_pcm_substream *);
-       int (*prepare)(struct snd_pcm_substream *);
-};
-
-extern int pxa2xx_pcm_new(struct snd_card *, struct pxa2xx_pcm_client *, struct snd_pcm **);
-
index 41af6b9cc3500bead51340637e24f4288e135100..1cf11cf51e1dd6912c3bdce14c9e651b4fd955c2 100644 (file)
@@ -57,6 +57,7 @@ source "sound/soc/kirkwood/Kconfig"
 source "sound/soc/img/Kconfig"
 source "sound/soc/intel/Kconfig"
 source "sound/soc/mediatek/Kconfig"
+source "sound/soc/meson/Kconfig"
 source "sound/soc/mxs/Kconfig"
 source "sound/soc/pxa/Kconfig"
 source "sound/soc/qcom/Kconfig"
index 06389a5385d71ac05806a9d1db7eab1678b2dc2a..62a5f87c3cfc435b4ff8b1984f77ec65b3e53578 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/
 obj-$(CONFIG_SND_SOC)  += img/
 obj-$(CONFIG_SND_SOC)  += intel/
 obj-$(CONFIG_SND_SOC)  += mediatek/
+obj-$(CONFIG_SND_SOC)  += meson/
 obj-$(CONFIG_SND_SOC)  += mxs/
 obj-$(CONFIG_SND_SOC)  += nuc900/
 obj-$(CONFIG_SND_SOC)  += omap/
index 6cbf9cf4d1a4c2e451a5d0f434b806dfbc414a87..58c1dcb4d2550f0931b182129747b471e84a7562 100644 (file)
@@ -8,6 +8,7 @@ config SND_SOC_AMD_CZ_DA7219MX98357_MACH
        select SND_SOC_DA7219
        select SND_SOC_MAX98357A
        select SND_SOC_ADAU7002
+       select REGULATOR
        depends on SND_SOC_AMD_ACP && I2C
        help
         This option enables machine driver for DA7219 and MAX9835.
index ccddc6650b9c79a112791e3d5ecd2e11d77e8494..8e3275a96a82102be7da0d4d2dc6b694c01571fd 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/acpi.h>
@@ -148,7 +150,8 @@ static int cz_da7219_startup(struct snd_pcm_substream *substream)
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                   &constraints_rates);
 
-       machine->i2s_instance = I2S_BT_INSTANCE;
+       machine->i2s_instance = I2S_SP_INSTANCE;
+       machine->capture_channel = CAP_CHANNEL1;
        return da7219_clk_enable(substream);
 }
 
@@ -163,7 +166,7 @@ static int cz_max_startup(struct snd_pcm_substream *substream)
        struct snd_soc_card *card = rtd->card;
        struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
 
-       machine->i2s_instance = I2S_SP_INSTANCE;
+       machine->i2s_instance = I2S_BT_INSTANCE;
        return da7219_clk_enable(substream);
 }
 
@@ -172,13 +175,24 @@ static void cz_max_shutdown(struct snd_pcm_substream *substream)
        da7219_clk_disable();
 }
 
-static int cz_dmic_startup(struct snd_pcm_substream *substream)
+static int cz_dmic0_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_card *card = rtd->card;
+       struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
+
+       machine->i2s_instance = I2S_BT_INSTANCE;
+       return da7219_clk_enable(substream);
+}
+
+static int cz_dmic1_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_card *card = rtd->card;
        struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
 
        machine->i2s_instance = I2S_SP_INSTANCE;
+       machine->capture_channel = CAP_CHANNEL0;
        return da7219_clk_enable(substream);
 }
 
@@ -197,23 +211,39 @@ static const struct snd_soc_ops cz_max_play_ops = {
        .shutdown = cz_max_shutdown,
 };
 
-static const struct snd_soc_ops cz_dmic_cap_ops = {
-       .startup = cz_dmic_startup,
+static const struct snd_soc_ops cz_dmic0_cap_ops = {
+       .startup = cz_dmic0_startup,
+       .shutdown = cz_dmic_shutdown,
+};
+
+static const struct snd_soc_ops cz_dmic1_cap_ops = {
+       .startup = cz_dmic1_startup,
        .shutdown = cz_dmic_shutdown,
 };
 
 static struct snd_soc_dai_link cz_dai_7219_98357[] = {
        {
-               .name = "amd-da7219-play-cap",
-               .stream_name = "Playback and Capture",
+               .name = "amd-da7219-play",
+               .stream_name = "Playback",
                .platform_name = "acp_audio_dma.0.auto",
-               .cpu_dai_name = "designware-i2s.3.auto",
+               .cpu_dai_name = "designware-i2s.1.auto",
                .codec_dai_name = "da7219-hifi",
                .codec_name = "i2c-DLGS7219:00",
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                | SND_SOC_DAIFMT_CBM_CFM,
                .init = cz_da7219_init,
                .dpcm_playback = 1,
+               .ops = &cz_da7219_cap_ops,
+       },
+       {
+               .name = "amd-da7219-cap",
+               .stream_name = "Capture",
+               .platform_name = "acp_audio_dma.0.auto",
+               .cpu_dai_name = "designware-i2s.2.auto",
+               .codec_dai_name = "da7219-hifi",
+               .codec_name = "i2c-DLGS7219:00",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
                .dpcm_capture = 1,
                .ops = &cz_da7219_cap_ops,
        },
@@ -221,7 +251,7 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
                .name = "amd-max98357-play",
                .stream_name = "HiFi Playback",
                .platform_name = "acp_audio_dma.0.auto",
-               .cpu_dai_name = "designware-i2s.1.auto",
+               .cpu_dai_name = "designware-i2s.3.auto",
                .codec_dai_name = "HiFi",
                .codec_name = "MX98357A:00",
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
@@ -230,8 +260,22 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
                .ops = &cz_max_play_ops,
        },
        {
-               .name = "dmic",
-               .stream_name = "DMIC Capture",
+               /* C panel DMIC */
+               .name = "dmic0",
+               .stream_name = "DMIC0 Capture",
+               .platform_name = "acp_audio_dma.0.auto",
+               .cpu_dai_name = "designware-i2s.3.auto",
+               .codec_dai_name = "adau7002-hifi",
+               .codec_name = "ADAU7002:00",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
+               .dpcm_capture = 1,
+               .ops = &cz_dmic0_cap_ops,
+       },
+       {
+               /* A/B panel DMIC */
+               .name = "dmic1",
+               .stream_name = "DMIC1 Capture",
                .platform_name = "acp_audio_dma.0.auto",
                .cpu_dai_name = "designware-i2s.2.auto",
                .codec_dai_name = "adau7002-hifi",
@@ -239,7 +283,7 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                | SND_SOC_DAIFMT_CBM_CFM,
                .dpcm_capture = 1,
-               .ops = &cz_dmic_cap_ops,
+               .ops = &cz_dmic1_cap_ops,
        },
 };
 
@@ -278,11 +322,52 @@ static struct snd_soc_card cz_card = {
        .num_controls = ARRAY_SIZE(cz_mc_controls),
 };
 
+static struct regulator_consumer_supply acp_da7219_supplies[] = {
+       REGULATOR_SUPPLY("VDD", "i2c-DLGS7219:00"),
+       REGULATOR_SUPPLY("VDDMIC", "i2c-DLGS7219:00"),
+       REGULATOR_SUPPLY("VDDIO", "i2c-DLGS7219:00"),
+       REGULATOR_SUPPLY("IOVDD", "ADAU7002:00"),
+};
+
+static struct regulator_init_data acp_da7219_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(acp_da7219_supplies),
+       .consumer_supplies = acp_da7219_supplies,
+};
+
+static struct regulator_config acp_da7219_cfg = {
+       .init_data = &acp_da7219_data,
+};
+
+static struct regulator_ops acp_da7219_ops = {
+};
+
+static struct regulator_desc acp_da7219_desc = {
+       .name = "reg-fixed-1.8V",
+       .type = REGULATOR_VOLTAGE,
+       .owner = THIS_MODULE,
+       .ops = &acp_da7219_ops,
+       .fixed_uV = 1800000, /* 1.8V */
+       .n_voltages = 1,
+};
+
 static int cz_probe(struct platform_device *pdev)
 {
        int ret;
        struct snd_soc_card *card;
        struct acp_platform_info *machine;
+       struct regulator_dev *rdev;
+
+       acp_da7219_cfg.dev = &pdev->dev;
+       rdev = devm_regulator_register(&pdev->dev, &acp_da7219_desc,
+                                      &acp_da7219_cfg);
+       if (IS_ERR(rdev)) {
+               dev_err(&pdev->dev, "Failed to register regulator: %d\n",
+                       (int)PTR_ERR(rdev));
+               return -EINVAL;
+       }
 
        machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),
                               GFP_KERNEL);
index 77203841c535017bd0fea9c0cd20c5722e5d0ead..94bcf69008df9276e3051bf5ec685faa7a2e30c8 100644 (file)
@@ -224,13 +224,11 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
                        switch (asic_type) {
                        case CHIP_STONEY:
                                dmadscr[i].xfer_val |=
-                               BIT(22) |
                                (ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC << 16) |
                                (size / 2);
                                break;
                        default:
                                dmadscr[i].xfer_val |=
-                               BIT(22) |
                                (ACP_DMA_ATTR_SHAREDMEM_TO_DAGB_ONION << 16) |
                                (size / 2);
                        }
@@ -322,20 +320,85 @@ static void config_acp_dma(void __iomem *acp_mmio,
                           struct audio_substream_data *rtd,
                           u32 asic_type)
 {
+       u16 ch_acp_sysmem, ch_acp_i2s;
+
        acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages,
                       rtd->pte_offset);
+
+       if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+               ch_acp_sysmem = rtd->ch1;
+               ch_acp_i2s = rtd->ch2;
+       } else {
+               ch_acp_i2s = rtd->ch1;
+               ch_acp_sysmem = rtd->ch2;
+       }
        /* Configure System memory <-> ACP SRAM DMA descriptors */
        set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size,
                                       rtd->direction, rtd->pte_offset,
-                                      rtd->ch1, rtd->sram_bank,
+                                      ch_acp_sysmem, rtd->sram_bank,
                                       rtd->dma_dscr_idx_1, asic_type);
        /* Configure ACP SRAM <-> I2S DMA descriptors */
        set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size,
                                       rtd->direction, rtd->sram_bank,
-                                      rtd->destination, rtd->ch2,
+                                      rtd->destination, ch_acp_i2s,
                                       rtd->dma_dscr_idx_2, asic_type);
 }
 
+static void acp_dma_cap_channel_enable(void __iomem *acp_mmio,
+                                      u16 cap_channel)
+{
+       u32 val, ch_reg, imr_reg, res_reg;
+
+       switch (cap_channel) {
+       case CAP_CHANNEL1:
+               ch_reg = mmACP_I2SMICSP_RER1;
+               res_reg = mmACP_I2SMICSP_RCR1;
+               imr_reg = mmACP_I2SMICSP_IMR1;
+               break;
+       case CAP_CHANNEL0:
+       default:
+               ch_reg = mmACP_I2SMICSP_RER0;
+               res_reg = mmACP_I2SMICSP_RCR0;
+               imr_reg = mmACP_I2SMICSP_IMR0;
+               break;
+       }
+       val = acp_reg_read(acp_mmio,
+                          mmACP_I2S_16BIT_RESOLUTION_EN);
+       if (val & ACP_I2S_MIC_16BIT_RESOLUTION_EN) {
+               acp_reg_write(0x0, acp_mmio, ch_reg);
+               /* Set 16bit resolution on capture */
+               acp_reg_write(0x2, acp_mmio, res_reg);
+       }
+       val = acp_reg_read(acp_mmio, imr_reg);
+       val &= ~ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK;
+       val &= ~ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK;
+       acp_reg_write(val, acp_mmio, imr_reg);
+       acp_reg_write(0x1, acp_mmio, ch_reg);
+}
+
+static void acp_dma_cap_channel_disable(void __iomem *acp_mmio,
+                                       u16 cap_channel)
+{
+       u32 val, ch_reg, imr_reg;
+
+       switch (cap_channel) {
+       case CAP_CHANNEL1:
+               imr_reg = mmACP_I2SMICSP_IMR1;
+               ch_reg = mmACP_I2SMICSP_RER1;
+               break;
+       case CAP_CHANNEL0:
+       default:
+               imr_reg = mmACP_I2SMICSP_IMR0;
+               ch_reg = mmACP_I2SMICSP_RER0;
+               break;
+       }
+       val = acp_reg_read(acp_mmio, imr_reg);
+       val |= ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK;
+       val |= ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK;
+       acp_reg_write(val, acp_mmio, imr_reg);
+       acp_reg_write(0x0, acp_mmio, ch_reg);
+}
+
 /* Start a given DMA channel transfer */
 static void acp_dma_start(void __iomem *acp_mmio, u16 ch_num)
 {
@@ -356,10 +419,8 @@ static void acp_dma_start(void __iomem *acp_mmio, u16 ch_num)
 
        switch (ch_num) {
        case ACP_TO_I2S_DMA_CH_NUM:
-       case ACP_TO_SYSRAM_CH_NUM:
        case I2S_TO_ACP_DMA_CH_NUM:
        case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM:
-       case ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM:
        case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM:
                dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
                break;
@@ -649,12 +710,6 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
                              acp_mmio, mmACP_EXTERNAL_INTR_STAT);
        }
 
-       if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) {
-               valid_irq = true;
-               acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16,
-                             acp_mmio, mmACP_EXTERNAL_INTR_STAT);
-       }
-
        if ((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) != 0) {
                valid_irq = true;
                snd_pcm_period_elapsed(irq_data->capture_i2sbt_stream);
@@ -663,13 +718,6 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
                              acp_mmio, mmACP_EXTERNAL_INTR_STAT);
        }
 
-       if ((intr_flag & BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) != 0) {
-               valid_irq = true;
-               acp_reg_write((intr_flag &
-                             BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) << 16,
-                             acp_mmio, mmACP_EXTERNAL_INTR_STAT);
-       }
-
        if (valid_irq)
                return IRQ_HANDLED;
        else
@@ -773,7 +821,10 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
        if (WARN_ON(!rtd))
                return -EINVAL;
 
-       rtd->i2s_instance = pinfo->i2s_instance;
+       if (pinfo) {
+               rtd->i2s_instance = pinfo->i2s_instance;
+               rtd->capture_channel = pinfo->capture_channel;
+       }
        if (adata->asic_type == CHIP_STONEY) {
                val = acp_reg_read(adata->acp_mmio,
                                   mmACP_I2S_16BIT_RESOLUTION_EN);
@@ -841,8 +892,8 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
                switch (rtd->i2s_instance) {
                case I2S_BT_INSTANCE:
                        rtd->pte_offset = ACP_ST_BT_CAPTURE_PTE_OFFSET;
-                       rtd->ch1 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM;
-                       rtd->ch2 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM;
+                       rtd->ch1 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM;
+                       rtd->ch2 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM;
                        rtd->sram_bank = ACP_SRAM_BANK_4_ADDRESS;
                        rtd->destination = FROM_BLUETOOTH;
                        rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH10;
@@ -856,8 +907,8 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
                case I2S_SP_INSTANCE:
                default:
                        rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET;
-                       rtd->ch1 = ACP_TO_SYSRAM_CH_NUM;
-                       rtd->ch2 = I2S_TO_ACP_DMA_CH_NUM;
+                       rtd->ch1 = I2S_TO_ACP_DMA_CH_NUM;
+                       rtd->ch2 = ACP_TO_SYSRAM_CH_NUM;
                        switch (adata->asic_type) {
                        case CHIP_STONEY:
                                rtd->pte_offset = ACP_ST_CAPTURE_PTE_OFFSET;
@@ -937,8 +988,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
        buffersize = frames_to_bytes(runtime, runtime->buffer_size);
        bytescount = acp_get_byte_count(rtd);
 
-       if (bytescount > rtd->bytescount)
-               bytescount -= rtd->bytescount;
+       bytescount -= rtd->bytescount;
        pos = do_div(bytescount, buffersize);
        return bytes_to_frames(runtime, pos);
 }
@@ -953,16 +1003,24 @@ static int acp_dma_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct audio_substream_data *rtd = runtime->private_data;
+       u16 ch_acp_sysmem, ch_acp_i2s;
 
        if (!rtd)
                return -EINVAL;
 
+       if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+               ch_acp_sysmem = rtd->ch1;
+               ch_acp_i2s = rtd->ch2;
+       } else {
+               ch_acp_i2s = rtd->ch1;
+               ch_acp_sysmem = rtd->ch2;
+       }
        config_acp_dma_channel(rtd->acp_mmio,
-                              rtd->ch1,
+                              ch_acp_sysmem,
                               rtd->dma_dscr_idx_1,
                               NUM_DSCRS_PER_CHANNEL, 0);
        config_acp_dma_channel(rtd->acp_mmio,
-                              rtd->ch2,
+                              ch_acp_i2s,
                               rtd->dma_dscr_idx_2,
                               NUM_DSCRS_PER_CHANNEL, 0);
        return 0;
@@ -971,7 +1029,6 @@ static int acp_dma_prepare(struct snd_pcm_substream *substream)
 static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        int ret;
-       u64 bytescount = 0;
 
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct audio_substream_data *rtd = runtime->private_data;
@@ -982,37 +1039,30 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
        case SNDRV_PCM_TRIGGER_RESUME:
-               bytescount = acp_get_byte_count(rtd);
-               if (rtd->bytescount == 0)
-                       rtd->bytescount = bytescount;
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                       acp_dma_start(rtd->acp_mmio, rtd->ch1);
-                       acp_dma_start(rtd->acp_mmio, rtd->ch2);
-               } else {
-                       acp_dma_start(rtd->acp_mmio, rtd->ch2);
-                       acp_dma_start(rtd->acp_mmio, rtd->ch1);
+               rtd->bytescount = acp_get_byte_count(rtd);
+               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+                       if (rtd->capture_channel == CAP_CHANNEL0) {
+                               acp_dma_cap_channel_disable(rtd->acp_mmio,
+                                                           CAP_CHANNEL1);
+                               acp_dma_cap_channel_enable(rtd->acp_mmio,
+                                                          CAP_CHANNEL0);
+                       }
+                       if (rtd->capture_channel == CAP_CHANNEL1) {
+                               acp_dma_cap_channel_disable(rtd->acp_mmio,
+                                                           CAP_CHANNEL0);
+                               acp_dma_cap_channel_enable(rtd->acp_mmio,
+                                                          CAP_CHANNEL1);
+                       }
                }
+               acp_dma_start(rtd->acp_mmio, rtd->ch1);
+               acp_dma_start(rtd->acp_mmio, rtd->ch2);
                ret = 0;
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               /* For playback, non circular dma should be stopped first
-                * i.e Sysram to acp dma transfer channel(rtd->ch1) should be
-                * stopped before stopping cirular dma which is acp sram to i2s
-                * fifo dma transfer channel(rtd->ch2). Where as in Capture
-                * scenario, i2s fifo to acp sram dma channel(rtd->ch2) stopped
-                * first before stopping acp sram to sysram which is circular
-                * dma(rtd->ch1).
-                */
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                       acp_dma_stop(rtd->acp_mmio, rtd->ch1);
-                       ret =  acp_dma_stop(rtd->acp_mmio, rtd->ch2);
-               } else {
-                       acp_dma_stop(rtd->acp_mmio, rtd->ch2);
-                       ret = acp_dma_stop(rtd->acp_mmio, rtd->ch1);
-               }
-               rtd->bytescount = 0;
+               acp_dma_stop(rtd->acp_mmio, rtd->ch2);
+               ret = acp_dma_stop(rtd->acp_mmio, rtd->ch1);
                break;
        default:
                ret = -EINVAL;
index 9cd3e96c84d473ef39bef686ecf16cd9411c18f1..0a2240bff62e14fe93292ded2dea3c2925303bcd 100644 (file)
@@ -55,6 +55,8 @@
 
 #define I2S_SP_INSTANCE                 0x01
 #define I2S_BT_INSTANCE                 0x02
+#define CAP_CHANNEL0                   0x00
+#define CAP_CHANNEL1                   0x01
 
 #define ACP_TILE_ON_MASK                0x03
 #define ACP_TILE_OFF_MASK               0x02
 #define ACP_TO_I2S_DMA_CH_NUM 13
 
 /* Capture DMA channels */
-#define ACP_TO_SYSRAM_CH_NUM 14
-#define I2S_TO_ACP_DMA_CH_NUM 15
+#define I2S_TO_ACP_DMA_CH_NUM 14
+#define ACP_TO_SYSRAM_CH_NUM 15
 
 /* Playback DMA Channels for I2S BT instance */
 #define SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM  8
 #define ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM 9
 
 /* Capture DMA Channels for I2S BT Instance */
-#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 10
-#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 11
+#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 10
+#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 11
 
 #define NUM_DSCRS_PER_CHANNEL 2
 
@@ -125,6 +127,7 @@ struct audio_substream_data {
        unsigned int order;
        u16 num_of_pages;
        u16 i2s_instance;
+       u16 capture_channel;
        u16 direction;
        u16 ch1;
        u16 ch2;
@@ -155,6 +158,7 @@ struct audio_drv_data {
  */
 struct acp_platform_info {
        u16 i2s_instance;
+       u16 capture_channel;
 };
 
 union acp_dma_count {
index 5d3b5af9fd92ff37d0bd585e6569002fd1c5d740..d88c1d995036c53922e5defc6d112e918a6062bd 100644 (file)
@@ -206,7 +206,6 @@ struct atmel_i2s_dev {
        struct regmap                           *regmap;
        struct clk                              *pclk;
        struct clk                              *gclk;
-       struct clk                              *aclk;
        struct snd_dmaengine_dai_dma_data       playback;
        struct snd_dmaengine_dai_dma_data       capture;
        unsigned int                            fmt;
@@ -303,7 +302,7 @@ static int atmel_i2s_get_gck_param(struct atmel_i2s_dev *dev, int fs)
 {
        int i, best;
 
-       if (!dev->gclk || !dev->aclk) {
+       if (!dev->gclk) {
                dev_err(dev->dev, "cannot generate the I2S Master Clock\n");
                return -EINVAL;
        }
@@ -421,7 +420,7 @@ static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
                                          bool enabled)
 {
        unsigned int mr, mr_mask;
-       unsigned long aclk_rate;
+       unsigned long gclk_rate;
        int ret;
 
        mr = 0;
@@ -445,35 +444,18 @@ static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
                /* Disable/unprepare the PMC generated clock. */
                clk_disable_unprepare(dev->gclk);
 
-               /* Disable/unprepare the PLL audio clock. */
-               clk_disable_unprepare(dev->aclk);
                return 0;
        }
 
        if (!dev->gck_param)
                return -EINVAL;
 
-       aclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1);
+       gclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1);
 
-       /* Fist change the PLL audio clock frequency ... */
-       ret = clk_set_rate(dev->aclk, aclk_rate);
+       ret = clk_set_rate(dev->gclk, gclk_rate);
        if (ret)
                return ret;
 
-       /*
-        * ... then set the PMC generated clock rate to the very same frequency
-        * to set the gclk parent to aclk.
-        */
-       ret = clk_set_rate(dev->gclk, aclk_rate);
-       if (ret)
-               return ret;
-
-       /* Prepare and enable the PLL audio clock first ... */
-       ret = clk_prepare_enable(dev->aclk);
-       if (ret)
-               return ret;
-
-       /* ... then prepare and enable the PMC generated clock. */
        ret = clk_prepare_enable(dev->gclk);
        if (ret)
                return ret;
@@ -668,28 +650,14 @@ static int atmel_i2s_probe(struct platform_device *pdev)
                return err;
        }
 
-       /* Get audio clocks to generate the I2S Master Clock (I2S_MCK) */
-       dev->aclk = devm_clk_get(&pdev->dev, "aclk");
+       /* Get audio clock to generate the I2S Master Clock (I2S_MCK) */
        dev->gclk = devm_clk_get(&pdev->dev, "gclk");
-       if (IS_ERR(dev->aclk) && IS_ERR(dev->gclk)) {
-               if (PTR_ERR(dev->aclk) == -EPROBE_DEFER ||
-                   PTR_ERR(dev->gclk) == -EPROBE_DEFER)
+       if (IS_ERR(dev->gclk)) {
+               if (PTR_ERR(dev->gclk) == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
                /* Master Mode not supported */
-               dev->aclk = NULL;
                dev->gclk = NULL;
-       } else if (IS_ERR(dev->gclk)) {
-               err = PTR_ERR(dev->gclk);
-               dev_err(&pdev->dev,
-                       "failed to get the PMC generated clock: %d\n", err);
-               return err;
-       } else if (IS_ERR(dev->aclk)) {
-               err = PTR_ERR(dev->aclk);
-               dev_err(&pdev->dev,
-                       "failed to get the PLL audio clock: %d\n", err);
-               return err;
        }
-
        dev->dev = &pdev->dev;
        dev->regmap = regmap;
        platform_set_drvdata(pdev, dev);
index 63cf62e9c9aa67733908f4011c30482b09e72457..cb09abf18dde803180666b5bfe78eefeb64c7af6 100644 (file)
@@ -74,12 +74,12 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_DA7219 if I2C
        select SND_SOC_DA732X if I2C
        select SND_SOC_DA9055 if I2C
-       select SND_SOC_DIO2125
        select SND_SOC_DMIC if GPIOLIB
        select SND_SOC_ES8316 if I2C
        select SND_SOC_ES8328_SPI if SPI_MASTER
        select SND_SOC_ES8328_I2C if I2C
        select SND_SOC_ES7134
+       select SND_SOC_ES7241
        select SND_SOC_GTM601
        select SND_SOC_HDAC_HDMI
        select SND_SOC_ICS43432
@@ -141,8 +141,10 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_RT5668 if I2C
        select SND_SOC_RT5670 if I2C
        select SND_SOC_RT5677 if I2C && SPI_MASTER
+       select SND_SOC_RT5682 if I2C
        select SND_SOC_SGTL5000 if I2C
        select SND_SOC_SI476X if MFD_SI476X_CORE
+       select SND_SOC_SIMPLE_AMPLIFIER
        select SND_SOC_SIRF_AUDIO_CODEC
        select SND_SOC_SPDIF
        select SND_SOC_SSM2305
@@ -572,10 +574,6 @@ config SND_SOC_DA732X
 config SND_SOC_DA9055
        tristate
 
-config SND_SOC_DIO2125
-       tristate "Dioo DIO2125 Amplifier"
-       select GPIOLIB
-
 config SND_SOC_DMIC
        tristate
 
@@ -588,6 +586,9 @@ config SND_SOC_HDMI_CODEC
 config SND_SOC_ES7134
        tristate "Everest Semi ES7134 CODEC"
 
+config SND_SOC_ES7241
+       tristate "Everest Semi ES7241 CODEC"
+
 config SND_SOC_ES8316
        tristate "Everest Semi ES8316 CODEC"
        depends on I2C
@@ -778,6 +779,7 @@ config SND_SOC_RL6231
        default y if SND_SOC_RT5668=y
        default y if SND_SOC_RT5670=y
        default y if SND_SOC_RT5677=y
+       default y if SND_SOC_RT5682=y
        default y if SND_SOC_RT1305=y
        default m if SND_SOC_RT5514=m
        default m if SND_SOC_RT5616=m
@@ -791,6 +793,7 @@ config SND_SOC_RL6231
        default m if SND_SOC_RT5668=m
        default m if SND_SOC_RT5670=m
        default m if SND_SOC_RT5677=m
+       default m if SND_SOC_RT5682=m
        default m if SND_SOC_RT1305=m
 
 config SND_SOC_RL6347A
@@ -871,6 +874,9 @@ config SND_SOC_RT5677_SPI
        tristate
        default SND_SOC_RT5677 && SPI
 
+config SND_SOC_RT5682
+       tristate
+
 #Freescale sgtl5000 codec
 config SND_SOC_SGTL5000
        tristate "Freescale SGTL5000 CODEC"
@@ -891,6 +897,10 @@ config SND_SOC_SIGMADSP_REGMAP
        tristate
        select SND_SOC_SIGMADSP
 
+config SND_SOC_SIMPLE_AMPLIFIER
+       tristate "Simple Audio Amplifier"
+       select GPIOLIB
+
 config SND_SOC_SIRF_AUDIO_CODEC
        tristate "SiRF SoC internal audio codec"
        select REGMAP_MMIO
@@ -953,8 +963,11 @@ config SND_SOC_TAS5086
        depends on I2C
 
 config SND_SOC_TAS571X
-       tristate "Texas Instruments TAS5711/TAS5717/TAS5719/TAS5721 power amplifiers"
+       tristate "Texas Instruments TAS571x power amplifiers"
        depends on I2C
+       help
+         Enable support for Texas Instruments TAS5707, TAS5711, TAS5717,
+         TAS5719 and TAS5721 power amplifiers
 
 config SND_SOC_TAS5720
        tristate "Texas Instruments TAS5720 Mono Audio amplifier"
@@ -1053,6 +1066,11 @@ config SND_SOC_UDA1380
         tristate
        depends on I2C
 
+config SND_SOC_WCD9335
+       tristate "WCD9335 Codec"
+       depends on MFD_WCD9335
+        tristate
+
 config SND_SOC_WL1273
        tristate
 
index e023fdf852215dea0e27bb5a9e2f7ac97e26a003..e3a3d4694e1555dab993b1f25c67d67056cc0cc8 100644 (file)
@@ -71,6 +71,7 @@ snd-soc-da732x-objs := da732x.o
 snd-soc-da9055-objs := da9055.o
 snd-soc-dmic-objs := dmic.o
 snd-soc-es7134-objs := es7134.o
+snd-soc-es7241-objs := es7241.o
 snd-soc-es8316-objs := es8316.o
 snd-soc-es8328-objs := es8328.o
 snd-soc-es8328-i2c-objs := es8328-i2c.o
@@ -146,6 +147,7 @@ snd-soc-rt5668-objs := rt5668.o
 snd-soc-rt5670-objs := rt5670.o
 snd-soc-rt5677-objs := rt5677.o
 snd-soc-rt5677-spi-objs := rt5677-spi.o
+snd-soc-rt5682-objs := rt5682.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
@@ -190,6 +192,7 @@ snd-soc-twl4030-objs := twl4030.o
 snd-soc-twl6040-objs := twl6040.o
 snd-soc-uda134x-objs := uda134x.o
 snd-soc-uda1380-objs := uda1380.o
+snd-soc-wcd9335-objs := wcd-clsh.o wcd9335.o
 snd-soc-wl1273-objs := wl1273.o
 snd-soc-wm-adsp-objs := wm_adsp.o
 snd-soc-wm0010-objs := wm0010.o
@@ -249,9 +252,9 @@ snd-soc-wm9713-objs := wm9713.o
 snd-soc-wm-hubs-objs := wm_hubs.o
 snd-soc-zx-aud96p22-objs := zx_aud96p22.o
 # Amp
-snd-soc-dio2125-objs := dio2125.o
 snd-soc-max9877-objs := max9877.o
 snd-soc-max98504-objs := max98504.o
+snd-soc-simple-amplifier-objs := simple-amplifier.o
 snd-soc-tpa6130a2-objs := tpa6130a2.o
 snd-soc-tas2552-objs := tas2552.o
 
@@ -329,6 +332,7 @@ obj-$(CONFIG_SND_SOC_DA732X)        += snd-soc-da732x.o
 obj-$(CONFIG_SND_SOC_DA9055)   += snd-soc-da9055.o
 obj-$(CONFIG_SND_SOC_DMIC)     += snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_ES7134)   += snd-soc-es7134.o
+obj-$(CONFIG_SND_SOC_ES7241)   += snd-soc-es7241.o
 obj-$(CONFIG_SND_SOC_ES8316)    += snd-soc-es8316.o
 obj-$(CONFIG_SND_SOC_ES8328)   += snd-soc-es8328.o
 obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
@@ -405,6 +409,7 @@ obj-$(CONFIG_SND_SOC_RT5668)        += snd-soc-rt5668.o
 obj-$(CONFIG_SND_SOC_RT5670)   += snd-soc-rt5670.o
 obj-$(CONFIG_SND_SOC_RT5677)   += snd-soc-rt5677.o
 obj-$(CONFIG_SND_SOC_RT5677_SPI)       += snd-soc-rt5677-spi.o
+obj-$(CONFIG_SND_SOC_RT5682)   += snd-soc-rt5682.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C)     += snd-soc-sigmadsp-i2c.o
@@ -447,6 +452,7 @@ obj-$(CONFIG_SND_SOC_TWL4030)       += snd-soc-twl4030.o
 obj-$(CONFIG_SND_SOC_TWL6040)  += snd-soc-twl6040.o
 obj-$(CONFIG_SND_SOC_UDA134X)  += snd-soc-uda134x.o
 obj-$(CONFIG_SND_SOC_UDA1380)  += snd-soc-uda1380.o
+obj-$(CONFIG_SND_SOC_WCD9335)  += snd-soc-wcd9335.o
 obj-$(CONFIG_SND_SOC_WL1273)   += snd-soc-wl1273.o
 obj-$(CONFIG_SND_SOC_WM0010)   += snd-soc-wm0010.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
@@ -507,7 +513,7 @@ obj-$(CONFIG_SND_SOC_WM_HUBS)       += snd-soc-wm-hubs.o
 obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
 
 # Amp
-obj-$(CONFIG_SND_SOC_DIO2125)  += snd-soc-dio2125.o
 obj-$(CONFIG_SND_SOC_MAX9877)  += snd-soc-max9877.o
 obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
+obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
 obj-$(CONFIG_SND_SOC_TPA6130A2)        += snd-soc-tpa6130a2.o
index ae41edd1c406b4fa38d1aed55670cfd227ee660a..57169b8ff14e3f4d02871ccbc074eb14fec5d5e5 100644 (file)
@@ -299,6 +299,7 @@ static const struct snd_soc_dapm_route adau17x1_dsp_dapm_routes[] = {
 
        { "DSP", NULL, "Left Decimator" },
        { "DSP", NULL, "Right Decimator" },
+       { "DSP", NULL, "Playback" },
 };
 
 static const struct snd_soc_dapm_route adau17x1_no_dsp_dapm_routes[] = {
index 31ec0ba2e639f2179c7574176f138c6e1cf106ea..299ada4dfaa009f7cdc1d04f6b02ac13987597ae 100644 (file)
@@ -558,7 +558,7 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev)
 }
 #endif /* CONFIG_PM */
 
-struct snd_soc_component_driver soc_codec_dev_ak4458 = {
+static const struct snd_soc_component_driver soc_codec_dev_ak4458 = {
        .probe                  = ak4458_probe,
        .remove                 = ak4458_remove,
        .controls               = ak4458_snd_controls,
index b7ee13406d93b0a6b4967a920dc02a6f1f3d399b..2fa83a1a84cf126f7b37b8da00fd46d4fd45548b 100644 (file)
@@ -1,13 +1,8 @@
-/*
- * ak4554.c
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ak4554.c
+//
+// Copyright (C) 2013 Renesas Solutions Corp.
+// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 
 #include <linux/module.h>
 #include <sound/soc.h>
@@ -97,6 +92,6 @@ static struct platform_driver ak4554_driver = {
 };
 module_platform_driver(ak4554_driver);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("SoC AK4554 driver");
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
index 8523ff9351cf59a61bcf48517fc7cc08484fdbec..c1181a20714ddeaa8c634fa8cff119c1d52079d0 100644 (file)
@@ -1,18 +1,14 @@
-/*
- * ak4613.c  --  Asahi Kasei ALSA Soc Audio driver
- *
- * Copyright (C) 2015 Renesas Electronics Corporation
- * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * Based on ak4642.c by Kuninori Morimoto
- * Based on wm8731.c by Richard Purdie
- * Based on ak4535.c by Richard Purdie
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// ak4613.c  --  Asahi Kasei ALSA Soc Audio driver
+//
+// Copyright (C) 2015 Renesas Electronics Corporation
+// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+//
+// Based on ak4642.c by Kuninori Morimoto
+// Based on wm8731.c by Richard Purdie
+// Based on ak4535.c by Richard Purdie
+// Based on wm8753.c by Liam Girdwood
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 605055964529880b9c8589c49837460bcc5bb681..3532370255140e03f2f91289b871ff59e98762ee 100644 (file)
@@ -1,17 +1,13 @@
-/*
- * ak4642.c  --  AK4642/AK4643 ALSA Soc Audio driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on wm8731.c by Richard Purdie
- * Based on ak4535.c by Richard Purdie
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// ak4642.c  --  AK4642/AK4643 ALSA Soc Audio driver
+//
+// Copyright (C) 2009 Renesas Solutions Corp.
+// Kuninori Morimoto <morimoto.kuninori@renesas.com>
+//
+// Based on wm8731.c by Richard Purdie
+// Based on ak4535.c by Richard Purdie
+// Based on wm8753.c by Liam Girdwood
 
 /* ** CAUTION **
  *
@@ -709,4 +705,4 @@ module_i2c_driver(ak4642_i2c_driver);
 
 MODULE_DESCRIPTION("Soc AK4642 driver");
 MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index f4ed5cc40661bd96af4a0c898a5ff26d4b16a664..448bb90c9c8e0aa7cac5df5b596b526c286ace04 100644 (file)
@@ -322,13 +322,13 @@ static int __maybe_unused ak5558_runtime_resume(struct device *dev)
        return regcache_sync(ak5558->regmap);
 }
 
-const struct dev_pm_ops ak5558_pm = {
+static const struct dev_pm_ops ak5558_pm = {
        SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL)
        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
                                pm_runtime_force_resume)
 };
 
-struct snd_soc_component_driver soc_codec_dev_ak5558 = {
+static const struct snd_soc_component_driver soc_codec_dev_ak5558 = {
        .probe                  = ak5558_probe,
        .remove                 = ak5558_remove,
        .controls               = ak5558_snd_controls,
index 196e9c343aeb79711530581209050f8568fb9e78..0da52ead91e0ed42aea0cd2ee8bc27da5f23b5df 100644 (file)
@@ -1283,6 +1283,12 @@ static int cs47l24_probe(struct platform_device *pdev)
                return ret;
        }
 
+       ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 1);
+       if (ret != 0)
+               dev_warn(&pdev->dev,
+                        "Failed to set compressed IRQ as a wake source: %d\n",
+                        ret);
+
        arizona_init_common(arizona);
 
        ret = arizona_init_vol_limit(arizona);
@@ -1306,6 +1312,7 @@ static int cs47l24_probe(struct platform_device *pdev)
 err_spk_irqs:
        arizona_free_spk_irqs(arizona);
 err_dsp_irq:
+       arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
        arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, cs47l24);
 
        return ret;
@@ -1323,6 +1330,7 @@ static int cs47l24_remove(struct platform_device *pdev)
 
        arizona_free_spk_irqs(arizona);
 
+       arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
        arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, cs47l24);
 
        return 0;
index 07dd33b095967d6fd7aebf999068eff0f496d72e..ab174b5114dcf10a7d513b0eaab6f0afa66c9436 100644 (file)
@@ -362,8 +362,27 @@ static int cx20442_component_probe(struct snd_soc_component *component)
                return -ENOMEM;
 
        cx20442->por = regulator_get(component->dev, "POR");
-       if (IS_ERR(cx20442->por))
-               dev_warn(component->dev, "failed to get the regulator");
+       if (IS_ERR(cx20442->por)) {
+               int err = PTR_ERR(cx20442->por);
+
+               dev_warn(component->dev, "failed to get POR supply (%d)", err);
+               /*
+                * When running on a non-dt platform and requested regulator
+                * is not available, regulator_get() never returns
+                * -EPROBE_DEFER as it is not able to justify if the regulator
+                * may still appear later.  On the other hand, the board can
+                * still set full constraints flag at late_initcall in order
+                * to instruct regulator_get() to return a dummy one if
+                * sufficient.  Hence, if we get -ENODEV here, let's convert
+                * it to -EPROBE_DEFER and wait for the board to decide or
+                * let Deferred Probe infrastructure handle this error.
+                */
+               if (err == -ENODEV)
+                       err = -EPROBE_DEFER;
+               kfree(cx20442);
+               return err;
+       }
+
        cx20442->tty = NULL;
 
        snd_soc_component_set_drvdata(component, cx20442);
index a664111b71844eeafa256b71af510a0acd682c2a..e172913d04a4a2b7d86aaafa046d30011a5e4539 100644 (file)
@@ -1,19 +1,14 @@
-/*
- * DA7210 ALSA Soc codec driver
- *
- * Copyright (c) 2009 Dialog Semiconductor
- * Written by David Chen <Dajun.chen@diasemi.com>
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// DA7210 ALSA Soc codec driver
+//
+// Copyright (c) 2009 Dialog Semiconductor
+// Written by David Chen <Dajun.chen@diasemi.com>
+//
+// Copyright (C) 2009 Renesas Solutions Corp.
+// Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
+//
+// Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
index 58515bb1a303655525ec2c259f4370f0868a0096..6d7bca7b78ca7dbcede3be58a5973ccd2a79cb05 100644 (file)
@@ -17,6 +17,7 @@
  * in the file called COPYING.
  */
 
+#include <linux/of_platform.h>
 #include <linux/module.h>
 #include <sound/soc.h>
 
  * The everest 7134 is a very simple DA converter with no register
  */
 
+struct es7134_clock_mode {
+       unsigned int rate_min;
+       unsigned int rate_max;
+       unsigned int *mclk_fs;
+       unsigned int mclk_fs_num;
+};
+
+struct es7134_chip {
+       struct snd_soc_dai_driver *dai_drv;
+       const struct es7134_clock_mode *modes;
+       unsigned int mode_num;
+       const struct snd_soc_dapm_widget *extra_widgets;
+       unsigned int extra_widget_num;
+       const struct snd_soc_dapm_route *extra_routes;
+       unsigned int extra_route_num;
+};
+
+struct es7134_data {
+       unsigned int mclk;
+       const struct es7134_chip *chip;
+};
+
+static int es7134_check_mclk(struct snd_soc_dai *dai,
+                            struct es7134_data *priv,
+                            unsigned int rate)
+{
+       unsigned int mfs = priv->mclk / rate;
+       int i, j;
+
+       for (i = 0; i < priv->chip->mode_num; i++) {
+               const struct es7134_clock_mode *mode = &priv->chip->modes[i];
+
+               if (rate < mode->rate_min || rate > mode->rate_max)
+                       continue;
+
+               for (j = 0; j < mode->mclk_fs_num; j++) {
+                       if (mode->mclk_fs[j] == mfs)
+                               return 0;
+               }
+
+               dev_err(dai->dev, "unsupported mclk_fs %u for rate %u\n",
+                       mfs, rate);
+               return -EINVAL;
+       }
+
+       /* should not happen */
+       dev_err(dai->dev, "unsupported rate: %u\n", rate);
+       return -EINVAL;
+}
+
+static int es7134_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
+{
+       struct es7134_data *priv = snd_soc_dai_get_drvdata(dai);
+
+       /* mclk has not been provided, assume it is OK */
+       if (!priv->mclk)
+               return 0;
+
+       return es7134_check_mclk(dai, priv, params_rate(params));
+}
+
+static int es7134_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+                            unsigned int freq, int dir)
+{
+       struct es7134_data *priv = snd_soc_dai_get_drvdata(dai);
+
+       if (dir == SND_SOC_CLOCK_IN && clk_id == 0) {
+               priv->mclk = freq;
+               return 0;
+       }
+
+       return -ENOTSUPP;
+}
+
 static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
        fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK |
@@ -38,8 +115,38 @@ static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        return 0;
 }
 
+static int es7134_component_probe(struct snd_soc_component *c)
+{
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(c);
+       struct es7134_data *priv = snd_soc_component_get_drvdata(c);
+       const struct es7134_chip *chip = priv->chip;
+       int ret;
+
+       if (chip->extra_widget_num) {
+               ret = snd_soc_dapm_new_controls(dapm, chip->extra_widgets,
+                                               chip->extra_widget_num);
+               if (ret) {
+                       dev_err(c->dev, "failed to add extra widgets\n");
+                       return ret;
+               }
+       }
+
+       if (chip->extra_route_num) {
+               ret = snd_soc_dapm_add_routes(dapm, chip->extra_routes,
+                                             chip->extra_route_num);
+               if (ret) {
+                       dev_err(c->dev, "failed to add extra routes\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dai_ops es7134_dai_ops = {
        .set_fmt        = es7134_set_fmt,
+       .hw_params      = es7134_hw_params,
+       .set_sysclk     = es7134_set_sysclk,
 };
 
 static struct snd_soc_dai_driver es7134_dai = {
@@ -48,7 +155,11 @@ static struct snd_soc_dai_driver es7134_dai = {
                .stream_name = "Playback",
                .channels_min = 2,
                .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_192000,
+               .rates = (SNDRV_PCM_RATE_8000_48000 |
+                         SNDRV_PCM_RATE_88200      |
+                         SNDRV_PCM_RATE_96000      |
+                         SNDRV_PCM_RATE_176400     |
+                         SNDRV_PCM_RATE_192000),
                .formats = (SNDRV_PCM_FMTBIT_S16_LE  |
                            SNDRV_PCM_FMTBIT_S18_3LE |
                            SNDRV_PCM_FMTBIT_S20_3LE |
@@ -58,18 +169,56 @@ static struct snd_soc_dai_driver es7134_dai = {
        .ops = &es7134_dai_ops,
 };
 
+static const struct es7134_clock_mode es7134_modes[] = {
+       {
+               /* Single speed mode */
+               .rate_min = 8000,
+               .rate_max = 50000,
+               .mclk_fs = (unsigned int[]) { 256, 384, 512, 768, 1024 },
+               .mclk_fs_num = 5,
+       }, {
+               /* Double speed mode */
+               .rate_min = 84000,
+               .rate_max = 100000,
+               .mclk_fs = (unsigned int[]) { 128, 192, 256, 384, 512 },
+               .mclk_fs_num = 5,
+       }, {
+               /* Quad speed mode */
+               .rate_min = 167000,
+               .rate_max = 192000,
+               .mclk_fs = (unsigned int[]) { 128, 192, 256 },
+               .mclk_fs_num = 3,
+       },
+};
+
+/* Digital I/O are also supplied by VDD on the es7134 */
+static const struct snd_soc_dapm_route es7134_extra_routes[] = {
+       { "Playback", NULL, "VDD", }
+};
+
+static const struct es7134_chip es7134_chip = {
+       .dai_drv = &es7134_dai,
+       .modes = es7134_modes,
+       .mode_num = ARRAY_SIZE(es7134_modes),
+       .extra_routes = es7134_extra_routes,
+       .extra_route_num = ARRAY_SIZE(es7134_extra_routes),
+};
+
 static const struct snd_soc_dapm_widget es7134_dapm_widgets[] = {
        SND_SOC_DAPM_OUTPUT("AOUTL"),
        SND_SOC_DAPM_OUTPUT("AOUTR"),
        SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_REGULATOR_SUPPLY("VDD", 0, 0),
 };
 
 static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
        { "AOUTL", NULL, "DAC" },
        { "AOUTR", NULL, "DAC" },
+       { "DAC", NULL, "VDD" },
 };
 
 static const struct snd_soc_component_driver es7134_component_driver = {
+       .probe                  = es7134_component_probe,
        .dapm_widgets           = es7134_dapm_widgets,
        .num_dapm_widgets       = ARRAY_SIZE(es7134_dapm_widgets),
        .dapm_routes            = es7134_dapm_routes,
@@ -80,17 +229,87 @@ static const struct snd_soc_component_driver es7134_component_driver = {
        .non_legacy_dai_naming  = 1,
 };
 
+static struct snd_soc_dai_driver es7154_dai = {
+       .name = "es7154-hifi",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = (SNDRV_PCM_RATE_8000_48000 |
+                         SNDRV_PCM_RATE_88200      |
+                         SNDRV_PCM_RATE_96000),
+               .formats = (SNDRV_PCM_FMTBIT_S16_LE  |
+                           SNDRV_PCM_FMTBIT_S18_3LE |
+                           SNDRV_PCM_FMTBIT_S20_3LE |
+                           SNDRV_PCM_FMTBIT_S24_3LE |
+                           SNDRV_PCM_FMTBIT_S24_LE),
+       },
+       .ops = &es7134_dai_ops,
+};
+
+static const struct es7134_clock_mode es7154_modes[] = {
+       {
+               /* Single speed mode */
+               .rate_min = 8000,
+               .rate_max = 50000,
+               .mclk_fs = (unsigned int[]) { 32, 64, 128, 192, 256,
+                                             384, 512, 768, 1024 },
+               .mclk_fs_num = 9,
+       }, {
+               /* Double speed mode */
+               .rate_min = 84000,
+               .rate_max = 100000,
+               .mclk_fs = (unsigned int[]) { 128, 192, 256, 384, 512,
+                                             768, 1024},
+               .mclk_fs_num = 7,
+       }
+};
+
+/* Es7154 has a separate supply for digital I/O  */
+static const struct snd_soc_dapm_widget es7154_extra_widgets[] = {
+       SND_SOC_DAPM_REGULATOR_SUPPLY("PVDD", 0, 0),
+};
+
+static const struct snd_soc_dapm_route es7154_extra_routes[] = {
+       { "Playback", NULL, "PVDD", }
+};
+
+static const struct es7134_chip es7154_chip = {
+       .dai_drv = &es7154_dai,
+       .modes = es7154_modes,
+       .mode_num = ARRAY_SIZE(es7154_modes),
+       .extra_routes = es7154_extra_routes,
+       .extra_route_num = ARRAY_SIZE(es7154_extra_routes),
+       .extra_widgets = es7154_extra_widgets,
+       .extra_widget_num = ARRAY_SIZE(es7154_extra_widgets),
+};
+
 static int es7134_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
+       struct es7134_data *priv;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       platform_set_drvdata(pdev, priv);
+
+       priv->chip = of_device_get_match_data(dev);
+       if (!priv->chip) {
+               dev_err(dev, "failed to match device\n");
+               return -ENODEV;
+       }
+
        return devm_snd_soc_register_component(&pdev->dev,
                                      &es7134_component_driver,
-                                     &es7134_dai, 1);
+                                     priv->chip->dai_drv, 1);
 }
 
 #ifdef CONFIG_OF
 static const struct of_device_id es7134_ids[] = {
-       { .compatible = "everest,es7134", },
-       { .compatible = "everest,es7144", },
+       { .compatible = "everest,es7134", .data = &es7134_chip },
+       { .compatible = "everest,es7144", .data = &es7134_chip },
+       { .compatible = "everest,es7154", .data = &es7154_chip },
        { }
 };
 MODULE_DEVICE_TABLE(of, es7134_ids);
diff --git a/sound/soc/codecs/es7241.c b/sound/soc/codecs/es7241.c
new file mode 100644 (file)
index 0000000..87991bd
--- /dev/null
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2018 BayLibre, SAS.
+// Author: Jerome Brunet <jbrunet@baylibre.com>
+
+#include <linux/gpio/consumer.h>
+#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+
+struct es7241_clock_mode {
+       unsigned int rate_min;
+       unsigned int rate_max;
+       unsigned int *slv_mfs;
+       unsigned int slv_mfs_num;
+       unsigned int mst_mfs;
+       unsigned int mst_m0:1;
+       unsigned int mst_m1:1;
+};
+
+struct es7241_chip {
+       const struct es7241_clock_mode *modes;
+       unsigned int mode_num;
+};
+
+struct es7241_data {
+       struct gpio_desc *reset;
+       struct gpio_desc *m0;
+       struct gpio_desc *m1;
+       unsigned int fmt;
+       unsigned int mclk;
+       bool is_slave;
+       const struct es7241_chip *chip;
+};
+
+static void es7241_set_mode(struct es7241_data *priv,  int m0, int m1)
+{
+       /* put the device in reset */
+       gpiod_set_value_cansleep(priv->reset, 0);
+
+       /* set the mode */
+       gpiod_set_value_cansleep(priv->m0, m0);
+       gpiod_set_value_cansleep(priv->m1, m1);
+
+       /* take the device out of reset - datasheet does not specify a delay */
+       gpiod_set_value_cansleep(priv->reset, 1);
+}
+
+static int es7241_set_slave_mode(struct es7241_data *priv,
+                                const struct es7241_clock_mode *mode,
+                                unsigned int mfs)
+{
+       int j;
+
+       if (!mfs)
+               goto out_ok;
+
+       for (j = 0; j < mode->slv_mfs_num; j++) {
+               if (mode->slv_mfs[j] == mfs)
+                       goto out_ok;
+       }
+
+       return -EINVAL;
+
+out_ok:
+       es7241_set_mode(priv, 1, 1);
+       return 0;
+}
+
+static int es7241_set_master_mode(struct es7241_data *priv,
+                                 const struct es7241_clock_mode *mode,
+                                 unsigned int mfs)
+{
+       /*
+        * We can't really set clock ratio, if the mclk/lrclk is different
+        * from what we provide, then error out
+        */
+       if (mfs && mfs != mode->mst_mfs)
+               return -EINVAL;
+
+       es7241_set_mode(priv, mode->mst_m0, mode->mst_m1);
+
+       return 0;
+}
+
+static int es7241_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
+{
+       struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+       unsigned int rate = params_rate(params);
+       unsigned int mfs = priv->mclk / rate;
+       int i;
+
+       for (i = 0; i < priv->chip->mode_num; i++) {
+               const struct es7241_clock_mode *mode = &priv->chip->modes[i];
+
+               if (rate < mode->rate_min || rate >= mode->rate_max)
+                       continue;
+
+               if (priv->is_slave)
+                       return es7241_set_slave_mode(priv, mode, mfs);
+               else
+                       return es7241_set_master_mode(priv, mode, mfs);
+       }
+
+       /* should not happen */
+       dev_err(dai->dev, "unsupported rate: %u\n", rate);
+       return -EINVAL;
+}
+
+static int es7241_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+                            unsigned int freq, int dir)
+{
+       struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+       if (dir == SND_SOC_CLOCK_IN && clk_id == 0) {
+               priv->mclk = freq;
+               return 0;
+       }
+
+       return -ENOTSUPP;
+}
+
+static int es7241_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+       if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
+               dev_err(dai->dev, "Unsupported dai clock inversion\n");
+               return -EINVAL;
+       }
+
+       if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != priv->fmt) {
+               dev_err(dai->dev, "Invalid dai format\n");
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               priv->is_slave = true;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               priv->is_slave = false;
+               break;
+
+       default:
+               dev_err(dai->dev, "Unsupported clock configuration\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct snd_soc_dai_ops es7241_dai_ops = {
+       .set_fmt        = es7241_set_fmt,
+       .hw_params      = es7241_hw_params,
+       .set_sysclk     = es7241_set_sysclk,
+};
+
+static struct snd_soc_dai_driver es7241_dai = {
+       .name = "es7241-hifi",
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_192000,
+               .formats = (SNDRV_PCM_FMTBIT_S16_LE  |
+                           SNDRV_PCM_FMTBIT_S24_3LE |
+                           SNDRV_PCM_FMTBIT_S24_LE),
+       },
+       .ops = &es7241_dai_ops,
+};
+
+static const struct es7241_clock_mode es7241_modes[] = {
+       {
+               /* Single speed mode */
+               .rate_min = 8000,
+               .rate_max = 50000,
+               .slv_mfs = (unsigned int[]) { 256, 384, 512, 768, 1024 },
+               .slv_mfs_num = 5,
+               .mst_mfs = 256,
+               .mst_m0 = 0,
+               .mst_m1 = 0,
+       }, {
+               /* Double speed mode */
+               .rate_min = 50000,
+               .rate_max = 100000,
+               .slv_mfs = (unsigned int[]) { 128, 192 },
+               .slv_mfs_num = 2,
+               .mst_mfs = 128,
+               .mst_m0 = 1,
+               .mst_m1 = 0,
+       }, {
+               /* Quad speed mode */
+               .rate_min = 100000,
+               .rate_max = 200000,
+               .slv_mfs = (unsigned int[]) { 64 },
+               .slv_mfs_num = 1,
+               .mst_mfs = 64,
+               .mst_m0 = 0,
+               .mst_m1 = 1,
+       },
+};
+
+static const struct es7241_chip es7241_chip = {
+       .modes = es7241_modes,
+       .mode_num = ARRAY_SIZE(es7241_modes),
+};
+
+static const struct snd_soc_dapm_widget es7241_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("AINL"),
+       SND_SOC_DAPM_INPUT("AINR"),
+       SND_SOC_DAPM_DAC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_REGULATOR_SUPPLY("VDDP", 0, 0),
+       SND_SOC_DAPM_REGULATOR_SUPPLY("VDDD", 0, 0),
+       SND_SOC_DAPM_REGULATOR_SUPPLY("VDDA", 0, 0),
+};
+
+static const struct snd_soc_dapm_route es7241_dapm_routes[] = {
+       { "ADC", NULL, "AINL", },
+       { "ADC", NULL, "AINR", },
+       { "ADC", NULL, "VDDA", },
+       { "Capture", NULL, "VDDP", },
+       { "Capture", NULL, "VDDD", },
+};
+
+static const struct snd_soc_component_driver es7241_component_driver = {
+       .dapm_widgets           = es7241_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(es7241_dapm_widgets),
+       .dapm_routes            = es7241_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(es7241_dapm_routes),
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+static void es7241_parse_fmt(struct device *dev, struct es7241_data *priv)
+{
+       bool is_leftj;
+
+       /*
+        * The format is given by a pull resistor on the SDOUT pin:
+        * pull-up for i2s, pull-down for left justified.
+        */
+       is_leftj = of_property_read_bool(dev->of_node,
+                                        "everest,sdout-pull-down");
+       if (is_leftj)
+               priv->fmt = SND_SOC_DAIFMT_LEFT_J;
+       else
+               priv->fmt = SND_SOC_DAIFMT_I2S;
+}
+
+static int es7241_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct es7241_data *priv;
+       int err;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       platform_set_drvdata(pdev, priv);
+
+       priv->chip = of_device_get_match_data(dev);
+       if (!priv->chip) {
+               dev_err(dev, "failed to match device\n");
+               return -ENODEV;
+       }
+
+       es7241_parse_fmt(dev, priv);
+
+       priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+       if (IS_ERR(priv->reset)) {
+               err = PTR_ERR(priv->reset);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'reset' gpio: %d", err);
+               return err;
+       }
+
+       priv->m0 = devm_gpiod_get_optional(dev, "m0", GPIOD_OUT_LOW);
+       if (IS_ERR(priv->m0)) {
+               err = PTR_ERR(priv->m0);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'm0' gpio: %d", err);
+               return err;
+       }
+
+       priv->m1 = devm_gpiod_get_optional(dev, "m1", GPIOD_OUT_LOW);
+       if (IS_ERR(priv->m1)) {
+               err = PTR_ERR(priv->m1);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'm1' gpio: %d", err);
+               return err;
+       }
+
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &es7241_component_driver,
+                                     &es7241_dai, 1);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id es7241_ids[] = {
+       { .compatible = "everest,es7241", .data = &es7241_chip },
+       { }
+};
+MODULE_DEVICE_TABLE(of, es7241_ids);
+#endif
+
+static struct platform_driver es7241_driver = {
+       .driver = {
+               .name = "es7241",
+               .of_match_table = of_match_ptr(es7241_ids),
+       },
+       .probe = es7241_probe,
+};
+
+module_platform_driver(es7241_driver);
+
+MODULE_DESCRIPTION("ASoC ES7241 audio codec driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL");
index 4748a9d5de3bd4d127922830cca4e01a826968a5..7b8533abf637319e56de6f68a37e88912d7a0c2f 100644 (file)
@@ -2093,6 +2093,75 @@ static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
 }
 
 #ifdef CONFIG_PM
+/*
+ * Power management sequences
+ * ==========================
+ *
+ * The following explains the PM handling of HDAC HDMI with its parent
+ * device SKL and display power usage
+ *
+ * Probe
+ * -----
+ * In SKL probe,
+ * 1. skl_probe_work() powers up the display (refcount++ -> 1)
+ * 2. enumerates the codecs on the link
+ * 3. powers down the display  (refcount-- -> 0)
+ *
+ * In HDAC HDMI probe,
+ * 1. hdac_hdmi_dev_probe() powers up the display (refcount++ -> 1)
+ * 2. probe the codec
+ * 3. put the HDAC HDMI device to runtime suspend
+ * 4. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
+ *
+ * Once children are runtime suspended, SKL device also goes to runtime
+ * suspend
+ *
+ * HDMI Playback
+ * -------------
+ * Open HDMI device,
+ * 1. skl_runtime_resume() invoked
+ * 2. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
+ *
+ * Close HDMI device,
+ * 1. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
+ * 2. skl_runtime_suspend() invoked
+ *
+ * S0/S3 Cycle with playback in progress
+ * -------------------------------------
+ * When the device is opened for playback, the device is runtime active
+ * already and the display refcount is 1 as explained above.
+ *
+ * Entering to S3,
+ * 1. hdmi_codec_prepare() invoke the runtime resume of codec which just
+ *    increments the PM runtime usage count of the codec since the device
+ *    is in use already
+ * 2. skl_suspend() powers down the display (refcount-- -> 0)
+ *
+ * Wakeup from S3,
+ * 1. skl_resume() powers up the display (refcount++ -> 1)
+ * 2. hdmi_codec_complete() invokes the runtime suspend of codec which just
+ *    decrements the PM runtime usage count of the codec since the device
+ *    is in use already
+ *
+ * Once playback is stopped, the display refcount is set to 0 as explained
+ * above in the HDMI playback sequence. The PM handlings are designed in
+ * such way that to balance the refcount of display power when the codec
+ * device put to S3 while playback is going on.
+ *
+ * S0/S3 Cycle without playback in progress
+ * ----------------------------------------
+ * Entering to S3,
+ * 1. hdmi_codec_prepare() invoke the runtime resume of codec
+ * 2. skl_runtime_resume() invoked
+ * 3. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
+ * 4. skl_suspend() powers down the display (refcount-- -> 0)
+ *
+ * Wakeup from S3,
+ * 1. skl_resume() powers up the display (refcount++ -> 1)
+ * 2. hdmi_codec_complete() invokes the runtime suspend of codec
+ * 3. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
+ * 4. skl_runtime_suspend() invoked
+ */
 static int hdac_hdmi_runtime_suspend(struct device *dev)
 {
        struct hdac_device *hdev = dev_to_hdac_dev(dev);
index 6bd14453f06ec4849628b90a5448bdaa6081d3ed..468d5143e2c4f700e2f6e7b519e8ad485fb7aa7d 100644 (file)
@@ -1274,7 +1274,7 @@ static int nau8824_calc_fll_param(unsigned int fll_in,
        fvco_max = 0;
        fvco_sel = ARRAY_SIZE(mclk_src_scaling);
        for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
-               fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
+               fvco = 256ULL * fs * 2 * mclk_src_scaling[i].param;
                if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
                        fvco_max < fvco) {
                        fvco_max = fvco;
index dc6ea4987b7d9a4fb132d41902dd6c0bf75e39f8..b9fed99d8b5ed389d15d41af269f79d3f6ae0ce3 100644 (file)
@@ -2016,7 +2016,7 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
        fvco_max = 0;
        fvco_sel = ARRAY_SIZE(mclk_src_scaling);
        for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
-               fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
+               fvco = 256ULL * fs * 2 * mclk_src_scaling[i].param;
                if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
                        fvco_max < fvco) {
                        fvco_max = fvco;
index 21f15219b3ad825ebaae5f0db7b45cc59e756765..8df6447c76a668d9c301f41303fae9e86cd4c5e7 100644 (file)
@@ -262,8 +262,7 @@ int pcm1789_common_exit(struct device *dev)
 {
        struct pcm1789_private *priv = dev_get_drvdata(dev);
 
-       if (&priv->work)
-               flush_work(&priv->work);
+       flush_work(&priv->work);
 
        return 0;
 }
index 88fde70b1e9ef775c1c263fe36c5a613a93546c0..690c26e7389e527567169464f47461b6a2f60e07 100644 (file)
@@ -265,7 +265,7 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_component *component = dai->component;
        struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
-       unsigned int format = params_format(params);
+       snd_pcm_format_t format = params_format(params);
        unsigned int width = params_width(params);
        unsigned int channels = params_channels(params);
        unsigned int div_lrck;
index f4c8c45f40103cf82f5450b93da3b7e446db3878..c4452efc79700a1e62f260f8362dec175e447294 100644 (file)
@@ -1066,7 +1066,7 @@ static void rt1305_calibrate(struct rt1305_priv *rt1305)
        pr_debug("Left_rhl = 0x%x rh=0x%x rl=0x%x\n", rhl, rh, rl);
        pr_info("Left channel %d.%dohm\n", (r0ohm/10), (r0ohm%10));
 
-       r0l = 562949953421312;
+       r0l = 562949953421312ULL;
        if (rhl != 0)
                do_div(r0l, rhl);
        pr_debug("Left_r0 = 0x%llx\n", r0l);
@@ -1083,7 +1083,7 @@ static void rt1305_calibrate(struct rt1305_priv *rt1305)
        pr_debug("Right_rhl = 0x%x rh=0x%x rl=0x%x\n", rhl, rh, rl);
        pr_info("Right channel %d.%dohm\n", (r0ohm/10), (r0ohm%10));
 
-       r0r = 562949953421312;
+       r0r = 562949953421312ULL;
        if (rhl != 0)
                do_div(r0r, rhl);
        pr_debug("Right_r0 = 0x%llx\n", r0r);
@@ -1150,17 +1150,11 @@ static int rt1305_i2c_probe(struct i2c_client *i2c,
        rt1305_reset(rt1305->regmap);
        rt1305_calibrate(rt1305);
 
-       return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt1305,
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt1305,
                        rt1305_dai, ARRAY_SIZE(rt1305_dai));
 }
 
-static int rt1305_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_component(&i2c->dev);
-
-       return 0;
-}
-
 static void rt1305_i2c_shutdown(struct i2c_client *client)
 {
        struct rt1305_priv *rt1305 = i2c_get_clientdata(client);
@@ -1180,7 +1174,6 @@ static struct i2c_driver rt1305_i2c_driver = {
 #endif
        },
        .probe = rt1305_i2c_probe,
-       .remove   = rt1305_i2c_remove,
        .shutdown = rt1305_i2c_shutdown,
        .id_table = rt1305_i2c_id,
 };
index cf6dce69eb2ad0bfe22c43236f80ffc228a9be46..e52e4670cf65c978822a359ae6bfcf445c08f5a2 100644 (file)
@@ -229,10 +229,10 @@ static SOC_ENUM_SINGLE_DECL(rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
 static const struct snd_kcontrol_new rt5631_snd_controls[] = {
        /* MIC */
        SOC_ENUM("MIC1 Mode Control",  rt5631_mic1_mode_enum),
-       SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2,
+       SOC_SINGLE_TLV("MIC1 Boost Volume", RT5631_MIC_CTRL_2,
                RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv),
        SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum),
-       SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2,
+       SOC_SINGLE_TLV("MIC2 Boost Volume", RT5631_MIC_CTRL_2,
                RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv),
        /* MONO IN */
        SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum),
index 6b5669f3e85d740d3c088ac17f87074af352afd0..985852fd972387025e46a418d2081c24de218892 100644 (file)
@@ -331,11 +331,13 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = {
        SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5651_DAC2_DIG_VOL,
                        RT5651_L_VOL_SFT, RT5651_R_VOL_SFT,
                        175, 0, dac_vol_tlv),
-       /* IN1/IN2 Control */
+       /* IN1/IN2/IN3 Control */
        SOC_SINGLE_TLV("IN1 Boost", RT5651_IN1_IN2,
                RT5651_BST_SFT1, 8, 0, bst_tlv),
        SOC_SINGLE_TLV("IN2 Boost", RT5651_IN1_IN2,
                RT5651_BST_SFT2, 8, 0, bst_tlv),
+       SOC_SINGLE_TLV("IN3 Boost", RT5651_IN3,
+               RT5651_BST_SFT1, 8, 0, bst_tlv),
        /* INL/INR Volume Control */
        SOC_DOUBLE_TLV("IN Capture Volume", RT5651_INL1_INR1_VOL,
                        RT5651_INL_VOL_SFT, RT5651_INR_VOL_SFT,
@@ -1581,6 +1583,24 @@ static void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component
        snd_soc_dapm_mutex_unlock(dapm);
 }
 
+static void rt5651_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+       snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+               RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_NOR);
+       rt5651->ovcd_irq_enabled = true;
+}
+
+static void rt5651_disable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+       snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+               RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_BP);
+       rt5651->ovcd_irq_enabled = false;
+}
+
 static void rt5651_clear_micbias1_ovcd(struct snd_soc_component *component)
 {
        snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
@@ -1622,10 +1642,80 @@ static bool rt5651_jack_inserted(struct snd_soc_component *component)
        return val == 0;
 }
 
-/* Jack detect timings */
+/* Jack detect and button-press timings */
 #define JACK_SETTLE_TIME       100 /* milli seconds */
 #define JACK_DETECT_COUNT      5
 #define JACK_DETECT_MAXCOUNT   20  /* Aprox. 2 seconds worth of tries */
+#define JACK_UNPLUG_TIME       80  /* milli seconds */
+#define BP_POLL_TIME           10  /* milli seconds */
+#define BP_POLL_MAXCOUNT       200 /* assume something is wrong after this */
+#define BP_THRESHOLD           3
+
+static void rt5651_start_button_press_work(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+       rt5651->poll_count = 0;
+       rt5651->press_count = 0;
+       rt5651->release_count = 0;
+       rt5651->pressed = false;
+       rt5651->press_reported = false;
+       rt5651_clear_micbias1_ovcd(component);
+       schedule_delayed_work(&rt5651->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
+
+static void rt5651_button_press_work(struct work_struct *work)
+{
+       struct rt5651_priv *rt5651 =
+               container_of(work, struct rt5651_priv, bp_work.work);
+       struct snd_soc_component *component = rt5651->component;
+
+       /* Check the jack was not removed underneath us */
+       if (!rt5651_jack_inserted(component))
+               return;
+
+       if (rt5651_micbias1_ovcd(component)) {
+               rt5651->release_count = 0;
+               rt5651->press_count++;
+               /* Remember till after JACK_UNPLUG_TIME wait */
+               if (rt5651->press_count >= BP_THRESHOLD)
+                       rt5651->pressed = true;
+               rt5651_clear_micbias1_ovcd(component);
+       } else {
+               rt5651->press_count = 0;
+               rt5651->release_count++;
+       }
+
+       /*
+        * The pins get temporarily shorted on jack unplug, so we poll for
+        * at least JACK_UNPLUG_TIME milli-seconds before reporting a press.
+        */
+       rt5651->poll_count++;
+       if (rt5651->poll_count < (JACK_UNPLUG_TIME / BP_POLL_TIME)) {
+               schedule_delayed_work(&rt5651->bp_work,
+                                     msecs_to_jiffies(BP_POLL_TIME));
+               return;
+       }
+
+       if (rt5651->pressed && !rt5651->press_reported) {
+               dev_dbg(component->dev, "headset button press\n");
+               snd_soc_jack_report(rt5651->hp_jack, SND_JACK_BTN_0,
+                                   SND_JACK_BTN_0);
+               rt5651->press_reported = true;
+       }
+
+       if (rt5651->release_count >= BP_THRESHOLD) {
+               if (rt5651->press_reported) {
+                       dev_dbg(component->dev, "headset button release\n");
+                       snd_soc_jack_report(rt5651->hp_jack, 0, SND_JACK_BTN_0);
+               }
+               /* Re-enable OVCD IRQ to detect next press */
+               rt5651_enable_micbias1_ovcd_irq(component);
+               return; /* Stop polling */
+       }
+
+       schedule_delayed_work(&rt5651->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
 
 static int rt5651_detect_headset(struct snd_soc_component *component)
 {
@@ -1676,15 +1766,58 @@ static void rt5651_jack_detect_work(struct work_struct *work)
 {
        struct rt5651_priv *rt5651 =
                container_of(work, struct rt5651_priv, jack_detect_work);
+       struct snd_soc_component *component = rt5651->component;
        int report = 0;
 
-       if (rt5651_jack_inserted(rt5651->component)) {
-               rt5651_enable_micbias1_for_ovcd(rt5651->component);
-               report = rt5651_detect_headset(rt5651->component);
-               rt5651_disable_micbias1_for_ovcd(rt5651->component);
+       if (!rt5651_jack_inserted(component)) {
+               /* Jack removed, or spurious IRQ? */
+               if (rt5651->hp_jack->status & SND_JACK_HEADPHONE) {
+                       if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) {
+                               cancel_delayed_work_sync(&rt5651->bp_work);
+                               rt5651_disable_micbias1_ovcd_irq(component);
+                               rt5651_disable_micbias1_for_ovcd(component);
+                       }
+                       snd_soc_jack_report(rt5651->hp_jack, 0,
+                                           SND_JACK_HEADSET | SND_JACK_BTN_0);
+                       dev_dbg(component->dev, "jack unplugged\n");
+               }
+       } else if (!(rt5651->hp_jack->status & SND_JACK_HEADPHONE)) {
+               /* Jack inserted */
+               WARN_ON(rt5651->ovcd_irq_enabled);
+               rt5651_enable_micbias1_for_ovcd(component);
+               report = rt5651_detect_headset(component);
+               if (report == SND_JACK_HEADSET) {
+                       /* Enable ovcd IRQ for button press detect. */
+                       rt5651_enable_micbias1_ovcd_irq(component);
+               } else {
+                       /* No more need for overcurrent detect. */
+                       rt5651_disable_micbias1_for_ovcd(component);
+               }
+               dev_dbg(component->dev, "detect report %#02x\n", report);
+               snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
+       } else if (rt5651->ovcd_irq_enabled && rt5651_micbias1_ovcd(component)) {
+               dev_dbg(component->dev, "OVCD IRQ\n");
+
+               /*
+                * The ovcd IRQ keeps firing while the button is pressed, so
+                * we disable it and start polling the button until released.
+                *
+                * The disable will make the IRQ pin 0 again and since we get
+                * IRQs on both edges (so as to detect both jack plugin and
+                * unplug) this means we will immediately get another IRQ.
+                * The ovcd_irq_enabled check above makes the 2ND IRQ a NOP.
+                */
+               rt5651_disable_micbias1_ovcd_irq(component);
+               rt5651_start_button_press_work(component);
+
+               /*
+                * If the jack-detect IRQ flag goes high (unplug) after our
+                * above rt5651_jack_inserted() check and before we have
+                * disabled the OVCD IRQ, the IRQ pin will stay high and as
+                * we react to edges, we miss the unplug event -> recheck.
+                */
+               queue_work(system_long_wq, &rt5651->jack_detect_work);
        }
-
-       snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
 }
 
 static irqreturn_t rt5651_irq(int irq, void *data)
@@ -1696,14 +1829,18 @@ static irqreturn_t rt5651_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int rt5651_set_jack(struct snd_soc_component *component,
-                          struct snd_soc_jack *hp_jack, void *data)
+static void rt5651_cancel_work(void *data)
 {
-       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
-       int ret;
+       struct rt5651_priv *rt5651 = data;
 
-       if (!rt5651->irq)
-               return -EINVAL;
+       cancel_work_sync(&rt5651->jack_detect_work);
+       cancel_delayed_work_sync(&rt5651->bp_work);
+}
+
+static void rt5651_enable_jack_detect(struct snd_soc_component *component,
+                                     struct snd_soc_jack *hp_jack)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        /* IRQ output on GPIO1 */
        snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1,
@@ -1730,10 +1867,10 @@ static int rt5651_set_jack(struct snd_soc_component *component,
                        RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN);
                break;
        case RT5651_JD_NULL:
-               return 0;
+               return;
        default:
                dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
-               return -EINVAL;
+               return;
        }
 
        /* Enable jack detect power */
@@ -1767,19 +1904,39 @@ static int rt5651_set_jack(struct snd_soc_component *component,
                RT5651_MB1_OC_STKY_MASK, RT5651_MB1_OC_STKY_EN);
 
        rt5651->hp_jack = hp_jack;
-
-       ret = devm_request_threaded_irq(component->dev, rt5651->irq, NULL,
-                                       rt5651_irq,
-                                       IRQF_TRIGGER_RISING |
-                                       IRQF_TRIGGER_FALLING |
-                                       IRQF_ONESHOT, "rt5651", rt5651);
-       if (ret) {
-               dev_err(component->dev, "Failed to reguest IRQ: %d\n", ret);
-               return ret;
+       if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) {
+               rt5651_enable_micbias1_for_ovcd(component);
+               rt5651_enable_micbias1_ovcd_irq(component);
        }
 
+       enable_irq(rt5651->irq);
        /* sync initial jack state */
        queue_work(system_power_efficient_wq, &rt5651->jack_detect_work);
+}
+
+static void rt5651_disable_jack_detect(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+       disable_irq(rt5651->irq);
+       rt5651_cancel_work(rt5651);
+
+       if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) {
+               rt5651_disable_micbias1_ovcd_irq(component);
+               rt5651_disable_micbias1_for_ovcd(component);
+               snd_soc_jack_report(rt5651->hp_jack, 0, SND_JACK_BTN_0);
+       }
+
+       rt5651->hp_jack = NULL;
+}
+
+static int rt5651_set_jack(struct snd_soc_component *component,
+                          struct snd_soc_jack *jack, void *data)
+{
+       if (jack)
+               rt5651_enable_jack_detect(component, jack);
+       else
+               rt5651_disable_jack_detect(component);
 
        return 0;
 }
@@ -2034,8 +2191,26 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
        rt5651->irq = i2c->irq;
        rt5651->hp_mute = 1;
 
+       INIT_DELAYED_WORK(&rt5651->bp_work, rt5651_button_press_work);
        INIT_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
 
+       /* Make sure work is stopped on probe-error / remove */
+       ret = devm_add_action_or_reset(&i2c->dev, rt5651_cancel_work, rt5651);
+       if (ret)
+               return ret;
+
+       ret = devm_request_irq(&i2c->dev, rt5651->irq, rt5651_irq,
+                              IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
+                              | IRQF_ONESHOT, "rt5651", rt5651);
+       if (ret == 0) {
+               /* Gets re-enabled by rt5651_set_jack() */
+               disable_irq(rt5651->irq);
+       } else {
+               dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n",
+                        rt5651->irq, ret);
+               rt5651->irq = -ENXIO;
+       }
+
        ret = devm_snd_soc_register_component(&i2c->dev,
                                &soc_component_dev_rt5651,
                                rt5651_dai, ARRAY_SIZE(rt5651_dai));
@@ -2043,15 +2218,6 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
        return ret;
 }
 
-static int rt5651_i2c_remove(struct i2c_client *i2c)
-{
-       struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
-
-       cancel_work_sync(&rt5651->jack_detect_work);
-
-       return 0;
-}
-
 static struct i2c_driver rt5651_i2c_driver = {
        .driver = {
                .name = "rt5651",
@@ -2059,7 +2225,6 @@ static struct i2c_driver rt5651_i2c_driver = {
                .of_match_table = of_match_ptr(rt5651_of_match),
        },
        .probe = rt5651_i2c_probe,
-       .remove   = rt5651_i2c_remove,
        .id_table = rt5651_i2c_id,
 };
 module_i2c_driver(rt5651_i2c_driver);
index 3a0968c53fde8ef5c5040d56c4621d4842af768e..ac6de6fb541498dfd18614a9321070d790fb5b2f 100644 (file)
@@ -2071,8 +2071,16 @@ struct rt5651_pll_code {
 struct rt5651_priv {
        struct snd_soc_component *component;
        struct regmap *regmap;
+       /* Jack and button detect data */
        struct snd_soc_jack *hp_jack;
        struct work_struct jack_detect_work;
+       struct delayed_work bp_work;
+       bool ovcd_irq_enabled;
+       bool pressed;
+       bool press_reported;
+       int press_count;
+       int release_count;
+       int poll_count;
        unsigned int jd_src;
        unsigned int ovcd_th;
        unsigned int ovcd_sf;
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
new file mode 100644 (file)
index 0000000..640d400
--- /dev/null
@@ -0,0 +1,2681 @@
+/*
+ * rt5682.c  --  RT5682 ALSA SoC audio component driver
+ *
+ * Copyright 2018 Realtek Semiconductor Corp.
+ * Author: Bard Liao <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/acpi.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/rt5682.h>
+
+#include "rl6231.h"
+#include "rt5682.h"
+
+#define RT5682_NUM_SUPPLIES 3
+
+static const char *rt5682_supply_names[RT5682_NUM_SUPPLIES] = {
+       "AVDD",
+       "MICVDD",
+       "VBAT",
+};
+
+struct rt5682_priv {
+       struct snd_soc_component *component;
+       struct rt5682_platform_data pdata;
+       struct regmap *regmap;
+       struct snd_soc_jack *hs_jack;
+       struct regulator_bulk_data supplies[RT5682_NUM_SUPPLIES];
+       struct delayed_work jack_detect_work;
+       struct delayed_work jd_check_work;
+       struct mutex calibrate_mutex;
+
+       int sysclk;
+       int sysclk_src;
+       int lrck[RT5682_AIFS];
+       int bclk[RT5682_AIFS];
+       int master[RT5682_AIFS];
+
+       int pll_src;
+       int pll_in;
+       int pll_out;
+
+       int jack_type;
+};
+
+static const struct reg_sequence patch_list[] = {
+       {0x01c1, 0x1000},
+};
+
+static const struct reg_default rt5682_reg[] = {
+       {0x0002, 0x8080},
+       {0x0003, 0x8000},
+       {0x0005, 0x0000},
+       {0x0006, 0x0000},
+       {0x0008, 0x800f},
+       {0x000b, 0x0000},
+       {0x0010, 0x4040},
+       {0x0011, 0x0000},
+       {0x0012, 0x1404},
+       {0x0013, 0x1000},
+       {0x0014, 0xa00a},
+       {0x0015, 0x0404},
+       {0x0016, 0x0404},
+       {0x0019, 0xafaf},
+       {0x001c, 0x2f2f},
+       {0x001f, 0x0000},
+       {0x0022, 0x5757},
+       {0x0023, 0x0039},
+       {0x0024, 0x000b},
+       {0x0026, 0xc0c4},
+       {0x0029, 0x8080},
+       {0x002a, 0xa0a0},
+       {0x002b, 0x0300},
+       {0x0030, 0x0000},
+       {0x003c, 0x0080},
+       {0x0044, 0x0c0c},
+       {0x0049, 0x0000},
+       {0x0061, 0x0000},
+       {0x0062, 0x0000},
+       {0x0063, 0x003f},
+       {0x0064, 0x0000},
+       {0x0065, 0x0000},
+       {0x0066, 0x0030},
+       {0x0067, 0x0000},
+       {0x006b, 0x0000},
+       {0x006c, 0x0000},
+       {0x006d, 0x2200},
+       {0x006e, 0x0a10},
+       {0x0070, 0x8000},
+       {0x0071, 0x8000},
+       {0x0073, 0x0000},
+       {0x0074, 0x0000},
+       {0x0075, 0x0002},
+       {0x0076, 0x0001},
+       {0x0079, 0x0000},
+       {0x007a, 0x0000},
+       {0x007b, 0x0000},
+       {0x007c, 0x0100},
+       {0x007e, 0x0000},
+       {0x0080, 0x0000},
+       {0x0081, 0x0000},
+       {0x0082, 0x0000},
+       {0x0083, 0x0000},
+       {0x0084, 0x0000},
+       {0x0085, 0x0000},
+       {0x0086, 0x0005},
+       {0x0087, 0x0000},
+       {0x0088, 0x0000},
+       {0x008c, 0x0003},
+       {0x008d, 0x0000},
+       {0x008e, 0x0060},
+       {0x008f, 0x1000},
+       {0x0091, 0x0c26},
+       {0x0092, 0x0073},
+       {0x0093, 0x0000},
+       {0x0094, 0x0080},
+       {0x0098, 0x0000},
+       {0x009a, 0x0000},
+       {0x009b, 0x0000},
+       {0x009c, 0x0000},
+       {0x009d, 0x0000},
+       {0x009e, 0x100c},
+       {0x009f, 0x0000},
+       {0x00a0, 0x0000},
+       {0x00a3, 0x0002},
+       {0x00a4, 0x0001},
+       {0x00ae, 0x2040},
+       {0x00af, 0x0000},
+       {0x00b6, 0x0000},
+       {0x00b7, 0x0000},
+       {0x00b8, 0x0000},
+       {0x00b9, 0x0002},
+       {0x00be, 0x0000},
+       {0x00c0, 0x0160},
+       {0x00c1, 0x82a0},
+       {0x00c2, 0x0000},
+       {0x00d0, 0x0000},
+       {0x00d1, 0x2244},
+       {0x00d2, 0x3300},
+       {0x00d3, 0x2200},
+       {0x00d4, 0x0000},
+       {0x00d9, 0x0009},
+       {0x00da, 0x0000},
+       {0x00db, 0x0000},
+       {0x00dc, 0x00c0},
+       {0x00dd, 0x2220},
+       {0x00de, 0x3131},
+       {0x00df, 0x3131},
+       {0x00e0, 0x3131},
+       {0x00e2, 0x0000},
+       {0x00e3, 0x4000},
+       {0x00e4, 0x0aa0},
+       {0x00e5, 0x3131},
+       {0x00e6, 0x3131},
+       {0x00e7, 0x3131},
+       {0x00e8, 0x3131},
+       {0x00ea, 0xb320},
+       {0x00eb, 0x0000},
+       {0x00f0, 0x0000},
+       {0x00f1, 0x00d0},
+       {0x00f2, 0x00d0},
+       {0x00f6, 0x0000},
+       {0x00fa, 0x0000},
+       {0x00fb, 0x0000},
+       {0x00fc, 0x0000},
+       {0x00fd, 0x0000},
+       {0x00fe, 0x10ec},
+       {0x00ff, 0x6530},
+       {0x0100, 0xa0a0},
+       {0x010b, 0x0000},
+       {0x010c, 0xae00},
+       {0x010d, 0xaaa0},
+       {0x010e, 0x8aa2},
+       {0x010f, 0x02a2},
+       {0x0110, 0xc000},
+       {0x0111, 0x04a2},
+       {0x0112, 0x2800},
+       {0x0113, 0x0000},
+       {0x0117, 0x0100},
+       {0x0125, 0x0410},
+       {0x0132, 0x6026},
+       {0x0136, 0x5555},
+       {0x0138, 0x3700},
+       {0x013a, 0x2000},
+       {0x013b, 0x2000},
+       {0x013c, 0x2005},
+       {0x013f, 0x0000},
+       {0x0142, 0x0000},
+       {0x0145, 0x0002},
+       {0x0146, 0x0000},
+       {0x0147, 0x0000},
+       {0x0148, 0x0000},
+       {0x0149, 0x0000},
+       {0x0150, 0x79a1},
+       {0x0151, 0x0000},
+       {0x0160, 0x4ec0},
+       {0x0161, 0x0080},
+       {0x0162, 0x0200},
+       {0x0163, 0x0800},
+       {0x0164, 0x0000},
+       {0x0165, 0x0000},
+       {0x0166, 0x0000},
+       {0x0167, 0x000f},
+       {0x0168, 0x000f},
+       {0x0169, 0x0021},
+       {0x0190, 0x413d},
+       {0x0194, 0x0000},
+       {0x0195, 0x0000},
+       {0x0197, 0x0022},
+       {0x0198, 0x0000},
+       {0x0199, 0x0000},
+       {0x01af, 0x0000},
+       {0x01b0, 0x0400},
+       {0x01b1, 0x0000},
+       {0x01b2, 0x0000},
+       {0x01b3, 0x0000},
+       {0x01b4, 0x0000},
+       {0x01b5, 0x0000},
+       {0x01b6, 0x01c3},
+       {0x01b7, 0x02a0},
+       {0x01b8, 0x03e9},
+       {0x01b9, 0x1389},
+       {0x01ba, 0xc351},
+       {0x01bb, 0x0009},
+       {0x01bc, 0x0018},
+       {0x01bd, 0x002a},
+       {0x01be, 0x004c},
+       {0x01bf, 0x0097},
+       {0x01c0, 0x433d},
+       {0x01c2, 0x0000},
+       {0x01c3, 0x0000},
+       {0x01c4, 0x0000},
+       {0x01c5, 0x0000},
+       {0x01c6, 0x0000},
+       {0x01c7, 0x0000},
+       {0x01c8, 0x40af},
+       {0x01c9, 0x0702},
+       {0x01ca, 0x0000},
+       {0x01cb, 0x0000},
+       {0x01cc, 0x5757},
+       {0x01cd, 0x5757},
+       {0x01ce, 0x5757},
+       {0x01cf, 0x5757},
+       {0x01d0, 0x5757},
+       {0x01d1, 0x5757},
+       {0x01d2, 0x5757},
+       {0x01d3, 0x5757},
+       {0x01d4, 0x5757},
+       {0x01d5, 0x5757},
+       {0x01d6, 0x0000},
+       {0x01d7, 0x0008},
+       {0x01d8, 0x0029},
+       {0x01d9, 0x3333},
+       {0x01da, 0x0000},
+       {0x01db, 0x0004},
+       {0x01dc, 0x0000},
+       {0x01de, 0x7c00},
+       {0x01df, 0x0320},
+       {0x01e0, 0x06a1},
+       {0x01e1, 0x0000},
+       {0x01e2, 0x0000},
+       {0x01e3, 0x0000},
+       {0x01e4, 0x0000},
+       {0x01e6, 0x0001},
+       {0x01e7, 0x0000},
+       {0x01e8, 0x0000},
+       {0x01ea, 0x0000},
+       {0x01eb, 0x0000},
+       {0x01ec, 0x0000},
+       {0x01ed, 0x0000},
+       {0x01ee, 0x0000},
+       {0x01ef, 0x0000},
+       {0x01f0, 0x0000},
+       {0x01f1, 0x0000},
+       {0x01f2, 0x0000},
+       {0x01f3, 0x0000},
+       {0x01f4, 0x0000},
+       {0x0210, 0x6297},
+       {0x0211, 0xa005},
+       {0x0212, 0x824c},
+       {0x0213, 0xf7ff},
+       {0x0214, 0xf24c},
+       {0x0215, 0x0102},
+       {0x0216, 0x00a3},
+       {0x0217, 0x0048},
+       {0x0218, 0xa2c0},
+       {0x0219, 0x0400},
+       {0x021a, 0x00c8},
+       {0x021b, 0x00c0},
+       {0x021c, 0x0000},
+       {0x0250, 0x4500},
+       {0x0251, 0x40b3},
+       {0x0252, 0x0000},
+       {0x0253, 0x0000},
+       {0x0254, 0x0000},
+       {0x0255, 0x0000},
+       {0x0256, 0x0000},
+       {0x0257, 0x0000},
+       {0x0258, 0x0000},
+       {0x0259, 0x0000},
+       {0x025a, 0x0005},
+       {0x0270, 0x0000},
+       {0x02ff, 0x0110},
+       {0x0300, 0x001f},
+       {0x0301, 0x032c},
+       {0x0302, 0x5f21},
+       {0x0303, 0x4000},
+       {0x0304, 0x4000},
+       {0x0305, 0x06d5},
+       {0x0306, 0x8000},
+       {0x0307, 0x0700},
+       {0x0310, 0x4560},
+       {0x0311, 0xa4a8},
+       {0x0312, 0x7418},
+       {0x0313, 0x0000},
+       {0x0314, 0x0006},
+       {0x0315, 0xffff},
+       {0x0316, 0xc400},
+       {0x0317, 0x0000},
+       {0x03c0, 0x7e00},
+       {0x03c1, 0x8000},
+       {0x03c2, 0x8000},
+       {0x03c3, 0x8000},
+       {0x03c4, 0x8000},
+       {0x03c5, 0x8000},
+       {0x03c6, 0x8000},
+       {0x03c7, 0x8000},
+       {0x03c8, 0x8000},
+       {0x03c9, 0x8000},
+       {0x03ca, 0x8000},
+       {0x03cb, 0x8000},
+       {0x03cc, 0x8000},
+       {0x03d0, 0x0000},
+       {0x03d1, 0x0000},
+       {0x03d2, 0x0000},
+       {0x03d3, 0x0000},
+       {0x03d4, 0x2000},
+       {0x03d5, 0x2000},
+       {0x03d6, 0x0000},
+       {0x03d7, 0x0000},
+       {0x03d8, 0x2000},
+       {0x03d9, 0x2000},
+       {0x03da, 0x2000},
+       {0x03db, 0x2000},
+       {0x03dc, 0x0000},
+       {0x03dd, 0x0000},
+       {0x03de, 0x0000},
+       {0x03df, 0x2000},
+       {0x03e0, 0x0000},
+       {0x03e1, 0x0000},
+       {0x03e2, 0x0000},
+       {0x03e3, 0x0000},
+       {0x03e4, 0x0000},
+       {0x03e5, 0x0000},
+       {0x03e6, 0x0000},
+       {0x03e7, 0x0000},
+       {0x03e8, 0x0000},
+       {0x03e9, 0x0000},
+       {0x03ea, 0x0000},
+       {0x03eb, 0x0000},
+       {0x03ec, 0x0000},
+       {0x03ed, 0x0000},
+       {0x03ee, 0x0000},
+       {0x03ef, 0x0000},
+       {0x03f0, 0x0800},
+       {0x03f1, 0x0800},
+       {0x03f2, 0x0800},
+       {0x03f3, 0x0800},
+};
+
+static bool rt5682_volatile_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case RT5682_RESET:
+       case RT5682_CBJ_CTRL_2:
+       case RT5682_INT_ST_1:
+       case RT5682_4BTN_IL_CMD_1:
+       case RT5682_AJD1_CTRL:
+       case RT5682_HP_CALIB_CTRL_1:
+       case RT5682_DEVICE_ID:
+       case RT5682_I2C_MODE:
+       case RT5682_HP_CALIB_CTRL_10:
+       case RT5682_EFUSE_CTRL_2:
+       case RT5682_JD_TOP_VC_VTRL:
+       case RT5682_HP_IMP_SENS_CTRL_19:
+       case RT5682_IL_CMD_1:
+       case RT5682_SAR_IL_CMD_2:
+       case RT5682_SAR_IL_CMD_4:
+       case RT5682_SAR_IL_CMD_10:
+       case RT5682_SAR_IL_CMD_11:
+       case RT5682_EFUSE_CTRL_6...RT5682_EFUSE_CTRL_11:
+       case RT5682_HP_CALIB_STA_1...RT5682_HP_CALIB_STA_11:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool rt5682_readable_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case RT5682_RESET:
+       case RT5682_VERSION_ID:
+       case RT5682_VENDOR_ID:
+       case RT5682_DEVICE_ID:
+       case RT5682_HP_CTRL_1:
+       case RT5682_HP_CTRL_2:
+       case RT5682_HPL_GAIN:
+       case RT5682_HPR_GAIN:
+       case RT5682_I2C_CTRL:
+       case RT5682_CBJ_BST_CTRL:
+       case RT5682_CBJ_CTRL_1:
+       case RT5682_CBJ_CTRL_2:
+       case RT5682_CBJ_CTRL_3:
+       case RT5682_CBJ_CTRL_4:
+       case RT5682_CBJ_CTRL_5:
+       case RT5682_CBJ_CTRL_6:
+       case RT5682_CBJ_CTRL_7:
+       case RT5682_DAC1_DIG_VOL:
+       case RT5682_STO1_ADC_DIG_VOL:
+       case RT5682_STO1_ADC_BOOST:
+       case RT5682_HP_IMP_GAIN_1:
+       case RT5682_HP_IMP_GAIN_2:
+       case RT5682_SIDETONE_CTRL:
+       case RT5682_STO1_ADC_MIXER:
+       case RT5682_AD_DA_MIXER:
+       case RT5682_STO1_DAC_MIXER:
+       case RT5682_A_DAC1_MUX:
+       case RT5682_DIG_INF2_DATA:
+       case RT5682_REC_MIXER:
+       case RT5682_CAL_REC:
+       case RT5682_ALC_BACK_GAIN:
+       case RT5682_PWR_DIG_1:
+       case RT5682_PWR_DIG_2:
+       case RT5682_PWR_ANLG_1:
+       case RT5682_PWR_ANLG_2:
+       case RT5682_PWR_ANLG_3:
+       case RT5682_PWR_MIXER:
+       case RT5682_PWR_VOL:
+       case RT5682_CLK_DET:
+       case RT5682_RESET_LPF_CTRL:
+       case RT5682_RESET_HPF_CTRL:
+       case RT5682_DMIC_CTRL_1:
+       case RT5682_I2S1_SDP:
+       case RT5682_I2S2_SDP:
+       case RT5682_ADDA_CLK_1:
+       case RT5682_ADDA_CLK_2:
+       case RT5682_I2S1_F_DIV_CTRL_1:
+       case RT5682_I2S1_F_DIV_CTRL_2:
+       case RT5682_TDM_CTRL:
+       case RT5682_TDM_ADDA_CTRL_1:
+       case RT5682_TDM_ADDA_CTRL_2:
+       case RT5682_DATA_SEL_CTRL_1:
+       case RT5682_TDM_TCON_CTRL:
+       case RT5682_GLB_CLK:
+       case RT5682_PLL_CTRL_1:
+       case RT5682_PLL_CTRL_2:
+       case RT5682_PLL_TRACK_1:
+       case RT5682_PLL_TRACK_2:
+       case RT5682_PLL_TRACK_3:
+       case RT5682_PLL_TRACK_4:
+       case RT5682_PLL_TRACK_5:
+       case RT5682_PLL_TRACK_6:
+       case RT5682_PLL_TRACK_11:
+       case RT5682_SDW_REF_CLK:
+       case RT5682_DEPOP_1:
+       case RT5682_DEPOP_2:
+       case RT5682_HP_CHARGE_PUMP_1:
+       case RT5682_HP_CHARGE_PUMP_2:
+       case RT5682_MICBIAS_1:
+       case RT5682_MICBIAS_2:
+       case RT5682_PLL_TRACK_12:
+       case RT5682_PLL_TRACK_14:
+       case RT5682_PLL2_CTRL_1:
+       case RT5682_PLL2_CTRL_2:
+       case RT5682_PLL2_CTRL_3:
+       case RT5682_PLL2_CTRL_4:
+       case RT5682_RC_CLK_CTRL:
+       case RT5682_I2S_M_CLK_CTRL_1:
+       case RT5682_I2S2_F_DIV_CTRL_1:
+       case RT5682_I2S2_F_DIV_CTRL_2:
+       case RT5682_EQ_CTRL_1:
+       case RT5682_EQ_CTRL_2:
+       case RT5682_IRQ_CTRL_1:
+       case RT5682_IRQ_CTRL_2:
+       case RT5682_IRQ_CTRL_3:
+       case RT5682_IRQ_CTRL_4:
+       case RT5682_INT_ST_1:
+       case RT5682_GPIO_CTRL_1:
+       case RT5682_GPIO_CTRL_2:
+       case RT5682_GPIO_CTRL_3:
+       case RT5682_HP_AMP_DET_CTRL_1:
+       case RT5682_HP_AMP_DET_CTRL_2:
+       case RT5682_MID_HP_AMP_DET:
+       case RT5682_LOW_HP_AMP_DET:
+       case RT5682_DELAY_BUF_CTRL:
+       case RT5682_SV_ZCD_1:
+       case RT5682_SV_ZCD_2:
+       case RT5682_IL_CMD_1:
+       case RT5682_IL_CMD_2:
+       case RT5682_IL_CMD_3:
+       case RT5682_IL_CMD_4:
+       case RT5682_IL_CMD_5:
+       case RT5682_IL_CMD_6:
+       case RT5682_4BTN_IL_CMD_1:
+       case RT5682_4BTN_IL_CMD_2:
+       case RT5682_4BTN_IL_CMD_3:
+       case RT5682_4BTN_IL_CMD_4:
+       case RT5682_4BTN_IL_CMD_5:
+       case RT5682_4BTN_IL_CMD_6:
+       case RT5682_4BTN_IL_CMD_7:
+       case RT5682_ADC_STO1_HP_CTRL_1:
+       case RT5682_ADC_STO1_HP_CTRL_2:
+       case RT5682_AJD1_CTRL:
+       case RT5682_JD1_THD:
+       case RT5682_JD2_THD:
+       case RT5682_JD_CTRL_1:
+       case RT5682_DUMMY_1:
+       case RT5682_DUMMY_2:
+       case RT5682_DUMMY_3:
+       case RT5682_DAC_ADC_DIG_VOL1:
+       case RT5682_BIAS_CUR_CTRL_2:
+       case RT5682_BIAS_CUR_CTRL_3:
+       case RT5682_BIAS_CUR_CTRL_4:
+       case RT5682_BIAS_CUR_CTRL_5:
+       case RT5682_BIAS_CUR_CTRL_6:
+       case RT5682_BIAS_CUR_CTRL_7:
+       case RT5682_BIAS_CUR_CTRL_8:
+       case RT5682_BIAS_CUR_CTRL_9:
+       case RT5682_BIAS_CUR_CTRL_10:
+       case RT5682_VREF_REC_OP_FB_CAP_CTRL:
+       case RT5682_CHARGE_PUMP_1:
+       case RT5682_DIG_IN_CTRL_1:
+       case RT5682_PAD_DRIVING_CTRL:
+       case RT5682_SOFT_RAMP_DEPOP:
+       case RT5682_CHOP_DAC:
+       case RT5682_CHOP_ADC:
+       case RT5682_CALIB_ADC_CTRL:
+       case RT5682_VOL_TEST:
+       case RT5682_SPKVDD_DET_STA:
+       case RT5682_TEST_MODE_CTRL_1:
+       case RT5682_TEST_MODE_CTRL_2:
+       case RT5682_TEST_MODE_CTRL_3:
+       case RT5682_TEST_MODE_CTRL_4:
+       case RT5682_TEST_MODE_CTRL_5:
+       case RT5682_PLL1_INTERNAL:
+       case RT5682_PLL2_INTERNAL:
+       case RT5682_STO_NG2_CTRL_1:
+       case RT5682_STO_NG2_CTRL_2:
+       case RT5682_STO_NG2_CTRL_3:
+       case RT5682_STO_NG2_CTRL_4:
+       case RT5682_STO_NG2_CTRL_5:
+       case RT5682_STO_NG2_CTRL_6:
+       case RT5682_STO_NG2_CTRL_7:
+       case RT5682_STO_NG2_CTRL_8:
+       case RT5682_STO_NG2_CTRL_9:
+       case RT5682_STO_NG2_CTRL_10:
+       case RT5682_STO1_DAC_SIL_DET:
+       case RT5682_SIL_PSV_CTRL1:
+       case RT5682_SIL_PSV_CTRL2:
+       case RT5682_SIL_PSV_CTRL3:
+       case RT5682_SIL_PSV_CTRL4:
+       case RT5682_SIL_PSV_CTRL5:
+       case RT5682_HP_IMP_SENS_CTRL_01:
+       case RT5682_HP_IMP_SENS_CTRL_02:
+       case RT5682_HP_IMP_SENS_CTRL_03:
+       case RT5682_HP_IMP_SENS_CTRL_04:
+       case RT5682_HP_IMP_SENS_CTRL_05:
+       case RT5682_HP_IMP_SENS_CTRL_06:
+       case RT5682_HP_IMP_SENS_CTRL_07:
+       case RT5682_HP_IMP_SENS_CTRL_08:
+       case RT5682_HP_IMP_SENS_CTRL_09:
+       case RT5682_HP_IMP_SENS_CTRL_10:
+       case RT5682_HP_IMP_SENS_CTRL_11:
+       case RT5682_HP_IMP_SENS_CTRL_12:
+       case RT5682_HP_IMP_SENS_CTRL_13:
+       case RT5682_HP_IMP_SENS_CTRL_14:
+       case RT5682_HP_IMP_SENS_CTRL_15:
+       case RT5682_HP_IMP_SENS_CTRL_16:
+       case RT5682_HP_IMP_SENS_CTRL_17:
+       case RT5682_HP_IMP_SENS_CTRL_18:
+       case RT5682_HP_IMP_SENS_CTRL_19:
+       case RT5682_HP_IMP_SENS_CTRL_20:
+       case RT5682_HP_IMP_SENS_CTRL_21:
+       case RT5682_HP_IMP_SENS_CTRL_22:
+       case RT5682_HP_IMP_SENS_CTRL_23:
+       case RT5682_HP_IMP_SENS_CTRL_24:
+       case RT5682_HP_IMP_SENS_CTRL_25:
+       case RT5682_HP_IMP_SENS_CTRL_26:
+       case RT5682_HP_IMP_SENS_CTRL_27:
+       case RT5682_HP_IMP_SENS_CTRL_28:
+       case RT5682_HP_IMP_SENS_CTRL_29:
+       case RT5682_HP_IMP_SENS_CTRL_30:
+       case RT5682_HP_IMP_SENS_CTRL_31:
+       case RT5682_HP_IMP_SENS_CTRL_32:
+       case RT5682_HP_IMP_SENS_CTRL_33:
+       case RT5682_HP_IMP_SENS_CTRL_34:
+       case RT5682_HP_IMP_SENS_CTRL_35:
+       case RT5682_HP_IMP_SENS_CTRL_36:
+       case RT5682_HP_IMP_SENS_CTRL_37:
+       case RT5682_HP_IMP_SENS_CTRL_38:
+       case RT5682_HP_IMP_SENS_CTRL_39:
+       case RT5682_HP_IMP_SENS_CTRL_40:
+       case RT5682_HP_IMP_SENS_CTRL_41:
+       case RT5682_HP_IMP_SENS_CTRL_42:
+       case RT5682_HP_IMP_SENS_CTRL_43:
+       case RT5682_HP_LOGIC_CTRL_1:
+       case RT5682_HP_LOGIC_CTRL_2:
+       case RT5682_HP_LOGIC_CTRL_3:
+       case RT5682_HP_CALIB_CTRL_1:
+       case RT5682_HP_CALIB_CTRL_2:
+       case RT5682_HP_CALIB_CTRL_3:
+       case RT5682_HP_CALIB_CTRL_4:
+       case RT5682_HP_CALIB_CTRL_5:
+       case RT5682_HP_CALIB_CTRL_6:
+       case RT5682_HP_CALIB_CTRL_7:
+       case RT5682_HP_CALIB_CTRL_9:
+       case RT5682_HP_CALIB_CTRL_10:
+       case RT5682_HP_CALIB_CTRL_11:
+       case RT5682_HP_CALIB_STA_1:
+       case RT5682_HP_CALIB_STA_2:
+       case RT5682_HP_CALIB_STA_3:
+       case RT5682_HP_CALIB_STA_4:
+       case RT5682_HP_CALIB_STA_5:
+       case RT5682_HP_CALIB_STA_6:
+       case RT5682_HP_CALIB_STA_7:
+       case RT5682_HP_CALIB_STA_8:
+       case RT5682_HP_CALIB_STA_9:
+       case RT5682_HP_CALIB_STA_10:
+       case RT5682_HP_CALIB_STA_11:
+       case RT5682_SAR_IL_CMD_1:
+       case RT5682_SAR_IL_CMD_2:
+       case RT5682_SAR_IL_CMD_3:
+       case RT5682_SAR_IL_CMD_4:
+       case RT5682_SAR_IL_CMD_5:
+       case RT5682_SAR_IL_CMD_6:
+       case RT5682_SAR_IL_CMD_7:
+       case RT5682_SAR_IL_CMD_8:
+       case RT5682_SAR_IL_CMD_9:
+       case RT5682_SAR_IL_CMD_10:
+       case RT5682_SAR_IL_CMD_11:
+       case RT5682_SAR_IL_CMD_12:
+       case RT5682_SAR_IL_CMD_13:
+       case RT5682_EFUSE_CTRL_1:
+       case RT5682_EFUSE_CTRL_2:
+       case RT5682_EFUSE_CTRL_3:
+       case RT5682_EFUSE_CTRL_4:
+       case RT5682_EFUSE_CTRL_5:
+       case RT5682_EFUSE_CTRL_6:
+       case RT5682_EFUSE_CTRL_7:
+       case RT5682_EFUSE_CTRL_8:
+       case RT5682_EFUSE_CTRL_9:
+       case RT5682_EFUSE_CTRL_10:
+       case RT5682_EFUSE_CTRL_11:
+       case RT5682_JD_TOP_VC_VTRL:
+       case RT5682_DRC1_CTRL_0:
+       case RT5682_DRC1_CTRL_1:
+       case RT5682_DRC1_CTRL_2:
+       case RT5682_DRC1_CTRL_3:
+       case RT5682_DRC1_CTRL_4:
+       case RT5682_DRC1_CTRL_5:
+       case RT5682_DRC1_CTRL_6:
+       case RT5682_DRC1_HARD_LMT_CTRL_1:
+       case RT5682_DRC1_HARD_LMT_CTRL_2:
+       case RT5682_DRC1_PRIV_1:
+       case RT5682_DRC1_PRIV_2:
+       case RT5682_DRC1_PRIV_3:
+       case RT5682_DRC1_PRIV_4:
+       case RT5682_DRC1_PRIV_5:
+       case RT5682_DRC1_PRIV_6:
+       case RT5682_DRC1_PRIV_7:
+       case RT5682_DRC1_PRIV_8:
+       case RT5682_EQ_AUTO_RCV_CTRL1:
+       case RT5682_EQ_AUTO_RCV_CTRL2:
+       case RT5682_EQ_AUTO_RCV_CTRL3:
+       case RT5682_EQ_AUTO_RCV_CTRL4:
+       case RT5682_EQ_AUTO_RCV_CTRL5:
+       case RT5682_EQ_AUTO_RCV_CTRL6:
+       case RT5682_EQ_AUTO_RCV_CTRL7:
+       case RT5682_EQ_AUTO_RCV_CTRL8:
+       case RT5682_EQ_AUTO_RCV_CTRL9:
+       case RT5682_EQ_AUTO_RCV_CTRL10:
+       case RT5682_EQ_AUTO_RCV_CTRL11:
+       case RT5682_EQ_AUTO_RCV_CTRL12:
+       case RT5682_EQ_AUTO_RCV_CTRL13:
+       case RT5682_ADC_L_EQ_LPF1_A1:
+       case RT5682_R_EQ_LPF1_A1:
+       case RT5682_L_EQ_LPF1_H0:
+       case RT5682_R_EQ_LPF1_H0:
+       case RT5682_L_EQ_BPF1_A1:
+       case RT5682_R_EQ_BPF1_A1:
+       case RT5682_L_EQ_BPF1_A2:
+       case RT5682_R_EQ_BPF1_A2:
+       case RT5682_L_EQ_BPF1_H0:
+       case RT5682_R_EQ_BPF1_H0:
+       case RT5682_L_EQ_BPF2_A1:
+       case RT5682_R_EQ_BPF2_A1:
+       case RT5682_L_EQ_BPF2_A2:
+       case RT5682_R_EQ_BPF2_A2:
+       case RT5682_L_EQ_BPF2_H0:
+       case RT5682_R_EQ_BPF2_H0:
+       case RT5682_L_EQ_BPF3_A1:
+       case RT5682_R_EQ_BPF3_A1:
+       case RT5682_L_EQ_BPF3_A2:
+       case RT5682_R_EQ_BPF3_A2:
+       case RT5682_L_EQ_BPF3_H0:
+       case RT5682_R_EQ_BPF3_H0:
+       case RT5682_L_EQ_BPF4_A1:
+       case RT5682_R_EQ_BPF4_A1:
+       case RT5682_L_EQ_BPF4_A2:
+       case RT5682_R_EQ_BPF4_A2:
+       case RT5682_L_EQ_BPF4_H0:
+       case RT5682_R_EQ_BPF4_H0:
+       case RT5682_L_EQ_HPF1_A1:
+       case RT5682_R_EQ_HPF1_A1:
+       case RT5682_L_EQ_HPF1_H0:
+       case RT5682_R_EQ_HPF1_H0:
+       case RT5682_L_EQ_PRE_VOL:
+       case RT5682_R_EQ_PRE_VOL:
+       case RT5682_L_EQ_POST_VOL:
+       case RT5682_R_EQ_POST_VOL:
+       case RT5682_I2C_MODE:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2250, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
+
+/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
+static const DECLARE_TLV_DB_RANGE(bst_tlv,
+       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+       1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+       2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
+       3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
+       6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
+       7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
+       8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
+);
+
+/* Interface data select */
+static const char * const rt5682_data_select[] = {
+       "L/R", "R/L", "L/L", "R/R"
+};
+
+static SOC_ENUM_SINGLE_DECL(rt5682_if2_adc_enum,
+       RT5682_DIG_INF2_DATA, RT5682_IF2_ADC_SEL_SFT, rt5682_data_select);
+
+static SOC_ENUM_SINGLE_DECL(rt5682_if1_01_adc_enum,
+       RT5682_TDM_ADDA_CTRL_1, RT5682_IF1_ADC1_SEL_SFT, rt5682_data_select);
+
+static SOC_ENUM_SINGLE_DECL(rt5682_if1_23_adc_enum,
+       RT5682_TDM_ADDA_CTRL_1, RT5682_IF1_ADC2_SEL_SFT, rt5682_data_select);
+
+static SOC_ENUM_SINGLE_DECL(rt5682_if1_45_adc_enum,
+       RT5682_TDM_ADDA_CTRL_1, RT5682_IF1_ADC3_SEL_SFT, rt5682_data_select);
+
+static SOC_ENUM_SINGLE_DECL(rt5682_if1_67_adc_enum,
+       RT5682_TDM_ADDA_CTRL_1, RT5682_IF1_ADC4_SEL_SFT, rt5682_data_select);
+
+static const struct snd_kcontrol_new rt5682_if2_adc_swap_mux =
+       SOC_DAPM_ENUM("IF2 ADC Swap Mux", rt5682_if2_adc_enum);
+
+static const struct snd_kcontrol_new rt5682_if1_01_adc_swap_mux =
+       SOC_DAPM_ENUM("IF1 01 ADC Swap Mux", rt5682_if1_01_adc_enum);
+
+static const struct snd_kcontrol_new rt5682_if1_23_adc_swap_mux =
+       SOC_DAPM_ENUM("IF1 23 ADC Swap Mux", rt5682_if1_23_adc_enum);
+
+static const struct snd_kcontrol_new rt5682_if1_45_adc_swap_mux =
+       SOC_DAPM_ENUM("IF1 45 ADC Swap Mux", rt5682_if1_45_adc_enum);
+
+static const struct snd_kcontrol_new rt5682_if1_67_adc_swap_mux =
+       SOC_DAPM_ENUM("IF1 67 ADC Swap Mux", rt5682_if1_67_adc_enum);
+
+static void rt5682_reset(struct regmap *regmap)
+{
+       regmap_write(regmap, RT5682_RESET, 0);
+       regmap_write(regmap, RT5682_I2C_MODE, 1);
+}
+/**
+ * rt5682_sel_asrc_clk_src - select ASRC clock source for a set of filters
+ * @component: SoC audio component device.
+ * @filter_mask: mask of filters.
+ * @clk_src: clock source
+ *
+ * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5682 can
+ * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
+ * support special i2s clock format suc