Unified · Split
| @@ -0,0 +1,88 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/dsp/fsl,dsp.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: NXP i.MX8 DSP core | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Daniel Baluta <daniel.baluta@nxp.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + Some boards from i.MX8 family contain a DSP core used for | |
| 14 | + advanced pre- and post- audio processing. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + enum: | |
| 19 | + - fsl,imx8qxp-dsp | |
| 20 | + | |
| 21 | + reg: | |
| 22 | + description: Should contain register location and length | |
| 23 | + | |
| 24 | + clocks: | |
| 25 | + items: | |
| 26 | + - description: ipg clock | |
| 27 | + - description: ocram clock | |
| 28 | + - description: core clock | |
| 29 | + | |
| 30 | + clock-names: | |
| 31 | + items: | |
| 32 | + - const: ipg | |
| 33 | + - const: ocram | |
| 34 | + - const: core | |
| 35 | + | |
| 36 | + power-domains: | |
| 37 | + description: | |
| 38 | + List of phandle and PM domain specifier as documented in | |
| 39 | + Documentation/devicetree/bindings/power/power_domain.txt | |
| 40 | + maxItems: 4 | |
| 41 | + | |
| 42 | + mboxes: | |
| 43 | + description: | |
| 44 | + List of <&phandle type channel> - 2 channels for TXDB, 2 channels for RXDB | |
| 45 | + (see mailbox/fsl,mu.txt) | |
| 46 | + maxItems: 4 | |
| 47 | + | |
| 48 | + mbox-names: | |
| 49 | + items: | |
| 50 | + - const: txdb0 | |
| 51 | + - const: txdb1 | |
| 52 | + - const: rxdb0 | |
| 53 | + - const: rxdb1 | |
| 54 | + | |
| 55 | + memory-region: | |
| 56 | + description: | |
| 57 | + phandle to a node describing reserved memory (System RAM memory) | |
| 58 | + used by DSP (see bindings/reserved-memory/reserved-memory.txt) | |
| 59 | + maxItems: 1 | |
| 60 | + | |
| 61 | +required: | |
| 62 | + - compatible | |
| 63 | + - reg | |
| 64 | + - clocks | |
| 65 | + - clock-names | |
| 66 | + - power-domains | |
| 67 | + - mboxes | |
| 68 | + - mbox-names | |
| 69 | + - memory-region | |
| 70 | + | |
| 71 | +examples: | |
| 72 | + - | | |
| 73 | + #include <dt-bindings/firmware/imx/rsrc.h> | |
| 74 | + #include <dt-bindings/clock/imx8-clock.h> | |
| 75 | + dsp@596e8000 { | |
| 76 | + compatible = "fsl,imx8qxp-dsp"; | |
| 77 | + reg = <0x596e8000 0x88000>; | |
| 78 | + clocks = <&adma_lpcg IMX_ADMA_LPCG_DSP_IPG_CLK>, | |
| 79 | + <&adma_lpcg IMX_ADMA_LPCG_OCRAM_IPG_CLK>, | |
| 80 | + <&adma_lpcg IMX_ADMA_LPCG_DSP_CORE_CLK>; | |
| 81 | + clock-names = "ipg", "ocram", "core"; | |
| 82 | + power-domains = <&pd IMX_SC_R_MU_13A>, | |
| 83 | + <&pd IMX_SC_R_MU_13B>, | |
| 84 | + <&pd IMX_SC_R_DSP>, | |
| 85 | + <&pd IMX_SC_R_DSP_RAM>; | |
| 86 | + mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1"; | |
| 87 | + mboxes = <&lsio_mu13 2 0>, <&lsio_mu13 2 1>, <&lsio_mu13 3 0>, <&lsio_mu13 3 1>; | |
| 88 | + }; | |
| @@ -70,7 +70,9 @@ allOf: · 69 unmodified lines | ||
| 70 | 70 | properties: |
| 71 | 71 | compatible: |
| 72 | 72 | contains: |
| 73 | − const: allwinner,sun8i-h3-spdif | |
| 73 | + enum: | |
| 74 | + - allwinner,sun8i-h3-spdif | |
| 75 | + - allwinner,sun50i-h6-spdif | |
| 74 | 76 | |
| 75 | 77 | then: |
| 76 | 78 | properties: |
| @@ -0,0 +1,39 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/sound/allwinner,sun50i-a64-codec-analog.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Allwinner A64 Analog Codec Device Tree Bindings | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Chen-Yu Tsai <wens@csie.org> | |
| 11 | + - Maxime Ripard <maxime.ripard@bootlin.com> | |
| 12 | + | |
| 13 | +properties: | |
| 14 | + compatible: | |
| 15 | + const: allwinner,sun50i-a64-codec-analog | |
| 16 | + | |
| 17 | + reg: | |
| 18 | + maxItems: 1 | |
| 19 | + | |
| 20 | + cpvdd-supply: | |
| 21 | + description: | |
| 22 | + Regulator for the headphone amplifier | |
| 23 | + | |
| 24 | +required: | |
| 25 | + - compatible | |
| 26 | + - reg | |
| 27 | + - cpvdd-supply | |
| 28 | + | |
| 29 | +additionalProperties: false | |
| 30 | + | |
| 31 | +examples: | |
| 32 | + - | | |
| 33 | + codec_analog: codec-analog@1f015c0 { | |
| 34 | + compatible = "allwinner,sun50i-a64-codec-analog"; | |
| 35 | + reg = <0x01f015c0 0x4>; | |
| 36 | + cpvdd-supply = <®_eldo1>; | |
| 37 | + }; | |
| 38 | + | |
| 39 | +... | |
| @@ -0,0 +1,57 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a33-codec.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Allwinner A33 Codec Device Tree Bindings | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Chen-Yu Tsai <wens@csie.org> | |
| 11 | + - Maxime Ripard <maxime.ripard@bootlin.com> | |
| 12 | + | |
| 13 | +properties: | |
| 14 | + "#sound-dai-cells": | |
| 15 | + const: 0 | |
| 16 | + | |
| 17 | + compatible: | |
| 18 | + const: allwinner,sun8i-a33-codec | |
| 19 | + | |
| 20 | + reg: | |
| 21 | + maxItems: 1 | |
| 22 | + | |
| 23 | + interrupts: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + clocks: | |
| 27 | + items: | |
| 28 | + - description: Bus Clock | |
| 29 | + - description: Module Clock | |
| 30 | + | |
| 31 | + clock-names: | |
| 32 | + items: | |
| 33 | + - const: bus | |
| 34 | + - const: mod | |
| 35 | + | |
| 36 | +required: | |
| 37 | + - "#sound-dai-cells" | |
| 38 | + - compatible | |
| 39 | + - reg | |
| 40 | + - interrupts | |
| 41 | + - clocks | |
| 42 | + - clock-names | |
| 43 | + | |
| 44 | +additionalProperties: false | |
| 45 | + | |
| 46 | +examples: | |
| 47 | + - | | |
| 48 | + audio-codec@1c22e00 { | |
| 49 | + #sound-dai-cells = <0>; | |
| 50 | + compatible = "allwinner,sun8i-a33-codec"; | |
| 51 | + reg = <0x01c22e00 0x400>; | |
| 52 | + interrupts = <0 29 4>; | |
| 53 | + clocks = <&ccu 47>, <&ccu 92>; | |
| 54 | + clock-names = "bus", "mod"; | |
| 55 | + }; | |
| 56 | + | |
| 57 | +... | |
| @@ -4,13 +4,18 @@ Required properties: · 3 unmodified lines | ||
| 4 | 4 | - compatible: 'amlogic,axg-toddr' or |
| 5 | 5 | 'amlogic,axg-toddr' or |
| 6 | 6 | 'amlogic,g12a-frddr' or |
| 7 | − 'amlogic,g12a-toddr' | |
| 7 | + 'amlogic,g12a-toddr' or | |
| 8 | + 'amlogic,sm1-frddr' or | |
| 9 | + 'amlogic,sm1-toddr' | |
| 8 | 10 | - reg: physical base address of the controller and length of memory |
| 9 | 11 | mapped region. |
| 10 | 12 | - interrupts: interrupt specifier for the fifo. |
| 11 | 13 | - clocks: phandle to the fifo peripheral clock provided by the audio |
| 12 | 14 | clock controller. |
| 13 | −- resets: phandle to memory ARB line provided by the arb reset controller. | |
| 15 | +- resets: list of reset phandle, one for each entry reset-names. | |
| 16 | +- reset-names: should contain the following: | |
| 17 | + * "arb" : memory ARB line (required) | |
| 18 | + * "rst" : dedicated device reset line (optional) | |
| 14 | 19 | - #sound-dai-cells: must be 0. |
| 15 | 20 | |
| 16 | 21 | Example of FRDDR A on the A113 SoC: |
| @@ -2,7 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | 4 | - compatible: 'amlogic,axg-pdm' or |
| 5 | − 'amlogic,g12a-pdm' | |
| 5 | + 'amlogic,g12a-pdm' or | |
| 6 | + 'amlogic,sm1-pdm' | |
| 6 | 7 | - reg: physical base address of the controller and length of memory |
| 7 | 8 | mapped region. |
| 8 | 9 | - clocks: list of clock phandle, one for each entry clock-names. |
| @@ -12,6 +13,9 @@ Required properties: · 3 unmodified lines | ||
| 12 | 13 | * "sysclk" : dsp system clock |
| 13 | 14 | - #sound-dai-cells: must be 0. |
| 14 | 15 | |
| 16 | +Optional property: | |
| 17 | +- resets: phandle to the dedicated reset line of the pdm input. | |
| 18 | + | |
| 15 | 19 | Example of PDM on the A113 SoC: |
| 16 | 20 | |
| 17 | 21 | pdm: audio-controller@ff632000 { |
| @@ -2,7 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | 4 | - compatible: 'amlogic,axg-spdifin' or |
| 5 | − 'amlogic,g12a-spdifin' | |
| 5 | + 'amlogic,g12a-spdifin' or | |
| 6 | + 'amlogic,sm1-spdifin' | |
| 6 | 7 | - interrupts: interrupt specifier for the spdif input. |
| 7 | 8 | - clocks: list of clock phandle, one for each entry clock-names. |
| 8 | 9 | - clock-names: should contain the following: |
| @@ -10,6 +11,9 @@ Required properties: · 1 unmodified line | ||
| 10 | 11 | * "refclk" : spdif input reference clock |
| 11 | 12 | - #sound-dai-cells: must be 0. |
| 12 | 13 | |
| 14 | +Optional property: | |
| 15 | +- resets: phandle to the dedicated reset line of the spdif input. | |
| 16 | + | |
| 13 | 17 | Example on the A113 SoC: |
| 14 | 18 | |
| 15 | 19 | spdifin: audio-controller@400 { |
| @@ -2,13 +2,17 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | 4 | - compatible: 'amlogic,axg-spdifout' or |
| 5 | − 'amlogic,g12a-spdifout' | |
| 5 | + 'amlogic,g12a-spdifout' or | |
| 6 | + 'amlogic,sm1-spdifout' | |
| 6 | 7 | - clocks: list of clock phandle, one for each entry clock-names. |
| 7 | 8 | - clock-names: should contain the following: |
| 8 | 9 | * "pclk" : peripheral clock. |
| 9 | 10 | * "mclk" : master clock |
| 10 | 11 | - #sound-dai-cells: must be 0. |
| 11 | 12 | |
| 13 | +Optional property: | |
| 14 | +- resets: phandle to the dedicated reset line of the spdif output. | |
| 15 | + | |
| 12 | 16 | Example on the A113 SoC: |
| 13 | 17 | |
| 14 | 18 | spdifout: audio-controller@480 { |
| @@ -4,7 +4,9 @@ Required properties: · 3 unmodified lines | ||
| 4 | 4 | - compatible: 'amlogic,axg-tdmin' or |
| 5 | 5 | 'amlogic,axg-tdmout' or |
| 6 | 6 | 'amlogic,g12a-tdmin' or |
| 7 | − 'amlogic,g12a-tdmout' | |
| 7 | + 'amlogic,g12a-tdmout' or | |
| 8 | + 'amlogic,sm1-tdmin' or | |
| 9 | + 'amlogic,sm1-tdmout | |
| 8 | 10 | - reg: physical base address of the controller and length of memory |
| 9 | 11 | mapped region. |
| 10 | 12 | - clocks: list of clock phandle, one for each entry clock-names. |
| @@ -1,10 +1,12 @@ | ||
| 1 | 1 | * Amlogic HDMI Tx control glue |
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | −- compatible: "amlogic,g12a-tohdmitx" | |
| 4 | +- compatible: "amlogic,g12a-tohdmitx" or | |
| 5 | + "amlogic,sm1-tohdmitx" | |
| 5 | 6 | - reg: physical base address of the controller and length of memory |
| 6 | 7 | mapped region. |
| 7 | 8 | - #sound-dai-cells: should be 1. |
| 9 | +- resets: phandle to the dedicated reset line of the hdmitx glue. | |
| 8 | 10 | |
| 9 | 11 | Example on the S905X2 SoC: |
| 10 | 12 | |
| @@ -12,6 +14,7 @@ tohdmitx: audio-controller@744 { · 1 unmodified line | ||
| 12 | 14 | compatible = "amlogic,g12a-tohdmitx"; |
| 13 | 15 | reg = <0x0 0x744 0x0 0x4>; |
| 14 | 16 | #sound-dai-cells = <1>; |
| 17 | + resets = <&clkc_audio AUD_RESET_TOHDMITX>; | |
| 15 | 18 | }; |
| 16 | 19 | |
| 17 | 20 | Example of an 'amlogic,axg-sound-card': |
| @@ -0,0 +1,23 @@ | ||
| 1 | +Everest ES8316 audio CODEC | |
| 2 | + | |
| 3 | +This device supports both I2C and SPI. | |
| 4 | + | |
| 5 | +Required properties: | |
| 6 | + | |
| 7 | + - compatible : should be "everest,es8316" | |
| 8 | + - reg : the I2C address of the device for I2C | |
| 9 | + | |
| 10 | +Optional properties: | |
| 11 | + | |
| 12 | + - clocks : a list of phandle, should contain entries for clock-names | |
| 13 | + - clock-names : should include as follows: | |
| 14 | + "mclk" : master clock (MCLK) of the device | |
| 15 | + | |
| 16 | +Example: | |
| 17 | + | |
| 18 | +es8316: codec@11 { | |
| 19 | + compatible = "everest,es8316"; | |
| 20 | + reg = <0x11>; | |
| 21 | + clocks = <&clks 10>; | |
| 22 | + clock-names = "mclk"; | |
| 23 | +}; | |
| @@ -7,8 +7,11 @@ other DSPs. It has up to six transmitters and four receivers. · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | Required properties: |
| 9 | 9 | |
| 10 | − - compatible : Compatible list, must contain "fsl,imx35-esai" or | |
| 11 | − "fsl,vf610-esai" | |
| 10 | + - compatible : Compatible list, should contain one of the following | |
| 11 | + compatibles: | |
| 12 | + "fsl,imx35-esai", | |
| 13 | + "fsl,vf610-esai", | |
| 14 | + "fsl,imx6ull-esai", | |
| 12 | 15 | |
| 13 | 16 | - reg : Offset and length of the register set for the device. |
| 14 | 17 | |
| @@ -8,7 +8,9 @@ codec/DSP interfaces. · 7 unmodified lines | ||
| 8 | 8 | Required properties: |
| 9 | 9 | |
| 10 | 10 | - compatible : Compatible list, contains "fsl,vf610-sai", |
| 11 | − "fsl,imx6sx-sai" or "fsl,imx6ul-sai" | |
| 11 | + "fsl,imx6sx-sai", "fsl,imx6ul-sai", | |
| 12 | + "fsl,imx7ulp-sai", "fsl,imx8mq-sai" or | |
| 13 | + "fsl,imx8qm-sai". | |
| 12 | 14 | |
| 13 | 15 | - reg : Offset and length of the register set for the device. |
| 14 | 16 | |
| @@ -1,14 +0,0 @@ | ||
| 1 | −* Allwinner A64 Codec Analog Controls | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | −- compatible: must be one of the following compatibles: | |
| 5 | − - "allwinner,sun50i-a64-codec-analog" | |
| 6 | −- reg: must contain the registers location and length | |
| 7 | −- cpvdd-supply: Regulator supply for the headphone amplifier | |
| 8 | − | |
| 9 | −Example: | |
| 10 | − codec_analog: codec-analog@1f015c0 { | |
| 11 | − compatible = "allwinner,sun50i-a64-codec-analog"; | |
| 12 | − reg = <0x01f015c0 0x4>; | |
| 13 | − cpvdd-supply = <®_eldo1>; | |
| 14 | − }; | |
| @@ -1,63 +0,0 @@ | ||
| 1 | −Allwinner SUN8I audio codec | |
| 2 | −------------------------------------ | |
| 3 | − | |
| 4 | −On Sun8i-A33 SoCs, the audio is separated in different parts: | |
| 5 | − - A DAI driver. It uses the "sun4i-i2s" driver which is | |
| 6 | − documented here: | |
| 7 | − Documentation/devicetree/bindings/sound/sun4i-i2s.txt | |
| 8 | − - An analog part of the codec which is handled as PRCM registers. | |
| 9 | − See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt | |
| 10 | − - An digital part of the codec which is documented in this current | |
| 11 | − binding documentation. | |
| 12 | − - And finally, an audio card which links all the above components. | |
| 13 | − The simple-audio card will be used. | |
| 14 | − See Documentation/devicetree/bindings/sound/simple-card.txt | |
| 15 | − | |
| 16 | −This bindings documentation exposes Sun8i codec (digital part). | |
| 17 | − | |
| 18 | −Required properties: | |
| 19 | −- compatible: must be "allwinner,sun8i-a33-codec" | |
| 20 | −- reg: must contain the registers location and length | |
| 21 | −- interrupts: must contain the codec interrupt | |
| 22 | −- clocks: a list of phandle + clock-specifer pairs, one for each entry | |
| 23 | − in clock-names. | |
| 24 | −- clock-names: should contain followings: | |
| 25 | − - "bus": the parent APB clock for this controller | |
| 26 | − - "mod": the parent module clock | |
| 27 | − | |
| 28 | −Here is an example to add a sound card and the codec binding on sun8i SoCs that | |
| 29 | −are similar to A33 using simple-card: | |
| 30 | − | |
| 31 | − sound { | |
| 32 | − compatible = "simple-audio-card"; | |
| 33 | − simple-audio-card,name = "sun8i-a33-audio"; | |
| 34 | − simple-audio-card,format = "i2s"; | |
| 35 | − simple-audio-card,frame-master = <&link_codec>; | |
| 36 | − simple-audio-card,bitclock-master = <&link_codec>; | |
| 37 | − simple-audio-card,mclk-fs = <512>; | |
| 38 | − simple-audio-card,aux-devs = <&codec_analog>; | |
| 39 | − simple-audio-card,routing = | |
| 40 | − "Left DAC", "Digital Left DAC", | |
| 41 | − "Right DAC", "Digital Right DAC"; | |
| 42 | − | |
| 43 | − simple-audio-card,cpu { | |
| 44 | − sound-dai = <&dai>; | |
| 45 | − }; | |
| 46 | − | |
| 47 | − link_codec: simple-audio-card,codec { | |
| 48 | − sound-dai = <&codec>; | |
| 49 | − }; | |
| 50 | − | |
| 51 | − soc@1c00000 { | |
| 52 | − [...] | |
| 53 | − | |
| 54 | − audio-codec@1c22e00 { | |
| 55 | − #sound-dai-cells = <0>; | |
| 56 | − compatible = "allwinner,sun8i-a33-codec"; | |
| 57 | − reg = <0x01c22e00 0x400>; | |
| 58 | − interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | |
| 59 | − clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>; | |
| 60 | − clock-names = "bus", "mod"; | |
| 61 | − }; | |
| 62 | − }; | |
| 63 | − | |
| @@ -0,0 +1,17 @@ | ||
| 1 | +UDA1334 audio CODEC | |
| 2 | + | |
| 3 | +This device uses simple GPIO pins for controlling codec settings. | |
| 4 | + | |
| 5 | +Required properties: | |
| 6 | + | |
| 7 | + - compatible : "nxp,uda1334" | |
| 8 | + - nxp,mute-gpios: a GPIO spec for the MUTE pin. | |
| 9 | + - nxp,deemph-gpios: a GPIO spec for the De-emphasis pin | |
| 10 | + | |
| 11 | +Example: | |
| 12 | + | |
| 13 | +uda1334: audio-codec { | |
| 14 | + compatible = "nxp,uda1334"; | |
| 15 | + nxp,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; | |
| 16 | + nxp,deemph-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>; | |
| 17 | +}; | |
| @@ -253,24 +253,6 @@ struct hdac_ext_bus_ops { · 252 unmodified lines | ||
| 253 | 253 | int (*hdev_detach)(struct hdac_device *hdev); |
| 254 | 254 | }; |
| 255 | 255 | |
| 256 | −/* | |
| 257 | − * Lowlevel I/O operators | |
| 258 | − */ | |
| 259 | −struct hdac_io_ops { | |
| 260 | − /* mapped register accesses */ | |
| 261 | − void (*reg_writel)(u32 value, u32 __iomem *addr); | |
| 262 | − u32 (*reg_readl)(u32 __iomem *addr); | |
| 263 | − void (*reg_writew)(u16 value, u16 __iomem *addr); | |
| 264 | − u16 (*reg_readw)(u16 __iomem *addr); | |
| 265 | − void (*reg_writeb)(u8 value, u8 __iomem *addr); | |
| 266 | − u8 (*reg_readb)(u8 __iomem *addr); | |
| 267 | − /* Allocation ops */ | |
| 268 | − int (*dma_alloc_pages)(struct hdac_bus *bus, int type, size_t size, | |
| 269 | − struct snd_dma_buffer *buf); | |
| 270 | − void (*dma_free_pages)(struct hdac_bus *bus, | |
| 271 | − struct snd_dma_buffer *buf); | |
| 272 | −}; | |
| 273 | − | |
| 274 | 256 | #define HDA_UNSOL_QUEUE_SIZE 64 |
| 275 | 257 | #define HDA_MAX_CODECS 8 /* limit by controller side */ |
| 276 | 258 | |
| @@ -304,7 +286,6 @@ struct hdac_rb { · 27 unmodified lines | ||
| 304 | 286 | struct hdac_bus { |
| 305 | 287 | struct device *dev; |
| 306 | 288 | const struct hdac_bus_ops *ops; |
| 307 | − const struct hdac_io_ops *io_ops; | |
| 308 | 289 | const struct hdac_ext_bus_ops *ext_ops; |
| 309 | 290 | |
| 310 | 291 | /* h/w resources */ |
| @@ -344,6 +325,7 @@ struct hdac_bus { · 33 unmodified lines | ||
| 344 | 325 | /* CORB/RIRB and position buffers */ |
| 345 | 326 | struct snd_dma_buffer rb; |
| 346 | 327 | struct snd_dma_buffer posbuf; |
| 328 | + int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */ | |
| 347 | 329 | |
| 348 | 330 | /* hdac_stream linked list */ |
| 349 | 331 | struct list_head stream_list; |
| @@ -384,8 +366,7 @@ struct hdac_bus { · 34 unmodified lines | ||
| 384 | 366 | }; |
| 385 | 367 | |
| 386 | 368 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, |
| 387 | − const struct hdac_bus_ops *ops, | |
| 388 | − const struct hdac_io_ops *io_ops); | |
| 369 | + const struct hdac_bus_ops *ops); | |
| 389 | 370 | void snd_hdac_bus_exit(struct hdac_bus *bus); |
| 390 | 371 | int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, |
| 391 | 372 | unsigned int cmd, unsigned int *res); |
| @@ -429,21 +410,38 @@ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, · 37 unmodified lines | ||
| 429 | 410 | int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus); |
| 430 | 411 | void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus); |
| 431 | 412 | |
| 413 | +#ifdef CONFIG_SND_HDA_ALIGNED_MMIO | |
| 414 | +unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask); | |
| 415 | +void snd_hdac_aligned_write(unsigned int val, void __iomem *addr, | |
| 416 | + unsigned int mask); | |
| 417 | +#define snd_hdac_reg_writeb(v, addr) snd_hdac_aligned_write(v, addr, 0xff) | |
| 418 | +#define snd_hdac_reg_writew(v, addr) snd_hdac_aligned_write(v, addr, 0xffff) | |
| 419 | +#define snd_hdac_reg_readb(addr) snd_hdac_aligned_read(addr, 0xff) | |
| 420 | +#define snd_hdac_reg_readw(addr) snd_hdac_aligned_read(addr, 0xffff) | |
| 421 | +#else /* CONFIG_SND_HDA_ALIGNED_MMIO */ | |
| 422 | +#define snd_hdac_reg_writeb(val, addr) writeb(val, addr) | |
| 423 | +#define snd_hdac_reg_writew(val, addr) writew(val, addr) | |
| 424 | +#define snd_hdac_reg_readb(addr) readb(addr) | |
| 425 | +#define snd_hdac_reg_readw(addr) readw(addr) | |
| 426 | +#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */ | |
| 427 | +#define snd_hdac_reg_writel(val, addr) writel(val, addr) | |
| 428 | +#define snd_hdac_reg_readl(addr) readl(addr) | |
| 429 | + | |
| 432 | 430 | /* |
| 433 | 431 | * macros for easy use |
| 434 | 432 | */ |
| 435 | 433 | #define _snd_hdac_chip_writeb(chip, reg, value) \ |
| 436 | − ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg))) | |
| 434 | + snd_hdac_reg_writeb(value, (chip)->remap_addr + (reg)) | |
| 437 | 435 | #define _snd_hdac_chip_readb(chip, reg) \ |
| 438 | − ((chip)->io_ops->reg_readb((chip)->remap_addr + (reg))) | |
| 436 | + snd_hdac_reg_readb((chip)->remap_addr + (reg)) | |
| 439 | 437 | #define _snd_hdac_chip_writew(chip, reg, value) \ |
| 440 | − ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + (reg))) | |
| 438 | + snd_hdac_reg_writew(value, (chip)->remap_addr + (reg)) | |
| 441 | 439 | #define _snd_hdac_chip_readw(chip, reg) \ |
| 442 | − ((chip)->io_ops->reg_readw((chip)->remap_addr + (reg))) | |
| 440 | + snd_hdac_reg_readw((chip)->remap_addr + (reg)) | |
| 443 | 441 | #define _snd_hdac_chip_writel(chip, reg, value) \ |
| 444 | − ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + (reg))) | |
| 442 | + snd_hdac_reg_writel(value, (chip)->remap_addr + (reg)) | |
| 445 | 443 | #define _snd_hdac_chip_readl(chip, reg) \ |
| 446 | − ((chip)->io_ops->reg_readl((chip)->remap_addr + (reg))) | |
| 444 | + snd_hdac_reg_readl((chip)->remap_addr + (reg)) | |
| 447 | 445 | |
| 448 | 446 | /* read/write a register, pass without AZX_REG_ prefix */ |
| 449 | 447 | #define snd_hdac_chip_writel(chip, reg, value) \ |
| @@ -548,24 +546,19 @@ int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus, · 98 unmodified lines | ||
| 548 | 546 | /* |
| 549 | 547 | * macros for easy use |
| 550 | 548 | */ |
| 551 | −#define _snd_hdac_stream_write(type, dev, reg, value) \ | |
| 552 | − ((dev)->bus->io_ops->reg_write ## type(value, (dev)->sd_addr + (reg))) | |
| 553 | −#define _snd_hdac_stream_read(type, dev, reg) \ | |
| 554 | − ((dev)->bus->io_ops->reg_read ## type((dev)->sd_addr + (reg))) | |
| 555 | − | |
| 556 | 549 | /* read/write a register, pass without AZX_REG_ prefix */ |
| 557 | 550 | #define snd_hdac_stream_writel(dev, reg, value) \ |
| 558 | − _snd_hdac_stream_write(l, dev, AZX_REG_ ## reg, value) | |
| 551 | + snd_hdac_reg_writel(value, (dev)->sd_addr + AZX_REG_ ## reg) | |
| 559 | 552 | #define snd_hdac_stream_writew(dev, reg, value) \ |
| 560 | − _snd_hdac_stream_write(w, dev, AZX_REG_ ## reg, value) | |
| 553 | + snd_hdac_reg_writew(value, (dev)->sd_addr + AZX_REG_ ## reg) | |
| 561 | 554 | #define snd_hdac_stream_writeb(dev, reg, value) \ |
| 562 | − _snd_hdac_stream_write(b, dev, AZX_REG_ ## reg, value) | |
| 555 | + snd_hdac_reg_writeb(value, (dev)->sd_addr + AZX_REG_ ## reg) | |
| 563 | 556 | #define snd_hdac_stream_readl(dev, reg) \ |
| 564 | − _snd_hdac_stream_read(l, dev, AZX_REG_ ## reg) | |
| 557 | + snd_hdac_reg_readl((dev)->sd_addr + AZX_REG_ ## reg) | |
| 565 | 558 | #define snd_hdac_stream_readw(dev, reg) \ |
| 566 | − _snd_hdac_stream_read(w, dev, AZX_REG_ ## reg) | |
| 559 | + snd_hdac_reg_readw((dev)->sd_addr + AZX_REG_ ## reg) | |
| 567 | 560 | #define snd_hdac_stream_readb(dev, reg) \ |
| 568 | − _snd_hdac_stream_read(b, dev, AZX_REG_ ## reg) | |
| 561 | + snd_hdac_reg_readb((dev)->sd_addr + AZX_REG_ ## reg) | |
| 569 | 562 | |
| 570 | 563 | /* update a register, pass without AZX_REG_ prefix */ |
| 571 | 564 | #define snd_hdac_stream_updatel(dev, reg, mask, val) \ |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, |
| 8 | 8 | const struct hdac_bus_ops *ops, |
| 9 | − const struct hdac_io_ops *io_ops, | |
| 10 | 9 | const struct hdac_ext_bus_ops *ext_ops); |
| 11 | 10 | |
| 12 | 11 | void snd_hdac_ext_bus_exit(struct hdac_bus *bus); |
| @@ -47,6 +47,9 @@ struct hdmi_codec_params { · 46 unmodified lines | ||
| 47 | 47 | int channels; |
| 48 | 48 | }; |
| 49 | 49 | |
| 50 | +typedef void (*hdmi_codec_plugged_cb)(struct device *dev, | |
| 51 | + bool plugged); | |
| 52 | + | |
| 50 | 53 | struct hdmi_codec_pdata; |
| 51 | 54 | struct hdmi_codec_ops { |
| 52 | 55 | /* |
| @@ -88,6 +91,14 @@ struct hdmi_codec_ops { · 35 unmodified lines | ||
| 88 | 91 | */ |
| 89 | 92 | int (*get_dai_id)(struct snd_soc_component *comment, |
| 90 | 93 | struct device_node *endpoint); |
| 94 | + | |
| 95 | + /* | |
| 96 | + * Hook callback function to handle connector plug event. | |
| 97 | + * Optional | |
| 98 | + */ | |
| 99 | + int (*hook_plugged_cb)(struct device *dev, void *data, | |
| 100 | + hdmi_codec_plugged_cb fn, | |
| 101 | + struct device *codec_dev); | |
| 91 | 102 | }; |
| 92 | 103 | |
| 93 | 104 | /* HDMI codec initalization data */ |
| @@ -99,6 +110,12 @@ struct hdmi_codec_pdata { · 5 unmodified lines | ||
| 99 | 110 | void *data; |
| 100 | 111 | }; |
| 101 | 112 | |
| 113 | +struct snd_soc_component; | |
| 114 | +struct snd_soc_jack; | |
| 115 | + | |
| 116 | +int hdmi_codec_set_jack_detect(struct snd_soc_component *component, | |
| 117 | + struct snd_soc_jack *jack); | |
| 118 | + | |
| 102 | 119 | #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" |
| 103 | 120 | |
| 104 | 121 | #endif /* __HDMI_CODEC_H__ */ |
| @@ -1,18 +1,17 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | 2 | /* |
| 3 | − * skl-nhlt.h - Intel HDA Platform NHLT header | |
| 3 | + * intel-nhlt.h - Intel HDA Platform NHLT header | |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2015 Intel Corp | |
| 6 | − * Author: Sanjiv Kumar <sanjiv.kumar@intel.com> | |
| 7 | − * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 8 | − * | |
| 9 | − * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 5 | + * Copyright (c) 2015-2019 Intel Corporation | |
| 10 | 6 | */ |
| 11 | −#ifndef __SKL_NHLT_H__ | |
| 12 | −#define __SKL_NHLT_H__ | |
| 7 | + | |
| 8 | +#ifndef __INTEL_NHLT_H__ | |
| 9 | +#define __INTEL_NHLT_H__ | |
| 13 | 10 | |
| 14 | 11 | #include <linux/acpi.h> |
| 15 | 12 | |
| 13 | +#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT) | |
| 14 | + | |
| 16 | 15 | struct wav_fmt { |
| 17 | 16 | u16 fmt_tag; |
| 18 | 17 | u16 channels; |
| @@ -97,16 +96,22 @@ struct nhlt_resource_desc { · 78 unmodified lines | ||
| 97 | 96 | #define MIC_ARRAY_2CH 2 |
| 98 | 97 | #define MIC_ARRAY_4CH 4 |
| 99 | 98 | |
| 100 | −struct nhlt_tdm_config { | |
| 99 | +struct nhlt_device_specific_config { | |
| 101 | 100 | u8 virtual_slot; |
| 102 | 101 | u8 config_type; |
| 103 | 102 | } __packed; |
| 104 | 103 | |
| 105 | 104 | struct nhlt_dmic_array_config { |
| 106 | − struct nhlt_tdm_config tdm_config; | |
| 105 | + struct nhlt_device_specific_config device_config; | |
| 107 | 106 | u8 array_type; |
| 108 | 107 | } __packed; |
| 109 | 108 | |
| 109 | +struct nhlt_vendor_dmic_array_config { | |
| 110 | + struct nhlt_dmic_array_config dmic_config; | |
| 111 | + u8 nb_mics; | |
| 112 | + /* TODO add vendor mic config */ | |
| 113 | +} __packed; | |
| 114 | + | |
| 110 | 115 | enum { |
| 111 | 116 | NHLT_MIC_ARRAY_2CH_SMALL = 0xa, |
| 112 | 117 | NHLT_MIC_ARRAY_2CH_BIG = 0xb, |
| @@ -116,4 +121,30 @@ enum { · 3 unmodified lines | ||
| 116 | 121 | NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf, |
| 117 | 122 | }; |
| 118 | 123 | |
| 124 | +struct nhlt_acpi_table *intel_nhlt_init(struct device *dev); | |
| 125 | + | |
| 126 | +void intel_nhlt_free(struct nhlt_acpi_table *addr); | |
| 127 | + | |
| 128 | +int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt); | |
| 129 | + | |
| 130 | +#else | |
| 131 | + | |
| 132 | +struct nhlt_acpi_table; | |
| 133 | + | |
| 134 | +static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev) | |
| 135 | +{ | |
| 136 | + return NULL; | |
| 137 | +} | |
| 138 | + | |
| 139 | +static inline void intel_nhlt_free(struct nhlt_acpi_table *addr) | |
| 140 | +{ | |
| 141 | +} | |
| 142 | + | |
| 143 | +static inline int intel_nhlt_get_dmic_geo(struct device *dev, | |
| 144 | + struct nhlt_acpi_table *nhlt) | |
| 145 | +{ | |
| 146 | + return 0; | |
| 147 | +} | |
| 148 | +#endif | |
| 149 | + | |
| 119 | 150 | #endif |
| @@ -117,6 +117,8 @@ struct snd_pcm_ops { · 116 unmodified lines | ||
| 117 | 117 | #define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ |
| 118 | 118 | #define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ |
| 119 | 119 | #define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */ |
| 120 | +#define SNDRV_PCM_RATE_352800 (1<<13) /* 352800Hz */ | |
| 121 | +#define SNDRV_PCM_RATE_384000 (1<<14) /* 384000Hz */ | |
| 120 | 122 | |
| 121 | 123 | #define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ |
| 122 | 124 | #define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ |
| @@ -129,6 +131,9 @@ struct snd_pcm_ops { · 6 unmodified lines | ||
| 129 | 131 | SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000) |
| 130 | 132 | #define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\ |
| 131 | 133 | SNDRV_PCM_RATE_192000) |
| 134 | +#define SNDRV_PCM_RATE_8000_384000 (SNDRV_PCM_RATE_8000_192000|\ | |
| 135 | + SNDRV_PCM_RATE_352800|\ | |
| 136 | + SNDRV_PCM_RATE_384000) | |
| 132 | 137 | #define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt) |
| 133 | 138 | #define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8) |
| 134 | 139 | #define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8) |
| @@ -25,6 +25,8 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[]; · 24 unmodified lines | ||
| 25 | 25 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[]; |
| 26 | 26 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[]; |
| 27 | 27 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[]; |
| 28 | +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[]; | |
| 29 | +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[]; | |
| 28 | 30 | |
| 29 | 31 | /* |
| 30 | 32 | * generic table used for HDA codec-based platforms, possibly with |
| @@ -0,0 +1,387 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | + * | |
| 3 | + * soc-component.h | |
| 4 | + * | |
| 5 | + * Copyright (c) 2019 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License version 2 as | |
| 9 | + * published by the Free Software Foundation. | |
| 10 | + */ | |
| 11 | +#ifndef __SOC_COMPONENT_H | |
| 12 | +#define __SOC_COMPONENT_H | |
| 13 | + | |
| 14 | +#include <sound/soc.h> | |
| 15 | + | |
| 16 | +/* | |
| 17 | + * Component probe and remove ordering levels for components with runtime | |
| 18 | + * dependencies. | |
| 19 | + */ | |
| 20 | +#define SND_SOC_COMP_ORDER_FIRST -2 | |
| 21 | +#define SND_SOC_COMP_ORDER_EARLY -1 | |
| 22 | +#define SND_SOC_COMP_ORDER_NORMAL 0 | |
| 23 | +#define SND_SOC_COMP_ORDER_LATE 1 | |
| 24 | +#define SND_SOC_COMP_ORDER_LAST 2 | |
| 25 | + | |
| 26 | +#define for_each_comp_order(order) \ | |
| 27 | + for (order = SND_SOC_COMP_ORDER_FIRST; \ | |
| 28 | + order <= SND_SOC_COMP_ORDER_LAST; \ | |
| 29 | + order++) | |
| 30 | + | |
| 31 | +/* component interface */ | |
| 32 | +struct snd_soc_component_driver { | |
| 33 | + const char *name; | |
| 34 | + | |
| 35 | + /* Default control and setup, added after probe() is run */ | |
| 36 | + const struct snd_kcontrol_new *controls; | |
| 37 | + unsigned int num_controls; | |
| 38 | + const struct snd_soc_dapm_widget *dapm_widgets; | |
| 39 | + unsigned int num_dapm_widgets; | |
| 40 | + const struct snd_soc_dapm_route *dapm_routes; | |
| 41 | + unsigned int num_dapm_routes; | |
| 42 | + | |
| 43 | + int (*probe)(struct snd_soc_component *component); | |
| 44 | + void (*remove)(struct snd_soc_component *component); | |
| 45 | + int (*suspend)(struct snd_soc_component *component); | |
| 46 | + int (*resume)(struct snd_soc_component *component); | |
| 47 | + | |
| 48 | + unsigned int (*read)(struct snd_soc_component *component, | |
| 49 | + unsigned int reg); | |
| 50 | + int (*write)(struct snd_soc_component *component, | |
| 51 | + unsigned int reg, unsigned int val); | |
| 52 | + | |
| 53 | + /* pcm creation and destruction */ | |
| 54 | + int (*pcm_new)(struct snd_soc_pcm_runtime *rtd); | |
| 55 | + void (*pcm_free)(struct snd_pcm *pcm); | |
| 56 | + | |
| 57 | + /* component wide operations */ | |
| 58 | + int (*set_sysclk)(struct snd_soc_component *component, | |
| 59 | + int clk_id, int source, unsigned int freq, int dir); | |
| 60 | + int (*set_pll)(struct snd_soc_component *component, int pll_id, | |
| 61 | + int source, unsigned int freq_in, unsigned int freq_out); | |
| 62 | + int (*set_jack)(struct snd_soc_component *component, | |
| 63 | + struct snd_soc_jack *jack, void *data); | |
| 64 | + | |
| 65 | + /* DT */ | |
| 66 | + int (*of_xlate_dai_name)(struct snd_soc_component *component, | |
| 67 | + struct of_phandle_args *args, | |
| 68 | + const char **dai_name); | |
| 69 | + int (*of_xlate_dai_id)(struct snd_soc_component *comment, | |
| 70 | + struct device_node *endpoint); | |
| 71 | + void (*seq_notifier)(struct snd_soc_component *component, | |
| 72 | + enum snd_soc_dapm_type type, int subseq); | |
| 73 | + int (*stream_event)(struct snd_soc_component *component, int event); | |
| 74 | + int (*set_bias_level)(struct snd_soc_component *component, | |
| 75 | + enum snd_soc_bias_level level); | |
| 76 | + | |
| 77 | + const struct snd_pcm_ops *ops; | |
| 78 | + const struct snd_compr_ops *compr_ops; | |
| 79 | + | |
| 80 | + /* probe ordering - for components with runtime dependencies */ | |
| 81 | + int probe_order; | |
| 82 | + int remove_order; | |
| 83 | + | |
| 84 | + /* | |
| 85 | + * signal if the module handling the component should not be removed | |
| 86 | + * if a pcm is open. Setting this would prevent the module | |
| 87 | + * refcount being incremented in probe() but allow it be incremented | |
| 88 | + * when a pcm is opened and decremented when it is closed. | |
| 89 | + */ | |
| 90 | + unsigned int module_get_upon_open:1; | |
| 91 | + | |
| 92 | + /* bits */ | |
| 93 | + unsigned int idle_bias_on:1; | |
| 94 | + unsigned int suspend_bias_off:1; | |
| 95 | + unsigned int use_pmdown_time:1; /* care pmdown_time at stop */ | |
| 96 | + unsigned int endianness:1; | |
| 97 | + unsigned int non_legacy_dai_naming:1; | |
| 98 | + | |
| 99 | + /* this component uses topology and ignore machine driver FEs */ | |
| 100 | + const char *ignore_machine; | |
| 101 | + const char *topology_name_prefix; | |
| 102 | + int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | |
| 103 | + struct snd_pcm_hw_params *params); | |
| 104 | + bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */ | |
| 105 | + int be_pcm_base; /* base device ID for all BE PCMs */ | |
| 106 | +}; | |
| 107 | + | |
| 108 | +struct snd_soc_component { | |
| 109 | + const char *name; | |
| 110 | + int id; | |
| 111 | + const char *name_prefix; | |
| 112 | + struct device *dev; | |
| 113 | + struct snd_soc_card *card; | |
| 114 | + | |
| 115 | + unsigned int active; | |
| 116 | + | |
| 117 | + unsigned int suspended:1; /* is in suspend PM state */ | |
| 118 | + | |
| 119 | + struct list_head list; | |
| 120 | + struct list_head card_aux_list; /* for auxiliary bound components */ | |
| 121 | + struct list_head card_list; | |
| 122 | + | |
| 123 | + const struct snd_soc_component_driver *driver; | |
| 124 | + | |
| 125 | + struct list_head dai_list; | |
| 126 | + int num_dai; | |
| 127 | + | |
| 128 | + struct regmap *regmap; | |
| 129 | + int val_bytes; | |
| 130 | + | |
| 131 | + struct mutex io_mutex; | |
| 132 | + | |
| 133 | + /* attached dynamic objects */ | |
| 134 | + struct list_head dobj_list; | |
| 135 | + | |
| 136 | + /* | |
| 137 | + * DO NOT use any of the fields below in drivers, they are temporary and | |
| 138 | + * are going to be removed again soon. If you use them in driver code | |
| 139 | + * the driver will be marked as BROKEN when these fields are removed. | |
| 140 | + */ | |
| 141 | + | |
| 142 | + /* Don't use these, use snd_soc_component_get_dapm() */ | |
| 143 | + struct snd_soc_dapm_context dapm; | |
| 144 | + | |
| 145 | + /* machine specific init */ | |
| 146 | + int (*init)(struct snd_soc_component *component); | |
| 147 | + | |
| 148 | +#ifdef CONFIG_DEBUG_FS | |
| 149 | + struct dentry *debugfs_root; | |
| 150 | + const char *debugfs_prefix; | |
| 151 | +#endif | |
| 152 | +}; | |
| 153 | + | |
| 154 | +#define for_each_component_dais(component, dai)\ | |
| 155 | + list_for_each_entry(dai, &(component)->dai_list, list) | |
| 156 | +#define for_each_component_dais_safe(component, dai, _dai)\ | |
| 157 | + list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list) | |
| 158 | + | |
| 159 | +/** | |
| 160 | + * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is | |
| 161 | + * embedded in | |
| 162 | + * @dapm: The DAPM context to cast to the component | |
| 163 | + * | |
| 164 | + * This function must only be used on DAPM contexts that are known to be part of | |
| 165 | + * a component (e.g. in a component driver). Otherwise the behavior is | |
| 166 | + * undefined. | |
| 167 | + */ | |
| 168 | +static inline struct snd_soc_component *snd_soc_dapm_to_component( | |
| 169 | + struct snd_soc_dapm_context *dapm) | |
| 170 | +{ | |
| 171 | + return container_of(dapm, struct snd_soc_component, dapm); | |
| 172 | +} | |
| 173 | + | |
| 174 | +/** | |
| 175 | + * snd_soc_component_get_dapm() - Returns the DAPM context associated with a | |
| 176 | + * component | |
| 177 | + * @component: The component for which to get the DAPM context | |
| 178 | + */ | |
| 179 | +static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm( | |
| 180 | + struct snd_soc_component *component) | |
| 181 | +{ | |
| 182 | + return &component->dapm; | |
| 183 | +} | |
| 184 | + | |
| 185 | +/** | |
| 186 | + * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level | |
| 187 | + * @component: The COMPONENT for which to initialize the DAPM bias level | |
| 188 | + * @level: The DAPM level to initialize to | |
| 189 | + * | |
| 190 | + * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level() | |
| 191 | + */ | |
| 192 | +static inline void | |
| 193 | +snd_soc_component_init_bias_level(struct snd_soc_component *component, | |
| 194 | + enum snd_soc_bias_level level) | |
| 195 | +{ | |
| 196 | + snd_soc_dapm_init_bias_level( | |
| 197 | + snd_soc_component_get_dapm(component), level); | |
| 198 | +} | |
| 199 | + | |
| 200 | +/** | |
| 201 | + * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level | |
| 202 | + * @component: The COMPONENT for which to get the DAPM bias level | |
| 203 | + * | |
| 204 | + * Returns: The current DAPM bias level of the COMPONENT. | |
| 205 | + */ | |
| 206 | +static inline enum snd_soc_bias_level | |
| 207 | +snd_soc_component_get_bias_level(struct snd_soc_component *component) | |
| 208 | +{ | |
| 209 | + return snd_soc_dapm_get_bias_level( | |
| 210 | + snd_soc_component_get_dapm(component)); | |
| 211 | +} | |
| 212 | + | |
| 213 | +/** | |
| 214 | + * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level | |
| 215 | + * @component: The COMPONENT for which to set the level | |
| 216 | + * @level: The level to set to | |
| 217 | + * | |
| 218 | + * Forces the COMPONENT bias level to a specific state. See | |
| 219 | + * snd_soc_dapm_force_bias_level(). | |
| 220 | + */ | |
| 221 | +static inline int | |
| 222 | +snd_soc_component_force_bias_level(struct snd_soc_component *component, | |
| 223 | + enum snd_soc_bias_level level) | |
| 224 | +{ | |
| 225 | + return snd_soc_dapm_force_bias_level( | |
| 226 | + snd_soc_component_get_dapm(component), | |
| 227 | + level); | |
| 228 | +} | |
| 229 | + | |
| 230 | +/** | |
| 231 | + * snd_soc_dapm_kcontrol_component() - Returns the component associated to a | |
| 232 | + * kcontrol | |
| 233 | + * @kcontrol: The kcontrol | |
| 234 | + * | |
| 235 | + * This function must only be used on DAPM contexts that are known to be part of | |
| 236 | + * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined | |
| 237 | + */ | |
| 238 | +static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component( | |
| 239 | + struct snd_kcontrol *kcontrol) | |
| 240 | +{ | |
| 241 | + return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol)); | |
| 242 | +} | |
| 243 | + | |
| 244 | +/** | |
| 245 | + * snd_soc_component_cache_sync() - Sync the register cache with the hardware | |
| 246 | + * @component: COMPONENT to sync | |
| 247 | + * | |
| 248 | + * Note: This function will call regcache_sync() | |
| 249 | + */ | |
| 250 | +static inline int snd_soc_component_cache_sync( | |
| 251 | + struct snd_soc_component *component) | |
| 252 | +{ | |
| 253 | + return regcache_sync(component->regmap); | |
| 254 | +} | |
| 255 | + | |
| 256 | +/* component IO */ | |
| 257 | +int snd_soc_component_read(struct snd_soc_component *component, | |
| 258 | + unsigned int reg, unsigned int *val); | |
| 259 | +unsigned int snd_soc_component_read32(struct snd_soc_component *component, | |
| 260 | + unsigned int reg); | |
| 261 | +int snd_soc_component_write(struct snd_soc_component *component, | |
| 262 | + unsigned int reg, unsigned int val); | |
| 263 | +int snd_soc_component_update_bits(struct snd_soc_component *component, | |
| 264 | + unsigned int reg, unsigned int mask, | |
| 265 | + unsigned int val); | |
| 266 | +int snd_soc_component_update_bits_async(struct snd_soc_component *component, | |
| 267 | + unsigned int reg, unsigned int mask, | |
| 268 | + unsigned int val); | |
| 269 | +void snd_soc_component_async_complete(struct snd_soc_component *component); | |
| 270 | +int snd_soc_component_test_bits(struct snd_soc_component *component, | |
| 271 | + unsigned int reg, unsigned int mask, | |
| 272 | + unsigned int value); | |
| 273 | + | |
| 274 | +/* component wide operations */ | |
| 275 | +int snd_soc_component_set_sysclk(struct snd_soc_component *component, | |
| 276 | + int clk_id, int source, | |
| 277 | + unsigned int freq, int dir); | |
| 278 | +int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, | |
| 279 | + int source, unsigned int freq_in, | |
| 280 | + unsigned int freq_out); | |
| 281 | +int snd_soc_component_set_jack(struct snd_soc_component *component, | |
| 282 | + struct snd_soc_jack *jack, void *data); | |
| 283 | + | |
| 284 | +void snd_soc_component_seq_notifier(struct snd_soc_component *component, | |
| 285 | + enum snd_soc_dapm_type type, int subseq); | |
| 286 | +int snd_soc_component_stream_event(struct snd_soc_component *component, | |
| 287 | + int event); | |
| 288 | +int snd_soc_component_set_bias_level(struct snd_soc_component *component, | |
| 289 | + enum snd_soc_bias_level level); | |
| 290 | + | |
| 291 | +#ifdef CONFIG_REGMAP | |
| 292 | +void snd_soc_component_init_regmap(struct snd_soc_component *component, | |
| 293 | + struct regmap *regmap); | |
| 294 | +void snd_soc_component_exit_regmap(struct snd_soc_component *component); | |
| 295 | +#endif | |
| 296 | + | |
| 297 | +#define snd_soc_component_module_get_when_probe(component)\ | |
| 298 | + snd_soc_component_module_get(component, 0) | |
| 299 | +#define snd_soc_component_module_get_when_open(component) \ | |
| 300 | + snd_soc_component_module_get(component, 1) | |
| 301 | +int snd_soc_component_module_get(struct snd_soc_component *component, | |
| 302 | + int upon_open); | |
| 303 | +#define snd_soc_component_module_put_when_remove(component) \ | |
| 304 | + snd_soc_component_module_put(component, 0) | |
| 305 | +#define snd_soc_component_module_put_when_close(component) \ | |
| 306 | + snd_soc_component_module_put(component, 1) | |
| 307 | +void snd_soc_component_module_put(struct snd_soc_component *component, | |
| 308 | + int upon_open); | |
| 309 | + | |
| 310 | +static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c, | |
| 311 | + void *data) | |
| 312 | +{ | |
| 313 | + dev_set_drvdata(c->dev, data); | |
| 314 | +} | |
| 315 | + | |
| 316 | +static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c) | |
| 317 | +{ | |
| 318 | + return dev_get_drvdata(c->dev); | |
| 319 | +} | |
| 320 | + | |
| 321 | +static inline bool snd_soc_component_is_active( | |
| 322 | + struct snd_soc_component *component) | |
| 323 | +{ | |
| 324 | + return component->active != 0; | |
| 325 | +} | |
| 326 | + | |
| 327 | +/* component pin */ | |
| 328 | +int snd_soc_component_enable_pin(struct snd_soc_component *component, | |
| 329 | + const char *pin); | |
| 330 | +int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, | |
| 331 | + const char *pin); | |
| 332 | +int snd_soc_component_disable_pin(struct snd_soc_component *component, | |
| 333 | + const char *pin); | |
| 334 | +int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, | |
| 335 | + const char *pin); | |
| 336 | +int snd_soc_component_nc_pin(struct snd_soc_component *component, | |
| 337 | + const char *pin); | |
| 338 | +int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, | |
| 339 | + const char *pin); | |
| 340 | +int snd_soc_component_get_pin_status(struct snd_soc_component *component, | |
| 341 | + const char *pin); | |
| 342 | +int snd_soc_component_force_enable_pin(struct snd_soc_component *component, | |
| 343 | + const char *pin); | |
| 344 | +int snd_soc_component_force_enable_pin_unlocked( | |
| 345 | + struct snd_soc_component *component, | |
| 346 | + const char *pin); | |
| 347 | + | |
| 348 | +/* component driver ops */ | |
| 349 | +int snd_soc_component_open(struct snd_soc_component *component, | |
| 350 | + struct snd_pcm_substream *substream); | |
| 351 | +int snd_soc_component_close(struct snd_soc_component *component, | |
| 352 | + struct snd_pcm_substream *substream); | |
| 353 | +int snd_soc_component_prepare(struct snd_soc_component *component, | |
| 354 | + struct snd_pcm_substream *substream); | |
| 355 | +int snd_soc_component_hw_params(struct snd_soc_component *component, | |
| 356 | + struct snd_pcm_substream *substream, | |
| 357 | + struct snd_pcm_hw_params *params); | |
| 358 | +int snd_soc_component_hw_free(struct snd_soc_component *component, | |
| 359 | + struct snd_pcm_substream *substream); | |
| 360 | +int snd_soc_component_trigger(struct snd_soc_component *component, | |
| 361 | + struct snd_pcm_substream *substream, | |
| 362 | + int cmd); | |
| 363 | +void snd_soc_component_suspend(struct snd_soc_component *component); | |
| 364 | +void snd_soc_component_resume(struct snd_soc_component *component); | |
| 365 | +int snd_soc_component_is_suspended(struct snd_soc_component *component); | |
| 366 | +int snd_soc_component_probe(struct snd_soc_component *component); | |
| 367 | +void snd_soc_component_remove(struct snd_soc_component *component); | |
| 368 | +int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component, | |
| 369 | + struct device_node *ep); | |
| 370 | +int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component, | |
| 371 | + struct of_phandle_args *args, | |
| 372 | + const char **dai_name); | |
| 373 | + | |
| 374 | +int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream); | |
| 375 | +int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, | |
| 376 | + unsigned int cmd, void *arg); | |
| 377 | +int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream, | |
| 378 | + int channel, unsigned long pos, | |
| 379 | + void __user *buf, unsigned long bytes); | |
| 380 | +struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream, | |
| 381 | + unsigned long offset); | |
| 382 | +int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream, | |
| 383 | + struct vm_area_struct *vma); | |
| 384 | +int snd_soc_pcm_component_new(struct snd_pcm *pcm); | |
| 385 | +void snd_soc_pcm_component_free(struct snd_pcm *pcm); | |
| 386 | + | |
| 387 | +#endif /* __SOC_COMPONENT_H */ | |
| @@ -145,6 +145,31 @@ int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai, · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | int snd_soc_dai_is_dummy(struct snd_soc_dai *dai); |
| 147 | 147 | |
| 148 | +int snd_soc_dai_hw_params(struct snd_soc_dai *dai, | |
| 149 | + struct snd_pcm_substream *substream, | |
| 150 | + struct snd_pcm_hw_params *params); | |
| 151 | +void snd_soc_dai_hw_free(struct snd_soc_dai *dai, | |
| 152 | + struct snd_pcm_substream *substream); | |
| 153 | +int snd_soc_dai_startup(struct snd_soc_dai *dai, | |
| 154 | + struct snd_pcm_substream *substream); | |
| 155 | +void snd_soc_dai_shutdown(struct snd_soc_dai *dai, | |
| 156 | + struct snd_pcm_substream *substream); | |
| 157 | +int snd_soc_dai_prepare(struct snd_soc_dai *dai, | |
| 158 | + struct snd_pcm_substream *substream); | |
| 159 | +int snd_soc_dai_trigger(struct snd_soc_dai *dai, | |
| 160 | + struct snd_pcm_substream *substream, int cmd); | |
| 161 | +int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai, | |
| 162 | + struct snd_pcm_substream *substream, int cmd); | |
| 163 | +snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai, | |
| 164 | + struct snd_pcm_substream *substream); | |
| 165 | +void snd_soc_dai_suspend(struct snd_soc_dai *dai); | |
| 166 | +void snd_soc_dai_resume(struct snd_soc_dai *dai); | |
| 167 | +int snd_soc_dai_probe(struct snd_soc_dai *dai); | |
| 168 | +int snd_soc_dai_remove(struct snd_soc_dai *dai); | |
| 169 | +int snd_soc_dai_compress_new(struct snd_soc_dai *dai, | |
| 170 | + struct snd_soc_pcm_runtime *rtd, int num); | |
| 171 | +bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream); | |
| 172 | + | |
| 148 | 173 | struct snd_soc_dai_ops { |
| 149 | 174 | /* |
| 150 | 175 | * DAI clocking configuration, all optional. |
| @@ -268,8 +293,6 @@ struct snd_soc_dai_driver { · 117 unmodified lines | ||
| 268 | 293 | /* Optional Callback used at pcm creation*/ |
| 269 | 294 | int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, |
| 270 | 295 | struct snd_soc_dai *dai); |
| 271 | − /* DAI is also used for the control bus */ | |
| 272 | − bool bus_control; | |
| 273 | 296 | |
| 274 | 297 | /* ops */ |
| 275 | 298 | const struct snd_soc_dai_ops *ops; |
| @@ -281,6 +304,7 @@ struct snd_soc_dai_driver { · 5 unmodified lines | ||
| 281 | 304 | unsigned int symmetric_rates:1; |
| 282 | 305 | unsigned int symmetric_channels:1; |
| 283 | 306 | unsigned int symmetric_samplebits:1; |
| 307 | + unsigned int bus_control:1; /* DAI is also used for the control bus */ | |
| 284 | 308 | |
| 285 | 309 | /* probe ordering - for components with runtime dependencies */ |
| 286 | 310 | int probe_order; |
| @@ -353,6 +353,8 @@ struct device; · 352 unmodified lines | ||
| 353 | 353 | #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ |
| 354 | 354 | #define SND_SOC_DAPM_PRE_POST_PMD \ |
| 355 | 355 | (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) |
| 356 | +#define SND_SOC_DAPM_PRE_POST_PMU \ | |
| 357 | + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU) | |
| 356 | 358 | |
| 357 | 359 | /* convenience event type detection */ |
| 358 | 360 | #define SND_SOC_DAPM_EVENT_ON(e) \ |
| @@ -417,6 +419,9 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream, · 58 unmodified lines | ||
| 417 | 419 | /* dapm path setup */ |
| 418 | 420 | int snd_soc_dapm_new_widgets(struct snd_soc_card *card); |
| 419 | 421 | void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); |
| 422 | +void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm, | |
| 423 | + struct snd_soc_card *card, | |
| 424 | + struct snd_soc_component *component); | |
| 420 | 425 | int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, |
| 421 | 426 | const struct snd_soc_dapm_route *route, int num); |
| 422 | 427 | int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, |
| @@ -662,8 +667,6 @@ struct snd_soc_dapm_context { · 239 unmodified lines | ||
| 662 | 667 | unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ |
| 663 | 668 | /* Go to BIAS_OFF in suspend if the DAPM context is idle */ |
| 664 | 669 | unsigned int suspend_bias_off:1; |
| 665 | − void (*seq_notifier)(struct snd_soc_dapm_context *, | |
| 666 | − enum snd_soc_dapm_type, int); | |
| 667 | 670 | |
| 668 | 671 | struct device *dev; /* from parent - for debug */ |
| 669 | 672 | struct snd_soc_component *component; /* parent component */ |
| @@ -673,10 +676,6 @@ struct snd_soc_dapm_context { · 3 unmodified lines | ||
| 673 | 676 | enum snd_soc_bias_level target_bias_level; |
| 674 | 677 | struct list_head list; |
| 675 | 678 | |
| 676 | − int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); | |
| 677 | − int (*set_bias_level)(struct snd_soc_dapm_context *dapm, | |
| 678 | − enum snd_soc_bias_level level); | |
| 679 | − | |
| 680 | 679 | struct snd_soc_dapm_wcache path_sink_cache; |
| 681 | 680 | struct snd_soc_dapm_wcache path_source_cache; |
| 682 | 681 | |
| @@ -142,9 +142,16 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream, · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | /* internal use only */ |
| 144 | 144 | int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); |
| 145 | −void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); | |
| 146 | 145 | int soc_dpcm_runtime_update(struct snd_soc_card *); |
| 147 | 146 | |
| 147 | +#ifdef CONFIG_DEBUG_FS | |
| 148 | +void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); | |
| 149 | +#else | |
| 150 | +static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) | |
| 151 | +{ | |
| 152 | +} | |
| 153 | +#endif | |
| 154 | + | |
| 148 | 155 | int dpcm_path_get(struct snd_soc_pcm_runtime *fe, |
| 149 | 156 | int stream, struct snd_soc_dapm_widget_list **list_); |
| 150 | 157 | int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, |
| @@ -362,21 +362,6 @@ · 361 unmodified lines | ||
| 362 | 362 | #define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \ |
| 363 | 363 | const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts) |
| 364 | 364 | |
| 365 | −/* | |
| 366 | − * Component probe and remove ordering levels for components with runtime | |
| 367 | − * dependencies. | |
| 368 | − */ | |
| 369 | −#define SND_SOC_COMP_ORDER_FIRST -2 | |
| 370 | −#define SND_SOC_COMP_ORDER_EARLY -1 | |
| 371 | −#define SND_SOC_COMP_ORDER_NORMAL 0 | |
| 372 | −#define SND_SOC_COMP_ORDER_LATE 1 | |
| 373 | −#define SND_SOC_COMP_ORDER_LAST 2 | |
| 374 | − | |
| 375 | −#define for_each_comp_order(order) \ | |
| 376 | − for (order = SND_SOC_COMP_ORDER_FIRST; \ | |
| 377 | − order <= SND_SOC_COMP_ORDER_LAST; \ | |
| 378 | − order++) | |
| 379 | − | |
| 380 | 365 | /* |
| 381 | 366 | * Bias levels |
| 382 | 367 | * |
| @@ -505,10 +490,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms); · 122 unmodified lines | ||
| 505 | 490 | int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, |
| 506 | 491 | const struct snd_pcm_hardware *hw); |
| 507 | 492 | |
| 508 | −int soc_dai_hw_params(struct snd_pcm_substream *substream, | |
| 509 | − struct snd_pcm_hw_params *params, | |
| 510 | − struct snd_soc_dai *dai); | |
| 511 | − | |
| 512 | 493 | /* Jack reporting */ |
| 513 | 494 | int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, |
| 514 | 495 | struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, |
| @@ -751,132 +732,6 @@ struct snd_soc_compr_ops { · 236 unmodified lines | ||
| 751 | 732 | int (*trigger)(struct snd_compr_stream *); |
| 752 | 733 | }; |
| 753 | 734 | |
| 754 | −/* component interface */ | |
| 755 | −struct snd_soc_component_driver { | |
| 756 | − const char *name; | |
| 757 | − | |
| 758 | − /* Default control and setup, added after probe() is run */ | |
| 759 | − const struct snd_kcontrol_new *controls; | |
| 760 | − unsigned int num_controls; | |
| 761 | − const struct snd_soc_dapm_widget *dapm_widgets; | |
| 762 | − unsigned int num_dapm_widgets; | |
| 763 | − const struct snd_soc_dapm_route *dapm_routes; | |
| 764 | − unsigned int num_dapm_routes; | |
| 765 | − | |
| 766 | − int (*probe)(struct snd_soc_component *); | |
| 767 | − void (*remove)(struct snd_soc_component *); | |
| 768 | − int (*suspend)(struct snd_soc_component *); | |
| 769 | − int (*resume)(struct snd_soc_component *); | |
| 770 | − | |
| 771 | − unsigned int (*read)(struct snd_soc_component *, unsigned int); | |
| 772 | − int (*write)(struct snd_soc_component *, unsigned int, unsigned int); | |
| 773 | − | |
| 774 | − /* pcm creation and destruction */ | |
| 775 | − int (*pcm_new)(struct snd_soc_pcm_runtime *); | |
| 776 | − void (*pcm_free)(struct snd_pcm *); | |
| 777 | − | |
| 778 | − /* component wide operations */ | |
| 779 | − int (*set_sysclk)(struct snd_soc_component *component, | |
| 780 | − int clk_id, int source, unsigned int freq, int dir); | |
| 781 | − int (*set_pll)(struct snd_soc_component *component, int pll_id, | |
| 782 | − int source, unsigned int freq_in, unsigned int freq_out); | |
| 783 | − int (*set_jack)(struct snd_soc_component *component, | |
| 784 | − struct snd_soc_jack *jack, void *data); | |
| 785 | − | |
| 786 | − /* DT */ | |
| 787 | − int (*of_xlate_dai_name)(struct snd_soc_component *component, | |
| 788 | − struct of_phandle_args *args, | |
| 789 | − const char **dai_name); | |
| 790 | − int (*of_xlate_dai_id)(struct snd_soc_component *comment, | |
| 791 | − struct device_node *endpoint); | |
| 792 | − void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type, | |
| 793 | − int subseq); | |
| 794 | − int (*stream_event)(struct snd_soc_component *, int event); | |
| 795 | − int (*set_bias_level)(struct snd_soc_component *component, | |
| 796 | − enum snd_soc_bias_level level); | |
| 797 | − | |
| 798 | − const struct snd_pcm_ops *ops; | |
| 799 | − const struct snd_compr_ops *compr_ops; | |
| 800 | − | |
| 801 | − /* probe ordering - for components with runtime dependencies */ | |
| 802 | − int probe_order; | |
| 803 | − int remove_order; | |
| 804 | − | |
| 805 | − /* | |
| 806 | − * signal if the module handling the component should not be removed | |
| 807 | − * if a pcm is open. Setting this would prevent the module | |
| 808 | − * refcount being incremented in probe() but allow it be incremented | |
| 809 | − * when a pcm is opened and decremented when it is closed. | |
| 810 | − */ | |
| 811 | − unsigned int module_get_upon_open:1; | |
| 812 | − | |
| 813 | − /* bits */ | |
| 814 | − unsigned int idle_bias_on:1; | |
| 815 | − unsigned int suspend_bias_off:1; | |
| 816 | − unsigned int use_pmdown_time:1; /* care pmdown_time at stop */ | |
| 817 | − unsigned int endianness:1; | |
| 818 | − unsigned int non_legacy_dai_naming:1; | |
| 819 | − | |
| 820 | − /* this component uses topology and ignore machine driver FEs */ | |
| 821 | − const char *ignore_machine; | |
| 822 | − const char *topology_name_prefix; | |
| 823 | − int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | |
| 824 | − struct snd_pcm_hw_params *params); | |
| 825 | − bool use_dai_pcm_id; /* use the DAI link PCM ID as PCM device number */ | |
| 826 | − int be_pcm_base; /* base device ID for all BE PCMs */ | |
| 827 | −}; | |
| 828 | − | |
| 829 | −struct snd_soc_component { | |
| 830 | − const char *name; | |
| 831 | − int id; | |
| 832 | − const char *name_prefix; | |
| 833 | − struct device *dev; | |
| 834 | − struct snd_soc_card *card; | |
| 835 | − | |
| 836 | − unsigned int active; | |
| 837 | − | |
| 838 | − unsigned int suspended:1; /* is in suspend PM state */ | |
| 839 | − | |
| 840 | − struct list_head list; | |
| 841 | − struct list_head card_aux_list; /* for auxiliary bound components */ | |
| 842 | − struct list_head card_list; | |
| 843 | − | |
| 844 | − const struct snd_soc_component_driver *driver; | |
| 845 | − | |
| 846 | − struct list_head dai_list; | |
| 847 | − int num_dai; | |
| 848 | − | |
| 849 | − struct regmap *regmap; | |
| 850 | − int val_bytes; | |
| 851 | − | |
| 852 | − struct mutex io_mutex; | |
| 853 | − | |
| 854 | − /* attached dynamic objects */ | |
| 855 | − struct list_head dobj_list; | |
| 856 | − | |
| 857 | − /* | |
| 858 | − * DO NOT use any of the fields below in drivers, they are temporary and | |
| 859 | − * are going to be removed again soon. If you use them in driver code the | |
| 860 | − * driver will be marked as BROKEN when these fields are removed. | |
| 861 | − */ | |
| 862 | − | |
| 863 | − /* Don't use these, use snd_soc_component_get_dapm() */ | |
| 864 | − struct snd_soc_dapm_context dapm; | |
| 865 | − | |
| 866 | − /* machine specific init */ | |
| 867 | − int (*init)(struct snd_soc_component *component); | |
| 868 | − | |
| 869 | −#ifdef CONFIG_DEBUG_FS | |
| 870 | − struct dentry *debugfs_root; | |
| 871 | − const char *debugfs_prefix; | |
| 872 | −#endif | |
| 873 | −}; | |
| 874 | − | |
| 875 | −#define for_each_component_dais(component, dai)\ | |
| 876 | − list_for_each_entry(dai, &(component)->dai_list, list) | |
| 877 | −#define for_each_component_dais_safe(component, dai, _dai)\ | |
| 878 | − list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list) | |
| 879 | − | |
| 880 | 735 | struct snd_soc_rtdcom_list { |
| 881 | 736 | struct snd_soc_component *component; |
| 882 | 737 | struct list_head list; /* rtd::component_list */ |
| @@ -1086,6 +941,7 @@ struct snd_soc_dai_link { · 203 unmodified lines | ||
| 1086 | 941 | #define COMP_CPU(_dai) { .dai_name = _dai, } |
| 1087 | 942 | #define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, } |
| 1088 | 943 | #define COMP_PLATFORM(_name) { .name = _name } |
| 944 | +#define COMP_AUX(_name) { .name = _name } | |
| 1089 | 945 | #define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } |
| 1090 | 946 | |
| 1091 | 947 | extern struct snd_soc_dai_link_component null_dailink_component[0]; |
| @@ -1107,14 +963,11 @@ struct snd_soc_codec_conf { · 15 unmodified lines | ||
| 1107 | 963 | }; |
| 1108 | 964 | |
| 1109 | 965 | struct snd_soc_aux_dev { |
| 1110 | − const char *name; /* Codec name */ | |
| 1111 | − | |
| 1112 | 966 | /* |
| 1113 | 967 | * specify multi-codec either by device name, or by |
| 1114 | 968 | * DT/OF node, but not both. |
| 1115 | 969 | */ |
| 1116 | − const char *codec_name; | |
| 1117 | − struct device_node *codec_of_node; | |
| 970 | + struct snd_soc_dai_link_component dlc; | |
| 1118 | 971 | |
| 1119 | 972 | /* codec/machine specific init - e.g. add machine controls */ |
| 1120 | 973 | int (*init)(struct snd_soc_component *component); |
| @@ -1135,6 +988,10 @@ struct snd_soc_card { · 14 unmodified lines | ||
| 1135 | 988 | struct mutex mutex; |
| 1136 | 989 | struct mutex dapm_mutex; |
| 1137 | 990 | |
| 991 | + /* Mutex for PCM operations */ | |
| 992 | + struct mutex pcm_mutex; | |
| 993 | + enum snd_soc_pcm_subclass pcm_subclass; | |
| 994 | + | |
| 1138 | 995 | spinlock_t dpcm_lock; |
| 1139 | 996 | |
| 1140 | 997 | bool instantiated; |
| @@ -1203,8 +1060,6 @@ struct snd_soc_card { · 62 unmodified lines | ||
| 1203 | 1060 | int num_of_dapm_routes; |
| 1204 | 1061 | bool fully_routed; |
| 1205 | 1062 | |
| 1206 | − struct work_struct deferred_resume_work; | |
| 1207 | − | |
| 1208 | 1063 | /* lists of probed devices belonging to this card */ |
| 1209 | 1064 | struct list_head component_dev_list; |
| 1210 | 1065 | struct list_head list; |
| @@ -1224,7 +1079,9 @@ struct snd_soc_card { · 13 unmodified lines | ||
| 1224 | 1079 | |
| 1225 | 1080 | #ifdef CONFIG_DEBUG_FS |
| 1226 | 1081 | struct dentry *debugfs_card_root; |
| 1227 | − struct dentry *debugfs_pop_time; | |
| 1082 | +#endif | |
| 1083 | +#ifdef CONFIG_PM_SLEEP | |
| 1084 | + struct work_struct deferred_resume_work; | |
| 1228 | 1085 | #endif |
| 1229 | 1086 | u32 pop_time; |
| 1230 | 1087 | |
| @@ -1234,6 +1091,10 @@ struct snd_soc_card { · 3 unmodified lines | ||
| 1234 | 1091 | for ((i) = 0; \ |
| 1235 | 1092 | ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \ |
| 1236 | 1093 | (i)++) |
| 1094 | +#define for_each_card_pre_auxs(card, i, aux) \ | |
| 1095 | + for ((i) = 0; \ | |
| 1096 | + ((i) < (card)->num_aux_devs) && ((aux) = &(card)->aux_dev[i]); \ | |
| 1097 | + (i)++) | |
| 1237 | 1098 | |
| 1238 | 1099 | #define for_each_card_links(card, link) \ |
| 1239 | 1100 | list_for_each_entry(link, &(card)->dai_link_list, list) |
| @@ -1245,6 +1106,12 @@ struct snd_soc_card { · 5 unmodified lines | ||
| 1245 | 1106 | #define for_each_card_rtds_safe(card, rtd, _rtd) \ |
| 1246 | 1107 | list_for_each_entry_safe(rtd, _rtd, &(card)->rtd_list, list) |
| 1247 | 1108 | |
| 1109 | +#define for_each_card_auxs(card, component) \ | |
| 1110 | + list_for_each_entry(component, &card->aux_comp_list, card_aux_list) | |
| 1111 | +#define for_each_card_auxs_safe(card, component, _comp) \ | |
| 1112 | + list_for_each_entry_safe(component, _comp, \ | |
| 1113 | + &card->aux_comp_list, card_aux_list) | |
| 1114 | + | |
| 1248 | 1115 | #define for_each_card_components(card, component) \ |
| 1249 | 1116 | list_for_each_entry(component, &(card)->component_dev_list, card_list) |
| 1250 | 1117 | |
| @@ -1253,8 +1120,6 @@ struct snd_soc_pcm_runtime { · 2 unmodified lines | ||
| 1253 | 1120 | struct device *dev; |
| 1254 | 1121 | struct snd_soc_card *card; |
| 1255 | 1122 | struct snd_soc_dai_link *dai_link; |
| 1256 | − struct mutex pcm_mutex; | |
| 1257 | − enum snd_soc_pcm_subclass pcm_subclass; | |
| 1258 | 1123 | struct snd_pcm_ops ops; |
| 1259 | 1124 | |
| 1260 | 1125 | unsigned int params_select; /* currently selected param for dai link */ |
| @@ -1342,134 +1207,6 @@ struct soc_enum { · 81 unmodified lines | ||
| 1342 | 1207 | struct snd_soc_dobj dobj; |
| 1343 | 1208 | }; |
| 1344 | 1209 | |
| 1345 | −/** | |
| 1346 | − * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is | |
| 1347 | − * embedded in | |
| 1348 | − * @dapm: The DAPM context to cast to the component | |
| 1349 | − * | |
| 1350 | − * This function must only be used on DAPM contexts that are known to be part of | |
| 1351 | − * a component (e.g. in a component driver). Otherwise the behavior is | |
| 1352 | − * undefined. | |
| 1353 | − */ | |
| 1354 | −static inline struct snd_soc_component *snd_soc_dapm_to_component( | |
| 1355 | − struct snd_soc_dapm_context *dapm) | |
| 1356 | −{ | |
| 1357 | − return container_of(dapm, struct snd_soc_component, dapm); | |
| 1358 | −} | |
| 1359 | − | |
| 1360 | −/** | |
| 1361 | − * snd_soc_component_get_dapm() - Returns the DAPM context associated with a | |
| 1362 | − * component | |
| 1363 | − * @component: The component for which to get the DAPM context | |
| 1364 | − */ | |
| 1365 | −static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm( | |
| 1366 | − struct snd_soc_component *component) | |
| 1367 | −{ | |
| 1368 | − return &component->dapm; | |
| 1369 | −} | |
| 1370 | − | |
| 1371 | −/** | |
| 1372 | − * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level | |
| 1373 | − * @component: The COMPONENT for which to initialize the DAPM bias level | |
| 1374 | − * @level: The DAPM level to initialize to | |
| 1375 | − * | |
| 1376 | − * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level(). | |
| 1377 | − */ | |
| 1378 | −static inline void | |
| 1379 | −snd_soc_component_init_bias_level(struct snd_soc_component *component, | |
| 1380 | − enum snd_soc_bias_level level) | |
| 1381 | −{ | |
| 1382 | − snd_soc_dapm_init_bias_level( | |
| 1383 | − snd_soc_component_get_dapm(component), level); | |
| 1384 | −} | |
| 1385 | − | |
| 1386 | −/** | |
| 1387 | − * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level | |
| 1388 | − * @component: The COMPONENT for which to get the DAPM bias level | |
| 1389 | − * | |
| 1390 | − * Returns: The current DAPM bias level of the COMPONENT. | |
| 1391 | − */ | |
| 1392 | −static inline enum snd_soc_bias_level | |
| 1393 | −snd_soc_component_get_bias_level(struct snd_soc_component *component) | |
| 1394 | −{ | |
| 1395 | − return snd_soc_dapm_get_bias_level( | |
| 1396 | − snd_soc_component_get_dapm(component)); | |
| 1397 | −} | |
| 1398 | − | |
| 1399 | −/** | |
| 1400 | − * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level | |
| 1401 | − * @component: The COMPONENT for which to set the level | |
| 1402 | − * @level: The level to set to | |
| 1403 | − * | |
| 1404 | − * Forces the COMPONENT bias level to a specific state. See | |
| 1405 | − * snd_soc_dapm_force_bias_level(). | |
| 1406 | − */ | |
| 1407 | −static inline int | |
| 1408 | −snd_soc_component_force_bias_level(struct snd_soc_component *component, | |
| 1409 | − enum snd_soc_bias_level level) | |
| 1410 | −{ | |
| 1411 | − return snd_soc_dapm_force_bias_level( | |
| 1412 | − snd_soc_component_get_dapm(component), | |
| 1413 | − level); | |
| 1414 | −} | |
| 1415 | − | |
| 1416 | −/** | |
| 1417 | − * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol | |
| 1418 | − * @kcontrol: The kcontrol | |
| 1419 | − * | |
| 1420 | − * This function must only be used on DAPM contexts that are known to be part of | |
| 1421 | − * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined. | |
| 1422 | − */ | |
| 1423 | −static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component( | |
| 1424 | − struct snd_kcontrol *kcontrol) | |
| 1425 | −{ | |
| 1426 | − return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol)); | |
| 1427 | −} | |
| 1428 | − | |
| 1429 | −/** | |
| 1430 | − * snd_soc_component_cache_sync() - Sync the register cache with the hardware | |
| 1431 | − * @component: COMPONENT to sync | |
| 1432 | − * | |
| 1433 | − * Note: This function will call regcache_sync() | |
| 1434 | − */ | |
| 1435 | −static inline int snd_soc_component_cache_sync( | |
| 1436 | − struct snd_soc_component *component) | |
| 1437 | −{ | |
| 1438 | − return regcache_sync(component->regmap); | |
| 1439 | −} | |
| 1440 | − | |
| 1441 | −/* component IO */ | |
| 1442 | −int snd_soc_component_read(struct snd_soc_component *component, | |
| 1443 | − unsigned int reg, unsigned int *val); | |
| 1444 | −unsigned int snd_soc_component_read32(struct snd_soc_component *component, | |
| 1445 | − unsigned int reg); | |
| 1446 | −int snd_soc_component_write(struct snd_soc_component *component, | |
| 1447 | − unsigned int reg, unsigned int val); | |
| 1448 | −int snd_soc_component_update_bits(struct snd_soc_component *component, | |
| 1449 | − unsigned int reg, unsigned int mask, unsigned int val); | |
| 1450 | −int snd_soc_component_update_bits_async(struct snd_soc_component *component, | |
| 1451 | − unsigned int reg, unsigned int mask, unsigned int val); | |
| 1452 | −void snd_soc_component_async_complete(struct snd_soc_component *component); | |
| 1453 | −int snd_soc_component_test_bits(struct snd_soc_component *component, | |
| 1454 | − unsigned int reg, unsigned int mask, unsigned int value); | |
| 1455 | − | |
| 1456 | −/* component wide operations */ | |
| 1457 | −int snd_soc_component_set_sysclk(struct snd_soc_component *component, | |
| 1458 | − int clk_id, int source, unsigned int freq, int dir); | |
| 1459 | −int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, | |
| 1460 | − int source, unsigned int freq_in, | |
| 1461 | − unsigned int freq_out); | |
| 1462 | −int snd_soc_component_set_jack(struct snd_soc_component *component, | |
| 1463 | − struct snd_soc_jack *jack, void *data); | |
| 1464 | − | |
| 1465 | −#ifdef CONFIG_REGMAP | |
| 1466 | − | |
| 1467 | −void snd_soc_component_init_regmap(struct snd_soc_component *component, | |
| 1468 | − struct regmap *regmap); | |
| 1469 | −void snd_soc_component_exit_regmap(struct snd_soc_component *component); | |
| 1470 | − | |
| 1471 | −#endif | |
| 1472 | − | |
| 1473 | 1210 | /* device driver data */ |
| 1474 | 1211 | |
| 1475 | 1212 | static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, |
| @@ -1483,27 +1220,6 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card) · 7 unmodified lines | ||
| 1483 | 1220 | return card->drvdata; |
| 1484 | 1221 | } |
| 1485 | 1222 | |
| 1486 | −static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c, | |
| 1487 | − void *data) | |
| 1488 | −{ | |
| 1489 | − dev_set_drvdata(c->dev, data); | |
| 1490 | −} | |
| 1491 | − | |
| 1492 | −static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c) | |
| 1493 | −{ | |
| 1494 | − return dev_get_drvdata(c->dev); | |
| 1495 | −} | |
| 1496 | − | |
| 1497 | −static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) | |
| 1498 | −{ | |
| 1499 | − INIT_LIST_HEAD(&card->widgets); | |
| 1500 | − INIT_LIST_HEAD(&card->paths); | |
| 1501 | − INIT_LIST_HEAD(&card->dapm_list); | |
| 1502 | − INIT_LIST_HEAD(&card->aux_comp_list); | |
| 1503 | − INIT_LIST_HEAD(&card->component_dev_list); | |
| 1504 | − INIT_LIST_HEAD(&card->list); | |
| 1505 | −} | |
| 1506 | − | |
| 1507 | 1223 | static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) |
| 1508 | 1224 | { |
| 1509 | 1225 | if (mc->reg == mc->rreg && mc->shift == mc->rshift) |
| @@ -1540,12 +1256,6 @@ static inline unsigned int snd_soc_enum_item_to_val(struct soc_enum *e, · 30 unmodified lines | ||
| 1540 | 1256 | return e->values[item]; |
| 1541 | 1257 | } |
| 1542 | 1258 | |
| 1543 | −static inline bool snd_soc_component_is_active( | |
| 1544 | − struct snd_soc_component *component) | |
| 1545 | −{ | |
| 1546 | − return component->active != 0; | |
| 1547 | −} | |
| 1548 | − | |
| 1549 | 1259 | /** |
| 1550 | 1260 | * snd_soc_kcontrol_component() - Returns the component that registered the |
| 1551 | 1261 | * control |
| @@ -1681,24 +1391,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm) · 129 unmodified lines | ||
| 1681 | 1391 | mutex_unlock(&dapm->card->dapm_mutex); |
| 1682 | 1392 | } |
| 1683 | 1393 | |
| 1684 | −int snd_soc_component_enable_pin(struct snd_soc_component *component, | |
| 1685 | − const char *pin); | |
| 1686 | −int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, | |
| 1687 | − const char *pin); | |
| 1688 | −int snd_soc_component_disable_pin(struct snd_soc_component *component, | |
| 1689 | − const char *pin); | |
| 1690 | −int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, | |
| 1691 | − const char *pin); | |
| 1692 | −int snd_soc_component_nc_pin(struct snd_soc_component *component, | |
| 1693 | − const char *pin); | |
| 1694 | −int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, | |
| 1695 | − const char *pin); | |
| 1696 | −int snd_soc_component_get_pin_status(struct snd_soc_component *component, | |
| 1697 | − const char *pin); | |
| 1698 | −int snd_soc_component_force_enable_pin(struct snd_soc_component *component, | |
| 1699 | − const char *pin); | |
| 1700 | −int snd_soc_component_force_enable_pin_unlocked( | |
| 1701 | − struct snd_soc_component *component, | |
| 1702 | − const char *pin); | |
| 1394 | +#include <sound/soc-component.h> | |
| 1703 | 1395 | |
| 1704 | 1396 | #endif |
| @@ -76,6 +76,9 @@ struct sof_ipc_dai_ssp_params { · 75 unmodified lines | ||
| 76 | 76 | uint16_t tdm_per_slot_padding_flag; |
| 77 | 77 | uint32_t clks_control; |
| 78 | 78 | uint32_t quirks; |
| 79 | + uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK | |
| 80 | + * will be driven, before sending data | |
| 81 | + */ | |
| 79 | 82 | } __packed; |
| 80 | 83 | |
| 81 | 84 | /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ |
| @@ -176,4 +179,13 @@ struct sof_ipc_dai_dmic_params { · 94 unmodified lines | ||
| 176 | 179 | struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; |
| 177 | 180 | } __packed; |
| 178 | 181 | |
| 182 | +/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ | |
| 183 | +struct sof_ipc_dai_alh_params { | |
| 184 | + struct sof_ipc_hdr hdr; | |
| 185 | + uint32_t stream_id; | |
| 186 | + | |
| 187 | + /* reserved for future use */ | |
| 188 | + uint32_t reserved[15]; | |
| 189 | +} __packed; | |
| 190 | + | |
| 179 | 191 | #endif |
| @@ -49,7 +49,9 @@ enum sof_ipc_dai_type { · 48 unmodified lines | ||
| 49 | 49 | SOF_DAI_INTEL_SSP, /**< Intel SSP */ |
| 50 | 50 | SOF_DAI_INTEL_DMIC, /**< Intel DMIC */ |
| 51 | 51 | SOF_DAI_INTEL_HDA, /**< Intel HD/A */ |
| 52 | − SOF_DAI_INTEL_SOUNDWIRE, /**< Intel SoundWire */ | |
| 52 | + SOF_DAI_INTEL_ALH, /**< Intel ALH */ | |
| 53 | + SOF_DAI_IMX_SAI, /**< i.MX SAI */ | |
| 54 | + SOF_DAI_IMX_ESAI, /**< i.MX ESAI */ | |
| 53 | 55 | }; |
| 54 | 56 | |
| 55 | 57 | /* general purpose DAI configuration */ |
| @@ -70,6 +72,7 @@ struct sof_ipc_dai_config { · 14 unmodified lines | ||
| 70 | 72 | struct sof_ipc_dai_ssp_params ssp; |
| 71 | 73 | struct sof_ipc_dai_dmic_params dmic; |
| 72 | 74 | struct sof_ipc_dai_hda_params hda; |
| 75 | + struct sof_ipc_dai_alh_params alh; | |
| 73 | 76 | }; |
| 74 | 77 | } __packed; |
| 75 | 78 | |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | /* SOF ABI version major, minor and patch numbers */ |
| 28 | 28 | #define SOF_ABI_MAJOR 3 |
| 29 | −#define SOF_ABI_MINOR 8 | |
| 29 | +#define SOF_ABI_MINOR 10 | |
| 30 | 30 | #define SOF_ABI_PATCH 0 |
| 31 | 31 | |
| 32 | 32 | /* SOF ABI version number. Format within 32bit word is MMmmmppp */ |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | #define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503 |
| 76 | 76 | #define SOF_TKN_INTEL_SSP_QUIRKS 504 |
| 77 | 77 | #define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505 |
| 78 | +#define SOF_TKN_INTEL_SSP_BCLK_DELAY 506 | |
| 78 | 79 | |
| 79 | 80 | /* DMIC */ |
| 80 | 81 | #define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600 |
| @@ -105,4 +106,12 @@ · 24 unmodified lines | ||
| 105 | 106 | /* for backward compatibility */ |
| 106 | 107 | #define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE |
| 107 | 108 | |
| 109 | +/* SAI */ | |
| 110 | +#define SOF_TKN_IMX_SAI_FIRST_TOKEN 1000 | |
| 111 | +/* TODO: Add SAI tokens */ | |
| 112 | + | |
| 113 | +/* ESAI */ | |
| 114 | +#define SOF_TKN_IMX_ESAI_FIRST_TOKEN 1100 | |
| 115 | +/* TODO: Add ESAI tokens */ | |
| 116 | + | |
| 108 | 117 | #endif |
| @@ -2170,7 +2170,7 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, · 2169 unmodified lines | ||
| 2170 | 2170 | |
| 2171 | 2171 | static const unsigned int rates[] = { |
| 2172 | 2172 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, |
| 2173 | − 48000, 64000, 88200, 96000, 176400, 192000 | |
| 2173 | + 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000 | |
| 2174 | 2174 | }; |
| 2175 | 2175 | |
| 2176 | 2176 | const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { |
| @@ -6,6 +6,9 @@ config SND_HDA_CORE · 5 unmodified lines | ||
| 6 | 6 | config SND_HDA_DSP_LOADER |
| 7 | 7 | bool |
| 8 | 8 | |
| 9 | +config SND_HDA_ALIGNED_MMIO | |
| 10 | + bool | |
| 11 | + | |
| 9 | 12 | config SND_HDA_COMPONENT |
| 10 | 13 | bool |
| 11 | 14 | |
| @@ -29,3 +32,8 @@ config SND_HDA_PREALLOC_SIZE · 17 unmodified lines | ||
| 29 | 32 | |
| 30 | 33 | Note that the pre-allocation size can be changed dynamically |
| 31 | 34 | via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too. |
| 35 | + | |
| 36 | +config SND_INTEL_NHLT | |
| 37 | + tristate | |
| 38 | + # this config should be selected only for Intel ACPI platforms. | |
| 39 | + # A fallback is provided so that the code compiles in all cases. | |
| @@ -13,3 +13,6 @@ obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #extended hda |
| 15 | 15 | obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/ |
| 16 | + | |
| 17 | +snd-intel-nhlt-objs := intel-nhlt.o | |
| 18 | +obj-$(CONFIG_SND_INTEL_NHLT) += snd-intel-nhlt.o | |
| @@ -17,80 +17,22 @@ · 16 unmodified lines | ||
| 17 | 17 | MODULE_DESCRIPTION("HDA extended core"); |
| 18 | 18 | MODULE_LICENSE("GPL v2"); |
| 19 | 19 | |
| 20 | −static void hdac_ext_writel(u32 value, u32 __iomem *addr) | |
| 21 | −{ | |
| 22 | − writel(value, addr); | |
| 23 | −} | |
| 24 | − | |
| 25 | −static u32 hdac_ext_readl(u32 __iomem *addr) | |
| 26 | −{ | |
| 27 | − return readl(addr); | |
| 28 | −} | |
| 29 | − | |
| 30 | −static void hdac_ext_writew(u16 value, u16 __iomem *addr) | |
| 31 | −{ | |
| 32 | − writew(value, addr); | |
| 33 | −} | |
| 34 | − | |
| 35 | −static u16 hdac_ext_readw(u16 __iomem *addr) | |
| 36 | −{ | |
| 37 | − return readw(addr); | |
| 38 | −} | |
| 39 | − | |
| 40 | −static void hdac_ext_writeb(u8 value, u8 __iomem *addr) | |
| 41 | −{ | |
| 42 | − writeb(value, addr); | |
| 43 | −} | |
| 44 | − | |
| 45 | −static u8 hdac_ext_readb(u8 __iomem *addr) | |
| 46 | −{ | |
| 47 | − return readb(addr); | |
| 48 | −} | |
| 49 | − | |
| 50 | −static int hdac_ext_dma_alloc_pages(struct hdac_bus *bus, int type, | |
| 51 | − size_t size, struct snd_dma_buffer *buf) | |
| 52 | −{ | |
| 53 | − return snd_dma_alloc_pages(type, bus->dev, size, buf); | |
| 54 | −} | |
| 55 | − | |
| 56 | −static void hdac_ext_dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) | |
| 57 | −{ | |
| 58 | − snd_dma_free_pages(buf); | |
| 59 | −} | |
| 60 | − | |
| 61 | −static const struct hdac_io_ops hdac_ext_default_io = { | |
| 62 | − .reg_writel = hdac_ext_writel, | |
| 63 | − .reg_readl = hdac_ext_readl, | |
| 64 | − .reg_writew = hdac_ext_writew, | |
| 65 | − .reg_readw = hdac_ext_readw, | |
| 66 | − .reg_writeb = hdac_ext_writeb, | |
| 67 | − .reg_readb = hdac_ext_readb, | |
| 68 | − .dma_alloc_pages = hdac_ext_dma_alloc_pages, | |
| 69 | − .dma_free_pages = hdac_ext_dma_free_pages, | |
| 70 | −}; | |
| 71 | − | |
| 72 | 20 | /** |
| 73 | 21 | * snd_hdac_ext_bus_init - initialize a HD-audio extended bus |
| 74 | 22 | * @ebus: the pointer to extended bus object |
| 75 | 23 | * @dev: device pointer |
| 76 | 24 | * @ops: bus verb operators |
| 77 | − * @io_ops: lowlevel I/O operators, can be NULL. If NULL core will use | |
| 78 | 25 | * default ops |
| 79 | 26 | * |
| 80 | 27 | * Returns 0 if successful, or a negative error code. |
| 81 | 28 | */ |
| 82 | 29 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, |
| 83 | 30 | const struct hdac_bus_ops *ops, |
| 84 | − const struct hdac_io_ops *io_ops, | |
| 85 | 31 | const struct hdac_ext_bus_ops *ext_ops) |
| 86 | 32 | { |
| 87 | 33 | int ret; |
| 88 | 34 | |
| 89 | − /* check if io ops are provided, if not load the defaults */ | |
| 90 | − if (io_ops == NULL) | |
| 91 | − io_ops = &hdac_ext_default_io; | |
| 92 | − | |
| 93 | − ret = snd_hdac_bus_init(bus, dev, ops, io_ops); | |
| 35 | + ret = snd_hdac_bus_init(bus, dev, ops); | |
| 94 | 36 | if (ret < 0) |
| 95 | 37 | return ret; |
| 96 | 38 | |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/init.h> |
| 7 | +#include <linux/io.h> | |
| 7 | 8 | #include <linux/device.h> |
| 8 | 9 | #include <linux/module.h> |
| 9 | 10 | #include <linux/export.h> |
| @@ -19,13 +20,11 @@ static const struct hdac_bus_ops default_ops = { · 9 unmodified lines | ||
| 19 | 20 | * snd_hdac_bus_init - initialize a HD-audio bas bus |
| 20 | 21 | * @bus: the pointer to bus object |
| 21 | 22 | * @ops: bus verb operators |
| 22 | − * @io_ops: lowlevel I/O operators | |
| 23 | 23 | * |
| 24 | 24 | * Returns 0 if successful, or a negative error code. |
| 25 | 25 | */ |
| 26 | 26 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, |
| 27 | − const struct hdac_bus_ops *ops, | |
| 28 | − const struct hdac_io_ops *io_ops) | |
| 27 | + const struct hdac_bus_ops *ops) | |
| 29 | 28 | { |
| 30 | 29 | memset(bus, 0, sizeof(*bus)); |
| 31 | 30 | bus->dev = dev; |
| @@ -33,7 +32,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, · 1 unmodified line | ||
| 33 | 32 | bus->ops = ops; |
| 34 | 33 | else |
| 35 | 34 | bus->ops = &default_ops; |
| 36 | − bus->io_ops = io_ops; | |
| 35 | + bus->dma_type = SNDRV_DMA_TYPE_DEV; | |
| 37 | 36 | INIT_LIST_HEAD(&bus->stream_list); |
| 38 | 37 | INIT_LIST_HEAD(&bus->codec_list); |
| 39 | 38 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); |
| @@ -217,3 +216,33 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus, · 177 unmodified lines | ||
| 217 | 216 | flush_work(&bus->unsol_work); |
| 218 | 217 | } |
| 219 | 218 | EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device); |
| 219 | + | |
| 220 | +#ifdef CONFIG_SND_HDA_ALIGNED_MMIO | |
| 221 | +/* Helpers for aligned read/write of mmio space, for Tegra */ | |
| 222 | +unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask) | |
| 223 | +{ | |
| 224 | + void __iomem *aligned_addr = | |
| 225 | + (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 226 | + unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 227 | + unsigned int v; | |
| 228 | + | |
| 229 | + v = readl(aligned_addr); | |
| 230 | + return (v >> shift) & mask; | |
| 231 | +} | |
| 232 | +EXPORT_SYMBOL_GPL(snd_hdac_aligned_read); | |
| 233 | + | |
| 234 | +void snd_hdac_aligned_write(unsigned int val, void __iomem *addr, | |
| 235 | + unsigned int mask) | |
| 236 | +{ | |
| 237 | + void __iomem *aligned_addr = | |
| 238 | + (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 239 | + unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 240 | + unsigned int v; | |
| 241 | + | |
| 242 | + v = readl(aligned_addr); | |
| 243 | + v &= ~(mask << shift); | |
| 244 | + v |= val << shift; | |
| 245 | + writel(v, aligned_addr); | |
| 246 | +} | |
| 247 | +EXPORT_SYMBOL_GPL(snd_hdac_aligned_write); | |
| 248 | +#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */ | |
| @@ -575,12 +575,13 @@ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus) · 574 unmodified lines | ||
| 575 | 575 | { |
| 576 | 576 | struct hdac_stream *s; |
| 577 | 577 | int num_streams = 0; |
| 578 | + int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV; | |
| 578 | 579 | int err; |
| 579 | 580 | |
| 580 | 581 | list_for_each_entry(s, &bus->stream_list, list) { |
| 581 | 582 | /* allocate memory for the BDL for each stream */ |
| 582 | − err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, | |
| 583 | − BDL_SIZE, &s->bdl); | |
| 583 | + err = snd_dma_alloc_pages(dma_type, bus->dev, | |
| 584 | + BDL_SIZE, &s->bdl); | |
| 584 | 585 | num_streams++; |
| 585 | 586 | if (err < 0) |
| 586 | 587 | return -ENOMEM; |
| @@ -589,16 +590,15 @@ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus) · 2 unmodified lines | ||
| 589 | 590 | if (WARN_ON(!num_streams)) |
| 590 | 591 | return -EINVAL; |
| 591 | 592 | /* allocate memory for the position buffer */ |
| 592 | − err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, | |
| 593 | − num_streams * 8, &bus->posbuf); | |
| 593 | + err = snd_dma_alloc_pages(dma_type, bus->dev, | |
| 594 | + num_streams * 8, &bus->posbuf); | |
| 594 | 595 | if (err < 0) |
| 595 | 596 | return -ENOMEM; |
| 596 | 597 | list_for_each_entry(s, &bus->stream_list, list) |
| 597 | 598 | s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8); |
| 598 | 599 | |
| 599 | 600 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ |
| 600 | − return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, | |
| 601 | − PAGE_SIZE, &bus->rb); | |
| 601 | + return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb); | |
| 602 | 602 | } |
| 603 | 603 | EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages); |
| 604 | 604 | |
| @@ -612,12 +612,12 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus) · 7 unmodified lines | ||
| 612 | 612 | |
| 613 | 613 | list_for_each_entry(s, &bus->stream_list, list) { |
| 614 | 614 | if (s->bdl.area) |
| 615 | − bus->io_ops->dma_free_pages(bus, &s->bdl); | |
| 615 | + snd_dma_free_pages(&s->bdl); | |
| 616 | 616 | } |
| 617 | 617 | |
| 618 | 618 | if (bus->rb.area) |
| 619 | − bus->io_ops->dma_free_pages(bus, &bus->rb); | |
| 619 | + snd_dma_free_pages(&bus->rb); | |
| 620 | 620 | if (bus->posbuf.area) |
| 621 | − bus->io_ops->dma_free_pages(bus, &bus->posbuf); | |
| 621 | + snd_dma_free_pages(&bus->posbuf); | |
| 622 | 622 | } |
| 623 | 623 | EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages); |
| @@ -680,8 +680,8 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, · 679 unmodified lines | ||
| 680 | 680 | azx_dev->locked = true; |
| 681 | 681 | spin_unlock_irq(&bus->reg_lock); |
| 682 | 682 | |
| 683 | − err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV_SG, | |
| 684 | − byte_size, bufp); | |
| 683 | + err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev, | |
| 684 | + byte_size, bufp); | |
| 685 | 685 | if (err < 0) |
| 686 | 686 | goto err_alloc; |
| 687 | 687 | |
| @@ -707,7 +707,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, · 19 unmodified lines | ||
| 707 | 707 | return azx_dev->stream_tag; |
| 708 | 708 | |
| 709 | 709 | error: |
| 710 | − bus->io_ops->dma_free_pages(bus, bufp); | |
| 710 | + snd_dma_free_pages(bufp); | |
| 711 | 711 | err_alloc: |
| 712 | 712 | spin_lock_irq(&bus->reg_lock); |
| 713 | 713 | azx_dev->locked = false; |
| @@ -754,7 +754,7 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, · 40 unmodified lines | ||
| 754 | 754 | azx_dev->period_bytes = 0; |
| 755 | 755 | azx_dev->format_val = 0; |
| 756 | 756 | |
| 757 | − bus->io_ops->dma_free_pages(bus, dmab); | |
| 757 | + snd_dma_free_pages(dmab); | |
| 758 | 758 | dmab->area = NULL; |
| 759 | 759 | |
| 760 | 760 | spin_lock_irq(&bus->reg_lock); |
| @@ -0,0 +1,107 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +// Copyright (c) 2015-2019 Intel Corporation | |
| 3 | + | |
| 4 | +#include <linux/acpi.h> | |
| 5 | +#include <sound/intel-nhlt.h> | |
| 6 | + | |
| 7 | +#define NHLT_ACPI_HEADER_SIG "NHLT" | |
| 8 | + | |
| 9 | +/* Unique identification for getting NHLT blobs */ | |
| 10 | +static guid_t osc_guid = | |
| 11 | + GUID_INIT(0xA69F886E, 0x6CEB, 0x4594, | |
| 12 | + 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53); | |
| 13 | + | |
| 14 | +struct nhlt_acpi_table *intel_nhlt_init(struct device *dev) | |
| 15 | +{ | |
| 16 | + acpi_handle handle; | |
| 17 | + union acpi_object *obj; | |
| 18 | + struct nhlt_resource_desc *nhlt_ptr; | |
| 19 | + struct nhlt_acpi_table *nhlt_table = NULL; | |
| 20 | + | |
| 21 | + handle = ACPI_HANDLE(dev); | |
| 22 | + if (!handle) { | |
| 23 | + dev_err(dev, "Didn't find ACPI_HANDLE\n"); | |
| 24 | + return NULL; | |
| 25 | + } | |
| 26 | + | |
| 27 | + obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL); | |
| 28 | + | |
| 29 | + if (!obj) | |
| 30 | + return NULL; | |
| 31 | + | |
| 32 | + if (obj->type != ACPI_TYPE_BUFFER) { | |
| 33 | + dev_dbg(dev, "No NHLT table found\n"); | |
| 34 | + ACPI_FREE(obj); | |
| 35 | + return NULL; | |
| 36 | + } | |
| 37 | + | |
| 38 | + nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; | |
| 39 | + if (nhlt_ptr->length) | |
| 40 | + nhlt_table = (struct nhlt_acpi_table *) | |
| 41 | + memremap(nhlt_ptr->min_addr, nhlt_ptr->length, | |
| 42 | + MEMREMAP_WB); | |
| 43 | + ACPI_FREE(obj); | |
| 44 | + if (nhlt_table && | |
| 45 | + (strncmp(nhlt_table->header.signature, | |
| 46 | + NHLT_ACPI_HEADER_SIG, | |
| 47 | + strlen(NHLT_ACPI_HEADER_SIG)) != 0)) { | |
| 48 | + memunmap(nhlt_table); | |
| 49 | + dev_err(dev, "NHLT ACPI header signature incorrect\n"); | |
| 50 | + return NULL; | |
| 51 | + } | |
| 52 | + return nhlt_table; | |
| 53 | +} | |
| 54 | +EXPORT_SYMBOL_GPL(intel_nhlt_init); | |
| 55 | + | |
| 56 | +void intel_nhlt_free(struct nhlt_acpi_table *nhlt) | |
| 57 | +{ | |
| 58 | + memunmap((void *)nhlt); | |
| 59 | +} | |
| 60 | +EXPORT_SYMBOL_GPL(intel_nhlt_free); | |
| 61 | + | |
| 62 | +int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt) | |
| 63 | +{ | |
| 64 | + struct nhlt_endpoint *epnt; | |
| 65 | + struct nhlt_dmic_array_config *cfg; | |
| 66 | + struct nhlt_vendor_dmic_array_config *cfg_vendor; | |
| 67 | + unsigned int dmic_geo = 0; | |
| 68 | + u8 j; | |
| 69 | + | |
| 70 | + if (!nhlt) | |
| 71 | + return 0; | |
| 72 | + | |
| 73 | + epnt = (struct nhlt_endpoint *)nhlt->desc; | |
| 74 | + | |
| 75 | + for (j = 0; j < nhlt->endpoint_count; j++) { | |
| 76 | + if (epnt->linktype == NHLT_LINK_DMIC) { | |
| 77 | + cfg = (struct nhlt_dmic_array_config *) | |
| 78 | + (epnt->config.caps); | |
| 79 | + switch (cfg->array_type) { | |
| 80 | + case NHLT_MIC_ARRAY_2CH_SMALL: | |
| 81 | + case NHLT_MIC_ARRAY_2CH_BIG: | |
| 82 | + dmic_geo = MIC_ARRAY_2CH; | |
| 83 | + break; | |
| 84 | + | |
| 85 | + case NHLT_MIC_ARRAY_4CH_1ST_GEOM: | |
| 86 | + case NHLT_MIC_ARRAY_4CH_L_SHAPED: | |
| 87 | + case NHLT_MIC_ARRAY_4CH_2ND_GEOM: | |
| 88 | + dmic_geo = MIC_ARRAY_4CH; | |
| 89 | + break; | |
| 90 | + case NHLT_MIC_ARRAY_VENDOR_DEFINED: | |
| 91 | + cfg_vendor = (struct nhlt_vendor_dmic_array_config *)cfg; | |
| 92 | + dmic_geo = cfg_vendor->nb_mics; | |
| 93 | + break; | |
| 94 | + default: | |
| 95 | + dev_warn(dev, "undefined DMIC array_type 0x%0x\n", | |
| 96 | + cfg->array_type); | |
| 97 | + } | |
| 98 | + } | |
| 99 | + epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); | |
| 100 | + } | |
| 101 | + | |
| 102 | + return dmic_geo; | |
| 103 | +} | |
| 104 | +EXPORT_SYMBOL_GPL(intel_nhlt_get_dmic_geo); | |
| 105 | + | |
| 106 | +MODULE_LICENSE("GPL v2"); | |
| 107 | +MODULE_DESCRIPTION("Intel NHLT driver"); | |
| @@ -12,6 +12,7 @@ config SND_HDA_INTEL · 11 unmodified lines | ||
| 12 | 12 | tristate "HD Audio PCI" |
| 13 | 13 | depends on SND_PCI |
| 14 | 14 | select SND_HDA |
| 15 | + select SND_INTEL_NHLT if ACPI | |
| 15 | 16 | help |
| 16 | 17 | Say Y here to include support for Intel "High Definition |
| 17 | 18 | Audio" (Azalia) and its compatible devices. |
| @@ -22,10 +23,20 @@ config SND_HDA_INTEL · 4 unmodified lines | ||
| 22 | 23 | To compile this driver as a module, choose M here: the module |
| 23 | 24 | will be called snd-hda-intel. |
| 24 | 25 | |
| 26 | +config SND_HDA_INTEL_DETECT_DMIC | |
| 27 | + bool "DMIC detection and probe abort" | |
| 28 | + depends on SND_HDA_INTEL | |
| 29 | + help | |
| 30 | + Say Y to detect digital microphones on SKL+ devices. DMICs | |
| 31 | + cannot be handled by the HDaudio legacy driver and are | |
| 32 | + currently only supported by the SOF driver. | |
| 33 | + If unsure say N. | |
| 34 | + | |
| 25 | 35 | config SND_HDA_TEGRA |
| 26 | 36 | tristate "NVIDIA Tegra HD Audio" |
| 27 | 37 | depends on ARCH_TEGRA |
| 28 | 38 | select SND_HDA |
| 39 | + select SND_HDA_ALIGNED_MMIO | |
| 29 | 40 | help |
| 30 | 41 | Say Y here to support the HDA controller present in NVIDIA |
| 31 | 42 | Tegra SoCs |
| @@ -846,7 +846,13 @@ static void snd_hda_codec_dev_release(struct device *dev) · 845 unmodified lines | ||
| 846 | 846 | snd_hda_sysfs_clear(codec); |
| 847 | 847 | kfree(codec->modelname); |
| 848 | 848 | kfree(codec->wcaps); |
| 849 | − kfree(codec); | |
| 849 | + | |
| 850 | + /* | |
| 851 | + * In the case of ASoC HD-audio, hda_codec is device managed. | |
| 852 | + * It will be freed when the ASoC device is removed. | |
| 853 | + */ | |
| 854 | + if (codec->core.type == HDA_DEV_LEGACY) | |
| 855 | + kfree(codec); | |
| 850 | 856 | } |
| 851 | 857 | |
| 852 | 858 | #define DEV_NAME_LEN 31 |
| @@ -1207,14 +1207,12 @@ void snd_hda_bus_reset(struct hda_bus *bus) · 1206 unmodified lines | ||
| 1207 | 1207 | } |
| 1208 | 1208 | |
| 1209 | 1209 | /* HD-audio bus initialization */ |
| 1210 | −int azx_bus_init(struct azx *chip, const char *model, | |
| 1211 | − const struct hdac_io_ops *io_ops) | |
| 1210 | +int azx_bus_init(struct azx *chip, const char *model) | |
| 1212 | 1211 | { |
| 1213 | 1212 | struct hda_bus *bus = &chip->bus; |
| 1214 | 1213 | int err; |
| 1215 | 1214 | |
| 1216 | − err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops, | |
| 1217 | − io_ops); | |
| 1215 | + err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops); | |
| 1218 | 1216 | if (err < 0) |
| 1219 | 1217 | return err; |
| 1220 | 1218 | |
| @@ -206,8 +206,7 @@ void azx_stop_chip(struct azx *chip); · 205 unmodified lines | ||
| 206 | 206 | irqreturn_t azx_interrupt(int irq, void *dev_id); |
| 207 | 207 | |
| 208 | 208 | /* Codec interface */ |
| 209 | −int azx_bus_init(struct azx *chip, const char *model, | |
| 210 | − const struct hdac_io_ops *io_ops); | |
| 209 | +int azx_bus_init(struct azx *chip, const char *model); | |
| 211 | 210 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots); |
| 212 | 211 | int azx_codec_configure(struct azx *chip); |
| 213 | 212 | int azx_init_streams(struct azx *chip); |
| @@ -46,6 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #include <sound/initval.h> |
| 47 | 47 | #include <sound/hdaudio.h> |
| 48 | 48 | #include <sound/hda_i915.h> |
| 49 | +#include <sound/intel-nhlt.h> | |
| 49 | 50 | #include <linux/vgaarb.h> |
| 50 | 51 | #include <linux/vga_switcheroo.h> |
| 51 | 52 | #include <linux/firmware.h> |
| @@ -125,6 +126,7 @@ static char *patch[SNDRV_CARDS]; · 73 unmodified lines | ||
| 125 | 126 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
| 126 | 127 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
| 127 | 128 | #endif |
| 129 | +static bool dmic_detect = IS_ENABLED(CONFIG_SND_HDA_INTEL_DETECT_DMIC); | |
| 128 | 130 | |
| 129 | 131 | module_param_array(index, int, NULL, 0444); |
| 130 | 132 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
| @@ -159,6 +161,8 @@ module_param_array(beep_mode, bool, NULL, 0444); · 28 unmodified lines | ||
| 159 | 161 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
| 160 | 162 | "(0=off, 1=on) (default=1)."); |
| 161 | 163 | #endif |
| 164 | +module_param(dmic_detect, bool, 0444); | |
| 165 | +MODULE_PARM_DESC(dmic_detect, "DMIC detect on SKL+ platforms"); | |
| 162 | 166 | |
| 163 | 167 | #ifdef CONFIG_PM |
| 164 | 168 | static int param_set_xint(const char *val, const struct kernel_param *kp); |
| @@ -1684,7 +1688,6 @@ static int default_bdl_pos_adj(struct azx *chip) · 1519 unmodified lines | ||
| 1684 | 1688 | /* |
| 1685 | 1689 | * constructor |
| 1686 | 1690 | */ |
| 1687 | −static const struct hdac_io_ops pci_hda_io_ops; | |
| 1688 | 1691 | static const struct hda_controller_ops pci_hda_ops; |
| 1689 | 1692 | |
| 1690 | 1693 | static int azx_create(struct snd_card *card, struct pci_dev *pci, |
| @@ -1744,13 +1747,17 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, · 53 unmodified lines | ||
| 1744 | 1747 | else |
| 1745 | 1748 | chip->bdl_pos_adj = bdl_pos_adj[dev]; |
| 1746 | 1749 | |
| 1747 | − err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); | |
| 1750 | + err = azx_bus_init(chip, model[dev]); | |
| 1748 | 1751 | if (err < 0) { |
| 1749 | 1752 | kfree(hda); |
| 1750 | 1753 | pci_disable_device(pci); |
| 1751 | 1754 | return err; |
| 1752 | 1755 | } |
| 1753 | 1756 | |
| 1757 | + /* use the non-cached pages in non-snoop mode */ | |
| 1758 | + if (!azx_snoop(chip)) | |
| 1759 | + azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_UC; | |
| 1760 | + | |
| 1754 | 1761 | /* Workaround for a communication error on CFL (bko#199007) and CNL */ |
| 1755 | 1762 | if (IS_CFL(pci) || IS_CNL(pci)) |
| 1756 | 1763 | azx_bus(chip)->polling_mode = 1; |
| @@ -1985,41 +1992,6 @@ static void azx_firmware_cb(const struct firmware *fw, void *context) · 228 unmodified lines | ||
| 1985 | 1992 | } |
| 1986 | 1993 | #endif |
| 1987 | 1994 | |
| 1988 | −/* | |
| 1989 | − * HDA controller ops. | |
| 1990 | − */ | |
| 1991 | − | |
| 1992 | −/* PCI register access. */ | |
| 1993 | −static void pci_azx_writel(u32 value, u32 __iomem *addr) | |
| 1994 | −{ | |
| 1995 | − writel(value, addr); | |
| 1996 | −} | |
| 1997 | − | |
| 1998 | −static u32 pci_azx_readl(u32 __iomem *addr) | |
| 1999 | −{ | |
| 2000 | − return readl(addr); | |
| 2001 | −} | |
| 2002 | − | |
| 2003 | −static void pci_azx_writew(u16 value, u16 __iomem *addr) | |
| 2004 | −{ | |
| 2005 | − writew(value, addr); | |
| 2006 | −} | |
| 2007 | − | |
| 2008 | −static u16 pci_azx_readw(u16 __iomem *addr) | |
| 2009 | −{ | |
| 2010 | − return readw(addr); | |
| 2011 | −} | |
| 2012 | − | |
| 2013 | −static void pci_azx_writeb(u8 value, u8 __iomem *addr) | |
| 2014 | −{ | |
| 2015 | − writeb(value, addr); | |
| 2016 | −} | |
| 2017 | − | |
| 2018 | −static u8 pci_azx_readb(u8 __iomem *addr) | |
| 2019 | −{ | |
| 2020 | − return readb(addr); | |
| 2021 | −} | |
| 2022 | − | |
| 2023 | 1995 | static int disable_msi_reset_irq(struct azx *chip) |
| 2024 | 1996 | { |
| 2025 | 1997 | struct hdac_bus *bus = azx_bus(chip); |
| @@ -2036,24 +2008,6 @@ static int disable_msi_reset_irq(struct azx *chip) · 10 unmodified lines | ||
| 2036 | 2008 | return 0; |
| 2037 | 2009 | } |
| 2038 | 2010 | |
| 2039 | −/* DMA page allocation helpers. */ | |
| 2040 | −static int dma_alloc_pages(struct hdac_bus *bus, | |
| 2041 | − int type, | |
| 2042 | − size_t size, | |
| 2043 | − struct snd_dma_buffer *buf) | |
| 2044 | −{ | |
| 2045 | − struct azx *chip = bus_to_azx(bus); | |
| 2046 | − | |
| 2047 | − if (!azx_snoop(chip) && type == SNDRV_DMA_TYPE_DEV) | |
| 2048 | − type = SNDRV_DMA_TYPE_DEV_UC; | |
| 2049 | − return snd_dma_alloc_pages(type, bus->dev, size, buf); | |
| 2050 | −} | |
| 2051 | − | |
| 2052 | −static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) | |
| 2053 | −{ | |
| 2054 | − snd_dma_free_pages(buf); | |
| 2055 | −} | |
| 2056 | − | |
| 2057 | 2011 | static void pcm_mmap_prepare(struct snd_pcm_substream *substream, |
| 2058 | 2012 | struct vm_area_struct *area) |
| 2059 | 2013 | { |
| @@ -2065,23 +2019,31 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, · 5 unmodified lines | ||
| 2065 | 2019 | #endif |
| 2066 | 2020 | } |
| 2067 | 2021 | |
| 2068 | −static const struct hdac_io_ops pci_hda_io_ops = { | |
| 2069 | − .reg_writel = pci_azx_writel, | |
| 2070 | − .reg_readl = pci_azx_readl, | |
| 2071 | − .reg_writew = pci_azx_writew, | |
| 2072 | − .reg_readw = pci_azx_readw, | |
| 2073 | − .reg_writeb = pci_azx_writeb, | |
| 2074 | − .reg_readb = pci_azx_readb, | |
| 2075 | − .dma_alloc_pages = dma_alloc_pages, | |
| 2076 | − .dma_free_pages = dma_free_pages, | |
| 2077 | −}; | |
| 2078 | − | |
| 2079 | 2022 | static const struct hda_controller_ops pci_hda_ops = { |
| 2080 | 2023 | .disable_msi_reset_irq = disable_msi_reset_irq, |
| 2081 | 2024 | .pcm_mmap_prepare = pcm_mmap_prepare, |
| 2082 | 2025 | .position_check = azx_position_check, |
| 2083 | 2026 | }; |
| 2084 | 2027 | |
| 2028 | +static int azx_check_dmic(struct pci_dev *pci, struct azx *chip) | |
| 2029 | +{ | |
| 2030 | + struct nhlt_acpi_table *nhlt; | |
| 2031 | + int ret = 0; | |
| 2032 | + | |
| 2033 | + if (chip->driver_type == AZX_DRIVER_SKL && | |
| 2034 | + pci->class != 0x040300) { | |
| 2035 | + nhlt = intel_nhlt_init(&pci->dev); | |
| 2036 | + if (nhlt) { | |
| 2037 | + if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) { | |
| 2038 | + ret = -ENODEV; | |
| 2039 | + dev_info(&pci->dev, "Digital mics found on Skylake+ platform, aborting probe\n"); | |
| 2040 | + } | |
| 2041 | + intel_nhlt_free(nhlt); | |
| 2042 | + } | |
| 2043 | + } | |
| 2044 | + return ret; | |
| 2045 | +} | |
| 2046 | + | |
| 2085 | 2047 | static int azx_probe(struct pci_dev *pci, |
| 2086 | 2048 | const struct pci_device_id *pci_id) |
| 2087 | 2049 | { |
| @@ -2112,6 +2074,17 @@ static int azx_probe(struct pci_dev *pci, · 24 unmodified lines | ||
| 2112 | 2074 | card->private_data = chip; |
| 2113 | 2075 | hda = container_of(chip, struct hda_intel, chip); |
| 2114 | 2076 | |
| 2077 | + /* | |
| 2078 | + * stop probe if digital microphones detected on Skylake+ platform | |
| 2079 | + * with the DSP enabled. This is an opt-in behavior defined at build | |
| 2080 | + * time or at run-time with a module parameter | |
| 2081 | + */ | |
| 2082 | + if (dmic_detect) { | |
| 2083 | + err = azx_check_dmic(pci, chip); | |
| 2084 | + if (err < 0) | |
| 2085 | + goto out_free; | |
| 2086 | + } | |
| 2087 | + | |
| 2115 | 2088 | pci_set_drvdata(pci, card); |
| 2116 | 2089 | |
| 2117 | 2090 | err = register_vga_switcheroo(chip); |
| @@ -75,88 +75,6 @@ MODULE_PARM_DESC(power_save, · 74 unmodified lines | ||
| 75 | 75 | #define power_save 0 |
| 76 | 76 | #endif |
| 77 | 77 | |
| 78 | −/* | |
| 79 | − * DMA page allocation ops. | |
| 80 | − */ | |
| 81 | −static int dma_alloc_pages(struct hdac_bus *bus, int type, size_t size, | |
| 82 | − struct snd_dma_buffer *buf) | |
| 83 | −{ | |
| 84 | − return snd_dma_alloc_pages(type, bus->dev, size, buf); | |
| 85 | −} | |
| 86 | − | |
| 87 | −static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) | |
| 88 | −{ | |
| 89 | − snd_dma_free_pages(buf); | |
| 90 | −} | |
| 91 | − | |
| 92 | −/* | |
| 93 | − * Register access ops. Tegra HDA register access is DWORD only. | |
| 94 | − */ | |
| 95 | −static void hda_tegra_writel(u32 value, u32 __iomem *addr) | |
| 96 | −{ | |
| 97 | − writel(value, addr); | |
| 98 | −} | |
| 99 | − | |
| 100 | −static u32 hda_tegra_readl(u32 __iomem *addr) | |
| 101 | −{ | |
| 102 | − return readl(addr); | |
| 103 | −} | |
| 104 | − | |
| 105 | −static void hda_tegra_writew(u16 value, u16 __iomem *addr) | |
| 106 | −{ | |
| 107 | − unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 108 | − void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 109 | − u32 v; | |
| 110 | − | |
| 111 | − v = readl(dword_addr); | |
| 112 | − v &= ~(0xffff << shift); | |
| 113 | − v |= value << shift; | |
| 114 | − writel(v, dword_addr); | |
| 115 | −} | |
| 116 | − | |
| 117 | −static u16 hda_tegra_readw(u16 __iomem *addr) | |
| 118 | −{ | |
| 119 | − unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 120 | − void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 121 | − u32 v; | |
| 122 | − | |
| 123 | − v = readl(dword_addr); | |
| 124 | − return (v >> shift) & 0xffff; | |
| 125 | −} | |
| 126 | − | |
| 127 | −static void hda_tegra_writeb(u8 value, u8 __iomem *addr) | |
| 128 | −{ | |
| 129 | − unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 130 | − void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 131 | − u32 v; | |
| 132 | − | |
| 133 | − v = readl(dword_addr); | |
| 134 | − v &= ~(0xff << shift); | |
| 135 | − v |= value << shift; | |
| 136 | − writel(v, dword_addr); | |
| 137 | −} | |
| 138 | − | |
| 139 | −static u8 hda_tegra_readb(u8 __iomem *addr) | |
| 140 | −{ | |
| 141 | − unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | |
| 142 | − void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3); | |
| 143 | − u32 v; | |
| 144 | − | |
| 145 | − v = readl(dword_addr); | |
| 146 | − return (v >> shift) & 0xff; | |
| 147 | −} | |
| 148 | − | |
| 149 | −static const struct hdac_io_ops hda_tegra_io_ops = { | |
| 150 | − .reg_writel = hda_tegra_writel, | |
| 151 | − .reg_readl = hda_tegra_readl, | |
| 152 | − .reg_writew = hda_tegra_writew, | |
| 153 | − .reg_readw = hda_tegra_readw, | |
| 154 | − .reg_writeb = hda_tegra_writeb, | |
| 155 | − .reg_readb = hda_tegra_readb, | |
| 156 | − .dma_alloc_pages = dma_alloc_pages, | |
| 157 | − .dma_free_pages = dma_free_pages, | |
| 158 | −}; | |
| 159 | − | |
| 160 | 78 | static const struct hda_controller_ops hda_tegra_ops; /* nothing special */ |
| 161 | 79 | |
| 162 | 80 | static void hda_tegra_init(struct hda_tegra *hda) |
| @@ -475,7 +393,7 @@ static int hda_tegra_create(struct snd_card *card, · 312 unmodified lines | ||
| 475 | 393 | |
| 476 | 394 | INIT_WORK(&hda->probe_work, hda_tegra_probe_work); |
| 477 | 395 | |
| 478 | − err = azx_bus_init(chip, NULL, &hda_tegra_io_ops); | |
| 396 | + err = azx_bus_init(chip, NULL); | |
| 479 | 397 | if (err < 0) |
| 480 | 398 | return err; |
| 481 | 399 | |
| @@ -51,7 +51,6 @@ source "sound/soc/dwc/Kconfig" · 50 unmodified lines | ||
| 51 | 51 | source "sound/soc/fsl/Kconfig" |
| 52 | 52 | source "sound/soc/hisilicon/Kconfig" |
| 53 | 53 | source "sound/soc/jz4740/Kconfig" |
| 54 | −source "sound/soc/nuc900/Kconfig" | |
| 55 | 54 | source "sound/soc/kirkwood/Kconfig" |
| 56 | 55 | source "sound/soc/img/Kconfig" |
| 57 | 56 | source "sound/soc/intel/Kconfig" |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o | |
| 2 | +snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o soc-component.o | |
| 3 | 3 | snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o |
| 4 | 4 | snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o |
| 5 | 5 | |
| @@ -39,7 +39,6 @@ obj-$(CONFIG_SND_SOC) += intel/ · 33 unmodified lines | ||
| 39 | 39 | obj-$(CONFIG_SND_SOC) += mediatek/ |
| 40 | 40 | obj-$(CONFIG_SND_SOC) += meson/ |
| 41 | 41 | obj-$(CONFIG_SND_SOC) += mxs/ |
| 42 | −obj-$(CONFIG_SND_SOC) += nuc900/ | |
| 43 | 42 | obj-$(CONFIG_SND_SOC) += kirkwood/ |
| 44 | 43 | obj-$(CONFIG_SND_SOC) += pxa/ |
| 45 | 44 | obj-$(CONFIG_SND_SOC) += qcom/ |
| @@ -1251,8 +1251,7 @@ static int acp_audio_probe(struct platform_device *pdev) · 1250 unmodified lines | ||
| 1251 | 1251 | if (!audio_drv_data) |
| 1252 | 1252 | return -ENOMEM; |
| 1253 | 1253 | |
| 1254 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1255 | − audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res); | |
| 1254 | + audio_drv_data->acp_mmio = devm_platform_ioremap_resource(pdev, 0); | |
| 1256 | 1255 | if (IS_ERR(audio_drv_data->acp_mmio)) |
| 1257 | 1256 | return PTR_ERR(audio_drv_data->acp_mmio); |
| 1258 | 1257 | |
| @@ -12,25 +12,31 @@ if SND_ATMEL_SOC · 11 unmodified lines | ||
| 12 | 12 | config SND_ATMEL_SOC_PDC |
| 13 | 13 | tristate |
| 14 | 14 | depends on HAS_DMA |
| 15 | − default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m | |
| 16 | − default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y) | |
| 17 | − | |
| 18 | −config SND_ATMEL_SOC_SSC_PDC | |
| 19 | − tristate | |
| 20 | 15 | |
| 21 | 16 | config SND_ATMEL_SOC_DMA |
| 22 | 17 | tristate |
| 23 | 18 | select SND_SOC_GENERIC_DMAENGINE_PCM |
| 24 | − default m if SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=m | |
| 25 | − default y if SND_ATMEL_SOC_SSC_DMA=y || (SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=y) | |
| 26 | − | |
| 27 | −config SND_ATMEL_SOC_SSC_DMA | |
| 28 | − tristate | |
| 29 | 19 | |
| 30 | 20 | config SND_ATMEL_SOC_SSC |
| 31 | 21 | tristate |
| 32 | − default y if SND_ATMEL_SOC_SSC_DMA=y || SND_ATMEL_SOC_SSC_PDC=y | |
| 33 | − default m if SND_ATMEL_SOC_SSC_DMA=m || SND_ATMEL_SOC_SSC_PDC=m | |
| 22 | + | |
| 23 | +config SND_ATMEL_SOC_SSC_PDC | |
| 24 | + tristate "SoC PCM DAI support for AT91 SSC controller using PDC" | |
| 25 | + depends on ATMEL_SSC | |
| 26 | + select SND_ATMEL_SOC_PDC | |
| 27 | + select SND_ATMEL_SOC_SSC | |
| 28 | + help | |
| 29 | + Say Y or M if you want to add support for Atmel SSC interface | |
| 30 | + in PDC mode configured using audio-graph-card in device-tree. | |
| 31 | + | |
| 32 | +config SND_ATMEL_SOC_SSC_DMA | |
| 33 | + tristate "SoC PCM DAI support for AT91 SSC controller using DMA" | |
| 34 | + depends on ATMEL_SSC | |
| 35 | + select SND_ATMEL_SOC_DMA | |
| 36 | + select SND_ATMEL_SOC_SSC | |
| 37 | + help | |
| 38 | + Say Y or M if you want to add support for Atmel SSC interface | |
| 39 | + in DMA mode configured using audio-graph-card in device-tree. | |
| 34 | 40 | |
| 35 | 41 | config SND_AT91_SOC_SAM9G20_WM8731 |
| 36 | 42 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" |
| @@ -571,11 +571,8 @@ static int atmel_classd_probe(struct platform_device *pdev) · 570 unmodified lines | ||
| 571 | 571 | dd->pdata = pdata; |
| 572 | 572 | |
| 573 | 573 | dd->irq = platform_get_irq(pdev, 0); |
| 574 | − if (dd->irq < 0) { | |
| 575 | − ret = dd->irq; | |
| 576 | − dev_err(dev, "failed to could not get irq: %d\n", ret); | |
| 577 | − return ret; | |
| 578 | − } | |
| 574 | + if (dd->irq < 0) | |
| 575 | + return dd->irq; | |
| 579 | 576 | |
| 580 | 577 | dd->pclk = devm_clk_get(dev, "pclk"); |
| 581 | 578 | if (IS_ERR(dd->pclk)) { |
| @@ -612,11 +612,8 @@ static int atmel_pdmic_probe(struct platform_device *pdev) · 611 unmodified lines | ||
| 612 | 612 | dd->dev = dev; |
| 613 | 613 | |
| 614 | 614 | dd->irq = platform_get_irq(pdev, 0); |
| 615 | − if (dd->irq < 0) { | |
| 616 | − ret = dd->irq; | |
| 617 | − dev_err(dev, "failed to get irq: %d\n", ret); | |
| 618 | − return ret; | |
| 619 | − } | |
| 615 | + if (dd->irq < 0) | |
| 616 | + return dd->irq; | |
| 620 | 617 | |
| 621 | 618 | dd->pclk = devm_clk_get(dev, "pclk"); |
| 622 | 619 | if (IS_ERR(dd->pclk)) { |
| @@ -471,7 +471,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 470 unmodified lines | ||
| 471 | 471 | int dir, channels, bits; |
| 472 | 472 | u32 tfmr, rfmr, tcmr, rcmr; |
| 473 | 473 | int ret; |
| 474 | − int fslen, fslen_ext; | |
| 474 | + int fslen, fslen_ext, fs_osync, fs_edge; | |
| 475 | 475 | u32 cmr_div; |
| 476 | 476 | u32 tcmr_period; |
| 477 | 477 | u32 rcmr_period; |
| @@ -558,226 +558,45 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 80 unmodified lines | ||
| 558 | 558 | /* |
| 559 | 559 | * Compute SSC register settings. |
| 560 | 560 | */ |
| 561 | − switch (ssc_p->daifmt | |
| 562 | − & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { | |
| 563 | 561 | |
| 564 | − case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: | |
| 565 | − /* | |
| 566 | − * I2S format, SSC provides BCLK and LRC clocks. | |
| 567 | − * | |
| 568 | − * The SSC transmit and receive clocks are generated | |
| 569 | − * from the MCK divider, and the BCLK signal | |
| 570 | − * is output on the SSC TK line. | |
| 571 | − */ | |
| 562 | + fslen_ext = (bits - 1) / 16; | |
| 563 | + fslen = (bits - 1) % 16; | |
| 572 | 564 | |
| 573 | − if (bits > 16 && !ssc->pdata->has_fslen_ext) { | |
| 574 | − dev_err(dai->dev, | |
| 575 | − "sample size %d is too large for SSC device\n", | |
| 576 | − bits); | |
| 577 | − return -EINVAL; | |
| 578 | − } | |
| 565 | + switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { | |
| 579 | 566 | |
| 580 | − fslen_ext = (bits - 1) / 16; | |
| 581 | − fslen = (bits - 1) % 16; | |
| 582 | − | |
| 583 | − rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | |
| 584 | − | SSC_BF(RCMR_STTDLY, START_DELAY) | |
| 585 | − | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | |
| 586 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 587 | − | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | |
| 588 | − | SSC_BF(RCMR_CKS, SSC_CKS_DIV); | |
| 589 | − | |
| 590 | − rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) | |
| 591 | − | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 592 | − | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) | |
| 593 | − | SSC_BF(RFMR_FSLEN, fslen) | |
| 594 | − | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 595 | − | SSC_BIT(RFMR_MSBF) | |
| 596 | − | SSC_BF(RFMR_LOOP, 0) | |
| 597 | − | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 598 | − | |
| 599 | − tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | |
| 600 | − | SSC_BF(TCMR_STTDLY, START_DELAY) | |
| 601 | − | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | |
| 602 | − | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 603 | − | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) | |
| 604 | − | SSC_BF(TCMR_CKS, SSC_CKS_DIV); | |
| 605 | − | |
| 606 | − tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) | |
| 607 | − | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 608 | − | SSC_BF(TFMR_FSDEN, 0) | |
| 609 | − | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) | |
| 610 | − | SSC_BF(TFMR_FSLEN, fslen) | |
| 611 | − | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 612 | − | SSC_BIT(TFMR_MSBF) | |
| 613 | − | SSC_BF(TFMR_DATDEF, 0) | |
| 614 | − | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 615 | − break; | |
| 567 | + case SND_SOC_DAIFMT_LEFT_J: | |
| 568 | + fs_osync = SSC_FSOS_POSITIVE; | |
| 569 | + fs_edge = SSC_START_RISING_RF; | |
| 570 | + | |
| 571 | + rcmr = SSC_BF(RCMR_STTDLY, 0); | |
| 572 | + tcmr = SSC_BF(TCMR_STTDLY, 0); | |
| 616 | 573 | |
| 617 | − case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: | |
| 618 | − /* I2S format, CODEC supplies BCLK and LRC clocks. */ | |
| 619 | − rcmr = SSC_BF(RCMR_PERIOD, 0) | |
| 620 | − | SSC_BF(RCMR_STTDLY, START_DELAY) | |
| 621 | − | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | |
| 622 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 623 | − | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | |
| 624 | − | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | |
| 625 | − SSC_CKS_PIN : SSC_CKS_CLOCK); | |
| 626 | − | |
| 627 | − rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 628 | − | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) | |
| 629 | − | SSC_BF(RFMR_FSLEN, 0) | |
| 630 | − | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 631 | − | SSC_BIT(RFMR_MSBF) | |
| 632 | − | SSC_BF(RFMR_LOOP, 0) | |
| 633 | − | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 634 | − | |
| 635 | − tcmr = SSC_BF(TCMR_PERIOD, 0) | |
| 636 | − | SSC_BF(TCMR_STTDLY, START_DELAY) | |
| 637 | − | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | |
| 638 | − | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 639 | − | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | |
| 640 | − | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? | |
| 641 | − SSC_CKS_CLOCK : SSC_CKS_PIN); | |
| 642 | − | |
| 643 | − tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 644 | − | SSC_BF(TFMR_FSDEN, 0) | |
| 645 | − | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) | |
| 646 | − | SSC_BF(TFMR_FSLEN, 0) | |
| 647 | − | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 648 | − | SSC_BIT(TFMR_MSBF) | |
| 649 | − | SSC_BF(TFMR_DATDEF, 0) | |
| 650 | − | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 651 | 574 | break; |
| 652 | 575 | |
| 653 | − case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: | |
| 654 | − /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ | |
| 655 | − if (bits > 16 && !ssc->pdata->has_fslen_ext) { | |
| 656 | − dev_err(dai->dev, | |
| 657 | − "sample size %d is too large for SSC device\n", | |
| 658 | − bits); | |
| 659 | − return -EINVAL; | |
| 660 | − } | |
| 576 | + case SND_SOC_DAIFMT_I2S: | |
| 577 | + fs_osync = SSC_FSOS_NEGATIVE; | |
| 578 | + fs_edge = SSC_START_FALLING_RF; | |
| 661 | 579 | |
| 662 | − fslen_ext = (bits - 1) / 16; | |
| 663 | − fslen = (bits - 1) % 16; | |
| 664 | − | |
| 665 | − rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | |
| 666 | − | SSC_BF(RCMR_STTDLY, START_DELAY) | |
| 667 | − | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | |
| 668 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 669 | − | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | |
| 670 | − | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | |
| 671 | − SSC_CKS_PIN : SSC_CKS_CLOCK); | |
| 672 | − | |
| 673 | − rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) | |
| 674 | − | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 675 | − | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) | |
| 676 | − | SSC_BF(RFMR_FSLEN, fslen) | |
| 677 | − | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 678 | − | SSC_BIT(RFMR_MSBF) | |
| 679 | − | SSC_BF(RFMR_LOOP, 0) | |
| 680 | − | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 681 | − | |
| 682 | − tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | |
| 683 | − | SSC_BF(TCMR_STTDLY, START_DELAY) | |
| 684 | − | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | |
| 685 | − | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 686 | − | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | |
| 687 | − | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? | |
| 688 | − SSC_CKS_CLOCK : SSC_CKS_PIN); | |
| 689 | − | |
| 690 | − tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) | |
| 691 | − | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE) | |
| 692 | − | SSC_BF(TFMR_FSDEN, 0) | |
| 693 | − | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) | |
| 694 | − | SSC_BF(TFMR_FSLEN, fslen) | |
| 695 | − | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 696 | − | SSC_BIT(TFMR_MSBF) | |
| 697 | − | SSC_BF(TFMR_DATDEF, 0) | |
| 698 | − | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 699 | − break; | |
| 580 | + rcmr = SSC_BF(RCMR_STTDLY, 1); | |
| 581 | + tcmr = SSC_BF(TCMR_STTDLY, 1); | |
| 700 | 582 | |
| 701 | − case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: | |
| 702 | − /* | |
| 703 | − * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. | |
| 704 | − * | |
| 705 | − * The SSC transmit and receive clocks are generated from the | |
| 706 | − * MCK divider, and the BCLK signal is output | |
| 707 | − * on the SSC TK line. | |
| 708 | − */ | |
| 709 | − rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | |
| 710 | − | SSC_BF(RCMR_STTDLY, 1) | |
| 711 | − | SSC_BF(RCMR_START, SSC_START_RISING_RF) | |
| 712 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 713 | − | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | |
| 714 | − | SSC_BF(RCMR_CKS, SSC_CKS_DIV); | |
| 715 | − | |
| 716 | − rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 717 | − | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) | |
| 718 | − | SSC_BF(RFMR_FSLEN, 0) | |
| 719 | − | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 720 | − | SSC_BIT(RFMR_MSBF) | |
| 721 | − | SSC_BF(RFMR_LOOP, 0) | |
| 722 | − | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 723 | − | |
| 724 | − tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | |
| 725 | − | SSC_BF(TCMR_STTDLY, 1) | |
| 726 | − | SSC_BF(TCMR_START, SSC_START_RISING_RF) | |
| 727 | − | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 728 | − | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) | |
| 729 | − | SSC_BF(TCMR_CKS, SSC_CKS_DIV); | |
| 730 | − | |
| 731 | − tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 732 | − | SSC_BF(TFMR_FSDEN, 0) | |
| 733 | − | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) | |
| 734 | − | SSC_BF(TFMR_FSLEN, 0) | |
| 735 | − | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 736 | − | SSC_BIT(TFMR_MSBF) | |
| 737 | − | SSC_BF(TFMR_DATDEF, 0) | |
| 738 | − | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 739 | 583 | break; |
| 740 | 584 | |
| 741 | − case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: | |
| 585 | + case SND_SOC_DAIFMT_DSP_A: | |
| 742 | 586 | /* |
| 743 | − * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. | |
| 587 | + * DSP/PCM Mode A format | |
| 744 | 588 | * |
| 745 | 589 | * Data is transferred on first BCLK after LRC pulse rising |
| 746 | 590 | * edge.If stereo, the right channel data is contiguous with |
| 747 | 591 | * the left channel data. |
| 748 | 592 | */ |
| 749 | − rcmr = SSC_BF(RCMR_PERIOD, 0) | |
| 750 | − | SSC_BF(RCMR_STTDLY, START_DELAY) | |
| 751 | − | SSC_BF(RCMR_START, SSC_START_RISING_RF) | |
| 752 | − | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 753 | − | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | |
| 754 | − | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | |
| 755 | − SSC_CKS_PIN : SSC_CKS_CLOCK); | |
| 756 | − | |
| 757 | − rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 758 | − | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) | |
| 759 | − | SSC_BF(RFMR_FSLEN, 0) | |
| 760 | − | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 761 | − | SSC_BIT(RFMR_MSBF) | |
| 762 | − | SSC_BF(RFMR_LOOP, 0) | |
| 763 | − | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 764 | − | |
| 765 | − tcmr = SSC_BF(TCMR_PERIOD, 0) | |
| 766 | − | SSC_BF(TCMR_STTDLY, START_DELAY) | |
| 767 | − | SSC_BF(TCMR_START, SSC_START_RISING_RF) | |
| 768 | − | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | |
| 769 | − | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | |
| 770 | − | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | |
| 771 | − SSC_CKS_CLOCK : SSC_CKS_PIN); | |
| 772 | − | |
| 773 | − tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 774 | − | SSC_BF(TFMR_FSDEN, 0) | |
| 775 | − | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) | |
| 776 | − | SSC_BF(TFMR_FSLEN, 0) | |
| 777 | − | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 778 | − | SSC_BIT(TFMR_MSBF) | |
| 779 | − | SSC_BF(TFMR_DATDEF, 0) | |
| 780 | − | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 593 | + fs_osync = SSC_FSOS_POSITIVE; | |
| 594 | + fs_edge = SSC_START_RISING_RF; | |
| 595 | + fslen = fslen_ext = 0; | |
| 596 | + | |
| 597 | + rcmr = SSC_BF(RCMR_STTDLY, 1); | |
| 598 | + tcmr = SSC_BF(TCMR_STTDLY, 1); | |
| 599 | + | |
| 781 | 600 | break; |
| 782 | 601 | |
| 783 | 602 | default: |
| @@ -785,6 +604,70 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line | ||
| 785 | 604 | ssc_p->daifmt); |
| 786 | 605 | return -EINVAL; |
| 787 | 606 | } |
| 607 | + | |
| 608 | + if (!atmel_ssc_cfs(ssc_p)) { | |
| 609 | + fslen = fslen_ext = 0; | |
| 610 | + rcmr_period = tcmr_period = 0; | |
| 611 | + fs_osync = SSC_FSOS_NONE; | |
| 612 | + } | |
| 613 | + | |
| 614 | + rcmr |= SSC_BF(RCMR_START, fs_edge); | |
| 615 | + tcmr |= SSC_BF(TCMR_START, fs_edge); | |
| 616 | + | |
| 617 | + if (atmel_ssc_cbs(ssc_p)) { | |
| 618 | + /* | |
| 619 | + * SSC provides BCLK | |
| 620 | + * | |
| 621 | + * The SSC transmit and receive clocks are generated from the | |
| 622 | + * MCK divider, and the BCLK signal is output | |
| 623 | + * on the SSC TK line. | |
| 624 | + */ | |
| 625 | + rcmr |= SSC_BF(RCMR_CKS, SSC_CKS_DIV) | |
| 626 | + | SSC_BF(RCMR_CKO, SSC_CKO_NONE); | |
| 627 | + | |
| 628 | + tcmr |= SSC_BF(TCMR_CKS, SSC_CKS_DIV) | |
| 629 | + | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS); | |
| 630 | + } else { | |
| 631 | + rcmr |= SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | |
| 632 | + SSC_CKS_PIN : SSC_CKS_CLOCK) | |
| 633 | + | SSC_BF(RCMR_CKO, SSC_CKO_NONE); | |
| 634 | + | |
| 635 | + tcmr |= SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? | |
| 636 | + SSC_CKS_CLOCK : SSC_CKS_PIN) | |
| 637 | + | SSC_BF(TCMR_CKO, SSC_CKO_NONE); | |
| 638 | + } | |
| 639 | + | |
| 640 | + rcmr |= SSC_BF(RCMR_PERIOD, rcmr_period) | |
| 641 | + | SSC_BF(RCMR_CKI, SSC_CKI_RISING); | |
| 642 | + | |
| 643 | + tcmr |= SSC_BF(TCMR_PERIOD, tcmr_period) | |
| 644 | + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING); | |
| 645 | + | |
| 646 | + rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) | |
| 647 | + | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 648 | + | SSC_BF(RFMR_FSOS, fs_osync) | |
| 649 | + | SSC_BF(RFMR_FSLEN, fslen) | |
| 650 | + | SSC_BF(RFMR_DATNB, (channels - 1)) | |
| 651 | + | SSC_BIT(RFMR_MSBF) | |
| 652 | + | SSC_BF(RFMR_LOOP, 0) | |
| 653 | + | SSC_BF(RFMR_DATLEN, (bits - 1)); | |
| 654 | + | |
| 655 | + tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) | |
| 656 | + | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | |
| 657 | + | SSC_BF(TFMR_FSDEN, 0) | |
| 658 | + | SSC_BF(TFMR_FSOS, fs_osync) | |
| 659 | + | SSC_BF(TFMR_FSLEN, fslen) | |
| 660 | + | SSC_BF(TFMR_DATNB, (channels - 1)) | |
| 661 | + | SSC_BIT(TFMR_MSBF) | |
| 662 | + | SSC_BF(TFMR_DATDEF, 0) | |
| 663 | + | SSC_BF(TFMR_DATLEN, (bits - 1)); | |
| 664 | + | |
| 665 | + if (fslen_ext && !ssc->pdata->has_fslen_ext) { | |
| 666 | + dev_err(dai->dev, "sample size %d is too large for SSC device\n", | |
| 667 | + bits); | |
| 668 | + return -EINVAL; | |
| 669 | + } | |
| 670 | + | |
| 788 | 671 | pr_debug("atmel_ssc_hw_params: " |
| 789 | 672 | "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", |
| 790 | 673 | rcmr, rfmr, tcmr, tfmr); |
| @@ -392,11 +392,11 @@ static int mchp_i2s_mcc_clk_get_rate_diff(struct clk *clk, · 391 unmodified lines | ||
| 392 | 392 | } |
| 393 | 393 | |
| 394 | 394 | static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, |
| 395 | − unsigned int bclk, unsigned int *mra) | |
| 395 | + unsigned int bclk, unsigned int *mra, | |
| 396 | + unsigned long *best_rate) | |
| 396 | 397 | { |
| 397 | 398 | unsigned long clk_rate; |
| 398 | 399 | unsigned long lcm_rate; |
| 399 | − unsigned long best_rate = 0; | |
| 400 | 400 | unsigned long best_diff_rate = ~0; |
| 401 | 401 | unsigned int sysclk; |
| 402 | 402 | struct clk *best_clk = NULL; |
| @@ -423,7 +423,7 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, · 20 unmodified lines | ||
| 423 | 423 | (clk_rate == bclk || clk_rate / (bclk * 2) <= GENMASK(5, 0)); |
| 424 | 424 | clk_rate += lcm_rate) { |
| 425 | 425 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->gclk, clk_rate, |
| 426 | − &best_clk, &best_rate, | |
| 426 | + &best_clk, best_rate, | |
| 427 | 427 | &best_diff_rate); |
| 428 | 428 | if (ret) { |
| 429 | 429 | dev_err(dev->dev, "gclk error for rate %lu: %d", |
| @@ -437,7 +437,7 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, · 7 unmodified lines | ||
| 437 | 437 | } |
| 438 | 438 | |
| 439 | 439 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->pclk, clk_rate, |
| 440 | − &best_clk, &best_rate, | |
| 440 | + &best_clk, best_rate, | |
| 441 | 441 | &best_diff_rate); |
| 442 | 442 | if (ret) { |
| 443 | 443 | dev_err(dev->dev, "pclk error for rate %lu: %d", |
| @@ -459,33 +459,17 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, · 15 unmodified lines | ||
| 459 | 459 | |
| 460 | 460 | dev_dbg(dev->dev, "source CLK is %s with rate %lu, diff %lu\n", |
| 461 | 461 | best_clk == dev->pclk ? "pclk" : "gclk", |
| 462 | − best_rate, best_diff_rate); | |
| 463 | − | |
| 464 | − /* set the rate */ | |
| 465 | − ret = clk_set_rate(best_clk, best_rate); | |
| 466 | − if (ret) { | |
| 467 | − dev_err(dev->dev, "unable to set rate %lu to %s: %d\n", | |
| 468 | − best_rate, best_clk == dev->pclk ? "PCLK" : "GCLK", | |
| 469 | − ret); | |
| 470 | − return ret; | |
| 471 | − } | |
| 462 | + *best_rate, best_diff_rate); | |
| 472 | 463 | |
| 473 | 464 | /* Configure divisors */ |
| 474 | 465 | if (dev->sysclk) |
| 475 | − *mra |= MCHP_I2SMCC_MRA_IMCKDIV(best_rate / (2 * sysclk)); | |
| 476 | − *mra |= MCHP_I2SMCC_MRA_ISCKDIV(best_rate / (2 * bclk)); | |
| 466 | + *mra |= MCHP_I2SMCC_MRA_IMCKDIV(*best_rate / (2 * sysclk)); | |
| 467 | + *mra |= MCHP_I2SMCC_MRA_ISCKDIV(*best_rate / (2 * bclk)); | |
| 477 | 468 | |
| 478 | − if (best_clk == dev->gclk) { | |
| 469 | + if (best_clk == dev->gclk) | |
| 479 | 470 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_GCLK; |
| 480 | − ret = clk_prepare(dev->gclk); | |
| 481 | − if (ret < 0) | |
| 482 | − dev_err(dev->dev, "unable to prepare GCLK: %d\n", ret); | |
| 483 | − else | |
| 484 | − dev->gclk_use = 1; | |
| 485 | − } else { | |
| 471 | + else | |
| 486 | 472 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_PCLK; |
| 487 | − dev->gclk_use = 0; | |
| 488 | − } | |
| 489 | 473 | |
| 490 | 474 | return 0; |
| 491 | 475 | } |
| @@ -502,6 +486,7 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, · 10 unmodified lines | ||
| 502 | 486 | struct snd_pcm_hw_params *params, |
| 503 | 487 | struct snd_soc_dai *dai) |
| 504 | 488 | { |
| 489 | + unsigned long rate = 0; | |
| 505 | 490 | struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai); |
| 506 | 491 | u32 mra = 0; |
| 507 | 492 | u32 mrb = 0; |
| @@ -640,6 +625,17 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, · 132 unmodified lines | ||
| 640 | 625 | return -EINVAL; |
| 641 | 626 | } |
| 642 | 627 | |
| 628 | + if (set_divs) { | |
| 629 | + bclk_rate = frame_length * params_rate(params); | |
| 630 | + ret = mchp_i2s_mcc_config_divs(dev, bclk_rate, &mra, | |
| 631 | + &rate); | |
| 632 | + if (ret) { | |
| 633 | + dev_err(dev->dev, | |
| 634 | + "unable to configure the divisors: %d\n", ret); | |
| 635 | + return ret; | |
| 636 | + } | |
| 637 | + } | |
| 638 | + | |
| 643 | 639 | /* |
| 644 | 640 | * If we are already running, the wanted setup must be |
| 645 | 641 | * the same with the one that's currently ongoing |
| @@ -656,19 +652,27 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, · 10 unmodified lines | ||
| 656 | 652 | return 0; |
| 657 | 653 | } |
| 658 | 654 | |
| 659 | − /* Save the number of channels to know what interrupts to enable */ | |
| 660 | − dev->channels = channels; | |
| 661 | − | |
| 662 | − if (set_divs) { | |
| 663 | − bclk_rate = frame_length * params_rate(params); | |
| 664 | − ret = mchp_i2s_mcc_config_divs(dev, bclk_rate, &mra); | |
| 655 | + if (mra & MCHP_I2SMCC_MRA_SRCCLK_GCLK && !dev->gclk_use) { | |
| 656 | + /* set the rate */ | |
| 657 | + ret = clk_set_rate(dev->gclk, rate); | |
| 665 | 658 | if (ret) { |
| 666 | − dev_err(dev->dev, "unable to configure the divisors: %d\n", | |
| 667 | − ret); | |
| 659 | + dev_err(dev->dev, | |
| 660 | + "unable to set rate %lu to GCLK: %d\n", | |
| 661 | + rate, ret); | |
| 662 | + return ret; | |
| 663 | + } | |
| 664 | + | |
| 665 | + ret = clk_prepare(dev->gclk); | |
| 666 | + if (ret < 0) { | |
| 667 | + dev_err(dev->dev, "unable to prepare GCLK: %d\n", ret); | |
| 668 | 668 | return ret; |
| 669 | 669 | } |
| 670 | + dev->gclk_use = 1; | |
| 670 | 671 | } |
| 671 | 672 | |
| 673 | + /* Save the number of channels to know what interrupts to enable */ | |
| 674 | + dev->channels = channels; | |
| 675 | + | |
| 672 | 676 | ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra); |
| 673 | 677 | if (ret < 0) { |
| 674 | 678 | if (dev->gclk_use) { |
| @@ -363,7 +363,7 @@ static const struct snd_soc_component_driver au1xpsc_ac97_component = { · 362 unmodified lines | ||
| 363 | 363 | static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) |
| 364 | 364 | { |
| 365 | 365 | int ret; |
| 366 | − struct resource *iores, *dmares; | |
| 366 | + struct resource *dmares; | |
| 367 | 367 | unsigned long sel; |
| 368 | 368 | struct au1xpsc_audio_data *wd; |
| 369 | 369 | |
| @@ -374,8 +374,7 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) · 4 unmodified lines | ||
| 374 | 374 | |
| 375 | 375 | mutex_init(&wd->lock); |
| 376 | 376 | |
| 377 | − iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 378 | − wd->mmio = devm_ioremap_resource(&pdev->dev, iores); | |
| 377 | + wd->mmio = devm_platform_ioremap_resource(pdev, 0); | |
| 379 | 378 | if (IS_ERR(wd->mmio)) |
| 380 | 379 | return PTR_ERR(wd->mmio); |
| 381 | 380 | |
| @@ -291,7 +291,7 @@ static const struct snd_soc_component_driver au1xpsc_i2s_component = { · 290 unmodified lines | ||
| 291 | 291 | |
| 292 | 292 | static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) |
| 293 | 293 | { |
| 294 | − struct resource *iores, *dmares; | |
| 294 | + struct resource *dmares; | |
| 295 | 295 | unsigned long sel; |
| 296 | 296 | struct au1xpsc_audio_data *wd; |
| 297 | 297 | |
| @@ -300,8 +300,7 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) · 2 unmodified lines | ||
| 300 | 300 | if (!wd) |
| 301 | 301 | return -ENOMEM; |
| 302 | 302 | |
| 303 | − iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 304 | − wd->mmio = devm_ioremap_resource(&pdev->dev, iores); | |
| 303 | + wd->mmio = devm_platform_ioremap_resource(pdev, 0); | |
| 305 | 304 | if (IS_ERR(wd->mmio)) |
| 306 | 305 | return PTR_ERR(wd->mmio); |
| 307 | 306 | |
| @@ -828,7 +828,6 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) · 827 unmodified lines | ||
| 828 | 828 | { |
| 829 | 829 | struct bcm2835_i2s_dev *dev; |
| 830 | 830 | int ret; |
| 831 | − struct resource *mem; | |
| 832 | 831 | void __iomem *base; |
| 833 | 832 | const __be32 *addr; |
| 834 | 833 | dma_addr_t dma_base; |
| @@ -848,8 +847,7 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 848 | 847 | } |
| 849 | 848 | |
| 850 | 849 | /* Request ioarea */ |
| 851 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 852 | − base = devm_ioremap_resource(&pdev->dev, mem); | |
| 850 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 853 | 851 | if (IS_ERR(base)) |
| 854 | 852 | return PTR_ERR(base); |
| 855 | 853 | |
| @@ -639,7 +639,6 @@ static int cygnus_pcm_hw_params(struct snd_pcm_substream *substream, · 638 unmodified lines | ||
| 639 | 639 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 640 | 640 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 641 | 641 | struct cygnus_aio_port *aio; |
| 642 | − int ret = 0; | |
| 643 | 642 | |
| 644 | 643 | aio = cygnus_dai_get_dma_data(substream); |
| 645 | 644 | dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); |
| @@ -647,7 +646,7 @@ static int cygnus_pcm_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line | ||
| 647 | 646 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
| 648 | 647 | runtime->dma_bytes = params_buffer_bytes(params); |
| 649 | 648 | |
| 650 | − return ret; | |
| 649 | + return 0; | |
| 651 | 650 | } |
| 652 | 651 | |
| 653 | 652 | static int cygnus_pcm_hw_free(struct snd_pcm_substream *substream) |
| @@ -668,7 +667,6 @@ static int cygnus_pcm_prepare(struct snd_pcm_substream *substream) · 14 unmodified lines | ||
| 668 | 667 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 669 | 668 | struct cygnus_aio_port *aio; |
| 670 | 669 | unsigned long bufsize, periodsize; |
| 671 | − int ret = 0; | |
| 672 | 670 | bool is_play; |
| 673 | 671 | u32 start; |
| 674 | 672 | struct ringbuf_regs *p_rbuf = NULL; |
| @@ -693,7 +691,7 @@ static int cygnus_pcm_prepare(struct snd_pcm_substream *substream) · 18 unmodified lines | ||
| 693 | 691 | ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start, |
| 694 | 692 | periodsize, bufsize); |
| 695 | 693 | |
| 696 | − return ret; | |
| 694 | + return 0; | |
| 697 | 695 | } |
| 698 | 696 | |
| 699 | 697 | static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream) |
| @@ -1342,11 +1342,8 @@ static int cygnus_ssp_probe(struct platform_device *pdev) · 1341 unmodified lines | ||
| 1342 | 1342 | } |
| 1343 | 1343 | |
| 1344 | 1344 | cygaud->irq_num = platform_get_irq(pdev, 0); |
| 1345 | − if (cygaud->irq_num <= 0) { | |
| 1346 | − dev_err(dev, "platform_get_irq failed\n"); | |
| 1347 | − err = cygaud->irq_num; | |
| 1348 | − return err; | |
| 1349 | − } | |
| 1345 | + if (cygaud->irq_num <= 0) | |
| 1346 | + return cygaud->irq_num; | |
| 1350 | 1347 | |
| 1351 | 1348 | err = audio_clk_init(pdev, cygaud); |
| 1352 | 1349 | if (err) { |
| @@ -362,7 +362,6 @@ static const struct snd_soc_component_driver ep93xx_ac97_component = { · 361 unmodified lines | ||
| 362 | 362 | static int ep93xx_ac97_probe(struct platform_device *pdev) |
| 363 | 363 | { |
| 364 | 364 | struct ep93xx_ac97_info *info; |
| 365 | − struct resource *res; | |
| 366 | 365 | int irq; |
| 367 | 366 | int ret; |
| 368 | 367 | |
| @@ -370,8 +369,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 370 | 369 | if (!info) |
| 371 | 370 | return -ENOMEM; |
| 372 | 371 | |
| 373 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 374 | − info->regs = devm_ioremap_resource(&pdev->dev, res); | |
| 372 | + info->regs = devm_platform_ioremap_resource(pdev, 0); | |
| 375 | 373 | if (IS_ERR(info->regs)) |
| 376 | 374 | return PTR_ERR(info->regs); |
| 377 | 375 | |
| @@ -430,15 +430,13 @@ static const struct snd_soc_component_driver ep93xx_i2s_component = { · 429 unmodified lines | ||
| 430 | 430 | static int ep93xx_i2s_probe(struct platform_device *pdev) |
| 431 | 431 | { |
| 432 | 432 | struct ep93xx_i2s_info *info; |
| 433 | − struct resource *res; | |
| 434 | 433 | int err; |
| 435 | 434 | |
| 436 | 435 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
| 437 | 436 | if (!info) |
| 438 | 437 | return -ENOMEM; |
| 439 | 438 | |
| 440 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 441 | − info->regs = devm_ioremap_resource(&pdev->dev, res); | |
| 439 | + info->regs = devm_platform_ioremap_resource(pdev, 0); | |
| 442 | 440 | if (IS_ERR(info->regs)) |
| 443 | 441 | return PTR_ERR(info->regs); |
| 444 | 442 | |
| @@ -529,10 +529,6 @@ static const struct snd_kcontrol_new pm860x_snd_controls[] = { · 528 unmodified lines | ||
| 529 | 529 | * DAPM Controls |
| 530 | 530 | */ |
| 531 | 531 | |
| 532 | −/* PCM Switch / PCM Interface */ | |
| 533 | −static const struct snd_kcontrol_new pcm_switch_controls = | |
| 534 | − SOC_DAPM_SINGLE("Switch", PM860X_ADC_EN_2, 0, 1, 0); | |
| 535 | − | |
| 536 | 532 | /* AUX1 Switch */ |
| 537 | 533 | static const struct snd_kcontrol_new aux1_switch_controls = |
| 538 | 534 | SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0); |
| @@ -549,17 +545,6 @@ static const struct snd_kcontrol_new lepa_switch_controls = · 10 unmodified lines | ||
| 549 | 545 | static const struct snd_kcontrol_new repa_switch_controls = |
| 550 | 546 | SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0); |
| 551 | 547 | |
| 552 | −/* PCM Mux / Mux7 */ | |
| 553 | −static const char *aif1_text[] = { | |
| 554 | − "PCM L", "PCM R", | |
| 555 | −}; | |
| 556 | − | |
| 557 | −static SOC_ENUM_SINGLE_DECL(aif1_enum, | |
| 558 | − PM860X_PCM_IFACE_3, 6, aif1_text); | |
| 559 | − | |
| 560 | −static const struct snd_kcontrol_new aif1_mux = | |
| 561 | − SOC_DAPM_ENUM("PCM Mux", aif1_enum); | |
| 562 | − | |
| 563 | 548 | /* I2S Mux / Mux9 */ |
| 564 | 549 | static const char *i2s_din_text[] = { |
| 565 | 550 | "DIN", "DIN1", |
| @@ -70,10 +70,12 @@ config SND_SOC_ALL_CODECS · 69 unmodified lines | ||
| 70 | 70 | select SND_SOC_CS43130 if I2C |
| 71 | 71 | select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI |
| 72 | 72 | select SND_SOC_CS4349 if I2C |
| 73 | + select SND_SOC_CS47L15 if MFD_CS47L15 | |
| 73 | 74 | select SND_SOC_CS47L24 if MFD_CS47L24 |
| 74 | 75 | select SND_SOC_CS47L35 if MFD_CS47L35 |
| 75 | 76 | select SND_SOC_CS47L85 if MFD_CS47L85 |
| 76 | 77 | select SND_SOC_CS47L90 if MFD_CS47L90 |
| 78 | + select SND_SOC_CS47L92 if MFD_CS47L92 | |
| 77 | 79 | select SND_SOC_CS53L30 if I2C |
| 78 | 80 | select SND_SOC_CX20442 if TTY |
| 79 | 81 | select SND_SOC_CX2072X if I2C |
| @@ -197,6 +199,7 @@ config SND_SOC_ALL_CODECS · 117 unmodified lines | ||
| 197 | 199 | select SND_SOC_TS3A227E if I2C |
| 198 | 200 | select SND_SOC_TWL4030 if TWL4030_CORE |
| 199 | 201 | select SND_SOC_TWL6040 if TWL6040_CORE |
| 202 | + select SND_SOC_UDA1334 if GPIOLIB | |
| 200 | 203 | select SND_SOC_UDA134X |
| 201 | 204 | select SND_SOC_UDA1380 if I2C |
| 202 | 205 | select SND_SOC_WCD9335 if SLIMBUS |
| @@ -581,6 +584,9 @@ config SND_SOC_CS4349 · 378 unmodified lines | ||
| 581 | 584 | tristate "Cirrus Logic CS4349 CODEC" |
| 582 | 585 | depends on I2C |
| 583 | 586 | |
| 587 | +config SND_SOC_CS47L15 | |
| 588 | + tristate | |
| 589 | + | |
| 584 | 590 | config SND_SOC_CS47L24 |
| 585 | 591 | tristate |
| 586 | 592 | |
| @@ -593,6 +599,9 @@ config SND_SOC_CS47L85 · 6 unmodified lines | ||
| 593 | 599 | config SND_SOC_CS47L90 |
| 594 | 600 | tristate |
| 595 | 601 | |
| 602 | +config SND_SOC_CS47L92 | |
| 603 | + tristate | |
| 604 | + | |
| 596 | 605 | # Cirrus Logic Quad-Channel ADC |
| 597 | 606 | config SND_SOC_CS53L30 |
| 598 | 607 | tristate "Cirrus Logic CS53L30 CODEC" |
| @@ -722,12 +731,16 @@ config SND_SOC_LOCHNAGAR_SC · 123 unmodified lines | ||
| 722 | 731 | |
| 723 | 732 | config SND_SOC_MADERA |
| 724 | 733 | tristate |
| 734 | + default y if SND_SOC_CS47L15=y | |
| 725 | 735 | default y if SND_SOC_CS47L35=y |
| 726 | 736 | default y if SND_SOC_CS47L85=y |
| 727 | 737 | default y if SND_SOC_CS47L90=y |
| 738 | + default y if SND_SOC_CS47L92=y | |
| 739 | + default m if SND_SOC_CS47L15=m | |
| 728 | 740 | default m if SND_SOC_CS47L35=m |
| 729 | 741 | default m if SND_SOC_CS47L85=m |
| 730 | 742 | default m if SND_SOC_CS47L90=m |
| 743 | + default m if SND_SOC_CS47L92=m | |
| 731 | 744 | |
| 732 | 745 | config SND_SOC_MAX98088 |
| 733 | 746 | tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec" |
| @@ -1195,6 +1208,14 @@ config SND_SOC_TWL4030 · 461 unmodified lines | ||
| 1195 | 1208 | config SND_SOC_TWL6040 |
| 1196 | 1209 | tristate |
| 1197 | 1210 | |
| 1211 | +config SND_SOC_UDA1334 | |
| 1212 | + tristate "NXP UDA1334 DAC" | |
| 1213 | + depends on GPIOLIB | |
| 1214 | + help | |
| 1215 | + The UDA1334 is an NXP audio codec, supports the I2S-bus data format | |
| 1216 | + and has basic features such as de-emphasis (at 44.1 kHz sampling | |
| 1217 | + rate) and mute. | |
| 1218 | + | |
| 1198 | 1219 | config SND_SOC_UDA134X |
| 1199 | 1220 | tristate |
| 1200 | 1221 | |
| @@ -64,10 +64,12 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o · 63 unmodified lines | ||
| 64 | 64 | snd-soc-cs43130-objs := cs43130.o |
| 65 | 65 | snd-soc-cs4341-objs := cs4341.o |
| 66 | 66 | snd-soc-cs4349-objs := cs4349.o |
| 67 | +snd-soc-cs47l15-objs := cs47l15.o | |
| 67 | 68 | snd-soc-cs47l24-objs := cs47l24.o |
| 68 | 69 | snd-soc-cs47l35-objs := cs47l35.o |
| 69 | 70 | snd-soc-cs47l85-objs := cs47l85.o |
| 70 | 71 | snd-soc-cs47l90-objs := cs47l90.o |
| 72 | +snd-soc-cs47l92-objs := cs47l92.o | |
| 71 | 73 | snd-soc-cs53l30-objs := cs53l30.o |
| 72 | 74 | snd-soc-cx20442-objs := cx20442.o |
| 73 | 75 | snd-soc-cx2072x-objs := cx2072x.o |
| @@ -210,6 +212,7 @@ snd-soc-tscs454-objs := tscs454.o · 136 unmodified lines | ||
| 210 | 212 | snd-soc-ts3a227e-objs := ts3a227e.o |
| 211 | 213 | snd-soc-twl4030-objs := twl4030.o |
| 212 | 214 | snd-soc-twl6040-objs := twl6040.o |
| 215 | +snd-soc-uda1334-objs := uda1334.o | |
| 213 | 216 | snd-soc-uda134x-objs := uda134x.o |
| 214 | 217 | snd-soc-uda1380-objs := uda1380.o |
| 215 | 218 | snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o |
| @@ -346,9 +349,11 @@ obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o · 130 unmodified lines | ||
| 346 | 349 | obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o |
| 347 | 350 | obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o |
| 348 | 351 | obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o |
| 352 | +obj-$(CONFIG_SND_SOC_CS47L15) += snd-soc-cs47l15.o | |
| 349 | 353 | obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o |
| 350 | 354 | obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o |
| 351 | 355 | obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o |
| 356 | +obj-$(CONFIG_SND_SOC_CS47L92) += snd-soc-cs47l92.o | |
| 352 | 357 | obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o |
| 353 | 358 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o |
| 354 | 359 | obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o |
| @@ -490,6 +495,7 @@ obj-$(CONFIG_SND_SOC_TSCS454) += snd-soc-tscs454.o · 135 unmodified lines | ||
| 490 | 495 | obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o |
| 491 | 496 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
| 492 | 497 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o |
| 498 | +obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o | |
| 493 | 499 | obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o |
| 494 | 500 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o |
| 495 | 501 | obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o |
| @@ -413,15 +413,10 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = { · 412 unmodified lines | ||
| 413 | 413 | .ops = &ad193x_dai_ops, |
| 414 | 414 | }; |
| 415 | 415 | |
| 416 | −struct ad193x_reg_default { | |
| 417 | − unsigned int reg; | |
| 418 | − unsigned int val; | |
| 419 | −}; | |
| 420 | − | |
| 421 | 416 | /* codec register values to set after reset */ |
| 422 | 417 | static void ad193x_reg_default_init(struct ad193x_priv *ad193x) |
| 423 | 418 | { |
| 424 | − const struct ad193x_reg_default reg_init[] = { | |
| 419 | + static const struct reg_sequence reg_init[] = { | |
| 425 | 420 | { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */ |
| 426 | 421 | { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */ |
| 427 | 422 | { 2, 0x40 }, /* DAC_CTRL0: TDM mode */ |
| @@ -437,21 +432,17 @@ static void ad193x_reg_default_init(struct ad193x_priv *ad193x) · 9 unmodified lines | ||
| 437 | 432 | { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */ |
| 438 | 433 | { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */ |
| 439 | 434 | }; |
| 440 | − const struct ad193x_reg_default reg_adc_init[] = { | |
| 435 | + static const struct reg_sequence reg_adc_init[] = { | |
| 441 | 436 | { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */ |
| 442 | 437 | { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */ |
| 443 | 438 | { 16, 0x00 }, /* ADC_CTRL2: reset */ |
| 444 | 439 | }; |
| 445 | − int i; | |
| 446 | 440 | |
| 447 | − for (i = 0; i < ARRAY_SIZE(reg_init); i++) | |
| 448 | − regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val); | |
| 441 | + regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init)); | |
| 449 | 442 | |
| 450 | 443 | if (ad193x_has_adc(ad193x)) { |
| 451 | − for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) { | |
| 452 | − regmap_write(ad193x->regmap, reg_adc_init[i].reg, | |
| 453 | − reg_adc_init[i].val); | |
| 454 | − } | |
| 444 | + regmap_multi_reg_write(ad193x->regmap, reg_adc_init, | |
| 445 | + ARRAY_SIZE(reg_adc_init)); | |
| 455 | 446 | } |
| 456 | 447 | } |
| 457 | 448 | |
| @@ -334,7 +334,7 @@ static struct cs4271_clk_cfg cs4271_clk_tab[] = { · 333 unmodified lines | ||
| 334 | 334 | {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2}, |
| 335 | 335 | }; |
| 336 | 336 | |
| 337 | −#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab) | |
| 337 | +#define CS4271_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab) | |
| 338 | 338 | |
| 339 | 339 | static int cs4271_hw_params(struct snd_pcm_substream *substream, |
| 340 | 340 | struct snd_pcm_hw_params *params, |
| @@ -383,13 +383,13 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream, · 42 unmodified lines | ||
| 383 | 383 | val = CS4271_MODE1_MODE_4X; |
| 384 | 384 | |
| 385 | 385 | ratio = cs4271->mclk / cs4271->rate; |
| 386 | − for (i = 0; i < CS4171_NR_RATIOS; i++) | |
| 386 | + for (i = 0; i < CS4271_NR_RATIOS; i++) | |
| 387 | 387 | if ((cs4271_clk_tab[i].master == cs4271->master) && |
| 388 | 388 | (cs4271_clk_tab[i].speed_mode == val) && |
| 389 | 389 | (cs4271_clk_tab[i].ratio == ratio)) |
| 390 | 390 | break; |
| 391 | 391 | |
| 392 | − if (i == CS4171_NR_RATIOS) { | |
| 392 | + if (i == CS4271_NR_RATIOS) { | |
| 393 | 393 | dev_err(component->dev, "Invalid sample rate\n"); |
| 394 | 394 | return -EINVAL; |
| 395 | 395 | } |
| @@ -199,14 +199,6 @@ static const struct soc_enum beep_bass_enum = · 198 unmodified lines | ||
| 199 | 199 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, |
| 200 | 200 | ARRAY_SIZE(beep_bass_text), beep_bass_text); |
| 201 | 201 | |
| 202 | −static const char * const adc_swap_text[] = { | |
| 203 | − "None", "A+B/2", "A-B/2", "Swap" | |
| 204 | −}; | |
| 205 | − | |
| 206 | −static const struct soc_enum adc_swap_enum = | |
| 207 | − SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3, | |
| 208 | − ARRAY_SIZE(adc_swap_text), adc_swap_text); | |
| 209 | − | |
| 210 | 202 | static const char * const pgaa_mux_text[] = { |
| 211 | 203 | "AIN1A", "AIN2A", "AIN3A"}; |
| 212 | 204 | |
| @@ -273,12 +273,6 @@ static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum, · 272 unmodified lines | ||
| 273 | 273 | CS42L73_MIXERCTL, 4, |
| 274 | 274 | cs42l73_spo_mixer_text); |
| 275 | 275 | |
| 276 | −static const struct snd_kcontrol_new vsp_output_mux = | |
| 277 | − SOC_DAPM_ENUM("Route", vsp_output_mux_enum); | |
| 278 | − | |
| 279 | −static const struct snd_kcontrol_new xsp_output_mux = | |
| 280 | − SOC_DAPM_ENUM("Route", xsp_output_mux_enum); | |
| 281 | − | |
| 282 | 276 | static const struct snd_kcontrol_new hp_amp_ctl = |
| 283 | 277 | SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1); |
| 284 | 278 | |
| @@ -684,6 +684,8 @@ static int cs42xx8_runtime_suspend(struct device *dev) · 683 unmodified lines | ||
| 684 | 684 | #endif |
| 685 | 685 | |
| 686 | 686 | const struct dev_pm_ops cs42xx8_pm = { |
| 687 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | |
| 688 | + pm_runtime_force_resume) | |
| 687 | 689 | SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) |
| 688 | 690 | }; |
| 689 | 691 | EXPORT_SYMBOL_GPL(cs42xx8_pm); |
| @@ -0,0 +1,1490 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +// | |
| 3 | +// ALSA SoC Audio driver for CS47L15 codec | |
| 4 | +// | |
| 5 | +// Copyright (C) 2016-2019 Cirrus Logic, Inc. and | |
| 6 | +// Cirrus Logic International Semiconductor Ltd. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#include <linux/module.h> | |
| 10 | +#include <linux/moduleparam.h> | |
| 11 | +#include <linux/device.h> | |
| 12 | +#include <linux/delay.h> | |
| 13 | +#include <linux/init.h> | |
| 14 | +#include <linux/pm.h> | |
| 15 | +#include <linux/pm_runtime.h> | |
| 16 | +#include <linux/regmap.h> | |
| 17 | +#include <sound/core.h> | |
| 18 | +#include <sound/pcm.h> | |
| 19 | +#include <sound/pcm_params.h> | |
| 20 | +#include <sound/soc.h> | |
| 21 | +#include <sound/tlv.h> | |
| 22 | + | |
| 23 | +#include <linux/irqchip/irq-madera.h> | |
| 24 | +#include <linux/mfd/madera/core.h> | |
| 25 | +#include <linux/mfd/madera/registers.h> | |
| 26 | + | |
| 27 | +#include "madera.h" | |
| 28 | +#include "wm_adsp.h" | |
| 29 | + | |
| 30 | +#define CS47L15_NUM_ADSP 1 | |
| 31 | +#define CS47L15_MONO_OUTPUTS 1 | |
| 32 | + | |
| 33 | +/* Mid-mode registers */ | |
| 34 | +#define CS47L15_ADC_INT_BIAS_MASK 0x3800 | |
| 35 | +#define CS47L15_ADC_INT_BIAS_SHIFT 11 | |
| 36 | +#define CS47L15_PGA_BIAS_SEL_MASK 0x03 | |
| 37 | +#define CS47L15_PGA_BIAS_SEL_SHIFT 0 | |
| 38 | + | |
| 39 | +#define DRV_NAME "cs47l15-codec" | |
| 40 | + | |
| 41 | +struct cs47l15 { | |
| 42 | + struct madera_priv core; | |
| 43 | + struct madera_fll fll[2]; | |
| 44 | + | |
| 45 | + bool in1_lp_mode; | |
| 46 | +}; | |
| 47 | + | |
| 48 | +static const struct wm_adsp_region cs47l15_dsp1_regions[] = { | |
| 49 | + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, | |
| 50 | + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, | |
| 51 | + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, | |
| 52 | + { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, | |
| 53 | +}; | |
| 54 | + | |
| 55 | +static const char * const cs47l15_outdemux_texts[] = { | |
| 56 | + "HPOUT", | |
| 57 | + "EPOUT", | |
| 58 | +}; | |
| 59 | + | |
| 60 | +static SOC_ENUM_SINGLE_DECL(cs47l15_outdemux_enum, SND_SOC_NOPM, 0, | |
| 61 | + cs47l15_outdemux_texts); | |
| 62 | + | |
| 63 | +static const struct snd_kcontrol_new cs47l15_outdemux = | |
| 64 | + SOC_DAPM_ENUM_EXT("HPOUT1 Demux", cs47l15_outdemux_enum, | |
| 65 | + madera_out1_demux_get, madera_out1_demux_put); | |
| 66 | + | |
| 67 | +static int cs47l15_adsp_power_ev(struct snd_soc_dapm_widget *w, | |
| 68 | + struct snd_kcontrol *kcontrol, | |
| 69 | + int event) | |
| 70 | +{ | |
| 71 | + struct snd_soc_component *component = | |
| 72 | + snd_soc_dapm_to_component(w->dapm); | |
| 73 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 74 | + struct madera_priv *priv = &cs47l15->core; | |
| 75 | + struct madera *madera = priv->madera; | |
| 76 | + unsigned int freq; | |
| 77 | + int ret; | |
| 78 | + | |
| 79 | + ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_2, &freq); | |
| 80 | + if (ret != 0) { | |
| 81 | + dev_err(madera->dev, | |
| 82 | + "Failed to read MADERA_DSP_CLOCK_2: %d\n", ret); | |
| 83 | + return ret; | |
| 84 | + } | |
| 85 | + | |
| 86 | + switch (event) { | |
| 87 | + case SND_SOC_DAPM_PRE_PMU: | |
| 88 | + ret = madera_set_adsp_clk(&cs47l15->core, w->shift, freq); | |
| 89 | + if (ret) | |
| 90 | + return ret; | |
| 91 | + break; | |
| 92 | + default: | |
| 93 | + break; | |
| 94 | + } | |
| 95 | + | |
| 96 | + return wm_adsp_early_event(w, kcontrol, event); | |
| 97 | +} | |
| 98 | + | |
| 99 | +#define CS47L15_NG_SRC(name, base) \ | |
| 100 | + SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ | |
| 101 | + SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ | |
| 102 | + SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \ | |
| 103 | + SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \ | |
| 104 | + SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0) | |
| 105 | + | |
| 106 | +static int cs47l15_in1_adc_get(struct snd_kcontrol *kcontrol, | |
| 107 | + struct snd_ctl_elem_value *ucontrol) | |
| 108 | +{ | |
| 109 | + struct snd_soc_component *component = | |
| 110 | + snd_soc_kcontrol_component(kcontrol); | |
| 111 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 112 | + | |
| 113 | + ucontrol->value.integer.value[0] = !!cs47l15->in1_lp_mode; | |
| 114 | + | |
| 115 | + return 0; | |
| 116 | +} | |
| 117 | + | |
| 118 | +static int cs47l15_in1_adc_put(struct snd_kcontrol *kcontrol, | |
| 119 | + struct snd_ctl_elem_value *ucontrol) | |
| 120 | +{ | |
| 121 | + struct snd_soc_component *component = | |
| 122 | + snd_soc_kcontrol_component(kcontrol); | |
| 123 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 124 | + | |
| 125 | + switch (ucontrol->value.integer.value[0]) { | |
| 126 | + case 0: | |
| 127 | + /* Set IN1 to normal mode */ | |
| 128 | + snd_soc_component_update_bits(component, MADERA_DMIC1L_CONTROL, | |
| 129 | + MADERA_IN1_OSR_MASK, | |
| 130 | + 5 << MADERA_IN1_OSR_SHIFT); | |
| 131 | + snd_soc_component_update_bits(component, CS47L15_ADC_INT_BIAS, | |
| 132 | + CS47L15_ADC_INT_BIAS_MASK, | |
| 133 | + 4 << CS47L15_ADC_INT_BIAS_SHIFT); | |
| 134 | + snd_soc_component_update_bits(component, CS47L15_PGA_BIAS_SEL, | |
| 135 | + CS47L15_PGA_BIAS_SEL_MASK, 0); | |
| 136 | + cs47l15->in1_lp_mode = false; | |
| 137 | + break; | |
| 138 | + default: | |
| 139 | + /* Set IN1 to LP mode */ | |
| 140 | + snd_soc_component_update_bits(component, MADERA_DMIC1L_CONTROL, | |
| 141 | + MADERA_IN1_OSR_MASK, | |
| 142 | + 4 << MADERA_IN1_OSR_SHIFT); | |
| 143 | + snd_soc_component_update_bits(component, CS47L15_ADC_INT_BIAS, | |
| 144 | + CS47L15_ADC_INT_BIAS_MASK, | |
| 145 | + 1 << CS47L15_ADC_INT_BIAS_SHIFT); | |
| 146 | + snd_soc_component_update_bits(component, CS47L15_PGA_BIAS_SEL, | |
| 147 | + CS47L15_PGA_BIAS_SEL_MASK, | |
| 148 | + 3 << CS47L15_PGA_BIAS_SEL_SHIFT); | |
| 149 | + cs47l15->in1_lp_mode = true; | |
| 150 | + break; | |
| 151 | + } | |
| 152 | + | |
| 153 | + return 0; | |
| 154 | +} | |
| 155 | + | |
| 156 | +static const struct snd_kcontrol_new cs47l15_snd_controls[] = { | |
| 157 | +SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]), | |
| 158 | +SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]), | |
| 159 | + | |
| 160 | +SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL, | |
| 161 | + MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 162 | +SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL, | |
| 163 | + MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 164 | + | |
| 165 | +SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum), | |
| 166 | + | |
| 167 | +SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL, MADERA_IN1L_HPF_SHIFT, 1, 0), | |
| 168 | +SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL, MADERA_IN1R_HPF_SHIFT, 1, 0), | |
| 169 | +SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL, MADERA_IN2L_HPF_SHIFT, 1, 0), | |
| 170 | +SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL, MADERA_IN2R_HPF_SHIFT, 1, 0), | |
| 171 | + | |
| 172 | +SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L, | |
| 173 | + MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 174 | +SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R, | |
| 175 | + MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 176 | +SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L, | |
| 177 | + MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 178 | +SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R, | |
| 179 | + MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 180 | + | |
| 181 | +SOC_ENUM("Input Ramp Up", madera_in_vi_ramp), | |
| 182 | +SOC_ENUM("Input Ramp Down", madera_in_vd_ramp), | |
| 183 | + | |
| 184 | +MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE), | |
| 185 | +MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE), | |
| 186 | +MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE), | |
| 187 | +MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE), | |
| 188 | + | |
| 189 | +MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2), | |
| 190 | +SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT, | |
| 191 | + 24, 0, madera_eq_tlv), | |
| 192 | +SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT, | |
| 193 | + 24, 0, madera_eq_tlv), | |
| 194 | +SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT, | |
| 195 | + 24, 0, madera_eq_tlv), | |
| 196 | +SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT, | |
| 197 | + 24, 0, madera_eq_tlv), | |
| 198 | +SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT, | |
| 199 | + 24, 0, madera_eq_tlv), | |
| 200 | + | |
| 201 | +MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2), | |
| 202 | +SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT, | |
| 203 | + 24, 0, madera_eq_tlv), | |
| 204 | +SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT, | |
| 205 | + 24, 0, madera_eq_tlv), | |
| 206 | +SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT, | |
| 207 | + 24, 0, madera_eq_tlv), | |
| 208 | +SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT, | |
| 209 | + 24, 0, madera_eq_tlv), | |
| 210 | +SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT, | |
| 211 | + 24, 0, madera_eq_tlv), | |
| 212 | + | |
| 213 | +MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2), | |
| 214 | +SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT, | |
| 215 | + 24, 0, madera_eq_tlv), | |
| 216 | +SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT, | |
| 217 | + 24, 0, madera_eq_tlv), | |
| 218 | +SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT, | |
| 219 | + 24, 0, madera_eq_tlv), | |
| 220 | +SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT, | |
| 221 | + 24, 0, madera_eq_tlv), | |
| 222 | +SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT, | |
| 223 | + 24, 0, madera_eq_tlv), | |
| 224 | + | |
| 225 | +MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2), | |
| 226 | +SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT, | |
| 227 | + 24, 0, madera_eq_tlv), | |
| 228 | +SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT, | |
| 229 | + 24, 0, madera_eq_tlv), | |
| 230 | +SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT, | |
| 231 | + 24, 0, madera_eq_tlv), | |
| 232 | +SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT, | |
| 233 | + 24, 0, madera_eq_tlv), | |
| 234 | +SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT, | |
| 235 | + 24, 0, madera_eq_tlv), | |
| 236 | + | |
| 237 | +MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE), | |
| 238 | +MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE), | |
| 239 | +MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE), | |
| 240 | +MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE), | |
| 241 | + | |
| 242 | +SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5, | |
| 243 | + MADERA_DRC1R_ENA | MADERA_DRC1L_ENA), | |
| 244 | +SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5, | |
| 245 | + MADERA_DRC2R_ENA | MADERA_DRC2L_ENA), | |
| 246 | + | |
| 247 | +MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE), | |
| 248 | +MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE), | |
| 249 | +MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE), | |
| 250 | +MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE), | |
| 251 | + | |
| 252 | +MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2), | |
| 253 | +MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2), | |
| 254 | +MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2), | |
| 255 | +MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2), | |
| 256 | + | |
| 257 | +SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode), | |
| 258 | +SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode), | |
| 259 | +SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode), | |
| 260 | +SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode), | |
| 261 | + | |
| 262 | +MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]), | |
| 263 | +MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]), | |
| 264 | +MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]), | |
| 265 | +MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]), | |
| 266 | + | |
| 267 | +WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), | |
| 268 | + | |
| 269 | +MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE), | |
| 270 | +MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE), | |
| 271 | + | |
| 272 | +SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR, | |
| 273 | + MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv), | |
| 274 | + | |
| 275 | +MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE), | |
| 276 | +MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE), | |
| 277 | +MADERA_MIXER_CONTROLS("SPKOUTL", MADERA_OUT4LMIX_INPUT_1_SOURCE), | |
| 278 | +MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE), | |
| 279 | +MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE), | |
| 280 | + | |
| 281 | +SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL, | |
| 282 | + MADERA_HP1_SC_ENA_SHIFT, 1, 0), | |
| 283 | + | |
| 284 | +SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L, | |
| 285 | + MADERA_OUT5_OSR_SHIFT, 1, 0), | |
| 286 | + | |
| 287 | +SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 288 | + MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1), | |
| 289 | +SOC_SINGLE("Speaker Digital Switch", MADERA_DAC_DIGITAL_VOLUME_4L, | |
| 290 | + MADERA_OUT4L_MUTE_SHIFT, 1, 1), | |
| 291 | +SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 292 | + MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1), | |
| 293 | + | |
| 294 | +SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 295 | + MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT, | |
| 296 | + 0xbf, 0, madera_digital_tlv), | |
| 297 | +SOC_SINGLE_TLV("Speaker Digital Volume", MADERA_DAC_DIGITAL_VOLUME_4L, | |
| 298 | + MADERA_OUT4L_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 299 | +SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 300 | + MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT, | |
| 301 | + 0xbf, 0, madera_digital_tlv), | |
| 302 | + | |
| 303 | +SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT, | |
| 304 | + MADERA_SPK1R_MUTE_SHIFT, 1, 1), | |
| 305 | + | |
| 306 | +SOC_ENUM("Output Ramp Up", madera_out_vi_ramp), | |
| 307 | +SOC_ENUM("Output Ramp Down", madera_out_vd_ramp), | |
| 308 | + | |
| 309 | +SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL, | |
| 310 | + MADERA_NGATE_ENA_SHIFT, 1, 0), | |
| 311 | +SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL, | |
| 312 | + MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv), | |
| 313 | +SOC_ENUM("Noise Gate Hold", madera_ng_hold), | |
| 314 | + | |
| 315 | +SOC_SINGLE_BOOL_EXT("IN1 LP Mode Switch", 0, | |
| 316 | + cs47l15_in1_adc_get, cs47l15_in1_adc_put), | |
| 317 | + | |
| 318 | +CS47L15_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L), | |
| 319 | +CS47L15_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R), | |
| 320 | +CS47L15_NG_SRC("SPKOUTL", MADERA_NOISE_GATE_SELECT_4L), | |
| 321 | +CS47L15_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L), | |
| 322 | +CS47L15_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R), | |
| 323 | + | |
| 324 | +MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE), | |
| 325 | +MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE), | |
| 326 | +MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE), | |
| 327 | +MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE), | |
| 328 | +MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE), | |
| 329 | +MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE), | |
| 330 | + | |
| 331 | +MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE), | |
| 332 | +MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE), | |
| 333 | +MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE), | |
| 334 | +MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE), | |
| 335 | + | |
| 336 | +MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE), | |
| 337 | +MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE), | |
| 338 | + | |
| 339 | +MADERA_GAINMUX_CONTROLS("SPDIF1TX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE), | |
| 340 | +MADERA_GAINMUX_CONTROLS("SPDIF1TX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE), | |
| 341 | + | |
| 342 | +WM_ADSP_FW_CONTROL("DSP1", 0), | |
| 343 | +}; | |
| 344 | + | |
| 345 | +MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE); | |
| 346 | +MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE); | |
| 347 | +MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE); | |
| 348 | +MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE); | |
| 349 | + | |
| 350 | +MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE); | |
| 351 | +MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE); | |
| 352 | +MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE); | |
| 353 | +MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE); | |
| 354 | + | |
| 355 | +MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE); | |
| 356 | +MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE); | |
| 357 | +MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE); | |
| 358 | +MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE); | |
| 359 | + | |
| 360 | +MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE); | |
| 361 | +MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE); | |
| 362 | +MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE); | |
| 363 | + | |
| 364 | +MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE); | |
| 365 | +MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE); | |
| 366 | + | |
| 367 | +MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE); | |
| 368 | +MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE); | |
| 369 | +MADERA_MIXER_ENUMS(SPKOUTL, MADERA_OUT4LMIX_INPUT_1_SOURCE); | |
| 370 | +MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE); | |
| 371 | +MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE); | |
| 372 | + | |
| 373 | +MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE); | |
| 374 | +MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE); | |
| 375 | +MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE); | |
| 376 | +MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE); | |
| 377 | +MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE); | |
| 378 | +MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE); | |
| 379 | + | |
| 380 | +MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE); | |
| 381 | +MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE); | |
| 382 | +MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE); | |
| 383 | +MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE); | |
| 384 | + | |
| 385 | +MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE); | |
| 386 | +MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE); | |
| 387 | + | |
| 388 | +MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE); | |
| 389 | +MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE); | |
| 390 | + | |
| 391 | +MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE); | |
| 392 | +MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE); | |
| 393 | +MADERA_MUX_ENUMS(ISRC1INT3, MADERA_ISRC1INT3MIX_INPUT_1_SOURCE); | |
| 394 | +MADERA_MUX_ENUMS(ISRC1INT4, MADERA_ISRC1INT4MIX_INPUT_1_SOURCE); | |
| 395 | + | |
| 396 | +MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE); | |
| 397 | +MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE); | |
| 398 | +MADERA_MUX_ENUMS(ISRC1DEC3, MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE); | |
| 399 | +MADERA_MUX_ENUMS(ISRC1DEC4, MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE); | |
| 400 | + | |
| 401 | +MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE); | |
| 402 | +MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE); | |
| 403 | +MADERA_MUX_ENUMS(ISRC2INT3, MADERA_ISRC2INT3MIX_INPUT_1_SOURCE); | |
| 404 | +MADERA_MUX_ENUMS(ISRC2INT4, MADERA_ISRC2INT4MIX_INPUT_1_SOURCE); | |
| 405 | + | |
| 406 | +MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE); | |
| 407 | +MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE); | |
| 408 | +MADERA_MUX_ENUMS(ISRC2DEC3, MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE); | |
| 409 | +MADERA_MUX_ENUMS(ISRC2DEC4, MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE); | |
| 410 | + | |
| 411 | +static const char * const cs47l15_aec_loopback_texts[] = { | |
| 412 | + "HPOUT1L", "HPOUT1R", "SPKOUTL", "SPKDAT1L", "SPKDAT1R", | |
| 413 | +}; | |
| 414 | + | |
| 415 | +static const unsigned int cs47l15_aec_loopback_values[] = { | |
| 416 | + 0, 1, 6, 8, 9, | |
| 417 | +}; | |
| 418 | + | |
| 419 | +static const struct soc_enum cs47l15_aec1_loopback = | |
| 420 | + SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1, | |
| 421 | + MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf, | |
| 422 | + ARRAY_SIZE(cs47l15_aec_loopback_texts), | |
| 423 | + cs47l15_aec_loopback_texts, | |
| 424 | + cs47l15_aec_loopback_values); | |
| 425 | + | |
| 426 | +static const struct soc_enum cs47l15_aec2_loopback = | |
| 427 | + SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_2, | |
| 428 | + MADERA_AEC2_LOOPBACK_SRC_SHIFT, 0xf, | |
| 429 | + ARRAY_SIZE(cs47l15_aec_loopback_texts), | |
| 430 | + cs47l15_aec_loopback_texts, | |
| 431 | + cs47l15_aec_loopback_values); | |
| 432 | + | |
| 433 | +static const struct snd_kcontrol_new cs47l15_aec_loopback_mux[] = { | |
| 434 | + SOC_DAPM_ENUM("AEC1 Loopback", cs47l15_aec1_loopback), | |
| 435 | + SOC_DAPM_ENUM("AEC2 Loopback", cs47l15_aec2_loopback), | |
| 436 | +}; | |
| 437 | + | |
| 438 | +static const struct snd_soc_dapm_widget cs47l15_dapm_widgets[] = { | |
| 439 | +SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT, | |
| 440 | + 0, madera_sysclk_ev, | |
| 441 | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | |
| 442 | +SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, | |
| 443 | + MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0), | |
| 444 | +SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, | |
| 445 | + MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0), | |
| 446 | + | |
| 447 | +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0), | |
| 448 | +SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS), | |
| 449 | +SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0), | |
| 450 | + | |
| 451 | +SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1, | |
| 452 | + MADERA_MICB1_ENA_SHIFT, 0, NULL, 0), | |
| 453 | + | |
| 454 | +SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5, | |
| 455 | + MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0), | |
| 456 | +SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5, | |
| 457 | + MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0), | |
| 458 | +SND_SOC_DAPM_SUPPLY("MICBIAS1C", MADERA_MIC_BIAS_CTRL_5, | |
| 459 | + MADERA_MICB1C_ENA_SHIFT, 0, NULL, 0), | |
| 460 | + | |
| 461 | +SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM, | |
| 462 | + MADERA_DOM_GRP_FX, 0, | |
| 463 | + madera_domain_clk_ev, | |
| 464 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 465 | +SND_SOC_DAPM_SUPPLY("ISRC1CLK", SND_SOC_NOPM, | |
| 466 | + MADERA_DOM_GRP_ISRC1, 0, | |
| 467 | + madera_domain_clk_ev, | |
| 468 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 469 | +SND_SOC_DAPM_SUPPLY("ISRC2CLK", SND_SOC_NOPM, | |
| 470 | + MADERA_DOM_GRP_ISRC2, 0, | |
| 471 | + madera_domain_clk_ev, | |
| 472 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 473 | +SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM, | |
| 474 | + MADERA_DOM_GRP_OUT, 0, | |
| 475 | + madera_domain_clk_ev, | |
| 476 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 477 | +SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM, | |
| 478 | + MADERA_DOM_GRP_SPD, 0, | |
| 479 | + madera_domain_clk_ev, | |
| 480 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 481 | +SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, | |
| 482 | + MADERA_DOM_GRP_DSP1, 0, | |
| 483 | + madera_domain_clk_ev, | |
| 484 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 485 | +SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM, | |
| 486 | + MADERA_DOM_GRP_AIF1, 0, | |
| 487 | + madera_domain_clk_ev, | |
| 488 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 489 | +SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM, | |
| 490 | + MADERA_DOM_GRP_AIF2, 0, | |
| 491 | + madera_domain_clk_ev, | |
| 492 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 493 | +SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM, | |
| 494 | + MADERA_DOM_GRP_AIF3, 0, | |
| 495 | + madera_domain_clk_ev, | |
| 496 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 497 | +SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM, | |
| 498 | + MADERA_DOM_GRP_PWM, 0, | |
| 499 | + madera_domain_clk_ev, | |
| 500 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 501 | + | |
| 502 | +SND_SOC_DAPM_SIGGEN("TONE"), | |
| 503 | +SND_SOC_DAPM_SIGGEN("NOISE"), | |
| 504 | + | |
| 505 | +SND_SOC_DAPM_INPUT("IN1ALN"), | |
| 506 | +SND_SOC_DAPM_INPUT("IN1ALP"), | |
| 507 | +SND_SOC_DAPM_INPUT("IN1BLN"), | |
| 508 | +SND_SOC_DAPM_INPUT("IN1BLP"), | |
| 509 | +SND_SOC_DAPM_INPUT("IN1ARN"), | |
| 510 | +SND_SOC_DAPM_INPUT("IN1ARP"), | |
| 511 | +SND_SOC_DAPM_INPUT("IN1BRN"), | |
| 512 | +SND_SOC_DAPM_INPUT("IN1BRP"), | |
| 513 | +SND_SOC_DAPM_INPUT("IN2N"), | |
| 514 | +SND_SOC_DAPM_INPUT("IN2P"), | |
| 515 | +SND_SOC_DAPM_INPUT("SPKRXDAT"), | |
| 516 | + | |
| 517 | +SND_SOC_DAPM_MUX("IN1L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]), | |
| 518 | +SND_SOC_DAPM_MUX("IN1R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]), | |
| 519 | + | |
| 520 | +SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]), | |
| 521 | +SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]), | |
| 522 | + | |
| 523 | +SND_SOC_DAPM_MUX("IN2L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]), | |
| 524 | +SND_SOC_DAPM_MUX("IN2R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]), | |
| 525 | + | |
| 526 | +SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"), | |
| 527 | +SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), | |
| 528 | + | |
| 529 | +SND_SOC_DAPM_OUTPUT("DSP Trigger Out"), | |
| 530 | + | |
| 531 | +SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l15_outdemux), | |
| 532 | + | |
| 533 | +SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT, | |
| 534 | + 0, NULL, 0), | |
| 535 | +SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT, | |
| 536 | + 0, NULL, 0), | |
| 537 | + | |
| 538 | +SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, | |
| 539 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0), | |
| 540 | +SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, | |
| 541 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0), | |
| 542 | +SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0, | |
| 543 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0), | |
| 544 | +SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0, | |
| 545 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0), | |
| 546 | +SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0, | |
| 547 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0), | |
| 548 | +SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0, | |
| 549 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0), | |
| 550 | + | |
| 551 | +SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, | |
| 552 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0), | |
| 553 | +SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0, | |
| 554 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0), | |
| 555 | +SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0, | |
| 556 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0), | |
| 557 | +SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0, | |
| 558 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0), | |
| 559 | + | |
| 560 | +SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0, | |
| 561 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0), | |
| 562 | +SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0, | |
| 563 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0), | |
| 564 | + | |
| 565 | +SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, | |
| 566 | + MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 567 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 568 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 569 | +SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, | |
| 570 | + MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 571 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 572 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 573 | +SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, | |
| 574 | + MADERA_OUT4L_ENA_SHIFT, 0, NULL, 0, madera_spk_ev, | |
| 575 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
| 576 | +SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1, | |
| 577 | + MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 578 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
| 579 | +SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1, | |
| 580 | + MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 581 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
| 582 | + | |
| 583 | +SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL, | |
| 584 | + MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0), | |
| 585 | +SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL, | |
| 586 | + MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0), | |
| 587 | +SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL, | |
| 588 | + MADERA_SPD1_ENA_SHIFT, 0, NULL, 0), | |
| 589 | + | |
| 590 | +/* | |
| 591 | + * mux_in widgets : arranged in the order of sources | |
| 592 | + * specified in MADERA_MIXER_INPUT_ROUTES | |
| 593 | + */ | |
| 594 | + | |
| 595 | +SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR, | |
| 596 | + MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), | |
| 597 | + | |
| 598 | +SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1, | |
| 599 | + MADERA_TONE1_ENA_SHIFT, 0, NULL, 0), | |
| 600 | +SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1, | |
| 601 | + MADERA_TONE2_ENA_SHIFT, 0, NULL, 0), | |
| 602 | + | |
| 603 | +SND_SOC_DAPM_SIGGEN("HAPTICS"), | |
| 604 | + | |
| 605 | +SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1, | |
| 606 | + MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0, | |
| 607 | + &cs47l15_aec_loopback_mux[0]), | |
| 608 | +SND_SOC_DAPM_MUX("AEC2 Loopback", MADERA_DAC_AEC_CONTROL_2, | |
| 609 | + MADERA_AEC2_LOOPBACK_ENA_SHIFT, 0, | |
| 610 | + &cs47l15_aec_loopback_mux[1]), | |
| 611 | + | |
| 612 | +SND_SOC_DAPM_PGA_E("IN1L", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT, | |
| 613 | + 0, NULL, 0, madera_in_ev, | |
| 614 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 615 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 616 | +SND_SOC_DAPM_PGA_E("IN1R", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT, | |
| 617 | + 0, NULL, 0, madera_in_ev, | |
| 618 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 619 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 620 | +SND_SOC_DAPM_PGA_E("IN2L", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT, | |
| 621 | + 0, NULL, 0, madera_in_ev, | |
| 622 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 623 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 624 | +SND_SOC_DAPM_PGA_E("IN2R", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT, | |
| 625 | + 0, NULL, 0, madera_in_ev, | |
| 626 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 627 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 628 | + | |
| 629 | +SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0, | |
| 630 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0), | |
| 631 | +SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0, | |
| 632 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0), | |
| 633 | +SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0, | |
| 634 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0), | |
| 635 | +SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0, | |
| 636 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0), | |
| 637 | +SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0, | |
| 638 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0), | |
| 639 | +SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0, | |
| 640 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0), | |
| 641 | + | |
| 642 | +SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, | |
| 643 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0), | |
| 644 | +SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0, | |
| 645 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0), | |
| 646 | +SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0, | |
| 647 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0), | |
| 648 | +SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0, | |
| 649 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0), | |
| 650 | + | |
| 651 | +SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |
| 652 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0), | |
| 653 | +SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | |
| 654 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0), | |
| 655 | + | |
| 656 | +SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0), | |
| 657 | +SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0), | |
| 658 | +SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0), | |
| 659 | +SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0), | |
| 660 | + | |
| 661 | +SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0, | |
| 662 | + NULL, 0), | |
| 663 | +SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0, | |
| 664 | + NULL, 0), | |
| 665 | +SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0, | |
| 666 | + NULL, 0), | |
| 667 | +SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0, | |
| 668 | + NULL, 0), | |
| 669 | + | |
| 670 | +SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0, NULL, 0), | |
| 671 | +SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0, NULL, 0), | |
| 672 | +SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0, NULL, 0), | |
| 673 | +SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0, NULL, 0), | |
| 674 | + | |
| 675 | +SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3, | |
| 676 | + MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0), | |
| 677 | +SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3, | |
| 678 | + MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0), | |
| 679 | +SND_SOC_DAPM_PGA("ISRC1DEC3", MADERA_ISRC_1_CTRL_3, | |
| 680 | + MADERA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0), | |
| 681 | +SND_SOC_DAPM_PGA("ISRC1DEC4", MADERA_ISRC_1_CTRL_3, | |
| 682 | + MADERA_ISRC1_DEC4_ENA_SHIFT, 0, NULL, 0), | |
| 683 | + | |
| 684 | +SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3, | |
| 685 | + MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0), | |
| 686 | +SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3, | |
| 687 | + MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0), | |
| 688 | +SND_SOC_DAPM_PGA("ISRC1INT3", MADERA_ISRC_1_CTRL_3, | |
| 689 | + MADERA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0), | |
| 690 | +SND_SOC_DAPM_PGA("ISRC1INT4", MADERA_ISRC_1_CTRL_3, | |
| 691 | + MADERA_ISRC1_INT4_ENA_SHIFT, 0, NULL, 0), | |
| 692 | + | |
| 693 | +SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3, | |
| 694 | + MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0), | |
| 695 | +SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3, | |
| 696 | + MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0), | |
| 697 | +SND_SOC_DAPM_PGA("ISRC2DEC3", MADERA_ISRC_2_CTRL_3, | |
| 698 | + MADERA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0), | |
| 699 | +SND_SOC_DAPM_PGA("ISRC2DEC4", MADERA_ISRC_2_CTRL_3, | |
| 700 | + MADERA_ISRC2_DEC4_ENA_SHIFT, 0, NULL, 0), | |
| 701 | + | |
| 702 | +SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3, | |
| 703 | + MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0), | |
| 704 | +SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3, | |
| 705 | + MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0), | |
| 706 | +SND_SOC_DAPM_PGA("ISRC2INT3", MADERA_ISRC_2_CTRL_3, | |
| 707 | + MADERA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0), | |
| 708 | +SND_SOC_DAPM_PGA("ISRC2INT4", MADERA_ISRC_2_CTRL_3, | |
| 709 | + MADERA_ISRC2_INT4_ENA_SHIFT, 0, NULL, 0), | |
| 710 | + | |
| 711 | +WM_ADSP2("DSP1", 0, cs47l15_adsp_power_ev), | |
| 712 | + | |
| 713 | +/* end of ordered widget list */ | |
| 714 | + | |
| 715 | +MADERA_MIXER_WIDGETS(EQ1, "EQ1"), | |
| 716 | +MADERA_MIXER_WIDGETS(EQ2, "EQ2"), | |
| 717 | +MADERA_MIXER_WIDGETS(EQ3, "EQ3"), | |
| 718 | +MADERA_MIXER_WIDGETS(EQ4, "EQ4"), | |
| 719 | + | |
| 720 | +MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"), | |
| 721 | +MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"), | |
| 722 | +MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"), | |
| 723 | +MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"), | |
| 724 | + | |
| 725 | +SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0, | |
| 726 | + &madera_drc_activity_output_mux[0]), | |
| 727 | +SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0, | |
| 728 | + &madera_drc_activity_output_mux[1]), | |
| 729 | + | |
| 730 | +MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"), | |
| 731 | +MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"), | |
| 732 | +MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"), | |
| 733 | +MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"), | |
| 734 | + | |
| 735 | +MADERA_MIXER_WIDGETS(PWM1, "PWM1"), | |
| 736 | +MADERA_MIXER_WIDGETS(PWM2, "PWM2"), | |
| 737 | + | |
| 738 | +MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"), | |
| 739 | +MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"), | |
| 740 | +MADERA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"), | |
| 741 | +MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), | |
| 742 | +MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"), | |
| 743 | + | |
| 744 | +MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | |
| 745 | +MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | |
| 746 | +MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), | |
| 747 | +MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), | |
| 748 | +MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), | |
| 749 | +MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), | |
| 750 | + | |
| 751 | +MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"), | |
| 752 | +MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |
| 753 | +MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"), | |
| 754 | +MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"), | |
| 755 | + | |
| 756 | +MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | |
| 757 | +MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | |
| 758 | + | |
| 759 | +MADERA_MUX_WIDGETS(SPD1TX1, "SPDIF1TX1"), | |
| 760 | +MADERA_MUX_WIDGETS(SPD1TX2, "SPDIF1TX2"), | |
| 761 | + | |
| 762 | +MADERA_DSP_WIDGETS(DSP1, "DSP1"), | |
| 763 | + | |
| 764 | +SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0, | |
| 765 | + &madera_dsp_trigger_output_mux[0]), | |
| 766 | + | |
| 767 | +MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"), | |
| 768 | +MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"), | |
| 769 | +MADERA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"), | |
| 770 | +MADERA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"), | |
| 771 | + | |
| 772 | +MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"), | |
| 773 | +MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"), | |
| 774 | +MADERA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"), | |
| 775 | +MADERA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"), | |
| 776 | + | |
| 777 | +MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"), | |
| 778 | +MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), | |
| 779 | +MADERA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"), | |
| 780 | +MADERA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"), | |
| 781 | + | |
| 782 | +MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), | |
| 783 | +MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), | |
| 784 | +MADERA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"), | |
| 785 | +MADERA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"), | |
| 786 | + | |
| 787 | +SND_SOC_DAPM_OUTPUT("HPOUTL"), | |
| 788 | +SND_SOC_DAPM_OUTPUT("HPOUTR"), | |
| 789 | +SND_SOC_DAPM_OUTPUT("EPOUTP"), | |
| 790 | +SND_SOC_DAPM_OUTPUT("EPOUTN"), | |
| 791 | +SND_SOC_DAPM_OUTPUT("SPKOUTN"), | |
| 792 | +SND_SOC_DAPM_OUTPUT("SPKOUTP"), | |
| 793 | +SND_SOC_DAPM_OUTPUT("SPKDAT1L"), | |
| 794 | +SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |
| 795 | +SND_SOC_DAPM_OUTPUT("SPDIF1"), | |
| 796 | + | |
| 797 | +SND_SOC_DAPM_OUTPUT("MICSUPP"), | |
| 798 | +}; | |
| 799 | + | |
| 800 | +#define MADERA_MIXER_INPUT_ROUTES(name) \ | |
| 801 | + { name, "Noise Generator", "Noise Generator" }, \ | |
| 802 | + { name, "Tone Generator 1", "Tone Generator 1" }, \ | |
| 803 | + { name, "Tone Generator 2", "Tone Generator 2" }, \ | |
| 804 | + { name, "Haptics", "HAPTICS" }, \ | |
| 805 | + { name, "AEC1", "AEC1 Loopback" }, \ | |
| 806 | + { name, "AEC2", "AEC2 Loopback" }, \ | |
| 807 | + { name, "IN1L", "IN1L" }, \ | |
| 808 | + { name, "IN1R", "IN1R" }, \ | |
| 809 | + { name, "IN2L", "IN2L" }, \ | |
| 810 | + { name, "IN2R", "IN2R" }, \ | |
| 811 | + { name, "AIF1RX1", "AIF1RX1" }, \ | |
| 812 | + { name, "AIF1RX2", "AIF1RX2" }, \ | |
| 813 | + { name, "AIF1RX3", "AIF1RX3" }, \ | |
| 814 | + { name, "AIF1RX4", "AIF1RX4" }, \ | |
| 815 | + { name, "AIF1RX5", "AIF1RX5" }, \ | |
| 816 | + { name, "AIF1RX6", "AIF1RX6" }, \ | |
| 817 | + { name, "AIF2RX1", "AIF2RX1" }, \ | |
| 818 | + { name, "AIF2RX2", "AIF2RX2" }, \ | |
| 819 | + { name, "AIF2RX3", "AIF2RX3" }, \ | |
| 820 | + { name, "AIF2RX4", "AIF2RX4" }, \ | |
| 821 | + { name, "AIF3RX1", "AIF3RX1" }, \ | |
| 822 | + { name, "AIF3RX2", "AIF3RX2" }, \ | |
| 823 | + { name, "EQ1", "EQ1" }, \ | |
| 824 | + { name, "EQ2", "EQ2" }, \ | |
| 825 | + { name, "EQ3", "EQ3" }, \ | |
| 826 | + { name, "EQ4", "EQ4" }, \ | |
| 827 | + { name, "DRC1L", "DRC1L" }, \ | |
| 828 | + { name, "DRC1R", "DRC1R" }, \ | |
| 829 | + { name, "DRC2L", "DRC2L" }, \ | |
| 830 | + { name, "DRC2R", "DRC2R" }, \ | |
| 831 | + { name, "LHPF1", "LHPF1" }, \ | |
| 832 | + { name, "LHPF2", "LHPF2" }, \ | |
| 833 | + { name, "LHPF3", "LHPF3" }, \ | |
| 834 | + { name, "LHPF4", "LHPF4" }, \ | |
| 835 | + { name, "ISRC1DEC1", "ISRC1DEC1" }, \ | |
| 836 | + { name, "ISRC1DEC2", "ISRC1DEC2" }, \ | |
| 837 | + { name, "ISRC1DEC3", "ISRC1DEC3" }, \ | |
| 838 | + { name, "ISRC1DEC4", "ISRC1DEC4" }, \ | |
| 839 | + { name, "ISRC1INT1", "ISRC1INT1" }, \ | |
| 840 | + { name, "ISRC1INT2", "ISRC1INT2" }, \ | |
| 841 | + { name, "ISRC1INT3", "ISRC1INT3" }, \ | |
| 842 | + { name, "ISRC1INT4", "ISRC1INT4" }, \ | |
| 843 | + { name, "ISRC2DEC1", "ISRC2DEC1" }, \ | |
| 844 | + { name, "ISRC2DEC2", "ISRC2DEC2" }, \ | |
| 845 | + { name, "ISRC2DEC3", "ISRC2DEC3" }, \ | |
| 846 | + { name, "ISRC2DEC4", "ISRC2DEC4" }, \ | |
| 847 | + { name, "ISRC2INT1", "ISRC2INT1" }, \ | |
| 848 | + { name, "ISRC2INT2", "ISRC2INT2" }, \ | |
| 849 | + { name, "ISRC2INT3", "ISRC2INT3" }, \ | |
| 850 | + { name, "ISRC2INT4", "ISRC2INT4" }, \ | |
| 851 | + { name, "DSP1.1", "DSP1" }, \ | |
| 852 | + { name, "DSP1.2", "DSP1" }, \ | |
| 853 | + { name, "DSP1.3", "DSP1" }, \ | |
| 854 | + { name, "DSP1.4", "DSP1" }, \ | |
| 855 | + { name, "DSP1.5", "DSP1" }, \ | |
| 856 | + { name, "DSP1.6", "DSP1" } | |
| 857 | + | |
| 858 | +static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = { | |
| 859 | + /* Internal clock domains */ | |
| 860 | + { "EQ1", NULL, "FXCLK" }, | |
| 861 | + { "EQ2", NULL, "FXCLK" }, | |
| 862 | + { "EQ3", NULL, "FXCLK" }, | |
| 863 | + { "EQ4", NULL, "FXCLK" }, | |
| 864 | + { "DRC1L", NULL, "FXCLK" }, | |
| 865 | + { "DRC1R", NULL, "FXCLK" }, | |
| 866 | + { "DRC2L", NULL, "FXCLK" }, | |
| 867 | + { "DRC2R", NULL, "FXCLK" }, | |
| 868 | + { "LHPF1", NULL, "FXCLK" }, | |
| 869 | + { "LHPF2", NULL, "FXCLK" }, | |
| 870 | + { "LHPF3", NULL, "FXCLK" }, | |
| 871 | + { "LHPF4", NULL, "FXCLK" }, | |
| 872 | + { "PWM1 Mixer", NULL, "PWMCLK" }, | |
| 873 | + { "PWM2 Mixer", NULL, "PWMCLK" }, | |
| 874 | + { "OUT1L", NULL, "OUTCLK" }, | |
| 875 | + { "OUT1R", NULL, "OUTCLK" }, | |
| 876 | + { "OUT4L", NULL, "OUTCLK" }, | |
| 877 | + { "OUT5L", NULL, "OUTCLK" }, | |
| 878 | + { "OUT5R", NULL, "OUTCLK" }, | |
| 879 | + { "AIF1TX1", NULL, "AIF1TXCLK" }, | |
| 880 | + { "AIF1TX2", NULL, "AIF1TXCLK" }, | |
| 881 | + { "AIF1TX3", NULL, "AIF1TXCLK" }, | |
| 882 | + { "AIF1TX4", NULL, "AIF1TXCLK" }, | |
| 883 | + { "AIF1TX5", NULL, "AIF1TXCLK" }, | |
| 884 | + { "AIF1TX6", NULL, "AIF1TXCLK" }, | |
| 885 | + { "AIF2TX1", NULL, "AIF2TXCLK" }, | |
| 886 | + { "AIF2TX2", NULL, "AIF2TXCLK" }, | |
| 887 | + { "AIF2TX3", NULL, "AIF2TXCLK" }, | |
| 888 | + { "AIF2TX4", NULL, "AIF2TXCLK" }, | |
| 889 | + { "AIF3TX1", NULL, "AIF3TXCLK" }, | |
| 890 | + { "AIF3TX2", NULL, "AIF3TXCLK" }, | |
| 891 | + { "SPD1TX1", NULL, "SPDCLK" }, | |
| 892 | + { "SPD1TX2", NULL, "SPDCLK" }, | |
| 893 | + { "DSP1", NULL, "DSP1CLK" }, | |
| 894 | + { "ISRC1DEC1", NULL, "ISRC1CLK" }, | |
| 895 | + { "ISRC1DEC2", NULL, "ISRC1CLK" }, | |
| 896 | + { "ISRC1DEC3", NULL, "ISRC1CLK" }, | |
| 897 | + { "ISRC1DEC4", NULL, "ISRC1CLK" }, | |
| 898 | + { "ISRC1INT1", NULL, "ISRC1CLK" }, | |
| 899 | + { "ISRC1INT2", NULL, "ISRC1CLK" }, | |
| 900 | + { "ISRC1INT3", NULL, "ISRC1CLK" }, | |
| 901 | + { "ISRC1INT4", NULL, "ISRC1CLK" }, | |
| 902 | + { "ISRC2DEC1", NULL, "ISRC2CLK" }, | |
| 903 | + { "ISRC2DEC2", NULL, "ISRC2CLK" }, | |
| 904 | + { "ISRC2DEC3", NULL, "ISRC2CLK" }, | |
| 905 | + { "ISRC2DEC4", NULL, "ISRC2CLK" }, | |
| 906 | + { "ISRC2INT1", NULL, "ISRC2CLK" }, | |
| 907 | + { "ISRC2INT2", NULL, "ISRC2CLK" }, | |
| 908 | + { "ISRC2INT3", NULL, "ISRC2CLK" }, | |
| 909 | + { "ISRC2INT4", NULL, "ISRC2CLK" }, | |
| 910 | + | |
| 911 | + { "OUT1L", NULL, "CPVDD1" }, | |
| 912 | + { "OUT1R", NULL, "CPVDD1" }, | |
| 913 | + { "OUT4L", NULL, "SPKVDD" }, | |
| 914 | + | |
| 915 | + { "OUT1L", NULL, "SYSCLK" }, | |
| 916 | + { "OUT1R", NULL, "SYSCLK" }, | |
| 917 | + { "OUT4L", NULL, "SYSCLK" }, | |
| 918 | + { "OUT5L", NULL, "SYSCLK" }, | |
| 919 | + { "OUT5R", NULL, "SYSCLK" }, | |
| 920 | + | |
| 921 | + { "SPD1", NULL, "SYSCLK" }, | |
| 922 | + { "SPD1", NULL, "SPD1TX1" }, | |
| 923 | + { "SPD1", NULL, "SPD1TX2" }, | |
| 924 | + | |
| 925 | + { "IN1L", NULL, "SYSCLK" }, | |
| 926 | + { "IN1R", NULL, "SYSCLK" }, | |
| 927 | + { "IN2L", NULL, "SYSCLK" }, | |
| 928 | + { "IN2R", NULL, "SYSCLK" }, | |
| 929 | + | |
| 930 | + { "MICBIAS1", NULL, "MICVDD" }, | |
| 931 | + | |
| 932 | + { "MICBIAS1A", NULL, "MICBIAS1" }, | |
| 933 | + { "MICBIAS1B", NULL, "MICBIAS1" }, | |
| 934 | + { "MICBIAS1C", NULL, "MICBIAS1" }, | |
| 935 | + | |
| 936 | + { "Noise Generator", NULL, "SYSCLK" }, | |
| 937 | + { "Tone Generator 1", NULL, "SYSCLK" }, | |
| 938 | + { "Tone Generator 2", NULL, "SYSCLK" }, | |
| 939 | + | |
| 940 | + { "Noise Generator", NULL, "NOISE" }, | |
| 941 | + { "Tone Generator 1", NULL, "TONE" }, | |
| 942 | + { "Tone Generator 2", NULL, "TONE" }, | |
| 943 | + | |
| 944 | + { "AIF1 Capture", NULL, "AIF1TX1" }, | |
| 945 | + { "AIF1 Capture", NULL, "AIF1TX2" }, | |
| 946 | + { "AIF1 Capture", NULL, "AIF1TX3" }, | |
| 947 | + { "AIF1 Capture", NULL, "AIF1TX4" }, | |
| 948 | + { "AIF1 Capture", NULL, "AIF1TX5" }, | |
| 949 | + { "AIF1 Capture", NULL, "AIF1TX6" }, | |
| 950 | + | |
| 951 | + { "AIF1RX1", NULL, "AIF1 Playback" }, | |
| 952 | + { "AIF1RX2", NULL, "AIF1 Playback" }, | |
| 953 | + { "AIF1RX3", NULL, "AIF1 Playback" }, | |
| 954 | + { "AIF1RX4", NULL, "AIF1 Playback" }, | |
| 955 | + { "AIF1RX5", NULL, "AIF1 Playback" }, | |
| 956 | + { "AIF1RX6", NULL, "AIF1 Playback" }, | |
| 957 | + | |
| 958 | + { "AIF2 Capture", NULL, "AIF2TX1" }, | |
| 959 | + { "AIF2 Capture", NULL, "AIF2TX2" }, | |
| 960 | + { "AIF2 Capture", NULL, "AIF2TX3" }, | |
| 961 | + { "AIF2 Capture", NULL, "AIF2TX4" }, | |
| 962 | + | |
| 963 | + { "AIF2RX1", NULL, "AIF2 Playback" }, | |
| 964 | + { "AIF2RX2", NULL, "AIF2 Playback" }, | |
| 965 | + { "AIF2RX3", NULL, "AIF2 Playback" }, | |
| 966 | + { "AIF2RX4", NULL, "AIF2 Playback" }, | |
| 967 | + | |
| 968 | + { "AIF3 Capture", NULL, "AIF3TX1" }, | |
| 969 | + { "AIF3 Capture", NULL, "AIF3TX2" }, | |
| 970 | + | |
| 971 | + { "AIF3RX1", NULL, "AIF3 Playback" }, | |
| 972 | + { "AIF3RX2", NULL, "AIF3 Playback" }, | |
| 973 | + | |
| 974 | + { "AIF1 Playback", NULL, "SYSCLK" }, | |
| 975 | + { "AIF2 Playback", NULL, "SYSCLK" }, | |
| 976 | + { "AIF3 Playback", NULL, "SYSCLK" }, | |
| 977 | + | |
| 978 | + { "AIF1 Capture", NULL, "SYSCLK" }, | |
| 979 | + { "AIF2 Capture", NULL, "SYSCLK" }, | |
| 980 | + { "AIF3 Capture", NULL, "SYSCLK" }, | |
| 981 | + | |
| 982 | + { "Audio Trace DSP", NULL, "DSP1" }, | |
| 983 | + | |
| 984 | + { "IN1L Analog Mux", "A", "IN1ALN" }, | |
| 985 | + { "IN1L Analog Mux", "A", "IN1ALP" }, | |
| 986 | + { "IN1L Analog Mux", "B", "IN1BLN" }, | |
| 987 | + { "IN1L Analog Mux", "B", "IN1BLP" }, | |
| 988 | + { "IN1R Analog Mux", "A", "IN1ARN" }, | |
| 989 | + { "IN1R Analog Mux", "A", "IN1ARP" }, | |
| 990 | + { "IN1R Analog Mux", "B", "IN1BRN" }, | |
| 991 | + { "IN1R Analog Mux", "B", "IN1BRP" }, | |
| 992 | + | |
| 993 | + { "IN1L Mode", "Analog", "IN1L Analog Mux" }, | |
| 994 | + { "IN1R Mode", "Analog", "IN1R Analog Mux" }, | |
| 995 | + | |
| 996 | + { "IN1L Mode", "Digital", "IN1ALN" }, | |
| 997 | + { "IN1L Mode", "Digital", "IN1ALP" }, | |
| 998 | + { "IN1R Mode", "Digital", "IN1ALN" }, | |
| 999 | + { "IN1R Mode", "Digital", "IN1ALP" }, | |
| 1000 | + | |
| 1001 | + { "IN1L", NULL, "IN1L Mode" }, | |
| 1002 | + { "IN1R", NULL, "IN1R Mode" }, | |
| 1003 | + | |
| 1004 | + { "IN2L Mode", "Analog", "IN2N" }, | |
| 1005 | + { "IN2L Mode", "Analog", "IN2P" }, | |
| 1006 | + | |
| 1007 | + { "IN2L Mode", "Digital", "SPKRXDAT" }, | |
| 1008 | + { "IN2R Mode", "Digital", "SPKRXDAT" }, | |
| 1009 | + | |
| 1010 | + { "IN2L", NULL, "IN2L Mode" }, | |
| 1011 | + { "IN2R", NULL, "IN2R Mode" }, | |
| 1012 | + | |
| 1013 | + MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | |
| 1014 | + MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | |
| 1015 | + MADERA_MIXER_ROUTES("OUT4L", "SPKOUTL"), | |
| 1016 | + MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"), | |
| 1017 | + MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"), | |
| 1018 | + | |
| 1019 | + MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"), | |
| 1020 | + MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"), | |
| 1021 | + | |
| 1022 | + MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), | |
| 1023 | + MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), | |
| 1024 | + MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), | |
| 1025 | + MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), | |
| 1026 | + MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), | |
| 1027 | + MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), | |
| 1028 | + | |
| 1029 | + MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"), | |
| 1030 | + MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"), | |
| 1031 | + MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"), | |
| 1032 | + MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"), | |
| 1033 | + | |
| 1034 | + MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), | |
| 1035 | + MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), | |
| 1036 | + | |
| 1037 | + MADERA_MUX_ROUTES("SPD1TX1", "SPDIF1TX1"), | |
| 1038 | + MADERA_MUX_ROUTES("SPD1TX2", "SPDIF1TX2"), | |
| 1039 | + | |
| 1040 | + MADERA_MIXER_ROUTES("EQ1", "EQ1"), | |
| 1041 | + MADERA_MIXER_ROUTES("EQ2", "EQ2"), | |
| 1042 | + MADERA_MIXER_ROUTES("EQ3", "EQ3"), | |
| 1043 | + MADERA_MIXER_ROUTES("EQ4", "EQ4"), | |
| 1044 | + | |
| 1045 | + MADERA_MIXER_ROUTES("DRC1L", "DRC1L"), | |
| 1046 | + MADERA_MIXER_ROUTES("DRC1R", "DRC1R"), | |
| 1047 | + MADERA_MIXER_ROUTES("DRC2L", "DRC2L"), | |
| 1048 | + MADERA_MIXER_ROUTES("DRC2R", "DRC2R"), | |
| 1049 | + | |
| 1050 | + MADERA_MIXER_ROUTES("LHPF1", "LHPF1"), | |
| 1051 | + MADERA_MIXER_ROUTES("LHPF2", "LHPF2"), | |
| 1052 | + MADERA_MIXER_ROUTES("LHPF3", "LHPF3"), | |
| 1053 | + MADERA_MIXER_ROUTES("LHPF4", "LHPF4"), | |
| 1054 | + | |
| 1055 | + MADERA_DSP_ROUTES("DSP1"), | |
| 1056 | + | |
| 1057 | + { "DSP Trigger Out", NULL, "DSP1 Trigger Output" }, | |
| 1058 | + | |
| 1059 | + { "DSP1 Trigger Output", "Switch", "DSP1" }, | |
| 1060 | + | |
| 1061 | + MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"), | |
| 1062 | + MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"), | |
| 1063 | + MADERA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"), | |
| 1064 | + MADERA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"), | |
| 1065 | + | |
| 1066 | + MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"), | |
| 1067 | + MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"), | |
| 1068 | + MADERA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"), | |
| 1069 | + MADERA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"), | |
| 1070 | + | |
| 1071 | + MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"), | |
| 1072 | + MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"), | |
| 1073 | + MADERA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"), | |
| 1074 | + MADERA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"), | |
| 1075 | + | |
| 1076 | + MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"), | |
| 1077 | + MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"), | |
| 1078 | + MADERA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"), | |
| 1079 | + MADERA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"), | |
| 1080 | + | |
| 1081 | + { "AEC1 Loopback", "HPOUT1L", "OUT1L" }, | |
| 1082 | + { "AEC1 Loopback", "HPOUT1R", "OUT1R" }, | |
| 1083 | + { "AEC2 Loopback", "HPOUT1L", "OUT1L" }, | |
| 1084 | + { "AEC2 Loopback", "HPOUT1R", "OUT1R" }, | |
| 1085 | + { "HPOUT1 Demux", NULL, "OUT1L" }, | |
| 1086 | + { "HPOUT1 Demux", NULL, "OUT1R" }, | |
| 1087 | + { "HPOUTL", "HPOUT", "HPOUT1 Demux" }, | |
| 1088 | + { "HPOUTR", "HPOUT", "HPOUT1 Demux" }, | |
| 1089 | + { "EPOUTP", "EPOUT", "HPOUT1 Demux" }, | |
| 1090 | + { "EPOUTN", "EPOUT", "HPOUT1 Demux" }, | |
| 1091 | + | |
| 1092 | + { "AEC1 Loopback", "SPKOUTL", "OUT4L" }, | |
| 1093 | + { "AEC2 Loopback", "SPKOUTL", "OUT4L" }, | |
| 1094 | + { "SPKOUTN", NULL, "OUT4L" }, | |
| 1095 | + { "SPKOUTP", NULL, "OUT4L" }, | |
| 1096 | + | |
| 1097 | + { "AEC1 Loopback", "SPKDAT1L", "OUT5L" }, | |
| 1098 | + { "AEC1 Loopback", "SPKDAT1R", "OUT5R" }, | |
| 1099 | + { "AEC2 Loopback", "SPKDAT1L", "OUT5L" }, | |
| 1100 | + { "AEC2 Loopback", "SPKDAT1R", "OUT5R" }, | |
| 1101 | + { "SPKDAT1L", NULL, "OUT5L" }, | |
| 1102 | + { "SPKDAT1R", NULL, "OUT5R" }, | |
| 1103 | + | |
| 1104 | + { "SPDIF1", NULL, "SPD1" }, | |
| 1105 | + | |
| 1106 | + { "MICSUPP", NULL, "SYSCLK" }, | |
| 1107 | + | |
| 1108 | + { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" }, | |
| 1109 | + { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" }, | |
| 1110 | + { "DRC1 Activity Output", "Switch", "DRC1L" }, | |
| 1111 | + { "DRC1 Activity Output", "Switch", "DRC1R" }, | |
| 1112 | + { "DRC2 Activity Output", "Switch", "DRC2L" }, | |
| 1113 | + { "DRC2 Activity Output", "Switch", "DRC2R" }, | |
| 1114 | +}; | |
| 1115 | + | |
| 1116 | +static int cs47l15_set_fll(struct snd_soc_component *component, int fll_id, | |
| 1117 | + int source, unsigned int fref, unsigned int fout) | |
| 1118 | +{ | |
| 1119 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 1120 | + | |
| 1121 | + switch (fll_id) { | |
| 1122 | + case MADERA_FLL1_REFCLK: | |
| 1123 | + return madera_set_fll_refclk(&cs47l15->fll[0], source, fref, | |
| 1124 | + fout); | |
| 1125 | + case MADERA_FLLAO_REFCLK: | |
| 1126 | + return madera_set_fll_ao_refclk(&cs47l15->fll[1], source, fref, | |
| 1127 | + fout); | |
| 1128 | + case MADERA_FLL1_SYNCCLK: | |
| 1129 | + return madera_set_fll_syncclk(&cs47l15->fll[0], source, fref, | |
| 1130 | + fout); | |
| 1131 | + default: | |
| 1132 | + return -EINVAL; | |
| 1133 | + } | |
| 1134 | +} | |
| 1135 | + | |
| 1136 | +static struct snd_soc_dai_driver cs47l15_dai[] = { | |
| 1137 | + { | |
| 1138 | + .name = "cs47l15-aif1", | |
| 1139 | + .id = 1, | |
| 1140 | + .base = MADERA_AIF1_BCLK_CTRL, | |
| 1141 | + .playback = { | |
| 1142 | + .stream_name = "AIF1 Playback", | |
| 1143 | + .channels_min = 1, | |
| 1144 | + .channels_max = 6, | |
| 1145 | + .rates = MADERA_RATES, | |
| 1146 | + .formats = MADERA_FORMATS, | |
| 1147 | + }, | |
| 1148 | + .capture = { | |
| 1149 | + .stream_name = "AIF1 Capture", | |
| 1150 | + .channels_min = 1, | |
| 1151 | + .channels_max = 6, | |
| 1152 | + .rates = MADERA_RATES, | |
| 1153 | + .formats = MADERA_FORMATS, | |
| 1154 | + }, | |
| 1155 | + .ops = &madera_dai_ops, | |
| 1156 | + .symmetric_rates = 1, | |
| 1157 | + .symmetric_samplebits = 1, | |
| 1158 | + }, | |
| 1159 | + { | |
| 1160 | + .name = "cs47l15-aif2", | |
| 1161 | + .id = 2, | |
| 1162 | + .base = MADERA_AIF2_BCLK_CTRL, | |
| 1163 | + .playback = { | |
| 1164 | + .stream_name = "AIF2 Playback", | |
| 1165 | + .channels_min = 1, | |
| 1166 | + .channels_max = 4, | |
| 1167 | + .rates = MADERA_RATES, | |
| 1168 | + .formats = MADERA_FORMATS, | |
| 1169 | + }, | |
| 1170 | + .capture = { | |
| 1171 | + .stream_name = "AIF2 Capture", | |
| 1172 | + .channels_min = 1, | |
| 1173 | + .channels_max = 4, | |
| 1174 | + .rates = MADERA_RATES, | |
| 1175 | + .formats = MADERA_FORMATS, | |
| 1176 | + }, | |
| 1177 | + .ops = &madera_dai_ops, | |
| 1178 | + .symmetric_rates = 1, | |
| 1179 | + .symmetric_samplebits = 1, | |
| 1180 | + }, | |
| 1181 | + { | |
| 1182 | + .name = "cs47l15-aif3", | |
| 1183 | + .id = 3, | |
| 1184 | + .base = MADERA_AIF3_BCLK_CTRL, | |
| 1185 | + .playback = { | |
| 1186 | + .stream_name = "AIF3 Playback", | |
| 1187 | + .channels_min = 1, | |
| 1188 | + .channels_max = 2, | |
| 1189 | + .rates = MADERA_RATES, | |
| 1190 | + .formats = MADERA_FORMATS, | |
| 1191 | + }, | |
| 1192 | + .capture = { | |
| 1193 | + .stream_name = "AIF3 Capture", | |
| 1194 | + .channels_min = 1, | |
| 1195 | + .channels_max = 2, | |
| 1196 | + .rates = MADERA_RATES, | |
| 1197 | + .formats = MADERA_FORMATS, | |
| 1198 | + }, | |
| 1199 | + .ops = &madera_dai_ops, | |
| 1200 | + .symmetric_rates = 1, | |
| 1201 | + .symmetric_samplebits = 1, | |
| 1202 | + }, | |
| 1203 | + { | |
| 1204 | + .name = "cs47l15-cpu-trace", | |
| 1205 | + .capture = { | |
| 1206 | + .stream_name = "Audio Trace CPU", | |
| 1207 | + .channels_min = 1, | |
| 1208 | + .channels_max = 6, | |
| 1209 | + .rates = MADERA_RATES, | |
| 1210 | + .formats = MADERA_FORMATS, | |
| 1211 | + }, | |
| 1212 | + .compress_new = snd_soc_new_compress, | |
| 1213 | + }, | |
| 1214 | + { | |
| 1215 | + .name = "cs47l15-dsp-trace", | |
| 1216 | + .capture = { | |
| 1217 | + .stream_name = "Audio Trace DSP", | |
| 1218 | + .channels_min = 1, | |
| 1219 | + .channels_max = 6, | |
| 1220 | + .rates = MADERA_RATES, | |
| 1221 | + .formats = MADERA_FORMATS, | |
| 1222 | + }, | |
| 1223 | + }, | |
| 1224 | +}; | |
| 1225 | + | |
| 1226 | +static int cs47l15_open(struct snd_compr_stream *stream) | |
| 1227 | +{ | |
| 1228 | + struct snd_soc_pcm_runtime *rtd = stream->private_data; | |
| 1229 | + struct snd_soc_component *component = | |
| 1230 | + snd_soc_rtdcom_lookup(rtd, DRV_NAME); | |
| 1231 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 1232 | + struct madera_priv *priv = &cs47l15->core; | |
| 1233 | + struct madera *madera = priv->madera; | |
| 1234 | + int n_adsp; | |
| 1235 | + | |
| 1236 | + if (strcmp(rtd->codec_dai->name, "cs47l15-dsp-trace") == 0) { | |
| 1237 | + n_adsp = 0; | |
| 1238 | + } else { | |
| 1239 | + dev_err(madera->dev, | |
| 1240 | + "No suitable compressed stream for DAI '%s'\n", | |
| 1241 | + rtd->codec_dai->name); | |
| 1242 | + return -EINVAL; | |
| 1243 | + } | |
| 1244 | + | |
| 1245 | + return wm_adsp_compr_open(&priv->adsp[n_adsp], stream); | |
| 1246 | +} | |
| 1247 | + | |
| 1248 | +static irqreturn_t cs47l15_adsp2_irq(int irq, void *data) | |
| 1249 | +{ | |
| 1250 | + struct cs47l15 *cs47l15 = data; | |
| 1251 | + struct madera_priv *priv = &cs47l15->core; | |
| 1252 | + struct madera *madera = priv->madera; | |
| 1253 | + int ret; | |
| 1254 | + | |
| 1255 | + ret = wm_adsp_compr_handle_irq(&priv->adsp[0]); | |
| 1256 | + if (ret == -ENODEV) { | |
| 1257 | + dev_err(madera->dev, "Spurious compressed data IRQ\n"); | |
| 1258 | + return IRQ_NONE; | |
| 1259 | + } | |
| 1260 | + | |
| 1261 | + return IRQ_HANDLED; | |
| 1262 | +} | |
| 1263 | + | |
| 1264 | +static int cs47l15_component_probe(struct snd_soc_component *component) | |
| 1265 | +{ | |
| 1266 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 1267 | + struct madera *madera = cs47l15->core.madera; | |
| 1268 | + int ret; | |
| 1269 | + | |
| 1270 | + snd_soc_component_init_regmap(component, madera->regmap); | |
| 1271 | + | |
| 1272 | + mutex_lock(&madera->dapm_ptr_lock); | |
| 1273 | + madera->dapm = snd_soc_component_get_dapm(component); | |
| 1274 | + mutex_unlock(&madera->dapm_ptr_lock); | |
| 1275 | + | |
| 1276 | + ret = madera_init_inputs(component); | |
| 1277 | + if (ret) | |
| 1278 | + return ret; | |
| 1279 | + | |
| 1280 | + ret = madera_init_outputs(component, CS47L15_MONO_OUTPUTS); | |
| 1281 | + if (ret) | |
| 1282 | + return ret; | |
| 1283 | + | |
| 1284 | + snd_soc_component_disable_pin(component, "HAPTICS"); | |
| 1285 | + | |
| 1286 | + ret = snd_soc_add_component_controls(component, | |
| 1287 | + madera_adsp_rate_controls, | |
| 1288 | + CS47L15_NUM_ADSP); | |
| 1289 | + if (ret) | |
| 1290 | + return ret; | |
| 1291 | + | |
| 1292 | + wm_adsp2_component_probe(&cs47l15->core.adsp[0], component); | |
| 1293 | + | |
| 1294 | + return 0; | |
| 1295 | +} | |
| 1296 | + | |
| 1297 | +static void cs47l15_component_remove(struct snd_soc_component *component) | |
| 1298 | +{ | |
| 1299 | + struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); | |
| 1300 | + struct madera *madera = cs47l15->core.madera; | |
| 1301 | + | |
| 1302 | + mutex_lock(&madera->dapm_ptr_lock); | |
| 1303 | + madera->dapm = NULL; | |
| 1304 | + mutex_unlock(&madera->dapm_ptr_lock); | |
| 1305 | + | |
| 1306 | + wm_adsp2_component_remove(&cs47l15->core.adsp[0], component); | |
| 1307 | +} | |
| 1308 | + | |
| 1309 | +#define CS47L15_DIG_VU 0x0200 | |
| 1310 | + | |
| 1311 | +static unsigned int cs47l15_digital_vu[] = { | |
| 1312 | + MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 1313 | + MADERA_DAC_DIGITAL_VOLUME_1R, | |
| 1314 | + MADERA_DAC_DIGITAL_VOLUME_4L, | |
| 1315 | + MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 1316 | + MADERA_DAC_DIGITAL_VOLUME_5R, | |
| 1317 | +}; | |
| 1318 | + | |
| 1319 | +static const struct snd_compr_ops cs47l15_compr_ops = { | |
| 1320 | + .open = &cs47l15_open, | |
| 1321 | + .free = &wm_adsp_compr_free, | |
| 1322 | + .set_params = &wm_adsp_compr_set_params, | |
| 1323 | + .get_caps = &wm_adsp_compr_get_caps, | |
| 1324 | + .trigger = &wm_adsp_compr_trigger, | |
| 1325 | + .pointer = &wm_adsp_compr_pointer, | |
| 1326 | + .copy = &wm_adsp_compr_copy, | |
| 1327 | +}; | |
| 1328 | + | |
| 1329 | +static const struct snd_soc_component_driver soc_component_dev_cs47l15 = { | |
| 1330 | + .probe = &cs47l15_component_probe, | |
| 1331 | + .remove = &cs47l15_component_remove, | |
| 1332 | + .set_sysclk = &madera_set_sysclk, | |
| 1333 | + .set_pll = &cs47l15_set_fll, | |
| 1334 | + .name = DRV_NAME, | |
| 1335 | + .compr_ops = &cs47l15_compr_ops, | |
| 1336 | + .controls = cs47l15_snd_controls, | |
| 1337 | + .num_controls = ARRAY_SIZE(cs47l15_snd_controls), | |
| 1338 | + .dapm_widgets = cs47l15_dapm_widgets, | |
| 1339 | + .num_dapm_widgets = ARRAY_SIZE(cs47l15_dapm_widgets), | |
| 1340 | + .dapm_routes = cs47l15_dapm_routes, | |
| 1341 | + .num_dapm_routes = ARRAY_SIZE(cs47l15_dapm_routes), | |
| 1342 | + .use_pmdown_time = 1, | |
| 1343 | + .endianness = 1, | |
| 1344 | + .non_legacy_dai_naming = 1, | |
| 1345 | +}; | |
| 1346 | + | |
| 1347 | +static int cs47l15_probe(struct platform_device *pdev) | |
| 1348 | +{ | |
| 1349 | + struct madera *madera = dev_get_drvdata(pdev->dev.parent); | |
| 1350 | + struct cs47l15 *cs47l15; | |
| 1351 | + int i, ret; | |
| 1352 | + | |
| 1353 | + BUILD_BUG_ON(ARRAY_SIZE(cs47l15_dai) > MADERA_MAX_DAI); | |
| 1354 | + | |
| 1355 | + /* quick exit if Madera irqchip driver hasn't completed probe */ | |
| 1356 | + if (!madera->irq_dev) { | |
| 1357 | + dev_dbg(&pdev->dev, "irqchip driver not ready\n"); | |
| 1358 | + return -EPROBE_DEFER; | |
| 1359 | + } | |
| 1360 | + | |
| 1361 | + cs47l15 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l15), | |
| 1362 | + GFP_KERNEL); | |
| 1363 | + if (!cs47l15) | |
| 1364 | + return -ENOMEM; | |
| 1365 | + | |
| 1366 | + platform_set_drvdata(pdev, cs47l15); | |
| 1367 | + | |
| 1368 | + cs47l15->core.madera = madera; | |
| 1369 | + cs47l15->core.dev = &pdev->dev; | |
| 1370 | + cs47l15->core.num_inputs = 4; | |
| 1371 | + | |
| 1372 | + ret = madera_core_init(&cs47l15->core); | |
| 1373 | + if (ret) | |
| 1374 | + return ret; | |
| 1375 | + | |
| 1376 | + ret = madera_init_overheat(&cs47l15->core); | |
| 1377 | + if (ret) | |
| 1378 | + goto error_core; | |
| 1379 | + | |
| 1380 | + ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1, | |
| 1381 | + "ADSP2 Compressed IRQ", cs47l15_adsp2_irq, | |
| 1382 | + cs47l15); | |
| 1383 | + if (ret != 0) { | |
| 1384 | + dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret); | |
| 1385 | + goto error_overheat; | |
| 1386 | + } | |
| 1387 | + | |
| 1388 | + ret = madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 1); | |
| 1389 | + if (ret) | |
| 1390 | + dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret); | |
| 1391 | + | |
| 1392 | + cs47l15->core.adsp[0].part = "cs47l15"; | |
| 1393 | + cs47l15->core.adsp[0].num = 1; | |
| 1394 | + cs47l15->core.adsp[0].type = WMFW_ADSP2; | |
| 1395 | + cs47l15->core.adsp[0].rev = 2; | |
| 1396 | + cs47l15->core.adsp[0].dev = madera->dev; | |
| 1397 | + cs47l15->core.adsp[0].regmap = madera->regmap_32bit; | |
| 1398 | + | |
| 1399 | + cs47l15->core.adsp[0].base = MADERA_DSP1_CONFIG_1; | |
| 1400 | + cs47l15->core.adsp[0].mem = cs47l15_dsp1_regions; | |
| 1401 | + cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions); | |
| 1402 | + | |
| 1403 | + cs47l15->core.adsp[0].lock_regions = | |
| 1404 | + WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3; | |
| 1405 | + | |
| 1406 | + ret = wm_adsp2_init(&cs47l15->core.adsp[0]); | |
| 1407 | + if (ret != 0) | |
| 1408 | + goto error_dsp_irq; | |
| 1409 | + | |
| 1410 | + ret = madera_init_bus_error_irq(&cs47l15->core, 0, wm_adsp2_bus_error); | |
| 1411 | + if (ret) | |
| 1412 | + goto error_adsp; | |
| 1413 | + | |
| 1414 | + madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1, | |
| 1415 | + &cs47l15->fll[0]); | |
| 1416 | + madera_init_fll(madera, 4, MADERA_FLLAO_CONTROL_1 - 1, | |
| 1417 | + &cs47l15->fll[1]); | |
| 1418 | + | |
| 1419 | + for (i = 0; i < ARRAY_SIZE(cs47l15_dai); i++) | |
| 1420 | + madera_init_dai(&cs47l15->core, i); | |
| 1421 | + | |
| 1422 | + /* Latch volume update bits */ | |
| 1423 | + for (i = 0; i < ARRAY_SIZE(cs47l15_digital_vu); i++) | |
| 1424 | + regmap_update_bits(madera->regmap, cs47l15_digital_vu[i], | |
| 1425 | + CS47L15_DIG_VU, CS47L15_DIG_VU); | |
| 1426 | + | |
| 1427 | + pm_runtime_enable(&pdev->dev); | |
| 1428 | + pm_runtime_idle(&pdev->dev); | |
| 1429 | + | |
| 1430 | + ret = devm_snd_soc_register_component(&pdev->dev, | |
| 1431 | + &soc_component_dev_cs47l15, | |
| 1432 | + cs47l15_dai, | |
| 1433 | + ARRAY_SIZE(cs47l15_dai)); | |
| 1434 | + if (ret < 0) { | |
| 1435 | + dev_err(&pdev->dev, "Failed to register component: %d\n", ret); | |
| 1436 | + goto error_pm_runtime; | |
| 1437 | + } | |
| 1438 | + | |
| 1439 | + return ret; | |
| 1440 | + | |
| 1441 | +error_pm_runtime: | |
| 1442 | + pm_runtime_disable(&pdev->dev); | |
| 1443 | + madera_free_bus_error_irq(&cs47l15->core, 0); | |
| 1444 | +error_adsp: | |
| 1445 | + wm_adsp2_remove(&cs47l15->core.adsp[0]); | |
| 1446 | +error_dsp_irq: | |
| 1447 | + madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 0); | |
| 1448 | + madera_free_irq(madera, MADERA_IRQ_DSP_IRQ1, cs47l15); | |
| 1449 | +error_overheat: | |
| 1450 | + madera_free_overheat(&cs47l15->core); | |
| 1451 | +error_core: | |
| 1452 | + madera_core_free(&cs47l15->core); | |
| 1453 | + | |
| 1454 | + return ret; | |
| 1455 | +} | |
| 1456 | + | |
| 1457 | +static int cs47l15_remove(struct platform_device *pdev) | |
| 1458 | +{ | |
| 1459 | + struct cs47l15 *cs47l15 = platform_get_drvdata(pdev); | |
| 1460 | + | |
| 1461 | + pm_runtime_disable(&pdev->dev); | |
| 1462 | + | |
| 1463 | + madera_free_bus_error_irq(&cs47l15->core, 0); | |
| 1464 | + | |
| 1465 | + wm_adsp2_remove(&cs47l15->core.adsp[0]); | |
| 1466 | + | |
| 1467 | + madera_set_irq_wake(cs47l15->core.madera, MADERA_IRQ_DSP_IRQ1, 0); | |
| 1468 | + madera_free_irq(cs47l15->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l15); | |
| 1469 | + madera_free_overheat(&cs47l15->core); | |
| 1470 | + madera_core_free(&cs47l15->core); | |
| 1471 | + | |
| 1472 | + return 0; | |
| 1473 | +} | |
| 1474 | + | |
| 1475 | +static struct platform_driver cs47l15_codec_driver = { | |
| 1476 | + .driver = { | |
| 1477 | + .name = "cs47l15-codec", | |
| 1478 | + }, | |
| 1479 | + .probe = &cs47l15_probe, | |
| 1480 | + .remove = &cs47l15_remove, | |
| 1481 | +}; | |
| 1482 | + | |
| 1483 | +module_platform_driver(cs47l15_codec_driver); | |
| 1484 | + | |
| 1485 | +MODULE_SOFTDEP("pre: madera irq-madera arizona-micsupp"); | |
| 1486 | +MODULE_DESCRIPTION("ASoC CS47L15 driver"); | |
| 1487 | +MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); | |
| 1488 | +MODULE_AUTHOR("Jaswinder Jassal <jjassal@opensource.cirrus.com>"); | |
| 1489 | +MODULE_LICENSE("GPL v2"); | |
| 1490 | +MODULE_ALIAS("platform:cs47l15-codec"); | |
| @@ -524,7 +524,7 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT, · 523 unmodified lines | ||
| 524 | 524 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 525 | 525 | SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, |
| 526 | 526 | MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0), |
| 527 | −SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, 6, | |
| 527 | +SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, MADERA_DSP_CLK_ENA_SHIFT, | |
| 528 | 528 | 0, NULL, 0), |
| 529 | 529 | |
| 530 | 530 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
| @@ -2402,13 +2402,6 @@ static irqreturn_t cs47l90_adsp2_irq(int irq, void *data) · 2401 unmodified lines | ||
| 2402 | 2402 | return IRQ_HANDLED; |
| 2403 | 2403 | } |
| 2404 | 2404 | |
| 2405 | −static irqreturn_t cs47l90_dsp_bus_error(int irq, void *data) | |
| 2406 | −{ | |
| 2407 | − struct wm_adsp *dsp = (struct wm_adsp *)data; | |
| 2408 | − | |
| 2409 | − return wm_adsp2_bus_error(dsp); | |
| 2410 | −} | |
| 2411 | − | |
| 2412 | 2405 | static int cs47l90_component_probe(struct snd_soc_component *component) |
| 2413 | 2406 | { |
| 2414 | 2407 | struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component); |
| @@ -2558,7 +2551,7 @@ static int cs47l90_probe(struct platform_device *pdev) · 143 unmodified lines | ||
| 2558 | 2551 | |
| 2559 | 2552 | if (ret == 0) { |
| 2560 | 2553 | ret = madera_init_bus_error_irq(&cs47l90->core, i, |
| 2561 | − cs47l90_dsp_bus_error); | |
| 2554 | + wm_adsp2_bus_error); | |
| 2562 | 2555 | if (ret != 0) |
| 2563 | 2556 | wm_adsp2_remove(&cs47l90->core.adsp[i]); |
| 2564 | 2557 | } |
| @@ -0,0 +1,2039 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +// | |
| 3 | +// ALSA SoC Audio driver for CS47L92 codec | |
| 4 | +// | |
| 5 | +// Copyright (C) 2016-2019 Cirrus Logic, Inc. and | |
| 6 | +// Cirrus Logic International Semiconductor Ltd. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#include <linux/module.h> | |
| 10 | +#include <linux/moduleparam.h> | |
| 11 | +#include <linux/device.h> | |
| 12 | +#include <linux/delay.h> | |
| 13 | +#include <linux/init.h> | |
| 14 | +#include <linux/pm.h> | |
| 15 | +#include <linux/pm_runtime.h> | |
| 16 | +#include <linux/regmap.h> | |
| 17 | +#include <sound/core.h> | |
| 18 | +#include <sound/pcm.h> | |
| 19 | +#include <sound/pcm_params.h> | |
| 20 | +#include <sound/soc.h> | |
| 21 | +#include <sound/tlv.h> | |
| 22 | + | |
| 23 | +#include <linux/irqchip/irq-madera.h> | |
| 24 | +#include <linux/mfd/madera/core.h> | |
| 25 | +#include <linux/mfd/madera/registers.h> | |
| 26 | + | |
| 27 | +#include "madera.h" | |
| 28 | +#include "wm_adsp.h" | |
| 29 | + | |
| 30 | +#define CS47L92_NUM_ADSP 1 | |
| 31 | +#define CS47L92_MONO_OUTPUTS 3 | |
| 32 | + | |
| 33 | +#define DRV_NAME "cs47l92-codec" | |
| 34 | + | |
| 35 | +struct cs47l92 { | |
| 36 | + struct madera_priv core; | |
| 37 | + struct madera_fll fll[2]; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +static const struct wm_adsp_region cs47l92_dsp1_regions[] = { | |
| 41 | + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, | |
| 42 | + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, | |
| 43 | + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, | |
| 44 | + { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, | |
| 45 | +}; | |
| 46 | + | |
| 47 | +static const char * const cs47l92_outdemux_texts[] = { | |
| 48 | + "HPOUT3", | |
| 49 | + "HPOUT4", | |
| 50 | +}; | |
| 51 | + | |
| 52 | +static int cs47l92_put_demux(struct snd_kcontrol *kcontrol, | |
| 53 | + struct snd_ctl_elem_value *ucontrol) | |
| 54 | +{ | |
| 55 | + struct snd_soc_component *component = | |
| 56 | + snd_soc_dapm_kcontrol_component(kcontrol); | |
| 57 | + struct snd_soc_dapm_context *dapm = | |
| 58 | + snd_soc_component_get_dapm(component); | |
| 59 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 60 | + struct madera_priv *priv = &cs47l92->core; | |
| 61 | + struct madera *madera = priv->madera; | |
| 62 | + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | |
| 63 | + unsigned int ep_sel, mux, change, cur; | |
| 64 | + bool out_mono; | |
| 65 | + int ret; | |
| 66 | + | |
| 67 | + if (ucontrol->value.enumerated.item[0] > e->items - 1) | |
| 68 | + return -EINVAL; | |
| 69 | + | |
| 70 | + mux = ucontrol->value.enumerated.item[0]; | |
| 71 | + | |
| 72 | + snd_soc_dapm_mutex_lock(dapm); | |
| 73 | + | |
| 74 | + ep_sel = mux << e->shift_l; | |
| 75 | + | |
| 76 | + change = snd_soc_component_test_bits(component, MADERA_OUTPUT_ENABLES_1, | |
| 77 | + MADERA_EP_SEL_MASK, | |
| 78 | + ep_sel); | |
| 79 | + if (!change) | |
| 80 | + goto end; | |
| 81 | + | |
| 82 | + ret = regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &cur); | |
| 83 | + if (ret != 0) | |
| 84 | + dev_warn(madera->dev, "Failed to read outputs: %d\n", ret); | |
| 85 | + | |
| 86 | + /* EP_SEL should not be modified while HPOUT3 or 4 is enabled */ | |
| 87 | + ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, | |
| 88 | + MADERA_OUT3L_ENA | MADERA_OUT3R_ENA, 0); | |
| 89 | + if (ret) | |
| 90 | + dev_warn(madera->dev, "Failed to disable outputs: %d\n", ret); | |
| 91 | + | |
| 92 | + usleep_range(2000, 3000); /* wait for wseq to complete */ | |
| 93 | + | |
| 94 | + ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, | |
| 95 | + MADERA_EP_SEL, ep_sel); | |
| 96 | + if (ret) { | |
| 97 | + dev_err(madera->dev, "Failed to set OUT3 demux: %d\n", ret); | |
| 98 | + } else { | |
| 99 | + out_mono = madera->pdata.codec.out_mono[2 + mux]; | |
| 100 | + | |
| 101 | + ret = madera_set_output_mode(component, 3, out_mono); | |
| 102 | + if (ret < 0) | |
| 103 | + dev_warn(madera->dev, | |
| 104 | + "Failed to set output mode: %d\n", ret); | |
| 105 | + } | |
| 106 | + | |
| 107 | + ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, | |
| 108 | + MADERA_OUT3L_ENA | MADERA_OUT3R_ENA, cur); | |
| 109 | + if (ret) { | |
| 110 | + dev_warn(madera->dev, "Failed to restore outputs: %d\n", ret); | |
| 111 | + } else { | |
| 112 | + /* wait for wseq */ | |
| 113 | + if (cur & (MADERA_OUT3L_ENA | MADERA_OUT3R_ENA)) | |
| 114 | + msleep(34); /* enable delay */ | |
| 115 | + else | |
| 116 | + usleep_range(2000, 3000); /* disable delay */ | |
| 117 | + } | |
| 118 | + | |
| 119 | +end: | |
| 120 | + snd_soc_dapm_mutex_unlock(dapm); | |
| 121 | + | |
| 122 | + return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); | |
| 123 | +} | |
| 124 | + | |
| 125 | +static SOC_ENUM_SINGLE_DECL(cs47l92_outdemux_enum, | |
| 126 | + MADERA_OUTPUT_ENABLES_1, | |
| 127 | + MADERA_EP_SEL_SHIFT, | |
| 128 | + cs47l92_outdemux_texts); | |
| 129 | + | |
| 130 | +static const struct snd_kcontrol_new cs47l92_outdemux = | |
| 131 | + SOC_DAPM_ENUM_EXT("OUT3 Demux", cs47l92_outdemux_enum, | |
| 132 | + snd_soc_dapm_get_enum_double, cs47l92_put_demux); | |
| 133 | + | |
| 134 | +static int cs47l92_adsp_power_ev(struct snd_soc_dapm_widget *w, | |
| 135 | + struct snd_kcontrol *kcontrol, | |
| 136 | + int event) | |
| 137 | +{ | |
| 138 | + struct snd_soc_component *component = | |
| 139 | + snd_soc_dapm_to_component(w->dapm); | |
| 140 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 141 | + struct madera_priv *priv = &cs47l92->core; | |
| 142 | + struct madera *madera = priv->madera; | |
| 143 | + unsigned int freq; | |
| 144 | + int ret; | |
| 145 | + | |
| 146 | + ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_2, &freq); | |
| 147 | + if (ret != 0) { | |
| 148 | + dev_err(madera->dev, | |
| 149 | + "Failed to read MADERA_DSP_CLOCK_2: %d\n", ret); | |
| 150 | + return ret; | |
| 151 | + } | |
| 152 | + | |
| 153 | + switch (event) { | |
| 154 | + case SND_SOC_DAPM_PRE_PMU: | |
| 155 | + ret = madera_set_adsp_clk(&cs47l92->core, w->shift, freq); | |
| 156 | + if (ret) | |
| 157 | + return ret; | |
| 158 | + break; | |
| 159 | + default: | |
| 160 | + break; | |
| 161 | + } | |
| 162 | + | |
| 163 | + return wm_adsp_early_event(w, kcontrol, event); | |
| 164 | +} | |
| 165 | + | |
| 166 | +#define CS47L92_NG_SRC(name, base) \ | |
| 167 | + SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ | |
| 168 | + SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ | |
| 169 | + SOC_SINGLE(name " NG HPOUT2L Switch", base, 2, 1, 0), \ | |
| 170 | + SOC_SINGLE(name " NG HPOUT2R Switch", base, 3, 1, 0), \ | |
| 171 | + SOC_SINGLE(name " NG HPOUT3L Switch", base, 4, 1, 0), \ | |
| 172 | + SOC_SINGLE(name " NG HPOUT3R Switch", base, 5, 1, 0), \ | |
| 173 | + SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \ | |
| 174 | + SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0) | |
| 175 | + | |
| 176 | +static const struct snd_kcontrol_new cs47l92_snd_controls[] = { | |
| 177 | +SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]), | |
| 178 | +SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]), | |
| 179 | +SOC_ENUM("IN3 OSR", madera_in_dmic_osr[2]), | |
| 180 | +SOC_ENUM("IN4 OSR", madera_in_dmic_osr[3]), | |
| 181 | + | |
| 182 | +SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL, | |
| 183 | + MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 184 | +SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL, | |
| 185 | + MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 186 | +SOC_SINGLE_RANGE_TLV("IN2L Volume", MADERA_IN2L_CONTROL, | |
| 187 | + MADERA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 188 | +SOC_SINGLE_RANGE_TLV("IN2R Volume", MADERA_IN2R_CONTROL, | |
| 189 | + MADERA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv), | |
| 190 | + | |
| 191 | +SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum), | |
| 192 | + | |
| 193 | +SOC_SINGLE_EXT("IN1L LP Switch", MADERA_ADC_DIGITAL_VOLUME_1L, | |
| 194 | + MADERA_IN1L_LP_MODE_SHIFT, 1, 0, | |
| 195 | + snd_soc_get_volsw, madera_lp_mode_put), | |
| 196 | +SOC_SINGLE_EXT("IN1R LP Switch", MADERA_ADC_DIGITAL_VOLUME_1R, | |
| 197 | + MADERA_IN1L_LP_MODE_SHIFT, 1, 0, | |
| 198 | + snd_soc_get_volsw, madera_lp_mode_put), | |
| 199 | +SOC_SINGLE_EXT("IN2L LP Switch", MADERA_ADC_DIGITAL_VOLUME_2L, | |
| 200 | + MADERA_IN1L_LP_MODE_SHIFT, 1, 0, | |
| 201 | + snd_soc_get_volsw, madera_lp_mode_put), | |
| 202 | +SOC_SINGLE_EXT("IN2R LP Switch", MADERA_ADC_DIGITAL_VOLUME_2R, | |
| 203 | + MADERA_IN1L_LP_MODE_SHIFT, 1, 0, | |
| 204 | + snd_soc_get_volsw, madera_lp_mode_put), | |
| 205 | + | |
| 206 | +SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL, | |
| 207 | + MADERA_IN1L_HPF_SHIFT, 1, 0), | |
| 208 | +SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL, | |
| 209 | + MADERA_IN1R_HPF_SHIFT, 1, 0), | |
| 210 | +SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL, | |
| 211 | + MADERA_IN2L_HPF_SHIFT, 1, 0), | |
| 212 | +SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL, | |
| 213 | + MADERA_IN2R_HPF_SHIFT, 1, 0), | |
| 214 | +SOC_SINGLE("IN3L HPF Switch", MADERA_IN3L_CONTROL, | |
| 215 | + MADERA_IN3L_HPF_SHIFT, 1, 0), | |
| 216 | +SOC_SINGLE("IN3R HPF Switch", MADERA_IN3R_CONTROL, | |
| 217 | + MADERA_IN3R_HPF_SHIFT, 1, 0), | |
| 218 | +SOC_SINGLE("IN4L HPF Switch", MADERA_IN4L_CONTROL, | |
| 219 | + MADERA_IN4L_HPF_SHIFT, 1, 0), | |
| 220 | +SOC_SINGLE("IN4R HPF Switch", MADERA_IN4R_CONTROL, | |
| 221 | + MADERA_IN4R_HPF_SHIFT, 1, 0), | |
| 222 | + | |
| 223 | +SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L, | |
| 224 | + MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 225 | +SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R, | |
| 226 | + MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 227 | +SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L, | |
| 228 | + MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 229 | +SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R, | |
| 230 | + MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 231 | +SOC_SINGLE_TLV("IN3L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3L, | |
| 232 | + MADERA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 233 | +SOC_SINGLE_TLV("IN3R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3R, | |
| 234 | + MADERA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 235 | +SOC_SINGLE_TLV("IN4L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4L, | |
| 236 | + MADERA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 237 | +SOC_SINGLE_TLV("IN4R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4R, | |
| 238 | + MADERA_IN4R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv), | |
| 239 | + | |
| 240 | +SOC_ENUM("Input Ramp Up", madera_in_vi_ramp), | |
| 241 | +SOC_ENUM("Input Ramp Down", madera_in_vd_ramp), | |
| 242 | + | |
| 243 | +MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE), | |
| 244 | +MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE), | |
| 245 | +MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE), | |
| 246 | +MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE), | |
| 247 | + | |
| 248 | +MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2), | |
| 249 | +SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT, | |
| 250 | + 24, 0, madera_eq_tlv), | |
| 251 | +SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT, | |
| 252 | + 24, 0, madera_eq_tlv), | |
| 253 | +SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT, | |
| 254 | + 24, 0, madera_eq_tlv), | |
| 255 | +SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT, | |
| 256 | + 24, 0, madera_eq_tlv), | |
| 257 | +SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT, | |
| 258 | + 24, 0, madera_eq_tlv), | |
| 259 | + | |
| 260 | +MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2), | |
| 261 | +SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT, | |
| 262 | + 24, 0, madera_eq_tlv), | |
| 263 | +SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT, | |
| 264 | + 24, 0, madera_eq_tlv), | |
| 265 | +SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT, | |
| 266 | + 24, 0, madera_eq_tlv), | |
| 267 | +SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT, | |
| 268 | + 24, 0, madera_eq_tlv), | |
| 269 | +SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT, | |
| 270 | + 24, 0, madera_eq_tlv), | |
| 271 | + | |
| 272 | +MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2), | |
| 273 | +SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT, | |
| 274 | + 24, 0, madera_eq_tlv), | |
| 275 | +SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT, | |
| 276 | + 24, 0, madera_eq_tlv), | |
| 277 | +SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT, | |
| 278 | + 24, 0, madera_eq_tlv), | |
| 279 | +SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT, | |
| 280 | + 24, 0, madera_eq_tlv), | |
| 281 | +SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT, | |
| 282 | + 24, 0, madera_eq_tlv), | |
| 283 | + | |
| 284 | +MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2), | |
| 285 | +SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT, | |
| 286 | + 24, 0, madera_eq_tlv), | |
| 287 | +SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT, | |
| 288 | + 24, 0, madera_eq_tlv), | |
| 289 | +SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT, | |
| 290 | + 24, 0, madera_eq_tlv), | |
| 291 | +SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT, | |
| 292 | + 24, 0, madera_eq_tlv), | |
| 293 | +SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT, | |
| 294 | + 24, 0, madera_eq_tlv), | |
| 295 | + | |
| 296 | +SOC_SINGLE("DAC High Performance Mode Switch", MADERA_OUTPUT_RATE_1, | |
| 297 | + MADERA_CP_DAC_MODE_SHIFT, 1, 0), | |
| 298 | + | |
| 299 | +MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE), | |
| 300 | +MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE), | |
| 301 | +MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE), | |
| 302 | +MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE), | |
| 303 | + | |
| 304 | +SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5, | |
| 305 | + MADERA_DRC1R_ENA | MADERA_DRC1L_ENA), | |
| 306 | +SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5, | |
| 307 | + MADERA_DRC2R_ENA | MADERA_DRC2L_ENA), | |
| 308 | + | |
| 309 | +MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE), | |
| 310 | +MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE), | |
| 311 | +MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE), | |
| 312 | +MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE), | |
| 313 | + | |
| 314 | +MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2), | |
| 315 | +MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2), | |
| 316 | +MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2), | |
| 317 | +MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2), | |
| 318 | + | |
| 319 | +SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode), | |
| 320 | +SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode), | |
| 321 | +SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode), | |
| 322 | +SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode), | |
| 323 | + | |
| 324 | +MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]), | |
| 325 | +MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]), | |
| 326 | +MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]), | |
| 327 | +MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]), | |
| 328 | +MADERA_RATE_ENUM("ASRC1 Rate 1", madera_asrc1_bidir_rate[0]), | |
| 329 | +MADERA_RATE_ENUM("ASRC1 Rate 2", madera_asrc1_bidir_rate[1]), | |
| 330 | + | |
| 331 | +WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), | |
| 332 | + | |
| 333 | +MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE), | |
| 334 | +MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE), | |
| 335 | + | |
| 336 | +SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR, | |
| 337 | + MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv), | |
| 338 | + | |
| 339 | +MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE), | |
| 340 | +MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE), | |
| 341 | +MADERA_MIXER_CONTROLS("HPOUT2L", MADERA_OUT2LMIX_INPUT_1_SOURCE), | |
| 342 | +MADERA_MIXER_CONTROLS("HPOUT2R", MADERA_OUT2RMIX_INPUT_1_SOURCE), | |
| 343 | +MADERA_MIXER_CONTROLS("HPOUT3L", MADERA_OUT3LMIX_INPUT_1_SOURCE), | |
| 344 | +MADERA_MIXER_CONTROLS("HPOUT3R", MADERA_OUT3RMIX_INPUT_1_SOURCE), | |
| 345 | +MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE), | |
| 346 | +MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE), | |
| 347 | + | |
| 348 | +SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL, | |
| 349 | + MADERA_HP1_SC_ENA_SHIFT, 1, 0), | |
| 350 | +SOC_SINGLE("HPOUT2 SC Protect Switch", MADERA_HP2_SHORT_CIRCUIT_CTRL, | |
| 351 | + MADERA_HP2_SC_ENA_SHIFT, 1, 0), | |
| 352 | +SOC_SINGLE("HPOUT3 SC Protect Switch", MADERA_HP3_SHORT_CIRCUIT_CTRL, | |
| 353 | + MADERA_HP3_SC_ENA_SHIFT, 1, 0), | |
| 354 | + | |
| 355 | +SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L, | |
| 356 | + MADERA_OUT5_OSR_SHIFT, 1, 0), | |
| 357 | + | |
| 358 | +SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 359 | + MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1), | |
| 360 | +SOC_DOUBLE_R("HPOUT2 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_2L, | |
| 361 | + MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_MUTE_SHIFT, 1, 1), | |
| 362 | +SOC_DOUBLE_R("HPOUT3 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_3L, | |
| 363 | + MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_MUTE_SHIFT, 1, 1), | |
| 364 | +SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 365 | + MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1), | |
| 366 | + | |
| 367 | +SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 368 | + MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT, | |
| 369 | + 0xbf, 0, madera_digital_tlv), | |
| 370 | +SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_2L, | |
| 371 | + MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_VOL_SHIFT, | |
| 372 | + 0xbf, 0, madera_digital_tlv), | |
| 373 | +SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_3L, | |
| 374 | + MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_VOL_SHIFT, | |
| 375 | + 0xbf, 0, madera_digital_tlv), | |
| 376 | +SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 377 | + MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT, | |
| 378 | + 0xbf, 0, madera_digital_tlv), | |
| 379 | + | |
| 380 | +SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT, | |
| 381 | + MADERA_SPK1R_MUTE_SHIFT, 1, 1), | |
| 382 | + | |
| 383 | +SOC_ENUM("Output Ramp Up", madera_out_vi_ramp), | |
| 384 | +SOC_ENUM("Output Ramp Down", madera_out_vd_ramp), | |
| 385 | + | |
| 386 | +SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL, | |
| 387 | + MADERA_NGATE_ENA_SHIFT, 1, 0), | |
| 388 | +SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL, | |
| 389 | + MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv), | |
| 390 | +SOC_ENUM("Noise Gate Hold", madera_ng_hold), | |
| 391 | + | |
| 392 | +SOC_ENUM_EXT("DFC1RX Width", madera_dfc_width[0], | |
| 393 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 394 | +SOC_ENUM_EXT("DFC1RX Type", madera_dfc_type[0], | |
| 395 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 396 | +SOC_ENUM_EXT("DFC1TX Width", madera_dfc_width[1], | |
| 397 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 398 | +SOC_ENUM_EXT("DFC1TX Type", madera_dfc_type[1], | |
| 399 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 400 | +SOC_ENUM_EXT("DFC2RX Width", madera_dfc_width[2], | |
| 401 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 402 | +SOC_ENUM_EXT("DFC2RX Type", madera_dfc_type[2], | |
| 403 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 404 | +SOC_ENUM_EXT("DFC2TX Width", madera_dfc_width[3], | |
| 405 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 406 | +SOC_ENUM_EXT("DFC2TX Type", madera_dfc_type[3], | |
| 407 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 408 | +SOC_ENUM_EXT("DFC3RX Width", madera_dfc_width[4], | |
| 409 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 410 | +SOC_ENUM_EXT("DFC3RX Type", madera_dfc_type[4], | |
| 411 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 412 | +SOC_ENUM_EXT("DFC3TX Width", madera_dfc_width[5], | |
| 413 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 414 | +SOC_ENUM_EXT("DFC3TX Type", madera_dfc_type[5], | |
| 415 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 416 | +SOC_ENUM_EXT("DFC4RX Width", madera_dfc_width[6], | |
| 417 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 418 | +SOC_ENUM_EXT("DFC4RX Type", madera_dfc_type[6], | |
| 419 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 420 | +SOC_ENUM_EXT("DFC4TX Width", madera_dfc_width[7], | |
| 421 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 422 | +SOC_ENUM_EXT("DFC4TX Type", madera_dfc_type[7], | |
| 423 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 424 | +SOC_ENUM_EXT("DFC5RX Width", madera_dfc_width[8], | |
| 425 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 426 | +SOC_ENUM_EXT("DFC5RX Type", madera_dfc_type[8], | |
| 427 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 428 | +SOC_ENUM_EXT("DFC5TX Width", madera_dfc_width[9], | |
| 429 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 430 | +SOC_ENUM_EXT("DFC5TX Type", madera_dfc_type[9], | |
| 431 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 432 | +SOC_ENUM_EXT("DFC6RX Width", madera_dfc_width[10], | |
| 433 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 434 | +SOC_ENUM_EXT("DFC6RX Type", madera_dfc_type[10], | |
| 435 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 436 | +SOC_ENUM_EXT("DFC6TX Width", madera_dfc_width[11], | |
| 437 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 438 | +SOC_ENUM_EXT("DFC6TX Type", madera_dfc_type[11], | |
| 439 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 440 | +SOC_ENUM_EXT("DFC7RX Width", madera_dfc_width[12], | |
| 441 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 442 | +SOC_ENUM_EXT("DFC7RX Type", madera_dfc_type[12], | |
| 443 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 444 | +SOC_ENUM_EXT("DFC7TX Width", madera_dfc_width[13], | |
| 445 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 446 | +SOC_ENUM_EXT("DFC7TX Type", madera_dfc_type[13], | |
| 447 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 448 | +SOC_ENUM_EXT("DFC8RX Width", madera_dfc_width[14], | |
| 449 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 450 | +SOC_ENUM_EXT("DFC8RX Type", madera_dfc_type[14], | |
| 451 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 452 | +SOC_ENUM_EXT("DFC8TX Width", madera_dfc_width[15], | |
| 453 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 454 | +SOC_ENUM_EXT("DFC8TX Type", madera_dfc_type[15], | |
| 455 | + snd_soc_get_enum_double, madera_dfc_put), | |
| 456 | + | |
| 457 | +CS47L92_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L), | |
| 458 | +CS47L92_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R), | |
| 459 | +CS47L92_NG_SRC("HPOUT2L", MADERA_NOISE_GATE_SELECT_2L), | |
| 460 | +CS47L92_NG_SRC("HPOUT2R", MADERA_NOISE_GATE_SELECT_2R), | |
| 461 | +CS47L92_NG_SRC("HPOUT3L", MADERA_NOISE_GATE_SELECT_3L), | |
| 462 | +CS47L92_NG_SRC("HPOUT3R", MADERA_NOISE_GATE_SELECT_3R), | |
| 463 | +CS47L92_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L), | |
| 464 | +CS47L92_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R), | |
| 465 | + | |
| 466 | +MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE), | |
| 467 | +MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE), | |
| 468 | +MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE), | |
| 469 | +MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE), | |
| 470 | +MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE), | |
| 471 | +MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE), | |
| 472 | +MADERA_MIXER_CONTROLS("AIF1TX7", MADERA_AIF1TX7MIX_INPUT_1_SOURCE), | |
| 473 | +MADERA_MIXER_CONTROLS("AIF1TX8", MADERA_AIF1TX8MIX_INPUT_1_SOURCE), | |
| 474 | + | |
| 475 | +MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE), | |
| 476 | +MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE), | |
| 477 | +MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE), | |
| 478 | +MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE), | |
| 479 | +MADERA_MIXER_CONTROLS("AIF2TX5", MADERA_AIF2TX5MIX_INPUT_1_SOURCE), | |
| 480 | +MADERA_MIXER_CONTROLS("AIF2TX6", MADERA_AIF2TX6MIX_INPUT_1_SOURCE), | |
| 481 | +MADERA_MIXER_CONTROLS("AIF2TX7", MADERA_AIF2TX7MIX_INPUT_1_SOURCE), | |
| 482 | +MADERA_MIXER_CONTROLS("AIF2TX8", MADERA_AIF2TX8MIX_INPUT_1_SOURCE), | |
| 483 | + | |
| 484 | +MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE), | |
| 485 | +MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE), | |
| 486 | +MADERA_MIXER_CONTROLS("AIF3TX3", MADERA_AIF3TX3MIX_INPUT_1_SOURCE), | |
| 487 | +MADERA_MIXER_CONTROLS("AIF3TX4", MADERA_AIF3TX4MIX_INPUT_1_SOURCE), | |
| 488 | + | |
| 489 | +MADERA_MIXER_CONTROLS("SLIMTX1", MADERA_SLIMTX1MIX_INPUT_1_SOURCE), | |
| 490 | +MADERA_MIXER_CONTROLS("SLIMTX2", MADERA_SLIMTX2MIX_INPUT_1_SOURCE), | |
| 491 | +MADERA_MIXER_CONTROLS("SLIMTX3", MADERA_SLIMTX3MIX_INPUT_1_SOURCE), | |
| 492 | +MADERA_MIXER_CONTROLS("SLIMTX4", MADERA_SLIMTX4MIX_INPUT_1_SOURCE), | |
| 493 | +MADERA_MIXER_CONTROLS("SLIMTX5", MADERA_SLIMTX5MIX_INPUT_1_SOURCE), | |
| 494 | +MADERA_MIXER_CONTROLS("SLIMTX6", MADERA_SLIMTX6MIX_INPUT_1_SOURCE), | |
| 495 | +MADERA_MIXER_CONTROLS("SLIMTX7", MADERA_SLIMTX7MIX_INPUT_1_SOURCE), | |
| 496 | +MADERA_MIXER_CONTROLS("SLIMTX8", MADERA_SLIMTX8MIX_INPUT_1_SOURCE), | |
| 497 | + | |
| 498 | +MADERA_GAINMUX_CONTROLS("SPDIFTX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE), | |
| 499 | +MADERA_GAINMUX_CONTROLS("SPDIFTX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE), | |
| 500 | + | |
| 501 | +WM_ADSP_FW_CONTROL("DSP1", 0), | |
| 502 | +}; | |
| 503 | + | |
| 504 | +MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE); | |
| 505 | +MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE); | |
| 506 | +MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE); | |
| 507 | +MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE); | |
| 508 | + | |
| 509 | +MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE); | |
| 510 | +MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE); | |
| 511 | +MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE); | |
| 512 | +MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE); | |
| 513 | + | |
| 514 | +MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE); | |
| 515 | +MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE); | |
| 516 | +MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE); | |
| 517 | +MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE); | |
| 518 | + | |
| 519 | +MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE); | |
| 520 | +MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE); | |
| 521 | +MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE); | |
| 522 | + | |
| 523 | +MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE); | |
| 524 | +MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE); | |
| 525 | + | |
| 526 | +MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE); | |
| 527 | +MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE); | |
| 528 | +MADERA_MIXER_ENUMS(OUT2L, MADERA_OUT2LMIX_INPUT_1_SOURCE); | |
| 529 | +MADERA_MIXER_ENUMS(OUT2R, MADERA_OUT2RMIX_INPUT_1_SOURCE); | |
| 530 | +MADERA_MIXER_ENUMS(OUT3L, MADERA_OUT3LMIX_INPUT_1_SOURCE); | |
| 531 | +MADERA_MIXER_ENUMS(OUT3R, MADERA_OUT3RMIX_INPUT_1_SOURCE); | |
| 532 | +MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE); | |
| 533 | +MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE); | |
| 534 | + | |
| 535 | +MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE); | |
| 536 | +MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE); | |
| 537 | +MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE); | |
| 538 | +MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE); | |
| 539 | +MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE); | |
| 540 | +MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE); | |
| 541 | +MADERA_MIXER_ENUMS(AIF1TX7, MADERA_AIF1TX7MIX_INPUT_1_SOURCE); | |
| 542 | +MADERA_MIXER_ENUMS(AIF1TX8, MADERA_AIF1TX8MIX_INPUT_1_SOURCE); | |
| 543 | + | |
| 544 | +MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE); | |
| 545 | +MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE); | |
| 546 | +MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE); | |
| 547 | +MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE); | |
| 548 | +MADERA_MIXER_ENUMS(AIF2TX5, MADERA_AIF2TX5MIX_INPUT_1_SOURCE); | |
| 549 | +MADERA_MIXER_ENUMS(AIF2TX6, MADERA_AIF2TX6MIX_INPUT_1_SOURCE); | |
| 550 | +MADERA_MIXER_ENUMS(AIF2TX7, MADERA_AIF2TX7MIX_INPUT_1_SOURCE); | |
| 551 | +MADERA_MIXER_ENUMS(AIF2TX8, MADERA_AIF2TX8MIX_INPUT_1_SOURCE); | |
| 552 | + | |
| 553 | +MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE); | |
| 554 | +MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE); | |
| 555 | +MADERA_MIXER_ENUMS(AIF3TX3, MADERA_AIF3TX3MIX_INPUT_1_SOURCE); | |
| 556 | +MADERA_MIXER_ENUMS(AIF3TX4, MADERA_AIF3TX4MIX_INPUT_1_SOURCE); | |
| 557 | + | |
| 558 | +MADERA_MIXER_ENUMS(SLIMTX1, MADERA_SLIMTX1MIX_INPUT_1_SOURCE); | |
| 559 | +MADERA_MIXER_ENUMS(SLIMTX2, MADERA_SLIMTX2MIX_INPUT_1_SOURCE); | |
| 560 | +MADERA_MIXER_ENUMS(SLIMTX3, MADERA_SLIMTX3MIX_INPUT_1_SOURCE); | |
| 561 | +MADERA_MIXER_ENUMS(SLIMTX4, MADERA_SLIMTX4MIX_INPUT_1_SOURCE); | |
| 562 | +MADERA_MIXER_ENUMS(SLIMTX5, MADERA_SLIMTX5MIX_INPUT_1_SOURCE); | |
| 563 | +MADERA_MIXER_ENUMS(SLIMTX6, MADERA_SLIMTX6MIX_INPUT_1_SOURCE); | |
| 564 | +MADERA_MIXER_ENUMS(SLIMTX7, MADERA_SLIMTX7MIX_INPUT_1_SOURCE); | |
| 565 | +MADERA_MIXER_ENUMS(SLIMTX8, MADERA_SLIMTX8MIX_INPUT_1_SOURCE); | |
| 566 | + | |
| 567 | +MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE); | |
| 568 | +MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE); | |
| 569 | + | |
| 570 | +MADERA_MUX_ENUMS(ASRC1IN1L, MADERA_ASRC1_1LMIX_INPUT_1_SOURCE); | |
| 571 | +MADERA_MUX_ENUMS(ASRC1IN1R, MADERA_ASRC1_1RMIX_INPUT_1_SOURCE); | |
| 572 | +MADERA_MUX_ENUMS(ASRC1IN2L, MADERA_ASRC1_2LMIX_INPUT_1_SOURCE); | |
| 573 | +MADERA_MUX_ENUMS(ASRC1IN2R, MADERA_ASRC1_2RMIX_INPUT_1_SOURCE); | |
| 574 | + | |
| 575 | +MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE); | |
| 576 | +MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE); | |
| 577 | + | |
| 578 | +MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE); | |
| 579 | +MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE); | |
| 580 | + | |
| 581 | +MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE); | |
| 582 | +MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE); | |
| 583 | + | |
| 584 | +MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE); | |
| 585 | +MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE); | |
| 586 | + | |
| 587 | +MADERA_MUX_ENUMS(DFC1, MADERA_DFC1MIX_INPUT_1_SOURCE); | |
| 588 | +MADERA_MUX_ENUMS(DFC2, MADERA_DFC2MIX_INPUT_1_SOURCE); | |
| 589 | +MADERA_MUX_ENUMS(DFC3, MADERA_DFC3MIX_INPUT_1_SOURCE); | |
| 590 | +MADERA_MUX_ENUMS(DFC4, MADERA_DFC4MIX_INPUT_1_SOURCE); | |
| 591 | +MADERA_MUX_ENUMS(DFC5, MADERA_DFC5MIX_INPUT_1_SOURCE); | |
| 592 | +MADERA_MUX_ENUMS(DFC6, MADERA_DFC6MIX_INPUT_1_SOURCE); | |
| 593 | +MADERA_MUX_ENUMS(DFC7, MADERA_DFC7MIX_INPUT_1_SOURCE); | |
| 594 | +MADERA_MUX_ENUMS(DFC8, MADERA_DFC8MIX_INPUT_1_SOURCE); | |
| 595 | + | |
| 596 | +static const char * const cs47l92_aec_loopback_texts[] = { | |
| 597 | + "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", | |
| 598 | + "SPKDAT1L", "SPKDAT1R", | |
| 599 | +}; | |
| 600 | + | |
| 601 | +static const unsigned int cs47l92_aec_loopback_values[] = { | |
| 602 | + 0, 1, 2, 3, 4, 5, 8, 9 | |
| 603 | +}; | |
| 604 | + | |
| 605 | +static const struct soc_enum cs47l92_aec_loopback = | |
| 606 | + SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1, | |
| 607 | + MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf, | |
| 608 | + ARRAY_SIZE(cs47l92_aec_loopback_texts), | |
| 609 | + cs47l92_aec_loopback_texts, | |
| 610 | + cs47l92_aec_loopback_values); | |
| 611 | + | |
| 612 | +static const struct snd_kcontrol_new cs47l92_aec_loopback_mux = | |
| 613 | + SOC_DAPM_ENUM("AEC1 Loopback", cs47l92_aec_loopback); | |
| 614 | + | |
| 615 | +static const struct snd_soc_dapm_widget cs47l92_dapm_widgets[] = { | |
| 616 | +SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT, | |
| 617 | + 0, madera_sysclk_ev, | |
| 618 | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | |
| 619 | +SND_SOC_DAPM_SUPPLY("ASYNCCLK", MADERA_ASYNC_CLOCK_1, | |
| 620 | + MADERA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | |
| 621 | +SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, | |
| 622 | + MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0), | |
| 623 | +SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", MADERA_OUTPUT_ASYNC_CLOCK, | |
| 624 | + MADERA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0), | |
| 625 | +SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, | |
| 626 | + MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0), | |
| 627 | + | |
| 628 | +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0), | |
| 629 | +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD2", 20, 0), | |
| 630 | +SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS), | |
| 631 | + | |
| 632 | +SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1, | |
| 633 | + MADERA_MICB1_ENA_SHIFT, 0, NULL, 0), | |
| 634 | +SND_SOC_DAPM_SUPPLY("MICBIAS2", MADERA_MIC_BIAS_CTRL_2, | |
| 635 | + MADERA_MICB1_ENA_SHIFT, 0, NULL, 0), | |
| 636 | + | |
| 637 | +SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5, | |
| 638 | + MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0), | |
| 639 | +SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5, | |
| 640 | + MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0), | |
| 641 | +SND_SOC_DAPM_SUPPLY("MICBIAS1C", MADERA_MIC_BIAS_CTRL_5, | |
| 642 | + MADERA_MICB1C_ENA_SHIFT, 0, NULL, 0), | |
| 643 | +SND_SOC_DAPM_SUPPLY("MICBIAS1D", MADERA_MIC_BIAS_CTRL_5, | |
| 644 | + MADERA_MICB1D_ENA_SHIFT, 0, NULL, 0), | |
| 645 | + | |
| 646 | +SND_SOC_DAPM_SUPPLY("MICBIAS2A", MADERA_MIC_BIAS_CTRL_6, | |
| 647 | + MADERA_MICB2A_ENA_SHIFT, 0, NULL, 0), | |
| 648 | +SND_SOC_DAPM_SUPPLY("MICBIAS2B", MADERA_MIC_BIAS_CTRL_6, | |
| 649 | + MADERA_MICB2B_ENA_SHIFT, 0, NULL, 0), | |
| 650 | + | |
| 651 | +SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM, | |
| 652 | + MADERA_DOM_GRP_FX, 0, | |
| 653 | + madera_domain_clk_ev, | |
| 654 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 655 | +SND_SOC_DAPM_SUPPLY("ASRC1CLK", SND_SOC_NOPM, | |
| 656 | + MADERA_DOM_GRP_ASRC1, 0, | |
| 657 | + madera_domain_clk_ev, | |
| 658 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 659 | +SND_SOC_DAPM_SUPPLY("ISRC1CLK", SND_SOC_NOPM, | |
| 660 | + MADERA_DOM_GRP_ISRC1, 0, | |
| 661 | + madera_domain_clk_ev, | |
| 662 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 663 | +SND_SOC_DAPM_SUPPLY("ISRC2CLK", SND_SOC_NOPM, | |
| 664 | + MADERA_DOM_GRP_ISRC2, 0, | |
| 665 | + madera_domain_clk_ev, | |
| 666 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 667 | +SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM, | |
| 668 | + MADERA_DOM_GRP_OUT, 0, | |
| 669 | + madera_domain_clk_ev, | |
| 670 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 671 | +SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM, | |
| 672 | + MADERA_DOM_GRP_SPD, 0, | |
| 673 | + madera_domain_clk_ev, | |
| 674 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 675 | +SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, | |
| 676 | + MADERA_DOM_GRP_DSP1, 0, | |
| 677 | + madera_domain_clk_ev, | |
| 678 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 679 | +SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM, | |
| 680 | + MADERA_DOM_GRP_AIF1, 0, | |
| 681 | + madera_domain_clk_ev, | |
| 682 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 683 | +SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM, | |
| 684 | + MADERA_DOM_GRP_AIF2, 0, | |
| 685 | + madera_domain_clk_ev, | |
| 686 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 687 | +SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM, | |
| 688 | + MADERA_DOM_GRP_AIF3, 0, | |
| 689 | + madera_domain_clk_ev, | |
| 690 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 691 | +SND_SOC_DAPM_SUPPLY("SLIMBUSCLK", SND_SOC_NOPM, | |
| 692 | + MADERA_DOM_GRP_SLIMBUS, 0, | |
| 693 | + madera_domain_clk_ev, | |
| 694 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 695 | +SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM, | |
| 696 | + MADERA_DOM_GRP_PWM, 0, | |
| 697 | + madera_domain_clk_ev, | |
| 698 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 699 | +SND_SOC_DAPM_SUPPLY("DFCCLK", SND_SOC_NOPM, | |
| 700 | + MADERA_DOM_GRP_DFC, 0, | |
| 701 | + madera_domain_clk_ev, | |
| 702 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 703 | + | |
| 704 | +SND_SOC_DAPM_SIGGEN("TONE"), | |
| 705 | +SND_SOC_DAPM_SIGGEN("NOISE"), | |
| 706 | + | |
| 707 | +SND_SOC_DAPM_INPUT("IN1ALN"), | |
| 708 | +SND_SOC_DAPM_INPUT("IN1ALP"), | |
| 709 | +SND_SOC_DAPM_INPUT("IN1BLN"), | |
| 710 | +SND_SOC_DAPM_INPUT("IN1BLP"), | |
| 711 | +SND_SOC_DAPM_INPUT("IN1ARN"), | |
| 712 | +SND_SOC_DAPM_INPUT("IN1ARP"), | |
| 713 | +SND_SOC_DAPM_INPUT("IN1BR"), | |
| 714 | +SND_SOC_DAPM_INPUT("IN2ALN"), | |
| 715 | +SND_SOC_DAPM_INPUT("IN2ALP"), | |
| 716 | +SND_SOC_DAPM_INPUT("IN2BL"), | |
| 717 | +SND_SOC_DAPM_INPUT("IN2ARN"), | |
| 718 | +SND_SOC_DAPM_INPUT("IN2ARP"), | |
| 719 | +SND_SOC_DAPM_INPUT("IN2BR"), | |
| 720 | + | |
| 721 | +SND_SOC_DAPM_MUX("IN1L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]), | |
| 722 | +SND_SOC_DAPM_MUX("IN1R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]), | |
| 723 | +SND_SOC_DAPM_MUX("IN2L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[2]), | |
| 724 | +SND_SOC_DAPM_MUX("IN2R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[3]), | |
| 725 | + | |
| 726 | +SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]), | |
| 727 | +SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]), | |
| 728 | + | |
| 729 | +SND_SOC_DAPM_MUX("IN2L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]), | |
| 730 | +SND_SOC_DAPM_MUX("IN2R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]), | |
| 731 | + | |
| 732 | +SND_SOC_DAPM_DEMUX("OUT3 Demux", SND_SOC_NOPM, 0, 0, &cs47l92_outdemux), | |
| 733 | + | |
| 734 | +SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"), | |
| 735 | +SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), | |
| 736 | + | |
| 737 | +SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT, | |
| 738 | + 0, NULL, 0), | |
| 739 | +SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT, | |
| 740 | + 0, NULL, 0), | |
| 741 | + | |
| 742 | +SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, | |
| 743 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0), | |
| 744 | +SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, | |
| 745 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0), | |
| 746 | +SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0, | |
| 747 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0), | |
| 748 | +SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0, | |
| 749 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0), | |
| 750 | +SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0, | |
| 751 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0), | |
| 752 | +SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0, | |
| 753 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0), | |
| 754 | +SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0, | |
| 755 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX7_ENA_SHIFT, 0), | |
| 756 | +SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0, | |
| 757 | + MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX8_ENA_SHIFT, 0), | |
| 758 | + | |
| 759 | +SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, | |
| 760 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0), | |
| 761 | +SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0, | |
| 762 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0), | |
| 763 | +SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0, | |
| 764 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0), | |
| 765 | +SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0, | |
| 766 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0), | |
| 767 | +SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0, | |
| 768 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX5_ENA_SHIFT, 0), | |
| 769 | +SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0, | |
| 770 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX6_ENA_SHIFT, 0), | |
| 771 | +SND_SOC_DAPM_AIF_OUT("AIF2TX7", NULL, 0, | |
| 772 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX7_ENA_SHIFT, 0), | |
| 773 | +SND_SOC_DAPM_AIF_OUT("AIF2TX8", NULL, 0, | |
| 774 | + MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX8_ENA_SHIFT, 0), | |
| 775 | + | |
| 776 | +SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0, | |
| 777 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 778 | + MADERA_SLIMTX1_ENA_SHIFT, 0), | |
| 779 | +SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0, | |
| 780 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 781 | + MADERA_SLIMTX2_ENA_SHIFT, 0), | |
| 782 | +SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0, | |
| 783 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 784 | + MADERA_SLIMTX3_ENA_SHIFT, 0), | |
| 785 | +SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0, | |
| 786 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 787 | + MADERA_SLIMTX4_ENA_SHIFT, 0), | |
| 788 | +SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0, | |
| 789 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 790 | + MADERA_SLIMTX5_ENA_SHIFT, 0), | |
| 791 | +SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0, | |
| 792 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 793 | + MADERA_SLIMTX6_ENA_SHIFT, 0), | |
| 794 | +SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0, | |
| 795 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 796 | + MADERA_SLIMTX7_ENA_SHIFT, 0), | |
| 797 | +SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0, | |
| 798 | + MADERA_SLIMBUS_TX_CHANNEL_ENABLE, | |
| 799 | + MADERA_SLIMTX8_ENA_SHIFT, 0), | |
| 800 | + | |
| 801 | +SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0, | |
| 802 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0), | |
| 803 | +SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0, | |
| 804 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0), | |
| 805 | +SND_SOC_DAPM_AIF_OUT("AIF3TX3", NULL, 0, | |
| 806 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX3_ENA_SHIFT, 0), | |
| 807 | +SND_SOC_DAPM_AIF_OUT("AIF3TX4", NULL, 0, | |
| 808 | + MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX4_ENA_SHIFT, 0), | |
| 809 | + | |
| 810 | +SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, | |
| 811 | + MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 812 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 813 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 814 | +SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, | |
| 815 | + MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 816 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 817 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 818 | +SND_SOC_DAPM_PGA_E("OUT2L", SND_SOC_NOPM, | |
| 819 | + MADERA_OUT2L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 820 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 821 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 822 | +SND_SOC_DAPM_PGA_E("OUT2R", SND_SOC_NOPM, | |
| 823 | + MADERA_OUT2R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev, | |
| 824 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 825 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 826 | +SND_SOC_DAPM_PGA_E("OUT3L", MADERA_OUTPUT_ENABLES_1, | |
| 827 | + MADERA_OUT3L_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 828 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 829 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 830 | +SND_SOC_DAPM_PGA_E("OUT3R", MADERA_OUTPUT_ENABLES_1, | |
| 831 | + MADERA_OUT3R_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 832 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 833 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 834 | +SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1, | |
| 835 | + MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 836 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
| 837 | +SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1, | |
| 838 | + MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev, | |
| 839 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
| 840 | + | |
| 841 | +SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL, | |
| 842 | + MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0), | |
| 843 | +SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL, | |
| 844 | + MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0), | |
| 845 | +SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL, | |
| 846 | + MADERA_SPD1_ENA_SHIFT, 0, NULL, 0), | |
| 847 | + | |
| 848 | +/* | |
| 849 | + * mux_in widgets : arranged in the order of sources | |
| 850 | + * specified in MADERA_MIXER_INPUT_ROUTES | |
| 851 | + */ | |
| 852 | + | |
| 853 | +SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR, | |
| 854 | + MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), | |
| 855 | + | |
| 856 | +SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1, | |
| 857 | + MADERA_TONE1_ENA_SHIFT, 0, NULL, 0), | |
| 858 | +SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1, | |
| 859 | + MADERA_TONE2_ENA_SHIFT, 0, NULL, 0), | |
| 860 | + | |
| 861 | +SND_SOC_DAPM_SIGGEN("HAPTICS"), | |
| 862 | + | |
| 863 | +SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1, | |
| 864 | + MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0, | |
| 865 | + &cs47l92_aec_loopback_mux), | |
| 866 | + | |
| 867 | +SND_SOC_DAPM_PGA_E("IN1L", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT, | |
| 868 | + 0, NULL, 0, madera_in_ev, | |
| 869 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 870 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 871 | +SND_SOC_DAPM_PGA_E("IN1R", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT, | |
| 872 | + 0, NULL, 0, madera_in_ev, | |
| 873 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 874 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 875 | +SND_SOC_DAPM_PGA_E("IN2L", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT, | |
| 876 | + 0, NULL, 0, madera_in_ev, | |
| 877 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 878 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 879 | +SND_SOC_DAPM_PGA_E("IN2R", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT, | |
| 880 | + 0, NULL, 0, madera_in_ev, | |
| 881 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 882 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 883 | +SND_SOC_DAPM_PGA_E("IN3L", MADERA_INPUT_ENABLES, MADERA_IN3L_ENA_SHIFT, | |
| 884 | + 0, NULL, 0, madera_in_ev, | |
| 885 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 886 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 887 | +SND_SOC_DAPM_PGA_E("IN3R", MADERA_INPUT_ENABLES, MADERA_IN3R_ENA_SHIFT, | |
| 888 | + 0, NULL, 0, madera_in_ev, | |
| 889 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 890 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 891 | +SND_SOC_DAPM_PGA_E("IN4L", MADERA_INPUT_ENABLES, MADERA_IN4L_ENA_SHIFT, | |
| 892 | + 0, NULL, 0, madera_in_ev, | |
| 893 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 894 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 895 | +SND_SOC_DAPM_PGA_E("IN4R", MADERA_INPUT_ENABLES, MADERA_IN4R_ENA_SHIFT, | |
| 896 | + 0, NULL, 0, madera_in_ev, | |
| 897 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | | |
| 898 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 899 | + | |
| 900 | +SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0, | |
| 901 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0), | |
| 902 | +SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0, | |
| 903 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0), | |
| 904 | +SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0, | |
| 905 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0), | |
| 906 | +SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0, | |
| 907 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0), | |
| 908 | +SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0, | |
| 909 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0), | |
| 910 | +SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0, | |
| 911 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0), | |
| 912 | +SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0, | |
| 913 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX7_ENA_SHIFT, 0), | |
| 914 | +SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0, | |
| 915 | + MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX8_ENA_SHIFT, 0), | |
| 916 | + | |
| 917 | +SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, | |
| 918 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0), | |
| 919 | +SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0, | |
| 920 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0), | |
| 921 | +SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0, | |
| 922 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0), | |
| 923 | +SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0, | |
| 924 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0), | |
| 925 | +SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0, | |
| 926 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX5_ENA_SHIFT, 0), | |
| 927 | +SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0, | |
| 928 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX6_ENA_SHIFT, 0), | |
| 929 | +SND_SOC_DAPM_AIF_IN("AIF2RX7", NULL, 0, | |
| 930 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX7_ENA_SHIFT, 0), | |
| 931 | +SND_SOC_DAPM_AIF_IN("AIF2RX8", NULL, 0, | |
| 932 | + MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX8_ENA_SHIFT, 0), | |
| 933 | + | |
| 934 | +SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |
| 935 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0), | |
| 936 | +SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | |
| 937 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0), | |
| 938 | +SND_SOC_DAPM_AIF_IN("AIF3RX3", NULL, 0, | |
| 939 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX3_ENA_SHIFT, 0), | |
| 940 | +SND_SOC_DAPM_AIF_IN("AIF3RX4", NULL, 0, | |
| 941 | + MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX4_ENA_SHIFT, 0), | |
| 942 | + | |
| 943 | +SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 944 | + MADERA_SLIMRX1_ENA_SHIFT, 0), | |
| 945 | +SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 946 | + MADERA_SLIMRX2_ENA_SHIFT, 0), | |
| 947 | +SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 948 | + MADERA_SLIMRX3_ENA_SHIFT, 0), | |
| 949 | +SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 950 | + MADERA_SLIMRX4_ENA_SHIFT, 0), | |
| 951 | +SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 952 | + MADERA_SLIMRX5_ENA_SHIFT, 0), | |
| 953 | +SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 954 | + MADERA_SLIMRX6_ENA_SHIFT, 0), | |
| 955 | +SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 956 | + MADERA_SLIMRX7_ENA_SHIFT, 0), | |
| 957 | +SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE, | |
| 958 | + MADERA_SLIMRX8_ENA_SHIFT, 0), | |
| 959 | + | |
| 960 | +SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0), | |
| 961 | +SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0), | |
| 962 | +SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0), | |
| 963 | +SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0), | |
| 964 | + | |
| 965 | +SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0, | |
| 966 | + NULL, 0), | |
| 967 | +SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0, | |
| 968 | + NULL, 0), | |
| 969 | +SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0, | |
| 970 | + NULL, 0), | |
| 971 | +SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0, | |
| 972 | + NULL, 0), | |
| 973 | + | |
| 974 | +SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0, | |
| 975 | + NULL, 0), | |
| 976 | +SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0, | |
| 977 | + NULL, 0), | |
| 978 | +SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0, | |
| 979 | + NULL, 0), | |
| 980 | +SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0, | |
| 981 | + NULL, 0), | |
| 982 | + | |
| 983 | +SND_SOC_DAPM_PGA("ASRC1IN1L", MADERA_ASRC1_ENABLE, | |
| 984 | + MADERA_ASRC1_IN1L_ENA_SHIFT, 0, NULL, 0), | |
| 985 | +SND_SOC_DAPM_PGA("ASRC1IN1R", MADERA_ASRC1_ENABLE, | |
| 986 | + MADERA_ASRC1_IN1R_ENA_SHIFT, 0, NULL, 0), | |
| 987 | +SND_SOC_DAPM_PGA("ASRC1IN2L", MADERA_ASRC1_ENABLE, | |
| 988 | + MADERA_ASRC1_IN2L_ENA_SHIFT, 0, NULL, 0), | |
| 989 | +SND_SOC_DAPM_PGA("ASRC1IN2R", MADERA_ASRC1_ENABLE, | |
| 990 | + MADERA_ASRC1_IN2R_ENA_SHIFT, 0, NULL, 0), | |
| 991 | + | |
| 992 | +SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3, | |
| 993 | + MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0), | |
| 994 | +SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3, | |
| 995 | + MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0), | |
| 996 | + | |
| 997 | +SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3, | |
| 998 | + MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0), | |
| 999 | +SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3, | |
| 1000 | + MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0), | |
| 1001 | + | |
| 1002 | +SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3, | |
| 1003 | + MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0), | |
| 1004 | +SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3, | |
| 1005 | + MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0), | |
| 1006 | + | |
| 1007 | +SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3, | |
| 1008 | + MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0), | |
| 1009 | +SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3, | |
| 1010 | + MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0), | |
| 1011 | + | |
| 1012 | +WM_ADSP2("DSP1", 0, cs47l92_adsp_power_ev), | |
| 1013 | + | |
| 1014 | +/* end of ordered widget list */ | |
| 1015 | + | |
| 1016 | +SND_SOC_DAPM_PGA("DFC1", MADERA_DFC1_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1017 | +SND_SOC_DAPM_PGA("DFC2", MADERA_DFC2_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1018 | +SND_SOC_DAPM_PGA("DFC3", MADERA_DFC3_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1019 | +SND_SOC_DAPM_PGA("DFC4", MADERA_DFC4_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1020 | +SND_SOC_DAPM_PGA("DFC5", MADERA_DFC5_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1021 | +SND_SOC_DAPM_PGA("DFC6", MADERA_DFC6_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1022 | +SND_SOC_DAPM_PGA("DFC7", MADERA_DFC7_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1023 | +SND_SOC_DAPM_PGA("DFC8", MADERA_DFC8_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0), | |
| 1024 | + | |
| 1025 | +MADERA_MIXER_WIDGETS(EQ1, "EQ1"), | |
| 1026 | +MADERA_MIXER_WIDGETS(EQ2, "EQ2"), | |
| 1027 | +MADERA_MIXER_WIDGETS(EQ3, "EQ3"), | |
| 1028 | +MADERA_MIXER_WIDGETS(EQ4, "EQ4"), | |
| 1029 | + | |
| 1030 | +MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"), | |
| 1031 | +MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"), | |
| 1032 | +MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"), | |
| 1033 | +MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"), | |
| 1034 | + | |
| 1035 | +SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0, | |
| 1036 | + &madera_drc_activity_output_mux[0]), | |
| 1037 | +SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0, | |
| 1038 | + &madera_drc_activity_output_mux[1]), | |
| 1039 | + | |
| 1040 | +MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"), | |
| 1041 | +MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"), | |
| 1042 | +MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"), | |
| 1043 | +MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"), | |
| 1044 | + | |
| 1045 | +MADERA_MIXER_WIDGETS(PWM1, "PWM1"), | |
| 1046 | +MADERA_MIXER_WIDGETS(PWM2, "PWM2"), | |
| 1047 | + | |
| 1048 | +MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"), | |
| 1049 | +MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"), | |
| 1050 | +MADERA_MIXER_WIDGETS(OUT2L, "HPOUT2L"), | |
| 1051 | +MADERA_MIXER_WIDGETS(OUT2R, "HPOUT2R"), | |
| 1052 | +MADERA_MIXER_WIDGETS(OUT3L, "HPOUT3L"), | |
| 1053 | +MADERA_MIXER_WIDGETS(OUT3R, "HPOUT3R"), | |
| 1054 | +MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), | |
| 1055 | +MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"), | |
| 1056 | + | |
| 1057 | +MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | |
| 1058 | +MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | |
| 1059 | +MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), | |
| 1060 | +MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), | |
| 1061 | +MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), | |
| 1062 | +MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), | |
| 1063 | +MADERA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"), | |
| 1064 | +MADERA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"), | |
| 1065 | + | |
| 1066 | +MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"), | |
| 1067 | +MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | |
| 1068 | +MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"), | |
| 1069 | +MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"), | |
| 1070 | +MADERA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"), | |
| 1071 | +MADERA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"), | |
| 1072 | +MADERA_MIXER_WIDGETS(AIF2TX7, "AIF2TX7"), | |
| 1073 | +MADERA_MIXER_WIDGETS(AIF2TX8, "AIF2TX8"), | |
| 1074 | + | |
| 1075 | +MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | |
| 1076 | +MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | |
| 1077 | +MADERA_MIXER_WIDGETS(AIF3TX3, "AIF3TX3"), | |
| 1078 | +MADERA_MIXER_WIDGETS(AIF3TX4, "AIF3TX4"), | |
| 1079 | + | |
| 1080 | +MADERA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"), | |
| 1081 | +MADERA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"), | |
| 1082 | +MADERA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"), | |
| 1083 | +MADERA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"), | |
| 1084 | +MADERA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"), | |
| 1085 | +MADERA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"), | |
| 1086 | +MADERA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"), | |
| 1087 | +MADERA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"), | |
| 1088 | + | |
| 1089 | +MADERA_MUX_WIDGETS(SPD1TX1, "SPDIFTX1"), | |
| 1090 | +MADERA_MUX_WIDGETS(SPD1TX2, "SPDIFTX2"), | |
| 1091 | + | |
| 1092 | +MADERA_MUX_WIDGETS(ASRC1IN1L, "ASRC1IN1L"), | |
| 1093 | +MADERA_MUX_WIDGETS(ASRC1IN1R, "ASRC1IN1R"), | |
| 1094 | +MADERA_MUX_WIDGETS(ASRC1IN2L, "ASRC1IN2L"), | |
| 1095 | +MADERA_MUX_WIDGETS(ASRC1IN2R, "ASRC1IN2R"), | |
| 1096 | + | |
| 1097 | +MADERA_DSP_WIDGETS(DSP1, "DSP1"), | |
| 1098 | + | |
| 1099 | +MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"), | |
| 1100 | +MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"), | |
| 1101 | + | |
| 1102 | +MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"), | |
| 1103 | +MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"), | |
| 1104 | + | |
| 1105 | +MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"), | |
| 1106 | +MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), | |
| 1107 | + | |
| 1108 | +MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), | |
| 1109 | +MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), | |
| 1110 | + | |
| 1111 | +MADERA_MUX_WIDGETS(DFC1, "DFC1"), | |
| 1112 | +MADERA_MUX_WIDGETS(DFC2, "DFC2"), | |
| 1113 | +MADERA_MUX_WIDGETS(DFC3, "DFC3"), | |
| 1114 | +MADERA_MUX_WIDGETS(DFC4, "DFC4"), | |
| 1115 | +MADERA_MUX_WIDGETS(DFC5, "DFC5"), | |
| 1116 | +MADERA_MUX_WIDGETS(DFC6, "DFC6"), | |
| 1117 | +MADERA_MUX_WIDGETS(DFC7, "DFC7"), | |
| 1118 | +MADERA_MUX_WIDGETS(DFC8, "DFC8"), | |
| 1119 | + | |
| 1120 | +SND_SOC_DAPM_OUTPUT("HPOUT1L"), | |
| 1121 | +SND_SOC_DAPM_OUTPUT("HPOUT1R"), | |
| 1122 | +SND_SOC_DAPM_OUTPUT("HPOUT2L"), | |
| 1123 | +SND_SOC_DAPM_OUTPUT("HPOUT2R"), | |
| 1124 | +SND_SOC_DAPM_OUTPUT("HPOUT3L"), | |
| 1125 | +SND_SOC_DAPM_OUTPUT("HPOUT3R"), | |
| 1126 | +SND_SOC_DAPM_OUTPUT("HPOUT4L"), | |
| 1127 | +SND_SOC_DAPM_OUTPUT("HPOUT4R"), | |
| 1128 | +SND_SOC_DAPM_OUTPUT("SPKDAT1L"), | |
| 1129 | +SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |
| 1130 | +SND_SOC_DAPM_OUTPUT("SPDIF1"), | |
| 1131 | + | |
| 1132 | +SND_SOC_DAPM_OUTPUT("MICSUPP"), | |
| 1133 | +}; | |
| 1134 | + | |
| 1135 | +#define MADERA_MIXER_INPUT_ROUTES(name) \ | |
| 1136 | + { name, "Noise Generator", "Noise Generator" }, \ | |
| 1137 | + { name, "Tone Generator 1", "Tone Generator 1" }, \ | |
| 1138 | + { name, "Tone Generator 2", "Tone Generator 2" }, \ | |
| 1139 | + { name, "Haptics", "HAPTICS" }, \ | |
| 1140 | + { name, "AEC1", "AEC1 Loopback" }, \ | |
| 1141 | + { name, "IN1L", "IN1L" }, \ | |
| 1142 | + { name, "IN1R", "IN1R" }, \ | |
| 1143 | + { name, "IN2L", "IN2L" }, \ | |
| 1144 | + { name, "IN2R", "IN2R" }, \ | |
| 1145 | + { name, "IN3L", "IN3L" }, \ | |
| 1146 | + { name, "IN3R", "IN3R" }, \ | |
| 1147 | + { name, "IN4L", "IN4L" }, \ | |
| 1148 | + { name, "IN4R", "IN4R" }, \ | |
| 1149 | + { name, "AIF1RX1", "AIF1RX1" }, \ | |
| 1150 | + { name, "AIF1RX2", "AIF1RX2" }, \ | |
| 1151 | + { name, "AIF1RX3", "AIF1RX3" }, \ | |
| 1152 | + { name, "AIF1RX4", "AIF1RX4" }, \ | |
| 1153 | + { name, "AIF1RX5", "AIF1RX5" }, \ | |
| 1154 | + { name, "AIF1RX6", "AIF1RX6" }, \ | |
| 1155 | + { name, "AIF1RX7", "AIF1RX7" }, \ | |
| 1156 | + { name, "AIF1RX8", "AIF1RX8" }, \ | |
| 1157 | + { name, "AIF2RX1", "AIF2RX1" }, \ | |
| 1158 | + { name, "AIF2RX2", "AIF2RX2" }, \ | |
| 1159 | + { name, "AIF2RX3", "AIF2RX3" }, \ | |
| 1160 | + { name, "AIF2RX4", "AIF2RX4" }, \ | |
| 1161 | + { name, "AIF2RX5", "AIF2RX5" }, \ | |
| 1162 | + { name, "AIF2RX6", "AIF2RX6" }, \ | |
| 1163 | + { name, "AIF2RX7", "AIF2RX7" }, \ | |
| 1164 | + { name, "AIF2RX8", "AIF2RX8" }, \ | |
| 1165 | + { name, "AIF3RX1", "AIF3RX1" }, \ | |
| 1166 | + { name, "AIF3RX2", "AIF3RX2" }, \ | |
| 1167 | + { name, "AIF3RX3", "AIF3RX3" }, \ | |
| 1168 | + { name, "AIF3RX4", "AIF3RX4" }, \ | |
| 1169 | + { name, "SLIMRX1", "SLIMRX1" }, \ | |
| 1170 | + { name, "SLIMRX2", "SLIMRX2" }, \ | |
| 1171 | + { name, "SLIMRX3", "SLIMRX3" }, \ | |
| 1172 | + { name, "SLIMRX4", "SLIMRX4" }, \ | |
| 1173 | + { name, "SLIMRX5", "SLIMRX5" }, \ | |
| 1174 | + { name, "SLIMRX6", "SLIMRX6" }, \ | |
| 1175 | + { name, "SLIMRX7", "SLIMRX7" }, \ | |
| 1176 | + { name, "SLIMRX8", "SLIMRX8" }, \ | |
| 1177 | + { name, "EQ1", "EQ1" }, \ | |
| 1178 | + { name, "EQ2", "EQ2" }, \ | |
| 1179 | + { name, "EQ3", "EQ3" }, \ | |
| 1180 | + { name, "EQ4", "EQ4" }, \ | |
| 1181 | + { name, "DRC1L", "DRC1L" }, \ | |
| 1182 | + { name, "DRC1R", "DRC1R" }, \ | |
| 1183 | + { name, "DRC2L", "DRC2L" }, \ | |
| 1184 | + { name, "DRC2R", "DRC2R" }, \ | |
| 1185 | + { name, "LHPF1", "LHPF1" }, \ | |
| 1186 | + { name, "LHPF2", "LHPF2" }, \ | |
| 1187 | + { name, "LHPF3", "LHPF3" }, \ | |
| 1188 | + { name, "LHPF4", "LHPF4" }, \ | |
| 1189 | + { name, "ASRC1IN1L", "ASRC1IN1L" }, \ | |
| 1190 | + { name, "ASRC1IN1R", "ASRC1IN1R" }, \ | |
| 1191 | + { name, "ASRC1IN2L", "ASRC1IN2L" }, \ | |
| 1192 | + { name, "ASRC1IN2R", "ASRC1IN2R" }, \ | |
| 1193 | + { name, "ISRC1DEC1", "ISRC1DEC1" }, \ | |
| 1194 | + { name, "ISRC1DEC2", "ISRC1DEC2" }, \ | |
| 1195 | + { name, "ISRC1INT1", "ISRC1INT1" }, \ | |
| 1196 | + { name, "ISRC1INT2", "ISRC1INT2" }, \ | |
| 1197 | + { name, "ISRC2DEC1", "ISRC2DEC1" }, \ | |
| 1198 | + { name, "ISRC2DEC2", "ISRC2DEC2" }, \ | |
| 1199 | + { name, "ISRC2INT1", "ISRC2INT1" }, \ | |
| 1200 | + { name, "ISRC2INT2", "ISRC2INT2" }, \ | |
| 1201 | + { name, "DSP1.1", "DSP1" }, \ | |
| 1202 | + { name, "DSP1.2", "DSP1" }, \ | |
| 1203 | + { name, "DSP1.3", "DSP1" }, \ | |
| 1204 | + { name, "DSP1.4", "DSP1" }, \ | |
| 1205 | + { name, "DSP1.5", "DSP1" }, \ | |
| 1206 | + { name, "DSP1.6", "DSP1" }, \ | |
| 1207 | + { name, "DFC1", "DFC1" }, \ | |
| 1208 | + { name, "DFC2", "DFC2" }, \ | |
| 1209 | + { name, "DFC3", "DFC3" }, \ | |
| 1210 | + { name, "DFC4", "DFC4" }, \ | |
| 1211 | + { name, "DFC5", "DFC5" }, \ | |
| 1212 | + { name, "DFC6", "DFC6" }, \ | |
| 1213 | + { name, "DFC7", "DFC7" }, \ | |
| 1214 | + { name, "DFC8", "DFC8" } | |
| 1215 | + | |
| 1216 | +static const struct snd_soc_dapm_route cs47l92_dapm_routes[] = { | |
| 1217 | + /* Internal clock domains */ | |
| 1218 | + { "EQ1", NULL, "FXCLK" }, | |
| 1219 | + { "EQ2", NULL, "FXCLK" }, | |
| 1220 | + { "EQ3", NULL, "FXCLK" }, | |
| 1221 | + { "EQ4", NULL, "FXCLK" }, | |
| 1222 | + { "DRC1L", NULL, "FXCLK" }, | |
| 1223 | + { "DRC1R", NULL, "FXCLK" }, | |
| 1224 | + { "DRC2L", NULL, "FXCLK" }, | |
| 1225 | + { "DRC2R", NULL, "FXCLK" }, | |
| 1226 | + { "LHPF1", NULL, "FXCLK" }, | |
| 1227 | + { "LHPF2", NULL, "FXCLK" }, | |
| 1228 | + { "LHPF3", NULL, "FXCLK" }, | |
| 1229 | + { "LHPF4", NULL, "FXCLK" }, | |
| 1230 | + { "PWM1 Mixer", NULL, "PWMCLK" }, | |
| 1231 | + { "PWM2 Mixer", NULL, "PWMCLK" }, | |
| 1232 | + { "OUT1L", NULL, "OUTCLK" }, | |
| 1233 | + { "OUT1R", NULL, "OUTCLK" }, | |
| 1234 | + { "OUT2L", NULL, "OUTCLK" }, | |
| 1235 | + { "OUT2R", NULL, "OUTCLK" }, | |
| 1236 | + { "OUT3L", NULL, "OUTCLK" }, | |
| 1237 | + { "OUT3R", NULL, "OUTCLK" }, | |
| 1238 | + { "OUT5L", NULL, "OUTCLK" }, | |
| 1239 | + { "OUT5R", NULL, "OUTCLK" }, | |
| 1240 | + { "AIF1TX1", NULL, "AIF1TXCLK" }, | |
| 1241 | + { "AIF1TX2", NULL, "AIF1TXCLK" }, | |
| 1242 | + { "AIF1TX3", NULL, "AIF1TXCLK" }, | |
| 1243 | + { "AIF1TX4", NULL, "AIF1TXCLK" }, | |
| 1244 | + { "AIF1TX5", NULL, "AIF1TXCLK" }, | |
| 1245 | + { "AIF1TX6", NULL, "AIF1TXCLK" }, | |
| 1246 | + { "AIF1TX7", NULL, "AIF1TXCLK" }, | |
| 1247 | + { "AIF1TX8", NULL, "AIF1TXCLK" }, | |
| 1248 | + { "AIF2TX1", NULL, "AIF2TXCLK" }, | |
| 1249 | + { "AIF2TX2", NULL, "AIF2TXCLK" }, | |
| 1250 | + { "AIF2TX3", NULL, "AIF2TXCLK" }, | |
| 1251 | + { "AIF2TX4", NULL, "AIF2TXCLK" }, | |
| 1252 | + { "AIF2TX5", NULL, "AIF2TXCLK" }, | |
| 1253 | + { "AIF2TX6", NULL, "AIF2TXCLK" }, | |
| 1254 | + { "AIF2TX7", NULL, "AIF2TXCLK" }, | |
| 1255 | + { "AIF2TX8", NULL, "AIF2TXCLK" }, | |
| 1256 | + { "AIF3TX1", NULL, "AIF3TXCLK" }, | |
| 1257 | + { "AIF3TX2", NULL, "AIF3TXCLK" }, | |
| 1258 | + { "AIF3TX3", NULL, "AIF3TXCLK" }, | |
| 1259 | + { "AIF3TX4", NULL, "AIF3TXCLK" }, | |
| 1260 | + { "SLIMTX1", NULL, "SLIMBUSCLK" }, | |
| 1261 | + { "SLIMTX2", NULL, "SLIMBUSCLK" }, | |
| 1262 | + { "SLIMTX3", NULL, "SLIMBUSCLK" }, | |
| 1263 | + { "SLIMTX4", NULL, "SLIMBUSCLK" }, | |
| 1264 | + { "SLIMTX5", NULL, "SLIMBUSCLK" }, | |
| 1265 | + { "SLIMTX6", NULL, "SLIMBUSCLK" }, | |
| 1266 | + { "SLIMTX7", NULL, "SLIMBUSCLK" }, | |
| 1267 | + { "SLIMTX8", NULL, "SLIMBUSCLK" }, | |
| 1268 | + { "SPD1TX1", NULL, "SPDCLK" }, | |
| 1269 | + { "SPD1TX2", NULL, "SPDCLK" }, | |
| 1270 | + { "DSP1", NULL, "DSP1CLK" }, | |
| 1271 | + { "ISRC1DEC1", NULL, "ISRC1CLK" }, | |
| 1272 | + { "ISRC1DEC2", NULL, "ISRC1CLK" }, | |
| 1273 | + { "ISRC1INT1", NULL, "ISRC1CLK" }, | |
| 1274 | + { "ISRC1INT2", NULL, "ISRC1CLK" }, | |
| 1275 | + { "ISRC2DEC1", NULL, "ISRC2CLK" }, | |
| 1276 | + { "ISRC2DEC2", NULL, "ISRC2CLK" }, | |
| 1277 | + { "ISRC2INT1", NULL, "ISRC2CLK" }, | |
| 1278 | + { "ISRC2INT2", NULL, "ISRC2CLK" }, | |
| 1279 | + { "ASRC1IN1L", NULL, "ASRC1CLK" }, | |
| 1280 | + { "ASRC1IN1R", NULL, "ASRC1CLK" }, | |
| 1281 | + { "ASRC1IN2L", NULL, "ASRC1CLK" }, | |
| 1282 | + { "ASRC1IN2R", NULL, "ASRC1CLK" }, | |
| 1283 | + { "DFC1", NULL, "DFCCLK" }, | |
| 1284 | + { "DFC2", NULL, "DFCCLK" }, | |
| 1285 | + { "DFC3", NULL, "DFCCLK" }, | |
| 1286 | + { "DFC4", NULL, "DFCCLK" }, | |
| 1287 | + { "DFC5", NULL, "DFCCLK" }, | |
| 1288 | + { "DFC6", NULL, "DFCCLK" }, | |
| 1289 | + { "DFC7", NULL, "DFCCLK" }, | |
| 1290 | + { "DFC8", NULL, "DFCCLK" }, | |
| 1291 | + | |
| 1292 | + { "OUT1L", NULL, "CPVDD1" }, | |
| 1293 | + { "OUT1L", NULL, "CPVDD2" }, | |
| 1294 | + { "OUT1R", NULL, "CPVDD1" }, | |
| 1295 | + { "OUT1R", NULL, "CPVDD2" }, | |
| 1296 | + { "OUT2L", NULL, "CPVDD1" }, | |
| 1297 | + { "OUT2L", NULL, "CPVDD2" }, | |
| 1298 | + { "OUT2R", NULL, "CPVDD1" }, | |
| 1299 | + { "OUT2R", NULL, "CPVDD2" }, | |
| 1300 | + { "OUT3L", NULL, "CPVDD1" }, | |
| 1301 | + { "OUT3L", NULL, "CPVDD2" }, | |
| 1302 | + { "OUT3R", NULL, "CPVDD1" }, | |
| 1303 | + { "OUT3R", NULL, "CPVDD2" }, | |
| 1304 | + | |
| 1305 | + { "OUT1L", NULL, "SYSCLK" }, | |
| 1306 | + { "OUT1R", NULL, "SYSCLK" }, | |
| 1307 | + { "OUT2L", NULL, "SYSCLK" }, | |
| 1308 | + { "OUT2R", NULL, "SYSCLK" }, | |
| 1309 | + { "OUT3L", NULL, "SYSCLK" }, | |
| 1310 | + { "OUT3R", NULL, "SYSCLK" }, | |
| 1311 | + { "OUT5L", NULL, "SYSCLK" }, | |
| 1312 | + { "OUT5R", NULL, "SYSCLK" }, | |
| 1313 | + | |
| 1314 | + { "SPD1", NULL, "SYSCLK" }, | |
| 1315 | + { "SPD1", NULL, "SPD1TX1" }, | |
| 1316 | + { "SPD1", NULL, "SPD1TX2" }, | |
| 1317 | + | |
| 1318 | + { "IN1L", NULL, "SYSCLK" }, | |
| 1319 | + { "IN1R", NULL, "SYSCLK" }, | |
| 1320 | + { "IN2L", NULL, "SYSCLK" }, | |
| 1321 | + { "IN2R", NULL, "SYSCLK" }, | |
| 1322 | + { "IN3L", NULL, "SYSCLK" }, | |
| 1323 | + { "IN3R", NULL, "SYSCLK" }, | |
| 1324 | + { "IN4L", NULL, "SYSCLK" }, | |
| 1325 | + { "IN4R", NULL, "SYSCLK" }, | |
| 1326 | + | |
| 1327 | + { "ASRC1IN1L", NULL, "SYSCLK" }, | |
| 1328 | + { "ASRC1IN1R", NULL, "SYSCLK" }, | |
| 1329 | + { "ASRC1IN2L", NULL, "SYSCLK" }, | |
| 1330 | + { "ASRC1IN2R", NULL, "SYSCLK" }, | |
| 1331 | + | |
| 1332 | + { "ASRC1IN1L", NULL, "ASYNCCLK" }, | |
| 1333 | + { "ASRC1IN1R", NULL, "ASYNCCLK" }, | |
| 1334 | + { "ASRC1IN2L", NULL, "ASYNCCLK" }, | |
| 1335 | + { "ASRC1IN2R", NULL, "ASYNCCLK" }, | |
| 1336 | + | |
| 1337 | + { "MICBIAS1", NULL, "MICVDD" }, | |
| 1338 | + { "MICBIAS2", NULL, "MICVDD" }, | |
| 1339 | + | |
| 1340 | + { "MICBIAS1A", NULL, "MICBIAS1" }, | |
| 1341 | + { "MICBIAS1B", NULL, "MICBIAS1" }, | |
| 1342 | + { "MICBIAS1C", NULL, "MICBIAS1" }, | |
| 1343 | + { "MICBIAS1D", NULL, "MICBIAS1" }, | |
| 1344 | + | |
| 1345 | + { "MICBIAS2A", NULL, "MICBIAS2" }, | |
| 1346 | + { "MICBIAS2B", NULL, "MICBIAS2" }, | |
| 1347 | + | |
| 1348 | + { "Noise Generator", NULL, "SYSCLK" }, | |
| 1349 | + { "Tone Generator 1", NULL, "SYSCLK" }, | |
| 1350 | + { "Tone Generator 2", NULL, "SYSCLK" }, | |
| 1351 | + | |
| 1352 | + { "Noise Generator", NULL, "NOISE" }, | |
| 1353 | + { "Tone Generator 1", NULL, "TONE" }, | |
| 1354 | + { "Tone Generator 2", NULL, "TONE" }, | |
| 1355 | + | |
| 1356 | + { "AIF1 Capture", NULL, "AIF1TX1" }, | |
| 1357 | + { "AIF1 Capture", NULL, "AIF1TX2" }, | |
| 1358 | + { "AIF1 Capture", NULL, "AIF1TX3" }, | |
| 1359 | + { "AIF1 Capture", NULL, "AIF1TX4" }, | |
| 1360 | + { "AIF1 Capture", NULL, "AIF1TX5" }, | |
| 1361 | + { "AIF1 Capture", NULL, "AIF1TX6" }, | |
| 1362 | + { "AIF1 Capture", NULL, "AIF1TX7" }, | |
| 1363 | + { "AIF1 Capture", NULL, "AIF1TX8" }, | |
| 1364 | + | |
| 1365 | + { "AIF1RX1", NULL, "AIF1 Playback" }, | |
| 1366 | + { "AIF1RX2", NULL, "AIF1 Playback" }, | |
| 1367 | + { "AIF1RX3", NULL, "AIF1 Playback" }, | |
| 1368 | + { "AIF1RX4", NULL, "AIF1 Playback" }, | |
| 1369 | + { "AIF1RX5", NULL, "AIF1 Playback" }, | |
| 1370 | + { "AIF1RX6", NULL, "AIF1 Playback" }, | |
| 1371 | + { "AIF1RX7", NULL, "AIF1 Playback" }, | |
| 1372 | + { "AIF1RX8", NULL, "AIF1 Playback" }, | |
| 1373 | + | |
| 1374 | + { "AIF2 Capture", NULL, "AIF2TX1" }, | |
| 1375 | + { "AIF2 Capture", NULL, "AIF2TX2" }, | |
| 1376 | + { "AIF2 Capture", NULL, "AIF2TX3" }, | |
| 1377 | + { "AIF2 Capture", NULL, "AIF2TX4" }, | |
| 1378 | + { "AIF2 Capture", NULL, "AIF2TX5" }, | |
| 1379 | + { "AIF2 Capture", NULL, "AIF2TX6" }, | |
| 1380 | + { "AIF2 Capture", NULL, "AIF2TX7" }, | |
| 1381 | + { "AIF2 Capture", NULL, "AIF2TX8" }, | |
| 1382 | + | |
| 1383 | + { "AIF2RX1", NULL, "AIF2 Playback" }, | |
| 1384 | + { "AIF2RX2", NULL, "AIF2 Playback" }, | |
| 1385 | + { "AIF2RX3", NULL, "AIF2 Playback" }, | |
| 1386 | + { "AIF2RX4", NULL, "AIF2 Playback" }, | |
| 1387 | + { "AIF2RX5", NULL, "AIF2 Playback" }, | |
| 1388 | + { "AIF2RX6", NULL, "AIF2 Playback" }, | |
| 1389 | + { "AIF2RX7", NULL, "AIF2 Playback" }, | |
| 1390 | + { "AIF2RX8", NULL, "AIF2 Playback" }, | |
| 1391 | + | |
| 1392 | + { "AIF3 Capture", NULL, "AIF3TX1" }, | |
| 1393 | + { "AIF3 Capture", NULL, "AIF3TX2" }, | |
| 1394 | + { "AIF3 Capture", NULL, "AIF3TX3" }, | |
| 1395 | + { "AIF3 Capture", NULL, "AIF3TX4" }, | |
| 1396 | + | |
| 1397 | + { "AIF3RX1", NULL, "AIF3 Playback" }, | |
| 1398 | + { "AIF3RX2", NULL, "AIF3 Playback" }, | |
| 1399 | + { "AIF3RX3", NULL, "AIF3 Playback" }, | |
| 1400 | + { "AIF3RX4", NULL, "AIF3 Playback" }, | |
| 1401 | + | |
| 1402 | + { "Slim1 Capture", NULL, "SLIMTX1" }, | |
| 1403 | + { "Slim1 Capture", NULL, "SLIMTX2" }, | |
| 1404 | + { "Slim1 Capture", NULL, "SLIMTX3" }, | |
| 1405 | + { "Slim1 Capture", NULL, "SLIMTX4" }, | |
| 1406 | + | |
| 1407 | + { "SLIMRX1", NULL, "Slim1 Playback" }, | |
| 1408 | + { "SLIMRX2", NULL, "Slim1 Playback" }, | |
| 1409 | + { "SLIMRX3", NULL, "Slim1 Playback" }, | |
| 1410 | + { "SLIMRX4", NULL, "Slim1 Playback" }, | |
| 1411 | + | |
| 1412 | + { "Slim2 Capture", NULL, "SLIMTX5" }, | |
| 1413 | + { "Slim2 Capture", NULL, "SLIMTX6" }, | |
| 1414 | + | |
| 1415 | + { "SLIMRX5", NULL, "Slim2 Playback" }, | |
| 1416 | + { "SLIMRX6", NULL, "Slim2 Playback" }, | |
| 1417 | + | |
| 1418 | + { "Slim3 Capture", NULL, "SLIMTX7" }, | |
| 1419 | + { "Slim3 Capture", NULL, "SLIMTX8" }, | |
| 1420 | + | |
| 1421 | + { "SLIMRX7", NULL, "Slim3 Playback" }, | |
| 1422 | + { "SLIMRX8", NULL, "Slim3 Playback" }, | |
| 1423 | + | |
| 1424 | + { "AIF1 Playback", NULL, "SYSCLK" }, | |
| 1425 | + { "AIF2 Playback", NULL, "SYSCLK" }, | |
| 1426 | + { "AIF3 Playback", NULL, "SYSCLK" }, | |
| 1427 | + { "Slim1 Playback", NULL, "SYSCLK" }, | |
| 1428 | + { "Slim2 Playback", NULL, "SYSCLK" }, | |
| 1429 | + { "Slim3 Playback", NULL, "SYSCLK" }, | |
| 1430 | + | |
| 1431 | + { "AIF1 Capture", NULL, "SYSCLK" }, | |
| 1432 | + { "AIF2 Capture", NULL, "SYSCLK" }, | |
| 1433 | + { "AIF3 Capture", NULL, "SYSCLK" }, | |
| 1434 | + { "Slim1 Capture", NULL, "SYSCLK" }, | |
| 1435 | + { "Slim2 Capture", NULL, "SYSCLK" }, | |
| 1436 | + { "Slim3 Capture", NULL, "SYSCLK" }, | |
| 1437 | + | |
| 1438 | + { "Audio Trace DSP", NULL, "DSP1" }, | |
| 1439 | + | |
| 1440 | + { "IN1L Analog Mux", "A", "IN1ALN" }, | |
| 1441 | + { "IN1L Analog Mux", "A", "IN1ALP" }, | |
| 1442 | + { "IN1L Analog Mux", "B", "IN1BLN" }, | |
| 1443 | + { "IN1L Analog Mux", "B", "IN1BLP" }, | |
| 1444 | + { "IN1R Analog Mux", "A", "IN1ARN" }, | |
| 1445 | + { "IN1R Analog Mux", "A", "IN1ARP" }, | |
| 1446 | + { "IN1R Analog Mux", "B", "IN1BR" }, | |
| 1447 | + { "IN1R Analog Mux", "B", "IN1ALN" }, | |
| 1448 | + | |
| 1449 | + { "IN1L Mode", "Analog", "IN1L Analog Mux" }, | |
| 1450 | + { "IN1R Mode", "Analog", "IN1R Analog Mux" }, | |
| 1451 | + | |
| 1452 | + { "IN1L Mode", "Digital", "IN1ALN" }, | |
| 1453 | + { "IN1L Mode", "Digital", "IN1ALP" }, | |
| 1454 | + { "IN1R Mode", "Digital", "IN1ALN" }, | |
| 1455 | + { "IN1R Mode", "Digital", "IN1ALP" }, | |
| 1456 | + | |
| 1457 | + { "IN1L", NULL, "IN1L Mode" }, | |
| 1458 | + { "IN1R", NULL, "IN1R Mode" }, | |
| 1459 | + | |
| 1460 | + { "IN2L Analog Mux", "A", "IN2ALN" }, | |
| 1461 | + { "IN2L Analog Mux", "A", "IN2ALP" }, | |
| 1462 | + { "IN2L Analog Mux", "B", "IN2ALN" }, | |
| 1463 | + { "IN2L Analog Mux", "B", "IN2BL" }, | |
| 1464 | + { "IN2R Analog Mux", "A", "IN2ARN" }, | |
| 1465 | + { "IN2R Analog Mux", "A", "IN2ARP" }, | |
| 1466 | + { "IN2R Analog Mux", "B", "IN2ARN" }, | |
| 1467 | + { "IN2R Analog Mux", "B", "IN2BR" }, | |
| 1468 | + | |
| 1469 | + { "IN2L Mode", "Analog", "IN2L Analog Mux" }, | |
| 1470 | + { "IN2R Mode", "Analog", "IN2R Analog Mux" }, | |
| 1471 | + | |
| 1472 | + { "IN2L Mode", "Digital", "IN2ALN" }, | |
| 1473 | + { "IN2L Mode", "Digital", "IN2ALP" }, | |
| 1474 | + { "IN2R Mode", "Digital", "IN2ALN" }, | |
| 1475 | + { "IN2R Mode", "Digital", "IN2ALP" }, | |
| 1476 | + | |
| 1477 | + { "IN2L", NULL, "IN2L Mode" }, | |
| 1478 | + { "IN2R", NULL, "IN2R Mode" }, | |
| 1479 | + | |
| 1480 | + { "IN3L", NULL, "IN1ARN" }, | |
| 1481 | + { "IN3L", NULL, "IN1ARP" }, | |
| 1482 | + { "IN3R", NULL, "IN1ARN" }, | |
| 1483 | + { "IN3R", NULL, "IN1ARP" }, | |
| 1484 | + | |
| 1485 | + { "IN4L", NULL, "IN2ARN" }, | |
| 1486 | + { "IN4L", NULL, "IN2ARP" }, | |
| 1487 | + { "IN4R", NULL, "IN2ARN" }, | |
| 1488 | + { "IN4R", NULL, "IN2ARP" }, | |
| 1489 | + | |
| 1490 | + MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | |
| 1491 | + MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | |
| 1492 | + MADERA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | |
| 1493 | + MADERA_MIXER_ROUTES("OUT2R", "HPOUT2R"), | |
| 1494 | + MADERA_MIXER_ROUTES("OUT3L", "HPOUT3L"), | |
| 1495 | + MADERA_MIXER_ROUTES("OUT3R", "HPOUT3R"), | |
| 1496 | + | |
| 1497 | + MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"), | |
| 1498 | + MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"), | |
| 1499 | + | |
| 1500 | + MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"), | |
| 1501 | + MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"), | |
| 1502 | + | |
| 1503 | + MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), | |
| 1504 | + MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), | |
| 1505 | + MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), | |
| 1506 | + MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), | |
| 1507 | + MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), | |
| 1508 | + MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), | |
| 1509 | + MADERA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"), | |
| 1510 | + MADERA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"), | |
| 1511 | + | |
| 1512 | + MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"), | |
| 1513 | + MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"), | |
| 1514 | + MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"), | |
| 1515 | + MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"), | |
| 1516 | + MADERA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"), | |
| 1517 | + MADERA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"), | |
| 1518 | + MADERA_MIXER_ROUTES("AIF2TX7", "AIF2TX7"), | |
| 1519 | + MADERA_MIXER_ROUTES("AIF2TX8", "AIF2TX8"), | |
| 1520 | + | |
| 1521 | + MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), | |
| 1522 | + MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), | |
| 1523 | + MADERA_MIXER_ROUTES("AIF3TX3", "AIF3TX3"), | |
| 1524 | + MADERA_MIXER_ROUTES("AIF3TX4", "AIF3TX4"), | |
| 1525 | + | |
| 1526 | + MADERA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"), | |
| 1527 | + MADERA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"), | |
| 1528 | + MADERA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"), | |
| 1529 | + MADERA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"), | |
| 1530 | + MADERA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"), | |
| 1531 | + MADERA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"), | |
| 1532 | + MADERA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"), | |
| 1533 | + MADERA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"), | |
| 1534 | + | |
| 1535 | + MADERA_MUX_ROUTES("SPD1TX1", "SPDIFTX1"), | |
| 1536 | + MADERA_MUX_ROUTES("SPD1TX2", "SPDIFTX2"), | |
| 1537 | + | |
| 1538 | + MADERA_MIXER_ROUTES("EQ1", "EQ1"), | |
| 1539 | + MADERA_MIXER_ROUTES("EQ2", "EQ2"), | |
| 1540 | + MADERA_MIXER_ROUTES("EQ3", "EQ3"), | |
| 1541 | + MADERA_MIXER_ROUTES("EQ4", "EQ4"), | |
| 1542 | + | |
| 1543 | + MADERA_MIXER_ROUTES("DRC1L", "DRC1L"), | |
| 1544 | + MADERA_MIXER_ROUTES("DRC1R", "DRC1R"), | |
| 1545 | + MADERA_MIXER_ROUTES("DRC2L", "DRC2L"), | |
| 1546 | + MADERA_MIXER_ROUTES("DRC2R", "DRC2R"), | |
| 1547 | + | |
| 1548 | + MADERA_MIXER_ROUTES("LHPF1", "LHPF1"), | |
| 1549 | + MADERA_MIXER_ROUTES("LHPF2", "LHPF2"), | |
| 1550 | + MADERA_MIXER_ROUTES("LHPF3", "LHPF3"), | |
| 1551 | + MADERA_MIXER_ROUTES("LHPF4", "LHPF4"), | |
| 1552 | + | |
| 1553 | + MADERA_MUX_ROUTES("ASRC1IN1L", "ASRC1IN1L"), | |
| 1554 | + MADERA_MUX_ROUTES("ASRC1IN1R", "ASRC1IN1R"), | |
| 1555 | + MADERA_MUX_ROUTES("ASRC1IN2L", "ASRC1IN2L"), | |
| 1556 | + MADERA_MUX_ROUTES("ASRC1IN2R", "ASRC1IN2R"), | |
| 1557 | + | |
| 1558 | + MADERA_DSP_ROUTES("DSP1"), | |
| 1559 | + | |
| 1560 | + MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"), | |
| 1561 | + MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"), | |
| 1562 | + | |
| 1563 | + MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"), | |
| 1564 | + MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"), | |
| 1565 | + | |
| 1566 | + MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"), | |
| 1567 | + MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"), | |
| 1568 | + | |
| 1569 | + MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"), | |
| 1570 | + MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"), | |
| 1571 | + | |
| 1572 | + { "AEC1 Loopback", "HPOUT1L", "OUT1L" }, | |
| 1573 | + { "AEC1 Loopback", "HPOUT1R", "OUT1R" }, | |
| 1574 | + { "HPOUT1L", NULL, "OUT1L" }, | |
| 1575 | + { "HPOUT1R", NULL, "OUT1R" }, | |
| 1576 | + | |
| 1577 | + { "AEC1 Loopback", "HPOUT2L", "OUT2L" }, | |
| 1578 | + { "AEC1 Loopback", "HPOUT2R", "OUT2R" }, | |
| 1579 | + { "HPOUT2L", NULL, "OUT2L" }, | |
| 1580 | + { "HPOUT2R", NULL, "OUT2R" }, | |
| 1581 | + | |
| 1582 | + { "AEC1 Loopback", "HPOUT3L", "OUT3L" }, | |
| 1583 | + { "AEC1 Loopback", "HPOUT3R", "OUT3R" }, | |
| 1584 | + { "OUT3 Demux", NULL, "OUT3L" }, | |
| 1585 | + { "OUT3 Demux", NULL, "OUT3R" }, | |
| 1586 | + | |
| 1587 | + { "HPOUT3L", "HPOUT3", "OUT3 Demux" }, | |
| 1588 | + { "HPOUT3R", "HPOUT3", "OUT3 Demux" }, | |
| 1589 | + { "HPOUT4L", "HPOUT4", "OUT3 Demux" }, | |
| 1590 | + { "HPOUT4R", "HPOUT4", "OUT3 Demux" }, | |
| 1591 | + | |
| 1592 | + { "AEC1 Loopback", "SPKDAT1L", "OUT5L" }, | |
| 1593 | + { "AEC1 Loopback", "SPKDAT1R", "OUT5R" }, | |
| 1594 | + { "SPKDAT1L", NULL, "OUT5L" }, | |
| 1595 | + { "SPKDAT1R", NULL, "OUT5R" }, | |
| 1596 | + | |
| 1597 | + { "SPDIF1", NULL, "SPD1" }, | |
| 1598 | + | |
| 1599 | + { "MICSUPP", NULL, "SYSCLK" }, | |
| 1600 | + | |
| 1601 | + { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" }, | |
| 1602 | + { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" }, | |
| 1603 | + { "DRC1 Activity Output", "Switch", "DRC1L" }, | |
| 1604 | + { "DRC1 Activity Output", "Switch", "DRC1R" }, | |
| 1605 | + { "DRC2 Activity Output", "Switch", "DRC2L" }, | |
| 1606 | + { "DRC2 Activity Output", "Switch", "DRC2R" }, | |
| 1607 | + | |
| 1608 | + MADERA_MUX_ROUTES("DFC1", "DFC1"), | |
| 1609 | + MADERA_MUX_ROUTES("DFC2", "DFC2"), | |
| 1610 | + MADERA_MUX_ROUTES("DFC3", "DFC3"), | |
| 1611 | + MADERA_MUX_ROUTES("DFC4", "DFC4"), | |
| 1612 | + MADERA_MUX_ROUTES("DFC5", "DFC5"), | |
| 1613 | + MADERA_MUX_ROUTES("DFC6", "DFC6"), | |
| 1614 | + MADERA_MUX_ROUTES("DFC7", "DFC7"), | |
| 1615 | + MADERA_MUX_ROUTES("DFC8", "DFC8"), | |
| 1616 | +}; | |
| 1617 | + | |
| 1618 | +static int cs47l92_set_fll(struct snd_soc_component *component, int fll_id, | |
| 1619 | + int source, unsigned int fref, unsigned int fout) | |
| 1620 | +{ | |
| 1621 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 1622 | + | |
| 1623 | + switch (fll_id) { | |
| 1624 | + case MADERA_FLL1_REFCLK: | |
| 1625 | + return madera_fllhj_set_refclk(&cs47l92->fll[0], source, fref, | |
| 1626 | + fout); | |
| 1627 | + case MADERA_FLL2_REFCLK: | |
| 1628 | + return madera_fllhj_set_refclk(&cs47l92->fll[1], source, fref, | |
| 1629 | + fout); | |
| 1630 | + default: | |
| 1631 | + return -EINVAL; | |
| 1632 | + } | |
| 1633 | +} | |
| 1634 | + | |
| 1635 | +static struct snd_soc_dai_driver cs47l92_dai[] = { | |
| 1636 | + { | |
| 1637 | + .name = "cs47l92-aif1", | |
| 1638 | + .id = 1, | |
| 1639 | + .base = MADERA_AIF1_BCLK_CTRL, | |
| 1640 | + .playback = { | |
| 1641 | + .stream_name = "AIF1 Playback", | |
| 1642 | + .channels_min = 1, | |
| 1643 | + .channels_max = 8, | |
| 1644 | + .rates = MADERA_RATES, | |
| 1645 | + .formats = MADERA_FORMATS, | |
| 1646 | + }, | |
| 1647 | + .capture = { | |
| 1648 | + .stream_name = "AIF1 Capture", | |
| 1649 | + .channels_min = 1, | |
| 1650 | + .channels_max = 8, | |
| 1651 | + .rates = MADERA_RATES, | |
| 1652 | + .formats = MADERA_FORMATS, | |
| 1653 | + }, | |
| 1654 | + .ops = &madera_dai_ops, | |
| 1655 | + .symmetric_rates = 1, | |
| 1656 | + .symmetric_samplebits = 1, | |
| 1657 | + }, | |
| 1658 | + { | |
| 1659 | + .name = "cs47l92-aif2", | |
| 1660 | + .id = 2, | |
| 1661 | + .base = MADERA_AIF2_BCLK_CTRL, | |
| 1662 | + .playback = { | |
| 1663 | + .stream_name = "AIF2 Playback", | |
| 1664 | + .channels_min = 1, | |
| 1665 | + .channels_max = 8, | |
| 1666 | + .rates = MADERA_RATES, | |
| 1667 | + .formats = MADERA_FORMATS, | |
| 1668 | + }, | |
| 1669 | + .capture = { | |
| 1670 | + .stream_name = "AIF2 Capture", | |
| 1671 | + .channels_min = 1, | |
| 1672 | + .channels_max = 8, | |
| 1673 | + .rates = MADERA_RATES, | |
| 1674 | + .formats = MADERA_FORMATS, | |
| 1675 | + }, | |
| 1676 | + .ops = &madera_dai_ops, | |
| 1677 | + .symmetric_rates = 1, | |
| 1678 | + .symmetric_samplebits = 1, | |
| 1679 | + }, | |
| 1680 | + { | |
| 1681 | + .name = "cs47l92-aif3", | |
| 1682 | + .id = 3, | |
| 1683 | + .base = MADERA_AIF3_BCLK_CTRL, | |
| 1684 | + .playback = { | |
| 1685 | + .stream_name = "AIF3 Playback", | |
| 1686 | + .channels_min = 1, | |
| 1687 | + .channels_max = 4, | |
| 1688 | + .rates = MADERA_RATES, | |
| 1689 | + .formats = MADERA_FORMATS, | |
| 1690 | + }, | |
| 1691 | + .capture = { | |
| 1692 | + .stream_name = "AIF3 Capture", | |
| 1693 | + .channels_min = 1, | |
| 1694 | + .channels_max = 4, | |
| 1695 | + .rates = MADERA_RATES, | |
| 1696 | + .formats = MADERA_FORMATS, | |
| 1697 | + }, | |
| 1698 | + .ops = &madera_dai_ops, | |
| 1699 | + .symmetric_rates = 1, | |
| 1700 | + .symmetric_samplebits = 1, | |
| 1701 | + }, | |
| 1702 | + { | |
| 1703 | + .name = "cs47l92-slim1", | |
| 1704 | + .id = 5, | |
| 1705 | + .playback = { | |
| 1706 | + .stream_name = "Slim1 Playback", | |
| 1707 | + .channels_min = 1, | |
| 1708 | + .channels_max = 4, | |
| 1709 | + .rates = MADERA_RATES, | |
| 1710 | + .formats = MADERA_FORMATS, | |
| 1711 | + }, | |
| 1712 | + .capture = { | |
| 1713 | + .stream_name = "Slim1 Capture", | |
| 1714 | + .channels_min = 1, | |
| 1715 | + .channels_max = 4, | |
| 1716 | + .rates = MADERA_RATES, | |
| 1717 | + .formats = MADERA_FORMATS, | |
| 1718 | + }, | |
| 1719 | + .ops = &madera_simple_dai_ops, | |
| 1720 | + }, | |
| 1721 | + { | |
| 1722 | + .name = "cs47l92-slim2", | |
| 1723 | + .id = 6, | |
| 1724 | + .playback = { | |
| 1725 | + .stream_name = "Slim2 Playback", | |
| 1726 | + .channels_min = 1, | |
| 1727 | + .channels_max = 2, | |
| 1728 | + .rates = MADERA_RATES, | |
| 1729 | + .formats = MADERA_FORMATS, | |
| 1730 | + }, | |
| 1731 | + .capture = { | |
| 1732 | + .stream_name = "Slim2 Capture", | |
| 1733 | + .channels_min = 1, | |
| 1734 | + .channels_max = 2, | |
| 1735 | + .rates = MADERA_RATES, | |
| 1736 | + .formats = MADERA_FORMATS, | |
| 1737 | + }, | |
| 1738 | + .ops = &madera_simple_dai_ops, | |
| 1739 | + }, | |
| 1740 | + { | |
| 1741 | + .name = "cs47l92-slim3", | |
| 1742 | + .id = 7, | |
| 1743 | + .playback = { | |
| 1744 | + .stream_name = "Slim3 Playback", | |
| 1745 | + .channels_min = 1, | |
| 1746 | + .channels_max = 2, | |
| 1747 | + .rates = MADERA_RATES, | |
| 1748 | + .formats = MADERA_FORMATS, | |
| 1749 | + }, | |
| 1750 | + .capture = { | |
| 1751 | + .stream_name = "Slim3 Capture", | |
| 1752 | + .channels_min = 1, | |
| 1753 | + .channels_max = 2, | |
| 1754 | + .rates = MADERA_RATES, | |
| 1755 | + .formats = MADERA_FORMATS, | |
| 1756 | + }, | |
| 1757 | + .ops = &madera_simple_dai_ops, | |
| 1758 | + }, | |
| 1759 | + { | |
| 1760 | + .name = "cs47l92-cpu-trace", | |
| 1761 | + .capture = { | |
| 1762 | + .stream_name = "Audio Trace CPU", | |
| 1763 | + .channels_min = 1, | |
| 1764 | + .channels_max = 2, | |
| 1765 | + .rates = MADERA_RATES, | |
| 1766 | + .formats = MADERA_FORMATS, | |
| 1767 | + }, | |
| 1768 | + .compress_new = snd_soc_new_compress, | |
| 1769 | + }, | |
| 1770 | + { | |
| 1771 | + .name = "cs47l92-dsp-trace", | |
| 1772 | + .capture = { | |
| 1773 | + .stream_name = "Audio Trace DSP", | |
| 1774 | + .channels_min = 1, | |
| 1775 | + .channels_max = 2, | |
| 1776 | + .rates = MADERA_RATES, | |
| 1777 | + .formats = MADERA_FORMATS, | |
| 1778 | + }, | |
| 1779 | + }, | |
| 1780 | +}; | |
| 1781 | + | |
| 1782 | +static int cs47l92_open(struct snd_compr_stream *stream) | |
| 1783 | +{ | |
| 1784 | + struct snd_soc_pcm_runtime *rtd = stream->private_data; | |
| 1785 | + struct snd_soc_component *component = | |
| 1786 | + snd_soc_rtdcom_lookup(rtd, DRV_NAME); | |
| 1787 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 1788 | + struct madera_priv *priv = &cs47l92->core; | |
| 1789 | + struct madera *madera = priv->madera; | |
| 1790 | + int n_adsp; | |
| 1791 | + | |
| 1792 | + if (strcmp(rtd->codec_dai->name, "cs47l92-dsp-trace") == 0) { | |
| 1793 | + n_adsp = 0; | |
| 1794 | + } else { | |
| 1795 | + dev_err(madera->dev, | |
| 1796 | + "No suitable compressed stream for DAI '%s'\n", | |
| 1797 | + rtd->codec_dai->name); | |
| 1798 | + return -EINVAL; | |
| 1799 | + } | |
| 1800 | + | |
| 1801 | + return wm_adsp_compr_open(&priv->adsp[n_adsp], stream); | |
| 1802 | +} | |
| 1803 | + | |
| 1804 | +static irqreturn_t cs47l92_adsp2_irq(int irq, void *data) | |
| 1805 | +{ | |
| 1806 | + struct cs47l92 *cs47l92 = data; | |
| 1807 | + struct madera_priv *priv = &cs47l92->core; | |
| 1808 | + struct madera *madera = priv->madera; | |
| 1809 | + int ret; | |
| 1810 | + | |
| 1811 | + ret = wm_adsp_compr_handle_irq(&priv->adsp[0]); | |
| 1812 | + if (ret == -ENODEV) { | |
| 1813 | + dev_err(madera->dev, "Spurious compressed data IRQ\n"); | |
| 1814 | + return IRQ_NONE; | |
| 1815 | + } | |
| 1816 | + | |
| 1817 | + return IRQ_HANDLED; | |
| 1818 | +} | |
| 1819 | + | |
| 1820 | +static int cs47l92_component_probe(struct snd_soc_component *component) | |
| 1821 | +{ | |
| 1822 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 1823 | + struct madera *madera = cs47l92->core.madera; | |
| 1824 | + int ret; | |
| 1825 | + | |
| 1826 | + snd_soc_component_init_regmap(component, madera->regmap); | |
| 1827 | + | |
| 1828 | + mutex_lock(&madera->dapm_ptr_lock); | |
| 1829 | + madera->dapm = snd_soc_component_get_dapm(component); | |
| 1830 | + mutex_unlock(&madera->dapm_ptr_lock); | |
| 1831 | + | |
| 1832 | + ret = madera_init_inputs(component); | |
| 1833 | + if (ret) | |
| 1834 | + return ret; | |
| 1835 | + | |
| 1836 | + ret = madera_init_outputs(component, CS47L92_MONO_OUTPUTS); | |
| 1837 | + if (ret) | |
| 1838 | + return ret; | |
| 1839 | + | |
| 1840 | + snd_soc_component_disable_pin(component, "HAPTICS"); | |
| 1841 | + | |
| 1842 | + ret = snd_soc_add_component_controls(component, | |
| 1843 | + madera_adsp_rate_controls, | |
| 1844 | + CS47L92_NUM_ADSP); | |
| 1845 | + if (ret) | |
| 1846 | + return ret; | |
| 1847 | + | |
| 1848 | + return wm_adsp2_component_probe(&cs47l92->core.adsp[0], component); | |
| 1849 | +} | |
| 1850 | + | |
| 1851 | +static void cs47l92_component_remove(struct snd_soc_component *component) | |
| 1852 | +{ | |
| 1853 | + struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); | |
| 1854 | + struct madera *madera = cs47l92->core.madera; | |
| 1855 | + | |
| 1856 | + mutex_lock(&madera->dapm_ptr_lock); | |
| 1857 | + madera->dapm = NULL; | |
| 1858 | + mutex_unlock(&madera->dapm_ptr_lock); | |
| 1859 | + | |
| 1860 | + wm_adsp2_component_remove(&cs47l92->core.adsp[0], component); | |
| 1861 | +} | |
| 1862 | + | |
| 1863 | +#define CS47L92_DIG_VU 0x0200 | |
| 1864 | + | |
| 1865 | +static unsigned int cs47l92_digital_vu[] = { | |
| 1866 | + MADERA_DAC_DIGITAL_VOLUME_1L, | |
| 1867 | + MADERA_DAC_DIGITAL_VOLUME_1R, | |
| 1868 | + MADERA_DAC_DIGITAL_VOLUME_2L, | |
| 1869 | + MADERA_DAC_DIGITAL_VOLUME_2R, | |
| 1870 | + MADERA_DAC_DIGITAL_VOLUME_3L, | |
| 1871 | + MADERA_DAC_DIGITAL_VOLUME_3R, | |
| 1872 | + MADERA_DAC_DIGITAL_VOLUME_5L, | |
| 1873 | + MADERA_DAC_DIGITAL_VOLUME_5R, | |
| 1874 | +}; | |
| 1875 | + | |
| 1876 | +static const struct snd_compr_ops cs47l92_compr_ops = { | |
| 1877 | + .open = &cs47l92_open, | |
| 1878 | + .free = &wm_adsp_compr_free, | |
| 1879 | + .set_params = &wm_adsp_compr_set_params, | |
| 1880 | + .get_caps = &wm_adsp_compr_get_caps, | |
| 1881 | + .trigger = &wm_adsp_compr_trigger, | |
| 1882 | + .pointer = &wm_adsp_compr_pointer, | |
| 1883 | + .copy = &wm_adsp_compr_copy, | |
| 1884 | +}; | |
| 1885 | + | |
| 1886 | +static const struct snd_soc_component_driver soc_component_dev_cs47l92 = { | |
| 1887 | + .probe = &cs47l92_component_probe, | |
| 1888 | + .remove = &cs47l92_component_remove, | |
| 1889 | + .set_sysclk = &madera_set_sysclk, | |
| 1890 | + .set_pll = &cs47l92_set_fll, | |
| 1891 | + .name = DRV_NAME, | |
| 1892 | + .compr_ops = &cs47l92_compr_ops, | |
| 1893 | + .controls = cs47l92_snd_controls, | |
| 1894 | + .num_controls = ARRAY_SIZE(cs47l92_snd_controls), | |
| 1895 | + .dapm_widgets = cs47l92_dapm_widgets, | |
| 1896 | + .num_dapm_widgets = ARRAY_SIZE(cs47l92_dapm_widgets), | |
| 1897 | + .dapm_routes = cs47l92_dapm_routes, | |
| 1898 | + .num_dapm_routes = ARRAY_SIZE(cs47l92_dapm_routes), | |
| 1899 | + .use_pmdown_time = 1, | |
| 1900 | + .endianness = 1, | |
| 1901 | + .non_legacy_dai_naming = 1, | |
| 1902 | +}; | |
| 1903 | + | |
| 1904 | +static int cs47l92_probe(struct platform_device *pdev) | |
| 1905 | +{ | |
| 1906 | + struct madera *madera = dev_get_drvdata(pdev->dev.parent); | |
| 1907 | + struct cs47l92 *cs47l92; | |
| 1908 | + int i, ret; | |
| 1909 | + | |
| 1910 | + BUILD_BUG_ON(ARRAY_SIZE(cs47l92_dai) > MADERA_MAX_DAI); | |
| 1911 | + | |
| 1912 | + /* quick exit if Madera irqchip driver hasn't completed probe */ | |
| 1913 | + if (!madera->irq_dev) { | |
| 1914 | + dev_dbg(&pdev->dev, "irqchip driver not ready\n"); | |
| 1915 | + return -EPROBE_DEFER; | |
| 1916 | + } | |
| 1917 | + | |
| 1918 | + cs47l92 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l92), GFP_KERNEL); | |
| 1919 | + if (!cs47l92) | |
| 1920 | + return -ENOMEM; | |
| 1921 | + | |
| 1922 | + platform_set_drvdata(pdev, cs47l92); | |
| 1923 | + | |
| 1924 | + cs47l92->core.madera = madera; | |
| 1925 | + cs47l92->core.dev = &pdev->dev; | |
| 1926 | + cs47l92->core.num_inputs = 8; | |
| 1927 | + | |
| 1928 | + ret = madera_core_init(&cs47l92->core); | |
| 1929 | + if (ret) | |
| 1930 | + return ret; | |
| 1931 | + | |
| 1932 | + ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1, | |
| 1933 | + "ADSP2 Compressed IRQ", cs47l92_adsp2_irq, | |
| 1934 | + cs47l92); | |
| 1935 | + if (ret != 0) { | |
| 1936 | + dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret); | |
| 1937 | + goto error_core; | |
| 1938 | + } | |
| 1939 | + | |
| 1940 | + ret = madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 1); | |
| 1941 | + if (ret) | |
| 1942 | + dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret); | |
| 1943 | + | |
| 1944 | + cs47l92->core.adsp[0].part = "cs47l92"; | |
| 1945 | + cs47l92->core.adsp[0].num = 1; | |
| 1946 | + cs47l92->core.adsp[0].type = WMFW_ADSP2; | |
| 1947 | + cs47l92->core.adsp[0].rev = 2; | |
| 1948 | + cs47l92->core.adsp[0].dev = madera->dev; | |
| 1949 | + cs47l92->core.adsp[0].regmap = madera->regmap_32bit; | |
| 1950 | + | |
| 1951 | + cs47l92->core.adsp[0].base = MADERA_DSP1_CONFIG_1; | |
| 1952 | + cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions; | |
| 1953 | + cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions); | |
| 1954 | + | |
| 1955 | + cs47l92->core.adsp[0].lock_regions = WM_ADSP2_REGION_1_9; | |
| 1956 | + | |
| 1957 | + ret = wm_adsp2_init(&cs47l92->core.adsp[0]); | |
| 1958 | + if (ret != 0) | |
| 1959 | + goto error_dsp_irq; | |
| 1960 | + | |
| 1961 | + ret = madera_init_bus_error_irq(&cs47l92->core, 0, wm_adsp2_bus_error); | |
| 1962 | + if (ret != 0) { | |
| 1963 | + wm_adsp2_remove(&cs47l92->core.adsp[0]); | |
| 1964 | + goto error_adsp; | |
| 1965 | + } | |
| 1966 | + | |
| 1967 | + madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1, | |
| 1968 | + &cs47l92->fll[0]); | |
| 1969 | + madera_init_fll(madera, 2, MADERA_FLL2_CONTROL_1 - 1, | |
| 1970 | + &cs47l92->fll[1]); | |
| 1971 | + | |
| 1972 | + for (i = 0; i < ARRAY_SIZE(cs47l92_dai); i++) | |
| 1973 | + madera_init_dai(&cs47l92->core, i); | |
| 1974 | + | |
| 1975 | + /* Latch volume update bits */ | |
| 1976 | + for (i = 0; i < ARRAY_SIZE(cs47l92_digital_vu); i++) | |
| 1977 | + regmap_update_bits(madera->regmap, cs47l92_digital_vu[i], | |
| 1978 | + CS47L92_DIG_VU, CS47L92_DIG_VU); | |
| 1979 | + | |
| 1980 | + pm_runtime_enable(&pdev->dev); | |
| 1981 | + pm_runtime_idle(&pdev->dev); | |
| 1982 | + | |
| 1983 | + ret = devm_snd_soc_register_component(&pdev->dev, | |
| 1984 | + &soc_component_dev_cs47l92, | |
| 1985 | + cs47l92_dai, | |
| 1986 | + ARRAY_SIZE(cs47l92_dai)); | |
| 1987 | + if (ret < 0) { | |
| 1988 | + dev_err(&pdev->dev, "Failed to register component: %d\n", ret); | |
| 1989 | + goto error_pm_runtime; | |
| 1990 | + } | |
| 1991 | + | |
| 1992 | + return ret; | |
| 1993 | + | |
| 1994 | +error_pm_runtime: | |
| 1995 | + pm_runtime_disable(&pdev->dev); | |
| 1996 | + madera_free_bus_error_irq(&cs47l92->core, 0); | |
| 1997 | +error_adsp: | |
| 1998 | + wm_adsp2_remove(&cs47l92->core.adsp[0]); | |
| 1999 | +error_dsp_irq: | |
| 2000 | + madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 0); | |
| 2001 | + madera_free_irq(madera, MADERA_IRQ_DSP_IRQ1, cs47l92); | |
| 2002 | +error_core: | |
| 2003 | + madera_core_free(&cs47l92->core); | |
| 2004 | + | |
| 2005 | + return ret; | |
| 2006 | +} | |
| 2007 | + | |
| 2008 | +static int cs47l92_remove(struct platform_device *pdev) | |
| 2009 | +{ | |
| 2010 | + struct cs47l92 *cs47l92 = platform_get_drvdata(pdev); | |
| 2011 | + | |
| 2012 | + pm_runtime_disable(&pdev->dev); | |
| 2013 | + | |
| 2014 | + madera_free_bus_error_irq(&cs47l92->core, 0); | |
| 2015 | + wm_adsp2_remove(&cs47l92->core.adsp[0]); | |
| 2016 | + | |
| 2017 | + madera_set_irq_wake(cs47l92->core.madera, MADERA_IRQ_DSP_IRQ1, 0); | |
| 2018 | + madera_free_irq(cs47l92->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l92); | |
| 2019 | + | |
| 2020 | + madera_core_free(&cs47l92->core); | |
| 2021 | + | |
| 2022 | + return 0; | |
| 2023 | +} | |
| 2024 | + | |
| 2025 | +static struct platform_driver cs47l92_codec_driver = { | |
| 2026 | + .driver = { | |
| 2027 | + .name = "cs47l92-codec", | |
| 2028 | + }, | |
| 2029 | + .probe = &cs47l92_probe, | |
| 2030 | + .remove = &cs47l92_remove, | |
| 2031 | +}; | |
| 2032 | + | |
| 2033 | +module_platform_driver(cs47l92_codec_driver); | |
| 2034 | + | |
| 2035 | +MODULE_SOFTDEP("pre: madera irq-madera arizona-micsupp"); | |
| 2036 | +MODULE_DESCRIPTION("ASoC CS47L92 driver"); | |
| 2037 | +MODULE_AUTHOR("Stuart Henderson <stuarth@opensource.cirrus.com>"); | |
| 2038 | +MODULE_LICENSE("GPL v2"); | |
| 2039 | +MODULE_ALIAS("platform:cs47l92-codec"); | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/acpi.h> |
| 12 | +#include <linux/clk.h> | |
| 12 | 13 | #include <linux/delay.h> |
| 13 | 14 | #include <linux/i2c.h> |
| 14 | 15 | #include <linux/mod_devicetable.h> |
| @@ -33,6 +34,7 @@ static const unsigned int supported_mclk_lrck_ratios[] = { · 18 unmodified lines | ||
| 33 | 34 | |
| 34 | 35 | struct es8316_priv { |
| 35 | 36 | struct mutex lock; |
| 37 | + struct clk *mclk; | |
| 36 | 38 | struct regmap *regmap; |
| 37 | 39 | struct snd_soc_component *component; |
| 38 | 40 | struct snd_soc_jack *jack; |
| @@ -363,13 +365,21 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, · 324 unmodified lines | ||
| 363 | 365 | { |
| 364 | 366 | struct snd_soc_component *component = codec_dai->component; |
| 365 | 367 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 366 | − int i; | |
| 368 | + int i, ret; | |
| 367 | 369 | int count = 0; |
| 368 | 370 | |
| 369 | 371 | es8316->sysclk = freq; |
| 370 | 372 | |
| 371 | − if (freq == 0) | |
| 373 | + if (freq == 0) { | |
| 374 | + es8316->sysclk_constraints.list = NULL; | |
| 375 | + es8316->sysclk_constraints.count = 0; | |
| 376 | + | |
| 372 | 377 | return 0; |
| 378 | + } | |
| 379 | + | |
| 380 | + ret = clk_set_rate(es8316->mclk, freq); | |
| 381 | + if (ret) | |
| 382 | + return ret; | |
| 373 | 383 | |
| 374 | 384 | /* Limit supported sample rates to ones that can be autodetected |
| 375 | 385 | * by the codec running in slave mode. |
| @@ -444,17 +454,10 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream, · 68 unmodified lines | ||
| 444 | 454 | struct snd_soc_component *component = dai->component; |
| 445 | 455 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 446 | 456 | |
| 447 | − if (es8316->sysclk == 0) { | |
| 448 | − dev_err(component->dev, "No sysclk provided\n"); | |
| 449 | − return -EINVAL; | |
| 450 | − } | |
| 451 | − | |
| 452 | − /* The set of sample rates that can be supported depends on the | |
| 453 | − * MCLK supplied to the CODEC. | |
| 454 | − */ | |
| 455 | − snd_pcm_hw_constraint_list(substream->runtime, 0, | |
| 456 | − SNDRV_PCM_HW_PARAM_RATE, | |
| 457 | − &es8316->sysclk_constraints); | |
| 457 | + if (es8316->sysclk_constraints.list) | |
| 458 | + snd_pcm_hw_constraint_list(substream->runtime, 0, | |
| 459 | + SNDRV_PCM_HW_PARAM_RATE, | |
| 460 | + &es8316->sysclk_constraints); | |
| 458 | 461 | |
| 459 | 462 | return 0; |
| 460 | 463 | } |
| @@ -466,11 +469,19 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, · 5 unmodified lines | ||
| 466 | 469 | struct snd_soc_component *component = dai->component; |
| 467 | 470 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 468 | 471 | u8 wordlen = 0; |
| 472 | + int i; | |
| 469 | 473 | |
| 470 | − if (!es8316->sysclk) { | |
| 471 | − dev_err(component->dev, "No MCLK configured\n"); | |
| 472 | − return -EINVAL; | |
| 474 | + /* Validate supported sample rates that are autodetected from MCLK */ | |
| 475 | + for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) { | |
| 476 | + const unsigned int ratio = supported_mclk_lrck_ratios[i]; | |
| 477 | + | |
| 478 | + if (es8316->sysclk % ratio != 0) | |
| 479 | + continue; | |
| 480 | + if (es8316->sysclk / ratio == params_rate(params)) | |
| 481 | + break; | |
| 473 | 482 | } |
| 483 | + if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS) | |
| 484 | + return -EINVAL; | |
| 474 | 485 | |
| 475 | 486 | switch (params_format(params)) { |
| 476 | 487 | case SNDRV_PCM_FORMAT_S16_LE: |
| @@ -700,9 +711,24 @@ static int es8316_set_jack(struct snd_soc_component *component, · 223 unmodified lines | ||
| 700 | 711 | static int es8316_probe(struct snd_soc_component *component) |
| 701 | 712 | { |
| 702 | 713 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 714 | + int ret; | |
| 703 | 715 | |
| 704 | 716 | es8316->component = component; |
| 705 | 717 | |
| 718 | + es8316->mclk = devm_clk_get_optional(component->dev, "mclk"); | |
| 719 | + if (IS_ERR(es8316->mclk)) { | |
| 720 | + dev_err(component->dev, "unable to get mclk\n"); | |
| 721 | + return PTR_ERR(es8316->mclk); | |
| 722 | + } | |
| 723 | + if (!es8316->mclk) | |
| 724 | + dev_warn(component->dev, "assuming static mclk\n"); | |
| 725 | + | |
| 726 | + ret = clk_prepare_enable(es8316->mclk); | |
| 727 | + if (ret) { | |
| 728 | + dev_err(component->dev, "unable to enable mclk\n"); | |
| 729 | + return ret; | |
| 730 | + } | |
| 731 | + | |
| 706 | 732 | /* Reset codec and enable current state machine */ |
| 707 | 733 | snd_soc_component_write(component, ES8316_RESET, 0x3f); |
| 708 | 734 | usleep_range(5000, 5500); |
| @@ -725,8 +751,16 @@ static int es8316_probe(struct snd_soc_component *component) · 16 unmodified lines | ||
| 725 | 751 | return 0; |
| 726 | 752 | } |
| 727 | 753 | |
| 754 | +static void es8316_remove(struct snd_soc_component *component) | |
| 755 | +{ | |
| 756 | + struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | |
| 757 | + | |
| 758 | + clk_disable_unprepare(es8316->mclk); | |
| 759 | +} | |
| 760 | + | |
| 728 | 761 | static const struct snd_soc_component_driver soc_component_dev_es8316 = { |
| 729 | 762 | .probe = es8316_probe, |
| 763 | + .remove = es8316_remove, | |
| 730 | 764 | .set_jack = es8316_set_jack, |
| 731 | 765 | .controls = es8316_snd_controls, |
| 732 | 766 | .num_controls = ARRAY_SIZE(es8316_snd_controls), |
| @@ -99,7 +99,6 @@ static SOC_ENUM_SINGLE_DECL(adcpol, · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); |
| 101 | 101 | static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); |
| 102 | −static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); | |
| 103 | 102 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); |
| 104 | 103 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); |
| 105 | 104 | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <linux/string.h> |
| 9 | 9 | #include <sound/core.h> |
| 10 | +#include <sound/jack.h> | |
| 10 | 11 | #include <sound/pcm.h> |
| 11 | 12 | #include <sound/pcm_params.h> |
| 12 | 13 | #include <sound/soc.h> |
| @@ -274,6 +275,8 @@ struct hdmi_codec_priv { · 261 unmodified lines | ||
| 274 | 275 | struct snd_pcm_chmap *chmap_info; |
| 275 | 276 | unsigned int chmap_idx; |
| 276 | 277 | struct mutex lock; |
| 278 | + struct snd_soc_jack *jack; | |
| 279 | + unsigned int jack_status; | |
| 277 | 280 | }; |
| 278 | 281 | |
| 279 | 282 | static const struct snd_soc_dapm_widget hdmi_widgets[] = { |
| @@ -663,6 +666,49 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) · 383 unmodified lines | ||
| 663 | 666 | return 0; |
| 664 | 667 | } |
| 665 | 668 | |
| 669 | +static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp, | |
| 670 | + unsigned int jack_status) | |
| 671 | +{ | |
| 672 | + if (hcp->jack && jack_status != hcp->jack_status) { | |
| 673 | + snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); | |
| 674 | + hcp->jack_status = jack_status; | |
| 675 | + } | |
| 676 | +} | |
| 677 | + | |
| 678 | +static void plugged_cb(struct device *dev, bool plugged) | |
| 679 | +{ | |
| 680 | + struct hdmi_codec_priv *hcp = dev_get_drvdata(dev); | |
| 681 | + | |
| 682 | + if (plugged) | |
| 683 | + hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); | |
| 684 | + else | |
| 685 | + hdmi_codec_jack_report(hcp, 0); | |
| 686 | +} | |
| 687 | + | |
| 688 | +/** | |
| 689 | + * hdmi_codec_set_jack_detect - register HDMI plugged callback | |
| 690 | + * @component: the hdmi-codec instance | |
| 691 | + * @jack: ASoC jack to report (dis)connection events on | |
| 692 | + */ | |
| 693 | +int hdmi_codec_set_jack_detect(struct snd_soc_component *component, | |
| 694 | + struct snd_soc_jack *jack) | |
| 695 | +{ | |
| 696 | + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); | |
| 697 | + int ret = -EOPNOTSUPP; | |
| 698 | + | |
| 699 | + if (hcp->hcd.ops->hook_plugged_cb) { | |
| 700 | + hcp->jack = jack; | |
| 701 | + ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, | |
| 702 | + hcp->hcd.data, | |
| 703 | + plugged_cb, | |
| 704 | + component->dev); | |
| 705 | + if (ret) | |
| 706 | + hcp->jack = NULL; | |
| 707 | + } | |
| 708 | + return ret; | |
| 709 | +} | |
| 710 | +EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect); | |
| 711 | + | |
| 666 | 712 | static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) |
| 667 | 713 | { |
| 668 | 714 | struct hdmi_codec_daifmt *cf = dai->playback_dma_data; |
| @@ -405,7 +405,6 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev) · 404 unmodified lines | ||
| 405 | 405 | { |
| 406 | 406 | struct rk3036_codec_priv *priv; |
| 407 | 407 | struct device_node *of_node = pdev->dev.of_node; |
| 408 | − struct resource *res; | |
| 409 | 408 | void __iomem *base; |
| 410 | 409 | struct regmap *grf; |
| 411 | 410 | int ret; |
| @@ -414,8 +413,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 414 | 413 | if (!priv) |
| 415 | 414 | return -ENOMEM; |
| 416 | 415 | |
| 417 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 418 | − base = devm_ioremap_resource(&pdev->dev, res); | |
| 416 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 419 | 417 | if (IS_ERR(base)) |
| 420 | 418 | return PTR_ERR(base); |
| 421 | 419 | |
| @@ -545,15 +545,13 @@ static int jz4725b_codec_probe(struct platform_device *pdev) · 544 unmodified lines | ||
| 545 | 545 | { |
| 546 | 546 | struct device *dev = &pdev->dev; |
| 547 | 547 | struct jz_icdc *icdc; |
| 548 | − struct resource *mem; | |
| 549 | 548 | int ret; |
| 550 | 549 | |
| 551 | 550 | icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL); |
| 552 | 551 | if (!icdc) |
| 553 | 552 | return -ENOMEM; |
| 554 | 553 | |
| 555 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 556 | − icdc->base = devm_ioremap_resource(dev, mem); | |
| 554 | + icdc->base = devm_platform_ioremap_resource(pdev, 0); | |
| 557 | 555 | if (IS_ERR(icdc->base)) |
| 558 | 556 | return PTR_ERR(icdc->base); |
| 559 | 557 | |
| @@ -318,7 +318,6 @@ static int jz4740_codec_probe(struct platform_device *pdev) · 317 unmodified lines | ||
| 318 | 318 | { |
| 319 | 319 | int ret; |
| 320 | 320 | struct jz4740_codec *jz4740_codec; |
| 321 | − struct resource *mem; | |
| 322 | 321 | void __iomem *base; |
| 323 | 322 | |
| 324 | 323 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), |
| @@ -326,8 +325,7 @@ static int jz4740_codec_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 326 | 325 | if (!jz4740_codec) |
| 327 | 326 | return -ENOMEM; |
| 328 | 327 | |
| 329 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 330 | − base = devm_ioremap_resource(&pdev->dev, mem); | |
| 328 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 331 | 329 | if (IS_ERR(base)) |
| 332 | 330 | return PTR_ERR(base); |
| 333 | 331 | |
| @@ -87,6 +87,16 @@ · 86 unmodified lines | ||
| 87 | 87 | #define MADERA_FLLAO_MIN_N 4 |
| 88 | 88 | #define MADERA_FLLAO_MAX_N 1023 |
| 89 | 89 | #define MADERA_FLLAO_MAX_FBDIV 254 |
| 90 | +#define MADERA_FLLHJ_INT_MAX_N 1023 | |
| 91 | +#define MADERA_FLLHJ_INT_MIN_N 1 | |
| 92 | +#define MADERA_FLLHJ_FRAC_MAX_N 255 | |
| 93 | +#define MADERA_FLLHJ_FRAC_MIN_N 4 | |
| 94 | +#define MADERA_FLLHJ_LOW_THRESH 192000 | |
| 95 | +#define MADERA_FLLHJ_MID_THRESH 1152000 | |
| 96 | +#define MADERA_FLLHJ_MAX_THRESH 13000000 | |
| 97 | +#define MADERA_FLLHJ_LOW_GAINS 0x23f0 | |
| 98 | +#define MADERA_FLLHJ_MID_GAINS 0x22f2 | |
| 99 | +#define MADERA_FLLHJ_HIGH_GAINS 0x21f0 | |
| 90 | 100 | |
| 91 | 101 | #define MADERA_FLL_SYNCHRONISER_OFFS 0x10 |
| 92 | 102 | #define CS47L35_FLL_SYNCHRONISER_OFFS 0xE |
| @@ -96,6 +106,7 @@ · 3 unmodified lines | ||
| 96 | 106 | #define MADERA_FLL_CONTROL_4_OFFS 0x4 |
| 97 | 107 | #define MADERA_FLL_CONTROL_5_OFFS 0x5 |
| 98 | 108 | #define MADERA_FLL_CONTROL_6_OFFS 0x6 |
| 109 | +#define MADERA_FLL_GAIN_OFFS 0x8 | |
| 99 | 110 | #define MADERA_FLL_CONTROL_7_OFFS 0x9 |
| 100 | 111 | #define MADERA_FLL_EFS_2_OFFS 0xA |
| 101 | 112 | #define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1 |
| @@ -107,6 +118,9 @@ · 5 unmodified lines | ||
| 107 | 118 | #define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7 |
| 108 | 119 | #define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9 |
| 109 | 120 | #define MADERA_FLL_GPIO_CLOCK_OFFS 0xA |
| 121 | +#define MADERA_FLL_CONTROL_10_OFFS 0xA | |
| 122 | +#define MADERA_FLL_CONTROL_11_OFFS 0xB | |
| 123 | +#define MADERA_FLL1_DIGITAL_TEST_1_OFFS 0xD | |
| 110 | 124 | |
| 111 | 125 | #define MADERA_FLLAO_CONTROL_1_OFFS 0x1 |
| 112 | 126 | #define MADERA_FLLAO_CONTROL_2_OFFS 0x2 |
| @@ -300,6 +314,100 @@ int madera_free_overheat(struct madera_priv *priv) · 187 unmodified lines | ||
| 300 | 314 | } |
| 301 | 315 | EXPORT_SYMBOL_GPL(madera_free_overheat); |
| 302 | 316 | |
| 317 | +static int madera_get_variable_u32_array(struct device *dev, | |
| 318 | + const char *propname, | |
| 319 | + u32 *dest, int n_max, | |
| 320 | + int multiple) | |
| 321 | +{ | |
| 322 | + int n, ret; | |
| 323 | + | |
| 324 | + n = device_property_count_u32(dev, propname); | |
| 325 | + if (n < 0) { | |
| 326 | + if (n == -EINVAL) | |
| 327 | + return 0; /* missing, ignore */ | |
| 328 | + | |
| 329 | + dev_warn(dev, "%s malformed (%d)\n", propname, n); | |
| 330 | + | |
| 331 | + return n; | |
| 332 | + } else if ((n % multiple) != 0) { | |
| 333 | + dev_warn(dev, "%s not a multiple of %d entries\n", | |
| 334 | + propname, multiple); | |
| 335 | + | |
| 336 | + return -EINVAL; | |
| 337 | + } | |
| 338 | + | |
| 339 | + if (n > n_max) | |
| 340 | + n = n_max; | |
| 341 | + | |
| 342 | + ret = device_property_read_u32_array(dev, propname, dest, n); | |
| 343 | + if (ret < 0) | |
| 344 | + return ret; | |
| 345 | + | |
| 346 | + return n; | |
| 347 | +} | |
| 348 | + | |
| 349 | +static void madera_prop_get_inmode(struct madera_priv *priv) | |
| 350 | +{ | |
| 351 | + struct madera *madera = priv->madera; | |
| 352 | + struct madera_codec_pdata *pdata = &madera->pdata.codec; | |
| 353 | + u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS]; | |
| 354 | + int n, i, in_idx, ch_idx; | |
| 355 | + | |
| 356 | + BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode) != MADERA_MAX_INPUT); | |
| 357 | + BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode[0]) != MADERA_MAX_MUXED_CHANNELS); | |
| 358 | + | |
| 359 | + n = madera_get_variable_u32_array(madera->dev, "cirrus,inmode", | |
| 360 | + tmp, ARRAY_SIZE(tmp), | |
| 361 | + MADERA_MAX_MUXED_CHANNELS); | |
| 362 | + if (n < 0) | |
| 363 | + return; | |
| 364 | + | |
| 365 | + in_idx = 0; | |
| 366 | + ch_idx = 0; | |
| 367 | + for (i = 0; i < n; ++i) { | |
| 368 | + pdata->inmode[in_idx][ch_idx] = tmp[i]; | |
| 369 | + | |
| 370 | + if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) { | |
| 371 | + ch_idx = 0; | |
| 372 | + ++in_idx; | |
| 373 | + } | |
| 374 | + } | |
| 375 | +} | |
| 376 | + | |
| 377 | +static void madera_prop_get_pdata(struct madera_priv *priv) | |
| 378 | +{ | |
| 379 | + struct madera *madera = priv->madera; | |
| 380 | + struct madera_codec_pdata *pdata = &madera->pdata.codec; | |
| 381 | + u32 out_mono[ARRAY_SIZE(pdata->out_mono)]; | |
| 382 | + int i, n; | |
| 383 | + | |
| 384 | + madera_prop_get_inmode(priv); | |
| 385 | + | |
| 386 | + n = madera_get_variable_u32_array(madera->dev, "cirrus,out-mono", | |
| 387 | + out_mono, ARRAY_SIZE(out_mono), 1); | |
| 388 | + if (n > 0) | |
| 389 | + for (i = 0; i < n; ++i) | |
| 390 | + pdata->out_mono[i] = !!out_mono[i]; | |
| 391 | + | |
| 392 | + madera_get_variable_u32_array(madera->dev, | |
| 393 | + "cirrus,max-channels-clocked", | |
| 394 | + pdata->max_channels_clocked, | |
| 395 | + ARRAY_SIZE(pdata->max_channels_clocked), | |
| 396 | + 1); | |
| 397 | + | |
| 398 | + madera_get_variable_u32_array(madera->dev, "cirrus,pdm-fmt", | |
| 399 | + pdata->pdm_fmt, | |
| 400 | + ARRAY_SIZE(pdata->pdm_fmt), 1); | |
| 401 | + | |
| 402 | + madera_get_variable_u32_array(madera->dev, "cirrus,pdm-mute", | |
| 403 | + pdata->pdm_mute, | |
| 404 | + ARRAY_SIZE(pdata->pdm_mute), 1); | |
| 405 | + | |
| 406 | + madera_get_variable_u32_array(madera->dev, "cirrus,dmic-ref", | |
| 407 | + pdata->dmic_ref, | |
| 408 | + ARRAY_SIZE(pdata->dmic_ref), 1); | |
| 409 | +} | |
| 410 | + | |
| 303 | 411 | int madera_core_init(struct madera_priv *priv) |
| 304 | 412 | { |
| 305 | 413 | int i; |
| @@ -308,6 +416,9 @@ int madera_core_init(struct madera_priv *priv) · 2 unmodified lines | ||
| 308 | 416 | BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]); |
| 309 | 417 | BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]); |
| 310 | 418 | |
| 419 | + if (!dev_get_platdata(priv->madera->dev)) | |
| 420 | + madera_prop_get_pdata(priv); | |
| 421 | + | |
| 311 | 422 | mutex_init(&priv->rate_lock); |
| 312 | 423 | |
| 313 | 424 | for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++) |
| @@ -944,6 +1055,10 @@ static void madera_configure_input_mode(struct madera *madera) · 630 unmodified lines | ||
| 944 | 1055 | int max_analogue_inputs, max_dmic_sup, i; |
| 945 | 1056 | |
| 946 | 1057 | switch (madera->type) { |
| 1058 | + case CS47L15: | |
| 1059 | + max_analogue_inputs = 1; | |
| 1060 | + max_dmic_sup = 2; | |
| 1061 | + break; | |
| 947 | 1062 | case CS47L35: |
| 948 | 1063 | max_analogue_inputs = 2; |
| 949 | 1064 | max_dmic_sup = 2; |
| @@ -1770,6 +1885,18 @@ const struct soc_enum madera_asrc1_rate[] = { · 820 unmodified lines | ||
| 1770 | 1885 | }; |
| 1771 | 1886 | EXPORT_SYMBOL_GPL(madera_asrc1_rate); |
| 1772 | 1887 | |
| 1888 | +const struct soc_enum madera_asrc1_bidir_rate[] = { | |
| 1889 | + SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1, | |
| 1890 | + MADERA_ASRC1_RATE1_SHIFT, 0xf, | |
| 1891 | + MADERA_RATE_ENUM_SIZE, | |
| 1892 | + madera_rate_text, madera_rate_val), | |
| 1893 | + SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2, | |
| 1894 | + MADERA_ASRC1_RATE2_SHIFT, 0xf, | |
| 1895 | + MADERA_RATE_ENUM_SIZE, | |
| 1896 | + madera_rate_text, madera_rate_val), | |
| 1897 | +}; | |
| 1898 | +EXPORT_SYMBOL_GPL(madera_asrc1_bidir_rate); | |
| 1899 | + | |
| 1773 | 1900 | const struct soc_enum madera_asrc2_rate[] = { |
| 1774 | 1901 | SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1, |
| 1775 | 1902 | MADERA_ASRC2_RATE1_SHIFT, 0xf, |
| @@ -2149,6 +2276,9 @@ int madera_out_ev(struct snd_soc_dapm_widget *w, · 373 unmodified lines | ||
| 2149 | 2276 | switch (madera->type) { |
| 2150 | 2277 | case CS47L90: |
| 2151 | 2278 | case CS47L91: |
| 2279 | + case CS42L92: | |
| 2280 | + case CS47L92: | |
| 2281 | + case CS47L93: | |
| 2152 | 2282 | out_up_delay = 6; |
| 2153 | 2283 | break; |
| 2154 | 2284 | default: |
| @@ -2264,9 +2394,17 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w, · 109 unmodified lines | ||
| 2264 | 2394 | madera->hp_ena &= ~mask; |
| 2265 | 2395 | madera->hp_ena |= val; |
| 2266 | 2396 | |
| 2267 | − /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */ | |
| 2268 | − regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); | |
| 2269 | − ep_sel &= MADERA_EP_SEL_MASK; | |
| 2397 | + switch (madera->type) { | |
| 2398 | + case CS42L92: | |
| 2399 | + case CS47L92: | |
| 2400 | + case CS47L93: | |
| 2401 | + break; | |
| 2402 | + default: | |
| 2403 | + /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */ | |
| 2404 | + regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); | |
| 2405 | + ep_sel &= MADERA_EP_SEL_MASK; | |
| 2406 | + break; | |
| 2407 | + } | |
| 2270 | 2408 | |
| 2271 | 2409 | /* Force off if HPDET has disabled the clamp for this output */ |
| 2272 | 2410 | if (!ep_sel && |
| @@ -2442,6 +2580,58 @@ static int madera_get_dspclk_setting(struct madera *madera, · 169 unmodified lines | ||
| 2442 | 2580 | } |
| 2443 | 2581 | } |
| 2444 | 2582 | |
| 2583 | +static int madera_set_outclk(struct snd_soc_component *component, | |
| 2584 | + unsigned int source, unsigned int freq) | |
| 2585 | +{ | |
| 2586 | + int div, div_inc, rate; | |
| 2587 | + | |
| 2588 | + switch (source) { | |
| 2589 | + case MADERA_OUTCLK_SYSCLK: | |
| 2590 | + dev_dbg(component->dev, "Configured OUTCLK to SYSCLK\n"); | |
| 2591 | + snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1, | |
| 2592 | + MADERA_OUT_CLK_SRC_MASK, source); | |
| 2593 | + return 0; | |
| 2594 | + case MADERA_OUTCLK_ASYNCCLK: | |
| 2595 | + dev_dbg(component->dev, "Configured OUTCLK to ASYNCCLK\n"); | |
| 2596 | + snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1, | |
| 2597 | + MADERA_OUT_CLK_SRC_MASK, source); | |
| 2598 | + return 0; | |
| 2599 | + case MADERA_OUTCLK_MCLK1: | |
| 2600 | + case MADERA_OUTCLK_MCLK2: | |
| 2601 | + case MADERA_OUTCLK_MCLK3: | |
| 2602 | + break; | |
| 2603 | + default: | |
| 2604 | + return -EINVAL; | |
| 2605 | + } | |
| 2606 | + | |
| 2607 | + if (freq % 4000) | |
| 2608 | + rate = 5644800; | |
| 2609 | + else | |
| 2610 | + rate = 6144000; | |
| 2611 | + | |
| 2612 | + div = 1; | |
| 2613 | + div_inc = 0; | |
| 2614 | + while (div <= 8) { | |
| 2615 | + if (freq / div == rate && !(freq % div)) { | |
| 2616 | + dev_dbg(component->dev, "Configured %dHz OUTCLK\n", rate); | |
| 2617 | + snd_soc_component_update_bits(component, | |
| 2618 | + MADERA_OUTPUT_RATE_1, | |
| 2619 | + MADERA_OUT_EXT_CLK_DIV_MASK | | |
| 2620 | + MADERA_OUT_CLK_SRC_MASK, | |
| 2621 | + (div_inc << MADERA_OUT_EXT_CLK_DIV_SHIFT) | | |
| 2622 | + source); | |
| 2623 | + return 0; | |
| 2624 | + } | |
| 2625 | + div_inc++; | |
| 2626 | + div *= 2; | |
| 2627 | + } | |
| 2628 | + | |
| 2629 | + dev_err(component->dev, | |
| 2630 | + "Unable to generate %dHz OUTCLK from %dHz MCLK\n", | |
| 2631 | + rate, freq); | |
| 2632 | + return -EINVAL; | |
| 2633 | +} | |
| 2634 | + | |
| 2445 | 2635 | int madera_set_sysclk(struct snd_soc_component *component, int clk_id, |
| 2446 | 2636 | int source, unsigned int freq, int dir) |
| 2447 | 2637 | { |
| @@ -2478,6 +2668,8 @@ int madera_set_sysclk(struct snd_soc_component *component, int clk_id, · 30 unmodified lines | ||
| 2478 | 2668 | case MADERA_CLK_OPCLK: |
| 2479 | 2669 | case MADERA_CLK_ASYNC_OPCLK: |
| 2480 | 2670 | return madera_set_opclk(component, clk_id, freq); |
| 2671 | + case MADERA_CLK_OUTCLK: | |
| 2672 | + return madera_set_outclk(component, source, freq); | |
| 2481 | 2673 | default: |
| 2482 | 2674 | return -EINVAL; |
| 2483 | 2675 | } |
| @@ -2691,6 +2883,10 @@ static const unsigned int madera_sr_vals[] = { · 207 unmodified lines | ||
| 2691 | 2883 | #define MADERA_192K_44K1_RATE_MASK 0x003E00 |
| 2692 | 2884 | #define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \ |
| 2693 | 2885 | MADERA_192K_44K1_RATE_MASK) |
| 2886 | +#define MADERA_384K_48K_RATE_MASK 0x0F007E | |
| 2887 | +#define MADERA_384K_44K1_RATE_MASK 0x007E00 | |
| 2888 | +#define MADERA_384K_RATE_MASK (MADERA_384K_48K_RATE_MASK | \ | |
| 2889 | + MADERA_384K_44K1_RATE_MASK) | |
| 2694 | 2890 | |
| 2695 | 2891 | static const struct snd_pcm_hw_constraint_list madera_constraint = { |
| 2696 | 2892 | .count = ARRAY_SIZE(madera_sr_vals), |
| @@ -2703,6 +2899,7 @@ static int madera_startup(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 2703 | 2899 | struct snd_soc_component *component = dai->component; |
| 2704 | 2900 | struct madera_priv *priv = snd_soc_component_get_drvdata(component); |
| 2705 | 2901 | struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1]; |
| 2902 | + struct madera *madera = priv->madera; | |
| 2706 | 2903 | unsigned int base_rate; |
| 2707 | 2904 | |
| 2708 | 2905 | if (!substream->runtime) |
| @@ -2722,12 +2919,26 @@ static int madera_startup(struct snd_pcm_substream *substream, · 13 unmodified lines | ||
| 2722 | 2919 | return 0; |
| 2723 | 2920 | } |
| 2724 | 2921 | |
| 2725 | − if (base_rate == 0) | |
| 2726 | − dai_priv->constraint.mask = MADERA_192K_RATE_MASK; | |
| 2727 | − else if (base_rate % 4000) | |
| 2728 | − dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK; | |
| 2729 | − else | |
| 2730 | − dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK; | |
| 2922 | + switch (madera->type) { | |
| 2923 | + case CS42L92: | |
| 2924 | + case CS47L92: | |
| 2925 | + case CS47L93: | |
| 2926 | + if (base_rate == 0) | |
| 2927 | + dai_priv->constraint.mask = MADERA_384K_RATE_MASK; | |
| 2928 | + else if (base_rate % 4000) | |
| 2929 | + dai_priv->constraint.mask = MADERA_384K_44K1_RATE_MASK; | |
| 2930 | + else | |
| 2931 | + dai_priv->constraint.mask = MADERA_384K_48K_RATE_MASK; | |
| 2932 | + break; | |
| 2933 | + default: | |
| 2934 | + if (base_rate == 0) | |
| 2935 | + dai_priv->constraint.mask = MADERA_192K_RATE_MASK; | |
| 2936 | + else if (base_rate % 4000) | |
| 2937 | + dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK; | |
| 2938 | + else | |
| 2939 | + dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK; | |
| 2940 | + break; | |
| 2941 | + } | |
| 2731 | 2942 | |
| 2732 | 2943 | return snd_pcm_hw_constraint_list(substream->runtime, 0, |
| 2733 | 2944 | SNDRV_PCM_HW_PARAM_RATE, |
| @@ -4048,6 +4259,308 @@ int madera_set_fll_ao_refclk(struct madera_fll *fll, int source, · 1314 unmodified lines | ||
| 4048 | 4259 | } |
| 4049 | 4260 | EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk); |
| 4050 | 4261 | |
| 4262 | +static int madera_fllhj_disable(struct madera_fll *fll) | |
| 4263 | +{ | |
| 4264 | + struct madera *madera = fll->madera; | |
| 4265 | + bool change; | |
| 4266 | + | |
| 4267 | + madera_fll_dbg(fll, "Disabling FLL\n"); | |
| 4268 | + | |
| 4269 | + /* Disable lockdet, but don't set ctrl_upd update but. This allows the | |
| 4270 | + * lock status bit to clear as normal, but should the FLL be enabled | |
| 4271 | + * again due to a control clock being required, the lock won't re-assert | |
| 4272 | + * as the FLL config registers are automatically applied when the FLL | |
| 4273 | + * enables. | |
| 4274 | + */ | |
| 4275 | + regmap_update_bits(madera->regmap, | |
| 4276 | + fll->base + MADERA_FLL_CONTROL_11_OFFS, | |
| 4277 | + MADERA_FLL1_LOCKDET_MASK, 0); | |
| 4278 | + regmap_update_bits(madera->regmap, | |
| 4279 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4280 | + MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK); | |
| 4281 | + regmap_update_bits_check(madera->regmap, | |
| 4282 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4283 | + MADERA_FLL1_ENA_MASK, 0, &change); | |
| 4284 | + | |
| 4285 | + madera_wait_for_fll(fll, false); | |
| 4286 | + | |
| 4287 | + /* ctrl_up gates the writes to all the fll's registers, setting it to 0 | |
| 4288 | + * here ensures that after a runtime suspend/resume cycle when one | |
| 4289 | + * enables the fll then ctrl_up is the last bit that is configured | |
| 4290 | + * by the fll enable code rather than the cache sync operation which | |
| 4291 | + * would have updated it much earlier before writing out all fll | |
| 4292 | + * registers | |
| 4293 | + */ | |
| 4294 | + regmap_update_bits(madera->regmap, | |
| 4295 | + fll->base + MADERA_FLL_CONTROL_2_OFFS, | |
| 4296 | + MADERA_FLL1_CTRL_UPD_MASK, 0); | |
| 4297 | + | |
| 4298 | + if (change) | |
| 4299 | + pm_runtime_put_autosuspend(madera->dev); | |
| 4300 | + | |
| 4301 | + return 0; | |
| 4302 | +} | |
| 4303 | + | |
| 4304 | +static int madera_fllhj_apply(struct madera_fll *fll, int fin) | |
| 4305 | +{ | |
| 4306 | + struct madera *madera = fll->madera; | |
| 4307 | + int refdiv, fref, fout, lockdet_thr, fbdiv, hp, fast_clk, fllgcd; | |
| 4308 | + bool frac = false; | |
| 4309 | + unsigned int fll_n, min_n, max_n, ratio, theta, lambda; | |
| 4310 | + unsigned int gains, val, num; | |
| 4311 | + | |
| 4312 | + madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout); | |
| 4313 | + | |
| 4314 | + for (refdiv = 0; refdiv < 4; refdiv++) | |
| 4315 | + if ((fin / (1 << refdiv)) <= MADERA_FLLHJ_MAX_THRESH) | |
| 4316 | + break; | |
| 4317 | + | |
| 4318 | + fref = fin / (1 << refdiv); | |
| 4319 | + | |
| 4320 | + /* Use simple heuristic approach to find a configuration that | |
| 4321 | + * should work for most input clocks. | |
| 4322 | + */ | |
| 4323 | + fast_clk = 0; | |
| 4324 | + fout = fll->fout; | |
| 4325 | + frac = fout % fref; | |
| 4326 | + | |
| 4327 | + if (fref < MADERA_FLLHJ_LOW_THRESH) { | |
| 4328 | + lockdet_thr = 2; | |
| 4329 | + gains = MADERA_FLLHJ_LOW_GAINS; | |
| 4330 | + if (frac) | |
| 4331 | + fbdiv = 256; | |
| 4332 | + else | |
| 4333 | + fbdiv = 4; | |
| 4334 | + } else if (fref < MADERA_FLLHJ_MID_THRESH) { | |
| 4335 | + lockdet_thr = 8; | |
| 4336 | + gains = MADERA_FLLHJ_MID_GAINS; | |
| 4337 | + fbdiv = 1; | |
| 4338 | + } else { | |
| 4339 | + lockdet_thr = 8; | |
| 4340 | + gains = MADERA_FLLHJ_HIGH_GAINS; | |
| 4341 | + fbdiv = 1; | |
| 4342 | + /* For high speed input clocks, enable 300MHz fast oscillator | |
| 4343 | + * when we're in fractional divider mode. | |
| 4344 | + */ | |
| 4345 | + if (frac) { | |
| 4346 | + fast_clk = 0x3; | |
| 4347 | + fout = fll->fout * 6; | |
| 4348 | + } | |
| 4349 | + } | |
| 4350 | + /* Use high performance mode for fractional configurations. */ | |
| 4351 | + if (frac) { | |
| 4352 | + hp = 0x3; | |
| 4353 | + min_n = MADERA_FLLHJ_FRAC_MIN_N; | |
| 4354 | + max_n = MADERA_FLLHJ_FRAC_MAX_N; | |
| 4355 | + } else { | |
| 4356 | + hp = 0x0; | |
| 4357 | + min_n = MADERA_FLLHJ_INT_MIN_N; | |
| 4358 | + max_n = MADERA_FLLHJ_INT_MAX_N; | |
| 4359 | + } | |
| 4360 | + | |
| 4361 | + ratio = fout / fref; | |
| 4362 | + | |
| 4363 | + madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n", | |
| 4364 | + refdiv, fref, frac); | |
| 4365 | + | |
| 4366 | + while (ratio / fbdiv < min_n) { | |
| 4367 | + fbdiv /= 2; | |
| 4368 | + if (fbdiv < 1) { | |
| 4369 | + madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv); | |
| 4370 | + return -EINVAL; | |
| 4371 | + } | |
| 4372 | + } | |
| 4373 | + while (frac && (ratio / fbdiv > max_n)) { | |
| 4374 | + fbdiv *= 2; | |
| 4375 | + if (fbdiv >= 1024) { | |
| 4376 | + madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv); | |
| 4377 | + return -EINVAL; | |
| 4378 | + } | |
| 4379 | + } | |
| 4380 | + | |
| 4381 | + madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n", | |
| 4382 | + lockdet_thr, hp, fbdiv); | |
| 4383 | + | |
| 4384 | + /* Calculate N.K values */ | |
| 4385 | + fllgcd = gcd(fout, fbdiv * fref); | |
| 4386 | + num = fout / fllgcd; | |
| 4387 | + lambda = (fref * fbdiv) / fllgcd; | |
| 4388 | + fll_n = num / lambda; | |
| 4389 | + theta = num % lambda; | |
| 4390 | + | |
| 4391 | + madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n", | |
| 4392 | + fll_n, fllgcd, theta, lambda); | |
| 4393 | + | |
| 4394 | + /* Some sanity checks before any registers are written. */ | |
| 4395 | + if (fll_n < min_n || fll_n > max_n) { | |
| 4396 | + madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n", | |
| 4397 | + frac ? "fractional" : "integer", min_n, max_n, | |
| 4398 | + fll_n); | |
| 4399 | + return -EINVAL; | |
| 4400 | + } | |
| 4401 | + if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) { | |
| 4402 | + madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n", | |
| 4403 | + frac ? "fractional" : "integer", fbdiv); | |
| 4404 | + return -EINVAL; | |
| 4405 | + } | |
| 4406 | + | |
| 4407 | + /* clear the ctrl_upd bit to guarantee we write to it later. */ | |
| 4408 | + regmap_write(madera->regmap, | |
| 4409 | + fll->base + MADERA_FLL_CONTROL_2_OFFS, | |
| 4410 | + fll_n << MADERA_FLL1_N_SHIFT); | |
| 4411 | + regmap_update_bits(madera->regmap, | |
| 4412 | + fll->base + MADERA_FLL_CONTROL_3_OFFS, | |
| 4413 | + MADERA_FLL1_THETA_MASK, | |
| 4414 | + theta << MADERA_FLL1_THETA_SHIFT); | |
| 4415 | + regmap_update_bits(madera->regmap, | |
| 4416 | + fll->base + MADERA_FLL_CONTROL_4_OFFS, | |
| 4417 | + MADERA_FLL1_LAMBDA_MASK, | |
| 4418 | + lambda << MADERA_FLL1_LAMBDA_SHIFT); | |
| 4419 | + regmap_update_bits(madera->regmap, | |
| 4420 | + fll->base + MADERA_FLL_CONTROL_5_OFFS, | |
| 4421 | + MADERA_FLL1_FB_DIV_MASK, | |
| 4422 | + fbdiv << MADERA_FLL1_FB_DIV_SHIFT); | |
| 4423 | + regmap_update_bits(madera->regmap, | |
| 4424 | + fll->base + MADERA_FLL_CONTROL_6_OFFS, | |
| 4425 | + MADERA_FLL1_REFCLK_DIV_MASK, | |
| 4426 | + refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT); | |
| 4427 | + regmap_update_bits(madera->regmap, | |
| 4428 | + fll->base + MADERA_FLL_GAIN_OFFS, | |
| 4429 | + 0xffff, | |
| 4430 | + gains); | |
| 4431 | + val = hp << MADERA_FLL1_HP_SHIFT; | |
| 4432 | + val |= 1 << MADERA_FLL1_PHASEDET_ENA_SHIFT; | |
| 4433 | + regmap_update_bits(madera->regmap, | |
| 4434 | + fll->base + MADERA_FLL_CONTROL_10_OFFS, | |
| 4435 | + MADERA_FLL1_HP_MASK | MADERA_FLL1_PHASEDET_ENA_MASK, | |
| 4436 | + val); | |
| 4437 | + regmap_update_bits(madera->regmap, | |
| 4438 | + fll->base + MADERA_FLL_CONTROL_11_OFFS, | |
| 4439 | + MADERA_FLL1_LOCKDET_THR_MASK, | |
| 4440 | + lockdet_thr << MADERA_FLL1_LOCKDET_THR_SHIFT); | |
| 4441 | + regmap_update_bits(madera->regmap, | |
| 4442 | + fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS, | |
| 4443 | + MADERA_FLL1_SYNC_EFS_ENA_MASK | | |
| 4444 | + MADERA_FLL1_CLK_VCO_FAST_SRC_MASK, | |
| 4445 | + fast_clk); | |
| 4446 | + | |
| 4447 | + return 0; | |
| 4448 | +} | |
| 4449 | + | |
| 4450 | +static int madera_fllhj_enable(struct madera_fll *fll) | |
| 4451 | +{ | |
| 4452 | + struct madera *madera = fll->madera; | |
| 4453 | + int already_enabled = madera_is_enabled_fll(fll, fll->base); | |
| 4454 | + int ret; | |
| 4455 | + | |
| 4456 | + if (already_enabled < 0) | |
| 4457 | + return already_enabled; | |
| 4458 | + | |
| 4459 | + if (!already_enabled) | |
| 4460 | + pm_runtime_get_sync(madera->dev); | |
| 4461 | + | |
| 4462 | + madera_fll_dbg(fll, "Enabling FLL, initially %s\n", | |
| 4463 | + already_enabled ? "enabled" : "disabled"); | |
| 4464 | + | |
| 4465 | + /* FLLn_HOLD must be set before configuring any registers */ | |
| 4466 | + regmap_update_bits(fll->madera->regmap, | |
| 4467 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4468 | + MADERA_FLL1_HOLD_MASK, | |
| 4469 | + MADERA_FLL1_HOLD_MASK); | |
| 4470 | + | |
| 4471 | + /* Apply refclk */ | |
| 4472 | + ret = madera_fllhj_apply(fll, fll->ref_freq); | |
| 4473 | + if (ret) { | |
| 4474 | + madera_fll_err(fll, "Failed to set FLL: %d\n", ret); | |
| 4475 | + goto out; | |
| 4476 | + } | |
| 4477 | + regmap_update_bits(madera->regmap, | |
| 4478 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4479 | + CS47L92_FLL1_REFCLK_SRC_MASK, | |
| 4480 | + fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT); | |
| 4481 | + | |
| 4482 | + regmap_update_bits(madera->regmap, | |
| 4483 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4484 | + MADERA_FLL1_ENA_MASK, | |
| 4485 | + MADERA_FLL1_ENA_MASK); | |
| 4486 | + | |
| 4487 | +out: | |
| 4488 | + regmap_update_bits(madera->regmap, | |
| 4489 | + fll->base + MADERA_FLL_CONTROL_11_OFFS, | |
| 4490 | + MADERA_FLL1_LOCKDET_MASK, | |
| 4491 | + MADERA_FLL1_LOCKDET_MASK); | |
| 4492 | + | |
| 4493 | + regmap_update_bits(madera->regmap, | |
| 4494 | + fll->base + MADERA_FLL_CONTROL_2_OFFS, | |
| 4495 | + MADERA_FLL1_CTRL_UPD_MASK, | |
| 4496 | + MADERA_FLL1_CTRL_UPD_MASK); | |
| 4497 | + | |
| 4498 | + /* Release the hold so that flln locks to external frequency */ | |
| 4499 | + regmap_update_bits(madera->regmap, | |
| 4500 | + fll->base + MADERA_FLL_CONTROL_1_OFFS, | |
| 4501 | + MADERA_FLL1_HOLD_MASK, | |
| 4502 | + 0); | |
| 4503 | + | |
| 4504 | + if (!already_enabled) | |
| 4505 | + madera_wait_for_fll(fll, true); | |
| 4506 | + | |
| 4507 | + return 0; | |
| 4508 | +} | |
| 4509 | + | |
| 4510 | +static int madera_fllhj_validate(struct madera_fll *fll, | |
| 4511 | + unsigned int ref_in, | |
| 4512 | + unsigned int fout) | |
| 4513 | +{ | |
| 4514 | + if (fout && !ref_in) { | |
| 4515 | + madera_fll_err(fll, "fllout set without valid input clk\n"); | |
| 4516 | + return -EINVAL; | |
| 4517 | + } | |
| 4518 | + | |
| 4519 | + if (fll->fout && fout != fll->fout) { | |
| 4520 | + madera_fll_err(fll, "Can't change output on active FLL\n"); | |
| 4521 | + return -EINVAL; | |
| 4522 | + } | |
| 4523 | + | |
| 4524 | + if (ref_in / MADERA_FLL_MAX_REFDIV > MADERA_FLLHJ_MAX_THRESH) { | |
| 4525 | + madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in); | |
| 4526 | + return -EINVAL; | |
| 4527 | + } | |
| 4528 | + | |
| 4529 | + return 0; | |
| 4530 | +} | |
| 4531 | + | |
| 4532 | +int madera_fllhj_set_refclk(struct madera_fll *fll, int source, | |
| 4533 | + unsigned int fin, unsigned int fout) | |
| 4534 | +{ | |
| 4535 | + int ret = 0; | |
| 4536 | + | |
| 4537 | + /* To remain consistent with previous FLLs, we expect fout to be | |
| 4538 | + * provided in the form of the required sysclk rate, which is | |
| 4539 | + * 2x the calculated fll out. | |
| 4540 | + */ | |
| 4541 | + if (fout) | |
| 4542 | + fout /= 2; | |
| 4543 | + | |
| 4544 | + if (fll->ref_src == source && fll->ref_freq == fin && | |
| 4545 | + fll->fout == fout) | |
| 4546 | + return 0; | |
| 4547 | + | |
| 4548 | + if (fin && fout && madera_fllhj_validate(fll, fin, fout)) | |
| 4549 | + return -EINVAL; | |
| 4550 | + | |
| 4551 | + fll->ref_src = source; | |
| 4552 | + fll->ref_freq = fin; | |
| 4553 | + fll->fout = fout; | |
| 4554 | + | |
| 4555 | + if (fout) | |
| 4556 | + ret = madera_fllhj_enable(fll); | |
| 4557 | + else | |
| 4558 | + madera_fllhj_disable(fll); | |
| 4559 | + | |
| 4560 | + return ret; | |
| 4561 | +} | |
| 4562 | +EXPORT_SYMBOL_GPL(madera_fllhj_set_refclk); | |
| 4563 | + | |
| 4051 | 4564 | /** |
| 4052 | 4565 | * madera_set_output_mode - Set the mode of the specified output |
| 4053 | 4566 | * |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #define MADERA_CLK_SYSCLK_3 6 |
| 48 | 48 | #define MADERA_CLK_ASYNCCLK_2 7 |
| 49 | 49 | #define MADERA_CLK_DSPCLK 8 |
| 50 | +#define MADERA_CLK_OUTCLK 9 | |
| 50 | 51 | |
| 51 | 52 | #define MADERA_CLK_SRC_MCLK1 0x0 |
| 52 | 53 | #define MADERA_CLK_SRC_MCLK2 0x1 |
| @@ -61,6 +62,12 @@ · 8 unmodified lines | ||
| 61 | 62 | #define MADERA_CLK_SRC_AIF4BCLK 0xB |
| 62 | 63 | #define MADERA_CLK_SRC_FLLAO 0xF |
| 63 | 64 | |
| 65 | +#define MADERA_OUTCLK_SYSCLK 0 | |
| 66 | +#define MADERA_OUTCLK_ASYNCCLK 1 | |
| 67 | +#define MADERA_OUTCLK_MCLK1 4 | |
| 68 | +#define MADERA_OUTCLK_MCLK2 5 | |
| 69 | +#define MADERA_OUTCLK_MCLK3 6 | |
| 70 | + | |
| 64 | 71 | #define MADERA_MIXER_VOL_MASK 0x00FE |
| 65 | 72 | #define MADERA_MIXER_VOL_SHIFT 1 |
| 66 | 73 | #define MADERA_MIXER_VOL_WIDTH 7 |
| @@ -326,6 +333,7 @@ extern const struct soc_enum madera_sample_rate[]; · 259 unmodified lines | ||
| 326 | 333 | extern const struct soc_enum madera_isrc_fsl[]; |
| 327 | 334 | extern const struct soc_enum madera_isrc_fsh[]; |
| 328 | 335 | extern const struct soc_enum madera_asrc1_rate[]; |
| 336 | +extern const struct soc_enum madera_asrc1_bidir_rate[]; | |
| 329 | 337 | extern const struct soc_enum madera_asrc2_rate[]; |
| 330 | 338 | extern const struct soc_enum madera_dfc_width[]; |
| 331 | 339 | extern const struct soc_enum madera_dfc_type[]; |
| @@ -403,6 +411,8 @@ int madera_set_fll_syncclk(struct madera_fll *fll, int source, · 71 unmodified lines | ||
| 403 | 411 | unsigned int fref, unsigned int fout); |
| 404 | 412 | int madera_set_fll_ao_refclk(struct madera_fll *fll, int source, |
| 405 | 413 | unsigned int fin, unsigned int fout); |
| 414 | +int madera_fllhj_set_refclk(struct madera_fll *fll, int source, | |
| 415 | + unsigned int fin, unsigned int fout); | |
| 406 | 416 | |
| 407 | 417 | int madera_core_init(struct madera_priv *priv); |
| 408 | 418 | int madera_core_free(struct madera_priv *priv); |
| @@ -154,10 +154,6 @@ static const DECLARE_TLV_DB_RANGE(max98371_gain_tlv, · 153 unmodified lines | ||
| 154 | 154 | 8, 10, TLV_DB_SCALE_ITEM(400, 100, 0) |
| 155 | 155 | ); |
| 156 | 156 | |
| 157 | −static const DECLARE_TLV_DB_RANGE(max98371_noload_gain_tlv, | |
| 158 | − 0, 11, TLV_DB_SCALE_ITEM(950, 100, 0), | |
| 159 | −); | |
| 160 | − | |
| 161 | 157 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1); |
| 162 | 158 | |
| 163 | 159 | static const struct snd_kcontrol_new max98371_snd_controls[] = { |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <sound/pcm_params.h> |
| 13 | 13 | #include <sound/soc.h> |
| 14 | 14 | #include <linux/gpio.h> |
| 15 | +#include <linux/of.h> | |
| 15 | 16 | #include <linux/of_gpio.h> |
| 16 | 17 | #include <sound/tlv.h> |
| 17 | 18 | #include "max98373.h" |
| @@ -901,6 +902,17 @@ static void max98373_slot_config(struct i2c_client *i2c, · 883 unmodified lines | ||
| 901 | 902 | else |
| 902 | 903 | max98373->i_slot = 1; |
| 903 | 904 | |
| 905 | + max98373->reset_gpio = of_get_named_gpio(dev->of_node, | |
| 906 | + "maxim,reset-gpio", 0); | |
| 907 | + if (!gpio_is_valid(max98373->reset_gpio)) { | |
| 908 | + dev_err(dev, "Looking up %s property in node %s failed %d\n", | |
| 909 | + "maxim,reset-gpio", dev->of_node->full_name, | |
| 910 | + max98373->reset_gpio); | |
| 911 | + } else { | |
| 912 | + dev_dbg(dev, "maxim,reset-gpio=%d", | |
| 913 | + max98373->reset_gpio); | |
| 914 | + } | |
| 915 | + | |
| 904 | 916 | if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) |
| 905 | 917 | max98373->spkfb_slot = value & 0xF; |
| 906 | 918 | else |
| @@ -929,7 +941,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c, · 22 unmodified lines | ||
| 929 | 941 | else |
| 930 | 942 | max98373->interleave_mode = false; |
| 931 | 943 | |
| 932 | − | |
| 933 | 944 | /* regmap initialization */ |
| 934 | 945 | max98373->regmap |
| 935 | 946 | = devm_regmap_init_i2c(i2c, &max98373_regmap); |
| @@ -940,6 +951,24 @@ static int max98373_i2c_probe(struct i2c_client *i2c, · 4 unmodified lines | ||
| 940 | 951 | return ret; |
| 941 | 952 | } |
| 942 | 953 | |
| 954 | + /* voltage/current slot & gpio configuration */ | |
| 955 | + max98373_slot_config(i2c, max98373); | |
| 956 | + | |
| 957 | + /* Power on device */ | |
| 958 | + if (gpio_is_valid(max98373->reset_gpio)) { | |
| 959 | + ret = gpio_request(max98373->reset_gpio, "MAX98373_RESET"); | |
| 960 | + if (ret) { | |
| 961 | + dev_err(&i2c->dev, "%s: Failed to request gpio %d\n", | |
| 962 | + __func__, max98373->reset_gpio); | |
| 963 | + gpio_free(max98373->reset_gpio); | |
| 964 | + return -EINVAL; | |
| 965 | + } | |
| 966 | + gpio_direction_output(max98373->reset_gpio, 0); | |
| 967 | + msleep(50); | |
| 968 | + gpio_direction_output(max98373->reset_gpio, 1); | |
| 969 | + msleep(20); | |
| 970 | + } | |
| 971 | + | |
| 943 | 972 | /* Check Revision ID */ |
| 944 | 973 | ret = regmap_read(max98373->regmap, |
| 945 | 974 | MAX98373_R21FF_REV_ID, ®); |
| @@ -950,9 +979,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c, · 4 unmodified lines | ||
| 950 | 979 | } |
| 951 | 980 | dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg); |
| 952 | 981 | |
| 953 | − /* voltage/current slot configuration */ | |
| 954 | − max98373_slot_config(i2c, max98373); | |
| 955 | − | |
| 956 | 982 | /* codec registeration */ |
| 957 | 983 | ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373, |
| 958 | 984 | max98373_dai, ARRAY_SIZE(max98373_dai)); |
| @@ -205,6 +205,7 @@ · 204 unmodified lines | ||
| 205 | 205 | |
| 206 | 206 | struct max98373_priv { |
| 207 | 207 | struct regmap *regmap; |
| 208 | + int reset_gpio; | |
| 208 | 209 | unsigned int v_slot; |
| 209 | 210 | unsigned int i_slot; |
| 210 | 211 | unsigned int spkfb_slot; |
| @@ -27,19 +27,6 @@ struct max9850_priv { · 26 unmodified lines | ||
| 27 | 27 | unsigned int sysclk; |
| 28 | 28 | }; |
| 29 | 29 | |
| 30 | −/* max9850 register cache */ | |
| 31 | −static const struct reg_default max9850_reg[] = { | |
| 32 | − { 2, 0x0c }, | |
| 33 | − { 3, 0x00 }, | |
| 34 | − { 4, 0x00 }, | |
| 35 | − { 5, 0x00 }, | |
| 36 | − { 6, 0x00 }, | |
| 37 | − { 7, 0x00 }, | |
| 38 | − { 8, 0x00 }, | |
| 39 | − { 9, 0x00 }, | |
| 40 | − { 10, 0x00 }, | |
| 41 | −}; | |
| 42 | − | |
| 43 | 30 | /* these registers are not used at the moment but provided for the sake of |
| 44 | 31 | * completeness */ |
| 45 | 32 | static bool max9850_volatile_register(struct device *dev, unsigned int reg) |
| @@ -20,15 +20,6 @@ static const char * const max98926_boost_voltage_txt[] = { · 19 unmodified lines | ||
| 20 | 20 | "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V" |
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | −static const char * const max98926_boost_current_txt[] = { | |
| 24 | − "0.6", "0.8", "1.0", "1.2", "1.4", "1.6", "1.8", "2.0", | |
| 25 | − "2.2", "2.4", "2.6", "2.8", "3.2", "3.6", "4.0", "4.4" | |
| 26 | −}; | |
| 27 | − | |
| 28 | −static const char *const max98926_dai_txt[] = { | |
| 29 | − "Left", "Right", "LeftRight", "LeftRightDiv2", | |
| 30 | −}; | |
| 31 | − | |
| 32 | 23 | static const char *const max98926_pdm_ch_text[] = { |
| 33 | 24 | "Current", "Voltage", |
| 34 | 25 | }; |
| @@ -56,7 +56,6 @@ static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0); · 55 unmodified lines | ||
| 56 | 56 | static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0); |
| 57 | 57 | static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0); |
| 58 | 58 | static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0); |
| 59 | −static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0); | |
| 60 | 59 | |
| 61 | 60 | static const char * const ml26124_companding[] = {"16bit PCM", "u-law", |
| 62 | 61 | "A-law"}; |
| @@ -1185,10 +1185,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) · 1184 unmodified lines | ||
| 1185 | 1185 | } |
| 1186 | 1186 | |
| 1187 | 1187 | irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); |
| 1188 | − if (irq < 0) { | |
| 1189 | − dev_err(dev, "failed to get mbhc switch irq\n"); | |
| 1188 | + if (irq < 0) | |
| 1190 | 1189 | return irq; |
| 1191 | − } | |
| 1192 | 1190 | |
| 1193 | 1191 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1194 | 1192 | pm8916_mbhc_switch_irq_handler, |
| @@ -1200,10 +1198,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 1200 | 1198 | |
| 1201 | 1199 | if (priv->mbhc_btn_enabled) { |
| 1202 | 1200 | irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); |
| 1203 | − if (irq < 0) { | |
| 1204 | − dev_err(dev, "failed to get button press irq\n"); | |
| 1201 | + if (irq < 0) | |
| 1205 | 1202 | return irq; |
| 1206 | − } | |
| 1207 | 1203 | |
| 1208 | 1204 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1209 | 1205 | mbhc_btn_press_irq_handler, |
| @@ -1214,10 +1210,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 1214 | 1210 | dev_err(dev, "cannot request mbhc button press irq\n"); |
| 1215 | 1211 | |
| 1216 | 1212 | irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); |
| 1217 | − if (irq < 0) { | |
| 1218 | − dev_err(dev, "failed to get button release irq\n"); | |
| 1213 | + if (irq < 0) | |
| 1219 | 1214 | return irq; |
| 1220 | − } | |
| 1221 | 1215 | |
| 1222 | 1216 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1223 | 1217 | mbhc_btn_release_irq_handler, |
| @@ -1143,7 +1143,6 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev) · 1142 unmodified lines | ||
| 1143 | 1143 | struct msm8916_wcd_digital_priv *priv; |
| 1144 | 1144 | struct device *dev = &pdev->dev; |
| 1145 | 1145 | void __iomem *base; |
| 1146 | − struct resource *mem_res; | |
| 1147 | 1146 | struct regmap *digital_map; |
| 1148 | 1147 | int ret; |
| 1149 | 1148 | |
| @@ -1151,8 +1150,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1151 | 1150 | if (!priv) |
| 1152 | 1151 | return -ENOMEM; |
| 1153 | 1152 | |
| 1154 | − mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1155 | − base = devm_ioremap_resource(&pdev->dev, mem_res); | |
| 1153 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 1156 | 1154 | if (IS_ERR(base)) |
| 1157 | 1155 | return PTR_ERR(base); |
| 1158 | 1156 | |
| @@ -1066,11 +1066,6 @@ static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w, · 1065 unmodified lines | ||
| 1066 | 1066 | return 0; |
| 1067 | 1067 | } |
| 1068 | 1068 | |
| 1069 | −/* DAPM Kcontrols */ | |
| 1070 | −static const struct snd_kcontrol_new mt_lineout_control = | |
| 1071 | − SOC_DAPM_SINGLE("Switch", MT6351_AUDDEC_ANA_CON3, | |
| 1072 | − RG_AUDLOLPWRUP_VAUDP32_BIT, 1, 0); | |
| 1073 | − | |
| 1074 | 1069 | /* DAPM Widgets */ |
| 1075 | 1070 | static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = { |
| 1076 | 1071 | /* Digital Clock */ |
| @@ -1730,6 +1730,10 @@ static int mt6358_dmic_enable(struct mt6358_priv *priv) · 1729 unmodified lines | ||
| 1730 | 1730 | |
| 1731 | 1731 | /* UL turn on */ |
| 1732 | 1732 | regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003); |
| 1733 | + | |
| 1734 | + /* Prevent pop noise form dmic hw */ | |
| 1735 | + msleep(100); | |
| 1736 | + | |
| 1733 | 1737 | return 0; |
| 1734 | 1738 | } |
| 1735 | 1739 | |
| @@ -2255,10 +2259,8 @@ static struct snd_soc_dai_driver mt6358_dai_driver[] = { · 519 unmodified lines | ||
| 2255 | 2259 | }, |
| 2256 | 2260 | }; |
| 2257 | 2261 | |
| 2258 | −static int mt6358_codec_init_reg(struct mt6358_priv *priv) | |
| 2262 | +static void mt6358_codec_init_reg(struct mt6358_priv *priv) | |
| 2259 | 2263 | { |
| 2260 | − int ret = 0; | |
| 2261 | − | |
| 2262 | 2264 | /* Disable HeadphoneL/HeadphoneR short circuit protection */ |
| 2263 | 2265 | regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0, |
| 2264 | 2266 | RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT, |
| @@ -2285,8 +2287,6 @@ static int mt6358_codec_init_reg(struct mt6358_priv *priv) · 20 unmodified lines | ||
| 2285 | 2287 | /* set gpio */ |
| 2286 | 2288 | playback_gpio_reset(priv); |
| 2287 | 2289 | capture_gpio_reset(priv); |
| 2288 | − | |
| 2289 | − return ret; | |
| 2290 | 2290 | } |
| 2291 | 2291 | |
| 2292 | 2292 | static int mt6358_codec_probe(struct snd_soc_component *cmpnt) |
| @@ -44,18 +44,25 @@ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = { · 43 unmodified lines | ||
| 44 | 44 | "VCCDA2" |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | +#define PCM3168A_DAI_DAC 0 | |
| 48 | +#define PCM3168A_DAI_ADC 1 | |
| 49 | + | |
| 50 | +/* ADC/DAC side parameters */ | |
| 51 | +struct pcm3168a_io_params { | |
| 52 | + bool master_mode; | |
| 53 | + unsigned int fmt; | |
| 54 | + int tdm_slots; | |
| 55 | + u32 tdm_mask; | |
| 56 | + int slot_width; | |
| 57 | +}; | |
| 58 | + | |
| 47 | 59 | struct pcm3168a_priv { |
| 48 | 60 | struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES]; |
| 49 | 61 | struct regmap *regmap; |
| 50 | 62 | struct clk *scki; |
| 51 | − bool adc_master_mode; | |
| 52 | − bool dac_master_mode; | |
| 53 | 63 | unsigned long sysclk; |
| 54 | − unsigned int adc_fmt; | |
| 55 | − unsigned int dac_fmt; | |
| 56 | − int tdm_slots; | |
| 57 | − u32 tdm_mask[2]; | |
| 58 | − int slot_width; | |
| 64 | + | |
| 65 | + struct pcm3168a_io_params io_params[2]; | |
| 59 | 66 | }; |
| 60 | 67 | |
| 61 | 68 | static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" }; |
| @@ -263,7 +270,7 @@ static unsigned int pcm3168a_scki_ratios[] = { · 201 unmodified lines | ||
| 263 | 270 | #define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios) |
| 264 | 271 | #define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2) |
| 265 | 272 | |
| 266 | −#define PCM1368A_MAX_SYSCLK 36864000 | |
| 273 | +#define PCM3168A_MAX_SYSCLK 36864000 | |
| 267 | 274 | |
| 268 | 275 | static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a) |
| 269 | 276 | { |
| @@ -296,7 +303,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai, · 26 unmodified lines | ||
| 296 | 303 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); |
| 297 | 304 | int ret; |
| 298 | 305 | |
| 299 | − if (freq > PCM1368A_MAX_SYSCLK) | |
| 306 | + if (freq > PCM3168A_MAX_SYSCLK) | |
| 300 | 307 | return -EINVAL; |
| 301 | 308 | |
| 302 | 309 | ret = clk_set_rate(pcm3168a->scki, freq); |
| @@ -308,8 +315,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai, · 5 unmodified lines | ||
| 308 | 315 | return 0; |
| 309 | 316 | } |
| 310 | 317 | |
| 311 | −static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, | |
| 312 | − unsigned int format, bool dac) | |
| 318 | +static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format) | |
| 313 | 319 | { |
| 314 | 320 | struct snd_soc_component *component = dai->component; |
| 315 | 321 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); |
| @@ -356,43 +362,31 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, · 40 unmodified lines | ||
| 356 | 362 | return -EINVAL; |
| 357 | 363 | } |
| 358 | 364 | |
| 359 | − if (dac) { | |
| 365 | + if (dai->id == PCM3168A_DAI_DAC) { | |
| 360 | 366 | reg = PCM3168A_DAC_PWR_MST_FMT; |
| 361 | 367 | mask = PCM3168A_DAC_FMT_MASK; |
| 362 | 368 | shift = PCM3168A_DAC_FMT_SHIFT; |
| 363 | − pcm3168a->dac_master_mode = master_mode; | |
| 364 | − pcm3168a->dac_fmt = fmt; | |
| 365 | 369 | } else { |
| 366 | 370 | reg = PCM3168A_ADC_MST_FMT; |
| 367 | 371 | mask = PCM3168A_ADC_FMTAD_MASK; |
| 368 | 372 | shift = PCM3168A_ADC_FMTAD_SHIFT; |
| 369 | − pcm3168a->adc_master_mode = master_mode; | |
| 370 | − pcm3168a->adc_fmt = fmt; | |
| 371 | 373 | } |
| 372 | 374 | |
| 375 | + pcm3168a->io_params[dai->id].master_mode = master_mode; | |
| 376 | + pcm3168a->io_params[dai->id].fmt = fmt; | |
| 377 | + | |
| 373 | 378 | regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); |
| 374 | 379 | |
| 375 | 380 | return 0; |
| 376 | 381 | } |
| 377 | 382 | |
| 378 | −static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai, | |
| 379 | − unsigned int format) | |
| 380 | −{ | |
| 381 | − return pcm3168a_set_dai_fmt(dai, format, true); | |
| 382 | −} | |
| 383 | − | |
| 384 | −static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai, | |
| 385 | − unsigned int format) | |
| 386 | −{ | |
| 387 | − return pcm3168a_set_dai_fmt(dai, format, false); | |
| 388 | −} | |
| 389 | − | |
| 390 | 383 | static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
| 391 | 384 | unsigned int rx_mask, int slots, |
| 392 | 385 | int slot_width) |
| 393 | 386 | { |
| 394 | 387 | struct snd_soc_component *component = dai->component; |
| 395 | 388 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); |
| 389 | + struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id]; | |
| 396 | 390 | |
| 397 | 391 | if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) { |
| 398 | 392 | dev_err(component->dev, |
| @@ -408,22 +402,13 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, · 9 unmodified lines | ||
| 408 | 402 | return -EINVAL; |
| 409 | 403 | } |
| 410 | 404 | |
| 411 | − if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) { | |
| 412 | − dev_err(component->dev, "Not matching slots %d vs %d\n", | |
| 413 | − pcm3168a->tdm_slots, slots); | |
| 414 | − return -EINVAL; | |
| 415 | − } | |
| 416 | − | |
| 417 | − if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) { | |
| 418 | − dev_err(component->dev, "Not matching slot_width %d vs %d\n", | |
| 419 | − pcm3168a->slot_width, slot_width); | |
| 420 | − return -EINVAL; | |
| 421 | − } | |
| 422 | − | |
| 423 | − pcm3168a->tdm_slots = slots; | |
| 424 | − pcm3168a->slot_width = slot_width; | |
| 425 | − pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; | |
| 426 | − pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; | |
| 405 | + io_params->tdm_slots = slots; | |
| 406 | + io_params->slot_width = slot_width; | |
| 407 | + /* Ignore the not relevant mask for the DAI/direction */ | |
| 408 | + if (dai->id == PCM3168A_DAI_DAC) | |
| 409 | + io_params->tdm_mask = tx_mask; | |
| 410 | + else | |
| 411 | + io_params->tdm_mask = rx_mask; | |
| 427 | 412 | |
| 428 | 413 | return 0; |
| 429 | 414 | } |
| @@ -434,7 +419,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 4 unmodified lines | ||
| 434 | 419 | { |
| 435 | 420 | struct snd_soc_component *component = dai->component; |
| 436 | 421 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); |
| 437 | − bool tx, master_mode; | |
| 422 | + struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id]; | |
| 423 | + bool master_mode; | |
| 438 | 424 | u32 val, mask, shift, reg; |
| 439 | 425 | unsigned int rate, fmt, ratio, max_ratio; |
| 440 | 426 | unsigned int tdm_slots; |
| @@ -444,23 +430,21 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines | ||
| 444 | 430 | |
| 445 | 431 | ratio = pcm3168a->sysclk / rate; |
| 446 | 432 | |
| 447 | − tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | |
| 448 | − if (tx) { | |
| 433 | + if (dai->id == PCM3168A_DAI_DAC) { | |
| 449 | 434 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC; |
| 450 | 435 | reg = PCM3168A_DAC_PWR_MST_FMT; |
| 451 | 436 | mask = PCM3168A_DAC_MSDA_MASK; |
| 452 | 437 | shift = PCM3168A_DAC_MSDA_SHIFT; |
| 453 | − master_mode = pcm3168a->dac_master_mode; | |
| 454 | − fmt = pcm3168a->dac_fmt; | |
| 455 | 438 | } else { |
| 456 | 439 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC; |
| 457 | 440 | reg = PCM3168A_ADC_MST_FMT; |
| 458 | 441 | mask = PCM3168A_ADC_MSAD_MASK; |
| 459 | 442 | shift = PCM3168A_ADC_MSAD_SHIFT; |
| 460 | − master_mode = pcm3168a->adc_master_mode; | |
| 461 | − fmt = pcm3168a->adc_fmt; | |
| 462 | 443 | } |
| 463 | 444 | |
| 445 | + master_mode = io_params->master_mode; | |
| 446 | + fmt = io_params->fmt; | |
| 447 | + | |
| 464 | 448 | for (i = 0; i < max_ratio; i++) { |
| 465 | 449 | if (pcm3168a_scki_ratios[i] == ratio) |
| 466 | 450 | break; |
| @@ -471,8 +455,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 4 unmodified lines | ||
| 471 | 455 | return -EINVAL; |
| 472 | 456 | } |
| 473 | 457 | |
| 474 | − if (pcm3168a->slot_width) | |
| 475 | − slot_width = pcm3168a->slot_width; | |
| 458 | + if (io_params->slot_width) | |
| 459 | + slot_width = io_params->slot_width; | |
| 476 | 460 | else |
| 477 | 461 | slot_width = params_width(params); |
| 478 | 462 | |
| @@ -497,8 +481,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 18 unmodified lines | ||
| 497 | 481 | return -EINVAL; |
| 498 | 482 | } |
| 499 | 483 | |
| 500 | − if (pcm3168a->tdm_slots) | |
| 501 | − tdm_slots = pcm3168a->tdm_slots; | |
| 484 | + if (io_params->tdm_slots) | |
| 485 | + tdm_slots = io_params->tdm_slots; | |
| 502 | 486 | else |
| 503 | 487 | tdm_slots = params_channels(params); |
| 504 | 488 | |
| @@ -534,7 +518,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 29 unmodified lines | ||
| 534 | 518 | |
| 535 | 519 | regmap_update_bits(pcm3168a->regmap, reg, mask, val); |
| 536 | 520 | |
| 537 | − if (tx) { | |
| 521 | + if (dai->id == PCM3168A_DAI_DAC) { | |
| 538 | 522 | mask = PCM3168A_DAC_FMT_MASK; |
| 539 | 523 | shift = PCM3168A_DAC_FMT_SHIFT; |
| 540 | 524 | } else { |
| @@ -552,20 +536,13 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 11 unmodified lines | ||
| 552 | 536 | { |
| 553 | 537 | struct snd_soc_component *component = dai->component; |
| 554 | 538 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); |
| 555 | − bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | |
| 556 | − unsigned int fmt; | |
| 557 | 539 | unsigned int sample_min; |
| 558 | 540 | unsigned int channel_max; |
| 559 | 541 | unsigned int channel_maxs[] = { |
| 560 | − 6, /* rx */ | |
| 561 | − 8 /* tx */ | |
| 542 | + 8, /* DAC */ | |
| 543 | + 6 /* ADC */ | |
| 562 | 544 | }; |
| 563 | 545 | |
| 564 | − if (tx) | |
| 565 | − fmt = pcm3168a->dac_fmt; | |
| 566 | − else | |
| 567 | − fmt = pcm3168a->adc_fmt; | |
| 568 | − | |
| 569 | 546 | /* |
| 570 | 547 | * Available Data Bits |
| 571 | 548 | * |
| @@ -578,7 +555,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 578 | 555 | * I2S |
| 579 | 556 | * LEFT_J |
| 580 | 557 | */ |
| 581 | − switch (fmt) { | |
| 558 | + switch (pcm3168a->io_params[dai->id].fmt) { | |
| 582 | 559 | case PCM3168A_FMT_RIGHT_J: |
| 583 | 560 | sample_min = 16; |
| 584 | 561 | channel_max = 2; |
| @@ -588,7 +565,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 3 unmodified lines | ||
| 588 | 565 | case PCM3168A_FMT_DSP_A: |
| 589 | 566 | case PCM3168A_FMT_DSP_B: |
| 590 | 567 | sample_min = 24; |
| 591 | − channel_max = channel_maxs[tx]; | |
| 568 | + channel_max = channel_maxs[dai->id]; | |
| 592 | 569 | break; |
| 593 | 570 | default: |
| 594 | 571 | sample_min = 24; |
| @@ -599,32 +576,29 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 4 unmodified lines | ||
| 599 | 576 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, |
| 600 | 577 | sample_min, 32); |
| 601 | 578 | |
| 579 | + /* Allow all channels in multi DIN/DOUT mode */ | |
| 580 | + if (pcm3168a->io_params[dai->id].tdm_slots == 2) | |
| 581 | + channel_max = channel_maxs[dai->id]; | |
| 582 | + | |
| 602 | 583 | snd_pcm_hw_constraint_minmax(substream->runtime, |
| 603 | 584 | SNDRV_PCM_HW_PARAM_CHANNELS, |
| 604 | 585 | 2, channel_max); |
| 605 | 586 | |
| 606 | 587 | return 0; |
| 607 | 588 | } |
| 608 | −static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = { | |
| 589 | +static const struct snd_soc_dai_ops pcm3168a_dai_ops = { | |
| 609 | 590 | .startup = pcm3168a_startup, |
| 610 | − .set_fmt = pcm3168a_set_dai_fmt_dac, | |
| 591 | + .set_fmt = pcm3168a_set_dai_fmt, | |
| 611 | 592 | .set_sysclk = pcm3168a_set_dai_sysclk, |
| 612 | 593 | .hw_params = pcm3168a_hw_params, |
| 613 | 594 | .digital_mute = pcm3168a_digital_mute, |
| 614 | 595 | .set_tdm_slot = pcm3168a_set_tdm_slot, |
| 615 | 596 | }; |
| 616 | 597 | |
| 617 | −static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = { | |
| 618 | − .startup = pcm3168a_startup, | |
| 619 | − .set_fmt = pcm3168a_set_dai_fmt_adc, | |
| 620 | − .set_sysclk = pcm3168a_set_dai_sysclk, | |
| 621 | − .hw_params = pcm3168a_hw_params, | |
| 622 | − .set_tdm_slot = pcm3168a_set_tdm_slot, | |
| 623 | −}; | |
| 624 | − | |
| 625 | 598 | static struct snd_soc_dai_driver pcm3168a_dais[] = { |
| 626 | 599 | { |
| 627 | 600 | .name = "pcm3168a-dac", |
| 601 | + .id = PCM3168A_DAI_DAC, | |
| 628 | 602 | .playback = { |
| 629 | 603 | .stream_name = "Playback", |
| 630 | 604 | .channels_min = 1, |
| @@ -632,10 +606,11 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = { · 1 unmodified line | ||
| 632 | 606 | .rates = SNDRV_PCM_RATE_8000_192000, |
| 633 | 607 | .formats = PCM3168A_FORMATS |
| 634 | 608 | }, |
| 635 | − .ops = &pcm3168a_dac_dai_ops | |
| 609 | + .ops = &pcm3168a_dai_ops | |
| 636 | 610 | }, |
| 637 | 611 | { |
| 638 | 612 | .name = "pcm3168a-adc", |
| 613 | + .id = PCM3168A_DAI_ADC, | |
| 639 | 614 | .capture = { |
| 640 | 615 | .stream_name = "Capture", |
| 641 | 616 | .channels_min = 1, |
| @@ -643,7 +618,7 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = { · 1 unmodified line | ||
| 643 | 618 | .rates = SNDRV_PCM_RATE_8000_96000, |
| 644 | 619 | .formats = PCM3168A_FORMATS |
| 645 | 620 | }, |
| 646 | − .ops = &pcm3168a_adc_dai_ops | |
| 621 | + .ops = &pcm3168a_dai_ops | |
| 647 | 622 | }, |
| 648 | 623 | }; |
| 649 | 624 | |
| @@ -432,7 +432,6 @@ static int rk3328_platform_probe(struct platform_device *pdev) · 431 unmodified lines | ||
| 432 | 432 | { |
| 433 | 433 | struct device_node *rk3328_np = pdev->dev.of_node; |
| 434 | 434 | struct rk3328_codec_priv *rk3328; |
| 435 | − struct resource *res; | |
| 436 | 435 | struct regmap *grf; |
| 437 | 436 | void __iomem *base; |
| 438 | 437 | int ret = 0; |
| @@ -482,8 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev) · 43 unmodified lines | ||
| 482 | 481 | return ret; |
| 483 | 482 | } |
| 484 | 483 | |
| 485 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 486 | − base = devm_ioremap_resource(&pdev->dev, res); | |
| 484 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 487 | 485 | if (IS_ERR(base)) |
| 488 | 486 | return PTR_ERR(base); |
| 489 | 487 | |
| @@ -978,9 +978,6 @@ static bool rt1011_readable_register(struct device *dev, unsigned int reg) · 977 unmodified lines | ||
| 978 | 978 | } |
| 979 | 979 | } |
| 980 | 980 | |
| 981 | −static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9435, 37, 0); | |
| 982 | −static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1739, 37, 0); | |
| 983 | − | |
| 984 | 981 | static const char * const rt1011_din_source_select[] = { |
| 985 | 982 | "Left", |
| 986 | 983 | "Right", |
| @@ -1029,6 +1026,8 @@ static const char * const rt1011_tdm_adc_swap_select[] = { · 42 unmodified lines | ||
| 1029 | 1026 | |
| 1030 | 1027 | static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6, |
| 1031 | 1028 | rt1011_tdm_adc_swap_select); |
| 1029 | +static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc2_1_enum, RT1011_TDM1_SET_3, 4, | |
| 1030 | + rt1011_tdm_adc_swap_select); | |
| 1032 | 1031 | |
| 1033 | 1032 | static void rt1011_reset(struct regmap *regmap) |
| 1034 | 1033 | { |
| @@ -1223,7 +1222,10 @@ static int rt1011_bq_drc_info(struct snd_kcontrol *kcontrol, · 188 unmodified lines | ||
| 1223 | 1222 | static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol, |
| 1224 | 1223 | struct snd_ctl_elem_value *ucontrol) |
| 1225 | 1224 | { |
| 1226 | − ucontrol->value.integer.value[0] = 0; | |
| 1225 | + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | |
| 1226 | + struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component); | |
| 1227 | + | |
| 1228 | + ucontrol->value.integer.value[0] = rt1011->cali_done; | |
| 1227 | 1229 | |
| 1228 | 1230 | return 0; |
| 1229 | 1231 | } |
| @@ -1237,6 +1239,7 @@ static int rt1011_r0_cali_put(struct snd_kcontrol *kcontrol, · 7 unmodified lines | ||
| 1237 | 1239 | if (!component->card->instantiated) |
| 1238 | 1240 | return 0; |
| 1239 | 1241 | |
| 1242 | + rt1011->cali_done = 0; | |
| 1240 | 1243 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF && |
| 1241 | 1244 | ucontrol->value.integer.value[0]) |
| 1242 | 1245 | rt1011_calibrate(rt1011, 1); |
| @@ -1333,7 +1336,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = { · 90 unmodified lines | ||
| 1333 | 1336 | /* TDM1 Data Out Selection */ |
| 1334 | 1337 | SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum), |
| 1335 | 1338 | SOC_ENUM("TDM1 DOUT Location", rt1011_tdm1_adc1_loc_enum), |
| 1336 | − SOC_ENUM("TDM1 ADCDAT Swap Select", rt1011_tdm_adc1_1_enum), | |
| 1339 | + SOC_ENUM("TDM1 ADC1DAT Swap Select", rt1011_tdm_adc1_1_enum), | |
| 1340 | + SOC_ENUM("TDM1 ADC2DAT Swap Select", rt1011_tdm_adc2_1_enum), | |
| 1337 | 1341 | |
| 1338 | 1342 | /* Data Out Mode */ |
| 1339 | 1343 | SOC_ENUM("I2S ADC DOUT Mode", rt1011_adc_dout_mode_enum), |
| @@ -1355,6 +1359,10 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = { · 15 unmodified lines | ||
| 1355 | 1359 | SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0, |
| 1356 | 1360 | rt1011_r0_cali_get, rt1011_r0_cali_put), |
| 1357 | 1361 | RT1011_R0_LOAD("R0 Load Mode"), |
| 1362 | + | |
| 1363 | + /* R0 temperature */ | |
| 1364 | + SOC_SINGLE("R0 Temperature", RT1011_STP_INITIAL_RESISTANCE_TEMP, | |
| 1365 | + 2, 255, 0), | |
| 1358 | 1366 | }; |
| 1359 | 1367 | |
| 1360 | 1368 | static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
| @@ -1511,7 +1519,8 @@ static const struct snd_soc_dapm_route rt1011_dapm_routes[] = { · 150 unmodified lines | ||
| 1511 | 1519 | |
| 1512 | 1520 | static int rt1011_get_clk_info(int sclk, int rate) |
| 1513 | 1521 | { |
| 1514 | − int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 1522 | + int i; | |
| 1523 | + static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 1515 | 1524 | |
| 1516 | 1525 | if (sclk <= 0 || rate <= 0) |
| 1517 | 1526 | return -EINVAL; |
| @@ -2139,6 +2148,7 @@ static int rt1011_calibrate(struct rt1011_priv *rt1011, unsigned char cali_flag) · 621 unmodified lines | ||
| 2139 | 2148 | r0_factor = ((format / r0[0] * 100) / 128) |
| 2140 | 2149 | - (r0_integer * 100); |
| 2141 | 2150 | rt1011->r0_reg = r0[0]; |
| 2151 | + rt1011->cali_done = 1; | |
| 2142 | 2152 | dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n", |
| 2143 | 2153 | r0_integer, r0_factor, r0[0]); |
| 2144 | 2154 | } |
| @@ -2189,6 +2199,13 @@ static void rt1011_calibration_work(struct work_struct *work) · 44 unmodified lines | ||
| 2189 | 2199 | |
| 2190 | 2200 | rt1011_calibrate(rt1011, 1); |
| 2191 | 2201 | |
| 2202 | + /* | |
| 2203 | + * This flag should reset after booting. | |
| 2204 | + * The factory test will do calibration again and use this flag to check | |
| 2205 | + * whether the calibration completed | |
| 2206 | + */ | |
| 2207 | + rt1011->cali_done = 0; | |
| 2208 | + | |
| 2192 | 2209 | /* initial */ |
| 2193 | 2210 | rt1011_reg_init(component); |
| 2194 | 2211 | } |
| @@ -227,6 +227,7 @@ · 226 unmodified lines | ||
| 227 | 227 | #define RT1011_STP_CALIB_RS_TEMP 0x152a |
| 228 | 228 | #define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538 |
| 229 | 229 | #define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539 |
| 230 | +#define RT1011_STP_INITIAL_RESISTANCE_TEMP 0x153c | |
| 230 | 231 | #define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e |
| 231 | 232 | #define RT1011_SPK_RESISTANCE_1 0x1544 |
| 232 | 233 | #define RT1011_SPK_RESISTANCE_2 0x1546 |
| @@ -665,7 +666,7 @@ struct rt1011_priv { · 432 unmodified lines | ||
| 665 | 666 | int pll_out; |
| 666 | 667 | |
| 667 | 668 | int bq_drc_set; |
| 668 | − unsigned int r0_reg; | |
| 669 | + unsigned int r0_reg, cali_done; | |
| 669 | 670 | int recv_spk_mode; |
| 670 | 671 | }; |
| 671 | 672 | |
| @@ -608,7 +608,8 @@ static const struct snd_soc_dapm_route rt1305_dapm_routes[] = { · 607 unmodified lines | ||
| 608 | 608 | |
| 609 | 609 | static int rt1305_get_clk_info(int sclk, int rate) |
| 610 | 610 | { |
| 611 | − int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 611 | + int i; | |
| 612 | + static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 612 | 613 | |
| 613 | 614 | if (sclk <= 0 || rate <= 0) |
| 614 | 615 | return -EINVAL; |
| @@ -1,13 +1,10 @@ | ||
| 1 | −/* | |
| 2 | − * rt1308.c -- RT1308 ALSA SoC amplifier component driver | |
| 3 | − * | |
| 4 | − * Copyright 2019 Realtek Semiconductor Corp. | |
| 5 | − * Author: Derek Fang <derek.fang@realtek.com> | |
| 6 | − * | |
| 7 | − * This program is free software; you can redistribute it and/or modify | |
| 8 | − * it under the terms of the GNU General Public License version 2 as | |
| 9 | − * published by the Free Software Foundation. | |
| 10 | − */ | |
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +// | |
| 3 | +// rt1308.c -- RT1308 ALSA SoC amplifier component driver | |
| 4 | +// | |
| 5 | +// Copyright 2019 Realtek Semiconductor Corp. | |
| 6 | +// Author: Derek Fang <derek.fang@realtek.com> | |
| 7 | +// | |
| 11 | 8 | |
| 12 | 9 | #include <linux/module.h> |
| 13 | 10 | #include <linux/moduleparam.h> |
| @@ -40,10 +37,10 @@ static const struct reg_sequence init_list[] = { · 26 unmodified lines | ||
| 40 | 37 | { RT1308_VREF, 0x18100000 }, |
| 41 | 38 | { RT1308_IV_SENSE, 0x87010000 }, |
| 42 | 39 | { RT1308_DUMMY_REG, 0x00000200 }, |
| 43 | − { RT1308_SIL_DET, 0x61c30000 }, | |
| 40 | + { RT1308_SIL_DET, 0xe1c30000 }, | |
| 44 | 41 | { RT1308_DC_CAL_2, 0x00ffff00 }, |
| 45 | 42 | { RT1308_CLK_DET, 0x01000000 }, |
| 46 | − { RT1308_POWER_STATUS, 0x00800000 }, | |
| 43 | + { RT1308_POWER_STATUS, 0x08800000 }, | |
| 47 | 44 | { RT1308_DAC_SET, 0xafaf0700 }, |
| 48 | 45 | |
| 49 | 46 | }; |
| @@ -308,12 +305,13 @@ static int rt1308_classd_event(struct snd_soc_dapm_widget *w, · 258 unmodified lines | ||
| 308 | 305 | case SND_SOC_DAPM_POST_PMU: |
| 309 | 306 | msleep(30); |
| 310 | 307 | snd_soc_component_update_bits(component, RT1308_POWER_STATUS, |
| 311 | − RT1308_POW_PDB_REG_BIT, RT1308_POW_PDB_REG_BIT); | |
| 308 | + RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT, | |
| 309 | + RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT); | |
| 312 | 310 | msleep(40); |
| 313 | 311 | break; |
| 314 | 312 | case SND_SOC_DAPM_PRE_PMD: |
| 315 | 313 | snd_soc_component_update_bits(component, RT1308_POWER_STATUS, |
| 316 | − RT1308_POW_PDB_REG_BIT, 0); | |
| 314 | + RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT, 0); | |
| 317 | 315 | usleep_range(150000, 200000); |
| 318 | 316 | break; |
| 319 | 317 | |
| @@ -438,7 +436,8 @@ static const struct snd_soc_dapm_route rt1308_dapm_routes[] = { · 118 unmodified lines | ||
| 438 | 436 | |
| 439 | 437 | static int rt1308_get_clk_info(int sclk, int rate) |
| 440 | 438 | { |
| 441 | − int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 439 | + int i; | |
| 440 | + static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | |
| 442 | 441 | |
| 443 | 442 | if (sclk <= 0 || rate <= 0) |
| 444 | 443 | return -EINVAL; |
| @@ -808,33 +807,11 @@ static void rt1308_efuse(struct rt1308_priv *rt1308) · 363 unmodified lines | ||
| 808 | 807 | { |
| 809 | 808 | regmap_write(rt1308->regmap, RT1308_RESET, 0); |
| 810 | 809 | |
| 811 | − regmap_write(rt1308->regmap, RT1308_POWER, 0xff371600); | |
| 812 | − regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52100000); | |
| 813 | − regmap_write(rt1308->regmap, RT1308_I2C_I2S_SDW_SET, 0x01014005); | |
| 814 | − regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501); | |
| 815 | − regmap_write(rt1308->regmap, RT1308_PADS_1, 0x50150505); | |
| 816 | − regmap_write(rt1308->regmap, RT1308_VREF, 0x18100000); | |
| 817 | − regmap_write(rt1308->regmap, RT1308_IV_SENSE, 0x87010000); | |
| 818 | − regmap_write(rt1308->regmap, RT1308_DUMMY_REG, 0x00000200); | |
| 819 | − regmap_write(rt1308->regmap, RT1308_SIL_DET, 0x61c30000); | |
| 820 | − regmap_write(rt1308->regmap, RT1308_CLK_DET, 0x03700000); | |
| 821 | − regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x50022f00); | |
| 822 | 810 | regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000); |
| 823 | − regmap_write(rt1308->regmap, RT1308_DC_CAL_2, 0x00ffff00); | |
| 824 | − regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x607e5501); | |
| 825 | − | |
| 826 | − regmap_write(rt1308->regmap, RT1308_CLK_2, 0x0060e000); | |
| 827 | − regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x04fe0f00); | |
| 828 | 811 | msleep(100); |
| 829 | 812 | regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00); |
| 830 | 813 | msleep(20); |
| 831 | 814 | regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000); |
| 832 | − | |
| 833 | − regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x00800000); | |
| 834 | − regmap_write(rt1308->regmap, RT1308_POWER, 0x0); | |
| 835 | − regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52000000); | |
| 836 | − regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501); | |
| 837 | − regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x10022f00); | |
| 838 | 815 | } |
| 839 | 816 | |
| 840 | 817 | static int rt1308_i2c_probe(struct i2c_client *i2c, |
| @@ -1,12 +1,10 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 1 | 2 | /* |
| 2 | − * RT1308.h -- RT1308 ALSA SoC amplifier component driver | |
| 3 | + * rt1308.h -- RT1308 ALSA SoC amplifier component driver | |
| 3 | 4 | * |
| 4 | 5 | * Copyright 2019 Realtek Semiconductor Corp. |
| 5 | 6 | * Author: Derek Fang <derek.fang@realtek.com> |
| 6 | 7 | * |
| 7 | − * This program is free software; you can redistribute it and/or modify | |
| 8 | − * it under the terms of the GNU General Public License version 2 as | |
| 9 | − * published by the Free Software Foundation. | |
| 10 | 8 | */ |
| 11 | 9 | |
| 12 | 10 | #ifndef _RT1308_H_ |
| @@ -2566,7 +2566,7 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w, · 2565 unmodified lines | ||
| 2566 | 2566 | return 0; |
| 2567 | 2567 | } |
| 2568 | 2568 | |
| 2569 | −static int rt5655_set_verf(struct snd_soc_dapm_widget *w, | |
| 2569 | +static int rt5665_set_verf(struct snd_soc_dapm_widget *w, | |
| 2570 | 2570 | struct snd_kcontrol *kcontrol, int event) |
| 2571 | 2571 | { |
| 2572 | 2572 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
| @@ -2686,11 +2686,11 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { · 113 unmodified lines | ||
| 2686 | 2686 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL, |
| 2687 | 2687 | RT5665_PWR_MIC_DET_BIT, 0, NULL, 0), |
| 2688 | 2688 | SND_SOC_DAPM_SUPPLY("Vref1", RT5665_PWR_ANLG_1, RT5665_PWR_VREF1_BIT, 0, |
| 2689 | − rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2689 | + rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2690 | 2690 | SND_SOC_DAPM_SUPPLY("Vref2", RT5665_PWR_ANLG_1, RT5665_PWR_VREF2_BIT, 0, |
| 2691 | − rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2691 | + rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2692 | 2692 | SND_SOC_DAPM_SUPPLY("Vref3", RT5665_PWR_ANLG_1, RT5665_PWR_VREF3_BIT, 0, |
| 2693 | − rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2693 | + rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | |
| 2694 | 2694 | |
| 2695 | 2695 | /* ASRC */ |
| 2696 | 2696 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5665_ASRC_1, |
| @@ -691,10 +691,12 @@ static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on) · 690 unmodified lines | ||
| 691 | 691 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
| 692 | 692 | |
| 693 | 693 | if (on) { |
| 694 | − regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2); | |
| 694 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, | |
| 695 | + RT5677_PWR_DSP, RT5677_PWR_DSP); | |
| 695 | 696 | rt5677->is_dsp_mode = true; |
| 696 | 697 | } else { |
| 697 | − regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x0); | |
| 698 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, | |
| 699 | + RT5677_PWR_DSP, 0x0); | |
| 698 | 700 | rt5677->is_dsp_mode = false; |
| 699 | 701 | } |
| 700 | 702 | } |
| @@ -4466,7 +4468,8 @@ static int rt5677_set_bias_level(struct snd_soc_component *component, · 3765 unmodified lines | ||
| 4466 | 4468 | |
| 4467 | 4469 | regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, |
| 4468 | 4470 | RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, |
| 4469 | − 0x0055); | |
| 4471 | + 5 << RT5677_LDO1_SEL_SFT | | |
| 4472 | + 5 << RT5677_LDO2_SEL_SFT); | |
| 4470 | 4473 | regmap_update_bits(rt5677->regmap, |
| 4471 | 4474 | RT5677_PR_BASE + RT5677_BIAS_CUR4, |
| 4472 | 4475 | 0x0f00, 0x0f00); |
| @@ -4490,9 +4493,11 @@ static int rt5677_set_bias_level(struct snd_soc_component *component, · 17 unmodified lines | ||
| 4490 | 4493 | case SND_SOC_BIAS_OFF: |
| 4491 | 4494 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); |
| 4492 | 4495 | regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); |
| 4493 | − regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000); | |
| 4494 | − regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022); | |
| 4495 | − regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); | |
| 4496 | + regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, | |
| 4497 | + 2 << RT5677_LDO1_SEL_SFT | | |
| 4498 | + 2 << RT5677_LDO2_SEL_SFT); | |
| 4499 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, | |
| 4500 | + RT5677_PWR_CORE, 0); | |
| 4496 | 4501 | regmap_update_bits(rt5677->regmap, |
| 4497 | 4502 | RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); |
| 4498 | 4503 | |
| @@ -4719,7 +4724,8 @@ static int rt5677_probe(struct snd_soc_component *component) · 220 unmodified lines | ||
| 4719 | 4724 | |
| 4720 | 4725 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, |
| 4721 | 4726 | ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020); |
| 4722 | − regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00); | |
| 4727 | + regmap_write(rt5677->regmap, RT5677_PWR_DSP2, | |
| 4728 | + RT5677_PWR_SLIM_ISO | RT5677_PWR_CORE_ISO); | |
| 4723 | 4729 | |
| 4724 | 4730 | for (i = 0; i < RT5677_GPIO_NUM; i++) |
| 4725 | 4731 | rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); |
| @@ -31,6 +31,13 @@ · 30 unmodified lines | ||
| 31 | 31 | #define SGTL5000_DAP_REG_OFFSET 0x0100 |
| 32 | 32 | #define SGTL5000_MAX_REG_OFFSET 0x013A |
| 33 | 33 | |
| 34 | +/* Delay for the VAG ramp up */ | |
| 35 | +#define SGTL5000_VAG_POWERUP_DELAY 500 /* ms */ | |
| 36 | +/* Delay for the VAG ramp down */ | |
| 37 | +#define SGTL5000_VAG_POWERDOWN_DELAY 500 /* ms */ | |
| 38 | + | |
| 39 | +#define SGTL5000_OUTPUTS_MUTE (SGTL5000_HP_MUTE | SGTL5000_LINE_OUT_MUTE) | |
| 40 | + | |
| 34 | 41 | /* default value of sgtl5000 registers */ |
| 35 | 42 | static const struct reg_default sgtl5000_reg_defaults[] = { |
| 36 | 43 | { SGTL5000_CHIP_DIG_POWER, 0x0000 }, |
| @@ -123,6 +130,13 @@ enum { · 86 unmodified lines | ||
| 123 | 130 | I2S_SCLK_STRENGTH_HIGH, |
| 124 | 131 | }; |
| 125 | 132 | |
| 133 | +enum { | |
| 134 | + HP_POWER_EVENT, | |
| 135 | + DAC_POWER_EVENT, | |
| 136 | + ADC_POWER_EVENT, | |
| 137 | + LAST_POWER_EVENT = ADC_POWER_EVENT | |
| 138 | +}; | |
| 139 | + | |
| 126 | 140 | /* sgtl5000 private structure in codec */ |
| 127 | 141 | struct sgtl5000_priv { |
| 128 | 142 | int sysclk; /* sysclk rate */ |
| @@ -137,8 +151,109 @@ struct sgtl5000_priv { · 8 unmodified lines | ||
| 137 | 151 | u8 micbias_voltage; |
| 138 | 152 | u8 lrclk_strength; |
| 139 | 153 | u8 sclk_strength; |
| 154 | + u16 mute_state[LAST_POWER_EVENT + 1]; | |
| 140 | 155 | }; |
| 141 | 156 | |
| 157 | +static inline int hp_sel_input(struct snd_soc_component *component) | |
| 158 | +{ | |
| 159 | + return (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_CTRL) & | |
| 160 | + SGTL5000_HP_SEL_MASK) >> SGTL5000_HP_SEL_SHIFT; | |
| 161 | +} | |
| 162 | + | |
| 163 | +static inline u16 mute_output(struct snd_soc_component *component, | |
| 164 | + u16 mute_mask) | |
| 165 | +{ | |
| 166 | + u16 mute_reg = snd_soc_component_read32(component, | |
| 167 | + SGTL5000_CHIP_ANA_CTRL); | |
| 168 | + | |
| 169 | + snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, | |
| 170 | + mute_mask, mute_mask); | |
| 171 | + return mute_reg; | |
| 172 | +} | |
| 173 | + | |
| 174 | +static inline void restore_output(struct snd_soc_component *component, | |
| 175 | + u16 mute_mask, u16 mute_reg) | |
| 176 | +{ | |
| 177 | + snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, | |
| 178 | + mute_mask, mute_reg); | |
| 179 | +} | |
| 180 | + | |
| 181 | +static void vag_power_on(struct snd_soc_component *component, u32 source) | |
| 182 | +{ | |
| 183 | + if (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) & | |
| 184 | + SGTL5000_VAG_POWERUP) | |
| 185 | + return; | |
| 186 | + | |
| 187 | + snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | |
| 188 | + SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); | |
| 189 | + | |
| 190 | + /* When VAG powering on to get local loop from Line-In, the sleep | |
| 191 | + * is required to avoid loud pop. | |
| 192 | + */ | |
| 193 | + if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN && | |
| 194 | + source == HP_POWER_EVENT) | |
| 195 | + msleep(SGTL5000_VAG_POWERUP_DELAY); | |
| 196 | +} | |
| 197 | + | |
| 198 | +static int vag_power_consumers(struct snd_soc_component *component, | |
| 199 | + u16 ana_pwr_reg, u32 source) | |
| 200 | +{ | |
| 201 | + int consumers = 0; | |
| 202 | + | |
| 203 | + /* count dac/adc consumers unconditional */ | |
| 204 | + if (ana_pwr_reg & SGTL5000_DAC_POWERUP) | |
| 205 | + consumers++; | |
| 206 | + if (ana_pwr_reg & SGTL5000_ADC_POWERUP) | |
| 207 | + consumers++; | |
| 208 | + | |
| 209 | + /* | |
| 210 | + * If the event comes from HP and Line-In is selected, | |
| 211 | + * current action is 'DAC to be powered down'. | |
| 212 | + * As HP_POWERUP is not set when HP muxed to line-in, | |
| 213 | + * we need to keep VAG power ON. | |
| 214 | + */ | |
| 215 | + if (source == HP_POWER_EVENT) { | |
| 216 | + if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN) | |
| 217 | + consumers++; | |
| 218 | + } else { | |
| 219 | + if (ana_pwr_reg & SGTL5000_HP_POWERUP) | |
| 220 | + consumers++; | |
| 221 | + } | |
| 222 | + | |
| 223 | + return consumers; | |
| 224 | +} | |
| 225 | + | |
| 226 | +static void vag_power_off(struct snd_soc_component *component, u32 source) | |
| 227 | +{ | |
| 228 | + u16 ana_pwr = snd_soc_component_read32(component, | |
| 229 | + SGTL5000_CHIP_ANA_POWER); | |
| 230 | + | |
| 231 | + if (!(ana_pwr & SGTL5000_VAG_POWERUP)) | |
| 232 | + return; | |
| 233 | + | |
| 234 | + /* | |
| 235 | + * This function calls when any of VAG power consumers is disappearing. | |
| 236 | + * Thus, if there is more than one consumer at the moment, as minimum | |
| 237 | + * one consumer will definitely stay after the end of the current | |
| 238 | + * event. | |
| 239 | + * Don't clear VAG_POWERUP if 2 or more consumers of VAG present: | |
| 240 | + * - LINE_IN (for HP events) / HP (for DAC/ADC events) | |
| 241 | + * - DAC | |
| 242 | + * - ADC | |
| 243 | + * (the current consumer is disappearing right now) | |
| 244 | + */ | |
| 245 | + if (vag_power_consumers(component, ana_pwr, source) >= 2) | |
| 246 | + return; | |
| 247 | + | |
| 248 | + snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | |
| 249 | + SGTL5000_VAG_POWERUP, 0); | |
| 250 | + /* In power down case, we need wait 400-1000 ms | |
| 251 | + * when VAG fully ramped down. | |
| 252 | + * As longer we wait, as smaller pop we've got. | |
| 253 | + */ | |
| 254 | + msleep(SGTL5000_VAG_POWERDOWN_DELAY); | |
| 255 | +} | |
| 256 | + | |
| 142 | 257 | /* |
| 143 | 258 | * mic_bias power on/off share the same register bits with |
| 144 | 259 | * output impedance of mic bias, when power on mic bias, we |
| @@ -170,36 +285,46 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, · 25 unmodified lines | ||
| 170 | 285 | return 0; |
| 171 | 286 | } |
| 172 | 287 | |
| 173 | −/* | |
| 174 | − * As manual described, ADC/DAC only works when VAG powerup, | |
| 175 | − * So enabled VAG before ADC/DAC up. | |
| 176 | − * In power down case, we need wait 400ms when vag fully ramped down. | |
| 177 | − */ | |
| 178 | −static int power_vag_event(struct snd_soc_dapm_widget *w, | |
| 179 | − struct snd_kcontrol *kcontrol, int event) | |
| 288 | +static int vag_and_mute_control(struct snd_soc_component *component, | |
| 289 | + int event, int event_source) | |
| 180 | 290 | { |
| 181 | − struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | |
| 182 | − const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP; | |
| 291 | + static const u16 mute_mask[] = { | |
| 292 | + /* | |
| 293 | + * Mask for HP_POWER_EVENT. | |
| 294 | + * Muxing Headphones have to be wrapped with mute/unmute | |
| 295 | + * headphones only. | |
| 296 | + */ | |
| 297 | + SGTL5000_HP_MUTE, | |
| 298 | + /* | |
| 299 | + * Masks for DAC_POWER_EVENT/ADC_POWER_EVENT. | |
| 300 | + * Muxing DAC or ADC block have to wrapped with mute/unmute | |
| 301 | + * both headphones and line-out. | |
| 302 | + */ | |
| 303 | + SGTL5000_OUTPUTS_MUTE, | |
| 304 | + SGTL5000_OUTPUTS_MUTE | |
| 305 | + }; | |
| 306 | + | |
| 307 | + struct sgtl5000_priv *sgtl5000 = | |
| 308 | + snd_soc_component_get_drvdata(component); | |
| 183 | 309 | |
| 184 | 310 | switch (event) { |
| 311 | + case SND_SOC_DAPM_PRE_PMU: | |
| 312 | + sgtl5000->mute_state[event_source] = | |
| 313 | + mute_output(component, mute_mask[event_source]); | |
| 314 | + break; | |
| 185 | 315 | case SND_SOC_DAPM_POST_PMU: |
| 186 | − snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | |
| 187 | − SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); | |
| 188 | − msleep(400); | |
| 316 | + vag_power_on(component, event_source); | |
| 317 | + restore_output(component, mute_mask[event_source], | |
| 318 | + sgtl5000->mute_state[event_source]); | |
| 189 | 319 | break; |
| 190 | − | |
| 191 | 320 | case SND_SOC_DAPM_PRE_PMD: |
| 192 | − /* | |
| 193 | − * Don't clear VAG_POWERUP, when both DAC and ADC are | |
| 194 | − * operational to prevent inadvertently starving the | |
| 195 | − * other one of them. | |
| 196 | − */ | |
| 197 | − if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) & | |
| 198 | − mask) != mask) { | |
| 199 | − snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | |
| 200 | − SGTL5000_VAG_POWERUP, 0); | |
| 201 | − msleep(400); | |
| 202 | − } | |
| 321 | + sgtl5000->mute_state[event_source] = | |
| 322 | + mute_output(component, mute_mask[event_source]); | |
| 323 | + vag_power_off(component, event_source); | |
| 324 | + break; | |
| 325 | + case SND_SOC_DAPM_POST_PMD: | |
| 326 | + restore_output(component, mute_mask[event_source], | |
| 327 | + sgtl5000->mute_state[event_source]); | |
| 203 | 328 | break; |
| 204 | 329 | default: |
| 205 | 330 | break; |
| @@ -208,6 +333,41 @@ static int power_vag_event(struct snd_soc_dapm_widget *w, · 2 unmodified lines | ||
| 208 | 333 | return 0; |
| 209 | 334 | } |
| 210 | 335 | |
| 336 | +/* | |
| 337 | + * Mute Headphone when power it up/down. | |
| 338 | + * Control VAG power on HP power path. | |
| 339 | + */ | |
| 340 | +static int headphone_pga_event(struct snd_soc_dapm_widget *w, | |
| 341 | + struct snd_kcontrol *kcontrol, int event) | |
| 342 | +{ | |
| 343 | + struct snd_soc_component *component = | |
| 344 | + snd_soc_dapm_to_component(w->dapm); | |
| 345 | + | |
| 346 | + return vag_and_mute_control(component, event, HP_POWER_EVENT); | |
| 347 | +} | |
| 348 | + | |
| 349 | +/* As manual describes, ADC/DAC powering up/down requires | |
| 350 | + * to mute outputs to avoid pops. | |
| 351 | + * Control VAG power on ADC/DAC power path. | |
| 352 | + */ | |
| 353 | +static int adc_updown_depop(struct snd_soc_dapm_widget *w, | |
| 354 | + struct snd_kcontrol *kcontrol, int event) | |
| 355 | +{ | |
| 356 | + struct snd_soc_component *component = | |
| 357 | + snd_soc_dapm_to_component(w->dapm); | |
| 358 | + | |
| 359 | + return vag_and_mute_control(component, event, ADC_POWER_EVENT); | |
| 360 | +} | |
| 361 | + | |
| 362 | +static int dac_updown_depop(struct snd_soc_dapm_widget *w, | |
| 363 | + struct snd_kcontrol *kcontrol, int event) | |
| 364 | +{ | |
| 365 | + struct snd_soc_component *component = | |
| 366 | + snd_soc_dapm_to_component(w->dapm); | |
| 367 | + | |
| 368 | + return vag_and_mute_control(component, event, DAC_POWER_EVENT); | |
| 369 | +} | |
| 370 | + | |
| 211 | 371 | /* input sources for ADC */ |
| 212 | 372 | static const char *adc_mux_text[] = { |
| 213 | 373 | "MIC_IN", "LINE_IN" |
| @@ -280,7 +440,10 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { · 66 unmodified lines | ||
| 280 | 440 | mic_bias_event, |
| 281 | 441 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 282 | 442 | |
| 283 | − SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0), | |
| 443 | + SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0, | |
| 444 | + headphone_pga_event, | |
| 445 | + SND_SOC_DAPM_PRE_POST_PMU | | |
| 446 | + SND_SOC_DAPM_PRE_POST_PMD), | |
| 284 | 447 | SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), |
| 285 | 448 | |
| 286 | 449 | SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux), |
| @@ -301,11 +464,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { · 14 unmodified lines | ||
| 301 | 464 | 0, SGTL5000_CHIP_DIG_POWER, |
| 302 | 465 | 1, 0), |
| 303 | 466 | |
| 304 | − SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), | |
| 305 | − SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), | |
| 306 | − | |
| 307 | − SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event), | |
| 308 | − SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event), | |
| 467 | + SND_SOC_DAPM_ADC_E("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0, | |
| 468 | + adc_updown_depop, SND_SOC_DAPM_PRE_POST_PMU | | |
| 469 | + SND_SOC_DAPM_PRE_POST_PMD), | |
| 470 | + SND_SOC_DAPM_DAC_E("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0, | |
| 471 | + dac_updown_depop, SND_SOC_DAPM_PRE_POST_PMU | | |
| 472 | + SND_SOC_DAPM_PRE_POST_PMD), | |
| 309 | 473 | }; |
| 310 | 474 | |
| 311 | 475 | /* routes for sgtl5000 */ |
| @@ -556,6 +720,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { · 244 unmodified lines | ||
| 556 | 720 | SGTL5000_CHIP_ANA_ADC_CTRL, |
| 557 | 721 | 8, 1, 0, capture_6db_attenuate), |
| 558 | 722 | SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0), |
| 723 | + SOC_SINGLE("Capture Switch", SGTL5000_CHIP_ANA_CTRL, 0, 1, 1), | |
| 559 | 724 | |
| 560 | 725 | SOC_DOUBLE_TLV("Headphone Playback Volume", |
| 561 | 726 | SGTL5000_CHIP_ANA_HP_CTRL, |
| @@ -1173,12 +1338,17 @@ static int sgtl5000_set_power_regs(struct snd_soc_component *component) · 611 unmodified lines | ||
| 1173 | 1338 | SGTL5000_INT_OSC_EN); |
| 1174 | 1339 | /* Enable VDDC charge pump */ |
| 1175 | 1340 | ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; |
| 1176 | − } else if (vddio >= 3100 && vdda >= 3100) { | |
| 1341 | + } else { | |
| 1177 | 1342 | ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; |
| 1178 | − /* VDDC use VDDIO rail */ | |
| 1179 | − lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; | |
| 1180 | − lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << | |
| 1181 | − SGTL5000_VDDC_MAN_ASSN_SHIFT; | |
| 1343 | + /* | |
| 1344 | + * if vddio == vdda the source of charge pump should be | |
| 1345 | + * assigned manually to VDDIO | |
| 1346 | + */ | |
| 1347 | + if (vddio == vdda) { | |
| 1348 | + lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; | |
| 1349 | + lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << | |
| 1350 | + SGTL5000_VDDC_MAN_ASSN_SHIFT; | |
| 1351 | + } | |
| 1182 | 1352 | } |
| 1183 | 1353 | |
| 1184 | 1354 | snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl); |
| @@ -1288,6 +1458,7 @@ static int sgtl5000_probe(struct snd_soc_component *component) · 103 unmodified lines | ||
| 1288 | 1458 | int ret; |
| 1289 | 1459 | u16 reg; |
| 1290 | 1460 | struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component); |
| 1461 | + unsigned int zcd_mask = SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN; | |
| 1291 | 1462 | |
| 1292 | 1463 | /* power up sgtl5000 */ |
| 1293 | 1464 | ret = sgtl5000_set_power_regs(component); |
| @@ -1296,7 +1467,7 @@ static int sgtl5000_probe(struct snd_soc_component *component) · 2 unmodified lines | ||
| 1296 | 1467 | |
| 1297 | 1468 | /* enable small pop, introduce 400ms delay in turning off */ |
| 1298 | 1469 | snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL, |
| 1299 | − SGTL5000_SMALL_POP, 1); | |
| 1470 | + SGTL5000_SMALL_POP, SGTL5000_SMALL_POP); | |
| 1300 | 1471 | |
| 1301 | 1472 | /* disable short cut detector */ |
| 1302 | 1473 | snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0); |
| @@ -1315,9 +1486,8 @@ static int sgtl5000_probe(struct snd_soc_component *component) · 12 unmodified lines | ||
| 1315 | 1486 | 0x1f); |
| 1316 | 1487 | snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg); |
| 1317 | 1488 | |
| 1318 | − snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL, | |
| 1319 | − SGTL5000_HP_ZCD_EN | | |
| 1320 | − SGTL5000_ADC_ZCD_EN); | |
| 1489 | + snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, | |
| 1490 | + zcd_mask, zcd_mask); | |
| 1321 | 1491 | |
| 1322 | 1492 | snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL, |
| 1323 | 1493 | SGTL5000_BIAS_R_MASK, |
| @@ -273,7 +273,7 @@ · 272 unmodified lines | ||
| 273 | 273 | #define SGTL5000_BIAS_CTRL_MASK 0x000e |
| 274 | 274 | #define SGTL5000_BIAS_CTRL_SHIFT 1 |
| 275 | 275 | #define SGTL5000_BIAS_CTRL_WIDTH 3 |
| 276 | −#define SGTL5000_SMALL_POP 1 | |
| 276 | +#define SGTL5000_SMALL_POP 0x0001 | |
| 277 | 277 | |
| 278 | 278 | /* |
| 279 | 279 | * SGTL5000_CHIP_MIC_CTRL |
| @@ -459,7 +459,6 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev) · 458 unmodified lines | ||
| 459 | 459 | int ret; |
| 460 | 460 | struct sirf_audio_codec *sirf_audio_codec; |
| 461 | 461 | void __iomem *base; |
| 462 | − struct resource *mem_res; | |
| 463 | 462 | |
| 464 | 463 | sirf_audio_codec = devm_kzalloc(&pdev->dev, |
| 465 | 464 | sizeof(struct sirf_audio_codec), GFP_KERNEL); |
| @@ -468,8 +467,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 468 | 467 | |
| 469 | 468 | platform_set_drvdata(pdev, sirf_audio_codec); |
| 470 | 469 | |
| 471 | − mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 472 | − base = devm_ioremap_resource(&pdev->dev, mem_res); | |
| 470 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 473 | 471 | if (IS_ERR(base)) |
| 474 | 472 | return PTR_ERR(base); |
| 475 | 473 | |
| @@ -67,8 +67,6 @@ static SOC_ENUM_SINGLE_DECL(rec_src_enum, · 66 unmodified lines | ||
| 67 | 67 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = |
| 68 | 68 | SOC_DAPM_ENUM("Input Select", rec_src_enum); |
| 69 | 69 | |
| 70 | −static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src, | |
| 71 | − TLV320AIC23_ANLG, 2, rec_src_text); | |
| 72 | 70 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, |
| 73 | 71 | TLV320AIC23_DIGT, 1, deemph_text); |
| 74 | 72 | |
| @@ -258,7 +258,6 @@ static SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, · 257 unmodified lines | ||
| 258 | 258 | static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, |
| 259 | 259 | mic_select_text); |
| 260 | 260 | |
| 261 | −static SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text); | |
| 262 | 261 | static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, |
| 263 | 262 | mic_select_text); |
| 264 | 263 | |
| @@ -1553,7 +1552,8 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, · 1288 unmodified lines | ||
| 1553 | 1552 | aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset", |
| 1554 | 1553 | GPIOD_OUT_LOW); |
| 1555 | 1554 | if (IS_ERR(aic31xx->gpio_reset)) { |
| 1556 | − dev_err(aic31xx->dev, "not able to acquire gpio\n"); | |
| 1555 | + if (PTR_ERR(aic31xx->gpio_reset) != -EPROBE_DEFER) | |
| 1556 | + dev_err(aic31xx->dev, "not able to acquire gpio\n"); | |
| 1557 | 1557 | return PTR_ERR(aic31xx->gpio_reset); |
| 1558 | 1558 | } |
| 1559 | 1559 | |
| @@ -1564,7 +1564,9 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, · 4 unmodified lines | ||
| 1564 | 1564 | ARRAY_SIZE(aic31xx->supplies), |
| 1565 | 1565 | aic31xx->supplies); |
| 1566 | 1566 | if (ret) { |
| 1567 | − dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); | |
| 1567 | + if (ret != -EPROBE_DEFER) | |
| 1568 | + dev_err(aic31xx->dev, | |
| 1569 | + "Failed to request supplies: %d\n", ret); | |
| 1568 | 1570 | return ret; |
| 1569 | 1571 | } |
| 1570 | 1572 | |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include "tscs454.h" |
| 24 | 24 | |
| 25 | −static const unsigned int PLL_48K_RATE = (48000 * 256); | |
| 26 | 25 | static const unsigned int PLL_44_1K_RATE = (44100 * 256); |
| 27 | 26 | |
| 28 | 27 | #define COEFF_SIZE 3 |
| @@ -1108,10 +1108,8 @@ static int twl6040_probe(struct snd_soc_component *component) · 1107 unmodified lines | ||
| 1108 | 1108 | priv->component = component; |
| 1109 | 1109 | |
| 1110 | 1110 | priv->plug_irq = platform_get_irq(pdev, 0); |
| 1111 | − if (priv->plug_irq < 0) { | |
| 1112 | − dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq); | |
| 1111 | + if (priv->plug_irq < 0) | |
| 1113 | 1112 | return priv->plug_irq; |
| 1114 | − } | |
| 1115 | 1113 | |
| 1116 | 1114 | INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); |
| 1117 | 1115 | |
| @@ -0,0 +1,295 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +// | |
| 3 | +// uda1334.c -- UDA1334 ALSA SoC Audio driver | |
| 4 | +// | |
| 5 | +// Based on WM8523 ALSA SoC Audio driver written by Mark Brown | |
| 6 | + | |
| 7 | +#include <linux/module.h> | |
| 8 | +#include <linux/moduleparam.h> | |
| 9 | +#include <linux/init.h> | |
| 10 | +#include <linux/delay.h> | |
| 11 | +#include <linux/slab.h> | |
| 12 | +#include <linux/gpio/consumer.h> | |
| 13 | +#include <linux/of_device.h> | |
| 14 | +#include <sound/core.h> | |
| 15 | +#include <sound/pcm.h> | |
| 16 | +#include <sound/pcm_params.h> | |
| 17 | +#include <sound/soc.h> | |
| 18 | +#include <sound/initval.h> | |
| 19 | + | |
| 20 | +#define UDA1334_NUM_RATES 6 | |
| 21 | + | |
| 22 | +/* codec private data */ | |
| 23 | +struct uda1334_priv { | |
| 24 | + struct gpio_desc *mute; | |
| 25 | + struct gpio_desc *deemph; | |
| 26 | + unsigned int sysclk; | |
| 27 | + unsigned int rate_constraint_list[UDA1334_NUM_RATES]; | |
| 28 | + struct snd_pcm_hw_constraint_list rate_constraint; | |
| 29 | +}; | |
| 30 | + | |
| 31 | +static const struct snd_soc_dapm_widget uda1334_dapm_widgets[] = { | |
| 32 | +SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), | |
| 33 | +SND_SOC_DAPM_OUTPUT("LINEVOUTL"), | |
| 34 | +SND_SOC_DAPM_OUTPUT("LINEVOUTR"), | |
| 35 | +}; | |
| 36 | + | |
| 37 | +static const struct snd_soc_dapm_route uda1334_dapm_routes[] = { | |
| 38 | + { "LINEVOUTL", NULL, "DAC" }, | |
| 39 | + { "LINEVOUTR", NULL, "DAC" }, | |
| 40 | +}; | |
| 41 | + | |
| 42 | +static int uda1334_put_deemph(struct snd_kcontrol *kcontrol, | |
| 43 | + struct snd_ctl_elem_value *ucontrol) | |
| 44 | +{ | |
| 45 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | |
| 46 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 47 | + int deemph = ucontrol->value.integer.value[0]; | |
| 48 | + | |
| 49 | + if (deemph > 1) | |
| 50 | + return -EINVAL; | |
| 51 | + | |
| 52 | + gpiod_set_value_cansleep(uda1334->deemph, deemph); | |
| 53 | + | |
| 54 | + return 0; | |
| 55 | +}; | |
| 56 | + | |
| 57 | +static int uda1334_get_deemph(struct snd_kcontrol *kcontrol, | |
| 58 | + struct snd_ctl_elem_value *ucontrol) | |
| 59 | +{ | |
| 60 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | |
| 61 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 62 | + int ret; | |
| 63 | + | |
| 64 | + ret = gpiod_get_value_cansleep(uda1334->deemph); | |
| 65 | + if (ret < 0) | |
| 66 | + return -EINVAL; | |
| 67 | + | |
| 68 | + ucontrol->value.integer.value[0] = ret; | |
| 69 | + | |
| 70 | + return 0; | |
| 71 | +}; | |
| 72 | + | |
| 73 | +static const struct snd_kcontrol_new uda1334_snd_controls[] = { | |
| 74 | + SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, | |
| 75 | + uda1334_get_deemph, uda1334_put_deemph), | |
| 76 | +}; | |
| 77 | + | |
| 78 | +static const struct { | |
| 79 | + int value; | |
| 80 | + int ratio; | |
| 81 | +} lrclk_ratios[UDA1334_NUM_RATES] = { | |
| 82 | + { 1, 128 }, | |
| 83 | + { 2, 192 }, | |
| 84 | + { 3, 256 }, | |
| 85 | + { 4, 384 }, | |
| 86 | + { 5, 512 }, | |
| 87 | + { 6, 768 }, | |
| 88 | +}; | |
| 89 | + | |
| 90 | +static int uda1334_startup(struct snd_pcm_substream *substream, | |
| 91 | + struct snd_soc_dai *dai) | |
| 92 | +{ | |
| 93 | + struct snd_soc_component *component = dai->component; | |
| 94 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 95 | + | |
| 96 | + /* | |
| 97 | + * The set of sample rates that can be supported depends on the | |
| 98 | + * MCLK supplied to the CODEC - enforce this. | |
| 99 | + */ | |
| 100 | + if (!uda1334->sysclk) { | |
| 101 | + dev_err(component->dev, | |
| 102 | + "No MCLK configured, call set_sysclk() on init\n"); | |
| 103 | + return -EINVAL; | |
| 104 | + } | |
| 105 | + | |
| 106 | + snd_pcm_hw_constraint_list(substream->runtime, 0, | |
| 107 | + SNDRV_PCM_HW_PARAM_RATE, | |
| 108 | + &uda1334->rate_constraint); | |
| 109 | + | |
| 110 | + gpiod_set_value_cansleep(uda1334->mute, 1); | |
| 111 | + | |
| 112 | + return 0; | |
| 113 | +} | |
| 114 | + | |
| 115 | +static void uda1334_shutdown(struct snd_pcm_substream *substream, | |
| 116 | + struct snd_soc_dai *dai) | |
| 117 | +{ | |
| 118 | + struct snd_soc_component *component = dai->component; | |
| 119 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 120 | + | |
| 121 | + gpiod_set_value_cansleep(uda1334->mute, 0); | |
| 122 | +} | |
| 123 | + | |
| 124 | +static int uda1334_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |
| 125 | + int clk_id, unsigned int freq, int dir) | |
| 126 | +{ | |
| 127 | + struct snd_soc_component *component = codec_dai->component; | |
| 128 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 129 | + unsigned int val; | |
| 130 | + int i, j = 0; | |
| 131 | + | |
| 132 | + uda1334->sysclk = freq; | |
| 133 | + | |
| 134 | + uda1334->rate_constraint.count = 0; | |
| 135 | + for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { | |
| 136 | + val = freq / lrclk_ratios[i].ratio; | |
| 137 | + /* | |
| 138 | + * Check that it's a standard rate since core can't | |
| 139 | + * cope with others and having the odd rates confuses | |
| 140 | + * constraint matching. | |
| 141 | + */ | |
| 142 | + | |
| 143 | + switch (val) { | |
| 144 | + case 8000: | |
| 145 | + case 32000: | |
| 146 | + case 44100: | |
| 147 | + case 48000: | |
| 148 | + case 64000: | |
| 149 | + case 88200: | |
| 150 | + case 96000: | |
| 151 | + dev_dbg(component->dev, "Supported sample rate: %dHz\n", | |
| 152 | + val); | |
| 153 | + uda1334->rate_constraint_list[j++] = val; | |
| 154 | + uda1334->rate_constraint.count++; | |
| 155 | + break; | |
| 156 | + default: | |
| 157 | + dev_dbg(component->dev, "Skipping sample rate: %dHz\n", | |
| 158 | + val); | |
| 159 | + } | |
| 160 | + } | |
| 161 | + | |
| 162 | + /* Need at least one supported rate... */ | |
| 163 | + if (uda1334->rate_constraint.count == 0) | |
| 164 | + return -EINVAL; | |
| 165 | + | |
| 166 | + return 0; | |
| 167 | +} | |
| 168 | + | |
| 169 | +static int uda1334_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |
| 170 | +{ | |
| 171 | + fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | | |
| 172 | + SND_SOC_DAIFMT_MASTER_MASK); | |
| 173 | + | |
| 174 | + if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | |
| 175 | + SND_SOC_DAIFMT_CBS_CFS)) { | |
| 176 | + dev_err(codec_dai->dev, "Invalid DAI format\n"); | |
| 177 | + return -EINVAL; | |
| 178 | + } | |
| 179 | + | |
| 180 | + return 0; | |
| 181 | +} | |
| 182 | + | |
| 183 | +static int uda1334_mute_stream(struct snd_soc_dai *dai, int mute, int stream) | |
| 184 | +{ | |
| 185 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(dai->component); | |
| 186 | + | |
| 187 | + if (uda1334->mute) | |
| 188 | + gpiod_set_value_cansleep(uda1334->mute, mute); | |
| 189 | + | |
| 190 | + return 0; | |
| 191 | +} | |
| 192 | + | |
| 193 | +#define UDA1334_RATES SNDRV_PCM_RATE_8000_96000 | |
| 194 | + | |
| 195 | +#define UDA1334_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | |
| 196 | + | |
| 197 | +static const struct snd_soc_dai_ops uda1334_dai_ops = { | |
| 198 | + .startup = uda1334_startup, | |
| 199 | + .shutdown = uda1334_shutdown, | |
| 200 | + .set_sysclk = uda1334_set_dai_sysclk, | |
| 201 | + .set_fmt = uda1334_set_fmt, | |
| 202 | + .mute_stream = uda1334_mute_stream, | |
| 203 | +}; | |
| 204 | + | |
| 205 | +static struct snd_soc_dai_driver uda1334_dai = { | |
| 206 | + .name = "uda1334-hifi", | |
| 207 | + .playback = { | |
| 208 | + .stream_name = "Playback", | |
| 209 | + .channels_min = 2, | |
| 210 | + .channels_max = 2, | |
| 211 | + .rates = UDA1334_RATES, | |
| 212 | + .formats = UDA1334_FORMATS, | |
| 213 | + }, | |
| 214 | + .ops = &uda1334_dai_ops, | |
| 215 | +}; | |
| 216 | + | |
| 217 | +static int uda1334_probe(struct snd_soc_component *component) | |
| 218 | +{ | |
| 219 | + struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component); | |
| 220 | + | |
| 221 | + uda1334->rate_constraint.list = &uda1334->rate_constraint_list[0]; | |
| 222 | + uda1334->rate_constraint.count = | |
| 223 | + ARRAY_SIZE(uda1334->rate_constraint_list); | |
| 224 | + | |
| 225 | + return 0; | |
| 226 | +} | |
| 227 | + | |
| 228 | +static const struct snd_soc_component_driver soc_component_dev_uda1334 = { | |
| 229 | + .probe = uda1334_probe, | |
| 230 | + .controls = uda1334_snd_controls, | |
| 231 | + .num_controls = ARRAY_SIZE(uda1334_snd_controls), | |
| 232 | + .dapm_widgets = uda1334_dapm_widgets, | |
| 233 | + .num_dapm_widgets = ARRAY_SIZE(uda1334_dapm_widgets), | |
| 234 | + .dapm_routes = uda1334_dapm_routes, | |
| 235 | + .num_dapm_routes = ARRAY_SIZE(uda1334_dapm_routes), | |
| 236 | + .idle_bias_on = 1, | |
| 237 | + .use_pmdown_time = 1, | |
| 238 | + .endianness = 1, | |
| 239 | + .non_legacy_dai_naming = 1, | |
| 240 | +}; | |
| 241 | + | |
| 242 | +static const struct of_device_id uda1334_of_match[] = { | |
| 243 | + { .compatible = "nxp,uda1334" }, | |
| 244 | + { /* sentinel*/ } | |
| 245 | +}; | |
| 246 | +MODULE_DEVICE_TABLE(of, uda1334_of_match); | |
| 247 | + | |
| 248 | +static int uda1334_codec_probe(struct platform_device *pdev) | |
| 249 | +{ | |
| 250 | + struct uda1334_priv *uda1334; | |
| 251 | + int ret; | |
| 252 | + | |
| 253 | + uda1334 = devm_kzalloc(&pdev->dev, sizeof(struct uda1334_priv), | |
| 254 | + GFP_KERNEL); | |
| 255 | + if (!uda1334) | |
| 256 | + return -ENOMEM; | |
| 257 | + | |
| 258 | + platform_set_drvdata(pdev, uda1334); | |
| 259 | + | |
| 260 | + uda1334->mute = devm_gpiod_get(&pdev->dev, "nxp,mute", GPIOD_OUT_LOW); | |
| 261 | + if (IS_ERR(uda1334->mute)) { | |
| 262 | + ret = PTR_ERR(uda1334->mute); | |
| 263 | + dev_err(&pdev->dev, "Failed to get mute line: %d\n", ret); | |
| 264 | + return ret; | |
| 265 | + } | |
| 266 | + | |
| 267 | + uda1334->deemph = devm_gpiod_get(&pdev->dev, "nxp,deemph", GPIOD_OUT_LOW); | |
| 268 | + if (IS_ERR(uda1334->deemph)) { | |
| 269 | + ret = PTR_ERR(uda1334->deemph); | |
| 270 | + dev_err(&pdev->dev, "Failed to get deemph line: %d\n", ret); | |
| 271 | + return ret; | |
| 272 | + } | |
| 273 | + | |
| 274 | + ret = devm_snd_soc_register_component(&pdev->dev, | |
| 275 | + &soc_component_dev_uda1334, | |
| 276 | + &uda1334_dai, 1); | |
| 277 | + if (ret < 0) | |
| 278 | + dev_err(&pdev->dev, "Failed to register component: %d\n", ret); | |
| 279 | + | |
| 280 | + return ret; | |
| 281 | +} | |
| 282 | + | |
| 283 | +static struct platform_driver uda1334_codec_driver = { | |
| 284 | + .probe = uda1334_codec_probe, | |
| 285 | + .driver = { | |
| 286 | + .name = "uda1334-codec", | |
| 287 | + .of_match_table = uda1334_of_match, | |
| 288 | + }, | |
| 289 | +}; | |
| 290 | +module_platform_driver(uda1334_codec_driver); | |
| 291 | + | |
| 292 | +MODULE_DESCRIPTION("ASoC UDA1334 driver"); | |
| 293 | +MODULE_AUTHOR("Andra Danciu <andradanciu1997@gmail.com>"); | |
| 294 | +MODULE_ALIAS("platform:uda1334-codec"); | |
| 295 | +MODULE_LICENSE("GPL v2"); | |
| @@ -65,7 +65,7 @@ struct wcd_clsh_ctrl { · 64 unmodified lines | ||
| 65 | 65 | #define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0 |
| 66 | 66 | #define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7) |
| 67 | 67 | #define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK GENMASK(7, 4) |
| 68 | −#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(0, 3) | |
| 68 | +#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(3, 0) | |
| 69 | 69 | #define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3) |
| 70 | 70 | #define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3) |
| 71 | 71 | #define WCD9XXX_HPH_CONST_SEL_BYPASS 0 |
| @@ -2071,9 +2071,10 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 2070 unmodified lines | ||
| 2071 | 2071 | .id = AIF1_PB, |
| 2072 | 2072 | .playback = { |
| 2073 | 2073 | .stream_name = "AIF1 Playback", |
| 2074 | − .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, | |
| 2074 | + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | | |
| 2075 | + SNDRV_PCM_RATE_384000, | |
| 2075 | 2076 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2076 | − .rate_max = 192000, | |
| 2077 | + .rate_max = 384000, | |
| 2077 | 2078 | .rate_min = 8000, |
| 2078 | 2079 | .channels_min = 1, |
| 2079 | 2080 | .channels_max = 2, |
| @@ -2099,10 +2100,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 19 unmodified lines | ||
| 2099 | 2100 | .id = AIF2_PB, |
| 2100 | 2101 | .playback = { |
| 2101 | 2102 | .stream_name = "AIF2 Playback", |
| 2102 | − .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, | |
| 2103 | + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | | |
| 2104 | + SNDRV_PCM_RATE_384000, | |
| 2103 | 2105 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2104 | 2106 | .rate_min = 8000, |
| 2105 | − .rate_max = 192000, | |
| 2107 | + .rate_max = 384000, | |
| 2106 | 2108 | .channels_min = 1, |
| 2107 | 2109 | .channels_max = 2, |
| 2108 | 2110 | }, |
| @@ -2127,10 +2129,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 18 unmodified lines | ||
| 2127 | 2129 | .id = AIF3_PB, |
| 2128 | 2130 | .playback = { |
| 2129 | 2131 | .stream_name = "AIF3 Playback", |
| 2130 | − .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, | |
| 2132 | + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | | |
| 2133 | + SNDRV_PCM_RATE_384000, | |
| 2131 | 2134 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2132 | 2135 | .rate_min = 8000, |
| 2133 | − .rate_max = 192000, | |
| 2136 | + .rate_max = 384000, | |
| 2134 | 2137 | .channels_min = 1, |
| 2135 | 2138 | .channels_max = 2, |
| 2136 | 2139 | }, |
| @@ -2155,10 +2158,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 18 unmodified lines | ||
| 2155 | 2158 | .id = AIF4_PB, |
| 2156 | 2159 | .playback = { |
| 2157 | 2160 | .stream_name = "AIF4 Playback", |
| 2158 | − .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, | |
| 2161 | + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | | |
| 2162 | + SNDRV_PCM_RATE_384000, | |
| 2159 | 2163 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2160 | 2164 | .rate_min = 8000, |
| 2161 | − .rate_max = 192000, | |
| 2165 | + .rate_max = 384000, | |
| 2162 | 2166 | .channels_min = 1, |
| 2163 | 2167 | .channels_max = 2, |
| 2164 | 2168 | }, |
| @@ -4062,7 +4066,8 @@ static int wcd9335_setup_irqs(struct wcd9335_codec *wcd) · 1897 unmodified lines | ||
| 4062 | 4066 | |
| 4063 | 4067 | ret = devm_request_threaded_irq(wcd->dev, irq, NULL, |
| 4064 | 4068 | wcd9335_irqs[i].handler, |
| 4065 | − IRQF_TRIGGER_RISING, | |
| 4069 | + IRQF_TRIGGER_RISING | | |
| 4070 | + IRQF_ONESHOT, | |
| 4066 | 4071 | wcd9335_irqs[i].name, wcd); |
| 4067 | 4072 | if (ret) { |
| 4068 | 4073 | dev_err(wcd->dev, "Failed to request %s\n", |
| @@ -140,7 +140,7 @@ struct pll_factors { · 139 unmodified lines | ||
| 140 | 140 | * to allow rounding later */ |
| 141 | 141 | #define FIXED_FLL_SIZE ((1 << 22) * 10) |
| 142 | 142 | |
| 143 | −static int wm8995_pll_factors(struct device *dev, | |
| 143 | +static int wm8955_pll_factors(struct device *dev, | |
| 144 | 144 | int Fref, int Fout, struct pll_factors *pll) |
| 145 | 145 | { |
| 146 | 146 | u64 Kpart; |
| @@ -279,7 +279,7 @@ static int wm8955_configure_clocking(struct snd_soc_component *component) · 132 unmodified lines | ||
| 279 | 279 | |
| 280 | 280 | /* Use the last divider configuration we saw for the |
| 281 | 281 | * sample rate. */ |
| 282 | − ret = wm8995_pll_factors(component->dev, wm8955->mclk_rate, | |
| 282 | + ret = wm8955_pll_factors(component->dev, wm8955->mclk_rate, | |
| 283 | 283 | clock_cfgs[sr].mclk, &pll); |
| 284 | 284 | if (ret != 0) { |
| 285 | 285 | dev_err(component->dev, |
| @@ -273,7 +273,7 @@ static const struct soc_enum wm8988_rline_enum = · 272 unmodified lines | ||
| 273 | 273 | wm8988_line_texts, |
| 274 | 274 | wm8988_line_values); |
| 275 | 275 | static const struct snd_kcontrol_new wm8988_right_line_controls = |
| 276 | − SOC_DAPM_ENUM("Route", wm8988_lline_enum); | |
| 276 | + SOC_DAPM_ENUM("Route", wm8988_rline_enum); | |
| 277 | 277 | |
| 278 | 278 | /* Left Mixer */ |
| 279 | 279 | static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { |
| @@ -4242,8 +4242,9 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp) · 4241 unmodified lines | ||
| 4242 | 4242 | } |
| 4243 | 4243 | } |
| 4244 | 4244 | |
| 4245 | −irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |
| 4245 | +irqreturn_t wm_adsp2_bus_error(int irq, void *data) | |
| 4246 | 4246 | { |
| 4247 | + struct wm_adsp *dsp = (struct wm_adsp *)data; | |
| 4247 | 4248 | unsigned int val; |
| 4248 | 4249 | struct regmap *regmap = dsp->regmap; |
| 4249 | 4250 | int ret = 0; |
| @@ -4307,8 +4308,9 @@ error: · 57 unmodified lines | ||
| 4307 | 4308 | } |
| 4308 | 4309 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); |
| 4309 | 4310 | |
| 4310 | −irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp) | |
| 4311 | +irqreturn_t wm_halo_bus_error(int irq, void *data) | |
| 4311 | 4312 | { |
| 4313 | + struct wm_adsp *dsp = (struct wm_adsp *)data; | |
| 4312 | 4314 | struct regmap *regmap = dsp->regmap; |
| 4313 | 4315 | unsigned int fault[6]; |
| 4314 | 4316 | struct reg_sequence clear[] = { |
| @@ -171,8 +171,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, · 170 unmodified lines | ||
| 171 | 171 | int wm_adsp_early_event(struct snd_soc_dapm_widget *w, |
| 172 | 172 | struct snd_kcontrol *kcontrol, int event); |
| 173 | 173 | |
| 174 | −irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp); | |
| 175 | −irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp); | |
| 174 | +irqreturn_t wm_adsp2_bus_error(int irq, void *data); | |
| 175 | +irqreturn_t wm_halo_bus_error(int irq, void *data); | |
| 176 | 176 | irqreturn_t wm_halo_wdt_expire(int irq, void *data); |
| 177 | 177 | |
| 178 | 178 | int wm_adsp_event(struct snd_soc_dapm_widget *w, |
| @@ -885,10 +885,8 @@ static int fsl_asrc_probe(struct platform_device *pdev) · 884 unmodified lines | ||
| 885 | 885 | } |
| 886 | 886 | |
| 887 | 887 | irq = platform_get_irq(pdev, 0); |
| 888 | − if (irq < 0) { | |
| 889 | − dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | |
| 888 | + if (irq < 0) | |
| 890 | 889 | return irq; |
| 891 | − } | |
| 892 | 890 | |
| 893 | 891 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, |
| 894 | 892 | dev_name(&pdev->dev), asrc_priv); |
| @@ -458,7 +458,6 @@ static int fsl_audmix_probe(struct platform_device *pdev) · 457 unmodified lines | ||
| 458 | 458 | { |
| 459 | 459 | struct device *dev = &pdev->dev; |
| 460 | 460 | struct fsl_audmix *priv; |
| 461 | − struct resource *res; | |
| 462 | 461 | const char *mdrv; |
| 463 | 462 | const struct of_device_id *of_id; |
| 464 | 463 | void __iomem *regs; |
| @@ -475,8 +474,7 @@ static int fsl_audmix_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 475 | 474 | return -ENOMEM; |
| 476 | 475 | |
| 477 | 476 | /* Get the addresses */ |
| 478 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 479 | − regs = devm_ioremap_resource(dev, res); | |
| 477 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 480 | 478 | if (IS_ERR(regs)) |
| 481 | 479 | return PTR_ERR(regs); |
| 482 | 480 | |
| @@ -32,15 +32,18 @@ · 31 unmodified lines | ||
| 32 | 32 | * @extalclk: esai clock source to derive HCK, SCK and FS |
| 33 | 33 | * @fsysclk: system clock source to derive HCK, SCK and FS |
| 34 | 34 | * @spbaclk: SPBA clock (optional, depending on SoC design) |
| 35 | + * @task: tasklet to handle the reset operation | |
| 35 | 36 | * @fifo_depth: depth of tx/rx FIFO |
| 36 | 37 | * @slot_width: width of each DAI slot |
| 37 | 38 | * @slots: number of slots |
| 39 | + * @channels: channel num for tx or rx | |
| 38 | 40 | * @hck_rate: clock rate of desired HCKx clock |
| 39 | 41 | * @sck_rate: clock rate of desired SCKx clock |
| 40 | 42 | * @hck_dir: the direction of HCKx pads |
| 41 | 43 | * @sck_div: if using PSR/PM dividers for SCKx clock |
| 42 | 44 | * @slave_mode: if fully using DAI slave mode |
| 43 | 45 | * @synchronous: if using tx/rx synchronous mode |
| 46 | + * @reset_at_xrun: flags for enable reset operaton | |
| 44 | 47 | * @name: driver name |
| 45 | 48 | */ |
| 46 | 49 | struct fsl_esai { |
| @@ -52,17 +55,20 @@ struct fsl_esai { · 5 unmodified lines | ||
| 52 | 55 | struct clk *extalclk; |
| 53 | 56 | struct clk *fsysclk; |
| 54 | 57 | struct clk *spbaclk; |
| 58 | + struct tasklet_struct task; | |
| 55 | 59 | u32 fifo_depth; |
| 56 | 60 | u32 slot_width; |
| 57 | 61 | u32 slots; |
| 58 | 62 | u32 tx_mask; |
| 59 | 63 | u32 rx_mask; |
| 64 | + u32 channels[2]; | |
| 60 | 65 | u32 hck_rate[2]; |
| 61 | 66 | u32 sck_rate[2]; |
| 62 | 67 | bool hck_dir[2]; |
| 63 | 68 | bool sck_div[2]; |
| 64 | 69 | bool slave_mode; |
| 65 | 70 | bool synchronous; |
| 71 | + bool reset_at_xrun; | |
| 66 | 72 | char name[32]; |
| 67 | 73 | }; |
| 68 | 74 | |
| @@ -71,8 +77,16 @@ static irqreturn_t esai_isr(int irq, void *devid) · 2 unmodified lines | ||
| 71 | 77 | struct fsl_esai *esai_priv = (struct fsl_esai *)devid; |
| 72 | 78 | struct platform_device *pdev = esai_priv->pdev; |
| 73 | 79 | u32 esr; |
| 80 | + u32 saisr; | |
| 74 | 81 | |
| 75 | 82 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); |
| 83 | + regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr); | |
| 84 | + | |
| 85 | + if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) && | |
| 86 | + esai_priv->reset_at_xrun) { | |
| 87 | + dev_dbg(&pdev->dev, "reset module for xrun\n"); | |
| 88 | + tasklet_schedule(&esai_priv->task); | |
| 89 | + } | |
| 76 | 90 | |
| 77 | 91 | if (esr & ESAI_ESR_TINIT_MASK) |
| 78 | 92 | dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); |
| @@ -543,64 +557,184 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, · 464 unmodified lines | ||
| 543 | 557 | return 0; |
| 544 | 558 | } |
| 545 | 559 | |
| 560 | +static int fsl_esai_hw_init(struct fsl_esai *esai_priv) | |
| 561 | +{ | |
| 562 | + struct platform_device *pdev = esai_priv->pdev; | |
| 563 | + int ret; | |
| 564 | + | |
| 565 | + /* Reset ESAI unit */ | |
| 566 | + ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, | |
| 567 | + ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK, | |
| 568 | + ESAI_ECR_ESAIEN | ESAI_ECR_ERST); | |
| 569 | + if (ret) { | |
| 570 | + dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret); | |
| 571 | + return ret; | |
| 572 | + } | |
| 573 | + | |
| 574 | + /* | |
| 575 | + * We need to enable ESAI so as to access some of its registers. | |
| 576 | + * Otherwise, we would fail to dump regmap from user space. | |
| 577 | + */ | |
| 578 | + ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, | |
| 579 | + ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK, | |
| 580 | + ESAI_ECR_ESAIEN); | |
| 581 | + if (ret) { | |
| 582 | + dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret); | |
| 583 | + return ret; | |
| 584 | + } | |
| 585 | + | |
| 586 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, | |
| 587 | + ESAI_PRRC_PDC_MASK, 0); | |
| 588 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, | |
| 589 | + ESAI_PCRC_PC_MASK, 0); | |
| 590 | + | |
| 591 | + return 0; | |
| 592 | +} | |
| 593 | + | |
| 594 | +static int fsl_esai_register_restore(struct fsl_esai *esai_priv) | |
| 595 | +{ | |
| 596 | + int ret; | |
| 597 | + | |
| 598 | + /* FIFO reset for safety */ | |
| 599 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, | |
| 600 | + ESAI_xFCR_xFR, ESAI_xFCR_xFR); | |
| 601 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, | |
| 602 | + ESAI_xFCR_xFR, ESAI_xFCR_xFR); | |
| 603 | + | |
| 604 | + regcache_mark_dirty(esai_priv->regmap); | |
| 605 | + ret = regcache_sync(esai_priv->regmap); | |
| 606 | + if (ret) | |
| 607 | + return ret; | |
| 608 | + | |
| 609 | + /* FIFO reset done */ | |
| 610 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0); | |
| 611 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0); | |
| 612 | + | |
| 613 | + return 0; | |
| 614 | +} | |
| 615 | + | |
| 616 | +static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx) | |
| 617 | +{ | |
| 618 | + u8 i, channels = esai_priv->channels[tx]; | |
| 619 | + u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | |
| 620 | + u32 mask; | |
| 621 | + | |
| 622 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 623 | + ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN); | |
| 624 | + | |
| 625 | + /* Write initial words reqiured by ESAI as normal procedure */ | |
| 626 | + for (i = 0; tx && i < channels; i++) | |
| 627 | + regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); | |
| 628 | + | |
| 629 | + /* | |
| 630 | + * When set the TE/RE in the end of enablement flow, there | |
| 631 | + * will be channel swap issue for multi data line case. | |
| 632 | + * In order to workaround this issue, we switch the bit | |
| 633 | + * enablement sequence to below sequence | |
| 634 | + * 1) clear the xSMB & xSMA: which is done in probe and | |
| 635 | + * stop state. | |
| 636 | + * 2) set TE/RE | |
| 637 | + * 3) set xSMB | |
| 638 | + * 4) set xSMA: xSMA is the last one in this flow, which | |
| 639 | + * will trigger esai to start. | |
| 640 | + */ | |
| 641 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 642 | + tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, | |
| 643 | + tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); | |
| 644 | + mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; | |
| 645 | + | |
| 646 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | |
| 647 | + ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); | |
| 648 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | |
| 649 | + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); | |
| 650 | + | |
| 651 | + /* Enable Exception interrupt */ | |
| 652 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 653 | + ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE); | |
| 654 | +} | |
| 655 | + | |
| 656 | +static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx) | |
| 657 | +{ | |
| 658 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 659 | + ESAI_xCR_xEIE_MASK, 0); | |
| 660 | + | |
| 661 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 662 | + tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); | |
| 663 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | |
| 664 | + ESAI_xSMA_xS_MASK, 0); | |
| 665 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | |
| 666 | + ESAI_xSMB_xS_MASK, 0); | |
| 667 | + | |
| 668 | + /* Disable and reset FIFO */ | |
| 669 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 670 | + ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR); | |
| 671 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 672 | + ESAI_xFCR_xFR, 0); | |
| 673 | +} | |
| 674 | + | |
| 675 | +static void fsl_esai_hw_reset(unsigned long arg) | |
| 676 | +{ | |
| 677 | + struct fsl_esai *esai_priv = (struct fsl_esai *)arg; | |
| 678 | + bool tx = true, rx = false, enabled[2]; | |
| 679 | + u32 tfcr, rfcr; | |
| 680 | + | |
| 681 | + /* Save the registers */ | |
| 682 | + regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr); | |
| 683 | + regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr); | |
| 684 | + enabled[tx] = tfcr & ESAI_xFCR_xFEN; | |
| 685 | + enabled[rx] = rfcr & ESAI_xFCR_xFEN; | |
| 686 | + | |
| 687 | + /* Stop the tx & rx */ | |
| 688 | + fsl_esai_trigger_stop(esai_priv, tx); | |
| 689 | + fsl_esai_trigger_stop(esai_priv, rx); | |
| 690 | + | |
| 691 | + /* Reset the esai, and ignore return value */ | |
| 692 | + fsl_esai_hw_init(esai_priv); | |
| 693 | + | |
| 694 | + /* Enforce ESAI personal resets for both TX and RX */ | |
| 695 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, | |
| 696 | + ESAI_xCR_xPR_MASK, ESAI_xCR_xPR); | |
| 697 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, | |
| 698 | + ESAI_xCR_xPR_MASK, ESAI_xCR_xPR); | |
| 699 | + | |
| 700 | + /* Restore registers by regcache_sync, and ignore return value */ | |
| 701 | + fsl_esai_register_restore(esai_priv); | |
| 702 | + | |
| 703 | + /* Remove ESAI personal resets by configuring PCRC and PRRC also */ | |
| 704 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, | |
| 705 | + ESAI_xCR_xPR_MASK, 0); | |
| 706 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, | |
| 707 | + ESAI_xCR_xPR_MASK, 0); | |
| 708 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, | |
| 709 | + ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO)); | |
| 710 | + regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, | |
| 711 | + ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO)); | |
| 712 | + | |
| 713 | + /* Restart tx / rx, if they already enabled */ | |
| 714 | + if (enabled[tx]) | |
| 715 | + fsl_esai_trigger_start(esai_priv, tx); | |
| 716 | + if (enabled[rx]) | |
| 717 | + fsl_esai_trigger_start(esai_priv, rx); | |
| 718 | +} | |
| 719 | + | |
| 546 | 720 | static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, |
| 547 | 721 | struct snd_soc_dai *dai) |
| 548 | 722 | { |
| 549 | 723 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
| 550 | 724 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 551 | − u8 i, channels = substream->runtime->channels; | |
| 552 | − u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | |
| 553 | − u32 mask; | |
| 725 | + | |
| 726 | + esai_priv->channels[tx] = substream->runtime->channels; | |
| 554 | 727 | |
| 555 | 728 | switch (cmd) { |
| 556 | 729 | case SNDRV_PCM_TRIGGER_START: |
| 557 | 730 | case SNDRV_PCM_TRIGGER_RESUME: |
| 558 | 731 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 559 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 560 | − ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN); | |
| 561 | − | |
| 562 | − /* Write initial words reqiured by ESAI as normal procedure */ | |
| 563 | − for (i = 0; tx && i < channels; i++) | |
| 564 | − regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); | |
| 565 | − | |
| 566 | − /* | |
| 567 | − * When set the TE/RE in the end of enablement flow, there | |
| 568 | − * will be channel swap issue for multi data line case. | |
| 569 | − * In order to workaround this issue, we switch the bit | |
| 570 | − * enablement sequence to below sequence | |
| 571 | − * 1) clear the xSMB & xSMA: which is done in probe and | |
| 572 | − * stop state. | |
| 573 | − * 2) set TE/RE | |
| 574 | − * 3) set xSMB | |
| 575 | − * 4) set xSMA: xSMA is the last one in this flow, which | |
| 576 | − * will trigger esai to start. | |
| 577 | − */ | |
| 578 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 579 | − tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, | |
| 580 | − tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); | |
| 581 | − mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; | |
| 582 | − | |
| 583 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | |
| 584 | − ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); | |
| 585 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | |
| 586 | − ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); | |
| 587 | − | |
| 732 | + fsl_esai_trigger_start(esai_priv, tx); | |
| 588 | 733 | break; |
| 589 | 734 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 590 | 735 | case SNDRV_PCM_TRIGGER_STOP: |
| 591 | 736 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 592 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | |
| 593 | − tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); | |
| 594 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | |
| 595 | − ESAI_xSMA_xS_MASK, 0); | |
| 596 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | |
| 597 | − ESAI_xSMB_xS_MASK, 0); | |
| 598 | − | |
| 599 | − /* Disable and reset FIFO */ | |
| 600 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 601 | − ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR); | |
| 602 | − regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | |
| 603 | − ESAI_xFCR_xFR, 0); | |
| 737 | + fsl_esai_trigger_stop(esai_priv, tx); | |
| 604 | 738 | break; |
| 605 | 739 | default: |
| 606 | 740 | return -EINVAL; |
| @@ -787,6 +921,10 @@ static int fsl_esai_probe(struct platform_device *pdev) · 180 unmodified lines | ||
| 787 | 921 | esai_priv->pdev = pdev; |
| 788 | 922 | snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); |
| 789 | 923 | |
| 924 | + if (of_device_is_compatible(np, "fsl,vf610-esai") || | |
| 925 | + of_device_is_compatible(np, "fsl,imx35-esai")) | |
| 926 | + esai_priv->reset_at_xrun = true; | |
| 927 | + | |
| 790 | 928 | /* Get the addresses and IRQ */ |
| 791 | 929 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 792 | 930 | regs = devm_ioremap_resource(&pdev->dev, res); |
| @@ -824,10 +962,8 @@ static int fsl_esai_probe(struct platform_device *pdev) · 31 unmodified lines | ||
| 824 | 962 | PTR_ERR(esai_priv->spbaclk)); |
| 825 | 963 | |
| 826 | 964 | irq = platform_get_irq(pdev, 0); |
| 827 | − if (irq < 0) { | |
| 828 | − dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | |
| 965 | + if (irq < 0) | |
| 829 | 966 | return irq; |
| 830 | − } | |
| 831 | 967 | |
| 832 | 968 | ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, |
| 833 | 969 | esai_priv->name, esai_priv); |
| @@ -866,22 +1002,9 @@ static int fsl_esai_probe(struct platform_device *pdev) · 32 unmodified lines | ||
| 866 | 1002 | |
| 867 | 1003 | dev_set_drvdata(&pdev->dev, esai_priv); |
| 868 | 1004 | |
| 869 | − /* Reset ESAI unit */ | |
| 870 | − ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST); | |
| 871 | − if (ret) { | |
| 872 | − dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret); | |
| 873 | − return ret; | |
| 874 | − } | |
| 875 | − | |
| 876 | − /* | |
| 877 | − * We need to enable ESAI so as to access some of its registers. | |
| 878 | − * Otherwise, we would fail to dump regmap from user space. | |
| 879 | − */ | |
| 880 | − ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN); | |
| 881 | − if (ret) { | |
| 882 | − dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret); | |
| 1005 | + ret = fsl_esai_hw_init(esai_priv); | |
| 1006 | + if (ret) | |
| 883 | 1007 | return ret; |
| 884 | − } | |
| 885 | 1008 | |
| 886 | 1009 | esai_priv->tx_mask = 0xFFFFFFFF; |
| 887 | 1010 | esai_priv->rx_mask = 0xFFFFFFFF; |
| @@ -899,6 +1022,9 @@ static int fsl_esai_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 899 | 1022 | return ret; |
| 900 | 1023 | } |
| 901 | 1024 | |
| 1025 | + tasklet_init(&esai_priv->task, fsl_esai_hw_reset, | |
| 1026 | + (unsigned long)esai_priv); | |
| 1027 | + | |
| 902 | 1028 | pm_runtime_enable(&pdev->dev); |
| 903 | 1029 | |
| 904 | 1030 | regcache_cache_only(esai_priv->regmap, true); |
| @@ -912,7 +1038,10 @@ static int fsl_esai_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 912 | 1038 | |
| 913 | 1039 | static int fsl_esai_remove(struct platform_device *pdev) |
| 914 | 1040 | { |
| 1041 | + struct fsl_esai *esai_priv = platform_get_drvdata(pdev); | |
| 1042 | + | |
| 915 | 1043 | pm_runtime_disable(&pdev->dev); |
| 1044 | + tasklet_kill(&esai_priv->task); | |
| 916 | 1045 | |
| 917 | 1046 | return 0; |
| 918 | 1047 | } |
| @@ -920,6 +1049,7 @@ static int fsl_esai_remove(struct platform_device *pdev) · 1 unmodified line | ||
| 920 | 1049 | static const struct of_device_id fsl_esai_dt_ids[] = { |
| 921 | 1050 | { .compatible = "fsl,imx35-esai", }, |
| 922 | 1051 | { .compatible = "fsl,vf610-esai", }, |
| 1052 | + { .compatible = "fsl,imx6ull-esai", }, | |
| 923 | 1053 | {} |
| 924 | 1054 | }; |
| 925 | 1055 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); |
| @@ -955,20 +1085,10 @@ static int fsl_esai_runtime_resume(struct device *dev) · 29 unmodified lines | ||
| 955 | 1085 | |
| 956 | 1086 | regcache_cache_only(esai->regmap, false); |
| 957 | 1087 | |
| 958 | − /* FIFO reset for safety */ | |
| 959 | − regmap_update_bits(esai->regmap, REG_ESAI_TFCR, | |
| 960 | − ESAI_xFCR_xFR, ESAI_xFCR_xFR); | |
| 961 | − regmap_update_bits(esai->regmap, REG_ESAI_RFCR, | |
| 962 | − ESAI_xFCR_xFR, ESAI_xFCR_xFR); | |
| 963 | − | |
| 964 | − ret = regcache_sync(esai->regmap); | |
| 1088 | + ret = fsl_esai_register_restore(esai); | |
| 965 | 1089 | if (ret) |
| 966 | 1090 | goto err_regcache_sync; |
| 967 | 1091 | |
| 968 | − /* FIFO reset done */ | |
| 969 | − regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0); | |
| 970 | − regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0); | |
| 971 | − | |
| 972 | 1092 | return 0; |
| 973 | 1093 | |
| 974 | 1094 | err_regcache_sync: |
| @@ -991,7 +1111,6 @@ static int fsl_esai_runtime_suspend(struct device *dev) · 16 unmodified lines | ||
| 991 | 1111 | struct fsl_esai *esai = dev_get_drvdata(dev); |
| 992 | 1112 | |
| 993 | 1113 | regcache_cache_only(esai->regmap, true); |
| 994 | − regcache_mark_dirty(esai->regmap); | |
| 995 | 1114 | |
| 996 | 1115 | if (!IS_ERR(esai->fsysclk)) |
| 997 | 1116 | clk_disable_unprepare(esai->fsysclk); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/dmaengine.h> |
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/of_address.h> |
| 12 | +#include <linux/of_device.h> | |
| 12 | 13 | #include <linux/pm_runtime.h> |
| 13 | 14 | #include <linux/regmap.h> |
| 14 | 15 | #include <linux/slab.h> |
| @@ -39,6 +40,7 @@ static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { · 24 unmodified lines | ||
| 39 | 40 | static irqreturn_t fsl_sai_isr(int irq, void *devid) |
| 40 | 41 | { |
| 41 | 42 | struct fsl_sai *sai = (struct fsl_sai *)devid; |
| 43 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 42 | 44 | struct device *dev = &sai->pdev->dev; |
| 43 | 45 | u32 flags, xcsr, mask; |
| 44 | 46 | bool irq_none = true; |
| @@ -51,7 +53,7 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) · 6 unmodified lines | ||
| 51 | 53 | mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; |
| 52 | 54 | |
| 53 | 55 | /* Tx IRQ */ |
| 54 | − regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); | |
| 56 | + regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr); | |
| 55 | 57 | flags = xcsr & mask; |
| 56 | 58 | |
| 57 | 59 | if (flags) |
| @@ -81,11 +83,11 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) · 23 unmodified lines | ||
| 81 | 83 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
| 82 | 84 | |
| 83 | 85 | if (flags) |
| 84 | − regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); | |
| 86 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr); | |
| 85 | 87 | |
| 86 | 88 | irq_rx: |
| 87 | 89 | /* Rx IRQ */ |
| 88 | − regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); | |
| 90 | + regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr); | |
| 89 | 91 | flags = xcsr & mask; |
| 90 | 92 | |
| 91 | 93 | if (flags) |
| @@ -115,7 +117,7 @@ irq_rx: · 23 unmodified lines | ||
| 115 | 117 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
| 116 | 118 | |
| 117 | 119 | if (flags) |
| 118 | − regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr); | |
| 120 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr); | |
| 119 | 121 | |
| 120 | 122 | out: |
| 121 | 123 | if (irq_none) |
| @@ -139,6 +141,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, · 17 unmodified lines | ||
| 139 | 141 | int clk_id, unsigned int freq, int fsl_dir) |
| 140 | 142 | { |
| 141 | 143 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 144 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 142 | 145 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
| 143 | 146 | u32 val_cr2 = 0; |
| 144 | 147 | |
| @@ -159,7 +162,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, · 14 unmodified lines | ||
| 159 | 162 | return -EINVAL; |
| 160 | 163 | } |
| 161 | 164 | |
| 162 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), | |
| 165 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), | |
| 163 | 166 | FSL_SAI_CR2_MSEL_MASK, val_cr2); |
| 164 | 167 | |
| 165 | 168 | return 0; |
| @@ -192,6 +195,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, · 26 unmodified lines | ||
| 192 | 195 | unsigned int fmt, int fsl_dir) |
| 193 | 196 | { |
| 194 | 197 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 198 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 195 | 199 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
| 196 | 200 | u32 val_cr2 = 0, val_cr4 = 0; |
| 197 | 201 | |
| @@ -286,9 +290,9 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, · 88 unmodified lines | ||
| 286 | 290 | return -EINVAL; |
| 287 | 291 | } |
| 288 | 292 | |
| 289 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), | |
| 293 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), | |
| 290 | 294 | FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); |
| 291 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), | |
| 295 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), | |
| 292 | 296 | FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | |
| 293 | 297 | FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); |
| 294 | 298 | |
| @@ -315,6 +319,7 @@ static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) · 20 unmodified lines | ||
| 315 | 319 | static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) |
| 316 | 320 | { |
| 317 | 321 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); |
| 322 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 318 | 323 | unsigned long clk_rate; |
| 319 | 324 | u32 savediv = 0, ratio, savesub = freq; |
| 320 | 325 | u32 id; |
| @@ -377,17 +382,17 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) · 56 unmodified lines | ||
| 377 | 382 | */ |
| 378 | 383 | if ((sai->synchronous[TX] && !sai->synchronous[RX]) || |
| 379 | 384 | (!tx && !sai->synchronous[RX])) { |
| 380 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR2, | |
| 385 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), | |
| 381 | 386 | FSL_SAI_CR2_MSEL_MASK, |
| 382 | 387 | FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); |
| 383 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR2, | |
| 388 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), | |
| 384 | 389 | FSL_SAI_CR2_DIV_MASK, savediv - 1); |
| 385 | 390 | } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || |
| 386 | 391 | (tx && !sai->synchronous[TX])) { |
| 387 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR2, | |
| 392 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), | |
| 388 | 393 | FSL_SAI_CR2_MSEL_MASK, |
| 389 | 394 | FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); |
| 390 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR2, | |
| 395 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), | |
| 391 | 396 | FSL_SAI_CR2_DIV_MASK, savediv - 1); |
| 392 | 397 | } |
| 393 | 398 | |
| @@ -402,6 +407,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, · 8 unmodified lines | ||
| 402 | 407 | struct snd_soc_dai *cpu_dai) |
| 403 | 408 | { |
| 404 | 409 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 410 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 405 | 411 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 406 | 412 | unsigned int channels = params_channels(params); |
| 407 | 413 | u32 word_width = params_width(params); |
| @@ -454,19 +460,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, · 46 unmodified lines | ||
| 454 | 460 | |
| 455 | 461 | if (!sai->is_slave_mode) { |
| 456 | 462 | if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { |
| 457 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR4, | |
| 463 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR4(ofs), | |
| 458 | 464 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 459 | 465 | val_cr4); |
| 460 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR5, | |
| 466 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR5(ofs), | |
| 461 | 467 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 462 | 468 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 463 | 469 | regmap_write(sai->regmap, FSL_SAI_TMR, |
| 464 | 470 | ~0UL - ((1 << channels) - 1)); |
| 465 | 471 | } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { |
| 466 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR4, | |
| 472 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR4(ofs), | |
| 467 | 473 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 468 | 474 | val_cr4); |
| 469 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR5, | |
| 475 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR5(ofs), | |
| 470 | 476 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 471 | 477 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 472 | 478 | regmap_write(sai->regmap, FSL_SAI_RMR, |
| @@ -474,10 +480,10 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line | ||
| 474 | 480 | } |
| 475 | 481 | } |
| 476 | 482 | |
| 477 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), | |
| 483 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), | |
| 478 | 484 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 479 | 485 | val_cr4); |
| 480 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), | |
| 486 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), | |
| 481 | 487 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 482 | 488 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 483 | 489 | regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); |
| @@ -505,6 +511,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, · 21 unmodified lines | ||
| 505 | 511 | struct snd_soc_dai *cpu_dai) |
| 506 | 512 | { |
| 507 | 513 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 514 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 515 | + | |
| 508 | 516 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 509 | 517 | u32 xcsr, count = 100; |
| 510 | 518 | |
| @@ -513,9 +521,9 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, · 2 unmodified lines | ||
| 513 | 521 | * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. |
| 514 | 522 | * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. |
| 515 | 523 | */ |
| 516 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, | |
| 517 | − sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); | |
| 518 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, | |
| 524 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC, | |
| 525 | + sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); | |
| 526 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC, | |
| 519 | 527 | sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); |
| 520 | 528 | |
| 521 | 529 | /* |
| @@ -526,43 +534,44 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, · 4 unmodified lines | ||
| 526 | 534 | case SNDRV_PCM_TRIGGER_START: |
| 527 | 535 | case SNDRV_PCM_TRIGGER_RESUME: |
| 528 | 536 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 529 | − regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | |
| 537 | + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), | |
| 530 | 538 | FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); |
| 531 | 539 | |
| 532 | − regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | |
| 540 | + regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), | |
| 533 | 541 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); |
| 534 | − regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | |
| 542 | + regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), | |
| 535 | 543 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); |
| 536 | 544 | |
| 537 | − regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | |
| 545 | + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), | |
| 538 | 546 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); |
| 539 | 547 | break; |
| 540 | 548 | case SNDRV_PCM_TRIGGER_STOP: |
| 541 | 549 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 542 | 550 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 543 | − regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | |
| 551 | + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), | |
| 544 | 552 | FSL_SAI_CSR_FRDE, 0); |
| 545 | − regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | |
| 553 | + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), | |
| 546 | 554 | FSL_SAI_CSR_xIE_MASK, 0); |
| 547 | 555 | |
| 548 | 556 | /* Check if the opposite FRDE is also disabled */ |
| 549 | − regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr); | |
| 557 | + regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr); | |
| 550 | 558 | if (!(xcsr & FSL_SAI_CSR_FRDE)) { |
| 551 | 559 | /* Disable both directions and reset their FIFOs */ |
| 552 | − regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | |
| 560 | + regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), | |
| 553 | 561 | FSL_SAI_CSR_TERE, 0); |
| 554 | − regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | |
| 562 | + regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), | |
| 555 | 563 | FSL_SAI_CSR_TERE, 0); |
| 556 | 564 | |
| 557 | 565 | /* TERE will remain set till the end of current frame */ |
| 558 | 566 | do { |
| 559 | 567 | udelay(10); |
| 560 | − regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr); | |
| 568 | + regmap_read(sai->regmap, | |
| 569 | + FSL_SAI_xCSR(tx, ofs), &xcsr); | |
| 561 | 570 | } while (--count && xcsr & FSL_SAI_CSR_TERE); |
| 562 | 571 | |
| 563 | − regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | |
| 572 | + regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), | |
| 564 | 573 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); |
| 565 | − regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | |
| 574 | + regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), | |
| 566 | 575 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); |
| 567 | 576 | |
| 568 | 577 | /* |
| @@ -574,13 +583,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, · 5 unmodified lines | ||
| 574 | 583 | */ |
| 575 | 584 | if (!sai->is_slave_mode) { |
| 576 | 585 | /* Software Reset for both Tx and Rx */ |
| 577 | − regmap_write(sai->regmap, | |
| 578 | − FSL_SAI_TCSR, FSL_SAI_CSR_SR); | |
| 579 | − regmap_write(sai->regmap, | |
| 580 | − FSL_SAI_RCSR, FSL_SAI_CSR_SR); | |
| 586 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), | |
| 587 | + FSL_SAI_CSR_SR); | |
| 588 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), | |
| 589 | + FSL_SAI_CSR_SR); | |
| 581 | 590 | /* Clear SR bit to finish the reset */ |
| 582 | − regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | |
| 583 | − regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | |
| 591 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); | |
| 592 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); | |
| 584 | 593 | } |
| 585 | 594 | } |
| 586 | 595 | break; |
| @@ -595,10 +604,12 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, · 8 unmodified lines | ||
| 595 | 604 | struct snd_soc_dai *cpu_dai) |
| 596 | 605 | { |
| 597 | 606 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 607 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 598 | 608 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 599 | 609 | int ret; |
| 600 | 610 | |
| 601 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, | |
| 611 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), | |
| 612 | + FSL_SAI_CR3_TRCE_MASK, | |
| 602 | 613 | FSL_SAI_CR3_TRCE); |
| 603 | 614 | |
| 604 | 615 | ret = snd_pcm_hw_constraint_list(substream->runtime, 0, |
| @@ -611,9 +622,11 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 611 | 622 | struct snd_soc_dai *cpu_dai) |
| 612 | 623 | { |
| 613 | 624 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 625 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 614 | 626 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 615 | 627 | |
| 616 | − regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); | |
| 628 | + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), | |
| 629 | + FSL_SAI_CR3_TRCE_MASK, 0); | |
| 617 | 630 | } |
| 618 | 631 | |
| 619 | 632 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { |
| @@ -630,18 +643,20 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { · 10 unmodified lines | ||
| 630 | 643 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
| 631 | 644 | { |
| 632 | 645 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); |
| 646 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 633 | 647 | |
| 634 | 648 | /* Software Reset for both Tx and Rx */ |
| 635 | − regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); | |
| 636 | − regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); | |
| 649 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); | |
| 650 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); | |
| 637 | 651 | /* Clear SR bit to finish the reset */ |
| 638 | − regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | |
| 639 | − regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | |
| 652 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); | |
| 653 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); | |
| 640 | 654 | |
| 641 | − regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, | |
| 642 | − FSL_SAI_MAXBURST_TX * 2); | |
| 643 | − regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, | |
| 644 | − FSL_SAI_MAXBURST_RX - 1); | |
| 655 | + regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), | |
| 656 | + FSL_SAI_CR1_RFW_MASK, | |
| 657 | + sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX); | |
| 658 | + regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs), | |
| 659 | + FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_RX - 1); | |
| 645 | 660 | |
| 646 | 661 | snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, |
| 647 | 662 | &sai->dma_params_rx); |
| @@ -678,41 +693,89 @@ static const struct snd_soc_component_driver fsl_component = { · 30 unmodified lines | ||
| 678 | 693 | .name = "fsl-sai", |
| 679 | 694 | }; |
| 680 | 695 | |
| 681 | −static struct reg_default fsl_sai_reg_defaults[] = { | |
| 682 | − {FSL_SAI_TCR1, 0}, | |
| 683 | − {FSL_SAI_TCR2, 0}, | |
| 684 | − {FSL_SAI_TCR3, 0}, | |
| 685 | − {FSL_SAI_TCR4, 0}, | |
| 686 | − {FSL_SAI_TCR5, 0}, | |
| 687 | − {FSL_SAI_TDR, 0}, | |
| 688 | − {FSL_SAI_TMR, 0}, | |
| 689 | − {FSL_SAI_RCR1, 0}, | |
| 690 | − {FSL_SAI_RCR2, 0}, | |
| 691 | − {FSL_SAI_RCR3, 0}, | |
| 692 | − {FSL_SAI_RCR4, 0}, | |
| 693 | − {FSL_SAI_RCR5, 0}, | |
| 694 | − {FSL_SAI_RMR, 0}, | |
| 696 | +static struct reg_default fsl_sai_reg_defaults_ofs0[] = { | |
| 697 | + {FSL_SAI_TCR1(0), 0}, | |
| 698 | + {FSL_SAI_TCR2(0), 0}, | |
| 699 | + {FSL_SAI_TCR3(0), 0}, | |
| 700 | + {FSL_SAI_TCR4(0), 0}, | |
| 701 | + {FSL_SAI_TCR5(0), 0}, | |
| 702 | + {FSL_SAI_TDR0, 0}, | |
| 703 | + {FSL_SAI_TDR1, 0}, | |
| 704 | + {FSL_SAI_TDR2, 0}, | |
| 705 | + {FSL_SAI_TDR3, 0}, | |
| 706 | + {FSL_SAI_TDR4, 0}, | |
| 707 | + {FSL_SAI_TDR5, 0}, | |
| 708 | + {FSL_SAI_TDR6, 0}, | |
| 709 | + {FSL_SAI_TDR7, 0}, | |
| 710 | + {FSL_SAI_TMR, 0}, | |
| 711 | + {FSL_SAI_RCR1(0), 0}, | |
| 712 | + {FSL_SAI_RCR2(0), 0}, | |
| 713 | + {FSL_SAI_RCR3(0), 0}, | |
| 714 | + {FSL_SAI_RCR4(0), 0}, | |
| 715 | + {FSL_SAI_RCR5(0), 0}, | |
| 716 | + {FSL_SAI_RMR, 0}, | |
| 717 | +}; | |
| 718 | + | |
| 719 | +static struct reg_default fsl_sai_reg_defaults_ofs8[] = { | |
| 720 | + {FSL_SAI_TCR1(8), 0}, | |
| 721 | + {FSL_SAI_TCR2(8), 0}, | |
| 722 | + {FSL_SAI_TCR3(8), 0}, | |
| 723 | + {FSL_SAI_TCR4(8), 0}, | |
| 724 | + {FSL_SAI_TCR5(8), 0}, | |
| 725 | + {FSL_SAI_TDR0, 0}, | |
| 726 | + {FSL_SAI_TDR1, 0}, | |
| 727 | + {FSL_SAI_TDR2, 0}, | |
| 728 | + {FSL_SAI_TDR3, 0}, | |
| 729 | + {FSL_SAI_TDR4, 0}, | |
| 730 | + {FSL_SAI_TDR5, 0}, | |
| 731 | + {FSL_SAI_TDR6, 0}, | |
| 732 | + {FSL_SAI_TDR7, 0}, | |
| 733 | + {FSL_SAI_TMR, 0}, | |
| 734 | + {FSL_SAI_RCR1(8), 0}, | |
| 735 | + {FSL_SAI_RCR2(8), 0}, | |
| 736 | + {FSL_SAI_RCR3(8), 0}, | |
| 737 | + {FSL_SAI_RCR4(8), 0}, | |
| 738 | + {FSL_SAI_RCR5(8), 0}, | |
| 739 | + {FSL_SAI_RMR, 0}, | |
| 695 | 740 | }; |
| 696 | 741 | |
| 697 | 742 | static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) |
| 698 | 743 | { |
| 744 | + struct fsl_sai *sai = dev_get_drvdata(dev); | |
| 745 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 746 | + | |
| 747 | + if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) | |
| 748 | + return true; | |
| 749 | + | |
| 750 | + if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) | |
| 751 | + return true; | |
| 752 | + | |
| 699 | 753 | switch (reg) { |
| 700 | − case FSL_SAI_TCSR: | |
| 701 | − case FSL_SAI_TCR1: | |
| 702 | − case FSL_SAI_TCR2: | |
| 703 | − case FSL_SAI_TCR3: | |
| 704 | − case FSL_SAI_TCR4: | |
| 705 | − case FSL_SAI_TCR5: | |
| 706 | − case FSL_SAI_TFR: | |
| 754 | + case FSL_SAI_TFR0: | |
| 755 | + case FSL_SAI_TFR1: | |
| 756 | + case FSL_SAI_TFR2: | |
| 757 | + case FSL_SAI_TFR3: | |
| 758 | + case FSL_SAI_TFR4: | |
| 759 | + case FSL_SAI_TFR5: | |
| 760 | + case FSL_SAI_TFR6: | |
| 761 | + case FSL_SAI_TFR7: | |
| 707 | 762 | case FSL_SAI_TMR: |
| 708 | − case FSL_SAI_RCSR: | |
| 709 | − case FSL_SAI_RCR1: | |
| 710 | − case FSL_SAI_RCR2: | |
| 711 | − case FSL_SAI_RCR3: | |
| 712 | − case FSL_SAI_RCR4: | |
| 713 | − case FSL_SAI_RCR5: | |
| 714 | − case FSL_SAI_RDR: | |
| 715 | − case FSL_SAI_RFR: | |
| 763 | + case FSL_SAI_RDR0: | |
| 764 | + case FSL_SAI_RDR1: | |
| 765 | + case FSL_SAI_RDR2: | |
| 766 | + case FSL_SAI_RDR3: | |
| 767 | + case FSL_SAI_RDR4: | |
| 768 | + case FSL_SAI_RDR5: | |
| 769 | + case FSL_SAI_RDR6: | |
| 770 | + case FSL_SAI_RDR7: | |
| 771 | + case FSL_SAI_RFR0: | |
| 772 | + case FSL_SAI_RFR1: | |
| 773 | + case FSL_SAI_RFR2: | |
| 774 | + case FSL_SAI_RFR3: | |
| 775 | + case FSL_SAI_RFR4: | |
| 776 | + case FSL_SAI_RFR5: | |
| 777 | + case FSL_SAI_RFR6: | |
| 778 | + case FSL_SAI_RFR7: | |
| 716 | 779 | case FSL_SAI_RMR: |
| 717 | 780 | return true; |
| 718 | 781 | default: |
| @@ -722,12 +785,37 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) · 3 unmodified lines | ||
| 722 | 785 | |
| 723 | 786 | static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) |
| 724 | 787 | { |
| 788 | + struct fsl_sai *sai = dev_get_drvdata(dev); | |
| 789 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 790 | + | |
| 791 | + if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs)) | |
| 792 | + return true; | |
| 793 | + | |
| 725 | 794 | switch (reg) { |
| 726 | − case FSL_SAI_TCSR: | |
| 727 | − case FSL_SAI_RCSR: | |
| 728 | − case FSL_SAI_TFR: | |
| 729 | − case FSL_SAI_RFR: | |
| 730 | − case FSL_SAI_RDR: | |
| 795 | + case FSL_SAI_TFR0: | |
| 796 | + case FSL_SAI_TFR1: | |
| 797 | + case FSL_SAI_TFR2: | |
| 798 | + case FSL_SAI_TFR3: | |
| 799 | + case FSL_SAI_TFR4: | |
| 800 | + case FSL_SAI_TFR5: | |
| 801 | + case FSL_SAI_TFR6: | |
| 802 | + case FSL_SAI_TFR7: | |
| 803 | + case FSL_SAI_RFR0: | |
| 804 | + case FSL_SAI_RFR1: | |
| 805 | + case FSL_SAI_RFR2: | |
| 806 | + case FSL_SAI_RFR3: | |
| 807 | + case FSL_SAI_RFR4: | |
| 808 | + case FSL_SAI_RFR5: | |
| 809 | + case FSL_SAI_RFR6: | |
| 810 | + case FSL_SAI_RFR7: | |
| 811 | + case FSL_SAI_RDR0: | |
| 812 | + case FSL_SAI_RDR1: | |
| 813 | + case FSL_SAI_RDR2: | |
| 814 | + case FSL_SAI_RDR3: | |
| 815 | + case FSL_SAI_RDR4: | |
| 816 | + case FSL_SAI_RDR5: | |
| 817 | + case FSL_SAI_RDR6: | |
| 818 | + case FSL_SAI_RDR7: | |
| 731 | 819 | return true; |
| 732 | 820 | default: |
| 733 | 821 | return false; |
| @@ -736,21 +824,25 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) · 2 unmodified lines | ||
| 736 | 824 | |
| 737 | 825 | static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) |
| 738 | 826 | { |
| 827 | + struct fsl_sai *sai = dev_get_drvdata(dev); | |
| 828 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 829 | + | |
| 830 | + if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) | |
| 831 | + return true; | |
| 832 | + | |
| 833 | + if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) | |
| 834 | + return true; | |
| 835 | + | |
| 739 | 836 | switch (reg) { |
| 740 | − case FSL_SAI_TCSR: | |
| 741 | − case FSL_SAI_TCR1: | |
| 742 | − case FSL_SAI_TCR2: | |
| 743 | − case FSL_SAI_TCR3: | |
| 744 | − case FSL_SAI_TCR4: | |
| 745 | − case FSL_SAI_TCR5: | |
| 746 | − case FSL_SAI_TDR: | |
| 837 | + case FSL_SAI_TDR0: | |
| 838 | + case FSL_SAI_TDR1: | |
| 839 | + case FSL_SAI_TDR2: | |
| 840 | + case FSL_SAI_TDR3: | |
| 841 | + case FSL_SAI_TDR4: | |
| 842 | + case FSL_SAI_TDR5: | |
| 843 | + case FSL_SAI_TDR6: | |
| 844 | + case FSL_SAI_TDR7: | |
| 747 | 845 | case FSL_SAI_TMR: |
| 748 | − case FSL_SAI_RCSR: | |
| 749 | − case FSL_SAI_RCR1: | |
| 750 | − case FSL_SAI_RCR2: | |
| 751 | − case FSL_SAI_RCR3: | |
| 752 | − case FSL_SAI_RCR4: | |
| 753 | − case FSL_SAI_RCR5: | |
| 754 | 846 | case FSL_SAI_RMR: |
| 755 | 847 | return true; |
| 756 | 848 | default: |
| @@ -758,14 +850,15 @@ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) · 1 unmodified line | ||
| 758 | 850 | } |
| 759 | 851 | } |
| 760 | 852 | |
| 761 | −static const struct regmap_config fsl_sai_regmap_config = { | |
| 853 | +static struct regmap_config fsl_sai_regmap_config = { | |
| 762 | 854 | .reg_bits = 32, |
| 763 | 855 | .reg_stride = 4, |
| 764 | 856 | .val_bits = 32, |
| 857 | + .fast_io = true, | |
| 765 | 858 | |
| 766 | 859 | .max_register = FSL_SAI_RMR, |
| 767 | − .reg_defaults = fsl_sai_reg_defaults, | |
| 768 | − .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults), | |
| 860 | + .reg_defaults = fsl_sai_reg_defaults_ofs0, | |
| 861 | + .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0), | |
| 769 | 862 | .readable_reg = fsl_sai_readable_reg, |
| 770 | 863 | .volatile_reg = fsl_sai_volatile_reg, |
| 771 | 864 | .writeable_reg = fsl_sai_writeable_reg, |
| @@ -788,10 +881,7 @@ static int fsl_sai_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 788 | 881 | return -ENOMEM; |
| 789 | 882 | |
| 790 | 883 | sai->pdev = pdev; |
| 791 | − | |
| 792 | − if (of_device_is_compatible(np, "fsl,imx6sx-sai") || | |
| 793 | − of_device_is_compatible(np, "fsl,imx6ul-sai")) | |
| 794 | − sai->sai_on_imx = true; | |
| 884 | + sai->soc_data = of_device_get_match_data(&pdev->dev); | |
| 795 | 885 | |
| 796 | 886 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); |
| 797 | 887 | |
| @@ -800,6 +890,12 @@ static int fsl_sai_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 800 | 890 | if (IS_ERR(base)) |
| 801 | 891 | return PTR_ERR(base); |
| 802 | 892 | |
| 893 | + if (sai->soc_data->reg_offset == 8) { | |
| 894 | + fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8; | |
| 895 | + fsl_sai_regmap_config.num_reg_defaults = | |
| 896 | + ARRAY_SIZE(fsl_sai_reg_defaults_ofs8); | |
| 897 | + } | |
| 898 | + | |
| 803 | 899 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, |
| 804 | 900 | "bus", base, &fsl_sai_regmap_config); |
| 805 | 901 | |
| @@ -832,10 +928,8 @@ static int fsl_sai_probe(struct platform_device *pdev) · 26 unmodified lines | ||
| 832 | 928 | } |
| 833 | 929 | |
| 834 | 930 | irq = platform_get_irq(pdev, 0); |
| 835 | − if (irq < 0) { | |
| 836 | − dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | |
| 931 | + if (irq < 0) | |
| 837 | 932 | return irq; |
| 838 | − } | |
| 839 | 933 | |
| 840 | 934 | ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); |
| 841 | 935 | if (ret) { |
| @@ -886,8 +980,8 @@ static int fsl_sai_probe(struct platform_device *pdev) · 44 unmodified lines | ||
| 886 | 980 | MCLK_DIR(index)); |
| 887 | 981 | } |
| 888 | 982 | |
| 889 | − sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; | |
| 890 | − sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; | |
| 983 | + sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; | |
| 984 | + sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; | |
| 891 | 985 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; |
| 892 | 986 | sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; |
| 893 | 987 | |
| @@ -900,7 +994,7 @@ static int fsl_sai_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 900 | 994 | if (ret) |
| 901 | 995 | return ret; |
| 902 | 996 | |
| 903 | − if (sai->sai_on_imx) | |
| 997 | + if (sai->soc_data->use_imx_pcm) | |
| 904 | 998 | return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); |
| 905 | 999 | else |
| 906 | 1000 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); |
| @@ -913,10 +1007,43 @@ static int fsl_sai_remove(struct platform_device *pdev) · 6 unmodified lines | ||
| 913 | 1007 | return 0; |
| 914 | 1008 | } |
| 915 | 1009 | |
| 1010 | +static const struct fsl_sai_soc_data fsl_sai_vf610_data = { | |
| 1011 | + .use_imx_pcm = false, | |
| 1012 | + .fifo_depth = 32, | |
| 1013 | + .reg_offset = 0, | |
| 1014 | +}; | |
| 1015 | + | |
| 1016 | +static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { | |
| 1017 | + .use_imx_pcm = true, | |
| 1018 | + .fifo_depth = 32, | |
| 1019 | + .reg_offset = 0, | |
| 1020 | +}; | |
| 1021 | + | |
| 1022 | +static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = { | |
| 1023 | + .use_imx_pcm = true, | |
| 1024 | + .fifo_depth = 16, | |
| 1025 | + .reg_offset = 8, | |
| 1026 | +}; | |
| 1027 | + | |
| 1028 | +static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = { | |
| 1029 | + .use_imx_pcm = true, | |
| 1030 | + .fifo_depth = 128, | |
| 1031 | + .reg_offset = 8, | |
| 1032 | +}; | |
| 1033 | + | |
| 1034 | +static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = { | |
| 1035 | + .use_imx_pcm = true, | |
| 1036 | + .fifo_depth = 64, | |
| 1037 | + .reg_offset = 0, | |
| 1038 | +}; | |
| 1039 | + | |
| 916 | 1040 | static const struct of_device_id fsl_sai_ids[] = { |
| 917 | − { .compatible = "fsl,vf610-sai", }, | |
| 918 | − { .compatible = "fsl,imx6sx-sai", }, | |
| 919 | − { .compatible = "fsl,imx6ul-sai", }, | |
| 1041 | + { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, | |
| 1042 | + { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, | |
| 1043 | + { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data }, | |
| 1044 | + { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data }, | |
| 1045 | + { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data }, | |
| 1046 | + { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data }, | |
| 920 | 1047 | { /* sentinel */ } |
| 921 | 1048 | }; |
| 922 | 1049 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); |
| @@ -943,6 +1070,7 @@ static int fsl_sai_runtime_suspend(struct device *dev) · 20 unmodified lines | ||
| 943 | 1070 | static int fsl_sai_runtime_resume(struct device *dev) |
| 944 | 1071 | { |
| 945 | 1072 | struct fsl_sai *sai = dev_get_drvdata(dev); |
| 1073 | + unsigned int ofs = sai->soc_data->reg_offset; | |
| 946 | 1074 | int ret; |
| 947 | 1075 | |
| 948 | 1076 | ret = clk_prepare_enable(sai->bus_clk); |
| @@ -964,11 +1092,11 @@ static int fsl_sai_runtime_resume(struct device *dev) · 15 unmodified lines | ||
| 964 | 1092 | } |
| 965 | 1093 | |
| 966 | 1094 | regcache_cache_only(sai->regmap, false); |
| 967 | − regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); | |
| 968 | − regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); | |
| 1095 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); | |
| 1096 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); | |
| 969 | 1097 | usleep_range(1000, 2000); |
| 970 | − regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | |
| 971 | − regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | |
| 1098 | + regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); | |
| 1099 | + regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); | |
| 972 | 1100 | |
| 973 | 1101 | ret = regcache_sync(sai->regmap); |
| 974 | 1102 | if (ret) |
| @@ -14,33 +14,61 @@ · 13 unmodified lines | ||
| 14 | 14 | SNDRV_PCM_FMTBIT_S32_LE) |
| 15 | 15 | |
| 16 | 16 | /* SAI Register Map Register */ |
| 17 | −#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ | |
| 18 | −#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ | |
| 19 | −#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ | |
| 20 | −#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ | |
| 21 | −#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ | |
| 22 | −#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ | |
| 23 | −#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ | |
| 24 | −#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ | |
| 17 | +#define FSL_SAI_TCSR(ofs) (0x00 + ofs) /* SAI Transmit Control */ | |
| 18 | +#define FSL_SAI_TCR1(ofs) (0x04 + ofs) /* SAI Transmit Configuration 1 */ | |
| 19 | +#define FSL_SAI_TCR2(ofs) (0x08 + ofs) /* SAI Transmit Configuration 2 */ | |
| 20 | +#define FSL_SAI_TCR3(ofs) (0x0c + ofs) /* SAI Transmit Configuration 3 */ | |
| 21 | +#define FSL_SAI_TCR4(ofs) (0x10 + ofs) /* SAI Transmit Configuration 4 */ | |
| 22 | +#define FSL_SAI_TCR5(ofs) (0x14 + ofs) /* SAI Transmit Configuration 5 */ | |
| 23 | +#define FSL_SAI_TDR0 0x20 /* SAI Transmit Data 0 */ | |
| 24 | +#define FSL_SAI_TDR1 0x24 /* SAI Transmit Data 1 */ | |
| 25 | +#define FSL_SAI_TDR2 0x28 /* SAI Transmit Data 2 */ | |
| 26 | +#define FSL_SAI_TDR3 0x2C /* SAI Transmit Data 3 */ | |
| 27 | +#define FSL_SAI_TDR4 0x30 /* SAI Transmit Data 4 */ | |
| 28 | +#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data 5 */ | |
| 29 | +#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data 6 */ | |
| 30 | +#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data 7 */ | |
| 31 | +#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO 0 */ | |
| 32 | +#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO 1 */ | |
| 33 | +#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO 2 */ | |
| 34 | +#define FSL_SAI_TFR3 0x4C /* SAI Transmit FIFO 3 */ | |
| 35 | +#define FSL_SAI_TFR4 0x50 /* SAI Transmit FIFO 4 */ | |
| 36 | +#define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO 5 */ | |
| 37 | +#define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO 6 */ | |
| 38 | +#define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO 7 */ | |
| 25 | 39 | #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ |
| 26 | −#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ | |
| 27 | −#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ | |
| 28 | −#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ | |
| 29 | −#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ | |
| 30 | −#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ | |
| 31 | −#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ | |
| 32 | −#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ | |
| 33 | −#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ | |
| 40 | +#define FSL_SAI_RCSR(ofs) (0x80 + ofs) /* SAI Receive Control */ | |
| 41 | +#define FSL_SAI_RCR1(ofs) (0x84 + ofs)/* SAI Receive Configuration 1 */ | |
| 42 | +#define FSL_SAI_RCR2(ofs) (0x88 + ofs) /* SAI Receive Configuration 2 */ | |
| 43 | +#define FSL_SAI_RCR3(ofs) (0x8c + ofs) /* SAI Receive Configuration 3 */ | |
| 44 | +#define FSL_SAI_RCR4(ofs) (0x90 + ofs) /* SAI Receive Configuration 4 */ | |
| 45 | +#define FSL_SAI_RCR5(ofs) (0x94 + ofs) /* SAI Receive Configuration 5 */ | |
| 46 | +#define FSL_SAI_RDR0 0xa0 /* SAI Receive Data 0 */ | |
| 47 | +#define FSL_SAI_RDR1 0xa4 /* SAI Receive Data 1 */ | |
| 48 | +#define FSL_SAI_RDR2 0xa8 /* SAI Receive Data 2 */ | |
| 49 | +#define FSL_SAI_RDR3 0xac /* SAI Receive Data 3 */ | |
| 50 | +#define FSL_SAI_RDR4 0xb0 /* SAI Receive Data 4 */ | |
| 51 | +#define FSL_SAI_RDR5 0xb4 /* SAI Receive Data 5 */ | |
| 52 | +#define FSL_SAI_RDR6 0xb8 /* SAI Receive Data 6 */ | |
| 53 | +#define FSL_SAI_RDR7 0xbc /* SAI Receive Data 7 */ | |
| 54 | +#define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO 0 */ | |
| 55 | +#define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO 1 */ | |
| 56 | +#define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO 2 */ | |
| 57 | +#define FSL_SAI_RFR3 0xcc /* SAI Receive FIFO 3 */ | |
| 58 | +#define FSL_SAI_RFR4 0xd0 /* SAI Receive FIFO 4 */ | |
| 59 | +#define FSL_SAI_RFR5 0xd4 /* SAI Receive FIFO 5 */ | |
| 60 | +#define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO 6 */ | |
| 61 | +#define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO 7 */ | |
| 34 | 62 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ |
| 35 | 63 | |
| 36 | −#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) | |
| 37 | −#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) | |
| 38 | −#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) | |
| 39 | −#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) | |
| 40 | −#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) | |
| 41 | −#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) | |
| 42 | −#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) | |
| 43 | −#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) | |
| 64 | +#define FSL_SAI_xCSR(tx, ofs) (tx ? FSL_SAI_TCSR(ofs) : FSL_SAI_RCSR(ofs)) | |
| 65 | +#define FSL_SAI_xCR1(tx, ofs) (tx ? FSL_SAI_TCR1(ofs) : FSL_SAI_RCR1(ofs)) | |
| 66 | +#define FSL_SAI_xCR2(tx, ofs) (tx ? FSL_SAI_TCR2(ofs) : FSL_SAI_RCR2(ofs)) | |
| 67 | +#define FSL_SAI_xCR3(tx, ofs) (tx ? FSL_SAI_TCR3(ofs) : FSL_SAI_RCR3(ofs)) | |
| 68 | +#define FSL_SAI_xCR4(tx, ofs) (tx ? FSL_SAI_TCR4(ofs) : FSL_SAI_RCR4(ofs)) | |
| 69 | +#define FSL_SAI_xCR5(tx, ofs) (tx ? FSL_SAI_TCR5(ofs) : FSL_SAI_RCR5(ofs)) | |
| 70 | +#define FSL_SAI_xDR(tx, ofs) (tx ? FSL_SAI_TDR(ofs) : FSL_SAI_RDR(ofs)) | |
| 71 | +#define FSL_SAI_xFR(tx, ofs) (tx ? FSL_SAI_TFR(ofs) : FSL_SAI_RFR(ofs)) | |
| 44 | 72 | #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) |
| 45 | 73 | |
| 46 | 74 | /* SAI Transmit/Receive Control Register */ |
| @@ -82,6 +110,7 @@ · 35 unmodified lines | ||
| 82 | 110 | |
| 83 | 111 | /* SAI Transmit and Receive Configuration 3 Register */ |
| 84 | 112 | #define FSL_SAI_CR3_TRCE BIT(16) |
| 113 | +#define FSL_SAI_CR3_TRCE_MASK GENMASK(23, 16) | |
| 85 | 114 | #define FSL_SAI_CR3_WDFL(x) (x) |
| 86 | 115 | #define FSL_SAI_CR3_WDFL_MASK 0x1f |
| 87 | 116 | |
| @@ -126,6 +155,12 @@ · 38 unmodified lines | ||
| 126 | 155 | #define FSL_SAI_MAXBURST_TX 6 |
| 127 | 156 | #define FSL_SAI_MAXBURST_RX 6 |
| 128 | 157 | |
| 158 | +struct fsl_sai_soc_data { | |
| 159 | + bool use_imx_pcm; | |
| 160 | + unsigned int fifo_depth; | |
| 161 | + unsigned int reg_offset; | |
| 162 | +}; | |
| 163 | + | |
| 129 | 164 | struct fsl_sai { |
| 130 | 165 | struct platform_device *pdev; |
| 131 | 166 | struct regmap *regmap; |
| @@ -135,7 +170,6 @@ struct fsl_sai { · 3 unmodified lines | ||
| 135 | 170 | bool is_slave_mode; |
| 136 | 171 | bool is_lsb_first; |
| 137 | 172 | bool is_dsp_mode; |
| 138 | − bool sai_on_imx; | |
| 139 | 173 | bool synchronous[2]; |
| 140 | 174 | |
| 141 | 175 | unsigned int mclk_id[2]; |
| @@ -143,6 +177,7 @@ struct fsl_sai { · 1 unmodified line | ||
| 143 | 177 | unsigned int slots; |
| 144 | 178 | unsigned int slot_width; |
| 145 | 179 | |
| 180 | + const struct fsl_sai_soc_data *soc_data; | |
| 146 | 181 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
| 147 | 182 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
| 148 | 183 | }; |
| @@ -1248,10 +1248,8 @@ static int fsl_spdif_probe(struct platform_device *pdev) · 1247 unmodified lines | ||
| 1248 | 1248 | } |
| 1249 | 1249 | |
| 1250 | 1250 | irq = platform_get_irq(pdev, 0); |
| 1251 | − if (irq < 0) { | |
| 1252 | − dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | |
| 1251 | + if (irq < 0) | |
| 1253 | 1252 | return irq; |
| 1254 | − } | |
| 1255 | 1253 | |
| 1256 | 1254 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, |
| 1257 | 1255 | dev_name(&pdev->dev), spdif_priv); |
| @@ -1510,10 +1510,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 1509 unmodified lines | ||
| 1510 | 1510 | } |
| 1511 | 1511 | |
| 1512 | 1512 | ssi->irq = platform_get_irq(pdev, 0); |
| 1513 | − if (ssi->irq < 0) { | |
| 1514 | − dev_err(dev, "no irq for node %s\n", pdev->name); | |
| 1513 | + if (ssi->irq < 0) | |
| 1515 | 1514 | return ssi->irq; |
| 1516 | − } | |
| 1517 | 1515 | |
| 1518 | 1516 | /* Set software limitations for synchronous mode except AC97 */ |
| 1519 | 1517 | if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { |
| @@ -325,14 +325,14 @@ static int imx_audmix_probe(struct platform_device *pdev) · 324 unmodified lines | ||
| 325 | 325 | priv->card.num_configs = priv->num_dai_conf; |
| 326 | 326 | priv->card.dapm_routes = priv->dapm_routes; |
| 327 | 327 | priv->card.num_dapm_routes = priv->num_dapm_routes; |
| 328 | − priv->card.dev = pdev->dev.parent; | |
| 328 | + priv->card.dev = &pdev->dev; | |
| 329 | 329 | priv->card.owner = THIS_MODULE; |
| 330 | 330 | priv->card.name = "imx-audmix"; |
| 331 | 331 | |
| 332 | 332 | platform_set_drvdata(pdev, &priv->card); |
| 333 | 333 | snd_soc_card_set_drvdata(&priv->card, priv); |
| 334 | 334 | |
| 335 | − ret = devm_snd_soc_register_card(pdev->dev.parent, &priv->card); | |
| 335 | + ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); | |
| 336 | 336 | if (ret) { |
| 337 | 337 | dev_err(&pdev->dev, "snd_soc_register_card failed\n"); |
| 338 | 338 | return ret; |
| @@ -300,12 +300,10 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, · 299 unmodified lines | ||
| 300 | 300 | |
| 301 | 301 | static int imx_audmux_probe(struct platform_device *pdev) |
| 302 | 302 | { |
| 303 | − struct resource *res; | |
| 304 | 303 | const struct of_device_id *of_id = |
| 305 | 304 | of_match_device(imx_audmux_dt_ids, &pdev->dev); |
| 306 | 305 | |
| 307 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 308 | − audmux_base = devm_ioremap_resource(&pdev->dev, res); | |
| 306 | + audmux_base = devm_platform_ioremap_resource(pdev, 0); | |
| 309 | 307 | if (IS_ERR(audmux_base)) |
| 310 | 308 | return PTR_ERR(audmux_base); |
| 311 | 309 | |
| @@ -520,10 +520,8 @@ static int imx_ssi_probe(struct platform_device *pdev) · 519 unmodified lines | ||
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | ssi->irq = platform_get_irq(pdev, 0); |
| 523 | − if (ssi->irq < 0) { | |
| 524 | − dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); | |
| 523 | + if (ssi->irq < 0) | |
| 525 | 524 | return ssi->irq; |
| 526 | − } | |
| 527 | 525 | |
| 528 | 526 | ssi->clk = devm_clk_get(&pdev->dev, NULL); |
| 529 | 527 | if (IS_ERR(ssi->clk)) { |
| @@ -129,6 +129,25 @@ static int asoc_simple_parse_dai(struct device_node *ep, · 128 unmodified lines | ||
| 129 | 129 | args.args[0] = graph_get_dai_id(ep); |
| 130 | 130 | args.args_count = (of_graph_get_endpoint_count(node) > 1); |
| 131 | 131 | |
| 132 | + /* | |
| 133 | + * FIXME | |
| 134 | + * | |
| 135 | + * Here, dlc->dai_name is pointer to CPU/Codec DAI name. | |
| 136 | + * If user unbinded CPU or Codec driver, but not for Sound Card, | |
| 137 | + * dlc->dai_name is keeping unbinded CPU or Codec | |
| 138 | + * driver's pointer. | |
| 139 | + * | |
| 140 | + * If user re-bind CPU or Codec driver again, ALSA SoC will try | |
| 141 | + * to rebind Card via snd_soc_try_rebind_card(), but because of | |
| 142 | + * above reason, it might can't bind Sound Card. | |
| 143 | + * Because Sound Card is pointing to released dai_name pointer. | |
| 144 | + * | |
| 145 | + * To avoid this rebind Card issue, | |
| 146 | + * 1) It needs to alloc memory to keep dai_name eventhough | |
| 147 | + * CPU or Codec driver was unbinded, or | |
| 148 | + * 2) user need to rebind Sound Card everytime | |
| 149 | + * if he unbinded CPU or Codec. | |
| 150 | + */ | |
| 132 | 151 | ret = snd_soc_get_dai_name(&args, &dlc->dai_name); |
| 133 | 152 | if (ret < 0) |
| 134 | 153 | return ret; |
| @@ -213,10 +213,17 @@ EXPORT_SYMBOL_GPL(asoc_simple_startup); · 212 unmodified lines | ||
| 213 | 213 | void asoc_simple_shutdown(struct snd_pcm_substream *substream) |
| 214 | 214 | { |
| 215 | 215 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 216 | + struct snd_soc_dai *codec_dai = rtd->codec_dai; | |
| 217 | + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | |
| 216 | 218 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
| 217 | 219 | struct simple_dai_props *dai_props = |
| 218 | 220 | simple_priv_to_props(priv, rtd->num); |
| 219 | 221 | |
| 222 | + if (dai_props->mclk_fs) { | |
| 223 | + snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN); | |
| 224 | + snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT); | |
| 225 | + } | |
| 226 | + | |
| 220 | 227 | asoc_simple_clk_disable(dai_props->cpu_dai); |
| 221 | 228 | |
| 222 | 229 | asoc_simple_clk_disable(dai_props->codec_dai); |
| @@ -46,7 +46,25 @@ static int asoc_simple_parse_dai(struct device_node *node, · 45 unmodified lines | ||
| 46 | 46 | if (ret) |
| 47 | 47 | return ret; |
| 48 | 48 | |
| 49 | − /* Get dai->name */ | |
| 49 | + /* | |
| 50 | + * FIXME | |
| 51 | + * | |
| 52 | + * Here, dlc->dai_name is pointer to CPU/Codec DAI name. | |
| 53 | + * If user unbinded CPU or Codec driver, but not for Sound Card, | |
| 54 | + * dlc->dai_name is keeping unbinded CPU or Codec | |
| 55 | + * driver's pointer. | |
| 56 | + * | |
| 57 | + * If user re-bind CPU or Codec driver again, ALSA SoC will try | |
| 58 | + * to rebind Card via snd_soc_try_rebind_card(), but because of | |
| 59 | + * above reason, it might can't bind Sound Card. | |
| 60 | + * Because Sound Card is pointing to released dai_name pointer. | |
| 61 | + * | |
| 62 | + * To avoid this rebind Card issue, | |
| 63 | + * 1) It needs to alloc memory to keep dai_name eventhough | |
| 64 | + * CPU or Codec driver was unbinded, or | |
| 65 | + * 2) user need to rebind Sound Card everytime | |
| 66 | + * if he unbinded CPU or Codec. | |
| 67 | + */ | |
| 50 | 68 | ret = snd_soc_of_get_dai_name(node, &dlc->dai_name); |
| 51 | 69 | if (ret < 0) |
| 52 | 70 | return ret; |
| @@ -424,7 +442,7 @@ static int simple_parse_aux_devs(struct device_node *node, · 371 unmodified lines | ||
| 424 | 442 | aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); |
| 425 | 443 | if (!aux_node) |
| 426 | 444 | return -EINVAL; |
| 427 | − card->aux_dev[i].codec_of_node = aux_node; | |
| 445 | + card->aux_dev[i].dlc.of_node = aux_node; | |
| 428 | 446 | } |
| 429 | 447 | |
| 430 | 448 | card->num_aux_devs = n; |
| @@ -215,6 +215,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON · 214 unmodified lines | ||
| 215 | 215 | select SND_SOC_INTEL_SST |
| 216 | 216 | select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC |
| 217 | 217 | select SND_SOC_ACPI_INTEL_MATCH |
| 218 | + select SND_INTEL_NHLT if ACPI | |
| 218 | 219 | help |
| 219 | 220 | If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ |
| 220 | 221 | GeminiLake or CannonLake platform with the DSP enabled in the BIOS |
| @@ -211,7 +211,7 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt, · 210 unmodified lines | ||
| 211 | 211 | static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) |
| 212 | 212 | { |
| 213 | 213 | struct sst_byt_stream *stream; |
| 214 | − u64 header = msg->header; | |
| 214 | + u64 header = msg->tx.header; | |
| 215 | 215 | u8 stream_id = sst_byt_header_str_id(header); |
| 216 | 216 | u8 stream_msg = sst_byt_header_msg_id(header); |
| 217 | 217 | |
| @@ -240,9 +240,10 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header) · 22 unmodified lines | ||
| 240 | 240 | if (msg == NULL) |
| 241 | 241 | return 1; |
| 242 | 242 | |
| 243 | + msg->rx.header = header; | |
| 243 | 244 | if (header & IPC_HEADER_LARGE(true)) { |
| 244 | − msg->rx_size = sst_byt_header_data(header); | |
| 245 | − sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size); | |
| 245 | + msg->rx.size = sst_byt_header_data(header); | |
| 246 | + sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size); | |
| 246 | 247 | } |
| 247 | 248 | |
| 248 | 249 | /* update any stream states */ |
| @@ -407,17 +408,18 @@ int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream, · 158 unmodified lines | ||
| 407 | 408 | |
| 408 | 409 | int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) |
| 409 | 410 | { |
| 410 | − struct sst_byt_alloc_params *str_req = &stream->request; | |
| 411 | − struct sst_byt_alloc_response *reply = &stream->reply; | |
| 412 | − u64 header; | |
| 411 | + struct sst_ipc_message request, reply = {0}; | |
| 413 | 412 | int ret; |
| 414 | 413 | |
| 415 | − header = sst_byt_header(IPC_IA_ALLOC_STREAM, | |
| 416 | − sizeof(*str_req) + sizeof(u32), | |
| 414 | + request.header = sst_byt_header(IPC_IA_ALLOC_STREAM, | |
| 415 | + sizeof(stream->request) + sizeof(u32), | |
| 417 | 416 | true, stream->str_id); |
| 418 | − ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req, | |
| 419 | − sizeof(*str_req), | |
| 420 | − reply, sizeof(*reply)); | |
| 417 | + request.data = &stream->request; | |
| 418 | + request.size = sizeof(stream->request); | |
| 419 | + reply.data = &stream->reply; | |
| 420 | + reply.size = sizeof(stream->reply); | |
| 421 | + | |
| 422 | + ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply); | |
| 421 | 423 | if (ret < 0) { |
| 422 | 424 | dev_err(byt->dev, "ipc: error stream commit failed\n"); |
| 423 | 425 | return ret; |
| @@ -430,7 +432,7 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) · 6 unmodified lines | ||
| 430 | 432 | |
| 431 | 433 | int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) |
| 432 | 434 | { |
| 433 | − u64 header; | |
| 435 | + struct sst_ipc_message request = {0}; | |
| 434 | 436 | int ret = 0; |
| 435 | 437 | struct sst_dsp *sst = byt->dsp; |
| 436 | 438 | unsigned long flags; |
| @@ -438,8 +440,9 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) · 1 unmodified line | ||
| 438 | 440 | if (!stream->commited) |
| 439 | 441 | goto out; |
| 440 | 442 | |
| 441 | − header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); | |
| 442 | − ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0); | |
| 443 | + request.header = sst_byt_header(IPC_IA_FREE_STREAM, | |
| 444 | + 0, false, stream->str_id); | |
| 445 | + ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL); | |
| 443 | 446 | if (ret < 0) { |
| 444 | 447 | dev_err(byt->dev, "ipc: free stream %d failed\n", |
| 445 | 448 | stream->str_id); |
| @@ -459,15 +462,13 @@ out: · 13 unmodified lines | ||
| 459 | 462 | static int sst_byt_stream_operations(struct sst_byt *byt, int type, |
| 460 | 463 | int stream_id, int wait) |
| 461 | 464 | { |
| 462 | − u64 header; | |
| 465 | + struct sst_ipc_message request = {0}; | |
| 463 | 466 | |
| 464 | − header = sst_byt_header(type, 0, false, stream_id); | |
| 467 | + request.header = sst_byt_header(type, 0, false, stream_id); | |
| 465 | 468 | if (wait) |
| 466 | − return sst_ipc_tx_message_wait(&byt->ipc, header, NULL, | |
| 467 | − 0, NULL, 0); | |
| 469 | + return sst_ipc_tx_message_wait(&byt->ipc, request, NULL); | |
| 468 | 470 | else |
| 469 | − return sst_ipc_tx_message_nowait(&byt->ipc, header, | |
| 470 | − NULL, 0); | |
| 471 | + return sst_ipc_tx_message_nowait(&byt->ipc, request); | |
| 471 | 472 | } |
| 472 | 473 | |
| 473 | 474 | /* stream ALSA trigger operations */ |
| @@ -475,19 +476,17 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream, · 1 unmodified line | ||
| 475 | 476 | u32 start_offset) |
| 476 | 477 | { |
| 477 | 478 | struct sst_byt_start_stream_params start_stream; |
| 478 | − void *tx_msg; | |
| 479 | − size_t size; | |
| 480 | − u64 header; | |
| 479 | + struct sst_ipc_message request; | |
| 481 | 480 | int ret; |
| 482 | 481 | |
| 483 | 482 | start_stream.byte_offset = start_offset; |
| 484 | − header = sst_byt_header(IPC_IA_START_STREAM, | |
| 483 | + request.header = sst_byt_header(IPC_IA_START_STREAM, | |
| 485 | 484 | sizeof(start_stream) + sizeof(u32), |
| 486 | 485 | true, stream->str_id); |
| 487 | − tx_msg = &start_stream; | |
| 488 | − size = sizeof(start_stream); | |
| 486 | + request.data = &start_stream; | |
| 487 | + request.size = sizeof(start_stream); | |
| 489 | 488 | |
| 490 | − ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size); | |
| 489 | + ret = sst_ipc_tx_message_nowait(&byt->ipc, request); | |
| 491 | 490 | if (ret < 0) |
| 492 | 491 | dev_err(byt->dev, "ipc: error failed to start stream %d\n", |
| 493 | 492 | stream->str_id); |
| @@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); · 129 unmodified lines | ||
| 623 | 622 | |
| 624 | 623 | static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
| 625 | 624 | { |
| 626 | − if (msg->header & IPC_HEADER_LARGE(true)) | |
| 627 | − sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | |
| 625 | + if (msg->tx.header & IPC_HEADER_LARGE(true)) | |
| 626 | + sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); | |
| 628 | 627 | |
| 629 | − sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header); | |
| 628 | + sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header); | |
| 630 | 629 | } |
| 631 | 630 | |
| 632 | 631 | static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text) |
| @@ -648,9 +647,9 @@ static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data, · 15 unmodified lines | ||
| 648 | 647 | size_t tx_size) |
| 649 | 648 | { |
| 650 | 649 | /* msg content = lower 32-bit of the header + data */ |
| 651 | − *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1); | |
| 652 | − memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size); | |
| 653 | − msg->tx_size += sizeof(u32); | |
| 650 | + *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1); | |
| 651 | + memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size); | |
| 652 | + msg->tx.size += sizeof(u32); | |
| 654 | 653 | } |
| 655 | 654 | |
| 656 | 655 | static u64 byt_reply_msg_match(u64 header, u64 *mask) |
| @@ -256,16 +256,20 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH · 255 unmodified lines | ||
| 256 | 256 | |
| 257 | 257 | endif ## SND_SOC_INTEL_SKL |
| 258 | 258 | |
| 259 | +config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC | |
| 260 | + tristate | |
| 261 | + select SND_SOC_DA7219 | |
| 262 | + select SND_SOC_MAX98357A | |
| 263 | + select SND_SOC_DMIC | |
| 264 | + select SND_SOC_HDAC_HDMI | |
| 265 | + | |
| 259 | 266 | if SND_SOC_INTEL_APL |
| 260 | 267 | |
| 261 | 268 | config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH |
| 262 | 269 | tristate "Broxton with DA7219 and MAX98357A in I2S Mode" |
| 263 | 270 | depends on I2C && ACPI |
| 264 | 271 | depends on MFD_INTEL_LPSS || COMPILE_TEST |
| 265 | − select SND_SOC_DA7219 | |
| 266 | − select SND_SOC_MAX98357A | |
| 267 | − select SND_SOC_DMIC | |
| 268 | − select SND_SOC_HDAC_HDMI | |
| 272 | + select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC | |
| 269 | 273 | select SND_HDA_DSP_LOADER |
| 270 | 274 | help |
| 271 | 275 | This adds support for ASoC machine driver for Broxton-P platforms |
| @@ -326,10 +330,7 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH · 54 unmodified lines | ||
| 326 | 330 | tristate "KBL with DA7219 and MAX98357A in I2S Mode" |
| 327 | 331 | depends on I2C && ACPI |
| 328 | 332 | depends on MFD_INTEL_LPSS || COMPILE_TEST |
| 329 | − select SND_SOC_DA7219 | |
| 330 | − select SND_SOC_MAX98357A | |
| 331 | − select SND_SOC_DMIC | |
| 332 | − select SND_SOC_HDAC_HDMI | |
| 333 | + select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC | |
| 333 | 334 | help |
| 334 | 335 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
| 335 | 336 | create an alsa sound card for DA7219 + MAX98357A I2S audio codec. |
| @@ -387,6 +388,7 @@ if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC · 51 unmodified lines | ||
| 387 | 388 | config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH |
| 388 | 389 | tristate "SKL/KBL/BXT/APL with HDA Codecs" |
| 389 | 390 | select SND_SOC_HDAC_HDMI |
| 391 | + select SND_SOC_DMIC | |
| 390 | 392 | # SND_SOC_HDAC_HDA is already selected |
| 391 | 393 | help |
| 392 | 394 | This adds support for ASoC machine driver for Intel platforms |
| @@ -412,4 +414,14 @@ config SND_SOC_INTEL_SOF_RT5682_MACH · 19 unmodified lines | ||
| 412 | 414 | If unsure select "N". |
| 413 | 415 | endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL |
| 414 | 416 | |
| 417 | +if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK) | |
| 418 | + | |
| 419 | +config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH | |
| 420 | + tristate "CML_LP with DA7219 and MAX98357A in I2S Mode" | |
| 421 | + depends on I2C && ACPI | |
| 422 | + depends on MFD_INTEL_LPSS || COMPILE_TEST | |
| 423 | + select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC | |
| 424 | + | |
| 425 | +endif ## SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK | |
| 426 | + | |
| 415 | 427 | endif ## SND_SOC_INTEL_MACH |
| @@ -340,7 +340,6 @@ static int bdw_rt5677_probe(struct platform_device *pdev) · 339 unmodified lines | ||
| 340 | 340 | { |
| 341 | 341 | struct bdw_rt5677_priv *bdw_rt5677; |
| 342 | 342 | struct snd_soc_acpi_mach *mach; |
| 343 | − const char *platform_name = NULL; | |
| 344 | 343 | int ret; |
| 345 | 344 | |
| 346 | 345 | bdw_rt5677_card.dev = &pdev->dev; |
| @@ -355,11 +354,8 @@ static int bdw_rt5677_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 355 | 354 | |
| 356 | 355 | /* override plaform name, if required */ |
| 357 | 356 | mach = (&pdev->dev)->platform_data; |
| 358 | − if (mach) /* extra check since legacy does not pass parameters */ | |
| 359 | − platform_name = mach->mach_params.platform; | |
| 360 | − | |
| 361 | 357 | ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card, |
| 362 | − platform_name); | |
| 358 | + mach->mach_params.platform); | |
| 363 | 359 | if (ret) |
| 364 | 360 | return ret; |
| 365 | 361 | |
| @@ -270,18 +270,14 @@ static struct snd_soc_card broadwell_rt286 = { · 269 unmodified lines | ||
| 270 | 270 | static int broadwell_audio_probe(struct platform_device *pdev) |
| 271 | 271 | { |
| 272 | 272 | struct snd_soc_acpi_mach *mach; |
| 273 | − const char *platform_name = NULL; | |
| 274 | 273 | int ret; |
| 275 | 274 | |
| 276 | 275 | broadwell_rt286.dev = &pdev->dev; |
| 277 | 276 | |
| 278 | 277 | /* override plaform name, if required */ |
| 279 | 278 | mach = (&pdev->dev)->platform_data; |
| 280 | − if (mach) /* extra check since legacy does not pass parameters */ | |
| 281 | − platform_name = mach->mach_params.platform; | |
| 282 | − | |
| 283 | 279 | ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, |
| 284 | − platform_name); | |
| 280 | + mach->mach_params.platform); | |
| 285 | 281 | if (ret) |
| 286 | 282 | return ret; |
| 287 | 283 | |
| @@ -179,10 +179,17 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) · 178 unmodified lines | ||
| 179 | 179 | int ret; |
| 180 | 180 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 181 | 181 | struct snd_soc_component *component = rtd->codec_dai->component; |
| 182 | + int clk_freq; | |
| 182 | 183 | |
| 183 | 184 | /* Configure sysclk for codec */ |
| 184 | − ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000, | |
| 185 | + if (soc_intel_is_cml()) | |
| 186 | + clk_freq = 24000000; | |
| 187 | + else | |
| 188 | + clk_freq = 19200000; | |
| 189 | + | |
| 190 | + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, | |
| 185 | 191 | SND_SOC_CLOCK_IN); |
| 192 | + | |
| 186 | 193 | if (ret) { |
| 187 | 194 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); |
| 188 | 195 | return ret; |
| @@ -683,6 +690,25 @@ static int broxton_audio_probe(struct platform_device *pdev) · 494 unmodified lines | ||
| 683 | 690 | broxton_dais[i].cpus->dai_name = "SSP2 Pin"; |
| 684 | 691 | } |
| 685 | 692 | } |
| 693 | + } else if (soc_intel_is_cml()) { | |
| 694 | + unsigned int i; | |
| 695 | + | |
| 696 | + broxton_audio_card.name = "cmlda7219max"; | |
| 697 | + | |
| 698 | + for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { | |
| 699 | + /* MAXIM_CODEC is connected to SSP1. */ | |
| 700 | + if (!strcmp(broxton_dais[i].codecs->dai_name, | |
| 701 | + BXT_MAXIM_CODEC_DAI)) { | |
| 702 | + broxton_dais[i].name = "SSP1-Codec"; | |
| 703 | + broxton_dais[i].cpus->dai_name = "SSP1 Pin"; | |
| 704 | + } | |
| 705 | + /* DIALOG_CODEC is connected to SSP0 */ | |
| 706 | + else if (!strcmp(broxton_dais[i].codecs->dai_name, | |
| 707 | + BXT_DIALOG_CODEC_DAI)) { | |
| 708 | + broxton_dais[i].name = "SSP0-Codec"; | |
| 709 | + broxton_dais[i].cpus->dai_name = "SSP0 Pin"; | |
| 710 | + } | |
| 711 | + } | |
| 686 | 712 | } |
| 687 | 713 | |
| 688 | 714 | /* override plaform name, if required */ |
| @@ -700,6 +726,7 @@ static int broxton_audio_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 700 | 726 | static const struct platform_device_id bxt_board_ids[] = { |
| 701 | 727 | { .name = "bxt_da7219_max98357a" }, |
| 702 | 728 | { .name = "glk_da7219_max98357a" }, |
| 729 | + { .name = "cml_da7219_max98357a" }, | |
| 703 | 730 | { } |
| 704 | 731 | }; |
| 705 | 732 | |
| @@ -720,6 +747,8 @@ MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>"); · 14 unmodified lines | ||
| 720 | 747 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); |
| 721 | 748 | MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); |
| 722 | 749 | MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); |
| 750 | +MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); | |
| 723 | 751 | MODULE_LICENSE("GPL v2"); |
| 724 | 752 | MODULE_ALIAS("platform:bxt_da7219_max98357a"); |
| 725 | 753 | MODULE_ALIAS("platform:glk_da7219_max98357a"); |
| 754 | +MODULE_ALIAS("platform:cml_da7219_max98357a"); | |
| @@ -324,9 +324,8 @@ static const struct snd_soc_ops cht_be_ssp2_ops = { · 323 unmodified lines | ||
| 324 | 324 | }; |
| 325 | 325 | |
| 326 | 326 | static struct snd_soc_aux_dev cht_max98090_headset_dev = { |
| 327 | − .name = "Headset Chip", | |
| 327 | + .dlc = COMP_AUX("i2c-104C227E:00"), | |
| 328 | 328 | .init = cht_max98090_headset_init, |
| 329 | − .codec_name = "i2c-104C227E:00", | |
| 330 | 329 | }; |
| 331 | 330 | |
| 332 | 331 | SND_SOC_DAILINK_DEF(dummy, |
| @@ -188,18 +188,14 @@ static struct snd_soc_card haswell_rt5640 = { · 187 unmodified lines | ||
| 188 | 188 | static int haswell_audio_probe(struct platform_device *pdev) |
| 189 | 189 | { |
| 190 | 190 | struct snd_soc_acpi_mach *mach; |
| 191 | − const char *platform_name = NULL; | |
| 192 | 191 | int ret; |
| 193 | 192 | |
| 194 | 193 | haswell_rt5640.dev = &pdev->dev; |
| 195 | 194 | |
| 196 | 195 | /* override plaform name, if required */ |
| 197 | 196 | mach = (&pdev->dev)->platform_data; |
| 198 | − if (mach) /* extra check since legacy does not pass parameters */ | |
| 199 | − platform_name = mach->mach_params.platform; | |
| 200 | − | |
| 201 | 197 | ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, |
| 202 | − platform_name); | |
| 198 | + mach->mach_params.platform); | |
| 203 | 199 | if (ret) |
| 204 | 200 | return ret; |
| 205 | 201 | |
| @@ -147,6 +147,11 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card) · 146 unmodified lines | ||
| 147 | 147 | if (err) |
| 148 | 148 | return err; |
| 149 | 149 | |
| 150 | + err = snd_jack_add_new_kctl(pcm->hdmi_jack.jack, | |
| 151 | + jack_name, SND_JACK_AVOUT); | |
| 152 | + if (err) | |
| 153 | + dev_warn(component->dev, "failed creating Jack kctl\n"); | |
| 154 | + | |
| 150 | 155 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, |
| 151 | 156 | &pcm->hdmi_jack); |
| 152 | 157 | if (err < 0) |
| @@ -23,6 +23,7 @@ static const struct snd_soc_dapm_widget skl_hda_widgets[] = { · 22 unmodified lines | ||
| 23 | 23 | SND_SOC_DAPM_MIC("Alt Analog In", NULL), |
| 24 | 24 | SND_SOC_DAPM_SPK("Digital Out", NULL), |
| 25 | 25 | SND_SOC_DAPM_MIC("Digital In", NULL), |
| 26 | + SND_SOC_DAPM_MIC("SoC DMIC", NULL), | |
| 26 | 27 | }; |
| 27 | 28 | |
| 28 | 29 | static const struct snd_soc_dapm_route skl_hda_map[] = { |
| @@ -41,6 +42,9 @@ static const struct snd_soc_dapm_route skl_hda_map[] = { · 12 unmodified lines | ||
| 41 | 42 | { "Codec Input Pin2", NULL, "Digital In" }, |
| 42 | 43 | { "Codec Input Pin3", NULL, "Alt Analog In" }, |
| 43 | 44 | |
| 45 | + /* digital mics */ | |
| 46 | + {"DMic", NULL, "SoC DMIC"}, | |
| 47 | + | |
| 44 | 48 | /* CODEC BE connections */ |
| 45 | 49 | { "Analog Codec Playback", NULL, "Analog CPU Playback" }, |
| 46 | 50 | { "Analog CPU Playback", NULL, "codec0_out" }, |
| @@ -91,8 +91,7 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { · 90 unmodified lines | ||
| 91 | 91 | { |
| 92 | 92 | .callback = sof_rt5682_quirk_cb, |
| 93 | 93 | .matches = { |
| 94 | − DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
| 95 | − DMI_MATCH(DMI_PRODUCT_NAME, "Hatch"), | |
| 94 | + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), | |
| 96 | 95 | }, |
| 97 | 96 | .driver_data = (void *)(SOF_RT5682_MCLK_EN | |
| 98 | 97 | SOF_RT5682_MCLK_24MHZ | |
| @@ -8,6 +8,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m · 7 unmodified lines | ||
| 8 | 8 | soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ |
| 9 | 9 | soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ |
| 10 | 10 | soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \ |
| 11 | + soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \ | |
| 11 | 12 | soc-acpi-intel-hda-match.o |
| 12 | 13 | |
| 13 | 14 | obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o |
| @@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs cml_codecs = { · 18 unmodified lines | ||
| 19 | 19 | .codecs = {"10EC5682"} |
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | +static struct snd_soc_acpi_codecs cml_spk_codecs = { | |
| 23 | + .num_codecs = 1, | |
| 24 | + .codecs = {"MX98357A"} | |
| 25 | +}; | |
| 26 | + | |
| 22 | 27 | struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { |
| 23 | 28 | { |
| 24 | 29 | .id = "INT34C2", |
| @@ -28,6 +33,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { · 3 unmodified lines | ||
| 28 | 33 | .sof_fw_filename = "sof-cnl.ri", |
| 29 | 34 | .sof_tplg_filename = "sof-cnl-rt274.tplg", |
| 30 | 35 | }, |
| 36 | + { | |
| 37 | + .id = "DLGS7219", | |
| 38 | + .drv_name = "cml_da7219_max98357a", | |
| 39 | + .quirk_data = &cml_spk_codecs, | |
| 40 | + .sof_fw_filename = "sof-cnl.ri", | |
| 41 | + .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg", | |
| 42 | + }, | |
| 31 | 43 | { |
| 32 | 44 | .id = "MX98357A", |
| 33 | 45 | .drv_name = "sof_rt5682", |
| @@ -0,0 +1,18 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * soc-apci-intel-ehl-match.c - tables and support for EHL ACPI enumeration. | |
| 4 | + * | |
| 5 | + * Copyright (c) 2019, Intel Corporation. | |
| 6 | + * | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <sound/soc-acpi.h> | |
| 10 | +#include <sound/soc-acpi-intel-match.h> | |
| 11 | + | |
| 12 | +struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = { | |
| 13 | + {}, | |
| 14 | +}; | |
| 15 | +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines); | |
| 16 | + | |
| 17 | +MODULE_LICENSE("GPL v2"); | |
| 18 | +MODULE_DESCRIPTION("Intel Common ACPI Match module"); | |
| @@ -0,0 +1,24 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * soc-apci-intel-tgl-match.c - tables and support for ICL ACPI enumeration. | |
| 4 | + * | |
| 5 | + * Copyright (c) 2019, Intel Corporation. | |
| 6 | + * | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <sound/soc-acpi.h> | |
| 10 | +#include <sound/soc-acpi-intel-match.h> | |
| 11 | + | |
| 12 | +struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = { | |
| 13 | + { | |
| 14 | + .id = "10EC1308", | |
| 15 | + .drv_name = "tgl_rt1308", | |
| 16 | + .sof_fw_filename = "sof-tgl.ri", | |
| 17 | + .sof_tplg_filename = "sof-tgl-rt1308.tplg", | |
| 18 | + }, | |
| 19 | + {}, | |
| 20 | +}; | |
| 21 | +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines); | |
| 22 | + | |
| 23 | +MODULE_LICENSE("GPL v2"); | |
| 24 | +MODULE_DESCRIPTION("Intel Common ACPI Match module"); | |
| @@ -36,6 +36,7 @@ SOC_INTEL_IS_CPU(byt, INTEL_FAM6_ATOM_SILVERMONT); · 35 unmodified lines | ||
| 36 | 36 | SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT); |
| 37 | 37 | SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT); |
| 38 | 38 | SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS); |
| 39 | +SOC_INTEL_IS_CPU(cml, INTEL_FAM6_KABYLAKE_MOBILE); | |
| 39 | 40 | |
| 40 | 41 | static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) |
| 41 | 42 | { |
| @@ -110,6 +111,10 @@ static inline bool soc_intel_is_glk(void) · 68 unmodified lines | ||
| 110 | 111 | return false; |
| 111 | 112 | } |
| 112 | 113 | |
| 114 | +static inline bool soc_intel_is_cml(void) | |
| 115 | +{ | |
| 116 | + return false; | |
| 117 | +} | |
| 113 | 118 | #endif |
| 114 | 119 | |
| 115 | 120 | #endif /* _SND_SOC_INTEL_QUIRKS_H */ |
| @@ -141,11 +141,12 @@ static int sst_acpi_probe(struct platform_device *pdev) · 140 unmodified lines | ||
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | platform_set_drvdata(pdev, sst_acpi); |
| 144 | + mach->pdata = sst_pdata; | |
| 144 | 145 | |
| 145 | 146 | /* register machine driver */ |
| 146 | 147 | sst_acpi->pdev_mach = |
| 147 | 148 | platform_device_register_data(dev, mach->drv_name, -1, |
| 148 | − sst_pdata, sizeof(*sst_pdata)); | |
| 149 | + mach, sizeof(*mach)); | |
| 149 | 150 | if (IS_ERR(sst_acpi->pdev_mach)) |
| 150 | 151 | return PTR_ERR(sst_acpi->pdev_mach); |
| 151 | 152 | |
| @@ -43,7 +43,7 @@ static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) · 42 unmodified lines | ||
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | static int tx_wait_done(struct sst_generic_ipc *ipc, |
| 46 | − struct ipc_message *msg, void *rx_data) | |
| 46 | + struct ipc_message *msg, struct sst_ipc_message *reply) | |
| 47 | 47 | { |
| 48 | 48 | unsigned long flags; |
| 49 | 49 | int ret; |
| @@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc, · 12 unmodified lines | ||
| 62 | 62 | } else { |
| 63 | 63 | |
| 64 | 64 | /* copy the data returned from DSP */ |
| 65 | − if (rx_data) | |
| 66 | − memcpy(rx_data, msg->rx_data, msg->rx_size); | |
| 65 | + if (reply) { | |
| 66 | + reply->header = msg->rx.header; | |
| 67 | + if (reply->data) | |
| 68 | + memcpy(reply->data, msg->rx.data, msg->rx.size); | |
| 69 | + } | |
| 67 | 70 | ret = msg->errno; |
| 68 | 71 | } |
| 69 | 72 | |
| @@ -72,9 +75,9 @@ static int tx_wait_done(struct sst_generic_ipc *ipc, · 2 unmodified lines | ||
| 72 | 75 | return ret; |
| 73 | 76 | } |
| 74 | 77 | |
| 75 | −static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, | |
| 76 | − void *tx_data, size_t tx_bytes, void *rx_data, | |
| 77 | − size_t rx_bytes, int wait) | |
| 78 | +static int ipc_tx_message(struct sst_generic_ipc *ipc, | |
| 79 | + struct sst_ipc_message request, | |
| 80 | + struct sst_ipc_message *reply, int wait) | |
| 78 | 81 | { |
| 79 | 82 | struct ipc_message *msg; |
| 80 | 83 | unsigned long flags; |
| @@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, · 6 unmodified lines | ||
| 87 | 90 | return -EBUSY; |
| 88 | 91 | } |
| 89 | 92 | |
| 90 | − msg->header = header; | |
| 91 | − msg->tx_size = tx_bytes; | |
| 92 | − msg->rx_size = rx_bytes; | |
| 93 | + msg->tx.header = request.header; | |
| 94 | + msg->tx.size = request.size; | |
| 95 | + msg->rx.header = 0; | |
| 96 | + msg->rx.size = reply ? reply->size : 0; | |
| 93 | 97 | msg->wait = wait; |
| 94 | 98 | msg->errno = 0; |
| 95 | 99 | msg->pending = false; |
| 96 | 100 | msg->complete = false; |
| 97 | 101 | |
| 98 | − if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL)) | |
| 99 | − ipc->ops.tx_data_copy(msg, tx_data, tx_bytes); | |
| 102 | + if ((request.size) && (ipc->ops.tx_data_copy != NULL)) | |
| 103 | + ipc->ops.tx_data_copy(msg, request.data, request.size); | |
| 100 | 104 | |
| 101 | 105 | list_add_tail(&msg->list, &ipc->tx_list); |
| 102 | 106 | schedule_work(&ipc->kwork); |
| 103 | 107 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); |
| 104 | 108 | |
| 105 | 109 | if (wait) |
| 106 | − return tx_wait_done(ipc, msg, rx_data); | |
| 110 | + return tx_wait_done(ipc, msg, reply); | |
| 107 | 111 | else |
| 108 | 112 | return 0; |
| 109 | 113 | } |
| @@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) · 8 unmodified lines | ||
| 118 | 122 | return -ENOMEM; |
| 119 | 123 | |
| 120 | 124 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { |
| 121 | − ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); | |
| 122 | − if (ipc->msg[i].tx_data == NULL) | |
| 125 | + ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); | |
| 126 | + if (ipc->msg[i].tx.data == NULL) | |
| 123 | 127 | goto free_mem; |
| 124 | 128 | |
| 125 | − ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); | |
| 126 | − if (ipc->msg[i].rx_data == NULL) { | |
| 127 | − kfree(ipc->msg[i].tx_data); | |
| 129 | + ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); | |
| 130 | + if (ipc->msg[i].rx.data == NULL) { | |
| 131 | + kfree(ipc->msg[i].tx.data); | |
| 128 | 132 | goto free_mem; |
| 129 | 133 | } |
| 130 | 134 | |
| @@ -136,8 +140,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) · 5 unmodified lines | ||
| 136 | 140 | |
| 137 | 141 | free_mem: |
| 138 | 142 | while (i > 0) { |
| 139 | − kfree(ipc->msg[i-1].tx_data); | |
| 140 | − kfree(ipc->msg[i-1].rx_data); | |
| 143 | + kfree(ipc->msg[i-1].tx.data); | |
| 144 | + kfree(ipc->msg[i-1].rx.data); | |
| 141 | 145 | --i; |
| 142 | 146 | } |
| 143 | 147 | kfree(ipc->msg); |
| @@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work) · 29 unmodified lines | ||
| 173 | 177 | spin_unlock_irq(&ipc->dsp->spinlock); |
| 174 | 178 | } |
| 175 | 179 | |
| 176 | −int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, | |
| 177 | − void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) | |
| 180 | +int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, | |
| 181 | + struct sst_ipc_message request, struct sst_ipc_message *reply) | |
| 178 | 182 | { |
| 179 | 183 | int ret; |
| 180 | 184 | |
| @@ -187,8 +191,7 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, · 6 unmodified lines | ||
| 187 | 191 | if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) |
| 188 | 192 | return -EIO; |
| 189 | 193 | |
| 190 | − ret = ipc_tx_message(ipc, header, tx_data, tx_bytes, | |
| 191 | − rx_data, rx_bytes, 1); | |
| 194 | + ret = ipc_tx_message(ipc, request, reply, 1); | |
| 192 | 195 | |
| 193 | 196 | if (ipc->ops.check_dsp_lp_on) |
| 194 | 197 | if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) |
| @@ -198,19 +201,17 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, · 3 unmodified lines | ||
| 198 | 201 | } |
| 199 | 202 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); |
| 200 | 203 | |
| 201 | −int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, | |
| 202 | − void *tx_data, size_t tx_bytes) | |
| 204 | +int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, | |
| 205 | + struct sst_ipc_message request) | |
| 203 | 206 | { |
| 204 | − return ipc_tx_message(ipc, header, tx_data, tx_bytes, | |
| 205 | − NULL, 0, 0); | |
| 207 | + return ipc_tx_message(ipc, request, NULL, 0); | |
| 206 | 208 | } |
| 207 | 209 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); |
| 208 | 210 | |
| 209 | −int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, | |
| 210 | − void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) | |
| 211 | +int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, | |
| 212 | + struct sst_ipc_message request, struct sst_ipc_message *reply) | |
| 211 | 213 | { |
| 212 | − return ipc_tx_message(ipc, header, tx_data, tx_bytes, | |
| 213 | − rx_data, rx_bytes, 1); | |
| 214 | + return ipc_tx_message(ipc, request, reply, 1); | |
| 214 | 215 | } |
| 215 | 216 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); |
| 216 | 217 | |
| @@ -232,7 +233,7 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, · 15 unmodified lines | ||
| 232 | 233 | } |
| 233 | 234 | |
| 234 | 235 | list_for_each_entry(msg, &ipc->rx_list, list) { |
| 235 | − if ((msg->header & mask) == header) | |
| 236 | + if ((msg->tx.header & mask) == header) | |
| 236 | 237 | return msg; |
| 237 | 238 | } |
| 238 | 239 | |
| @@ -306,8 +307,8 @@ void sst_ipc_fini(struct sst_generic_ipc *ipc) · 67 unmodified lines | ||
| 306 | 307 | |
| 307 | 308 | if (ipc->msg) { |
| 308 | 309 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { |
| 309 | − kfree(ipc->msg[i].tx_data); | |
| 310 | − kfree(ipc->msg[i].rx_data); | |
| 310 | + kfree(ipc->msg[i].tx.data); | |
| 311 | + kfree(ipc->msg[i].rx.data); | |
| 311 | 312 | } |
| 312 | 313 | kfree(ipc->msg); |
| 313 | 314 | } |
| @@ -17,15 +17,16 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #define IPC_MAX_MAILBOX_BYTES 256 |
| 19 | 19 | |
| 20 | −struct ipc_message { | |
| 21 | − struct list_head list; | |
| 20 | +struct sst_ipc_message { | |
| 22 | 21 | u64 header; |
| 22 | + void *data; | |
| 23 | + size_t size; | |
| 24 | +}; | |
| 23 | 25 | |
| 24 | − /* direction wrt host CPU */ | |
| 25 | − char *tx_data; | |
| 26 | − size_t tx_size; | |
| 27 | − char *rx_data; | |
| 28 | − size_t rx_size; | |
| 26 | +struct ipc_message { | |
| 27 | + struct list_head list; | |
| 28 | + struct sst_ipc_message tx; | |
| 29 | + struct sst_ipc_message rx; | |
| 29 | 30 | |
| 30 | 31 | wait_queue_head_t waitq; |
| 31 | 32 | bool pending; |
| @@ -35,6 +36,7 @@ struct ipc_message { · 3 unmodified lines | ||
| 35 | 36 | }; |
| 36 | 37 | |
| 37 | 38 | struct sst_generic_ipc; |
| 39 | +struct sst_dsp; | |
| 38 | 40 | |
| 39 | 41 | struct sst_plat_ipc_ops { |
| 40 | 42 | void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); |
| @@ -65,14 +67,14 @@ struct sst_generic_ipc { · 24 unmodified lines | ||
| 65 | 67 | struct sst_plat_ipc_ops ops; |
| 66 | 68 | }; |
| 67 | 69 | |
| 68 | −int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, | |
| 69 | − void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); | |
| 70 | +int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, | |
| 71 | + struct sst_ipc_message request, struct sst_ipc_message *reply); | |
| 70 | 72 | |
| 71 | −int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, | |
| 72 | − void *tx_data, size_t tx_bytes); | |
| 73 | +int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, | |
| 74 | + struct sst_ipc_message request); | |
| 73 | 75 | |
| 74 | −int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, | |
| 75 | − void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); | |
| 76 | +int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, | |
| 77 | + struct sst_ipc_message request, struct sst_ipc_message *reply); | |
| 76 | 78 | |
| 77 | 79 | struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, |
| 78 | 80 | u64 header); |
| @@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work) · 510 unmodified lines | ||
| 511 | 511 | static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) |
| 512 | 512 | { |
| 513 | 513 | struct sst_hsw_stream *stream; |
| 514 | − u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK); | |
| 514 | + u32 header = msg->tx.header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK); | |
| 515 | 515 | u32 stream_id = msg_get_stream_id(header); |
| 516 | 516 | u32 stream_msg = msg_get_stream_type(header); |
| 517 | 517 | |
| @@ -552,6 +552,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header) · 34 unmodified lines | ||
| 552 | 552 | return -EIO; |
| 553 | 553 | } |
| 554 | 554 | |
| 555 | + msg->rx.header = header; | |
| 555 | 556 | /* first process the header */ |
| 556 | 557 | switch (reply) { |
| 557 | 558 | case IPC_GLB_REPLY_PENDING: |
| @@ -562,13 +563,13 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header) · 4 unmodified lines | ||
| 562 | 563 | case IPC_GLB_REPLY_SUCCESS: |
| 563 | 564 | if (msg->pending) { |
| 564 | 565 | trace_ipc_pending_reply("completed", header); |
| 565 | − sst_dsp_inbox_read(hsw->dsp, msg->rx_data, | |
| 566 | − msg->rx_size); | |
| 566 | + sst_dsp_inbox_read(hsw->dsp, msg->rx.data, | |
| 567 | + msg->rx.size); | |
| 567 | 568 | hsw->ipc.pending = false; |
| 568 | 569 | } else { |
| 569 | 570 | /* copy data from the DSP */ |
| 570 | − sst_dsp_outbox_read(hsw->dsp, msg->rx_data, | |
| 571 | − msg->rx_size); | |
| 571 | + sst_dsp_outbox_read(hsw->dsp, msg->rx.data, | |
| 572 | + msg->rx.size); | |
| 572 | 573 | } |
| 573 | 574 | break; |
| 574 | 575 | /* these will be rare - but useful for debug */ |
| @@ -810,11 +811,13 @@ static irqreturn_t hsw_irq_thread(int irq, void *context) · 235 unmodified lines | ||
| 810 | 811 | int sst_hsw_fw_get_version(struct sst_hsw *hsw, |
| 811 | 812 | struct sst_hsw_ipc_fw_version *version) |
| 812 | 813 | { |
| 814 | + struct sst_ipc_message request = {0}, reply = {0}; | |
| 813 | 815 | int ret; |
| 814 | 816 | |
| 815 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, | |
| 816 | − IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), | |
| 817 | − NULL, 0, version, sizeof(*version)); | |
| 817 | + request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION); | |
| 818 | + reply.data = version; | |
| 819 | + reply.size = sizeof(*version); | |
| 820 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); | |
| 818 | 821 | if (ret < 0) |
| 819 | 822 | dev_err(hsw->dev, "error: get version failed\n"); |
| 820 | 823 | |
| @@ -840,7 +843,7 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, · 19 unmodified lines | ||
| 840 | 843 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) |
| 841 | 844 | { |
| 842 | 845 | struct sst_hsw_ipc_volume_req *req; |
| 843 | − u32 header; | |
| 846 | + struct sst_ipc_message request; | |
| 844 | 847 | int ret; |
| 845 | 848 | |
| 846 | 849 | trace_ipc_request("set stream volume", stream->reply.stream_hw_id); |
| @@ -848,11 +851,11 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, · 1 unmodified line | ||
| 848 | 851 | if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) |
| 849 | 852 | return -EINVAL; |
| 850 | 853 | |
| 851 | − header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | | |
| 854 | + request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | | |
| 852 | 855 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); |
| 853 | − header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); | |
| 854 | − header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | |
| 855 | − header |= (stage_id << IPC_STG_ID_SHIFT); | |
| 856 | + request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); | |
| 857 | + request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | |
| 858 | + request.header |= (stage_id << IPC_STG_ID_SHIFT); | |
| 856 | 859 | |
| 857 | 860 | req = &stream->vol_req; |
| 858 | 861 | req->target_volume = volume; |
| @@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, · 18 unmodified lines | ||
| 877 | 880 | req->channel = channel; |
| 878 | 881 | } |
| 879 | 882 | |
| 880 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req, | |
| 881 | − sizeof(*req), NULL, 0); | |
| 883 | + request.data = req; | |
| 884 | + request.size = sizeof(*req); | |
| 885 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 882 | 886 | if (ret < 0) { |
| 883 | 887 | dev_err(hsw->dev, "error: set stream volume failed\n"); |
| 884 | 888 | return ret; |
| @@ -905,7 +909,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, · 20 unmodified lines | ||
| 905 | 909 | u32 volume) |
| 906 | 910 | { |
| 907 | 911 | struct sst_hsw_ipc_volume_req req; |
| 908 | − u32 header; | |
| 912 | + struct sst_ipc_message request; | |
| 909 | 913 | int ret; |
| 910 | 914 | |
| 911 | 915 | trace_ipc_request("set mixer volume", volume); |
| @@ -933,18 +937,19 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, · 21 unmodified lines | ||
| 933 | 937 | req.channel = channel; |
| 934 | 938 | } |
| 935 | 939 | |
| 936 | − header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | | |
| 940 | + request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | | |
| 937 | 941 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); |
| 938 | − header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); | |
| 939 | − header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | |
| 940 | − header |= (stage_id << IPC_STG_ID_SHIFT); | |
| 942 | + request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); | |
| 943 | + request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | |
| 944 | + request.header |= (stage_id << IPC_STG_ID_SHIFT); | |
| 941 | 945 | |
| 942 | 946 | req.curve_duration = hsw->curve_duration; |
| 943 | 947 | req.curve_type = hsw->curve_type; |
| 944 | 948 | req.target_volume = volume; |
| 945 | 949 | |
| 946 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req, | |
| 947 | − sizeof(req), NULL, 0); | |
| 950 | + request.data = &req; | |
| 951 | + request.size = sizeof(req); | |
| 952 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 948 | 953 | if (ret < 0) { |
| 949 | 954 | dev_err(hsw->dev, "error: set mixer volume failed\n"); |
| 950 | 955 | return ret; |
| @@ -983,7 +988,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, · 32 unmodified lines | ||
| 983 | 988 | |
| 984 | 989 | int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) |
| 985 | 990 | { |
| 986 | − u32 header; | |
| 991 | + struct sst_ipc_message request; | |
| 987 | 992 | int ret = 0; |
| 988 | 993 | struct sst_dsp *sst = hsw->dsp; |
| 989 | 994 | unsigned long flags; |
| @@ -1000,10 +1005,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) · 10 unmodified lines | ||
| 1000 | 1005 | trace_ipc_request("stream free", stream->host_id); |
| 1001 | 1006 | |
| 1002 | 1007 | stream->free_req.stream_id = stream->reply.stream_hw_id; |
| 1003 | − header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); | |
| 1008 | + request.header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); | |
| 1009 | + request.data = &stream->free_req; | |
| 1010 | + request.size = sizeof(stream->free_req); | |
| 1004 | 1011 | |
| 1005 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req, | |
| 1006 | − sizeof(stream->free_req), NULL, 0); | |
| 1012 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 1007 | 1013 | if (ret < 0) { |
| 1008 | 1014 | dev_err(hsw->dev, "error: free stream %d failed\n", |
| 1009 | 1015 | stream->free_req.stream_id); |
| @@ -1175,9 +1181,7 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw, · 165 unmodified lines | ||
| 1175 | 1181 | |
| 1176 | 1182 | int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) |
| 1177 | 1183 | { |
| 1178 | − struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request; | |
| 1179 | − struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply; | |
| 1180 | − u32 header; | |
| 1184 | + struct sst_ipc_message request, reply = {0}; | |
| 1181 | 1185 | int ret; |
| 1182 | 1186 | |
| 1183 | 1187 | if (!stream) { |
| @@ -1192,10 +1196,13 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) · 8 unmodified lines | ||
| 1192 | 1196 | |
| 1193 | 1197 | trace_ipc_request("stream alloc", stream->host_id); |
| 1194 | 1198 | |
| 1195 | − header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); | |
| 1199 | + request.header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); | |
| 1200 | + request.data = &stream->request; | |
| 1201 | + request.size = sizeof(stream->request); | |
| 1202 | + reply.data = &stream->reply; | |
| 1203 | + reply.size = sizeof(stream->reply); | |
| 1196 | 1204 | |
| 1197 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req, | |
| 1198 | − sizeof(*str_req), reply, sizeof(*reply)); | |
| 1205 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); | |
| 1199 | 1206 | if (ret < 0) { |
| 1200 | 1207 | dev_err(hsw->dev, "error: stream commit failed\n"); |
| 1201 | 1208 | return ret; |
| @@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw, · 33 unmodified lines | ||
| 1235 | 1242 | ABI to be opaque to client PCM drivers to cope with any future ABI changes */ |
| 1236 | 1243 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw) |
| 1237 | 1244 | { |
| 1238 | − struct sst_hsw_ipc_stream_info_reply *reply; | |
| 1239 | − u32 header; | |
| 1245 | + struct sst_ipc_message request = {0}, reply = {0}; | |
| 1240 | 1246 | int ret; |
| 1241 | 1247 | |
| 1242 | − reply = &hsw->mixer_info; | |
| 1243 | − header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO); | |
| 1248 | + request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO); | |
| 1249 | + reply.data = &hsw->mixer_info; | |
| 1250 | + reply.size = sizeof(hsw->mixer_info); | |
| 1244 | 1251 | |
| 1245 | 1252 | trace_ipc_request("get global mixer info", 0); |
| 1246 | 1253 | |
| 1247 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, | |
| 1248 | − reply, sizeof(*reply)); | |
| 1254 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); | |
| 1249 | 1255 | if (ret < 0) { |
| 1250 | 1256 | dev_err(hsw->dev, "error: get stream info failed\n"); |
| 1251 | 1257 | return ret; |
| 1252 | 1258 | } |
| 1253 | 1259 | |
| 1254 | − trace_hsw_mixer_info_reply(reply); | |
| 1260 | + trace_hsw_mixer_info_reply(&hsw->mixer_info); | |
| 1255 | 1261 | |
| 1256 | 1262 | return 0; |
| 1257 | 1263 | } |
| @@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw) · 2 unmodified lines | ||
| 1260 | 1266 | static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type, |
| 1261 | 1267 | int stream_id, int wait) |
| 1262 | 1268 | { |
| 1263 | − u32 header; | |
| 1269 | + struct sst_ipc_message request = {0}; | |
| 1264 | 1270 | |
| 1265 | − header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type); | |
| 1266 | − header |= (stream_id << IPC_STR_ID_SHIFT); | |
| 1271 | + request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE); | |
| 1272 | + request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT); | |
| 1267 | 1273 | |
| 1268 | 1274 | if (wait) |
| 1269 | − return sst_ipc_tx_message_wait(&hsw->ipc, header, | |
| 1270 | − NULL, 0, NULL, 0); | |
| 1275 | + return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 1271 | 1276 | else |
| 1272 | − return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0); | |
| 1277 | + return sst_ipc_tx_message_nowait(&hsw->ipc, request); | |
| 1273 | 1278 | } |
| 1274 | 1279 | |
| 1275 | 1280 | /* Stream ALSA trigger operations */ |
| @@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, · 101 unmodified lines | ||
| 1377 | 1382 | enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, |
| 1378 | 1383 | enum sst_hsw_device_mode mode, u32 clock_divider) |
| 1379 | 1384 | { |
| 1385 | + struct sst_ipc_message request; | |
| 1380 | 1386 | struct sst_hsw_ipc_device_config_req config; |
| 1381 | − u32 header; | |
| 1382 | 1387 | int ret; |
| 1383 | 1388 | |
| 1384 | 1389 | trace_ipc_request("set device config", dev); |
| @@ -1394,10 +1399,11 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, · 9 unmodified lines | ||
| 1394 | 1399 | |
| 1395 | 1400 | trace_hsw_device_config_req(&config); |
| 1396 | 1401 | |
| 1397 | − header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); | |
| 1402 | + request.header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); | |
| 1403 | + request.data = &config; | |
| 1404 | + request.size = sizeof(config); | |
| 1398 | 1405 | |
| 1399 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config, | |
| 1400 | − sizeof(config), NULL, 0); | |
| 1406 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 1401 | 1407 | if (ret < 0) |
| 1402 | 1408 | dev_err(hsw->dev, "error: set device formats failed\n"); |
| 1403 | 1409 | |
| @@ -1409,16 +1415,20 @@ EXPORT_SYMBOL_GPL(sst_hsw_device_set_config); · 5 unmodified lines | ||
| 1409 | 1415 | int sst_hsw_dx_set_state(struct sst_hsw *hsw, |
| 1410 | 1416 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) |
| 1411 | 1417 | { |
| 1412 | − u32 header, state_; | |
| 1418 | + struct sst_ipc_message request, reply = {0}; | |
| 1419 | + u32 state_; | |
| 1413 | 1420 | int ret, item; |
| 1414 | 1421 | |
| 1415 | − header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE); | |
| 1416 | 1422 | state_ = state; |
| 1423 | + request.header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE); | |
| 1424 | + request.data = &state_; | |
| 1425 | + request.size = sizeof(state_); | |
| 1426 | + reply.data = dx; | |
| 1427 | + reply.size = sizeof(*dx); | |
| 1417 | 1428 | |
| 1418 | 1429 | trace_ipc_request("PM enter Dx state", state); |
| 1419 | 1430 | |
| 1420 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_, | |
| 1421 | − sizeof(state_), dx, sizeof(*dx)); | |
| 1431 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); | |
| 1422 | 1432 | if (ret < 0) { |
| 1423 | 1433 | dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); |
| 1424 | 1434 | return ret; |
| @@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, · 453 unmodified lines | ||
| 1878 | 1888 | u32 module_id, u32 instance_id) |
| 1879 | 1889 | { |
| 1880 | 1890 | int ret; |
| 1881 | − u32 header = 0; | |
| 1891 | + struct sst_ipc_message request; | |
| 1882 | 1892 | struct sst_hsw_ipc_module_config config; |
| 1883 | 1893 | struct sst_module *module; |
| 1884 | 1894 | struct sst_module_runtime *runtime; |
| @@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, · 22 unmodified lines | ||
| 1907 | 1917 | return -ENXIO; |
| 1908 | 1918 | } |
| 1909 | 1919 | |
| 1910 | − header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 1920 | + request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 1911 | 1921 | IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) | |
| 1912 | 1922 | IPC_MODULE_ID(module_id); |
| 1913 | − dev_dbg(dev, "module enable header: %x\n", header); | |
| 1923 | + dev_dbg(dev, "module enable header: %x\n", (u32)request.header); | |
| 1914 | 1924 | |
| 1915 | 1925 | config.map.module_entries_count = 1; |
| 1916 | 1926 | config.map.module_entries[0].module_id = module->id; |
| @@ -1932,8 +1942,9 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, · 15 unmodified lines | ||
| 1932 | 1942 | config.scratch_mem.size, config.scratch_mem.offset, |
| 1933 | 1943 | config.map.module_entries[0].entry_point); |
| 1934 | 1944 | |
| 1935 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, | |
| 1936 | − &config, sizeof(config), NULL, 0); | |
| 1945 | + request.data = &config; | |
| 1946 | + request.size = sizeof(config); | |
| 1947 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 1937 | 1948 | if (ret < 0) |
| 1938 | 1949 | dev_err(dev, "ipc: module enable failed - %d\n", ret); |
| 1939 | 1950 | else |
| @@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, · 6 unmodified lines | ||
| 1946 | 1957 | u32 module_id, u32 instance_id) |
| 1947 | 1958 | { |
| 1948 | 1959 | int ret; |
| 1949 | − u32 header; | |
| 1960 | + struct sst_ipc_message request = {0}; | |
| 1950 | 1961 | struct sst_module *module; |
| 1951 | 1962 | struct device *dev = hsw->dev; |
| 1952 | 1963 | struct sst_dsp *dsp = hsw->dsp; |
| @@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, · 14 unmodified lines | ||
| 1967 | 1978 | return -ENXIO; |
| 1968 | 1979 | } |
| 1969 | 1980 | |
| 1970 | − header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 1981 | + request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 1971 | 1982 | IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) | |
| 1972 | 1983 | IPC_MODULE_ID(module_id); |
| 1973 | 1984 | |
| 1974 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0); | |
| 1985 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 1975 | 1986 | if (ret < 0) |
| 1976 | 1987 | dev_err(dev, "module disable failed - %d\n", ret); |
| 1977 | 1988 | else |
| @@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, · 7 unmodified lines | ||
| 1985 | 1996 | u32 param_size, char *param) |
| 1986 | 1997 | { |
| 1987 | 1998 | int ret; |
| 1988 | − u32 header = 0; | |
| 1989 | − u32 payload_size = 0, transfer_parameter_size = 0; | |
| 1999 | + struct sst_ipc_message request = {0}; | |
| 2000 | + u32 payload_size = 0; | |
| 1990 | 2001 | struct sst_hsw_transfer_parameter *parameter; |
| 1991 | 2002 | struct device *dev = hsw->dev; |
| 1992 | 2003 | |
| 1993 | − header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 2004 | + request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | | |
| 1994 | 2005 | IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) | |
| 1995 | 2006 | IPC_MODULE_ID(module_id); |
| 1996 | − dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header); | |
| 2007 | + dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", | |
| 2008 | + (u32)request.header); | |
| 1997 | 2009 | |
| 1998 | 2010 | payload_size = param_size + |
| 1999 | 2011 | sizeof(struct sst_hsw_transfer_parameter) - |
| @@ -2003,14 +2015,14 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, · 3 unmodified lines | ||
| 2003 | 2015 | |
| 2004 | 2016 | if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) { |
| 2005 | 2017 | /* short parameter, mailbox can contain data */ |
| 2006 | − dev_dbg(dev, "transfer parameter size : %d\n", | |
| 2007 | − transfer_parameter_size); | |
| 2018 | + dev_dbg(dev, "transfer parameter size : %zu\n", | |
| 2019 | + request.size); | |
| 2008 | 2020 | |
| 2009 | − transfer_parameter_size = ALIGN(payload_size, 4); | |
| 2010 | − dev_dbg(dev, "transfer parameter aligned size : %d\n", | |
| 2011 | − transfer_parameter_size); | |
| 2021 | + request.size = ALIGN(payload_size, 4); | |
| 2022 | + dev_dbg(dev, "transfer parameter aligned size : %zu\n", | |
| 2023 | + request.size); | |
| 2012 | 2024 | |
| 2013 | − parameter = kzalloc(transfer_parameter_size, GFP_KERNEL); | |
| 2025 | + parameter = kzalloc(request.size, GFP_KERNEL); | |
| 2014 | 2026 | if (parameter == NULL) |
| 2015 | 2027 | return -ENOMEM; |
| 2016 | 2028 | |
| @@ -2022,9 +2034,9 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, · 5 unmodified lines | ||
| 2022 | 2034 | |
| 2023 | 2035 | parameter->parameter_id = parameter_id; |
| 2024 | 2036 | parameter->data_size = param_size; |
| 2037 | + request.data = parameter; | |
| 2025 | 2038 | |
| 2026 | − ret = sst_ipc_tx_message_wait(&hsw->ipc, header, | |
| 2027 | − parameter, transfer_parameter_size , NULL, 0); | |
| 2039 | + ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | |
| 2028 | 2040 | if (ret < 0) |
| 2029 | 2041 | dev_err(dev, "ipc: module set parameter failed - %d\n", ret); |
| 2030 | 2042 | |
| @@ -2041,8 +2053,8 @@ static struct sst_dsp_device hsw_dev = { · 10 unmodified lines | ||
| 2041 | 2053 | static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
| 2042 | 2054 | { |
| 2043 | 2055 | /* send the message */ |
| 2044 | − sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | |
| 2045 | − sst_dsp_ipc_msg_tx(ipc->dsp, msg->header); | |
| 2056 | + sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); | |
| 2057 | + sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header); | |
| 2046 | 2058 | } |
| 2047 | 2059 | |
| 2048 | 2060 | static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) |
| @@ -2063,7 +2075,7 @@ static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) · 14 unmodified lines | ||
| 2063 | 2075 | static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data, |
| 2064 | 2076 | size_t tx_size) |
| 2065 | 2077 | { |
| 2066 | − memcpy(msg->tx_data, tx_data, tx_size); | |
| 2078 | + memcpy(msg->tx.data, tx_data, tx_size); | |
| 2067 | 2079 | } |
| 2068 | 2080 | |
| 2069 | 2081 | static u64 hsw_reply_msg_match(u64 header, u64 *mask) |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \ | |
| 3 | −skl-topology.o | |
| 2 | +snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o skl-topology.o \ | |
| 3 | + skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o skl-sst-cldma.o \ | |
| 4 | + skl-sst.o bxt-sst.o cnl-sst.o skl-sst-utils.o | |
| 4 | 5 | |
| 5 | 6 | ifdef CONFIG_DEBUG_FS |
| 6 | 7 | snd-soc-skl-objs += skl-debug.o |
| @@ -8,13 +9,6 @@ endif · 1 unmodified line | ||
| 8 | 9 | |
| 9 | 10 | obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o |
| 10 | 11 | |
| 11 | −# Skylake IPC Support | |
| 12 | −snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \ | |
| 13 | − skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \ | |
| 14 | − skl-sst-utils.o | |
| 15 | − | |
| 16 | −obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o | |
| 17 | − | |
| 18 | 12 | #Skylake Clock device support |
| 19 | 13 | snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o |
| 20 | 14 | |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include "../common/sst-dsp.h" |
| 16 | 16 | #include "../common/sst-dsp-priv.h" |
| 17 | −#include "skl-sst-ipc.h" | |
| 17 | +#include "skl.h" | |
| 18 | 18 | |
| 19 | 19 | #define BXT_BASEFW_TIMEOUT 3000 |
| 20 | 20 | #define BXT_INIT_TIMEOUT 300 |
| @@ -49,7 +49,7 @@ static int · 28 unmodified lines | ||
| 49 | 49 | bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) |
| 50 | 50 | { |
| 51 | 51 | struct snd_dma_buffer dmab; |
| 52 | − struct skl_sst *skl = ctx->thread_context; | |
| 52 | + struct skl_dev *skl = ctx->thread_context; | |
| 53 | 53 | struct firmware stripped_fw; |
| 54 | 54 | int ret = 0, i, dma_id, stream_tag; |
| 55 | 55 | |
| @@ -184,7 +184,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) · 128 unmodified lines | ||
| 184 | 184 | static int bxt_load_base_firmware(struct sst_dsp *ctx) |
| 185 | 185 | { |
| 186 | 186 | struct firmware stripped_fw; |
| 187 | − struct skl_sst *skl = ctx->thread_context; | |
| 187 | + struct skl_dev *skl = ctx->thread_context; | |
| 188 | 188 | int ret, i; |
| 189 | 189 | |
| 190 | 190 | if (ctx->fw == NULL) { |
| @@ -268,7 +268,7 @@ sst_load_base_firmware_failed: · 77 unmodified lines | ||
| 268 | 268 | */ |
| 269 | 269 | static int bxt_d0i3_target_state(struct sst_dsp *ctx) |
| 270 | 270 | { |
| 271 | − struct skl_sst *skl = ctx->thread_context; | |
| 271 | + struct skl_dev *skl = ctx->thread_context; | |
| 272 | 272 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 273 | 273 | |
| 274 | 274 | if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING) |
| @@ -288,8 +288,8 @@ static void bxt_set_dsp_D0i3(struct work_struct *work) · 13 unmodified lines | ||
| 288 | 288 | { |
| 289 | 289 | int ret; |
| 290 | 290 | struct skl_ipc_d0ix_msg msg; |
| 291 | − struct skl_sst *skl = container_of(work, | |
| 292 | − struct skl_sst, d0i3.work.work); | |
| 291 | + struct skl_dev *skl = container_of(work, | |
| 292 | + struct skl_dev, d0i3.work.work); | |
| 293 | 293 | struct sst_dsp *ctx = skl->dsp; |
| 294 | 294 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 295 | 295 | int target_state; |
| @@ -331,7 +331,7 @@ static void bxt_set_dsp_D0i3(struct work_struct *work) · 35 unmodified lines | ||
| 331 | 331 | |
| 332 | 332 | static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx) |
| 333 | 333 | { |
| 334 | − struct skl_sst *skl = ctx->thread_context; | |
| 334 | + struct skl_dev *skl = ctx->thread_context; | |
| 335 | 335 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 336 | 336 | |
| 337 | 337 | /* Schedule D0i3 only if the usecase ref counts are appropriate */ |
| @@ -350,7 +350,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx) · 12 unmodified lines | ||
| 350 | 350 | { |
| 351 | 351 | int ret; |
| 352 | 352 | struct skl_ipc_d0ix_msg msg; |
| 353 | − struct skl_sst *skl = ctx->thread_context; | |
| 353 | + struct skl_dev *skl = ctx->thread_context; | |
| 354 | 354 | |
| 355 | 355 | dev_dbg(ctx->dev, "In %s:\n", __func__); |
| 356 | 356 | |
| @@ -389,7 +389,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx) · 32 unmodified lines | ||
| 389 | 389 | |
| 390 | 390 | static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) |
| 391 | 391 | { |
| 392 | − struct skl_sst *skl = ctx->thread_context; | |
| 392 | + struct skl_dev *skl = ctx->thread_context; | |
| 393 | 393 | int ret; |
| 394 | 394 | struct skl_ipc_dxstate_info dx; |
| 395 | 395 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| @@ -486,7 +486,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) · 90 unmodified lines | ||
| 486 | 486 | { |
| 487 | 487 | int ret; |
| 488 | 488 | struct skl_ipc_dxstate_info dx; |
| 489 | − struct skl_sst *skl = ctx->thread_context; | |
| 489 | + struct skl_dev *skl = ctx->thread_context; | |
| 490 | 490 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 491 | 491 | |
| 492 | 492 | dx.core_mask = core_mask; |
| @@ -548,9 +548,9 @@ static struct sst_dsp_device skl_dev = { · 55 unmodified lines | ||
| 548 | 548 | |
| 549 | 549 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 550 | 550 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 551 | − struct skl_sst **dsp) | |
| 551 | + struct skl_dev **dsp) | |
| 552 | 552 | { |
| 553 | − struct skl_sst *skl; | |
| 553 | + struct skl_dev *skl; | |
| 554 | 554 | struct sst_dsp *sst; |
| 555 | 555 | int ret; |
| 556 | 556 | |
| @@ -591,10 +591,10 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, · 34 unmodified lines | ||
| 591 | 591 | } |
| 592 | 592 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); |
| 593 | 593 | |
| 594 | −int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) | |
| 594 | +int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl) | |
| 595 | 595 | { |
| 596 | 596 | int ret; |
| 597 | − struct sst_dsp *sst = ctx->dsp; | |
| 597 | + struct sst_dsp *sst = skl->dsp; | |
| 598 | 598 | |
| 599 | 599 | ret = sst->fw_ops.load_fw(sst); |
| 600 | 600 | if (ret < 0) { |
| @@ -604,29 +604,29 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) · 3 unmodified lines | ||
| 604 | 604 | |
| 605 | 605 | skl_dsp_init_core_state(sst); |
| 606 | 606 | |
| 607 | − if (ctx->lib_count > 1) { | |
| 608 | − ret = sst->fw_ops.load_library(sst, ctx->lib_info, | |
| 609 | − ctx->lib_count); | |
| 607 | + if (skl->lib_count > 1) { | |
| 608 | + ret = sst->fw_ops.load_library(sst, skl->lib_info, | |
| 609 | + skl->lib_count); | |
| 610 | 610 | if (ret < 0) { |
| 611 | 611 | dev_err(dev, "Load Library failed : %x\n", ret); |
| 612 | 612 | return ret; |
| 613 | 613 | } |
| 614 | 614 | } |
| 615 | − ctx->is_first_boot = false; | |
| 615 | + skl->is_first_boot = false; | |
| 616 | 616 | |
| 617 | 617 | return 0; |
| 618 | 618 | } |
| 619 | 619 | EXPORT_SYMBOL_GPL(bxt_sst_init_fw); |
| 620 | 620 | |
| 621 | −void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | |
| 621 | +void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl) | |
| 622 | 622 | { |
| 623 | 623 | |
| 624 | − skl_release_library(ctx->lib_info, ctx->lib_count); | |
| 625 | − if (ctx->dsp->fw) | |
| 626 | − release_firmware(ctx->dsp->fw); | |
| 627 | − skl_freeup_uuid_list(ctx); | |
| 628 | − skl_ipc_free(&ctx->ipc); | |
| 629 | − ctx->dsp->ops->free(ctx->dsp); | |
| 624 | + skl_release_library(skl->lib_info, skl->lib_count); | |
| 625 | + if (skl->dsp->fw) | |
| 626 | + release_firmware(skl->dsp->fw); | |
| 627 | + skl_freeup_uuid_list(skl); | |
| 628 | + skl_ipc_free(&skl->ipc); | |
| 629 | + skl->dsp->ops->free(skl->dsp); | |
| 630 | 630 | } |
| 631 | 631 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); |
| 632 | 632 | |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #define __CNL_SST_DSP_H__ |
| 10 | 10 | |
| 11 | 11 | struct sst_dsp; |
| 12 | −struct skl_sst; | |
| 13 | 12 | struct sst_dsp_device; |
| 14 | 13 | struct sst_generic_ipc; |
| 15 | 14 | |
| @@ -97,8 +96,8 @@ void cnl_ipc_free(struct sst_generic_ipc *ipc); · 81 unmodified lines | ||
| 97 | 96 | |
| 98 | 97 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 99 | 98 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 100 | − struct skl_sst **dsp); | |
| 101 | −int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | |
| 102 | −void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | |
| 99 | + struct skl_dev **dsp); | |
| 100 | +int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl); | |
| 101 | +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); | |
| 103 | 102 | |
| 104 | 103 | #endif /*__CNL_SST_DSP_H__*/ |
| @@ -24,8 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "../common/sst-dsp-priv.h" |
| 25 | 25 | #include "../common/sst-ipc.h" |
| 26 | 26 | #include "cnl-sst-dsp.h" |
| 27 | −#include "skl-sst-dsp.h" | |
| 28 | −#include "skl-sst-ipc.h" | |
| 27 | +#include "skl.h" | |
| 29 | 28 | |
| 30 | 29 | #define CNL_FW_ROM_INIT 0x1 |
| 31 | 30 | #define CNL_FW_INIT 0x5 |
| @@ -109,7 +108,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) · 77 unmodified lines | ||
| 109 | 108 | static int cnl_load_base_firmware(struct sst_dsp *ctx) |
| 110 | 109 | { |
| 111 | 110 | struct firmware stripped_fw; |
| 112 | − struct skl_sst *cnl = ctx->thread_context; | |
| 111 | + struct skl_dev *cnl = ctx->thread_context; | |
| 113 | 112 | int ret; |
| 114 | 113 | |
| 115 | 114 | if (!ctx->fw) { |
| @@ -167,7 +166,7 @@ cnl_load_base_firmware_failed: · 51 unmodified lines | ||
| 167 | 166 | |
| 168 | 167 | static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) |
| 169 | 168 | { |
| 170 | − struct skl_sst *cnl = ctx->thread_context; | |
| 169 | + struct skl_dev *cnl = ctx->thread_context; | |
| 171 | 170 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 172 | 171 | struct skl_ipc_dxstate_info dx; |
| 173 | 172 | int ret; |
| @@ -229,7 +228,7 @@ err: · 55 unmodified lines | ||
| 229 | 228 | |
| 230 | 229 | static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) |
| 231 | 230 | { |
| 232 | − struct skl_sst *cnl = ctx->thread_context; | |
| 231 | + struct skl_dev *cnl = ctx->thread_context; | |
| 233 | 232 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 234 | 233 | struct skl_ipc_dxstate_info dx; |
| 235 | 234 | int ret; |
| @@ -293,7 +292,7 @@ static struct sst_ops cnl_ops = { · 57 unmodified lines | ||
| 293 | 292 | static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) |
| 294 | 293 | { |
| 295 | 294 | struct sst_dsp *dsp = context; |
| 296 | − struct skl_sst *cnl = sst_dsp_get_thread_context(dsp); | |
| 295 | + struct skl_dev *cnl = sst_dsp_get_thread_context(dsp); | |
| 297 | 296 | struct sst_generic_ipc *ipc = &cnl->ipc; |
| 298 | 297 | struct skl_ipc_header header = {0}; |
| 299 | 298 | u32 hipcida, hipctdr, hipctdd; |
| @@ -367,10 +366,10 @@ static struct sst_dsp_device cnl_dev = { · 67 unmodified lines | ||
| 367 | 366 | |
| 368 | 367 | static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
| 369 | 368 | { |
| 370 | − struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); | |
| 369 | + struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header); | |
| 371 | 370 | |
| 372 | − if (msg->tx_size) | |
| 373 | − sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | |
| 371 | + if (msg->tx.size) | |
| 372 | + sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); | |
| 374 | 373 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, |
| 375 | 374 | header->extension); |
| 376 | 375 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, |
| @@ -386,7 +385,7 @@ static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp) · 9 unmodified lines | ||
| 386 | 385 | return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); |
| 387 | 386 | } |
| 388 | 387 | |
| 389 | −static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) | |
| 388 | +static int cnl_ipc_init(struct device *dev, struct skl_dev *cnl) | |
| 390 | 389 | { |
| 391 | 390 | struct sst_generic_ipc *ipc; |
| 392 | 391 | int err; |
| @@ -415,9 +414,9 @@ static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) · 22 unmodified lines | ||
| 415 | 414 | |
| 416 | 415 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 417 | 416 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 418 | − struct skl_sst **dsp) | |
| 417 | + struct skl_dev **dsp) | |
| 419 | 418 | { |
| 420 | − struct skl_sst *cnl; | |
| 419 | + struct skl_dev *cnl; | |
| 421 | 420 | struct sst_dsp *sst; |
| 422 | 421 | int ret; |
| 423 | 422 | |
| @@ -454,12 +453,12 @@ int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, · 30 unmodified lines | ||
| 454 | 453 | } |
| 455 | 454 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); |
| 456 | 455 | |
| 457 | −int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) | |
| 456 | +int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl) | |
| 458 | 457 | { |
| 459 | 458 | int ret; |
| 460 | − struct sst_dsp *sst = ctx->dsp; | |
| 459 | + struct sst_dsp *sst = skl->dsp; | |
| 461 | 460 | |
| 462 | − ret = ctx->dsp->fw_ops.load_fw(sst); | |
| 461 | + ret = skl->dsp->fw_ops.load_fw(sst); | |
| 463 | 462 | if (ret < 0) { |
| 464 | 463 | dev_err(dev, "load base fw failed: %d", ret); |
| 465 | 464 | return ret; |
| @@ -467,21 +466,21 @@ int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) · 1 unmodified line | ||
| 467 | 466 | |
| 468 | 467 | skl_dsp_init_core_state(sst); |
| 469 | 468 | |
| 470 | − ctx->is_first_boot = false; | |
| 469 | + skl->is_first_boot = false; | |
| 471 | 470 | |
| 472 | 471 | return 0; |
| 473 | 472 | } |
| 474 | 473 | EXPORT_SYMBOL_GPL(cnl_sst_init_fw); |
| 475 | 474 | |
| 476 | −void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | |
| 475 | +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl) | |
| 477 | 476 | { |
| 478 | − if (ctx->dsp->fw) | |
| 479 | − release_firmware(ctx->dsp->fw); | |
| 477 | + if (skl->dsp->fw) | |
| 478 | + release_firmware(skl->dsp->fw); | |
| 480 | 479 | |
| 481 | − skl_freeup_uuid_list(ctx); | |
| 482 | − cnl_ipc_free(&ctx->ipc); | |
| 480 | + skl_freeup_uuid_list(skl); | |
| 481 | + cnl_ipc_free(&skl->ipc); | |
| 483 | 482 | |
| 484 | − ctx->dsp->ops->free(ctx->dsp); | |
| 483 | + skl->dsp->ops->free(skl->dsp); | |
| 485 | 484 | } |
| 486 | 485 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); |
| 487 | 486 | |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #define FW_REG_SIZE 0x60 |
| 21 | 21 | |
| 22 | 22 | struct skl_debug { |
| 23 | − struct skl *skl; | |
| 23 | + struct skl_dev *skl; | |
| 24 | 24 | struct device *dev; |
| 25 | 25 | |
| 26 | 26 | struct dentry *fs; |
| @@ -66,6 +66,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf, · 39 unmodified lines | ||
| 66 | 66 | size_t count, loff_t *ppos) |
| 67 | 67 | { |
| 68 | 68 | struct skl_module_cfg *mconfig = file->private_data; |
| 69 | + struct skl_module *module = mconfig->module; | |
| 70 | + struct skl_module_res *res = &module->resources[mconfig->res_idx]; | |
| 69 | 71 | char *buf; |
| 70 | 72 | ssize_t ret; |
| 71 | 73 | |
| @@ -79,8 +81,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf, · 7 unmodified lines | ||
| 79 | 81 | mconfig->id.pvt_id); |
| 80 | 82 | |
| 81 | 83 | ret += snprintf(buf + ret, MOD_BUF - ret, |
| 82 | − "Resources:\n\tMCPS %#x\n\tIBS %#x\n\tOBS %#x\t\n", | |
| 83 | − mconfig->mcps, mconfig->ibs, mconfig->obs); | |
| 84 | + "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n", | |
| 85 | + res->cpc, res->ibs, res->obs); | |
| 84 | 86 | |
| 85 | 87 | ret += snprintf(buf + ret, MOD_BUF - ret, |
| 86 | 88 | "Module data:\n\tCore %d\n\tIn queue %d\n\t" |
| @@ -162,17 +164,15 @@ void skl_debug_init_module(struct skl_debug *d, · 75 unmodified lines | ||
| 162 | 164 | struct snd_soc_dapm_widget *w, |
| 163 | 165 | struct skl_module_cfg *mconfig) |
| 164 | 166 | { |
| 165 | − if (!debugfs_create_file(w->name, 0444, | |
| 166 | − d->modules, mconfig, | |
| 167 | − &mcfg_fops)) | |
| 168 | − dev_err(d->dev, "%s: module debugfs init failed\n", w->name); | |
| 167 | + debugfs_create_file(w->name, 0444, d->modules, mconfig, | |
| 168 | + &mcfg_fops); | |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, |
| 172 | 172 | size_t count, loff_t *ppos) |
| 173 | 173 | { |
| 174 | 174 | struct skl_debug *d = file->private_data; |
| 175 | − struct sst_dsp *sst = d->skl->skl_sst->dsp; | |
| 175 | + struct sst_dsp *sst = d->skl->dsp; | |
| 176 | 176 | size_t w0_stat_sz = sst->addr.w0_stat_sz; |
| 177 | 177 | void __iomem *in_base = sst->mailbox.in_base; |
| 178 | 178 | void __iomem *fw_reg_addr; |
| @@ -213,7 +213,7 @@ static const struct file_operations soft_regs_ctrl_fops = { · 34 unmodified lines | ||
| 213 | 213 | .llseek = default_llseek, |
| 214 | 214 | }; |
| 215 | 215 | |
| 216 | −struct skl_debug *skl_debugfs_init(struct skl *skl) | |
| 216 | +struct skl_debug *skl_debugfs_init(struct skl_dev *skl) | |
| 217 | 217 | { |
| 218 | 218 | struct skl_debug *d; |
| 219 | 219 | |
| @@ -222,37 +222,21 @@ struct skl_debug *skl_debugfs_init(struct skl *skl) · 2 unmodified lines | ||
| 222 | 222 | return NULL; |
| 223 | 223 | |
| 224 | 224 | /* create the debugfs dir with platform component's debugfs as parent */ |
| 225 | − d->fs = debugfs_create_dir("dsp", | |
| 226 | − skl->component->debugfs_root); | |
| 227 | − if (IS_ERR(d->fs) || !d->fs) { | |
| 228 | − dev_err(&skl->pci->dev, "debugfs root creation failed\n"); | |
| 229 | − return NULL; | |
| 230 | − } | |
| 225 | + d->fs = debugfs_create_dir("dsp", skl->component->debugfs_root); | |
| 231 | 226 | |
| 232 | 227 | d->skl = skl; |
| 233 | 228 | d->dev = &skl->pci->dev; |
| 234 | 229 | |
| 235 | 230 | /* now create the module dir */ |
| 236 | 231 | d->modules = debugfs_create_dir("modules", d->fs); |
| 237 | − if (IS_ERR(d->modules) || !d->modules) { | |
| 238 | − dev_err(&skl->pci->dev, "modules debugfs create failed\n"); | |
| 239 | − goto err; | |
| 240 | − } | |
| 241 | 232 | |
| 242 | − if (!debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d, | |
| 243 | − &soft_regs_ctrl_fops)) { | |
| 244 | − dev_err(d->dev, "fw soft regs control debugfs init failed\n"); | |
| 245 | − goto err; | |
| 246 | − } | |
| 233 | + debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d, | |
| 234 | + &soft_regs_ctrl_fops); | |
| 247 | 235 | |
| 248 | 236 | return d; |
| 249 | − | |
| 250 | −err: | |
| 251 | − debugfs_remove_recursive(d->fs); | |
| 252 | − return NULL; | |
| 253 | 237 | } |
| 254 | 238 | |
| 255 | −void skl_debugfs_exit(struct skl *skl) | |
| 239 | +void skl_debugfs_exit(struct skl_dev *skl) | |
| 256 | 240 | { |
| 257 | 241 | struct skl_debug *d = skl->debugfs; |
| 258 | 242 | |
| @@ -25,29 +25,18 @@ · 24 unmodified lines | ||
| 25 | 25 | static int skl_alloc_dma_buf(struct device *dev, |
| 26 | 26 | struct snd_dma_buffer *dmab, size_t size) |
| 27 | 27 | { |
| 28 | − struct hdac_bus *bus = dev_get_drvdata(dev); | |
| 29 | − | |
| 30 | − if (!bus) | |
| 31 | − return -ENODEV; | |
| 32 | − | |
| 33 | − return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab); | |
| 28 | + return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab); | |
| 34 | 29 | } |
| 35 | 30 | |
| 36 | 31 | static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) |
| 37 | 32 | { |
| 38 | − struct hdac_bus *bus = dev_get_drvdata(dev); | |
| 39 | − | |
| 40 | − if (!bus) | |
| 41 | − return -ENODEV; | |
| 42 | − | |
| 43 | − bus->io_ops->dma_free_pages(bus, dmab); | |
| 44 | − | |
| 33 | + snd_dma_free_pages(dmab); | |
| 45 | 34 | return 0; |
| 46 | 35 | } |
| 47 | 36 | |
| 48 | 37 | #define SKL_ASTATE_PARAM_ID 4 |
| 49 | 38 | |
| 50 | −void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data) | |
| 39 | +void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data) | |
| 51 | 40 | { |
| 52 | 41 | struct skl_ipc_large_config_msg msg = {0}; |
| 53 | 42 | |
| @@ -55,25 +44,7 @@ void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data) · 1 unmodified line | ||
| 55 | 44 | msg.param_data_size = (cnt * sizeof(struct skl_astate_param) + |
| 56 | 45 | sizeof(cnt)); |
| 57 | 46 | |
| 58 | − skl_ipc_set_large_config(&ctx->ipc, &msg, data); | |
| 59 | −} | |
| 60 | − | |
| 61 | −#define NOTIFICATION_PARAM_ID 3 | |
| 62 | −#define NOTIFICATION_MASK 0xf | |
| 63 | − | |
| 64 | −/* disable notfication for underruns/overruns from firmware module */ | |
| 65 | −void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) | |
| 66 | −{ | |
| 67 | − struct notification_mask mask; | |
| 68 | − struct skl_ipc_large_config_msg msg = {0}; | |
| 69 | − | |
| 70 | − mask.notify = NOTIFICATION_MASK; | |
| 71 | − mask.enable = enable; | |
| 72 | − | |
| 73 | − msg.large_param_id = NOTIFICATION_PARAM_ID; | |
| 74 | − msg.param_data_size = sizeof(mask); | |
| 75 | − | |
| 76 | − skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask); | |
| 47 | + skl_ipc_set_large_config(&skl->ipc, &msg, data); | |
| 77 | 48 | } |
| 78 | 49 | |
| 79 | 50 | static int skl_dsp_setup_spib(struct device *dev, unsigned int size, |
| @@ -277,7 +248,7 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) · 197 unmodified lines | ||
| 277 | 248 | return NULL; |
| 278 | 249 | } |
| 279 | 250 | |
| 280 | −int skl_init_dsp(struct skl *skl) | |
| 251 | +int skl_init_dsp(struct skl_dev *skl) | |
| 281 | 252 | { |
| 282 | 253 | void __iomem *mmio_base; |
| 283 | 254 | struct hdac_bus *bus = skl_to_bus(skl); |
| @@ -307,13 +278,13 @@ int skl_init_dsp(struct skl *skl) · 23 unmodified lines | ||
| 307 | 278 | loader_ops = ops->loader_ops(); |
| 308 | 279 | ret = ops->init(bus->dev, mmio_base, irq, |
| 309 | 280 | skl->fw_name, loader_ops, |
| 310 | − &skl->skl_sst); | |
| 281 | + &skl); | |
| 311 | 282 | |
| 312 | 283 | if (ret < 0) |
| 313 | 284 | goto unmap_mmio; |
| 314 | 285 | |
| 315 | − skl->skl_sst->dsp_ops = ops; | |
| 316 | − cores = &skl->skl_sst->cores; | |
| 286 | + skl->dsp_ops = ops; | |
| 287 | + cores = &skl->cores; | |
| 317 | 288 | cores->count = ops->num_cores; |
| 318 | 289 | |
| 319 | 290 | cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); |
| @@ -342,21 +313,20 @@ unmap_mmio: · 22 unmodified lines | ||
| 342 | 313 | return ret; |
| 343 | 314 | } |
| 344 | 315 | |
| 345 | −int skl_free_dsp(struct skl *skl) | |
| 316 | +int skl_free_dsp(struct skl_dev *skl) | |
| 346 | 317 | { |
| 347 | 318 | struct hdac_bus *bus = skl_to_bus(skl); |
| 348 | − struct skl_sst *ctx = skl->skl_sst; | |
| 349 | 319 | |
| 350 | 320 | /* disable ppcap interrupt */ |
| 351 | 321 | snd_hdac_ext_bus_ppcap_int_enable(bus, false); |
| 352 | 322 | |
| 353 | − ctx->dsp_ops->cleanup(bus->dev, ctx); | |
| 323 | + skl->dsp_ops->cleanup(bus->dev, skl); | |
| 354 | 324 | |
| 355 | − kfree(ctx->cores.state); | |
| 356 | − kfree(ctx->cores.usage_count); | |
| 325 | + kfree(skl->cores.state); | |
| 326 | + kfree(skl->cores.usage_count); | |
| 357 | 327 | |
| 358 | − if (ctx->dsp->addr.lpe) | |
| 359 | − iounmap(ctx->dsp->addr.lpe); | |
| 328 | + if (skl->dsp->addr.lpe) | |
| 329 | + iounmap(skl->dsp->addr.lpe); | |
| 360 | 330 | |
| 361 | 331 | return 0; |
| 362 | 332 | } |
| @@ -368,15 +338,14 @@ int skl_free_dsp(struct skl *skl) · 5 unmodified lines | ||
| 368 | 338 | * mode during system suspend. In the case of normal suspend, cancel |
| 369 | 339 | * any pending D0i3 work. |
| 370 | 340 | */ |
| 371 | −int skl_suspend_late_dsp(struct skl *skl) | |
| 341 | +int skl_suspend_late_dsp(struct skl_dev *skl) | |
| 372 | 342 | { |
| 373 | − struct skl_sst *ctx = skl->skl_sst; | |
| 374 | 343 | struct delayed_work *dwork; |
| 375 | 344 | |
| 376 | − if (!ctx) | |
| 345 | + if (!skl) | |
| 377 | 346 | return 0; |
| 378 | 347 | |
| 379 | − dwork = &ctx->d0i3.work; | |
| 348 | + dwork = &skl->d0i3.work; | |
| 380 | 349 | |
| 381 | 350 | if (dwork->work.func) { |
| 382 | 351 | if (skl->supend_active) |
| @@ -388,9 +357,8 @@ int skl_suspend_late_dsp(struct skl *skl) · 5 unmodified lines | ||
| 388 | 357 | return 0; |
| 389 | 358 | } |
| 390 | 359 | |
| 391 | −int skl_suspend_dsp(struct skl *skl) | |
| 360 | +int skl_suspend_dsp(struct skl_dev *skl) | |
| 392 | 361 | { |
| 393 | − struct skl_sst *ctx = skl->skl_sst; | |
| 394 | 362 | struct hdac_bus *bus = skl_to_bus(skl); |
| 395 | 363 | int ret; |
| 396 | 364 | |
| @@ -398,7 +366,7 @@ int skl_suspend_dsp(struct skl *skl) · 1 unmodified line | ||
| 398 | 366 | if (!bus->ppcap) |
| 399 | 367 | return 0; |
| 400 | 368 | |
| 401 | − ret = skl_dsp_sleep(ctx->dsp); | |
| 369 | + ret = skl_dsp_sleep(skl->dsp); | |
| 402 | 370 | if (ret < 0) |
| 403 | 371 | return ret; |
| 404 | 372 | |
| @@ -409,9 +377,8 @@ int skl_suspend_dsp(struct skl *skl) · 4 unmodified lines | ||
| 409 | 377 | return 0; |
| 410 | 378 | } |
| 411 | 379 | |
| 412 | −int skl_resume_dsp(struct skl *skl) | |
| 380 | +int skl_resume_dsp(struct skl_dev *skl) | |
| 413 | 381 | { |
| 414 | − struct skl_sst *ctx = skl->skl_sst; | |
| 415 | 382 | struct hdac_bus *bus = skl_to_bus(skl); |
| 416 | 383 | int ret; |
| 417 | 384 | |
| @@ -424,26 +391,24 @@ int skl_resume_dsp(struct skl *skl) · 6 unmodified lines | ||
| 424 | 391 | snd_hdac_ext_bus_ppcap_int_enable(bus, true); |
| 425 | 392 | |
| 426 | 393 | /* check if DSP 1st boot is done */ |
| 427 | − if (skl->skl_sst->is_first_boot) | |
| 394 | + if (skl->is_first_boot) | |
| 428 | 395 | return 0; |
| 429 | 396 | |
| 430 | 397 | /* |
| 431 | 398 | * Disable dynamic clock and power gating during firmware |
| 432 | 399 | * and library download |
| 433 | 400 | */ |
| 434 | − ctx->enable_miscbdcge(ctx->dev, false); | |
| 435 | − ctx->clock_power_gating(ctx->dev, false); | |
| 401 | + skl->enable_miscbdcge(skl->dev, false); | |
| 402 | + skl->clock_power_gating(skl->dev, false); | |
| 436 | 403 | |
| 437 | − ret = skl_dsp_wake(ctx->dsp); | |
| 438 | − ctx->enable_miscbdcge(ctx->dev, true); | |
| 439 | − ctx->clock_power_gating(ctx->dev, true); | |
| 404 | + ret = skl_dsp_wake(skl->dsp); | |
| 405 | + skl->enable_miscbdcge(skl->dev, true); | |
| 406 | + skl->clock_power_gating(skl->dev, true); | |
| 440 | 407 | if (ret < 0) |
| 441 | 408 | return ret; |
| 442 | 409 | |
| 443 | − skl_dsp_enable_notification(skl->skl_sst, false); | |
| 444 | − | |
| 445 | 410 | if (skl->cfg.astate_cfg != NULL) { |
| 446 | − skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count, | |
| 411 | + skl_dsp_set_astate_cfg(skl, skl->cfg.astate_cfg->count, | |
| 447 | 412 | skl->cfg.astate_cfg); |
| 448 | 413 | } |
| 449 | 414 | return ret; |
| @@ -476,7 +441,7 @@ enum skl_bitdepth skl_get_bit_depth(int params) · 26 unmodified lines | ||
| 476 | 441 | * which are read from widget information passed through topology binary |
| 477 | 442 | * This is send when we create a module with INIT_INSTANCE IPC msg |
| 478 | 443 | */ |
| 479 | −static void skl_set_base_module_format(struct skl_sst *ctx, | |
| 444 | +static void skl_set_base_module_format(struct skl_dev *skl, | |
| 480 | 445 | struct skl_module_cfg *mconfig, |
| 481 | 446 | struct skl_base_cfg *base_cfg) |
| 482 | 447 | { |
| @@ -493,7 +458,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, · 10 unmodified lines | ||
| 493 | 458 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; |
| 494 | 459 | base_cfg->audio_fmt.sample_type = format->sample_type; |
| 495 | 460 | |
| 496 | − dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", | |
| 461 | + dev_dbg(skl->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", | |
| 497 | 462 | format->bit_depth, format->valid_bit_depth, |
| 498 | 463 | format->ch_cfg); |
| 499 | 464 | |
| @@ -501,7 +466,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, · 1 unmodified line | ||
| 501 | 466 | |
| 502 | 467 | base_cfg->audio_fmt.interleaving = format->interleaving_style; |
| 503 | 468 | |
| 504 | − base_cfg->cps = res->cps; | |
| 469 | + base_cfg->cpc = res->cpc; | |
| 505 | 470 | base_cfg->ibs = res->ibs; |
| 506 | 471 | base_cfg->obs = res->obs; |
| 507 | 472 | base_cfg->is_pages = res->is_pages; |
| @@ -530,7 +495,7 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig, · 22 unmodified lines | ||
| 530 | 495 | * Calculate the gatewat settings required for copier module, type of |
| 531 | 496 | * gateway and index of gateway to use |
| 532 | 497 | */ |
| 533 | −static u32 skl_get_node_id(struct skl_sst *ctx, | |
| 498 | +static u32 skl_get_node_id(struct skl_dev *skl, | |
| 534 | 499 | struct skl_module_cfg *mconfig) |
| 535 | 500 | { |
| 536 | 501 | union skl_connector_node_id node_id = {0}; |
| @@ -587,16 +552,15 @@ static u32 skl_get_node_id(struct skl_sst *ctx, · 50 unmodified lines | ||
| 587 | 552 | return node_id.val; |
| 588 | 553 | } |
| 589 | 554 | |
| 590 | −static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, | |
| 555 | +static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl, | |
| 591 | 556 | struct skl_module_cfg *mconfig, |
| 592 | 557 | struct skl_cpr_cfg *cpr_mconfig) |
| 593 | 558 | { |
| 594 | 559 | u32 dma_io_buf; |
| 595 | 560 | struct skl_module_res *res; |
| 596 | 561 | int res_idx = mconfig->res_idx; |
| 597 | − struct skl *skl = get_skl_ctx(ctx->dev); | |
| 598 | 562 | |
| 599 | − cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); | |
| 563 | + cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(skl, mconfig); | |
| 600 | 564 | |
| 601 | 565 | if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { |
| 602 | 566 | cpr_mconfig->cpr_feature_mask = 0; |
| @@ -627,7 +591,7 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, · 24 unmodified lines | ||
| 627 | 591 | break; |
| 628 | 592 | |
| 629 | 593 | default: |
| 630 | − dev_warn(ctx->dev, "wrong connection type: %d\n", | |
| 594 | + dev_warn(skl->dev, "wrong connection type: %d\n", | |
| 631 | 595 | mconfig->hw_conn_type); |
| 632 | 596 | return; |
| 633 | 597 | } |
| @@ -653,7 +617,7 @@ skip_buf_size_calc: · 19 unmodified lines | ||
| 653 | 617 | #define DMA_CONTROL_ID 5 |
| 654 | 618 | #define DMA_I2S_BLOB_SIZE 21 |
| 655 | 619 | |
| 656 | −int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, | |
| 620 | +int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps, | |
| 657 | 621 | u32 caps_size, u32 node_id) |
| 658 | 622 | { |
| 659 | 623 | struct skl_dma_control *dma_ctrl; |
| @@ -686,14 +650,14 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, · 26 unmodified lines | ||
| 686 | 650 | |
| 687 | 651 | memcpy(dma_ctrl->config_data, caps, caps_size); |
| 688 | 652 | |
| 689 | − err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl); | |
| 653 | + err = skl_ipc_set_large_config(&skl->ipc, &msg, (u32 *)dma_ctrl); | |
| 690 | 654 | |
| 691 | 655 | kfree(dma_ctrl); |
| 692 | 656 | return err; |
| 693 | 657 | } |
| 694 | 658 | EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control); |
| 695 | 659 | |
| 696 | −static void skl_setup_out_format(struct skl_sst *ctx, | |
| 660 | +static void skl_setup_out_format(struct skl_dev *skl, | |
| 697 | 661 | struct skl_module_cfg *mconfig, |
| 698 | 662 | struct skl_audio_data_format *out_fmt) |
| 699 | 663 | { |
| @@ -711,7 +675,7 @@ static void skl_setup_out_format(struct skl_sst *ctx, · 11 unmodified lines | ||
| 711 | 675 | out_fmt->interleaving = format->interleaving_style; |
| 712 | 676 | out_fmt->sample_type = format->sample_type; |
| 713 | 677 | |
| 714 | − dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", | |
| 678 | + dev_dbg(skl->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", | |
| 715 | 679 | out_fmt->number_of_channels, format->s_freq, format->bit_depth); |
| 716 | 680 | } |
| 717 | 681 | |
| @@ -720,7 +684,7 @@ static void skl_setup_out_format(struct skl_sst *ctx, · 2 unmodified lines | ||
| 720 | 684 | * configuration and the target frequency as extra parameter passed as src |
| 721 | 685 | * config |
| 722 | 686 | */ |
| 723 | −static void skl_set_src_format(struct skl_sst *ctx, | |
| 687 | +static void skl_set_src_format(struct skl_dev *skl, | |
| 724 | 688 | struct skl_module_cfg *mconfig, |
| 725 | 689 | struct skl_src_module_cfg *src_mconfig) |
| 726 | 690 | { |
| @@ -728,7 +692,7 @@ static void skl_set_src_format(struct skl_sst *ctx, · 1 unmodified line | ||
| 728 | 692 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; |
| 729 | 693 | struct skl_module_fmt *fmt = &iface->outputs[0].fmt; |
| 730 | 694 | |
| 731 | − skl_set_base_module_format(ctx, mconfig, | |
| 695 | + skl_set_base_module_format(skl, mconfig, | |
| 732 | 696 | (struct skl_base_cfg *)src_mconfig); |
| 733 | 697 | |
| 734 | 698 | src_mconfig->src_cfg = fmt->s_freq; |
| @@ -739,7 +703,7 @@ static void skl_set_src_format(struct skl_sst *ctx, · 4 unmodified lines | ||
| 739 | 703 | * module configuration and channel configuration |
| 740 | 704 | * It also take coefficients and now we have defaults applied here |
| 741 | 705 | */ |
| 742 | −static void skl_set_updown_mixer_format(struct skl_sst *ctx, | |
| 706 | +static void skl_set_updown_mixer_format(struct skl_dev *skl, | |
| 743 | 707 | struct skl_module_cfg *mconfig, |
| 744 | 708 | struct skl_up_down_mixer_cfg *mixer_mconfig) |
| 745 | 709 | { |
| @@ -747,7 +711,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, · 1 unmodified line | ||
| 747 | 711 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; |
| 748 | 712 | struct skl_module_fmt *fmt = &iface->outputs[0].fmt; |
| 749 | 713 | |
| 750 | − skl_set_base_module_format(ctx, mconfig, | |
| 714 | + skl_set_base_module_format(skl, mconfig, | |
| 751 | 715 | (struct skl_base_cfg *)mixer_mconfig); |
| 752 | 716 | mixer_mconfig->out_ch_cfg = fmt->ch_cfg; |
| 753 | 717 | mixer_mconfig->ch_map = fmt->ch_map; |
| @@ -760,17 +724,17 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, · 6 unmodified lines | ||
| 760 | 724 | * format, gateway settings |
| 761 | 725 | * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg |
| 762 | 726 | */ |
| 763 | −static void skl_set_copier_format(struct skl_sst *ctx, | |
| 727 | +static void skl_set_copier_format(struct skl_dev *skl, | |
| 764 | 728 | struct skl_module_cfg *mconfig, |
| 765 | 729 | struct skl_cpr_cfg *cpr_mconfig) |
| 766 | 730 | { |
| 767 | 731 | struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; |
| 768 | 732 | struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig; |
| 769 | 733 | |
| 770 | − skl_set_base_module_format(ctx, mconfig, base_cfg); | |
| 734 | + skl_set_base_module_format(skl, mconfig, base_cfg); | |
| 771 | 735 | |
| 772 | − skl_setup_out_format(ctx, mconfig, out_fmt); | |
| 773 | − skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); | |
| 736 | + skl_setup_out_format(skl, mconfig, out_fmt); | |
| 737 | + skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig); | |
| 774 | 738 | } |
| 775 | 739 | |
| 776 | 740 | /* |
| @@ -778,13 +742,13 @@ static void skl_set_copier_format(struct skl_sst *ctx, · 1 unmodified line | ||
| 778 | 742 | * configuration and params |
| 779 | 743 | */ |
| 780 | 744 | |
| 781 | −static void skl_set_algo_format(struct skl_sst *ctx, | |
| 745 | +static void skl_set_algo_format(struct skl_dev *skl, | |
| 782 | 746 | struct skl_module_cfg *mconfig, |
| 783 | 747 | struct skl_algo_cfg *algo_mcfg) |
| 784 | 748 | { |
| 785 | 749 | struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; |
| 786 | 750 | |
| 787 | − skl_set_base_module_format(ctx, mconfig, base_cfg); | |
| 751 | + skl_set_base_module_format(skl, mconfig, base_cfg); | |
| 788 | 752 | |
| 789 | 753 | if (mconfig->formats_config.caps_size == 0) |
| 790 | 754 | return; |
| @@ -802,7 +766,7 @@ static void skl_set_algo_format(struct skl_sst *ctx, · 11 unmodified lines | ||
| 802 | 766 | * Mic select module take base module configuration and out-format |
| 803 | 767 | * configuration |
| 804 | 768 | */ |
| 805 | −static void skl_set_base_outfmt_format(struct skl_sst *ctx, | |
| 769 | +static void skl_set_base_outfmt_format(struct skl_dev *skl, | |
| 806 | 770 | struct skl_module_cfg *mconfig, |
| 807 | 771 | struct skl_base_outfmt_cfg *base_outfmt_mcfg) |
| 808 | 772 | { |
| @@ -810,11 +774,11 @@ static void skl_set_base_outfmt_format(struct skl_sst *ctx, · 1 unmodified line | ||
| 810 | 774 | struct skl_base_cfg *base_cfg = |
| 811 | 775 | (struct skl_base_cfg *)base_outfmt_mcfg; |
| 812 | 776 | |
| 813 | − skl_set_base_module_format(ctx, mconfig, base_cfg); | |
| 814 | − skl_setup_out_format(ctx, mconfig, out_fmt); | |
| 777 | + skl_set_base_module_format(skl, mconfig, base_cfg); | |
| 778 | + skl_setup_out_format(skl, mconfig, out_fmt); | |
| 815 | 779 | } |
| 816 | 780 | |
| 817 | −static u16 skl_get_module_param_size(struct skl_sst *ctx, | |
| 781 | +static u16 skl_get_module_param_size(struct skl_dev *skl, | |
| 818 | 782 | struct skl_module_cfg *mconfig) |
| 819 | 783 | { |
| 820 | 784 | u16 param_size; |
| @@ -859,14 +823,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx, · 38 unmodified lines | ||
| 859 | 823 | * base module format configuration |
| 860 | 824 | */ |
| 861 | 825 | |
| 862 | −static int skl_set_module_format(struct skl_sst *ctx, | |
| 826 | +static int skl_set_module_format(struct skl_dev *skl, | |
| 863 | 827 | struct skl_module_cfg *module_config, |
| 864 | 828 | u16 *module_config_size, |
| 865 | 829 | void **param_data) |
| 866 | 830 | { |
| 867 | 831 | u16 param_size; |
| 868 | 832 | |
| 869 | − param_size = skl_get_module_param_size(ctx, module_config); | |
| 833 | + param_size = skl_get_module_param_size(skl, module_config); | |
| 870 | 834 | |
| 871 | 835 | *param_data = kzalloc(param_size, GFP_KERNEL); |
| 872 | 836 | if (NULL == *param_data) |
| @@ -876,35 +840,36 @@ static int skl_set_module_format(struct skl_sst *ctx, · 3 unmodified lines | ||
| 876 | 840 | |
| 877 | 841 | switch (module_config->m_type) { |
| 878 | 842 | case SKL_MODULE_TYPE_COPIER: |
| 879 | − skl_set_copier_format(ctx, module_config, *param_data); | |
| 843 | + skl_set_copier_format(skl, module_config, *param_data); | |
| 880 | 844 | break; |
| 881 | 845 | |
| 882 | 846 | case SKL_MODULE_TYPE_SRCINT: |
| 883 | − skl_set_src_format(ctx, module_config, *param_data); | |
| 847 | + skl_set_src_format(skl, module_config, *param_data); | |
| 884 | 848 | break; |
| 885 | 849 | |
| 886 | 850 | case SKL_MODULE_TYPE_UPDWMIX: |
| 887 | − skl_set_updown_mixer_format(ctx, module_config, *param_data); | |
| 851 | + skl_set_updown_mixer_format(skl, module_config, *param_data); | |
| 888 | 852 | break; |
| 889 | 853 | |
| 890 | 854 | case SKL_MODULE_TYPE_ALGO: |
| 891 | − skl_set_algo_format(ctx, module_config, *param_data); | |
| 855 | + skl_set_algo_format(skl, module_config, *param_data); | |
| 892 | 856 | break; |
| 893 | 857 | |
| 894 | 858 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
| 895 | 859 | case SKL_MODULE_TYPE_MIC_SELECT: |
| 896 | 860 | case SKL_MODULE_TYPE_KPB: |
| 897 | − skl_set_base_outfmt_format(ctx, module_config, *param_data); | |
| 861 | + skl_set_base_outfmt_format(skl, module_config, *param_data); | |
| 898 | 862 | break; |
| 899 | 863 | |
| 900 | 864 | default: |
| 901 | − skl_set_base_module_format(ctx, module_config, *param_data); | |
| 865 | + skl_set_base_module_format(skl, module_config, *param_data); | |
| 902 | 866 | break; |
| 903 | 867 | |
| 904 | 868 | } |
| 905 | 869 | |
| 906 | − dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", | |
| 907 | − module_config->id.module_id, param_size); | |
| 870 | + dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n", | |
| 871 | + module_config->m_type, module_config->id.module_id, | |
| 872 | + param_size); | |
| 908 | 873 | print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, |
| 909 | 874 | *param_data, param_size, false); |
| 910 | 875 | return 0; |
| @@ -1004,7 +969,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max, · 93 unmodified lines | ||
| 1004 | 969 | * We first calculate the module format, based on module type and then |
| 1005 | 970 | * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper |
| 1006 | 971 | */ |
| 1007 | −int skl_init_module(struct skl_sst *ctx, | |
| 972 | +int skl_init_module(struct skl_dev *skl, | |
| 1008 | 973 | struct skl_module_cfg *mconfig) |
| 1009 | 974 | { |
| 1010 | 975 | u16 module_config_size = 0; |
| @@ -1012,19 +977,19 @@ int skl_init_module(struct skl_sst *ctx, · 1 unmodified line | ||
| 1012 | 977 | int ret; |
| 1013 | 978 | struct skl_ipc_init_instance_msg msg; |
| 1014 | 979 | |
| 1015 | − dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, | |
| 980 | + dev_dbg(skl->dev, "%s: module_id = %d instance=%d\n", __func__, | |
| 1016 | 981 | mconfig->id.module_id, mconfig->id.pvt_id); |
| 1017 | 982 | |
| 1018 | 983 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { |
| 1019 | − dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", | |
| 984 | + dev_err(skl->dev, "Pipe not created state= %d pipe_id= %d\n", | |
| 1020 | 985 | mconfig->pipe->state, mconfig->pipe->ppl_id); |
| 1021 | 986 | return -EIO; |
| 1022 | 987 | } |
| 1023 | 988 | |
| 1024 | − ret = skl_set_module_format(ctx, mconfig, | |
| 989 | + ret = skl_set_module_format(skl, mconfig, | |
| 1025 | 990 | &module_config_size, ¶m_data); |
| 1026 | 991 | if (ret < 0) { |
| 1027 | − dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret); | |
| 992 | + dev_err(skl->dev, "Failed to set module format ret=%d\n", ret); | |
| 1028 | 993 | return ret; |
| 1029 | 994 | } |
| 1030 | 995 | |
| @@ -1035,9 +1000,9 @@ int skl_init_module(struct skl_sst *ctx, · 4 unmodified lines | ||
| 1035 | 1000 | msg.core_id = mconfig->core_id; |
| 1036 | 1001 | msg.domain = mconfig->domain; |
| 1037 | 1002 | |
| 1038 | − ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); | |
| 1003 | + ret = skl_ipc_init_instance(&skl->ipc, &msg, param_data); | |
| 1039 | 1004 | if (ret < 0) { |
| 1040 | − dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret); | |
| 1005 | + dev_err(skl->dev, "Failed to init instance ret=%d\n", ret); | |
| 1041 | 1006 | kfree(param_data); |
| 1042 | 1007 | return ret; |
| 1043 | 1008 | } |
| @@ -1046,15 +1011,15 @@ int skl_init_module(struct skl_sst *ctx, · 2 unmodified lines | ||
| 1046 | 1011 | return ret; |
| 1047 | 1012 | } |
| 1048 | 1013 | |
| 1049 | −static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg | |
| 1014 | +static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg | |
| 1050 | 1015 | *src_module, struct skl_module_cfg *dst_module) |
| 1051 | 1016 | { |
| 1052 | − dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", | |
| 1017 | + dev_dbg(skl->dev, "%s: src module_id = %d src_instance=%d\n", | |
| 1053 | 1018 | __func__, src_module->id.module_id, src_module->id.pvt_id); |
| 1054 | − dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, | |
| 1019 | + dev_dbg(skl->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, | |
| 1055 | 1020 | dst_module->id.module_id, dst_module->id.pvt_id); |
| 1056 | 1021 | |
| 1057 | − dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", | |
| 1022 | + dev_dbg(skl->dev, "src_module state = %d dst module state = %d\n", | |
| 1058 | 1023 | src_module->m_state, dst_module->m_state); |
| 1059 | 1024 | } |
| 1060 | 1025 | |
| @@ -1063,7 +1028,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg · 2 unmodified lines | ||
| 1063 | 1028 | * it is already bind. |
| 1064 | 1029 | * Find the pin allocated and unbind then using bind_unbind IPC |
| 1065 | 1030 | */ |
| 1066 | −int skl_unbind_modules(struct skl_sst *ctx, | |
| 1031 | +int skl_unbind_modules(struct skl_dev *skl, | |
| 1067 | 1032 | struct skl_module_cfg *src_mcfg, |
| 1068 | 1033 | struct skl_module_cfg *dst_mcfg) |
| 1069 | 1034 | { |
| @@ -1075,7 +1040,7 @@ int skl_unbind_modules(struct skl_sst *ctx, · 5 unmodified lines | ||
| 1075 | 1040 | int out_max = src_mcfg->module->max_output_pins; |
| 1076 | 1041 | int src_index, dst_index, src_pin_state, dst_pin_state; |
| 1077 | 1042 | |
| 1078 | − skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); | |
| 1043 | + skl_dump_bind_info(skl, src_mcfg, dst_mcfg); | |
| 1079 | 1044 | |
| 1080 | 1045 | /* get src queue index */ |
| 1081 | 1046 | src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); |
| @@ -1104,7 +1069,7 @@ int skl_unbind_modules(struct skl_sst *ctx, · 22 unmodified lines | ||
| 1104 | 1069 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
| 1105 | 1070 | msg.bind = false; |
| 1106 | 1071 | |
| 1107 | − ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | |
| 1072 | + ret = skl_ipc_bind_unbind(&skl->ipc, &msg); | |
| 1108 | 1073 | if (!ret) { |
| 1109 | 1074 | /* free queue only if unbind is success */ |
| 1110 | 1075 | skl_free_queue(src_mcfg->m_out_pin, src_index); |
| @@ -1142,7 +1107,7 @@ static void fill_pin_params(struct skl_audio_data_format *pin_fmt, · 31 unmodified lines | ||
| 1142 | 1107 | * This function finds the pins and then sends bund_unbind IPC message to |
| 1143 | 1108 | * DSP using IPC helper |
| 1144 | 1109 | */ |
| 1145 | −int skl_bind_modules(struct skl_sst *ctx, | |
| 1110 | +int skl_bind_modules(struct skl_dev *skl, | |
| 1146 | 1111 | struct skl_module_cfg *src_mcfg, |
| 1147 | 1112 | struct skl_module_cfg *dst_mcfg) |
| 1148 | 1113 | { |
| @@ -1156,7 +1121,7 @@ int skl_bind_modules(struct skl_sst *ctx, · 7 unmodified lines | ||
| 1156 | 1121 | struct skl_module *module; |
| 1157 | 1122 | struct skl_module_iface *fmt; |
| 1158 | 1123 | |
| 1159 | − skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); | |
| 1124 | + skl_dump_bind_info(skl, src_mcfg, dst_mcfg); | |
| 1160 | 1125 | |
| 1161 | 1126 | if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || |
| 1162 | 1127 | dst_mcfg->m_state < SKL_MODULE_INIT_DONE) |
| @@ -1188,7 +1153,7 @@ int skl_bind_modules(struct skl_sst *ctx, · 25 unmodified lines | ||
| 1188 | 1153 | |
| 1189 | 1154 | format = &fmt->outputs[src_index].fmt; |
| 1190 | 1155 | fill_pin_params(&(pin_fmt.dst_fmt), format); |
| 1191 | − ret = skl_set_module_params(ctx, (void *)&pin_fmt, | |
| 1156 | + ret = skl_set_module_params(skl, (void *)&pin_fmt, | |
| 1192 | 1157 | sizeof(struct skl_cpr_pin_fmt), |
| 1193 | 1158 | CPR_SINK_FMT_PARAM_ID, src_mcfg); |
| 1194 | 1159 | |
| @@ -1198,7 +1163,7 @@ int skl_bind_modules(struct skl_sst *ctx, · 3 unmodified lines | ||
| 1198 | 1163 | |
| 1199 | 1164 | msg.dst_queue = dst_index; |
| 1200 | 1165 | |
| 1201 | − dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", | |
| 1166 | + dev_dbg(skl->dev, "src queue = %d dst queue =%d\n", | |
| 1202 | 1167 | msg.src_queue, msg.dst_queue); |
| 1203 | 1168 | |
| 1204 | 1169 | msg.module_id = src_mcfg->id.module_id; |
| @@ -1207,7 +1172,7 @@ int skl_bind_modules(struct skl_sst *ctx, · 2 unmodified lines | ||
| 1207 | 1172 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
| 1208 | 1173 | msg.bind = true; |
| 1209 | 1174 | |
| 1210 | − ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | |
| 1175 | + ret = skl_ipc_bind_unbind(&skl->ipc, &msg); | |
| 1211 | 1176 | |
| 1212 | 1177 | if (!ret) { |
| 1213 | 1178 | src_mcfg->m_state = SKL_MODULE_BIND_DONE; |
| @@ -1223,12 +1188,12 @@ out: · 9 unmodified lines | ||
| 1223 | 1188 | return ret; |
| 1224 | 1189 | } |
| 1225 | 1190 | |
| 1226 | −static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe, | |
| 1191 | +static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe, | |
| 1227 | 1192 | enum skl_ipc_pipeline_state state) |
| 1228 | 1193 | { |
| 1229 | − dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state); | |
| 1194 | + dev_dbg(skl->dev, "%s: pipe_state = %d\n", __func__, state); | |
| 1230 | 1195 | |
| 1231 | − return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state); | |
| 1196 | + return skl_ipc_set_pipeline_state(&skl->ipc, pipe->ppl_id, state); | |
| 1232 | 1197 | } |
| 1233 | 1198 | |
| 1234 | 1199 | /* |
| @@ -1237,17 +1202,17 @@ static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe, · 2 unmodified lines | ||
| 1237 | 1202 | * This function creates pipeline, by sending create pipeline IPC messages |
| 1238 | 1203 | * to FW |
| 1239 | 1204 | */ |
| 1240 | −int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe) | |
| 1205 | +int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 1241 | 1206 | { |
| 1242 | 1207 | int ret; |
| 1243 | 1208 | |
| 1244 | − dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id); | |
| 1209 | + dev_dbg(skl->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id); | |
| 1245 | 1210 | |
| 1246 | − ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages, | |
| 1211 | + ret = skl_ipc_create_pipeline(&skl->ipc, pipe->memory_pages, | |
| 1247 | 1212 | pipe->pipe_priority, pipe->ppl_id, |
| 1248 | 1213 | pipe->lp_mode); |
| 1249 | 1214 | if (ret < 0) { |
| 1250 | − dev_err(ctx->dev, "Failed to create pipeline\n"); | |
| 1215 | + dev_err(skl->dev, "Failed to create pipeline\n"); | |
| 1251 | 1216 | return ret; |
| 1252 | 1217 | } |
| 1253 | 1218 | |
| @@ -1262,11 +1227,11 @@ int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe) · 8 unmodified lines | ||
| 1262 | 1227 | * reset state. Finish the procedure by sending delete pipeline IPC. |
| 1263 | 1228 | * DSP will stop the DMA engines and release resources |
| 1264 | 1229 | */ |
| 1265 | −int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) | |
| 1230 | +int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 1266 | 1231 | { |
| 1267 | 1232 | int ret; |
| 1268 | 1233 | |
| 1269 | − dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); | |
| 1234 | + dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); | |
| 1270 | 1235 | |
| 1271 | 1236 | /* If pipe was not created in FW, do not try to delete it */ |
| 1272 | 1237 | if (pipe->state < SKL_PIPE_CREATED) |
| @@ -1274,9 +1239,9 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 1 unmodified line | ||
| 1274 | 1239 | |
| 1275 | 1240 | /* If pipe is started, do stop the pipe in FW. */ |
| 1276 | 1241 | if (pipe->state >= SKL_PIPE_STARTED) { |
| 1277 | − ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); | |
| 1242 | + ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED); | |
| 1278 | 1243 | if (ret < 0) { |
| 1279 | − dev_err(ctx->dev, "Failed to stop pipeline\n"); | |
| 1244 | + dev_err(skl->dev, "Failed to stop pipeline\n"); | |
| 1280 | 1245 | return ret; |
| 1281 | 1246 | } |
| 1282 | 1247 | |
| @@ -1284,17 +1249,17 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 1 unmodified line | ||
| 1284 | 1249 | } |
| 1285 | 1250 | |
| 1286 | 1251 | /* reset pipe state before deletion */ |
| 1287 | − ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); | |
| 1252 | + ret = skl_set_pipe_state(skl, pipe, PPL_RESET); | |
| 1288 | 1253 | if (ret < 0) { |
| 1289 | − dev_err(ctx->dev, "Failed to reset pipe ret=%d\n", ret); | |
| 1254 | + dev_err(skl->dev, "Failed to reset pipe ret=%d\n", ret); | |
| 1290 | 1255 | return ret; |
| 1291 | 1256 | } |
| 1292 | 1257 | |
| 1293 | 1258 | pipe->state = SKL_PIPE_RESET; |
| 1294 | 1259 | |
| 1295 | − ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); | |
| 1260 | + ret = skl_ipc_delete_pipeline(&skl->ipc, pipe->ppl_id); | |
| 1296 | 1261 | if (ret < 0) { |
| 1297 | − dev_err(ctx->dev, "Failed to delete pipeline\n"); | |
| 1262 | + dev_err(skl->dev, "Failed to delete pipeline\n"); | |
| 1298 | 1263 | return ret; |
| 1299 | 1264 | } |
| 1300 | 1265 | |
| @@ -1308,28 +1273,28 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 7 unmodified lines | ||
| 1308 | 1273 | * For processing data the pipe need to be run by sending IPC set pipe state |
| 1309 | 1274 | * to DSP |
| 1310 | 1275 | */ |
| 1311 | −int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) | |
| 1276 | +int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 1312 | 1277 | { |
| 1313 | 1278 | int ret; |
| 1314 | 1279 | |
| 1315 | − dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); | |
| 1280 | + dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); | |
| 1316 | 1281 | |
| 1317 | 1282 | /* If pipe was not created in FW, do not try to pause or delete */ |
| 1318 | 1283 | if (pipe->state < SKL_PIPE_CREATED) |
| 1319 | 1284 | return 0; |
| 1320 | 1285 | |
| 1321 | 1286 | /* Pipe has to be paused before it is started */ |
| 1322 | − ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); | |
| 1287 | + ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED); | |
| 1323 | 1288 | if (ret < 0) { |
| 1324 | − dev_err(ctx->dev, "Failed to pause pipe\n"); | |
| 1289 | + dev_err(skl->dev, "Failed to pause pipe\n"); | |
| 1325 | 1290 | return ret; |
| 1326 | 1291 | } |
| 1327 | 1292 | |
| 1328 | 1293 | pipe->state = SKL_PIPE_PAUSED; |
| 1329 | 1294 | |
| 1330 | − ret = skl_set_pipe_state(ctx, pipe, PPL_RUNNING); | |
| 1295 | + ret = skl_set_pipe_state(skl, pipe, PPL_RUNNING); | |
| 1331 | 1296 | if (ret < 0) { |
| 1332 | − dev_err(ctx->dev, "Failed to start pipe\n"); | |
| 1297 | + dev_err(skl->dev, "Failed to start pipe\n"); | |
| 1333 | 1298 | return ret; |
| 1334 | 1299 | } |
| 1335 | 1300 | |
| @@ -1342,19 +1307,19 @@ int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 6 unmodified lines | ||
| 1342 | 1307 | * Stop the pipeline by sending set pipe state IPC |
| 1343 | 1308 | * DSP doesnt implement stop so we always send pause message |
| 1344 | 1309 | */ |
| 1345 | −int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) | |
| 1310 | +int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 1346 | 1311 | { |
| 1347 | 1312 | int ret; |
| 1348 | 1313 | |
| 1349 | − dev_dbg(ctx->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id); | |
| 1314 | + dev_dbg(skl->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id); | |
| 1350 | 1315 | |
| 1351 | 1316 | /* If pipe was not created in FW, do not try to pause or delete */ |
| 1352 | 1317 | if (pipe->state < SKL_PIPE_PAUSED) |
| 1353 | 1318 | return 0; |
| 1354 | 1319 | |
| 1355 | − ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); | |
| 1320 | + ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED); | |
| 1356 | 1321 | if (ret < 0) { |
| 1357 | − dev_dbg(ctx->dev, "Failed to stop pipe\n"); | |
| 1322 | + dev_dbg(skl->dev, "Failed to stop pipe\n"); | |
| 1358 | 1323 | return ret; |
| 1359 | 1324 | } |
| 1360 | 1325 | |
| @@ -1367,7 +1332,7 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 6 unmodified lines | ||
| 1367 | 1332 | * Reset the pipeline by sending set pipe state IPC this will reset the DMA |
| 1368 | 1333 | * from the DSP side |
| 1369 | 1334 | */ |
| 1370 | −int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) | |
| 1335 | +int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 1371 | 1336 | { |
| 1372 | 1337 | int ret; |
| 1373 | 1338 | |
| @@ -1375,9 +1340,9 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 1 unmodified line | ||
| 1375 | 1340 | if (pipe->state < SKL_PIPE_PAUSED) |
| 1376 | 1341 | return 0; |
| 1377 | 1342 | |
| 1378 | − ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); | |
| 1343 | + ret = skl_set_pipe_state(skl, pipe, PPL_RESET); | |
| 1379 | 1344 | if (ret < 0) { |
| 1380 | − dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret); | |
| 1345 | + dev_dbg(skl->dev, "Failed to reset pipe ret=%d\n", ret); | |
| 1381 | 1346 | return ret; |
| 1382 | 1347 | } |
| 1383 | 1348 | |
| @@ -1387,7 +1352,7 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) · 3 unmodified lines | ||
| 1387 | 1352 | } |
| 1388 | 1353 | |
| 1389 | 1354 | /* Algo parameter set helper function */ |
| 1390 | −int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, | |
| 1355 | +int skl_set_module_params(struct skl_dev *skl, u32 *params, int size, | |
| 1391 | 1356 | u32 param_id, struct skl_module_cfg *mcfg) |
| 1392 | 1357 | { |
| 1393 | 1358 | struct skl_ipc_large_config_msg msg; |
| @@ -1397,18 +1362,19 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, · 3 unmodified lines | ||
| 1397 | 1362 | msg.param_data_size = size; |
| 1398 | 1363 | msg.large_param_id = param_id; |
| 1399 | 1364 | |
| 1400 | − return skl_ipc_set_large_config(&ctx->ipc, &msg, params); | |
| 1365 | + return skl_ipc_set_large_config(&skl->ipc, &msg, params); | |
| 1401 | 1366 | } |
| 1402 | 1367 | |
| 1403 | −int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, | |
| 1368 | +int skl_get_module_params(struct skl_dev *skl, u32 *params, int size, | |
| 1404 | 1369 | u32 param_id, struct skl_module_cfg *mcfg) |
| 1405 | 1370 | { |
| 1406 | 1371 | struct skl_ipc_large_config_msg msg; |
| 1372 | + size_t bytes = size; | |
| 1407 | 1373 | |
| 1408 | 1374 | msg.module_id = mcfg->id.module_id; |
| 1409 | 1375 | msg.instance_id = mcfg->id.pvt_id; |
| 1410 | 1376 | msg.param_data_size = size; |
| 1411 | 1377 | msg.large_param_id = param_id; |
| 1412 | 1378 | |
| 1413 | − return skl_ipc_get_large_config(&ctx->ipc, &msg, params); | |
| 1379 | + return skl_ipc_get_large_config(&skl->ipc, &msg, ¶ms, &bytes); | |
| 1414 | 1380 | } |
| @@ -9,57 +9,10 @@ · 8 unmodified lines | ||
| 9 | 9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 10 | 10 | */ |
| 11 | 11 | #include <linux/pci.h> |
| 12 | +#include <sound/intel-nhlt.h> | |
| 12 | 13 | #include "skl.h" |
| 13 | 14 | #include "skl-i2s.h" |
| 14 | 15 | |
| 15 | −#define NHLT_ACPI_HEADER_SIG "NHLT" | |
| 16 | − | |
| 17 | −/* Unique identification for getting NHLT blobs */ | |
| 18 | −static guid_t osc_guid = | |
| 19 | − GUID_INIT(0xA69F886E, 0x6CEB, 0x4594, | |
| 20 | − 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53); | |
| 21 | − | |
| 22 | − | |
| 23 | −struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) | |
| 24 | −{ | |
| 25 | − acpi_handle handle; | |
| 26 | − union acpi_object *obj; | |
| 27 | − struct nhlt_resource_desc *nhlt_ptr = NULL; | |
| 28 | − struct nhlt_acpi_table *nhlt_table = NULL; | |
| 29 | − | |
| 30 | − handle = ACPI_HANDLE(dev); | |
| 31 | − if (!handle) { | |
| 32 | − dev_err(dev, "Didn't find ACPI_HANDLE\n"); | |
| 33 | − return NULL; | |
| 34 | − } | |
| 35 | − | |
| 36 | − obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL); | |
| 37 | − if (obj && obj->type == ACPI_TYPE_BUFFER) { | |
| 38 | − nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; | |
| 39 | − if (nhlt_ptr->length) | |
| 40 | − nhlt_table = (struct nhlt_acpi_table *) | |
| 41 | − memremap(nhlt_ptr->min_addr, nhlt_ptr->length, | |
| 42 | − MEMREMAP_WB); | |
| 43 | − ACPI_FREE(obj); | |
| 44 | − if (nhlt_table && (strncmp(nhlt_table->header.signature, | |
| 45 | − NHLT_ACPI_HEADER_SIG, | |
| 46 | − strlen(NHLT_ACPI_HEADER_SIG)) != 0)) { | |
| 47 | − memunmap(nhlt_table); | |
| 48 | − dev_err(dev, "NHLT ACPI header signature incorrect\n"); | |
| 49 | − return NULL; | |
| 50 | − } | |
| 51 | − return nhlt_table; | |
| 52 | − } | |
| 53 | − | |
| 54 | − dev_err(dev, "device specific method to extract NHLT blob failed\n"); | |
| 55 | − return NULL; | |
| 56 | −} | |
| 57 | − | |
| 58 | −void skl_nhlt_free(struct nhlt_acpi_table *nhlt) | |
| 59 | −{ | |
| 60 | − memunmap((void *) nhlt); | |
| 61 | −} | |
| 62 | − | |
| 63 | 16 | static struct nhlt_specific_cfg *skl_get_specific_cfg( |
| 64 | 17 | struct device *dev, struct nhlt_fmt *fmt, |
| 65 | 18 | u8 no_ch, u32 rate, u16 bps, u8 linktype) |
| @@ -126,7 +79,7 @@ static bool skl_check_ep_match(struct device *dev, struct nhlt_endpoint *epnt, · 60 unmodified lines | ||
| 126 | 79 | } |
| 127 | 80 | |
| 128 | 81 | struct nhlt_specific_cfg |
| 129 | −*skl_get_ep_blob(struct skl *skl, u32 instance, u8 link_type, | |
| 82 | +*skl_get_ep_blob(struct skl_dev *skl, u32 instance, u8 link_type, | |
| 130 | 83 | u8 s_fmt, u8 num_ch, u32 s_rate, |
| 131 | 84 | u8 dirn, u8 dev_type) |
| 132 | 85 | { |
| @@ -162,48 +115,6 @@ struct nhlt_specific_cfg · 29 unmodified lines | ||
| 162 | 115 | return NULL; |
| 163 | 116 | } |
| 164 | 117 | |
| 165 | −int skl_get_dmic_geo(struct skl *skl) | |
| 166 | −{ | |
| 167 | − struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | |
| 168 | − struct nhlt_endpoint *epnt; | |
| 169 | − struct nhlt_dmic_array_config *cfg; | |
| 170 | − struct device *dev = &skl->pci->dev; | |
| 171 | − unsigned int dmic_geo = 0; | |
| 172 | − u8 j; | |
| 173 | − | |
| 174 | − if (!nhlt) | |
| 175 | − return 0; | |
| 176 | − | |
| 177 | − epnt = (struct nhlt_endpoint *)nhlt->desc; | |
| 178 | − | |
| 179 | − for (j = 0; j < nhlt->endpoint_count; j++) { | |
| 180 | − if (epnt->linktype == NHLT_LINK_DMIC) { | |
| 181 | − cfg = (struct nhlt_dmic_array_config *) | |
| 182 | − (epnt->config.caps); | |
| 183 | − switch (cfg->array_type) { | |
| 184 | − case NHLT_MIC_ARRAY_2CH_SMALL: | |
| 185 | − case NHLT_MIC_ARRAY_2CH_BIG: | |
| 186 | − dmic_geo |= MIC_ARRAY_2CH; | |
| 187 | − break; | |
| 188 | − | |
| 189 | − case NHLT_MIC_ARRAY_4CH_1ST_GEOM: | |
| 190 | − case NHLT_MIC_ARRAY_4CH_L_SHAPED: | |
| 191 | − case NHLT_MIC_ARRAY_4CH_2ND_GEOM: | |
| 192 | − dmic_geo |= MIC_ARRAY_4CH; | |
| 193 | − break; | |
| 194 | − | |
| 195 | − default: | |
| 196 | − dev_warn(dev, "undefined DMIC array_type 0x%0x\n", | |
| 197 | − cfg->array_type); | |
| 198 | − | |
| 199 | − } | |
| 200 | − } | |
| 201 | − epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); | |
| 202 | − } | |
| 203 | − | |
| 204 | − return dmic_geo; | |
| 205 | −} | |
| 206 | − | |
| 207 | 118 | static void skl_nhlt_trim_space(char *trim) |
| 208 | 119 | { |
| 209 | 120 | char *s = trim; |
| @@ -219,7 +130,7 @@ static void skl_nhlt_trim_space(char *trim) · 9 unmodified lines | ||
| 219 | 130 | s[cnt] = '\0'; |
| 220 | 131 | } |
| 221 | 132 | |
| 222 | −int skl_nhlt_update_topology_bin(struct skl *skl) | |
| 133 | +int skl_nhlt_update_topology_bin(struct skl_dev *skl) | |
| 223 | 134 | { |
| 224 | 135 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 225 | 136 | struct hdac_bus *bus = skl_to_bus(skl); |
| @@ -243,7 +154,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev, · 17 unmodified lines | ||
| 243 | 154 | { |
| 244 | 155 | struct pci_dev *pci = to_pci_dev(dev); |
| 245 | 156 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 246 | − struct skl *skl = bus_to_skl(bus); | |
| 157 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 247 | 158 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 248 | 159 | char platform_id[32]; |
| 249 | 160 | |
| @@ -257,7 +168,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev, · 7 unmodified lines | ||
| 257 | 168 | |
| 258 | 169 | static DEVICE_ATTR(platform_id, 0444, skl_nhlt_platform_id_show, NULL); |
| 259 | 170 | |
| 260 | −int skl_nhlt_create_sysfs(struct skl *skl) | |
| 171 | +int skl_nhlt_create_sysfs(struct skl_dev *skl) | |
| 261 | 172 | { |
| 262 | 173 | struct device *dev = &skl->pci->dev; |
| 263 | 174 | |
| @@ -267,7 +178,7 @@ int skl_nhlt_create_sysfs(struct skl *skl) · 3 unmodified lines | ||
| 267 | 178 | return 0; |
| 268 | 179 | } |
| 269 | 180 | |
| 270 | −void skl_nhlt_remove_sysfs(struct skl *skl) | |
| 181 | +void skl_nhlt_remove_sysfs(struct skl_dev *skl) | |
| 271 | 182 | { |
| 272 | 183 | struct device *dev = &skl->pci->dev; |
| 273 | 184 | |
| @@ -279,7 +190,7 @@ void skl_nhlt_remove_sysfs(struct skl *skl) · 5 unmodified lines | ||
| 279 | 190 | * stores all possible rates supported in a rate table for the corresponding |
| 280 | 191 | * sclk/sclkfs. |
| 281 | 192 | */ |
| 282 | −static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks, | |
| 193 | +static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks, | |
| 283 | 194 | struct nhlt_fmt *fmt, u8 id) |
| 284 | 195 | { |
| 285 | 196 | struct skl_i2s_config_blob_ext *i2s_config_ext; |
| @@ -377,7 +288,7 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks, · 91 unmodified lines | ||
| 377 | 288 | } |
| 378 | 289 | } |
| 379 | 290 | |
| 380 | −static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk, | |
| 291 | +static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk, | |
| 381 | 292 | struct nhlt_fmt *fmt, u8 id) |
| 382 | 293 | { |
| 383 | 294 | struct skl_i2s_config_blob_ext *i2s_config_ext; |
| @@ -421,7 +332,7 @@ static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk, · 37 unmodified lines | ||
| 421 | 332 | mclk[id].parent_name = parent->name; |
| 422 | 333 | } |
| 423 | 334 | |
| 424 | −void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks) | |
| 335 | +void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks) | |
| 425 | 336 | { |
| 426 | 337 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 427 | 338 | struct nhlt_endpoint *epnt; |
| @@ -116,7 +116,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, · 115 unmodified lines | ||
| 116 | 116 | { |
| 117 | 117 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 118 | 118 | struct snd_soc_dapm_widget *w; |
| 119 | − struct skl *skl = bus_to_skl(bus); | |
| 119 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 120 | 120 | |
| 121 | 121 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 122 | 122 | w = dai->playback_widget; |
| @@ -132,7 +132,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, · 9 unmodified lines | ||
| 132 | 132 | int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) |
| 133 | 133 | { |
| 134 | 134 | struct hdac_bus *bus = dev_get_drvdata(dev); |
| 135 | − struct skl *skl = bus_to_skl(bus); | |
| 135 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 136 | 136 | unsigned int format_val; |
| 137 | 137 | struct hdac_stream *hstream; |
| 138 | 138 | struct hdac_ext_stream *stream; |
| @@ -224,7 +224,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream, · 85 unmodified lines | ||
| 224 | 224 | struct hdac_ext_stream *stream; |
| 225 | 225 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 226 | 226 | struct skl_dma_params *dma_params; |
| 227 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 227 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 228 | 228 | struct skl_module_cfg *mconfig; |
| 229 | 229 | |
| 230 | 230 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); |
| @@ -271,7 +271,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream, · 40 unmodified lines | ||
| 271 | 271 | static int skl_pcm_prepare(struct snd_pcm_substream *substream, |
| 272 | 272 | struct snd_soc_dai *dai) |
| 273 | 273 | { |
| 274 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 274 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 275 | 275 | struct skl_module_cfg *mconfig; |
| 276 | 276 | int ret; |
| 277 | 277 | |
| @@ -288,7 +288,7 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream, · 10 unmodified lines | ||
| 288 | 288 | mconfig->pipe->state == SKL_PIPE_CREATED || |
| 289 | 289 | mconfig->pipe->state == SKL_PIPE_PAUSED)) { |
| 290 | 290 | |
| 291 | − ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe); | |
| 291 | + ret = skl_reset_pipe(skl, mconfig->pipe); | |
| 292 | 292 | |
| 293 | 293 | if (ret < 0) |
| 294 | 294 | return ret; |
| @@ -350,7 +350,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream, · 55 unmodified lines | ||
| 350 | 350 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); |
| 351 | 351 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 352 | 352 | struct skl_dma_params *dma_params = NULL; |
| 353 | − struct skl *skl = bus_to_skl(bus); | |
| 353 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 354 | 354 | struct skl_module_cfg *mconfig; |
| 355 | 355 | |
| 356 | 356 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); |
| @@ -370,9 +370,9 @@ static void skl_pcm_close(struct snd_pcm_substream *substream, · 13 unmodified lines | ||
| 370 | 370 | * CGCTL.MISCBDCGE if disabled by driver |
| 371 | 371 | */ |
| 372 | 372 | if (!strncmp(dai->name, "Reference Pin", 13) && |
| 373 | − skl->skl_sst->miscbdcg_disabled) { | |
| 374 | − skl->skl_sst->enable_miscbdcge(dai->dev, true); | |
| 375 | − skl->skl_sst->miscbdcg_disabled = false; | |
| 373 | + skl->miscbdcg_disabled) { | |
| 374 | + skl->enable_miscbdcge(dai->dev, true); | |
| 375 | + skl->miscbdcg_disabled = false; | |
| 376 | 376 | } |
| 377 | 377 | |
| 378 | 378 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); |
| @@ -387,7 +387,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream, · 8 unmodified lines | ||
| 387 | 387 | { |
| 388 | 388 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 389 | 389 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); |
| 390 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 390 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 391 | 391 | struct skl_module_cfg *mconfig; |
| 392 | 392 | int ret; |
| 393 | 393 | |
| @@ -396,7 +396,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 396 | 396 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); |
| 397 | 397 | |
| 398 | 398 | if (mconfig) { |
| 399 | − ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe); | |
| 399 | + ret = skl_reset_pipe(skl, mconfig->pipe); | |
| 400 | 400 | if (ret < 0) |
| 401 | 401 | dev_err(dai->dev, "%s:Reset failed ret =%d", |
| 402 | 402 | __func__, ret); |
| @@ -471,8 +471,7 @@ static int skl_decoupled_trigger(struct snd_pcm_substream *substream, · 68 unmodified lines | ||
| 471 | 471 | static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, |
| 472 | 472 | struct snd_soc_dai *dai) |
| 473 | 473 | { |
| 474 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 475 | − struct skl_sst *ctx = skl->skl_sst; | |
| 474 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 476 | 475 | struct skl_module_cfg *mconfig; |
| 477 | 476 | struct hdac_bus *bus = get_bus_ctx(substream); |
| 478 | 477 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); |
| @@ -515,7 +514,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, · 36 unmodified lines | ||
| 515 | 514 | ret = skl_decoupled_trigger(substream, cmd); |
| 516 | 515 | if (ret < 0) |
| 517 | 516 | return ret; |
| 518 | − return skl_run_pipe(ctx, mconfig->pipe); | |
| 517 | + return skl_run_pipe(skl, mconfig->pipe); | |
| 519 | 518 | break; |
| 520 | 519 | |
| 521 | 520 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| @@ -526,7 +525,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, · 4 unmodified lines | ||
| 526 | 525 | * there are no underrun/overrun in the case if there is a delay |
| 527 | 526 | * between the two operations. |
| 528 | 527 | */ |
| 529 | − ret = skl_stop_pipe(ctx, mconfig->pipe); | |
| 528 | + ret = skl_stop_pipe(skl, mconfig->pipe); | |
| 530 | 529 | if (ret < 0) |
| 531 | 530 | return ret; |
| 532 | 531 | |
| @@ -602,14 +601,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, · 69 unmodified lines | ||
| 602 | 601 | static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, |
| 603 | 602 | struct snd_soc_dai *dai) |
| 604 | 603 | { |
| 605 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 604 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 606 | 605 | struct skl_module_cfg *mconfig = NULL; |
| 607 | 606 | |
| 608 | 607 | /* In case of XRUN recovery, reset the FW pipe to clean state */ |
| 609 | 608 | mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); |
| 610 | 609 | if (mconfig && !mconfig->pipe->passthru && |
| 611 | 610 | (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN)) |
| 612 | − skl_reset_pipe(skl->skl_sst, mconfig->pipe); | |
| 611 | + skl_reset_pipe(skl, mconfig->pipe); | |
| 613 | 612 | |
| 614 | 613 | return 0; |
| 615 | 614 | } |
| @@ -1301,7 +1300,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) · 685 unmodified lines | ||
| 1301 | 1300 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 1302 | 1301 | struct snd_pcm *pcm = rtd->pcm; |
| 1303 | 1302 | unsigned int size; |
| 1304 | − struct skl *skl = bus_to_skl(bus); | |
| 1303 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1305 | 1304 | |
| 1306 | 1305 | if (dai->driver->playback.channels_min || |
| 1307 | 1306 | dai->driver->capture.channels_min) { |
| @@ -1318,9 +1317,9 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) · 10 unmodified lines | ||
| 1318 | 1317 | return 0; |
| 1319 | 1318 | } |
| 1320 | 1319 | |
| 1321 | −static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) | |
| 1320 | +static int skl_get_module_info(struct skl_dev *skl, | |
| 1321 | + struct skl_module_cfg *mconfig) | |
| 1322 | 1322 | { |
| 1323 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1324 | 1323 | struct skl_module_inst_id *pin_id; |
| 1325 | 1324 | guid_t *uuid_mod, *uuid_tplg; |
| 1326 | 1325 | struct skl_module *skl_module; |
| @@ -1329,12 +1328,12 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) · 2 unmodified lines | ||
| 1329 | 1328 | |
| 1330 | 1329 | uuid_mod = (guid_t *)mconfig->guid; |
| 1331 | 1330 | |
| 1332 | − if (list_empty(&ctx->uuid_list)) { | |
| 1333 | − dev_err(ctx->dev, "Module list is empty\n"); | |
| 1331 | + if (list_empty(&skl->uuid_list)) { | |
| 1332 | + dev_err(skl->dev, "Module list is empty\n"); | |
| 1334 | 1333 | return -EIO; |
| 1335 | 1334 | } |
| 1336 | 1335 | |
| 1337 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 1336 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 1338 | 1337 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 1339 | 1338 | mconfig->id.module_id = module->id; |
| 1340 | 1339 | if (mconfig->module) |
| @@ -1361,7 +1360,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) · 20 unmodified lines | ||
| 1361 | 1360 | if (skl->nr_modules && ret) |
| 1362 | 1361 | return ret; |
| 1363 | 1362 | |
| 1364 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 1363 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 1365 | 1364 | for (i = 0; i < MAX_IN_QUEUE; i++) { |
| 1366 | 1365 | pin_id = &mconfig->m_in_pin[i].id; |
| 1367 | 1366 | if (guid_equal(&pin_id->mod_uuid, &module->uuid)) |
| @@ -1378,7 +1377,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) · 10 unmodified lines | ||
| 1378 | 1377 | return 0; |
| 1379 | 1378 | } |
| 1380 | 1379 | |
| 1381 | −static int skl_populate_modules(struct skl *skl) | |
| 1380 | +static int skl_populate_modules(struct skl_dev *skl) | |
| 1382 | 1381 | { |
| 1383 | 1382 | struct skl_pipeline *p; |
| 1384 | 1383 | struct skl_pipe_module *m; |
| @@ -1393,7 +1392,7 @@ static int skl_populate_modules(struct skl *skl) · 8 unmodified lines | ||
| 1393 | 1392 | |
| 1394 | 1393 | ret = skl_get_module_info(skl, mconfig); |
| 1395 | 1394 | if (ret < 0) { |
| 1396 | − dev_err(skl->skl_sst->dev, | |
| 1395 | + dev_err(skl->dev, | |
| 1397 | 1396 | "query module info failed\n"); |
| 1398 | 1397 | return ret; |
| 1399 | 1398 | } |
| @@ -1408,7 +1407,7 @@ static int skl_populate_modules(struct skl *skl) · 8 unmodified lines | ||
| 1408 | 1407 | static int skl_platform_soc_probe(struct snd_soc_component *component) |
| 1409 | 1408 | { |
| 1410 | 1409 | struct hdac_bus *bus = dev_get_drvdata(component->dev); |
| 1411 | − struct skl *skl = bus_to_skl(bus); | |
| 1410 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1412 | 1411 | const struct skl_dsp_ops *ops; |
| 1413 | 1412 | int ret; |
| 1414 | 1413 | |
| @@ -1434,22 +1433,21 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) · 19 unmodified lines | ||
| 1434 | 1433 | * Disable dynamic clock and power gating during firmware |
| 1435 | 1434 | * and library download |
| 1436 | 1435 | */ |
| 1437 | − skl->skl_sst->enable_miscbdcge(component->dev, false); | |
| 1438 | − skl->skl_sst->clock_power_gating(component->dev, false); | |
| 1436 | + skl->enable_miscbdcge(component->dev, false); | |
| 1437 | + skl->clock_power_gating(component->dev, false); | |
| 1439 | 1438 | |
| 1440 | − ret = ops->init_fw(component->dev, skl->skl_sst); | |
| 1441 | − skl->skl_sst->enable_miscbdcge(component->dev, true); | |
| 1442 | − skl->skl_sst->clock_power_gating(component->dev, true); | |
| 1439 | + ret = ops->init_fw(component->dev, skl); | |
| 1440 | + skl->enable_miscbdcge(component->dev, true); | |
| 1441 | + skl->clock_power_gating(component->dev, true); | |
| 1443 | 1442 | if (ret < 0) { |
| 1444 | 1443 | dev_err(component->dev, "Failed to boot first fw: %d\n", ret); |
| 1445 | 1444 | return ret; |
| 1446 | 1445 | } |
| 1447 | 1446 | skl_populate_modules(skl); |
| 1448 | − skl->skl_sst->update_d0i3c = skl_update_d0i3c; | |
| 1449 | − skl_dsp_enable_notification(skl->skl_sst, false); | |
| 1447 | + skl->update_d0i3c = skl_update_d0i3c; | |
| 1450 | 1448 | |
| 1451 | 1449 | if (skl->cfg.astate_cfg != NULL) { |
| 1452 | − skl_dsp_set_astate_cfg(skl->skl_sst, | |
| 1450 | + skl_dsp_set_astate_cfg(skl, | |
| 1453 | 1451 | skl->cfg.astate_cfg->count, |
| 1454 | 1452 | skl->cfg.astate_cfg); |
| 1455 | 1453 | } |
| @@ -1463,7 +1461,7 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) · 7 unmodified lines | ||
| 1463 | 1461 | static void skl_pcm_remove(struct snd_soc_component *component) |
| 1464 | 1462 | { |
| 1465 | 1463 | struct hdac_bus *bus = dev_get_drvdata(component->dev); |
| 1466 | − struct skl *skl = bus_to_skl(bus); | |
| 1464 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1467 | 1465 | |
| 1468 | 1466 | skl_tplg_exit(component, bus); |
| 1469 | 1467 | |
| @@ -1486,7 +1484,7 @@ int skl_platform_register(struct device *dev) · 16 unmodified lines | ||
| 1486 | 1484 | struct snd_soc_dai_driver *dais; |
| 1487 | 1485 | int num_dais = ARRAY_SIZE(skl_platform_dai); |
| 1488 | 1486 | struct hdac_bus *bus = dev_get_drvdata(dev); |
| 1489 | − struct skl *skl = bus_to_skl(bus); | |
| 1487 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1490 | 1488 | |
| 1491 | 1489 | skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), |
| 1492 | 1490 | GFP_KERNEL); |
| @@ -1520,7 +1518,7 @@ err: · 27 unmodified lines | ||
| 1520 | 1518 | int skl_platform_unregister(struct device *dev) |
| 1521 | 1519 | { |
| 1522 | 1520 | struct hdac_bus *bus = dev_get_drvdata(dev); |
| 1523 | − struct skl *skl = bus_to_skl(bus); | |
| 1521 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1524 | 1522 | struct skl_module_deferred_bind *modules, *tmp; |
| 1525 | 1523 | |
| 1526 | 1524 | if (!list_empty(&skl->bind_list)) { |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/platform_device.h> |
| 12 | 12 | #include <linux/clk-provider.h> |
| 13 | 13 | #include <linux/clkdev.h> |
| 14 | +#include <sound/intel-nhlt.h> | |
| 14 | 15 | #include "skl.h" |
| 15 | 16 | #include "skl-ssp-clk.h" |
| 16 | 17 | #include "skl-topology.h" |
| @@ -101,7 +102,7 @@ static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type) · 84 unmodified lines | ||
| 101 | 102 | } |
| 102 | 103 | |
| 103 | 104 | /* Sends dma control IPC to turn the clock ON/OFF */ |
| 104 | −static int skl_send_clk_dma_control(struct skl *skl, | |
| 105 | +static int skl_send_clk_dma_control(struct skl_dev *skl, | |
| 105 | 106 | struct skl_clk_rate_cfg_table *rcfg, |
| 106 | 107 | u32 vbus_id, u8 clk_type, |
| 107 | 108 | bool enable) |
| @@ -152,7 +153,7 @@ static int skl_send_clk_dma_control(struct skl *skl, · 44 unmodified lines | ||
| 152 | 153 | memcpy(i2s_config + sp_cfg->size, data, size); |
| 153 | 154 | |
| 154 | 155 | node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4)); |
| 155 | − ret = skl_dsp_set_dma_control(skl->skl_sst, (u32 *)i2s_config, | |
| 156 | + ret = skl_dsp_set_dma_control(skl, (u32 *)i2s_config, | |
| 156 | 157 | i2s_config_size, node_id); |
| 157 | 158 | kfree(i2s_config); |
| 158 | 159 | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "../common/sst-dsp.h" |
| 13 | 13 | #include "../common/sst-ipc.h" |
| 14 | 14 | #include "../common/sst-dsp-priv.h" |
| 15 | −#include "skl-sst-ipc.h" | |
| 15 | +#include "skl.h" | |
| 16 | 16 | |
| 17 | 17 | /* various timeout values */ |
| 18 | 18 | #define SKL_DSP_PU_TO 50 |
| @@ -33,7 +33,7 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state) · 14 unmodified lines | ||
| 33 | 33 | */ |
| 34 | 34 | void skl_dsp_init_core_state(struct sst_dsp *ctx) |
| 35 | 35 | { |
| 36 | − struct skl_sst *skl = ctx->thread_context; | |
| 36 | + struct skl_dev *skl = ctx->thread_context; | |
| 37 | 37 | int i; |
| 38 | 38 | |
| 39 | 39 | skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; |
| @@ -48,7 +48,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx) · 8 unmodified lines | ||
| 48 | 48 | /* Get the mask for all enabled cores */ |
| 49 | 49 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx) |
| 50 | 50 | { |
| 51 | − struct skl_sst *skl = ctx->thread_context; | |
| 51 | + struct skl_dev *skl = ctx->thread_context; | |
| 52 | 52 | unsigned int core_mask, en_cores_mask; |
| 53 | 53 | u32 val; |
| 54 | 54 | |
| @@ -335,7 +335,7 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id) · 280 unmodified lines | ||
| 335 | 335 | */ |
| 336 | 336 | int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) |
| 337 | 337 | { |
| 338 | − struct skl_sst *skl = ctx->thread_context; | |
| 338 | + struct skl_dev *skl = ctx->thread_context; | |
| 339 | 339 | int ret = 0; |
| 340 | 340 | |
| 341 | 341 | if (core_id >= skl->cores.count) { |
| @@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(skl_dsp_get_core); · 22 unmodified lines | ||
| 364 | 364 | |
| 365 | 365 | int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id) |
| 366 | 366 | { |
| 367 | − struct skl_sst *skl = ctx->thread_context; | |
| 367 | + struct skl_dev *skl = ctx->thread_context; | |
| 368 | 368 | int ret = 0; |
| 369 | 369 | |
| 370 | 370 | if (core_id >= skl->cores.count) { |
| @@ -15,9 +15,9 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "skl-sst-cldma.h" |
| 16 | 16 | |
| 17 | 17 | struct sst_dsp; |
| 18 | −struct skl_sst; | |
| 19 | 18 | struct sst_dsp_device; |
| 20 | 19 | struct skl_lib_info; |
| 20 | +struct skl_dev; | |
| 21 | 21 | |
| 22 | 22 | /* Intel HD Audio General DSP Registers */ |
| 23 | 23 | #define SKL_ADSP_GEN_BASE 0x0 |
| @@ -222,32 +222,31 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id); · 198 unmodified lines | ||
| 222 | 222 | int skl_dsp_boot(struct sst_dsp *ctx); |
| 223 | 223 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 224 | 224 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 225 | − struct skl_sst **dsp); | |
| 225 | + struct skl_dev **dsp); | |
| 226 | 226 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 227 | 227 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 228 | − struct skl_sst **dsp); | |
| 229 | −int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | |
| 230 | −int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx); | |
| 231 | −void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | |
| 232 | −void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | |
| 228 | + struct skl_dev **dsp); | |
| 229 | +int skl_sst_init_fw(struct device *dev, struct skl_dev *skl); | |
| 230 | +int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl); | |
| 231 | +void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); | |
| 232 | +void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); | |
| 233 | 233 | |
| 234 | 234 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
| 235 | 235 | unsigned int offset, int index); |
| 236 | −int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id); | |
| 237 | −int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id); | |
| 238 | −int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | |
| 236 | +int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id); | |
| 237 | +int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id); | |
| 238 | +int skl_get_pvt_instance_id_map(struct skl_dev *skl, | |
| 239 | 239 | int module_id, int instance_id); |
| 240 | −void skl_freeup_uuid_list(struct skl_sst *ctx); | |
| 240 | +void skl_freeup_uuid_list(struct skl_dev *skl); | |
| 241 | 241 | |
| 242 | 242 | int skl_dsp_strip_extended_manifest(struct firmware *fw); |
| 243 | −void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); | |
| 244 | 243 | |
| 245 | −void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data); | |
| 244 | +void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data); | |
| 246 | 245 | |
| 247 | 246 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, |
| 248 | − struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, | |
| 247 | + struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp, | |
| 249 | 248 | struct sst_dsp_device *skl_dev); |
| 250 | −int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, | |
| 249 | +int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo, | |
| 251 | 250 | struct firmware *stripped_fw, |
| 252 | 251 | unsigned int hdr_offset, int index); |
| 253 | 252 | void skl_release_library(struct skl_lib_info *linfo, int lib_count); |
| @@ -281,7 +281,7 @@ void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, · 280 unmodified lines | ||
| 281 | 281 | size_t tx_size) |
| 282 | 282 | { |
| 283 | 283 | if (tx_size) |
| 284 | − memcpy(msg->tx_data, tx_data, tx_size); | |
| 284 | + memcpy(msg->tx.data, tx_data, tx_size); | |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) |
| @@ -295,10 +295,10 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) · 7 unmodified lines | ||
| 295 | 295 | /* Lock to be held by caller */ |
| 296 | 296 | static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
| 297 | 297 | { |
| 298 | − struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); | |
| 298 | + struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header); | |
| 299 | 299 | |
| 300 | − if (msg->tx_size) | |
| 301 | − sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | |
| 300 | + if (msg->tx.size) | |
| 301 | + sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); | |
| 302 | 302 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, |
| 303 | 303 | header->extension); |
| 304 | 304 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, |
| @@ -345,7 +345,7 @@ out: · 40 unmodified lines | ||
| 345 | 345 | int skl_ipc_process_notification(struct sst_generic_ipc *ipc, |
| 346 | 346 | struct skl_ipc_header header) |
| 347 | 347 | { |
| 348 | − struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); | |
| 348 | + struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc); | |
| 349 | 349 | |
| 350 | 350 | if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { |
| 351 | 351 | switch (IPC_GLB_NOTIFY_TYPE(header.primary)) { |
| @@ -436,7 +436,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc, · 84 unmodified lines | ||
| 436 | 436 | struct ipc_message *msg; |
| 437 | 437 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; |
| 438 | 438 | u64 *ipc_header = (u64 *)(&header); |
| 439 | − struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); | |
| 439 | + struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc); | |
| 440 | 440 | unsigned long flags; |
| 441 | 441 | |
| 442 | 442 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); |
| @@ -447,11 +447,12 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc, · 4 unmodified lines | ||
| 447 | 447 | return; |
| 448 | 448 | } |
| 449 | 449 | |
| 450 | + msg->rx.header = *ipc_header; | |
| 450 | 451 | /* first process the header */ |
| 451 | 452 | if (reply == IPC_GLB_REPLY_SUCCESS) { |
| 452 | 453 | dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); |
| 453 | 454 | /* copy the rx data from the mailbox */ |
| 454 | − sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); | |
| 455 | + sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size); | |
| 455 | 456 | switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { |
| 456 | 457 | case IPC_GLB_LOAD_MULTIPLE_MODS: |
| 457 | 458 | case IPC_GLB_LOAD_LIBRARY: |
| @@ -488,7 +489,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc, · 30 unmodified lines | ||
| 488 | 489 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) |
| 489 | 490 | { |
| 490 | 491 | struct sst_dsp *dsp = context; |
| 491 | − struct skl_sst *skl = sst_dsp_get_thread_context(dsp); | |
| 492 | + struct skl_dev *skl = sst_dsp_get_thread_context(dsp); | |
| 492 | 493 | struct sst_generic_ipc *ipc = &skl->ipc; |
| 493 | 494 | struct skl_ipc_header header = {0}; |
| 494 | 495 | u32 hipcie, hipct, hipcte; |
| @@ -595,7 +596,7 @@ bool skl_ipc_int_status(struct sst_dsp *ctx) · 100 unmodified lines | ||
| 595 | 596 | SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC; |
| 596 | 597 | } |
| 597 | 598 | |
| 598 | −int skl_ipc_init(struct device *dev, struct skl_sst *skl) | |
| 599 | +int skl_ipc_init(struct device *dev, struct skl_dev *skl) | |
| 599 | 600 | { |
| 600 | 601 | struct sst_generic_ipc *ipc; |
| 601 | 602 | int err; |
| @@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, · 33 unmodified lines | ||
| 635 | 636 | u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode) |
| 636 | 637 | { |
| 637 | 638 | struct skl_ipc_header header = {0}; |
| 638 | − u64 *ipc_header = (u64 *)(&header); | |
| 639 | + struct sst_ipc_message request = {0}; | |
| 639 | 640 | int ret; |
| 640 | 641 | |
| 641 | 642 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -646,9 +647,10 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, · 4 unmodified lines | ||
| 646 | 647 | header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size); |
| 647 | 648 | |
| 648 | 649 | header.extension = IPC_PPL_LP_MODE(lp_mode); |
| 650 | + request.header = *(u64 *)(&header); | |
| 649 | 651 | |
| 650 | 652 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); |
| 651 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 653 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 652 | 654 | if (ret < 0) { |
| 653 | 655 | dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); |
| 654 | 656 | return ret; |
| @@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline); · 6 unmodified lines | ||
| 661 | 663 | int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) |
| 662 | 664 | { |
| 663 | 665 | struct skl_ipc_header header = {0}; |
| 664 | − u64 *ipc_header = (u64 *)(&header); | |
| 666 | + struct sst_ipc_message request = {0}; | |
| 665 | 667 | int ret; |
| 666 | 668 | |
| 667 | 669 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| 668 | 670 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); |
| 669 | 671 | header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL); |
| 670 | 672 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 673 | + request.header = *(u64 *)(&header); | |
| 671 | 674 | |
| 672 | 675 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); |
| 673 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 676 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 674 | 677 | if (ret < 0) { |
| 675 | 678 | dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); |
| 676 | 679 | return ret; |
| @@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, · 7 unmodified lines | ||
| 684 | 687 | u8 instance_id, enum skl_ipc_pipeline_state state) |
| 685 | 688 | { |
| 686 | 689 | struct skl_ipc_header header = {0}; |
| 687 | − u64 *ipc_header = (u64 *)(&header); | |
| 690 | + struct sst_ipc_message request = {0}; | |
| 688 | 691 | int ret; |
| 689 | 692 | |
| 690 | 693 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -692,9 +695,10 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, · 1 unmodified line | ||
| 692 | 695 | header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE); |
| 693 | 696 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 694 | 697 | header.primary |= IPC_PPL_STATE(state); |
| 698 | + request.header = *(u64 *)(&header); | |
| 695 | 699 | |
| 696 | 700 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); |
| 697 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 701 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 698 | 702 | if (ret < 0) { |
| 699 | 703 | dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); |
| 700 | 704 | return ret; |
| @@ -707,7 +711,7 @@ int · 6 unmodified lines | ||
| 707 | 711 | skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) |
| 708 | 712 | { |
| 709 | 713 | struct skl_ipc_header header = {0}; |
| 710 | − u64 *ipc_header = (u64 *)(&header); | |
| 714 | + struct sst_ipc_message request = {0}; | |
| 711 | 715 | int ret; |
| 712 | 716 | |
| 713 | 717 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -716,8 +720,10 @@ skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) · 2 unmodified lines | ||
| 716 | 720 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 717 | 721 | |
| 718 | 722 | header.extension = IPC_DMA_ID(dma_id); |
| 723 | + request.header = *(u64 *)(&header); | |
| 724 | + | |
| 719 | 725 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); |
| 720 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 726 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 721 | 727 | if (ret < 0) { |
| 722 | 728 | dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); |
| 723 | 729 | return ret; |
| @@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline); · 6 unmodified lines | ||
| 730 | 736 | int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) |
| 731 | 737 | { |
| 732 | 738 | struct skl_ipc_header header = {0}; |
| 733 | − u64 *ipc_header = (u64 *)(&header); | |
| 739 | + struct sst_ipc_message request = {0}; | |
| 734 | 740 | int ret; |
| 735 | 741 | |
| 736 | 742 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| 737 | 743 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); |
| 738 | 744 | header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL); |
| 739 | 745 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 746 | + request.header = *(u64 *)(&header); | |
| 740 | 747 | |
| 741 | 748 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); |
| 742 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 749 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 743 | 750 | if (ret < 0) { |
| 744 | 751 | dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); |
| 745 | 752 | return ret; |
| @@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, · 7 unmodified lines | ||
| 753 | 760 | u16 module_id, struct skl_ipc_dxstate_info *dx) |
| 754 | 761 | { |
| 755 | 762 | struct skl_ipc_header header = {0}; |
| 756 | − u64 *ipc_header = (u64 *)(&header); | |
| 763 | + struct sst_ipc_message request; | |
| 757 | 764 | int ret; |
| 758 | 765 | |
| 759 | 766 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); |
| @@ -762,10 +769,13 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, · 2 unmodified lines | ||
| 762 | 769 | header.primary |= IPC_MOD_INSTANCE_ID(instance_id); |
| 763 | 770 | header.primary |= IPC_MOD_ID(module_id); |
| 764 | 771 | |
| 772 | + request.header = *(u64 *)(&header); | |
| 773 | + request.data = dx; | |
| 774 | + request.size = sizeof(*dx); | |
| 775 | + | |
| 765 | 776 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
| 766 | 777 | header.primary, header.extension); |
| 767 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | |
| 768 | − dx, sizeof(*dx), NULL, 0); | |
| 778 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 769 | 779 | if (ret < 0) { |
| 770 | 780 | dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); |
| 771 | 781 | return ret; |
| @@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, · 7 unmodified lines | ||
| 779 | 789 | struct skl_ipc_init_instance_msg *msg, void *param_data) |
| 780 | 790 | { |
| 781 | 791 | struct skl_ipc_header header = {0}; |
| 782 | − u64 *ipc_header = (u64 *)(&header); | |
| 792 | + struct sst_ipc_message request; | |
| 783 | 793 | int ret; |
| 784 | 794 | u32 *buffer = (u32 *)param_data; |
| 785 | 795 | /* param_block_size must be in dwords */ |
| @@ -799,10 +809,13 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, · 13 unmodified lines | ||
| 799 | 809 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); |
| 800 | 810 | header.extension |= IPC_DOMAIN(msg->domain); |
| 801 | 811 | |
| 812 | + request.header = *(u64 *)(&header); | |
| 813 | + request.data = param_data; | |
| 814 | + request.size = msg->param_data_size; | |
| 815 | + | |
| 802 | 816 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
| 803 | 817 | header.primary, header.extension); |
| 804 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data, | |
| 805 | − msg->param_data_size, NULL, 0); | |
| 818 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 806 | 819 | |
| 807 | 820 | if (ret < 0) { |
| 808 | 821 | dev_err(ipc->dev, "ipc: init instance failed\n"); |
| @@ -817,7 +830,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, · 8 unmodified lines | ||
| 817 | 830 | struct skl_ipc_bind_unbind_msg *msg) |
| 818 | 831 | { |
| 819 | 832 | struct skl_ipc_header header = {0}; |
| 820 | − u64 *ipc_header = (u64 *)(&header); | |
| 833 | + struct sst_ipc_message request = {0}; | |
| 821 | 834 | u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND; |
| 822 | 835 | int ret; |
| 823 | 836 | |
| @@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, · 7 unmodified lines | ||
| 831 | 844 | header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id); |
| 832 | 845 | header.extension |= IPC_DST_QUEUE(msg->dst_queue); |
| 833 | 846 | header.extension |= IPC_SRC_QUEUE(msg->src_queue); |
| 847 | + request.header = *(u64 *)(&header); | |
| 834 | 848 | |
| 835 | 849 | dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, |
| 836 | 850 | header.extension); |
| 837 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 851 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 838 | 852 | if (ret < 0) { |
| 839 | 853 | dev_err(ipc->dev, "ipc: bind/unbind failed\n"); |
| 840 | 854 | return ret; |
| @@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc, · 13 unmodified lines | ||
| 854 | 868 | u8 module_cnt, void *data) |
| 855 | 869 | { |
| 856 | 870 | struct skl_ipc_header header = {0}; |
| 857 | − u64 *ipc_header = (u64 *)(&header); | |
| 871 | + struct sst_ipc_message request; | |
| 858 | 872 | int ret; |
| 859 | 873 | |
| 860 | 874 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -862,8 +876,11 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc, · 1 unmodified line | ||
| 862 | 876 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); |
| 863 | 877 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); |
| 864 | 878 | |
| 865 | − ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data, | |
| 866 | − (sizeof(u16) * module_cnt)); | |
| 879 | + request.header = *(u64 *)(&header); | |
| 880 | + request.data = data; | |
| 881 | + request.size = sizeof(u16) * module_cnt; | |
| 882 | + | |
| 883 | + ret = sst_ipc_tx_message_nowait(ipc, request); | |
| 867 | 884 | if (ret < 0) |
| 868 | 885 | dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); |
| 869 | 886 | |
| @@ -875,7 +892,7 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt, · 5 unmodified lines | ||
| 875 | 892 | void *data) |
| 876 | 893 | { |
| 877 | 894 | struct skl_ipc_header header = {0}; |
| 878 | − u64 *ipc_header = (u64 *)(&header); | |
| 895 | + struct sst_ipc_message request; | |
| 879 | 896 | int ret; |
| 880 | 897 | |
| 881 | 898 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -883,8 +900,11 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt, · 1 unmodified line | ||
| 883 | 900 | header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS); |
| 884 | 901 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); |
| 885 | 902 | |
| 886 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, | |
| 887 | − (sizeof(u16) * module_cnt), NULL, 0); | |
| 903 | + request.header = *(u64 *)(&header); | |
| 904 | + request.data = data; | |
| 905 | + request.size = sizeof(u16) * module_cnt; | |
| 906 | + | |
| 907 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 888 | 908 | if (ret < 0) |
| 889 | 909 | dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret); |
| 890 | 910 | |
| @@ -896,7 +916,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, · 5 unmodified lines | ||
| 896 | 916 | struct skl_ipc_large_config_msg *msg, u32 *param) |
| 897 | 917 | { |
| 898 | 918 | struct skl_ipc_header header = {0}; |
| 899 | − u64 *ipc_header = (u64 *)(&header); | |
| 919 | + struct sst_ipc_message request; | |
| 900 | 920 | int ret = 0; |
| 901 | 921 | size_t sz_remaining, tx_size, data_offset; |
| 902 | 922 | |
| @@ -923,9 +943,11 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, · 20 unmodified lines | ||
| 923 | 943 | header.primary, header.extension); |
| 924 | 944 | dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", |
| 925 | 945 | (unsigned)data_offset, (unsigned)tx_size); |
| 926 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | |
| 927 | − ((char *)param) + data_offset, | |
| 928 | − tx_size, NULL, 0); | |
| 946 | + | |
| 947 | + request.header = *(u64 *)(&header); | |
| 948 | + request.data = ((char *)param) + data_offset; | |
| 949 | + request.size = tx_size; | |
| 950 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 929 | 951 | if (ret < 0) { |
| 930 | 952 | dev_err(ipc->dev, |
| 931 | 953 | "ipc: set large config fail, err: %d\n", ret); |
| @@ -947,12 +969,17 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, · 15 unmodified lines | ||
| 947 | 969 | EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); |
| 948 | 970 | |
| 949 | 971 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, |
| 950 | − struct skl_ipc_large_config_msg *msg, u32 *param) | |
| 972 | + struct skl_ipc_large_config_msg *msg, | |
| 973 | + u32 **payload, size_t *bytes) | |
| 951 | 974 | { |
| 952 | 975 | struct skl_ipc_header header = {0}; |
| 953 | − u64 *ipc_header = (u64 *)(&header); | |
| 954 | − int ret = 0; | |
| 955 | − size_t sz_remaining, rx_size, data_offset; | |
| 976 | + struct sst_ipc_message request, reply = {0}; | |
| 977 | + unsigned int *buf; | |
| 978 | + int ret; | |
| 979 | + | |
| 980 | + reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL); | |
| 981 | + if (!reply.data) | |
| 982 | + return -ENOMEM; | |
| 956 | 983 | |
| 957 | 984 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); |
| 958 | 985 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); |
| @@ -965,33 +992,21 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, · 6 unmodified lines | ||
| 965 | 992 | header.extension |= IPC_FINAL_BLOCK(1); |
| 966 | 993 | header.extension |= IPC_INITIAL_BLOCK(1); |
| 967 | 994 | |
| 968 | − sz_remaining = msg->param_data_size; | |
| 969 | − data_offset = 0; | |
| 995 | + request.header = *(u64 *)&header; | |
| 996 | + request.data = *payload; | |
| 997 | + request.size = *bytes; | |
| 998 | + reply.size = SKL_ADSP_W1_SZ; | |
| 970 | 999 | |
| 971 | − while (sz_remaining != 0) { | |
| 972 | − rx_size = sz_remaining > SKL_ADSP_W1_SZ | |
| 973 | − ? SKL_ADSP_W1_SZ : sz_remaining; | |
| 974 | − if (rx_size == sz_remaining) | |
| 975 | − header.extension |= IPC_FINAL_BLOCK(1); | |
| 976 | − | |
| 977 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, | |
| 978 | − ((char *)param) + data_offset, | |
| 979 | − msg->param_data_size); | |
| 980 | − if (ret < 0) { | |
| 981 | − dev_err(ipc->dev, | |
| 982 | − "ipc: get large config fail, err: %d\n", ret); | |
| 983 | − return ret; | |
| 984 | − } | |
| 985 | − sz_remaining -= rx_size; | |
| 986 | − data_offset = msg->param_data_size - sz_remaining; | |
| 1000 | + ret = sst_ipc_tx_message_wait(ipc, request, &reply); | |
| 1001 | + if (ret < 0) | |
| 1002 | + dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret); | |
| 987 | 1003 | |
| 988 | − /* clear the fields */ | |
| 989 | − header.extension &= IPC_INITIAL_BLOCK_CLEAR; | |
| 990 | − header.extension &= IPC_DATA_OFFSET_SZ_CLEAR; | |
| 991 | − /* fill the fields */ | |
| 992 | − header.extension |= IPC_INITIAL_BLOCK(1); | |
| 993 | − header.extension |= IPC_DATA_OFFSET_SZ(data_offset); | |
| 994 | − } | |
| 1004 | + reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK; | |
| 1005 | + buf = krealloc(reply.data, reply.size, GFP_KERNEL); | |
| 1006 | + if (!buf) | |
| 1007 | + return -ENOMEM; | |
| 1008 | + *payload = buf; | |
| 1009 | + *bytes = reply.size; | |
| 995 | 1010 | |
| 996 | 1011 | return ret; |
| 997 | 1012 | } |
| @@ -1001,7 +1016,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, · 3 unmodified lines | ||
| 1001 | 1016 | u8 dma_id, u8 table_id, bool wait) |
| 1002 | 1017 | { |
| 1003 | 1018 | struct skl_ipc_header header = {0}; |
| 1004 | − u64 *ipc_header = (u64 *)(&header); | |
| 1019 | + struct sst_ipc_message request = {0}; | |
| 1005 | 1020 | int ret = 0; |
| 1006 | 1021 | |
| 1007 | 1022 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| @@ -1009,12 +1024,12 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, · 1 unmodified line | ||
| 1009 | 1024 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); |
| 1010 | 1025 | header.primary |= IPC_MOD_INSTANCE_ID(table_id); |
| 1011 | 1026 | header.primary |= IPC_MOD_ID(dma_id); |
| 1027 | + request.header = *(u64 *)(&header); | |
| 1012 | 1028 | |
| 1013 | 1029 | if (wait) |
| 1014 | − ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | |
| 1015 | − NULL, 0, NULL, 0); | |
| 1030 | + ret = sst_ipc_tx_message_wait(ipc, request, NULL); | |
| 1016 | 1031 | else |
| 1017 | − ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0); | |
| 1032 | + ret = sst_ipc_tx_message_nowait(ipc, request); | |
| 1018 | 1033 | |
| 1019 | 1034 | if (ret < 0) |
| 1020 | 1035 | dev_err(ipc->dev, "ipc: load lib failed\n"); |
| @@ -1026,7 +1041,7 @@ EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library); · 5 unmodified lines | ||
| 1026 | 1041 | int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) |
| 1027 | 1042 | { |
| 1028 | 1043 | struct skl_ipc_header header = {0}; |
| 1029 | − u64 *ipc_header = (u64 *)(&header); | |
| 1044 | + struct sst_ipc_message request = {0}; | |
| 1030 | 1045 | int ret; |
| 1031 | 1046 | |
| 1032 | 1047 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); |
| @@ -1037,6 +1052,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) · 4 unmodified lines | ||
| 1037 | 1052 | |
| 1038 | 1053 | header.extension = IPC_D0IX_WAKE(msg->wake); |
| 1039 | 1054 | header.extension |= IPC_D0IX_STREAMING(msg->streaming); |
| 1055 | + request.header = *(u64 *)(&header); | |
| 1040 | 1056 | |
| 1041 | 1057 | dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, |
| 1042 | 1058 | header.primary, header.extension); |
| @@ -1044,7 +1060,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) · 1 unmodified line | ||
| 1044 | 1060 | /* |
| 1045 | 1061 | * Use the nopm IPC here as we dont want it checking for D0iX |
| 1046 | 1062 | */ |
| 1047 | − ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0); | |
| 1063 | + ret = sst_ipc_tx_message_nopm(ipc, request, NULL); | |
| 1048 | 1064 | if (ret < 0) |
| 1049 | 1065 | dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret); |
| 1050 | 1066 | |
| @@ -10,9 +10,9 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/irqreturn.h> |
| 12 | 12 | #include "../common/sst-ipc.h" |
| 13 | +#include "skl-sst-dsp.h" | |
| 13 | 14 | |
| 14 | 15 | struct sst_dsp; |
| 15 | −struct skl_sst; | |
| 16 | 16 | struct sst_generic_ipc; |
| 17 | 17 | |
| 18 | 18 | enum skl_ipc_pipeline_state { |
| @@ -67,54 +67,6 @@ struct skl_lib_info { · 48 unmodified lines | ||
| 67 | 67 | const struct firmware *fw; |
| 68 | 68 | }; |
| 69 | 69 | |
| 70 | −struct skl_sst { | |
| 71 | − struct device *dev; | |
| 72 | − struct sst_dsp *dsp; | |
| 73 | − | |
| 74 | − /* boot */ | |
| 75 | − wait_queue_head_t boot_wait; | |
| 76 | − bool boot_complete; | |
| 77 | − | |
| 78 | − /* module load */ | |
| 79 | − wait_queue_head_t mod_load_wait; | |
| 80 | − bool mod_load_complete; | |
| 81 | − bool mod_load_status; | |
| 82 | − | |
| 83 | − /* IPC messaging */ | |
| 84 | − struct sst_generic_ipc ipc; | |
| 85 | − | |
| 86 | − /* callback for miscbdge */ | |
| 87 | − void (*enable_miscbdcge)(struct device *dev, bool enable); | |
| 88 | − /* Is CGCTL.MISCBDCGE disabled */ | |
| 89 | − bool miscbdcg_disabled; | |
| 90 | − | |
| 91 | − /* Populate module information */ | |
| 92 | − struct list_head uuid_list; | |
| 93 | − | |
| 94 | − /* Is firmware loaded */ | |
| 95 | − bool fw_loaded; | |
| 96 | − | |
| 97 | − /* first boot ? */ | |
| 98 | − bool is_first_boot; | |
| 99 | − | |
| 100 | − /* multi-core */ | |
| 101 | − struct skl_dsp_cores cores; | |
| 102 | − | |
| 103 | − /* library info */ | |
| 104 | − struct skl_lib_info lib_info[SKL_MAX_LIB]; | |
| 105 | − int lib_count; | |
| 106 | − | |
| 107 | − /* Callback to update D0i3C register */ | |
| 108 | − void (*update_d0i3c)(struct device *dev, bool enable); | |
| 109 | − | |
| 110 | − struct skl_d0i3_data d0i3; | |
| 111 | − | |
| 112 | − const struct skl_dsp_ops *dsp_ops; | |
| 113 | − | |
| 114 | − /* Callback to update dynamic clock and power gating registers */ | |
| 115 | − void (*clock_power_gating)(struct device *dev, bool enable); | |
| 116 | −}; | |
| 117 | − | |
| 118 | 70 | struct skl_ipc_init_instance_msg { |
| 119 | 71 | u32 module_id; |
| 120 | 72 | u32 instance_id; |
| @@ -187,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, · 66 unmodified lines | ||
| 187 | 139 | struct skl_ipc_large_config_msg *msg, u32 *param); |
| 188 | 140 | |
| 189 | 141 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, |
| 190 | − struct skl_ipc_large_config_msg *msg, u32 *param); | |
| 142 | + struct skl_ipc_large_config_msg *msg, | |
| 143 | + u32 **payload, size_t *bytes); | |
| 191 | 144 | |
| 192 | 145 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, |
| 193 | 146 | u8 dma_id, u8 table_id, bool wait); |
| @@ -204,7 +157,7 @@ void skl_ipc_int_disable(struct sst_dsp *dsp); · 10 unmodified lines | ||
| 204 | 157 | |
| 205 | 158 | bool skl_ipc_int_status(struct sst_dsp *dsp); |
| 206 | 159 | void skl_ipc_free(struct sst_generic_ipc *ipc); |
| 207 | −int skl_ipc_init(struct device *dev, struct skl_sst *skl); | |
| 160 | +int skl_ipc_init(struct device *dev, struct skl_dev *skl); | |
| 208 | 161 | void skl_clear_module_cnt(struct sst_dsp *ctx); |
| 209 | 162 | |
| 210 | 163 | void skl_ipc_process_reply(struct sst_generic_ipc *ipc, |
| @@ -8,10 +8,9 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/device.h> |
| 9 | 9 | #include <linux/slab.h> |
| 10 | 10 | #include <linux/uuid.h> |
| 11 | −#include "skl-sst-dsp.h" | |
| 12 | 11 | #include "../common/sst-dsp.h" |
| 13 | 12 | #include "../common/sst-dsp-priv.h" |
| 14 | −#include "skl-sst-ipc.h" | |
| 13 | +#include "skl.h" | |
| 15 | 14 | |
| 16 | 15 | #define DEFAULT_HASH_SHA256_LEN 32 |
| 17 | 16 | |
| @@ -99,12 +98,12 @@ static int skl_get_pvtid_map(struct uuid_module *module, int instance_id) · 81 unmodified lines | ||
| 99 | 98 | return -EINVAL; |
| 100 | 99 | } |
| 101 | 100 | |
| 102 | −int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | |
| 101 | +int skl_get_pvt_instance_id_map(struct skl_dev *skl, | |
| 103 | 102 | int module_id, int instance_id) |
| 104 | 103 | { |
| 105 | 104 | struct uuid_module *module; |
| 106 | 105 | |
| 107 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 106 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 108 | 107 | if (module->id == module_id) |
| 109 | 108 | return skl_get_pvtid_map(module, instance_id); |
| 110 | 109 | } |
| @@ -163,19 +162,19 @@ static inline int skl_pvtid_128(struct uuid_module *module) · 52 unmodified lines | ||
| 163 | 162 | /** |
| 164 | 163 | * skl_get_pvt_id: generate a private id for use as module id |
| 165 | 164 | * |
| 166 | − * @ctx: driver context | |
| 165 | + * @skl: driver context | |
| 167 | 166 | * @uuid_mod: module's uuid |
| 168 | 167 | * @instance_id: module's instance id |
| 169 | 168 | * |
| 170 | 169 | * This generates a 128 bit private unique id for a module TYPE so that |
| 171 | 170 | * module instance is unique |
| 172 | 171 | */ |
| 173 | −int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id) | |
| 172 | +int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id) | |
| 174 | 173 | { |
| 175 | 174 | struct uuid_module *module; |
| 176 | 175 | int pvt_id; |
| 177 | 176 | |
| 178 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 177 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 179 | 178 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 180 | 179 | |
| 181 | 180 | pvt_id = skl_pvtid_128(module); |
| @@ -194,18 +193,18 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id); · 12 unmodified lines | ||
| 194 | 193 | /** |
| 195 | 194 | * skl_put_pvt_id: free up the private id allocated |
| 196 | 195 | * |
| 197 | − * @ctx: driver context | |
| 196 | + * @skl: driver context | |
| 198 | 197 | * @uuid_mod: module's uuid |
| 199 | 198 | * @pvt_id: module pvt id |
| 200 | 199 | * |
| 201 | 200 | * This frees a 128 bit private unique id previously generated |
| 202 | 201 | */ |
| 203 | −int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id) | |
| 202 | +int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id) | |
| 204 | 203 | { |
| 205 | 204 | int i; |
| 206 | 205 | struct uuid_module *module; |
| 207 | 206 | |
| 208 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 207 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 209 | 208 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 210 | 209 | |
| 211 | 210 | if (*pvt_id != 0) |
| @@ -234,7 +233,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, · 22 unmodified lines | ||
| 234 | 233 | struct adsp_module_entry *mod_entry; |
| 235 | 234 | int i, num_entry, size; |
| 236 | 235 | const char *buf; |
| 237 | − struct skl_sst *skl = ctx->thread_context; | |
| 236 | + struct skl_dev *skl = ctx->thread_context; | |
| 238 | 237 | struct uuid_module *module; |
| 239 | 238 | struct firmware stripped_fw; |
| 240 | 239 | unsigned int safe_file; |
| @@ -317,11 +316,11 @@ free_uuid_list: · 76 unmodified lines | ||
| 317 | 316 | return ret; |
| 318 | 317 | } |
| 319 | 318 | |
| 320 | −void skl_freeup_uuid_list(struct skl_sst *ctx) | |
| 319 | +void skl_freeup_uuid_list(struct skl_dev *skl) | |
| 321 | 320 | { |
| 322 | 321 | struct uuid_module *uuid, *_uuid; |
| 323 | 322 | |
| 324 | − list_for_each_entry_safe(uuid, _uuid, &ctx->uuid_list, list) { | |
| 323 | + list_for_each_entry_safe(uuid, _uuid, &skl->uuid_list, list) { | |
| 325 | 324 | list_del(&uuid->list); |
| 326 | 325 | kfree(uuid); |
| 327 | 326 | } |
| @@ -355,16 +354,12 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw) · 27 unmodified lines | ||
| 355 | 354 | } |
| 356 | 355 | |
| 357 | 356 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, |
| 358 | − struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, | |
| 357 | + struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp, | |
| 359 | 358 | struct sst_dsp_device *skl_dev) |
| 360 | 359 | { |
| 361 | − struct skl_sst *skl; | |
| 360 | + struct skl_dev *skl = *dsp; | |
| 362 | 361 | struct sst_dsp *sst; |
| 363 | 362 | |
| 364 | − skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); | |
| 365 | − if (skl == NULL) | |
| 366 | − return -ENOMEM; | |
| 367 | − | |
| 368 | 363 | skl->dev = dev; |
| 369 | 364 | skl_dev->thread_context = skl; |
| 370 | 365 | INIT_LIST_HEAD(&skl->uuid_list); |
| @@ -381,13 +376,11 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, · 10 unmodified lines | ||
| 381 | 376 | INIT_LIST_HEAD(&sst->module_list); |
| 382 | 377 | |
| 383 | 378 | skl->is_first_boot = true; |
| 384 | − if (dsp) | |
| 385 | − *dsp = skl; | |
| 386 | 379 | |
| 387 | 380 | return 0; |
| 388 | 381 | } |
| 389 | 382 | |
| 390 | −int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, | |
| 383 | +int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo, | |
| 391 | 384 | struct firmware *stripped_fw, |
| 392 | 385 | unsigned int hdr_offset, int index) |
| 393 | 386 | { |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include "../common/sst-dsp.h" |
| 17 | 17 | #include "../common/sst-dsp-priv.h" |
| 18 | 18 | #include "../common/sst-ipc.h" |
| 19 | −#include "skl-sst-ipc.h" | |
| 19 | +#include "skl.h" | |
| 20 | 20 | |
| 21 | 21 | #define SKL_BASEFW_TIMEOUT 300 |
| 22 | 22 | #define SKL_INIT_TIMEOUT 1000 |
| @@ -66,7 +66,7 @@ static int skl_transfer_firmware(struct sst_dsp *ctx, · 43 unmodified lines | ||
| 66 | 66 | static int skl_load_base_firmware(struct sst_dsp *ctx) |
| 67 | 67 | { |
| 68 | 68 | int ret = 0, i; |
| 69 | − struct skl_sst *skl = ctx->thread_context; | |
| 69 | + struct skl_dev *skl = ctx->thread_context; | |
| 70 | 70 | struct firmware stripped_fw; |
| 71 | 71 | u32 reg; |
| 72 | 72 | |
| @@ -161,7 +161,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) · 88 unmodified lines | ||
| 161 | 161 | { |
| 162 | 162 | int ret; |
| 163 | 163 | struct skl_ipc_dxstate_info dx; |
| 164 | − struct skl_sst *skl = ctx->thread_context; | |
| 164 | + struct skl_dev *skl = ctx->thread_context; | |
| 165 | 165 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 166 | 166 | |
| 167 | 167 | /* If core0 is being turned on, we need to load the FW */ |
| @@ -215,7 +215,7 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) · 47 unmodified lines | ||
| 215 | 215 | { |
| 216 | 216 | int ret; |
| 217 | 217 | struct skl_ipc_dxstate_info dx; |
| 218 | − struct skl_sst *skl = ctx->thread_context; | |
| 218 | + struct skl_dev *skl = ctx->thread_context; | |
| 219 | 219 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 220 | 220 | |
| 221 | 221 | dx.core_mask = core_mask; |
| @@ -332,7 +332,7 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, · 110 unmodified lines | ||
| 332 | 332 | u32 size, u16 mod_id, u8 table_id, bool is_module) |
| 333 | 333 | { |
| 334 | 334 | int ret, bytes_left, curr_pos; |
| 335 | − struct skl_sst *skl = ctx->thread_context; | |
| 335 | + struct skl_dev *skl = ctx->thread_context; | |
| 336 | 336 | skl->mod_load_complete = false; |
| 337 | 337 | |
| 338 | 338 | bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); |
| @@ -384,7 +384,7 @@ out: · 45 unmodified lines | ||
| 384 | 384 | static int |
| 385 | 385 | skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) |
| 386 | 386 | { |
| 387 | − struct skl_sst *skl = ctx->thread_context; | |
| 387 | + struct skl_dev *skl = ctx->thread_context; | |
| 388 | 388 | struct firmware stripped_fw; |
| 389 | 389 | int ret, i; |
| 390 | 390 | |
| @@ -413,8 +413,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) · 22 unmodified lines | ||
| 413 | 413 | int ret = 0; |
| 414 | 414 | char mod_name[64]; /* guid str = 32 chars + 4 hyphens */ |
| 415 | 415 | |
| 416 | − snprintf(mod_name, sizeof(mod_name), "%s%pUL%s", | |
| 417 | − "intel/dsp_fw_", guid, ".bin"); | |
| 416 | + snprintf(mod_name, sizeof(mod_name), "intel/dsp_fw_%pUL.bin", guid); | |
| 418 | 417 | |
| 419 | 418 | module_entry = skl_module_get_from_id(ctx, mod_id); |
| 420 | 419 | if (module_entry == NULL) { |
| @@ -443,7 +442,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) · 22 unmodified lines | ||
| 443 | 442 | static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id) |
| 444 | 443 | { |
| 445 | 444 | int usage_cnt; |
| 446 | − struct skl_sst *skl = ctx->thread_context; | |
| 445 | + struct skl_dev *skl = ctx->thread_context; | |
| 447 | 446 | int ret = 0; |
| 448 | 447 | |
| 449 | 448 | usage_cnt = skl_put_module(ctx, mod_id); |
| @@ -518,9 +517,10 @@ static struct sst_dsp_device skl_dev = { · 68 unmodified lines | ||
| 518 | 517 | }; |
| 519 | 518 | |
| 520 | 519 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 521 | − const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp) | |
| 520 | + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | |
| 521 | + struct skl_dev **dsp) | |
| 522 | 522 | { |
| 523 | − struct skl_sst *skl; | |
| 523 | + struct skl_dev *skl; | |
| 524 | 524 | struct sst_dsp *sst; |
| 525 | 525 | int ret; |
| 526 | 526 | |
| @@ -554,10 +554,10 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, · 27 unmodified lines | ||
| 554 | 554 | } |
| 555 | 555 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); |
| 556 | 556 | |
| 557 | −int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) | |
| 557 | +int skl_sst_init_fw(struct device *dev, struct skl_dev *skl) | |
| 558 | 558 | { |
| 559 | 559 | int ret; |
| 560 | − struct sst_dsp *sst = ctx->dsp; | |
| 560 | + struct sst_dsp *sst = skl->dsp; | |
| 561 | 561 | |
| 562 | 562 | ret = sst->fw_ops.load_fw(sst); |
| 563 | 563 | if (ret < 0) { |
| @@ -567,32 +567,32 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) · 3 unmodified lines | ||
| 567 | 567 | |
| 568 | 568 | skl_dsp_init_core_state(sst); |
| 569 | 569 | |
| 570 | − if (ctx->lib_count > 1) { | |
| 571 | − ret = sst->fw_ops.load_library(sst, ctx->lib_info, | |
| 572 | − ctx->lib_count); | |
| 570 | + if (skl->lib_count > 1) { | |
| 571 | + ret = sst->fw_ops.load_library(sst, skl->lib_info, | |
| 572 | + skl->lib_count); | |
| 573 | 573 | if (ret < 0) { |
| 574 | 574 | dev_err(dev, "Load Library failed : %x\n", ret); |
| 575 | 575 | return ret; |
| 576 | 576 | } |
| 577 | 577 | } |
| 578 | − ctx->is_first_boot = false; | |
| 578 | + skl->is_first_boot = false; | |
| 579 | 579 | |
| 580 | 580 | return 0; |
| 581 | 581 | } |
| 582 | 582 | EXPORT_SYMBOL_GPL(skl_sst_init_fw); |
| 583 | 583 | |
| 584 | −void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | |
| 584 | +void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl) | |
| 585 | 585 | { |
| 586 | 586 | |
| 587 | − if (ctx->dsp->fw) | |
| 588 | − release_firmware(ctx->dsp->fw); | |
| 589 | − skl_clear_module_table(ctx->dsp); | |
| 590 | − skl_freeup_uuid_list(ctx); | |
| 591 | − skl_ipc_free(&ctx->ipc); | |
| 592 | − ctx->dsp->ops->free(ctx->dsp); | |
| 593 | − if (ctx->boot_complete) { | |
| 594 | − ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); | |
| 595 | − skl_cldma_int_disable(ctx->dsp); | |
| 587 | + if (skl->dsp->fw) | |
| 588 | + release_firmware(skl->dsp->fw); | |
| 589 | + skl_clear_module_table(skl->dsp); | |
| 590 | + skl_freeup_uuid_list(skl); | |
| 591 | + skl_ipc_free(&skl->ipc); | |
| 592 | + skl->dsp->ops->free(skl->dsp); | |
| 593 | + if (skl->boot_complete) { | |
| 594 | + skl->dsp->cl_dev.ops.cl_cleanup_controller(skl->dsp); | |
| 595 | + skl_cldma_int_disable(skl->dsp); | |
| 596 | 596 | } |
| 597 | 597 | } |
| 598 | 598 | EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/types.h> |
| 13 | 13 | #include <linux/firmware.h> |
| 14 | 14 | #include <linux/uuid.h> |
| 15 | +#include <sound/intel-nhlt.h> | |
| 15 | 16 | #include <sound/soc.h> |
| 16 | 17 | #include <sound/soc-topology.h> |
| 17 | 18 | #include <uapi/sound/snd_sst_tokens.h> |
| @@ -45,9 +46,9 @@ static const int mic_quatro_list[][SKL_CH_QUATRO] = { · 27 unmodified lines | ||
| 45 | 46 | #define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ |
| 46 | 47 | ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq)) |
| 47 | 48 | |
| 48 | −void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps) | |
| 49 | +void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps) | |
| 49 | 50 | { |
| 50 | − struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; | |
| 51 | + struct skl_d0i3_data *d0i3 = &skl->d0i3; | |
| 51 | 52 | |
| 52 | 53 | switch (caps) { |
| 53 | 54 | case SKL_D0I3_NONE: |
| @@ -64,9 +65,9 @@ void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps) · 10 unmodified lines | ||
| 64 | 65 | } |
| 65 | 66 | } |
| 66 | 67 | |
| 67 | −void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps) | |
| 68 | +void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps) | |
| 68 | 69 | { |
| 69 | − struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; | |
| 70 | + struct skl_d0i3_data *d0i3 = &skl->d0i3; | |
| 70 | 71 | |
| 71 | 72 | switch (caps) { |
| 72 | 73 | case SKL_D0I3_NONE: |
| @@ -109,118 +110,23 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w, · 36 unmodified lines | ||
| 109 | 110 | } |
| 110 | 111 | } |
| 111 | 112 | |
| 112 | −/* | |
| 113 | − * Each pipelines needs memory to be allocated. Check if we have free memory | |
| 114 | − * from available pool. | |
| 115 | − */ | |
| 116 | −static bool skl_is_pipe_mem_avail(struct skl *skl, | |
| 117 | − struct skl_module_cfg *mconfig) | |
| 118 | −{ | |
| 119 | − struct skl_sst *ctx = skl->skl_sst; | |
| 120 | − | |
| 121 | − if (skl->resource.mem + mconfig->pipe->memory_pages > | |
| 122 | − skl->resource.max_mem) { | |
| 123 | − dev_err(ctx->dev, | |
| 124 | − "%s: module_id %d instance %d\n", __func__, | |
| 125 | − mconfig->id.module_id, | |
| 126 | − mconfig->id.instance_id); | |
| 127 | − dev_err(ctx->dev, | |
| 128 | − "exceeds ppl memory available %d mem %d\n", | |
| 129 | − skl->resource.max_mem, skl->resource.mem); | |
| 130 | − return false; | |
| 131 | − } else { | |
| 132 | − return true; | |
| 133 | − } | |
| 134 | −} | |
| 135 | − | |
| 136 | −/* | |
| 137 | − * Add the mem to the mem pool. This is freed when pipe is deleted. | |
| 138 | − * Note: DSP does actual memory management we only keep track for complete | |
| 139 | − * pool | |
| 140 | − */ | |
| 141 | −static void skl_tplg_alloc_pipe_mem(struct skl *skl, | |
| 142 | − struct skl_module_cfg *mconfig) | |
| 143 | −{ | |
| 144 | − skl->resource.mem += mconfig->pipe->memory_pages; | |
| 145 | −} | |
| 146 | − | |
| 147 | −/* | |
| 148 | − * Pipeline needs needs DSP CPU resources for computation, this is | |
| 149 | − * quantified in MCPS (Million Clocks Per Second) required for module/pipe | |
| 150 | − * | |
| 151 | − * Each pipelines needs mcps to be allocated. Check if we have mcps for this | |
| 152 | − * pipe. | |
| 153 | − */ | |
| 154 | − | |
| 155 | −static bool skl_is_pipe_mcps_avail(struct skl *skl, | |
| 156 | − struct skl_module_cfg *mconfig) | |
| 157 | −{ | |
| 158 | − struct skl_sst *ctx = skl->skl_sst; | |
| 159 | − u8 res_idx = mconfig->res_idx; | |
| 160 | − struct skl_module_res *res = &mconfig->module->resources[res_idx]; | |
| 161 | − | |
| 162 | − if (skl->resource.mcps + res->cps > skl->resource.max_mcps) { | |
| 163 | − dev_err(ctx->dev, | |
| 164 | − "%s: module_id %d instance %d\n", __func__, | |
| 165 | − mconfig->id.module_id, mconfig->id.instance_id); | |
| 166 | − dev_err(ctx->dev, | |
| 167 | − "exceeds ppl mcps available %d > mem %d\n", | |
| 168 | − skl->resource.max_mcps, skl->resource.mcps); | |
| 169 | − return false; | |
| 170 | − } else { | |
| 171 | − return true; | |
| 172 | − } | |
| 173 | −} | |
| 174 | − | |
| 175 | −static void skl_tplg_alloc_pipe_mcps(struct skl *skl, | |
| 176 | − struct skl_module_cfg *mconfig) | |
| 177 | −{ | |
| 178 | − u8 res_idx = mconfig->res_idx; | |
| 179 | − struct skl_module_res *res = &mconfig->module->resources[res_idx]; | |
| 180 | − | |
| 181 | − skl->resource.mcps += res->cps; | |
| 182 | −} | |
| 183 | − | |
| 184 | −/* | |
| 185 | − * Free the mcps when tearing down | |
| 186 | − */ | |
| 187 | −static void | |
| 188 | −skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) | |
| 189 | −{ | |
| 190 | − u8 res_idx = mconfig->res_idx; | |
| 191 | − struct skl_module_res *res = &mconfig->module->resources[res_idx]; | |
| 192 | − | |
| 193 | − skl->resource.mcps -= res->cps; | |
| 194 | −} | |
| 195 | − | |
| 196 | −/* | |
| 197 | − * Free the memory when tearing down | |
| 198 | − */ | |
| 199 | −static void | |
| 200 | −skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig) | |
| 201 | −{ | |
| 202 | − skl->resource.mem -= mconfig->pipe->memory_pages; | |
| 203 | −} | |
| 204 | − | |
| 205 | − | |
| 206 | −static void skl_dump_mconfig(struct skl_sst *ctx, | |
| 207 | − struct skl_module_cfg *mcfg) | |
| 113 | +static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg) | |
| 208 | 114 | { |
| 209 | 115 | struct skl_module_iface *iface = &mcfg->module->formats[0]; |
| 210 | 116 | |
| 211 | − dev_dbg(ctx->dev, "Dumping config\n"); | |
| 212 | − dev_dbg(ctx->dev, "Input Format:\n"); | |
| 213 | − dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels); | |
| 214 | − dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); | |
| 215 | − dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); | |
| 216 | − dev_dbg(ctx->dev, "valid bit depth = %d\n", | |
| 117 | + dev_dbg(skl->dev, "Dumping config\n"); | |
| 118 | + dev_dbg(skl->dev, "Input Format:\n"); | |
| 119 | + dev_dbg(skl->dev, "channels = %d\n", iface->inputs[0].fmt.channels); | |
| 120 | + dev_dbg(skl->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); | |
| 121 | + dev_dbg(skl->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); | |
| 122 | + dev_dbg(skl->dev, "valid bit depth = %d\n", | |
| 217 | 123 | iface->inputs[0].fmt.valid_bit_depth); |
| 218 | − dev_dbg(ctx->dev, "Output Format:\n"); | |
| 219 | − dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels); | |
| 220 | − dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); | |
| 221 | − dev_dbg(ctx->dev, "valid bit depth = %d\n", | |
| 124 | + dev_dbg(skl->dev, "Output Format:\n"); | |
| 125 | + dev_dbg(skl->dev, "channels = %d\n", iface->outputs[0].fmt.channels); | |
| 126 | + dev_dbg(skl->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); | |
| 127 | + dev_dbg(skl->dev, "valid bit depth = %d\n", | |
| 222 | 128 | iface->outputs[0].fmt.valid_bit_depth); |
| 223 | − dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg); | |
| 129 | + dev_dbg(skl->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg); | |
| 224 | 130 | } |
| 225 | 131 | |
| 226 | 132 | static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) |
| @@ -322,7 +228,7 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, · 95 unmodified lines | ||
| 322 | 228 | * params, so once we have calculate params, we need buffer calculation as |
| 323 | 229 | * well. |
| 324 | 230 | */ |
| 325 | −static void skl_tplg_update_buffer_size(struct skl_sst *ctx, | |
| 231 | +static void skl_tplg_update_buffer_size(struct skl_dev *skl, | |
| 326 | 232 | struct skl_module_cfg *mcfg) |
| 327 | 233 | { |
| 328 | 234 | int multiplier = 1; |
| @@ -374,13 +280,12 @@ static u8 skl_tplg_be_dev_type(int dev_type) · 45 unmodified lines | ||
| 374 | 280 | } |
| 375 | 281 | |
| 376 | 282 | static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, |
| 377 | − struct skl_sst *ctx) | |
| 283 | + struct skl_dev *skl) | |
| 378 | 284 | { |
| 379 | 285 | struct skl_module_cfg *m_cfg = w->priv; |
| 380 | 286 | int link_type, dir; |
| 381 | 287 | u32 ch, s_freq, s_fmt; |
| 382 | 288 | struct nhlt_specific_cfg *cfg; |
| 383 | − struct skl *skl = get_skl_ctx(ctx->dev); | |
| 384 | 289 | u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); |
| 385 | 290 | int fmt_idx = m_cfg->fmt_idx; |
| 386 | 291 | struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; |
| @@ -389,7 +294,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, · 2 unmodified lines | ||
| 389 | 294 | if (m_cfg->formats_config.caps_size > 0) |
| 390 | 295 | return 0; |
| 391 | 296 | |
| 392 | − dev_dbg(ctx->dev, "Applying default cfg blob\n"); | |
| 297 | + dev_dbg(skl->dev, "Applying default cfg blob\n"); | |
| 393 | 298 | switch (m_cfg->dev_type) { |
| 394 | 299 | case SKL_DEVICE_DMIC: |
| 395 | 300 | link_type = NHLT_LINK_DMIC; |
| @@ -425,9 +330,9 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, · 29 unmodified lines | ||
| 425 | 330 | m_cfg->formats_config.caps_size = cfg->size; |
| 426 | 331 | m_cfg->formats_config.caps = (u32 *) &cfg->caps; |
| 427 | 332 | } else { |
| 428 | − dev_err(ctx->dev, "Blob NULL for id %x type %d dirn %d\n", | |
| 333 | + dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n", | |
| 429 | 334 | m_cfg->vbus_id, link_type, dir); |
| 430 | − dev_err(ctx->dev, "PCM: ch %d, freq %d, fmt %d\n", | |
| 335 | + dev_err(skl->dev, "PCM: ch %d, freq %d, fmt %d\n", | |
| 431 | 336 | ch, s_freq, s_fmt); |
| 432 | 337 | return -EIO; |
| 433 | 338 | } |
| @@ -436,7 +341,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, · 2 unmodified lines | ||
| 436 | 341 | } |
| 437 | 342 | |
| 438 | 343 | static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, |
| 439 | − struct skl_sst *ctx) | |
| 344 | + struct skl_dev *skl) | |
| 440 | 345 | { |
| 441 | 346 | struct skl_module_cfg *m_cfg = w->priv; |
| 442 | 347 | struct skl_pipe_params *params = m_cfg->pipe->p_params; |
| @@ -446,10 +351,10 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, · 3 unmodified lines | ||
| 446 | 351 | if (!m_cfg->params_fixup) |
| 447 | 352 | return; |
| 448 | 353 | |
| 449 | − dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n", | |
| 354 | + dev_dbg(skl->dev, "Mconfig for widget=%s BEFORE updation\n", | |
| 450 | 355 | w->name); |
| 451 | 356 | |
| 452 | − skl_dump_mconfig(ctx, m_cfg); | |
| 357 | + skl_dump_mconfig(skl, m_cfg); | |
| 453 | 358 | |
| 454 | 359 | if (p_conn_type == SKL_PIPE_CONN_TYPE_FE) |
| 455 | 360 | is_fe = true; |
| @@ -457,12 +362,12 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, · 1 unmodified line | ||
| 457 | 362 | is_fe = false; |
| 458 | 363 | |
| 459 | 364 | skl_tplg_update_params_fixup(m_cfg, params, is_fe); |
| 460 | − skl_tplg_update_buffer_size(ctx, m_cfg); | |
| 365 | + skl_tplg_update_buffer_size(skl, m_cfg); | |
| 461 | 366 | |
| 462 | − dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n", | |
| 367 | + dev_dbg(skl->dev, "Mconfig for widget=%s AFTER updation\n", | |
| 463 | 368 | w->name); |
| 464 | 369 | |
| 465 | − skl_dump_mconfig(ctx, m_cfg); | |
| 370 | + skl_dump_mconfig(skl, m_cfg); | |
| 466 | 371 | } |
| 467 | 372 | |
| 468 | 373 | /* |
| @@ -471,7 +376,7 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, · 2 unmodified lines | ||
| 471 | 376 | * set module params will be done after module is initialised. |
| 472 | 377 | */ |
| 473 | 378 | static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, |
| 474 | − struct skl_sst *ctx) | |
| 379 | + struct skl_dev *skl) | |
| 475 | 380 | { |
| 476 | 381 | int i, ret; |
| 477 | 382 | struct skl_module_cfg *mconfig = w->priv; |
| @@ -483,7 +388,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, · 5 unmodified lines | ||
| 483 | 388 | if (mconfig->formats_config.caps_size > 0 && |
| 484 | 389 | mconfig->formats_config.set_params == SKL_PARAM_SET) { |
| 485 | 390 | sp_cfg = &mconfig->formats_config; |
| 486 | − ret = skl_set_module_params(ctx, sp_cfg->caps, | |
| 391 | + ret = skl_set_module_params(skl, sp_cfg->caps, | |
| 487 | 392 | sp_cfg->caps_size, |
| 488 | 393 | sp_cfg->param_id, mconfig); |
| 489 | 394 | if (ret < 0) |
| @@ -497,7 +402,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, · 7 unmodified lines | ||
| 497 | 402 | bc = (struct skl_algo_data *)sb->dobj.private; |
| 498 | 403 | |
| 499 | 404 | if (bc->set_params == SKL_PARAM_SET) { |
| 500 | − ret = skl_set_module_params(ctx, | |
| 405 | + ret = skl_set_module_params(skl, | |
| 501 | 406 | (u32 *)bc->params, bc->size, |
| 502 | 407 | bc->param_id, mconfig); |
| 503 | 408 | if (ret < 0) |
| @@ -542,15 +447,15 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w) · 38 unmodified lines | ||
| 542 | 447 | return 0; |
| 543 | 448 | } |
| 544 | 449 | |
| 545 | −static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe, | |
| 450 | +static int skl_tplg_module_prepare(struct skl_dev *skl, struct skl_pipe *pipe, | |
| 546 | 451 | struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg) |
| 547 | 452 | { |
| 548 | 453 | switch (mcfg->dev_type) { |
| 549 | 454 | case SKL_DEVICE_HDAHOST: |
| 550 | − return skl_pcm_host_dma_prepare(ctx->dev, pipe->p_params); | |
| 455 | + return skl_pcm_host_dma_prepare(skl->dev, pipe->p_params); | |
| 551 | 456 | |
| 552 | 457 | case SKL_DEVICE_HDALINK: |
| 553 | − return skl_pcm_link_dma_prepare(ctx->dev, pipe->p_params); | |
| 458 | + return skl_pcm_link_dma_prepare(skl->dev, pipe->p_params); | |
| 554 | 459 | } |
| 555 | 460 | |
| 556 | 461 | return 0; |
| @@ -562,12 +467,11 @@ static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe, · 5 unmodified lines | ||
| 562 | 467 | * skl_init_module() routine, so invoke that for all modules in a pipeline |
| 563 | 468 | */ |
| 564 | 469 | static int |
| 565 | −skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |
| 470 | +skl_tplg_init_pipe_modules(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 566 | 471 | { |
| 567 | 472 | struct skl_pipe_module *w_module; |
| 568 | 473 | struct snd_soc_dapm_widget *w; |
| 569 | 474 | struct skl_module_cfg *mconfig; |
| 570 | − struct skl_sst *ctx = skl->skl_sst; | |
| 571 | 475 | u8 cfg_idx; |
| 572 | 476 | int ret = 0; |
| 573 | 477 | |
| @@ -578,7 +482,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 4 unmodified lines | ||
| 578 | 482 | |
| 579 | 483 | /* check if module ids are populated */ |
| 580 | 484 | if (mconfig->id.module_id < 0) { |
| 581 | − dev_err(skl->skl_sst->dev, | |
| 485 | + dev_err(skl->dev, | |
| 582 | 486 | "module %pUL id not populated\n", |
| 583 | 487 | (guid_t *)mconfig->guid); |
| 584 | 488 | return -EIO; |
| @@ -588,12 +492,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 3 unmodified lines | ||
| 588 | 492 | mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; |
| 589 | 493 | mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; |
| 590 | 494 | |
| 591 | − /* check resource available */ | |
| 592 | − if (!skl_is_pipe_mcps_avail(skl, mconfig)) | |
| 593 | − return -ENOMEM; | |
| 594 | − | |
| 595 | − if (mconfig->module->loadable && ctx->dsp->fw_ops.load_mod) { | |
| 596 | − ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, | |
| 495 | + if (mconfig->module->loadable && skl->dsp->fw_ops.load_mod) { | |
| 496 | + ret = skl->dsp->fw_ops.load_mod(skl->dsp, | |
| 597 | 497 | mconfig->id.module_id, mconfig->guid); |
| 598 | 498 | if (ret < 0) |
| 599 | 499 | return ret; |
| @@ -602,50 +502,50 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 2 unmodified lines | ||
| 602 | 502 | } |
| 603 | 503 | |
| 604 | 504 | /* prepare the DMA if the module is gateway cpr */ |
| 605 | − ret = skl_tplg_module_prepare(ctx, pipe, w, mconfig); | |
| 505 | + ret = skl_tplg_module_prepare(skl, pipe, w, mconfig); | |
| 606 | 506 | if (ret < 0) |
| 607 | 507 | return ret; |
| 608 | 508 | |
| 609 | 509 | /* update blob if blob is null for be with default value */ |
| 610 | − skl_tplg_update_be_blob(w, ctx); | |
| 510 | + skl_tplg_update_be_blob(w, skl); | |
| 611 | 511 | |
| 612 | 512 | /* |
| 613 | 513 | * apply fix/conversion to module params based on |
| 614 | 514 | * FE/BE params |
| 615 | 515 | */ |
| 616 | − skl_tplg_update_module_params(w, ctx); | |
| 516 | + skl_tplg_update_module_params(w, skl); | |
| 617 | 517 | uuid_mod = (guid_t *)mconfig->guid; |
| 618 | − mconfig->id.pvt_id = skl_get_pvt_id(ctx, uuid_mod, | |
| 518 | + mconfig->id.pvt_id = skl_get_pvt_id(skl, uuid_mod, | |
| 619 | 519 | mconfig->id.instance_id); |
| 620 | 520 | if (mconfig->id.pvt_id < 0) |
| 621 | 521 | return ret; |
| 622 | 522 | skl_tplg_set_module_init_data(w); |
| 623 | 523 | |
| 624 | − ret = skl_dsp_get_core(ctx->dsp, mconfig->core_id); | |
| 524 | + ret = skl_dsp_get_core(skl->dsp, mconfig->core_id); | |
| 625 | 525 | if (ret < 0) { |
| 626 | − dev_err(ctx->dev, "Failed to wake up core %d ret=%d\n", | |
| 526 | + dev_err(skl->dev, "Failed to wake up core %d ret=%d\n", | |
| 627 | 527 | mconfig->core_id, ret); |
| 628 | 528 | return ret; |
| 629 | 529 | } |
| 630 | 530 | |
| 631 | − ret = skl_init_module(ctx, mconfig); | |
| 531 | + ret = skl_init_module(skl, mconfig); | |
| 632 | 532 | if (ret < 0) { |
| 633 | − skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); | |
| 533 | + skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id); | |
| 634 | 534 | goto err; |
| 635 | 535 | } |
| 636 | − skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 637 | − ret = skl_tplg_set_module_params(w, ctx); | |
| 536 | + | |
| 537 | + ret = skl_tplg_set_module_params(w, skl); | |
| 638 | 538 | if (ret < 0) |
| 639 | 539 | goto err; |
| 640 | 540 | } |
| 641 | 541 | |
| 642 | 542 | return 0; |
| 643 | 543 | err: |
| 644 | − skl_dsp_put_core(ctx->dsp, mconfig->core_id); | |
| 544 | + skl_dsp_put_core(skl->dsp, mconfig->core_id); | |
| 645 | 545 | return ret; |
| 646 | 546 | } |
| 647 | 547 | |
| 648 | −static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, | |
| 548 | +static int skl_tplg_unload_pipe_modules(struct skl_dev *skl, | |
| 649 | 549 | struct skl_pipe *pipe) |
| 650 | 550 | { |
| 651 | 551 | int ret = 0; |
| @@ -657,19 +557,19 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, · 5 unmodified lines | ||
| 657 | 557 | mconfig = w_module->w->priv; |
| 658 | 558 | uuid_mod = (guid_t *)mconfig->guid; |
| 659 | 559 | |
| 660 | − if (mconfig->module->loadable && ctx->dsp->fw_ops.unload_mod && | |
| 560 | + if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod && | |
| 661 | 561 | mconfig->m_state > SKL_MODULE_UNINIT) { |
| 662 | − ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, | |
| 562 | + ret = skl->dsp->fw_ops.unload_mod(skl->dsp, | |
| 663 | 563 | mconfig->id.module_id); |
| 664 | 564 | if (ret < 0) |
| 665 | 565 | return -EIO; |
| 666 | 566 | } |
| 667 | − skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); | |
| 567 | + skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id); | |
| 668 | 568 | |
| 669 | − ret = skl_dsp_put_core(ctx->dsp, mconfig->core_id); | |
| 569 | + ret = skl_dsp_put_core(skl->dsp, mconfig->core_id); | |
| 670 | 570 | if (ret < 0) { |
| 671 | 571 | /* don't return; continue with other modules */ |
| 672 | − dev_err(ctx->dev, "Failed to sleep core %d ret=%d\n", | |
| 572 | + dev_err(skl->dev, "Failed to sleep core %d ret=%d\n", | |
| 673 | 573 | mconfig->core_id, ret); |
| 674 | 574 | } |
| 675 | 575 | } |
| @@ -686,9 +586,8 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, · 10 unmodified lines | ||
| 686 | 586 | * 0th configuratation by default for such pipes. |
| 687 | 587 | */ |
| 688 | 588 | static int |
| 689 | −skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) | |
| 589 | +skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig) | |
| 690 | 590 | { |
| 691 | − struct skl_sst *ctx = skl->skl_sst; | |
| 692 | 591 | struct skl_pipe *pipe = mconfig->pipe; |
| 693 | 592 | struct skl_pipe_params *params = pipe->p_params; |
| 694 | 593 | struct skl_path_config *pconfig = &pipe->configs[0]; |
| @@ -702,7 +601,7 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) · 7 unmodified lines | ||
| 702 | 601 | } |
| 703 | 602 | |
| 704 | 603 | if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) { |
| 705 | − dev_dbg(ctx->dev, "No conn_type detected, take 0th config\n"); | |
| 604 | + dev_dbg(skl->dev, "No conn_type detected, take 0th config\n"); | |
| 706 | 605 | pipe->cur_config_idx = 0; |
| 707 | 606 | pipe->memory_pages = pconfig->mem_pages; |
| 708 | 607 | |
| @@ -726,13 +625,13 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) · 17 unmodified lines | ||
| 726 | 625 | fmt->channels, fmt->freq, fmt->bps)) { |
| 727 | 626 | pipe->cur_config_idx = i; |
| 728 | 627 | pipe->memory_pages = pconfig->mem_pages; |
| 729 | − dev_dbg(ctx->dev, "Using pipe config: %d\n", i); | |
| 628 | + dev_dbg(skl->dev, "Using pipe config: %d\n", i); | |
| 730 | 629 | |
| 731 | 630 | return 0; |
| 732 | 631 | } |
| 733 | 632 | } |
| 734 | 633 | |
| 735 | − dev_err(ctx->dev, "Invalid pipe config: %d %d %d for pipe: %d\n", | |
| 634 | + dev_err(skl->dev, "Invalid pipe config: %d %d %d for pipe: %d\n", | |
| 736 | 635 | params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); |
| 737 | 636 | return -EINVAL; |
| 738 | 637 | } |
| @@ -740,44 +639,32 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) · 1 unmodified line | ||
| 740 | 639 | /* |
| 741 | 640 | * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we |
| 742 | 641 | * need create the pipeline. So we do following: |
| 743 | − * - check the resources | |
| 744 | 642 | * - Create the pipeline |
| 745 | 643 | * - Initialize the modules in pipeline |
| 746 | 644 | * - finally bind all modules together |
| 747 | 645 | */ |
| 748 | 646 | static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, |
| 749 | − struct skl *skl) | |
| 647 | + struct skl_dev *skl) | |
| 750 | 648 | { |
| 751 | 649 | int ret; |
| 752 | 650 | struct skl_module_cfg *mconfig = w->priv; |
| 753 | 651 | struct skl_pipe_module *w_module; |
| 754 | 652 | struct skl_pipe *s_pipe = mconfig->pipe; |
| 755 | 653 | struct skl_module_cfg *src_module = NULL, *dst_module, *module; |
| 756 | − struct skl_sst *ctx = skl->skl_sst; | |
| 757 | 654 | struct skl_module_deferred_bind *modules; |
| 758 | 655 | |
| 759 | 656 | ret = skl_tplg_get_pipe_config(skl, mconfig); |
| 760 | 657 | if (ret < 0) |
| 761 | 658 | return ret; |
| 762 | 659 | |
| 763 | − /* check resource available */ | |
| 764 | − if (!skl_is_pipe_mcps_avail(skl, mconfig)) | |
| 765 | − return -EBUSY; | |
| 766 | − | |
| 767 | − if (!skl_is_pipe_mem_avail(skl, mconfig)) | |
| 768 | − return -ENOMEM; | |
| 769 | − | |
| 770 | 660 | /* |
| 771 | 661 | * Create a list of modules for pipe. |
| 772 | 662 | * This list contains modules from source to sink |
| 773 | 663 | */ |
| 774 | − ret = skl_create_pipeline(ctx, mconfig->pipe); | |
| 664 | + ret = skl_create_pipeline(skl, mconfig->pipe); | |
| 775 | 665 | if (ret < 0) |
| 776 | 666 | return ret; |
| 777 | 667 | |
| 778 | − skl_tplg_alloc_pipe_mem(skl, mconfig); | |
| 779 | − skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 780 | − | |
| 781 | 668 | /* Init all pipe modules from source to sink */ |
| 782 | 669 | ret = skl_tplg_init_pipe_modules(skl, s_pipe); |
| 783 | 670 | if (ret < 0) |
| @@ -792,7 +679,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 8 unmodified lines | ||
| 792 | 679 | continue; |
| 793 | 680 | } |
| 794 | 681 | |
| 795 | − ret = skl_bind_modules(ctx, src_module, dst_module); | |
| 682 | + ret = skl_bind_modules(skl, src_module, dst_module); | |
| 796 | 683 | if (ret < 0) |
| 797 | 684 | return ret; |
| 798 | 685 | |
| @@ -810,7 +697,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 11 unmodified lines | ||
| 810 | 697 | list_for_each_entry(modules, &skl->bind_list, node) { |
| 811 | 698 | module = w_module->w->priv; |
| 812 | 699 | if (modules->dst == module) |
| 813 | − skl_bind_modules(ctx, modules->src, | |
| 700 | + skl_bind_modules(skl, modules->src, | |
| 814 | 701 | modules->dst); |
| 815 | 702 | } |
| 816 | 703 | } |
| @@ -818,7 +705,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 1 unmodified line | ||
| 818 | 705 | return 0; |
| 819 | 706 | } |
| 820 | 707 | |
| 821 | −static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, | |
| 708 | +static int skl_fill_sink_instance_id(struct skl_dev *skl, u32 *params, | |
| 822 | 709 | int size, struct skl_module_cfg *mcfg) |
| 823 | 710 | { |
| 824 | 711 | int i, pvt_id; |
| @@ -829,7 +716,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, · 4 unmodified lines | ||
| 829 | 716 | struct skl_mod_inst_map *inst = kpb_params->u.map; |
| 830 | 717 | |
| 831 | 718 | for (i = 0; i < kpb_params->num_modules; i++) { |
| 832 | − pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id, | |
| 719 | + pvt_id = skl_get_pvt_instance_id_map(skl, inst->mod_id, | |
| 833 | 720 | inst->inst_id); |
| 834 | 721 | if (pvt_id < 0) |
| 835 | 722 | return -EINVAL; |
| @@ -849,7 +736,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, · 13 unmodified lines | ||
| 849 | 736 | * send params after binding |
| 850 | 737 | */ |
| 851 | 738 | static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, |
| 852 | − struct skl_module_cfg *mcfg, struct skl_sst *ctx) | |
| 739 | + struct skl_module_cfg *mcfg, struct skl_dev *skl) | |
| 853 | 740 | { |
| 854 | 741 | int i, ret; |
| 855 | 742 | struct skl_module_cfg *mconfig = w->priv; |
| @@ -876,7 +763,7 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, · 20 unmodified lines | ||
| 876 | 763 | if (mconfig->formats_config.caps_size > 0 && |
| 877 | 764 | mconfig->formats_config.set_params == SKL_PARAM_BIND) { |
| 878 | 765 | sp_cfg = &mconfig->formats_config; |
| 879 | − ret = skl_set_module_params(ctx, sp_cfg->caps, | |
| 766 | + ret = skl_set_module_params(skl, sp_cfg->caps, | |
| 880 | 767 | sp_cfg->caps_size, |
| 881 | 768 | sp_cfg->param_id, mconfig); |
| 882 | 769 | if (ret < 0) |
| @@ -894,10 +781,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, · 11 unmodified lines | ||
| 894 | 781 | if (!params) |
| 895 | 782 | return -ENOMEM; |
| 896 | 783 | |
| 897 | − skl_fill_sink_instance_id(ctx, params, bc->max, | |
| 784 | + skl_fill_sink_instance_id(skl, params, bc->max, | |
| 898 | 785 | mconfig); |
| 899 | 786 | |
| 900 | − ret = skl_set_module_params(ctx, params, | |
| 787 | + ret = skl_set_module_params(skl, params, | |
| 901 | 788 | bc->max, bc->param_id, mconfig); |
| 902 | 789 | kfree(params); |
| 903 | 790 | |
| @@ -910,11 +797,11 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, · 6 unmodified lines | ||
| 910 | 797 | return 0; |
| 911 | 798 | } |
| 912 | 799 | |
| 913 | −static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid) | |
| 800 | +static int skl_get_module_id(struct skl_dev *skl, guid_t *uuid) | |
| 914 | 801 | { |
| 915 | 802 | struct uuid_module *module; |
| 916 | 803 | |
| 917 | − list_for_each_entry(module, &ctx->uuid_list, list) { | |
| 804 | + list_for_each_entry(module, &skl->uuid_list, list) { | |
| 918 | 805 | if (guid_equal(uuid, &module->uuid)) |
| 919 | 806 | return module->id; |
| 920 | 807 | } |
| @@ -922,7 +809,7 @@ static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid) · 1 unmodified line | ||
| 922 | 809 | return -EINVAL; |
| 923 | 810 | } |
| 924 | 811 | |
| 925 | −static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, | |
| 812 | +static int skl_tplg_find_moduleid_from_uuid(struct skl_dev *skl, | |
| 926 | 813 | const struct snd_kcontrol_new *k) |
| 927 | 814 | { |
| 928 | 815 | struct soc_bytes_ext *sb = (void *) k->private_value; |
| @@ -942,7 +829,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, · 13 unmodified lines | ||
| 942 | 829 | params->num_modules = uuid_params->num_modules; |
| 943 | 830 | |
| 944 | 831 | for (i = 0; i < uuid_params->num_modules; i++) { |
| 945 | − module_id = skl_get_module_id(skl->skl_sst, | |
| 832 | + module_id = skl_get_module_id(skl, | |
| 946 | 833 | &uuid_params->u.map_uuid[i].mod_uuid); |
| 947 | 834 | if (module_id < 0) { |
| 948 | 835 | devm_kfree(bus->dev, params); |
| @@ -966,7 +853,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, · 17 unmodified lines | ||
| 966 | 853 | * Retrieve the module id from UUID mentioned in the |
| 967 | 854 | * post bind params |
| 968 | 855 | */ |
| 969 | −void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, | |
| 856 | +void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl, | |
| 970 | 857 | struct snd_soc_dapm_widget *w) |
| 971 | 858 | { |
| 972 | 859 | struct skl_module_cfg *mconfig = w->priv; |
| @@ -985,12 +872,12 @@ void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, · 12 unmodified lines | ||
| 985 | 872 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && |
| 986 | 873 | (skl_tplg_find_moduleid_from_uuid(skl, |
| 987 | 874 | &w->kcontrol_news[i]) < 0)) |
| 988 | − dev_err(skl->skl_sst->dev, | |
| 875 | + dev_err(skl->dev, | |
| 989 | 876 | "%s: invalid kpb post bind params\n", |
| 990 | 877 | __func__); |
| 991 | 878 | } |
| 992 | 879 | |
| 993 | −static int skl_tplg_module_add_deferred_bind(struct skl *skl, | |
| 880 | +static int skl_tplg_module_add_deferred_bind(struct skl_dev *skl, | |
| 994 | 881 | struct skl_module_cfg *src, struct skl_module_cfg *dst) |
| 995 | 882 | { |
| 996 | 883 | struct skl_module_deferred_bind *m_list, *modules; |
| @@ -1028,26 +915,27 @@ static int skl_tplg_module_add_deferred_bind(struct skl *skl, · 31 unmodified lines | ||
| 1028 | 915 | } |
| 1029 | 916 | |
| 1030 | 917 | static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, |
| 1031 | − struct skl *skl, | |
| 918 | + struct skl_dev *skl, | |
| 1032 | 919 | struct snd_soc_dapm_widget *src_w, |
| 1033 | 920 | struct skl_module_cfg *src_mconfig) |
| 1034 | 921 | { |
| 1035 | 922 | struct snd_soc_dapm_path *p; |
| 1036 | 923 | struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL; |
| 1037 | 924 | struct skl_module_cfg *sink_mconfig; |
| 1038 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1039 | 925 | int ret; |
| 1040 | 926 | |
| 1041 | 927 | snd_soc_dapm_widget_for_each_sink_path(w, p) { |
| 1042 | 928 | if (!p->connect) |
| 1043 | 929 | continue; |
| 1044 | 930 | |
| 1045 | − dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); | |
| 1046 | − dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); | |
| 931 | + dev_dbg(skl->dev, | |
| 932 | + "%s: src widget=%s\n", __func__, w->name); | |
| 933 | + dev_dbg(skl->dev, | |
| 934 | + "%s: sink widget=%s\n", __func__, p->sink->name); | |
| 1047 | 935 | |
| 1048 | 936 | next_sink = p->sink; |
| 1049 | 937 | |
| 1050 | − if (!is_skl_dsp_widget_type(p->sink, ctx->dev)) | |
| 938 | + if (!is_skl_dsp_widget_type(p->sink, skl->dev)) | |
| 1051 | 939 | return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig); |
| 1052 | 940 | |
| 1053 | 941 | /* |
| @@ -1056,7 +944,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, · 2 unmodified lines | ||
| 1056 | 944 | * they are ones used for SKL so check that first |
| 1057 | 945 | */ |
| 1058 | 946 | if ((p->sink->priv != NULL) && |
| 1059 | − is_skl_dsp_widget_type(p->sink, ctx->dev)) { | |
| 947 | + is_skl_dsp_widget_type(p->sink, skl->dev)) { | |
| 1060 | 948 | |
| 1061 | 949 | sink = p->sink; |
| 1062 | 950 | sink_mconfig = sink->priv; |
| @@ -1088,19 +976,21 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, · 25 unmodified lines | ||
| 1088 | 976 | continue; |
| 1089 | 977 | |
| 1090 | 978 | /* Bind source to sink, mixin is always source */ |
| 1091 | − ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig); | |
| 979 | + ret = skl_bind_modules(skl, src_mconfig, sink_mconfig); | |
| 1092 | 980 | if (ret) |
| 1093 | 981 | return ret; |
| 1094 | 982 | |
| 1095 | 983 | /* set module params after bind */ |
| 1096 | − skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx); | |
| 1097 | − skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); | |
| 984 | + skl_tplg_set_module_bind_params(src_w, | |
| 985 | + src_mconfig, skl); | |
| 986 | + skl_tplg_set_module_bind_params(sink, | |
| 987 | + sink_mconfig, skl); | |
| 1098 | 988 | |
| 1099 | 989 | /* Start sinks pipe first */ |
| 1100 | 990 | if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { |
| 1101 | 991 | if (sink_mconfig->pipe->conn_type != |
| 1102 | 992 | SKL_PIPE_CONN_TYPE_FE) |
| 1103 | − ret = skl_run_pipe(ctx, | |
| 993 | + ret = skl_run_pipe(skl, | |
| 1104 | 994 | sink_mconfig->pipe); |
| 1105 | 995 | if (ret) |
| 1106 | 996 | return ret; |
| @@ -1125,10 +1015,9 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, · 18 unmodified lines | ||
| 1125 | 1015 | * - Then run current pipe |
| 1126 | 1016 | */ |
| 1127 | 1017 | static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, |
| 1128 | − struct skl *skl) | |
| 1018 | + struct skl_dev *skl) | |
| 1129 | 1019 | { |
| 1130 | 1020 | struct skl_module_cfg *src_mconfig; |
| 1131 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1132 | 1021 | int ret = 0; |
| 1133 | 1022 | |
| 1134 | 1023 | src_mconfig = w->priv; |
| @@ -1144,25 +1033,24 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 9 unmodified lines | ||
| 1144 | 1033 | |
| 1145 | 1034 | /* Start source pipe last after starting all sinks */ |
| 1146 | 1035 | if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) |
| 1147 | − return skl_run_pipe(ctx, src_mconfig->pipe); | |
| 1036 | + return skl_run_pipe(skl, src_mconfig->pipe); | |
| 1148 | 1037 | |
| 1149 | 1038 | return 0; |
| 1150 | 1039 | } |
| 1151 | 1040 | |
| 1152 | 1041 | static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( |
| 1153 | − struct snd_soc_dapm_widget *w, struct skl *skl) | |
| 1042 | + struct snd_soc_dapm_widget *w, struct skl_dev *skl) | |
| 1154 | 1043 | { |
| 1155 | 1044 | struct snd_soc_dapm_path *p; |
| 1156 | 1045 | struct snd_soc_dapm_widget *src_w = NULL; |
| 1157 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1158 | 1046 | |
| 1159 | 1047 | snd_soc_dapm_widget_for_each_source_path(w, p) { |
| 1160 | 1048 | src_w = p->source; |
| 1161 | 1049 | if (!p->connect) |
| 1162 | 1050 | continue; |
| 1163 | 1051 | |
| 1164 | − dev_dbg(ctx->dev, "sink widget=%s\n", w->name); | |
| 1165 | − dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); | |
| 1052 | + dev_dbg(skl->dev, "sink widget=%s\n", w->name); | |
| 1053 | + dev_dbg(skl->dev, "src widget=%s\n", p->source->name); | |
| 1166 | 1054 | |
| 1167 | 1055 | /* |
| 1168 | 1056 | * here we will check widgets in sink pipelines, so that can |
| @@ -1170,7 +1058,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( · 1 unmodified line | ||
| 1170 | 1058 | * ones used for SKL so check that first |
| 1171 | 1059 | */ |
| 1172 | 1060 | if ((p->source->priv != NULL) && |
| 1173 | − is_skl_dsp_widget_type(p->source, ctx->dev)) { | |
| 1061 | + is_skl_dsp_widget_type(p->source, skl->dev)) { | |
| 1174 | 1062 | return p->source; |
| 1175 | 1063 | } |
| 1176 | 1064 | } |
| @@ -1191,12 +1079,11 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( · 14 unmodified lines | ||
| 1191 | 1079 | * - start this pipeline |
| 1192 | 1080 | */ |
| 1193 | 1081 | static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, |
| 1194 | − struct skl *skl) | |
| 1082 | + struct skl_dev *skl) | |
| 1195 | 1083 | { |
| 1196 | 1084 | int ret = 0; |
| 1197 | 1085 | struct snd_soc_dapm_widget *source, *sink; |
| 1198 | 1086 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1199 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1200 | 1087 | int src_pipe_started = 0; |
| 1201 | 1088 | |
| 1202 | 1089 | sink = w; |
| @@ -1222,16 +1109,16 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, · 19 unmodified lines | ||
| 1222 | 1109 | } |
| 1223 | 1110 | |
| 1224 | 1111 | if (src_pipe_started) { |
| 1225 | − ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig); | |
| 1112 | + ret = skl_bind_modules(skl, src_mconfig, sink_mconfig); | |
| 1226 | 1113 | if (ret) |
| 1227 | 1114 | return ret; |
| 1228 | 1115 | |
| 1229 | 1116 | /* set module params after bind */ |
| 1230 | − skl_tplg_set_module_bind_params(source, src_mconfig, ctx); | |
| 1231 | − skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); | |
| 1117 | + skl_tplg_set_module_bind_params(source, src_mconfig, skl); | |
| 1118 | + skl_tplg_set_module_bind_params(sink, sink_mconfig, skl); | |
| 1232 | 1119 | |
| 1233 | 1120 | if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) |
| 1234 | − ret = skl_run_pipe(ctx, sink_mconfig->pipe); | |
| 1121 | + ret = skl_run_pipe(skl, sink_mconfig->pipe); | |
| 1235 | 1122 | } |
| 1236 | 1123 | |
| 1237 | 1124 | return ret; |
| @@ -1244,16 +1131,15 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, · 6 unmodified lines | ||
| 1244 | 1131 | * - unbind with source pipelines if still connected |
| 1245 | 1132 | */ |
| 1246 | 1133 | static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, |
| 1247 | − struct skl *skl) | |
| 1134 | + struct skl_dev *skl) | |
| 1248 | 1135 | { |
| 1249 | 1136 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1250 | 1137 | int ret = 0, i; |
| 1251 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1252 | 1138 | |
| 1253 | 1139 | sink_mconfig = w->priv; |
| 1254 | 1140 | |
| 1255 | 1141 | /* Stop the pipe */ |
| 1256 | − ret = skl_stop_pipe(ctx, sink_mconfig->pipe); | |
| 1142 | + ret = skl_stop_pipe(skl, sink_mconfig->pipe); | |
| 1257 | 1143 | if (ret) |
| 1258 | 1144 | return ret; |
| 1259 | 1145 | |
| @@ -1263,7 +1149,7 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, · 3 unmodified lines | ||
| 1263 | 1149 | if (!src_mconfig) |
| 1264 | 1150 | continue; |
| 1265 | 1151 | |
| 1266 | − ret = skl_unbind_modules(ctx, | |
| 1152 | + ret = skl_unbind_modules(skl, | |
| 1267 | 1153 | src_mconfig, sink_mconfig); |
| 1268 | 1154 | } |
| 1269 | 1155 | } |
| @@ -1273,28 +1159,22 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, · 3 unmodified lines | ||
| 1273 | 1159 | |
| 1274 | 1160 | /* |
| 1275 | 1161 | * in the Post-PMD event of mixer we need to do following: |
| 1276 | − * - Free the mcps used | |
| 1277 | − * - Free the mem used | |
| 1278 | 1162 | * - Unbind the modules within the pipeline |
| 1279 | 1163 | * - Delete the pipeline (modules are not required to be explicitly |
| 1280 | 1164 | * deleted, pipeline delete is enough here |
| 1281 | 1165 | */ |
| 1282 | 1166 | static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, |
| 1283 | − struct skl *skl) | |
| 1167 | + struct skl_dev *skl) | |
| 1284 | 1168 | { |
| 1285 | 1169 | struct skl_module_cfg *mconfig = w->priv; |
| 1286 | 1170 | struct skl_pipe_module *w_module; |
| 1287 | 1171 | struct skl_module_cfg *src_module = NULL, *dst_module; |
| 1288 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1289 | 1172 | struct skl_pipe *s_pipe = mconfig->pipe; |
| 1290 | 1173 | struct skl_module_deferred_bind *modules, *tmp; |
| 1291 | 1174 | |
| 1292 | 1175 | if (s_pipe->state == SKL_PIPE_INVALID) |
| 1293 | 1176 | return -EINVAL; |
| 1294 | 1177 | |
| 1295 | − skl_tplg_free_pipe_mcps(skl, mconfig); | |
| 1296 | − skl_tplg_free_pipe_mem(skl, mconfig); | |
| 1297 | − | |
| 1298 | 1178 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1299 | 1179 | if (list_empty(&skl->bind_list)) |
| 1300 | 1180 | break; |
| @@ -1307,7 +1187,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, · 6 unmodified lines | ||
| 1307 | 1187 | * modules from deferred bind list. |
| 1308 | 1188 | */ |
| 1309 | 1189 | if (modules->dst == src_module) { |
| 1310 | − skl_unbind_modules(ctx, modules->src, | |
| 1190 | + skl_unbind_modules(skl, modules->src, | |
| 1311 | 1191 | modules->dst); |
| 1312 | 1192 | } |
| 1313 | 1193 | |
| @@ -1327,44 +1207,40 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, · 13 unmodified lines | ||
| 1327 | 1207 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1328 | 1208 | dst_module = w_module->w->priv; |
| 1329 | 1209 | |
| 1330 | − if (mconfig->m_state >= SKL_MODULE_INIT_DONE) | |
| 1331 | − skl_tplg_free_pipe_mcps(skl, dst_module); | |
| 1332 | 1210 | if (src_module == NULL) { |
| 1333 | 1211 | src_module = dst_module; |
| 1334 | 1212 | continue; |
| 1335 | 1213 | } |
| 1336 | 1214 | |
| 1337 | − skl_unbind_modules(ctx, src_module, dst_module); | |
| 1215 | + skl_unbind_modules(skl, src_module, dst_module); | |
| 1338 | 1216 | src_module = dst_module; |
| 1339 | 1217 | } |
| 1340 | 1218 | |
| 1341 | − skl_delete_pipe(ctx, mconfig->pipe); | |
| 1219 | + skl_delete_pipe(skl, mconfig->pipe); | |
| 1342 | 1220 | |
| 1343 | 1221 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1344 | 1222 | src_module = w_module->w->priv; |
| 1345 | 1223 | src_module->m_state = SKL_MODULE_UNINIT; |
| 1346 | 1224 | } |
| 1347 | 1225 | |
| 1348 | − return skl_tplg_unload_pipe_modules(ctx, s_pipe); | |
| 1226 | + return skl_tplg_unload_pipe_modules(skl, s_pipe); | |
| 1349 | 1227 | } |
| 1350 | 1228 | |
| 1351 | 1229 | /* |
| 1352 | 1230 | * in the Post-PMD event of PGA we need to do following: |
| 1353 | − * - Free the mcps used | |
| 1354 | 1231 | * - Stop the pipeline |
| 1355 | 1232 | * - In source pipe is connected, unbind with source pipelines |
| 1356 | 1233 | */ |
| 1357 | 1234 | static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, |
| 1358 | − struct skl *skl) | |
| 1235 | + struct skl_dev *skl) | |
| 1359 | 1236 | { |
| 1360 | 1237 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1361 | 1238 | int ret = 0, i; |
| 1362 | − struct skl_sst *ctx = skl->skl_sst; | |
| 1363 | 1239 | |
| 1364 | 1240 | src_mconfig = w->priv; |
| 1365 | 1241 | |
| 1366 | 1242 | /* Stop the pipe since this is a mixin module */ |
| 1367 | − ret = skl_stop_pipe(ctx, src_mconfig->pipe); | |
| 1243 | + ret = skl_stop_pipe(skl, src_mconfig->pipe); | |
| 1368 | 1244 | if (ret) |
| 1369 | 1245 | return ret; |
| 1370 | 1246 | |
| @@ -1377,7 +1253,7 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, · 6 unmodified lines | ||
| 1377 | 1253 | * This is a connecter and if path is found that means |
| 1378 | 1254 | * unbind between source and sink has not happened yet |
| 1379 | 1255 | */ |
| 1380 | − ret = skl_unbind_modules(ctx, src_mconfig, | |
| 1256 | + ret = skl_unbind_modules(skl, src_mconfig, | |
| 1381 | 1257 | sink_mconfig); |
| 1382 | 1258 | } |
| 1383 | 1259 | } |
| @@ -1395,7 +1271,7 @@ static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w, · 11 unmodified lines | ||
| 1395 | 1271 | struct snd_kcontrol *k, int event) |
| 1396 | 1272 | { |
| 1397 | 1273 | struct snd_soc_dapm_context *dapm = w->dapm; |
| 1398 | − struct skl *skl = get_skl_ctx(dapm->dev); | |
| 1274 | + struct skl_dev *skl = get_skl_ctx(dapm->dev); | |
| 1399 | 1275 | |
| 1400 | 1276 | switch (event) { |
| 1401 | 1277 | case SND_SOC_DAPM_PRE_PMU: |
| @@ -1425,7 +1301,7 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w, · 23 unmodified lines | ||
| 1425 | 1301 | |
| 1426 | 1302 | { |
| 1427 | 1303 | struct snd_soc_dapm_context *dapm = w->dapm; |
| 1428 | − struct skl *skl = get_skl_ctx(dapm->dev); | |
| 1304 | + struct skl_dev *skl = get_skl_ctx(dapm->dev); | |
| 1429 | 1305 | |
| 1430 | 1306 | switch (event) { |
| 1431 | 1307 | case SND_SOC_DAPM_PRE_PMU: |
| @@ -1446,10 +1322,10 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol, · 14 unmodified lines | ||
| 1446 | 1322 | struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; |
| 1447 | 1323 | struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); |
| 1448 | 1324 | struct skl_module_cfg *mconfig = w->priv; |
| 1449 | − struct skl *skl = get_skl_ctx(w->dapm->dev); | |
| 1325 | + struct skl_dev *skl = get_skl_ctx(w->dapm->dev); | |
| 1450 | 1326 | |
| 1451 | 1327 | if (w->power) |
| 1452 | − skl_get_module_params(skl->skl_sst, (u32 *)bc->params, | |
| 1328 | + skl_get_module_params(skl, (u32 *)bc->params, | |
| 1453 | 1329 | bc->size, bc->param_id, mconfig); |
| 1454 | 1330 | |
| 1455 | 1331 | /* decrement size for TLV header */ |
| @@ -1481,7 +1357,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol, · 25 unmodified lines | ||
| 1481 | 1357 | struct soc_bytes_ext *sb = |
| 1482 | 1358 | (struct soc_bytes_ext *)kcontrol->private_value; |
| 1483 | 1359 | struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private; |
| 1484 | − struct skl *skl = get_skl_ctx(w->dapm->dev); | |
| 1360 | + struct skl_dev *skl = get_skl_ctx(w->dapm->dev); | |
| 1485 | 1361 | |
| 1486 | 1362 | if (ac->params) { |
| 1487 | 1363 | /* |
| @@ -1498,7 +1374,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol, · 10 unmodified lines | ||
| 1498 | 1374 | return -EFAULT; |
| 1499 | 1375 | |
| 1500 | 1376 | if (w->power) |
| 1501 | − return skl_set_module_params(skl->skl_sst, | |
| 1377 | + return skl_set_module_params(skl, | |
| 1502 | 1378 | (u32 *)ac->params, ac->size, |
| 1503 | 1379 | ac->param_id, mconfig); |
| 1504 | 1380 | } |
| @@ -1659,7 +1535,7 @@ int skl_tplg_update_pipe_params(struct device *dev, · 154 unmodified lines | ||
| 1659 | 1535 | struct skl_pipe_params *params) |
| 1660 | 1536 | { |
| 1661 | 1537 | struct skl_module_res *res = &mconfig->module->resources[0]; |
| 1662 | − struct skl *skl = get_skl_ctx(dev); | |
| 1538 | + struct skl_dev *skl = get_skl_ctx(dev); | |
| 1663 | 1539 | struct skl_module_fmt *format = NULL; |
| 1664 | 1540 | u8 cfg_idx = mconfig->pipe->cur_config_idx; |
| 1665 | 1541 | |
| @@ -1856,7 +1732,7 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, · 190 unmodified lines | ||
| 1856 | 1732 | struct skl_pipe_params *params) |
| 1857 | 1733 | { |
| 1858 | 1734 | struct nhlt_specific_cfg *cfg; |
| 1859 | − struct skl *skl = get_skl_ctx(dai->dev); | |
| 1735 | + struct skl_dev *skl = get_skl_ctx(dai->dev); | |
| 1860 | 1736 | int link_type = skl_tplg_be_link_type(mconfig->dev_type); |
| 1861 | 1737 | u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type); |
| 1862 | 1738 | |
| @@ -2070,7 +1946,7 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev, · 207 unmodified lines | ||
| 2070 | 1946 | * Return an existing pipe if the pipe already exists. |
| 2071 | 1947 | */ |
| 2072 | 1948 | static int skl_tplg_add_pipe(struct device *dev, |
| 2073 | − struct skl_module_cfg *mconfig, struct skl *skl, | |
| 1949 | + struct skl_module_cfg *mconfig, struct skl_dev *skl, | |
| 2074 | 1950 | struct snd_soc_tplg_vendor_value_elem *tkn_elem) |
| 2075 | 1951 | { |
| 2076 | 1952 | struct skl_pipeline *ppl; |
| @@ -2330,10 +2206,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 253 unmodified lines | ||
| 2330 | 2206 | return -EINVAL; |
| 2331 | 2207 | |
| 2332 | 2208 | switch (tkn_elem->token) { |
| 2333 | − case SKL_TKN_MM_U32_CPS: | |
| 2334 | − res->cps = tkn_elem->value; | |
| 2335 | − break; | |
| 2336 | − | |
| 2337 | 2209 | case SKL_TKN_MM_U32_DMA_SIZE: |
| 2338 | 2210 | res->dma_buffer_size = tkn_elem->value; |
| 2339 | 2211 | break; |
| @@ -2354,10 +2226,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 14 unmodified lines | ||
| 2354 | 2226 | res->ibs = tkn_elem->value; |
| 2355 | 2227 | break; |
| 2356 | 2228 | |
| 2357 | − case SKL_TKN_U32_MAX_MCPS: | |
| 2358 | − res->cps = tkn_elem->value; | |
| 2359 | − break; | |
| 2360 | − | |
| 2361 | 2229 | case SKL_TKN_MM_U32_RES_PIN_ID: |
| 2362 | 2230 | case SKL_TKN_MM_U32_PIN_BUF: |
| 2363 | 2231 | ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res, |
| @@ -2366,6 +2234,11 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 2 unmodified lines | ||
| 2366 | 2234 | return ret; |
| 2367 | 2235 | break; |
| 2368 | 2236 | |
| 2237 | + case SKL_TKN_MM_U32_CPS: | |
| 2238 | + case SKL_TKN_U32_MAX_MCPS: | |
| 2239 | + /* ignore unused tokens */ | |
| 2240 | + break; | |
| 2241 | + | |
| 2369 | 2242 | default: |
| 2370 | 2243 | dev_err(dev, "Not a res type token: %d", tkn_elem->token); |
| 2371 | 2244 | return -EINVAL; |
| @@ -2381,7 +2254,7 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 9 unmodified lines | ||
| 2381 | 2254 | */ |
| 2382 | 2255 | static int skl_tplg_get_token(struct device *dev, |
| 2383 | 2256 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
| 2384 | − struct skl *skl, struct skl_module_cfg *mconfig) | |
| 2257 | + struct skl_dev *skl, struct skl_module_cfg *mconfig) | |
| 2385 | 2258 | { |
| 2386 | 2259 | int tkn_count = 0; |
| 2387 | 2260 | int ret; |
| @@ -2631,7 +2504,7 @@ static int skl_tplg_get_token(struct device *dev, · 243 unmodified lines | ||
| 2631 | 2504 | * module private data |
| 2632 | 2505 | */ |
| 2633 | 2506 | static int skl_tplg_get_tokens(struct device *dev, |
| 2634 | − char *pvt_data, struct skl *skl, | |
| 2507 | + char *pvt_data, struct skl_dev *skl, | |
| 2635 | 2508 | struct skl_module_cfg *mconfig, int block_size) |
| 2636 | 2509 | { |
| 2637 | 2510 | struct snd_soc_tplg_vendor_array *array; |
| @@ -2727,8 +2600,8 @@ static int skl_tplg_get_desc_blocks(struct device *dev, · 89 unmodified lines | ||
| 2727 | 2600 | * Otherwise we create a new instance and add into driver list |
| 2728 | 2601 | */ |
| 2729 | 2602 | static int skl_tplg_add_pipe_v4(struct device *dev, |
| 2730 | − struct skl_module_cfg *mconfig, struct skl *skl, | |
| 2731 | − struct skl_dfw_v4_pipe *dfw_pipe) | |
| 2603 | + struct skl_module_cfg *mconfig, struct skl_dev *skl, | |
| 2604 | + struct skl_dfw_v4_pipe *dfw_pipe) | |
| 2732 | 2605 | { |
| 2733 | 2606 | struct skl_pipeline *ppl; |
| 2734 | 2607 | struct skl_pipe *pipe; |
| @@ -2804,7 +2677,7 @@ static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt, · 69 unmodified lines | ||
| 2804 | 2677 | } |
| 2805 | 2678 | |
| 2806 | 2679 | static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, |
| 2807 | − struct skl *skl, struct device *dev, | |
| 2680 | + struct skl_dev *skl, struct device *dev, | |
| 2808 | 2681 | struct skl_module_cfg *mconfig) |
| 2809 | 2682 | { |
| 2810 | 2683 | struct skl_dfw_v4_module *dfw = |
| @@ -2818,7 +2691,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, · 7 unmodified lines | ||
| 2818 | 2691 | return ret; |
| 2819 | 2692 | mconfig->id.module_id = -1; |
| 2820 | 2693 | mconfig->id.instance_id = dfw->instance_id; |
| 2821 | − mconfig->module->resources[0].cps = dfw->max_mcps; | |
| 2694 | + mconfig->module->resources[0].cpc = dfw->max_mcps / 1000; | |
| 2822 | 2695 | mconfig->module->resources[0].ibs = dfw->ibs; |
| 2823 | 2696 | mconfig->module->resources[0].obs = dfw->obs; |
| 2824 | 2697 | mconfig->core_id = dfw->core_id; |
| @@ -2886,7 +2759,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, · 61 unmodified lines | ||
| 2886 | 2759 | * for the type and size of the suceeding data block. |
| 2887 | 2760 | */ |
| 2888 | 2761 | static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, |
| 2889 | − struct skl *skl, struct device *dev, | |
| 2762 | + struct skl_dev *skl, struct device *dev, | |
| 2890 | 2763 | struct skl_module_cfg *mconfig) |
| 2891 | 2764 | { |
| 2892 | 2765 | struct snd_soc_tplg_vendor_array *array; |
| @@ -2981,9 +2854,8 @@ static void skl_clear_pin_config(struct snd_soc_component *component, · 88 unmodified lines | ||
| 2981 | 2854 | } |
| 2982 | 2855 | } |
| 2983 | 2856 | |
| 2984 | −void skl_cleanup_resources(struct skl *skl) | |
| 2857 | +void skl_cleanup_resources(struct skl_dev *skl) | |
| 2985 | 2858 | { |
| 2986 | − struct skl_sst *ctx = skl->skl_sst; | |
| 2987 | 2859 | struct snd_soc_component *soc_component = skl->component; |
| 2988 | 2860 | struct snd_soc_dapm_widget *w; |
| 2989 | 2861 | struct snd_soc_card *card; |
| @@ -2995,15 +2867,12 @@ void skl_cleanup_resources(struct skl *skl) · 5 unmodified lines | ||
| 2995 | 2867 | if (!card || !card->instantiated) |
| 2996 | 2868 | return; |
| 2997 | 2869 | |
| 2998 | − skl->resource.mem = 0; | |
| 2999 | − skl->resource.mcps = 0; | |
| 3000 | − | |
| 3001 | 2870 | list_for_each_entry(w, &card->widgets, list) { |
| 3002 | − if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL) | |
| 2871 | + if (is_skl_dsp_widget_type(w, skl->dev) && w->priv != NULL) | |
| 3003 | 2872 | skl_clear_pin_config(soc_component, w); |
| 3004 | 2873 | } |
| 3005 | 2874 | |
| 3006 | − skl_clear_module_cnt(ctx->dsp); | |
| 2875 | + skl_clear_module_cnt(skl->dsp); | |
| 3007 | 2876 | } |
| 3008 | 2877 | |
| 3009 | 2878 | /* |
| @@ -3019,7 +2888,7 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index, · 9 unmodified lines | ||
| 3019 | 2888 | { |
| 3020 | 2889 | int ret; |
| 3021 | 2890 | struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); |
| 3022 | − struct skl *skl = bus_to_skl(bus); | |
| 2891 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 3023 | 2892 | struct skl_module_cfg *mconfig; |
| 3024 | 2893 | |
| 3025 | 2894 | if (!tplg_w->priv.size) |
| @@ -3163,21 +3032,21 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, · 137 unmodified lines | ||
| 3163 | 3032 | |
| 3164 | 3033 | static int skl_tplg_fill_str_mfest_tkn(struct device *dev, |
| 3165 | 3034 | struct snd_soc_tplg_vendor_string_elem *str_elem, |
| 3166 | − struct skl *skl) | |
| 3035 | + struct skl_dev *skl) | |
| 3167 | 3036 | { |
| 3168 | 3037 | int tkn_count = 0; |
| 3169 | 3038 | static int ref_count; |
| 3170 | 3039 | |
| 3171 | 3040 | switch (str_elem->token) { |
| 3172 | 3041 | case SKL_TKN_STR_LIB_NAME: |
| 3173 | − if (ref_count > skl->skl_sst->lib_count - 1) { | |
| 3042 | + if (ref_count > skl->lib_count - 1) { | |
| 3174 | 3043 | ref_count = 0; |
| 3175 | 3044 | return -EINVAL; |
| 3176 | 3045 | } |
| 3177 | 3046 | |
| 3178 | − strncpy(skl->skl_sst->lib_info[ref_count].name, | |
| 3047 | + strncpy(skl->lib_info[ref_count].name, | |
| 3179 | 3048 | str_elem->string, |
| 3180 | − ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name)); | |
| 3049 | + ARRAY_SIZE(skl->lib_info[ref_count].name)); | |
| 3181 | 3050 | ref_count++; |
| 3182 | 3051 | break; |
| 3183 | 3052 | |
| @@ -3192,7 +3061,7 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev, · 8 unmodified lines | ||
| 3192 | 3061 | |
| 3193 | 3062 | static int skl_tplg_get_str_tkn(struct device *dev, |
| 3194 | 3063 | struct snd_soc_tplg_vendor_array *array, |
| 3195 | − struct skl *skl) | |
| 3064 | + struct skl_dev *skl) | |
| 3196 | 3065 | { |
| 3197 | 3066 | int tkn_count = 0, ret; |
| 3198 | 3067 | struct snd_soc_tplg_vendor_string_elem *str_elem; |
| @@ -3299,7 +3168,7 @@ static int skl_tplg_fill_mod_info(struct device *dev, · 100 unmodified lines | ||
| 3299 | 3168 | |
| 3300 | 3169 | static int skl_tplg_get_int_tkn(struct device *dev, |
| 3301 | 3170 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
| 3302 | − struct skl *skl) | |
| 3171 | + struct skl_dev *skl) | |
| 3303 | 3172 | { |
| 3304 | 3173 | int tkn_count = 0, ret; |
| 3305 | 3174 | static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; |
| @@ -3319,7 +3188,7 @@ static int skl_tplg_get_int_tkn(struct device *dev, · 13 unmodified lines | ||
| 3319 | 3188 | |
| 3320 | 3189 | switch (tkn_elem->token) { |
| 3321 | 3190 | case SKL_TKN_U32_LIB_COUNT: |
| 3322 | − skl->skl_sst->lib_count = tkn_elem->value; | |
| 3191 | + skl->lib_count = tkn_elem->value; | |
| 3323 | 3192 | break; |
| 3324 | 3193 | |
| 3325 | 3194 | case SKL_TKN_U8_NUM_MOD: |
| @@ -3465,35 +3334,17 @@ static int skl_tplg_get_int_tkn(struct device *dev, · 139 unmodified lines | ||
| 3465 | 3334 | return tkn_count; |
| 3466 | 3335 | } |
| 3467 | 3336 | |
| 3468 | −static int skl_tplg_get_manifest_uuid(struct device *dev, | |
| 3469 | − struct skl *skl, | |
| 3470 | − struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) | |
| 3471 | −{ | |
| 3472 | − static int ref_count; | |
| 3473 | − struct skl_module *mod; | |
| 3474 | − | |
| 3475 | − if (uuid_tkn->token == SKL_TKN_UUID) { | |
| 3476 | − mod = skl->modules[ref_count]; | |
| 3477 | − guid_copy(&mod->uuid, (guid_t *)&uuid_tkn->uuid); | |
| 3478 | − ref_count++; | |
| 3479 | − } else { | |
| 3480 | − dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token); | |
| 3481 | − return -EINVAL; | |
| 3482 | − } | |
| 3483 | − | |
| 3484 | − return 0; | |
| 3485 | −} | |
| 3486 | − | |
| 3487 | 3337 | /* |
| 3488 | 3338 | * Fill the manifest structure by parsing the tokens based on the |
| 3489 | 3339 | * type. |
| 3490 | 3340 | */ |
| 3491 | 3341 | static int skl_tplg_get_manifest_tkn(struct device *dev, |
| 3492 | − char *pvt_data, struct skl *skl, | |
| 3342 | + char *pvt_data, struct skl_dev *skl, | |
| 3493 | 3343 | int block_size) |
| 3494 | 3344 | { |
| 3495 | 3345 | int tkn_count = 0, ret; |
| 3496 | 3346 | int off = 0, tuple_size = 0; |
| 3347 | + u8 uuid_index = 0; | |
| 3497 | 3348 | struct snd_soc_tplg_vendor_array *array; |
| 3498 | 3349 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; |
| 3499 | 3350 | |
| @@ -3516,9 +3367,17 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, · 16 unmodified lines | ||
| 3516 | 3367 | continue; |
| 3517 | 3368 | |
| 3518 | 3369 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: |
| 3519 | − ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid); | |
| 3520 | − if (ret < 0) | |
| 3521 | − return ret; | |
| 3370 | + if (array->uuid->token != SKL_TKN_UUID) { | |
| 3371 | + dev_err(dev, "Not an UUID token: %d\n", | |
| 3372 | + array->uuid->token); | |
| 3373 | + return -EINVAL; | |
| 3374 | + } | |
| 3375 | + if (uuid_index >= skl->nr_modules) { | |
| 3376 | + dev_err(dev, "Too many UUID tokens\n"); | |
| 3377 | + return -EINVAL; | |
| 3378 | + } | |
| 3379 | + guid_copy(&skl->modules[uuid_index++]->uuid, | |
| 3380 | + (guid_t *)&array->uuid->uuid); | |
| 3522 | 3381 | |
| 3523 | 3382 | tuple_size += sizeof(*array->uuid); |
| 3524 | 3383 | continue; |
| @@ -3550,7 +3409,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, · 25 unmodified lines | ||
| 3550 | 3409 | * preceded by descriptors for type and size of data block. |
| 3551 | 3410 | */ |
| 3552 | 3411 | static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, |
| 3553 | − struct device *dev, struct skl *skl) | |
| 3412 | + struct device *dev, struct skl_dev *skl) | |
| 3554 | 3413 | { |
| 3555 | 3414 | struct snd_soc_tplg_vendor_array *array; |
| 3556 | 3415 | int num_blocks, block_size = 0, block_type, off = 0; |
| @@ -3612,7 +3471,7 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index, · 55 unmodified lines | ||
| 3612 | 3471 | struct snd_soc_tplg_manifest *manifest) |
| 3613 | 3472 | { |
| 3614 | 3473 | struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); |
| 3615 | − struct skl *skl = bus_to_skl(bus); | |
| 3474 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 3616 | 3475 | |
| 3617 | 3476 | /* proceed only if we have private data defined */ |
| 3618 | 3477 | if (manifest->priv.size == 0) |
| @@ -3620,9 +3479,9 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index, · 1 unmodified line | ||
| 3620 | 3479 | |
| 3621 | 3480 | skl_tplg_get_manifest_data(manifest, bus->dev, skl); |
| 3622 | 3481 | |
| 3623 | − if (skl->skl_sst->lib_count > SKL_MAX_LIB) { | |
| 3482 | + if (skl->lib_count > SKL_MAX_LIB) { | |
| 3624 | 3483 | dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", |
| 3625 | − skl->skl_sst->lib_count); | |
| 3484 | + skl->lib_count); | |
| 3626 | 3485 | return -EINVAL; |
| 3627 | 3486 | } |
| 3628 | 3487 | |
| @@ -3671,7 +3530,7 @@ static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component) · 42 unmodified lines | ||
| 3671 | 3530 | return 0; |
| 3672 | 3531 | } |
| 3673 | 3532 | |
| 3674 | −static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe) | |
| 3533 | +static void skl_tplg_set_pipe_type(struct skl_dev *skl, struct skl_pipe *pipe) | |
| 3675 | 3534 | { |
| 3676 | 3535 | struct skl_pipe_module *w_module; |
| 3677 | 3536 | struct snd_soc_dapm_widget *w; |
| @@ -3694,10 +3553,6 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe) · 16 unmodified lines | ||
| 3694 | 3553 | pipe->passthru = false; |
| 3695 | 3554 | } |
| 3696 | 3555 | |
| 3697 | −/* This will be read from topology manifest, currently defined here */ | |
| 3698 | −#define SKL_MAX_MCPS 30000000 | |
| 3699 | −#define SKL_FW_MAX_MEM 1000000 | |
| 3700 | − | |
| 3701 | 3556 | /* |
| 3702 | 3557 | * SKL topology init routine |
| 3703 | 3558 | */ |
| @@ -3705,7 +3560,7 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus) · 1 unmodified line | ||
| 3705 | 3560 | { |
| 3706 | 3561 | int ret; |
| 3707 | 3562 | const struct firmware *fw; |
| 3708 | − struct skl *skl = bus_to_skl(bus); | |
| 3563 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 3709 | 3564 | struct skl_pipeline *ppl; |
| 3710 | 3565 | |
| 3711 | 3566 | ret = request_firmware(&fw, skl->tplg_name, bus->dev); |
| @@ -3724,31 +3579,30 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus) · 12 unmodified lines | ||
| 3724 | 3579 | * The complete tplg for SKL is loaded as index 0, we don't use |
| 3725 | 3580 | * any other index |
| 3726 | 3581 | */ |
| 3727 | − ret = snd_soc_tplg_component_load(component, | |
| 3728 | − &skl_tplg_ops, fw, 0); | |
| 3582 | + ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw, 0); | |
| 3729 | 3583 | if (ret < 0) { |
| 3730 | 3584 | dev_err(bus->dev, "tplg component load failed%d\n", ret); |
| 3731 | − release_firmware(fw); | |
| 3732 | − return -EINVAL; | |
| 3585 | + goto err; | |
| 3733 | 3586 | } |
| 3734 | 3587 | |
| 3735 | − skl->resource.max_mcps = SKL_MAX_MCPS; | |
| 3736 | − skl->resource.max_mem = SKL_FW_MAX_MEM; | |
| 3737 | − | |
| 3738 | − skl->tplg = fw; | |
| 3739 | 3588 | ret = skl_tplg_create_pipe_widget_list(component); |
| 3740 | − if (ret < 0) | |
| 3741 | − return ret; | |
| 3589 | + if (ret < 0) { | |
| 3590 | + dev_err(bus->dev, "tplg create pipe widget list failed%d\n", | |
| 3591 | + ret); | |
| 3592 | + goto err; | |
| 3593 | + } | |
| 3742 | 3594 | |
| 3743 | 3595 | list_for_each_entry(ppl, &skl->ppl_list, node) |
| 3744 | 3596 | skl_tplg_set_pipe_type(skl, ppl->pipe); |
| 3745 | 3597 | |
| 3746 | − return 0; | |
| 3598 | +err: | |
| 3599 | + release_firmware(fw); | |
| 3600 | + return ret; | |
| 3747 | 3601 | } |
| 3748 | 3602 | |
| 3749 | 3603 | void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus) |
| 3750 | 3604 | { |
| 3751 | − struct skl *skl = bus_to_skl(bus); | |
| 3605 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 3752 | 3606 | struct skl_pipeline *ppl, *tmp; |
| 3753 | 3607 | |
| 3754 | 3608 | if (!list_empty(&skl->ppl_list)) |
| @@ -3757,6 +3611,4 @@ void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus) · 2 unmodified lines | ||
| 3757 | 3611 | |
| 3758 | 3612 | /* clean up topology */ |
| 3759 | 3613 | snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); |
| 3760 | − | |
| 3761 | − release_firmware(skl->tplg); | |
| 3762 | 3614 | } |
| @@ -101,7 +101,7 @@ struct skl_audio_data_format { · 100 unmodified lines | ||
| 101 | 101 | } __packed; |
| 102 | 102 | |
| 103 | 103 | struct skl_base_cfg { |
| 104 | − u32 cps; | |
| 104 | + u32 cpc; | |
| 105 | 105 | u32 ibs; |
| 106 | 106 | u32 obs; |
| 107 | 107 | u32 is_pages; |
| @@ -140,11 +140,6 @@ struct skl_src_module_cfg { · 32 unmodified lines | ||
| 140 | 140 | enum skl_s_freq src_cfg; |
| 141 | 141 | } __packed; |
| 142 | 142 | |
| 143 | −struct notification_mask { | |
| 144 | − u32 notify; | |
| 145 | − u32 enable; | |
| 146 | −} __packed; | |
| 147 | − | |
| 148 | 143 | struct skl_up_down_mixer_cfg { |
| 149 | 144 | struct skl_base_cfg base_cfg; |
| 150 | 145 | enum skl_ch_cfg out_ch_cfg; |
| @@ -348,7 +343,6 @@ struct skl_module_pin_resources { · 197 unmodified lines | ||
| 348 | 343 | struct skl_module_res { |
| 349 | 344 | u8 id; |
| 350 | 345 | u32 is_pages; |
| 351 | − u32 cps; | |
| 352 | 346 | u32 ibs; |
| 353 | 347 | u32 obs; |
| 354 | 348 | u32 dma_buffer_size; |
| @@ -389,9 +383,6 @@ struct skl_module_cfg { · 34 unmodified lines | ||
| 389 | 383 | u8 out_queue_mask; |
| 390 | 384 | u8 in_queue; |
| 391 | 385 | u8 out_queue; |
| 392 | − u32 mcps; | |
| 393 | − u32 ibs; | |
| 394 | − u32 obs; | |
| 395 | 386 | u8 is_loadable; |
| 396 | 387 | u8 core_id; |
| 397 | 388 | u8 dev_type; |
| @@ -447,7 +438,7 @@ enum skl_channel { · 49 unmodified lines | ||
| 447 | 438 | SKL_CH_QUATRO = 4, |
| 448 | 439 | }; |
| 449 | 440 | |
| 450 | −static inline struct skl *get_skl_ctx(struct device *dev) | |
| 441 | +static inline struct skl_dev *get_skl_ctx(struct device *dev) | |
| 451 | 442 | { |
| 452 | 443 | struct hdac_bus *bus = dev_get_drvdata(dev); |
| 453 | 444 | |
| @@ -456,7 +447,7 @@ static inline struct skl *get_skl_ctx(struct device *dev) · 2 unmodified lines | ||
| 456 | 447 | |
| 457 | 448 | int skl_tplg_be_update_params(struct snd_soc_dai *dai, |
| 458 | 449 | struct skl_pipe_params *params); |
| 459 | −int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, | |
| 450 | +int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps, | |
| 460 | 451 | u32 caps_size, u32 node_id); |
| 461 | 452 | void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, |
| 462 | 453 | struct skl_pipe_params *params, int stream); |
| @@ -469,32 +460,32 @@ struct skl_module_cfg *skl_tplg_fe_get_cpr_module( · 6 unmodified lines | ||
| 469 | 460 | int skl_tplg_update_pipe_params(struct device *dev, |
| 470 | 461 | struct skl_module_cfg *mconfig, struct skl_pipe_params *params); |
| 471 | 462 | |
| 472 | −void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps); | |
| 473 | −void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps); | |
| 463 | +void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps); | |
| 464 | +void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps); | |
| 474 | 465 | |
| 475 | −int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 466 | +int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 476 | 467 | |
| 477 | −int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 468 | +int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 478 | 469 | |
| 479 | −int skl_pause_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 470 | +int skl_pause_pipe(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 480 | 471 | |
| 481 | −int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 472 | +int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 482 | 473 | |
| 483 | −int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 474 | +int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 484 | 475 | |
| 485 | −int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); | |
| 476 | +int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe); | |
| 486 | 477 | |
| 487 | −int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config); | |
| 478 | +int skl_init_module(struct skl_dev *skl, struct skl_module_cfg *module_config); | |
| 488 | 479 | |
| 489 | −int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg | |
| 480 | +int skl_bind_modules(struct skl_dev *skl, struct skl_module_cfg | |
| 490 | 481 | *src_module, struct skl_module_cfg *dst_module); |
| 491 | 482 | |
| 492 | −int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg | |
| 483 | +int skl_unbind_modules(struct skl_dev *skl, struct skl_module_cfg | |
| 493 | 484 | *src_module, struct skl_module_cfg *dst_module); |
| 494 | 485 | |
| 495 | −int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, | |
| 486 | +int skl_set_module_params(struct skl_dev *skl, u32 *params, int size, | |
| 496 | 487 | u32 param_id, struct skl_module_cfg *mcfg); |
| 497 | −int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, | |
| 488 | +int skl_get_module_params(struct skl_dev *skl, u32 *params, int size, | |
| 498 | 489 | u32 param_id, struct skl_module_cfg *mcfg); |
| 499 | 490 | |
| 500 | 491 | struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, |
| @@ -508,6 +499,6 @@ int skl_pcm_link_dma_prepare(struct device *dev, · 7 unmodified lines | ||
| 508 | 499 | int skl_dai_load(struct snd_soc_component *cmp, int index, |
| 509 | 500 | struct snd_soc_dai_driver *dai_drv, |
| 510 | 501 | struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai); |
| 511 | −void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, | |
| 502 | +void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl, | |
| 512 | 503 | struct snd_soc_dapm_widget *w); |
| 513 | 504 | #endif |
| @@ -26,9 +26,11 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <sound/hdaudio.h> |
| 27 | 27 | #include <sound/hda_i915.h> |
| 28 | 28 | #include <sound/hda_codec.h> |
| 29 | +#include <sound/intel-nhlt.h> | |
| 29 | 30 | #include "skl.h" |
| 30 | 31 | #include "skl-sst-dsp.h" |
| 31 | 32 | #include "skl-sst-ipc.h" |
| 33 | + | |
| 32 | 34 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 33 | 35 | #include "../../../soc/codecs/hdac_hda.h" |
| 34 | 36 | #endif |
| @@ -50,7 +52,7 @@ static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg, · 15 unmodified lines | ||
| 50 | 52 | pci_write_config_byte(pci, reg, data); |
| 51 | 53 | } |
| 52 | 54 | |
| 53 | −static void skl_init_pci(struct skl *skl) | |
| 55 | +static void skl_init_pci(struct skl_dev *skl) | |
| 54 | 56 | { |
| 55 | 57 | struct hdac_bus *bus = skl_to_bus(skl); |
| 56 | 58 | |
| @@ -132,7 +134,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) · 75 unmodified lines | ||
| 132 | 134 | |
| 133 | 135 | /* Reset stream-to-link mapping */ |
| 134 | 136 | list_for_each_entry(hlink, &bus->hlink_list, list) |
| 135 | − bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); | |
| 137 | + writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); | |
| 136 | 138 | |
| 137 | 139 | skl_enable_miscbdcge(bus->dev, true); |
| 138 | 140 | |
| @@ -252,7 +254,7 @@ static irqreturn_t skl_threaded_handler(int irq, void *dev_id) · 113 unmodified lines | ||
| 252 | 254 | |
| 253 | 255 | static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect) |
| 254 | 256 | { |
| 255 | − struct skl *skl = bus_to_skl(bus); | |
| 257 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 256 | 258 | int ret; |
| 257 | 259 | |
| 258 | 260 | ret = request_threaded_irq(skl->pci->irq, skl_interrupt, |
| @@ -276,7 +278,7 @@ static int skl_suspend_late(struct device *dev) · 17 unmodified lines | ||
| 276 | 278 | { |
| 277 | 279 | struct pci_dev *pci = to_pci_dev(dev); |
| 278 | 280 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 279 | − struct skl *skl = bus_to_skl(bus); | |
| 281 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 280 | 282 | |
| 281 | 283 | return skl_suspend_late_dsp(skl); |
| 282 | 284 | } |
| @@ -284,7 +286,7 @@ static int skl_suspend_late(struct device *dev) · 1 unmodified line | ||
| 284 | 286 | #ifdef CONFIG_PM |
| 285 | 287 | static int _skl_suspend(struct hdac_bus *bus) |
| 286 | 288 | { |
| 287 | − struct skl *skl = bus_to_skl(bus); | |
| 289 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 288 | 290 | struct pci_dev *pci = to_pci_dev(bus->dev); |
| 289 | 291 | int ret; |
| 290 | 292 | |
| @@ -307,7 +309,7 @@ static int _skl_suspend(struct hdac_bus *bus) · 16 unmodified lines | ||
| 307 | 309 | |
| 308 | 310 | static int _skl_resume(struct hdac_bus *bus) |
| 309 | 311 | { |
| 310 | − struct skl *skl = bus_to_skl(bus); | |
| 312 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 311 | 313 | |
| 312 | 314 | skl_init_pci(skl); |
| 313 | 315 | skl_dum_set(bus); |
| @@ -325,7 +327,7 @@ static int skl_suspend(struct device *dev) · 11 unmodified lines | ||
| 325 | 327 | { |
| 326 | 328 | struct pci_dev *pci = to_pci_dev(dev); |
| 327 | 329 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 328 | − struct skl *skl = bus_to_skl(bus); | |
| 330 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 329 | 331 | int ret; |
| 330 | 332 | |
| 331 | 333 | /* |
| @@ -345,7 +347,7 @@ static int skl_suspend(struct device *dev) · 13 unmodified lines | ||
| 345 | 347 | ret = _skl_suspend(bus); |
| 346 | 348 | if (ret < 0) |
| 347 | 349 | return ret; |
| 348 | − skl->skl_sst->fw_loaded = false; | |
| 350 | + skl->fw_loaded = false; | |
| 349 | 351 | } |
| 350 | 352 | |
| 351 | 353 | return 0; |
| @@ -355,7 +357,7 @@ static int skl_resume(struct device *dev) · 3 unmodified lines | ||
| 355 | 357 | { |
| 356 | 358 | struct pci_dev *pci = to_pci_dev(dev); |
| 357 | 359 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 358 | − struct skl *skl = bus_to_skl(bus); | |
| 360 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 359 | 361 | struct hdac_ext_link *hlink = NULL; |
| 360 | 362 | int ret; |
| 361 | 363 | |
| @@ -430,7 +432,7 @@ static const struct dev_pm_ops skl_pm = { · 68 unmodified lines | ||
| 430 | 432 | */ |
| 431 | 433 | static int skl_free(struct hdac_bus *bus) |
| 432 | 434 | { |
| 433 | − struct skl *skl = bus_to_skl(bus); | |
| 435 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 434 | 436 | |
| 435 | 437 | skl->init_done = 0; /* to be sure */ |
| 436 | 438 | |
| @@ -475,7 +477,7 @@ static struct skl_ssp_clk skl_ssp_clks[] = { · 38 unmodified lines | ||
| 475 | 477 | {.name = "ssp5_sclkfs"}, |
| 476 | 478 | }; |
| 477 | 479 | |
| 478 | −static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl, | |
| 480 | +static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl, | |
| 479 | 481 | struct snd_soc_acpi_mach *machines) |
| 480 | 482 | { |
| 481 | 483 | struct hdac_bus *bus = skl_to_bus(skl); |
| @@ -494,7 +496,7 @@ static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl, · 12 unmodified lines | ||
| 494 | 496 | return mach; |
| 495 | 497 | } |
| 496 | 498 | |
| 497 | −static int skl_find_machine(struct skl *skl, void *driver_data) | |
| 499 | +static int skl_find_machine(struct skl_dev *skl, void *driver_data) | |
| 498 | 500 | { |
| 499 | 501 | struct hdac_bus *bus = skl_to_bus(skl); |
| 500 | 502 | struct snd_soc_acpi_mach *mach = driver_data; |
| @@ -516,13 +518,15 @@ static int skl_find_machine(struct skl *skl, void *driver_data) · 15 unmodified lines | ||
| 516 | 518 | |
| 517 | 519 | if (pdata) { |
| 518 | 520 | skl->use_tplg_pcm = pdata->use_tplg_pcm; |
| 519 | − mach->mach_params.dmic_num = skl_get_dmic_geo(skl); | |
| 521 | + mach->mach_params.dmic_num = | |
| 522 | + intel_nhlt_get_dmic_geo(&skl->pci->dev, | |
| 523 | + skl->nhlt); | |
| 520 | 524 | } |
| 521 | 525 | |
| 522 | 526 | return 0; |
| 523 | 527 | } |
| 524 | 528 | |
| 525 | −static int skl_machine_device_register(struct skl *skl) | |
| 529 | +static int skl_machine_device_register(struct skl_dev *skl) | |
| 526 | 530 | { |
| 527 | 531 | struct snd_soc_acpi_mach *mach = skl->mach; |
| 528 | 532 | struct hdac_bus *bus = skl_to_bus(skl); |
| @@ -558,13 +562,13 @@ static int skl_machine_device_register(struct skl *skl) · 29 unmodified lines | ||
| 558 | 562 | return 0; |
| 559 | 563 | } |
| 560 | 564 | |
| 561 | −static void skl_machine_device_unregister(struct skl *skl) | |
| 565 | +static void skl_machine_device_unregister(struct skl_dev *skl) | |
| 562 | 566 | { |
| 563 | 567 | if (skl->i2s_dev) |
| 564 | 568 | platform_device_unregister(skl->i2s_dev); |
| 565 | 569 | } |
| 566 | 570 | |
| 567 | −static int skl_dmic_device_register(struct skl *skl) | |
| 571 | +static int skl_dmic_device_register(struct skl_dev *skl) | |
| 568 | 572 | { |
| 569 | 573 | struct hdac_bus *bus = skl_to_bus(skl); |
| 570 | 574 | struct platform_device *pdev; |
| @@ -588,7 +592,7 @@ static int skl_dmic_device_register(struct skl *skl) · 17 unmodified lines | ||
| 588 | 592 | return 0; |
| 589 | 593 | } |
| 590 | 594 | |
| 591 | −static void skl_dmic_device_unregister(struct skl *skl) | |
| 595 | +static void skl_dmic_device_unregister(struct skl_dev *skl) | |
| 592 | 596 | { |
| 593 | 597 | if (skl->dmic_dev) |
| 594 | 598 | platform_device_unregister(skl->dmic_dev); |
| @@ -626,7 +630,7 @@ static void init_skl_xtal_rate(int pci_id) · 31 unmodified lines | ||
| 626 | 630 | } |
| 627 | 631 | } |
| 628 | 632 | |
| 629 | −static int skl_clock_device_register(struct skl *skl) | |
| 633 | +static int skl_clock_device_register(struct skl_dev *skl) | |
| 630 | 634 | { |
| 631 | 635 | struct platform_device_info pdevinfo = {NULL}; |
| 632 | 636 | struct skl_clk_pdata *clk_pdata; |
| @@ -656,7 +660,7 @@ static int skl_clock_device_register(struct skl *skl) · 23 unmodified lines | ||
| 656 | 660 | return PTR_ERR_OR_ZERO(skl->clk_dev); |
| 657 | 661 | } |
| 658 | 662 | |
| 659 | −static void skl_clock_device_unregister(struct skl *skl) | |
| 663 | +static void skl_clock_device_unregister(struct skl_dev *skl) | |
| 660 | 664 | { |
| 661 | 665 | if (skl->clk_dev) |
| 662 | 666 | platform_device_unregister(skl->clk_dev); |
| @@ -692,7 +696,7 @@ static int probe_codec(struct hdac_bus *bus, int addr) · 29 unmodified lines | ||
| 692 | 696 | unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | |
| 693 | 697 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; |
| 694 | 698 | unsigned int res = -1; |
| 695 | − struct skl *skl = bus_to_skl(bus); | |
| 699 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 696 | 700 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 697 | 701 | struct hdac_hda_priv *hda_codec; |
| 698 | 702 | int err; |
| @@ -792,7 +796,7 @@ static int skl_i915_init(struct hdac_bus *bus) · 93 unmodified lines | ||
| 792 | 796 | |
| 793 | 797 | static void skl_probe_work(struct work_struct *work) |
| 794 | 798 | { |
| 795 | − struct skl *skl = container_of(work, struct skl, probe_work); | |
| 799 | + struct skl_dev *skl = container_of(work, struct skl_dev, probe_work); | |
| 796 | 800 | struct hdac_bus *bus = skl_to_bus(skl); |
| 797 | 801 | struct hdac_ext_link *hlink = NULL; |
| 798 | 802 | int err; |
| @@ -854,11 +858,10 @@ out_err: · 55 unmodified lines | ||
| 854 | 858 | * constructor |
| 855 | 859 | */ |
| 856 | 860 | static int skl_create(struct pci_dev *pci, |
| 857 | − const struct hdac_io_ops *io_ops, | |
| 858 | − struct skl **rskl) | |
| 861 | + struct skl_dev **rskl) | |
| 859 | 862 | { |
| 860 | 863 | struct hdac_ext_bus_ops *ext_ops = NULL; |
| 861 | − struct skl *skl; | |
| 864 | + struct skl_dev *skl; | |
| 862 | 865 | struct hdac_bus *bus; |
| 863 | 866 | struct hda_bus *hbus; |
| 864 | 867 | int err; |
| @@ -884,7 +887,7 @@ static int skl_create(struct pci_dev *pci, · 19 unmodified lines | ||
| 884 | 887 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 885 | 888 | ext_ops = snd_soc_hdac_hda_get_ops(); |
| 886 | 889 | #endif |
| 887 | − snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops); | |
| 890 | + snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, ext_ops); | |
| 888 | 891 | bus->use_posbuf = 1; |
| 889 | 892 | skl->pci = pci; |
| 890 | 893 | INIT_WORK(&skl->probe_work, skl_probe_work); |
| @@ -902,7 +905,7 @@ static int skl_create(struct pci_dev *pci, · 11 unmodified lines | ||
| 902 | 905 | |
| 903 | 906 | static int skl_first_init(struct hdac_bus *bus) |
| 904 | 907 | { |
| 905 | − struct skl *skl = bus_to_skl(bus); | |
| 908 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 906 | 909 | struct pci_dev *pci = skl->pci; |
| 907 | 910 | int err; |
| 908 | 911 | unsigned short gcap; |
| @@ -978,7 +981,7 @@ static int skl_first_init(struct hdac_bus *bus) · 69 unmodified lines | ||
| 978 | 981 | static int skl_probe(struct pci_dev *pci, |
| 979 | 982 | const struct pci_device_id *pci_id) |
| 980 | 983 | { |
| 981 | − struct skl *skl; | |
| 984 | + struct skl_dev *skl; | |
| 982 | 985 | struct hdac_bus *bus = NULL; |
| 983 | 986 | int err; |
| 984 | 987 | |
| @@ -1013,7 +1016,7 @@ static int skl_probe(struct pci_dev *pci, · 28 unmodified lines | ||
| 1013 | 1016 | } |
| 1014 | 1017 | |
| 1015 | 1018 | /* we use ext core ops, so provide NULL for ops here */ |
| 1016 | − err = skl_create(pci, NULL, &skl); | |
| 1019 | + err = skl_create(pci, &skl); | |
| 1017 | 1020 | if (err < 0) |
| 1018 | 1021 | return err; |
| 1019 | 1022 | |
| @@ -1029,7 +1032,7 @@ static int skl_probe(struct pci_dev *pci, · 9 unmodified lines | ||
| 1029 | 1032 | |
| 1030 | 1033 | device_disable_async_suspend(bus->dev); |
| 1031 | 1034 | |
| 1032 | − skl->nhlt = skl_nhlt_init(bus->dev); | |
| 1035 | + skl->nhlt = intel_nhlt_init(bus->dev); | |
| 1033 | 1036 | |
| 1034 | 1037 | if (skl->nhlt == NULL) { |
| 1035 | 1038 | #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| @@ -1071,8 +1074,8 @@ static int skl_probe(struct pci_dev *pci, · 35 unmodified lines | ||
| 1071 | 1074 | dev_dbg(bus->dev, "error failed to register dsp\n"); |
| 1072 | 1075 | goto out_nhlt_free; |
| 1073 | 1076 | } |
| 1074 | − skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; | |
| 1075 | − skl->skl_sst->clock_power_gating = skl_clock_power_gating; | |
| 1077 | + skl->enable_miscbdcge = skl_enable_miscbdcge; | |
| 1078 | + skl->clock_power_gating = skl_clock_power_gating; | |
| 1076 | 1079 | |
| 1077 | 1080 | if (bus->mlcap) |
| 1078 | 1081 | snd_hdac_ext_bus_get_ml_capabilities(bus); |
| @@ -1095,7 +1098,7 @@ out_dsp_free: · 16 unmodified lines | ||
| 1095 | 1098 | out_clk_free: |
| 1096 | 1099 | skl_clock_device_unregister(skl); |
| 1097 | 1100 | out_nhlt_free: |
| 1098 | − skl_nhlt_free(skl->nhlt); | |
| 1101 | + intel_nhlt_free(skl->nhlt); | |
| 1099 | 1102 | out_free: |
| 1100 | 1103 | skl_free(bus); |
| 1101 | 1104 | |
| @@ -1107,7 +1110,7 @@ static void skl_shutdown(struct pci_dev *pci) · 5 unmodified lines | ||
| 1107 | 1110 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 1108 | 1111 | struct hdac_stream *s; |
| 1109 | 1112 | struct hdac_ext_stream *stream; |
| 1110 | − struct skl *skl; | |
| 1113 | + struct skl_dev *skl; | |
| 1111 | 1114 | |
| 1112 | 1115 | if (!bus) |
| 1113 | 1116 | return; |
| @@ -1129,7 +1132,7 @@ static void skl_shutdown(struct pci_dev *pci) · 15 unmodified lines | ||
| 1129 | 1132 | static void skl_remove(struct pci_dev *pci) |
| 1130 | 1133 | { |
| 1131 | 1134 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 1132 | − struct skl *skl = bus_to_skl(bus); | |
| 1135 | + struct skl_dev *skl = bus_to_skl(bus); | |
| 1133 | 1136 | |
| 1134 | 1137 | cancel_work_sync(&skl->probe_work); |
| 1135 | 1138 | |
| @@ -1144,7 +1147,7 @@ static void skl_remove(struct pci_dev *pci) · 8 unmodified lines | ||
| 1144 | 1147 | skl_dmic_device_unregister(skl); |
| 1145 | 1148 | skl_clock_device_unregister(skl); |
| 1146 | 1149 | skl_nhlt_remove_sysfs(skl); |
| 1147 | − skl_nhlt_free(skl->nhlt); | |
| 1150 | + intel_nhlt_free(skl->nhlt); | |
| 1148 | 1151 | skl_free(bus); |
| 1149 | 1152 | dev_set_drvdata(&pci->dev, NULL); |
| 1150 | 1153 | } |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <sound/hdaudio_ext.h> |
| 17 | 17 | #include <sound/hda_codec.h> |
| 18 | 18 | #include <sound/soc.h> |
| 19 | −#include "skl-nhlt.h" | |
| 20 | 19 | #include "skl-ssp-clk.h" |
| 20 | +#include "skl-sst-ipc.h" | |
| 21 | 21 | |
| 22 | 22 | #define SKL_SUSPEND_DELAY 2000 |
| 23 | 23 | |
| @@ -40,13 +40,6 @@ · 16 unmodified lines | ||
| 40 | 40 | #define AZX_VS_EM2_DUM BIT(23) |
| 41 | 41 | #define AZX_REG_VS_EM2_L1SEN BIT(13) |
| 42 | 42 | |
| 43 | −struct skl_dsp_resource { | |
| 44 | − u32 max_mcps; | |
| 45 | − u32 max_mem; | |
| 46 | − u32 mcps; | |
| 47 | − u32 mem; | |
| 48 | −}; | |
| 49 | − | |
| 50 | 43 | struct skl_debug; |
| 51 | 44 | |
| 52 | 45 | struct skl_astate_param { |
| @@ -63,7 +56,7 @@ struct skl_fw_config { · 10 unmodified lines | ||
| 63 | 56 | struct skl_astate_config *astate_cfg; |
| 64 | 57 | }; |
| 65 | 58 | |
| 66 | −struct skl { | |
| 59 | +struct skl_dev { | |
| 67 | 60 | struct hda_bus hbus; |
| 68 | 61 | struct pci_dev *pci; |
| 69 | 62 | |
| @@ -75,16 +68,13 @@ struct skl { · 5 unmodified lines | ||
| 75 | 68 | struct snd_soc_dai_driver *dais; |
| 76 | 69 | |
| 77 | 70 | struct nhlt_acpi_table *nhlt; /* nhlt ptr */ |
| 78 | − struct skl_sst *skl_sst; /* sst skl ctx */ | |
| 79 | 71 | |
| 80 | − struct skl_dsp_resource resource; | |
| 81 | 72 | struct list_head ppl_list; |
| 82 | 73 | struct list_head bind_list; |
| 83 | 74 | |
| 84 | 75 | const char *fw_name; |
| 85 | 76 | char tplg_name[64]; |
| 86 | 77 | unsigned short pci_id; |
| 87 | − const struct firmware *tplg; | |
| 88 | 78 | |
| 89 | 79 | int supend_active; |
| 90 | 80 | |
| @@ -96,13 +86,59 @@ struct skl { · 5 unmodified lines | ||
| 96 | 86 | bool use_tplg_pcm; |
| 97 | 87 | struct skl_fw_config cfg; |
| 98 | 88 | struct snd_soc_acpi_mach *mach; |
| 89 | + | |
| 90 | + struct device *dev; | |
| 91 | + struct sst_dsp *dsp; | |
| 92 | + | |
| 93 | + /* boot */ | |
| 94 | + wait_queue_head_t boot_wait; | |
| 95 | + bool boot_complete; | |
| 96 | + | |
| 97 | + /* module load */ | |
| 98 | + wait_queue_head_t mod_load_wait; | |
| 99 | + bool mod_load_complete; | |
| 100 | + bool mod_load_status; | |
| 101 | + | |
| 102 | + /* IPC messaging */ | |
| 103 | + struct sst_generic_ipc ipc; | |
| 104 | + | |
| 105 | + /* callback for miscbdge */ | |
| 106 | + void (*enable_miscbdcge)(struct device *dev, bool enable); | |
| 107 | + /* Is CGCTL.MISCBDCGE disabled */ | |
| 108 | + bool miscbdcg_disabled; | |
| 109 | + | |
| 110 | + /* Populate module information */ | |
| 111 | + struct list_head uuid_list; | |
| 112 | + | |
| 113 | + /* Is firmware loaded */ | |
| 114 | + bool fw_loaded; | |
| 115 | + | |
| 116 | + /* first boot ? */ | |
| 117 | + bool is_first_boot; | |
| 118 | + | |
| 119 | + /* multi-core */ | |
| 120 | + struct skl_dsp_cores cores; | |
| 121 | + | |
| 122 | + /* library info */ | |
| 123 | + struct skl_lib_info lib_info[SKL_MAX_LIB]; | |
| 124 | + int lib_count; | |
| 125 | + | |
| 126 | + /* Callback to update D0i3C register */ | |
| 127 | + void (*update_d0i3c)(struct device *dev, bool enable); | |
| 128 | + | |
| 129 | + struct skl_d0i3_data d0i3; | |
| 130 | + | |
| 131 | + const struct skl_dsp_ops *dsp_ops; | |
| 132 | + | |
| 133 | + /* Callback to update dynamic clock and power gating registers */ | |
| 134 | + void (*clock_power_gating)(struct device *dev, bool enable); | |
| 99 | 135 | }; |
| 100 | 136 | |
| 101 | 137 | #define skl_to_bus(s) (&(s)->hbus.core) |
| 102 | −#define bus_to_skl(bus) container_of(bus, struct skl, hbus.core) | |
| 138 | +#define bus_to_skl(bus) container_of(bus, struct skl_dev, hbus.core) | |
| 103 | 139 | |
| 104 | 140 | #define skl_to_hbus(s) (&(s)->hbus) |
| 105 | −#define hbus_to_skl(hbus) container_of((hbus), struct skl, (hbus)) | |
| 141 | +#define hbus_to_skl(hbus) container_of((hbus), struct skl_dev, (hbus)) | |
| 106 | 142 | |
| 107 | 143 | /* to pass dai dma data */ |
| 108 | 144 | struct skl_dma_params { |
| @@ -121,52 +157,49 @@ struct skl_dsp_ops { · 12 unmodified lines | ||
| 121 | 157 | int (*init)(struct device *dev, void __iomem *mmio_base, |
| 122 | 158 | int irq, const char *fw_name, |
| 123 | 159 | struct skl_dsp_loader_ops loader_ops, |
| 124 | − struct skl_sst **skl_sst); | |
| 125 | − int (*init_fw)(struct device *dev, struct skl_sst *ctx); | |
| 126 | − void (*cleanup)(struct device *dev, struct skl_sst *ctx); | |
| 160 | + struct skl_dev **skl_sst); | |
| 161 | + int (*init_fw)(struct device *dev, struct skl_dev *skl); | |
| 162 | + void (*cleanup)(struct device *dev, struct skl_dev *skl); | |
| 127 | 163 | }; |
| 128 | 164 | |
| 129 | 165 | int skl_platform_unregister(struct device *dev); |
| 130 | 166 | int skl_platform_register(struct device *dev); |
| 131 | 167 | |
| 132 | −struct nhlt_acpi_table *skl_nhlt_init(struct device *dev); | |
| 133 | −void skl_nhlt_free(struct nhlt_acpi_table *addr); | |
| 134 | −struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, | |
| 168 | +struct nhlt_specific_cfg *skl_get_ep_blob(struct skl_dev *skl, u32 instance, | |
| 135 | 169 | u8 link_type, u8 s_fmt, u8 no_ch, |
| 136 | 170 | u32 s_rate, u8 dirn, u8 dev_type); |
| 137 | 171 | |
| 138 | −int skl_get_dmic_geo(struct skl *skl); | |
| 139 | −int skl_nhlt_update_topology_bin(struct skl *skl); | |
| 140 | −int skl_init_dsp(struct skl *skl); | |
| 141 | −int skl_free_dsp(struct skl *skl); | |
| 142 | −int skl_suspend_late_dsp(struct skl *skl); | |
| 143 | −int skl_suspend_dsp(struct skl *skl); | |
| 144 | −int skl_resume_dsp(struct skl *skl); | |
| 145 | −void skl_cleanup_resources(struct skl *skl); | |
| 172 | +int skl_nhlt_update_topology_bin(struct skl_dev *skl); | |
| 173 | +int skl_init_dsp(struct skl_dev *skl); | |
| 174 | +int skl_free_dsp(struct skl_dev *skl); | |
| 175 | +int skl_suspend_late_dsp(struct skl_dev *skl); | |
| 176 | +int skl_suspend_dsp(struct skl_dev *skl); | |
| 177 | +int skl_resume_dsp(struct skl_dev *skl); | |
| 178 | +void skl_cleanup_resources(struct skl_dev *skl); | |
| 146 | 179 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); |
| 147 | 180 | void skl_update_d0i3c(struct device *dev, bool enable); |
| 148 | −int skl_nhlt_create_sysfs(struct skl *skl); | |
| 149 | −void skl_nhlt_remove_sysfs(struct skl *skl); | |
| 150 | −void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks); | |
| 181 | +int skl_nhlt_create_sysfs(struct skl_dev *skl); | |
| 182 | +void skl_nhlt_remove_sysfs(struct skl_dev *skl); | |
| 183 | +void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks); | |
| 151 | 184 | struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id); |
| 152 | −int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, | |
| 185 | +int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps, | |
| 153 | 186 | u32 caps_size, u32 node_id); |
| 154 | 187 | |
| 155 | 188 | struct skl_module_cfg; |
| 156 | 189 | |
| 157 | 190 | #ifdef CONFIG_DEBUG_FS |
| 158 | −struct skl_debug *skl_debugfs_init(struct skl *skl); | |
| 159 | −void skl_debugfs_exit(struct skl *skl); | |
| 191 | +struct skl_debug *skl_debugfs_init(struct skl_dev *skl); | |
| 192 | +void skl_debugfs_exit(struct skl_dev *skl); | |
| 160 | 193 | void skl_debug_init_module(struct skl_debug *d, |
| 161 | 194 | struct snd_soc_dapm_widget *w, |
| 162 | 195 | struct skl_module_cfg *mconfig); |
| 163 | 196 | #else |
| 164 | −static inline struct skl_debug *skl_debugfs_init(struct skl *skl) | |
| 197 | +static inline struct skl_debug *skl_debugfs_init(struct skl_dev *skl) | |
| 165 | 198 | { |
| 166 | 199 | return NULL; |
| 167 | 200 | } |
| 168 | 201 | |
| 169 | −static inline void skl_debugfs_exit(struct skl *skl) | |
| 202 | +static inline void skl_debugfs_exit(struct skl_dev *skl) | |
| 170 | 203 | {} |
| 171 | 204 | |
| 172 | 205 | static inline void skl_debug_init_module(struct skl_debug *d, |
| @@ -523,7 +523,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) · 522 unmodified lines | ||
| 523 | 523 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
| 524 | 524 | struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; |
| 525 | 525 | struct kirkwood_dma_data *priv; |
| 526 | − struct resource *mem; | |
| 527 | 526 | struct device_node *np = pdev->dev.of_node; |
| 528 | 527 | int err; |
| 529 | 528 | |
| @@ -533,16 +532,13 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 533 | 532 | |
| 534 | 533 | dev_set_drvdata(&pdev->dev, priv); |
| 535 | 534 | |
| 536 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 537 | − priv->io = devm_ioremap_resource(&pdev->dev, mem); | |
| 535 | + priv->io = devm_platform_ioremap_resource(pdev, 0); | |
| 538 | 536 | if (IS_ERR(priv->io)) |
| 539 | 537 | return PTR_ERR(priv->io); |
| 540 | 538 | |
| 541 | 539 | priv->irq = platform_get_irq(pdev, 0); |
| 542 | − if (priv->irq < 0) { | |
| 543 | − dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); | |
| 540 | + if (priv->irq < 0) | |
| 544 | 541 | return priv->irq; |
| 545 | − } | |
| 546 | 542 | |
| 547 | 543 | if (np) { |
| 548 | 544 | priv->burst = 128; /* might be 32 or 128 */ |
| @@ -1335,10 +1335,8 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev) · 1334 unmodified lines | ||
| 1335 | 1335 | |
| 1336 | 1336 | /* irq */ |
| 1337 | 1337 | irq_id = platform_get_irq(pdev, 0); |
| 1338 | − if (irq_id <= 0) { | |
| 1339 | − dev_err(dev, "%pOFn no irq found\n", dev->of_node); | |
| 1338 | + if (irq_id <= 0) | |
| 1340 | 1339 | return irq_id < 0 ? irq_id : -ENXIO; |
| 1341 | − } | |
| 1342 | 1340 | |
| 1343 | 1341 | ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler, |
| 1344 | 1342 | IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle", |
| @@ -63,27 +63,6 @@ enum audio_base_clock { · 62 unmodified lines | ||
| 63 | 63 | MT2701_BASE_CLK_NUM, |
| 64 | 64 | }; |
| 65 | 65 | |
| 66 | −static const unsigned int mt2701_afe_backup_list[] = { | |
| 67 | − AUDIO_TOP_CON0, | |
| 68 | − AUDIO_TOP_CON4, | |
| 69 | − AUDIO_TOP_CON5, | |
| 70 | − ASYS_TOP_CON, | |
| 71 | − AFE_CONN0, | |
| 72 | − AFE_CONN1, | |
| 73 | − AFE_CONN2, | |
| 74 | − AFE_CONN3, | |
| 75 | − AFE_CONN15, | |
| 76 | − AFE_CONN16, | |
| 77 | − AFE_CONN17, | |
| 78 | − AFE_CONN18, | |
| 79 | − AFE_CONN19, | |
| 80 | − AFE_CONN20, | |
| 81 | − AFE_CONN21, | |
| 82 | − AFE_CONN22, | |
| 83 | − AFE_DAC_CON0, | |
| 84 | − AFE_MEMIF_PBUF_SIZE, | |
| 85 | −}; | |
| 86 | − | |
| 87 | 66 | struct mt2701_i2s_data { |
| 88 | 67 | int i2s_ctrl_reg; |
| 89 | 68 | int i2s_asrc_fs_shift; |
| @@ -60,6 +60,27 @@ static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = { · 59 unmodified lines | ||
| 60 | 60 | { .rate = 352800, .regvalue = 24 }, |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | +static const unsigned int mt2701_afe_backup_list[] = { | |
| 64 | + AUDIO_TOP_CON0, | |
| 65 | + AUDIO_TOP_CON4, | |
| 66 | + AUDIO_TOP_CON5, | |
| 67 | + ASYS_TOP_CON, | |
| 68 | + AFE_CONN0, | |
| 69 | + AFE_CONN1, | |
| 70 | + AFE_CONN2, | |
| 71 | + AFE_CONN3, | |
| 72 | + AFE_CONN15, | |
| 73 | + AFE_CONN16, | |
| 74 | + AFE_CONN17, | |
| 75 | + AFE_CONN18, | |
| 76 | + AFE_CONN19, | |
| 77 | + AFE_CONN20, | |
| 78 | + AFE_CONN21, | |
| 79 | + AFE_CONN22, | |
| 80 | + AFE_DAC_CON0, | |
| 81 | + AFE_MEMIF_PBUF_SIZE, | |
| 82 | +}; | |
| 83 | + | |
| 63 | 84 | static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) |
| 64 | 85 | { |
| 65 | 86 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
| @@ -796,14 +817,6 @@ static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = { · 730 unmodified lines | ||
| 796 | 817 | SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), |
| 797 | 818 | }; |
| 798 | 819 | |
| 799 | −static const struct snd_kcontrol_new mt2701_afe_o23_mix[] = { | |
| 800 | − SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0), | |
| 801 | −}; | |
| 802 | − | |
| 803 | −static const struct snd_kcontrol_new mt2701_afe_o24_mix[] = { | |
| 804 | − SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0), | |
| 805 | −}; | |
| 806 | − | |
| 807 | 820 | static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { |
| 808 | 821 | SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0), |
| 809 | 822 | }; |
| @@ -832,11 +845,6 @@ static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = { · 22 unmodified lines | ||
| 832 | 845 | PWR2_TOP_CON, 18, 1, 0), |
| 833 | 846 | }; |
| 834 | 847 | |
| 835 | −static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = { | |
| 836 | − SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S4 Out Switch", | |
| 837 | − PWR2_TOP_CON, 19, 1, 0), | |
| 838 | −}; | |
| 839 | − | |
| 840 | 848 | static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { |
| 841 | 849 | /* inter-connections */ |
| 842 | 850 | SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), |
| @@ -1342,10 +1350,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) · 499 unmodified lines | ||
| 1342 | 1350 | return -ENOMEM; |
| 1343 | 1351 | |
| 1344 | 1352 | irq_id = platform_get_irq_byname(pdev, "asys"); |
| 1345 | − if (irq_id < 0) { | |
| 1346 | − dev_err(dev, "unable to get ASYS IRQ\n"); | |
| 1353 | + if (irq_id < 0) | |
| 1347 | 1354 | return irq_id; |
| 1348 | − } | |
| 1349 | 1355 | |
| 1350 | 1356 | ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, |
| 1351 | 1357 | IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); |
| @@ -749,7 +749,6 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev) · 748 unmodified lines | ||
| 749 | 749 | { |
| 750 | 750 | struct mtk_base_afe *afe; |
| 751 | 751 | struct mt6797_afe_private *afe_priv; |
| 752 | − struct resource *res; | |
| 753 | 752 | struct device *dev; |
| 754 | 753 | int i, irq_id, ret; |
| 755 | 754 | |
| @@ -774,9 +773,7 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev) · 18 unmodified lines | ||
| 774 | 773 | } |
| 775 | 774 | |
| 776 | 775 | /* regmap init */ |
| 777 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 778 | − | |
| 779 | − afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | |
| 776 | + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); | |
| 780 | 777 | if (IS_ERR(afe->base_addr)) |
| 781 | 778 | return PTR_ERR(afe->base_addr); |
| 782 | 779 | |
| @@ -1056,7 +1056,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) · 1055 unmodified lines | ||
| 1056 | 1056 | int irq_id; |
| 1057 | 1057 | struct mtk_base_afe *afe; |
| 1058 | 1058 | struct mt8173_afe_private *afe_priv; |
| 1059 | − struct resource *res; | |
| 1060 | 1059 | |
| 1061 | 1060 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); |
| 1062 | 1061 | if (ret) |
| @@ -1075,10 +1074,8 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 1075 | 1074 | afe->dev = &pdev->dev; |
| 1076 | 1075 | |
| 1077 | 1076 | irq_id = platform_get_irq(pdev, 0); |
| 1078 | − if (irq_id <= 0) { | |
| 1079 | − dev_err(afe->dev, "np %pOFn no irq\n", afe->dev->of_node); | |
| 1077 | + if (irq_id <= 0) | |
| 1080 | 1078 | return irq_id < 0 ? irq_id : -ENXIO; |
| 1081 | − } | |
| 1082 | 1079 | ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, |
| 1083 | 1080 | 0, "Afe_ISR_Handle", (void *)afe); |
| 1084 | 1081 | if (ret) { |
| @@ -1086,8 +1083,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1086 | 1083 | return ret; |
| 1087 | 1084 | } |
| 1088 | 1085 | |
| 1089 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1090 | − afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | |
| 1086 | + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); | |
| 1091 | 1087 | if (IS_ERR(afe->base_addr)) |
| 1092 | 1088 | return PTR_ERR(afe->base_addr); |
| 1093 | 1089 | |
| @@ -116,15 +116,6 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, · 115 unmodified lines | ||
| 116 | 116 | return 0; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | −static const struct snd_soc_dapm_widget | |
| 120 | −mt8183_da7219_max98357_dapm_widgets[] = { | |
| 121 | − SND_SOC_DAPM_OUTPUT("IT6505_8CH"), | |
| 122 | −}; | |
| 123 | − | |
| 124 | −static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { | |
| 125 | − {"IT6505_8CH", NULL, "TDM"}, | |
| 126 | −}; | |
| 127 | − | |
| 128 | 119 | /* FE */ |
| 129 | 120 | SND_SOC_DAILINK_DEFS(playback1, |
| 130 | 121 | DAILINK_COMP_ARRAY(COMP_CPU("DL1")), |
| @@ -370,7 +361,7 @@ static int · 239 unmodified lines | ||
| 370 | 361 | mt8183_da7219_max98357_headset_init(struct snd_soc_component *component); |
| 371 | 362 | |
| 372 | 363 | static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { |
| 373 | − .name = "Headset Chip", | |
| 364 | + .dlc = COMP_EMPTY(), | |
| 374 | 365 | .init = mt8183_da7219_max98357_headset_init, |
| 375 | 366 | }; |
| 376 | 367 | |
| @@ -436,10 +427,10 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 436 | 427 | dai_link->platforms->of_node = platform_node; |
| 437 | 428 | } |
| 438 | 429 | |
| 439 | − mt8183_da7219_max98357_headset_dev.codec_of_node = | |
| 430 | + mt8183_da7219_max98357_headset_dev.dlc.of_node = | |
| 440 | 431 | of_parse_phandle(pdev->dev.of_node, |
| 441 | 432 | "mediatek,headset-codec", 0); |
| 442 | − if (!mt8183_da7219_max98357_headset_dev.codec_of_node) { | |
| 433 | + if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { | |
| 443 | 434 | dev_err(&pdev->dev, |
| 444 | 435 | "Property 'mediatek,headset-codec' missing/invalid\n"); |
| 445 | 436 | return -EINVAL; |
| @@ -15,13 +15,30 @@ · 14 unmodified lines | ||
| 15 | 15 | struct mtk_afe_tdm_priv { |
| 16 | 16 | int bck_id; |
| 17 | 17 | int bck_rate; |
| 18 | − | |
| 18 | + int tdm_out_mode; | |
| 19 | + int bck_invert; | |
| 20 | + int lck_invert; | |
| 19 | 21 | int mclk_id; |
| 20 | 22 | int mclk_multiple; /* according to sample rate */ |
| 21 | 23 | int mclk_rate; |
| 22 | 24 | int mclk_apll; |
| 23 | 25 | }; |
| 24 | 26 | |
| 27 | +enum { | |
| 28 | + TDM_OUT_I2S = 0, | |
| 29 | + TDM_OUT_TDM = 1, | |
| 30 | +}; | |
| 31 | + | |
| 32 | +enum { | |
| 33 | + TDM_BCK_NON_INV = 0, | |
| 34 | + TDM_BCK_INV = 1, | |
| 35 | +}; | |
| 36 | + | |
| 37 | +enum { | |
| 38 | + TDM_LCK_NON_INV = 0, | |
| 39 | + TDM_LCK_INV = 1, | |
| 40 | +}; | |
| 41 | + | |
| 25 | 42 | enum { |
| 26 | 43 | TDM_WLEN_16_BIT = 1, |
| 27 | 44 | TDM_WLEN_32_BIT = 2, |
| @@ -93,6 +110,25 @@ static unsigned int get_tdm_ch(unsigned int ch) · 65 unmodified lines | ||
| 93 | 110 | } |
| 94 | 111 | } |
| 95 | 112 | |
| 113 | +static unsigned int get_tdm_ch_fixup(unsigned int channels) | |
| 114 | +{ | |
| 115 | + if (channels > 4) | |
| 116 | + return 8; | |
| 117 | + else if (channels > 2) | |
| 118 | + return 4; | |
| 119 | + else | |
| 120 | + return 2; | |
| 121 | +} | |
| 122 | + | |
| 123 | +static unsigned int get_tdm_ch_per_sdata(unsigned int mode, | |
| 124 | + unsigned int channels) | |
| 125 | +{ | |
| 126 | + if (mode == TDM_OUT_TDM) | |
| 127 | + return get_tdm_ch_fixup(channels); | |
| 128 | + else | |
| 129 | + return 2; | |
| 130 | +} | |
| 131 | + | |
| 96 | 132 | /* interconnection */ |
| 97 | 133 | enum { |
| 98 | 134 | HDMI_CONN_CH0 = 0, |
| @@ -433,8 +469,11 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, · 334 unmodified lines | ||
| 433 | 469 | struct mt8183_afe_private *afe_priv = afe->platform_priv; |
| 434 | 470 | int tdm_id = dai->id; |
| 435 | 471 | struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; |
| 472 | + unsigned int tdm_out_mode = tdm_priv->tdm_out_mode; | |
| 436 | 473 | unsigned int rate = params_rate(params); |
| 437 | 474 | unsigned int channels = params_channels(params); |
| 475 | + unsigned int out_channels_per_sdata = | |
| 476 | + get_tdm_ch_per_sdata(tdm_out_mode, channels); | |
| 438 | 477 | snd_pcm_format_t format = params_format(params); |
| 439 | 478 | unsigned int tdm_con = 0; |
| 440 | 479 | |
| @@ -448,7 +487,7 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, · 7 unmodified lines | ||
| 448 | 487 | |
| 449 | 488 | /* calculate bck */ |
| 450 | 489 | tdm_priv->bck_rate = rate * |
| 451 | − channels * | |
| 490 | + out_channels_per_sdata * | |
| 452 | 491 | snd_pcm_format_physical_width(format); |
| 453 | 492 | |
| 454 | 493 | if (tdm_priv->bck_rate > tdm_priv->mclk_rate) |
| @@ -461,50 +500,72 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 461 | 500 | __func__, |
| 462 | 501 | tdm_id, rate, channels, format, |
| 463 | 502 | tdm_priv->mclk_rate, tdm_priv->bck_rate); |
| 503 | + dev_info(afe->dev, "%s(), out_channels_per_sdata = %d\n", | |
| 504 | + __func__, out_channels_per_sdata); | |
| 464 | 505 | |
| 465 | 506 | /* set tdm */ |
| 466 | − tdm_con = 1 << BCK_INVERSE_SFT; | |
| 467 | − tdm_con |= 1 << LRCK_INVERSE_SFT; | |
| 468 | − tdm_con |= 1 << DELAY_DATA_SFT; | |
| 507 | + if (tdm_priv->bck_invert) | |
| 508 | + regmap_update_bits(afe->regmap, AUDIO_TOP_CON3, | |
| 509 | + BCK_INVERSE_MASK_SFT, | |
| 510 | + 0x1 << BCK_INVERSE_SFT); | |
| 511 | + | |
| 512 | + if (tdm_priv->lck_invert) | |
| 513 | + tdm_con |= 1 << LRCK_INVERSE_SFT; | |
| 514 | + | |
| 515 | + if (tdm_priv->tdm_out_mode == TDM_OUT_I2S) { | |
| 516 | + tdm_con |= 1 << DELAY_DATA_SFT; | |
| 517 | + tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT; | |
| 518 | + } else if (tdm_priv->tdm_out_mode == TDM_OUT_TDM) { | |
| 519 | + tdm_con |= 0 << DELAY_DATA_SFT; | |
| 520 | + tdm_con |= 0 << LRCK_TDM_WIDTH_SFT; | |
| 521 | + } | |
| 522 | + | |
| 469 | 523 | tdm_con |= 1 << LEFT_ALIGN_SFT; |
| 470 | 524 | tdm_con |= get_tdm_wlen(format) << WLEN_SFT; |
| 471 | − tdm_con |= get_tdm_ch(channels) << CHANNEL_NUM_SFT; | |
| 525 | + tdm_con |= get_tdm_ch(out_channels_per_sdata) << CHANNEL_NUM_SFT; | |
| 472 | 526 | tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT; |
| 473 | − tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT; | |
| 474 | 527 | regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); |
| 475 | 528 | |
| 476 | − switch (channels) { | |
| 477 | − case 1: | |
| 478 | − case 2: | |
| 529 | + if (out_channels_per_sdata == 2) { | |
| 530 | + switch (channels) { | |
| 531 | + case 1: | |
| 532 | + case 2: | |
| 533 | + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 534 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; | |
| 535 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; | |
| 536 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | |
| 537 | + break; | |
| 538 | + case 3: | |
| 539 | + case 4: | |
| 540 | + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 541 | + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 542 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; | |
| 543 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | |
| 544 | + break; | |
| 545 | + case 5: | |
| 546 | + case 6: | |
| 547 | + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 548 | + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 549 | + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; | |
| 550 | + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | |
| 551 | + break; | |
| 552 | + case 7: | |
| 553 | + case 8: | |
| 554 | + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 555 | + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 556 | + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; | |
| 557 | + tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT; | |
| 558 | + break; | |
| 559 | + default: | |
| 560 | + tdm_con = 0; | |
| 561 | + } | |
| 562 | + } else { | |
| 479 | 563 | tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; |
| 480 | 564 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; |
| 481 | 565 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; |
| 482 | 566 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; |
| 483 | − break; | |
| 484 | − case 3: | |
| 485 | − case 4: | |
| 486 | − tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 487 | − tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 488 | − tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; | |
| 489 | − tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | |
| 490 | − break; | |
| 491 | − case 5: | |
| 492 | − case 6: | |
| 493 | − tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 494 | − tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 495 | − tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; | |
| 496 | − tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | |
| 497 | − break; | |
| 498 | − case 7: | |
| 499 | − case 8: | |
| 500 | − tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | |
| 501 | − tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; | |
| 502 | − tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; | |
| 503 | − tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT; | |
| 504 | − break; | |
| 505 | − default: | |
| 506 | − tdm_con = 0; | |
| 507 | 567 | } |
| 568 | + | |
| 508 | 569 | regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); |
| 509 | 570 | |
| 510 | 571 | regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, |
| @@ -573,10 +634,58 @@ static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai, · 62 unmodified lines | ||
| 573 | 634 | return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); |
| 574 | 635 | } |
| 575 | 636 | |
| 637 | +static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |
| 638 | +{ | |
| 639 | + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); | |
| 640 | + struct mt8183_afe_private *afe_priv = afe->platform_priv; | |
| 641 | + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; | |
| 642 | + | |
| 643 | + if (!tdm_priv) { | |
| 644 | + dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__); | |
| 645 | + return -EINVAL; | |
| 646 | + } | |
| 647 | + | |
| 648 | + /* DAI mode*/ | |
| 649 | + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | |
| 650 | + case SND_SOC_DAIFMT_I2S: | |
| 651 | + tdm_priv->tdm_out_mode = TDM_OUT_I2S; | |
| 652 | + break; | |
| 653 | + case SND_SOC_DAIFMT_DSP_A: | |
| 654 | + tdm_priv->tdm_out_mode = TDM_OUT_TDM; | |
| 655 | + break; | |
| 656 | + default: | |
| 657 | + tdm_priv->tdm_out_mode = TDM_OUT_I2S; | |
| 658 | + } | |
| 659 | + | |
| 660 | + /* DAI clock inversion*/ | |
| 661 | + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | |
| 662 | + case SND_SOC_DAIFMT_NB_NF: | |
| 663 | + tdm_priv->bck_invert = TDM_BCK_NON_INV; | |
| 664 | + tdm_priv->lck_invert = TDM_LCK_NON_INV; | |
| 665 | + break; | |
| 666 | + case SND_SOC_DAIFMT_NB_IF: | |
| 667 | + tdm_priv->bck_invert = TDM_BCK_NON_INV; | |
| 668 | + tdm_priv->lck_invert = TDM_LCK_INV; | |
| 669 | + break; | |
| 670 | + case SND_SOC_DAIFMT_IB_NF: | |
| 671 | + tdm_priv->bck_invert = TDM_BCK_INV; | |
| 672 | + tdm_priv->lck_invert = TDM_LCK_NON_INV; | |
| 673 | + break; | |
| 674 | + case SND_SOC_DAIFMT_IB_IF: | |
| 675 | + default: | |
| 676 | + tdm_priv->bck_invert = TDM_BCK_INV; | |
| 677 | + tdm_priv->lck_invert = TDM_LCK_INV; | |
| 678 | + break; | |
| 679 | + } | |
| 680 | + | |
| 681 | + return 0; | |
| 682 | +} | |
| 683 | + | |
| 576 | 684 | static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { |
| 577 | 685 | .hw_params = mtk_dai_tdm_hw_params, |
| 578 | 686 | .trigger = mtk_dai_tdm_trigger, |
| 579 | 687 | .set_sysclk = mtk_dai_tdm_set_sysclk, |
| 688 | + .set_fmt = mtk_dai_tdm_set_fmt, | |
| 580 | 689 | }; |
| 581 | 690 | |
| 582 | 691 | /* dai driver */ |
| @@ -15,7 +15,22 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "mt8183-afe-common.h" |
| 16 | 16 | #include "../../codecs/ts3a227e.h" |
| 17 | 17 | |
| 18 | −static struct snd_soc_jack headset_jack; | |
| 18 | +enum PINCTRL_PIN_STATE { | |
| 19 | + PIN_STATE_DEFAULT = 0, | |
| 20 | + PIN_TDM_OUT_ON, | |
| 21 | + PIN_TDM_OUT_OFF, | |
| 22 | + PIN_STATE_MAX | |
| 23 | +}; | |
| 24 | + | |
| 25 | +static const char * const mt8183_pin_str[PIN_STATE_MAX] = { | |
| 26 | + "default", "aud_tdm_out_on", "aud_tdm_out_off", | |
| 27 | +}; | |
| 28 | + | |
| 29 | +struct mt8183_mt6358_ts3a227_max98357_priv { | |
| 30 | + struct pinctrl *pinctrl; | |
| 31 | + struct pinctrl_state *pin_states[PIN_STATE_MAX]; | |
| 32 | + struct snd_soc_jack headset_jack; | |
| 33 | +}; | |
| 19 | 34 | |
| 20 | 35 | static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, |
| 21 | 36 | struct snd_pcm_hw_params *params) |
| @@ -46,16 +61,6 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, · 24 unmodified lines | ||
| 46 | 61 | return 0; |
| 47 | 62 | } |
| 48 | 63 | |
| 49 | −static const struct snd_soc_dapm_widget | |
| 50 | −mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = { | |
| 51 | − SND_SOC_DAPM_OUTPUT("IT6505_8CH"), | |
| 52 | −}; | |
| 53 | − | |
| 54 | −static const struct snd_soc_dapm_route | |
| 55 | −mt8183_mt6358_ts3a227_max98357_dapm_routes[] = { | |
| 56 | − {"IT6505_8CH", NULL, "TDM"}, | |
| 57 | −}; | |
| 58 | − | |
| 59 | 64 | static int |
| 60 | 65 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( |
| 61 | 66 | struct snd_pcm_substream *substream) |
| @@ -183,6 +188,47 @@ SND_SOC_DAILINK_DEFS(tdm, · 121 unmodified lines | ||
| 183 | 188 | DAILINK_COMP_ARRAY(COMP_DUMMY()), |
| 184 | 189 | DAILINK_COMP_ARRAY(COMP_EMPTY())); |
| 185 | 190 | |
| 191 | +static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream) | |
| 192 | +{ | |
| 193 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 194 | + struct mt8183_mt6358_ts3a227_max98357_priv *priv = | |
| 195 | + snd_soc_card_get_drvdata(rtd->card); | |
| 196 | + int ret; | |
| 197 | + | |
| 198 | + if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON])) | |
| 199 | + return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]); | |
| 200 | + | |
| 201 | + ret = pinctrl_select_state(priv->pinctrl, | |
| 202 | + priv->pin_states[PIN_TDM_OUT_ON]); | |
| 203 | + if (ret) | |
| 204 | + dev_err(rtd->card->dev, "%s failed to select state %d\n", | |
| 205 | + __func__, ret); | |
| 206 | + | |
| 207 | + return ret; | |
| 208 | +} | |
| 209 | + | |
| 210 | +static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream) | |
| 211 | +{ | |
| 212 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 213 | + struct mt8183_mt6358_ts3a227_max98357_priv *priv = | |
| 214 | + snd_soc_card_get_drvdata(rtd->card); | |
| 215 | + int ret; | |
| 216 | + | |
| 217 | + if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) | |
| 218 | + return; | |
| 219 | + | |
| 220 | + ret = pinctrl_select_state(priv->pinctrl, | |
| 221 | + priv->pin_states[PIN_TDM_OUT_OFF]); | |
| 222 | + if (ret) | |
| 223 | + dev_err(rtd->card->dev, "%s failed to select state %d\n", | |
| 224 | + __func__, ret); | |
| 225 | +} | |
| 226 | + | |
| 227 | +static struct snd_soc_ops mt8183_mt6358_tdm_ops = { | |
| 228 | + .startup = mt8183_mt6358_tdm_startup, | |
| 229 | + .shutdown = mt8183_mt6358_tdm_shutdown, | |
| 230 | +}; | |
| 231 | + | |
| 186 | 232 | static struct snd_soc_dai_link |
| 187 | 233 | mt8183_mt6358_ts3a227_max98357_dai_links[] = { |
| 188 | 234 | /* FE */ |
| @@ -333,33 +379,30 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = { · 144 unmodified lines | ||
| 333 | 379 | { |
| 334 | 380 | .name = "TDM", |
| 335 | 381 | .no_pcm = 1, |
| 382 | + .dai_fmt = SND_SOC_DAIFMT_I2S | | |
| 383 | + SND_SOC_DAIFMT_IB_IF | | |
| 384 | + SND_SOC_DAIFMT_CBM_CFM, | |
| 336 | 385 | .dpcm_playback = 1, |
| 337 | 386 | .ignore_suspend = 1, |
| 387 | + .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, | |
| 388 | + .ops = &mt8183_mt6358_tdm_ops, | |
| 338 | 389 | SND_SOC_DAILINK_REG(tdm), |
| 339 | 390 | }, |
| 340 | 391 | }; |
| 341 | 392 | |
| 342 | −static int | |
| 343 | −mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *cpnt); | |
| 344 | − | |
| 345 | −static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = { | |
| 346 | − .name = "Headset Chip", | |
| 347 | − .init = mt8183_mt6358_ts3a227_max98357_headset_init, | |
| 348 | −}; | |
| 349 | − | |
| 350 | 393 | static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { |
| 351 | 394 | .name = "mt8183_mt6358_ts3a227_max98357", |
| 352 | 395 | .owner = THIS_MODULE, |
| 353 | 396 | .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, |
| 354 | 397 | .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), |
| 355 | − .aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev, | |
| 356 | − .num_aux_devs = 1, | |
| 357 | 398 | }; |
| 358 | 399 | |
| 359 | 400 | static int |
| 360 | 401 | mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) |
| 361 | 402 | { |
| 362 | 403 | int ret; |
| 404 | + struct mt8183_mt6358_ts3a227_max98357_priv *priv = | |
| 405 | + snd_soc_card_get_drvdata(component->card); | |
| 363 | 406 | |
| 364 | 407 | /* Enable Headset and 4 Buttons Jack detection */ |
| 365 | 408 | ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, |
| @@ -367,23 +410,29 @@ mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) · 1 unmodified line | ||
| 367 | 410 | SND_JACK_HEADSET | |
| 368 | 411 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
| 369 | 412 | SND_JACK_BTN_2 | SND_JACK_BTN_3, |
| 370 | − &headset_jack, | |
| 413 | + &priv->headset_jack, | |
| 371 | 414 | NULL, 0); |
| 372 | 415 | if (ret) |
| 373 | 416 | return ret; |
| 374 | 417 | |
| 375 | − ret = ts3a227e_enable_jack_detect(component, &headset_jack); | |
| 418 | + ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack); | |
| 376 | 419 | |
| 377 | 420 | return ret; |
| 378 | 421 | } |
| 379 | 422 | |
| 423 | +static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = { | |
| 424 | + .dlc = COMP_EMPTY(), | |
| 425 | + .init = mt8183_mt6358_ts3a227_max98357_headset_init, | |
| 426 | +}; | |
| 427 | + | |
| 380 | 428 | static int |
| 381 | 429 | mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) |
| 382 | 430 | { |
| 383 | 431 | struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; |
| 384 | 432 | struct device_node *platform_node; |
| 385 | 433 | struct snd_soc_dai_link *dai_link; |
| 386 | − struct pinctrl *default_pins; | |
| 434 | + struct mt8183_mt6358_ts3a227_max98357_priv *priv; | |
| 435 | + int ret; | |
| 387 | 436 | int i; |
| 388 | 437 | |
| 389 | 438 | card->dev = &pdev->dev; |
| @@ -401,21 +450,53 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 401 | 450 | dai_link->platforms->of_node = platform_node; |
| 402 | 451 | } |
| 403 | 452 | |
| 404 | − mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node = | |
| 453 | + mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node = | |
| 405 | 454 | of_parse_phandle(pdev->dev.of_node, |
| 406 | 455 | "mediatek,headset-codec", 0); |
| 407 | − if (!mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node) { | |
| 408 | − dev_err(&pdev->dev, | |
| 409 | − "Property 'mediatek,headset-codec' missing/invalid\n"); | |
| 410 | − return -EINVAL; | |
| 456 | + if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) { | |
| 457 | + card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev; | |
| 458 | + card->num_aux_devs = 1; | |
| 411 | 459 | } |
| 412 | 460 | |
| 413 | − default_pins = | |
| 414 | − devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); | |
| 415 | − if (IS_ERR(default_pins)) { | |
| 416 | − dev_err(&pdev->dev, "%s set pins failed\n", | |
| 461 | + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | |
| 462 | + if (!priv) | |
| 463 | + return -ENOMEM; | |
| 464 | + | |
| 465 | + snd_soc_card_set_drvdata(card, priv); | |
| 466 | + | |
| 467 | + priv->pinctrl = devm_pinctrl_get(&pdev->dev); | |
| 468 | + if (IS_ERR(priv->pinctrl)) { | |
| 469 | + dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n", | |
| 417 | 470 | __func__); |
| 418 | − return PTR_ERR(default_pins); | |
| 471 | + return PTR_ERR(priv->pinctrl); | |
| 472 | + } | |
| 473 | + | |
| 474 | + for (i = 0; i < PIN_STATE_MAX; i++) { | |
| 475 | + priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl, | |
| 476 | + mt8183_pin_str[i]); | |
| 477 | + if (IS_ERR(priv->pin_states[i])) { | |
| 478 | + ret = PTR_ERR(priv->pin_states[i]); | |
| 479 | + dev_info(&pdev->dev, "%s Can't find pin state %s %d\n", | |
| 480 | + __func__, mt8183_pin_str[i], ret); | |
| 481 | + } | |
| 482 | + } | |
| 483 | + | |
| 484 | + if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) { | |
| 485 | + ret = pinctrl_select_state(priv->pinctrl, | |
| 486 | + priv->pin_states[PIN_TDM_OUT_OFF]); | |
| 487 | + if (ret) | |
| 488 | + dev_info(&pdev->dev, | |
| 489 | + "%s failed to select state %d\n", | |
| 490 | + __func__, ret); | |
| 491 | + } | |
| 492 | + | |
| 493 | + if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) { | |
| 494 | + ret = pinctrl_select_state(priv->pinctrl, | |
| 495 | + priv->pin_states[PIN_STATE_DEFAULT]); | |
| 496 | + if (ret) | |
| 497 | + dev_info(&pdev->dev, | |
| 498 | + "%s failed to select state %d\n", | |
| 499 | + __func__, ret); | |
| 419 | 500 | } |
| 420 | 501 | |
| 421 | 502 | return devm_snd_soc_register_card(&pdev->dev, card); |
| @@ -445,4 +526,3 @@ MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver"); · 23 unmodified lines | ||
| 445 | 526 | MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); |
| 446 | 527 | MODULE_LICENSE("GPL v2"); |
| 447 | 528 | MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); |
| 448 | − | |
| @@ -413,6 +413,11 @@ · 412 unmodified lines | ||
| 413 | 413 | #define AFE_MAX_REGISTER AFE_GENERAL2_ASRC_2CH_CON13 |
| 414 | 414 | #define AFE_IRQ_STATUS_BITS 0x1fff |
| 415 | 415 | |
| 416 | +/* AUDIO_TOP_CON3 */ | |
| 417 | +#define BCK_INVERSE_SFT 3 | |
| 418 | +#define BCK_INVERSE_MASK 0x1 | |
| 419 | +#define BCK_INVERSE_MASK_SFT (0x1 << 3) | |
| 420 | + | |
| 416 | 421 | /* AFE_DAC_CON0 */ |
| 417 | 422 | #define AWB2_ON_SFT 29 |
| 418 | 423 | #define AWB2_ON_MASK 0x1 |
| @@ -1596,9 +1601,6 @@ · 1177 unmodified lines | ||
| 1596 | 1601 | #define TDM_EN_SFT 0 |
| 1597 | 1602 | #define TDM_EN_MASK 0x1 |
| 1598 | 1603 | #define TDM_EN_MASK_SFT (0x1 << 0) |
| 1599 | −#define BCK_INVERSE_SFT 1 | |
| 1600 | −#define BCK_INVERSE_MASK 0x1 | |
| 1601 | −#define BCK_INVERSE_MASK_SFT (0x1 << 1) | |
| 1602 | 1604 | #define LRCK_INVERSE_SFT 2 |
| 1603 | 1605 | #define LRCK_INVERSE_MASK 0x1 |
| 1604 | 1606 | #define LRCK_INVERSE_MASK_SFT (0x1 << 2) |
| @@ -111,6 +111,7 @@ static void axg_card_clean_references(struct axg_card *priv) · 110 unmodified lines | ||
| 111 | 111 | struct snd_soc_card *card = &priv->card; |
| 112 | 112 | struct snd_soc_dai_link *link; |
| 113 | 113 | struct snd_soc_dai_link_component *codec; |
| 114 | + struct snd_soc_aux_dev *aux; | |
| 114 | 115 | int i, j; |
| 115 | 116 | |
| 116 | 117 | if (card->dai_link) { |
| @@ -123,8 +124,8 @@ static void axg_card_clean_references(struct axg_card *priv) · 6 unmodified lines | ||
| 123 | 124 | } |
| 124 | 125 | |
| 125 | 126 | if (card->aux_dev) { |
| 126 | − for (i = 0; i < card->num_aux_devs; i++) | |
| 127 | − of_node_put(card->aux_dev[i].codec_of_node); | |
| 127 | + for_each_card_pre_auxs(card, i, aux) | |
| 128 | + of_node_put(aux->dlc.of_node); | |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | 131 | kfree(card->dai_link); |
| @@ -157,10 +158,10 @@ static int axg_card_add_aux_devices(struct snd_soc_card *card) · 26 unmodified lines | ||
| 157 | 158 | card->aux_dev = aux; |
| 158 | 159 | card->num_aux_devs = num; |
| 159 | 160 | |
| 160 | − for (i = 0; i < card->num_aux_devs; i++, aux++) { | |
| 161 | − aux->codec_of_node = | |
| 161 | + for_each_card_pre_auxs(card, i, aux) { | |
| 162 | + aux->dlc.of_node = | |
| 162 | 163 | of_parse_phandle(node, "audio-aux-devs", i); |
| 163 | − if (!aux->codec_of_node) | |
| 164 | + if (!aux->dlc.of_node) | |
| 164 | 165 | return -EINVAL; |
| 165 | 166 | } |
| 166 | 167 | |
| @@ -306,7 +306,7 @@ static const struct regmap_config axg_fifo_regmap_cfg = { · 305 unmodified lines | ||
| 306 | 306 | .reg_bits = 32, |
| 307 | 307 | .val_bits = 32, |
| 308 | 308 | .reg_stride = 4, |
| 309 | − .max_register = FIFO_INIT_ADDR, | |
| 309 | + .max_register = FIFO_CTRL2, | |
| 310 | 310 | }; |
| 311 | 311 | |
| 312 | 312 | int axg_fifo_probe(struct platform_device *pdev) |
| @@ -314,7 +314,6 @@ int axg_fifo_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 314 | 314 | struct device *dev = &pdev->dev; |
| 315 | 315 | const struct axg_fifo_match_data *data; |
| 316 | 316 | struct axg_fifo *fifo; |
| 317 | − struct resource *res; | |
| 318 | 317 | void __iomem *regs; |
| 319 | 318 | |
| 320 | 319 | data = of_device_get_match_data(dev); |
| @@ -328,8 +327,7 @@ int axg_fifo_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 328 | 327 | return -ENOMEM; |
| 329 | 328 | platform_set_drvdata(pdev, fifo); |
| 330 | 329 | |
| 331 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 332 | − regs = devm_ioremap_resource(dev, res); | |
| 330 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 333 | 331 | if (IS_ERR(regs)) |
| 334 | 332 | return PTR_ERR(regs); |
| 335 | 333 | |
| @@ -61,6 +61,7 @@ struct snd_soc_pcm_runtime; · 60 unmodified lines | ||
| 61 | 61 | #define STATUS1_INT_STS(x) ((x) << 0) |
| 62 | 62 | #define FIFO_STATUS2 0x18 |
| 63 | 63 | #define FIFO_INIT_ADDR 0x24 |
| 64 | +#define FIFO_CTRL2 0x28 | |
| 64 | 65 | |
| 65 | 66 | struct axg_fifo { |
| 66 | 67 | struct regmap *map; |
| @@ -23,6 +23,12 @@ · 22 unmodified lines | ||
| 23 | 23 | #define CTRL0_SEL3_SHIFT 8 |
| 24 | 24 | #define CTRL0_SEL3_EN_SHIFT 11 |
| 25 | 25 | #define CTRL1_FRDDR_FORCE_FINISH BIT(12) |
| 26 | +#define CTRL2_SEL1_SHIFT 0 | |
| 27 | +#define CTRL2_SEL1_EN_SHIFT 4 | |
| 28 | +#define CTRL2_SEL2_SHIFT 8 | |
| 29 | +#define CTRL2_SEL2_EN_SHIFT 12 | |
| 30 | +#define CTRL2_SEL3_SHIFT 16 | |
| 31 | +#define CTRL2_SEL3_EN_SHIFT 20 | |
| 26 | 32 | |
| 27 | 33 | static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream, |
| 28 | 34 | struct snd_soc_dai *dai) |
| @@ -104,7 +110,7 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = { · 75 unmodified lines | ||
| 104 | 110 | }; |
| 105 | 111 | |
| 106 | 112 | static const char * const axg_frddr_sel_texts[] = { |
| 107 | − "OUT 0", "OUT 1", "OUT 2", "OUT 3" | |
| 113 | + "OUT 0", "OUT 1", "OUT 2", "OUT 3", "OUT 4", "OUT 5", "OUT 6", "OUT 7", | |
| 108 | 114 | }; |
| 109 | 115 | |
| 110 | 116 | static SOC_ENUM_SINGLE_DECL(axg_frddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, |
| @@ -120,6 +126,10 @@ static const struct snd_soc_dapm_widget axg_frddr_dapm_widgets[] = { · 9 unmodified lines | ||
| 120 | 126 | SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 121 | 127 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 122 | 128 | SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 129 | + SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 130 | + SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 131 | + SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 132 | + SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 123 | 133 | }; |
| 124 | 134 | |
| 125 | 135 | static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = { |
| @@ -128,6 +138,10 @@ static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = { · 2 unmodified lines | ||
| 128 | 138 | { "OUT 1", "OUT 1", "SINK SEL" }, |
| 129 | 139 | { "OUT 2", "OUT 2", "SINK SEL" }, |
| 130 | 140 | { "OUT 3", "OUT 3", "SINK SEL" }, |
| 141 | + { "OUT 4", "OUT 4", "SINK SEL" }, | |
| 142 | + { "OUT 5", "OUT 5", "SINK SEL" }, | |
| 143 | + { "OUT 6", "OUT 6", "SINK SEL" }, | |
| 144 | + { "OUT 7", "OUT 7", "SINK SEL" }, | |
| 131 | 145 | }; |
| 132 | 146 | |
| 133 | 147 | static const struct snd_soc_component_driver axg_frddr_component_drv = { |
| @@ -162,16 +176,12 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = { · 28 unmodified lines | ||
| 162 | 176 | .pcm_new = axg_frddr_pcm_new, |
| 163 | 177 | }; |
| 164 | 178 | |
| 165 | −static const char * const g12a_frddr_sel_texts[] = { | |
| 166 | − "OUT 0", "OUT 1", "OUT 2", "OUT 3", "OUT 4", | |
| 167 | −}; | |
| 168 | − | |
| 169 | 179 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, |
| 170 | − g12a_frddr_sel_texts); | |
| 180 | + axg_frddr_sel_texts); | |
| 171 | 181 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel2_enum, FIFO_CTRL0, CTRL0_SEL2_SHIFT, |
| 172 | − g12a_frddr_sel_texts); | |
| 182 | + axg_frddr_sel_texts); | |
| 173 | 183 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel3_enum, FIFO_CTRL0, CTRL0_SEL3_SHIFT, |
| 174 | − g12a_frddr_sel_texts); | |
| 184 | + axg_frddr_sel_texts); | |
| 175 | 185 | |
| 176 | 186 | static const struct snd_kcontrol_new g12a_frddr_out1_demux = |
| 177 | 187 | SOC_DAPM_ENUM("Output Src 1", g12a_frddr_sel1_enum); |
| @@ -211,6 +221,9 @@ static const struct snd_soc_dapm_widget g12a_frddr_dapm_widgets[] = { · 33 unmodified lines | ||
| 211 | 221 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 212 | 222 | SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 213 | 223 | SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 224 | + SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 225 | + SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 226 | + SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 214 | 227 | }; |
| 215 | 228 | |
| 216 | 229 | static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = { |
| @@ -228,16 +241,25 @@ static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = { · 11 unmodified lines | ||
| 228 | 241 | { "OUT 2", "OUT 2", "SINK 1 SEL" }, |
| 229 | 242 | { "OUT 3", "OUT 3", "SINK 1 SEL" }, |
| 230 | 243 | { "OUT 4", "OUT 4", "SINK 1 SEL" }, |
| 244 | + { "OUT 5", "OUT 5", "SINK 1 SEL" }, | |
| 245 | + { "OUT 6", "OUT 6", "SINK 1 SEL" }, | |
| 246 | + { "OUT 7", "OUT 7", "SINK 1 SEL" }, | |
| 231 | 247 | { "OUT 0", "OUT 0", "SINK 2 SEL" }, |
| 232 | 248 | { "OUT 1", "OUT 1", "SINK 2 SEL" }, |
| 233 | 249 | { "OUT 2", "OUT 2", "SINK 2 SEL" }, |
| 234 | 250 | { "OUT 3", "OUT 3", "SINK 2 SEL" }, |
| 235 | 251 | { "OUT 4", "OUT 4", "SINK 2 SEL" }, |
| 252 | + { "OUT 5", "OUT 5", "SINK 2 SEL" }, | |
| 253 | + { "OUT 6", "OUT 6", "SINK 2 SEL" }, | |
| 254 | + { "OUT 7", "OUT 7", "SINK 2 SEL" }, | |
| 236 | 255 | { "OUT 0", "OUT 0", "SINK 3 SEL" }, |
| 237 | 256 | { "OUT 1", "OUT 1", "SINK 3 SEL" }, |
| 238 | 257 | { "OUT 2", "OUT 2", "SINK 3 SEL" }, |
| 239 | 258 | { "OUT 3", "OUT 3", "SINK 3 SEL" }, |
| 240 | 259 | { "OUT 4", "OUT 4", "SINK 3 SEL" }, |
| 260 | + { "OUT 5", "OUT 5", "SINK 3 SEL" }, | |
| 261 | + { "OUT 6", "OUT 6", "SINK 3 SEL" }, | |
| 262 | + { "OUT 7", "OUT 7", "SINK 3 SEL" }, | |
| 241 | 263 | }; |
| 242 | 264 | |
| 243 | 265 | static const struct snd_soc_component_driver g12a_frddr_component_drv = { |
| @@ -253,6 +275,70 @@ static const struct axg_fifo_match_data g12a_frddr_match_data = { · 9 unmodified lines | ||
| 253 | 275 | .dai_drv = &g12a_frddr_dai_drv |
| 254 | 276 | }; |
| 255 | 277 | |
| 278 | +/* On SM1, the output selection in on CTRL2 */ | |
| 279 | +static const struct snd_kcontrol_new sm1_frddr_out1_enable = | |
| 280 | + SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2, | |
| 281 | + CTRL2_SEL1_EN_SHIFT, 1, 0); | |
| 282 | +static const struct snd_kcontrol_new sm1_frddr_out2_enable = | |
| 283 | + SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2, | |
| 284 | + CTRL2_SEL2_EN_SHIFT, 1, 0); | |
| 285 | +static const struct snd_kcontrol_new sm1_frddr_out3_enable = | |
| 286 | + SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2, | |
| 287 | + CTRL2_SEL3_EN_SHIFT, 1, 0); | |
| 288 | + | |
| 289 | +static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel1_enum, FIFO_CTRL2, CTRL2_SEL1_SHIFT, | |
| 290 | + axg_frddr_sel_texts); | |
| 291 | +static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel2_enum, FIFO_CTRL2, CTRL2_SEL2_SHIFT, | |
| 292 | + axg_frddr_sel_texts); | |
| 293 | +static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel3_enum, FIFO_CTRL2, CTRL2_SEL3_SHIFT, | |
| 294 | + axg_frddr_sel_texts); | |
| 295 | + | |
| 296 | +static const struct snd_kcontrol_new sm1_frddr_out1_demux = | |
| 297 | + SOC_DAPM_ENUM("Output Src 1", sm1_frddr_sel1_enum); | |
| 298 | +static const struct snd_kcontrol_new sm1_frddr_out2_demux = | |
| 299 | + SOC_DAPM_ENUM("Output Src 2", sm1_frddr_sel2_enum); | |
| 300 | +static const struct snd_kcontrol_new sm1_frddr_out3_demux = | |
| 301 | + SOC_DAPM_ENUM("Output Src 3", sm1_frddr_sel3_enum); | |
| 302 | + | |
| 303 | +static const struct snd_soc_dapm_widget sm1_frddr_dapm_widgets[] = { | |
| 304 | + SND_SOC_DAPM_AIF_OUT("SRC 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 305 | + SND_SOC_DAPM_AIF_OUT("SRC 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 306 | + SND_SOC_DAPM_AIF_OUT("SRC 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 307 | + SND_SOC_DAPM_SWITCH("SRC 1 EN", SND_SOC_NOPM, 0, 0, | |
| 308 | + &sm1_frddr_out1_enable), | |
| 309 | + SND_SOC_DAPM_SWITCH("SRC 2 EN", SND_SOC_NOPM, 0, 0, | |
| 310 | + &sm1_frddr_out2_enable), | |
| 311 | + SND_SOC_DAPM_SWITCH("SRC 3 EN", SND_SOC_NOPM, 0, 0, | |
| 312 | + &sm1_frddr_out3_enable), | |
| 313 | + SND_SOC_DAPM_DEMUX("SINK 1 SEL", SND_SOC_NOPM, 0, 0, | |
| 314 | + &sm1_frddr_out1_demux), | |
| 315 | + SND_SOC_DAPM_DEMUX("SINK 2 SEL", SND_SOC_NOPM, 0, 0, | |
| 316 | + &sm1_frddr_out2_demux), | |
| 317 | + SND_SOC_DAPM_DEMUX("SINK 3 SEL", SND_SOC_NOPM, 0, 0, | |
| 318 | + &sm1_frddr_out3_demux), | |
| 319 | + SND_SOC_DAPM_AIF_OUT("OUT 0", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 320 | + SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 321 | + SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 322 | + SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 323 | + SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 324 | + SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 325 | + SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 326 | + SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 327 | +}; | |
| 328 | + | |
| 329 | +static const struct snd_soc_component_driver sm1_frddr_component_drv = { | |
| 330 | + .dapm_widgets = sm1_frddr_dapm_widgets, | |
| 331 | + .num_dapm_widgets = ARRAY_SIZE(sm1_frddr_dapm_widgets), | |
| 332 | + .dapm_routes = g12a_frddr_dapm_routes, | |
| 333 | + .num_dapm_routes = ARRAY_SIZE(g12a_frddr_dapm_routes), | |
| 334 | + .ops = &g12a_fifo_pcm_ops | |
| 335 | +}; | |
| 336 | + | |
| 337 | +static const struct axg_fifo_match_data sm1_frddr_match_data = { | |
| 338 | + .component_drv = &sm1_frddr_component_drv, | |
| 339 | + .dai_drv = &g12a_frddr_dai_drv | |
| 340 | +}; | |
| 341 | + | |
| 256 | 342 | static const struct of_device_id axg_frddr_of_match[] = { |
| 257 | 343 | { |
| 258 | 344 | .compatible = "amlogic,axg-frddr", |
| @@ -260,6 +346,9 @@ static const struct of_device_id axg_frddr_of_match[] = { · 1 unmodified line | ||
| 260 | 346 | }, { |
| 261 | 347 | .compatible = "amlogic,g12a-frddr", |
| 262 | 348 | .data = &g12a_frddr_match_data, |
| 349 | + }, { | |
| 350 | + .compatible = "amlogic,sm1-frddr", | |
| 351 | + .data = &sm1_frddr_match_data, | |
| 263 | 352 | }, {} |
| 264 | 353 | }; |
| 265 | 354 | MODULE_DEVICE_TABLE(of, axg_frddr_of_match); |
| @@ -585,7 +585,6 @@ static int axg_pdm_probe(struct platform_device *pdev) · 584 unmodified lines | ||
| 585 | 585 | { |
| 586 | 586 | struct device *dev = &pdev->dev; |
| 587 | 587 | struct axg_pdm *priv; |
| 588 | − struct resource *res; | |
| 589 | 588 | void __iomem *regs; |
| 590 | 589 | int ret; |
| 591 | 590 | |
| @@ -600,8 +599,7 @@ static int axg_pdm_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 600 | 599 | return -ENODEV; |
| 601 | 600 | } |
| 602 | 601 | |
| 603 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 604 | − regs = devm_ioremap_resource(dev, res); | |
| 602 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 605 | 603 | if (IS_ERR(regs)) |
| 606 | 604 | return PTR_ERR(regs); |
| 607 | 605 | |
| @@ -453,7 +453,6 @@ static int axg_spdifin_probe(struct platform_device *pdev) · 452 unmodified lines | ||
| 453 | 453 | struct device *dev = &pdev->dev; |
| 454 | 454 | struct axg_spdifin *priv; |
| 455 | 455 | struct snd_soc_dai_driver *dai_drv; |
| 456 | − struct resource *res; | |
| 457 | 456 | void __iomem *regs; |
| 458 | 457 | int ret; |
| 459 | 458 | |
| @@ -468,8 +467,7 @@ static int axg_spdifin_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 468 | 467 | return -ENODEV; |
| 469 | 468 | } |
| 470 | 469 | |
| 471 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 472 | − regs = devm_ioremap_resource(dev, res); | |
| 470 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 473 | 471 | if (IS_ERR(regs)) |
| 474 | 472 | return PTR_ERR(regs); |
| 475 | 473 | |
| @@ -401,7 +401,6 @@ static int axg_spdifout_probe(struct platform_device *pdev) · 400 unmodified lines | ||
| 401 | 401 | { |
| 402 | 402 | struct device *dev = &pdev->dev; |
| 403 | 403 | struct axg_spdifout *priv; |
| 404 | − struct resource *res; | |
| 405 | 404 | void __iomem *regs; |
| 406 | 405 | int ret; |
| 407 | 406 | |
| @@ -410,8 +409,7 @@ static int axg_spdifout_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 410 | 409 | return -ENOMEM; |
| 411 | 410 | platform_set_drvdata(pdev, priv); |
| 412 | 411 | |
| 413 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 414 | − regs = devm_ioremap_resource(dev, res); | |
| 412 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 415 | 413 | if (IS_ERR(regs)) |
| 416 | 414 | return PTR_ERR(regs); |
| 417 | 415 | |
| @@ -253,7 +253,6 @@ int axg_tdm_formatter_probe(struct platform_device *pdev) · 252 unmodified lines | ||
| 253 | 253 | struct device *dev = &pdev->dev; |
| 254 | 254 | const struct axg_tdm_formatter_driver *drv; |
| 255 | 255 | struct axg_tdm_formatter *formatter; |
| 256 | − struct resource *res; | |
| 257 | 256 | void __iomem *regs; |
| 258 | 257 | int ret; |
| 259 | 258 | |
| @@ -269,8 +268,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 269 | 268 | platform_set_drvdata(pdev, formatter); |
| 270 | 269 | formatter->drv = drv; |
| 271 | 270 | |
| 272 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 273 | − regs = devm_ioremap_resource(dev, res); | |
| 271 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 274 | 272 | if (IS_ERR(regs)) |
| 275 | 273 | return PTR_ERR(regs); |
| 276 | 274 | |
| @@ -43,7 +43,8 @@ static const struct regmap_config axg_tdmin_regmap_cfg = { · 42 unmodified lines | ||
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | 45 | static const char * const axg_tdmin_sel_texts[] = { |
| 46 | − "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", | |
| 46 | + "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7", | |
| 47 | + "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15", | |
| 47 | 48 | }; |
| 48 | 49 | |
| 49 | 50 | /* Change to special mux control to reset dapm */ |
| @@ -164,12 +165,22 @@ static int axg_tdmin_prepare(struct regmap *map, · 114 unmodified lines | ||
| 164 | 165 | } |
| 165 | 166 | |
| 166 | 167 | static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = { |
| 167 | − SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 168 | − SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 169 | − SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 170 | − SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 171 | − SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 172 | − SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 168 | + SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 169 | + SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 170 | + SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 171 | + SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 172 | + SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 173 | + SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 174 | + SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 175 | + SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 176 | + SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 177 | + SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 178 | + SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 179 | + SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 180 | + SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 181 | + SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 182 | + SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 183 | + SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 173 | 184 | SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_tdmin_in_mux), |
| 174 | 185 | SND_SOC_DAPM_PGA_E("DEC", SND_SOC_NOPM, 0, 0, NULL, 0, |
| 175 | 186 | axg_tdm_formatter_event, |
| @@ -178,12 +189,22 @@ static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = { · 2 unmodified lines | ||
| 178 | 189 | }; |
| 179 | 190 | |
| 180 | 191 | static const struct snd_soc_dapm_route axg_tdmin_dapm_routes[] = { |
| 181 | − { "SRC SEL", "IN 0", "IN 0" }, | |
| 182 | − { "SRC SEL", "IN 1", "IN 1" }, | |
| 183 | − { "SRC SEL", "IN 2", "IN 2" }, | |
| 184 | − { "SRC SEL", "IN 3", "IN 3" }, | |
| 185 | − { "SRC SEL", "IN 4", "IN 4" }, | |
| 186 | − { "SRC SEL", "IN 5", "IN 5" }, | |
| 192 | + { "SRC SEL", "IN 0", "IN 0" }, | |
| 193 | + { "SRC SEL", "IN 1", "IN 1" }, | |
| 194 | + { "SRC SEL", "IN 2", "IN 2" }, | |
| 195 | + { "SRC SEL", "IN 3", "IN 3" }, | |
| 196 | + { "SRC SEL", "IN 4", "IN 4" }, | |
| 197 | + { "SRC SEL", "IN 5", "IN 5" }, | |
| 198 | + { "SRC SEL", "IN 6", "IN 6" }, | |
| 199 | + { "SRC SEL", "IN 7", "IN 7" }, | |
| 200 | + { "SRC SEL", "IN 8", "IN 8" }, | |
| 201 | + { "SRC SEL", "IN 9", "IN 9" }, | |
| 202 | + { "SRC SEL", "IN 10", "IN 10" }, | |
| 203 | + { "SRC SEL", "IN 11", "IN 11" }, | |
| 204 | + { "SRC SEL", "IN 12", "IN 12" }, | |
| 205 | + { "SRC SEL", "IN 13", "IN 13" }, | |
| 206 | + { "SRC SEL", "IN 14", "IN 14" }, | |
| 207 | + { "SRC SEL", "IN 15", "IN 15" }, | |
| 187 | 208 | { "DEC", NULL, "SRC SEL" }, |
| 188 | 209 | { "OUT", NULL, "DEC" }, |
| 189 | 210 | }; |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #define TDMOUT_CTRL1 0x04 |
| 25 | 25 | #define TDMOUT_CTRL1_TYPE_MASK GENMASK(6, 4) |
| 26 | 26 | #define TDMOUT_CTRL1_TYPE(x) ((x) << 4) |
| 27 | +#define SM1_TDMOUT_CTRL1_GAIN_EN 7 | |
| 27 | 28 | #define TDMOUT_CTRL1_MSB_POS_MASK GENMASK(12, 8) |
| 28 | 29 | #define TDMOUT_CTRL1_MSB_POS(x) ((x) << 8) |
| 29 | 30 | #define TDMOUT_CTRL1_SEL_SHIFT 24 |
| @@ -51,25 +52,6 @@ static const struct regmap_config axg_tdmout_regmap_cfg = { · 21 unmodified lines | ||
| 51 | 52 | .max_register = TDMOUT_MASK_VAL, |
| 52 | 53 | }; |
| 53 | 54 | |
| 54 | −static const struct snd_kcontrol_new axg_tdmout_controls[] = { | |
| 55 | − SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0), | |
| 56 | − SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0), | |
| 57 | − SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0), | |
| 58 | − SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0), | |
| 59 | − SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1, | |
| 60 | − TDMOUT_CTRL1_GAIN_EN, 1, 0), | |
| 61 | −}; | |
| 62 | − | |
| 63 | −static const char * const tdmout_sel_texts[] = { | |
| 64 | − "IN 0", "IN 1", "IN 2", | |
| 65 | −}; | |
| 66 | − | |
| 67 | −static SOC_ENUM_SINGLE_DECL(axg_tdmout_sel_enum, TDMOUT_CTRL1, | |
| 68 | − TDMOUT_CTRL1_SEL_SHIFT, tdmout_sel_texts); | |
| 69 | − | |
| 70 | −static const struct snd_kcontrol_new axg_tdmout_in_mux = | |
| 71 | − SOC_DAPM_ENUM("Input Source", axg_tdmout_sel_enum); | |
| 72 | − | |
| 73 | 55 | static struct snd_soc_dai * |
| 74 | 56 | axg_tdmout_get_be(struct snd_soc_dapm_widget *w) |
| 75 | 57 | { |
| @@ -197,6 +179,25 @@ static int axg_tdmout_prepare(struct regmap *map, · 121 unmodified lines | ||
| 197 | 179 | return axg_tdm_formatter_set_channel_masks(map, ts, TDMOUT_MASK0); |
| 198 | 180 | } |
| 199 | 181 | |
| 182 | +static const struct snd_kcontrol_new axg_tdmout_controls[] = { | |
| 183 | + SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0), | |
| 184 | + SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0), | |
| 185 | + SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0), | |
| 186 | + SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0), | |
| 187 | + SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1, | |
| 188 | + TDMOUT_CTRL1_GAIN_EN, 1, 0), | |
| 189 | +}; | |
| 190 | + | |
| 191 | +static const char * const axg_tdmout_sel_texts[] = { | |
| 192 | + "IN 0", "IN 1", "IN 2", | |
| 193 | +}; | |
| 194 | + | |
| 195 | +static SOC_ENUM_SINGLE_DECL(axg_tdmout_sel_enum, TDMOUT_CTRL1, | |
| 196 | + TDMOUT_CTRL1_SEL_SHIFT, axg_tdmout_sel_texts); | |
| 197 | + | |
| 198 | +static const struct snd_kcontrol_new axg_tdmout_in_mux = | |
| 199 | + SOC_DAPM_ENUM("Input Source", axg_tdmout_sel_enum); | |
| 200 | + | |
| 200 | 201 | static const struct snd_soc_dapm_widget axg_tdmout_dapm_widgets[] = { |
| 201 | 202 | SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 202 | 203 | SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), |
| @@ -252,6 +253,67 @@ static const struct axg_tdm_formatter_driver g12a_tdmout_drv = { · 49 unmodified lines | ||
| 252 | 253 | }, |
| 253 | 254 | }; |
| 254 | 255 | |
| 256 | +static const struct snd_kcontrol_new sm1_tdmout_controls[] = { | |
| 257 | + SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0), | |
| 258 | + SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0), | |
| 259 | + SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0), | |
| 260 | + SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0), | |
| 261 | + SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1, | |
| 262 | + SM1_TDMOUT_CTRL1_GAIN_EN, 1, 0), | |
| 263 | +}; | |
| 264 | + | |
| 265 | +static const char * const sm1_tdmout_sel_texts[] = { | |
| 266 | + "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", | |
| 267 | +}; | |
| 268 | + | |
| 269 | +static SOC_ENUM_SINGLE_DECL(sm1_tdmout_sel_enum, TDMOUT_CTRL1, | |
| 270 | + TDMOUT_CTRL1_SEL_SHIFT, sm1_tdmout_sel_texts); | |
| 271 | + | |
| 272 | +static const struct snd_kcontrol_new sm1_tdmout_in_mux = | |
| 273 | + SOC_DAPM_ENUM("Input Source", sm1_tdmout_sel_enum); | |
| 274 | + | |
| 275 | +static const struct snd_soc_dapm_widget sm1_tdmout_dapm_widgets[] = { | |
| 276 | + SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 277 | + SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 278 | + SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 279 | + SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 280 | + SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 281 | + SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_tdmout_in_mux), | |
| 282 | + SND_SOC_DAPM_PGA_E("ENC", SND_SOC_NOPM, 0, 0, NULL, 0, | |
| 283 | + axg_tdm_formatter_event, | |
| 284 | + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD)), | |
| 285 | + SND_SOC_DAPM_AIF_OUT("OUT", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 286 | +}; | |
| 287 | + | |
| 288 | +static const struct snd_soc_dapm_route sm1_tdmout_dapm_routes[] = { | |
| 289 | + { "SRC SEL", "IN 0", "IN 0" }, | |
| 290 | + { "SRC SEL", "IN 1", "IN 1" }, | |
| 291 | + { "SRC SEL", "IN 2", "IN 2" }, | |
| 292 | + { "SRC SEL", "IN 3", "IN 3" }, | |
| 293 | + { "SRC SEL", "IN 4", "IN 4" }, | |
| 294 | + { "ENC", NULL, "SRC SEL" }, | |
| 295 | + { "OUT", NULL, "ENC" }, | |
| 296 | +}; | |
| 297 | + | |
| 298 | +static const struct snd_soc_component_driver sm1_tdmout_component_drv = { | |
| 299 | + .controls = sm1_tdmout_controls, | |
| 300 | + .num_controls = ARRAY_SIZE(sm1_tdmout_controls), | |
| 301 | + .dapm_widgets = sm1_tdmout_dapm_widgets, | |
| 302 | + .num_dapm_widgets = ARRAY_SIZE(sm1_tdmout_dapm_widgets), | |
| 303 | + .dapm_routes = sm1_tdmout_dapm_routes, | |
| 304 | + .num_dapm_routes = ARRAY_SIZE(sm1_tdmout_dapm_routes), | |
| 305 | +}; | |
| 306 | + | |
| 307 | +static const struct axg_tdm_formatter_driver sm1_tdmout_drv = { | |
| 308 | + .component_drv = &sm1_tdmout_component_drv, | |
| 309 | + .regmap_cfg = &axg_tdmout_regmap_cfg, | |
| 310 | + .ops = &axg_tdmout_ops, | |
| 311 | + .quirks = &(const struct axg_tdm_formatter_hw) { | |
| 312 | + .invert_sclk = true, | |
| 313 | + .skew_offset = 2, | |
| 314 | + }, | |
| 315 | +}; | |
| 316 | + | |
| 255 | 317 | static const struct of_device_id axg_tdmout_of_match[] = { |
| 256 | 318 | { |
| 257 | 319 | .compatible = "amlogic,axg-tdmout", |
| @@ -259,6 +321,9 @@ static const struct of_device_id axg_tdmout_of_match[] = { · 1 unmodified line | ||
| 259 | 321 | }, { |
| 260 | 322 | .compatible = "amlogic,g12a-tdmout", |
| 261 | 323 | .data = &g12a_tdmout_drv, |
| 324 | + }, { | |
| 325 | + .compatible = "amlogic,sm1-tdmout", | |
| 326 | + .data = &sm1_tdmout_drv, | |
| 262 | 327 | }, {} |
| 263 | 328 | }; |
| 264 | 329 | MODULE_DEVICE_TABLE(of, axg_tdmout_of_match); |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) |
| 26 | 26 | #define CTRL0_TODDR_LSB_POS(x) ((x) << 3) |
| 27 | 27 | #define CTRL1_TODDR_FORCE_FINISH BIT(25) |
| 28 | +#define CTRL1_SEL_SHIFT 28 | |
| 28 | 29 | |
| 29 | 30 | #define TODDR_MSB_POS 31 |
| 30 | 31 | |
| @@ -142,16 +143,11 @@ static struct snd_soc_dai_driver axg_toddr_dai_drv = { · 111 unmodified lines | ||
| 142 | 143 | }; |
| 143 | 144 | |
| 144 | 145 | static const char * const axg_toddr_sel_texts[] = { |
| 145 | − "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 6" | |
| 146 | + "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7" | |
| 146 | 147 | }; |
| 147 | 148 | |
| 148 | −static const unsigned int axg_toddr_sel_values[] = { | |
| 149 | − 0, 1, 2, 3, 4, 6 | |
| 150 | −}; | |
| 151 | − | |
| 152 | −static SOC_VALUE_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, | |
| 153 | − CTRL0_SEL_SHIFT, CTRL0_SEL_MASK, | |
| 154 | − axg_toddr_sel_texts, axg_toddr_sel_values); | |
| 149 | +static SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, | |
| 150 | + axg_toddr_sel_texts); | |
| 155 | 151 | |
| 156 | 152 | static const struct snd_kcontrol_new axg_toddr_in_mux = |
| 157 | 153 | SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum); |
| @@ -163,7 +159,9 @@ static const struct snd_soc_dapm_widget axg_toddr_dapm_widgets[] = { · 5 unmodified lines | ||
| 163 | 159 | SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 164 | 160 | SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 165 | 161 | SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 162 | + SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 166 | 163 | SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 164 | + SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 167 | 165 | }; |
| 168 | 166 | |
| 169 | 167 | static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { |
| @@ -173,7 +171,9 @@ static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { · 3 unmodified lines | ||
| 173 | 171 | { "SRC SEL", "IN 2", "IN 2" }, |
| 174 | 172 | { "SRC SEL", "IN 3", "IN 3" }, |
| 175 | 173 | { "SRC SEL", "IN 4", "IN 4" }, |
| 174 | + { "SRC SEL", "IN 5", "IN 5" }, | |
| 176 | 175 | { "SRC SEL", "IN 6", "IN 6" }, |
| 176 | + { "SRC SEL", "IN 7", "IN 7" }, | |
| 177 | 177 | }; |
| 178 | 178 | |
| 179 | 179 | static const struct snd_soc_component_driver axg_toddr_component_drv = { |
| @@ -222,6 +222,70 @@ static const struct axg_fifo_match_data g12a_toddr_match_data = { · 42 unmodified lines | ||
| 222 | 222 | .dai_drv = &g12a_toddr_dai_drv |
| 223 | 223 | }; |
| 224 | 224 | |
| 225 | +static const char * const sm1_toddr_sel_texts[] = { | |
| 226 | + "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7", | |
| 227 | + "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15" | |
| 228 | +}; | |
| 229 | + | |
| 230 | +static SOC_ENUM_SINGLE_DECL(sm1_toddr_sel_enum, FIFO_CTRL1, CTRL1_SEL_SHIFT, | |
| 231 | + sm1_toddr_sel_texts); | |
| 232 | + | |
| 233 | +static const struct snd_kcontrol_new sm1_toddr_in_mux = | |
| 234 | + SOC_DAPM_ENUM("Input Source", sm1_toddr_sel_enum); | |
| 235 | + | |
| 236 | +static const struct snd_soc_dapm_widget sm1_toddr_dapm_widgets[] = { | |
| 237 | + SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_toddr_in_mux), | |
| 238 | + SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 239 | + SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 240 | + SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 241 | + SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 242 | + SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 243 | + SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 244 | + SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 245 | + SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 246 | + SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 247 | + SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 248 | + SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 249 | + SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 250 | + SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 251 | + SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 252 | + SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 253 | + SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0), | |
| 254 | +}; | |
| 255 | + | |
| 256 | +static const struct snd_soc_dapm_route sm1_toddr_dapm_routes[] = { | |
| 257 | + { "Capture", NULL, "SRC SEL" }, | |
| 258 | + { "SRC SEL", "IN 0", "IN 0" }, | |
| 259 | + { "SRC SEL", "IN 1", "IN 1" }, | |
| 260 | + { "SRC SEL", "IN 2", "IN 2" }, | |
| 261 | + { "SRC SEL", "IN 3", "IN 3" }, | |
| 262 | + { "SRC SEL", "IN 4", "IN 4" }, | |
| 263 | + { "SRC SEL", "IN 5", "IN 5" }, | |
| 264 | + { "SRC SEL", "IN 6", "IN 6" }, | |
| 265 | + { "SRC SEL", "IN 7", "IN 7" }, | |
| 266 | + { "SRC SEL", "IN 8", "IN 8" }, | |
| 267 | + { "SRC SEL", "IN 9", "IN 9" }, | |
| 268 | + { "SRC SEL", "IN 10", "IN 10" }, | |
| 269 | + { "SRC SEL", "IN 11", "IN 11" }, | |
| 270 | + { "SRC SEL", "IN 12", "IN 12" }, | |
| 271 | + { "SRC SEL", "IN 13", "IN 13" }, | |
| 272 | + { "SRC SEL", "IN 14", "IN 14" }, | |
| 273 | + { "SRC SEL", "IN 15", "IN 15" }, | |
| 274 | +}; | |
| 275 | + | |
| 276 | +static const struct snd_soc_component_driver sm1_toddr_component_drv = { | |
| 277 | + .dapm_widgets = sm1_toddr_dapm_widgets, | |
| 278 | + .num_dapm_widgets = ARRAY_SIZE(sm1_toddr_dapm_widgets), | |
| 279 | + .dapm_routes = sm1_toddr_dapm_routes, | |
| 280 | + .num_dapm_routes = ARRAY_SIZE(sm1_toddr_dapm_routes), | |
| 281 | + .ops = &g12a_fifo_pcm_ops | |
| 282 | +}; | |
| 283 | + | |
| 284 | +static const struct axg_fifo_match_data sm1_toddr_match_data = { | |
| 285 | + .component_drv = &sm1_toddr_component_drv, | |
| 286 | + .dai_drv = &g12a_toddr_dai_drv | |
| 287 | +}; | |
| 288 | + | |
| 225 | 289 | static const struct of_device_id axg_toddr_of_match[] = { |
| 226 | 290 | { |
| 227 | 291 | .compatible = "amlogic,axg-toddr", |
| @@ -229,6 +293,9 @@ static const struct of_device_id axg_toddr_of_match[] = { · 1 unmodified line | ||
| 229 | 293 | }, { |
| 230 | 294 | .compatible = "amlogic,g12a-toddr", |
| 231 | 295 | .data = &g12a_toddr_match_data, |
| 296 | + }, { | |
| 297 | + .compatible = "amlogic,sm1-toddr", | |
| 298 | + .data = &sm1_toddr_match_data, | |
| 232 | 299 | }, {} |
| 233 | 300 | }; |
| 234 | 301 | MODULE_DEVICE_TABLE(of, axg_toddr_of_match); |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #define CTRL0_SPDIF_CLK_SEL BIT(0) |
| 29 | 29 | |
| 30 | 30 | struct g12a_tohdmitx_input { |
| 31 | − struct snd_pcm_hw_params params; | |
| 31 | + struct snd_soc_pcm_stream params; | |
| 32 | 32 | unsigned int fmt; |
| 33 | 33 | }; |
| 34 | 34 | |
| @@ -225,26 +225,17 @@ static int g12a_tohdmitx_input_hw_params(struct snd_pcm_substream *substream, · 190 unmodified lines | ||
| 225 | 225 | { |
| 226 | 226 | struct g12a_tohdmitx_input *data = dai->playback_dma_data; |
| 227 | 227 | |
| 228 | − /* Save the stream params for the downstream link */ | |
| 229 | − memcpy(&data->params, params, sizeof(*params)); | |
| 228 | + data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params)); | |
| 229 | + data->params.rate_min = params_rate(params); | |
| 230 | + data->params.rate_max = params_rate(params); | |
| 231 | + data->params.formats = 1 << params_format(params); | |
| 232 | + data->params.channels_min = params_channels(params); | |
| 233 | + data->params.channels_max = params_channels(params); | |
| 234 | + data->params.sig_bits = dai->driver->playback.sig_bits; | |
| 230 | 235 | |
| 231 | 236 | return 0; |
| 232 | 237 | } |
| 233 | 238 | |
| 234 | −static int g12a_tohdmitx_output_hw_params(struct snd_pcm_substream *substream, | |
| 235 | − struct snd_pcm_hw_params *params, | |
| 236 | − struct snd_soc_dai *dai) | |
| 237 | −{ | |
| 238 | − struct g12a_tohdmitx_input *in_data = | |
| 239 | − g12a_tohdmitx_get_input_data(dai->capture_widget); | |
| 240 | − | |
| 241 | − if (!in_data) | |
| 242 | − return -ENODEV; | |
| 243 | − | |
| 244 | − memcpy(params, &in_data->params, sizeof(*params)); | |
| 245 | − | |
| 246 | − return 0; | |
| 247 | −} | |
| 248 | 239 | |
| 249 | 240 | static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai, |
| 250 | 241 | unsigned int fmt) |
| @@ -266,6 +257,14 @@ static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream, · 15 unmodified lines | ||
| 266 | 257 | if (!in_data) |
| 267 | 258 | return -ENODEV; |
| 268 | 259 | |
| 260 | + if (WARN_ON(!rtd->dai_link->params)) { | |
| 261 | + dev_warn(dai->dev, "codec2codec link expected\n"); | |
| 262 | + return -EINVAL; | |
| 263 | + } | |
| 264 | + | |
| 265 | + /* Replace link params with the input params */ | |
| 266 | + rtd->dai_link->params = &in_data->params; | |
| 267 | + | |
| 269 | 268 | if (!in_data->fmt) |
| 270 | 269 | return 0; |
| 271 | 270 | |
| @@ -278,7 +277,6 @@ static const struct snd_soc_dai_ops g12a_tohdmitx_input_ops = { · 6 unmodified lines | ||
| 278 | 277 | }; |
| 279 | 278 | |
| 280 | 279 | static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = { |
| 281 | − .hw_params = g12a_tohdmitx_output_hw_params, | |
| 282 | 280 | .startup = g12a_tohdmitx_output_startup, |
| 283 | 281 | }; |
| 284 | 282 | |
| @@ -378,12 +376,10 @@ MODULE_DEVICE_TABLE(of, g12a_tohdmitx_of_match); · 93 unmodified lines | ||
| 378 | 376 | static int g12a_tohdmitx_probe(struct platform_device *pdev) |
| 379 | 377 | { |
| 380 | 378 | struct device *dev = &pdev->dev; |
| 381 | − struct resource *res; | |
| 382 | 379 | void __iomem *regs; |
| 383 | 380 | struct regmap *map; |
| 384 | 381 | |
| 385 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 386 | − regs = devm_ioremap_resource(dev, res); | |
| 382 | + regs = devm_platform_ioremap_resource(pdev, 0); | |
| 387 | 383 | if (IS_ERR(regs)) |
| 388 | 384 | return PTR_ERR(regs); |
| 389 | 385 | |
| @@ -732,7 +732,6 @@ static int mxs_saif_mclk_init(struct platform_device *pdev) · 731 unmodified lines | ||
| 732 | 732 | static int mxs_saif_probe(struct platform_device *pdev) |
| 733 | 733 | { |
| 734 | 734 | struct device_node *np = pdev->dev.of_node; |
| 735 | − struct resource *iores; | |
| 736 | 735 | struct mxs_saif *saif; |
| 737 | 736 | int irq, ret = 0; |
| 738 | 737 | struct device_node *master; |
| @@ -786,19 +785,13 @@ static int mxs_saif_probe(struct platform_device *pdev) · 47 unmodified lines | ||
| 786 | 785 | return ret; |
| 787 | 786 | } |
| 788 | 787 | |
| 789 | − iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 790 | − | |
| 791 | − saif->base = devm_ioremap_resource(&pdev->dev, iores); | |
| 788 | + saif->base = devm_platform_ioremap_resource(pdev, 0); | |
| 792 | 789 | if (IS_ERR(saif->base)) |
| 793 | 790 | return PTR_ERR(saif->base); |
| 794 | 791 | |
| 795 | 792 | irq = platform_get_irq(pdev, 0); |
| 796 | − if (irq < 0) { | |
| 797 | − ret = irq; | |
| 798 | − dev_err(&pdev->dev, "failed to get irq resource: %d\n", | |
| 799 | − ret); | |
| 800 | − return ret; | |
| 801 | − } | |
| 793 | + if (irq < 0) | |
| 794 | + return irq; | |
| 802 | 795 | |
| 803 | 796 | saif->dev = &pdev->dev; |
| 804 | 797 | ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0, |
| @@ -1,29 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −## | |
| 3 | −## NUC900 series AC97 API | |
| 4 | −## | |
| 5 | −config SND_SOC_NUC900 | |
| 6 | − tristate "SoC Audio for NUC900 series" | |
| 7 | − depends on ARCH_W90X900 | |
| 8 | − select SND_SOC_NUC900_AC97 | |
| 9 | − help | |
| 10 | − This option enables support for AC97 mode on the NUC900 SoC. | |
| 11 | − | |
| 12 | −config SND_SOC_NUC900_AC97 | |
| 13 | − tristate | |
| 14 | − select AC97_BUS | |
| 15 | − select SND_AC97_CODEC | |
| 16 | − select SND_SOC_AC97_BUS | |
| 17 | − | |
| 18 | − | |
| 19 | −## | |
| 20 | −## Boards | |
| 21 | −## | |
| 22 | −config SND_SOC_NUC900EVB | |
| 23 | − tristate "NUC900 AC97 support for demo board" | |
| 24 | − depends on SND_SOC_NUC900 | |
| 25 | − select SND_SOC_NUC900_AC97 | |
| 26 | − select SND_SOC_AC97_CODEC | |
| 27 | − help | |
| 28 | − Select this option to enable audio (AC97) on the | |
| 29 | − NUC900 demoboard. | |
| @@ -1,12 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0 | |
| 2 | −# NUC900 series audio | |
| 3 | −snd-soc-nuc900-pcm-objs := nuc900-pcm.o | |
| 4 | −snd-soc-nuc900-ac97-objs := nuc900-ac97.o | |
| 5 | − | |
| 6 | −obj-$(CONFIG_SND_SOC_NUC900) += snd-soc-nuc900-pcm.o | |
| 7 | −obj-$(CONFIG_SND_SOC_NUC900_AC97) += snd-soc-nuc900-ac97.o | |
| 8 | − | |
| 9 | −# Boards | |
| 10 | −snd-soc-nuc900-audio-objs := nuc900-audio.o | |
| 11 | − | |
| 12 | −obj-$(CONFIG_SND_SOC_NUC900EVB) += snd-soc-nuc900-audio.o | |
| @@ -1,391 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −/* | |
| 3 | − * Copyright (c) 2009-2010 Nuvoton technology corporation. | |
| 4 | − * | |
| 5 | − * Wan ZongShun <mcuos.com@gmail.com> | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#include <linux/init.h> | |
| 9 | −#include <linux/module.h> | |
| 10 | −#include <linux/slab.h> | |
| 11 | −#include <linux/device.h> | |
| 12 | −#include <linux/delay.h> | |
| 13 | −#include <linux/mutex.h> | |
| 14 | −#include <linux/suspend.h> | |
| 15 | −#include <sound/core.h> | |
| 16 | −#include <sound/pcm.h> | |
| 17 | −#include <sound/initval.h> | |
| 18 | −#include <sound/soc.h> | |
| 19 | −#include <linux/clk.h> | |
| 20 | − | |
| 21 | −#include <mach/mfp.h> | |
| 22 | − | |
| 23 | −#include "nuc900-audio.h" | |
| 24 | − | |
| 25 | −static DEFINE_MUTEX(ac97_mutex); | |
| 26 | −struct nuc900_audio *nuc900_ac97_data; | |
| 27 | −EXPORT_SYMBOL_GPL(nuc900_ac97_data); | |
| 28 | − | |
| 29 | −static int nuc900_checkready(void) | |
| 30 | −{ | |
| 31 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 32 | − | |
| 33 | − if (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS0) & CODEC_READY)) | |
| 34 | − return -EPERM; | |
| 35 | − | |
| 36 | − return 0; | |
| 37 | −} | |
| 38 | − | |
| 39 | −/* AC97 controller reads codec register */ | |
| 40 | −static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97, | |
| 41 | − unsigned short reg) | |
| 42 | −{ | |
| 43 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 44 | − unsigned long timeout = 0x10000, val; | |
| 45 | − | |
| 46 | − mutex_lock(&ac97_mutex); | |
| 47 | − | |
| 48 | − val = nuc900_checkready(); | |
| 49 | − if (val) { | |
| 50 | − dev_err(nuc900_audio->dev, "AC97 codec is not ready\n"); | |
| 51 | − goto out; | |
| 52 | − } | |
| 53 | − | |
| 54 | − /* set the R_WB bit and write register index */ | |
| 55 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, R_WB | reg); | |
| 56 | − | |
| 57 | − /* set the valid frame bit and valid slots */ | |
| 58 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); | |
| 59 | − val |= (VALID_FRAME | SLOT1_VALID); | |
| 60 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val); | |
| 61 | − | |
| 62 | − udelay(100); | |
| 63 | − | |
| 64 | − /* polling the AC_R_FINISH */ | |
| 65 | − while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH) | |
| 66 | − && --timeout) | |
| 67 | − mdelay(1); | |
| 68 | − | |
| 69 | − if (!timeout) { | |
| 70 | − dev_err(nuc900_audio->dev, "AC97 read register time out !\n"); | |
| 71 | − val = -EPERM; | |
| 72 | − goto out; | |
| 73 | − } | |
| 74 | − | |
| 75 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0) ; | |
| 76 | − val &= ~SLOT1_VALID; | |
| 77 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val); | |
| 78 | − | |
| 79 | − if (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS1) >> 2 != reg) { | |
| 80 | − dev_err(nuc900_audio->dev, | |
| 81 | − "R_INDEX of REG_ACTL_ACIS1 not match!\n"); | |
| 82 | − } | |
| 83 | − | |
| 84 | − udelay(100); | |
| 85 | − val = (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS2) & 0xFFFF); | |
| 86 | − | |
| 87 | −out: | |
| 88 | − mutex_unlock(&ac97_mutex); | |
| 89 | − return val; | |
| 90 | −} | |
| 91 | − | |
| 92 | −/* AC97 controller writes to codec register */ | |
| 93 | −static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |
| 94 | − unsigned short val) | |
| 95 | −{ | |
| 96 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 97 | − unsigned long tmp, timeout = 0x10000; | |
| 98 | − | |
| 99 | − mutex_lock(&ac97_mutex); | |
| 100 | − | |
| 101 | − tmp = nuc900_checkready(); | |
| 102 | − if (tmp) | |
| 103 | − dev_err(nuc900_audio->dev, "AC97 codec is not ready\n"); | |
| 104 | − | |
| 105 | − /* clear the R_WB bit and write register index */ | |
| 106 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, reg); | |
| 107 | − | |
| 108 | − /* write register value */ | |
| 109 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS2, val); | |
| 110 | − | |
| 111 | − /* set the valid frame bit and valid slots */ | |
| 112 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); | |
| 113 | − tmp |= SLOT1_VALID | SLOT2_VALID | VALID_FRAME; | |
| 114 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); | |
| 115 | − | |
| 116 | − udelay(100); | |
| 117 | − | |
| 118 | − /* polling the AC_W_FINISH */ | |
| 119 | − while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH) | |
| 120 | − && --timeout) | |
| 121 | − mdelay(1); | |
| 122 | − | |
| 123 | − if (!timeout) | |
| 124 | − dev_err(nuc900_audio->dev, "AC97 write register time out !\n"); | |
| 125 | − | |
| 126 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); | |
| 127 | − tmp &= ~(SLOT1_VALID | SLOT2_VALID); | |
| 128 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); | |
| 129 | − | |
| 130 | − mutex_unlock(&ac97_mutex); | |
| 131 | − | |
| 132 | −} | |
| 133 | − | |
| 134 | −static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97) | |
| 135 | −{ | |
| 136 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 137 | − unsigned long val; | |
| 138 | − | |
| 139 | − mutex_lock(&ac97_mutex); | |
| 140 | − | |
| 141 | − /* warm reset AC 97 */ | |
| 142 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON); | |
| 143 | − val |= AC_W_RES; | |
| 144 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val); | |
| 145 | − | |
| 146 | − udelay(100); | |
| 147 | − | |
| 148 | − val = nuc900_checkready(); | |
| 149 | − if (val) | |
| 150 | − dev_err(nuc900_audio->dev, "AC97 codec is not ready\n"); | |
| 151 | − | |
| 152 | − mutex_unlock(&ac97_mutex); | |
| 153 | −} | |
| 154 | − | |
| 155 | −static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97) | |
| 156 | −{ | |
| 157 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 158 | − unsigned long val; | |
| 159 | − | |
| 160 | − mutex_lock(&ac97_mutex); | |
| 161 | − | |
| 162 | − /* reset Audio Controller */ | |
| 163 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 164 | − val |= ACTL_RESET_BIT; | |
| 165 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 166 | − | |
| 167 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 168 | − val &= (~ACTL_RESET_BIT); | |
| 169 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 170 | − | |
| 171 | − /* reset AC-link interface */ | |
| 172 | − | |
| 173 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 174 | − val |= AC_RESET; | |
| 175 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 176 | − | |
| 177 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 178 | − val &= ~AC_RESET; | |
| 179 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 180 | − | |
| 181 | − /* cold reset AC 97 */ | |
| 182 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON); | |
| 183 | − val |= AC_C_RES; | |
| 184 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val); | |
| 185 | − | |
| 186 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON); | |
| 187 | − val &= (~AC_C_RES); | |
| 188 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val); | |
| 189 | − | |
| 190 | − udelay(100); | |
| 191 | − | |
| 192 | − mutex_unlock(&ac97_mutex); | |
| 193 | − | |
| 194 | −} | |
| 195 | − | |
| 196 | −/* AC97 controller operations */ | |
| 197 | −static struct snd_ac97_bus_ops nuc900_ac97_ops = { | |
| 198 | − .read = nuc900_ac97_read, | |
| 199 | − .write = nuc900_ac97_write, | |
| 200 | − .reset = nuc900_ac97_cold_reset, | |
| 201 | − .warm_reset = nuc900_ac97_warm_reset, | |
| 202 | −}; | |
| 203 | − | |
| 204 | −static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, | |
| 205 | − int cmd, struct snd_soc_dai *dai) | |
| 206 | −{ | |
| 207 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 208 | − int ret; | |
| 209 | − unsigned long val, tmp; | |
| 210 | − | |
| 211 | − ret = 0; | |
| 212 | − | |
| 213 | − switch (cmd) { | |
| 214 | − case SNDRV_PCM_TRIGGER_START: | |
| 215 | − case SNDRV_PCM_TRIGGER_RESUME: | |
| 216 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 217 | − if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
| 218 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); | |
| 219 | − tmp |= (SLOT3_VALID | SLOT4_VALID | VALID_FRAME); | |
| 220 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); | |
| 221 | − | |
| 222 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR); | |
| 223 | − tmp |= (P_DMA_END_IRQ | P_DMA_MIDDLE_IRQ); | |
| 224 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, tmp); | |
| 225 | − val |= AC_PLAY; | |
| 226 | − } else { | |
| 227 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR); | |
| 228 | − tmp |= (R_DMA_END_IRQ | R_DMA_MIDDLE_IRQ); | |
| 229 | − | |
| 230 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, tmp); | |
| 231 | − val |= AC_RECORD; | |
| 232 | − } | |
| 233 | − | |
| 234 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 235 | − | |
| 236 | − break; | |
| 237 | − case SNDRV_PCM_TRIGGER_STOP: | |
| 238 | − case SNDRV_PCM_TRIGGER_SUSPEND: | |
| 239 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 240 | − if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
| 241 | − tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0); | |
| 242 | − tmp &= ~(SLOT3_VALID | SLOT4_VALID); | |
| 243 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp); | |
| 244 | − | |
| 245 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, RESET_PRSR); | |
| 246 | − val &= ~AC_PLAY; | |
| 247 | − } else { | |
| 248 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, RESET_PRSR); | |
| 249 | − val &= ~AC_RECORD; | |
| 250 | − } | |
| 251 | − | |
| 252 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 253 | − | |
| 254 | − break; | |
| 255 | − default: | |
| 256 | − ret = -EINVAL; | |
| 257 | − } | |
| 258 | − | |
| 259 | − return ret; | |
| 260 | −} | |
| 261 | − | |
| 262 | −static int nuc900_ac97_probe(struct snd_soc_dai *dai) | |
| 263 | −{ | |
| 264 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 265 | − unsigned long val; | |
| 266 | − | |
| 267 | − mutex_lock(&ac97_mutex); | |
| 268 | − | |
| 269 | − /* enable unit clock */ | |
| 270 | − clk_enable(nuc900_audio->clk); | |
| 271 | − | |
| 272 | − /* enable audio controller and AC-link interface */ | |
| 273 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON); | |
| 274 | − val |= (IIS_AC_PIN_SEL | ACLINK_EN); | |
| 275 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val); | |
| 276 | − | |
| 277 | − mutex_unlock(&ac97_mutex); | |
| 278 | − | |
| 279 | − return 0; | |
| 280 | −} | |
| 281 | − | |
| 282 | −static int nuc900_ac97_remove(struct snd_soc_dai *dai) | |
| 283 | −{ | |
| 284 | − struct nuc900_audio *nuc900_audio = nuc900_ac97_data; | |
| 285 | − | |
| 286 | − clk_disable(nuc900_audio->clk); | |
| 287 | − return 0; | |
| 288 | −} | |
| 289 | − | |
| 290 | −static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = { | |
| 291 | − .trigger = nuc900_ac97_trigger, | |
| 292 | −}; | |
| 293 | − | |
| 294 | −static struct snd_soc_dai_driver nuc900_ac97_dai = { | |
| 295 | − .probe = nuc900_ac97_probe, | |
| 296 | − .remove = nuc900_ac97_remove, | |
| 297 | − .bus_control = true, | |
| 298 | − .playback = { | |
| 299 | − .rates = SNDRV_PCM_RATE_8000_48000, | |
| 300 | − .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 301 | − .channels_min = 1, | |
| 302 | − .channels_max = 2, | |
| 303 | − }, | |
| 304 | − .capture = { | |
| 305 | − .rates = SNDRV_PCM_RATE_8000_48000, | |
| 306 | − .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 307 | − .channels_min = 1, | |
| 308 | − .channels_max = 2, | |
| 309 | − }, | |
| 310 | − .ops = &nuc900_ac97_dai_ops, | |
| 311 | −}; | |
| 312 | − | |
| 313 | −static const struct snd_soc_component_driver nuc900_ac97_component = { | |
| 314 | − .name = "nuc900-ac97", | |
| 315 | −}; | |
| 316 | − | |
| 317 | −static int nuc900_ac97_drvprobe(struct platform_device *pdev) | |
| 318 | −{ | |
| 319 | − struct nuc900_audio *nuc900_audio; | |
| 320 | − int ret; | |
| 321 | − | |
| 322 | − if (nuc900_ac97_data) | |
| 323 | − return -EBUSY; | |
| 324 | − | |
| 325 | − nuc900_audio = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_audio), | |
| 326 | − GFP_KERNEL); | |
| 327 | − if (!nuc900_audio) | |
| 328 | − return -ENOMEM; | |
| 329 | − | |
| 330 | − spin_lock_init(&nuc900_audio->lock); | |
| 331 | − | |
| 332 | − nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 333 | − nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev, | |
| 334 | − nuc900_audio->res); | |
| 335 | − if (IS_ERR(nuc900_audio->mmio)) | |
| 336 | − return PTR_ERR(nuc900_audio->mmio); | |
| 337 | − | |
| 338 | − nuc900_audio->clk = devm_clk_get(&pdev->dev, NULL); | |
| 339 | − if (IS_ERR(nuc900_audio->clk)) { | |
| 340 | − ret = PTR_ERR(nuc900_audio->clk); | |
| 341 | − goto out; | |
| 342 | − } | |
| 343 | − | |
| 344 | − ret = platform_get_irq(pdev, 0); | |
| 345 | − if (ret < 0) | |
| 346 | − goto out; | |
| 347 | − nuc900_audio->irq_num = ret; | |
| 348 | − | |
| 349 | − nuc900_ac97_data = nuc900_audio; | |
| 350 | − | |
| 351 | − ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops); | |
| 352 | − if (ret) | |
| 353 | − goto out; | |
| 354 | − | |
| 355 | − ret = devm_snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, | |
| 356 | − &nuc900_ac97_dai, 1); | |
| 357 | − if (ret) | |
| 358 | − goto out; | |
| 359 | − | |
| 360 | − /* enbale ac97 multifunction pin */ | |
| 361 | − mfp_set_groupg(nuc900_audio->dev, NULL); | |
| 362 | − | |
| 363 | − return 0; | |
| 364 | − | |
| 365 | −out: | |
| 366 | − snd_soc_set_ac97_ops(NULL); | |
| 367 | − return ret; | |
| 368 | −} | |
| 369 | − | |
| 370 | −static int nuc900_ac97_drvremove(struct platform_device *pdev) | |
| 371 | −{ | |
| 372 | − nuc900_ac97_data = NULL; | |
| 373 | − snd_soc_set_ac97_ops(NULL); | |
| 374 | − | |
| 375 | − return 0; | |
| 376 | −} | |
| 377 | − | |
| 378 | −static struct platform_driver nuc900_ac97_driver = { | |
| 379 | − .driver = { | |
| 380 | − .name = "nuc900-ac97", | |
| 381 | − }, | |
| 382 | − .probe = nuc900_ac97_drvprobe, | |
| 383 | − .remove = nuc900_ac97_drvremove, | |
| 384 | −}; | |
| 385 | − | |
| 386 | −module_platform_driver(nuc900_ac97_driver); | |
| 387 | − | |
| 388 | −MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | |
| 389 | −MODULE_DESCRIPTION("NUC900 AC97 SoC driver!"); | |
| 390 | −MODULE_LICENSE("GPL"); | |
| 391 | −MODULE_ALIAS("platform:nuc900-ac97"); | |
| @@ -1,73 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −/* | |
| 3 | − * Copyright (c) 2010 Nuvoton technology corporation. | |
| 4 | − * | |
| 5 | − * Wan ZongShun <mcuos.com@gmail.com> | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#include <linux/module.h> | |
| 9 | −#include <linux/moduleparam.h> | |
| 10 | −#include <linux/timer.h> | |
| 11 | −#include <linux/interrupt.h> | |
| 12 | −#include <linux/platform_device.h> | |
| 13 | − | |
| 14 | −#include <sound/core.h> | |
| 15 | −#include <sound/pcm.h> | |
| 16 | −#include <sound/soc.h> | |
| 17 | − | |
| 18 | −#include "nuc900-audio.h" | |
| 19 | − | |
| 20 | −SND_SOC_DAILINK_DEFS(ac97, | |
| 21 | − DAILINK_COMP_ARRAY(COMP_CPU("nuc900-ac97")), | |
| 22 | − DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")), | |
| 23 | − DAILINK_COMP_ARRAY(COMP_PLATFORM("nuc900-pcm-audio"))); | |
| 24 | − | |
| 25 | −static struct snd_soc_dai_link nuc900evb_ac97_dai = { | |
| 26 | − .name = "AC97", | |
| 27 | − .stream_name = "AC97 HiFi", | |
| 28 | − SND_SOC_DAILINK_REG(ac97), | |
| 29 | −}; | |
| 30 | − | |
| 31 | −static struct snd_soc_card nuc900evb_audio_machine = { | |
| 32 | − .name = "NUC900EVB_AC97", | |
| 33 | − .owner = THIS_MODULE, | |
| 34 | − .dai_link = &nuc900evb_ac97_dai, | |
| 35 | − .num_links = 1, | |
| 36 | −}; | |
| 37 | − | |
| 38 | −static struct platform_device *nuc900evb_asoc_dev; | |
| 39 | − | |
| 40 | −static int __init nuc900evb_audio_init(void) | |
| 41 | −{ | |
| 42 | − int ret; | |
| 43 | − | |
| 44 | − ret = -ENOMEM; | |
| 45 | − nuc900evb_asoc_dev = platform_device_alloc("soc-audio", -1); | |
| 46 | − if (!nuc900evb_asoc_dev) | |
| 47 | − goto out; | |
| 48 | − | |
| 49 | − /* nuc900 board audio device */ | |
| 50 | − platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_audio_machine); | |
| 51 | − | |
| 52 | − ret = platform_device_add(nuc900evb_asoc_dev); | |
| 53 | − | |
| 54 | − if (ret) { | |
| 55 | − platform_device_put(nuc900evb_asoc_dev); | |
| 56 | − nuc900evb_asoc_dev = NULL; | |
| 57 | − } | |
| 58 | − | |
| 59 | −out: | |
| 60 | − return ret; | |
| 61 | −} | |
| 62 | − | |
| 63 | −static void __exit nuc900evb_audio_exit(void) | |
| 64 | −{ | |
| 65 | − platform_device_unregister(nuc900evb_asoc_dev); | |
| 66 | −} | |
| 67 | − | |
| 68 | −module_init(nuc900evb_audio_init); | |
| 69 | −module_exit(nuc900evb_audio_exit); | |
| 70 | − | |
| 71 | −MODULE_LICENSE("GPL"); | |
| 72 | −MODULE_DESCRIPTION("NUC900 Series ASoC audio support"); | |
| 73 | −MODULE_AUTHOR("Wan ZongShun"); | |
| @@ -1,108 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | −/* | |
| 3 | − * Copyright (c) 2010 Nuvoton technology corporation. | |
| 4 | − * | |
| 5 | − * Wan ZongShun <mcuos.com@gmail.com> | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#ifndef _NUC900_AUDIO_H | |
| 9 | −#define _NUC900_AUDIO_H | |
| 10 | − | |
| 11 | −#include <linux/io.h> | |
| 12 | − | |
| 13 | −/* Audio Control Registers */ | |
| 14 | −#define ACTL_CON 0x00 | |
| 15 | −#define ACTL_RESET 0x04 | |
| 16 | −#define ACTL_RDSTB 0x08 | |
| 17 | −#define ACTL_RDST_LENGTH 0x0C | |
| 18 | −#define ACTL_RDSTC 0x10 | |
| 19 | −#define ACTL_RSR 0x14 | |
| 20 | −#define ACTL_PDSTB 0x18 | |
| 21 | −#define ACTL_PDST_LENGTH 0x1C | |
| 22 | −#define ACTL_PDSTC 0x20 | |
| 23 | −#define ACTL_PSR 0x24 | |
| 24 | −#define ACTL_IISCON 0x28 | |
| 25 | −#define ACTL_ACCON 0x2C | |
| 26 | −#define ACTL_ACOS0 0x30 | |
| 27 | −#define ACTL_ACOS1 0x34 | |
| 28 | −#define ACTL_ACOS2 0x38 | |
| 29 | −#define ACTL_ACIS0 0x3C | |
| 30 | −#define ACTL_ACIS1 0x40 | |
| 31 | −#define ACTL_ACIS2 0x44 | |
| 32 | −#define ACTL_COUNTER 0x48 | |
| 33 | − | |
| 34 | −/* bit definition of REG_ACTL_CON register */ | |
| 35 | −#define R_DMA_IRQ 0x1000 | |
| 36 | −#define T_DMA_IRQ 0x0800 | |
| 37 | −#define IIS_AC_PIN_SEL 0x0100 | |
| 38 | −#define FIFO_TH 0x0080 | |
| 39 | −#define ADC_EN 0x0010 | |
| 40 | −#define M80_EN 0x0008 | |
| 41 | −#define ACLINK_EN 0x0004 | |
| 42 | −#define IIS_EN 0x0002 | |
| 43 | − | |
| 44 | −/* bit definition of REG_ACTL_RESET register */ | |
| 45 | −#define W5691_PLAY 0x20000 | |
| 46 | −#define ACTL_RESET_BIT 0x10000 | |
| 47 | −#define RECORD_RIGHT_CHNNEL 0x08000 | |
| 48 | −#define RECORD_LEFT_CHNNEL 0x04000 | |
| 49 | −#define PLAY_RIGHT_CHNNEL 0x02000 | |
| 50 | −#define PLAY_LEFT_CHNNEL 0x01000 | |
| 51 | −#define DAC_PLAY 0x00800 | |
| 52 | −#define ADC_RECORD 0x00400 | |
| 53 | −#define M80_PLAY 0x00200 | |
| 54 | −#define AC_RECORD 0x00100 | |
| 55 | −#define AC_PLAY 0x00080 | |
| 56 | −#define IIS_RECORD 0x00040 | |
| 57 | −#define IIS_PLAY 0x00020 | |
| 58 | −#define DAC_RESET 0x00010 | |
| 59 | −#define ADC_RESET 0x00008 | |
| 60 | −#define M80_RESET 0x00004 | |
| 61 | −#define AC_RESET 0x00002 | |
| 62 | −#define IIS_RESET 0x00001 | |
| 63 | − | |
| 64 | −/* bit definition of REG_ACTL_ACCON register */ | |
| 65 | −#define AC_BCLK_PU_EN 0x20 | |
| 66 | −#define AC_R_FINISH 0x10 | |
| 67 | −#define AC_W_FINISH 0x08 | |
| 68 | −#define AC_W_RES 0x04 | |
| 69 | −#define AC_C_RES 0x02 | |
| 70 | − | |
| 71 | −/* bit definition of ACTL_RSR register */ | |
| 72 | −#define R_FIFO_EMPTY 0x04 | |
| 73 | −#define R_DMA_END_IRQ 0x02 | |
| 74 | −#define R_DMA_MIDDLE_IRQ 0x01 | |
| 75 | − | |
| 76 | −/* bit definition of ACTL_PSR register */ | |
| 77 | −#define P_FIFO_EMPTY 0x04 | |
| 78 | −#define P_DMA_END_IRQ 0x02 | |
| 79 | −#define P_DMA_MIDDLE_IRQ 0x01 | |
| 80 | − | |
| 81 | −/* bit definition of ACTL_ACOS0 register */ | |
| 82 | −#define SLOT1_VALID 0x01 | |
| 83 | −#define SLOT2_VALID 0x02 | |
| 84 | −#define SLOT3_VALID 0x04 | |
| 85 | −#define SLOT4_VALID 0x08 | |
| 86 | −#define VALID_FRAME 0x10 | |
| 87 | − | |
| 88 | −/* bit definition of ACTL_ACOS1 register */ | |
| 89 | −#define R_WB 0x80 | |
| 90 | − | |
| 91 | −#define CODEC_READY 0x10 | |
| 92 | −#define RESET_PRSR 0x00 | |
| 93 | −#define AUDIO_WRITE(addr, val) __raw_writel(val, addr) | |
| 94 | −#define AUDIO_READ(addr) __raw_readl(addr) | |
| 95 | − | |
| 96 | −struct nuc900_audio { | |
| 97 | − void __iomem *mmio; | |
| 98 | − spinlock_t lock; | |
| 99 | − unsigned long irq_num; | |
| 100 | − struct resource *res; | |
| 101 | − struct clk *clk; | |
| 102 | − struct device *dev; | |
| 103 | − | |
| 104 | −}; | |
| 105 | − | |
| 106 | −extern struct nuc900_audio *nuc900_ac97_data; | |
| 107 | − | |
| 108 | −#endif /*end _NUC900_AUDIO_H */ | |
| @@ -1,321 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −/* | |
| 3 | − * Copyright (c) 2010 Nuvoton technology corporation. | |
| 4 | − * | |
| 5 | − * Wan ZongShun <mcuos.com@gmail.com> | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#include <linux/module.h> | |
| 9 | −#include <linux/init.h> | |
| 10 | −#include <linux/io.h> | |
| 11 | −#include <linux/platform_device.h> | |
| 12 | −#include <linux/slab.h> | |
| 13 | −#include <linux/dma-mapping.h> | |
| 14 | − | |
| 15 | −#include <sound/core.h> | |
| 16 | −#include <sound/pcm.h> | |
| 17 | −#include <sound/pcm_params.h> | |
| 18 | −#include <sound/soc.h> | |
| 19 | − | |
| 20 | −#include <mach/hardware.h> | |
| 21 | − | |
| 22 | −#include "nuc900-audio.h" | |
| 23 | − | |
| 24 | −static const struct snd_pcm_hardware nuc900_pcm_hardware = { | |
| 25 | − .info = SNDRV_PCM_INFO_INTERLEAVED | | |
| 26 | − SNDRV_PCM_INFO_BLOCK_TRANSFER | | |
| 27 | − SNDRV_PCM_INFO_MMAP | | |
| 28 | − SNDRV_PCM_INFO_MMAP_VALID | | |
| 29 | − SNDRV_PCM_INFO_PAUSE | | |
| 30 | − SNDRV_PCM_INFO_RESUME, | |
| 31 | − .buffer_bytes_max = 4*1024, | |
| 32 | − .period_bytes_min = 1*1024, | |
| 33 | − .period_bytes_max = 4*1024, | |
| 34 | − .periods_min = 1, | |
| 35 | − .periods_max = 1024, | |
| 36 | −}; | |
| 37 | − | |
| 38 | −static int nuc900_dma_hw_params(struct snd_pcm_substream *substream, | |
| 39 | − struct snd_pcm_hw_params *params) | |
| 40 | −{ | |
| 41 | − return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | |
| 42 | −} | |
| 43 | − | |
| 44 | −static void nuc900_update_dma_register(struct snd_pcm_substream *substream) | |
| 45 | −{ | |
| 46 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 47 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 48 | − void __iomem *mmio_addr, *mmio_len; | |
| 49 | − | |
| 50 | − if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
| 51 | − mmio_addr = nuc900_audio->mmio + ACTL_PDSTB; | |
| 52 | − mmio_len = nuc900_audio->mmio + ACTL_PDST_LENGTH; | |
| 53 | − } else { | |
| 54 | − mmio_addr = nuc900_audio->mmio + ACTL_RDSTB; | |
| 55 | − mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH; | |
| 56 | − } | |
| 57 | − | |
| 58 | − AUDIO_WRITE(mmio_addr, runtime->dma_addr); | |
| 59 | − AUDIO_WRITE(mmio_len, runtime->dma_bytes); | |
| 60 | −} | |
| 61 | − | |
| 62 | −static void nuc900_dma_start(struct snd_pcm_substream *substream) | |
| 63 | −{ | |
| 64 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 65 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 66 | − unsigned long val; | |
| 67 | − | |
| 68 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON); | |
| 69 | − val |= (T_DMA_IRQ | R_DMA_IRQ); | |
| 70 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val); | |
| 71 | −} | |
| 72 | − | |
| 73 | −static void nuc900_dma_stop(struct snd_pcm_substream *substream) | |
| 74 | −{ | |
| 75 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 76 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 77 | − unsigned long val; | |
| 78 | − | |
| 79 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON); | |
| 80 | − val &= ~(T_DMA_IRQ | R_DMA_IRQ); | |
| 81 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val); | |
| 82 | −} | |
| 83 | − | |
| 84 | −static irqreturn_t nuc900_dma_interrupt(int irq, void *dev_id) | |
| 85 | −{ | |
| 86 | − struct snd_pcm_substream *substream = dev_id; | |
| 87 | − struct nuc900_audio *nuc900_audio = substream->runtime->private_data; | |
| 88 | − unsigned long val; | |
| 89 | − | |
| 90 | − spin_lock(&nuc900_audio->lock); | |
| 91 | − | |
| 92 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON); | |
| 93 | − | |
| 94 | − if (val & R_DMA_IRQ) { | |
| 95 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | R_DMA_IRQ); | |
| 96 | − | |
| 97 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR); | |
| 98 | − | |
| 99 | − if (val & R_DMA_MIDDLE_IRQ) { | |
| 100 | − val |= R_DMA_MIDDLE_IRQ; | |
| 101 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val); | |
| 102 | − } | |
| 103 | − | |
| 104 | − if (val & R_DMA_END_IRQ) { | |
| 105 | − val |= R_DMA_END_IRQ; | |
| 106 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val); | |
| 107 | − } | |
| 108 | − } else if (val & T_DMA_IRQ) { | |
| 109 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | T_DMA_IRQ); | |
| 110 | − | |
| 111 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR); | |
| 112 | − | |
| 113 | − if (val & P_DMA_MIDDLE_IRQ) { | |
| 114 | − val |= P_DMA_MIDDLE_IRQ; | |
| 115 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val); | |
| 116 | − } | |
| 117 | − | |
| 118 | − if (val & P_DMA_END_IRQ) { | |
| 119 | − val |= P_DMA_END_IRQ; | |
| 120 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val); | |
| 121 | − } | |
| 122 | − } else { | |
| 123 | − dev_err(nuc900_audio->dev, "Wrong DMA interrupt status!\n"); | |
| 124 | − spin_unlock(&nuc900_audio->lock); | |
| 125 | − return IRQ_HANDLED; | |
| 126 | − } | |
| 127 | − | |
| 128 | − spin_unlock(&nuc900_audio->lock); | |
| 129 | − | |
| 130 | − snd_pcm_period_elapsed(substream); | |
| 131 | − | |
| 132 | − return IRQ_HANDLED; | |
| 133 | −} | |
| 134 | − | |
| 135 | −static int nuc900_dma_hw_free(struct snd_pcm_substream *substream) | |
| 136 | −{ | |
| 137 | − snd_pcm_lib_free_pages(substream); | |
| 138 | − return 0; | |
| 139 | −} | |
| 140 | − | |
| 141 | −static int nuc900_dma_prepare(struct snd_pcm_substream *substream) | |
| 142 | −{ | |
| 143 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 144 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 145 | − unsigned long flags, val; | |
| 146 | − int ret = 0; | |
| 147 | − | |
| 148 | − spin_lock_irqsave(&nuc900_audio->lock, flags); | |
| 149 | − | |
| 150 | − nuc900_update_dma_register(substream); | |
| 151 | − | |
| 152 | − val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); | |
| 153 | − | |
| 154 | − switch (runtime->channels) { | |
| 155 | − case 1: | |
| 156 | − if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
| 157 | − val &= ~(PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL); | |
| 158 | − val |= PLAY_RIGHT_CHNNEL; | |
| 159 | − } else { | |
| 160 | − val &= ~(RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL); | |
| 161 | − val |= RECORD_RIGHT_CHNNEL; | |
| 162 | − } | |
| 163 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 164 | − break; | |
| 165 | − case 2: | |
| 166 | − if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | |
| 167 | − val |= (PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL); | |
| 168 | − else | |
| 169 | − val |= (RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL); | |
| 170 | − AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val); | |
| 171 | − break; | |
| 172 | − default: | |
| 173 | − ret = -EINVAL; | |
| 174 | − } | |
| 175 | − spin_unlock_irqrestore(&nuc900_audio->lock, flags); | |
| 176 | − return ret; | |
| 177 | −} | |
| 178 | − | |
| 179 | −static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd) | |
| 180 | −{ | |
| 181 | − int ret = 0; | |
| 182 | − | |
| 183 | − switch (cmd) { | |
| 184 | − case SNDRV_PCM_TRIGGER_START: | |
| 185 | − case SNDRV_PCM_TRIGGER_RESUME: | |
| 186 | − nuc900_dma_start(substream); | |
| 187 | − break; | |
| 188 | − | |
| 189 | − case SNDRV_PCM_TRIGGER_STOP: | |
| 190 | − case SNDRV_PCM_TRIGGER_SUSPEND: | |
| 191 | − nuc900_dma_stop(substream); | |
| 192 | − break; | |
| 193 | − | |
| 194 | − default: | |
| 195 | − ret = -EINVAL; | |
| 196 | − break; | |
| 197 | − } | |
| 198 | − | |
| 199 | − return ret; | |
| 200 | −} | |
| 201 | − | |
| 202 | −static int nuc900_dma_getposition(struct snd_pcm_substream *substream, | |
| 203 | − dma_addr_t *src, dma_addr_t *dst) | |
| 204 | −{ | |
| 205 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 206 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 207 | − | |
| 208 | − if (src != NULL) | |
| 209 | − *src = AUDIO_READ(nuc900_audio->mmio + ACTL_PDSTC); | |
| 210 | − | |
| 211 | − if (dst != NULL) | |
| 212 | − *dst = AUDIO_READ(nuc900_audio->mmio + ACTL_RDSTC); | |
| 213 | − | |
| 214 | − return 0; | |
| 215 | −} | |
| 216 | − | |
| 217 | −static snd_pcm_uframes_t nuc900_dma_pointer(struct snd_pcm_substream *substream) | |
| 218 | −{ | |
| 219 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 220 | − dma_addr_t src, dst; | |
| 221 | − unsigned long res; | |
| 222 | − | |
| 223 | − nuc900_dma_getposition(substream, &src, &dst); | |
| 224 | − | |
| 225 | − if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | |
| 226 | − res = dst - runtime->dma_addr; | |
| 227 | − else | |
| 228 | − res = src - runtime->dma_addr; | |
| 229 | − | |
| 230 | − return bytes_to_frames(substream->runtime, res); | |
| 231 | −} | |
| 232 | − | |
| 233 | −static int nuc900_dma_open(struct snd_pcm_substream *substream) | |
| 234 | −{ | |
| 235 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 236 | − struct nuc900_audio *nuc900_audio; | |
| 237 | − | |
| 238 | − snd_soc_set_runtime_hwparams(substream, &nuc900_pcm_hardware); | |
| 239 | − | |
| 240 | − nuc900_audio = nuc900_ac97_data; | |
| 241 | − | |
| 242 | − if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt, | |
| 243 | − 0, "nuc900-dma", substream)) | |
| 244 | − return -EBUSY; | |
| 245 | − | |
| 246 | − runtime->private_data = nuc900_audio; | |
| 247 | − | |
| 248 | − return 0; | |
| 249 | −} | |
| 250 | − | |
| 251 | −static int nuc900_dma_close(struct snd_pcm_substream *substream) | |
| 252 | −{ | |
| 253 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 254 | − struct nuc900_audio *nuc900_audio = runtime->private_data; | |
| 255 | − | |
| 256 | − free_irq(nuc900_audio->irq_num, substream); | |
| 257 | − | |
| 258 | − return 0; | |
| 259 | −} | |
| 260 | − | |
| 261 | −static int nuc900_dma_mmap(struct snd_pcm_substream *substream, | |
| 262 | − struct vm_area_struct *vma) | |
| 263 | −{ | |
| 264 | − struct snd_pcm_runtime *runtime = substream->runtime; | |
| 265 | − | |
| 266 | − return dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area, | |
| 267 | − runtime->dma_addr, runtime->dma_bytes); | |
| 268 | −} | |
| 269 | − | |
| 270 | −static const struct snd_pcm_ops nuc900_dma_ops = { | |
| 271 | − .open = nuc900_dma_open, | |
| 272 | − .close = nuc900_dma_close, | |
| 273 | − .ioctl = snd_pcm_lib_ioctl, | |
| 274 | − .hw_params = nuc900_dma_hw_params, | |
| 275 | − .hw_free = nuc900_dma_hw_free, | |
| 276 | − .prepare = nuc900_dma_prepare, | |
| 277 | − .trigger = nuc900_dma_trigger, | |
| 278 | − .pointer = nuc900_dma_pointer, | |
| 279 | − .mmap = nuc900_dma_mmap, | |
| 280 | −}; | |
| 281 | − | |
| 282 | −static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) | |
| 283 | −{ | |
| 284 | − struct snd_card *card = rtd->card->snd_card; | |
| 285 | − struct snd_pcm *pcm = rtd->pcm; | |
| 286 | − int ret; | |
| 287 | − | |
| 288 | − ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); | |
| 289 | − if (ret) | |
| 290 | − return ret; | |
| 291 | − | |
| 292 | − snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | |
| 293 | − card->dev, 4 * 1024, (4 * 1024) - 1); | |
| 294 | − | |
| 295 | − return 0; | |
| 296 | −} | |
| 297 | − | |
| 298 | −static const struct snd_soc_component_driver nuc900_soc_component = { | |
| 299 | − .ops = &nuc900_dma_ops, | |
| 300 | − .pcm_new = nuc900_dma_new, | |
| 301 | −}; | |
| 302 | − | |
| 303 | −static int nuc900_soc_platform_probe(struct platform_device *pdev) | |
| 304 | −{ | |
| 305 | − return devm_snd_soc_register_component(&pdev->dev, &nuc900_soc_component, | |
| 306 | − NULL, 0); | |
| 307 | −} | |
| 308 | − | |
| 309 | −static struct platform_driver nuc900_pcm_driver = { | |
| 310 | − .driver = { | |
| 311 | − .name = "nuc900-pcm-audio", | |
| 312 | − }, | |
| 313 | − | |
| 314 | − .probe = nuc900_soc_platform_probe, | |
| 315 | −}; | |
| 316 | − | |
| 317 | −module_platform_driver(nuc900_pcm_driver); | |
| 318 | − | |
| 319 | −MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>"); | |
| 320 | −MODULE_DESCRIPTION("nuc900 Audio DMA module"); | |
| 321 | −MODULE_LICENSE("GPL"); | |
| @@ -399,7 +399,6 @@ static const struct snd_soc_component_driver mmp_sspa_component = { · 398 unmodified lines | ||
| 399 | 399 | static int asoc_mmp_sspa_probe(struct platform_device *pdev) |
| 400 | 400 | { |
| 401 | 401 | struct sspa_priv *priv; |
| 402 | − struct resource *res; | |
| 403 | 402 | |
| 404 | 403 | priv = devm_kzalloc(&pdev->dev, |
| 405 | 404 | sizeof(struct sspa_priv), GFP_KERNEL); |
| @@ -417,8 +416,7 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 417 | 416 | if (priv->dma_params == NULL) |
| 418 | 417 | return -ENOMEM; |
| 419 | 418 | |
| 420 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 421 | − priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res); | |
| 419 | + priv->sspa->mmio_base = devm_platform_ioremap_resource(pdev, 0); | |
| 422 | 420 | if (IS_ERR(priv->sspa->mmio_base)) |
| 423 | 421 | return PTR_ERR(priv->sspa->mmio_base); |
| 424 | 422 | |
| @@ -53,12 +53,18 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 52 unmodified lines | ||
| 53 | 53 | link->num_cpus = 1; |
| 54 | 54 | link->num_platforms = 1; |
| 55 | 55 | |
| 56 | + ret = of_property_read_string(np, "link-name", &link->name); | |
| 57 | + if (ret) { | |
| 58 | + dev_err(card->dev, "error getting codec dai_link name\n"); | |
| 59 | + goto err; | |
| 60 | + } | |
| 61 | + | |
| 56 | 62 | cpu = of_get_child_by_name(np, "cpu"); |
| 57 | 63 | platform = of_get_child_by_name(np, "platform"); |
| 58 | 64 | codec = of_get_child_by_name(np, "codec"); |
| 59 | 65 | |
| 60 | 66 | if (!cpu) { |
| 61 | − dev_err(dev, "Can't find cpu DT node\n"); | |
| 67 | + dev_err(dev, "%s: Can't find cpu DT node\n", link->name); | |
| 62 | 68 | ret = -EINVAL; |
| 63 | 69 | goto err; |
| 64 | 70 | } |
| @@ -66,7 +72,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 1 unmodified line | ||
| 66 | 72 | ret = of_parse_phandle_with_args(cpu, "sound-dai", |
| 67 | 73 | "#sound-dai-cells", 0, &args); |
| 68 | 74 | if (ret) { |
| 69 | − dev_err(card->dev, "error getting cpu phandle\n"); | |
| 75 | + dev_err(card->dev, "%s: error getting cpu phandle\n", link->name); | |
| 70 | 76 | goto err; |
| 71 | 77 | } |
| 72 | 78 | link->cpus->of_node = args.np; |
| @@ -74,7 +80,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 1 unmodified line | ||
| 74 | 80 | |
| 75 | 81 | ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name); |
| 76 | 82 | if (ret) { |
| 77 | − dev_err(card->dev, "error getting cpu dai name\n"); | |
| 83 | + dev_err(card->dev, "%s: error getting cpu dai name\n", link->name); | |
| 78 | 84 | goto err; |
| 79 | 85 | } |
| 80 | 86 | |
| @@ -83,14 +89,14 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 2 unmodified lines | ||
| 83 | 89 | "sound-dai", |
| 84 | 90 | 0); |
| 85 | 91 | if (!link->platforms->of_node) { |
| 86 | − dev_err(card->dev, "platform dai not found\n"); | |
| 92 | + dev_err(card->dev, "%s: platform dai not found\n", link->name); | |
| 87 | 93 | ret = -EINVAL; |
| 88 | 94 | goto err; |
| 89 | 95 | } |
| 90 | 96 | |
| 91 | 97 | ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); |
| 92 | 98 | if (ret < 0) { |
| 93 | − dev_err(card->dev, "codec dai not found\n"); | |
| 99 | + dev_err(card->dev, "%s: codec dai not found\n", link->name); | |
| 94 | 100 | goto err; |
| 95 | 101 | } |
| 96 | 102 | link->no_pcm = 1; |
| @@ -110,12 +116,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 13 unmodified lines | ||
| 110 | 116 | } |
| 111 | 117 | |
| 112 | 118 | link->ignore_suspend = 1; |
| 113 | − ret = of_property_read_string(np, "link-name", &link->name); | |
| 114 | − if (ret) { | |
| 115 | − dev_err(card->dev, "error getting codec dai_link name\n"); | |
| 116 | − goto err; | |
| 117 | − } | |
| 118 | − | |
| 119 | 119 | link->nonatomic = 1; |
| 120 | 120 | link->dpcm_playback = 1; |
| 121 | 121 | link->dpcm_capture = 1; |
| @@ -564,11 +564,8 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev) · 563 unmodified lines | ||
| 564 | 564 | int ret; |
| 565 | 565 | |
| 566 | 566 | drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); |
| 567 | − if (drvdata->lpaif_irq < 0) { | |
| 568 | − dev_err(&pdev->dev, "error getting irq handle: %d\n", | |
| 569 | − drvdata->lpaif_irq); | |
| 567 | + if (drvdata->lpaif_irq < 0) | |
| 570 | 568 | return -ENODEV; |
| 571 | − } | |
| 572 | 569 | |
| 573 | 570 | /* ensure audio hardware is disabled */ |
| 574 | 571 | ret = regmap_write(drvdata->lpaif_map, |
| @@ -419,6 +419,9 @@ static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, · 418 unmodified lines | ||
| 419 | 419 | struct rk_i2s_dev *i2s = to_info(cpu_dai); |
| 420 | 420 | int ret; |
| 421 | 421 | |
| 422 | + if (freq == 0) | |
| 423 | + return 0; | |
| 424 | + | |
| 422 | 425 | ret = clk_set_rate(i2s->mclk, freq); |
| 423 | 426 | if (ret) |
| 424 | 427 | dev_err(i2s->dev, "Fail to set mclk %d\n", ret); |
| @@ -45,7 +45,6 @@ static const struct snd_soc_dapm_widget rk_dapm_widgets[] = { · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | static const struct snd_soc_dapm_route rk_audio_map[] = { |
| 47 | 47 | {"IN34", NULL, "Headset Mic"}, |
| 48 | − {"IN34", NULL, "MICBIAS"}, | |
| 49 | 48 | {"Headset Mic", NULL, "MICBIAS"}, |
| 50 | 49 | {"DMICL", NULL, "Int Mic"}, |
| 51 | 50 | {"Headphone", NULL, "HPL"}, |
| @@ -172,7 +171,7 @@ static struct snd_soc_dai_link rk_dailink = { · 120 unmodified lines | ||
| 172 | 171 | static int rk_98090_headset_init(struct snd_soc_component *component); |
| 173 | 172 | |
| 174 | 173 | static struct snd_soc_aux_dev rk_98090_headset_dev = { |
| 175 | − .name = "Headset Chip", | |
| 174 | + .dlc = COMP_EMPTY(), | |
| 176 | 175 | .init = rk_98090_headset_init, |
| 177 | 176 | }; |
| 178 | 177 | |
| @@ -238,9 +237,9 @@ static int snd_rk_mc_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 238 | 237 | |
| 239 | 238 | rk_dailink.platforms->of_node = rk_dailink.cpus->of_node; |
| 240 | 239 | |
| 241 | − rk_98090_headset_dev.codec_of_node = of_parse_phandle(np, | |
| 240 | + rk_98090_headset_dev.dlc.of_node = of_parse_phandle(np, | |
| 242 | 241 | "rockchip,headset-codec", 0); |
| 243 | − if (!rk_98090_headset_dev.codec_of_node) { | |
| 242 | + if (!rk_98090_headset_dev.dlc.of_node) { | |
| 244 | 243 | dev_err(&pdev->dev, |
| 245 | 244 | "Property 'rockchip,headset-codec' missing/invalid\n"); |
| 246 | 245 | return -EINVAL; |
| @@ -297,8 +297,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { · 296 unmodified lines | ||
| 297 | 297 | |
| 298 | 298 | static struct snd_soc_aux_dev neo1973_aux_devs[] = { |
| 299 | 299 | { |
| 300 | − .name = "dfbmcs320", | |
| 301 | − .codec_name = "dfbmcs320.0", | |
| 300 | + .dlc = COMP_AUX("dfbmcs320.0"), | |
| 302 | 301 | }, |
| 303 | 302 | }; |
| 304 | 303 | |
| @@ -240,8 +240,7 @@ static int speyside_wm9081_init(struct snd_soc_component *component) · 239 unmodified lines | ||
| 240 | 240 | |
| 241 | 241 | static struct snd_soc_aux_dev speyside_aux_dev[] = { |
| 242 | 242 | { |
| 243 | − .name = "wm9081", | |
| 244 | − .codec_name = "wm9081.1-006c", | |
| 243 | + .dlc = COMP_AUX("wm9081.1-006c"), | |
| 245 | 244 | .init = speyside_wm9081_init, |
| 246 | 245 | }, |
| 247 | 246 | }; |
| @@ -307,7 +307,6 @@ static struct snd_soc_aux_dev tm2_speaker_amp_dev; · 306 unmodified lines | ||
| 307 | 307 | static int tm2_late_probe(struct snd_soc_card *card) |
| 308 | 308 | { |
| 309 | 309 | struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); |
| 310 | − struct snd_soc_dai_link_component dlc = { 0 }; | |
| 311 | 310 | unsigned int ch_map[] = { 0, 1 }; |
| 312 | 311 | struct snd_soc_dai *amp_pdm_dai; |
| 313 | 312 | struct snd_soc_pcm_runtime *rtd; |
| @@ -334,8 +333,7 @@ static int tm2_late_probe(struct snd_soc_card *card) · 20 unmodified lines | ||
| 334 | 333 | return ret; |
| 335 | 334 | } |
| 336 | 335 | |
| 337 | − dlc.of_node = tm2_speaker_amp_dev.codec_of_node; | |
| 338 | − amp_pdm_dai = snd_soc_find_dai(&dlc); | |
| 336 | + amp_pdm_dai = snd_soc_find_dai(&tm2_speaker_amp_dev.dlc); | |
| 339 | 337 | if (!amp_pdm_dai) |
| 340 | 338 | return -ENODEV; |
| 341 | 339 | |
| @@ -532,9 +530,9 @@ static int tm2_probe(struct platform_device *pdev) · 190 unmodified lines | ||
| 532 | 530 | return ret; |
| 533 | 531 | } |
| 534 | 532 | |
| 535 | − card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node, | |
| 533 | + card->aux_dev[0].dlc.of_node = of_parse_phandle(dev->of_node, | |
| 536 | 534 | "audio-amplifier", 0); |
| 537 | − if (!card->aux_dev[0].codec_of_node) { | |
| 535 | + if (!card->aux_dev[0].dlc.of_node) { | |
| 538 | 536 | dev_err(dev, "audio-amplifier property invalid or missing\n"); |
| 539 | 537 | return -EINVAL; |
| 540 | 538 | } |
| @@ -623,7 +621,7 @@ dai_node_put: · 82 unmodified lines | ||
| 623 | 621 | of_node_put(cpu_dai_node[i]); |
| 624 | 622 | } |
| 625 | 623 | |
| 626 | − of_node_put(card->aux_dev[0].codec_of_node); | |
| 624 | + of_node_put(card->aux_dev[0].dlc.of_node); | |
| 627 | 625 | |
| 628 | 626 | return ret; |
| 629 | 627 | } |
| @@ -1421,6 +1421,20 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream, · 1420 unmodified lines | ||
| 1421 | 1421 | params_buffer_bytes(hw_params)); |
| 1422 | 1422 | } |
| 1423 | 1423 | |
| 1424 | +static int rsnd_hw_free(struct snd_pcm_substream *substream) | |
| 1425 | +{ | |
| 1426 | + struct snd_soc_dai *dai = rsnd_substream_to_dai(substream); | |
| 1427 | + struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | |
| 1428 | + struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); | |
| 1429 | + int ret; | |
| 1430 | + | |
| 1431 | + ret = rsnd_dai_call(hw_free, io, substream); | |
| 1432 | + if (ret) | |
| 1433 | + return ret; | |
| 1434 | + | |
| 1435 | + return snd_pcm_lib_free_pages(substream); | |
| 1436 | +} | |
| 1437 | + | |
| 1424 | 1438 | static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) |
| 1425 | 1439 | { |
| 1426 | 1440 | struct snd_soc_dai *dai = rsnd_substream_to_dai(substream); |
| @@ -1436,7 +1450,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) · 9 unmodified lines | ||
| 1436 | 1450 | static const struct snd_pcm_ops rsnd_pcm_ops = { |
| 1437 | 1451 | .ioctl = snd_pcm_lib_ioctl, |
| 1438 | 1452 | .hw_params = rsnd_hw_params, |
| 1439 | − .hw_free = snd_pcm_lib_free_pages, | |
| 1453 | + .hw_free = rsnd_hw_free, | |
| 1440 | 1454 | .pointer = rsnd_pointer, |
| 1441 | 1455 | }; |
| 1442 | 1456 | |
| @@ -327,6 +327,9 @@ struct rsnd_mod_ops { · 326 unmodified lines | ||
| 327 | 327 | int (*cleanup)(struct rsnd_mod *mod, |
| 328 | 328 | struct rsnd_dai_stream *io, |
| 329 | 329 | struct rsnd_priv *priv); |
| 330 | + int (*hw_free)(struct rsnd_mod *mod, | |
| 331 | + struct rsnd_dai_stream *io, | |
| 332 | + struct snd_pcm_substream *substream); | |
| 330 | 333 | u32 *(*get_status)(struct rsnd_mod *mod, |
| 331 | 334 | struct rsnd_dai_stream *io, |
| 332 | 335 | enum rsnd_mod_type type); |
| @@ -351,12 +354,12 @@ struct rsnd_mod { · 18 unmodified lines | ||
| 351 | 354 | * |
| 352 | 355 | * B 0: init 1: quit |
| 353 | 356 | * C 0: start 1: stop |
| 357 | + * D 0: hw_params 1: hw_free | |
| 354 | 358 | * |
| 355 | 359 | * H is always called (see __rsnd_mod_call) |
| 356 | 360 | * H 0: probe 1: remove |
| 357 | 361 | * H 0: pcm_new |
| 358 | 362 | * H 0: fallback |
| 359 | − * H 0: hw_params | |
| 360 | 363 | * H 0: pointer |
| 361 | 364 | * H 0: prepare |
| 362 | 365 | * H 0: cleanup |
| @@ -365,12 +368,13 @@ struct rsnd_mod { · 2 unmodified lines | ||
| 365 | 368 | #define __rsnd_mod_shift_quit 4 |
| 366 | 369 | #define __rsnd_mod_shift_start 8 |
| 367 | 370 | #define __rsnd_mod_shift_stop 8 |
| 371 | +#define __rsnd_mod_shift_hw_params 12 | |
| 372 | +#define __rsnd_mod_shift_hw_free 12 | |
| 368 | 373 | #define __rsnd_mod_shift_probe 28 /* always called */ |
| 369 | 374 | #define __rsnd_mod_shift_remove 28 /* always called */ |
| 370 | 375 | #define __rsnd_mod_shift_irq 28 /* always called */ |
| 371 | 376 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ |
| 372 | 377 | #define __rsnd_mod_shift_fallback 28 /* always called */ |
| 373 | −#define __rsnd_mod_shift_hw_params 28 /* always called */ | |
| 374 | 378 | #define __rsnd_mod_shift_pointer 28 /* always called */ |
| 375 | 379 | #define __rsnd_mod_shift_prepare 28 /* always called */ |
| 376 | 380 | #define __rsnd_mod_shift_cleanup 28 /* always called */ |
| @@ -383,10 +387,11 @@ struct rsnd_mod { · 6 unmodified lines | ||
| 383 | 387 | #define __rsnd_mod_add_quit -1 |
| 384 | 388 | #define __rsnd_mod_add_start 1 |
| 385 | 389 | #define __rsnd_mod_add_stop -1 |
| 390 | +#define __rsnd_mod_add_hw_params 1 | |
| 391 | +#define __rsnd_mod_add_hw_free -1 | |
| 386 | 392 | #define __rsnd_mod_add_irq 0 |
| 387 | 393 | #define __rsnd_mod_add_pcm_new 0 |
| 388 | 394 | #define __rsnd_mod_add_fallback 0 |
| 389 | −#define __rsnd_mod_add_hw_params 0 | |
| 390 | 395 | #define __rsnd_mod_add_pointer 0 |
| 391 | 396 | |
| 392 | 397 | #define __rsnd_mod_call_probe 0 |
| @@ -402,6 +407,7 @@ struct rsnd_mod { · 9 unmodified lines | ||
| 402 | 407 | #define __rsnd_mod_call_fallback 0 |
| 403 | 408 | #define __rsnd_mod_call_hw_params 0 |
| 404 | 409 | #define __rsnd_mod_call_pointer 0 |
| 410 | +#define __rsnd_mod_call_hw_free 1 | |
| 405 | 411 | |
| 406 | 412 | #define rsnd_mod_to_priv(mod) ((mod)->priv) |
| 407 | 413 | #define rsnd_mod_power_on(mod) clk_enable((mod)->clk) |
| @@ -359,7 +359,6 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev) · 358 unmodified lines | ||
| 359 | 359 | int ret; |
| 360 | 360 | struct sirf_usp *usp; |
| 361 | 361 | void __iomem *base; |
| 362 | − struct resource *mem_res; | |
| 363 | 362 | |
| 364 | 363 | usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), |
| 365 | 364 | GFP_KERNEL); |
| @@ -368,8 +367,7 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 368 | 367 | |
| 369 | 368 | platform_set_drvdata(pdev, usp); |
| 370 | 369 | |
| 371 | − mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 372 | − base = devm_ioremap_resource(&pdev->dev, mem_res); | |
| 370 | + base = devm_platform_ioremap_resource(pdev, 0); | |
| 373 | 371 | if (IS_ERR(base)) |
| 374 | 372 | return PTR_ERR(base); |
| 375 | 373 | usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
| @@ -0,0 +1,561 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +// | |
| 3 | +// soc-component.c | |
| 4 | +// | |
| 5 | +// Copyright (C) 2019 Renesas Electronics Corp. | |
| 6 | +// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
| 7 | +// | |
| 8 | +#include <linux/module.h> | |
| 9 | +#include <sound/soc.h> | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * snd_soc_component_set_sysclk - configure COMPONENT system or master clock. | |
| 13 | + * @component: COMPONENT | |
| 14 | + * @clk_id: DAI specific clock ID | |
| 15 | + * @source: Source for the clock | |
| 16 | + * @freq: new clock frequency in Hz | |
| 17 | + * @dir: new clock direction - input/output. | |
| 18 | + * | |
| 19 | + * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. | |
| 20 | + */ | |
| 21 | +int snd_soc_component_set_sysclk(struct snd_soc_component *component, | |
| 22 | + int clk_id, int source, unsigned int freq, | |
| 23 | + int dir) | |
| 24 | +{ | |
| 25 | + if (component->driver->set_sysclk) | |
| 26 | + return component->driver->set_sysclk(component, clk_id, source, | |
| 27 | + freq, dir); | |
| 28 | + | |
| 29 | + return -ENOTSUPP; | |
| 30 | +} | |
| 31 | +EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk); | |
| 32 | + | |
| 33 | +/* | |
| 34 | + * snd_soc_component_set_pll - configure component PLL. | |
| 35 | + * @component: COMPONENT | |
| 36 | + * @pll_id: DAI specific PLL ID | |
| 37 | + * @source: DAI specific source for the PLL | |
| 38 | + * @freq_in: PLL input clock frequency in Hz | |
| 39 | + * @freq_out: requested PLL output clock frequency in Hz | |
| 40 | + * | |
| 41 | + * Configures and enables PLL to generate output clock based on input clock. | |
| 42 | + */ | |
| 43 | +int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, | |
| 44 | + int source, unsigned int freq_in, | |
| 45 | + unsigned int freq_out) | |
| 46 | +{ | |
| 47 | + if (component->driver->set_pll) | |
| 48 | + return component->driver->set_pll(component, pll_id, source, | |
| 49 | + freq_in, freq_out); | |
| 50 | + | |
| 51 | + return -EINVAL; | |
| 52 | +} | |
| 53 | +EXPORT_SYMBOL_GPL(snd_soc_component_set_pll); | |
| 54 | + | |
| 55 | +void snd_soc_component_seq_notifier(struct snd_soc_component *component, | |
| 56 | + enum snd_soc_dapm_type type, int subseq) | |
| 57 | +{ | |
| 58 | + if (component->driver->seq_notifier) | |
| 59 | + component->driver->seq_notifier(component, type, subseq); | |
| 60 | +} | |
| 61 | + | |
| 62 | +int snd_soc_component_stream_event(struct snd_soc_component *component, | |
| 63 | + int event) | |
| 64 | +{ | |
| 65 | + if (component->driver->stream_event) | |
| 66 | + return component->driver->stream_event(component, event); | |
| 67 | + | |
| 68 | + return 0; | |
| 69 | +} | |
| 70 | + | |
| 71 | +int snd_soc_component_set_bias_level(struct snd_soc_component *component, | |
| 72 | + enum snd_soc_bias_level level) | |
| 73 | +{ | |
| 74 | + if (component->driver->set_bias_level) | |
| 75 | + return component->driver->set_bias_level(component, level); | |
| 76 | + | |
| 77 | + return 0; | |
| 78 | +} | |
| 79 | + | |
| 80 | +int snd_soc_component_enable_pin(struct snd_soc_component *component, | |
| 81 | + const char *pin) | |
| 82 | +{ | |
| 83 | + struct snd_soc_dapm_context *dapm = | |
| 84 | + snd_soc_component_get_dapm(component); | |
| 85 | + char *full_name; | |
| 86 | + int ret; | |
| 87 | + | |
| 88 | + if (!component->name_prefix) | |
| 89 | + return snd_soc_dapm_enable_pin(dapm, pin); | |
| 90 | + | |
| 91 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 92 | + if (!full_name) | |
| 93 | + return -ENOMEM; | |
| 94 | + | |
| 95 | + ret = snd_soc_dapm_enable_pin(dapm, full_name); | |
| 96 | + kfree(full_name); | |
| 97 | + | |
| 98 | + return ret; | |
| 99 | +} | |
| 100 | +EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin); | |
| 101 | + | |
| 102 | +int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, | |
| 103 | + const char *pin) | |
| 104 | +{ | |
| 105 | + struct snd_soc_dapm_context *dapm = | |
| 106 | + snd_soc_component_get_dapm(component); | |
| 107 | + char *full_name; | |
| 108 | + int ret; | |
| 109 | + | |
| 110 | + if (!component->name_prefix) | |
| 111 | + return snd_soc_dapm_enable_pin_unlocked(dapm, pin); | |
| 112 | + | |
| 113 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 114 | + if (!full_name) | |
| 115 | + return -ENOMEM; | |
| 116 | + | |
| 117 | + ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name); | |
| 118 | + kfree(full_name); | |
| 119 | + | |
| 120 | + return ret; | |
| 121 | +} | |
| 122 | +EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked); | |
| 123 | + | |
| 124 | +int snd_soc_component_disable_pin(struct snd_soc_component *component, | |
| 125 | + const char *pin) | |
| 126 | +{ | |
| 127 | + struct snd_soc_dapm_context *dapm = | |
| 128 | + snd_soc_component_get_dapm(component); | |
| 129 | + char *full_name; | |
| 130 | + int ret; | |
| 131 | + | |
| 132 | + if (!component->name_prefix) | |
| 133 | + return snd_soc_dapm_disable_pin(dapm, pin); | |
| 134 | + | |
| 135 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 136 | + if (!full_name) | |
| 137 | + return -ENOMEM; | |
| 138 | + | |
| 139 | + ret = snd_soc_dapm_disable_pin(dapm, full_name); | |
| 140 | + kfree(full_name); | |
| 141 | + | |
| 142 | + return ret; | |
| 143 | +} | |
| 144 | +EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin); | |
| 145 | + | |
| 146 | +int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, | |
| 147 | + const char *pin) | |
| 148 | +{ | |
| 149 | + struct snd_soc_dapm_context *dapm = | |
| 150 | + snd_soc_component_get_dapm(component); | |
| 151 | + char *full_name; | |
| 152 | + int ret; | |
| 153 | + | |
| 154 | + if (!component->name_prefix) | |
| 155 | + return snd_soc_dapm_disable_pin_unlocked(dapm, pin); | |
| 156 | + | |
| 157 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 158 | + if (!full_name) | |
| 159 | + return -ENOMEM; | |
| 160 | + | |
| 161 | + ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name); | |
| 162 | + kfree(full_name); | |
| 163 | + | |
| 164 | + return ret; | |
| 165 | +} | |
| 166 | +EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked); | |
| 167 | + | |
| 168 | +int snd_soc_component_nc_pin(struct snd_soc_component *component, | |
| 169 | + const char *pin) | |
| 170 | +{ | |
| 171 | + struct snd_soc_dapm_context *dapm = | |
| 172 | + snd_soc_component_get_dapm(component); | |
| 173 | + char *full_name; | |
| 174 | + int ret; | |
| 175 | + | |
| 176 | + if (!component->name_prefix) | |
| 177 | + return snd_soc_dapm_nc_pin(dapm, pin); | |
| 178 | + | |
| 179 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 180 | + if (!full_name) | |
| 181 | + return -ENOMEM; | |
| 182 | + | |
| 183 | + ret = snd_soc_dapm_nc_pin(dapm, full_name); | |
| 184 | + kfree(full_name); | |
| 185 | + | |
| 186 | + return ret; | |
| 187 | +} | |
| 188 | +EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin); | |
| 189 | + | |
| 190 | +int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, | |
| 191 | + const char *pin) | |
| 192 | +{ | |
| 193 | + struct snd_soc_dapm_context *dapm = | |
| 194 | + snd_soc_component_get_dapm(component); | |
| 195 | + char *full_name; | |
| 196 | + int ret; | |
| 197 | + | |
| 198 | + if (!component->name_prefix) | |
| 199 | + return snd_soc_dapm_nc_pin_unlocked(dapm, pin); | |
| 200 | + | |
| 201 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 202 | + if (!full_name) | |
| 203 | + return -ENOMEM; | |
| 204 | + | |
| 205 | + ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name); | |
| 206 | + kfree(full_name); | |
| 207 | + | |
| 208 | + return ret; | |
| 209 | +} | |
| 210 | +EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked); | |
| 211 | + | |
| 212 | +int snd_soc_component_get_pin_status(struct snd_soc_component *component, | |
| 213 | + const char *pin) | |
| 214 | +{ | |
| 215 | + struct snd_soc_dapm_context *dapm = | |
| 216 | + snd_soc_component_get_dapm(component); | |
| 217 | + char *full_name; | |
| 218 | + int ret; | |
| 219 | + | |
| 220 | + if (!component->name_prefix) | |
| 221 | + return snd_soc_dapm_get_pin_status(dapm, pin); | |
| 222 | + | |
| 223 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 224 | + if (!full_name) | |
| 225 | + return -ENOMEM; | |
| 226 | + | |
| 227 | + ret = snd_soc_dapm_get_pin_status(dapm, full_name); | |
| 228 | + kfree(full_name); | |
| 229 | + | |
| 230 | + return ret; | |
| 231 | +} | |
| 232 | +EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status); | |
| 233 | + | |
| 234 | +int snd_soc_component_force_enable_pin(struct snd_soc_component *component, | |
| 235 | + const char *pin) | |
| 236 | +{ | |
| 237 | + struct snd_soc_dapm_context *dapm = | |
| 238 | + snd_soc_component_get_dapm(component); | |
| 239 | + char *full_name; | |
| 240 | + int ret; | |
| 241 | + | |
| 242 | + if (!component->name_prefix) | |
| 243 | + return snd_soc_dapm_force_enable_pin(dapm, pin); | |
| 244 | + | |
| 245 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 246 | + if (!full_name) | |
| 247 | + return -ENOMEM; | |
| 248 | + | |
| 249 | + ret = snd_soc_dapm_force_enable_pin(dapm, full_name); | |
| 250 | + kfree(full_name); | |
| 251 | + | |
| 252 | + return ret; | |
| 253 | +} | |
| 254 | +EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin); | |
| 255 | + | |
| 256 | +int snd_soc_component_force_enable_pin_unlocked( | |
| 257 | + struct snd_soc_component *component, | |
| 258 | + const char *pin) | |
| 259 | +{ | |
| 260 | + struct snd_soc_dapm_context *dapm = | |
| 261 | + snd_soc_component_get_dapm(component); | |
| 262 | + char *full_name; | |
| 263 | + int ret; | |
| 264 | + | |
| 265 | + if (!component->name_prefix) | |
| 266 | + return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); | |
| 267 | + | |
| 268 | + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); | |
| 269 | + if (!full_name) | |
| 270 | + return -ENOMEM; | |
| 271 | + | |
| 272 | + ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name); | |
| 273 | + kfree(full_name); | |
| 274 | + | |
| 275 | + return ret; | |
| 276 | +} | |
| 277 | +EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked); | |
| 278 | + | |
| 279 | +/** | |
| 280 | + * snd_soc_component_set_jack - configure component jack. | |
| 281 | + * @component: COMPONENTs | |
| 282 | + * @jack: structure to use for the jack | |
| 283 | + * @data: can be used if codec driver need extra data for configuring jack | |
| 284 | + * | |
| 285 | + * Configures and enables jack detection function. | |
| 286 | + */ | |
| 287 | +int snd_soc_component_set_jack(struct snd_soc_component *component, | |
| 288 | + struct snd_soc_jack *jack, void *data) | |
| 289 | +{ | |
| 290 | + if (component->driver->set_jack) | |
| 291 | + return component->driver->set_jack(component, jack, data); | |
| 292 | + | |
| 293 | + return -ENOTSUPP; | |
| 294 | +} | |
| 295 | +EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); | |
| 296 | + | |
| 297 | +int snd_soc_component_module_get(struct snd_soc_component *component, | |
| 298 | + int upon_open) | |
| 299 | +{ | |
| 300 | + if (component->driver->module_get_upon_open == !!upon_open && | |
| 301 | + !try_module_get(component->dev->driver->owner)) | |
| 302 | + return -ENODEV; | |
| 303 | + | |
| 304 | + return 0; | |
| 305 | +} | |
| 306 | + | |
| 307 | +void snd_soc_component_module_put(struct snd_soc_component *component, | |
| 308 | + int upon_open) | |
| 309 | +{ | |
| 310 | + if (component->driver->module_get_upon_open == !!upon_open) | |
| 311 | + module_put(component->dev->driver->owner); | |
| 312 | +} | |
| 313 | + | |
| 314 | +int snd_soc_component_open(struct snd_soc_component *component, | |
| 315 | + struct snd_pcm_substream *substream) | |
| 316 | +{ | |
| 317 | + if (component->driver->ops && | |
| 318 | + component->driver->ops->open) | |
| 319 | + return component->driver->ops->open(substream); | |
| 320 | + | |
| 321 | + return 0; | |
| 322 | +} | |
| 323 | + | |
| 324 | +int snd_soc_component_close(struct snd_soc_component *component, | |
| 325 | + struct snd_pcm_substream *substream) | |
| 326 | +{ | |
| 327 | + if (component->driver->ops && | |
| 328 | + component->driver->ops->close) | |
| 329 | + return component->driver->ops->close(substream); | |
| 330 | + | |
| 331 | + return 0; | |
| 332 | +} | |
| 333 | + | |
| 334 | +int snd_soc_component_prepare(struct snd_soc_component *component, | |
| 335 | + struct snd_pcm_substream *substream) | |
| 336 | +{ | |
| 337 | + if (component->driver->ops && | |
| 338 | + component->driver->ops->prepare) | |
| 339 | + return component->driver->ops->prepare(substream); | |
| 340 | + | |
| 341 | + return 0; | |
| 342 | +} | |
| 343 | + | |
| 344 | +int snd_soc_component_hw_params(struct snd_soc_component *component, | |
| 345 | + struct snd_pcm_substream *substream, | |
| 346 | + struct snd_pcm_hw_params *params) | |
| 347 | +{ | |
| 348 | + if (component->driver->ops && | |
| 349 | + component->driver->ops->hw_params) | |
| 350 | + return component->driver->ops->hw_params(substream, params); | |
| 351 | + | |
| 352 | + return 0; | |
| 353 | +} | |
| 354 | + | |
| 355 | +int snd_soc_component_hw_free(struct snd_soc_component *component, | |
| 356 | + struct snd_pcm_substream *substream) | |
| 357 | +{ | |
| 358 | + if (component->driver->ops && | |
| 359 | + component->driver->ops->hw_free) | |
| 360 | + return component->driver->ops->hw_free(substream); | |
| 361 | + | |
| 362 | + return 0; | |
| 363 | +} | |
| 364 | + | |
| 365 | +int snd_soc_component_trigger(struct snd_soc_component *component, | |
| 366 | + struct snd_pcm_substream *substream, | |
| 367 | + int cmd) | |
| 368 | +{ | |
| 369 | + if (component->driver->ops && | |
| 370 | + component->driver->ops->trigger) | |
| 371 | + return component->driver->ops->trigger(substream, cmd); | |
| 372 | + | |
| 373 | + return 0; | |
| 374 | +} | |
| 375 | + | |
| 376 | +void snd_soc_component_suspend(struct snd_soc_component *component) | |
| 377 | +{ | |
| 378 | + if (component->driver->suspend) | |
| 379 | + component->driver->suspend(component); | |
| 380 | + component->suspended = 1; | |
| 381 | +} | |
| 382 | + | |
| 383 | +void snd_soc_component_resume(struct snd_soc_component *component) | |
| 384 | +{ | |
| 385 | + if (component->driver->resume) | |
| 386 | + component->driver->resume(component); | |
| 387 | + component->suspended = 0; | |
| 388 | +} | |
| 389 | + | |
| 390 | +int snd_soc_component_is_suspended(struct snd_soc_component *component) | |
| 391 | +{ | |
| 392 | + return component->suspended; | |
| 393 | +} | |
| 394 | + | |
| 395 | +int snd_soc_component_probe(struct snd_soc_component *component) | |
| 396 | +{ | |
| 397 | + if (component->driver->probe) | |
| 398 | + return component->driver->probe(component); | |
| 399 | + | |
| 400 | + return 0; | |
| 401 | +} | |
| 402 | + | |
| 403 | +void snd_soc_component_remove(struct snd_soc_component *component) | |
| 404 | +{ | |
| 405 | + if (component->driver->remove) | |
| 406 | + component->driver->remove(component); | |
| 407 | +} | |
| 408 | + | |
| 409 | +int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component, | |
| 410 | + struct device_node *ep) | |
| 411 | +{ | |
| 412 | + if (component->driver->of_xlate_dai_id) | |
| 413 | + return component->driver->of_xlate_dai_id(component, ep); | |
| 414 | + | |
| 415 | + return -ENOTSUPP; | |
| 416 | +} | |
| 417 | + | |
| 418 | +int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component, | |
| 419 | + struct of_phandle_args *args, | |
| 420 | + const char **dai_name) | |
| 421 | +{ | |
| 422 | + if (component->driver->of_xlate_dai_name) | |
| 423 | + return component->driver->of_xlate_dai_name(component, | |
| 424 | + args, dai_name); | |
| 425 | + return -ENOTSUPP; | |
| 426 | +} | |
| 427 | + | |
| 428 | +int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) | |
| 429 | +{ | |
| 430 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 431 | + struct snd_soc_component *component; | |
| 432 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 433 | + | |
| 434 | + for_each_rtdcom(rtd, rtdcom) { | |
| 435 | + component = rtdcom->component; | |
| 436 | + | |
| 437 | + /* FIXME: use 1st pointer */ | |
| 438 | + if (component->driver->ops && | |
| 439 | + component->driver->ops->pointer) | |
| 440 | + return component->driver->ops->pointer(substream); | |
| 441 | + } | |
| 442 | + | |
| 443 | + return 0; | |
| 444 | +} | |
| 445 | + | |
| 446 | +int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, | |
| 447 | + unsigned int cmd, void *arg) | |
| 448 | +{ | |
| 449 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 450 | + struct snd_soc_component *component; | |
| 451 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 452 | + | |
| 453 | + for_each_rtdcom(rtd, rtdcom) { | |
| 454 | + component = rtdcom->component; | |
| 455 | + | |
| 456 | + /* FIXME: use 1st ioctl */ | |
| 457 | + if (component->driver->ops && | |
| 458 | + component->driver->ops->ioctl) | |
| 459 | + return component->driver->ops->ioctl(substream, | |
| 460 | + cmd, arg); | |
| 461 | + } | |
| 462 | + | |
| 463 | + return snd_pcm_lib_ioctl(substream, cmd, arg); | |
| 464 | +} | |
| 465 | + | |
| 466 | +int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream, | |
| 467 | + int channel, unsigned long pos, | |
| 468 | + void __user *buf, unsigned long bytes) | |
| 469 | +{ | |
| 470 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 471 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 472 | + struct snd_soc_component *component; | |
| 473 | + | |
| 474 | + for_each_rtdcom(rtd, rtdcom) { | |
| 475 | + component = rtdcom->component; | |
| 476 | + | |
| 477 | + /* FIXME. it returns 1st copy now */ | |
| 478 | + if (component->driver->ops && | |
| 479 | + component->driver->ops->copy_user) | |
| 480 | + return component->driver->ops->copy_user( | |
| 481 | + substream, channel, pos, buf, bytes); | |
| 482 | + } | |
| 483 | + | |
| 484 | + return -EINVAL; | |
| 485 | +} | |
| 486 | + | |
| 487 | +struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream, | |
| 488 | + unsigned long offset) | |
| 489 | +{ | |
| 490 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 491 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 492 | + struct snd_soc_component *component; | |
| 493 | + struct page *page; | |
| 494 | + | |
| 495 | + for_each_rtdcom(rtd, rtdcom) { | |
| 496 | + component = rtdcom->component; | |
| 497 | + | |
| 498 | + /* FIXME. it returns 1st page now */ | |
| 499 | + if (component->driver->ops && | |
| 500 | + component->driver->ops->page) { | |
| 501 | + page = component->driver->ops->page(substream, offset); | |
| 502 | + if (page) | |
| 503 | + return page; | |
| 504 | + } | |
| 505 | + } | |
| 506 | + | |
| 507 | + return NULL; | |
| 508 | +} | |
| 509 | + | |
| 510 | +int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream, | |
| 511 | + struct vm_area_struct *vma) | |
| 512 | +{ | |
| 513 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 514 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 515 | + struct snd_soc_component *component; | |
| 516 | + | |
| 517 | + for_each_rtdcom(rtd, rtdcom) { | |
| 518 | + component = rtdcom->component; | |
| 519 | + | |
| 520 | + /* FIXME. it returns 1st mmap now */ | |
| 521 | + if (component->driver->ops && | |
| 522 | + component->driver->ops->mmap) | |
| 523 | + return component->driver->ops->mmap(substream, vma); | |
| 524 | + } | |
| 525 | + | |
| 526 | + return -EINVAL; | |
| 527 | +} | |
| 528 | + | |
| 529 | +int snd_soc_pcm_component_new(struct snd_pcm *pcm) | |
| 530 | +{ | |
| 531 | + struct snd_soc_pcm_runtime *rtd = pcm->private_data; | |
| 532 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 533 | + struct snd_soc_component *component; | |
| 534 | + int ret; | |
| 535 | + | |
| 536 | + for_each_rtdcom(rtd, rtdcom) { | |
| 537 | + component = rtdcom->component; | |
| 538 | + | |
| 539 | + if (component->driver->pcm_new) { | |
| 540 | + ret = component->driver->pcm_new(rtd); | |
| 541 | + if (ret < 0) | |
| 542 | + return ret; | |
| 543 | + } | |
| 544 | + } | |
| 545 | + | |
| 546 | + return 0; | |
| 547 | +} | |
| 548 | + | |
| 549 | +void snd_soc_pcm_component_free(struct snd_pcm *pcm) | |
| 550 | +{ | |
| 551 | + struct snd_soc_pcm_runtime *rtd = pcm->private_data; | |
| 552 | + struct snd_soc_rtdcom_list *rtdcom; | |
| 553 | + struct snd_soc_component *component; | |
| 554 | + | |
| 555 | + for_each_rtdcom(rtd, rtdcom) { | |
| 556 | + component = rtdcom->component; | |
| 557 | + | |
| 558 | + if (component->driver->pcm_free) | |
| 559 | + component->driver->pcm_free(pcm); | |
| 560 | + } | |
| 561 | +} | |
| @@ -80,7 +80,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) · 79 unmodified lines | ||
| 80 | 80 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 81 | 81 | int ret; |
| 82 | 82 | |
| 83 | − mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | |
| 83 | + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); | |
| 84 | 84 | |
| 85 | 85 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { |
| 86 | 86 | ret = cpu_dai->driver->cops->startup(cstream, cpu_dai); |
| @@ -108,7 +108,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) · 21 unmodified lines | ||
| 108 | 108 | |
| 109 | 109 | snd_soc_runtime_activate(rtd, cstream->direction); |
| 110 | 110 | |
| 111 | − mutex_unlock(&rtd->pcm_mutex); | |
| 111 | + mutex_unlock(&rtd->card->pcm_mutex); | |
| 112 | 112 | |
| 113 | 113 | return 0; |
| 114 | 114 | |
| @@ -118,7 +118,7 @@ machine_err: · 3 unmodified lines | ||
| 118 | 118 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) |
| 119 | 119 | cpu_dai->driver->cops->shutdown(cstream, cpu_dai); |
| 120 | 120 | out: |
| 121 | − mutex_unlock(&rtd->pcm_mutex); | |
| 121 | + mutex_unlock(&rtd->card->pcm_mutex); | |
| 122 | 122 | return ret; |
| 123 | 123 | } |
| 124 | 124 | |
| @@ -224,7 +224,7 @@ static void close_delayed_work(struct work_struct *work) · 99 unmodified lines | ||
| 224 | 224 | container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); |
| 225 | 225 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 226 | 226 | |
| 227 | − mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | |
| 227 | + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); | |
| 228 | 228 | |
| 229 | 229 | dev_dbg(rtd->dev, |
| 230 | 230 | "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n", |
| @@ -239,7 +239,7 @@ static void close_delayed_work(struct work_struct *work) · 8 unmodified lines | ||
| 239 | 239 | SND_SOC_DAPM_STREAM_STOP); |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | − mutex_unlock(&rtd->pcm_mutex); | |
| 242 | + mutex_unlock(&rtd->card->pcm_mutex); | |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | static int soc_compr_free(struct snd_compr_stream *cstream) |
| @@ -249,7 +249,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) · 3 unmodified lines | ||
| 249 | 249 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 250 | 250 | int stream; |
| 251 | 251 | |
| 252 | − mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | |
| 252 | + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); | |
| 253 | 253 | |
| 254 | 254 | if (cstream->direction == SND_COMPRESS_PLAYBACK) |
| 255 | 255 | stream = SNDRV_PCM_STREAM_PLAYBACK; |
| @@ -292,7 +292,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) · 36 unmodified lines | ||
| 292 | 292 | SND_SOC_DAPM_STREAM_STOP); |
| 293 | 293 | } |
| 294 | 294 | |
| 295 | − mutex_unlock(&rtd->pcm_mutex); | |
| 295 | + mutex_unlock(&rtd->card->pcm_mutex); | |
| 296 | 296 | return 0; |
| 297 | 297 | } |
| 298 | 298 | |
| @@ -375,7 +375,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) · 76 unmodified lines | ||
| 375 | 375 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 376 | 376 | int ret; |
| 377 | 377 | |
| 378 | − mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); | |
| 378 | + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); | |
| 379 | 379 | |
| 380 | 380 | ret = soc_compr_components_trigger(cstream, cmd); |
| 381 | 381 | if (ret < 0) |
| @@ -394,7 +394,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) · 12 unmodified lines | ||
| 394 | 394 | } |
| 395 | 395 | |
159 more lines aren’t shown here.
This diff is large: its 1743 lines aren’t shown here.
This diff is large: its 408 lines aren’t shown here.
This diff is large: its 573 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 994 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 395 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 195 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 957 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 310 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.