Merge remote-tracking branch 'sound-asoc/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 01:02:25 +0000 (11:02 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 01:02:25 +0000 (11:02 +1000)
275 files changed:
Documentation/devicetree/bindings/sound/nau8810.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt
Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt [deleted file]
Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/rt5659.txt
Documentation/devicetree/bindings/sound/simple-scu-card.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
arch/arm/mach-s3c24xx/mach-mini2440.c
include/sound/l3.h
include/sound/s3c24xx_uda134x.h
include/sound/simple_card_utils.h
include/sound/soc.h
include/uapi/sound/Kbuild
include/uapi/sound/asoc.h
include/uapi/sound/snd_sst_tokens.h [new file with mode: 0644]
sound/soc/amd/acp-pcm-dma.c
sound/soc/atmel/atmel-classd.c
sound/soc/atmel/atmel-pcm-pdc.c
sound/soc/atmel/atmel-pdmic.c
sound/soc/codecs/88pm860x-codec.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1836.c
sound/soc/codecs/ad193x.c
sound/soc/codecs/ad1980.c
sound/soc/codecs/ad73311.c
sound/soc/codecs/adau1373.c
sound/soc/codecs/adau1701.c
sound/soc/codecs/adau1761.c
sound/soc/codecs/adau1781.c
sound/soc/codecs/adau1977.c
sound/soc/codecs/adau7002.c
sound/soc/codecs/adav80x.c
sound/soc/codecs/ads117x.c
sound/soc/codecs/ak4104.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/ak4554.c
sound/soc/codecs/ak4613.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/ak5386.c
sound/soc/codecs/alc5632.c
sound/soc/codecs/arizona.c
sound/soc/codecs/bt-sco.c
sound/soc/codecs/cs35l32.c
sound/soc/codecs/cs35l33.c
sound/soc/codecs/cs4265.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l56.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/cs42xx8.c
sound/soc/codecs/cs4349.c
sound/soc/codecs/cs47l24.c
sound/soc/codecs/cs53l30.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/da7213.c
sound/soc/codecs/da7213.h
sound/soc/codecs/da7218.c
sound/soc/codecs/da7218.h
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/da7219.c
sound/soc/codecs/da732x.c
sound/soc/codecs/da9055.c
sound/soc/codecs/dmic.c
sound/soc/codecs/es8328.c
sound/soc/codecs/gtm601.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdmi-codec.c
sound/soc/codecs/inno_rk3036.c
sound/soc/codecs/isabelle.c
sound/soc/codecs/jz4740.c
sound/soc/codecs/l3.c
sound/soc/codecs/lm49453.c
sound/soc/codecs/max98088.c
sound/soc/codecs/max98095.c
sound/soc/codecs/max98357a.c
sound/soc/codecs/max98371.c
sound/soc/codecs/max9850.c
sound/soc/codecs/max9860.c
sound/soc/codecs/max9867.c
sound/soc/codecs/max98925.c
sound/soc/codecs/max98926.c
sound/soc/codecs/mc13783.c
sound/soc/codecs/ml26124.c
sound/soc/codecs/nau8810.c [new file with mode: 0644]
sound/soc/codecs/nau8810.h [new file with mode: 0644]
sound/soc/codecs/nau8825.c
sound/soc/codecs/pcm1681.c
sound/soc/codecs/pcm179x.c
sound/soc/codecs/pcm3008.c
sound/soc/codecs/pcm3168a.c
sound/soc/codecs/pcm512x.c
sound/soc/codecs/rt286.c
sound/soc/codecs/rt298.c
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5514.h
sound/soc/codecs/rt5616.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt5640.h
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5651.c
sound/soc/codecs/rt5659.c
sound/soc/codecs/rt5659.h
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5677.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/si476x.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/spdif_receiver.c
sound/soc/codecs/spdif_transmitter.c
sound/soc/codecs/ssm2518.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/ssm4567.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/sta350.c
sound/soc/codecs/sta529.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/sti-sas.c
sound/soc/codecs/tas2552.c
sound/soc/codecs/tas5086.c
sound/soc/codecs/tas571x.c
sound/soc/codecs/tas5720.c
sound/soc/codecs/tfa9879.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic31xx.c
sound/soc/codecs/tlv320aic32x4.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/twl4030.c
sound/soc/codecs/twl6040.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wl1273.c
sound/soc/codecs/wm0010.c
sound/soc/codecs/wm1250-ev1.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8400.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8727.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8770.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8782.c
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8971.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8978.c
sound/soc/codecs/wm8983.c
sound/soc/codecs/wm8985.c
sound/soc/codecs/wm8988.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8991.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8995.c
sound/soc/codecs/wm8996.c
sound/soc/codecs/wm8997.c
sound/soc/codecs/wm8998.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9090.c
sound/soc/codecs/wm9705.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/dwc/designware_i2s.c
sound/soc/fsl/fsl_asrc.c
sound/soc/fsl/fsl_asrc_dma.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_sai.c
sound/soc/generic/Kconfig
sound/soc/generic/Makefile
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card.c
sound/soc/generic/simple-scu-card.c [new file with mode: 0644]
sound/soc/img/pistachio-internal-dac.c
sound/soc/intel/Kconfig
sound/soc/intel/atom/sst-atom-controls.c
sound/soc/intel/atom/sst-atom-controls.h
sound/soc/intel/atom/sst-mfld-platform-pcm.c
sound/soc/intel/atom/sst/sst.c
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/atom/sst/sst_ipc.c
sound/soc/intel/atom/sst/sst_pvt.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/haswell/sst-haswell-pcm.c
sound/soc/intel/skylake/bxt-sst.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-sst-dsp.h
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/intel/skylake/skl-sst-ipc.h
sound/soc/intel/skylake/skl-sst-utils.c
sound/soc/intel/skylake/skl-sst.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl-tplg-interface.h
sound/soc/intel/skylake/skl.h
sound/soc/kirkwood/kirkwood-dma.c
sound/soc/mediatek/common/mtk-afe-fe-dai.c
sound/soc/omap/mcbsp.c
sound/soc/omap/omap-abe-twl6040.c
sound/soc/omap/omap-pcm.c
sound/soc/qcom/apq8016_sbc.c
sound/soc/qcom/lpass-platform.c
sound/soc/qcom/lpass.h
sound/soc/rockchip/Kconfig
sound/soc/rockchip/Makefile
sound/soc/rockchip/rk3399_gru_sound.c [new file with mode: 0644]
sound/soc/rockchip/rockchip_i2s.c
sound/soc/rockchip/rockchip_spdif.c
sound/soc/samsung/ac97.c
sound/soc/samsung/dma.h
sound/soc/samsung/dmaengine.c
sound/soc/samsung/i2s.c
sound/soc/samsung/idma.c
sound/soc/samsung/pcm.c
sound/soc/samsung/s3c-i2s-v2.c
sound/soc/samsung/s3c-i2s-v2.h
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c24xx-i2s.c
sound/soc/samsung/s3c24xx_uda134x.c
sound/soc/samsung/smdk_wm8580pcm.c
sound/soc/samsung/smdk_wm8994pcm.c
sound/soc/samsung/spdif.c
sound/soc/sh/Kconfig
sound/soc/sh/rcar/Makefile
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/rsrc-card.c [deleted file]
sound/soc/sh/rcar/ssi.c
sound/soc/soc-ac97.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-ops.c
sound/soc/soc-topology.c
sound/soc/soc-utils.c
sound/soc/sunxi/Kconfig
sound/soc/sunxi/sun4i-codec.c
sound/soc/sunxi/sun4i-spdif.c
sound/soc/tegra/Kconfig
sound/soc/tegra/Makefile
sound/soc/tegra/tegra_rt5640.c
sound/soc/tegra/tegra_sgtl5000.c [new file with mode: 0644]
sound/soc/ux500/ux500_msp_dai.c

diff --git a/Documentation/devicetree/bindings/sound/nau8810.txt b/Documentation/devicetree/bindings/sound/nau8810.txt
new file mode 100644 (file)
index 0000000..05830e4
--- /dev/null
@@ -0,0 +1,16 @@
+NAU8810 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+  - compatible : "nuvoton,nau8810"
+
+  - reg : the I2C address of the device.
+
+Example:
+
+codec: nau8810@1a {
+       compatible = "nuvoton,nau8810";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt
new file mode 100644 (file)
index 0000000..5da7da4
--- /dev/null
@@ -0,0 +1,42 @@
+NVIDIA Tegra audio complex, with SGTL5000 CODEC
+
+Required properties:
+- compatible : "nvidia,tegra-audio-sgtl5000"
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names : Must include the following entries:
+  - pll_a
+  - pll_a_out0
+  - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,audio-routing : A list of the connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source. Valid names for sources and
+  sinks are the SGTL5000's pins (as documented in its binding), and the jacks
+  on the board:
+
+  * Headphone Jack
+  * Line In Jack
+  * Mic Jack
+
+- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
+  connected to the CODEC.
+- nvidia,audio-codec : The phandle of the SGTL5000 audio codec.
+
+Example:
+
+sound {
+       compatible = "toradex,tegra-audio-sgtl5000-apalis_t30",
+                    "nvidia,tegra-audio-sgtl5000";
+       nvidia,model = "Toradex Apalis T30";
+       nvidia,audio-routing =
+               "Headphone Jack", "HP_OUT",
+               "LINE_IN", "Line In Jack",
+               "MIC_IN", "Mic Jack";
+       nvidia,i2s-controller = <&tegra_i2s2>;
+       nvidia,audio-codec = <&sgtl5000>;
+       clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+                <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+                <&tegra_car TEGRA30_CLK_EXTERN1>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
+};
index 48129368d4d971800cca39e58f28b2df9c8170a6..d9d8635ff94ce65faa0f3a5f14333266145f189a 100644 (file)
@@ -16,6 +16,24 @@ Required properties:
                                * "spkr-iomux"
 - qcom,model           : Name of the sound card.
 
+- qcom,audio-routing   : A list of the connections between audio components.
+                         Each entry is a pair of strings, the first being the
+                         connection's sink, the second being the connection's
+                         source. Valid names could be power supplies, MicBias
+                         of msm8x16_wcd codec and the jacks on the board:
+
+                         Power supplies:
+                         * MIC BIAS External1
+                         * MIC BIAS External2
+                         * MIC BIAS Internal1
+                         * MIC BIAS Internal2
+
+                         Board connectors:
+                         * Headset Mic
+                         * Secondary Mic",
+                         * DMIC
+                         * Ext Spk
+
 Dai-link subnode properties and subnodes:
 
 Required dai-link subnodes:
@@ -37,6 +55,18 @@ sound: sound {
        reg-names = "mic-iomux", "spkr-iomux";
        qcom,model = "DB410c";
 
+       qcom,audio-routing =
+               "MIC BIAS External1", "Handset Mic",
+               "MIC BIAS Internal2", "Headset Mic",
+               "MIC BIAS External1", "Secondary Mic",
+               "AMIC1", "MIC BIAS External1",
+               "AMIC2", "MIC BIAS Internal2",
+               "AMIC3", "MIC BIAS External1",
+               "DMIC1", "MIC BIAS Internal1",
+               "MIC BIAS Internal1", "Digital Mic1",
+               "DMIC2", "MIC BIAS Internal1",
+               "MIC BIAS Internal1", "Digital Mic2";
+
        /* I2S - Internal codec */
        internal-dai-link@0 {
                cpu { /* PRIMARY */
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
deleted file mode 100644 (file)
index 255ece3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-Renesas Sampling Rate Convert Sound Card:
-
-Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC <-> codec.
-
-Required properties:
-
-- compatible                           : "renesas,rsrc-card{,<board>}"
-                                         Examples with boards are:
-                                           - "renesas,rsrc-card"
-                                           - "renesas,rsrc-card,lager"
-                                           - "renesas,rsrc-card,koelsch"
-Optional properties:
-
-- card_name                            : User specified audio sound card name, one string
-                                         property.
-- cpu                                  : CPU   sub-node
-- codec                                        : CODEC sub-node
-
-Optional subnode properties:
-
-- format                               : CPU/CODEC common audio format.
-                                         "i2s", "right_j", "left_j" , "dsp_a"
-                                         "dsp_b", "ac97", "pdm", "msb", "lsb"
-- frame-master                         : Indicates dai-link frame master.
-                                         phandle to a cpu or codec subnode.
-- bitclock-master                      : Indicates dai-link bit clock master.
-                                         phandle to a cpu or codec subnode.
-- bitclock-inversion                   : bool property. Add this if the
-                                         dai-link uses bit clock inversion.
-- frame-inversion                      : bool property. Add this if the
-                                         dai-link uses frame clock inversion.
-- convert-rate                         : platform specified sampling rate convert
-- convert-channels                     : platform specified converted channel size (2 - 8 ch)
-- audio-prefix                         : see audio-routing
-- audio-routing                                : A list of the connections between audio components.
-                                         Each entry is a pair of strings, the first being the connection's sink,
-                                         the second being the connection's source. Valid names for sources.
-                                         use audio-prefix if some components is using same sink/sources naming.
-                                         it can be used if compatible was "renesas,rsrc-card";
-
-Required CPU/CODEC subnodes properties:
-
-- sound-dai                            : phandle and port of CPU/CODEC
-
-Optional CPU/CODEC subnodes properties:
-
-- clocks / system-clock-frequency      : specify subnode's clock if needed.
-                                         it can be specified via "clocks" if system has
-                                         clock node (= common clock), or "system-clock-frequency"
-                                         (if system doens't support common clock)
-                                         If a clock is specified, it is
-                                         enabled with clk_prepare_enable()
-                                         in dai startup() and disabled with
-                                         clk_disable_unprepare() in dai
-                                         shutdown().
-
-Example
-
-sound {
-       compatible = "renesas,rsrc-card,lager";
-
-       card-name = "rsnd-ak4643";
-       format = "left_j";
-       bitclock-master = <&sndcodec>;
-       frame-master = <&sndcodec>;
-
-       sndcpu: cpu {
-               sound-dai = <&rcar_sound>;
-       };
-
-       sndcodec: codec {
-               sound-dai = <&ak4643>;
-               system-clock-frequency = <11289600>;
-       };
-};
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
new file mode 100644 (file)
index 0000000..f19b6c8
--- /dev/null
@@ -0,0 +1,15 @@
+ROCKCHIP with MAX98357A/RT5514/DA7219 codecs on GRU boards
+
+Required properties:
+- compatible: "rockchip,rk3399-gru-sound"
+- rockchip,cpu: The phandle of the Rockchip I2S controller that's
+  connected to the codecs
+- rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
+
+Example:
+
+sound {
+       compatible = "rockchip,rk3399-gru-sound";
+       rockchip,cpu = <&i2s0>;
+       rockchip,codec = <&max98357a &rt5514 &da7219>;
+};
index 5f79e7fde0328d93b19d340f31cba9c77d9f94e4..1766e0543fc51b85ee045eba78fe72e4b62f7a58 100644 (file)
@@ -12,6 +12,9 @@ Required properties:
 
 Optional properties:
 
+- clocks: The phandle of the master clock to the CODEC
+- clock-names: Should be "mclk"
+
 - realtek,in1-differential
 - realtek,in3-differential
 - realtek,in4-differential
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
new file mode 100644 (file)
index 0000000..d6fe47e
--- /dev/null
@@ -0,0 +1,110 @@
+ASoC simple SCU Sound Card
+
+Simple-Card specifies audio DAI connections of SoC <-> codec.
+
+Required properties:
+
+- compatible                           : "simple-scu-audio-card"
+                                         "renesas,rsrc-card"
+
+Optional properties:
+
+- simple-audio-card,name               : User specified audio sound card name, one string
+                                         property.
+- simple-audio-card,cpu                        : CPU   sub-node
+- simple-audio-card,codec              : CODEC sub-node
+
+Optional subnode properties:
+
+- simple-audio-card,format             : CPU/CODEC common audio format.
+                                         "i2s", "right_j", "left_j" , "dsp_a"
+                                         "dsp_b", "ac97", "pdm", "msb", "lsb"
+- simple-audio-card,frame-master       : Indicates dai-link frame master.
+                                         phandle to a cpu or codec subnode.
+- simple-audio-card,bitclock-master    : Indicates dai-link bit clock master.
+                                         phandle to a cpu or codec subnode.
+- simple-audio-card,bitclock-inversion : bool property. Add this if the
+                                         dai-link uses bit clock inversion.
+- simple-audio-card,frame-inversion    : bool property. Add this if the
+                                         dai-link uses frame clock inversion.
+- simple-audio-card,convert-rate       : platform specified sampling rate convert
+- simple-audio-card,convert-channels   : platform specified converted channel size (2 - 8 ch)
+- simple-audio-card,prefix             : see audio-routing
+- simple-audio-card,routing            : A list of the connections between audio components.
+                                         Each entry is a pair of strings, the first being the connection's sink,
+                                         the second being the connection's source. Valid names for sources.
+                                         use audio-prefix if some components is using same sink/sources naming.
+                                         it can be used if compatible was "renesas,rsrc-card";
+
+Required CPU/CODEC subnodes properties:
+
+- sound-dai                            : phandle and port of CPU/CODEC
+
+Optional CPU/CODEC subnodes properties:
+
+- clocks / system-clock-frequency      : specify subnode's clock if needed.
+                                         it can be specified via "clocks" if system has
+                                         clock node (= common clock), or "system-clock-frequency"
+                                         (if system doens't support common clock)
+                                         If a clock is specified, it is
+                                         enabled with clk_prepare_enable()
+                                         in dai startup() and disabled with
+                                         clk_disable_unprepare() in dai
+                                         shutdown().
+
+Example 1. Sampling Rate Covert
+
+sound {
+       compatible = "simple-scu-audio-card";
+
+       simple-audio-card,name = "rsnd-ak4643";
+       simple-audio-card,format = "left_j";
+       simple-audio-card,format = "left_j";
+       simple-audio-card,bitclock-master = <&sndcodec>;
+       simple-audio-card,frame-master = <&sndcodec>;
+
+       simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */
+
+       simple-audio-card,prefix = "ak4642";
+       simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
+                       "DAI0 Capture", "ak4642 Capture";
+
+       sndcpu: simple-audio-card,cpu {
+               sound-dai = <&rcar_sound>;
+       };
+
+       sndcodec: simple-audio-card,codec {
+               sound-dai = <&ak4643>;
+               system-clock-frequency = <11289600>;
+       };
+};
+
+Example 2. 2 CPU 1 Codec
+
+sound {
+       compatible = "renesas,rsrc-card";
+
+       card-name = "rsnd-ak4643";
+       format = "left_j";
+       bitclock-master = <&dpcmcpu>;
+       frame-master = <&dpcmcpu>;
+
+       convert-rate = <48000>;  /* see audio_clk_a */
+
+       audio-prefix = "ak4642";
+       audio-routing = "ak4642 Playback", "DAI0 Playback",
+                       "ak4642 Playback", "DAI1 Playback";
+
+       dpcmcpu: cpu@0 {
+               sound-dai = <&rcar_sound 0>;
+       };
+
+       cpu@1 {
+               sound-dai = <&rcar_sound 1>;
+       };
+
+       codec {
+               sound-dai = <&ak4643>;
+               clocks = <&audio_clock>;
+       };
+};
index 13503aa505a9cc4e4a3920f69e1fb61c6746fa09..0230c4d20506edaf919883afe352e089c6d8531e 100644 (file)
@@ -9,6 +9,7 @@ Required properties:
 
   - compatible         : should be one of the following:
     - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
+    - "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
 
   - reg                        : Offset and length of the register set for the device.
 
@@ -25,6 +26,8 @@ Required properties:
        "apb"             clock for the spdif bus.
        "spdif"           clock for spdif controller.
 
+  - resets             : reset specifier for the ahb reset (A31 and newer only)
+
 Example:
 
 spdif: spdif@01c21000 {
index bbf41322d726ebf61ef054a23985d8d187d64027..ec60bd4a1646f094edead1037483b5ed3aea3fba 100644 (file)
@@ -497,9 +497,28 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
        },
 };
 
+static struct uda134x_platform_data s3c24xx_uda134x = {
+       .l3 = {
+               .gpio_clk = S3C2410_GPB(4),
+               .gpio_data = S3C2410_GPB(3),
+               .gpio_mode = S3C2410_GPB(2),
+               .use_gpios = 1,
+               .data_hold = 1,
+               .data_setup = 1,
+               .clock_high = 1,
+               .mode_hold = 1,
+               .mode = 1,
+               .mode_setup = 1,
+       },
+       .model = UDA134X_UDA1341,
+};
+
 static struct platform_device uda1340_codec = {
                .name = "uda134x-codec",
                .id = -1,
+               .dev = {
+                       .platform_data  = &s3c24xx_uda134x,
+               },
 };
 
 static struct platform_device *mini2440_devices[] __initdata = {
index 423a08f0f1b0677b77bd3a81ba50bfb5b3968816..1471da22adad7a8539bba87c4befc55562f4b0ad 100644 (file)
@@ -2,9 +2,15 @@
 #define _L3_H_ 1
 
 struct l3_pins {
-       void (*setdat)(int);
-       void (*setclk)(int);
-       void (*setmode)(int);
+       void (*setdat)(struct l3_pins *, int);
+       void (*setclk)(struct l3_pins *, int);
+       void (*setmode)(struct l3_pins *, int);
+
+       int gpio_data;
+       int gpio_clk;
+       int gpio_mode;
+       int use_gpios;
+
        int data_hold;
        int data_setup;
        int clock_high;
@@ -13,6 +19,9 @@ struct l3_pins {
        int mode_setup;
 };
 
+struct device;
+
 int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
+int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap);
 
 #endif
index 33df4cb909d31d6c18e9b8284a31595388550a74..ffaf1f098c8e4967eaac91e64af924e8d683cbff 100644 (file)
@@ -7,7 +7,6 @@ struct s3c24xx_uda134x_platform_data {
        int l3_clk;
        int l3_mode;
        int l3_data;
-       void (*power) (int);
        int model;
 };
 
index 86088aed9002a8d5643ffcda33df64607397fe9d..fd6412551145a8df0c003c6b4b190b5c34b0f91f 100644 (file)
@@ -27,10 +27,45 @@ int asoc_simple_card_parse_daifmt(struct device *dev,
                                  struct device_node *codec,
                                  char *prefix,
                                  unsigned int *retfmt);
+__printf(3, 4)
 int asoc_simple_card_set_dailink_name(struct device *dev,
                                      struct snd_soc_dai_link *dai_link,
                                      const char *fmt, ...);
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
                                     char *prefix);
 
+#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai)             \
+       asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
+#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai)           \
+       asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
+int asoc_simple_card_parse_clk(struct device_node *node,
+                              struct device_node *dai_of_node,
+                              struct asoc_simple_dai *simple_dai);
+
+#define asoc_simple_card_parse_cpu(node, dai_link,                             \
+                                  list_name, cells_name, is_single_link)       \
+       asoc_simple_card_parse_dai(node, &dai_link->cpu_of_node,                \
+               &dai_link->cpu_dai_name, list_name, cells_name, is_single_link)
+#define asoc_simple_card_parse_codec(node, dai_link, list_name, cells_name)    \
+       asoc_simple_card_parse_dai(node, &dai_link->codec_of_node,              \
+               &dai_link->codec_dai_name, list_name, cells_name, NULL)
+#define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \
+       asoc_simple_card_parse_dai(node, &dai_link->platform_of_node,           \
+               NULL, list_name, cells_name, NULL)
+int asoc_simple_card_parse_dai(struct device_node *node,
+                                 struct device_node **endpoint_np,
+                                 const char **dai_name,
+                                 const char *list_name,
+                                 const char *cells_name,
+                                 int *is_single_links);
+
+int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
+                             struct asoc_simple_dai *simple_dai);
+
+int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link);
+void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
+                                     int is_single_links);
+
+int asoc_simple_card_clean_reference(struct snd_soc_card *card);
+
 #endif /* __SIMPLE_CARD_CORE_H */
index 6144882cc96a59f3b6251ace1fefff0584e8f084..4f1c784e44f634016153b3ff4f0a1b7d3b652b95 100644 (file)
@@ -898,14 +898,6 @@ struct snd_soc_codec_driver {
        int (*resume)(struct snd_soc_codec *);
        struct snd_soc_component_driver component_driver;
 
-       /* Default control and setup, added after probe() is run */
-       const struct snd_kcontrol_new *controls;
-       int num_controls;
-       const struct snd_soc_dapm_widget *dapm_widgets;
-       int num_dapm_widgets;
-       const struct snd_soc_dapm_route *dapm_routes;
-       int num_dapm_routes;
-
        /* codec wide operations */
        int (*set_sysclk)(struct snd_soc_codec *codec,
                          int clk_id, int source, unsigned int freq, int dir);
@@ -1547,17 +1539,6 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo
        return snd_soc_component_get_drvdata(&platform->component);
 }
 
-static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
-               void *data)
-{
-       dev_set_drvdata(rtd->dev, data);
-}
-
-static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
-{
-       return dev_get_drvdata(rtd->dev);
-}
-
 static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
 {
        INIT_LIST_HEAD(&card->codec_dev_list);
index 691984cb0b915da8afbc60211145d9dbb45c7143..9578d8bdbf31fe5f1675704bc6fad8b090b96b31 100644 (file)
@@ -13,3 +13,4 @@ header-y += sb16_csp.h
 header-y += sfnt_info.h
 header-y += tlv.h
 header-y += usb_stream.h
+header-y += snd_sst_tokens.h
index e4701a3c633187c25a832580eb0af5fe70f2ade4..33d00a4ce6567f03f1cb52b08a5e72bda04efbaf 100644 (file)
@@ -83,7 +83,7 @@
 #define SND_SOC_TPLG_NUM_TEXTS         16
 
 /* ABI version */
-#define SND_SOC_TPLG_ABI_VERSION       0x4
+#define SND_SOC_TPLG_ABI_VERSION       0x5
 
 /* Max size of TLV data */
 #define SND_SOC_TPLG_TLV_SIZE          32
 #define SND_SOC_TPLG_TYPE_CODEC_LINK   9
 #define SND_SOC_TPLG_TYPE_BACKEND_LINK 10
 #define SND_SOC_TPLG_TYPE_PDATA                11
-#define SND_SOC_TPLG_TYPE_MAX  SND_SOC_TPLG_TYPE_PDATA
+#define SND_SOC_TPLG_TYPE_BE_DAI       12
+#define SND_SOC_TPLG_TYPE_MAX          SND_SOC_TPLG_TYPE_BE_DAI
 
 /* vendor block IDs - please add new vendor types to end */
 #define SND_SOC_TPLG_TYPE_VENDOR_FW    1000
 #define SND_SOC_TPLG_TUPLE_TYPE_WORD   4
 #define SND_SOC_TPLG_TUPLE_TYPE_SHORT  5
 
+/* BE DAI flags */
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES         (1 << 0)
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
+
 /*
  * Block Header.
  * This header precedes all object and object arrays below.
@@ -251,6 +257,7 @@ struct snd_soc_tplg_stream_caps {
        __le32 period_size_max; /* max period size bytes */
        __le32 buffer_size_min; /* min buffer size bytes */
        __le32 buffer_size_max; /* max buffer size bytes */
+       __le32 sig_bits;        /* number of bits of content */
 } __attribute__((packed));
 
 /*
@@ -285,6 +292,8 @@ struct snd_soc_tplg_manifest {
        __le32 graph_elems;     /* number of graph elements */
        __le32 pcm_elems;       /* number of PCM elements */
        __le32 dai_link_elems;  /* number of DAI link elements */
+       __le32 be_dai_elems;    /* number of BE DAI elements */
+       __le32 reserved[20];    /* reserved for new ABI element types */
        struct snd_soc_tplg_private priv;
 } __attribute__((packed));
 
@@ -450,4 +459,26 @@ struct snd_soc_tplg_link_config {
        struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
        __le32 num_streams;     /* number of streams */
 } __attribute__((packed));
+
+/*
+ * Describes SW/FW specific features of BE DAI.
+ *
+ * File block representation for BE DAI :-
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_hdr           |  1  |
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_be_dai        |  N  |
+ * +-----------------------------------+-----+
+ */
+struct snd_soc_tplg_be_dai {
+       __le32 size;            /* in bytes of this structure */
+       char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */
+       __le32 dai_id;          /* unique ID - used to match */
+       __le32 playback;        /* supports playback mode */
+       __le32 capture;         /* supports capture mode */
+       struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
+       __le32 flag_mask;       /* bitmask of flags to configure */
+       __le32 flags;           /* SND_SOC_TPLG_DAI_FLGBIT_* */
+       struct snd_soc_tplg_private priv;
+} __attribute__((packed));
 #endif
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
new file mode 100644 (file)
index 0000000..1ee2e94
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * snd_sst_tokens.h - Intel SST tokens definition
+ *
+ * Copyright (C) 2016 Intel Corp
+ * Author: Shreyas NC <shreyas.nc@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 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.
+ */
+#ifndef __SND_SST_TOKENS_H__
+#define __SND_SST_TOKENS_H__
+
+/**
+ * %SKL_TKN_UUID:               Module UUID
+ *
+ * %SKL_TKN_U8_BLOCK_TYPE:      Type of the private data block.Can be:
+ *                              tuples, bytes, short and words
+ *
+ * %SKL_TKN_U8_IN_PIN_TYPE:     Input pin type,
+ *                              homogenous=0, heterogenous=1
+ *
+ * %SKL_TKN_U8_OUT_PIN_TYPE:    Output pin type,
+ *                              homogenous=0, heterogenous=1
+ * %SKL_TKN_U8_DYN_IN_PIN:      Configure Input pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_DYN_OUT_PIN:     Configure Output pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_IN_QUEUE_COUNT:  Store the number of Input pins
+ *
+ * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
+ *
+ * %SKL_TKN_U8_TIME_SLOT:       TDM slot number
+ *
+ * %SKL_TKN_U8_CORE_ID:         Stores module affinity value.Can take
+ *                              the values:
+ *                              SKL_AFFINITY_CORE_0 = 0,
+ *                              SKL_AFFINITY_CORE_1,
+ *                              SKL_AFFINITY_CORE_MAX
+ *
+ * %SKL_TKN_U8_MOD_TYPE:        Module type value.
+ *
+ * %SKL_TKN_U8_CONN_TYPE:       Module connection type can be a FE,
+ *                              BE or NONE as defined :
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
+ *
+ * %SKL_TKN_U8_DEV_TYPE:        Type of device to which the module is
+ *                              connected
+ *                              Can take the values:
+ *                              SKL_DEVICE_BT = 0x0,
+ *                              SKL_DEVICE_DMIC = 0x1,
+ *                              SKL_DEVICE_I2S = 0x2,
+ *                              SKL_DEVICE_SLIMBUS = 0x3,
+ *                              SKL_DEVICE_HDALINK = 0x4,
+ *                              SKL_DEVICE_HDAHOST = 0x5,
+ *                              SKL_DEVICE_NONE
+ *
+ * %SKL_TKN_U8_HW_CONN_TYPE:    Connection type of the HW to which the
+ *                              module is connected
+ *                              SKL_CONN_NONE = 0,
+ *                              SKL_CONN_SOURCE = 1,
+ *                              SKL_CONN_SINK = 2
+ *
+ * %SKL_TKN_U16_PIN_INST_ID:    Stores the pin instance id
+ *
+ * %SKL_TKN_U16_MOD_INST_ID:    Stores the mdule instance id
+ *
+ * %SKL_TKN_U32_MAX_MCPS:       Module max mcps value
+ *
+ * %SKL_TKN_U32_MEM_PAGES:      Module resource pages
+ *
+ * %SKL_TKN_U32_OBS:            Stores Output Buffer size
+ *
+ * %SKL_TKN_U32_IBS:            Stores input buffer size
+ *
+ * %SKL_TKN_U32_VBUS_ID:        Module VBUS_ID. PDM=0, SSP0=0,
+ *                              SSP1=1,SSP2=2,
+ *                              SSP3=3, SSP4=4,
+ *                              SSP5=5, SSP6=6,INVALID
+ *
+ * %SKL_TKN_U32_PARAMS_FIXUP:   Module Params fixup mask
+ * %SKL_TKN_U32_CONVERTER:      Module params converter mask
+ * %SKL_TKN_U32_PIPE_ID:        Stores the pipe id
+ *
+ * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
+ *                              connected to. It can be
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
+ *
+ * %SKL_TKN_U32_PIPE_PRIORITY:  Pipe priority value
+ * %SKL_TKN_U32_PIPE_MEM_PGS:   Pipe resource pages
+ *
+ * %SKL_TKN_U32_DIR_PIN_COUNT:  Value for the direction to set input/output
+ *                              formats and the pin count.
+ *                              The first 4 bits have the direction
+ *                              value and the next 4 have
+ *                              the pin count value.
+ *                              SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
+ *                              The input and output formats
+ *                              share the same set of tokens
+ *                              with the distinction between input
+ *                              and output made by reading direction
+ *                              token.
+ *
+ * %SKL_TKN_U32_FMT_CH:         Supported channel count
+ *
+ * %SKL_TKN_U32_FMT_FREQ:       Supported frequency/sample rate
+ *
+ * %SKL_TKN_U32_FMT_BIT_DEPTH:  Supported container size
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
+ *
+ * %SKL_TKN_U32_FMT_CH_CONFIG:  Supported channel configurations for the
+ *                              input/output.
+ *
+ * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
+ *                              channel or per sample. The values can be :
+ *                              SKL_INTERLEAVING_PER_CHANNEL = 0,
+ *                              SKL_INTERLEAVING_PER_SAMPLE = 1,
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_TYPE:
+ *                              Specifies the sample type. Can take the
+ *                              values: SKL_SAMPLE_TYPE_INT_MSB = 0,
+ *                              SKL_SAMPLE_TYPE_INT_LSB = 1,
+ *                              SKL_SAMPLE_TYPE_INT_SIGNED = 2,
+ *                              SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
+ *                              SKL_SAMPLE_TYPE_FLOAT = 4
+ *
+ * %SKL_TKN_U32_CH_MAP:         Channel map values
+ * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
+ *                              SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
+ *                              SKL_PARAM_SET, SKL_PARAM_BIND
+ *
+ * %SKL_TKN_U32_MOD_PARAM_ID:   ID of the module params
+ *
+ * %SKL_TKN_U32_CAPS_SET_PARAMS:
+ *                              Set params value
+ *
+ * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
+ *
+ * %SKL_TKN_U32_CAPS_SIZE:      Caps size
+ *
+ * %SKL_TKN_U32_PROC_DOMAIN:    Specify processing domain
+ *
+ * %SKL_TKN_U32_LIB_COUNT:      Specifies the number of libraries
+ *
+ * %SKL_TKN_STR_LIB_NAME:       Specifies the library name
+ *
+ * module_id and loadable flags dont have tokens as these values will be
+ * read from the DSP FW manifest
+ */
+enum SKL_TKNS {
+       SKL_TKN_UUID = 1,
+       SKL_TKN_U8_NUM_BLOCKS,
+       SKL_TKN_U8_BLOCK_TYPE,
+       SKL_TKN_U8_IN_PIN_TYPE,
+       SKL_TKN_U8_OUT_PIN_TYPE,
+       SKL_TKN_U8_DYN_IN_PIN,
+       SKL_TKN_U8_DYN_OUT_PIN,
+       SKL_TKN_U8_IN_QUEUE_COUNT,
+       SKL_TKN_U8_OUT_QUEUE_COUNT,
+       SKL_TKN_U8_TIME_SLOT,
+       SKL_TKN_U8_CORE_ID,
+       SKL_TKN_U8_MOD_TYPE,
+       SKL_TKN_U8_CONN_TYPE,
+       SKL_TKN_U8_DEV_TYPE,
+       SKL_TKN_U8_HW_CONN_TYPE,
+       SKL_TKN_U16_MOD_INST_ID,
+       SKL_TKN_U16_BLOCK_SIZE,
+       SKL_TKN_U32_MAX_MCPS,
+       SKL_TKN_U32_MEM_PAGES,
+       SKL_TKN_U32_OBS,
+       SKL_TKN_U32_IBS,
+       SKL_TKN_U32_VBUS_ID,
+       SKL_TKN_U32_PARAMS_FIXUP,
+       SKL_TKN_U32_CONVERTER,
+       SKL_TKN_U32_PIPE_ID,
+       SKL_TKN_U32_PIPE_CONN_TYPE,
+       SKL_TKN_U32_PIPE_PRIORITY,
+       SKL_TKN_U32_PIPE_MEM_PGS,
+       SKL_TKN_U32_DIR_PIN_COUNT,
+       SKL_TKN_U32_FMT_CH,
+       SKL_TKN_U32_FMT_FREQ,
+       SKL_TKN_U32_FMT_BIT_DEPTH,
+       SKL_TKN_U32_FMT_SAMPLE_SIZE,
+       SKL_TKN_U32_FMT_CH_CONFIG,
+       SKL_TKN_U32_FMT_INTERLEAVE,
+       SKL_TKN_U32_FMT_SAMPLE_TYPE,
+       SKL_TKN_U32_FMT_CH_MAP,
+       SKL_TKN_U32_PIN_MOD_ID,
+       SKL_TKN_U32_PIN_INST_ID,
+       SKL_TKN_U32_MOD_SET_PARAMS,
+       SKL_TKN_U32_MOD_PARAM_ID,
+       SKL_TKN_U32_CAPS_SET_PARAMS,
+       SKL_TKN_U32_CAPS_PARAMS_ID,
+       SKL_TKN_U32_CAPS_SIZE,
+       SKL_TKN_U32_PROC_DOMAIN,
+       SKL_TKN_U32_LIB_COUNT,
+       SKL_TKN_STR_LIB_NAME,
+       SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
+};
+
+#endif
index d1fb035f44db8fd7026d97e1148f0c09eb4d1679..504c7cd7f58a335b4c5c35c1cccb36f5d4536c22 100644 (file)
@@ -897,7 +897,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static struct snd_pcm_ops acp_dma_ops = {
+static const struct snd_pcm_ops acp_dma_ops = {
        .open = acp_dma_open,
        .close = acp_dma_close,
        .ioctl = snd_pcm_lib_ioctl,
index 6d9b8b44e2dae93feedc644f0a0568c3dd883927..89ac5f5a93eb31f510d8ab189badc781fd319e6f 100644 (file)
@@ -308,9 +308,11 @@ static struct regmap *atmel_classd_codec_get_remap(struct device *dev)
 
 static struct snd_soc_codec_driver soc_codec_dev_classd = {
        .probe          = atmel_classd_codec_probe,
-       .controls       = atmel_classd_snd_controls,
-       .num_controls   = ARRAY_SIZE(atmel_classd_snd_controls),
        .get_regmap     = atmel_classd_codec_get_remap,
+       .component_driver = {
+               .controls               = atmel_classd_snd_controls,
+               .num_controls           = ARRAY_SIZE(atmel_classd_snd_controls),
+       },
 };
 
 /* codec dai component */
index da861b44413f7f7f6e199b9d2aa9340691ed5b2f..91b7069c34994b8248d44218066e0ff20124a1bb 100644 (file)
@@ -381,7 +381,7 @@ static int atmel_pcm_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static struct snd_pcm_ops atmel_pcm_ops = {
+static const struct snd_pcm_ops atmel_pcm_ops = {
        .open           = atmel_pcm_open,
        .close          = atmel_pcm_close,
        .ioctl          = snd_pcm_lib_ioctl,
index 5f56da60c92ff6398d3eba82ab2ce7e0b75fd649..c917df7715d1b4fb7b315c7f81f32ebe3308f87d 100644 (file)
@@ -80,7 +80,7 @@ static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev)
 
        if (pdata->mic_max_freq < pdata->mic_min_freq) {
                dev_err(dev,
-                       "mic-max-freq should not less than mic-min-freq\n");
+                       "mic-max-freq should not be less than mic-min-freq\n");
                return ERR_PTR(-EINVAL);
        }
 
@@ -115,8 +115,10 @@ static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream,
                return ret;
 
        ret =  clk_prepare_enable(dd->pclk);
-       if (ret)
+       if (ret) {
+               clk_disable_unprepare(dd->gclk);
                return ret;
+       }
 
        /* Clear all bits in the Control Register(PDMIC_CR) */
        regmap_write(dd->regmap, PDMIC_CR, 0);
@@ -283,7 +285,7 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
        8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0),
 );
 
-int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
+static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
@@ -357,8 +359,10 @@ static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
        .probe          = atmel_pdmic_codec_probe,
-       .controls       = atmel_pdmic_snd_controls,
-       .num_controls   = ARRAY_SIZE(atmel_pdmic_snd_controls),
+       .component_driver = {
+               .controls               = atmel_pdmic_snd_controls,
+               .num_controls           = ARRAY_SIZE(atmel_pdmic_snd_controls),
+       },
 };
 
 /* codec dai component */
@@ -596,7 +600,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
        dd->irq = platform_get_irq(pdev, 0);
        if (dd->irq < 0) {
                ret = dd->irq;
-               dev_err(dev, "failed to could not get irq: %d\n", ret);
+               dev_err(dev, "failed to get irq: %d\n", ret);
                return ret;
        }
 
@@ -614,7 +618,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* The gclk clock frequency must always be tree times
+       /* The gclk clock frequency must always be three times
         * lower than the pclk clock frequency
         */
        ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3);
@@ -649,7 +653,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* Get the minimal and maximal sample rate that micphone supports */
+       /* Get the minimal and maximal sample rate that the microphone supports */
        atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max);
 
        /* register cpu dai */
index e8bed6b0c9dbdb26bf90d0e77ba849c02f62e642..b013a4c62b6334dd44ae4b833aef9b6de35cfa21 100644 (file)
@@ -1361,12 +1361,14 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
        .set_bias_level = pm860x_set_bias_level,
        .get_regmap     = pm860x_get_regmap,
 
-       .controls = pm860x_snd_controls,
-       .num_controls = ARRAY_SIZE(pm860x_snd_controls),
-       .dapm_widgets = pm860x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets),
-       .dapm_routes = pm860x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes),
+       .component_driver = {
+               .controls               = pm860x_snd_controls,
+               .num_controls           = ARRAY_SIZE(pm860x_snd_controls),
+               .dapm_widgets           = pm860x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pm860x_dapm_widgets),
+               .dapm_routes            = pm860x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pm860x_dapm_routes),
+       },
 };
 
 static int pm860x_codec_probe(struct platform_device *pdev)
index 1cd6ab344d67def61db455d956ac2d7075a1f6d8..b3fd110b1325c2e9e68266a20b722c50d4d2a6ea 100644 (file)
@@ -92,6 +92,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_MC13783 if MFD_MC13XXX
        select SND_SOC_ML26124 if I2C
+       select SND_SOC_NAU8810 if I2C
        select SND_SOC_NAU8825 if I2C
        select SND_SOC_HDMI_CODEC
        select SND_SOC_PCM1681 if I2C
@@ -1064,6 +1065,10 @@ config SND_SOC_MC13783
 config SND_SOC_ML26124
        tristate
 
+config SND_SOC_NAU8810
+       tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
+       depends on I2C
+
 config SND_SOC_NAU8825
        tristate
 
index 58036af2c7d9837b347ea2b6cdccaad72a711a53..ffaa523a7556226031df566e926447a007b3e0f9 100644 (file)
@@ -86,6 +86,7 @@ snd-soc-max9850-objs := max9850.o
 snd-soc-max9860-objs := max9860.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
+snd-soc-nau8810-objs := nau8810.o
 snd-soc-nau8825-objs := nau8825.o
 snd-soc-hdmi-codec-objs := hdmi-codec.o
 snd-soc-pcm1681-objs := pcm1681.o
@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_MAX9850)       += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MAX9860)  += snd-soc-max9860.o
 obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)  += snd-soc-ml26124.o
+obj-$(CONFIG_SND_SOC_NAU8810)   += snd-soc-nau8810.o
 obj-$(CONFIG_SND_SOC_NAU8825)   += snd-soc-nau8825.o
 obj-$(CONFIG_SND_SOC_HDMI_CODEC)       += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)  += snd-soc-pcm1681.o
index 2fc89155f14a1a2de2eddc2ca60c2f5f5c1190fb..935ff7cb71c57ca9c458be5a032c0a9e8f190a28 100644 (file)
@@ -2408,28 +2408,28 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
 {
        u32 value;
 
-       if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL))
+       if (of_property_read_bool(np, "stericsson,amic1-type-single-ended"))
                codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
        else
                codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;
 
-       if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL))
+       if (of_property_read_bool(np, "stericsson,amic2-type-single-ended"))
                codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
        else
                codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;
 
        /* Has a non-standard Vamic been requested? */
-       if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL))
+       if (of_property_read_bool(np, "stericsson,amic1a-bias-vamic2"))
                codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
        else
                codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;
 
-       if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL))
+       if (of_property_read_bool(np, "stericsson,amic1b-bias-vamic2"))
                codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
        else
                codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;
 
-       if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL))
+       if (of_property_read_bool(np, "stericsson,amic2-bias-vamic1"))
                codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
        else
                codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;
@@ -2525,12 +2525,14 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver ab8500_codec_driver = {
        .probe =                ab8500_codec_probe,
-       .controls =             ab8500_ctrls,
-       .num_controls =         ARRAY_SIZE(ab8500_ctrls),
-       .dapm_widgets =         ab8500_dapm_widgets,
-       .num_dapm_widgets =     ARRAY_SIZE(ab8500_dapm_widgets),
-       .dapm_routes =          ab8500_dapm_routes,
-       .num_dapm_routes =      ARRAY_SIZE(ab8500_dapm_routes),
+       .component_driver = {
+               .controls =             ab8500_ctrls,
+               .num_controls =         ARRAY_SIZE(ab8500_ctrls),
+               .dapm_widgets =         ab8500_dapm_widgets,
+               .num_dapm_widgets =     ARRAY_SIZE(ab8500_dapm_widgets),
+               .dapm_routes =          ab8500_dapm_routes,
+               .num_dapm_routes =      ARRAY_SIZE(ab8500_dapm_routes),
+       },
 };
 
 static int ab8500_codec_driver_probe(struct platform_device *pdev)
index 5b3224c6394312cfebe9cf933f40451ee73fdb01..f7f04c6be01e78402e6901fe14ed35fa7754921b 100644 (file)
@@ -117,10 +117,12 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
        .suspend =      ac97_soc_suspend,
        .resume =       ac97_soc_resume,
 
-       .dapm_widgets = ac97_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ac97_widgets),
-       .dapm_routes = ac97_routes,
-       .num_dapm_routes = ARRAY_SIZE(ac97_routes),
+       .component_driver = {
+               .dapm_widgets           = ac97_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ac97_widgets),
+               .dapm_routes            = ac97_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ac97_routes),
+       },
 };
 
 static int ac97_probe(struct platform_device *pdev)
index e2ce6c4d7ece402548102e3f12ad61164e3689ae..a478239aadacca6815167c8d1ea8205f34aa035d 100644 (file)
@@ -327,12 +327,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
        .suspend = ad1836_suspend,
        .resume = ad1836_resume,
 
-       .controls = ad183x_controls,
-       .num_controls = ARRAY_SIZE(ad183x_controls),
-       .dapm_widgets = ad183x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets),
-       .dapm_routes = ad183x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
+       .component_driver = {
+               .controls               = ad183x_controls,
+               .num_controls           = ARRAY_SIZE(ad183x_controls),
+               .dapm_widgets           = ad183x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ad183x_dapm_widgets),
+               .dapm_routes            = ad183x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ad183x_dapm_routes),
+       },
 };
 
 static const struct reg_default ad1836_reg_defaults[] = {
index 3a3f3f2343d75e7ee8b9b29abd3ee6887c1437f4..d643557d89a74d753567ed75821ebb16a0477415 100644 (file)
@@ -410,12 +410,14 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
        .probe = ad193x_codec_probe,
-       .controls = ad193x_snd_controls,
-       .num_controls = ARRAY_SIZE(ad193x_snd_controls),
-       .dapm_widgets = ad193x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
-       .dapm_routes = audio_paths,
-       .num_dapm_routes = ARRAY_SIZE(audio_paths),
+       .component_driver = {
+               .controls               = ad193x_snd_controls,
+               .num_controls           = ARRAY_SIZE(ad193x_snd_controls),
+               .dapm_widgets           = ad193x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ad193x_dapm_widgets),
+               .dapm_routes            = audio_paths,
+               .num_dapm_routes        = ARRAY_SIZE(audio_paths),
+       },
 };
 
 const struct regmap_config ad193x_regmap_config = {
index 9ef20dbccbe31c6fd7f82c58da18117b64187a91..b7c1b9f4bf5f9d070e6daaa656a0059e644aff26 100644 (file)
@@ -299,12 +299,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
        .probe =        ad1980_soc_probe,
        .remove =       ad1980_soc_remove,
 
-       .controls = ad1980_snd_ac97_controls,
-       .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls),
-       .dapm_widgets = ad1980_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets),
-       .dapm_routes = ad1980_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes),
+       .component_driver = {
+               .controls               = ad1980_snd_ac97_controls,
+               .num_controls           = ARRAY_SIZE(ad1980_snd_ac97_controls),
+               .dapm_widgets           = ad1980_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ad1980_dapm_widgets),
+               .dapm_routes            = ad1980_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ad1980_dapm_routes),
+       },
 };
 
 static int ad1980_probe(struct platform_device *pdev)
index a9400aef60b58b28ecb096c0ddb129ca3ba40b83..3e358a49442d2ded0af95b0ba8dccab006912806 100644 (file)
@@ -55,10 +55,12 @@ static struct snd_soc_dai_driver ad73311_dai = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
-       .dapm_widgets = ad73311_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets),
-       .dapm_routes = ad73311_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = ad73311_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ad73311_dapm_widgets),
+               .dapm_routes            = ad73311_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ad73311_dapm_routes),
+       },
 };
 
 static int ad73311_probe(struct platform_device *pdev)
index 1556b360fa1516b2c5048b980274e72d8540a228..8fa9045571ff44f7b9a698197d8d066e42695e64 100644 (file)
@@ -1466,12 +1466,14 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
 
        .set_pll = adau1373_set_pll,
 
-       .controls = adau1373_controls,
-       .num_controls = ARRAY_SIZE(adau1373_controls),
-       .dapm_widgets = adau1373_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
-       .dapm_routes = adau1373_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
+       .component_driver = {
+               .controls               = adau1373_controls,
+               .num_controls           = ARRAY_SIZE(adau1373_controls),
+               .dapm_widgets           = adau1373_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau1373_dapm_widgets),
+               .dapm_routes            = adau1373_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau1373_dapm_routes),
+       },
 };
 
 static int adau1373_i2c_probe(struct i2c_client *client,
index de53c0d7bf101fd449e596fbf40cf8bf89e639c2..3bad1bc8c00a3d93d74c6f419c96f30a479e4afb 100644 (file)
@@ -765,13 +765,14 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
        .set_bias_level         = adau1701_set_bias_level,
        .idle_bias_off          = true,
 
-       .controls               = adau1701_controls,
-       .num_controls           = ARRAY_SIZE(adau1701_controls),
-       .dapm_widgets           = adau1701_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(adau1701_dapm_widgets),
-       .dapm_routes            = adau1701_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(adau1701_dapm_routes),
-
+       .component_driver = {
+               .controls               = adau1701_controls,
+               .num_controls           = ARRAY_SIZE(adau1701_controls),
+               .dapm_widgets           = adau1701_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau1701_dapm_widgets),
+               .dapm_routes            = adau1701_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau1701_dapm_routes),
+       },
        .set_sysclk             = adau1701_set_sysclk,
 };
 
index b95d29dbd13dcfe6fb00722bfc980122e7b74286..3bc3cc559dde0a1430ff671332bae4ca840bf9a9 100644 (file)
@@ -719,12 +719,14 @@ static const struct snd_soc_codec_driver adau1761_codec_driver = {
        .set_bias_level = adau1761_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = adau1761_controls,
-       .num_controls = ARRAY_SIZE(adau1761_controls),
-       .dapm_widgets = adau1x61_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
-       .dapm_routes = adau1x61_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
+       .component_driver = {
+               .controls               = adau1761_controls,
+               .num_controls           = ARRAY_SIZE(adau1761_controls),
+               .dapm_widgets           = adau1x61_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau1x61_dapm_widgets),
+               .dapm_routes            = adau1x61_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau1x61_dapm_routes),
+       },
 };
 
 #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
index bc1bb56dae63cd1101ca6b9e6823af9d1b01a0ba..546071c6c0d09472df2170f514ec277fc6f7293d 100644 (file)
@@ -432,12 +432,14 @@ static const struct snd_soc_codec_driver adau1781_codec_driver = {
        .set_bias_level = adau1781_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = adau1781_controls,
-       .num_controls = ARRAY_SIZE(adau1781_controls),
-       .dapm_widgets = adau1781_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets),
-       .dapm_routes = adau1781_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes),
+       .component_driver = {
+               .controls               = adau1781_controls,
+               .num_controls           = ARRAY_SIZE(adau1781_controls),
+               .dapm_widgets           = adau1781_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau1781_dapm_widgets),
+               .dapm_routes            = adau1781_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau1781_dapm_routes),
+       },
 };
 
 #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
index 9bdd15f408c164e9756f52e2ea041df9a0f65293..b319db6a69f8dd073fe39a25998b0212cb5d94e2 100644 (file)
@@ -873,12 +873,14 @@ static struct snd_soc_codec_driver adau1977_codec_driver = {
        .set_sysclk = adau1977_set_sysclk,
        .idle_bias_off = true,
 
-       .controls = adau1977_snd_controls,
-       .num_controls = ARRAY_SIZE(adau1977_snd_controls),
-       .dapm_widgets = adau1977_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets),
-       .dapm_routes = adau1977_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes),
+       .component_driver = {
+               .controls               = adau1977_snd_controls,
+               .num_controls           = ARRAY_SIZE(adau1977_snd_controls),
+               .dapm_widgets           = adau1977_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau1977_dapm_widgets),
+               .dapm_routes            = adau1977_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau1977_dapm_routes),
+       },
 };
 
 static int adau1977_setup_micbias(struct adau1977 *adau1977)
index 9df72c6adcca9890cf1e9ff6f7d80e0b5a88e9a9..6384c5491de8e53d1fb94aa136cb37b0d916f31d 100644 (file)
@@ -39,10 +39,12 @@ static struct snd_soc_dai_driver adau7002_dai = {
 };
 
 static const struct snd_soc_codec_driver adau7002_codec_driver = {
-       .dapm_widgets = adau7002_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets),
-       .dapm_routes = adau7002_routes,
-       .num_dapm_routes = ARRAY_SIZE(adau7002_routes),
+       .component_driver = {
+               .dapm_widgets           = adau7002_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adau7002_widgets),
+               .dapm_routes            = adau7002_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adau7002_routes),
+       },
 };
 
 static int adau7002_probe(struct platform_device *pdev)
index acff8d62059cf49de24585aeac9c2143412c0175..6e793ebb588333c7ee39ee851ccb6c66ad746ad3 100644 (file)
@@ -834,12 +834,14 @@ static struct snd_soc_codec_driver adav80x_codec_driver = {
        .set_pll = adav80x_set_pll,
        .set_sysclk = adav80x_set_sysclk,
 
-       .controls = adav80x_controls,
-       .num_controls = ARRAY_SIZE(adav80x_controls),
-       .dapm_widgets = adav80x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
-       .dapm_routes = adav80x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
+       .component_driver = {
+               .controls               = adav80x_controls,
+               .num_controls           = ARRAY_SIZE(adav80x_controls),
+               .dapm_widgets           = adav80x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(adav80x_dapm_widgets),
+               .dapm_routes            = adav80x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(adav80x_dapm_routes),
+       },
 };
 
 int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
index c5be1bdc2c9abfbeb61082e118fa2971db1258af..90c756d183b46168204839e56ae117694116a37c 100644 (file)
@@ -59,10 +59,12 @@ static struct snd_soc_dai_driver ads117x_dai = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_ads117x = {
-       .dapm_widgets = ads117x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets),
-       .dapm_routes = ads117x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = ads117x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ads117x_dapm_widgets),
+               .dapm_routes            = ads117x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ads117x_dapm_routes),
+       },
 };
 
 static int ads117x_probe(struct platform_device *pdev)
index 595d02d7602c9f53aff29d6c86e7af1923109360..bdca8793e630029431744c220a8ea66dfe8e1668 100644 (file)
@@ -245,10 +245,12 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
        .suspend = ak4104_soc_suspend,
        .resume = ak4104_soc_resume,
 
-       .dapm_widgets = ak4104_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),
-       .dapm_routes = ak4104_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = ak4104_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4104_dapm_widgets),
+               .dapm_routes            = ak4104_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ak4104_dapm_routes),
+       }
 };
 
 static const struct regmap_config ak4104_regmap = {
index 54428c64387bc0501f96eb6145b52727bf479553..66cfffde9a122e5369fb5f6561e730206cfbd6bd 100644 (file)
@@ -395,12 +395,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
        .set_bias_level = ak4535_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = ak4535_snd_controls,
-       .num_controls = ARRAY_SIZE(ak4535_snd_controls),
-       .dapm_widgets = ak4535_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
-       .dapm_routes = ak4535_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
+       .component_driver = {
+               .controls               = ak4535_snd_controls,
+               .num_controls           = ARRAY_SIZE(ak4535_snd_controls),
+               .dapm_widgets           = ak4535_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4535_dapm_widgets),
+               .dapm_routes            = ak4535_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(ak4535_audio_map),
+       },
 };
 
 static int ak4535_i2c_probe(struct i2c_client *i2c,
index 298dedc051403b9dd8ae309a134e6fb9447893c2..b92c548b9d299048964c63a1daf27351d773f624 100644 (file)
@@ -65,10 +65,12 @@ static struct snd_soc_dai_driver ak4554_dai = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
-       .dapm_widgets = ak4554_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets),
-       .dapm_routes = ak4554_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = ak4554_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4554_dapm_widgets),
+               .dapm_routes            = ak4554_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ak4554_dapm_routes),
+       },
 };
 
 static int ak4554_soc_probe(struct platform_device *pdev)
index 97798d250f08689eff1093979e2ce9bb116f66eb..e819dd8c82fdced146515a9da7c604f783bc2d32 100644 (file)
@@ -458,12 +458,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
        .suspend                = ak4613_suspend,
        .resume                 = ak4613_resume,
        .set_bias_level         = ak4613_set_bias_level,
-       .controls               = ak4613_snd_controls,
-       .num_controls           = ARRAY_SIZE(ak4613_snd_controls),
-       .dapm_widgets           = ak4613_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(ak4613_dapm_widgets),
-       .dapm_routes            = ak4613_intercon,
-       .num_dapm_routes        = ARRAY_SIZE(ak4613_intercon),
+       .component_driver = {
+               .controls               = ak4613_snd_controls,
+               .num_controls           = ARRAY_SIZE(ak4613_snd_controls),
+               .dapm_widgets           = ak4613_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4613_dapm_widgets),
+               .dapm_routes            = ak4613_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(ak4613_intercon),
+       },
 };
 
 static void ak4613_parse_of(struct ak4613_priv *priv,
index b14176f8d884a9f05f72e667b6ac8b52ee4c90e2..c91717d08513594d54faef506ec30fe12967fc73 100644 (file)
@@ -505,12 +505,14 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
-       .controls               = ak4641_snd_controls,
-       .num_controls           = ARRAY_SIZE(ak4641_snd_controls),
-       .dapm_widgets           = ak4641_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(ak4641_dapm_widgets),
-       .dapm_routes            = ak4641_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(ak4641_audio_map),
+       .component_driver = {
+               .controls               = ak4641_snd_controls,
+               .num_controls           = ARRAY_SIZE(ak4641_snd_controls),
+               .dapm_widgets           = ak4641_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4641_dapm_widgets),
+               .dapm_routes            = ak4641_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(ak4641_audio_map),
+       },
        .set_bias_level         = ak4641_set_bias_level,
        .suspend_bias_off       = true,
 };
index cc941d66ec3d2f4d1d75104f46c1329ebb9abb8a..2609f95b7d197946c5449610c28287920f6b6c10 100644 (file)
@@ -555,12 +555,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
        .suspend                = ak4642_suspend,
        .resume                 = ak4642_resume,
        .set_bias_level         = ak4642_set_bias_level,
-       .controls               = ak4642_snd_controls,
-       .num_controls           = ARRAY_SIZE(ak4642_snd_controls),
-       .dapm_widgets           = ak4642_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
-       .dapm_routes            = ak4642_intercon,
-       .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
+       .component_driver = {
+               .controls               = ak4642_snd_controls,
+               .num_controls           = ARRAY_SIZE(ak4642_snd_controls),
+               .dapm_widgets           = ak4642_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
+               .dapm_routes            = ak4642_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
+       },
 };
 
 static const struct regmap_config ak4642_regmap = {
index c73a9f6914b63e03e369b537df6a4a9f3c4068ae..6088afaabf62c56d63a0fea375761e4a247477b0 100644 (file)
@@ -612,12 +612,14 @@ static struct snd_soc_dai_driver ak4671_dai = {
 
 static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
        .set_bias_level = ak4671_set_bias_level,
-       .controls = ak4671_snd_controls,
-       .num_controls = ARRAY_SIZE(ak4671_snd_controls),
-       .dapm_widgets = ak4671_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
-       .dapm_routes = ak4671_intercon,
-       .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
+       .component_driver = {
+               .controls               = ak4671_snd_controls,
+               .num_controls           = ARRAY_SIZE(ak4671_snd_controls),
+               .dapm_widgets           = ak4671_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak4671_dapm_widgets),
+               .dapm_routes            = ak4671_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(ak4671_intercon),
+       },
 };
 
 static const struct regmap_config ak4671_regmap = {
index afa95360826d5f5da2703c18899140da63739b03..0ef2df223336700ec1b55c70eb073b0960e2a18d 100644 (file)
@@ -74,10 +74,12 @@ static struct snd_soc_codec_driver soc_codec_ak5386 = {
        .remove = ak5386_soc_remove,
        .suspend = ak5386_soc_suspend,
        .resume = ak5386_soc_resume,
-       .dapm_widgets = ak5386_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets),
-       .dapm_routes = ak5386_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = ak5386_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ak5386_dapm_widgets),
+               .dapm_routes            = ak5386_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ak5386_dapm_routes),
+       },
 };
 
 static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
index 4d3ba33eb6f928dc32146645b195d528592711c5..adb80d8719bdd813ec850583ee10ce68880a153b 100644 (file)
@@ -1072,12 +1072,14 @@ static const struct snd_soc_codec_driver soc_codec_device_alc5632 = {
        .set_bias_level = alc5632_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = alc5632_snd_controls,
-       .num_controls = ARRAY_SIZE(alc5632_snd_controls),
-       .dapm_widgets = alc5632_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
-       .dapm_routes = alc5632_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
+       .component_driver = {
+               .controls               = alc5632_snd_controls,
+               .num_controls           = ARRAY_SIZE(alc5632_snd_controls),
+               .dapm_widgets           = alc5632_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(alc5632_dapm_widgets),
+               .dapm_routes            = alc5632_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(alc5632_dapm_routes),
+       },
 };
 
 static const struct regmap_config alc5632_regmap = {
index ecfdbfcae366cf5840e40b1c847d9bc6d56ba4e4..ded235f3090fcb4e0ca2fae0da0911768ba9d885 100644 (file)
@@ -1920,8 +1920,8 @@ static struct {
 
 struct arizona_fll_cfg {
        int n;
-       int theta;
-       int lambda;
+       unsigned int theta;
+       unsigned int lambda;
        int refdiv;
        int outdiv;
        int fratio;
@@ -2218,11 +2218,11 @@ static int arizona_enable_fll(struct arizona_fll *fll)
 
        if (already_enabled) {
                /* Facilitate smooth refclk across the transition */
-               regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
-                                        ARIZONA_FLL1_GAIN_MASK, 0);
                regmap_update_bits(fll->arizona->regmap, fll->base + 1,
                                   ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
                udelay(32);
+               regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
+                                        ARIZONA_FLL1_GAIN_MASK, 0);
        }
 
        /*
@@ -2233,6 +2233,10 @@ static int arizona_enable_fll(struct arizona_fll *fll)
            fll->ref_src != fll->sync_src) {
                arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
 
+               /* Ref path hardcodes lambda to 65536 when sync is on */
+               if (fll->sync_src >= 0 && cfg.lambda)
+                       cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
+
                arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
                                  false);
                if (fll->sync_src >= 0) {
@@ -2268,7 +2272,7 @@ static int arizona_enable_fll(struct arizona_fll *fll)
                                         ARIZONA_FLL1_SYNC_BW);
 
        if (!already_enabled)
-               pm_runtime_get(arizona->dev);
+               pm_runtime_get_sync(arizona->dev);
 
        regmap_update_bits_async(arizona->regmap, fll->base + 1,
                                 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
index 2a8d0ee141d414228bb8cc1d67994416b0a7cd25..8014e697d5407d0b43f3bf03089a349c31e0b03a 100644 (file)
@@ -63,10 +63,12 @@ static struct snd_soc_dai_driver bt_sco_dai[] = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
-       .dapm_widgets = bt_sco_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets),
-       .dapm_routes = bt_sco_routes,
-       .num_dapm_routes = ARRAY_SIZE(bt_sco_routes),
+       .component_driver = {
+               .dapm_widgets           = bt_sco_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(bt_sco_widgets),
+               .dapm_routes            = bt_sco_routes,
+               .num_dapm_routes        = ARRAY_SIZE(bt_sco_routes),
+       },
 };
 
 static int bt_sco_probe(struct platform_device *pdev)
index 287d13740be4e08bbbf7ce29526a97c4eed7b814..7e9806206648c0eafc9a11ca468027ff3b67a0c0 100644 (file)
@@ -231,13 +231,14 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
 static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
        .set_sysclk = cs35l32_codec_set_sysclk,
 
-       .dapm_widgets = cs35l32_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets),
-       .dapm_routes = cs35l32_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map),
-
-       .controls = cs35l32_snd_controls,
-       .num_controls = ARRAY_SIZE(cs35l32_snd_controls),
+       .component_driver = {
+               .controls               = cs35l32_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs35l32_snd_controls),
+               .dapm_widgets           = cs35l32_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs35l32_dapm_widgets),
+               .dapm_routes            = cs35l32_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs35l32_audio_map),
+       },
 };
 
 /* Current and threshold powerup sequence Pg37 in datasheet */
index 6f9c1addcd7fa4e928b959c19e4bf940bebce586..6df29fa30fb9d8d17216026b925fb8df1ba7dc3c 100644 (file)
@@ -837,13 +837,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
        .set_bias_level = cs35l33_set_bias_level,
        .set_sysclk = cs35l33_codec_set_sysclk,
 
-       .dapm_widgets = cs35l33_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets),
-       .dapm_routes = cs35l33_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map),
-       .controls = cs35l33_snd_controls,
-       .num_controls = ARRAY_SIZE(cs35l33_snd_controls),
-
+       .component_driver = {
+               .controls               = cs35l33_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs35l33_snd_controls),
+               .dapm_widgets           = cs35l33_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs35l33_dapm_widgets),
+               .dapm_routes            = cs35l33_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs35l33_audio_map),
+       },
        .idle_bias_off = true,
 };
 
index 55db19ddc5ff34a7fa1134488d972d7bc2ceeae8..fd966bb851cbcb0c2dcd8b5a3713c26b5e6ec7c8 100644 (file)
@@ -547,13 +547,14 @@ static struct snd_soc_dai_driver cs4265_dai[] = {
 static const struct snd_soc_codec_driver soc_codec_cs4265 = {
        .set_bias_level = cs4265_set_bias_level,
 
-       .dapm_widgets = cs4265_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets),
-       .dapm_routes = cs4265_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map),
-
-       .controls = cs4265_snd_controls,
-       .num_controls = ARRAY_SIZE(cs4265_snd_controls),
+       .component_driver = {
+               .controls               = cs4265_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs4265_snd_controls),
+               .dapm_widgets           = cs4265_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs4265_dapm_widgets),
+               .dapm_routes            = cs4265_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs4265_audio_map),
+       },
 };
 
 static const struct regmap_config cs4265_regmap = {
index e07807d96b68069b10c0e1319359b8ed52905ecc..18baea2f7d654528cf52617bfb0c58fc2e3b8efe 100644 (file)
@@ -617,12 +617,14 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
        .suspend =              cs4270_soc_suspend,
        .resume =               cs4270_soc_resume,
 
-       .controls =             cs4270_snd_controls,
-       .num_controls =         ARRAY_SIZE(cs4270_snd_controls),
-       .dapm_widgets =         cs4270_dapm_widgets,
-       .num_dapm_widgets =     ARRAY_SIZE(cs4270_dapm_widgets),
-       .dapm_routes =          cs4270_dapm_routes,
-       .num_dapm_routes =      ARRAY_SIZE(cs4270_dapm_routes),
+       .component_driver = {
+               .controls =             cs4270_snd_controls,
+               .num_controls =         ARRAY_SIZE(cs4270_snd_controls),
+               .dapm_widgets =         cs4270_dapm_widgets,
+               .num_dapm_widgets =     ARRAY_SIZE(cs4270_dapm_widgets),
+               .dapm_routes =          cs4270_dapm_routes,
+               .num_dapm_routes =      ARRAY_SIZE(cs4270_dapm_routes),
+       },
 };
 
 /*
index 0c0010b254213f11ff19783b0ebafbd3bd37b491..8c0f3b89b5bc8a37178f6b630fc20560af742b2a 100644 (file)
@@ -645,12 +645,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
        .suspend                = cs4271_soc_suspend,
        .resume                 = cs4271_soc_resume,
 
-       .controls               = cs4271_snd_controls,
-       .num_controls           = ARRAY_SIZE(cs4271_snd_controls),
-       .dapm_widgets           = cs4271_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(cs4271_dapm_widgets),
-       .dapm_routes            = cs4271_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(cs4271_dapm_routes),
+       .component_driver = {
+               .controls               = cs4271_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs4271_snd_controls),
+               .dapm_widgets           = cs4271_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs4271_dapm_widgets),
+               .dapm_routes            = cs4271_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs4271_dapm_routes),
+       },
 };
 
 static int cs4271_common_probe(struct device *dev,
index 35488f14e2378ada271328a97504a9558b746836..96cfe38943cd44aa29885c76fbe48b4b8391d9a3 100644 (file)
@@ -507,12 +507,14 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
        .probe = cs42l51_codec_probe,
 
-       .controls = cs42l51_snd_controls,
-       .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
-       .dapm_widgets = cs42l51_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets),
-       .dapm_routes = cs42l51_routes,
-       .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
+       .component_driver = {
+               .controls               = cs42l51_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs42l51_snd_controls),
+               .dapm_widgets           = cs42l51_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs42l51_dapm_widgets),
+               .dapm_routes            = cs42l51_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs42l51_routes),
+       },
 };
 
 const struct regmap_config cs42l51_regmap = {
index 47b97fcefb0ba76818d6c01bcb0e24a8afa02c31..0d9c4a57301bb4a150c34d0f4e29384cd55915f5 100644 (file)
@@ -1056,13 +1056,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
        .set_bias_level = cs42l52_set_bias_level,
        .suspend_bias_off = true,
 
-       .dapm_widgets = cs42l52_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets),
-       .dapm_routes = cs42l52_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map),
-
-       .controls = cs42l52_snd_controls,
-       .num_controls = ARRAY_SIZE(cs42l52_snd_controls),
+       .component_driver = {
+               .controls               = cs42l52_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs42l52_snd_controls),
+               .dapm_widgets           = cs42l52_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs42l52_dapm_widgets),
+               .dapm_routes            = cs42l52_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs42l52_audio_map),
+       },
 };
 
 /* Current and threshold powerup sequence Pg37 */
index eec1ff853b98bdc1ca7c2390a9cd50ec44edbf2c..54c1768bc81859f5f2a66cc7388ac272879c236a 100644 (file)
@@ -1121,13 +1121,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
        .set_bias_level = cs42l56_set_bias_level,
        .suspend_bias_off = true,
 
-       .dapm_widgets = cs42l56_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets),
-       .dapm_routes = cs42l56_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map),
-
-       .controls = cs42l56_snd_controls,
-       .num_controls = ARRAY_SIZE(cs42l56_snd_controls),
+       .component_driver = {
+               .controls               = cs42l56_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs42l56_snd_controls),
+               .dapm_widgets           = cs42l56_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs42l56_dapm_widgets),
+               .dapm_routes            = cs42l56_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs42l56_audio_map),
+       },
 };
 
 static const struct regmap_config cs42l56_regmap = {
index 42a8fd4e1f9b3f284d6dcc01dc67cf6475d5a192..71ba5605495fc15c5fc267fc1daa9b2631569e10 100644 (file)
@@ -794,7 +794,7 @@ struct cs42l73_mclk_div {
        u8 mmcc;
 };
 
-static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
+static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
        /* MCLK, Sample Rate, xMMCC[5:0] */
        {5644800, 11025, 0x30},
        {5644800, 22050, 0x20},
@@ -844,7 +844,7 @@ struct cs42l73_mclkx_div {
        u8 mclkdiv;
 };
 
-static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
+static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
        {5644800,  1, 0},       /* 5644800 */
        {6000000,  1, 0},       /* 6000000 */
        {6144000,  1, 0},       /* 6144000 */
@@ -1257,13 +1257,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
        .set_bias_level = cs42l73_set_bias_level,
        .suspend_bias_off = true,
 
-       .dapm_widgets = cs42l73_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
-       .dapm_routes = cs42l73_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map),
-
-       .controls = cs42l73_snd_controls,
-       .num_controls = ARRAY_SIZE(cs42l73_snd_controls),
+       .component_driver = {
+               .controls               = cs42l73_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs42l73_snd_controls),
+               .dapm_widgets           = cs42l73_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs42l73_dapm_widgets),
+               .dapm_routes            = cs42l73_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cs42l73_audio_map),
+       },
 };
 
 static const struct regmap_config cs42l73_regmap = {
index 1179101b2b055a639e711049dc389d34e999a011..b4d87379d2bcba6ae490bce1198edda6f57f5f20 100644 (file)
@@ -411,12 +411,14 @@ static const struct snd_soc_codec_driver cs42xx8_driver = {
        .probe = cs42xx8_codec_probe,
        .idle_bias_off = true,
 
-       .controls = cs42xx8_snd_controls,
-       .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
-       .dapm_widgets = cs42xx8_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
-       .dapm_routes = cs42xx8_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
+       .component_driver = {
+               .controls               = cs42xx8_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs42xx8_snd_controls),
+               .dapm_widgets           = cs42xx8_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs42xx8_dapm_widgets),
+               .dapm_routes            = cs42xx8_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs42xx8_dapm_routes),
+       },
 };
 
 const struct cs42xx8_driver_data cs42448_data = {
index 0ac8fc5ed4ae4ac23940d19fce9079a52b0f0976..231ca935cdf3bdf22e7db0866a0dabfa61084e1e 100644 (file)
@@ -256,13 +256,14 @@ static struct snd_soc_dai_driver cs4349_dai = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
-       .controls               = cs4349_snd_controls,
-       .num_controls           = ARRAY_SIZE(cs4349_snd_controls),
-
-       .dapm_widgets           = cs4349_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(cs4349_dapm_widgets),
-       .dapm_routes            = cs4349_routes,
-       .num_dapm_routes        = ARRAY_SIZE(cs4349_routes),
+       .component_driver = {
+               .controls               = cs4349_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs4349_snd_controls),
+               .dapm_widgets           = cs4349_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs4349_dapm_widgets),
+               .dapm_routes            = cs4349_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs4349_routes),
+       },
 };
 
 static const struct regmap_config cs4349_regmap = {
index 954a4f5d3338c5c96b137296e16e10042e67795f..257b15233b7e3e7e76a25a3862e3eb08e7cc953c 100644 (file)
@@ -746,6 +746,16 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
        { "IN2L", NULL, "SYSCLK" },
        { "IN2R", NULL, "SYSCLK" },
 
+       { "ASRC1L", NULL, "SYSCLK" },
+       { "ASRC1R", NULL, "SYSCLK" },
+       { "ASRC2L", NULL, "SYSCLK" },
+       { "ASRC2R", NULL, "SYSCLK" },
+
+       { "ASRC1L", NULL, "ASYNCCLK" },
+       { "ASRC1R", NULL, "ASYNCCLK" },
+       { "ASRC2L", NULL, "ASYNCCLK" },
+       { "ASRC2R", NULL, "ASYNCCLK" },
+
        { "MICBIAS1", NULL, "MICVDD" },
        { "MICBIAS2", NULL, "MICVDD" },
 
@@ -1190,12 +1200,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
        .set_sysclk = arizona_set_sysclk,
        .set_pll = cs47l24_set_fll,
 
-       .controls = cs47l24_snd_controls,
-       .num_controls = ARRAY_SIZE(cs47l24_snd_controls),
-       .dapm_widgets = cs47l24_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets),
-       .dapm_routes = cs47l24_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
+       .component_driver = {
+               .controls               = cs47l24_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs47l24_snd_controls),
+               .dapm_widgets           = cs47l24_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs47l24_dapm_widgets),
+               .dapm_routes            = cs47l24_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs47l24_dapm_routes),
+       },
 };
 
 static struct snd_compr_ops cs47l24_compr_ops = {
index 2c0d9c430a8ca3d7cef2600b062a95ceb923a4e1..cb47fb595ff412fd6a4a80aaf5a7d1e7f67f3ca6 100644 (file)
@@ -466,7 +466,7 @@ struct cs53l30_mclk_div {
        u8 mclk_int_scale;
 };
 
-static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
+static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
        /* NOTE: Enable MCLK_INT_SCALE to save power. */
 
        /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */
@@ -511,7 +511,7 @@ struct cs53l30_mclkx_div {
        u8 mclkdiv;
 };
 
-static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
+static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
        {5644800,  1, CS53L30_MCLK_DIV_BY_1},
        {6000000,  1, CS53L30_MCLK_DIV_BY_1},
        {6144000,  1, CS53L30_MCLK_DIV_BY_1},
@@ -897,13 +897,14 @@ static struct snd_soc_codec_driver cs53l30_driver = {
        .set_bias_level = cs53l30_set_bias_level,
        .idle_bias_off = true,
 
-       .dapm_widgets = cs53l30_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets),
-       .dapm_routes = cs53l30_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes),
-
-       .controls = cs53l30_snd_controls,
-       .num_controls = ARRAY_SIZE(cs53l30_snd_controls),
+       .component_driver = {
+               .controls               = cs53l30_snd_controls,
+               .num_controls           = ARRAY_SIZE(cs53l30_snd_controls),
+               .dapm_widgets           = cs53l30_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cs53l30_dapm_widgets),
+               .dapm_routes            = cs53l30_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(cs53l30_dapm_routes),
+       },
 };
 
 static struct regmap_config cs53l30_regmap = {
@@ -999,8 +1000,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
        /* Check if MCLK provided */
        cs53l30->mclk = devm_clk_get(dev, "mclk");
        if (IS_ERR(cs53l30->mclk)) {
-               if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) {
-                       ret = -EPROBE_DEFER;
+               if (PTR_ERR(cs53l30->mclk) != -ENOENT) {
+                       ret = PTR_ERR(cs53l30->mclk);
                        goto error;
                }
                /* Otherwise mark the mclk pointer to NULL */
index fb3885fe0afb75a872a8d08f7d6fb931555e2446..2c12471e42a68dd7ed865cd581a1f27728da85ee 100644 (file)
@@ -407,10 +407,12 @@ static struct snd_soc_codec_driver cx20442_codec_dev = {
        .reg_word_size = sizeof(u8),
        .read = cx20442_read_reg_cache,
        .write = cx20442_write,
-       .dapm_widgets = cx20442_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
-       .dapm_routes = cx20442_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
+       .component_driver = {
+               .dapm_widgets           = cx20442_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(cx20442_dapm_widgets),
+               .dapm_routes            = cx20442_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(cx20442_audio_map),
+       },
 };
 
 static int cx20442_platform_probe(struct platform_device *pdev)
index af23a61b7b283aacd7a8950b5b42cd440151d843..17053dfc94cf07cafea279351d8382db829add1b 100644 (file)
@@ -1167,13 +1167,14 @@ static int da7210_probe(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
        .probe                  = da7210_probe,
 
-       .controls               = da7210_snd_controls,
-       .num_controls           = ARRAY_SIZE(da7210_snd_controls),
-
-       .dapm_widgets           = da7210_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da7210_dapm_widgets),
-       .dapm_routes            = da7210_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(da7210_audio_map),
+       .component_driver = {
+               .controls               = da7210_snd_controls,
+               .num_controls           = ARRAY_SIZE(da7210_snd_controls),
+               .dapm_widgets           = da7210_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da7210_dapm_widgets),
+               .dapm_routes            = da7210_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(da7210_audio_map),
+       },
 };
 
 #if IS_ENABLED(CONFIG_I2C)
index bcf1834c564812a6af86d547eb880cd93e83214e..12da55882c06b6c075878b7cee0d1a38da5efffb 100644 (file)
@@ -750,11 +750,18 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
                snd_soc_update_bits(codec, DA7213_PC_COUNT,
                                    DA7213_PC_FREERUN_MASK, 0);
 
-               /* Slave mode, if SRM not enabled no need for status checks */
+               /* If SRM not enabled then nothing more to do */
                pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
                if (!(pll_ctrl & DA7213_PLL_SRM_EN))
                        return 0;
 
+               /* Assist 32KHz mode PLL lock */
+               if (pll_ctrl & DA7213_PLL_32K_MODE) {
+                       snd_soc_write(codec, 0xF0, 0x8B);
+                       snd_soc_write(codec, 0xF2, 0x03);
+                       snd_soc_write(codec, 0xF0, 0x00);
+               }
+
                /* Check SRM has locked */
                do {
                        pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
@@ -771,6 +778,14 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
 
                return 0;
        case SND_SOC_DAPM_POST_PMD:
+               /* Revert 32KHz PLL lock udpates if applied previously */
+               pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
+               if (pll_ctrl & DA7213_PLL_32K_MODE) {
+                       snd_soc_write(codec, 0xF0, 0x8B);
+                       snd_soc_write(codec, 0xF2, 0x01);
+                       snd_soc_write(codec, 0xF0, 0x00);
+               }
+
                /* PC free-running */
                snd_soc_update_bits(codec, DA7213_PC_COUNT,
                                    DA7213_PC_FREERUN_MASK,
@@ -1297,10 +1312,13 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
        switch (clk_id) {
        case DA7213_CLKSRC_MCLK:
-               da7213->mclk_squarer_en = false;
+               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+                                   DA7213_PLL_MCLK_SQR_EN, 0);
                break;
        case DA7213_CLKSRC_MCLK_SQR:
-               da7213->mclk_squarer_en = true;
+               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+                                   DA7213_PLL_MCLK_SQR_EN,
+                                   DA7213_PLL_MCLK_SQR_EN);
                break;
        default:
                dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
@@ -1324,7 +1342,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-/* Supported PLL input frequencies are 5MHz - 54MHz. */
+/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
 static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
@@ -1336,22 +1354,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        u32 freq_ref;
        u64 frac_div;
 
-       /* Reset PLL configuration */
-       snd_soc_write(codec, DA7213_PLL_CTRL, 0);
-
-       pll_ctrl = 0;
-
        /* Workout input divider based on MCLK rate */
        if (da7213->mclk_rate == 32768) {
+               if (!da7213->master) {
+                       dev_err(codec->dev,
+                               "32KHz only valid if codec is clock master\n");
+                       return -EINVAL;
+               }
+
                /* 32KHz PLL Mode */
                indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ;
                indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
+               source = DA7213_SYSCLK_PLL_32KHZ;
                freq_ref = 3750000;
-               pll_ctrl |= DA7213_PLL_32K_MODE;
+
        } else {
-               /* 5 - 54MHz MCLK */
                if (da7213->mclk_rate < 5000000) {
-                       goto pll_err;
+                       dev_err(codec->dev,
+                               "PLL input clock %d below valid range\n",
+                               da7213->mclk_rate);
+                       return -EINVAL;
                } else if (da7213->mclk_rate <= 9000000) {
                        indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ;
                        indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL;
@@ -1365,32 +1387,44 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                        indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
                        indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
                } else {
-                       goto pll_err;
+                       dev_err(codec->dev,
+                               "PLL input clock %d above valid range\n",
+                               da7213->mclk_rate);
+                       return -EINVAL;
                }
                freq_ref = (da7213->mclk_rate / indiv);
        }
 
-       pll_ctrl |= indiv_bits;
+       pll_ctrl = indiv_bits;
 
-       /* PLL Bypass mode */
-       if (source == DA7213_SYSCLK_MCLK) {
-               snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
+       /* Configure PLL */
+       switch (source) {
+       case DA7213_SYSCLK_MCLK:
+               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+                                   DA7213_PLL_INDIV_MASK |
+                                   DA7213_PLL_MODE_MASK, pll_ctrl);
                return 0;
-       }
+       case DA7213_SYSCLK_PLL:
+               break;
+       case DA7213_SYSCLK_PLL_SRM:
+               pll_ctrl |= DA7213_PLL_SRM_EN;
+               fout = DA7213_PLL_FREQ_OUT_94310400;
+               break;
+       case DA7213_SYSCLK_PLL_32KHZ:
+               if (da7213->mclk_rate != 32768) {
+                       dev_err(codec->dev,
+                               "32KHz mode only valid with 32KHz MCLK\n");
+                       return -EINVAL;
+               }
 
-       /*
-        * If Codec is slave and SRM enabled,
-        * freq_out is (98304000 + 90316800)/2 = 94310400
-        */
-       if (!da7213->master && da7213->srm_en) {
+               pll_ctrl |= DA7213_PLL_32K_MODE | DA7213_PLL_SRM_EN;
                fout = DA7213_PLL_FREQ_OUT_94310400;
-               pll_ctrl |= DA7213_PLL_SRM_EN;
+               break;
+       default:
+               dev_err(codec->dev, "Invalid PLL config\n");
+               return -EINVAL;
        }
 
-       /* Enable MCLK squarer if required */
-       if (da7213->mclk_squarer_en)
-               pll_ctrl |= DA7213_PLL_MCLK_SQR_EN;
-
        /* Calculate dividers for PLL */
        pll_integer = fout / freq_ref;
        frac_div = (u64)(fout % freq_ref) * 8192ULL;
@@ -1405,14 +1439,19 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
        /* Enable PLL */
        pll_ctrl |= DA7213_PLL_EN;
-       snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
+       snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+                           DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK,
+                           pll_ctrl);
+
+       /* Assist 32KHz mode PLL lock */
+       if (source == DA7213_SYSCLK_PLL_32KHZ) {
+               snd_soc_write(codec, 0xF0, 0x8B);
+               snd_soc_write(codec, 0xF1, 0x03);
+               snd_soc_write(codec, 0xF1, 0x01);
+               snd_soc_write(codec, 0xF0, 0x00);
+       }
 
        return 0;
-
-pll_err:
-       dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n",
-               da7213->mclk_rate);
-       return -EINVAL;
 }
 
 /* DAI operations */
@@ -1454,11 +1493,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-       case SND_SOC_BIAS_PREPARE:
                break;
-       case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       /* MCLK */
+       case SND_SOC_BIAS_PREPARE:
+               /* Enable MCLK for transition to ON state */
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
                        if (da7213->mclk) {
                                ret = clk_prepare_enable(da7213->mclk);
                                if (ret) {
@@ -1467,21 +1505,24 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
                                        return ret;
                                }
                        }
-
+               }
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
                        /* Enable VMID reference & master bias */
                        snd_soc_update_bits(codec, DA7213_REFERENCES,
                                            DA7213_VMID_EN | DA7213_BIAS_EN,
                                            DA7213_VMID_EN | DA7213_BIAS_EN);
+               } else {
+                       /* Remove MCLK */
+                       if (da7213->mclk)
+                               clk_disable_unprepare(da7213->mclk);
                }
                break;
        case SND_SOC_BIAS_OFF:
                /* Disable VMID reference & master bias */
                snd_soc_update_bits(codec, DA7213_REFERENCES,
                                    DA7213_VMID_EN | DA7213_BIAS_EN, 0);
-
-               /* MCLK */
-               if (da7213->mclk)
-                       clk_disable_unprepare(da7213->mclk);
                break;
        }
        return 0;
@@ -1605,9 +1646,6 @@ static int da7213_probe(struct snd_soc_codec *codec)
                            DA7213_ALC_CALIB_MODE_MAN, 0);
        da7213->alc_calib_auto = true;
 
-       /* Default to using SRM for slave mode */
-       da7213->srm_en = true;
-
        /* Default PC counter to free-running */
        snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
                            DA7213_PC_FREERUN_MASK);
@@ -1740,13 +1778,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7213 = {
        .probe                  = da7213_probe,
        .set_bias_level         = da7213_set_bias_level,
 
-       .controls               = da7213_snd_controls,
-       .num_controls           = ARRAY_SIZE(da7213_snd_controls),
-
-       .dapm_widgets           = da7213_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da7213_dapm_widgets),
-       .dapm_routes            = da7213_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(da7213_audio_map),
+       .component_driver = {
+               .controls               = da7213_snd_controls,
+               .num_controls           = ARRAY_SIZE(da7213_snd_controls),
+               .dapm_widgets           = da7213_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da7213_dapm_widgets),
+               .dapm_routes            = da7213_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(da7213_audio_map),
+       },
 };
 
 static const struct regmap_config da7213_regmap_config = {
index fbb7a356a5016d95c65f5fb8675751b40ac725ff..16ef56f77cd48c36e1dbab0a862652f44faecb52 100644 (file)
 #define DA7213_PLL_32K_MODE                                    (0x1 << 5)
 #define DA7213_PLL_SRM_EN                                      (0x1 << 6)
 #define DA7213_PLL_EN                                          (0x1 << 7)
+#define DA7213_PLL_MODE_MASK                                   (0x7 << 5)
 
 /* DA7213_DAI_CLK_MODE = 0x28 */
 #define DA7213_DAI_BCLKS_PER_WCLK_32                           (0x0 << 0)
 #define DA7213_ALC_AVG_ITERATIONS      5
 
 /* PLL related */
-#define DA7213_SYSCLK_MCLK                     0
-#define DA7213_SYSCLK_PLL                      1
 #define DA7213_PLL_FREQ_OUT_90316800           90316800
 #define DA7213_PLL_FREQ_OUT_98304000           98304000
 #define DA7213_PLL_FREQ_OUT_94310400           94310400
@@ -515,6 +514,13 @@ enum da7213_clk_src {
        DA7213_CLKSRC_MCLK_SQR,
 };
 
+enum da7213_sys_clk {
+       DA7213_SYSCLK_MCLK = 0,
+       DA7213_SYSCLK_PLL,
+       DA7213_SYSCLK_PLL_SRM,
+       DA7213_SYSCLK_PLL_32KHZ
+};
+
 /* Codec private data */
 struct da7213_priv {
        struct regmap *regmap;
@@ -522,8 +528,6 @@ struct da7213_priv {
        unsigned int mclk_rate;
        int clk_src;
        bool master;
-       bool mclk_squarer_en;
-       bool srm_en;
        bool alc_calib_auto;
        bool alc_en;
        struct da7213_platform_data *pdata;
index 99ce23e113bf74804e671642e5d836a8ea273157..c69e97654fc63e7b9f9a06776daeaba199a8b952 100644 (file)
@@ -1819,7 +1819,7 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        if (da7218->mclk_rate == freq)
                return 0;
 
-       if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
+       if ((freq < 2000000) || (freq > 54000000)) {
                dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
                        freq);
                return -EINVAL;
@@ -1866,11 +1866,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        u32 freq_ref;
        u64 frac_div;
 
-       /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
-       if (da7218->mclk_rate == 32768) {
-               indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;
-               indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;
-       } else if (da7218->mclk_rate < 2000000) {
+       /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
+       if (da7218->mclk_rate < 2000000) {
                dev_err(codec->dev, "PLL input clock %d below valid range\n",
                        da7218->mclk_rate);
                return -EINVAL;
@@ -1911,9 +1908,6 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        case DA7218_SYSCLK_PLL_SRM:
                pll_ctrl |= DA7218_PLL_MODE_SRM;
                break;
-       case DA7218_SYSCLK_PLL_32KHZ:
-               pll_ctrl |= DA7218_PLL_MODE_32KHZ;
-               break;
        default:
                dev_err(codec->dev, "Invalid PLL config\n");
                return -EINVAL;
@@ -2589,20 +2583,22 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-       case SND_SOC_BIAS_PREPARE:
                break;
-       case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       /* MCLK */
+       case SND_SOC_BIAS_PREPARE:
+               /* Enable MCLK for transition to ON state */
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
                        if (da7218->mclk) {
                                ret = clk_prepare_enable(da7218->mclk);
                                if (ret) {
-                                       dev_err(codec->dev,
-                                               "Failed to enable mclk\n");
+                                       dev_err(codec->dev, "Failed to enable mclk\n");
                                        return ret;
                                }
                        }
+               }
 
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
                        /* Master bias */
                        snd_soc_update_bits(codec, DA7218_REFERENCES,
                                            DA7218_BIAS_EN_MASK,
@@ -2612,6 +2608,10 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
                        snd_soc_update_bits(codec, DA7218_LDO_CTRL,
                                            DA7218_LDO_EN_MASK,
                                            DA7218_LDO_EN_MASK);
+               } else {
+                       /* Remove MCLK */
+                       if (da7218->mclk)
+                               clk_disable_unprepare(da7218->mclk);
                }
                break;
        case SND_SOC_BIAS_OFF:
@@ -2625,10 +2625,6 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
                        snd_soc_update_bits(codec, DA7218_REFERENCES,
                                            DA7218_BIAS_EN_MASK, 0);
                }
-
-               /* MCLK */
-               if (da7218->mclk)
-                       clk_disable_unprepare(da7218->mclk);
                break;
        }
 
@@ -3045,13 +3041,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7218 = {
        .resume                 = da7218_resume,
        .set_bias_level         = da7218_set_bias_level,
 
-       .controls               = da7218_snd_controls,
-       .num_controls           = ARRAY_SIZE(da7218_snd_controls),
-
-       .dapm_widgets           = da7218_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da7218_dapm_widgets),
-       .dapm_routes            = da7218_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(da7218_audio_map),
+       .component_driver = {
+               .controls               = da7218_snd_controls,
+               .num_controls           = ARRAY_SIZE(da7218_snd_controls),
+               .dapm_widgets           = da7218_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da7218_dapm_widgets),
+               .dapm_routes            = da7218_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(da7218_audio_map),
+       },
 };
 
 
index 477cd37723cfd90a28cd0461e8f8ff277db58ef0..4f7ec21069a48d098b0ff8dceb0ddc2db0614dd5 100644 (file)
 #define DA7218_PLL_MODE_BYPASS         (0x0 << 6)
 #define DA7218_PLL_MODE_NORMAL         (0x1 << 6)
 #define DA7218_PLL_MODE_SRM            (0x2 << 6)
-#define DA7218_PLL_MODE_32KHZ          (0x3 << 6)
 
 /* DA7218_PLL_FRAC_TOP = 0x92 */
 #define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT        0
@@ -1371,7 +1370,6 @@ enum da7218_sys_clk {
        DA7218_SYSCLK_MCLK = 0,
        DA7218_SYSCLK_PLL,
        DA7218_SYSCLK_PLL_SRM,
-       DA7218_SYSCLK_PLL_32KHZ
 };
 
 enum da7218_dev_id {
index f0057cd223a4e2dfa23e2acd23d6154cd9ec993f..4e369a1c5d88707eee3011d59aa406339e27bd1f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 #include <linux/i2c.h>
 #include <linux/property.h>
 #include <linux/pm_wakeirq.h>
@@ -115,12 +116,23 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 
        u16 tonegen_freq_hptest;
        u8 accdet_cfg8;
-       int report = 0;
+       int report = 0, ret = 0;
 
        /* Lock DAPM and any Kcontrols that are affected by this test */
        snd_soc_dapm_mutex_lock(dapm);
        mutex_lock(&da7219->lock);
 
+       /* Ensure MCLK is available for HP test procedure */
+       if (da7219->mclk) {
+               ret = clk_prepare_enable(da7219->mclk);
+               if (ret) {
+                       dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
+                       mutex_unlock(&da7219->lock);
+                       snd_soc_dapm_mutex_unlock(dapm);
+                       return;
+               }
+       }
+
        /* Bypass cache so it saves current settings */
        regcache_cache_bypass(da7219->regmap, true);
 
@@ -250,6 +262,10 @@ static void da7219_aad_hptest_work(struct work_struct *work)
        snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
                            DA7219_HP_R_AMP_OE_MASK);
 
+       /* Remove MCLK, if previously enabled */
+       if (da7219->mclk)
+               clk_disable_unprepare(da7219->mclk);
+
        mutex_unlock(&da7219->lock);
        snd_soc_dapm_mutex_unlock(dapm);
 
index 50ea94317cb3216d116b9351cf5387a0213b4689..1ada845a3ecda07fa31bd3950a0c68a4ff885d12 100644 (file)
@@ -1508,11 +1508,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-       case SND_SOC_BIAS_PREPARE:
                break;
-       case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       /* MCLK */
+       case SND_SOC_BIAS_PREPARE:
+               /* Enable MCLK for transition to ON state */
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
                        if (da7219->mclk) {
                                ret = clk_prepare_enable(da7219->mclk);
                                if (ret) {
@@ -1521,11 +1520,19 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
                                        return ret;
                                }
                        }
+               }
 
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
                        /* Master bias */
                        snd_soc_update_bits(codec, DA7219_REFERENCES,
                                            DA7219_BIAS_EN_MASK,
                                            DA7219_BIAS_EN_MASK);
+               } else {
+                       /* Remove MCLK */
+                       if (da7219->mclk)
+                               clk_disable_unprepare(da7219->mclk);
                }
                break;
        case SND_SOC_BIAS_OFF:
@@ -1534,9 +1541,6 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
                        snd_soc_update_bits(codec, DA7219_REFERENCES,
                                            DA7219_BIAS_EN_MASK, 0);
 
-               /* MCLK */
-               if (da7219->mclk)
-                       clk_disable_unprepare(da7219->mclk);
                break;
        }
 
@@ -1767,13 +1771,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7219 = {
        .resume                 = da7219_resume,
        .set_bias_level         = da7219_set_bias_level,
 
-       .controls               = da7219_snd_controls,
-       .num_controls           = ARRAY_SIZE(da7219_snd_controls),
-
-       .dapm_widgets           = da7219_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da7219_dapm_widgets),
-       .dapm_routes            = da7219_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(da7219_audio_map),
+       .component_driver = {
+               .controls               = da7219_snd_controls,
+               .num_controls           = ARRAY_SIZE(da7219_snd_controls),
+               .dapm_widgets           = da7219_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da7219_dapm_widgets),
+               .dapm_routes            = da7219_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(da7219_audio_map),
+       },
 };
 
 
index 461506a4ca6a2ddb790b1646f27bce2d7abf25ba..c1cc1c1c28f26d75a24ca0ee792c615996a06d66 100644 (file)
@@ -1501,12 +1501,14 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
 
 static struct snd_soc_codec_driver soc_codec_dev_da732x = {
        .set_bias_level         = da732x_set_bias_level,
-       .controls               = da732x_snd_controls,
-       .num_controls           = ARRAY_SIZE(da732x_snd_controls),
-       .dapm_widgets           = da732x_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da732x_dapm_widgets),
-       .dapm_routes            = da732x_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(da732x_dapm_routes),
+       .component_driver = {
+               .controls               = da732x_snd_controls,
+               .num_controls           = ARRAY_SIZE(da732x_snd_controls),
+               .dapm_widgets           = da732x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da732x_dapm_widgets),
+               .dapm_routes            = da732x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(da732x_dapm_routes),
+       },
        .set_pll                = da732x_set_dai_pll,
 };
 
index 0b2ede8db97886f3102ce1f227d389fd86bcd934..4efb5f897a0c01943a6b977eb4e4eb269ee55336 100644 (file)
@@ -1455,13 +1455,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da9055 = {
        .probe                  = da9055_probe,
        .set_bias_level         = da9055_set_bias_level,
 
-       .controls               = da9055_snd_controls,
-       .num_controls           = ARRAY_SIZE(da9055_snd_controls),
-
-       .dapm_widgets           = da9055_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(da9055_dapm_widgets),
-       .dapm_routes            = da9055_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(da9055_audio_map),
+       .component_driver = {
+               .controls               = da9055_snd_controls,
+               .num_controls           = ARRAY_SIZE(da9055_snd_controls),
+               .dapm_widgets           = da9055_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(da9055_dapm_widgets),
+               .dapm_routes            = da9055_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(da9055_audio_map),
+       },
 };
 
 static const struct regmap_config da9055_regmap_config = {
index fde53251c0474ce4148dccc77094af40012774ea..c82b9dc41e9a2b8ab2a3358ca96abc21dfd639cd 100644 (file)
@@ -51,10 +51,12 @@ static const struct snd_soc_dapm_route intercon[] = {
 };
 
 static struct snd_soc_codec_driver soc_dmic = {
-       .dapm_widgets = dmic_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets),
-       .dapm_routes = intercon,
-       .num_dapm_routes = ARRAY_SIZE(intercon),
+       .component_driver = {
+               .dapm_widgets           = dmic_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(dmic_dapm_widgets),
+               .dapm_routes            = intercon,
+               .num_dapm_routes        = ARRAY_SIZE(intercon),
+       },
 };
 
 static int dmic_dev_probe(struct platform_device *pdev)
index 2086d7107622d17ac3d750591f91c58db4993d8d..37722194b107e8a733bb124be480ff46b63749ef 100644 (file)
@@ -823,12 +823,14 @@ static struct snd_soc_codec_driver es8328_codec_driver = {
        .set_bias_level   = es8328_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls         = es8328_snd_controls,
-       .num_controls     = ARRAY_SIZE(es8328_snd_controls),
-       .dapm_widgets     = es8328_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets),
-       .dapm_routes      = es8328_dapm_routes,
-       .num_dapm_routes  = ARRAY_SIZE(es8328_dapm_routes),
+       .component_driver = {
+               .controls               = es8328_snd_controls,
+               .num_controls           = ARRAY_SIZE(es8328_snd_controls),
+               .dapm_widgets           = es8328_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(es8328_dapm_widgets),
+               .dapm_routes            = es8328_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(es8328_dapm_routes),
+       },
 };
 
 int es8328_probe(struct device *dev, struct regmap *regmap)
index 0b80052996d3d17c528414c91adfe42bf898a472..926b1a4e37d46825a4dd3741bb7865b794245a3f 100644 (file)
@@ -52,10 +52,12 @@ static struct snd_soc_dai_driver gtm601_dai = {
 };
 
 static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = {
-       .dapm_widgets = gtm601_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets),
-       .dapm_routes = gtm601_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = gtm601_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(gtm601_dapm_widgets),
+               .dapm_routes            = gtm601_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(gtm601_dapm_routes),
+       },
 };
 
 static int gtm601_platform_probe(struct platform_device *pdev)
index 4e181b270d95022b01f50d37b618b72eb0e68bed..c602c4960924c1553c6e2b54450e4dbe5fbc5f92 100644 (file)
@@ -614,7 +614,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
                        (!pin->eld.eld_valid)) {
 
                dev_warn(&hdac->hdac.dev,
-                       "Failed: montior present? %d ELD valid?: %d for pin: %d\n",
+                       "Failed: monitor present? %d ELD valid?: %d for pin: %d\n",
                        pin->eld.monitor_present, pin->eld.eld_valid, pin->nid);
 
                return 0;
index f27d115626db7d4cb250c41e788eb5f4b329d91c..b904492d774473a99d5e1aa451f18ff276f83732 100644 (file)
 
 #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
 
+struct hdmi_device {
+       struct device *dev;
+       struct list_head list;
+       int cnt;
+};
+#define pos_to_hdmi_device(pos)        container_of((pos), struct hdmi_device, list)
+LIST_HEAD(hdmi_device_list);
+
+#define DAI_NAME_SIZE 16
 struct hdmi_codec_priv {
        struct hdmi_codec_pdata hcd;
        struct snd_soc_dai_driver *daidrv;
@@ -320,7 +329,6 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
                         SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
 
 static struct snd_soc_dai_driver hdmi_i2s_dai = {
-       .name = "i2s-hifi",
        .id = DAI_ID_I2S,
        .playback = {
                .stream_name = "Playback",
@@ -334,7 +342,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
 };
 
 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
-       .name = "spdif-hifi",
        .id = DAI_ID_SPDIF,
        .playback = {
                .stream_name = "Playback",
@@ -346,13 +353,37 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
        .ops = &hdmi_dai_ops,
 };
 
+static char hdmi_dai_name[][DAI_NAME_SIZE] = {
+       "hdmi-hifi.0",
+       "hdmi-hifi.1",
+       "hdmi-hifi.2",
+       "hdmi-hifi.3",
+};
+
+static int hdmi_of_xlate_dai_name(struct snd_soc_component *component,
+                                 struct of_phandle_args *args,
+                                 const char **dai_name)
+{
+       int id = args->args[0];
+
+       if (id < ARRAY_SIZE(hdmi_dai_name)) {
+               *dai_name = hdmi_dai_name[id];
+               return 0;
+       }
+
+       return -EAGAIN;
+}
+
 static struct snd_soc_codec_driver hdmi_codec = {
-       .controls = hdmi_controls,
-       .num_controls = ARRAY_SIZE(hdmi_controls),
-       .dapm_widgets = hdmi_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
-       .dapm_routes = hdmi_routes,
-       .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
+       .component_driver = {
+               .controls               = hdmi_controls,
+               .num_controls           = ARRAY_SIZE(hdmi_controls),
+               .dapm_widgets           = hdmi_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(hdmi_widgets),
+               .dapm_routes            = hdmi_routes,
+               .num_dapm_routes        = ARRAY_SIZE(hdmi_routes),
+               .of_xlate_dai_name      = hdmi_of_xlate_dai_name,
+       },
 };
 
 static int hdmi_codec_probe(struct platform_device *pdev)
@@ -360,6 +391,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
        struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
        struct device *dev = &pdev->dev;
        struct hdmi_codec_priv *hcp;
+       struct hdmi_device *hd;
+       struct list_head *pos;
        int dai_count, i = 0;
        int ret;
 
@@ -381,6 +414,31 @@ static int hdmi_codec_probe(struct platform_device *pdev)
        if (!hcp)
                return -ENOMEM;
 
+       hd = NULL;
+       list_for_each(pos, &hdmi_device_list) {
+               struct hdmi_device *tmp = pos_to_hdmi_device(pos);
+
+               if (tmp->dev == dev->parent) {
+                       hd = tmp;
+                       break;
+               }
+       }
+
+       if (!hd) {
+               hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
+               if (!hd)
+                       return -ENOMEM;
+
+               hd->dev = dev->parent;
+
+               list_add_tail(&hd->list, &hdmi_device_list);
+       }
+
+       if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
+               dev_err(dev, "too many hdmi codec are deteced\n");
+               return -EINVAL;
+       }
+
        hcp->hcd = *hcd;
        mutex_init(&hcp->current_stream_lock);
 
@@ -393,11 +451,14 @@ static int hdmi_codec_probe(struct platform_device *pdev)
                hcp->daidrv[i] = hdmi_i2s_dai;
                hcp->daidrv[i].playback.channels_max =
                        hcd->max_i2s_channels;
+               hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
                i++;
        }
 
-       if (hcd->spdif)
+       if (hcd->spdif) {
                hcp->daidrv[i] = hdmi_spdif_dai;
+               hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
+       }
 
        ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
                                     dai_count);
index 9b6e8840a1b56d5741ade1ee35c3a32034edfe9a..b918ba5c8ce5ce73acc35e843241b409113ea292 100644 (file)
@@ -380,12 +380,14 @@ static struct snd_soc_codec_driver rk3036_codec_driver = {
        .probe                  = rk3036_codec_probe,
        .remove                 = rk3036_codec_remove,
        .set_bias_level         = rk3036_codec_set_bias_level,
-       .controls               = rk3036_codec_dapm_controls,
-       .num_controls           = ARRAY_SIZE(rk3036_codec_dapm_controls),
-       .dapm_routes            = rk3036_codec_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(rk3036_codec_dapm_routes),
-       .dapm_widgets           = rk3036_codec_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(rk3036_codec_dapm_widgets),
+       .component_driver = {
+               .controls               = rk3036_codec_dapm_controls,
+               .num_controls           = ARRAY_SIZE(rk3036_codec_dapm_controls),
+               .dapm_routes            = rk3036_codec_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rk3036_codec_dapm_routes),
+               .dapm_widgets           = rk3036_codec_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rk3036_codec_dapm_widgets),
+       },
 };
 
 static const struct regmap_config rk3036_codec_regmap_config = {
index be448373d39afa390a2c1cd444bb44cd5975c69b..a4b0eded984aff2ce711fc70c84545ef3df02fcd 100644 (file)
@@ -1089,12 +1089,14 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
 
 static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
        .set_bias_level = isabelle_set_bias_level,
-       .controls = isabelle_snd_controls,
-       .num_controls = ARRAY_SIZE(isabelle_snd_controls),
-       .dapm_widgets = isabelle_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets),
-       .dapm_routes = isabelle_intercon,
-       .num_dapm_routes = ARRAY_SIZE(isabelle_intercon),
+       .component_driver = {
+               .controls               = isabelle_snd_controls,
+               .num_controls           = ARRAY_SIZE(isabelle_snd_controls),
+               .dapm_widgets           = isabelle_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(isabelle_dapm_widgets),
+               .dapm_routes            = isabelle_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(isabelle_intercon),
+       },
        .idle_bias_off = true,
 };
 
index 1f5ab99956ed234d5e81c31011602002cc944ad3..0290fab383da8864086e7e617051a15b65d3b1e7 100644 (file)
@@ -298,12 +298,14 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
        .set_bias_level = jz4740_codec_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = jz4740_codec_controls,
-       .num_controls = ARRAY_SIZE(jz4740_codec_controls),
-       .dapm_widgets = jz4740_codec_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
-       .dapm_routes = jz4740_codec_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
+       .component_driver = {
+               .controls               = jz4740_codec_controls,
+               .num_controls           = ARRAY_SIZE(jz4740_codec_controls),
+               .dapm_widgets           = jz4740_codec_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(jz4740_codec_dapm_widgets),
+               .dapm_routes            = jz4740_codec_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(jz4740_codec_dapm_routes),
+       },
 };
 
 static const struct regmap_config jz4740_codec_regmap_config = {
index 5353af58862cd949e72d1631cce01a03c4d8b091..a10ea3c716c67b2d3324ce00283271becb126a87 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
 
 #include <sound/l3.h>
 
@@ -32,11 +34,11 @@ static void sendbyte(struct l3_pins *adap, unsigned int byte)
        int i;
 
        for (i = 0; i < 8; i++) {
-               adap->setclk(0);
+               adap->setclk(adap, 0);
                udelay(adap->data_hold);
-               adap->setdat(byte & 1);
+               adap->setdat(adap, byte & 1);
                udelay(adap->data_setup);
-               adap->setclk(1);
+               adap->setclk(adap, 1);
                udelay(adap->clock_high);
                byte >>= 1;
        }
@@ -55,10 +57,10 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
        for (i = 0; i < len; i++) {
                if (i) {
                        udelay(adap->mode_hold);
-                       adap->setmode(0);
+                       adap->setmode(adap, 0);
                        udelay(adap->mode);
                }
-               adap->setmode(1);
+               adap->setmode(adap, 1);
                udelay(adap->mode_setup);
                sendbyte(adap, buf[i]);
        }
@@ -66,26 +68,71 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
 
 int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
 {
-       adap->setclk(1);
-       adap->setdat(1);
-       adap->setmode(1);
+       adap->setclk(adap, 1);
+       adap->setdat(adap, 1);
+       adap->setmode(adap, 1);
        udelay(adap->mode);
 
-       adap->setmode(0);
+       adap->setmode(adap, 0);
        udelay(adap->mode_setup);
        sendbyte(adap, addr);
        udelay(adap->mode_hold);
 
        sendbytes(adap, data, len);
 
-       adap->setclk(1);
-       adap->setdat(1);
-       adap->setmode(0);
+       adap->setclk(adap, 1);
+       adap->setdat(adap, 1);
+       adap->setmode(adap, 0);
 
        return len;
 }
 EXPORT_SYMBOL_GPL(l3_write);
 
+
+static void l3_set_clk(struct l3_pins *adap, int val)
+{
+       gpio_set_value(adap->gpio_clk, val);
+}
+
+static void l3_set_data(struct l3_pins *adap, int val)
+{
+       gpio_set_value(adap->gpio_data, val);
+}
+
+static void l3_set_mode(struct l3_pins *adap, int val)
+{
+       gpio_set_value(adap->gpio_mode, val);
+}
+
+int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap)
+{
+       int ret;
+
+       if (!adap->use_gpios)
+               return -EINVAL;
+
+       ret = devm_gpio_request_one(dev, adap->gpio_data,
+                               GPIOF_OUT_INIT_LOW, "l3_data");
+       if (ret < 0)
+               return ret;
+       adap->setdat = l3_set_data;
+
+       ret = devm_gpio_request_one(dev, adap->gpio_clk,
+                               GPIOF_OUT_INIT_LOW, "l3_clk");
+       if (ret < 0)
+               return ret;
+       adap->setclk = l3_set_clk;
+
+       ret = devm_gpio_request_one(dev, adap->gpio_mode,
+                               GPIOF_OUT_INIT_LOW, "l3_mode");
+       if (ret < 0)
+               return ret;
+       adap->setmode = l3_set_mode;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(l3_set_gpio_ops);
+
 MODULE_DESCRIPTION("L3 bit-banging driver");
 MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
 MODULE_LICENSE("GPL");
index 9af5640e3446be9b8cb770193e1dbeedef355911..8d413c2677ccad5287d06a41d33c586296056985 100644 (file)
@@ -1391,12 +1391,14 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
 
 static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
        .set_bias_level = lm49453_set_bias_level,
-       .controls = lm49453_snd_controls,
-       .num_controls = ARRAY_SIZE(lm49453_snd_controls),
-       .dapm_widgets = lm49453_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets),
-       .dapm_routes = lm49453_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map),
+       .component_driver = {
+               .controls               = lm49453_snd_controls,
+               .num_controls           = ARRAY_SIZE(lm49453_snd_controls),
+               .dapm_widgets           = lm49453_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(lm49453_dapm_widgets),
+               .dapm_routes            = lm49453_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(lm49453_audio_map),
+       },
        .idle_bias_off = true,
 };
 
index fc22804cabc5942acca6921c034fa98f234041dc..72f77455582eb4ad4f76c4b0cc1713c7c007177c 100644 (file)
@@ -1704,12 +1704,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
        .set_bias_level = max98088_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = max98088_snd_controls,
-       .num_controls = ARRAY_SIZE(max98088_snd_controls),
-       .dapm_widgets = max98088_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
-       .dapm_routes = max98088_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
+       .component_driver = {
+               .controls               = max98088_snd_controls,
+               .num_controls           = ARRAY_SIZE(max98088_snd_controls),
+               .dapm_widgets           = max98088_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max98088_dapm_widgets),
+               .dapm_routes            = max98088_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(max98088_audio_map),
+       },
 };
 
 static int max98088_i2c_probe(struct i2c_client *i2c,
index 3577003f39cf8feaba0d97bb313e277b3b763ce7..6f8a757876ed9c758c2c4719c8d563f18b3e9983 100644 (file)
@@ -2108,12 +2108,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
        .suspend = max98095_suspend,
        .resume  = max98095_resume,
        .set_bias_level = max98095_set_bias_level,
-       .controls = max98095_snd_controls,
-       .num_controls = ARRAY_SIZE(max98095_snd_controls),
-       .dapm_widgets     = max98095_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
-       .dapm_routes     = max98095_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
+       .component_driver = {
+               .controls               = max98095_snd_controls,
+               .num_controls           = ARRAY_SIZE(max98095_snd_controls),
+               .dapm_widgets           = max98095_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max98095_dapm_widgets),
+               .dapm_routes            = max98095_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(max98095_audio_map),
+       },
 };
 
 static int max98095_i2c_probe(struct i2c_client *i2c,
index 5b1dfb1518fbeaa151da656fc5d3e1198ad681ed..6a6b68a4cb527fc389b61d6e70524f13f11b3b5a 100644 (file)
@@ -74,10 +74,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver max98357a_codec_driver = {
        .probe                  = max98357a_codec_probe,
-       .dapm_widgets           = max98357a_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(max98357a_dapm_widgets),
-       .dapm_routes            = max98357a_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(max98357a_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = max98357a_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max98357a_dapm_widgets),
+               .dapm_routes            = max98357a_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(max98357a_dapm_routes),
+       },
 };
 
 static const struct snd_soc_dai_ops max98357a_dai_ops = {
index 02352ed8961c47ccb270ef9ff8f7aff3784bd4ca..781be9ba8dba0f212e1939f4cb995e64024a3d49 100644 (file)
@@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(of, max98371_of_match);
 static struct i2c_driver max98371_i2c_driver = {
        .driver = {
                .name = "max98371",
-               .owner = THIS_MODULE,
                .pm = NULL,
                .of_match_table = of_match_ptr(max98371_of_match),
        },
index c14a79d026a10418cd7e34304dc984e0b75a4e90..0610840733d1629d7fdd12f3dcdcf023681b3c42 100644 (file)
@@ -306,12 +306,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
        .set_bias_level = max9850_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = max9850_controls,
-       .num_controls = ARRAY_SIZE(max9850_controls),
-       .dapm_widgets = max9850_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets),
-       .dapm_routes = max9850_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes),
+       .component_driver = {
+               .controls               = max9850_controls,
+               .num_controls           = ARRAY_SIZE(max9850_controls),
+               .dapm_widgets           = max9850_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max9850_dapm_widgets),
+               .dapm_routes            = max9850_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(max9850_dapm_routes),
+       },
 };
 
 static int max9850_i2c_probe(struct i2c_client *i2c,
index 68074c92a7c0c0ab09ecbd3fe53771910ce4180e..499bdbfd0a2d93e7fa88da23915027a53556b238 100644 (file)
@@ -538,12 +538,14 @@ static struct snd_soc_codec_driver max9860_codec_driver = {
        .set_bias_level = max9860_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = max9860_controls,
-       .num_controls = ARRAY_SIZE(max9860_controls),
-       .dapm_widgets = max9860_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets),
-       .dapm_routes = max9860_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes),
+       .component_driver = {
+               .controls               = max9860_controls,
+               .num_controls           = ARRAY_SIZE(max9860_controls),
+               .dapm_widgets           = max9860_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max9860_dapm_widgets),
+               .dapm_routes            = max9860_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(max9860_dapm_routes),
+       },
 };
 
 #ifdef CONFIG_PM
index 2a22fddeb6afa02dbfb26b452cd4fd0f91b4024d..c9673235078d5df788947d60d88330bcad0c37eb 100644 (file)
@@ -417,12 +417,14 @@ static int max9867_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver max9867_codec = {
        .probe = max9867_probe,
-       .controls = max9867_snd_controls,
-       .num_controls = ARRAY_SIZE(max9867_snd_controls),
-       .dapm_routes = max9867_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
-       .dapm_widgets = max9867_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
+       .component_driver = {
+               .controls               = max9867_snd_controls,
+               .num_controls           = ARRAY_SIZE(max9867_snd_controls),
+               .dapm_routes            = max9867_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(max9867_audio_map),
+               .dapm_widgets           = max9867_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max9867_dapm_widgets),
+       },
 };
 
 static bool max9867_volatile_register(struct device *dev, unsigned int reg)
index 5990de3179991d94db534cf5dd721833455f23ef..327eaa25c9bd798df29b7fe6b055127193899a9b 100644 (file)
@@ -540,12 +540,14 @@ static int max98925_probe(struct snd_soc_codec *codec)
 
 static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
        .probe            = max98925_probe,
-       .controls = max98925_snd_controls,
-       .num_controls = ARRAY_SIZE(max98925_snd_controls),
-       .dapm_routes = max98925_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(max98925_audio_map),
-       .dapm_widgets = max98925_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets),
+       .component_driver = {
+               .controls               = max98925_snd_controls,
+               .num_controls           = ARRAY_SIZE(max98925_snd_controls),
+               .dapm_routes            = max98925_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(max98925_audio_map),
+               .dapm_widgets           = max98925_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max98925_dapm_widgets),
+       },
 };
 
 static const struct regmap_config max98925_regmap = {
index 8d14adae5cc5c836d634ee5ddcfd5c64e6add1b0..5830a81e535ad7d073cde70d68766e4e6ce24143 100644 (file)
@@ -498,12 +498,14 @@ static int max98926_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_max98926 = {
        .probe  = max98926_probe,
-       .controls = max98926_snd_controls,
-       .num_controls = ARRAY_SIZE(max98926_snd_controls),
-       .dapm_routes = max98926_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(max98926_audio_map),
-       .dapm_widgets = max98926_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets),
+       .component_driver = {
+               .controls               = max98926_snd_controls,
+               .num_controls           = ARRAY_SIZE(max98926_snd_controls),
+               .dapm_routes            = max98926_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(max98926_audio_map),
+               .dapm_widgets           = max98926_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(max98926_dapm_widgets),
+       },
 };
 
 static const struct regmap_config max98926_regmap = {
index 3e770cbe7f0f49e63d92d2e29d413023ba52f03f..90562703dcfdb1eb8c3a76c87303457173c7a28b 100644 (file)
@@ -737,12 +737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
        .probe          = mc13783_probe,
        .remove         = mc13783_remove,
        .get_regmap     = mc13783_get_regmap,
-       .controls       = mc13783_control_list,
-       .num_controls   = ARRAY_SIZE(mc13783_control_list),
-       .dapm_widgets   = mc13783_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets),
-       .dapm_routes    = mc13783_routes,
-       .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
+       .component_driver = {
+               .controls               = mc13783_control_list,
+               .num_controls           = ARRAY_SIZE(mc13783_control_list),
+               .dapm_widgets           = mc13783_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(mc13783_dapm_widgets),
+               .dapm_routes            = mc13783_routes,
+               .num_dapm_routes        = ARRAY_SIZE(mc13783_routes),
+       },
 };
 
 static int __init mc13783_codec_probe(struct platform_device *pdev)
index f561c78b9e0e0ca8df6e4647786009b596bc2b9b..69e5e18880c53c35835b0bb8e5b5eb749c0c16b7 100644 (file)
@@ -541,12 +541,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
        .probe =        ml26124_probe,
        .set_bias_level = ml26124_set_bias_level,
        .suspend_bias_off = true,
-       .dapm_widgets = ml26124_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
-       .dapm_routes = ml26124_intercon,
-       .num_dapm_routes = ARRAY_SIZE(ml26124_intercon),
-       .controls = ml26124_snd_controls,
-       .num_controls = ARRAY_SIZE(ml26124_snd_controls),
+       .component_driver = {
+               .controls               = ml26124_snd_controls,
+               .num_controls           = ARRAY_SIZE(ml26124_snd_controls),
+               .dapm_widgets           = ml26124_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ml26124_dapm_widgets),
+               .dapm_routes            = ml26124_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(ml26124_intercon),
+       },
 };
 
 static const struct regmap_config ml26124_i2c_regmap = {
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c
new file mode 100644 (file)
index 0000000..e455186
--- /dev/null
@@ -0,0 +1,884 @@
+/*
+ * nau8810.c  --  NAU8810 ALSA Soc Audio driver
+ *
+ * Copyright 2016 Nuvoton Technology Corp.
+ *
+ * Author: David Lin <ctlin0@nuvoton.com>
+ *
+ * Based on WM8974.c
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "nau8810.h"
+
+#define NAU_PLL_FREQ_MAX 100000000
+#define NAU_PLL_FREQ_MIN 90000000
+#define NAU_PLL_REF_MAX 33000000
+#define NAU_PLL_REF_MIN 8000000
+#define NAU_PLL_OPTOP_MIN 6
+
+
+static const int nau8810_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 };
+
+static const struct reg_default nau8810_reg_defaults[] = {
+       { NAU8810_REG_POWER1, 0x0000 },
+       { NAU8810_REG_POWER2, 0x0000 },
+       { NAU8810_REG_POWER3, 0x0000 },
+       { NAU8810_REG_IFACE, 0x0050 },
+       { NAU8810_REG_COMP, 0x0000 },
+       { NAU8810_REG_CLOCK, 0x0140 },
+       { NAU8810_REG_SMPLR, 0x0000 },
+       { NAU8810_REG_DAC, 0x0000 },
+       { NAU8810_REG_DACGAIN, 0x00FF },
+       { NAU8810_REG_ADC, 0x0100 },
+       { NAU8810_REG_ADCGAIN, 0x00FF },
+       { NAU8810_REG_EQ1, 0x012C },
+       { NAU8810_REG_EQ2, 0x002C },
+       { NAU8810_REG_EQ3, 0x002C },
+       { NAU8810_REG_EQ4, 0x002C },
+       { NAU8810_REG_EQ5, 0x002C },
+       { NAU8810_REG_DACLIM1, 0x0032 },
+       { NAU8810_REG_DACLIM2, 0x0000 },
+       { NAU8810_REG_NOTCH1, 0x0000 },
+       { NAU8810_REG_NOTCH2, 0x0000 },
+       { NAU8810_REG_NOTCH3, 0x0000 },
+       { NAU8810_REG_NOTCH4, 0x0000 },
+       { NAU8810_REG_ALC1, 0x0038 },
+       { NAU8810_REG_ALC2, 0x000B },
+       { NAU8810_REG_ALC3, 0x0032 },
+       { NAU8810_REG_NOISEGATE, 0x0000 },
+       { NAU8810_REG_PLLN, 0x0008 },
+       { NAU8810_REG_PLLK1, 0x000C },
+       { NAU8810_REG_PLLK2, 0x0093 },
+       { NAU8810_REG_PLLK3, 0x00E9 },
+       { NAU8810_REG_ATTEN, 0x0000 },
+       { NAU8810_REG_INPUT_SIGNAL, 0x0003 },
+       { NAU8810_REG_PGAGAIN, 0x0010 },
+       { NAU8810_REG_ADCBOOST, 0x0100 },
+       { NAU8810_REG_OUTPUT, 0x0002 },
+       { NAU8810_REG_SPKMIX, 0x0001 },
+       { NAU8810_REG_SPKGAIN, 0x0039 },
+       { NAU8810_REG_MONOMIX, 0x0001 },
+       { NAU8810_REG_POWER4, 0x0000 },
+       { NAU8810_REG_TSLOTCTL1, 0x0000 },
+       { NAU8810_REG_TSLOTCTL2, 0x0020 },
+       { NAU8810_REG_DEVICE_REVID, 0x0000 },
+       { NAU8810_REG_I2C_DEVICEID, 0x001A },
+       { NAU8810_REG_ADDITIONID, 0x00CA },
+       { NAU8810_REG_RESERVE, 0x0124 },
+       { NAU8810_REG_OUTCTL, 0x0001 },
+       { NAU8810_REG_ALC1ENHAN1, 0x0010 },
+       { NAU8810_REG_ALC1ENHAN2, 0x0000 },
+       { NAU8810_REG_MISCCTL, 0x0000 },
+       { NAU8810_REG_OUTTIEOFF, 0x0000 },
+       { NAU8810_REG_AGCP2POUT, 0x0000 },
+       { NAU8810_REG_AGCPOUT, 0x0000 },
+       { NAU8810_REG_AMTCTL, 0x0000 },
+       { NAU8810_REG_OUTTIEOFFMAN, 0x0000 },
+};
+
+static bool nau8810_readable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case NAU8810_REG_RESET ... NAU8810_REG_SMPLR:
+       case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN:
+       case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN:
+       case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5:
+       case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2:
+       case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4:
+       case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN:
+       case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN:
+       case NAU8810_REG_ADCBOOST:
+       case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX:
+       case NAU8810_REG_SPKGAIN:
+       case NAU8810_REG_MONOMIX:
+       case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2:
+       case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE:
+       case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2:
+       case NAU8810_REG_MISCCTL:
+       case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool nau8810_writeable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case NAU8810_REG_RESET ... NAU8810_REG_SMPLR:
+       case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN:
+       case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN:
+       case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5:
+       case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2:
+       case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4:
+       case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN:
+       case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN:
+       case NAU8810_REG_ADCBOOST:
+       case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX:
+       case NAU8810_REG_SPKGAIN:
+       case NAU8810_REG_MONOMIX:
+       case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2:
+       case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2:
+       case NAU8810_REG_MISCCTL:
+       case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool nau8810_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case NAU8810_REG_RESET:
+       case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE:
+               return true;
+       default:
+               return false;
+       }
+}
+
+/* The EQ parameters get function is to get the 5 band equalizer control.
+ * The regmap raw read can't work here because regmap doesn't provide
+ * value format for value width of 9 bits. Therefore, the driver reads data
+ * from cache and makes value format according to the endianness of
+ * bytes type control element.
+ */
+static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+       int i, reg, reg_val;
+       u16 *val;
+
+       val = (u16 *)ucontrol->value.bytes.data;
+       reg = NAU8810_REG_EQ1;
+       for (i = 0; i < params->max / sizeof(u16); i++) {
+               regmap_read(nau8810->regmap, reg + i, &reg_val);
+               /* conversion of 16-bit integers between native CPU format
+                * and big endian format
+                */
+               reg_val = cpu_to_be16(reg_val);
+               memcpy(val + i, &reg_val, sizeof(reg_val));
+       }
+
+       return 0;
+}
+
+/* The EQ parameters put function is to make configuration of 5 band equalizer
+ * control. These configuration includes central frequency, equalizer gain,
+ * cut-off frequency, bandwidth control, and equalizer path.
+ * The regmap raw write can't work here because regmap doesn't provide
+ * register and value format for register with address 7 bits and value 9 bits.
+ * Therefore, the driver makes value format according to the endianness of
+ * bytes type control element and writes data to codec.
+ */
+static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+       void *data;
+       u16 *val, value;
+       int i, reg, ret;
+
+       data = kmemdup(ucontrol->value.bytes.data,
+               params->max, GFP_KERNEL | GFP_DMA);
+       if (!data)
+               return -ENOMEM;
+
+       val = (u16 *)data;
+       reg = NAU8810_REG_EQ1;
+       for (i = 0; i < params->max / sizeof(u16); i++) {
+               /* conversion of 16-bit integers between native CPU format
+                * and big endian format
+                */
+               value = be16_to_cpu(*(val + i));
+               ret = regmap_write(nau8810->regmap, reg + i, value);
+               if (ret) {
+                       dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n",
+                               reg + i, ret);
+                       kfree(data);
+                       return ret;
+               }
+       }
+       kfree(data);
+
+       return 0;
+}
+
+static const char * const nau8810_companding[] = {
+       "Off", "NC", "u-law", "A-law" };
+
+static const struct soc_enum nau8810_companding_adc_enum =
+       SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_ADCCM_SFT,
+               ARRAY_SIZE(nau8810_companding), nau8810_companding);
+
+static const struct soc_enum nau8810_companding_dac_enum =
+       SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_DACCM_SFT,
+               ARRAY_SIZE(nau8810_companding), nau8810_companding);
+
+static const char * const nau8810_deemp[] = {
+       "None", "32kHz", "44.1kHz", "48kHz" };
+
+static const struct soc_enum nau8810_deemp_enum =
+       SOC_ENUM_SINGLE(NAU8810_REG_DAC, NAU8810_DEEMP_SFT,
+               ARRAY_SIZE(nau8810_deemp), nau8810_deemp);
+
+static const char * const nau8810_eqmode[] = {"Capture", "Playback" };
+
+static const struct soc_enum nau8810_eqmode_enum =
+       SOC_ENUM_SINGLE(NAU8810_REG_EQ1, NAU8810_EQM_SFT,
+               ARRAY_SIZE(nau8810_eqmode), nau8810_eqmode);
+
+static const char * const nau8810_alc[] = {"Normal", "Limiter" };
+
+static const struct soc_enum nau8810_alc_enum =
+       SOC_ENUM_SINGLE(NAU8810_REG_ALC3, NAU8810_ALCM_SFT,
+               ARRAY_SIZE(nau8810_alc), nau8810_alc);
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
+static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
+
+static const struct snd_kcontrol_new nau8810_snd_controls[] = {
+       SOC_ENUM("ADC Companding", nau8810_companding_adc_enum),
+       SOC_ENUM("DAC Companding", nau8810_companding_dac_enum),
+       SOC_ENUM("DAC De-emphasis", nau8810_deemp_enum),
+
+       SOC_ENUM("EQ Function", nau8810_eqmode_enum),
+       SND_SOC_BYTES_EXT("EQ Parameters", 10,
+                 nau8810_eq_get, nau8810_eq_put),
+
+       SOC_SINGLE("DAC Inversion Switch", NAU8810_REG_DAC,
+               NAU8810_DACPL_SFT, 1, 0),
+       SOC_SINGLE_TLV("Playback Volume", NAU8810_REG_DACGAIN,
+               NAU8810_DACGAIN_SFT, 0xff, 0, digital_tlv),
+
+       SOC_SINGLE("High Pass Filter Switch", NAU8810_REG_ADC,
+               NAU8810_HPFEN_SFT, 1, 0),
+       SOC_SINGLE("High Pass Cut Off", NAU8810_REG_ADC,
+               NAU8810_HPF_SFT, 0x7, 0),
+
+       SOC_SINGLE("ADC Inversion Switch", NAU8810_REG_ADC,
+               NAU8810_ADCPL_SFT, 1, 0),
+       SOC_SINGLE_TLV("Capture Volume", NAU8810_REG_ADCGAIN,
+               NAU8810_ADCGAIN_SFT, 0xff, 0, digital_tlv),
+
+       SOC_SINGLE_TLV("EQ1 Volume", NAU8810_REG_EQ1,
+               NAU8810_EQ1GC_SFT, 0x18, 1, eq_tlv),
+       SOC_SINGLE_TLV("EQ2 Volume", NAU8810_REG_EQ2,
+               NAU8810_EQ2GC_SFT, 0x18, 1, eq_tlv),
+       SOC_SINGLE_TLV("EQ3 Volume", NAU8810_REG_EQ3,
+               NAU8810_EQ3GC_SFT, 0x18, 1, eq_tlv),
+       SOC_SINGLE_TLV("EQ4 Volume", NAU8810_REG_EQ4,
+               NAU8810_EQ4GC_SFT, 0x18, 1, eq_tlv),
+       SOC_SINGLE_TLV("EQ5 Volume", NAU8810_REG_EQ5,
+               NAU8810_EQ5GC_SFT, 0x18, 1, eq_tlv),
+
+       SOC_SINGLE("DAC Limiter Switch", NAU8810_REG_DACLIM1,
+               NAU8810_DACLIMEN_SFT, 1, 0),
+       SOC_SINGLE("DAC Limiter Decay", NAU8810_REG_DACLIM1,
+               NAU8810_DACLIMDCY_SFT, 0xf, 0),
+       SOC_SINGLE("DAC Limiter Attack", NAU8810_REG_DACLIM1,
+               NAU8810_DACLIMATK_SFT, 0xf, 0),
+       SOC_SINGLE("DAC Limiter Threshold", NAU8810_REG_DACLIM2,
+               NAU8810_DACLIMTHL_SFT, 0x7, 0),
+       SOC_SINGLE("DAC Limiter Boost", NAU8810_REG_DACLIM2,
+               NAU8810_DACLIMBST_SFT, 0xf, 0),
+
+       SOC_ENUM("ALC Mode", nau8810_alc_enum),
+       SOC_SINGLE("ALC Enable Switch", NAU8810_REG_ALC1,
+               NAU8810_ALCEN_SFT, 1, 0),
+       SOC_SINGLE("ALC Max Volume", NAU8810_REG_ALC1,
+               NAU8810_ALCMXGAIN_SFT, 0x7, 0),
+       SOC_SINGLE("ALC Min Volume", NAU8810_REG_ALC1,
+               NAU8810_ALCMINGAIN_SFT, 0x7, 0),
+       SOC_SINGLE("ALC ZC Switch", NAU8810_REG_ALC2,
+               NAU8810_ALCZC_SFT, 1, 0),
+       SOC_SINGLE("ALC Hold", NAU8810_REG_ALC2,
+               NAU8810_ALCHT_SFT, 0xf, 0),
+       SOC_SINGLE("ALC Target", NAU8810_REG_ALC2,
+               NAU8810_ALCSL_SFT, 0xf, 0),
+       SOC_SINGLE("ALC Decay", NAU8810_REG_ALC3,
+               NAU8810_ALCDCY_SFT, 0xf, 0),
+       SOC_SINGLE("ALC Attack", NAU8810_REG_ALC3,
+               NAU8810_ALCATK_SFT, 0xf, 0),
+       SOC_SINGLE("ALC Noise Gate Switch", NAU8810_REG_NOISEGATE,
+               NAU8810_ALCNEN_SFT, 1, 0),
+       SOC_SINGLE("ALC Noise Gate Threshold", NAU8810_REG_NOISEGATE,
+               NAU8810_ALCNTH_SFT, 0x7, 0),
+
+       SOC_SINGLE("PGA ZC Switch", NAU8810_REG_PGAGAIN,
+               NAU8810_PGAZC_SFT, 1, 0),
+       SOC_SINGLE_TLV("PGA Volume", NAU8810_REG_PGAGAIN,
+               NAU8810_PGAGAIN_SFT, 0x3f, 0, inpga_tlv),
+
+       SOC_SINGLE("Speaker ZC Switch", NAU8810_REG_SPKGAIN,
+               NAU8810_SPKZC_SFT, 1, 0),
+       SOC_SINGLE("Speaker Mute Switch", NAU8810_REG_SPKGAIN,
+               NAU8810_SPKMT_SFT, 1, 0),
+       SOC_SINGLE_TLV("Speaker Volume", NAU8810_REG_SPKGAIN,
+               NAU8810_SPKGAIN_SFT, 0x3f, 0, spk_tlv),
+
+       SOC_SINGLE("Capture Boost(+20dB)", NAU8810_REG_ADCBOOST,
+               NAU8810_PGABST_SFT, 1, 0),
+       SOC_SINGLE("Mono Mute Switch", NAU8810_REG_MONOMIX,
+               NAU8810_MOUTMXMT_SFT, 1, 0),
+
+       SOC_SINGLE("DAC Oversampling Rate(128x) Switch", NAU8810_REG_DAC,
+               NAU8810_DACOS_SFT, 1, 0),
+       SOC_SINGLE("ADC Oversampling Rate(128x) Switch", NAU8810_REG_ADC,
+               NAU8810_ADCOS_SFT, 1, 0),
+};
+
+/* Speaker Output Mixer */
+static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
+               NAU8810_BYPSPK_SFT, 1, 0),
+       SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX,
+               NAU8810_DACSPK_SFT, 1, 0),
+};
+
+/* Mono Output Mixer */
+static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
+               NAU8810_BYPMOUT_SFT, 1, 0),
+       SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX,
+               NAU8810_DACMOUT_SFT, 1, 0),
+};
+
+/* PGA Mute */
+static const struct snd_kcontrol_new nau8810_inpga_mute[] = {
+       SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
+               NAU8810_PGAMT_SFT, 1, 0),
+};
+
+/* Input PGA */
+static const struct snd_kcontrol_new nau8810_inpga[] = {
+       SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
+               NAU8810_NMICPGA_SFT, 1, 0),
+       SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL,
+               NAU8810_PMICPGA_SFT, 1, 0),
+};
+
+/* Mic Input boost vol */
+static const struct snd_kcontrol_new nau8810_mic_boost_controls =
+       SOC_DAPM_SINGLE("Mic Volume", NAU8810_REG_ADCBOOST,
+               NAU8810_PMICBSTGAIN_SFT, 0x7, 0);
+
+/* Loopback Switch */
+static const struct snd_kcontrol_new nau8810_loopback =
+       SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP,
+               NAU8810_ADDAP_SFT, 1, 0);
+
+static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
+                        struct snd_soc_dapm_widget *sink)
+{
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       unsigned int value;
+
+       regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value);
+       return (value & NAU8810_CLKM_MASK);
+}
+
+static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
+       SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3,
+               NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0],
+               ARRAY_SIZE(nau8810_speaker_mixer_controls)),
+       SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3,
+               NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0],
+               ARRAY_SIZE(nau8810_mono_mixer_controls)),
+       SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3,
+               NAU8810_DAC_EN_SFT, 0),
+       SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2,
+               NAU8810_ADC_EN_SFT, 0),
+       SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3,
+               NAU8810_NSPK_EN_SFT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("SpkP Out", NAU8810_REG_POWER3,
+               NAU8810_PSPK_EN_SFT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Mono Out", NAU8810_REG_POWER3,
+               NAU8810_MOUT_EN_SFT, 0, NULL, 0),
+
+       SND_SOC_DAPM_MIXER("Input PGA", NAU8810_REG_POWER2,
+               NAU8810_PGA_EN_SFT, 0, nau8810_inpga,
+               ARRAY_SIZE(nau8810_inpga)),
+       SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
+               NAU8810_BST_EN_SFT, 0, nau8810_inpga_mute,
+               ARRAY_SIZE(nau8810_inpga_mute)),
+
+       SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
+               NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("PLL", NAU8810_REG_POWER1,
+               NAU8810_PLL_EN_SFT, 0, NULL, 0),
+
+       SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
+               &nau8810_loopback),
+
+       SND_SOC_DAPM_INPUT("MICN"),
+       SND_SOC_DAPM_INPUT("MICP"),
+       SND_SOC_DAPM_OUTPUT("MONOOUT"),
+       SND_SOC_DAPM_OUTPUT("SPKOUTP"),
+       SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+};
+
+static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
+       {"DAC", NULL, "PLL", check_mclk_select_pll},
+
+       /* Mono output mixer */
+       {"Mono Mixer", "PCM Playback Switch", "DAC"},
+       {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
+
+       /* Speaker output mixer */
+       {"Speaker Mixer", "PCM Playback Switch", "DAC"},
+       {"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"},
+
+       /* Outputs */
+       {"Mono Out", NULL, "Mono Mixer"},
+       {"MONOOUT", NULL, "Mono Out"},
+       {"SpkN Out", NULL, "Speaker Mixer"},
+       {"SpkP Out", NULL, "Speaker Mixer"},
+       {"SPKOUTN", NULL, "SpkN Out"},
+       {"SPKOUTP", NULL, "SpkP Out"},
+
+       /* Input Boost Stage */
+       {"ADC", NULL, "Input Boost Stage"},
+       {"ADC", NULL, "PLL", check_mclk_select_pll},
+       {"Input Boost Stage", NULL, "Input PGA"},
+       {"Input Boost Stage", NULL, "MICP"},
+
+       /* Input PGA */
+       {"Input PGA", NULL, "Mic Bias"},
+       {"Input PGA", "MicN Switch", "MICN"},
+       {"Input PGA", "MicP Switch", "MICP"},
+
+       /* Digital Looptack */
+       {"Digital Loopback", "Switch", "ADC"},
+       {"DAC", NULL, "Digital Loopback"},
+};
+
+static int nau8810_set_sysclk(struct snd_soc_dai *dai,
+                                int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+
+       nau8810->clk_id = clk_id;
+       nau8810->sysclk = freq;
+       dev_dbg(nau8810->dev, "master sysclk %dHz, source %s\n",
+               freq, clk_id == NAU8810_SCLK_PLL ? "PLL" : "MCLK");
+
+       return 0;
+}
+
+static int nau88l0_calc_pll(unsigned int pll_in,
+       unsigned int fs, struct nau8810_pll *pll_param)
+{
+       u64 f2, f2_max, pll_ratio;
+       int i, scal_sel;
+
+       if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN)
+               return -EINVAL;
+
+       f2_max = 0;
+       scal_sel = ARRAY_SIZE(nau8810_mclk_scaler);
+       for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) {
+               f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10;
+               if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX &&
+                       f2_max < f2) {
+                       f2_max = f2;
+                       scal_sel = i;
+               }
+       }
+       if (ARRAY_SIZE(nau8810_mclk_scaler) == scal_sel)
+               return -EINVAL;
+       pll_param->mclk_scaler = scal_sel;
+       f2 = f2_max;
+
+       /* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional
+        * input; round up the 24+4bit.
+        */
+       pll_ratio = div_u64(f2 << 28, pll_in);
+       pll_param->pre_factor = 0;
+       if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) {
+               pll_ratio <<= 1;
+               pll_param->pre_factor = 1;
+       }
+       pll_param->pll_int = (pll_ratio >> 28) & 0xF;
+       pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4);
+
+       return 0;
+}
+
+static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
+       int source, unsigned int freq_in, unsigned int freq_out)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct regmap *map = nau8810->regmap;
+       struct nau8810_pll *pll_param = &nau8810->pll;
+       int ret, fs;
+
+       fs = freq_out / 256;
+       ret = nau88l0_calc_pll(freq_in, fs, pll_param);
+       if (ret < 0) {
+               dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in);
+               return ret;
+       }
+       dev_info(nau8810->dev, "pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n",
+               pll_param->pll_int, pll_param->pll_frac, pll_param->mclk_scaler,
+               pll_param->pre_factor);
+
+       regmap_update_bits(map, NAU8810_REG_PLLN,
+               NAU8810_PLLMCLK_DIV2 | NAU8810_PLLN_MASK,
+               (pll_param->pre_factor ? NAU8810_PLLMCLK_DIV2 : 0) |
+               pll_param->pll_int);
+       regmap_write(map, NAU8810_REG_PLLK1,
+               (pll_param->pll_frac >> NAU8810_PLLK1_SFT) &
+               NAU8810_PLLK1_MASK);
+       regmap_write(map, NAU8810_REG_PLLK2,
+               (pll_param->pll_frac >> NAU8810_PLLK2_SFT) &
+               NAU8810_PLLK2_MASK);
+       regmap_write(map, NAU8810_REG_PLLK3,
+               pll_param->pll_frac & NAU8810_PLLK3_MASK);
+       regmap_update_bits(map, NAU8810_REG_CLOCK, NAU8810_MCLKSEL_MASK,
+               pll_param->mclk_scaler << NAU8810_MCLKSEL_SFT);
+       regmap_update_bits(map, NAU8810_REG_CLOCK,
+               NAU8810_CLKM_MASK, NAU8810_CLKM_PLL);
+
+       return 0;
+}
+
+static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       u16 ctrl1_val = 0, ctrl2_val = 0;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               ctrl2_val |= NAU8810_CLKIO_MASTER;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               ctrl1_val |= NAU8810_AIFMT_I2S;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               ctrl1_val |= NAU8810_AIFMT_LEFT;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               ctrl1_val |= NAU8810_AIFMT_PCM_A;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               ctrl1_val |= NAU8810_BCLKP_IB | NAU8810_FSP_IF;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               ctrl1_val |= NAU8810_BCLKP_IB;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               ctrl1_val |= NAU8810_FSP_IF;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE,
+               NAU8810_AIFMT_MASK | NAU8810_FSP_IF |
+               NAU8810_BCLKP_IB, ctrl1_val);
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
+               NAU8810_CLKIO_MASK, ctrl2_val);
+
+       return 0;
+}
+
+static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate)
+{
+       int i, sclk, imclk = rate * 256, div = 0;
+
+       if (!nau8810->sysclk) {
+               dev_err(nau8810->dev, "Make mclk div configuration fail because of invalid system clock\n");
+               return -EINVAL;
+       }
+
+       /* Configure the master clock prescaler div to make system
+        * clock to approximate the internal master clock (IMCLK);
+        * and large or equal to IMCLK.
+        */
+       for (i = 1; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) {
+               sclk = (nau8810->sysclk * 10) /
+                       nau8810_mclk_scaler[i];
+               if (sclk < imclk)
+                       break;
+               div = i;
+       }
+       dev_dbg(nau8810->dev,
+               "master clock prescaler %x for fs %d\n", div, rate);
+
+       /* master clock from MCLK and disable PLL */
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
+               NAU8810_MCLKSEL_MASK, (div << NAU8810_MCLKSEL_SFT));
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
+               NAU8810_CLKM_MASK, NAU8810_CLKM_MCLK);
+
+       return 0;
+}
+
+static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       int val_len = 0, val_rate = 0, ret = 0;
+
+       switch (params_width(params)) {
+       case 16:
+               break;
+       case 20:
+               val_len |= NAU8810_WLEN_20;
+               break;
+       case 24:
+               val_len |= NAU8810_WLEN_24;
+               break;
+       case 32:
+               val_len |= NAU8810_WLEN_32;
+               break;
+       }
+
+       switch (params_rate(params)) {
+       case 8000:
+               val_rate |= NAU8810_SMPLR_8K;
+               break;
+       case 11025:
+               val_rate |= NAU8810_SMPLR_12K;
+               break;
+       case 16000:
+               val_rate |= NAU8810_SMPLR_16K;
+               break;
+       case 22050:
+               val_rate |= NAU8810_SMPLR_24K;
+               break;
+       case 32000:
+               val_rate |= NAU8810_SMPLR_32K;
+               break;
+       case 44100:
+       case 48000:
+               break;
+       }
+
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE,
+               NAU8810_WLEN_MASK, val_len);
+       regmap_update_bits(nau8810->regmap, NAU8810_REG_SMPLR,
+               NAU8810_SMPLR_MASK, val_rate);
+
+       /* If the master clock is from MCLK, provide the runtime FS for driver
+        * to get the master clock prescaler configuration.
+        */
+       if (nau8810->clk_id == NAU8810_SCLK_MCLK) {
+               ret = nau8810_mclk_clkdiv(nau8810, params_rate(params));
+               if (ret < 0)
+                       dev_err(nau8810->dev, "MCLK div configuration fail\n");
+       }
+
+       return ret;
+}
+
+static int nau8810_set_bias_level(struct snd_soc_codec *codec,
+       enum snd_soc_bias_level level)
+{
+       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct regmap *map = nau8810->regmap;
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+       case SND_SOC_BIAS_PREPARE:
+               regmap_update_bits(map, NAU8810_REG_POWER1,
+                       NAU8810_REFIMP_MASK, NAU8810_REFIMP_80K);
+               break;
+
+       case SND_SOC_BIAS_STANDBY:
+               regmap_update_bits(map, NAU8810_REG_POWER1,
+                       NAU8810_IOBUF_EN | NAU8810_ABIAS_EN,
+                       NAU8810_IOBUF_EN | NAU8810_ABIAS_EN);
+
+               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+                       regcache_sync(map);
+                       regmap_update_bits(map, NAU8810_REG_POWER1,
+                               NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K);
+                       mdelay(100);
+               }
+               regmap_update_bits(map, NAU8810_REG_POWER1,
+                       NAU8810_REFIMP_MASK, NAU8810_REFIMP_300K);
+               break;
+
+       case SND_SOC_BIAS_OFF:
+               regmap_write(map, NAU8810_REG_POWER1, 0);
+               regmap_write(map, NAU8810_REG_POWER2, 0);
+               regmap_write(map, NAU8810_REG_POWER3, 0);
+               break;
+       }
+
+       return 0;
+}
+
+
+#define NAU8810_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define NAU8810_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops nau8810_ops = {
+       .hw_params = nau8810_pcm_hw_params,
+       .set_fmt = nau8810_set_dai_fmt,
+       .set_sysclk = nau8810_set_sysclk,
+       .set_pll = nau8810_set_pll,
+};
+
+static struct snd_soc_dai_driver nau8810_dai = {
+       .name = "nau8810-hifi",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 1,
+               .channels_max = 2,   /* Only 1 channel of data */
+               .rates = NAU8810_RATES,
+               .formats = NAU8810_FORMATS,
+       },
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,   /* Only 1 channel of data */
+               .rates = NAU8810_RATES,
+               .formats = NAU8810_FORMATS,
+       },
+       .ops = &nau8810_ops,
+       .symmetric_rates = 1,
+};
+
+static const struct regmap_config nau8810_regmap_config = {
+       .reg_bits = 7,
+       .val_bits = 9,
+
+       .max_register = NAU8810_REG_MAX,
+       .readable_reg = nau8810_readable_reg,
+       .writeable_reg = nau8810_writeable_reg,
+       .volatile_reg = nau8810_volatile_reg,
+
+       .cache_type = REGCACHE_RBTREE,
+       .reg_defaults = nau8810_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults),
+};
+
+static struct snd_soc_codec_driver nau8810_codec_driver = {
+       .set_bias_level = nau8810_set_bias_level,
+       .suspend_bias_off = true,
+
+       .component_driver = {
+               .controls = nau8810_snd_controls,
+               .num_controls = ARRAY_SIZE(nau8810_snd_controls),
+               .dapm_widgets = nau8810_dapm_widgets,
+               .num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets),
+               .dapm_routes = nau8810_dapm_routes,
+               .num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes),
+       },
+};
+
+static int nau8810_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+{
+       struct device *dev = &i2c->dev;
+       struct nau8810 *nau8810 = dev_get_platdata(dev);
+
+       if (!nau8810) {
+               nau8810 = devm_kzalloc(dev, sizeof(*nau8810), GFP_KERNEL);
+               if (!nau8810)
+                       return -ENOMEM;
+       }
+       i2c_set_clientdata(i2c, nau8810);
+
+       nau8810->regmap = devm_regmap_init_i2c(i2c, &nau8810_regmap_config);
+       if (IS_ERR(nau8810->regmap))
+               return PTR_ERR(nau8810->regmap);
+       nau8810->dev = dev;
+
+       regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00);
+
+       return snd_soc_register_codec(dev,
+               &nau8810_codec_driver, &nau8810_dai, 1);
+}
+
+static int nau8810_i2c_remove(struct i2c_client *client)
+{
+       snd_soc_unregister_codec(&client->dev);
+
+       return 0;
+}
+
+static const struct i2c_device_id nau8810_i2c_id[] = {
+       { "nau8810", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id nau8810_of_match[] = {
+       { .compatible = "nuvoton,nau8810", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, nau8810_of_match);
+#endif
+
+static struct i2c_driver nau8810_i2c_driver = {
+       .driver = {
+               .name = "nau8810",
+               .of_match_table = of_match_ptr(nau8810_of_match),
+       },
+       .probe =    nau8810_i2c_probe,
+       .remove =   nau8810_i2c_remove,
+       .id_table = nau8810_i2c_id,
+};
+
+module_i2c_driver(nau8810_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC NAU8810 driver");
+MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/nau8810.h b/sound/soc/codecs/nau8810.h
new file mode 100644 (file)
index 0000000..df88265
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * NAU8810 ALSA SoC audio driver
+ *
+ * Copyright 2016 Nuvoton Technology Corp.
+ * Author: David Lin <ctlin0@nuvoton.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 __NAU8810_H__
+#define __NAU8810_H__
+
+#define NAU8810_REG_RESET              0x00
+#define NAU8810_REG_POWER1             0x01
+#define NAU8810_REG_POWER2             0x02
+#define NAU8810_REG_POWER3             0x03
+#define NAU8810_REG_IFACE              0x04
+#define NAU8810_REG_COMP               0x05
+#define NAU8810_REG_CLOCK              0x06
+#define NAU8810_REG_SMPLR              0x07
+#define NAU8810_REG_DAC                0x0A
+#define NAU8810_REG_DACGAIN            0x0B
+#define NAU8810_REG_ADC                0x0E
+#define NAU8810_REG_ADCGAIN            0x0F
+#define NAU8810_REG_EQ1                0x12
+#define NAU8810_REG_EQ2                0x13
+#define NAU8810_REG_EQ3                0x14
+#define NAU8810_REG_EQ4                0x15
+#define NAU8810_REG_EQ5                0x16
+#define NAU8810_REG_DACLIM1            0x18
+#define NAU8810_REG_DACLIM2            0x19
+#define NAU8810_REG_NOTCH1             0x1B
+#define NAU8810_REG_NOTCH2             0x1C
+#define NAU8810_REG_NOTCH3             0x1D
+#define NAU8810_REG_NOTCH4             0x1E
+#define NAU8810_REG_ALC1               0x20
+#define NAU8810_REG_ALC2               0x21
+#define NAU8810_REG_ALC3               0x22
+#define NAU8810_REG_NOISEGATE          0x23
+#define NAU8810_REG_PLLN               0x24
+#define NAU8810_REG_PLLK1              0x25
+#define NAU8810_REG_PLLK2              0x26
+#define NAU8810_REG_PLLK3              0x27
+#define NAU8810_REG_ATTEN              0x28
+#define NAU8810_REG_INPUT_SIGNAL       0x2C
+#define NAU8810_REG_PGAGAIN            0x2D
+#define NAU8810_REG_ADCBOOST           0x2F
+#define NAU8810_REG_OUTPUT             0x31
+#define NAU8810_REG_SPKMIX             0x32
+#define NAU8810_REG_SPKGAIN            0x36
+#define NAU8810_REG_MONOMIX            0x38
+#define NAU8810_REG_POWER4             0x3A
+#define NAU8810_REG_TSLOTCTL1          0x3B
+#define NAU8810_REG_TSLOTCTL2          0x3C
+#define NAU8810_REG_DEVICE_REVID       0x3E
+#define NAU8810_REG_I2C_DEVICEID       0x3F
+#define NAU8810_REG_ADDITIONID 0x40
+#define NAU8810_REG_RESERVE            0x41
+#define NAU8810_REG_OUTCTL             0x45
+#define NAU8810_REG_ALC1ENHAN1 0x46
+#define NAU8810_REG_ALC1ENHAN2 0x47
+#define NAU8810_REG_MISCCTL            0x49
+#define NAU8810_REG_OUTTIEOFF          0x4B
+#define NAU8810_REG_AGCP2POUT  0x4C
+#define NAU8810_REG_AGCPOUT            0x4D
+#define NAU8810_REG_AMTCTL             0x4E
+#define NAU8810_REG_OUTTIEOFFMAN       0x4F
+#define NAU8810_REG_MAX                NAU8810_REG_OUTTIEOFFMAN
+
+
+/* NAU8810_REG_POWER1 (0x1) */
+#define NAU8810_DCBUF_EN               (0x1 << 8)
+#define NAU8810_PLL_EN_SFT             5
+#define NAU8810_MICBIAS_EN_SFT 4
+#define NAU8810_ABIAS_EN               (0x1 << 3)
+#define NAU8810_IOBUF_EN               (0x1 << 2)
+#define NAU8810_REFIMP_MASK            0x3
+#define NAU8810_REFIMP_DIS             0x0
+#define NAU8810_REFIMP_80K             0x1
+#define NAU8810_REFIMP_300K            0x2
+#define NAU8810_REFIMP_3K              0x3
+
+/* NAU8810_REG_POWER2 (0x2) */
+#define NAU8810_BST_EN_SFT             4
+#define NAU8810_PGA_EN_SFT             2
+#define NAU8810_ADC_EN_SFT             0
+
+/* NAU8810_REG_POWER3 (0x3) */
+#define NAU8810_DAC_EN_SFT             0
+#define NAU8810_SPKMX_EN_SFT           2
+#define NAU8810_MOUTMX_EN_SFT  3
+#define NAU8810_PSPK_EN_SFT            5
+#define NAU8810_NSPK_EN_SFT            6
+#define NAU8810_MOUT_EN_SFT            7
+
+/* NAU8810_REG_IFACE (0x4) */
+#define NAU8810_AIFMT_SFT              3
+#define NAU8810_AIFMT_MASK             (0x3 << NAU8810_AIFMT_SFT)
+#define NAU8810_AIFMT_RIGHT            (0x0 << NAU8810_AIFMT_SFT)
+#define NAU8810_AIFMT_LEFT             (0x1 << NAU8810_AIFMT_SFT)
+#define NAU8810_AIFMT_I2S              (0x2 << NAU8810_AIFMT_SFT)
+#define NAU8810_AIFMT_PCM_A            (0x3 << NAU8810_AIFMT_SFT)
+#define NAU8810_WLEN_SFT               5
+#define NAU8810_WLEN_MASK              (0x3 << NAU8810_WLEN_SFT)
+#define NAU8810_WLEN_16                (0x0 << NAU8810_WLEN_SFT)
+#define NAU8810_WLEN_20                (0x1 << NAU8810_WLEN_SFT)
+#define NAU8810_WLEN_24                (0x2 << NAU8810_WLEN_SFT)
+#define NAU8810_WLEN_32                (0x3 << NAU8810_WLEN_SFT)
+#define NAU8810_FSP_IF                 (0x1 << 7)
+#define NAU8810_BCLKP_IB               (0x1 << 8)
+
+/* NAU8810_REG_COMP (0x5) */
+#define NAU8810_ADDAP_SFT              0
+#define NAU8810_ADCCM_SFT              1
+#define NAU8810_DACCM_SFT              3
+
+/* NAU8810_REG_CLOCK (0x6) */
+#define NAU8810_CLKIO_MASK             0x1
+#define NAU8810_CLKIO_SLAVE            0x0
+#define NAU8810_CLKIO_MASTER           0x1
+#define NAU8810_BCLKSEL_SFT            2
+#define NAU8810_BCLKSEL_MASK           (0x7 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_1              (0x0 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_2              (0x1 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_4              (0x2 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_8              (0x3 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_16             (0x4 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_BCLKDIV_32             (0x5 << NAU8810_BCLKSEL_SFT)
+#define NAU8810_MCLKSEL_SFT            5
+#define NAU8810_MCLKSEL_MASK           (0x7 << NAU8810_MCLKSEL_SFT)
+#define NAU8810_CLKM_SFT               8
+#define NAU8810_CLKM_MASK              (0x1 << NAU8810_CLKM_SFT)
+#define NAU8810_CLKM_MCLK              (0x0 << NAU8810_CLKM_SFT)
+#define NAU8810_CLKM_PLL               (0x1 << NAU8810_CLKM_SFT)
+
+/* NAU8810_REG_SMPLR (0x7) */
+#define NAU8810_SMPLR_SFT              1
+#define NAU8810_SMPLR_MASK             (0x7 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_48K              (0x0 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_32K              (0x1 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_24K              (0x2 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_16K              (0x3 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_12K              (0x4 << NAU8810_SMPLR_SFT)
+#define NAU8810_SMPLR_8K               (0x5 << NAU8810_SMPLR_SFT)
+
+/* NAU8810_REG_DAC (0xA) */
+#define NAU8810_DACPL_SFT              0
+#define NAU8810_DACOS_SFT              3
+#define NAU8810_DEEMP_SFT              4
+
+/* NAU8810_REG_DACGAIN (0xB) */
+#define NAU8810_DACGAIN_SFT            0
+
+/* NAU8810_REG_ADC (0xE) */
+#define NAU8810_ADCPL_SFT              0
+#define NAU8810_ADCOS_SFT              3
+#define NAU8810_HPF_SFT                4
+#define NAU8810_HPFEN_SFT              8
+
+/* NAU8810_REG_ADCGAIN (0xF) */
+#define NAU8810_ADCGAIN_SFT            0
+
+/* NAU8810_REG_EQ1 (0x12) */
+#define NAU8810_EQ1GC_SFT              0
+#define NAU8810_EQ1CF_SFT              5
+#define NAU8810_EQM_SFT                8
+
+/* NAU8810_REG_EQ2 (0x13) */
+#define NAU8810_EQ2GC_SFT              0
+#define NAU8810_EQ2CF_SFT              5
+#define NAU8810_EQ2BW_SFT              8
+
+/* NAU8810_REG_EQ3 (0x14) */
+#define NAU8810_EQ3GC_SFT              0
+#define NAU8810_EQ3CF_SFT              5
+#define NAU8810_EQ3BW_SFT              8
+
+/* NAU8810_REG_EQ4 (0x15) */
+#define NAU8810_EQ4GC_SFT              0
+#define NAU8810_EQ4CF_SFT              5
+#define NAU8810_EQ4BW_SFT              8
+
+/* NAU8810_REG_EQ5 (0x16) */
+#define NAU8810_EQ5GC_SFT              0
+#define NAU8810_EQ5CF_SFT              5
+
+/* NAU8810_REG_DACLIM1 (0x18) */
+#define NAU8810_DACLIMATK_SFT          0
+#define NAU8810_DACLIMDCY_SFT          4
+#define NAU8810_DACLIMEN_SFT           8
+
+/* NAU8810_REG_DACLIM2 (0x19) */
+#define NAU8810_DACLIMBST_SFT          0
+#define NAU8810_DACLIMTHL_SFT          4
+
+/* NAU8810_REG_ALC1 (0x20) */
+#define NAU8810_ALCMINGAIN_SFT 0
+#define NAU8810_ALCMXGAIN_SFT          3
+#define NAU8810_ALCEN_SFT              8
+
+/* NAU8810_REG_ALC2 (0x21) */
+#define NAU8810_ALCSL_SFT              0
+#define NAU8810_ALCHT_SFT              4
+#define NAU8810_ALCZC_SFT              8
+
+/* NAU8810_REG_ALC3 (0x22) */
+#define NAU8810_ALCATK_SFT             0
+#define NAU8810_ALCDCY_SFT             4
+#define NAU8810_ALCM_SFT               8
+
+/* NAU8810_REG_NOISEGATE (0x23) */
+#define NAU8810_ALCNTH_SFT             0
+#define NAU8810_ALCNEN_SFT             3
+
+/* NAU8810_REG_PLLN (0x24) */
+#define NAU8810_PLLN_MASK              0xF
+#define NAU8810_PLLMCLK_DIV2           (0x1 << 4)
+
+/* NAU8810_REG_PLLK1 (0x25) */
+#define NAU8810_PLLK1_SFT              18
+#define NAU8810_PLLK1_MASK             0x3F
+
+/* NAU8810_REG_PLLK2 (0x26) */
+#define NAU8810_PLLK2_SFT              9
+#define NAU8810_PLLK2_MASK             0x1FF
+
+/* NAU8810_REG_PLLK3 (0x27) */
+#define NAU8810_PLLK3_MASK             0x1FF
+
+/* NAU8810_REG_INPUT_SIGNAL (0x2C) */
+#define NAU8810_PMICPGA_SFT            0
+#define NAU8810_NMICPGA_SFT            1
+
+/* NAU8810_REG_PGAGAIN (0x2D) */
+#define NAU8810_PGAGAIN_SFT            0
+#define NAU8810_PGAMT_SFT              6
+#define NAU8810_PGAZC_SFT              7
+
+/* NAU8810_REG_ADCBOOST (0x2F) */
+#define NAU8810_PMICBSTGAIN_SFT        4
+#define NAU8810_PGABST_SFT             8
+
+/* NAU8810_REG_SPKMIX (0x32) */
+#define NAU8810_DACSPK_SFT             0
+#define NAU8810_BYPSPK_SFT             1
+
+/* NAU8810_REG_SPKGAIN (0x36) */
+#define NAU8810_SPKGAIN_SFT            0
+#define NAU8810_SPKMT_SFT              6
+#define NAU8810_SPKZC_SFT              7
+
+/* NAU8810_REG_MONOMIX (0x38) */
+#define NAU8810_DACMOUT_SFT            0
+#define NAU8810_BYPMOUT_SFT            1
+#define NAU8810_MOUTMXMT_SFT           6
+
+
+/* System Clock Source */
+enum {
+       NAU8810_SCLK_MCLK,
+       NAU8810_SCLK_PLL,
+};
+
+struct nau8810_pll {
+       int pre_factor;
+       int mclk_scaler;
+       int pll_frac;
+       int pll_int;
+};
+
+struct nau8810 {
+       struct device *dev;
+       struct regmap *regmap;
+       struct nau8810_pll pll;
+       int sysclk;
+       int clk_id;
+};
+
+#endif
index 2e59a85e360b67cb89ffed8fca86148db8d0a6c1..057785beb892eec1814358d1fbdf3f7ebdf368fd 100644 (file)
@@ -2256,12 +2256,14 @@ static struct snd_soc_codec_driver nau8825_codec_driver = {
        .suspend = nau8825_suspend,
        .resume = nau8825_resume,
 
-       .controls = nau8825_controls,
-       .num_controls = ARRAY_SIZE(nau8825_controls),
-       .dapm_widgets = nau8825_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
-       .dapm_routes = nau8825_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
+       .component_driver = {
+               .controls               = nau8825_controls,
+               .num_controls           = ARRAY_SIZE(nau8825_controls),
+               .dapm_widgets           = nau8825_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(nau8825_dapm_widgets),
+               .dapm_routes            = nau8825_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(nau8825_dapm_routes),
+       },
 };
 
 static void nau8825_reset_chip(struct regmap *regmap)
index 33e1fc2d1598bcc0a0f19647644663c9035facfe..0b14efab6280dd88b7a72c7df84fb3625a15f650 100644 (file)
@@ -289,12 +289,14 @@ static const struct regmap_config pcm1681_regmap = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
-       .controls               = pcm1681_controls,
-       .num_controls           = ARRAY_SIZE(pcm1681_controls),
-       .dapm_widgets           = pcm1681_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(pcm1681_dapm_widgets),
-       .dapm_routes            = pcm1681_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(pcm1681_dapm_routes),
+       .component_driver = {
+               .controls               = pcm1681_controls,
+               .num_controls           = ARRAY_SIZE(pcm1681_controls),
+               .dapm_widgets           = pcm1681_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pcm1681_dapm_widgets),
+               .dapm_routes            = pcm1681_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pcm1681_dapm_routes),
+       },
 };
 
 static const struct i2c_device_id pcm1681_i2c_id[] = {
index 88fbdd184aa0a5b6d2e6e5a757738e8442a8b0d0..b813a154ddd97e1c31f79e815a938db0538531e3 100644 (file)
@@ -206,12 +206,14 @@ const struct regmap_config pcm179x_regmap_config = {
 EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
 
 static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
-       .controls               = pcm179x_controls,
-       .num_controls           = ARRAY_SIZE(pcm179x_controls),
-       .dapm_widgets           = pcm179x_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(pcm179x_dapm_widgets),
-       .dapm_routes            = pcm179x_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(pcm179x_dapm_routes),
+       .component_driver = {
+               .controls               = pcm179x_controls,
+               .num_controls           = ARRAY_SIZE(pcm179x_controls),
+               .dapm_widgets           = pcm179x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pcm179x_dapm_widgets),
+               .dapm_routes            = pcm179x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pcm179x_dapm_routes),
+       },
 };
 
 int pcm179x_common_init(struct device *dev, struct regmap *regmap)
index 8fb445f33f6f2a23c0d30f15c37ef590609c91cc..708af05486f634012da081f78421b676b21d1f7c 100644 (file)
@@ -99,10 +99,12 @@ static struct snd_soc_dai_driver pcm3008_dai = {
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
-       .dapm_widgets = pcm3008_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets),
-       .dapm_routes = pcm3008_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = pcm3008_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pcm3008_dapm_widgets),
+               .dapm_routes            = pcm3008_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pcm3008_dapm_routes),
+       },
 };
 
 static int pcm3008_codec_probe(struct platform_device *pdev)
index 992a77edcd5d1ff90d8857860972dadc4b86d7d7..39bc02d5bc5dd54880ddee611cbf89000432f5e8 100644 (file)
@@ -599,12 +599,14 @@ EXPORT_SYMBOL_GPL(pcm3168a_regmap);
 
 static const struct snd_soc_codec_driver pcm3168a_driver = {
        .idle_bias_off = true,
-       .controls = pcm3168a_snd_controls,
-       .num_controls = ARRAY_SIZE(pcm3168a_snd_controls),
-       .dapm_widgets = pcm3168a_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets),
-       .dapm_routes = pcm3168a_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes)
+       .component_driver = {
+               .controls               = pcm3168a_snd_controls,
+               .num_controls           = ARRAY_SIZE(pcm3168a_snd_controls),
+               .dapm_widgets           = pcm3168a_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pcm3168a_dapm_widgets),
+               .dapm_routes            = pcm3168a_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pcm3168a_dapm_routes)
+       },
 };
 
 int pcm3168a_probe(struct device *dev, struct regmap *regmap)
index 047c48953a20cd4075000ac294a17fe59baedcde..72b19e62f6267698aea45d2410d616d91c1825cb 100644 (file)
@@ -1348,12 +1348,14 @@ static struct snd_soc_codec_driver pcm512x_codec_driver = {
        .set_bias_level = pcm512x_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = pcm512x_controls,
-       .num_controls = ARRAY_SIZE(pcm512x_controls),
-       .dapm_widgets = pcm512x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
-       .dapm_routes = pcm512x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
+       .component_driver = {
+               .controls               = pcm512x_controls,
+               .num_controls           = ARRAY_SIZE(pcm512x_controls),
+               .dapm_widgets           = pcm512x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pcm512x_dapm_widgets),
+               .dapm_routes            = pcm512x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pcm512x_dapm_routes),
+       },
 };
 
 static const struct regmap_range_cfg pcm512x_range = {
index 74c0e4eb3788dca775f17207c6c7fb35f5629cab..9c365a7f758dbb9f1227c726f148b19672402f7c 100644 (file)
@@ -1053,12 +1053,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt286 = {
        .resume = rt286_resume,
        .set_bias_level = rt286_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt286_snd_controls,
-       .num_controls = ARRAY_SIZE(rt286_snd_controls),
-       .dapm_widgets = rt286_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
-       .dapm_routes = rt286_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
+       .component_driver = {
+               .controls               = rt286_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt286_snd_controls),
+               .dapm_widgets           = rt286_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt286_dapm_widgets),
+               .dapm_routes            = rt286_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt286_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt286_regmap = {
index f80cfe4d2ef2f050e1b3d43103fcadc789144ce1..55558643166fda708ccb781daffcc9ed40806bc2 100644 (file)
@@ -1095,12 +1095,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt298 = {
        .resume = rt298_resume,
        .set_bias_level = rt298_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt298_snd_controls,
-       .num_controls = ARRAY_SIZE(rt298_snd_controls),
-       .dapm_widgets = rt298_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
-       .dapm_routes = rt298_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
+       .component_driver = {
+               .controls               = rt298_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt298_snd_controls),
+               .dapm_widgets           = rt298_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt298_dapm_widgets),
+               .dapm_routes            = rt298_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt298_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt298_regmap = {
index 77ff8ebe6dfbed557c856cf18de6aeccf810654f..09103aab0cb2639486cb59f746619c9ea743890a 100644 (file)
@@ -236,7 +236,7 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
        return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
 }
 
-static struct snd_pcm_ops rt5514_spi_pcm_ops = {
+static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
        .open           = rt5514_spi_pcm_open,
        .hw_params      = rt5514_spi_hw_params,
        .hw_free        = rt5514_spi_hw_free,
index 7162f05101d9e8859b4451aa20af7e3233b9270a..f24b7cfd3a89fabab6f3c92d2907931a00e028b7 100644 (file)
@@ -278,7 +278,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
        8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0)
 );
 
-static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
 
 static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
@@ -352,10 +352,10 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
        SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
                RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
        SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1,
-               RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
+               RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 63, 0,
                adc_vol_tlv),
        SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1,
-               RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
+               RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 63, 0,
                adc_vol_tlv),
        SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
                rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
@@ -1023,12 +1023,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
        .probe = rt5514_probe,
        .idle_bias_off = true,
        .set_bias_level = rt5514_set_bias_level,
-       .controls = rt5514_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5514_snd_controls),
-       .dapm_widgets = rt5514_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets),
-       .dapm_routes = rt5514_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes),
+       .component_driver = {
+               .controls               = rt5514_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5514_snd_controls),
+               .dapm_widgets           = rt5514_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5514_dapm_widgets),
+               .dapm_routes            = rt5514_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5514_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5514_i2c_regmap = {
index 68883c68e999cc42ce64ff15cd88720936352c35..229de0e2c88c614695b5bab80d18e7b5ac1dbd62 100644 (file)
 #define RT5514_AD_AD_MIX_BIT                   10
 #define RT5514_AD_AD_MUTE                      (0x1 << 7)
 #define RT5514_AD_AD_MUTE_BIT                  7
-#define RT5514_AD_GAIN_MASK                    (0x7f << 0)
-#define RT5514_AD_GAIN_SFT                     0
+#define RT5514_AD_GAIN_MASK                    (0x3f << 1)
+#define RT5514_AD_GAIN_SFT                     1
 
 /*  RT5514_ANA_CTRL_MICBST (0x2220) */
 #define RT5514_SEL_BSTL_MASK                   (0xf << 4)
index f527b5b2817ba4f432766acd677c1e84c23174d5..e92a1490fa68e8144bdf30f8e9bee4c5d0576040 100644 (file)
@@ -1302,12 +1302,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
        .resume = rt5616_resume,
        .set_bias_level = rt5616_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5616_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5616_snd_controls),
-       .dapm_widgets = rt5616_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets),
-       .dapm_routes = rt5616_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes),
+       .component_driver = {
+               .controls               = rt5616_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5616_snd_controls),
+               .dapm_widgets           = rt5616_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5616_dapm_widgets),
+               .dapm_routes            = rt5616_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5616_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5616_regmap = {
index 1be2bab7dee3a1b20bc30508938f5b28f02a5998..0e418089c053ca716619da9ad79aca4090f8415b 100644 (file)
@@ -1657,12 +1657,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
        .probe = rt5631_probe,
        .set_bias_level = rt5631_set_bias_level,
        .suspend_bias_off = true,
-       .controls = rt5631_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5631_snd_controls),
-       .dapm_widgets = rt5631_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
-       .dapm_routes = rt5631_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
+       .component_driver = {
+               .controls               = rt5631_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5631_snd_controls),
+               .dapm_widgets           = rt5631_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5631_dapm_widgets),
+               .dapm_routes            = rt5631_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5631_dapm_routes),
+       },
 };
 
 static const struct i2c_device_id rt5631_i2c_id[] = {
index 09e8988bbb2d0fb3ddb4fcea1667fe8b56703a39..3cc1135fc2cd1cba29a5c39b5060b3899abe90df 100644 (file)
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
        case RT5640_SCLK_S_PLL1:
                reg_val |= RT5640_SCLK_SRC_PLL1;
                break;
+       case RT5640_SCLK_S_RCCLK:
+               reg_val |= RT5640_SCLK_SRC_RCCLK;
+               break;
        default:
                dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
@@ -2261,12 +2264,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
        .resume = rt5640_resume,
        .set_bias_level = rt5640_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5640_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5640_snd_controls),
-       .dapm_widgets = rt5640_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets),
-       .dapm_routes = rt5640_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes),
+       .component_driver = {
+               .controls               = rt5640_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5640_snd_controls),
+               .dapm_widgets           = rt5640_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5640_dapm_widgets),
+               .dapm_routes            = rt5640_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5640_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5640_regmap = {
index 58b664b06c166caecdac1400be9d9f0e4eebb190..90c88711c72a227a2442d0a93e82782fb3439770 100644 (file)
 #define RT5640_SCLK_SRC_SFT                    14
 #define RT5640_SCLK_SRC_MCLK                   (0x0 << 14)
 #define RT5640_SCLK_SRC_PLL1                   (0x1 << 14)
+#define RT5640_SCLK_SRC_RCCLK                  (0x2 << 14)
 #define RT5640_PLL1_SRC_MASK                   (0x3 << 12)
 #define RT5640_PLL1_SRC_SFT                    12
 #define RT5640_PLL1_SRC_MCLK                   (0x0 << 12)
index 490bfe66134636ecf3efaaee3a5c741ce87e5b1e..10c2a564a715dc82e198a4bb50c5691662685c7a 100644 (file)
@@ -3484,12 +3484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
        .resume = rt5645_resume,
        .set_bias_level = rt5645_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5645_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5645_snd_controls),
-       .dapm_widgets = rt5645_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets),
-       .dapm_routes = rt5645_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes),
+       .component_driver = {
+               .controls               = rt5645_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5645_snd_controls),
+               .dapm_widgets           = rt5645_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5645_dapm_widgets),
+               .dapm_routes            = rt5645_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5645_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5645_regmap = {
index 7a6197042423b6713ed8e38f72b47922c8d34bc7..f5d34153e21fc4cf10c3e9d45436ad9e14efa166 100644 (file)
@@ -1712,12 +1712,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5651 = {
        .resume = rt5651_resume,
        .set_bias_level = rt5651_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5651_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5651_snd_controls),
-       .dapm_widgets = rt5651_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets),
-       .dapm_routes = rt5651_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes),
+       .component_driver = {
+               .controls               = rt5651_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5651_snd_controls),
+               .dapm_widgets           = rt5651_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5651_dapm_widgets),
+               .dapm_routes            = rt5651_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5651_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5651_regmap = {
index 1b30914c2d916ddd70db50b6e6203eeb0ef486e3..db54550aed60eaee1e724c291d60b358469716d2 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -3565,7 +3566,9 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 static int rt5659_set_bias_level(struct snd_soc_codec *codec,
                        enum snd_soc_bias_level level)
 {
+       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
        struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       int ret;
 
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
@@ -3582,6 +3585,17 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
                        RT5659_PWR_FV1 | RT5659_PWR_FV2);
                break;
 
+       case SND_SOC_BIAS_STANDBY:
+               if (dapm->bias_level == SND_SOC_BIAS_OFF) {
+                       ret = clk_prepare_enable(rt5659->mclk);
+                       if (ret) {
+                               dev_err(codec->dev,
+                                       "failed to enable MCLK: %d\n", ret);
+                               return ret;
+                       }
+               }
+               break;
+
        case SND_SOC_BIAS_OFF:
                regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
                        RT5659_PWR_LDO, 0);
@@ -3591,6 +3605,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
                        RT5659_PWR_MB | RT5659_PWR_VREF2);
                regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
                        RT5659_DIG_GATE_CTRL, 0);
+               clk_disable_unprepare(rt5659->mclk);
                break;
 
        default:
@@ -3722,12 +3737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
        .resume = rt5659_resume,
        .set_bias_level = rt5659_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5659_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5659_snd_controls),
-       .dapm_widgets = rt5659_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets),
-       .dapm_routes = rt5659_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
+       .component_driver = {
+               .controls               = rt5659_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5659_snd_controls),
+               .dapm_widgets           = rt5659_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5659_dapm_widgets),
+               .dapm_routes            = rt5659_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5659_dapm_routes),
+       },
 };
 
 
@@ -4020,6 +4037,15 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
 
        regmap_write(rt5659->regmap, RT5659_RESET, 0);
 
+       /* Check if MCLK provided */
+       rt5659->mclk = devm_clk_get(&i2c->dev, "mclk");
+       if (IS_ERR(rt5659->mclk)) {
+               if (PTR_ERR(rt5659->mclk) != -ENOENT)
+                       return PTR_ERR(rt5659->mclk);
+               /* Otherwise mark the mclk pointer to NULL */
+               rt5659->mclk = NULL;
+       }
+
        rt5659_calibrate(rt5659);
 
        /* line in diff mode*/
@@ -4163,6 +4189,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
                if (ret)
                        dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
 
+               /* Enable IRQ output for GPIO1 pin any way */
+               regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
+                                  RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
        }
 
        return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
index d31c9e5bcec8adf93731532b1ef036da70ac959c..d69b0eb5a334474575e2a1f62b02b20cebeecedb 100644 (file)
@@ -1796,6 +1796,7 @@ struct rt5659_priv {
        struct gpio_desc *gpiod_reset;
        struct snd_soc_jack *hs_jack;
        struct delayed_work jack_detect_work;
+       struct clk *mclk;
 
        int sysclk;
        int sysclk_src;
index 8ef467f64f03b309082c66f0d43007eb39cb3aba..49caf1393aebd5d837a102a199a76f05a11712c0 100644 (file)
@@ -2777,12 +2777,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
        .resume = rt5670_resume,
        .set_bias_level = rt5670_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5670_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5670_snd_controls),
-       .dapm_widgets = rt5670_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets),
-       .dapm_routes = rt5670_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes),
+       .component_driver = {
+               .controls               = rt5670_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5670_snd_controls),
+               .dapm_widgets           = rt5670_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5670_dapm_widgets),
+               .dapm_routes            = rt5670_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5670_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5670_regmap = {
index da9483c1c6fbbf53edbf78c6570618815ace8d69..7df422c60a7c479f3018523b9413b88d8a9d8bc7 100644 (file)
@@ -4657,7 +4657,7 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
        return regmap_irq_get_virq(data, irq);
 }
 
-static struct gpio_chip rt5677_template_chip = {
+static const struct gpio_chip rt5677_template_chip = {
        .label                  = "rt5677",
        .owner                  = THIS_MODULE,
        .direction_output       = rt5677_gpio_direction_out,
@@ -4974,12 +4974,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5677 = {
        .resume = rt5677_resume,
        .set_bias_level = rt5677_set_bias_level,
        .idle_bias_off = true,
-       .controls = rt5677_snd_controls,
-       .num_controls = ARRAY_SIZE(rt5677_snd_controls),
-       .dapm_widgets = rt5677_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets),
-       .dapm_routes = rt5677_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes),
+       .component_driver = {
+               .controls               = rt5677_snd_controls,
+               .num_controls           = ARRAY_SIZE(rt5677_snd_controls),
+               .dapm_widgets           = rt5677_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(rt5677_dapm_widgets),
+               .dapm_routes            = rt5677_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(rt5677_dapm_routes),
+       },
 };
 
 static const struct regmap_config rt5677_regmap_physical = {
index 527b759c1562dab6229f1d4c345d1ac21530c62b..1589325855bc10ca41c1180de3e06b745d32ee19 100644 (file)
@@ -411,6 +411,8 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
                        0, 8,
                        0x7f, 1,
                        headphone_volume),
+       SOC_SINGLE("Headphone Playback Switch", SGTL5000_CHIP_ANA_CTRL,
+                       4, 1, 1),
        SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
                        5, 1, 0),
 
@@ -423,6 +425,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
                        SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT,
                        0x1f, 1,
                        lineout_volume),
+       SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1),
 };
 
 /* mute the codec used by alsa core */
@@ -1151,12 +1154,14 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
        .remove = sgtl5000_remove,
        .set_bias_level = sgtl5000_set_bias_level,
        .suspend_bias_off = true,
-       .controls = sgtl5000_snd_controls,
-       .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
-       .dapm_widgets = sgtl5000_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
-       .dapm_routes = sgtl5000_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
+       .component_driver = {
+               .controls               = sgtl5000_snd_controls,
+               .num_controls           = ARRAY_SIZE(sgtl5000_snd_controls),
+               .dapm_widgets           = sgtl5000_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(sgtl5000_dapm_widgets),
+               .dapm_routes            = sgtl5000_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(sgtl5000_dapm_routes),
+       },
 };
 
 static const struct regmap_config sgtl5000_regmap = {
index a8402d0af0ea814fd9965e0c0e3d0f7e4d668dd2..5344f4aa8fde74bdb78f302aa711100e391cd3d5 100644 (file)
@@ -238,10 +238,12 @@ static struct regmap *si476x_get_regmap(struct device *dev)
 
 static struct snd_soc_codec_driver soc_codec_dev_si476x = {
        .get_regmap = si476x_get_regmap,
-       .dapm_widgets = si476x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets),
-       .dapm_routes = si476x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = si476x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(si476x_dapm_widgets),
+               .dapm_routes            = si476x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(si476x_dapm_routes),
+       },
 };
 
 static int si476x_platform_probe(struct platform_device *pdev)
index 3a7de0159f2464f14f124de3cc09741e0f49e612..eae54c37cff948fcb38f0665d0a3dfd16e1acba1 100644 (file)
@@ -888,12 +888,14 @@ static struct snd_soc_codec_driver sn95031_codec = {
        .set_bias_level = sn95031_set_vaud_bias,
        .idle_bias_off  = true,
 
-       .controls       = sn95031_snd_controls,
-       .num_controls   = ARRAY_SIZE(sn95031_snd_controls),
-       .dapm_widgets   = sn95031_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(sn95031_dapm_widgets),
-       .dapm_routes    = sn95031_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(sn95031_audio_map),
+       .component_driver = {
+               .controls               = sn95031_snd_controls,
+               .num_controls           = ARRAY_SIZE(sn95031_snd_controls),
+               .dapm_widgets           = sn95031_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(sn95031_dapm_widgets),
+               .dapm_routes            = sn95031_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(sn95031_audio_map),
+       },
 };
 
 static int sn95031_device_probe(struct platform_device *pdev)
index 3ec41ccbf4e2e8571956daa27a37b3acddd6a3e9..234f87b54838b964d6c42ab5db5c0214824b5707 100644 (file)
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dir_routes[] = {
                        SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
 
 static struct snd_soc_codec_driver soc_codec_spdif_dir = {
-       .dapm_widgets = dir_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(dir_widgets),
-       .dapm_routes = dir_routes,
-       .num_dapm_routes = ARRAY_SIZE(dir_routes),
+       .component_driver = {
+               .dapm_widgets           = dir_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(dir_widgets),
+               .dapm_routes            = dir_routes,
+               .num_dapm_routes        = ARRAY_SIZE(dir_routes),
+       },
 };
 
 static struct snd_soc_dai_driver dir_stub_dai = {
index ef634a9ad673a599329dbb5f6a5cad3a95d2c7af..ee367536a4980a930984f386e515a84f3517de9f 100644 (file)
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dit_routes[] = {
 };
 
 static struct snd_soc_codec_driver soc_codec_spdif_dit = {
-       .dapm_widgets = dit_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(dit_widgets),
-       .dapm_routes = dit_routes,
-       .num_dapm_routes = ARRAY_SIZE(dit_routes),
+       .component_driver = {
+               .dapm_widgets           = dit_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(dit_widgets),
+               .dapm_routes            = dit_routes,
+               .num_dapm_routes        = ARRAY_SIZE(dit_routes),
+       },
 };
 
 static struct snd_soc_dai_driver dit_stub_dai = {
index e2e0bfa7ec20f9df40a3e4385e3edf44e3f0d15d..38a85f3adc802ffea8c577065e69e9f9617ec081 100644 (file)
@@ -715,12 +715,14 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = {
        .set_sysclk = ssm2518_set_sysclk,
        .idle_bias_off = true,
 
-       .controls = ssm2518_snd_controls,
-       .num_controls = ARRAY_SIZE(ssm2518_snd_controls),
-       .dapm_widgets = ssm2518_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets),
-       .dapm_routes = ssm2518_routes,
-       .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
+       .component_driver = {
+               .controls               = ssm2518_snd_controls,
+               .num_controls           = ARRAY_SIZE(ssm2518_snd_controls),
+               .dapm_widgets           = ssm2518_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ssm2518_dapm_widgets),
+               .dapm_routes            = ssm2518_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ssm2518_routes),
+       },
 };
 
 static const struct regmap_config ssm2518_regmap_config = {
index 4452fea0b11857b7a6d004b3b1892a50aeba246f..993bde29ca1bcc6e611bf8d7b7b1f83caa0ce396 100644 (file)
@@ -597,12 +597,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
        .set_bias_level = ssm2602_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = ssm260x_snd_controls,
-       .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
-       .dapm_widgets = ssm260x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
-       .dapm_routes = ssm260x_routes,
-       .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
+       .component_driver = {
+               .controls               = ssm260x_snd_controls,
+               .num_controls           = ARRAY_SIZE(ssm260x_snd_controls),
+               .dapm_widgets           = ssm260x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ssm260x_dapm_widgets),
+               .dapm_routes            = ssm260x_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ssm260x_routes),
+       },
 };
 
 static bool ssm2602_register_volatile(struct device *dev, unsigned int reg)
index 080c78e88e102199cb9b8923f0556ce084ad22d8..2bb5a11c9ba19d1d81310558e2b78f550d3eafc9 100644 (file)
@@ -421,12 +421,14 @@ static struct snd_soc_codec_driver ssm4567_codec_driver = {
        .set_bias_level = ssm4567_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = ssm4567_snd_controls,
-       .num_controls = ARRAY_SIZE(ssm4567_snd_controls),
-       .dapm_widgets = ssm4567_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets),
-       .dapm_routes = ssm4567_routes,
-       .num_dapm_routes = ARRAY_SIZE(ssm4567_routes),
+       .component_driver = {
+               .controls               = ssm4567_snd_controls,
+               .num_controls           = ARRAY_SIZE(ssm4567_snd_controls),
+               .dapm_widgets           = ssm4567_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(ssm4567_dapm_widgets),
+               .dapm_routes            = ssm4567_routes,
+               .num_dapm_routes        = ARRAY_SIZE(ssm4567_routes),
+       },
 };
 
 static const struct regmap_config ssm4567_regmap_config = {
index a9844b2ac829d03ae4142a69b6b815fc9df02f44..0790ae8530d96dba77d25165aefb8f5f2ad88779 100644 (file)
@@ -991,12 +991,14 @@ static const struct snd_soc_codec_driver sta32x_codec = {
        .remove =               sta32x_remove,
        .set_bias_level =       sta32x_set_bias_level,
        .suspend_bias_off =     true,
-       .controls =             sta32x_snd_controls,
-       .num_controls =         ARRAY_SIZE(sta32x_snd_controls),
-       .dapm_widgets =         sta32x_dapm_widgets,
-       .num_dapm_widgets =     ARRAY_SIZE(sta32x_dapm_widgets),
-       .dapm_routes =          sta32x_dapm_routes,
-       .num_dapm_routes =      ARRAY_SIZE(sta32x_dapm_routes),
+       .component_driver = {
+               .controls =             sta32x_snd_controls,
+               .num_controls =         ARRAY_SIZE(sta32x_snd_controls),
+               .dapm_widgets =         sta32x_dapm_widgets,
+               .num_dapm_widgets =     ARRAY_SIZE(sta32x_dapm_widgets),
+               .dapm_routes =          sta32x_dapm_routes,
+               .num_dapm_routes =      ARRAY_SIZE(sta32x_dapm_routes),
+       },
 };
 
 static const struct regmap_config sta32x_regmap = {
index 33a4612f0a078747e620aeb991cb38404083fe58..9644c20f44e32dca38209693a088ed0585aa011c 100644 (file)
@@ -1057,12 +1057,14 @@ static const struct snd_soc_codec_driver sta350_codec = {
        .remove =               sta350_remove,
        .set_bias_level =       sta350_set_bias_level,
        .suspend_bias_off =     true,
-       .controls =             sta350_snd_controls,
-       .num_controls =         ARRAY_SIZE(sta350_snd_controls),
-       .dapm_widgets =         sta350_dapm_widgets,
-       .num_dapm_widgets =     ARRAY_SIZE(sta350_dapm_widgets),
-       .dapm_routes =          sta350_dapm_routes,
-       .num_dapm_routes =      ARRAY_SIZE(sta350_dapm_routes),
+       .component_driver = {
+               .controls =             sta350_snd_controls,
+               .num_controls =         ARRAY_SIZE(sta350_snd_controls),
+               .dapm_widgets =         sta350_dapm_widgets,
+               .num_dapm_widgets =     ARRAY_SIZE(sta350_dapm_widgets),
+               .dapm_routes =          sta350_dapm_routes,
+               .num_dapm_routes =      ARRAY_SIZE(sta350_dapm_routes),
+       },
 };
 
 static const struct regmap_config sta350_regmap = {
index 2cdaca943a8c488fceea517165f07aa0d47c8b60..d4b384e4b2664cf8b080ba5271fef8bcce0df5e3 100644 (file)
@@ -317,8 +317,10 @@ static const struct snd_soc_codec_driver sta529_codec_driver = {
        .set_bias_level = sta529_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = sta529_snd_controls,
-       .num_controls = ARRAY_SIZE(sta529_snd_controls),
+       .component_driver = {
+               .controls               = sta529_snd_controls,
+               .num_controls           = ARRAY_SIZE(sta529_snd_controls),
+       },
 };
 
 static const struct regmap_config sta529_regmap = {
index 0945c51df003df37f415b4cbf9d9076826f1c7b6..2c5941f3a23405c091ff09bccb9fd2be4a69989d 100644 (file)
@@ -320,8 +320,10 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec)
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
-       .controls = stac9766_snd_ac97_controls,
-       .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls),
+       .component_driver = {
+               .controls               = stac9766_snd_ac97_controls,
+               .num_controls           = ARRAY_SIZE(stac9766_snd_ac97_controls),
+       },
        .write = stac9766_ac97_write,
        .read = stac9766_ac97_read,
        .set_bias_level = stac9766_set_bias_level,
index 160d61a66204b25db880c0e7eb7618344026e81e..7b31ee9b82bc87beb493427049fc82d75e1127e8 100644 (file)
@@ -591,11 +591,11 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
        sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
 
        /* Set dapms*/
-       sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
-       sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
+       sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
+       sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
 
-       sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
-       sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
+       sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes;
+       sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
 
        /* Store context */
        dev_set_drvdata(&pdev->dev, drvdata);
index cc1d3981fa4b6b92c018d596a0aaac1192f141f1..baf455e8c2f7b038b0883e43184d12e99c46cfb7 100644 (file)
@@ -667,12 +667,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
        .resume = tas2552_resume,
        .ignore_pmdown_time = true,
 
-       .controls = tas2552_snd_controls,
-       .num_controls = ARRAY_SIZE(tas2552_snd_controls),
-       .dapm_widgets = tas2552_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets),
-       .dapm_routes = tas2552_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map),
+       .component_driver = {
+               .controls               = tas2552_snd_controls,
+               .num_controls           = ARRAY_SIZE(tas2552_snd_controls),
+               .dapm_widgets           = tas2552_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tas2552_dapm_widgets),
+               .dapm_routes            = tas2552_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(tas2552_audio_map),
+       },
 };
 
 static const struct regmap_config tas2552_regmap_config = {
index d49d25d5195796345bee582537fa3751d4eacfa6..b7de857abb16bd5fa4cc28abdf76332040a23234 100644 (file)
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
        val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios),
                             priv->mclk / priv->rate);
        if (val < 0) {
-               dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n");
+               dev_err(codec->dev, "Invalid MCLK / Fs ratio\n");
                return -EINVAL;
        }
 
@@ -890,12 +890,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
        .remove                 = tas5086_remove,
        .suspend                = tas5086_soc_suspend,
        .resume                 = tas5086_soc_resume,
-       .controls               = tas5086_controls,
-       .num_controls           = ARRAY_SIZE(tas5086_controls),
-       .dapm_widgets           = tas5086_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(tas5086_dapm_widgets),
-       .dapm_routes            = tas5086_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(tas5086_dapm_routes),
+       .component_driver = {
+               .controls               = tas5086_controls,
+               .num_controls           = ARRAY_SIZE(tas5086_controls),
+               .dapm_widgets           = tas5086_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tas5086_dapm_widgets),
+               .dapm_routes            = tas5086_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(tas5086_dapm_routes),
+       },
 };
 
 static const struct i2c_device_id tas5086_i2c_id[] = {
index d8baca3f8413d19bcdefd44a8917769bf484766f..df5e5cb33baaba035b1d9db577cbf772855ac3e9 100644 (file)
@@ -658,10 +658,12 @@ static const struct snd_soc_codec_driver tas571x_codec = {
        .set_bias_level = tas571x_set_bias_level,
        .idle_bias_off = true,
 
-       .dapm_widgets = tas571x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets),
-       .dapm_routes = tas571x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = tas571x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tas571x_dapm_widgets),
+               .dapm_routes            = tas571x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(tas571x_dapm_routes),
+       },
 };
 
 static struct snd_soc_dai_driver tas571x_dai = {
@@ -754,8 +756,8 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
 
        memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
-       priv->codec_driver.controls = priv->chip->controls;
-       priv->codec_driver.num_controls = priv->chip->num_controls;
+       priv->codec_driver.component_driver.controls = priv->chip->controls;
+       priv->codec_driver.component_driver.num_controls = priv->chip->num_controls;
 
        if (priv->chip->vol_reg_size == 2) {
                /*
index f54fb46b77c2f767896a6fb7b7b2ca7bf3c16598..c65b917598d2e20e7a93f3759c86e1f59bdf15f4 100644 (file)
@@ -489,12 +489,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = {
        .suspend = tas5720_suspend,
        .resume = tas5720_resume,
 
-       .controls = tas5720_snd_controls,
-       .num_controls = ARRAY_SIZE(tas5720_snd_controls),
-       .dapm_widgets = tas5720_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets),
-       .dapm_routes = tas5720_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map),
+       .component_driver = {
+               .controls               = tas5720_snd_controls,
+               .num_controls           = ARRAY_SIZE(tas5720_snd_controls),
+               .dapm_widgets           = tas5720_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tas5720_dapm_widgets),
+               .dapm_routes            = tas5720_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(tas5720_audio_map),
+       },
 };
 
 /* PCM rates supported by the TAS5720 driver */
index cb5310d89c0f4fd33e59d93c04eefb324f00c61e..95e0a7abeb7ae290b9979833d29e41fc537dc251 100644 (file)
@@ -231,13 +231,14 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
 };
 
 static const struct snd_soc_codec_driver tfa9879_codec = {
-       .controls = tfa9879_controls,
-       .num_controls = ARRAY_SIZE(tfa9879_controls),
-
-       .dapm_widgets = tfa9879_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets),
-       .dapm_routes = tfa9879_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes),
+       .component_driver = {
+               .controls               = tfa9879_controls,
+               .num_controls           = ARRAY_SIZE(tfa9879_controls),
+               .dapm_widgets           = tfa9879_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tfa9879_dapm_widgets),
+               .dapm_routes            = tfa9879_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(tfa9879_dapm_routes),
+       },
 };
 
 static const struct regmap_config tfa9879_regmap = {
index cd8c02b6e4de471ceb7b3d33b8687fb98310b8ea..410cae0f2060474313872d6b9110bf05d3368e43 100644 (file)
@@ -583,12 +583,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
        .set_bias_level = tlv320aic23_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = tlv320aic23_snd_controls,
-       .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls),
-       .dapm_widgets = tlv320aic23_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
-       .dapm_routes = tlv320aic23_intercon,
-       .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
+       .component_driver = {
+               .controls               = tlv320aic23_snd_controls,
+               .num_controls           = ARRAY_SIZE(tlv320aic23_snd_controls),
+               .dapm_widgets           = tlv320aic23_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tlv320aic23_dapm_widgets),
+               .dapm_routes            = tlv320aic23_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(tlv320aic23_intercon),
+       },
 };
 
 int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
index 2c904d7150ad7968b0f15928ba68c4e6ddcc16b5..14aa96d417198500bf94a037e58592fad654119f 100644 (file)
@@ -321,12 +321,14 @@ static int aic26_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver aic26_soc_codec_dev = {
        .probe = aic26_probe,
-       .controls = aic26_snd_controls,
-       .num_controls = ARRAY_SIZE(aic26_snd_controls),
-       .dapm_widgets = tlv320aic26_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets),
-       .dapm_routes = tlv320aic26_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
+       .component_driver = {
+               .controls               = aic26_snd_controls,
+               .num_controls           = ARRAY_SIZE(aic26_snd_controls),
+               .dapm_widgets           = tlv320aic26_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(tlv320aic26_dapm_widgets),
+               .dapm_routes            = tlv320aic26_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(tlv320aic26_dapm_routes),
+       },
 };
 
 static const struct regmap_config aic26_regmap = {
index 3c5e1df01c19a31bb1069b8c1731d49e4fbee5e5..e46fb472e48dc965c8378faca1bceed69bdb1d98 100644 (file)
@@ -1114,12 +1114,14 @@ static struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
        .set_bias_level         = aic31xx_set_bias_level,
        .suspend_bias_off       = true,
 
-       .controls               = aic31xx_snd_controls,
-       .num_controls           = ARRAY_SIZE(aic31xx_snd_controls),
-       .dapm_widgets           = aic31xx_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(aic31xx_dapm_widgets),
-       .dapm_routes            = aic31xx_audio_map,
-       .num_dapm_routes        = ARRAY_SIZE(aic31xx_audio_map),
+       .component_driver = {
+               .controls               = aic31xx_snd_controls,
+               .num_controls           = ARRAY_SIZE(aic31xx_snd_controls),
+               .dapm_widgets           = aic31xx_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(aic31xx_dapm_widgets),
+               .dapm_routes            = aic31xx_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(aic31xx_audio_map),
+       },
 };
 
 static const struct snd_soc_dai_ops aic31xx_dai_ops = {
index 85d4978d0384e318bfce59502e186eaf3359ae2b..28fdfc5ec54430d82083bc2e62d727ae5b046699 100644 (file)
@@ -797,12 +797,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
        .set_bias_level = aic32x4_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = aic32x4_snd_controls,
-       .num_controls = ARRAY_SIZE(aic32x4_snd_controls),
-       .dapm_widgets = aic32x4_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
-       .dapm_routes = aic32x4_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
+       .component_driver = {
+               .controls               = aic32x4_snd_controls,
+               .num_controls           = ARRAY_SIZE(aic32x4_snd_controls),
+               .dapm_widgets           = aic32x4_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(aic32x4_dapm_widgets),
+               .dapm_routes            = aic32x4_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(aic32x4_dapm_routes),
+       },
 };
 
 static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
index a564759845f980119a29c49633cb537ef685bcd9..5a8d96ec058c5e5464a251d86edcc2920c5e14c7 100644 (file)
@@ -1670,12 +1670,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
        .idle_bias_off = true,
        .probe = aic3x_probe,
        .remove = aic3x_remove,
-       .controls = aic3x_snd_controls,
-       .num_controls = ARRAY_SIZE(aic3x_snd_controls),
-       .dapm_widgets = aic3x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
-       .dapm_routes = intercon,
-       .num_dapm_routes = ARRAY_SIZE(intercon),
+       .component_driver = {
+               .controls               = aic3x_snd_controls,
+               .num_controls           = ARRAY_SIZE(aic3x_snd_controls),
+               .dapm_widgets           = aic3x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(aic3x_dapm_widgets),
+               .dapm_routes            = intercon,
+               .num_dapm_routes        = ARRAY_SIZE(intercon),
+       },
 };
 
 /*
index f7a6ce7e5fb12b7ab183428b28d6c69409676d08..d64eac74d1cc7c85c46023a1474a497a2108664d 100644 (file)
@@ -1453,12 +1453,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
        .probe = dac33_soc_probe,
        .remove = dac33_soc_remove,
 
-       .controls = dac33_snd_controls,
-       .num_controls = ARRAY_SIZE(dac33_snd_controls),
-       .dapm_widgets = dac33_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets),
-       .dapm_routes = audio_map,
-       .num_dapm_routes = ARRAY_SIZE(audio_map),
+       .component_driver = {
+               .controls               = dac33_snd_controls,
+               .num_controls           = ARRAY_SIZE(dac33_snd_controls),
+               .dapm_widgets           = dac33_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(dac33_dapm_widgets),
+               .dapm_routes            = audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(audio_map),
+       },
 };
 
 #define DAC33_RATES    (SNDRV_PCM_RATE_44100 | \
index a5a4e9f75c57f89e88f3047d980cf286f36569af..a2104d68169d9e6bc9aa30fe8269070a6dc88e40 100644 (file)
@@ -2199,12 +2199,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
        .set_bias_level = twl4030_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = twl4030_snd_controls,
-       .num_controls = ARRAY_SIZE(twl4030_snd_controls),
-       .dapm_widgets = twl4030_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets),
-       .dapm_routes = intercon,
-       .num_dapm_routes = ARRAY_SIZE(intercon),
+       .component_driver = {
+               .controls               = twl4030_snd_controls,
+               .num_controls           = ARRAY_SIZE(twl4030_snd_controls),
+               .dapm_widgets           = twl4030_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(twl4030_dapm_widgets),
+               .dapm_routes            = intercon,
+               .num_dapm_routes        = ARRAY_SIZE(intercon),
+       },
 };
 
 static int twl4030_codec_probe(struct platform_device *pdev)
index 1f7081043566fe8f6d7557e730009e9b7de6f84a..748036e851ea4d129266ca1e4d97b38e387c4eed 100644 (file)
@@ -1156,12 +1156,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
        .suspend_bias_off = true,
        .ignore_pmdown_time = true,
 
-       .controls = twl6040_snd_controls,
-       .num_controls = ARRAY_SIZE(twl6040_snd_controls),
-       .dapm_widgets = twl6040_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
-       .dapm_routes = intercon,
-       .num_dapm_routes = ARRAY_SIZE(intercon),
+       .component_driver = {
+               .controls               = twl6040_snd_controls,
+               .num_controls           = ARRAY_SIZE(twl6040_snd_controls),
+               .dapm_widgets           = twl6040_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(twl6040_dapm_widgets),
+               .dapm_routes            = intercon,
+               .num_dapm_routes        = ARRAY_SIZE(intercon),
+       },
 };
 
 static int twl6040_codec_probe(struct platform_device *pdev)
index e4c694c758b810e4ae041436fdb364baf4684fd6..5fdee874406d72b1d444a9e3823dbe34c41e66cf 100644 (file)
@@ -523,10 +523,12 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
        .set_bias_level = uda134x_set_bias_level,
        .suspend_bias_off = true,
 
-       .dapm_widgets = uda134x_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets),
-       .dapm_routes = uda134x_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = uda134x_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(uda134x_dapm_widgets),
+               .dapm_routes            = uda134x_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(uda134x_dapm_routes),
+       },
 };
 
 static const struct regmap_config uda134x_regmap_config = {
@@ -544,6 +546,7 @@ static int uda134x_codec_probe(struct platform_device *pdev)
 {
        struct uda134x_platform_data *pd = pdev->dev.platform_data;
        struct uda134x_priv *uda134x;
+       int ret;
 
        if (!pd) {
                dev_err(&pdev->dev, "Missing L3 bitbang function\n");
@@ -557,6 +560,12 @@ static int uda134x_codec_probe(struct platform_device *pdev)
        uda134x->pd = pd;
        platform_set_drvdata(pdev, uda134x);
 
+       if (pd->l3.use_gpios) {
+               ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3);
+               if (ret < 0)
+                       return ret;
+       }
+
        uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd,
                &uda134x_regmap_config);
        if (IS_ERR(uda134x->regmap))
index 35f0469ebb16a37af8e146bb4e16be1c5c457192..533e3bb444e4d2ee05ee6772db636539cb726af0 100644 (file)
@@ -765,12 +765,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
        .reg_cache_default = uda1380_reg,
        .reg_cache_step = 1,
 
-       .controls = uda1380_snd_controls,
-       .num_controls = ARRAY_SIZE(uda1380_snd_controls),
-       .dapm_widgets = uda1380_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
-       .dapm_routes = uda1380_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
+       .component_driver = {
+               .controls               = uda1380_snd_controls,
+               .num_controls           = ARRAY_SIZE(uda1380_snd_controls),
+               .dapm_widgets           = uda1380_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(uda1380_dapm_widgets),
+               .dapm_routes            = uda1380_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(uda1380_dapm_routes),
+       },
 };
 
 #if IS_ENABLED(CONFIG_I2C)
index 1b79778098d29ffbb377efc24576825cdfe8038c..fcffb6e707d9b8fcdacddb77d445eb5d738837ef 100644 (file)
@@ -484,12 +484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
        .probe = wl1273_probe,
        .remove = wl1273_remove,
 
-       .controls = wl1273_controls,
-       .num_controls = ARRAY_SIZE(wl1273_controls),
-       .dapm_widgets = wl1273_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),
-       .dapm_routes = wl1273_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),
+       .component_driver = {
+               .controls               = wl1273_controls,
+               .num_controls           = ARRAY_SIZE(wl1273_controls),
+               .dapm_widgets           = wl1273_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wl1273_dapm_widgets),
+               .dapm_routes            = wl1273_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wl1273_dapm_routes),
+       },
 };
 
 static int wl1273_platform_probe(struct platform_device *pdev)
index e3c34bdc277272cac380e0e0b6a8765f4749ab32..0eb5dcf4c29ddfdebf4cb4323d5a640652051b14 100644 (file)
@@ -789,16 +789,18 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
 
 static int wm0010_probe(struct snd_soc_codec *codec);
 
-static struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
        .probe = wm0010_probe,
        .set_bias_level = wm0010_set_bias_level,
        .set_sysclk = wm0010_set_sysclk,
        .idle_bias_off = true,
 
-       .dapm_widgets = wm0010_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets),
-       .dapm_routes = wm0010_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = wm0010_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm0010_dapm_widgets),
+               .dapm_routes            = wm0010_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm0010_dapm_routes),
+       },
 };
 
 #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
index ec45c5b220b100263f380800f1cc27f731861ffc..cf5f0580df6a852225ef70f39a6af22fe1255cc9 100644 (file)
@@ -141,12 +141,13 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = {
        .ops = &wm1250_ev1_ops,
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
-       .dapm_widgets = wm1250_ev1_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
-       .dapm_routes = wm1250_ev1_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
-
+static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
+       .component_driver = {
+               .dapm_widgets           = wm1250_ev1_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
+               .dapm_routes            = wm1250_ev1_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm1250_ev1_dapm_routes),
+       },
        .set_bias_level = wm1250_ev1_set_bias_level,
        .idle_bias_off = true,
 };
index f2664396be6fd752c3fa62f398a6e2e1857eef91..23cde3a0dc112427cdc5eec64619eb32b43a4595 100644 (file)
@@ -799,18 +799,20 @@ static int wm2000_remove(struct snd_soc_codec *codec)
        return wm2000_anc_transition(wm2000, ANC_OFF);
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
        .probe = wm2000_probe,
        .remove = wm2000_remove,
        .suspend = wm2000_suspend,
        .resume = wm2000_resume,
 
-       .dapm_widgets = wm2000_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
-       .dapm_routes = wm2000_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map),
-       .controls = wm2000_controls,
-       .num_controls = ARRAY_SIZE(wm2000_controls),
+       .component_driver = {
+               .controls               = wm2000_controls,
+               .num_controls           = ARRAY_SIZE(wm2000_controls),
+               .dapm_widgets           = wm2000_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm2000_dapm_widgets),
+               .dapm_routes            = wm2000_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(wm2000_audio_map),
+       },
 };
 
 static int wm2000_i2c_probe(struct i2c_client *i2c,
index fd1439ecb50ad312e24c9bf7e735b7728c96d6c9..606bf88abfc444a9036695eebb0e459419041997 100644 (file)
@@ -2103,7 +2103,7 @@ static struct snd_soc_dai_driver wm2200_dai = {
        .ops = &wm2200_dai_ops,
 };
 
-static struct snd_soc_codec_driver soc_codec_wm2200 = {
+static const struct snd_soc_codec_driver soc_codec_wm2200 = {
        .probe = wm2200_probe,
 
        .idle_bias_off = true,
@@ -2111,12 +2111,14 @@ static struct snd_soc_codec_driver soc_codec_wm2200 = {
        .set_sysclk = wm2200_set_sysclk,
        .set_pll = wm2200_set_fll,
 
-       .controls = wm2200_snd_controls,
-       .num_controls = ARRAY_SIZE(wm2200_snd_controls),
-       .dapm_widgets = wm2200_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
-       .dapm_routes = wm2200_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
+       .component_driver = {
+               .controls               = wm2200_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm2200_snd_controls),
+               .dapm_widgets           = wm2200_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm2200_dapm_widgets),
+               .dapm_routes            = wm2200_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm2200_dapm_routes),
+       },
 };
 
 static irqreturn_t wm2200_irq(int irq, void *data)
index 512a9d25fe6f34e82aeaeb0065673aa7a43c931f..560575000cc5e5aef666570c78e1f8df714ad718 100644 (file)
@@ -2285,7 +2285,7 @@ static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
                                  (1 << WM5100_GP1_DIR_SHIFT));
 }
 
-static struct gpio_chip wm5100_template_chip = {
+static const struct gpio_chip wm5100_template_chip = {
        .label                  = "wm5100",
        .owner                  = THIS_MODULE,
        .direction_output       = wm5100_gpio_direction_out,
@@ -2381,7 +2381,7 @@ static int wm5100_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
        .probe =        wm5100_probe,
        .remove =       wm5100_remove,
 
@@ -2390,12 +2390,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
        .idle_bias_off = 1,
 
        .seq_notifier = wm5100_seq_notifier,
-       .controls = wm5100_snd_controls,
-       .num_controls = ARRAY_SIZE(wm5100_snd_controls),
-       .dapm_widgets = wm5100_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
-       .dapm_routes = wm5100_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
+       .component_driver = {
+               .controls               = wm5100_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm5100_snd_controls),
+               .dapm_widgets           = wm5100_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm5100_dapm_widgets),
+               .dapm_routes            = wm5100_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm5100_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm5100_regmap = {
index 846deed6af417c7fcca17f35960679acb1ac4013..ed03ed27d3815be081fb13fb4a6945a7701fac09 100644 (file)
@@ -1521,6 +1521,16 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        { "IN3L", NULL, "SYSCLK" },
        { "IN3R", NULL, "SYSCLK" },
 
+       { "ASRC1L", NULL, "SYSCLK" },
+       { "ASRC1R", NULL, "SYSCLK" },
+       { "ASRC2L", NULL, "SYSCLK" },
+       { "ASRC2R", NULL, "SYSCLK" },
+
+       { "ASRC1L", NULL, "ASYNCCLK" },
+       { "ASRC1R", NULL, "ASYNCCLK" },
+       { "ASRC2L", NULL, "ASYNCCLK" },
+       { "ASRC2R", NULL, "ASYNCCLK" },
+
        { "MICBIAS1", NULL, "MICVDD" },
        { "MICBIAS2", NULL, "MICVDD" },
        { "MICBIAS3", NULL, "MICVDD" },
@@ -1990,7 +2000,7 @@ static struct regmap *wm5102_get_regmap(struct device *dev)
        return priv->core.arizona->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
        .probe = wm5102_codec_probe,
        .remove = wm5102_codec_remove,
        .get_regmap = wm5102_get_regmap,
@@ -2000,12 +2010,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
        .set_sysclk = arizona_set_sysclk,
        .set_pll = wm5102_set_fll,
 
-       .controls = wm5102_snd_controls,
-       .num_controls = ARRAY_SIZE(wm5102_snd_controls),
-       .dapm_widgets = wm5102_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets),
-       .dapm_routes = wm5102_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
+       .component_driver = {
+               .controls               = wm5102_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm5102_snd_controls),
+               .dapm_widgets           = wm5102_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm5102_dapm_widgets),
+               .dapm_routes            = wm5102_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm5102_dapm_routes),
+       },
 };
 
 static struct snd_compr_ops wm5102_compr_ops = {
index 156547026a40e86506b01b7d56c1d84c73239227..53d35fece1c7cfbe2ab9910649a17dde7bd1b109 100644 (file)
@@ -1745,6 +1745,16 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "IN4L", NULL, "SYSCLK" },
        { "IN4R", NULL, "SYSCLK" },
 
+       { "ASRC1L", NULL, "SYSCLK" },
+       { "ASRC1R", NULL, "SYSCLK" },
+       { "ASRC2L", NULL, "SYSCLK" },
+       { "ASRC2R", NULL, "SYSCLK" },
+
+       { "ASRC1L", NULL, "ASYNCCLK" },
+       { "ASRC1R", NULL, "ASYNCCLK" },
+       { "ASRC2L", NULL, "ASYNCCLK" },
+       { "ASRC2R", NULL, "ASYNCCLK" },
+
        { "MICBIAS1", NULL, "MICVDD" },
        { "MICBIAS2", NULL, "MICVDD" },
        { "MICBIAS3", NULL, "MICVDD" },
@@ -2347,7 +2357,7 @@ static struct regmap *wm5110_get_regmap(struct device *dev)
        return priv->core.arizona->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
        .probe = wm5110_codec_probe,
        .remove = wm5110_codec_remove,
        .get_regmap = wm5110_get_regmap,
@@ -2357,12 +2367,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
        .set_sysclk = arizona_set_sysclk,
        .set_pll = wm5110_set_fll,
 
-       .controls = wm5110_snd_controls,
-       .num_controls = ARRAY_SIZE(wm5110_snd_controls),
-       .dapm_widgets = wm5110_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets),
-       .dapm_routes = wm5110_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
+       .component_driver = {
+               .controls               = wm5110_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm5110_snd_controls),
+               .dapm_widgets           = wm5110_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm5110_dapm_widgets),
+               .dapm_routes            = wm5110_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm5110_dapm_routes),
+       },
 };
 
 static struct snd_compr_ops wm5110_compr_ops = {
index ffbf3df8ae970329cd91a317d88018b3009150f4..2efc5b41ad0fe32f138384e91462af562e627a7d 100644 (file)
@@ -1587,19 +1587,21 @@ static struct regmap *wm8350_get_regmap(struct device *dev)
        return wm8350->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
        .probe =        wm8350_codec_probe,
        .remove =       wm8350_codec_remove,
        .get_regmap =   wm8350_get_regmap,
        .set_bias_level = wm8350_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8350_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8350_snd_controls),
-       .dapm_widgets = wm8350_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets),
-       .dapm_routes = wm8350_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
+       .component_driver = {
+               .controls               = wm8350_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8350_snd_controls),
+               .dapm_widgets           = wm8350_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8350_dapm_widgets),
+               .dapm_routes            = wm8350_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8350_dapm_routes),
+       },
 };
 
 static int wm8350_probe(struct platform_device *pdev)
index b1d346aa4696af67c2c082f5a3bba8f702e6ea9e..6c59fb933bd6a940571fdccd8f3b4af765f7d256 100644 (file)
@@ -1332,19 +1332,21 @@ static struct regmap *wm8400_get_regmap(struct device *dev)
        return wm8400->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
        .probe =        wm8400_codec_probe,
        .remove =       wm8400_codec_remove,
        .get_regmap =   wm8400_get_regmap,
        .set_bias_level = wm8400_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8400_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8400_snd_controls),
-       .dapm_widgets = wm8400_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets),
-       .dapm_routes = wm8400_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
+       .component_driver = {
+               .controls               = wm8400_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8400_snd_controls),
+               .dapm_widgets           = wm8400_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8400_dapm_widgets),
+               .dapm_routes            = wm8400_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8400_dapm_routes),
+       },
 };
 
 static int wm8400_probe(struct platform_device *pdev)
index 99e40e629cca878aa643f32fecfe53e9d85c3f08..119ceac684ae136e236c9fe83d1aff8bac646e33 100644 (file)
@@ -581,17 +581,19 @@ static int wm8510_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
        .probe =        wm8510_probe,
        .set_bias_level = wm8510_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8510_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8510_snd_controls),
-       .dapm_widgets = wm8510_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets),
-       .dapm_routes = wm8510_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes),
+       .component_driver = {
+               .controls               = wm8510_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8510_snd_controls),
+               .dapm_widgets           = wm8510_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8510_dapm_widgets),
+               .dapm_routes            = wm8510_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8510_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8510_of_match[] = {
index aa287a3965e71f77bc8772969543f4344f93facb..deb2e075428ec9e29acdbcb981dc34630b0df0ff 100644 (file)
@@ -413,17 +413,19 @@ static int wm8523_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
        .probe =        wm8523_probe,
        .set_bias_level = wm8523_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8523_controls,
-       .num_controls = ARRAY_SIZE(wm8523_controls),
-       .dapm_widgets = wm8523_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
-       .dapm_routes = wm8523_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
+       .component_driver = {
+               .controls               = wm8523_controls,
+               .num_controls           = ARRAY_SIZE(wm8523_controls),
+               .dapm_widgets           = wm8523_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8523_dapm_widgets),
+               .dapm_routes            = wm8523_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8523_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8523_of_match[] = {
index 66602bf02f6e43f755306bcd6cc04f2b1514c456..faa7287a52535798aa6dfd56e8c9fe2bd0ba111f 100644 (file)
@@ -899,17 +899,19 @@ static int wm8580_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
        .probe =        wm8580_probe,
        .remove =       wm8580_remove,
        .set_bias_level = wm8580_set_bias_level,
 
-       .controls = wm8580_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8580_snd_controls),
-       .dapm_widgets = wm8580_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets),
-       .dapm_routes = wm8580_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes),
+       .component_driver = {
+               .controls               = wm8580_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8580_snd_controls),
+               .dapm_widgets           = wm8580_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8580_dapm_widgets),
+               .dapm_routes            = wm8580_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8580_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8580_of_match[] = {
index c759ec068e976cb732cad35ea83a508beaa6d03b..2b376c9c99afa94a85ce205a7550ebc2fd0c1994 100644 (file)
@@ -367,17 +367,19 @@ static int wm8711_probe(struct snd_soc_codec *codec)
 
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
        .probe =        wm8711_probe,
        .set_bias_level = wm8711_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8711_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8711_snd_controls),
-       .dapm_widgets = wm8711_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
-       .dapm_routes = wm8711_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
+       .component_driver = {
+               .controls               = wm8711_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8711_snd_controls),
+               .dapm_widgets           = wm8711_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8711_dapm_widgets),
+               .dapm_routes            = wm8711_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8711_intercon),
+       },
 };
 
 static const struct of_device_id wm8711_of_match[] = {
index bb25a75f92a22749c47685e9373b7763c28af0e4..7fde077a014be3f59af9d03ddbeaf22d048d91ab 100644 (file)
@@ -53,11 +53,13 @@ static struct snd_soc_dai_driver wm8727_dai = {
                },
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
-       .dapm_widgets = wm8727_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets),
-       .dapm_routes = wm8727_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes),
+static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
+       .component_driver = {
+               .dapm_widgets           = wm8727_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8727_dapm_widgets),
+               .dapm_routes            = wm8727_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8727_dapm_routes),
+       },
 };
 
 static int wm8727_probe(struct platform_device *pdev)
index 1564e6926527f05ed892332f8ad38aea14382cef..797cc6e7c70fee2fea6547e2e76efba9a5a17b78 100644 (file)
@@ -211,16 +211,18 @@ static struct snd_soc_dai_driver wm8728_dai = {
        .ops = &wm8728_dai_ops,
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
        .set_bias_level = wm8728_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8728_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8728_snd_controls),
-       .dapm_widgets = wm8728_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
-       .dapm_routes = wm8728_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
+       .component_driver = {
+               .controls               = wm8728_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8728_snd_controls),
+               .dapm_widgets           = wm8728_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8728_dapm_widgets),
+               .dapm_routes            = wm8728_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8728_intercon),
+       },
 };
 
 static const struct of_device_id wm8728_of_match[] = {
index d18261a442560cd2c108c34295bd5b1776a6ebf4..4f9a1eb281204ba3d88380f914658e1b94c57ecf 100644 (file)
@@ -628,16 +628,18 @@ err_regulator_enable:
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
        .set_bias_level = wm8731_set_bias_level,
        .suspend_bias_off = true,
 
-       .dapm_widgets = wm8731_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
-       .dapm_routes = wm8731_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
-       .controls =     wm8731_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8731_snd_controls),
+       .component_driver = {
+               .controls               = wm8731_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8731_snd_controls),
+               .dapm_widgets           = wm8731_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8731_dapm_widgets),
+               .dapm_routes            = wm8731_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8731_intercon),
+       },
 };
 
 static const struct of_device_id wm8731_of_match[] = {
index e7807601e675c7fc288fd3f03aa1bb70a21ee960..f0cb1c4afe3cec6429038af5eaee5e892c478917 100644 (file)
@@ -573,17 +573,19 @@ err_get:
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
        .probe          = wm8737_probe,
        .set_bias_level = wm8737_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8737_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8737_snd_controls),
-       .dapm_widgets = wm8737_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets),
-       .dapm_routes = intercon,
-       .num_dapm_routes = ARRAY_SIZE(intercon),
+       .component_driver = {
+               .controls               = wm8737_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8737_snd_controls),
+               .dapm_widgets           = wm8737_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8737_dapm_widgets),
+               .dapm_routes            = intercon,
+               .num_dapm_routes        = ARRAY_SIZE(intercon),
+       },
 };
 
 static const struct of_device_id wm8737_of_match[] = {
index 36ef91fe05116438d6a59b9da9bb38abe0bf5fd7..565d477cd790ee64b071515d44badf5779d192e0 100644 (file)
@@ -497,15 +497,17 @@ static int wm8741_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
        .probe =        wm8741_probe,
        .remove =       wm8741_remove,
        .resume =       wm8741_resume,
 
-       .dapm_widgets = wm8741_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets),
-       .dapm_routes = wm8741_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = wm8741_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8741_dapm_widgets),
+               .dapm_routes            = wm8741_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8741_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8741_of_match[] = {
index bd9dcd2161bc9cb394d9aa40833b6221a44420a1..0da2bbaf06d1f33e89b48497865d477d58696e1c 100644 (file)
@@ -708,17 +708,19 @@ static int wm8750_probe(struct snd_soc_codec *codec)
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
        .probe =        wm8750_probe,
        .set_bias_level = wm8750_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8750_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8750_snd_controls),
-       .dapm_widgets = wm8750_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
-       .dapm_routes = wm8750_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes),
+       .component_driver = {
+               .controls               = wm8750_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8750_snd_controls),
+               .dapm_widgets           = wm8750_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8750_dapm_widgets),
+               .dapm_routes            = wm8750_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8750_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8750_of_match[] = {
index cdcc91282e8a15ac3d226591df88da1b45da4c99..9bdf5447f6f60fcdace934194f2c81337e4c5195 100644 (file)
@@ -1478,18 +1478,20 @@ static int wm8753_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
        .probe =        wm8753_probe,
        .resume =       wm8753_resume,
        .set_bias_level = wm8753_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8753_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8753_snd_controls),
-       .dapm_widgets = wm8753_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
-       .dapm_routes = wm8753_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
+       .component_driver = {
+               .controls               = wm8753_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8753_snd_controls),
+               .dapm_widgets           = wm8753_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8753_dapm_widgets),
+               .dapm_routes            = wm8753_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8753_dapm_routes),
+       },
 };
 
 static const struct of_device_id wm8753_of_match[] = {
index df6178464b008cb0ab57ec424d32e2389baad63d..d6edcbbdec12e3839babe286fa16a0e28fbd551b 100644 (file)
@@ -608,17 +608,19 @@ err_reg_enable:
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
        .probe = wm8770_probe,
        .set_bias_level = wm8770_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = wm8770_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8770_snd_controls),
-       .dapm_widgets = wm8770_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets),
-       .dapm_routes = wm8770_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8770_intercon),
+       .component_driver = {
+               .controls               = wm8770_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8770_snd_controls),
+               .dapm_widgets           = wm8770_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8770_dapm_widgets),
+               .dapm_routes            = wm8770_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8770_intercon),
+       },
 };
 
 static const struct of_device_id wm8770_of_match[] = {
index 5af44f9a8cf2395f78ba70b8e1d2d911452d2618..ae30480b3976875bcf2747189a61ea960416f79a 100644 (file)
@@ -425,17 +425,19 @@ static int wm8776_probe(struct snd_soc_codec *codec)
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
        .probe =        wm8776_probe,
        .set_bias_level = wm8776_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8776_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8776_snd_controls),
-       .dapm_widgets = wm8776_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets),
-       .dapm_routes = routes,
-       .num_dapm_routes = ARRAY_SIZE(routes),
+       .component_driver = {
+               .controls               = wm8776_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8776_snd_controls),
+               .dapm_widgets           = wm8776_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8776_dapm_widgets),
+               .dapm_routes            = routes,
+               .num_dapm_routes        = ARRAY_SIZE(routes),
+       },
 };
 
 static const struct of_device_id wm8776_of_match[] = {
index fb55fd845d273fc9fa41670e41568379f346e9ec..bcda210185050a0ddc3901ba244f0bbdc70dfee8 100644 (file)
@@ -50,11 +50,13 @@ static struct snd_soc_dai_driver wm8782_dai = {
        },
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
-       .dapm_widgets = wm8782_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets),
-       .dapm_routes = wm8782_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes),
+static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
+       .component_driver = {
+               .dapm_widgets           = wm8782_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8782_dapm_widgets),
+               .dapm_routes            = wm8782_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8782_dapm_routes),
+       },
 };
 
 static int wm8782_probe(struct platform_device *pdev)
index 8d914702cae4a3fe2c0ca0599cd1ec79f7322c83..af95d648265b3e92e345101542b332aee35191d4 100644 (file)
@@ -545,10 +545,12 @@ static struct snd_soc_dai_driver wm8804_dai = {
 static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
        .idle_bias_off = true,
 
-       .dapm_widgets = wm8804_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets),
-       .dapm_routes = wm8804_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes),
+       .component_driver = {
+               .dapm_widgets           = wm8804_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8804_dapm_widgets),
+               .dapm_routes            = wm8804_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8804_dapm_routes),
+       },
 };
 
 const struct regmap_config wm8804_regmap_config = {
index 5d8dca88d612b3ecdd04e180fc4473dd3ed1d3c6..c77b49a293116820bf4e003ed0146d43d8c8eacd 100644 (file)
@@ -1208,18 +1208,20 @@ static int wm8900_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
        .probe =        wm8900_probe,
        .suspend =      wm8900_suspend,
        .resume =       wm8900_resume,
        .set_bias_level = wm8900_set_bias_level,
 
-       .controls = wm8900_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8900_snd_controls),
-       .dapm_widgets = wm8900_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets),
-       .dapm_routes = wm8900_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
+       .component_driver = {
+               .controls               = wm8900_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8900_snd_controls),
+               .dapm_widgets           = wm8900_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8900_dapm_widgets),
+               .dapm_routes            = wm8900_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8900_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8900_regmap = {
index a26ca490cf31f9be6bbe61801b39cfe3218c8058..6e887c2c42b1a33808a3bc513dcf5f4b1c481de1 100644 (file)
@@ -1830,7 +1830,7 @@ static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
                           !!value << WM8903_GP1_LVL_SHIFT);
 }
 
-static struct gpio_chip wm8903_template_chip = {
+static const struct gpio_chip wm8903_template_chip = {
        .label                  = "wm8903",
        .owner                  = THIS_MODULE,
        .request                = wm8903_gpio_request,
@@ -1874,18 +1874,20 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
 }
 #endif
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
        .resume =       wm8903_resume,
        .set_bias_level = wm8903_set_bias_level,
        .seq_notifier = wm8903_seq_notifier,
        .suspend_bias_off = true,
 
-       .controls = wm8903_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8903_snd_controls),
-       .dapm_widgets = wm8903_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
-       .dapm_routes = wm8903_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
+       .component_driver = {
+               .controls               = wm8903_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8903_snd_controls),
+               .dapm_widgets           = wm8903_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8903_dapm_widgets),
+               .dapm_routes            = wm8903_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8903_intercon),
+       },
 };
 
 static const struct regmap_config wm8903_regmap = {
index edd7a77091942cd7b873e9c193baed54dd6186c6..4fd350e8420dd80471ee862a0793548ab0d9edf9 100644 (file)
@@ -2086,7 +2086,7 @@ static int wm8904_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
        .probe =        wm8904_probe,
        .remove =       wm8904_remove,
        .set_bias_level = wm8904_set_bias_level,
index 1c600819f7689b451ae4da81922649961de47c08..b5935625feeb83a774752164a4e47c4cf0b1eee6 100644 (file)
@@ -723,17 +723,19 @@ static int wm8940_probe(struct snd_soc_codec *codec)
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
        .probe =        wm8940_probe,
        .set_bias_level = wm8940_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls =     wm8940_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8940_snd_controls),
-       .dapm_widgets = wm8940_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets),
-       .dapm_routes =  wm8940_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes),
+       .component_driver = {
+               .controls               = wm8940_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8940_snd_controls),
+               .dapm_widgets           = wm8940_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8940_dapm_widgets),
+               .dapm_routes            = wm8940_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8940_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8940_regmap = {
index 9db00d53abe76f58be4e74a4b4e5342c3a19147d..1edc7b1df31de2a845fb1a5e06669a3b09bdd2c4 100644 (file)
@@ -940,17 +940,19 @@ err_enable:
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
        .probe =        wm8955_probe,
        .set_bias_level = wm8955_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls =     wm8955_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8955_snd_controls),
-       .dapm_widgets = wm8955_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets),
-       .dapm_routes =  wm8955_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes),
+       .component_driver = {
+               .controls               = wm8955_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8955_snd_controls),
+               .dapm_widgets           = wm8955_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8955_dapm_widgets),
+               .dapm_routes            = wm8955_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8955_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8955_regmap = {
index d7f444f874604d7d8a6df4a05aa634fe5448fdfd..be3244361210c15c8e91180eaf11b705e753953e 100644 (file)
@@ -1264,7 +1264,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
        .probe =        wm8960_probe,
        .set_bias_level = wm8960_set_bias_level,
        .suspend_bias_off = true,
index e30446a047407711ea236f14a52dd93aec2ca2d4..e23ceac760153ba592fbc1b0003a3207e5d2a7a7 100644 (file)
@@ -882,18 +882,20 @@ static int wm8961_resume(struct snd_soc_codec *codec)
 #define wm8961_resume NULL
 #endif
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
        .probe =        wm8961_probe,
        .resume =       wm8961_resume,
        .set_bias_level = wm8961_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8961_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8961_snd_controls),
-       .dapm_widgets = wm8961_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets),
-       .dapm_routes = audio_paths,
-       .num_dapm_routes = ARRAY_SIZE(audio_paths),
+       .component_driver = {
+               .controls               = wm8961_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8961_snd_controls),
+               .dapm_widgets           = wm8961_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8961_dapm_widgets),
+               .dapm_routes            = audio_paths,
+               .num_dapm_routes        = ARRAY_SIZE(audio_paths),
+       },
 };
 
 static const struct regmap_config wm8961_regmap = {
index f3109da247692377d1240ebd72b58fe16d8683cf..fd2731d171dd02511ecb85d67a1189b509db4c71 100644 (file)
@@ -3357,7 +3357,7 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip,
        return 0;
 }
 
-static struct gpio_chip wm8962_template_chip = {
+static const struct gpio_chip wm8962_template_chip = {
        .label                  = "wm8962",
        .owner                  = THIS_MODULE,
        .request                = wm8962_gpio_request,
@@ -3479,7 +3479,7 @@ static int wm8962_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
        .probe =        wm8962_probe,
        .remove =       wm8962_remove,
        .set_bias_level = wm8962_set_bias_level,
@@ -3713,7 +3713,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
                                            ARRAY_SIZE(wm8962_dc_measure));
                if (ret != 0)
                        dev_err(&i2c->dev,
-                               "Failed to configure for DC mesurement: %d\n",
+                               "Failed to configure for DC measurement: %d\n",
                                ret);
        }
 
index 2cdde32c43c634d2b6e280908a22cebd8268da5a..887d31cf39457574733f303c78ddd8dd98ef9214 100644 (file)
@@ -649,17 +649,19 @@ static int wm8971_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
        .probe =        wm8971_probe,
        .set_bias_level = wm8971_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8971_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8971_snd_controls),
-       .dapm_widgets = wm8971_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets),
-       .dapm_routes = wm8971_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
+       .component_driver = {
+               .controls               = wm8971_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8971_snd_controls),
+               .dapm_widgets           = wm8971_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8971_dapm_widgets),
+               .dapm_routes            = wm8971_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8971_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8971_regmap = {
index dc8c3b1ebb6fe9a98b3468daa5cc6d9e06f6ae6a..d414ddd6e197fd63f023ee2822f9626ddf7f640d 100644 (file)
@@ -676,17 +676,19 @@ static int wm8974_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
        .probe =        wm8974_probe,
        .set_bias_level = wm8974_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8974_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8974_snd_controls),
-       .dapm_widgets = wm8974_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
-       .dapm_routes = wm8974_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
+       .component_driver = {
+               .controls               = wm8974_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8974_snd_controls),
+               .dapm_widgets           = wm8974_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8974_dapm_widgets),
+               .dapm_routes            = wm8974_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8974_dapm_routes),
+       },
 };
 
 static int wm8974_i2c_probe(struct i2c_client *i2c,
index d36d6001fbb7e7a15067a34db07af1637d89cddd..90b2d418ef606247da30944b82190b92bb1e9db1 100644 (file)
@@ -993,18 +993,20 @@ static int wm8978_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
        .probe =        wm8978_probe,
        .suspend =      wm8978_suspend,
        .resume =       wm8978_resume,
        .set_bias_level = wm8978_set_bias_level,
 
-       .controls = wm8978_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8978_snd_controls),
-       .dapm_widgets = wm8978_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets),
-       .dapm_routes = wm8978_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes),
+       .component_driver = {
+               .controls               = wm8978_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8978_snd_controls),
+               .dapm_widgets           = wm8978_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8978_dapm_widgets),
+               .dapm_routes            = wm8978_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8978_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8978_regmap_config = {
index 0c002a5712cb4f261cd84454f38e24a89836519a..bfdbe72ee687daf17bbb3bd9fe5cc6f5ab7026af 100644 (file)
@@ -976,16 +976,18 @@ static struct snd_soc_dai_driver wm8983_dai = {
        .symmetric_rates = 1
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
        .probe = wm8983_probe,
        .set_bias_level = wm8983_set_bias_level,
        .suspend_bias_off = true,
-       .controls = wm8983_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8983_snd_controls),
-       .dapm_widgets = wm8983_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
-       .dapm_routes = wm8983_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
+       .component_driver = {
+               .controls               = wm8983_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8983_snd_controls),
+               .dapm_widgets           = wm8983_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8983_dapm_widgets),
+               .dapm_routes            = wm8983_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(wm8983_audio_map),
+       },
 };
 
 static const struct regmap_config wm8983_regmap = {
index 7347abff4b2c3eaaa71c4c18131622d2d9ec3402..05344f974ff31b7f3d9879d4fafa335ac8996cfb 100644 (file)
@@ -1105,17 +1105,19 @@ static struct snd_soc_dai_driver wm8985_dai = {
        .symmetric_rates = 1
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
        .probe = wm8985_probe,
        .set_bias_level = wm8985_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8985_common_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8985_common_snd_controls),
-       .dapm_widgets = wm8985_common_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets),
-       .dapm_routes = wm8985_common_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes),
+       .component_driver = {
+               .controls               = wm8985_common_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8985_common_snd_controls),
+               .dapm_widgets           = wm8985_common_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8985_common_dapm_widgets),
+               .dapm_routes            = wm8985_common_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8985_common_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8985_regmap = {
index 895721a256f048259ad2ee596a33316f5115c1c6..b0d0219532f2de85ef8ace86236e31e72ac69305 100644 (file)
@@ -817,12 +817,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
        .set_bias_level = wm8988_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8988_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8988_snd_controls),
-       .dapm_widgets = wm8988_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
-       .dapm_routes = wm8988_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
+       .component_driver = {
+               .controls               = wm8988_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8988_snd_controls),
+               .dapm_widgets           = wm8988_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8988_dapm_widgets),
+               .dapm_routes            = wm8988_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8988_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8988_regmap = {
index 23ecd30d8bcad392204528466332eb1d4c0bf7a3..a8945001e6963a6adb81f008ae4aa09e2dc54b12 100644 (file)
@@ -1294,17 +1294,19 @@ static int wm8990_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
        .probe =        wm8990_probe,
        .set_bias_level = wm8990_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls =     wm8990_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8990_snd_controls),
-       .dapm_widgets = wm8990_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets),
-       .dapm_routes =  wm8990_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes),
+       .component_driver = {
+               .controls               = wm8990_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8990_snd_controls),
+               .dapm_widgets           = wm8990_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8990_dapm_widgets),
+               .dapm_routes            = wm8990_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8990_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8990_regmap = {
index c9ee0ac6a65441fbaef3a30f95565d169e32a81b..98437904079400bce635dbf96d3efab53ec8ac46 100644 (file)
@@ -1232,16 +1232,18 @@ static struct snd_soc_dai_driver wm8991_dai = {
        .ops = &wm8991_ops
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
        .set_bias_level = wm8991_set_bias_level,
        .suspend_bias_off = true,
 
-       .controls = wm8991_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8991_snd_controls),
-       .dapm_widgets = wm8991_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets),
-       .dapm_routes = wm8991_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes),
+       .component_driver = {
+               .controls               = wm8991_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8991_snd_controls),
+               .dapm_widgets           = wm8991_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8991_dapm_widgets),
+               .dapm_routes            = wm8991_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8991_dapm_routes),
+       },
 };
 
 static const struct regmap_config wm8991_regmap = {
index 8668c4c391b07be20309503c9f2f5568051b99cc..195f7bf6eb22aa716da8c09a379f26c91e83edf2 100644 (file)
@@ -1613,7 +1613,7 @@ static const struct regmap_config wm8993_regmap = {
        .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
        .probe =        wm8993_probe,
        .suspend =      wm8993_suspend,
        .resume =       wm8993_resume,
index a18aecb4993590e6a7bd936b238fee544462a6bc..3896523b71e9c924d1c62dbb0661f6945e840c4f 100644 (file)
@@ -4439,7 +4439,7 @@ static struct regmap *wm8994_get_regmap(struct device *dev)
        return control->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .probe =        wm8994_codec_probe,
        .remove =       wm8994_codec_remove,
        .suspend =      wm8994_codec_suspend,
index 24500bafb0a89708edf155862b0d7a1e0fb93029..19b08a5cae625f0362fc29e2b4e5198588ed089f 100644 (file)
@@ -2192,12 +2192,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
        .set_bias_level = wm8995_set_bias_level,
        .idle_bias_off = true,
 
-       .controls = wm8995_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8995_snd_controls),
-       .dapm_widgets = wm8995_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets),
-       .dapm_routes = wm8995_intercon,
-       .num_dapm_routes = ARRAY_SIZE(wm8995_intercon),
+       .component_driver = {
+               .controls               = wm8995_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8995_snd_controls),
+               .dapm_widgets           = wm8995_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8995_dapm_widgets),
+               .dapm_routes            = wm8995_intercon,
+               .num_dapm_routes        = ARRAY_SIZE(wm8995_intercon),
+       },
 };
 
 static const struct regmap_config wm8995_regmap = {
index a7304425121855b701f1cf1d98ae70232ad84bc3..8affa49691200e47f6b6d4ed4462b5f1f6d5c37f 100644 (file)
@@ -2184,7 +2184,7 @@ static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
                                  (1 << WM8996_GP1_DIR_SHIFT));
 }
 
-static struct gpio_chip wm8996_template_chip = {
+static const struct gpio_chip wm8996_template_chip = {
        .label                  = "wm8996",
        .owner                  = THIS_MODULE,
        .direction_output       = wm8996_gpio_direction_out,
@@ -2684,18 +2684,20 @@ static int wm8996_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
        .probe =        wm8996_probe,
        .remove =       wm8996_remove,
        .set_bias_level = wm8996_set_bias_level,
        .idle_bias_off  = true,
        .seq_notifier = wm8996_seq_notifier,
-       .controls = wm8996_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8996_snd_controls),
-       .dapm_widgets = wm8996_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets),
-       .dapm_routes = wm8996_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
+       .component_driver = {
+               .controls               = wm8996_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8996_snd_controls),
+               .dapm_widgets           = wm8996_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8996_dapm_widgets),
+               .dapm_routes            = wm8996_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8996_dapm_routes),
+       },
        .set_pll = wm8996_set_fll,
 };
 
index 6b0785b5a5c5a52b5fe92f48ba89985ddf450a8c..2f2821b3382f055a9560413240797e4c56579c61 100644 (file)
@@ -1095,7 +1095,7 @@ static struct regmap *wm8997_get_regmap(struct device *dev)
        return priv->core.arizona->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
        .probe = wm8997_codec_probe,
        .remove = wm8997_codec_remove,
        .get_regmap =   wm8997_get_regmap,
@@ -1105,12 +1105,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
        .set_sysclk = arizona_set_sysclk,
        .set_pll = wm8997_set_fll,
 
-       .controls = wm8997_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8997_snd_controls),
-       .dapm_widgets = wm8997_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets),
-       .dapm_routes = wm8997_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes),
+       .component_driver = {
+               .controls               = wm8997_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8997_snd_controls),
+               .dapm_widgets           = wm8997_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8997_dapm_widgets),
+               .dapm_routes            = wm8997_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8997_dapm_routes),
+       },
 };
 
 static int wm8997_probe(struct platform_device *pdev)
index 3a5c896a2d138f3fd9c7294786e5663373c10231..bcc2e1060a6c3ce1e48fce7ea2780249830e6525 100644 (file)
@@ -966,6 +966,16 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
        { "IN2A", NULL, "SYSCLK" },
        { "IN2B", NULL, "SYSCLK" },
 
+       { "ASRC1L", NULL, "SYSCLK" },
+       { "ASRC1R", NULL, "SYSCLK" },
+       { "ASRC2L", NULL, "SYSCLK" },
+       { "ASRC2R", NULL, "SYSCLK" },
+
+       { "ASRC1L", NULL, "ASYNCCLK" },
+       { "ASRC1R", NULL, "ASYNCCLK" },
+       { "ASRC2L", NULL, "ASYNCCLK" },
+       { "ASRC2R", NULL, "ASYNCCLK" },
+
        { "SPD1", NULL, "SYSCLK" },
        { "SPD1", NULL, "SPD1TX1" },
        { "SPD1", NULL, "SPD1TX2" },
@@ -1351,7 +1361,7 @@ static struct regmap *wm8998_get_regmap(struct device *dev)
        return priv->core.arizona->regmap;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
        .probe = wm8998_codec_probe,
        .remove = wm8998_codec_remove,
        .get_regmap = wm8998_get_regmap,
@@ -1361,12 +1371,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
        .set_sysclk = arizona_set_sysclk,
        .set_pll = wm8998_set_fll,
 
-       .controls = wm8998_snd_controls,
-       .num_controls = ARRAY_SIZE(wm8998_snd_controls),
-       .dapm_widgets = wm8998_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets),
-       .dapm_routes = wm8998_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes),
+       .component_driver = {
+               .controls               = wm8998_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm8998_snd_controls),
+               .dapm_widgets           = wm8998_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm8998_dapm_widgets),
+               .dapm_routes            = wm8998_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(wm8998_dapm_routes),
+       },
 };
 
 static int wm8998_probe(struct platform_device *pdev)
index 363b3b6676163e8c0b110efd165c5eccd7ec9e1a..856867ec2813486eafb1399b22c2e8e4af5fc474 100644 (file)
@@ -1274,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
        .probe =        wm9081_probe,
 
        .set_sysclk = wm9081_set_sysclk,
@@ -1282,12 +1282,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
 
        .idle_bias_off = true,
 
-       .controls         = wm9081_snd_controls,
-       .num_controls     = ARRAY_SIZE(wm9081_snd_controls),
-       .dapm_widgets     = wm9081_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
-       .dapm_routes     = wm9081_audio_paths,
-       .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
+       .component_driver = {
+               .controls               = wm9081_snd_controls,
+               .num_controls           = ARRAY_SIZE(wm9081_snd_controls),
+               .dapm_widgets           = wm9081_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm9081_dapm_widgets),
+               .dapm_routes            = wm9081_audio_paths,
+               .num_dapm_routes        = ARRAY_SIZE(wm9081_audio_paths),
+       },
 };
 
 static const struct regmap_config wm9081_regmap = {
index 5d737290f5475f615ac9c1b536d6311602884e9d..5a131385cb2ff258e1d16edc895b37a1ad7fc719 100644 (file)
@@ -550,7 +550,7 @@ static int wm9090_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
        .probe =        wm9090_probe,
        .set_bias_level = wm9090_set_bias_level,
        .suspend_bias_off = true,
index 744842c76a60c3c76c32fa2827482d527f5b327a..dcdd055db57b6fe38f085932f1f6b7e9ea063417 100644 (file)
@@ -352,7 +352,7 @@ static int wm9705_soc_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
        .probe =        wm9705_soc_probe,
        .remove =       wm9705_soc_remove,
        .suspend =      wm9705_soc_suspend,
@@ -364,12 +364,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
        .reg_cache_step = 2,
        .reg_cache_default = wm9705_reg,
 
-       .controls = wm9705_snd_ac97_controls,
-       .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls),
-       .dapm_widgets = wm9705_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
-       .dapm_routes = wm9705_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
+       .component_driver = {
+               .controls               = wm9705_snd_ac97_controls,
+               .num_controls           = ARRAY_SIZE(wm9705_snd_ac97_controls),
+               .dapm_widgets           = wm9705_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm9705_dapm_widgets),
+               .dapm_routes            = wm9705_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(wm9705_audio_map),
+       },
 };
 
 static int wm9705_probe(struct platform_device *pdev)
index 488a92224249f064922e4c019ab5065f07b87c74..557709eac698fb60c6a66d5af9a88bf744e8256c 100644 (file)
@@ -669,7 +669,7 @@ static int wm9712_soc_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
        .probe =        wm9712_soc_probe,
        .remove =       wm9712_soc_remove,
        .resume =       wm9712_soc_resume,
@@ -682,12 +682,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
        .reg_cache_step = 2,
        .reg_cache_default = wm9712_reg,
 
-       .controls = wm9712_snd_ac97_controls,
-       .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls),
-       .dapm_widgets = wm9712_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
-       .dapm_routes = wm9712_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
+       .component_driver = {
+               .controls               = wm9712_snd_ac97_controls,
+               .num_controls           = ARRAY_SIZE(wm9712_snd_ac97_controls),
+               .dapm_widgets           = wm9712_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm9712_dapm_widgets),
+               .dapm_routes            = wm9712_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(wm9712_audio_map),
+       },
 };
 
 static int wm9712_probe(struct platform_device *pdev)
index 9849643ef8099c7f3340a719cf160c8ce633f9c5..e4301ddb1b84e434ce3bbfa5997f20658af30dbd 100644 (file)
@@ -1235,19 +1235,21 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
+static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
        .probe =        wm9713_soc_probe,
        .remove =       wm9713_soc_remove,
        .suspend =      wm9713_soc_suspend,
        .resume =       wm9713_soc_resume,
        .set_bias_level = wm9713_set_bias_level,
 
-       .controls = wm9713_snd_ac97_controls,
-       .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls),
-       .dapm_widgets = wm9713_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
-       .dapm_routes = wm9713_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
+       .component_driver = {
+               .controls               = wm9713_snd_ac97_controls,
+               .num_controls           = ARRAY_SIZE(wm9713_snd_ac97_controls),
+               .dapm_widgets           = wm9713_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(wm9713_dapm_widgets),
+               .dapm_routes            = wm9713_audio_map,
+               .num_dapm_routes        = ARRAY_SIZE(wm9713_audio_map),
+       },
 };
 
 static int wm9713_probe(struct platform_device *pdev)
index 05c2d33aa74dd9273100c9e8edf1b00bb57d8e35..3c5a9804d3f5edc259b25bd129b40918fe80197b 100644 (file)
@@ -1218,7 +1218,7 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
 
        snd_mask_none(&nfmt);
 
-       for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
+       for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
                if (snd_mask_test(fmt, i)) {
                        uint sbits = snd_pcm_format_width(i);
                        int ppm;
index dc97f4349e66fc5c6c337c01c2cf75356902b34b..2998954a1c7459e02c3397956e690a276120f06d 100644 (file)
@@ -577,7 +577,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
                dev->capability |= DWC_I2S_PLAY;
                dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
                dev->play_dma_data.dt.addr_width = bus_widths[idx];
-               dev->play_dma_data.dt.chan_name = "TX";
                dev->play_dma_data.dt.fifo_size = fifo_depth *
                        (fifo_width[idx2]) >> 8;
                dev->play_dma_data.dt.maxburst = 16;
@@ -588,7 +587,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
                dev->capability |= DWC_I2S_RECORD;
                dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
                dev->capture_dma_data.dt.addr_width = bus_widths[idx];
-               dev->capture_dma_data.dt.chan_name = "RX";
                dev->capture_dma_data.dt.fifo_size = fifo_depth *
                        (fifo_width[idx2] >> 8);
                dev->capture_dma_data.dt.maxburst = 16;
index c1a0e01cb8e79e1007c4b9ef7117206e4c891882..b7157ce23479d332f12d4d5ae2a648ce31f6c49d 100644 (file)
@@ -879,7 +879,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
                }
        }
 
-       if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-asrc")) {
+       if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
                asrc_priv->channel_bits = 3;
                clk_map[IN] = input_clk_map_imx35;
                clk_map[OUT] = output_clk_map_imx35;
@@ -892,7 +892,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
        ret = fsl_asrc_init(asrc_priv);
        if (ret) {
                dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
-               return -EINVAL;
+               return ret;
        }
 
        asrc_priv->channel_avail = 10;
@@ -901,14 +901,14 @@ static int fsl_asrc_probe(struct platform_device *pdev)
                                   &asrc_priv->asrc_rate);
        if (ret) {
                dev_err(&pdev->dev, "failed to get output rate\n");
-               return -EINVAL;
+               return ret;
        }
 
        ret = of_property_read_u32(np, "fsl,asrc-width",
                                   &asrc_priv->asrc_width);
        if (ret) {
                dev_err(&pdev->dev, "failed to get output width\n");
-               return -EINVAL;
+               return ret;
        }
 
        if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) {
@@ -933,8 +933,6 @@ static int fsl_asrc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       dev_info(&pdev->dev, "driver registered\n");
-
        return 0;
 }
 
index ffc000bc1f15bffb9c96937e532d04feadddac4a..dc30d780f8742437d9fd6ef3db7cd0ada76c9013 100644 (file)
@@ -322,7 +322,7 @@ static snd_pcm_uframes_t fsl_asrc_dma_pcm_pointer(struct snd_pcm_substream *subs
        return bytes_to_frames(substream->runtime, pair->pos);
 }
 
-static struct snd_pcm_ops fsl_asrc_dma_pcm_ops = {
+static const struct snd_pcm_ops fsl_asrc_dma_pcm_ops = {
        .ioctl          = snd_pcm_lib_ioctl,
        .hw_params      = fsl_asrc_dma_hw_params,
        .hw_free        = fsl_asrc_dma_hw_free,
index 26a90e12ede44d613e5fa6094c0144aac279a12d..e927955ba982491186c8eee228d6393b2750cb60 100644 (file)
@@ -77,19 +77,19 @@ static irqreturn_t esai_isr(int irq, void *devid)
        regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
 
        if (esr & ESAI_ESR_TINIT_MASK)
-               dev_dbg(&pdev->dev, "isr: Transmition Initialized\n");
+               dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
 
        if (esr & ESAI_ESR_RFF_MASK)
                dev_warn(&pdev->dev, "isr: Receiving overrun\n");
 
        if (esr & ESAI_ESR_TFE_MASK)
-               dev_warn(&pdev->dev, "isr: Transmition underrun\n");
+               dev_warn(&pdev->dev, "isr: Transmission underrun\n");
 
        if (esr & ESAI_ESR_TLS_MASK)
                dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
 
        if (esr & ESAI_ESR_TDE_MASK)
-               dev_dbg(&pdev->dev, "isr: Transmition data exception\n");
+               dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
 
        if (esr & ESAI_ESR_TED_MASK)
                dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
index 2147994ab46f6826824a3954947ed45285e0baae..9fadf7e31c5f86459efc0b70fb1674f45da5a289 100644 (file)
@@ -801,8 +801,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
 
        sai->pdev = pdev;
 
-       if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai") ||
-           of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai"))
+       if (of_device_is_compatible(np, "fsl,imx6sx-sai") ||
+           of_device_is_compatible(np, "fsl,imx6ul-sai"))
                sai->sai_on_imx = true;
 
        sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
@@ -883,7 +883,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
        }
 
        if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
-           of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) {
+           of_device_is_compatible(np, "fsl,imx6ul-sai")) {
                gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
                if (IS_ERR(gpr)) {
                        dev_err(&pdev->dev, "cannot find iomuxc registers\n");
index c01c5dd68601b69d519f0fb7d1953efc994f61bd..b95ae4918fcab3e3a8cf2125b88adf6916f2a749 100644 (file)
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD
        select SND_SIMPLE_CARD_UTILS
        help
          This option enables generic simple sound card support
+
+config SND_SIMPLE_SCU_CARD
+       tristate "ASoC Simple SCU sound card support"
+       depends on OF
+       select SND_SIMPLE_CARD_UTILS
+       help
+         This option enables generic simple SCU sound card support.
+         It supports DPCM of multi CPU single Codec ststem.
index 2d53c8d70705b2688a748967bbd0517335138fe2..ee750f3023baf8acdb8ecd3b2dcf7bc943d6dcd9 100644 (file)
@@ -1,5 +1,7 @@
 snd-soc-simple-card-utils-objs := simple-card-utils.o
 snd-soc-simple-card-objs       := simple-card.o
+snd-soc-simple-scu-card-objs   := simple-scu-card.o
 
 obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)    += snd-soc-simple-card-utils.o
 obj-$(CONFIG_SND_SIMPLE_CARD)          += snd-soc-simple-card.o
+obj-$(CONFIG_SND_SIMPLE_SCU_CARD)      += snd-soc-simple-scu-card.o
index 9599de69a880eb2a59ecb3fe142eb84a7ddacbcc..1cb39309f5d5b25151d37481c776758754783a63 100644 (file)
@@ -7,6 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <sound/simple_card_utils.h>
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
 
+int asoc_simple_card_parse_clk(struct device_node *node,
+                              struct device_node *dai_of_node,
+                              struct asoc_simple_dai *simple_dai)
+{
+       struct clk *clk;
+       u32 val;
+
+       /*
+        * Parse dai->sysclk come from "clocks = <&xxx>"
+        * (if system has common clock)
+        *  or "system-clock-frequency = <xxx>"
+        *  or device's module clock.
+        */
+       clk = of_clk_get(node, 0);
+       if (!IS_ERR(clk)) {
+               simple_dai->sysclk = clk_get_rate(clk);
+               simple_dai->clk = clk;
+       } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
+               simple_dai->sysclk = val;
+       } else {
+               clk = of_clk_get(dai_of_node, 0);
+               if (!IS_ERR(clk))
+                       simple_dai->sysclk = clk_get_rate(clk);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk);
+
+int asoc_simple_card_parse_dai(struct device_node *node,
+                                   struct device_node **dai_of_node,
+                                   const char **dai_name,
+                                   const char *list_name,
+                                   const char *cells_name,
+                                   int *is_single_link)
+{
+       struct of_phandle_args args;
+       int ret;
+
+       if (!node)
+               return 0;
+
+       /*
+        * Get node via "sound-dai = <&phandle port>"
+        * it will be used as xxx_of_node on soc_bind_dai_link()
+        */
+       ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args);
+       if (ret)
+               return ret;
+
+       /* Get dai->name */
+       if (dai_name) {
+               ret = snd_soc_of_get_dai_name(node, dai_name);
+               if (ret < 0)
+                       return ret;
+       }
+
+       *dai_of_node = args.np;
+
+       if (is_single_link)
+               *is_single_link = !args.args_count;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
+
+int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
+                             struct asoc_simple_dai *simple_dai)
+{
+       int ret;
+
+       if (simple_dai->sysclk) {
+               ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0);
+               if (ret && ret != -ENOTSUPP) {
+                       dev_err(dai->dev, "simple-card: set_sysclk error\n");
+                       return ret;
+               }
+       }
+
+       if (simple_dai->slots) {
+               ret = snd_soc_dai_set_tdm_slot(dai,
+                                              simple_dai->tx_slot_mask,
+                                              simple_dai->rx_slot_mask,
+                                              simple_dai->slots,
+                                              simple_dai->slot_width);
+               if (ret && ret != -ENOTSUPP) {
+                       dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_init_dai);
+
+int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link)
+{
+       if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
+               return -EINVAL;
+
+       /* Assumes platform == cpu */
+       if (!dai_link->platform_of_node)
+               dai_link->platform_of_node = dai_link->cpu_of_node;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_dailink);
+
+void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
+                                      int is_single_links)
+{
+       /*
+        * In soc_bind_dai_link() will check cpu name after
+        * of_node matching if dai_link has cpu_dai_name.
+        * but, it will never match if name was created by
+        * fmt_single_name() remove cpu_dai_name if cpu_args
+        * was 0. See:
+        *      fmt_single_name()
+        *      fmt_multiple_name()
+        */
+       if (is_single_links)
+               dai_link->cpu_dai_name = NULL;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_cpu);
+
+int asoc_simple_card_clean_reference(struct snd_soc_card *card)
+{
+       struct snd_soc_dai_link *dai_link;
+       int num_links;
+
+       for (num_links = 0, dai_link = card->dai_link;
+            num_links < card->num_links;
+            num_links++, dai_link++) {
+               of_node_put(dai_link->cpu_of_node);
+               of_node_put(dai_link->codec_of_node);
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
+
 /* Module information */
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
index 43295f02498239ef0578168f281f2856e38f6b5a..fe0bc5c469e27fa20681819d898b03645a88f1f7 100644 (file)
@@ -37,13 +37,15 @@ struct simple_card_data {
        unsigned int mclk_fs;
        struct asoc_simple_jack hp_jack;
        struct asoc_simple_jack mic_jack;
-       struct snd_soc_dai_link dai_link[];     /* dynamically allocated */
+       struct snd_soc_dai_link *dai_link;
 };
 
 #define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
-#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
-#define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
 
+#define DAI    "sound-dai"
+#define CELL   "#sound-dai-cells"
 #define PREFIX "simple-audio-card,"
 
 #define asoc_simple_card_init_hp(card, sjack, prefix)\
@@ -112,13 +114,13 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
        struct simple_dai_props *dai_props =
-               &priv->dai_props[rtd->num];
+               simple_priv_to_props(priv, rtd->num);
        int ret;
 
        ret = clk_prepare_enable(dai_props->cpu_dai.clk);
        if (ret)
                return ret;
-       
+
        ret = clk_prepare_enable(dai_props->codec_dai.clk);
        if (ret)
                clk_disable_unprepare(dai_props->cpu_dai.clk);
@@ -131,7 +133,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
        struct simple_dai_props *dai_props =
-               &priv->dai_props[rtd->num];
+               simple_priv_to_props(priv, rtd->num);
 
        clk_disable_unprepare(dai_props->cpu_dai.clk);
 
@@ -145,7 +147,8 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
-       struct simple_dai_props *dai_props = &priv->dai_props[rtd->num];
+       struct simple_dai_props *dai_props =
+               simple_priv_to_props(priv, rtd->num);
        unsigned int mclk, mclk_fs = 0;
        int ret = 0;
 
@@ -177,51 +180,20 @@ static struct snd_soc_ops asoc_simple_card_ops = {
        .hw_params = asoc_simple_card_hw_params,
 };
 
-static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
-                                      struct asoc_simple_dai *set)
-{
-       int ret;
-
-       if (set->sysclk) {
-               ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
-               if (ret && ret != -ENOTSUPP) {
-                       dev_err(dai->dev, "simple-card: set_sysclk error\n");
-                       goto err;
-               }
-       }
-
-       if (set->slots) {
-               ret = snd_soc_dai_set_tdm_slot(dai,
-                                              set->tx_slot_mask,
-                                              set->rx_slot_mask,
-                                               set->slots,
-                                               set->slot_width);
-               if (ret && ret != -ENOTSUPP) {
-                       dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
-                       goto err;
-               }
-       }
-
-       ret = 0;
-
-err:
-       return ret;
-}
-
 static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
        struct snd_soc_dai *codec = rtd->codec_dai;
        struct snd_soc_dai *cpu = rtd->cpu_dai;
-       struct simple_dai_props *dai_props;
+       struct simple_dai_props *dai_props =
+               simple_priv_to_props(priv, rtd->num);
        int ret;
 
-       dai_props = &priv->dai_props[rtd->num];
-       ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
+       ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
        if (ret < 0)
                return ret;
 
-       ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai);
+       ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
        if (ret < 0)
                return ret;
 
@@ -236,78 +208,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-static int
-asoc_simple_card_sub_parse_of(struct device_node *np,
-                             struct asoc_simple_dai *dai,
-                             struct device_node **p_node,
-                             const char **name,
-                             int *args_count)
-{
-       struct of_phandle_args args;
-       struct clk *clk;
-       u32 val;
-       int ret;
-
-       if (!np)
-               return 0;
-
-       /*
-        * Get node via "sound-dai = <&phandle port>"
-        * it will be used as xxx_of_node on soc_bind_dai_link()
-        */
-       ret = of_parse_phandle_with_args(np, "sound-dai",
-                                        "#sound-dai-cells", 0, &args);
-       if (ret)
-               return ret;
-
-       *p_node = args.np;
-
-       if (args_count)
-               *args_count = args.args_count;
-
-       /* Get dai->name */
-       if (name) {
-               ret = snd_soc_of_get_dai_name(np, name);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (!dai)
-               return 0;
-
-       /* Parse TDM slot */
-       ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
-                                       &dai->rx_slot_mask,
-                                       &dai->slots, &dai->slot_width);
-       if (ret)
-               return ret;
-
-       /*
-        * Parse dai->sysclk come from "clocks = <&xxx>"
-        * (if system has common clock)
-        *  or "system-clock-frequency = <xxx>"
-        *  or device's module clock.
-        */
-       if (of_property_read_bool(np, "clocks")) {
-               clk = of_clk_get(np, 0);
-               if (IS_ERR(clk)) {
-                       ret = PTR_ERR(clk);
-                       return ret;
-               }
-
-               dai->sysclk = clk_get_rate(clk);
-               dai->clk = clk;
-       } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
-               dai->sysclk = val;
-       } else {
-               clk = of_clk_get(args.np, 0);
-               if (!IS_ERR(clk))
-                       dai->sysclk = clk_get_rate(clk);
-       }
-
-       return 0;
-}
-
 static int asoc_simple_card_dai_link_of(struct device_node *node,
                                        struct simple_card_data *priv,
                                        int idx,
@@ -316,13 +216,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
        struct device *dev = simple_priv_to_dev(priv);
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
+       struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+       struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
        struct device_node *cpu = NULL;
        struct device_node *plat = NULL;
        struct device_node *codec = NULL;
        char prop[128];
        char *prefix = "";
-       int ret, cpu_args;
-       u32 val;
+       int ret, single_cpu;
 
        /* For single DAI link & old style of DT node */
        if (is_top_level_node)
@@ -348,36 +249,46 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
        if (ret < 0)
                goto dai_link_of_err;
 
-       if (!of_property_read_u32(node, "mclk-fs", &val))
-               dai_props->mclk_fs = val;
+       of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
 
-       ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai,
-                                           &dai_link->cpu_of_node,
-                                           &dai_link->cpu_dai_name,
-                                           &cpu_args);
+       ret = asoc_simple_card_parse_cpu(cpu, dai_link,
+                                        DAI, CELL, &single_cpu);
        if (ret < 0)
                goto dai_link_of_err;
 
-       ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai,
-                                           &dai_link->codec_of_node,
-                                           &dai_link->codec_dai_name, NULL);
+       ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL);
        if (ret < 0)
                goto dai_link_of_err;
 
-       ret = asoc_simple_card_sub_parse_of(plat, NULL,
-                                           &dai_link->platform_of_node,
-                                           NULL, NULL);
+       ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL);
        if (ret < 0)
                goto dai_link_of_err;
 
-       if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
-               ret = -EINVAL;
+       ret = snd_soc_of_parse_tdm_slot(cpu,    &cpu_dai->tx_slot_mask,
+                                               &cpu_dai->rx_slot_mask,
+                                               &cpu_dai->slots,
+                                               &cpu_dai->slot_width);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = snd_soc_of_parse_tdm_slot(codec,  &codec_dai->tx_slot_mask,
+                                               &codec_dai->rx_slot_mask,
+                                               &codec_dai->slots,
+                                               &codec_dai->slot_width);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai);
+       if (ret < 0)
                goto dai_link_of_err;
-       }
 
-       /* Assumes platform == cpu */
-       if (!dai_link->platform_of_node)
-               dai_link->platform_of_node = dai_link->cpu_of_node;
+       ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_card_canonicalize_dailink(dai_link);
+       if (ret < 0)
+               goto dai_link_of_err;
 
        ret = asoc_simple_card_set_dailink_name(dev, dai_link,
                                                "%s-%s",
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
                dai_link->codec_dai_name,
                dai_props->codec_dai.sysclk);
 
-       /*
-        * In soc_bind_dai_link() will check cpu name after
-        * of_node matching if dai_link has cpu_dai_name.
-        * but, it will never match if name was created by
-        * fmt_single_name() remove cpu_dai_name if cpu_args
-        * was 0. See:
-        *      fmt_single_name()
-        *      fmt_multiple_name()
-        */
-       if (!cpu_args)
-               dai_link->cpu_dai_name = NULL;
+       asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);
 
 dai_link_of_err:
        of_node_put(cpu);
@@ -421,18 +322,20 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                                     struct simple_card_data *priv)
 {
        struct device *dev = simple_priv_to_dev(priv);
-       u32 val;
+       struct device_node *dai_link;
        int ret;
 
        if (!node)
                return -EINVAL;
 
+       dai_link = of_get_child_by_name(node, PREFIX "dai-link");
+
        /* The off-codec widgets */
        if (of_property_read_bool(node, PREFIX "widgets")) {
                ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
                                        PREFIX "widgets");
                if (ret)
-                       return ret;
+                       goto card_parse_end;
        }
 
        /* DAPM routes */
@@ -440,16 +343,14 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
                                        PREFIX "routing");
                if (ret)
-                       return ret;
+                       goto card_parse_end;
        }
 
        /* Factor to mclk, used in hw_params() */
-       ret = of_property_read_u32(node, PREFIX "mclk-fs", &val);
-       if (ret == 0)
-               priv->mclk_fs = val;
+       of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);
 
        /* Single/Muti DAI link(s) & New style of DT node */
-       if (of_get_child_by_name(node, PREFIX "dai-link")) {
+       if (dai_link) {
                struct device_node *np = NULL;
                int i = 0;
 
@@ -459,7 +360,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                                                           i, false);
                        if (ret < 0) {
                                of_node_put(np);
-                               return ret;
+                               goto card_parse_end;
                        }
                        i++;
                }
@@ -467,66 +368,51 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                /* For single DAI link & old style of DT node */
                ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
                if (ret < 0)
-                       return ret;
+                       goto card_parse_end;
        }
 
        ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
-       if (ret)
-               return ret;
-
-       return 0;
-}
 
-/* Decrease the reference count of the device nodes */
-static int asoc_simple_card_unref(struct snd_soc_card *card)
-{
-       struct snd_soc_dai_link *dai_link;
-       int num_links;
+card_parse_end:
+       of_node_put(dai_link);
 
-       for (num_links = 0, dai_link = card->dai_link;
-            num_links < card->num_links;
-            num_links++, dai_link++) {
-               of_node_put(dai_link->cpu_of_node);
-               of_node_put(dai_link->codec_of_node);
-       }
-       return 0;
+       return ret;
 }
 
 static int asoc_simple_card_probe(struct platform_device *pdev)
 {
        struct simple_card_data *priv;
        struct snd_soc_dai_link *dai_link;
+       struct simple_dai_props *dai_props;
        struct device_node *np = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
-       int num_links, ret;
+       int num, ret;
 
        /* Get the number of DAI links */
        if (np && of_get_child_by_name(np, PREFIX "dai-link"))
-               num_links = of_get_child_count(np);
+               num = of_get_child_count(np);
        else
-               num_links = 1;
+               num = 1;
 
        /* Allocate the private data and the DAI link array */
-       priv = devm_kzalloc(dev,
-                       sizeof(*priv) + sizeof(*dai_link) * num_links,
-                       GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       /* Init snd_soc_card */
-       priv->snd_card.owner = THIS_MODULE;
-       priv->snd_card.dev = dev;
-       dai_link = priv->dai_link;
-       priv->snd_card.dai_link = dai_link;
-       priv->snd_card.num_links = num_links;
-
-       /* Get room for the other properties */
-       priv->dai_props = devm_kzalloc(dev,
-                       sizeof(*priv->dai_props) * num_links,
-                       GFP_KERNEL);
-       if (!priv->dai_props)
+       dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+       dai_link  = devm_kzalloc(dev, sizeof(*dai_link)  * num, GFP_KERNEL);
+       if (!dai_props || !dai_link)
                return -ENOMEM;
 
+       priv->dai_props                 = dai_props;
+       priv->dai_link                  = dai_link;
+
+       /* Init snd_soc_card */
+       priv->snd_card.owner            = THIS_MODULE;
+       priv->snd_card.dev              = dev;
+       priv->snd_card.dai_link         = priv->dai_link;
+       priv->snd_card.num_links        = num;
+
        if (np && of_device_is_available(np)) {
 
                ret = asoc_simple_card_parse_of(np, priv);
@@ -567,7 +453,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
                                        sizeof(priv->dai_props->cpu_dai));
                memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
                                        sizeof(priv->dai_props->codec_dai));
-
        }
 
        snd_soc_card_set_drvdata(&priv->snd_card, priv);
@@ -575,9 +460,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
        ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
        if (ret >= 0)
                return ret;
-
 err:
-       asoc_simple_card_unref(&priv->snd_card);
+       asoc_simple_card_clean_reference(&priv->snd_card);
+
        return ret;
 }
 
@@ -589,7 +474,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
        asoc_simple_card_remove_jack(&priv->hp_jack);
        asoc_simple_card_remove_jack(&priv->mic_jack);
 
-       return asoc_simple_card_unref(card);
+       return asoc_simple_card_clean_reference(card);
 }
 
 static const struct of_device_id asoc_simple_of_match[] = {
@@ -611,6 +496,6 @@ static struct platform_driver asoc_simple_card = {
 module_platform_driver(asoc_simple_card);
 
 MODULE_ALIAS("platform:asoc-simple-card");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("ASoC Simple Sound Card");
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
new file mode 100644 (file)
index 0000000..b9973a5
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * ASoC simple SCU sound card support
+ *
+ * Copyright (C) 2015 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on ${LINUX}/sound/soc/generic/simple-card.c
+ *
+ * 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/clk.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <sound/simple_card_utils.h>
+
+struct asoc_simple_card_priv {
+       struct snd_soc_card snd_card;
+       struct snd_soc_codec_conf codec_conf;
+       struct asoc_simple_dai *dai_props;
+       struct snd_soc_dai_link *dai_link;
+       u32 convert_rate;
+       u32 convert_channels;
+};
+
+#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+#define DAI    "sound-dai"
+#define CELL   "#sound-dai-cells"
+#define PREFIX "simple-audio-card,"
+
+static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct asoc_simple_card_priv *priv =    snd_soc_card_get_drvdata(rtd->card);
+       struct asoc_simple_dai *dai_props =
+               simple_priv_to_props(priv, rtd->num);
+
+       return clk_prepare_enable(dai_props->clk);
+}
+
+static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct asoc_simple_card_priv *priv =    snd_soc_card_get_drvdata(rtd->card);
+       struct asoc_simple_dai *dai_props =
+               simple_priv_to_props(priv, rtd->num);
+
+       clk_disable_unprepare(dai_props->clk);
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+       .startup = asoc_simple_card_startup,
+       .shutdown = asoc_simple_card_shutdown,
+};
+
+static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_dai *dai;
+       struct snd_soc_dai_link *dai_link;
+       struct asoc_simple_dai *dai_props;
+       int num = rtd->num;
+
+       dai_link        = simple_priv_to_link(priv, num);
+       dai_props       = simple_priv_to_props(priv, num);
+       dai             = dai_link->dynamic ?
+                               rtd->cpu_dai :
+                               rtd->codec_dai;
+
+       return asoc_simple_card_init_dai(dai, dai_props);
+}
+
+static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+                                       struct snd_pcm_hw_params *params)
+{
+       struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_interval *rate = hw_param_interval(params,
+                                                     SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval *channels = hw_param_interval(params,
+                                               SNDRV_PCM_HW_PARAM_CHANNELS);
+
+       if (priv->convert_rate)
+               rate->min =
+               rate->max = priv->convert_rate;
+
+       if (priv->convert_channels)
+               channels->min =
+               channels->max = priv->convert_channels;
+
+       return 0;
+}
+
+static int asoc_simple_card_parse_links(struct device_node *np,
+                                       struct asoc_simple_card_priv *priv,
+                                       unsigned int daifmt,
+                                       int idx, bool is_fe)
+{
+       struct device *dev = simple_priv_to_dev(priv);
+       struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+       struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
+       int ret;
+
+       if (is_fe) {
+               int is_single_links = 0;
+
+               /* BE is dummy */
+               dai_link->codec_of_node         = NULL;
+               dai_link->codec_dai_name        = "snd-soc-dummy-dai";
+               dai_link->codec_name            = "snd-soc-dummy";
+
+               /* FE settings */
+               dai_link->dynamic               = 1;
+               dai_link->dpcm_merged_format    = 1;
+
+               ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
+                                                &is_single_links);
+               if (ret)
+                       return ret;
+
+               ret = asoc_simple_card_parse_clk_cpu(np, dai_link, dai_props);
+               if (ret < 0)
+                       return ret;
+
+               ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+                                                       "fe.%s",
+                                                       dai_link->cpu_dai_name);
+               if (ret < 0)
+                       return ret;
+
+               asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
+       } else {
+               /* FE is dummy */
+               dai_link->cpu_of_node           = NULL;
+               dai_link->cpu_dai_name          = "snd-soc-dummy-dai";
+               dai_link->cpu_name              = "snd-soc-dummy";
+
+               /* BE settings */
+               dai_link->no_pcm                = 1;
+               dai_link->be_hw_params_fixup    = asoc_simple_card_be_hw_params_fixup;
+
+               ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
+               if (ret < 0)
+                       return ret;
+
+               ret = asoc_simple_card_parse_clk_codec(np, dai_link, dai_props);
+               if (ret < 0)
+                       return ret;
+
+               ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+                                                       "be.%s",
+                                                       dai_link->codec_dai_name);
+               if (ret < 0)
+                       return ret;
+
+               snd_soc_of_parse_audio_prefix(&priv->snd_card,
+                                             &priv->codec_conf,
+                                             dai_link->codec_of_node,
+                                             PREFIX "prefix");
+       }
+
+       ret = snd_soc_of_parse_tdm_slot(np,
+                                       &dai_props->tx_slot_mask,
+                                       &dai_props->rx_slot_mask,
+                                       &dai_props->slots,
+                                       &dai_props->slot_width);
+       if (ret)
+               return ret;
+
+       ret = asoc_simple_card_canonicalize_dailink(dai_link);
+       if (ret < 0)
+               return ret;
+
+       dai_link->dai_fmt               = daifmt;
+       dai_link->dpcm_playback         = 1;
+       dai_link->dpcm_capture          = 1;
+       dai_link->ops                   = &asoc_simple_card_ops;
+       dai_link->init                  = asoc_simple_card_dai_init;
+
+       dev_dbg(dev, "\t%s / %04x / %d\n",
+               dai_link->name,
+               dai_link->dai_fmt,
+               dai_props->sysclk);
+
+       return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *node,
+                                struct asoc_simple_card_priv *priv)
+{
+       struct device *dev = simple_priv_to_dev(priv);
+       struct device_node *np;
+       unsigned int daifmt = 0;
+       int ret, i;
+       bool is_fe;
+
+       /* find 1st codec */
+       np = of_get_child_by_name(node, PREFIX "codec");
+       if (!np)
+               return -ENODEV;
+
+       ret = asoc_simple_card_parse_daifmt(dev, node, np,
+                                           PREFIX, &daifmt);
+       if (ret < 0)
+               return ret;
+
+       i = 0;
+       for_each_child_of_node(node, np) {
+               is_fe = false;
+               if (strcmp(np->name, PREFIX "cpu") == 0)
+                       is_fe = true;
+
+               ret = asoc_simple_card_parse_links(np, priv, daifmt, i, is_fe);
+               if (ret < 0)
+                       return ret;
+               i++;
+       }
+
+       return 0;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+                             struct asoc_simple_card_priv *priv,
+                             struct device *dev)
+{
+       struct asoc_simple_dai *props;
+       struct snd_soc_dai_link *links;
+       int ret;
+       int num;
+
+       if (!node)
+               return -EINVAL;
+
+       num = of_get_child_count(node);
+       props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL);
+       links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL);
+       if (!props || !links)
+               return -ENOMEM;
+
+       priv->dai_props = props;
+       priv->dai_link  = links;
+
+       /* Init snd_soc_card */
+       priv->snd_card.owner                    = THIS_MODULE;
+       priv->snd_card.dev                      = dev;
+       priv->snd_card.dai_link                 = priv->dai_link;
+       priv->snd_card.num_links                = num;
+       priv->snd_card.codec_conf               = &priv->codec_conf;
+       priv->snd_card.num_configs              = 1;
+
+       ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing");
+       if (ret < 0)
+               return ret;
+
+       /* sampling rate convert */
+       of_property_read_u32(node, PREFIX "convert-rate", &priv->convert_rate);
+
+       /* channels transfer */
+       of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels);
+
+       ret = asoc_simple_card_dai_link_of(node, priv);
+       if (ret < 0)
+               return ret;
+
+       ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(dev, "New card: %s\n",
+               priv->snd_card.name ? priv->snd_card.name : "");
+       dev_dbg(dev, "convert_rate     %d\n", priv->convert_rate);
+       dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
+
+       return 0;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+       struct asoc_simple_card_priv *priv;
+       struct device_node *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       /* Allocate the private data */
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       ret = asoc_simple_card_parse_of(np, priv, dev);
+       if (ret < 0) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "parse error %d\n", ret);
+               goto err;
+       }
+
+       snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+       ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
+       if (ret >= 0)
+               return ret;
+err:
+       asoc_simple_card_clean_reference(&priv->snd_card);
+
+       return ret;
+}
+
+static int asoc_simple_card_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+       return asoc_simple_card_clean_reference(card);
+}
+
+static const struct of_device_id asoc_simple_of_match[] = {
+       { .compatible = "renesas,rsrc-card", },
+       { .compatible = "simple-scu-audio-card", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
+
+static struct platform_driver asoc_simple_card = {
+       .driver = {
+               .name = "simple-scu-audio-card",
+               .of_match_table = asoc_simple_of_match,
+       },
+       .probe = asoc_simple_card_probe,
+       .remove = asoc_simple_card_remove,
+};
+
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-scu-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple SCU Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
index 162a0fd68c7b1df28c9b37d667e060e83f9a78ef..53e11c6d4e22cbabfdabcf1c01cc30ffd9c92b85 100644 (file)
@@ -134,12 +134,14 @@ static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
 static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
        .probe = pistachio_internal_dac_codec_probe,
        .idle_bias_off = true,
-       .controls = pistachio_internal_dac_snd_controls,
-       .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
-       .dapm_widgets = pistachio_internal_dac_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets),
-       .dapm_routes = pistachio_internal_dac_routes,
-       .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes),
+       .component_driver = {
+               .controls               = pistachio_internal_dac_snd_controls,
+               .num_controls           = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
+               .dapm_widgets           = pistachio_internal_dac_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(pistachio_internal_dac_widgets),
+               .dapm_routes            = pistachio_internal_dac_routes,
+               .num_dapm_routes        = ARRAY_SIZE(pistachio_internal_dac_routes),
+       },
 };
 
 static int pistachio_internal_dac_probe(struct platform_device *pdev)
index a20c3dfbcb5dd5fa2b058defabb6a318a895cc79..fc6e78050a799b0925ce7315705584241203b87d 100644 (file)
@@ -25,6 +25,7 @@ config SND_SST_IPC_ACPI
        tristate
        select SND_SST_IPC
        select SND_SOC_INTEL_SST
+       select IOSF_MBI
 
 config SND_SOC_INTEL_SST
        tristate
index 98720a93de8a1fa20999bb464d4e02e8ee5c45c1..0838478c4c3f90cf716d2284541e688003c29e20 100644 (file)
@@ -1,4 +1,4 @@
-/*
+ /*
  *  sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld
  *
  *  Copyright (C) 2013-14 Intel Corp
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10,
 
 /* Look up table to convert MIXER SW bit regs to SWM inputs */
 static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = {
+       [SST_IP_MODEM]          = SST_SWM_IN_MODEM,
        [SST_IP_CODEC0]         = SST_SWM_IN_CODEC0,
        [SST_IP_CODEC1]         = SST_SWM_IN_CODEC1,
        [SST_IP_LOOP0]          = SST_SWM_IN_SPROT_LOOP,
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
 /* SBA mixers - 16 inputs */
 #define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name)                                                        \
        static const struct snd_kcontrol_new kctl_name[] = {                                    \
+               SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0),           \
                SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0),         \
                SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0),         \
                SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0),      \
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
        }
 
 #define SST_SBA_MIXER_GRAPH_MAP(mix_name)                      \
+       { mix_name, "modem_in Switch",  "modem_in" },           \
        { mix_name, "codec_in0 Switch", "codec_in0" },          \
        { mix_name, "codec_in1 Switch", "codec_in1" },          \
        { mix_name, "sprot_loop_in Switch",     "sprot_loop_in" },      \
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls);
 SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls);
 SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls);
 SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls);
+SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls);
 
 /*
  * sst_handle_vb_timer - Start/Stop the DSP scheduler
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai)
 int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable)
 {
        struct sst_data *drv = snd_soc_dai_get_drvdata(dai);
-       const struct sst_ssp_config *config;
+       int ssp_id;
 
        dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id);
 
+       if (strcmp(id, "ssp0-port") == 0)
+               ssp_id = SSP_MODEM;
+       else if (strcmp(id, "ssp2-port") == 0)
+               ssp_id = SSP_CODEC;
+       else {
+               dev_dbg(dai->dev, "port %s is not supported\n", id);
+               return -1;
+       }
+
        SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst);
        drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP;
        drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp)
                                - sizeof(struct sst_dsp_header);
 
-       config = &sst_ssp_configs;
-       dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id);
+       drv->ssp_cmd.selection = ssp_id;
+       dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id);
 
        if (enable)
                drv->ssp_cmd.switch_state = SST_SWITCH_ON;
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w,
 }
 
 static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
+       SST_AIF_IN("modem_in", sst_set_be_modules),
        SST_AIF_IN("codec_in0", sst_set_be_modules),
        SST_AIF_IN("codec_in1", sst_set_be_modules),
+       SST_AIF_OUT("modem_out", sst_set_be_modules),
        SST_AIF_OUT("codec_out0", sst_set_be_modules),
        SST_AIF_OUT("codec_out1", sst_set_be_modules),
 
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
                      sst_mix_codec0_controls, sst_swm_mixer_event),
        SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
                      sst_mix_codec1_controls, sst_swm_mixer_event),
+       SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM,
+                     sst_mix_modem_controls, sst_swm_mixer_event),
+
 };
 
 static const struct snd_soc_dapm_route intercon[] = {
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = {
        SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"),
        {"codec_out1", NULL, "codec_out1 mix 0"},
        SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"),
+       {"modem_out", NULL, "modem_out mix 0"},
+       SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"),
+
 
 };
 static const char * const slot_names[] = {
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = {
        SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]),
        SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]),
        SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]),
+       SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]),
+       SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]),
+
 };
 
 #define SST_GAIN_NUM_CONTROLS 3
index e0113112f668d8c8d8a2fe8692b87d85d92181af..351d814696858f09b386363f6d6e1b6fe8022466 100644 (file)
@@ -35,6 +35,8 @@ enum {
 /* define a bit for each mixer input */
 #define SST_MIX_IP(x)          (x)
 
+#define SST_IP_MODEM           SST_MIX_IP(0)
+#define SST_IP_BT              SST_MIX_IP(1)
 #define SST_IP_CODEC0          SST_MIX_IP(2)
 #define SST_IP_CODEC1          SST_MIX_IP(3)
 #define SST_IP_LOOP0           SST_MIX_IP(4)
@@ -63,6 +65,7 @@ enum {
  * Audio DSP Path Ids. Specified by the audio DSP FW
  */
 enum sst_path_index {
+       SST_PATH_INDEX_MODEM_OUT                = (0x00 << SST_PATH_ID_SHIFT),
        SST_PATH_INDEX_CODEC_OUT0               = (0x02 << SST_PATH_ID_SHIFT),
        SST_PATH_INDEX_CODEC_OUT1               = (0x03 << SST_PATH_ID_SHIFT),
 
@@ -80,6 +83,7 @@ enum sst_path_index {
 
 
        /* Start of input paths */
+       SST_PATH_INDEX_MODEM_IN                 = (0x80 << SST_PATH_ID_SHIFT),
        SST_PATH_INDEX_CODEC_IN0                = (0x82 << SST_PATH_ID_SHIFT),
        SST_PATH_INDEX_CODEC_IN1                = (0x83 << SST_PATH_ID_SHIFT),
 
@@ -105,6 +109,7 @@ enum sst_path_index {
  * path IDs
  */
 enum sst_swm_inputs {
+       SST_SWM_IN_MODEM        = (SST_PATH_INDEX_MODEM_IN        | SST_DEFAULT_CELL_NBR),
        SST_SWM_IN_CODEC0       = (SST_PATH_INDEX_CODEC_IN0       | SST_DEFAULT_CELL_NBR),
        SST_SWM_IN_CODEC1       = (SST_PATH_INDEX_CODEC_IN1       | SST_DEFAULT_CELL_NBR),
        SST_SWM_IN_SPROT_LOOP   = (SST_PATH_INDEX_SPROT_LOOP_IN   | SST_DEFAULT_CELL_NBR),
@@ -124,6 +129,7 @@ enum sst_swm_inputs {
  * path IDs
  */
 enum sst_swm_outputs {
+       SST_SWM_OUT_MODEM       = (SST_PATH_INDEX_MODEM_OUT       | SST_DEFAULT_CELL_NBR),
        SST_SWM_OUT_CODEC0      = (SST_PATH_INDEX_CODEC_OUT0      | SST_DEFAULT_CELL_NBR),
        SST_SWM_OUT_CODEC1      = (SST_PATH_INDEX_CODEC_OUT1      | SST_DEFAULT_CELL_NBR),
        SST_SWM_OUT_SPROT_LOOP  = (SST_PATH_INDEX_SPROT_LOOP_OUT  | SST_DEFAULT_CELL_NBR),
index 52ed434cbca6a9e0a08ebc64bb8ee84111f479d9..25c6d87c818e7caf4bdd904b7b72d17887f58b25 100644 (file)
@@ -670,7 +670,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
        return str_info->buffer_ptr;
 }
 
-static struct snd_pcm_ops sst_platform_ops = {
+static const struct snd_pcm_ops sst_platform_ops = {
        .open = sst_platform_open,
        .ioctl = snd_pcm_lib_ioctl,
        .trigger = sst_platform_pcm_trigger,
index a4b458e770894f0ccb8935ba139aa8a0e5edb6a9..9b6e27385dc90742a37ae2e17a4eca4fe4aca2dd 100644 (file)
@@ -190,7 +190,8 @@ int sst_driver_ops(struct intel_sst_drv *sst)
 
        default:
                dev_err(sst->dev,
-                       "SST Driver capablities missing for dev_id: %x", sst->dev_id);
+                       "SST Driver capabilities missing for dev_id: %x",
+                       sst->dev_id);
                return -EINVAL;
        };
 }
@@ -441,7 +442,7 @@ static int intel_sst_suspend(struct device *dev)
                struct stream_info *stream = &ctx->streams[i];
 
                if (stream->status == STREAM_RUNNING) {
-                       dev_err(dev, "stream %d is running, cant susupend, abort\n", i);
+                       dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
                        return -EBUSY;
                }
        }
index 4d31849712273712549f404c9773daef0860f186..773acfbaaf2f11c30d67874673d7c6cb1b537778 100644 (file)
@@ -39,6 +39,8 @@
 #include <acpi/platform/aclinux.h>
 #include <acpi/actypes.h>
 #include <acpi/acpi_bus.h>
+#include <asm/cpu_device_id.h>
+#include <asm/iosf_mbi.h>
 #include "../sst-mfld-platform.h"
 #include "../../common/sst-dsp.h"
 #include "../../common/sst-acpi.h"
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = {
        .acpi_ipc_irq_index = 5,
 };
 
+/* BYTCR has different BIOS from BYT */
+static const struct sst_res_info bytcr_res_info = {
+       .shim_offset = 0x140000,
+       .shim_size = 0x000100,
+       .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
+       .ssp0_offset = 0xa0000,
+       .ssp0_size = 0x1000,
+       .dma0_offset = 0x98000,
+       .dma0_size = 0x4000,
+       .dma1_offset = 0x9c000,
+       .dma1_size = 0x4000,
+       .iram_offset = 0x0c0000,
+       .iram_size = 0x14000,
+       .dram_offset = 0x100000,
+       .dram_size = 0x28000,
+       .mbox_offset = 0x144000,
+       .mbox_size = 0x1000,
+       .acpi_lpe_res_index = 0,
+       .acpi_ddr_index = 2,
+       .acpi_ipc_irq_index = 0
+};
+
 static struct sst_platform_info byt_rvp_platform_data = {
        .probe_data = &byt_fwparse_info,
        .ipc_info = &byt_ipc_info,
@@ -215,6 +239,47 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
        return 0;
 }
 
+
+static int is_byt_cr(struct device *dev, bool *bytcr)
+{
+       int status = 0;
+
+       if (IS_ENABLED(CONFIG_IOSF_MBI)) {
+               static const struct x86_cpu_id cpu_ids[] = {
+                       { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
+                       {}
+               };
+               int status;
+               u32 bios_status;
+
+               if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) {
+                       /* bail silently */
+                       return status;
+               }
+
+               status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
+                                      MBI_REG_READ, /* 0x10 */
+                                      0x006, /* BIOS_CONFIG */
+                                      &bios_status);
+
+               if (status) {
+                       dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
+               } else {
+                       /* bits 26:27 mirror PMIC options */
+                       bios_status = (bios_status >> 26) & 3;
+
+                       if ((bios_status == 1) || (bios_status == 3))
+                               *bytcr = true;
+                       else
+                               dev_info(dev, "BYT-CR not detected\n");
+               }
+       } else {
+               dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n");
+       }
+       return status;
+}
+
+
 static int sst_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -226,6 +291,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
        struct platform_device *plat_dev;
        struct sst_platform_info *pdata;
        unsigned int dev_id;
+       bool bytcr = false;
 
        id = acpi_match_device(dev->driver->acpi_match_table, dev);
        if (!id)
@@ -251,6 +317,18 @@ static int sst_acpi_probe(struct platform_device *pdev)
 
        dev_dbg(dev, "ACPI device id: %x\n", dev_id);
 
+       ret = sst_alloc_drv_context(&ctx, dev, dev_id);
+       if (ret < 0)
+               return ret;
+
+       ret = is_byt_cr(dev, &bytcr);
+       if (!((ret < 0) || (bytcr == false))) {
+               dev_info(dev, "Detected Baytrail-CR platform\n");
+
+               /* override resource info */
+               byt_rvp_platform_data.res_info = &bytcr_res_info;
+       }
+
        plat_dev = platform_device_register_data(dev, pdata->platform, -1,
                                                NULL, 0);
        if (IS_ERR(plat_dev)) {
@@ -271,10 +349,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
                return PTR_ERR(mdev);
        }
 
-       ret = sst_alloc_drv_context(&ctx, dev, dev_id);
-       if (ret < 0)
-               return ret;
-
        /* Fill sst platform data */
        ctx->pdata = pdata;
        strcpy(ctx->firmware_name, mach->fw_filename);
index 8afa6fe7b0b0023e7877717bad8bbbcfbcce2ec4..bfc889950bb2964abc4653afdc9cee9bc3bde248 100644 (file)
@@ -267,6 +267,9 @@ static void process_fw_async_msg(struct intel_sst_drv *sst_drv_ctx,
                                "Period elapsed rcvd for pipe id 0x%x\n",
                                pipe_id);
                        stream = &sst_drv_ctx->streams[str_id];
+                       /* If stream is dropped, skip processing this message*/
+                       if (stream->status == STREAM_INIT)
+                               break;
                        if (stream->period_elapsed)
                                stream->period_elapsed(stream->pcm_substream);
                        if (stream->compr_cb)
index adb32fefd693a059574674b414abc7d2811985e7..b1e6b8f34a6a797d335e9630b4972842400977f2 100644 (file)
@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
 
        if (response) {
                ret = sst_wait_timeout(sst, block);
-               if (ret < 0) {
+               if (ret < 0)
                        goto out;
-               } else if(block->data) {
-                       if (!data)
-                               goto out;
-                       *data = kzalloc(block->size, GFP_KERNEL);
-                       if (!(*data)) {
+
+               if (data && block->data) {
+                       *data = kmemdup(block->data, block->size, GFP_KERNEL);
+                       if (!*data) {
                                ret = -ENOMEM;
                                goto out;
-                       } else
-                               memcpy(data, (void *) block->data, block->size);
+                       }
                }
        }
 out:
index 88efb62439ba3f8b74832729cac15c6365930857..bff77a1f27fca127cd2a2ae0a5177915b7d1a65f 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/device.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/platform_sst_audio.h>
+#include <linux/clk.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "../../codecs/rt5640.h"
 #include "../atom/sst-atom-controls.h"
 #include "../common/sst-acpi.h"
+#include "../common/sst-dsp.h"
 
 enum {
        BYT_RT5640_DMIC1_MAP,
        BYT_RT5640_DMIC2_MAP,
        BYT_RT5640_IN1_MAP,
+       BYT_RT5640_IN3_MAP,
 };
 
 #define BYT_RT5640_MAP(quirk)  ((quirk) & 0xff)
 #define BYT_RT5640_DMIC_EN     BIT(16)
+#define BYT_RT5640_MONO_SPEAKER BIT(17)
+#define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
+#define BYT_RT5640_SSP2_AIF2     BIT(19) /* default is using AIF1  */
+#define BYT_RT5640_SSP0_AIF1     BIT(20)
+#define BYT_RT5640_SSP0_AIF2     BIT(21)
+#define BYT_RT5640_MCLK_EN     BIT(22)
+#define BYT_RT5640_MCLK_25MHZ  BIT(23)
+
+struct byt_rt5640_private {
+       struct clk *mclk;
+};
 
 static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
-                                       BYT_RT5640_DMIC_EN;
+                                       BYT_RT5640_DMIC_EN |
+                                       BYT_RT5640_MCLK_EN;
+
+static void log_quirks(struct device *dev)
+{
+       if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP)
+               dev_info(dev, "quirk DMIC1_MAP enabled");
+       if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP)
+               dev_info(dev, "quirk DMIC2_MAP enabled");
+       if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP)
+               dev_info(dev, "quirk IN1_MAP enabled");
+       if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP)
+               dev_info(dev, "quirk IN3_MAP enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN)
+               dev_info(dev, "quirk DMIC enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
+               dev_info(dev, "quirk MONO_SPEAKER enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+               dev_info(dev, "quirk DIFF_MIC enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2)
+               dev_info(dev, "quirk SSP2_AIF2 enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1)
+               dev_info(dev, "quirk SSP0_AIF1 enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)
+               dev_info(dev, "quirk SSP0_AIF2 enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
+               dev_info(dev, "quirk MCLK_EN enabled");
+       if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
+               dev_info(dev, "quirk MCLK_25MHZ enabled");
+}
+
+
+#define BYT_CODEC_DAI1 "rt5640-aif1"
+#define BYT_CODEC_DAI2 "rt5640-aif2"
+
+static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card)
+{
+       struct snd_soc_pcm_runtime *rtd;
+
+       list_for_each_entry(rtd, &card->rtd_list, list) {
+               if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1,
+                            strlen(BYT_CODEC_DAI1)))
+                       return rtd->codec_dai;
+               if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
+                               strlen(BYT_CODEC_DAI2)))
+                       return rtd->codec_dai;
+
+       }
+       return NULL;
+}
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+                                 struct snd_kcontrol *k, int  event)
+{
+       struct snd_soc_dapm_context *dapm = w->dapm;
+       struct snd_soc_card *card = dapm->card;
+       struct snd_soc_dai *codec_dai;
+       struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+       int ret;
+
+       codec_dai = byt_get_codec_dai(card);
+       if (!codec_dai) {
+               dev_err(card->dev,
+                       "Codec dai not found; Unable to set platform clock\n");
+               return -EIO;
+       }
+
+       if (SND_SOC_DAPM_EVENT_ON(event)) {
+               if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
+                       ret = clk_prepare_enable(priv->mclk);
+                       if (ret < 0) {
+                               dev_err(card->dev,
+                                       "could not configure MCLK state");
+                               return ret;
+                       }
+               }
+               ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
+                                            48000 * 512,
+                                            SND_SOC_CLOCK_IN);
+       } else {
+               /*
+                * Set codec clock source to internal clock before
+                * turning off the platform clock. Codec needs clock
+                * for Jack detection and button press
+                */
+               ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
+                                            0,
+                                            SND_SOC_CLOCK_IN);
+               if (!ret) {
+                       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
+                               clk_disable_unprepare(priv->mclk);
+               }
+       }
+
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
 
 static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
        SND_SOC_DAPM_HP("Headphone", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
        SND_SOC_DAPM_MIC("Internal Mic", NULL),
        SND_SOC_DAPM_SPK("Speaker", NULL),
+       SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+                           platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+                           SND_SOC_DAPM_POST_PMD),
+
 };
 
 static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
-       {"AIF1 Playback", NULL, "ssp2 Tx"},
-       {"ssp2 Tx", NULL, "codec_out0"},
-       {"ssp2 Tx", NULL, "codec_out1"},
-       {"codec_in0", NULL, "ssp2 Rx"},
-       {"codec_in1", NULL, "ssp2 Rx"},
-       {"ssp2 Rx", NULL, "AIF1 Capture"},
+       {"Headphone", NULL, "Platform Clock"},
+       {"Headset Mic", NULL, "Platform Clock"},
+       {"Internal Mic", NULL, "Platform Clock"},
+       {"Speaker", NULL, "Platform Clock"},
 
        {"Headset Mic", NULL, "MICBIAS1"},
        {"IN2P", NULL, "Headset Mic"},
        {"Headphone", NULL, "HPOL"},
        {"Headphone", NULL, "HPOR"},
-       {"Speaker", NULL, "SPOLP"},
-       {"Speaker", NULL, "SPOLN"},
-       {"Speaker", NULL, "SPORP"},
-       {"Speaker", NULL, "SPORN"},
 };
 
 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
        {"IN1P", NULL, "Internal Mic"},
 };
 
+static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
+       {"Internal Mic", NULL, "MICBIAS1"},
+       {"IN3P", NULL, "Internal Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
+       {"ssp2 Tx", NULL, "codec_out0"},
+       {"ssp2 Tx", NULL, "codec_out1"},
+       {"codec_in0", NULL, "ssp2 Rx"},
+       {"codec_in1", NULL, "ssp2 Rx"},
+
+       {"AIF1 Playback", NULL, "ssp2 Tx"},
+       {"ssp2 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
+       {"ssp2 Tx", NULL, "codec_out0"},
+       {"ssp2 Tx", NULL, "codec_out1"},
+       {"codec_in0", NULL, "ssp2 Rx"},
+       {"codec_in1", NULL, "ssp2 Rx"},
+
+       {"AIF2 Playback", NULL, "ssp2 Tx"},
+       {"ssp2 Rx", NULL, "AIF2 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
+       {"ssp0 Tx", NULL, "modem_out"},
+       {"modem_in", NULL, "ssp0 Rx"},
+
+       {"AIF1 Playback", NULL, "ssp0 Tx"},
+       {"ssp0 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
+       {"ssp0 Tx", NULL, "modem_out"},
+       {"modem_in", NULL, "ssp0 Rx"},
+
+       {"AIF2 Playback", NULL, "ssp0 Tx"},
+       {"ssp0 Rx", NULL, "AIF2 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
+       {"Speaker", NULL, "SPOLP"},
+       {"Speaker", NULL, "SPOLN"},
+       {"Speaker", NULL, "SPORP"},
+       {"Speaker", NULL, "SPORN"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
+       {"Speaker", NULL, "SPOLP"},
+       {"Speaker", NULL, "SPOLN"},
+};
+
 static const struct snd_kcontrol_new byt_rt5640_controls[] = {
        SOC_DAPM_PIN_SWITCH("Headphone"),
        SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        int ret;
 
-       snd_soc_dai_set_bclk_ratio(codec_dai, 50);
-
        ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
                                     params_rate(params) * 512,
                                     SND_SOC_CLOCK_IN);
+
        if (ret < 0) {
                dev_err(rtd->dev, "can't set codec clock %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1,
-                                 params_rate(params) * 50,
-                                 params_rate(params) * 512);
+       if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
+               /* use bitclock as PLL input */
+               if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+                       (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+
+                       /* 2x16 bit slots on SSP0 */
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5640_PLL1_S_BCLK1,
+                                               params_rate(params) * 32,
+                                               params_rate(params) * 512);
+               } else {
+                       /* 2x15 bit slots on SSP2 */
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5640_PLL1_S_BCLK1,
+                                               params_rate(params) * 50,
+                                               params_rate(params) * 512);
+               }
+       } else {
+               if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5640_PLL1_S_MCLK,
+                                               25000000,
+                                               params_rate(params) * 512);
+               } else {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5640_PLL1_S_MCLK,
+                                               19200000,
+                                               params_rate(params) * 512);
+               }
+       }
+
        if (ret < 0) {
                dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
                return ret;
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
        {
                .callback = byt_rt5640_quirk_cb,
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+               },
+               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
+                                                BYT_RT5640_MCLK_EN),
+       },
+       {
+               .callback = byt_rt5640_quirk_cb,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
                },
-               .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
+               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
+                                                BYT_RT5640_MONO_SPEAKER |
+                                                BYT_RT5640_DIFF_MIC |
+                                                BYT_RT5640_SSP0_AIF2 |
+                                                BYT_RT5640_MCLK_EN
+                                                ),
        },
        {
                .callback = byt_rt5640_quirk_cb,
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "DellInc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
                },
                .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
+                                                BYT_RT5640_DMIC_EN |
+                                                BYT_RT5640_MCLK_EN),
+       },
+       {
+               .callback = byt_rt5640_quirk_cb,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
+               },
+               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
+                                                BYT_RT5640_MCLK_EN),
+       },
+       {
+               .callback = byt_rt5640_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
+               },
+               .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP |
                                                 BYT_RT5640_DMIC_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
+                       DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
                },
-               .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
+               .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
+                                               BYT_RT5640_MCLK_EN |
+                                               BYT_RT5640_SSP0_AIF1),
+       },
+       {
+               .callback = byt_rt5640_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+               },
+               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
+                                                BYT_RT5640_MCLK_EN |
+                                                BYT_RT5640_SSP0_AIF1),
+
        },
        {}
 };
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
        struct snd_soc_codec *codec = runtime->codec;
        struct snd_soc_card *card = runtime->card;
        const struct snd_soc_dapm_route *custom_map;
+       struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
        int num_routes;
 
        card->dapm.idle_bias_off = true;
 
        rt5640_sel_asrc_clk_src(codec,
                                RT5640_DA_STEREO_FILTER |
-                               RT5640_AD_STEREO_FILTER,
+                               RT5640_DA_MONO_L_FILTER |
+                               RT5640_DA_MONO_R_FILTER |
+                               RT5640_AD_STEREO_FILTER |
+                               RT5640_AD_MONO_L_FILTER |
+                               RT5640_AD_MONO_R_FILTER,
                                RT5640_CLK_SEL_ASRC);
 
        ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
                custom_map = byt_rt5640_intmic_in1_map;
                num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
                break;
+       case BYT_RT5640_IN3_MAP:
+               custom_map = byt_rt5640_intmic_in3_map;
+               num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
+               break;
        case BYT_RT5640_DMIC2_MAP:
                custom_map = byt_rt5640_intmic_dmic2_map;
                num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
        if (ret)
                return ret;
 
+       if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_ssp2_aif2_map,
+                                       ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
+       } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_ssp0_aif1_map,
+                                       ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
+       } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_ssp0_aif2_map,
+                                       ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
+       } else {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_ssp2_aif1_map,
+                                       ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
+       }
+       if (ret)
+               return ret;
+
+       if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_mono_spk_map,
+                                       ARRAY_SIZE(byt_rt5640_mono_spk_map));
+       } else {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5640_stereo_spk_map,
+                                       ARRAY_SIZE(byt_rt5640_stereo_spk_map));
+       }
+       if (ret)
+               return ret;
+
+       if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
+               snd_soc_update_bits(codec,  RT5640_IN1_IN2, RT5640_IN_DF1,
+                                   RT5640_IN_DF1);
+       }
+
        if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
                ret = rt5640_dmic_enable(codec, 0, 0);
                if (ret)
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
        snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
        snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
 
+       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
+               /*
+                * The firmware might enable the clock at
+                * boot (this information may or may not
+                * be reflected in the enable clock register).
+                * To change the rate we must disable the clock
+                * first to cover these cases. Due to common
+                * clock framework restrictions that do not allow
+                * to disable a clock that has not been enabled,
+                * we need to enable the clock first.
+                */
+               ret = clk_prepare_enable(priv->mclk);
+               if (!ret)
+                       clk_disable_unprepare(priv->mclk);
+
+               if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
+                       ret = clk_set_rate(priv->mclk, 25000000);
+               else
+                       ret = clk_set_rate(priv->mclk, 19200000);
+
+               if (ret)
+                       dev_err(card->dev, "unable to set MCLK rate\n");
+       }
+
        return ret;
 }
 
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
                                                SNDRV_PCM_HW_PARAM_CHANNELS);
        int ret;
 
-       /* The DSP will covert the FE rate to 48k, stereo, 24bits */
+       /* The DSP will covert the FE rate to 48k, stereo */
        rate->min = rate->max = 48000;
        channels->min = channels->max = 2;
 
-       /* set SSP2 to 24-bit */
-       params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+       if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+               (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+
+               /* set SSP0 to 16-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+
+               /*
+                * Default mode for SSP configuration is TDM 4 slot, override config
+                * with explicit setting to I2S 2ch 16-bit. The word length is set with
+                * dai_set_tdm_slot() since there is no other API exposed
+                */
+               ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
+                                       SND_SOC_DAIFMT_I2S     |
+                                       SND_SOC_DAIFMT_NB_IF   |
+                                       SND_SOC_DAIFMT_CBS_CFS
+                       );
+               if (ret < 0) {
+                       dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
+                       return ret;
+               }
 
-       /*
-        * Default mode for SSP configuration is TDM 4 slot, override config
-        * with explicit setting to I2S 2ch 24-bit. The word length is set with
-        * dai_set_tdm_slot() since there is no other API exposed
-        */
-       ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
-                                 SND_SOC_DAIFMT_I2S     |
-                                 SND_SOC_DAIFMT_NB_IF   |
-                                 SND_SOC_DAIFMT_CBS_CFS
-                                 );
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
-               return ret;
-       }
+               ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
+               if (ret < 0) {
+                       dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
+                       return ret;
+               }
 
-       ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
-               return ret;
-       }
+       } else {
+
+               /* set SSP2 to 24-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+               /*
+                * Default mode for SSP configuration is TDM 4 slot, override config
+                * with explicit setting to I2S 2ch 24-bit. The word length is set with
+                * dai_set_tdm_slot() since there is no other API exposed
+                */
+               ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
+                                       SND_SOC_DAIFMT_I2S     |
+                                       SND_SOC_DAIFMT_NB_IF   |
+                                       SND_SOC_DAIFMT_CBS_CFS
+                       );
+               if (ret < 0) {
+                       dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
+                       return ret;
+               }
 
+               ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+               if (ret < 0) {
+                       dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
+                       return ret;
+               }
+       }
        return 0;
 }
 
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
        {
                .name = "SSP2-Codec",
                .id = 1,
-               .cpu_dai_name = "ssp2-port",
+               .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
-               .codec_dai_name = "rt5640-aif1",
+               .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
                .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = {
 };
 
 static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
+static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+
+static bool is_valleyview(void)
+{
+       static const struct x86_cpu_id cpu_ids[] = {
+               { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
+               {}
+       };
+
+       if (!x86_match_cpu(cpu_ids))
+               return false;
+       return true;
+}
+
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
        const char *i2c_name = NULL;
        int i;
        int dai_index;
+       struct byt_rt5640_private *priv;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
+       if (!priv)
+               return -ENOMEM;
 
        /* register the soc card */
        byt_rt5640_card.dev = &pdev->dev;
        mach = byt_rt5640_card.dev->platform_data;
+       snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
 
        /* fix index of codec dai */
        dai_index = MERR_DPCM_COMPR + 1;
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
                byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
        }
 
+       /*
+        * swap SSP0 if bytcr is detected
+        * (will be overridden if DMI quirk is detected)
+        */
+       if (is_valleyview()) {
+               struct sst_platform_info *p_info = mach->pdata;
+               const struct sst_res_info *res_info = p_info->res_info;
+
+               /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */
+               if (res_info->acpi_ipc_irq_index == 0) {
+                       byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
+               }
+       }
+
        /* check quirks before creating card */
        dmi_check_system(byt_rt5640_quirk_table);
+       log_quirks(&pdev->dev);
+
+       if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
+           (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+
+               /* fixup codec aif name */
+               snprintf(byt_rt5640_codec_aif_name,
+                       sizeof(byt_rt5640_codec_aif_name),
+                       "%s", "rt5640-aif2");
+
+               byt_rt5640_dais[dai_index].codec_dai_name =
+                       byt_rt5640_codec_aif_name;
+       }
+
+       if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+           (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+
+               /* fixup cpu dai name name */
+               snprintf(byt_rt5640_cpu_dai_name,
+                       sizeof(byt_rt5640_cpu_dai_name),
+                       "%s", "ssp0-port");
+
+               byt_rt5640_dais[dai_index].cpu_dai_name =
+                       byt_rt5640_cpu_dai_name;
+       }
+
+       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
+               priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+               if (IS_ERR(priv->mclk)) {
+                       dev_err(&pdev->dev,
+                               "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
+                               PTR_ERR(priv->mclk));
+                       return PTR_ERR(priv->mclk);
+               }
+       }
 
        ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
 
index 3154525c2b83596eac3a2c57ce4d6b2ac0dfaf8d..9e4094e2c6e319a02aefecd039e68d5fd1465201 100644 (file)
@@ -871,7 +871,7 @@ out:
        return ret;
 }
 
-static struct snd_pcm_ops hsw_pcm_ops = {
+static const struct snd_pcm_ops hsw_pcm_ops = {
        .open           = hsw_pcm_open,
        .close          = hsw_pcm_close,
        .ioctl          = snd_pcm_lib_ioctl,
index 2663781278aa8b9648e23d7bc6fcc7623bb834e8..48a4ae583dd9e45e133f28d8712be70e5950e619 100644 (file)
@@ -23,6 +23,7 @@
 #include "../common/sst-dsp.h"
 #include "../common/sst-dsp-priv.h"
 #include "skl-sst-ipc.h"
+#include "skl-tplg-interface.h"
 
 #define BXT_BASEFW_TIMEOUT     3000
 #define BXT_INIT_TIMEOUT       500
 #define BXT_INSTANCE_ID 0
 #define BXT_BASE_FW_MODULE_ID 0
 
+#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
+
 static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
 {
         return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
 }
 
+static int
+bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo)
+{
+       struct snd_dma_buffer dmab;
+       struct skl_sst *skl = ctx->thread_context;
+       const struct firmware *fw = NULL;
+       struct firmware stripped_fw;
+       int ret = 0, i, dma_id, stream_tag;
+
+       /* library indices start from 1 to N. 0 represents base FW */
+       for (i = 1; i < minfo->lib_count; i++) {
+               ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev);
+               if (ret < 0) {
+                       dev_err(ctx->dev, "Request lib %s failed:%d\n",
+                                       minfo->lib[i].name, ret);
+                       return ret;
+               }
+
+               if (skl->is_first_boot) {
+                       ret = snd_skl_parse_uuids(ctx, fw,
+                                       BXT_ADSP_FW_BIN_HDR_OFFSET, i);
+                       if (ret < 0)
+                               goto load_library_failed;
+               }
+
+               stripped_fw.data = fw->data;
+               stripped_fw.size = fw->size;
+               skl_dsp_strip_extended_manifest(&stripped_fw);
+
+               stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
+                                       stripped_fw.size, &dmab);
+               if (stream_tag <= 0) {
+                       dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
+                                       stream_tag);
+                       ret = stream_tag;
+                       goto load_library_failed;
+               }
+
+               dma_id = stream_tag - 1;
+               memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
+
+               ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
+               ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
+               if (ret < 0)
+                       dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
+                                       minfo->lib[i].name, ret);
+
+               ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
+               ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
+               release_firmware(fw);
+               fw = NULL;
+       }
+
+       return ret;
+
+load_library_failed:
+       release_firmware(fw);
+       return ret;
+}
+
 /*
  * First boot sequence has some extra steps. Core 0 waits for power
  * status on core 1, so power up core 1 also momentarily, keep it in
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
        return ret;
 }
 
-#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
-
 static int bxt_load_base_firmware(struct sst_dsp *ctx)
 {
        struct firmware stripped_fw;
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
        if (ctx->fw == NULL)
                goto sst_load_base_firmware_failed;
 
-       ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET);
-       if (ret < 0)
-               goto sst_load_base_firmware_failed;
+       /* prase uuids on first boot */
+       if (skl->is_first_boot) {
+               ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
+               if (ret < 0)
+                       goto sst_load_base_firmware_failed;
+       }
 
        stripped_fw.data = ctx->fw->data;
        stripped_fw.size = ctx->fw->size;
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
        int ret;
        struct skl_ipc_dxstate_info dx;
        unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
+       struct skl_dfw_manifest *minfo = &skl->manifest;
 
        if (skl->fw_loaded == false) {
                skl->boot_complete = false;
                ret = bxt_load_base_firmware(ctx);
-               if (ret < 0)
+               if (ret < 0) {
                        dev_err(ctx->dev, "reload fw failed: %d\n", ret);
+                       return ret;
+               }
+
+               if (minfo->lib_count > 1) {
+                       ret = bxt_load_library(ctx, minfo);
+                       if (ret < 0) {
+                               dev_err(ctx->dev, "reload libs failed: %d\n", ret);
+                               return ret;
+                       }
+               }
                return ret;
        }
 
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = {
        .set_state_D3 = bxt_set_dsp_D3,
        .load_fw = bxt_load_base_firmware,
        .get_fw_errcode = bxt_get_errorcode,
+       .load_library = bxt_load_library,
 };
 
 static struct sst_ops skl_ops = {
@@ -397,6 +473,19 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
        skl->cores.count = 2;
        skl->boot_complete = false;
        init_waitqueue_head(&skl->boot_wait);
+       skl->is_first_boot = true;
+
+       if (dsp)
+               *dsp = skl;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
+
+int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
+{
+       int ret;
+       struct sst_dsp *sst = ctx->dsp;
 
        ret = sst->fw_ops.load_fw(sst);
        if (ret < 0) {
@@ -406,13 +495,18 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
 
        skl_dsp_init_core_state(sst);
 
-       if (dsp)
-               *dsp = skl;
+       if (ctx->manifest.lib_count > 1) {
+               ret = sst->fw_ops.load_library(sst, &ctx->manifest);
+               if (ret < 0) {
+                       dev_err(dev, "Load Library failed : %x", ret);
+                       return ret;
+               }
+       }
+       ctx->is_first_boot = false;
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
-
+EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
 
 void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
 {
index 83a731fc884ea0967358333185aed672e963a1ff..8eb5ba2dae3abc610635363eb9498bec086c2603 100644 (file)
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = {
                .id = 0x9d70,
                .loader_ops = skl_get_loader_ops,
                .init = skl_sst_dsp_init,
+               .init_fw = skl_sst_init_fw,
                .cleanup = skl_sst_dsp_cleanup
        },
        {
                .id = 0x9d71,
                .loader_ops = skl_get_loader_ops,
                .init = skl_sst_dsp_init,
+               .init_fw = skl_sst_init_fw,
                .cleanup = skl_sst_dsp_cleanup
        },
        {
                .id = 0x5a98,
                .loader_ops = bxt_get_loader_ops,
                .init = bxt_sst_dsp_init,
+               .init_fw = bxt_sst_init_fw,
                .cleanup = bxt_sst_dsp_cleanup
        },
 };
 
-static int skl_get_dsp_ops(int pci_id)
+const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
                if (dsp_ops[i].id == pci_id)
-                       return i;
+                       return &dsp_ops[i];
        }
 
-       return -EINVAL;
+       return NULL;
 }
 
 int skl_init_dsp(struct skl *skl)
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl)
        struct hdac_bus *bus = ebus_to_hbus(ebus);
        struct skl_dsp_loader_ops loader_ops;
        int irq = bus->irq;
-       int ret, index;
+       const struct skl_dsp_ops *ops;
+       int ret;
 
        /* enable ppcap interrupt */
        snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl)
                return -ENXIO;
        }
 
-       index  = skl_get_dsp_ops(skl->pci->device);
-       if (index  < 0)
-               return -EINVAL;
+       ops = skl_get_dsp_ops(skl->pci->device);
+       if (!ops)
+               return -EIO;
 
-       loader_ops = dsp_ops[index].loader_ops();
-       ret = dsp_ops[index].init(bus->dev, mmio_base, irq,
-                       skl->fw_name, loader_ops, &skl->skl_sst);
+       loader_ops = ops->loader_ops();
+       ret = ops->init(bus->dev, mmio_base, irq,
+                               skl->fw_name, loader_ops,
+                               &skl->skl_sst);
 
        if (ret < 0)
                return ret;
 
-       skl_dsp_enable_notification(skl->skl_sst, false);
        dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
 
        return ret;
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl)
        struct hdac_ext_bus *ebus = &skl->ebus;
        struct hdac_bus *bus = ebus_to_hbus(ebus);
        struct skl_sst *ctx = skl->skl_sst;
-       int index;
+       const struct skl_dsp_ops *ops;
 
        /* disable  ppcap interrupt */
        snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
 
-       index = skl_get_dsp_ops(skl->pci->device);
-       if (index  < 0)
+       ops = skl_get_dsp_ops(skl->pci->device);
+       if (!ops)
                return -EIO;
 
-       dsp_ops[index].cleanup(bus->dev, ctx);
+       ops->cleanup(bus->dev, ctx);
 
        if (ctx->dsp->addr.lpe)
                iounmap(ctx->dsp->addr.lpe);
@@ -323,6 +327,10 @@ int skl_resume_dsp(struct skl *skl)
        snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
        snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
 
+       /* check if DSP 1st boot is done */
+       if (skl->skl_sst->is_first_boot == true)
+               return 0;
+
        ret = skl_dsp_wake(ctx->dsp);
        if (ret < 0)
                return ret;
@@ -862,6 +870,7 @@ int skl_init_module(struct skl_sst *ctx,
        msg.ppl_instance_id = mconfig->pipe->ppl_id;
        msg.param_data_size = module_config_size;
        msg.core_id = mconfig->core_id;
+       msg.domain = mconfig->domain;
 
        ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
        if (ret < 0) {
index 5ae86c227d453eceb39852cd50e4015483f44e3f..86c125f52cde9e37da45a01fda373d9686270517 100644 (file)
@@ -1020,7 +1020,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
 {
        struct hdac_ext_bus *ebus = get_bus_ctx(substream);
 
-       if ((ebus_to_hbus(ebus))->ppcap)
+       if (!(ebus_to_hbus(ebus))->ppcap)
                return skl_coupled_trigger(substream, cmd);
 
        return 0;
@@ -1093,7 +1093,7 @@ static int skl_get_time_info(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_pcm_ops skl_platform_ops = {
+static const struct snd_pcm_ops skl_platform_ops = {
        .open = skl_platform_open,
        .ioctl = snd_pcm_lib_ioctl,
        .trigger = skl_platform_pcm_trigger,
@@ -1138,12 +1138,40 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
        return retval;
 }
 
+static int skl_populate_modules(struct skl *skl)
+{
+       struct skl_pipeline *p;
+       struct skl_pipe_module *m;
+       struct snd_soc_dapm_widget *w;
+       struct skl_module_cfg *mconfig;
+       int ret;
+
+       list_for_each_entry(p, &skl->ppl_list, node) {
+               list_for_each_entry(m, &p->pipe->w_list, node) {
+
+                       w = m->w;
+                       mconfig = w->priv;
+
+                       ret = snd_skl_get_module_info(skl->skl_sst, mconfig);
+                       if (ret < 0) {
+                               dev_err(skl->skl_sst->dev,
+                                       "query module info failed:%d\n", ret);
+                               goto err;
+                       }
+               }
+       }
+err:
+       return ret;
+}
+
 static int skl_platform_soc_probe(struct snd_soc_platform *platform)
 {
        struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
        struct skl *skl = ebus_to_skl(ebus);
+       const struct skl_dsp_ops *ops;
        int ret;
 
+       pm_runtime_get_sync(platform->dev);
        if ((ebus_to_hbus(ebus))->ppcap) {
                ret = skl_tplg_init(platform, ebus);
                if (ret < 0) {
@@ -1151,7 +1179,26 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
                        return ret;
                }
                skl->platform = platform;
+
+               /* load the firmwares, since all is set */
+               ops = skl_get_dsp_ops(skl->pci->device);
+               if (!ops)
+                       return -EIO;
+
+               if (skl->skl_sst->is_first_boot == false) {
+                       dev_err(platform->dev, "DSP reports first boot done!!!\n");
+                       return -EIO;
+               }
+
+               ret = ops->init_fw(platform->dev, skl->skl_sst);
+               if (ret < 0) {
+                       dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
+                       return ret;
+               }
+               skl_populate_modules(skl);
        }
+       pm_runtime_mark_last_busy(platform->dev);
+       pm_runtime_put_autosuspend(platform->dev);
 
        return 0;
 }
index 0f8629ef79ac86a315029b19e28a780323d9b11c..6ad5cab4b0d5da423557f35e2ef5cca74257ac2c 100644 (file)
@@ -20,6 +20,7 @@
 #include <sound/memalloc.h>
 #include "skl-sst-cldma.h"
 #include "skl-tplg-interface.h"
+#include "skl-topology.h"
 
 struct sst_dsp;
 struct skl_sst;
@@ -133,6 +134,8 @@ enum skl_dsp_states {
 struct skl_dsp_fw_ops {
        int (*load_fw)(struct sst_dsp  *ctx);
        /* FW module parser/loader */
+       int (*load_library)(struct sst_dsp *ctx,
+               struct skl_dfw_manifest *minfo);
        int (*parse_fw)(struct sst_dsp *ctx);
        int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
        int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
@@ -203,12 +206,15 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
 int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
                const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
                struct skl_sst **dsp);
+int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
+int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
 void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
 void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
 
-int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
-               struct skl_dfw_module *dfw_config);
-int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset);
+int snd_skl_get_module_info(struct skl_sst *ctx,
+                               struct skl_module_cfg *mconfig);
+int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
+                               unsigned int offset, int index);
 void skl_freeup_uuid_list(struct skl_sst *ctx);
 
 int skl_dsp_strip_extended_manifest(struct firmware *fw);
index 96f2f6889b1893bea1cce2445cdf024b35b4e21e..74dbecc3afaab7b41b9202c502b6c3be5cd4ccf9 100644 (file)
 #define IPC_CORE_ID(x)                 (((x) & IPC_CORE_ID_MASK) \
                                        << IPC_CORE_ID_SHIFT)
 
+#define IPC_DOMAIN_SHIFT                28
+#define IPC_DOMAIN_MASK                 0x1
+#define IPC_DOMAIN(x)                   (((x) & IPC_DOMAIN_MASK) \
+                                       << IPC_DOMAIN_SHIFT)
+
 /* Bind/Unbind message extension register */
 #define IPC_DST_MOD_ID_SHIFT           0
 #define IPC_DST_MOD_ID(x)              (((x) & IPC_MOD_ID_MASK) \
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type {
        IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
        IPC_GLB_SAVE_PPL = 22,
        IPC_GLB_RESTORE_PPL = 23,
+       IPC_GLB_LOAD_LIBRARY = 24,
        IPC_GLB_NOTIFY = 26,
        IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
 };
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
        header.extension = IPC_CORE_ID(msg->core_id);
        header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
        header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
+       header.extension |= IPC_DOMAIN(msg->domain);
 
        dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
                         header.primary, header.extension);
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
        return ret;
 }
 EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
+
+int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
+                               u8 dma_id, u8 table_id)
+{
+       struct skl_ipc_header header = {0};
+       u64 *ipc_header = (u64 *)(&header);
+       int ret = 0;
+
+       header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
+       header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
+       header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
+       header.primary |= IPC_MOD_INSTANCE_ID(table_id);
+       header.primary |= IPC_MOD_ID(dma_id);
+
+       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+
+       if (ret < 0)
+               dev_err(ipc->dev, "ipc: load lib failed\n");
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
index 2e3d4e80ef97553fb0573b1d9f7d888fb41cb58c..0334ed4af0312a89eef15a09f05a67c88465272b 100644 (file)
@@ -66,7 +66,7 @@ struct skl_sst {
 
        /* callback for miscbdge */
        void (*enable_miscbdcge)(struct device *dev, bool enable);
-       /*Is CGCTL.MISCBDCGE disabled*/
+       /* Is CGCTL.MISCBDCGE disabled */
        bool miscbdcg_disabled;
 
        /* Populate module information */
@@ -75,8 +75,14 @@ struct skl_sst {
        /* Is firmware loaded */
        bool fw_loaded;
 
+       /* first boot ? */
+       bool is_first_boot;
+
        /* multi-core */
        struct skl_dsp_cores cores;
+
+       /* tplg manifest */
+       struct skl_dfw_manifest manifest;
 };
 
 struct skl_ipc_init_instance_msg {
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg {
        u16 param_data_size;
        u8 ppl_instance_id;
        u8 core_id;
+       u8 domain;
 };
 
 struct skl_ipc_bind_unbind_msg {
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
                struct skl_ipc_large_config_msg *msg, u32 *param);
 
+int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
+                       u8 dma_id, u8 table_id);
+
 void skl_ipc_int_enable(struct sst_dsp *dsp);
 void skl_ipc_op_int_enable(struct sst_dsp *ctx);
 void skl_ipc_op_int_disable(struct sst_dsp *ctx);
index ddcb52a5185481057fc40b406bf3f09077b51984..3a508b7a004128c5ffc4a08f3cdf5ad3cd7546e8 100644 (file)
 /* FW Extended Manifest Header id = $AE1 */
 #define SKL_EXT_MANIFEST_HEADER_MAGIC   0x31454124
 
-struct skl_dfw_module_mod {
-       char name[100];
-       struct skl_dfw_module skl_dfw_mod;
-};
-
 struct UUID {
        u8 id[16];
 };
@@ -115,13 +110,13 @@ struct skl_ext_manifest_hdr {
        u32 entries;
 };
 
-int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
-                       struct skl_dfw_module *dfw_config)
+int snd_skl_get_module_info(struct skl_sst *ctx,
+                               struct skl_module_cfg *mconfig)
 {
        struct uuid_module *module;
        uuid_le *uuid_mod;
 
-       uuid_mod = (uuid_le *)uuid;
+       uuid_mod = (uuid_le *)mconfig->guid;
 
        if (list_empty(&ctx->uuid_list)) {
                dev_err(ctx->dev, "Module list is empty\n");
@@ -130,8 +125,8 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
 
        list_for_each_entry(module, &ctx->uuid_list, list) {
                if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
-                       dfw_config->module_id = module->id;
-                       dfw_config->is_loadable = module->is_loadable;
+                       mconfig->id.module_id = module->id;
+                       mconfig->is_loadable = module->is_loadable;
 
                        return 0;
                }
@@ -145,7 +140,8 @@ EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
  * Parse the firmware binary to get the UUID, module id
  * and loadable flags
  */
-int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
+int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
+                       unsigned int offset, int index)
 {
        struct adsp_fw_hdr *adsp_hdr;
        struct adsp_module_entry *mod_entry;
@@ -158,8 +154,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
        unsigned int safe_file;
 
        /* Get the FW pointer to derive ADSP header */
-       stripped_fw.data = ctx->fw->data;
-       stripped_fw.size = ctx->fw->size;
+       stripped_fw.data = fw->data;
+       stripped_fw.size = fw->size;
 
        skl_dsp_strip_extended_manifest(&stripped_fw);
 
@@ -210,7 +206,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
                uuid_bin = (uuid_le *)mod_entry->uuid.id;
                memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
 
-               module->id = i;
+               module->id = (i | (index << 12));
                module->is_loadable = mod_entry->type.load_type;
 
                list_add_tail(&module->list, &skl->uuid_list);
index 588f899ceb652b5efcb2b87451a058f6dfc2ab0d..064fc7ee3d88adbd11ab5c083ea6788e4bb056d4 100644 (file)
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
                }
        }
 
-       ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET);
-       if (ret < 0) {
-               dev_err(ctx->dev,
-                               "UUID parsing err: %d\n", ret);
-               release_firmware(ctx->fw);
-               skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
-               return ret;
+       /* prase uuids on first boot */
+       if (skl->is_first_boot) {
+               ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0);
+               if (ret < 0) {
+                       dev_err(ctx->dev, "UUID parsing err: %d\n", ret);
+                       release_firmware(ctx->fw);
+                       skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
+                       return ret;
+               }
        }
 
        /* check for extended manifest */
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
                return ret;
 
        skl->cores.count = 2;
+       skl->is_first_boot = true;
+
+       if (dsp)
+               *dsp = skl;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
+
+int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
+{
+       int ret;
+       struct sst_dsp *sst = ctx->dsp;
 
        ret = sst->fw_ops.load_fw(sst);
        if (ret < 0) {
                dev_err(dev, "Load base fw failed : %d", ret);
-               goto cleanup;
+               return ret;
        }
 
        skl_dsp_init_core_state(sst);
+       ctx->is_first_boot = false;
 
-       if (dsp)
-               *dsp = skl;
-
-       return ret;
-
-cleanup:
-       skl_sst_dsp_cleanup(dev, skl);
-       return ret;
+       return 0;
 }
-EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
+EXPORT_SYMBOL_GPL(skl_sst_init_fw);
 
 void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
 {
index cc0150fc2601ef10e163a239b76a4a6fabd1130c..2d475b7209634a28b57d50a0e46f9c9b35599898 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/firmware.h>
 #include <sound/soc.h>
 #include <sound/soc-topology.h>
+#include <uapi/sound/snd_sst_tokens.h>
 #include "skl-sst-dsp.h"
 #include "skl-sst-ipc.h"
 #include "skl-topology.h"
@@ -32,6 +33,8 @@
 #define SKL_CH_FIXUP_MASK              (1 << 0)
 #define SKL_RATE_FIXUP_MASK            (1 << 1)
 #define SKL_FMT_FIXUP_MASK             (1 << 2)
+#define SKL_IN_DIR_BIT_MASK            BIT(0)
+#define SKL_PIN_COUNT_MASK             GENMASK(7, 4)
 
 /*
  * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
@@ -473,6 +476,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
                w = w_module->w;
                mconfig = w->priv;
 
+               /* check if module ids are populated */
+               if (mconfig->id.module_id < 0) {
+                       dev_err(skl->skl_sst->dev,
+                                       "module %pUL id not populated\n",
+                                       (uuid_le *)mconfig->guid);
+                       return -EIO;
+               }
+
                /* check resource available */
                if (!skl_is_pipe_mcps_avail(skl, mconfig))
                        return -ENOMEM;
@@ -512,6 +523,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
 static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
         struct skl_pipe *pipe)
 {
+       int ret;
        struct skl_pipe_module *w_module = NULL;
        struct skl_module_cfg *mconfig = NULL;
 
@@ -519,9 +531,12 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
                mconfig  = w_module->w->priv;
 
                if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
-                       mconfig->m_state > SKL_MODULE_UNINIT)
-                       return ctx->dsp->fw_ops.unload_mod(ctx->dsp,
+                       mconfig->m_state > SKL_MODULE_UNINIT) {
+                       ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp,
                                                mconfig->id.module_id);
+                       if (ret < 0)
+                               return -EIO;
+               }
        }
 
        /* no modules to unload in this path, so return */
@@ -1460,85 +1475,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
                                        skl_tplg_tlv_control_set},
 };
 
-/*
- * The topology binary passes the pin info for a module so initialize the pin
- * info passed into module instance
- */
-static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
-                                               struct skl_module_pin *m_pin,
-                                               bool is_dynamic, int max_pin)
+static int skl_tplg_fill_pipe_tkn(struct device *dev,
+                       struct skl_pipe *pipe, u32 tkn,
+                       u32 tkn_val)
 {
-       int i;
 
-       for (i = 0; i < max_pin; i++) {
-               m_pin[i].id.module_id = dfw_pin[i].module_id;
-               m_pin[i].id.instance_id = dfw_pin[i].instance_id;
-               m_pin[i].in_use = false;
-               m_pin[i].is_dynamic = is_dynamic;
-               m_pin[i].pin_state = SKL_PIN_UNBIND;
+       switch (tkn) {
+       case SKL_TKN_U32_PIPE_CONN_TYPE:
+               pipe->conn_type = tkn_val;
+               break;
+
+       case SKL_TKN_U32_PIPE_PRIORITY:
+               pipe->pipe_priority = tkn_val;
+               break;
+
+       case SKL_TKN_U32_PIPE_MEM_PGS:
+               pipe->memory_pages = tkn_val;
+               break;
+
+       default:
+               dev_err(dev, "Token not handled %d\n", tkn);
+               return -EINVAL;
        }
+
+       return 0;
 }
 
 /*
- * Add pipeline from topology binary into driver pipeline list
- *
- * If already added we return that instance
- * Otherwise we create a new instance and add into driver list
+ * Add pipeline by parsing the relevant tokens
+ * Return an existing pipe if the pipe already exists.
  */
-static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
-                       struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
+static int skl_tplg_add_pipe(struct device *dev,
+               struct skl_module_cfg *mconfig, struct skl *skl,
+               struct snd_soc_tplg_vendor_value_elem *tkn_elem)
 {
        struct skl_pipeline *ppl;
        struct skl_pipe *pipe;
        struct skl_pipe_params *params;
 
        list_for_each_entry(ppl, &skl->ppl_list, node) {
-               if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
-                       return ppl->pipe;
+               if (ppl->pipe->ppl_id == tkn_elem->value) {
+                       mconfig->pipe = ppl->pipe;
+                       return EEXIST;
+               }
        }
 
        ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
        if (!ppl)
-               return NULL;
+               return -ENOMEM;
 
        pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
        if (!pipe)
-               return NULL;
+               return -ENOMEM;
 
        params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
        if (!params)
-               return NULL;
+               return -ENOMEM;
 
-       pipe->ppl_id = dfw_pipe->pipe_id;
-       pipe->memory_pages = dfw_pipe->memory_pages;
-       pipe->pipe_priority = dfw_pipe->pipe_priority;
-       pipe->conn_type = dfw_pipe->conn_type;
-       pipe->state = SKL_PIPE_INVALID;
        pipe->p_params = params;
+       pipe->ppl_id = tkn_elem->value;
        INIT_LIST_HEAD(&pipe->w_list);
 
        ppl->pipe = pipe;
        list_add(&ppl->node, &skl->ppl_list);
 
-       return ppl->pipe;
+       mconfig->pipe = pipe;
+       mconfig->pipe->state = SKL_PIPE_INVALID;
+
+       return 0;
+}
+
+static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
+                       struct skl_module_pin *m_pin,
+                       int pin_index, u32 value)
+{
+       switch (tkn) {
+       case SKL_TKN_U32_PIN_MOD_ID:
+               m_pin[pin_index].id.module_id = value;
+               break;
+
+       case SKL_TKN_U32_PIN_INST_ID:
+               m_pin[pin_index].id.instance_id = value;
+               break;
+
+       default:
+               dev_err(dev, "%d Not a pin token\n", value);
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
-static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
-                               struct skl_dfw_module_fmt *src_fmt,
-                               int pins)
+/*
+ * Parse for pin config specific tokens to fill up the
+ * module private data
+ */
+static int skl_tplg_fill_pins_info(struct device *dev,
+               struct skl_module_cfg *mconfig,
+               struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+               int dir, int pin_count)
+{
+       int ret;
+       struct skl_module_pin *m_pin;
+
+       switch (dir) {
+       case SKL_DIR_IN:
+               m_pin = mconfig->m_in_pin;
+               break;
+
+       case SKL_DIR_OUT:
+               m_pin = mconfig->m_out_pin;
+               break;
+
+       default:
+               dev_err(dev, "Invalid direction value");
+               return -EINVAL;
+       }
+
+       ret = skl_tplg_fill_pin(dev, tkn_elem->token,
+                       m_pin, pin_count, tkn_elem->value);
+
+       if (ret < 0)
+               return ret;
+
+       m_pin[pin_count].in_use = false;
+       m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
+
+       return 0;
+}
+
+/*
+ * Fill up input/output module config format based
+ * on the direction
+ */
+static int skl_tplg_fill_fmt(struct device *dev,
+               struct skl_module_cfg *mconfig, u32 tkn,
+               u32 value, u32 dir, u32 pin_count)
+{
+       struct skl_module_fmt *dst_fmt;
+
+       switch (dir) {
+       case SKL_DIR_IN:
+               dst_fmt = mconfig->in_fmt;
+               dst_fmt += pin_count;
+               break;
+
+       case SKL_DIR_OUT:
+               dst_fmt = mconfig->out_fmt;
+               dst_fmt += pin_count;
+               break;
+
+       default:
+               dev_err(dev, "Invalid direction value");
+               return -EINVAL;
+       }
+
+       switch (tkn) {
+       case SKL_TKN_U32_FMT_CH:
+               dst_fmt->channels  = value;
+               break;
+
+       case SKL_TKN_U32_FMT_FREQ:
+               dst_fmt->s_freq = value;
+               break;
+
+       case SKL_TKN_U32_FMT_BIT_DEPTH:
+               dst_fmt->bit_depth = value;
+               break;
+
+       case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+               dst_fmt->valid_bit_depth = value;
+               break;
+
+       case SKL_TKN_U32_FMT_CH_CONFIG:
+               dst_fmt->ch_cfg = value;
+               break;
+
+       case SKL_TKN_U32_FMT_INTERLEAVE:
+               dst_fmt->interleaving_style = value;
+               break;
+
+       case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+               dst_fmt->sample_type = value;
+               break;
+
+       case SKL_TKN_U32_FMT_CH_MAP:
+               dst_fmt->ch_map = value;
+               break;
+
+       default:
+               dev_err(dev, "Invalid token %d", tkn);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
+             struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
+{
+       if (uuid_tkn->token == SKL_TKN_UUID)
+               memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
+       else {
+               dev_err(dev, "Not an UUID token tkn %d", uuid_tkn->token);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void skl_tplg_fill_pin_dynamic_val(
+               struct skl_module_pin *mpin, u32 pin_count, u32 value)
 {
        int i;
 
-       for (i = 0; i < pins; i++) {
-               dst_fmt[i].channels  = src_fmt[i].channels;
-               dst_fmt[i].s_freq = src_fmt[i].freq;
-               dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
-               dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
-               dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
-               dst_fmt[i].ch_map = src_fmt[i].ch_map;
-               dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
-               dst_fmt[i].sample_type = src_fmt[i].sample_type;
+       for (i = 0; i < pin_count; i++)
+               mpin[i].is_dynamic = value;
+}
+
+/*
+ * Parse tokens to fill up the module private data
+ */
+static int skl_tplg_get_token(struct device *dev,
+               struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+               struct skl *skl, struct skl_module_cfg *mconfig)
+{
+       int tkn_count = 0;
+       int ret;
+       static int is_pipe_exists;
+       static int pin_index, dir;
+
+       if (tkn_elem->token > SKL_TKN_MAX)
+               return -EINVAL;
+
+       switch (tkn_elem->token) {
+       case SKL_TKN_U8_IN_QUEUE_COUNT:
+               mconfig->max_in_queue = tkn_elem->value;
+               mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue *
+                                       sizeof(*mconfig->m_in_pin),
+                                       GFP_KERNEL);
+               if (!mconfig->m_in_pin)
+                       return -ENOMEM;
+
+               break;
+
+       case SKL_TKN_U8_OUT_QUEUE_COUNT:
+               mconfig->max_out_queue = tkn_elem->value;
+               mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue *
+                                       sizeof(*mconfig->m_out_pin),
+                                       GFP_KERNEL);
+
+               if (!mconfig->m_out_pin)
+                       return -ENOMEM;
+
+               break;
+
+       case SKL_TKN_U8_DYN_IN_PIN:
+               if (!mconfig->m_in_pin)
+                       return -ENOMEM;
+
+               skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin,
+                       mconfig->max_in_queue, tkn_elem->value);
+
+               break;
+
+       case SKL_TKN_U8_DYN_OUT_PIN:
+               if (!mconfig->m_out_pin)
+                       return -ENOMEM;
+
+               skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin,
+                       mconfig->max_out_queue, tkn_elem->value);
+
+               break;
+
+       case SKL_TKN_U8_TIME_SLOT:
+               mconfig->time_slot = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U8_CORE_ID:
+               mconfig->core_id = tkn_elem->value;
+
+       case SKL_TKN_U8_MOD_TYPE:
+               mconfig->m_type = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U8_DEV_TYPE:
+               mconfig->dev_type = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U8_HW_CONN_TYPE:
+               mconfig->hw_conn_type = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U16_MOD_INST_ID:
+               mconfig->id.instance_id =
+               tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_MEM_PAGES:
+               mconfig->mem_pages = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_MAX_MCPS:
+               mconfig->mcps = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_OBS:
+               mconfig->obs = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_IBS:
+               mconfig->ibs = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_VBUS_ID:
+               mconfig->vbus_id = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_PARAMS_FIXUP:
+               mconfig->params_fixup = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_CONVERTER:
+               mconfig->converter = tkn_elem->value;
+               break;
+
+       case SKL_TKN_U32_PIPE_ID:
+               ret = skl_tplg_add_pipe(dev,
+                               mconfig, skl, tkn_elem);
+
+               if (ret < 0)
+                       return is_pipe_exists;
+
+               if (ret == EEXIST)
+                       is_pipe_exists = 1;
+
+               break;
+
+       case SKL_TKN_U32_PIPE_CONN_TYPE:
+       case SKL_TKN_U32_PIPE_PRIORITY:
+       case SKL_TKN_U32_PIPE_MEM_PGS:
+               if (is_pipe_exists) {
+                       ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
+                                       tkn_elem->token, tkn_elem->value);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               break;
+
+       /*
+        * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
+        * direction and the pin count. The first four bits represent
+        * direction and next four the pin count.
+        */
+       case SKL_TKN_U32_DIR_PIN_COUNT:
+               dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
+               pin_index = (tkn_elem->value &
+                       SKL_PIN_COUNT_MASK) >> 4;
+
+               break;
+
+       case SKL_TKN_U32_FMT_CH:
+       case SKL_TKN_U32_FMT_FREQ:
+       case SKL_TKN_U32_FMT_BIT_DEPTH:
+       case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+       case SKL_TKN_U32_FMT_CH_CONFIG:
+       case SKL_TKN_U32_FMT_INTERLEAVE:
+       case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+       case SKL_TKN_U32_FMT_CH_MAP:
+               ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token,
+                               tkn_elem->value, dir, pin_index);
+
+               if (ret < 0)
+                       return ret;
+
+               break;
+
+       case SKL_TKN_U32_PIN_MOD_ID:
+       case SKL_TKN_U32_PIN_INST_ID:
+               ret = skl_tplg_fill_pins_info(dev,
+                               mconfig, tkn_elem, dir,
+                               pin_index);
+               if (ret < 0)
+                       return ret;
+
+               break;
+
+       case SKL_TKN_U32_CAPS_SIZE:
+               mconfig->formats_config.caps_size =
+                       tkn_elem->value;
+
+               break;
+
+       case SKL_TKN_U32_PROC_DOMAIN:
+               mconfig->domain =
+                       tkn_elem->value;
+
+               break;
+
+       case SKL_TKN_U8_IN_PIN_TYPE:
+       case SKL_TKN_U8_OUT_PIN_TYPE:
+       case SKL_TKN_U8_CONN_TYPE:
+               break;
+
+       default:
+               dev_err(dev, "Token %d not handled\n",
+                               tkn_elem->token);
+               return -EINVAL;
+       }
+
+       tkn_count++;
+
+       return tkn_count;
+}
+
+/*
+ * Parse the vendor array for specific tokens to construct
+ * module private data
+ */
+static int skl_tplg_get_tokens(struct device *dev,
+               char *pvt_data, struct skl *skl,
+               struct skl_module_cfg *mconfig, int block_size)
+{
+       struct snd_soc_tplg_vendor_array *array;
+       struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+       int tkn_count = 0, ret;
+       int off = 0, tuple_size = 0;
+
+       if (block_size <= 0)
+               return -EINVAL;
+
+       while (tuple_size < block_size) {
+               array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
+
+               off += array->size;
+
+               switch (array->type) {
+               case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+                       dev_warn(dev, "no string tokens expected for skl tplg");
+                       continue;
+
+               case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+                       ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
+                       if (ret < 0)
+                               return ret;
+
+                       tuple_size += sizeof(*array->uuid);
+
+                       continue;
+
+               default:
+                       tkn_elem = array->value;
+                       tkn_count = 0;
+                       break;
+               }
+
+               while (tkn_count <= (array->num_elems - 1)) {
+                       ret = skl_tplg_get_token(dev, tkn_elem,
+                                       skl, mconfig);
+
+                       if (ret < 0)
+                               return ret;
+
+                       tkn_count = tkn_count + ret;
+                       tkn_elem++;
+               }
+
+               tuple_size += tkn_count * sizeof(*tkn_elem);
        }
+
+       return 0;
+}
+
+/*
+ * Every data block is preceded by a descriptor to read the number
+ * of data blocks, they type of the block and it's size
+ */
+static int skl_tplg_get_desc_blocks(struct device *dev,
+               struct snd_soc_tplg_vendor_array *array)
+{
+       struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+
+       tkn_elem = array->value;
+
+       switch (tkn_elem->token) {
+       case SKL_TKN_U8_NUM_BLOCKS:
+       case SKL_TKN_U8_BLOCK_TYPE:
+       case SKL_TKN_U16_BLOCK_SIZE:
+               return tkn_elem->value;
+
+       default:
+               dev_err(dev, "Invalid descriptor token %d", tkn_elem->token);
+               break;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * Parse the private data for the token and corresponding value.
+ * The private data can have multiple data blocks. So, a data block
+ * is preceded by a descriptor for number of blocks and a descriptor
+ * for the type and size of the suceeding data block.
+ */
+static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
+                               struct skl *skl, struct device *dev,
+                               struct skl_module_cfg *mconfig)
+{
+       struct snd_soc_tplg_vendor_array *array;
+       int num_blocks, block_size = 0, block_type, off = 0;
+       char *data;
+       int ret;
+
+       /* Read the NUM_DATA_BLOCKS descriptor */
+       array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
+       ret = skl_tplg_get_desc_blocks(dev, array);
+       if (ret < 0)
+               return ret;
+       num_blocks = ret;
+
+       off += array->size;
+       array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off);
+
+       /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
+       while (num_blocks > 0) {
+               ret = skl_tplg_get_desc_blocks(dev, array);
+
+               if (ret < 0)
+                       return ret;
+               block_type = ret;
+               off += array->size;
+
+               array = (struct snd_soc_tplg_vendor_array *)
+                       (tplg_w->priv.data + off);
+
+               ret = skl_tplg_get_desc_blocks(dev, array);
+
+               if (ret < 0)
+                       return ret;
+               block_size = ret;
+               off += array->size;
+
+               array = (struct snd_soc_tplg_vendor_array *)
+                       (tplg_w->priv.data + off);
+
+               data = (tplg_w->priv.data + off);
+
+               if (block_type == SKL_TYPE_TUPLE) {
+                       ret = skl_tplg_get_tokens(dev, data,
+                                       skl, mconfig, block_size);
+
+                       if (ret < 0)
+                               return ret;
+
+                       --num_blocks;
+               } else {
+                       if (mconfig->formats_config.caps_size > 0)
+                               memcpy(mconfig->formats_config.caps, data,
+                                       mconfig->formats_config.caps_size);
+                       --num_blocks;
+               }
+       }
+
+       return 0;
 }
 
 static void skl_clear_pin_config(struct snd_soc_platform *platform,
@@ -1606,9 +2106,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
        struct skl *skl = ebus_to_skl(ebus);
        struct hdac_bus *bus = ebus_to_hbus(ebus);
        struct skl_module_cfg *mconfig;
-       struct skl_pipe *pipe;
-       struct skl_dfw_module *dfw_config =
-                               (struct skl_dfw_module *)tplg_w->priv.data;
 
        if (!tplg_w->priv.size)
                goto bind_event;
@@ -1619,76 +2116,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
                return -ENOMEM;
 
        w->priv = mconfig;
-       memcpy(&mconfig->guid, &dfw_config->uuid, 16);
 
-       ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config);
+       /*
+        * module binary can be loaded later, so set it to query when
+        * module is load for a use case
+        */
+       mconfig->id.module_id = -1;
+
+       /* Parse private data for tuples */
+       ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
        if (ret < 0)
                return ret;
-
-       mconfig->id.module_id = dfw_config->module_id;
-       mconfig->id.instance_id = dfw_config->instance_id;
-       mconfig->mcps = dfw_config->max_mcps;
-       mconfig->ibs = dfw_config->ibs;
-       mconfig->obs = dfw_config->obs;
-       mconfig->core_id = dfw_config->core_id;
-       mconfig->max_in_queue = dfw_config->max_in_queue;
-       mconfig->max_out_queue = dfw_config->max_out_queue;
-       mconfig->is_loadable = dfw_config->is_loadable;
-       skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
-                                               MODULE_MAX_IN_PINS);
-       skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
-                                               MODULE_MAX_OUT_PINS);
-
-       mconfig->params_fixup = dfw_config->params_fixup;
-       mconfig->converter = dfw_config->converter;
-       mconfig->m_type = dfw_config->module_type;
-       mconfig->vbus_id = dfw_config->vbus_id;
-       mconfig->mem_pages = dfw_config->mem_pages;
-
-       pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
-       if (pipe)
-               mconfig->pipe = pipe;
-
-       mconfig->dev_type = dfw_config->dev_type;
-       mconfig->hw_conn_type = dfw_config->hw_conn_type;
-       mconfig->time_slot = dfw_config->time_slot;
-       mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
-
-       mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
-                                               sizeof(*mconfig->m_in_pin),
-                                               GFP_KERNEL);
-       if (!mconfig->m_in_pin)
-               return -ENOMEM;
-
-       mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
-                                               sizeof(*mconfig->m_out_pin),
-                                               GFP_KERNEL);
-       if (!mconfig->m_out_pin)
-               return -ENOMEM;
-
-       skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
-                                               dfw_config->is_dynamic_in_pin,
-                                               mconfig->max_in_queue);
-
-       skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
-                                                dfw_config->is_dynamic_out_pin,
-                                                       mconfig->max_out_queue);
-
-
-       if (mconfig->formats_config.caps_size == 0)
-               goto bind_event;
-
-       mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
-                       mconfig->formats_config.caps_size, GFP_KERNEL);
-
-       if (mconfig->formats_config.caps == NULL)
-               return -ENOMEM;
-
-       memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
-                                                dfw_config->caps.caps_size);
-       mconfig->formats_config.param_id = dfw_config->caps.param_id;
-       mconfig->formats_config.set_params = dfw_config->caps.set_params;
-
 bind_event:
        if (tplg_w->event_type == 0) {
                dev_dbg(bus->dev, "ASoC: No event handler required\n");
@@ -1767,11 +2205,229 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
        return 0;
 }
 
+static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
+               struct snd_soc_tplg_vendor_string_elem *str_elem,
+               struct skl_dfw_manifest *minfo)
+{
+       int tkn_count = 0;
+       static int ref_count;
+
+       switch (str_elem->token) {
+       case SKL_TKN_STR_LIB_NAME:
+               if (ref_count > minfo->lib_count - 1) {
+                       ref_count = 0;
+                       return -EINVAL;
+               }
+
+               strncpy(minfo->lib[ref_count].name, str_elem->string,
+                               ARRAY_SIZE(minfo->lib[ref_count].name));
+               ref_count++;
+               tkn_count++;
+               break;
+
+       default:
+               dev_err(dev, "Not a string token %d", str_elem->token);
+               break;
+       }
+
+       return tkn_count;
+}
+
+static int skl_tplg_get_str_tkn(struct device *dev,
+               struct snd_soc_tplg_vendor_array *array,
+               struct skl_dfw_manifest *minfo)
+{
+       int tkn_count = 0, ret;
+       struct snd_soc_tplg_vendor_string_elem *str_elem;
+
+       str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
+       while (tkn_count < array->num_elems) {
+               ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo);
+               str_elem++;
+
+               if (ret < 0)
+                       return ret;
+
+               tkn_count = tkn_count + ret;
+       }
+
+       return tkn_count;
+}
+
+static int skl_tplg_get_int_tkn(struct device *dev,
+               struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+               struct skl_dfw_manifest *minfo)
+{
+       int tkn_count = 0;
+
+       switch (tkn_elem->token) {
+       case SKL_TKN_U32_LIB_COUNT:
+               minfo->lib_count = tkn_elem->value;
+               tkn_count++;
+               break;
+
+       default:
+               dev_err(dev, "Not a manifest token %d", tkn_elem->token);
+               return -EINVAL;
+       }
+
+       return tkn_count;
+}
+
+/*
+ * Fill the manifest structure by parsing the tokens based on the
+ * type.
+ */
+static int skl_tplg_get_manifest_tkn(struct device *dev,
+               char *pvt_data, struct skl_dfw_manifest *minfo,
+               int block_size)
+{
+       int tkn_count = 0, ret;
+       int off = 0, tuple_size = 0;
+       struct snd_soc_tplg_vendor_array *array;
+       struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+
+       if (block_size <= 0)
+               return -EINVAL;
+
+       while (tuple_size < block_size) {
+               array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
+               off += array->size;
+               switch (array->type) {
+               case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+                       ret = skl_tplg_get_str_tkn(dev, array, minfo);
+
+                       if (ret < 0)
+                               return ret;
+                       tkn_count += ret;
+
+                       tuple_size += tkn_count *
+                               sizeof(struct snd_soc_tplg_vendor_string_elem);
+                       continue;
+
+               case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+                       dev_warn(dev, "no uuid tokens for skl tplf manifest");
+                       continue;
+
+               default:
+                       tkn_elem = array->value;
+                       tkn_count = 0;
+                       break;
+               }
+
+               while (tkn_count <= array->num_elems - 1) {
+                       ret = skl_tplg_get_int_tkn(dev,
+                                       tkn_elem, minfo);
+                       if (ret < 0)
+                               return ret;
+
+                       tkn_count = tkn_count + ret;
+                       tkn_elem++;
+                       tuple_size += tkn_count *
+                               sizeof(struct snd_soc_tplg_vendor_value_elem);
+                       break;
+               }
+               tkn_count = 0;
+       }
+
+       return 0;
+}
+
+/*
+ * Parse manifest private data for tokens. The private data block is
+ * preceded by descriptors for type and size of data block.
+ */
+static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
+                       struct device *dev, struct skl_dfw_manifest *minfo)
+{
+       struct snd_soc_tplg_vendor_array *array;
+       int num_blocks, block_size = 0, block_type, off = 0;
+       char *data;
+       int ret;
+
+       /* Read the NUM_DATA_BLOCKS descriptor */
+       array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
+       ret = skl_tplg_get_desc_blocks(dev, array);
+       if (ret < 0)
+               return ret;
+       num_blocks = ret;
+
+       off += array->size;
+       array = (struct snd_soc_tplg_vendor_array *)
+                       (manifest->priv.data + off);
+
+       /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
+       while (num_blocks > 0) {
+               ret = skl_tplg_get_desc_blocks(dev, array);
+
+               if (ret < 0)
+                       return ret;
+               block_type = ret;
+               off += array->size;
+
+               array = (struct snd_soc_tplg_vendor_array *)
+                       (manifest->priv.data + off);
+
+               ret = skl_tplg_get_desc_blocks(dev, array);
+
+               if (ret < 0)
+                       return ret;
+               block_size = ret;
+               off += array->size;
+
+               array = (struct snd_soc_tplg_vendor_array *)
+                       (manifest->priv.data + off);
+
+               data = (manifest->priv.data + off);
+
+               if (block_type == SKL_TYPE_TUPLE) {
+                       ret = skl_tplg_get_manifest_tkn(dev, data, minfo,
+                                       block_size);
+
+                       if (ret < 0)
+                               return ret;
+
+                       --num_blocks;
+               } else {
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int skl_manifest_load(struct snd_soc_component *cmpnt,
+                               struct snd_soc_tplg_manifest *manifest)
+{
+       struct skl_dfw_manifest *minfo;
+       struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
+       struct hdac_bus *bus = ebus_to_hbus(ebus);
+       struct skl *skl = ebus_to_skl(ebus);
+       int ret = 0;
+
+       /* proceed only if we have private data defined */
+       if (manifest->priv.size == 0)
+               return 0;
+
+       minfo = &skl->skl_sst->manifest;
+
+       skl_tplg_get_manifest_data(manifest, bus->dev, minfo);
+
+       if (minfo->lib_count > HDA_MAX_LIB) {
+               dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
+                                       minfo->lib_count);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
 static struct snd_soc_tplg_ops skl_tplg_ops  = {
        .widget_load = skl_tplg_widget_load,
        .control_load = skl_tplg_control_load,
        .bytes_ext_ops = skl_tlv_ops,
        .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
+       .manifest = skl_manifest_load,
 };
 
 /*
index 22d3ef83817dfdfa762c65d08bba11b4628dc74f..37f45cc32a44a273e2e3610c3012a33f1a8275a7 100644 (file)
@@ -133,7 +133,7 @@ struct skl_i2s_config_blob {
 struct skl_dma_control {
        u32 node_id;
        u32 config_length;
-       u32 config_data[1];
+       u32 config_data[0];
 } __packed;
 
 struct skl_cpr_cfg {
@@ -216,7 +216,7 @@ struct skl_module_fmt {
 struct skl_module_cfg;
 
 struct skl_module_inst_id {
-       u32 module_id;
+       int module_id;
        u32 instance_id;
 };
 
index a32e5e9cc5302f33e9d2bf1b7d60918fa383f4c1..e208724f9db3ed2f8e2c4f5957be018d942b07a0 100644 (file)
@@ -148,84 +148,34 @@ enum skl_module_param_type {
        SKL_PARAM_BIND
 };
 
-struct skl_dfw_module_pin {
-       u16 module_id;
-       u16 instance_id;
-} __packed;
-
-struct skl_dfw_module_fmt {
-       u32 channels;
-       u32 freq;
-       u32 bit_depth;
-       u32 valid_bit_depth;
-       u32 ch_cfg;
-       u32 interleaving_style;
-       u32 sample_type;
-       u32 ch_map;
-} __packed;
-
-struct skl_dfw_module_caps {
+struct skl_dfw_algo_data {
        u32 set_params:2;
        u32 rsvd:30;
        u32 param_id;
-       u32 caps_size;
-       u32 caps[HDA_SST_CFG_MAX];
-};
-
-struct skl_dfw_pipe {
-       u8 pipe_id;
-       u8 pipe_priority;
-       u16 conn_type:4;
-       u16 rsvd:4;
-       u16 memory_pages:8;
+       u32 max;
+       char params[0];
 } __packed;
 
-struct skl_dfw_module {
-       u8 uuid[16];
-
-       u16 module_id;
-       u16 instance_id;
-       u32 max_mcps;
-       u32 mem_pages;
-       u32 obs;
-       u32 ibs;
-       u32 vbus_id;
-
-       u32 max_in_queue:8;
-       u32 max_out_queue:8;
-       u32 time_slot:8;
-       u32 core_id:4;
-       u32 rsvd1:4;
-
-       u32 module_type:8;
-       u32 conn_type:4;
-       u32 dev_type:4;
-       u32 hw_conn_type:4;
-       u32 rsvd2:12;
-
-       u32 params_fixup:8;
-       u32 converter:8;
-       u32 input_pin_type:1;
-       u32 output_pin_type:1;
-       u32 is_dynamic_in_pin:1;
-       u32 is_dynamic_out_pin:1;
-       u32 is_loadable:1;
-       u32 rsvd3:11;
-
-       struct skl_dfw_pipe pipe;
-       struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
-       struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
-       struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
-       struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
-       struct skl_dfw_module_caps caps;
+#define LIB_NAME_LENGTH        128
+#define HDA_MAX_LIB    16
+
+struct lib_info {
+       char name[LIB_NAME_LENGTH];
 } __packed;
 
-struct skl_dfw_algo_data {
-       u32 set_params:2;
-       u32 rsvd:30;
-       u32 param_id;
-       u32 max;
-       char params[0];
+struct skl_dfw_manifest {
+       u32 lib_count;
+       struct lib_info lib[HDA_MAX_LIB];
 } __packed;
 
+enum skl_tkn_dir {
+       SKL_DIR_IN,
+       SKL_DIR_OUT
+};
+
+enum skl_tuple_type {
+       SKL_TYPE_TUPLE,
+       SKL_TYPE_DATA
+};
+
 #endif
index 9064e5b0d67689be97299d5f5ae2f9a361a547f6..5d4fbb094c48da9fe238b8c27f09f3c41141d0ed 100644 (file)
@@ -105,6 +105,7 @@ struct skl_dsp_ops {
                        int irq, const char *fw_name,
                        struct skl_dsp_loader_ops loader_ops,
                        struct skl_sst **skl_sst);
+       int (*init_fw)(struct device *dev, struct skl_sst *ctx);
        void (*cleanup)(struct device *dev, struct skl_sst *ctx);
 };
 
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl);
 int skl_suspend_dsp(struct skl *skl);
 int skl_resume_dsp(struct skl *skl);
 void skl_cleanup_resources(struct skl *skl);
+const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
 #endif /* __SOUND_SOC_SKL_H */
index dbfdfe99c69df940259363d7404e0690aa07b92f..dafd22e874e99139ccca45599fd8393c93f75dd2 100644 (file)
@@ -242,7 +242,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
        return count;
 }
 
-static struct snd_pcm_ops kirkwood_dma_ops = {
+static const struct snd_pcm_ops kirkwood_dma_ops = {
        .open =         kirkwood_dma_open,
        .close =        kirkwood_dma_close,
        .ioctl =        snd_pcm_lib_ioctl,
index b788791b0a35b2b80c7fe0d41f79b13bb3120cbd..ac231d33d8fe845b48efc7037f9e1f460526fd7d 100644 (file)
@@ -23,7 +23,8 @@
 
 #define AFE_BASE_END_OFFSET 8
 
-int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
+static int mtk_regmap_update_bits(struct regmap *map, int reg,
+                          unsigned int mask,
                           unsigned int val)
 {
        if (reg < 0)
@@ -31,7 +32,7 @@ int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
        return regmap_update_bits(map, reg, mask, val);
 }
 
-int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
+static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
 {
        if (reg < 0)
                return 0;
index 76ce33199bf9cfcb98ff79c000fde8d17ec851c7..06fec5699cc8bd984e110a6b82b115b019e8f576 100644 (file)
@@ -221,7 +221,8 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
 
        /* Enable TX/RX sync error interrupts by default */
        if (mcbsp->irq)
-               MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN);
+               MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN |
+                           RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN);
 }
 
 /**
index f61b3b58083b9c7cf6d8848de3318b00902ce61b..89fe95e877db0d533163a0ec9f8918d4702c0194 100644 (file)
@@ -305,23 +305,14 @@ static int omap_abe_probe(struct platform_device *pdev)
 
        snd_soc_card_set_drvdata(card, priv);
 
-       ret = snd_soc_register_card(card);
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
        if (ret)
-               dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+               dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n",
                        ret);
 
        return ret;
 }
 
-static int omap_abe_remove(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_card(card);
-
-       return 0;
-}
-
 static const struct of_device_id omap_abe_of_match[] = {
        {.compatible = "ti,abe-twl6040", },
        { },
@@ -335,7 +326,6 @@ static struct platform_driver omap_abe_driver = {
                .of_match_table = omap_abe_of_match,
        },
        .probe = omap_abe_probe,
-       .remove = omap_abe_remove,
 };
 
 static int __init omap_abe_init(void)
index a84f677234f08c5bd1ddaa7cd4a444111d4d8cf5..94e9ff791f3aa5b9d053b1acf4b14b0a0a99203a 100644 (file)
@@ -58,7 +58,7 @@ static void omap_pcm_limit_supported_formats(void)
 {
        int i;
 
-       for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
+       for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
                switch (snd_pcm_format_physical_width(i)) {
                case 8:
                case 16:
index 1289543c8fb2594dfa4a9d6f9be16f70d0e67c5c..07f91e918b2349b75271ac319f85e6416a4199e6 100644 (file)
@@ -85,6 +85,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
                return ERR_PTR(ret);
        }
 
+       /* DAPM routes */
+       if (of_property_read_bool(node, "qcom,audio-routing")) {
+               ret = snd_soc_of_parse_audio_routing(card,
+                                       "qcom,audio-routing");
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+
        /* Populate links */
        num_links = of_get_child_count(node);
 
@@ -147,6 +156,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
        return data;
 }
 
+static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = {
+
+       SND_SOC_DAPM_MIC("Handset Mic", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+       SND_SOC_DAPM_MIC("Secondary Mic", NULL),
+       SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+       SND_SOC_DAPM_MIC("Digital Mic2", NULL),
+};
+
 static int apq8016_sbc_platform_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -159,6 +177,8 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        card->dev = dev;
+       card->dapm_widgets = apq8016_sbc_dapm_widgets;
+       card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets);
        data = apq8016_sbc_parse_of(card);
        if (IS_ERR(data)) {
                dev_err(&pdev->dev, "Error resolving dai links: %ld\n",
index db000c6987a1ced1695d9127398cc8a479853c6f..e2ff538a8aa5b63c4117f35365c39057b1f5360a 100644 (file)
@@ -84,9 +84,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
        struct lpass_data *drvdata =
                snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct lpass_pcm_data *pcm_data = drvdata->private_data;
        struct lpass_variant *v = drvdata->variant;
        snd_pcm_format_t format = params_format(params);
        unsigned int channels = params_channels(params);
@@ -177,9 +177,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
        struct lpass_data *drvdata =
                snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct lpass_pcm_data *pcm_data = drvdata->private_data;
        struct lpass_variant *v = drvdata->variant;
        unsigned int reg;
        int ret;
@@ -201,9 +201,9 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
        struct lpass_data *drvdata =
                snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct lpass_pcm_data *pcm_data = drvdata->private_data;
        struct lpass_variant *v = drvdata->variant;
        int ret, ch, dir = substream->stream;
 
@@ -255,9 +255,9 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
                int cmd)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
        struct lpass_data *drvdata =
                snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct lpass_pcm_data *pcm_data = drvdata->private_data;
        struct lpass_variant *v = drvdata->variant;
        int ret, ch, dir = substream->stream;
 
@@ -331,9 +331,9 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
                struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
        struct lpass_data *drvdata =
                        snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct lpass_pcm_data *pcm_data = drvdata->private_data;
        struct lpass_variant *v = drvdata->variant;
        unsigned int base_addr, curr_addr;
        int ret, ch, dir = substream->stream;
@@ -372,7 +372,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
                        runtime->dma_bytes);
 }
 
-static struct snd_pcm_ops lpass_platform_pcm_ops = {
+static const struct snd_pcm_ops lpass_platform_pcm_ops = {
        .open           = lpass_platform_pcmops_open,
        .ioctl          = snd_pcm_lib_ioctl,
        .hw_params      = lpass_platform_pcmops_hw_params,
@@ -483,7 +483,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
                return -ENOMEM;
 
        data->i2s_port = cpu_dai->driver->id;
-       snd_soc_pcm_set_drvdata(soc_runtime, data);
+       drvdata->private_data = data;
 
        psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
        if (psubstream) {
@@ -570,8 +570,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm)
                substream = pcm->streams[i].substream;
                if (substream) {
                        rt = substream->private_data;
-                       data = snd_soc_pcm_get_drvdata(rt);
                        drvdata = snd_soc_platform_get_drvdata(rt->platform);
+                       data = drvdata->private_data;
 
                        ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                                ? data->rdma_ch
index 30714ad1e138d405a89643351c4ff30e5b5e2c1f..35b3cea8207d8e61773a938d7fead9b3adb8d087 100644 (file)
@@ -58,6 +58,8 @@ struct lpass_data {
        /* 8016 specific */
        struct clk *pcnoc_mport_clk;
        struct clk *pcnoc_sway_clk;
+
+       void *private_data;
 };
 
 /* Vairant data per each SOC */
index f1e0c703e0d2f105226c2becffafc852f1927879..c783f9a22595d657dd7d5697f8a300b52a5d6029 100644 (file)
@@ -41,3 +41,15 @@ config SND_SOC_ROCKCHIP_RT5645
        help
          Say Y or M here if you want to add support for SoC audio on Rockchip
          boards using the RT5645/RT5650 codec, such as Veyron.
+
+config SND_SOC_RK3399_GRU_SOUND
+       tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards"
+       depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI
+       select SND_SOC_ROCKCHIP_I2S
+       select SND_SOC_MAX98357A
+       select SND_SOC_RT5514
+       select SND_SOC_DA7219
+       select SND_SOC_RT5514_SPI
+       help
+         Say Y or M here if you want to add support multiple codecs for SoC
+         audio on Rockchip RK3399 GRU boards.
index c0bf560125f3d8d4fc4131fd65cbb277be8bb8ac..84e5c7c700e780e8b8f241f784132c7a2f788d4b 100644 (file)
@@ -7,6 +7,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
 
 snd-soc-rockchip-max98090-objs := rockchip_max98090.o
 snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
+snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o
+obj-$(CONFIG_SND_SOC_RK3399_GRU_SOUND) += snd-soc-rk3399-gru-sound.o
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
new file mode 100644 (file)
index 0000000..164b6da
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
+ *
+ * Copyright (c) 2016, ROCKCHIP CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include "rockchip_i2s.h"
+#include "../codecs/da7219.h"
+#include "../codecs/da7219-aad.h"
+#include "../codecs/rt5514.h"
+
+#define DRV_NAME "rk3399-gru-sound"
+
+#define SOUND_FS       256
+
+static struct snd_soc_jack rockchip_sound_jack;
+
+static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphones", NULL),
+       SND_SOC_DAPM_SPK("Speakers", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+       SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route rockchip_dapm_routes[] = {
+       /* Input Lines */
+       {"MIC", NULL, "Headset Mic"},
+       {"DMIC1L", NULL, "Int Mic"},
+       {"DMIC1R", NULL, "Int Mic"},
+
+       /* Output Lines */
+       {"Headphones", NULL, "HPL"},
+       {"Headphones", NULL, "HPR"},
+       {"Speakers", NULL, "Speaker"},
+};
+
+static const struct snd_kcontrol_new rockchip_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Headphones"),
+       SOC_DAPM_PIN_SWITCH("Speakers"),
+       SOC_DAPM_PIN_SWITCH("Headset Mic"),
+       SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       unsigned int mclk;
+       int ret;
+
+       /* max98357a supports these sample rates */
+       switch (params_rate(params)) {
+       case 8000:
+       case 16000:
+       case 48000:
+       case 96000:
+               mclk = params_rate(params) * SOUND_FS;
+               break;
+       default:
+               dev_err(rtd->card->dev, "%s() doesn't support this sample rate: %d\n",
+                               __func__, params_rate(params));
+               return -EINVAL;
+       }
+
+       ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0);
+       if (ret) {
+               dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
+                               __func__, mclk, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       unsigned int mclk;
+       int ret;
+
+       mclk = params_rate(params) * SOUND_FS;
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+                                    SND_SOC_CLOCK_OUT);
+       if (ret < 0) {
+               dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
+                                    mclk, SND_SOC_CLOCK_IN);
+       if (ret) {
+               dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
+                               __func__, params_rate(params) * 512, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int mclk, ret;
+
+       /* in bypass mode, the mclk has to be one of the frequencies below */
+       switch (params_rate(params)) {
+       case 8000:
+       case 16000:
+       case 24000:
+       case 32000:
+       case 48000:
+       case 64000:
+       case 96000:
+               mclk = 12288000;
+               break;
+       case 11025:
+       case 22050:
+       case 44100:
+       case 88200:
+               mclk = 11289600;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+                                    SND_SOC_CLOCK_OUT);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_codec *codec = rtd->codec_dais[0]->codec;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int ret;
+
+       /* We need default MCLK and PLL settings for the accessory detection */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
+               return ret;
+       }
+
+       /* Enable Headset and 4 Buttons Jack detection */
+       ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+                                   SND_JACK_HEADSET | SND_JACK_LINEOUT |
+                                   SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                                   SND_JACK_BTN_2 | SND_JACK_BTN_3,
+                                   &rockchip_sound_jack, NULL, 0);
+
+       if (ret) {
+               dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
+               return ret;
+       }
+
+       da7219_aad_jack_det(codec, &rockchip_sound_jack);
+
+       return 0;
+}
+
+static struct snd_soc_ops rockchip_sound_max98357a_ops = {
+       .hw_params = rockchip_sound_max98357a_hw_params,
+};
+
+static struct snd_soc_ops rockchip_sound_rt5514_ops = {
+       .hw_params = rockchip_sound_rt5514_hw_params,
+};
+
+static struct snd_soc_ops rockchip_sound_da7219_ops = {
+       .hw_params = rockchip_sound_da7219_hw_params,
+};
+
+enum {
+       DAILINK_MAX98357A,
+       DAILINK_RT5514,
+       DAILINK_DA7219,
+       DAILINK_RT5514_DSP,
+};
+
+#define DAILINK_ENTITIES       (DAILINK_DA7219 + 1)
+
+static struct snd_soc_dai_link rockchip_dailinks[] = {
+       [DAILINK_MAX98357A] = {
+               .name = "MAX98357A",
+               .stream_name = "MAX98357A PCM",
+               .codec_dai_name = "HiFi",
+               .ops = &rockchip_sound_max98357a_ops,
+               /* set max98357a as slave */
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+       },
+       [DAILINK_RT5514] = {
+               .name = "RT5514",
+               .stream_name = "RT5514 PCM",
+               .codec_dai_name = "rt5514-aif1",
+               .ops = &rockchip_sound_rt5514_ops,
+               /* set rt5514 as slave */
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+       },
+       [DAILINK_DA7219] = {
+               .name = "DA7219",
+               .stream_name = "DA7219 PCM",
+               .codec_dai_name = "da7219-hifi",
+               .init = rockchip_sound_da7219_init,
+               .ops = &rockchip_sound_da7219_ops,
+               /* set da7219 as slave */
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+       },
+       /* RT5514 DSP for voice wakeup via spi bus */
+       [DAILINK_RT5514_DSP] = {
+               .name = "RT5514 DSP",
+               .stream_name = "Wake on Voice",
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+       },
+};
+
+static struct snd_soc_card rockchip_sound_card = {
+       .name = "rk3399-gru-sound",
+       .owner = THIS_MODULE,
+       .dai_link = rockchip_dailinks,
+       .num_links =  ARRAY_SIZE(rockchip_dailinks),
+       .dapm_widgets = rockchip_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
+       .dapm_routes = rockchip_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes),
+       .controls = rockchip_controls,
+       .num_controls = ARRAY_SIZE(rockchip_controls),
+};
+
+static int rockchip_sound_match_stub(struct device *dev, void *data)
+{
+       return 1;
+}
+
+static int rockchip_sound_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &rockchip_sound_card;
+       struct device_node *cpu_node;
+       struct device *dev;
+       struct device_driver *drv;
+       int i, ret;
+
+       cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0);
+       if (!cpu_node) {
+               dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < DAILINK_ENTITIES; i++) {
+               rockchip_dailinks[i].platform_of_node = cpu_node;
+               rockchip_dailinks[i].cpu_of_node = cpu_node;
+
+               rockchip_dailinks[i].codec_of_node =
+                       of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i);
+               if (!rockchip_dailinks[i].codec_of_node) {
+                       dev_err(&pdev->dev,
+                               "Property[%d] 'rockchip,codec' missing or invalid\n", i);
+                       return -EINVAL;
+               }
+       }
+
+       /**
+        * To acquire the spi driver of the rt5514 and set the dai-links names
+        * for soc_bind_dai_link
+        */
+       drv = driver_find("rt5514", &spi_bus_type);
+       if (!drv) {
+               dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n");
+               return -EINVAL;
+       }
+
+       dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub);
+       if (!dev) {
+               dev_err(&pdev->dev, "Can not find the rt5514 device\n");
+               return -ENODEV;
+       }
+
+       rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
+       rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
+       rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
+       if (ret)
+               dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+                       __func__, ret);
+
+       return ret;
+}
+
+static const struct of_device_id rockchip_sound_of_match[] = {
+       { .compatible = "rockchip,rk3399-gru-sound", },
+       {},
+};
+
+static struct platform_driver rockchip_sound_driver = {
+       .probe = rockchip_sound_probe,
+       .driver = {
+               .name = DRV_NAME,
+               .of_match_table = rockchip_sound_of_match,
+#ifdef CONFIG_PM
+               .pm = &snd_soc_pm_ops,
+#endif
+       },
+};
+
+module_platform_driver(rockchip_sound_driver);
+
+MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);
index 652e8c5ea1667185f6bb191a2cc8a3714cd74c1b..974915cb4c4fd8a0c0f44c8d5cd2935411c10646 100644 (file)
@@ -57,6 +57,7 @@ static int i2s_runtime_suspend(struct device *dev)
 {
        struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
 
+       regcache_cache_only(i2s->regmap, true);
        clk_disable_unprepare(i2s->mclk);
 
        return 0;
@@ -73,7 +74,14 @@ static int i2s_runtime_resume(struct device *dev)
                return ret;
        }
 
-       return 0;
+       regcache_cache_only(i2s->regmap, false);
+       regcache_mark_dirty(i2s->regmap);
+
+       ret = regcache_sync(i2s->regmap);
+       if (ret)
+               clk_disable_unprepare(i2s->mclk);
+
+       return ret;
 }
 
 static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
index 4ca265737edaaf3def95014793f6837d9de065b0..fa8101d1e16f276b2e5e7a8e70cbb2ab384ad9be 100644 (file)
@@ -65,6 +65,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev)
 {
        struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
 
+       regcache_cache_only(spdif->regmap, true);
        clk_disable_unprepare(spdif->mclk);
        clk_disable_unprepare(spdif->hclk);
 
@@ -88,7 +89,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
                return ret;
        }
 
-       return 0;
+       regcache_cache_only(spdif->regmap, false);
+       regcache_mark_dirty(spdif->regmap);
+
+       ret = regcache_sync(spdif->regmap);
+       if (ret) {
+               clk_disable_unprepare(spdif->mclk);
+               clk_disable_unprepare(spdif->hclk);
+       }
+
+       return ret;
 }
 
 static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
index 547d3103208897ab1d515621bf9d303e345337ba..5eafb6667a3b001b958746f693befb6cce476a22 100644 (file)
@@ -38,16 +38,16 @@ struct s3c_ac97_info {
 };
 static struct s3c_ac97_info s3c_ac97;
 
-static struct s3c_dma_params s3c_ac97_pcm_out = {
-       .dma_size       = 4,
+static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_out = {
+       .addr_width     = 4,
 };
 
-static struct s3c_dma_params s3c_ac97_pcm_in = {
-       .dma_size       = 4,
+static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_in = {
+       .addr_width     = 4,
 };
 
-static struct s3c_dma_params s3c_ac97_mic_in = {
-       .dma_size       = 4,
+static struct snd_dmaengine_dai_dma_data s3c_ac97_mic_in = {
+       .addr_width     = 4,
 };
 
 static void s3c_ac97_activate(struct snd_ac97 *ac97)
@@ -273,14 +273,14 @@ static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
 
 static int s3c_ac97_dai_probe(struct snd_soc_dai *dai)
 {
-       samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in);
+       snd_soc_dai_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in);
 
        return 0;
 }
 
 static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai)
 {
-       samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in);
+       snd_soc_dai_init_dma_data(dai, NULL, &s3c_ac97_mic_in);
 
        return 0;
 }
@@ -346,12 +346,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
        if (IS_ERR(s3c_ac97.regs))
                return PTR_ERR(s3c_ac97.regs);
 
-       s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
-       s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
-       s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
-       s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
-       s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
-       s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
+       s3c_ac97_pcm_out.filter_data = ac97_pdata->dma_playback;
+       s3c_ac97_pcm_out.addr = mem_res->start + S3C_AC97_PCM_DATA;
+       s3c_ac97_pcm_in.filter_data = ac97_pdata->dma_capture;
+       s3c_ac97_pcm_in.addr = mem_res->start + S3C_AC97_PCM_DATA;
+       s3c_ac97_mic_in.filter_data = ac97_pdata->dma_capture_mic;
+       s3c_ac97_mic_in.addr = mem_res->start + S3C_AC97_MIC_DATA;
 
        init_completion(&s3c_ac97.done);
        mutex_init(&s3c_ac97.lock);
index 3830f297e0b668d1ac8900f6e9ae10ed5a020bf7..7ae580d677c82228edb025b0780e8e2f748d3cf0 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  dma.h --
- *
  *  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
@@ -9,27 +7,15 @@
  *  ALSA PCM interface for the Samsung SoC
  */
 
-#ifndef _S3C_AUDIO_H
-#define _S3C_AUDIO_H
+#ifndef _SAMSUNG_DMA_H
+#define _SAMSUNG_DMA_H
 
 #include <sound/dmaengine_pcm.h>
-#include <linux/dmaengine.h>
-
-struct s3c_dma_params {
-       void *slave;                            /* Channel ID */
-       dma_addr_t dma_addr;
-       int dma_size;                   /* Size of the DMA transfer */
-       char *ch_name;
-       struct snd_dmaengine_dai_dma_data dma_data;
-};
 
-void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
-                               struct s3c_dma_params *playback,
-                               struct s3c_dma_params *capture);
 /*
  * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx",
  * otherwise actual DMA channel names must be passed to this function.
  */
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
                                       const char *tx, const char *rx);
-#endif
+#endif /* _SAMSUNG_DMA_H */
index 2c87f380bfc434b12591412a149e3f43e12c993d..9104c98deeb75ab8ac3113e5be85ff4958fa2bdf 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/amba/pl08x.h>
-#include <linux/platform_data/dma-s3c24xx.h>
-
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/soc.h>
-#include <sound/soc-dai.h>
 
 #include "dma.h"
 
-void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
-                               struct s3c_dma_params *playback,
-                               struct s3c_dma_params *capture)
-{
-       struct snd_dmaengine_dai_dma_data *playback_data = NULL;
-       struct snd_dmaengine_dai_dma_data *capture_data = NULL;
-
-       if (playback) {
-               playback_data = &playback->dma_data;
-               playback_data->filter_data = playback->slave;
-               playback_data->chan_name = playback->ch_name;
-               playback_data->addr = playback->dma_addr;
-               playback_data->addr_width = playback->dma_size;
-       }
-       if (capture) {
-               capture_data = &capture->dma_data;
-               capture_data->filter_data = capture->slave;
-               capture_data->chan_name = capture->ch_name;
-               capture_data->addr = capture->dma_addr;
-               capture_data->addr_width = capture->dma_size;
-       }
-
-       snd_soc_dai_init_dma_data(dai, playback_data, capture_data);
-}
-EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
-
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
                                       const char *tx, const char *rx)
 {
        unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
-
        struct snd_dmaengine_pcm_config *pcm_conf;
 
        pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL);
index 50635ee8ff20cb74478d6726bdd083c6557418fc..7e32cf4581f8a853a2e53bf49cbb84e1bd11f0b8 100644 (file)
@@ -87,9 +87,9 @@ struct i2s_dai {
        /* Driver for this DAI */
        struct snd_soc_dai_driver i2s_dai_drv;
        /* DMA parameters */
-       struct s3c_dma_params dma_playback;
-       struct s3c_dma_params dma_capture;
-       struct s3c_dma_params idma_playback;
+       struct snd_dmaengine_dai_dma_data dma_playback;
+       struct snd_dmaengine_dai_dma_data dma_capture;
+       struct snd_dmaengine_dai_dma_data idma_playback;
        dma_filter_fn filter;
        u32     quirks;
        u32     suspend_i2smod;
@@ -692,15 +692,15 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
                break;
        case 2:
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       i2s->dma_playback.dma_size = 4;
+                       i2s->dma_playback.addr_width = 4;
                else
-                       i2s->dma_capture.dma_size = 4;
+                       i2s->dma_capture.addr_width = 4;
                break;
        case 1:
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       i2s->dma_playback.dma_size = 2;
+                       i2s->dma_playback.addr_width = 2;
                else
-                       i2s->dma_capture.dma_size = 2;
+                       i2s->dma_capture.addr_width = 2;
 
                break;
        default:
@@ -754,7 +754,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
        writel(mod, i2s->addr + I2SMOD);
        spin_unlock_irqrestore(i2s->lock, flags);
 
-       samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
+       snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
 
        i2s->frmclk = params_rate(params);
 
@@ -991,10 +991,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
        unsigned long flags;
 
        if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */
-               samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback,
+               snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback,
                                           NULL);
        } else {
-               samsung_asoc_init_dma_data(dai, &i2s->dma_playback,
+               snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
                                           &i2s->dma_capture);
 
                if (i2s->quirks & QUIRK_NEED_RSTCLR)
@@ -1002,7 +1002,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 
                if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
                        idma_reg_addr_init(i2s->addr,
-                                       i2s->sec_dai->idma_playback.dma_addr);
+                                       i2s->sec_dai->idma_playback.addr);
        }
 
        /* Reset any constraint on RFS and BFS */
@@ -1262,8 +1262,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                        return -EINVAL;
                }
 
-               pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
-               pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
+               pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback;
+               pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
                pri_dai->filter = i2s_pdata->dma_filter;
 
                if (&i2s_pdata->type)
@@ -1302,12 +1302,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
                return ret;
        }
-       pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
-       pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
-       pri_dai->dma_playback.ch_name = "tx";
-       pri_dai->dma_capture.ch_name = "rx";
-       pri_dai->dma_playback.dma_size = 4;
-       pri_dai->dma_capture.dma_size = 4;
+       pri_dai->dma_playback.addr = regs_base + I2STXD;
+       pri_dai->dma_capture.addr = regs_base + I2SRXD;
+       pri_dai->dma_playback.chan_name = "tx";
+       pri_dai->dma_capture.chan_name = "rx";
+       pri_dai->dma_playback.addr_width = 4;
+       pri_dai->dma_capture.addr_width = 4;
        pri_dai->quirks = quirks;
        pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
 
@@ -1318,31 +1318,33 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                sec_dai = i2s_alloc_dai(pdev, true);
                if (!sec_dai) {
                        dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_disable_clk;
                }
 
                sec_dai->lock = &pri_dai->spinlock;
                sec_dai->variant_regs = pri_dai->variant_regs;
-               sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
-               sec_dai->dma_playback.ch_name = "tx-sec";
+               sec_dai->dma_playback.addr = regs_base + I2STXDS;
+               sec_dai->dma_playback.chan_name = "tx-sec";
 
                if (!np) {
-                       sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
+                       sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
                        sec_dai->filter = i2s_pdata->dma_filter;
                }
 
-               sec_dai->dma_playback.dma_size = 4;
+               sec_dai->dma_playback.addr_width = 4;
                sec_dai->addr = pri_dai->addr;
                sec_dai->clk = pri_dai->clk;
                sec_dai->quirks = quirks;
-               sec_dai->idma_playback.dma_addr = idma_addr;
+               sec_dai->idma_playback.addr = idma_addr;
                sec_dai->pri_dai = pri_dai;
                pri_dai->sec_dai = sec_dai;
        }
 
        if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
                dev_err(&pdev->dev, "Unable to configure gpio\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_disable_clk;
        }
 
        ret = devm_snd_soc_register_component(&pri_dai->pdev->dev,
@@ -1366,6 +1368,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 err_free_dai:
        if (sec_dai)
                i2s_free_sec_dai(sec_dai);
+err_disable_clk:
+       clk_disable_unprepare(pri_dai->clk);
        return ret;
 }
 
index 4ed29ffc1c54e5f0bdff27eafb5cb35c80b15afe..3e408158625dbb3d1c22d20d54b6b735f36524df 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "i2s.h"
 #include "idma.h"
-#include "dma.h"
 #include "i2s-regs.h"
 
 #define ST_RUNNING             (1<<0)
index 490c1a87fd66232c798741ed13452802cfcf7223..43e367a9acc368d148c0a5afbe777c2874f2ea30 100644 (file)
@@ -127,25 +127,25 @@ struct s3c_pcm_info {
        struct clk      *pclk;
        struct clk      *cclk;
 
-       struct s3c_dma_params   *dma_playback;
-       struct s3c_dma_params   *dma_capture;
+       struct snd_dmaengine_dai_dma_data *dma_playback;
+       struct snd_dmaengine_dai_dma_data *dma_capture;
 };
 
-static struct s3c_dma_params s3c_pcm_stereo_out[] = {
+static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_out[] = {
        [0] = {
-               .dma_size       = 4,
+               .addr_width     = 4,
        },
        [1] = {
-               .dma_size       = 4,
+               .addr_width     = 4,
        },
 };
 
-static struct s3c_dma_params s3c_pcm_stereo_in[] = {
+static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_in[] = {
        [0] = {
-               .dma_size       = 4,
+               .addr_width     = 4,
        },
        [1] = {
-               .dma_size       = 4,
+               .addr_width     = 4,
        },
 };
 
@@ -552,15 +552,13 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
        }
        clk_prepare_enable(pcm->pclk);
 
-       s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
-                                                       + S3C_PCM_RXFIFO;
-       s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
-                                                       + S3C_PCM_TXFIFO;
+       s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO;
+       s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO;
 
        filter = NULL;
        if (pcm_pdata) {
-               s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
-               s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
+               s3c_pcm_stereo_in[pdev->id].filter_data = pcm_pdata->dma_capture;
+               s3c_pcm_stereo_out[pdev->id].filter_data = pcm_pdata->dma_playback;
                filter = pcm_pdata->dma_filter;
        }
 
index bf8ae79b0fd2fcf9c9856de51e89a8183b9f847d..644f186fd35c4b62a5fa016407385352ae10d066 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "regs-i2s-v2.h"
 #include "s3c-i2s-v2.h"
-#include "dma.h"
 
 #undef S3C_IIS_V2_SUPPORTED
 
@@ -302,7 +301,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
        struct s3c_i2sv2_info *i2s = to_info(dai);
-       struct s3c_dma_params *dma_data;
+       struct snd_dmaengine_dai_dma_data *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
index d0684145ed1fd50967c1ce27075af3636aec15aa..182d80564e374b81fd2bbd86a159ebe1bfd137e1 100644 (file)
@@ -60,8 +60,8 @@ struct s3c_i2sv2_info {
 
        unsigned char    master;
 
-       struct s3c_dma_params   *dma_playback;
-       struct s3c_dma_params   *dma_capture;
+       struct snd_dmaengine_dai_dma_data *dma_playback;
+       struct snd_dmaengine_dai_dma_data *dma_capture;
 
        u32              suspend_iismod;
        u32              suspend_iiscon;
index d45dffb297d8f90d92113e84b2b45b08547f47d4..3e89fbc0c51d046049f6b6413d554c7e62186055 100644 (file)
 
 #include <linux/platform_data/asoc-s3c.h>
 
-static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
-       .ch_name        = "tx",
-       .dma_size       = 4,
+static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = {
+       .chan_name      = "tx",
+       .addr_width     = 4,
 };
 
-static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
-       .ch_name        = "rx",
-       .dma_size       = 4,
+static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = {
+       .chan_name      = "rx",
+       .addr_width     = 4,
 };
 
 static struct s3c_i2sv2_info s3c2412_i2s;
@@ -52,8 +52,8 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
 
        pr_debug("Entered %s\n", __func__);
 
-       samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
-               &s3c2412_i2s_pcm_stereo_in);
+       snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
+                                       &s3c2412_i2s_pcm_stereo_in);
 
        ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
        if (ret)
@@ -163,10 +163,10 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
        if (IS_ERR(s3c2412_i2s.regs))
                return PTR_ERR(s3c2412_i2s.regs);
 
-       s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
-       s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback;
-       s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
-       s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture;
+       s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD;
+       s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
+       s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
+       s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
 
        ret = s3c_i2sv2_register_component(&pdev->dev, -1,
                                           &s3c2412_i2s_component,
index 3e76f2a75a24d53477a8d4d7844c9b052a1fbd94..c78a936a30995639fdb6cf6c97008d7504b1ea5e 100644 (file)
 
 #include <linux/platform_data/asoc-s3c.h>
 
-static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
-       .ch_name        = "tx",
-       .dma_size       = 2,
+static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = {
+       .chan_name      = "tx",
+       .addr_width     = 2,
 };
 
-static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
-       .ch_name        = "rx",
-       .dma_size       = 2,
+static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = {
+       .chan_name      = "rx",
+       .addr_width     = 2,
 };
 
 struct s3c24xx_i2s_info {
@@ -360,8 +360,8 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
 {
        pr_debug("Entered %s\n", __func__);
 
-       samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
-               &s3c24xx_i2s_pcm_stereo_in);
+       snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
+                                       &s3c24xx_i2s_pcm_stereo_in);
 
        s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
        if (IS_ERR(s3c24xx_i2s.iis_clk)) {
@@ -469,10 +469,10 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
        if (IS_ERR(s3c24xx_i2s.regs))
                return PTR_ERR(s3c24xx_i2s.regs);
 
-       s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
-       s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback;
-       s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
-       s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture;
+       s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO;
+       s3c24xx_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
+       s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
+       s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
 
        ret = devm_snd_soc_register_component(&pdev->dev,
                        &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
index 92e88bca386e8199d4316898d27195e64251a626..7853fbe6ccc92b6785bef74a913add08655b22ec 100644 (file)
@@ -54,8 +54,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 };
 #endif
 
-static struct platform_device *s3c24xx_uda134x_snd_device;
-
 static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -66,17 +64,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
        int ret = 0;
 
        mutex_lock(&clk_lock);
-       pr_debug("%s %d\n", __func__, clk_users);
+
        if (clk_users == 0) {
-               xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
+               xtal = clk_get(rtd->dev, "xtal");
                if (IS_ERR(xtal)) {
-                       printk(KERN_ERR "%s cannot get xtal\n", __func__);
+                       dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
                        ret = PTR_ERR(xtal);
                } else {
                        pclk = clk_get(cpu_dai->dev, "iis");
                        if (IS_ERR(pclk)) {
-                               printk(KERN_ERR "%s cannot get pclk\n",
-                                      __func__);
+                               dev_err(rtd->dev, "%s cannot get pclk\n",
+                                       __func__);
                                clk_put(xtal);
                                ret = PTR_ERR(pclk);
                        }
@@ -102,8 +100,8 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
                                                 SNDRV_PCM_HW_PARAM_RATE,
                                                 &hw_constraints_rates);
                if (ret < 0)
-                       printk(KERN_ERR "%s cannot set constraints\n",
-                              __func__);
+                       dev_err(rtd->dev, "%s cannot set constraints\n",
+                               __func__);
 #endif
        }
        return ret;
@@ -112,7 +110,6 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
 static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
 {
        mutex_lock(&clk_lock);
-       pr_debug("%s %d\n", __func__, clk_users);
        clk_users -= 1;
        if (clk_users == 0) {
                clk_put(xtal);
@@ -159,18 +156,19 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
                clk_source = S3C24XX_CLKSRC_PCLK;
                div = bi % 33;
        }
-       pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
+
+       dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi);
 
        clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
-       pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
-                fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
-                clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
-                div, clk, err);
+
+       dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__,
+               fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
+               clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
+               div, clk, err);
 
        if ((err * 100 / rate) > 5) {
-               printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
-                      "too different from desired (%ld%%)\n",
-                      err * 100 / rate);
+               dev_err(rtd->dev, "effective frequency too different "
+                                 "from desired (%ld%%)\n", err * 100 / rate);
                return -EINVAL;
        }
 
@@ -227,115 +225,27 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
        .num_links = 1,
 };
 
-static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
-
-static void setdat(int v)
-{
-       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
-}
-
-static void setclk(int v)
-{
-       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
-}
-
-static void setmode(int v)
-{
-       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
-}
-
-/* FIXME - This must be codec platform data but in which board file ?? */
-static struct uda134x_platform_data s3c24xx_uda134x = {
-       .l3 = {
-               .setdat = setdat,
-               .setclk = setclk,
-               .setmode = setmode,
-               .data_hold = 1,
-               .data_setup = 1,
-               .clock_high = 1,
-               .mode_hold = 1,
-               .mode = 1,
-               .mode_setup = 1,
-       },
-};
-
-static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
-{
-       if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
-               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
-                      "l3 %s pin already in use", fun);
-               return -EBUSY;
-       }
-       gpio_direction_output(pin, 0);
-       return 0;
-}
-
 static int s3c24xx_uda134x_probe(struct platform_device *pdev)
 {
+       struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
        int ret;
 
-       printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
+       platform_set_drvdata(pdev, card);
+       card->dev = &pdev->dev;
 
-       s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
-       if (s3c24xx_uda134x_l3_pins == NULL) {
-               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
-                      "unable to find platform data\n");
-               return -ENODEV;
-       }
-       s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
-       s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
-
-       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
-                                     "data") < 0)
-               return -EBUSY;
-       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
-                                     "clk") < 0) {
-               gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
-               return -EBUSY;
-       }
-       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
-                                     "mode") < 0) {
-               gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
-               gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
-               return -EBUSY;
-       }
-
-       s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!s3c24xx_uda134x_snd_device) {
-               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
-                      "Unable to register\n");
-               return -ENOMEM;
-       }
-
-       platform_set_drvdata(s3c24xx_uda134x_snd_device,
-                            &snd_soc_s3c24xx_uda134x);
-       platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));
-       ret = platform_device_add(s3c24xx_uda134x_snd_device);
-       if (ret) {
-               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
-               platform_device_put(s3c24xx_uda134x_snd_device);
-       }
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
+       if (ret)
+               dev_err(&pdev->dev, "failed to register card: %d\n", ret);
 
        return ret;
 }
 
-static int s3c24xx_uda134x_remove(struct platform_device *pdev)
-{
-       platform_device_unregister(s3c24xx_uda134x_snd_device);
-       gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
-       gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
-       gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
-       return 0;
-}
-
 static struct platform_driver s3c24xx_uda134x_driver = {
        .probe  = s3c24xx_uda134x_probe,
-       .remove = s3c24xx_uda134x_remove,
        .driver = {
                .name = "s3c24xx_uda134x",
        },
 };
-
 module_platform_driver(s3c24xx_uda134x_driver);
 
 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
index 6deec5234c92960410a222c718e270c5dd2fe072..a6d223310c677bc0071e132b97282ca27c1dbda0 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/mach-types.h>
 
 #include "../codecs/wm8580.h"
-#include "dma.h"
 #include "pcm.h"
 
 /*
index b1c89ec2d999ce3f410282dfdf1ecfb30b7cfe4e..2e621496be8bb12e9a27feec36cf1009fe3840cf 100644 (file)
@@ -15,7 +15,6 @@
 #include <sound/pcm_params.h>
 
 #include "../codecs/wm8994.h"
-#include "dma.h"
 #include "pcm.h"
 
 /*
index 0cb9c8567546fe2e9aad562d0a997f1a290346e3..26c1fbed4d3543da990ea3277a24f8fb87887818 100644 (file)
@@ -90,10 +90,10 @@ struct samsung_spdif_info {
        u32             saved_clkcon;
        u32             saved_con;
        u32             saved_cstas;
-       struct s3c_dma_params   *dma_playback;
+       struct snd_dmaengine_dai_dma_data *dma_playback;
 };
 
-static struct s3c_dma_params spdif_stereo_out;
+static struct snd_dmaengine_dai_dma_data spdif_stereo_out;
 static struct samsung_spdif_info spdif_info;
 
 static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai)
@@ -179,7 +179,7 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
        void __iomem *regs = spdif->regs;
-       struct s3c_dma_params *dma_data;
+       struct snd_dmaengine_dai_dma_data *dma_data;
        u32 con, clkcon, cstas;
        unsigned long flags;
        int i, ratio;
@@ -425,11 +425,11 @@ static int spdif_probe(struct platform_device *pdev)
                goto err4;
        }
 
-       spdif_stereo_out.dma_size = 2;
-       spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
+       spdif_stereo_out.addr_width = 2;
+       spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF;
        filter = NULL;
        if (spdif_pdata) {
-               spdif_stereo_out.slave = spdif_pdata->dma_playback;
+               spdif_stereo_out.filter_data = spdif_pdata->dma_playback;
                filter = spdif_pdata->dma_filter;
        }
 
index 9311f119feb5da5b8889427d603a642e3b124cd3..6db6405d952f87c9b742ae833ea2735f9925e9db 100644 (file)
@@ -42,12 +42,6 @@ config SND_SOC_RCAR
        help
          This option enables R-Car SRU/SCU/SSIU/SSI sound support
 
-config SND_SOC_RSRC_CARD
-       tristate "Renesas Sampling Rate Convert Sound Card"
-       select SND_SIMPLE_CARD_UTILS
-       help
-         This option enables simple sound if you need sampling rate convert
-
 ##
 ## Boards
 ##
index a89ddf75869531f17acfddafcf3fa895613c06aa..9c3d5aed99d1441322fc80ec23a6ac165f65ba7e 100644 (file)
@@ -1,5 +1,2 @@
 snd-soc-rcar-objs      := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
 obj-$(CONFIG_SND_SOC_RCAR)     += snd-soc-rcar.o
-
-snd-soc-rsrc-card-objs := rsrc-card.o
-obj-$(CONFIG_SND_SOC_RSRC_CARD)        += snd-soc-rsrc-card.o
index 3351a701c60ee3525b1b441908d7f8bcb628e8f0..f718a200f77d0b06ffc2dbfb064f2bb62b4bd645 100644 (file)
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
 /*
  *     rsnd_mod functions
  */
+#ifdef DEBUG
 void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
 {
        if (mod->type != type) {
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
                         rsnd_mod_name(mod), rsnd_mod_id(mod));
        }
 }
+#endif
 
 char *rsnd_mod_name(struct rsnd_mod *mod)
 {
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
deleted file mode 100644 (file)
index fa37f84..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Renesas Sampling Rate Convert Sound Card for DPCM
- *
- * Copyright (C) 2015 Renesas Solutions Corp.
- * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * based on ${LINUX}/sound/soc/generic/simple-card.c
- *
- * 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/clk.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/string.h>
-#include <sound/jack.h>
-#include <sound/soc.h>
-#include <sound/soc-dai.h>
-#include <sound/simple_card_utils.h>
-
-struct rsrc_card_of_data {
-       const char *prefix;
-       const struct snd_soc_dapm_route *routes;
-       int num_routes;
-};
-
-static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = {
-       {"ak4642 Playback", NULL, "DAI0 Playback"},
-       {"DAI0 Capture", NULL, "ak4642 Capture"},
-};
-
-static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
-       .prefix         = "ak4642",
-       .routes         = routes_ssi0_ak4642,
-       .num_routes     = ARRAY_SIZE(routes_ssi0_ak4642),
-};
-
-static const struct of_device_id rsrc_card_of_match[] = {
-       { .compatible = "renesas,rsrc-card,lager",      .data = &routes_of_ssi0_ak4642 },
-       { .compatible = "renesas,rsrc-card,koelsch",    .data = &routes_of_ssi0_ak4642 },
-       { .compatible = "renesas,rsrc-card", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
-
-#define IDX_CPU                0
-#define IDX_CODEC      1
-struct rsrc_card_priv {
-       struct snd_soc_card snd_card;
-       struct snd_soc_codec_conf codec_conf;
-       struct asoc_simple_dai *dai_props;
-       struct snd_soc_dai_link *dai_link;
-       u32 convert_rate;
-       u32 convert_channels;
-};
-
-#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
-#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
-#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i))
-
-static int rsrc_card_startup(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct rsrc_card_priv *priv =   snd_soc_card_get_drvdata(rtd->card);
-       struct asoc_simple_dai *dai_props =
-               rsrc_priv_to_props(priv, rtd->num);
-
-       return clk_prepare_enable(dai_props->clk);
-}
-
-static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct rsrc_card_priv *priv =   snd_soc_card_get_drvdata(rtd->card);
-       struct asoc_simple_dai *dai_props =
-               rsrc_priv_to_props(priv, rtd->num);
-
-       clk_disable_unprepare(dai_props->clk);
-}
-
-static struct snd_soc_ops rsrc_card_ops = {
-       .startup = rsrc_card_startup,
-       .shutdown = rsrc_card_shutdown,
-};
-
-static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_dai *dai;
-       struct snd_soc_dai_link *dai_link;
-       struct asoc_simple_dai *dai_props;
-       int num = rtd->num;
-       int ret;
-
-       dai_link        = rsrc_priv_to_link(priv, num);
-       dai_props       = rsrc_priv_to_props(priv, num);
-       dai             = dai_link->dynamic ?
-                               rtd->cpu_dai :
-                               rtd->codec_dai;
-
-       if (dai_props->sysclk) {
-               ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0);
-               if (ret && ret != -ENOTSUPP) {
-                       dev_err(dai->dev, "set_sysclk error\n");
-                       goto err;
-               }
-       }
-
-       if (dai_props->slots) {
-               ret = snd_soc_dai_set_tdm_slot(dai,
-                                              dai_props->tx_slot_mask,
-                                              dai_props->rx_slot_mask,
-                                              dai_props->slots,
-                                              dai_props->slot_width);
-               if (ret && ret != -ENOTSUPP) {
-                       dev_err(dai->dev, "set_tdm_slot error\n");
-                       goto err;
-               }
-       }
-
-       ret = 0;
-
-err:
-       return ret;
-}
-
-static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
-                                       struct snd_pcm_hw_params *params)
-{
-       struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_interval *rate = hw_param_interval(params,
-                                                     SNDRV_PCM_HW_PARAM_RATE);
-       struct snd_interval *channels = hw_param_interval(params,
-                                               SNDRV_PCM_HW_PARAM_CHANNELS);
-
-       if (priv->convert_rate)
-               rate->min =
-               rate->max = priv->convert_rate;
-
-       if (priv->convert_channels)
-               channels->min =
-               channels->max = priv->convert_channels;
-
-       return 0;
-}
-
-static int rsrc_card_parse_links(struct device_node *np,
-                                struct rsrc_card_priv *priv,
-                                int idx, bool is_fe)
-{
-       struct device *dev = rsrc_priv_to_dev(priv);
-       struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
-       struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
-       struct of_phandle_args args;
-       int ret;
-
-       /*
-        * Get node via "sound-dai = <&phandle port>"
-        * it will be used as xxx_of_node on soc_bind_dai_link()
-        */
-       ret = of_parse_phandle_with_args(np, "sound-dai",
-                                        "#sound-dai-cells", 0, &args);
-       if (ret)
-               return ret;
-
-       /* Parse TDM slot */
-       ret = snd_soc_of_parse_tdm_slot(np,
-                                       &dai_props->tx_slot_mask,
-                                       &dai_props->rx_slot_mask,
-                                       &dai_props->slots,
-                                       &dai_props->slot_width);
-       if (ret)
-               return ret;
-
-       if (is_fe) {
-               /* BE is dummy */
-               dai_link->codec_of_node         = NULL;
-               dai_link->codec_dai_name        = "snd-soc-dummy-dai";
-               dai_link->codec_name            = "snd-soc-dummy";
-
-               /* FE settings */
-               dai_link->dynamic               = 1;
-               dai_link->dpcm_merged_format    = 1;
-               dai_link->cpu_of_node           = args.np;
-               ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name);
-               if (ret < 0)
-                       return ret;
-
-               ret = asoc_simple_card_set_dailink_name(dev, dai_link,
-                                                       "fe.%s",
-                                                       dai_link->cpu_dai_name);
-               if (ret < 0)
-                       return ret;
-
-               /*
-                * In soc_bind_dai_link() will check cpu name after
-                * of_node matching if dai_link has cpu_dai_name.
-                * but, it will never match if name was created by
-                * fmt_single_name() remove cpu_dai_name if cpu_args
-                * was 0. See:
-                *      fmt_single_name()
-                *      fmt_multiple_name()
-                */
-               if (!args.args_count)
-                       dai_link->cpu_dai_name = NULL;
-       } else {
-               const struct rsrc_card_of_data *of_data;
-
-               of_data = of_device_get_match_data(dev);
-
-               /* FE is dummy */
-               dai_link->cpu_of_node           = NULL;
-               dai_link->cpu_dai_name          = "snd-soc-dummy-dai";
-               dai_link->cpu_name              = "snd-soc-dummy";
-
-               /* BE settings */
-               dai_link->no_pcm                = 1;
-               dai_link->be_hw_params_fixup    = rsrc_card_be_hw_params_fixup;
-               dai_link->codec_of_node         = args.np;
-               ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
-               if (ret < 0)
-                       return ret;
-
-               ret = asoc_simple_card_set_dailink_name(dev, dai_link,
-                                                       "be.%s",
-                                                       dai_link->codec_dai_name);
-               if (ret < 0)
-                       return ret;
-
-               /* additional name prefix */
-               if (of_data) {
-                       priv->codec_conf.of_node = dai_link->codec_of_node;
-                       priv->codec_conf.name_prefix = of_data->prefix;
-               } else {
-                       snd_soc_of_parse_audio_prefix(&priv->snd_card,
-                                                     &priv->codec_conf,
-                                                     dai_link->codec_of_node,
-                                                     "audio-prefix");
-               }
-       }
-
-       /* Simple Card assumes platform == cpu */
-       dai_link->platform_of_node      = dai_link->cpu_of_node;
-       dai_link->dpcm_playback         = 1;
-       dai_link->dpcm_capture          = 1;
-       dai_link->ops                   = &rsrc_card_ops;
-       dai_link->init                  = rsrc_card_dai_init;
-
-       return 0;
-}
-
-static int rsrc_card_parse_clk(struct device_node *np,
-                              struct rsrc_card_priv *priv,
-                              int idx, bool is_fe)
-{
-       struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
-       struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
-       struct clk *clk;
-       struct device_node *of_np = is_fe ?     dai_link->cpu_of_node :
-                                               dai_link->codec_of_node;
-       u32 val;
-
-       /*
-        * Parse dai->sysclk come from "clocks = <&xxx>"
-        * (if system has common clock)
-        *  or "system-clock-frequency = <xxx>"
-        *  or device's module clock.
-        */
-       if (of_property_read_bool(np, "clocks")) {
-               clk = of_clk_get(np, 0);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
-
-               dai_props->sysclk = clk_get_rate(clk);
-               dai_props->clk = clk;
-       } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
-               dai_props->sysclk = val;
-       } else {
-               clk = of_clk_get(of_np, 0);
-               if (!IS_ERR(clk))
-                       dai_props->sysclk = clk_get_rate(clk);
-       }
-
-       return 0;
-}
-
-static int rsrc_card_dai_sub_link_of(struct device_node *node,
-                                    struct device_node *np,
-                                    struct rsrc_card_priv *priv,
-                                    int idx, bool is_fe)
-{
-       struct device *dev = rsrc_priv_to_dev(priv);
-       struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
-       struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
-       int ret;
-
-       ret = rsrc_card_parse_links(np, priv, idx, is_fe);
-       if (ret < 0)
-               return ret;
-
-       ret = rsrc_card_parse_clk(np, priv, idx, is_fe);
-       if (ret < 0)
-               return ret;
-
-       dev_dbg(dev, "\t%s / %04x / %d\n",
-               dai_link->name,
-               dai_link->dai_fmt,
-               dai_props->sysclk);
-
-       return ret;
-}
-
-static int rsrc_card_dai_link_of(struct device_node *node,
-                                struct rsrc_card_priv *priv)
-{
-       struct device *dev = rsrc_priv_to_dev(priv);
-       struct snd_soc_dai_link *dai_link;
-       struct device_node *np;
-       unsigned int daifmt = 0;
-       int ret, i;
-       bool is_fe;
-
-       /* find 1st codec */
-       i = 0;
-       for_each_child_of_node(node, np) {
-               dai_link = rsrc_priv_to_link(priv, i);
-
-               if (strcmp(np->name, "codec") == 0) {
-                       ret = asoc_simple_card_parse_daifmt(dev, node, np,
-                                                           NULL, &daifmt);
-                       if (ret < 0)
-                               return ret;
-                       break;
-               }
-               i++;
-       }
-
-       i = 0;
-       for_each_child_of_node(node, np) {
-               dai_link = rsrc_priv_to_link(priv, i);
-               dai_link->dai_fmt = daifmt;
-
-               is_fe = false;
-               if (strcmp(np->name, "cpu") == 0)
-                       is_fe = true;
-
-               ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe);
-               if (ret < 0)
-                       return ret;
-               i++;
-       }
-
-       return 0;
-}
-
-static int rsrc_card_parse_of(struct device_node *node,
-                             struct rsrc_card_priv *priv,
-                             struct device *dev)
-{
-       const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev);
-       struct asoc_simple_dai *props;
-       struct snd_soc_dai_link *links;
-       int ret;
-       int num;
-
-       if (!node)
-               return -EINVAL;
-
-       num = of_get_child_count(node);
-       props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL);
-       links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL);
-       if (!props || !links)
-               return -ENOMEM;
-
-       priv->dai_props = props;
-       priv->dai_link  = links;
-
-       /* Init snd_soc_card */
-       priv->snd_card.owner                    = THIS_MODULE;
-       priv->snd_card.dev                      = dev;
-       priv->snd_card.dai_link                 = priv->dai_link;
-       priv->snd_card.num_links                = num;
-       priv->snd_card.codec_conf               = &priv->codec_conf;
-       priv->snd_card.num_configs              = 1;
-
-       if (of_data) {
-               priv->snd_card.of_dapm_routes           = of_data->routes;
-               priv->snd_card.num_of_dapm_routes       = of_data->num_routes;
-       } else {
-               snd_soc_of_parse_audio_routing(&priv->snd_card,
-                                              "audio-routing");
-       }
-
-       /* sampling rate convert */
-       of_property_read_u32(node, "convert-rate", &priv->convert_rate);
-
-       /* channels transfer */
-       of_property_read_u32(node, "convert-channels", &priv->convert_channels);
-
-       dev_dbg(dev, "New rsrc-audio-card: %s\n",
-               priv->snd_card.name ? priv->snd_card.name : "");
-       dev_dbg(dev, "SRC : convert_rate     %d\n", priv->convert_rate);
-       dev_dbg(dev, "CTU : convert_channels %d\n", priv->convert_channels);
-
-       ret = rsrc_card_dai_link_of(node, priv);
-       if (ret < 0)
-               return ret;
-
-       ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-");
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-/* Decrease the reference count of the device nodes */
-static int rsrc_card_unref(struct snd_soc_card *card)
-{
-       struct snd_soc_dai_link *dai_link;
-       int num_links;
-
-       for (num_links = 0, dai_link = card->dai_link;
-            num_links < card->num_links;
-            num_links++, dai_link++) {
-               of_node_put(dai_link->cpu_of_node);
-               of_node_put(dai_link->codec_of_node);
-       }
-       return 0;
-}
-
-static int rsrc_card_probe(struct platform_device *pdev)
-{
-       struct rsrc_card_priv *priv;
-       struct device_node *np = pdev->dev.of_node;
-       struct device *dev = &pdev->dev;
-       int ret;
-
-       /* Allocate the private data */
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       ret = rsrc_card_parse_of(np, priv, dev);
-       if (ret < 0) {
-               if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "parse error %d\n", ret);
-               goto err;
-       }
-
-       snd_soc_card_set_drvdata(&priv->snd_card, priv);
-
-       ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
-       if (ret >= 0)
-               return ret;
-err:
-       rsrc_card_unref(&priv->snd_card);
-
-       return ret;
-}
-
-static int rsrc_card_remove(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-       return rsrc_card_unref(card);
-}
-
-static struct platform_driver rsrc_card = {
-       .driver = {
-               .name = "renesas-src-audio-card",
-               .of_match_table = rsrc_card_of_match,
-       },
-       .probe = rsrc_card_probe,
-       .remove = rsrc_card_remove,
-};
-
-module_platform_driver(rsrc_card);
-
-MODULE_ALIAS("platform:renesas-src-audio-card");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
-MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
index 5f848f0547457338e122f5309914f3036c308836..6cb6db005fc45dd3e562fe480c0e353db7a6116a 100644 (file)
@@ -928,7 +928,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
                }
 
                ops = &rsnd_ssi_non_ops;
-               if (of_get_property(np, "pio-transfer", NULL))
+               if (of_property_read_bool(np, "pio-transfer"))
                        ops = &rsnd_ssi_pio_ops;
                else
                        ops = &rsnd_ssi_dma_ops;
index bc4a55bb3fd95ec085bb948579150f01de213472..6c8b0b0c56ece5e551b3d722b853c48ff22899b7 100644 (file)
@@ -116,7 +116,7 @@ static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
        return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
 }
 
-static struct gpio_chip snd_soc_ac97_gpio_chip = {
+static const struct gpio_chip snd_soc_ac97_gpio_chip = {
        .label                  = "snd_soc_ac97",
        .owner                  = THIS_MODULE,
        .request                = snd_soc_ac97_gpio_request,
index 4afa8dba5e982f664b1a214226688c50dfee1212..c0bbcd9032613a78aef551ce697cabc792880bad 100644 (file)
@@ -3332,19 +3332,6 @@ int snd_soc_register_codec(struct device *dev,
        if (ret)
                goto err_free;
 
-       if (codec_drv->controls) {
-               codec->component.controls = codec_drv->controls;
-               codec->component.num_controls = codec_drv->num_controls;
-       }
-       if (codec_drv->dapm_widgets) {
-               codec->component.dapm_widgets = codec_drv->dapm_widgets;
-               codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
-       }
-       if (codec_drv->dapm_routes) {
-               codec->component.dapm_routes = codec_drv->dapm_routes;
-               codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
-       }
-
        if (codec_drv->probe)
                codec->component.probe = snd_soc_codec_drv_probe;
        if (codec_drv->remove)
@@ -3732,7 +3719,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
         * SND_SOC_DAIFMT_CLOCK_MASK area
         */
        snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);
-       if (of_get_property(np, prop, NULL))
+       if (of_property_read_bool(np, prop))
                format |= SND_SOC_DAIFMT_CONT;
        else
                format |= SND_SOC_DAIFMT_GATED;
index d908ff8f97554cacdf6658288222744209287aee..3bbe32ee4630479ae55ea22f28690eef538aa75b 100644 (file)
@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
                        case snd_soc_dapm_switch:
                        case snd_soc_dapm_mixer:
                        case snd_soc_dapm_pga:
+                       case snd_soc_dapm_out_drv:
                                wname_in_long_name = true;
                                kcname_in_long_name = true;
                                break;
@@ -1169,7 +1170,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
  * @custom_stop_condition: (optional) a function meant to stop the widget graph
  *                         walk based on custom logic.
  *
- * Queries DAPM graph as to whether an valid audio stream path exists for
+ * Queries DAPM graph as to whether a valid audio stream path exists for
  * the initial stream specified by name. This takes into account
  * current mixer and mux kcontrol settings. Creates list of valid widgets.
  *
@@ -1294,8 +1295,7 @@ static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
        return w->new_power;
 }
 
-/* Generic check to see if a widget should be powered.
- */
+/* Generic check to see if a widget should be powered. */
 static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
 {
        int in, out;
@@ -1646,7 +1646,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
        struct snd_soc_dapm_context *d = data;
        int ret;
 
-       /* If we're off and we're not supposed to be go into STANDBY */
+       /* If we're off and we're not supposed to go into STANDBY */
        if (d->bias_level == SND_SOC_BIAS_OFF &&
            d->target_bias_level != SND_SOC_BIAS_OFF) {
                if (d->dev)
@@ -1798,7 +1798,7 @@ static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm)
  * A complete path is a route that has valid endpoints i.e.:-
  *
  *  o DAC to output pin.
- *  o Input Pin to ADC.
+ *  o Input pin to ADC.
  *  o Input pin to Output pin (bypass, sidetone)
  *  o DAC to ADC (loopback).
  */
@@ -2114,7 +2114,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
  * soc_dapm_connect_path() - Connects or disconnects a path
  * @path: The path to update
  * @connect: The new connect state of the path. True if the path is connected,
- *  false if it is disconneted.
+ *  false if it is disconnected.
  * @reason: The reason why the path changed (for debugging only)
  */
 static void soc_dapm_connect_path(struct snd_soc_dapm_path *path,
@@ -2233,7 +2233,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
                if (w->dapm != dapm)
                        continue;
 
-               /* only display widgets that burnm power */
+               /* only display widgets that burn power */
                switch (w->id) {
                case snd_soc_dapm_hp:
                case snd_soc_dapm_mic:
@@ -2461,7 +2461,7 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
 
        switch (w->id) {
        case snd_soc_dapm_input:
-               /* On a fully routed card a input is never a source */
+               /* On a fully routed card an input is never a source */
                if (w->dapm->card->fully_routed)
                        return;
                ep = SND_SOC_DAPM_EP_SOURCE;
@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
        }
        mutex_unlock(&card->dapm_mutex);
 
+       if (ret)
+               return ret;
+
        if (invert)
                ucontrol->value.integer.value[0] = max - val;
        else
@@ -3200,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
        if (e->shift_l != e->shift_r) {
                if (item[1] > e->items)
                        return -EINVAL;
-               val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
+               val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
                mask |= e->mask << e->shift_r;
        }
 
@@ -3445,7 +3448,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
                w->endpoints[dir] = -1;
        }
 
-       /* machine layer set ups unconnected pins and insertions */
+       /* machine layer sets up unconnected pins and insertions */
        w->connected = 1;
        return w;
 }
index a513a34a51d299a8bf7d9ef7799717ceb4a42430..9fc1a7bb8b953a7a2955ea1ca2d31b30fccfee37 100644 (file)
@@ -77,7 +77,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
        item = snd_soc_enum_val_to_item(e, val);
        ucontrol->value.enumerated.item[0] = item;
        if (e->shift_l != e->shift_r) {
-               val = (reg_val >> e->shift_l) & e->mask;
+               val = (reg_val >> e->shift_r) & e->mask;
                item = snd_soc_enum_val_to_item(e, val);
                ucontrol->value.enumerated.item[1] = item;
        }
index ee7f15aa46fca30400a07d8b8cf4f44717f0a89f..6b05047a4134da76ff9abe96da16e5f6123d12aa 100644 (file)
 #define SOC_TPLG_PASS_PCM_DAI          4
 #define SOC_TPLG_PASS_GRAPH            5
 #define SOC_TPLG_PASS_PINS             6
+#define SOC_TPLG_PASS_BE_DAI           7
 
 #define SOC_TPLG_PASS_START    SOC_TPLG_PASS_MANIFEST
-#define SOC_TPLG_PASS_END      SOC_TPLG_PASS_PINS
+#define SOC_TPLG_PASS_END      SOC_TPLG_PASS_BE_DAI
 
 struct soc_tplg {
        const struct firmware *fw;
@@ -1475,6 +1476,7 @@ widget:
        if (widget == NULL) {
                dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n",
                        w->name);
+               ret = -ENOMEM;
                goto hdr_err;
        }
 
@@ -1554,6 +1556,25 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
        stream->rate_min = caps->rate_min;
        stream->rate_max = caps->rate_max;
        stream->formats = caps->formats;
+       stream->sig_bits = caps->sig_bits;
+}
+
+static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
+                         unsigned int flag_mask, unsigned int flags)
+{
+       if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES)
+               dai_drv->symmetric_rates =
+                       flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0;
+
+       if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS)
+               dai_drv->symmetric_channels =
+                       flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS ?
+                       1 : 0;
+
+       if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS)
+               dai_drv->symmetric_samplebits =
+                       flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ?
+                       1 : 0;
 }
 
 static int soc_tplg_dai_create(struct soc_tplg *tplg,
@@ -1690,8 +1711,96 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
        return 0;
 }
 
+/* *
+ * soc_tplg_be_dai_config - Find and configure an existing BE DAI.
+ * @tplg: topology context
+ * @be: topology BE DAI configs.
+ *
+ * The BE dai should already be registered by the platform driver. The
+ * platform driver should specify the BE DAI name and ID for matching.
+ */
+static int soc_tplg_be_dai_config(struct soc_tplg *tplg,
+                                 struct snd_soc_tplg_be_dai *be)
+{
+       struct snd_soc_dai_link_component dai_component = {0};
+       struct snd_soc_dai *dai;
+       struct snd_soc_dai_driver *dai_drv;
+       struct snd_soc_pcm_stream *stream;
+       struct snd_soc_tplg_stream_caps *caps;
+       int ret;
+
+       dai_component.dai_name = be->dai_name;
+       dai = snd_soc_find_dai(&dai_component);
+       if (!dai) {
+               dev_err(tplg->dev, "ASoC: BE DAI %s not registered\n",
+                       be->dai_name);
+               return -EINVAL;
+       }
+
+       if (be->dai_id != dai->id) {
+               dev_err(tplg->dev, "ASoC: BE DAI %s id mismatch\n",
+                       be->dai_name);
+               return -EINVAL;
+       }
+
+       dai_drv = dai->driver;
+       if (!dai_drv)
+               return -EINVAL;
+
+       if (be->playback) {
+               stream = &dai_drv->playback;
+               caps = &be->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
+               set_stream_info(stream, caps);
+       }
+
+       if (be->capture) {
+               stream = &dai_drv->capture;
+               caps = &be->caps[SND_SOC_TPLG_STREAM_CAPTURE];
+               set_stream_info(stream, caps);
+       }
+
+       if (be->flag_mask)
+               set_dai_flags(dai_drv, be->flag_mask, be->flags);
+
+       /* pass control to component driver for optional further init */
+       ret = soc_tplg_dai_load(tplg, dai_drv);
+       if (ret < 0) {
+               dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg,
+                                     struct snd_soc_tplg_hdr *hdr)
+{
+       struct snd_soc_tplg_be_dai *be;
+       int count = hdr->count;
+       int i;
+
+       if (tplg->pass != SOC_TPLG_PASS_BE_DAI)
+               return 0;
+
+       /* config the existing BE DAIs */
+       for (i = 0; i < count; i++) {
+               be = (struct snd_soc_tplg_be_dai *)tplg->pos;
+               if (be->size != sizeof(*be)) {
+                       dev_err(tplg->dev, "ASoC: invalid BE DAI size\n");
+                       return -EINVAL;
+               }
+
+               soc_tplg_be_dai_config(tplg, be);
+               tplg->pos += (sizeof(*be) + be->priv.size);
+       }
+
+       dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count);
+       return 0;
+}
+
+
 static int soc_tplg_manifest_load(struct soc_tplg *tplg,
-       struct snd_soc_tplg_hdr *hdr)
+                                 struct snd_soc_tplg_hdr *hdr)
 {
        struct snd_soc_tplg_manifest *manifest;
 
@@ -1793,6 +1902,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg,
                return soc_tplg_dapm_widget_elems_load(tplg, hdr);
        case SND_SOC_TPLG_TYPE_PCM:
                return soc_tplg_pcm_elems_load(tplg, hdr);
+       case SND_SOC_TPLG_TYPE_BE_DAI:
+               return soc_tplg_be_dai_elems_load(tplg, hdr);
        case SND_SOC_TPLG_TYPE_MANIFEST:
                return soc_tplg_manifest_load(tplg, hdr);
        default:
index 53dd085d3ee20fd5db326366db72054990886118..393e8f0fe2cc6902c4bfaf7a54519496c2d073a5 100644 (file)
@@ -80,7 +80,7 @@ static int dummy_dma_open(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static struct snd_pcm_ops dummy_dma_ops = {
+static const struct snd_pcm_ops dummy_dma_ops = {
        .open           = dummy_dma_open,
        .ioctl          = snd_pcm_lib_ioctl,
 };
index 2a954bd01fd83e827e8e0b544384046703b973b5..dd2368297fd39c6d79a237f4e0c76a2bd7f438a4 100644 (file)
@@ -1,4 +1,5 @@
 menu "Allwinner SoC Audio support"
+       depends on ARCH_SUNXI || COMPILE_TEST
 
 config SND_SUN4I_CODEC
        tristate "Allwinner A10 Codec Support"
index 44f170c73b06a95a71d3b1a1680db37a8fb227f8..0e19c5070005736c4cb5ae27fc374ecb25d67030 100644 (file)
@@ -628,12 +628,14 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
-       .controls               = sun4i_codec_widgets,
-       .num_controls           = ARRAY_SIZE(sun4i_codec_widgets),
-       .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
-       .dapm_routes            = sun4i_codec_codec_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+       .component_driver = {
+               .controls               = sun4i_codec_widgets,
+               .num_controls           = ARRAY_SIZE(sun4i_codec_widgets),
+               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
+               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
+               .dapm_routes            = sun4i_codec_codec_dapm_routes,
+               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+       },
 };
 
 static const struct snd_soc_component_driver sun4i_codec_component = {
index 0b04fb02125cd86060c398947ad7d1ee0e700322..88fbb3a1e66015640a40ff61a70879911ddba38e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -162,6 +163,7 @@ struct sun4i_spdif_dev {
        struct platform_device *pdev;
        struct clk *spdif_clk;
        struct clk *apb_clk;
+       struct reset_control *rst;
        struct snd_soc_dai_driver cpu_dai_drv;
        struct regmap *regmap;
        struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -411,6 +413,7 @@ static const struct snd_soc_dapm_route dit_routes[] = {
 
 static const struct of_device_id sun4i_spdif_of_match[] = {
        { .compatible = "allwinner,sun4i-a10-spdif", },
+       { .compatible = "allwinner,sun6i-a31-spdif", },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
@@ -482,11 +485,23 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
        }
 
        host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO;
-       host->dma_params_tx.maxburst = 4;
+       host->dma_params_tx.maxburst = 8;
        host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
        platform_set_drvdata(pdev, host);
 
+       if (of_device_is_compatible(pdev->dev.of_node,
+                                   "allwinner,sun6i-a31-spdif")) {
+               host->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+               if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
+                       goto err_disable_apb_clk;
+               }
+               if (!IS_ERR(host->rst))
+                       reset_control_deassert(host->rst);
+       }
+
        ret = devm_snd_soc_register_component(&pdev->dev,
                                &sun4i_spdif_component, &sun4i_spdif_dai, 1);
        if (ret)
index a6768f832c6fe87e4679e0df7f47e51e81e3b8a4..efbe8d4c019eefa5c77b3e500c2eec248ff0410f 100644 (file)
@@ -138,3 +138,14 @@ config SND_SOC_TEGRA_RT5677
        help
          Say Y or M here if you want to add support for SoC audio on Tegra
          boards using the RT5677 codec, such as Ryu.
+
+config SND_SOC_TEGRA_SGTL5000
+       tristate "SoC Audio support for Tegra boards using a SGTL5000 codec"
+       depends on SND_SOC_TEGRA && I2C && GPIOLIB
+       select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
+       select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
+       select SND_SOC_SGTL5000
+       help
+         Say Y or M here if you want to add support for SoC audio on Tegra
+         boards using the SGTL5000 codec, such as Apalis T30, Apalis TK1 or
+         Colibri T30.
index 9171655ad843213c1eea2028cf8fccd74d73887e..f214a3fd0024635a471667d36645ec93126c9b03 100644 (file)
@@ -26,6 +26,7 @@ snd-soc-tegra-wm9712-objs := tegra_wm9712.o
 snd-soc-tegra-trimslice-objs := trimslice.o
 snd-soc-tegra-alc5632-objs := tegra_alc5632.o
 snd-soc-tegra-max98090-objs := tegra_max98090.o
+snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o
 
 obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
 obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
 obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
 obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
 obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o
+obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o
\ No newline at end of file
index 773daecaa5e89f04700fafc049d922e37a1f35b7..e5ef4e9c4ac59cdc81bde106f472818e1ba44039 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec.
+* tegra_rt5640.c - Tegra machine ASoC driver for boards using RT5640 codec.
  *
  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
  *
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c
new file mode 100644 (file)
index 0000000..1e76869
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * tegra_sgtl5000.c - Tegra machine ASoC driver for boards using SGTL5000 codec
+ *
+ * Author: Marcel Ziswiler <marcel@ziswiler.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Based on code copyright/by:
+ *
+ * Copyright (C) 2010-2012 - NVIDIA, Inc.
+ * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
+ * Copyright 2007 Wolfson Microelectronics PLC.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "../codecs/sgtl5000.h"
+
+#include "tegra_asoc_utils.h"
+
+#define DRV_NAME "tegra-snd-sgtl5000"
+
+struct tegra_sgtl5000 {
+       struct tegra_asoc_utils_data util_data;
+};
+
+static int tegra_sgtl5000_hw_params(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_card *card = rtd->card;
+       struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card);
+       int srate, mclk;
+       int err;
+
+       srate = params_rate(params);
+       switch (srate) {
+       case 11025:
+       case 22050:
+       case 44100:
+       case 88200:
+               mclk = 11289600;
+               break;
+       default:
+               mclk = 12288000;
+               break;
+       }
+
+       err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
+       if (err < 0) {
+               dev_err(card->dev, "Can't configure clocks\n");
+               return err;
+       }
+
+       err = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk,
+                                    SND_SOC_CLOCK_IN);
+       if (err < 0) {
+               dev_err(card->dev, "codec_dai clock not set\n");
+               return err;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops tegra_sgtl5000_ops = {
+       .hw_params = tegra_sgtl5000_hw_params,
+};
+
+static const struct snd_soc_dapm_widget tegra_sgtl5000_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_LINE("Line In Jack", NULL),
+       SND_SOC_DAPM_MIC("Mic Jack", NULL),
+};
+
+static struct snd_soc_dai_link tegra_sgtl5000_dai = {
+       .name = "sgtl5000",
+       .stream_name = "HiFi",
+       .codec_dai_name = "sgtl5000",
+       .ops = &tegra_sgtl5000_ops,
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+};
+
+static struct snd_soc_card snd_soc_tegra_sgtl5000 = {
+       .name = "tegra-sgtl5000",
+       .owner = THIS_MODULE,
+       .dai_link = &tegra_sgtl5000_dai,
+       .num_links = 1,
+       .dapm_widgets = tegra_sgtl5000_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(tegra_sgtl5000_dapm_widgets),
+       .fully_routed = true,
+};
+
+static int tegra_sgtl5000_driver_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct snd_soc_card *card = &snd_soc_tegra_sgtl5000;
+       struct tegra_sgtl5000 *machine;
+       int ret;
+
+       machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000),
+                              GFP_KERNEL);
+       if (!machine) {
+               dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n");
+               return -ENOMEM;
+       }
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+       snd_soc_card_set_drvdata(card, machine);
+
+       ret = snd_soc_of_parse_card_name(card, "nvidia,model");
+       if (ret)
+               goto err;
+
+       ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
+       if (ret)
+               goto err;
+
+       tegra_sgtl5000_dai.codec_of_node = of_parse_phandle(np,
+                       "nvidia,audio-codec", 0);
+       if (!tegra_sgtl5000_dai.codec_of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'nvidia,audio-codec' missing or invalid\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       tegra_sgtl5000_dai.cpu_of_node = of_parse_phandle(np,
+                       "nvidia,i2s-controller", 0);
+       if (!tegra_sgtl5000_dai.cpu_of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'nvidia,i2s-controller' missing/invalid\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       tegra_sgtl5000_dai.platform_of_node = tegra_sgtl5000_dai.cpu_of_node;
+
+       ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
+       if (ret)
+               goto err;
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                       ret);
+               goto err_fini_utils;
+       }
+
+       return 0;
+
+err_fini_utils:
+       tegra_asoc_utils_fini(&machine->util_data);
+err:
+       return ret;
+}
+
+static int tegra_sgtl5000_driver_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card);
+       int ret;
+
+       ret = snd_soc_unregister_card(card);
+
+       tegra_asoc_utils_fini(&machine->util_data);
+
+       return ret;
+}
+
+static const struct of_device_id tegra_sgtl5000_of_match[] = {
+       { .compatible = "nvidia,tegra-audio-sgtl5000", },
+       { /* sentinel */ },
+};
+
+static struct platform_driver tegra_sgtl5000_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .pm = &snd_soc_pm_ops,
+               .of_match_table = tegra_sgtl5000_of_match,
+       },
+       .probe = tegra_sgtl5000_driver_probe,
+       .remove = tegra_sgtl5000_driver_remove,
+};
+module_platform_driver(tegra_sgtl5000_driver);
+
+MODULE_AUTHOR("Marcel Ziswiler <marcel@ziswiler.com>");
+MODULE_DESCRIPTION("Tegra SGTL5000 machine ASoC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_sgtl5000_of_match);
index 6d5698b25bd4b25c92c128860527245167d665d0..b343efd9be5ba7e9d39fa1cf28f30d41f78b82ce 100644 (file)
@@ -187,7 +187,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
 
        default:
                dev_err(dai->dev,
-                       "%s: Error: Unsopported inversion (fmt = 0x%x)!\n",
+                       "%s: Error: Unsupported inversion (fmt = 0x%x)!\n",
                        __func__, fmt);
 
                return -EINVAL;
@@ -218,7 +218,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
                break;
 
        default:
-               dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n",
+               dev_err(dai->dev, "%s: Error: Unsupported master (fmt = 0x%x)!\n",
                        __func__, fmt);
 
                return -EINVAL;
@@ -374,7 +374,7 @@ static int setup_msp_config(struct snd_pcm_substream *substream,
                break;
 
        default:
-               dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n",
+               dev_err(dai->dev, "%s: Error: Unsupported format (%d)!\n",
                        __func__, fmt);
                return -EINVAL;
        }
This page took 0.241547 seconds and 5 git commands to generate.